@@ -3,11 +3,6 @@ import semmle.code.java.dataflow.TaintTracking2
33import semmle.code.java.dataflow.TaintTracking
44import semmle.code.java.dataflow.DataFlow
55
6- // TODO:
7- // todo #1: make representation of source that can be shared across the configs
8- // todo #2: make representation of sink that can be shared across the configs
9- // todo #3: finish adding tracking for algo type/name... need flow/taint-tracking for across methods??
10- // todo #3a: 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.)
116// ******* DATAFLOW BELOW *************************************************************************
127/**
138 * Asymmetric (RSA, DSA, DH) key length data flow tracking configuration.
@@ -16,8 +11,10 @@ class AsymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
1611 AsymmetricKeyTrackingConfiguration ( ) { this = "AsymmetricKeyTrackingConfiguration" }
1712
1813 override predicate isSource ( DataFlow:: Node source ) {
14+ // ! may need to change below to still use `keysize` variable as the source, not the spec
15+ // ! also need to look into specs for DSA and DH more
1916 exists ( ClassInstanceExpr rsaGenParamSpec |
20- rsaGenParamSpec .getConstructedType ( ) instanceof RSAGenParameterSpec and // ! double-check if should just use getType() instead
17+ rsaGenParamSpec .getConstructedType ( ) instanceof RSAGenParameterSpec and
2118 rsaGenParamSpec .getArgument ( 0 ) .( IntegerLiteral ) .getIntValue ( ) < 2048 and
2219 source .asExpr ( ) = rsaGenParamSpec
2320 )
@@ -26,18 +23,8 @@ class AsymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
2623 }
2724
2825 override predicate isSink ( DataFlow:: Node sink ) {
29- exists ( MethodAccess ma , VarAccess va |
26+ exists ( MethodAccess ma |
3027 ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
31- //ma.getFile().getBaseName().matches("SignatureTest.java") and
32- // va.getVariable()
33- // .getAnAssignedValue()
34- // .(JavaSecurityKeyPairGenerator)
35- // .getAlgoSpec()
36- // .(StringLiteral)
37- // .getValue()
38- // .toUpperCase()
39- // .matches(["RSA", "DSA", "DH"]) and
40- // ma.getQualifier() = va and
4128 exists (
4229 JavaSecurityKeyPairGenerator jpg , KeyPairGeneratorInitConfiguration kpgConfig ,
4330 DataFlow:: PathNode source , DataFlow:: PathNode dest
@@ -52,41 +39,25 @@ class AsymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
5239 }
5340}
5441
55- // predicate hasInsufficientKeySize(string msg) { hasShortAsymmetricKeyPair(msg) }
56- // predicate hasShortAsymmetricKeyPair(string msg) {
57- // exists(AsymmetricKeyTrackingConfiguration config1, DataFlow::Node source, DataFlow::Node sink |
58- // config1.hasFlow(source, sink)
59- // ) and
60- // msg = "Key size should be at least 2048 bits for " + "___" + " encryption."
61- // }
6242/**
6343 * Asymmetric (EC) key length data flow tracking configuration.
6444 */
6545class AsymmetricECCKeyTrackingConfiguration extends TaintTracking2:: Configuration {
6646 AsymmetricECCKeyTrackingConfiguration ( ) { this = "AsymmetricECCKeyTrackingConfiguration" }
6747
6848 override predicate isSource ( DataFlow:: Node source ) {
49+ // ! may need to change below to still use `keysize` variable as the source, not the spec
6950 exists ( ClassInstanceExpr ecGenParamSpec |
70- getECKeySize ( ecGenParamSpec .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) ) < 256 and // ! can generate EC with just the keysize and not the curve apparently... (based on netty/netty FP example)
51+ getECKeySize ( ecGenParamSpec .getArgument ( 0 ) .( StringLiteral ) .getValue ( ) ) < 256 and
7152 source .asExpr ( ) = ecGenParamSpec
7253 )
7354 or
7455 source .asExpr ( ) .( IntegerLiteral ) .getIntValue ( ) < 256
7556 }
7657
7758 override predicate isSink ( DataFlow:: Node sink ) {
78- exists ( MethodAccess ma , VarAccess va |
59+ exists ( MethodAccess ma |
7960 ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
80- //ma.getArgument(0).getType() instanceof ECGenParameterSpec and // ! can generate EC with just the keysize and not the curve apparently... (based on netty/netty FP example)
81- // va.getVariable()
82- // .getAnAssignedValue()
83- // .(JavaSecurityKeyPairGenerator)
84- // .getAlgoSpec()
85- // .(StringLiteral)
86- // .getValue()
87- // .toUpperCase()
88- // .matches(["EC%"]) and
89- // ma.getQualifier() = va and
9061 exists (
9162 JavaSecurityKeyPairGenerator jpg , KeyPairGeneratorInitConfiguration kpgConfig ,
9263 DataFlow:: PathNode source , DataFlow:: PathNode dest
@@ -112,17 +83,8 @@ class SymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
11283 }
11384
11485 override predicate isSink ( DataFlow:: Node sink ) {
115- exists ( MethodAccess ma , VarAccess va |
86+ exists ( MethodAccess ma |
11687 ma .getMethod ( ) instanceof KeyGeneratorInitMethod and
117- // va.getVariable()
118- // .getAnAssignedValue()
119- // .(JavaxCryptoKeyGenerator)
120- // .getAlgoSpec()
121- // .(StringLiteral)
122- // .getValue()
123- // .toUpperCase()
124- // .matches(["AES"]) and
125- // ma.getQualifier() = va and
12688 exists (
12789 JavaxCryptoKeyGenerator jcg , KeyGeneratorInitConfiguration kgConfig ,
12890 DataFlow:: PathNode source , DataFlow:: PathNode dest
@@ -137,14 +99,49 @@ class SymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
13799 }
138100}
139101
140- // ! below doesn't work for some reason...
102+ // ! below predicate doesn't work
141103// predicate hasInsufficientKeySize2(DataFlow::PathNode source, DataFlow::PathNode sink) {
142104// exists(AsymmetricKeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink))
143105// or
144106// exists(SymmetricKeyTrackingConfiguration config2 | config2.hasFlowPath(source, sink))
145107// }
146- // ******** Need the below for the above ********
147- // ! move to Encryption.qll?
108+ // ******** Need the below models for the above configs ********
109+ /** Taint configuration tracking flow from a key generator to a `init` method call. */
110+ private class KeyGeneratorInitConfiguration extends TaintTracking:: Configuration {
111+ KeyGeneratorInitConfiguration ( ) { this = "KeyGeneratorInitConfiguration" }
112+
113+ override predicate isSource ( DataFlow:: Node source ) {
114+ source .asExpr ( ) instanceof JavaxCryptoKeyGenerator
115+ }
116+
117+ override predicate isSink ( DataFlow:: Node sink ) {
118+ exists ( MethodAccess ma |
119+ ma .getMethod ( ) instanceof KeyGeneratorInitMethod and
120+ sink .asExpr ( ) = ma .getQualifier ( )
121+ )
122+ }
123+ }
124+
125+ /**
126+ * Taint configuration tracking flow from a keypair generator to
127+ * an `initialize` method call.
128+ */
129+ private class KeyPairGeneratorInitConfiguration extends TaintTracking:: Configuration {
130+ KeyPairGeneratorInitConfiguration ( ) { this = "KeyPairGeneratorInitConfiguration" }
131+
132+ override predicate isSource ( DataFlow:: Node source ) {
133+ source .asExpr ( ) instanceof JavaSecurityKeyPairGenerator
134+ }
135+
136+ override predicate isSink ( DataFlow:: Node sink ) {
137+ exists ( MethodAccess ma |
138+ ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
139+ sink .asExpr ( ) = ma .getQualifier ( )
140+ )
141+ }
142+ }
143+
144+ // ! move some/all of below to Encryption.qll or elsewhere?
148145/** The Java class `java.security.spec.ECGenParameterSpec`. */
149146private class ECGenParameterSpec extends RefType {
150147 ECGenParameterSpec ( ) { this .hasQualifiedName ( "java.security.spec" , "ECGenParameterSpec" ) }
@@ -155,7 +152,6 @@ private class RSAGenParameterSpec extends RefType {
155152 RSAGenParameterSpec ( ) { this .hasQualifiedName ( "java.security.spec" , "RSAKeyGenParameterSpec" ) }
156153}
157154
158- // ! move to Encryption.qll?
159155/** Returns the key size in the EC algorithm string */
160156bindingset [ algorithm]
161157private int getECKeySize ( string algorithm ) {
@@ -169,7 +165,6 @@ private int getECKeySize(string algorithm) {
169165 result = algorithm .regexpCapture ( ".*[a-zA-Z](\\d+)[a-zA-Z].*" , 1 ) .toInt ( )
170166}
171167
172- // ! move to Encryption.qll?
173168/** The `init` method declared in `javax.crypto.KeyGenerator`. */
174169private class KeyGeneratorInitMethod extends Method {
175170 KeyGeneratorInitMethod ( ) {
@@ -178,7 +173,6 @@ private class KeyGeneratorInitMethod extends Method {
178173 }
179174}
180175
181- // ! move to Encryption.qll?
182176/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
183177private class KeyPairGeneratorInitMethod extends Method {
184178 KeyPairGeneratorInitMethod ( ) {
@@ -190,9 +184,6 @@ private class KeyPairGeneratorInitMethod extends Method {
190184// ******* DATAFLOW ABOVE *************************************************************************
191185// ************************************************************************************************
192186// ************************************************************************************************
193- // ************************************************************************************************
194- // ************************************************************************************************
195- // ************************************************************************************************
196187// ******* OLD/UNUSED OR EXPERIMENTAL CODE BELOW **************************************************
197188class UnsafeSymmetricKeySize extends IntegerLiteral {
198189 UnsafeSymmetricKeySize ( ) { this .getIntValue ( ) < 128 }
@@ -201,38 +192,10 @@ class UnsafeSymmetricKeySize extends IntegerLiteral {
201192class UnsafeAsymmetricKeySize extends IntegerLiteral {
202193 UnsafeAsymmetricKeySize ( ) { this .getIntValue ( ) < 2048 }
203194}
204-
205- /** Taint configuration tracking flow from a key generator to a `init` method call. */
206- private class KeyGeneratorInitConfiguration extends TaintTracking:: Configuration {
207- KeyGeneratorInitConfiguration ( ) { this = "KeyGeneratorInitConfiguration" }
208-
209- override predicate isSource ( DataFlow:: Node source ) {
210- source .asExpr ( ) instanceof JavaxCryptoKeyGenerator
211- }
212-
213- override predicate isSink ( DataFlow:: Node sink ) {
214- exists ( MethodAccess ma |
215- ma .getMethod ( ) instanceof KeyGeneratorInitMethod and
216- sink .asExpr ( ) = ma .getQualifier ( )
217- )
218- }
219- }
220-
221- /**
222- * Taint configuration tracking flow from a keypair generator to
223- * an `initialize` method call.
224- */
225- private class KeyPairGeneratorInitConfiguration extends TaintTracking:: Configuration {
226- KeyPairGeneratorInitConfiguration ( ) { this = "KeyPairGeneratorInitConfiguration" }
227-
228- override predicate isSource ( DataFlow:: Node source ) {
229- source .asExpr ( ) instanceof JavaSecurityKeyPairGenerator
230- }
231-
232- override predicate isSink ( DataFlow:: Node sink ) {
233- exists ( MethodAccess ma |
234- ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
235- sink .asExpr ( ) = ma .getQualifier ( )
236- )
237- }
238- }
195+ // TODO:
196+ // ! todo #0a: find a better way to combine the two needed taint-tracking configs so can go back to having a path-graph...
197+ // ! todo #0b: possible to combine the 3 dataflow configs?
198+ // todo #1: make representation of source that can be shared across the configs
199+ // todo #2: make representation of sink that can be shared across the configs
200+ // 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.)
201+ // todo #4: refactor to be more like the Python version? (or not possible because of lack of DataFlow::Node for void method in Java?)
0 commit comments