@@ -15,36 +15,40 @@ abstract class InsufficientKeySizeSink extends DataFlow::Node {
15
15
predicate hasState ( DataFlow:: FlowState state ) { state instanceof DataFlow:: FlowStateEmpty }
16
16
}
17
17
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. */
19
20
private class AsymmetricNonEcSource extends InsufficientKeySizeSource {
20
21
AsymmetricNonEcSource ( ) { getNodeIntValue ( this ) < 2048 }
21
22
22
23
override predicate hasState ( DataFlow:: FlowState state ) { state = "2048" }
23
24
}
24
25
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 . */
26
27
private class AsymmetricEcSource extends InsufficientKeySizeSource {
27
28
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
30
33
}
31
34
32
35
override predicate hasState ( DataFlow:: FlowState state ) { state = "256" }
33
36
}
34
37
35
- /** A source for an insufficient key size (symmetric: AES) . */
38
+ /** A source for an insufficient key size used in AES algorithms . */
36
39
private class SymmetricSource extends InsufficientKeySizeSource {
37
40
SymmetricSource ( ) { getNodeIntValue ( this ) < 128 }
38
41
39
42
override predicate hasState ( DataFlow:: FlowState state ) { state = "128" }
40
43
}
41
44
45
+ // ************************** SOURCES HELPER PREDICATES **************************
46
+ /** Returns the integer value of a given Node. */
42
47
private int getNodeIntValue ( DataFlow:: Node node ) {
43
48
result = node .asExpr ( ) .( IntegerLiteral ) .getIntValue ( )
44
49
}
45
50
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 */
48
52
bindingset [ algorithm]
49
53
private int getEcKeySize ( string algorithm ) {
50
54
algorithm .matches ( "sec%" ) and // specification such as "secp256r1"
@@ -57,31 +61,26 @@ private int getEcKeySize(string algorithm) {
57
61
result = algorithm .regexpCapture ( ".*[a-zA-Z](\\d+)[a-zA-Z].*" , 1 ) .toInt ( )
58
62
}
59
63
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. */
61
66
private class AsymmetricNonEcSink extends InsufficientKeySizeSink {
62
67
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 |
67
69
kg .getAlgoName ( ) .matches ( [ "RSA" , "DSA" , "DH" ] ) and
68
70
DataFlow:: localExprFlow ( kg , ma .getQualifier ( ) ) and
69
71
this .asExpr ( ) = ma .getKeySizeArg ( )
70
72
)
71
73
or
72
- exists ( AsymmetricNonEcSpec s | this .asExpr ( ) = s .getKeySizeArg ( ) )
74
+ exists ( AsymmetricNonEcSpec spec | this .asExpr ( ) = spec .getKeySizeArg ( ) )
73
75
}
74
76
75
77
override predicate hasState ( DataFlow:: FlowState state ) { state = "2048" }
76
78
}
77
79
78
- /** A sink for an insufficient key size (asymmetric-ec) . */
80
+ /** A sink for an insufficient key size used in elliptic curve (EC) algorithms . */
79
81
private class AsymmetricEcSink extends InsufficientKeySizeSink {
80
82
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 |
85
84
kg .getAlgoName ( ) .matches ( "EC%" ) and
86
85
DataFlow:: localExprFlow ( kg , ma .getQualifier ( ) ) and
87
86
this .asExpr ( ) = ma .getKeySizeArg ( )
@@ -93,11 +92,11 @@ private class AsymmetricEcSink extends InsufficientKeySizeSink {
93
92
override predicate hasState ( DataFlow:: FlowState state ) { state = "256" }
94
93
}
95
94
96
- /** A sink for an insufficient key size (symmetric) . */
95
+ /** A sink for an insufficient key size used in AES algorithms . */
97
96
private class SymmetricSink extends InsufficientKeySizeSink {
98
97
SymmetricSink ( ) {
99
98
//hasKeySizeInInitMethod(this, "symmetric")
100
- exists ( SymmInitMethodAccess ma , SymmKeyGen kg |
99
+ exists ( SymmetricInitMethodAccess ma , SymmetricKeyGenerator kg |
101
100
kg .getAlgoName ( ) = "AES" and
102
101
DataFlow:: localExprFlow ( kg , ma .getQualifier ( ) ) and
103
102
this .asExpr ( ) = ma .getKeySizeArg ( )
@@ -107,55 +106,57 @@ private class SymmetricSink extends InsufficientKeySizeSink {
107
106
override predicate hasState ( DataFlow:: FlowState state ) { state = "128" }
108
107
}
109
108
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. */
111
113
Argument getKeySizeArg ( ) { result = this .getArgument ( 0 ) }
112
114
}
113
115
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 }
116
119
}
117
120
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 }
120
124
}
121
125
122
- abstract class KeyGen extends JavaxCryptoAlgoSpec {
126
+ /** An instance of a key generator. */
127
+ abstract class KeyGeneratorObject extends JavaxCryptoAlgoSpec {
123
128
string getAlgoName ( ) { result = this .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) }
124
129
}
125
130
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 }
128
134
129
- // ! this override is repetitive...
130
135
override Expr getAlgoSpec ( ) { result = this .( MethodAccess ) .getArgument ( 0 ) }
131
136
}
132
137
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 }
135
141
136
- // ! this override is repetitive...
137
142
override Expr getAlgoSpec ( ) { result = this .( MethodAccess ) .getArgument ( 0 ) }
138
143
}
139
144
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 {
143
147
Argument getKeySizeArg ( ) { result = this .getArgument ( 0 ) }
144
148
}
145
149
146
- class AsymmetricNonEcSpec extends AsymmetricAlgoSpec {
150
+ /** An instance of an RSA, DSA, or DH algorithm specification. */
151
+ private class AsymmetricNonEcSpec extends AlgoSpec {
147
152
AsymmetricNonEcSpec ( ) {
148
153
this .getConstructedType ( ) instanceof RsaKeyGenParameterSpec or
149
154
this .getConstructedType ( ) instanceof DsaGenParameterSpec or
150
155
this .getConstructedType ( ) instanceof DhGenParameterSpec
151
156
}
152
157
}
153
158
154
- class AsymmetricEcSpec extends AsymmetricAlgoSpec {
159
+ /** An instance of an elliptic curve (EC) algorithm specification. */
160
+ private class AsymmetricEcSpec extends AlgoSpec {
155
161
AsymmetricEcSpec ( ) { this .getConstructedType ( ) instanceof EcGenParameterSpec }
156
162
}
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