@@ -15,36 +15,40 @@ abstract class InsufficientKeySizeSink extends DataFlow::Node {
1515 predicate hasState ( DataFlow:: FlowState state ) { state instanceof DataFlow:: FlowStateEmpty }
1616}
1717
18- /** A source for an insufficient key size (asymmetric-non-ec: RSA, DSA, DH). */
18+ // *********************************** SOURCES ***********************************
19+ /** A source for an insufficient key size used in RSA, DSA, and DH algorithms. */
1920private class AsymmetricNonEcSource extends InsufficientKeySizeSource {
2021 AsymmetricNonEcSource ( ) { getNodeIntValue ( this ) < 2048 }
2122
2223 override predicate hasState ( DataFlow:: FlowState state ) { state = "2048" }
2324}
2425
25- /** A source for an insufficient key size (asymmetric-ec: EC%) . */
26+ /** A source for an insufficient key size used in elliptic curve (EC) algorithms . */
2627private class AsymmetricEcSource extends InsufficientKeySizeSource {
2728 AsymmetricEcSource ( ) {
28- getNodeIntValue ( this ) < 256 or
29- getEcKeySize ( this .asExpr ( ) .( StringLiteral ) .getValue ( ) ) < 256 // for cases when the key size is embedded in the curve name
29+ getNodeIntValue ( this ) < 256
30+ or
31+ // the below is needed for cases when the key size is embedded in the curve name
32+ getEcKeySize ( this .asExpr ( ) .( StringLiteral ) .getValue ( ) ) < 256
3033 }
3134
3235 override predicate hasState ( DataFlow:: FlowState state ) { state = "256" }
3336}
3437
35- /** A source for an insufficient key size (symmetric: AES) . */
38+ /** A source for an insufficient key size used in AES algorithms . */
3639private class SymmetricSource extends InsufficientKeySizeSource {
3740 SymmetricSource ( ) { getNodeIntValue ( this ) < 128 }
3841
3942 override predicate hasState ( DataFlow:: FlowState state ) { state = "128" }
4043}
4144
45+ // ************************** SOURCES HELPER PREDICATES **************************
46+ /** Returns the integer value of a given Node. */
4247private int getNodeIntValue ( DataFlow:: Node node ) {
4348 result = node .asExpr ( ) .( IntegerLiteral ) .getIntValue ( )
4449}
4550
46- // TODO: check if any other regex should be added based on some MRVA results.
47- /** Returns the key size in the EC algorithm string */
51+ /** Returns the key size from an EC algorithm curve name string */
4852bindingset [ algorithm]
4953private int getEcKeySize ( string algorithm ) {
5054 algorithm .matches ( "sec%" ) and // specification such as "secp256r1"
@@ -57,31 +61,26 @@ private int getEcKeySize(string algorithm) {
5761 result = algorithm .regexpCapture ( ".*[a-zA-Z](\\d+)[a-zA-Z].*" , 1 ) .toInt ( )
5862}
5963
60- /** A sink for an insufficient key size (asymmetric-non-ec). */
64+ // ************************************ SINKS ************************************
65+ /** A sink for an insufficient key size used in RSA, DSA, and DH algorithms. */
6166private class AsymmetricNonEcSink extends InsufficientKeySizeSink {
6267 AsymmetricNonEcSink ( ) {
63- // hasKeySizeInInitMethod(this, "asymmetric-non-ec")
64- // or
65- //hasKeySizeInSpec(this, "asymmetric-non-ec")
66- exists ( AsymmInitMethodAccess ma , AsymmKeyGen kg |
68+ exists ( AsymmetricInitMethodAccess ma , AsymmetricKeyGenerator kg |
6769 kg .getAlgoName ( ) .matches ( [ "RSA" , "DSA" , "DH" ] ) and
6870 DataFlow:: localExprFlow ( kg , ma .getQualifier ( ) ) and
6971 this .asExpr ( ) = ma .getKeySizeArg ( )
7072 )
7173 or
72- exists ( AsymmetricNonEcSpec s | this .asExpr ( ) = s .getKeySizeArg ( ) )
74+ exists ( AsymmetricNonEcSpec spec | this .asExpr ( ) = spec .getKeySizeArg ( ) )
7375 }
7476
7577 override predicate hasState ( DataFlow:: FlowState state ) { state = "2048" }
7678}
7779
78- /** A sink for an insufficient key size (asymmetric-ec) . */
80+ /** A sink for an insufficient key size used in elliptic curve (EC) algorithms . */
7981private class AsymmetricEcSink extends InsufficientKeySizeSink {
8082 AsymmetricEcSink ( ) {
81- // hasKeySizeInInitMethod(this, "asymmetric-ec")
82- // or
83- //hasKeySizeInSpec(this, "asymmetric-ec")
84- exists ( AsymmInitMethodAccess ma , AsymmKeyGen kg |
83+ exists ( AsymmetricInitMethodAccess ma , AsymmetricKeyGenerator kg |
8584 kg .getAlgoName ( ) .matches ( "EC%" ) and
8685 DataFlow:: localExprFlow ( kg , ma .getQualifier ( ) ) and
8786 this .asExpr ( ) = ma .getKeySizeArg ( )
@@ -93,11 +92,11 @@ private class AsymmetricEcSink extends InsufficientKeySizeSink {
9392 override predicate hasState ( DataFlow:: FlowState state ) { state = "256" }
9493}
9594
96- /** A sink for an insufficient key size (symmetric) . */
95+ /** A sink for an insufficient key size used in AES algorithms . */
9796private class SymmetricSink extends InsufficientKeySizeSink {
9897 SymmetricSink ( ) {
9998 //hasKeySizeInInitMethod(this, "symmetric")
100- exists ( SymmInitMethodAccess ma , SymmKeyGen kg |
99+ exists ( SymmetricInitMethodAccess ma , SymmetricKeyGenerator kg |
101100 kg .getAlgoName ( ) = "AES" and
102101 DataFlow:: localExprFlow ( kg , ma .getQualifier ( ) ) and
103102 this .asExpr ( ) = ma .getKeySizeArg ( )
@@ -107,55 +106,57 @@ private class SymmetricSink extends InsufficientKeySizeSink {
107106 override predicate hasState ( DataFlow:: FlowState state ) { state = "128" }
108107}
109108
110- abstract class InitMethodAccess extends MethodAccess {
109+ // ********************** SINKS HELPER CLASSES & PREDICATES **********************
110+ /** A call to a method that initializes a key generator. */
111+ abstract class KeyGenInitMethodAccess extends MethodAccess {
112+ /** Gets the `keysize` argument of this call. */
111113 Argument getKeySizeArg ( ) { result = this .getArgument ( 0 ) }
112114}
113115
114- class AsymmInitMethodAccess extends InitMethodAccess {
115- AsymmInitMethodAccess ( ) { this .getMethod ( ) instanceof KeyPairGeneratorInitMethod }
116+ /** A call to the `initialize` method declared in `java.security.KeyPairGenerator`. */
117+ private class AsymmetricInitMethodAccess extends KeyGenInitMethodAccess {
118+ AsymmetricInitMethodAccess ( ) { this .getMethod ( ) instanceof KeyPairGeneratorInitMethod }
116119}
117120
118- class SymmInitMethodAccess extends InitMethodAccess {
119- SymmInitMethodAccess ( ) { this .getMethod ( ) instanceof KeyGeneratorInitMethod }
121+ /** A call to the `init` method declared in `javax.crypto.KeyGenerator`. */
122+ private class SymmetricInitMethodAccess extends KeyGenInitMethodAccess {
123+ SymmetricInitMethodAccess ( ) { this .getMethod ( ) instanceof KeyGeneratorInitMethod }
120124}
121125
122- abstract class KeyGen extends JavaxCryptoAlgoSpec {
126+ /** An instance of a key generator. */
127+ abstract class KeyGeneratorObject extends JavaxCryptoAlgoSpec {
123128 string getAlgoName ( ) { result = this .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) }
124129}
125130
126- class AsymmKeyGen extends KeyGen {
127- AsymmKeyGen ( ) { this instanceof JavaSecurityKeyPairGenerator }
131+ /** An instance of a `java.security.KeyPairGenerator`. */
132+ private class AsymmetricKeyGenerator extends KeyGeneratorObject {
133+ AsymmetricKeyGenerator ( ) { this instanceof JavaSecurityKeyPairGenerator }
128134
129- // ! this override is repetitive...
130135 override Expr getAlgoSpec ( ) { result = this .( MethodAccess ) .getArgument ( 0 ) }
131136}
132137
133- class SymmKeyGen extends KeyGen {
134- SymmKeyGen ( ) { this instanceof JavaxCryptoKeyGenerator }
138+ /** An instance of a `javax.crypto.KeyGenerator`. */
139+ private class SymmetricKeyGenerator extends KeyGeneratorObject {
140+ SymmetricKeyGenerator ( ) { this instanceof JavaxCryptoKeyGenerator }
135141
136- // ! this override is repetitive...
137142 override Expr getAlgoSpec ( ) { result = this .( MethodAccess ) .getArgument ( 0 ) }
138143}
139144
140- // ! use below instead of/in above?? (actually I don't think I need any of this, can just use AsymmetricNonEcSpec and EcGenParameterSpec directly???)
141- // Algo spec
142- abstract class AsymmetricAlgoSpec extends ClassInstanceExpr {
145+ /** An instance of an algorithm specification. */
146+ abstract class AlgoSpec extends ClassInstanceExpr {
143147 Argument getKeySizeArg ( ) { result = this .getArgument ( 0 ) }
144148}
145149
146- class AsymmetricNonEcSpec extends AsymmetricAlgoSpec {
150+ /** An instance of an RSA, DSA, or DH algorithm specification. */
151+ private class AsymmetricNonEcSpec extends AlgoSpec {
147152 AsymmetricNonEcSpec ( ) {
148153 this .getConstructedType ( ) instanceof RsaKeyGenParameterSpec or
149154 this .getConstructedType ( ) instanceof DsaGenParameterSpec or
150155 this .getConstructedType ( ) instanceof DhGenParameterSpec
151156 }
152157}
153158
154- class AsymmetricEcSpec extends AsymmetricAlgoSpec {
159+ /** An instance of an elliptic curve (EC) algorithm specification. */
160+ private class AsymmetricEcSpec extends AlgoSpec {
155161 AsymmetricEcSpec ( ) { this .getConstructedType ( ) instanceof EcGenParameterSpec }
156162}
157- // TODO:
158- // todo #0: look into use of specs without keygen objects; should spec not be a sink in these cases?
159- // todo #3: make list of algo names more easily reusable (either as constant-type variable at top of file, or model as own class to share, etc.)
160- // todo: add barrier guard for !=0 conditional case
161- // todo: only update key sizes (and key size strings) in one place in the code
0 commit comments