@@ -4,97 +4,6 @@ import semmle.code.java.security.Encryption
44import semmle.code.java.dataflow.DataFlow
55import semmle.code.java.dataflow.TaintTracking
66
7- //import semmle.code.java.dataflow.internal.DataFlowImplCommonPublic
8- //import semmle.code.java.dataflow.FlowSources
9- //import semmle.code.java.dataflow.internal.DataFlowNodes
10- /**
11- * A key length data flow tracking configuration.
12- */
13- class KeyTrackingConfiguration extends DataFlow:: Configuration {
14- KeyTrackingConfiguration ( ) { this = "KeyTrackingConfiguration" }
15-
16- override predicate isSource ( DataFlow:: Node source , DataFlow:: FlowState state ) {
17- //state instanceof DataFlow::FlowStateEmpty and
18- // SYMMETRIC
19- source .asExpr ( ) .( IntegerLiteral ) .getIntValue ( ) < 128 and state = "128"
20- or
21- // ASYMMETRIC
22- source .asExpr ( ) .( IntegerLiteral ) .getIntValue ( ) < 2048 and state = "2048"
23- or
24- source .asExpr ( ) .( IntegerLiteral ) .getIntValue ( ) < 256 and state = "256"
25- or
26- getECKeySize ( source .asExpr ( ) .( StringLiteral ) .getValue ( ) ) < 256 and state = "256" // need this for the cases when the key size is embedded in the curve name.
27- }
28-
29- override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowState state ) {
30- // SYMMETRIC
31- exists ( MethodAccess ma , JavaxCryptoKeyGenerator jcg |
32- ma .getMethod ( ) instanceof KeyGeneratorInitMethod and
33- jcg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) = "AES" and
34- DataFlow:: localExprFlow ( jcg , ma .getQualifier ( ) ) and
35- sink .asExpr ( ) = ma .getArgument ( 0 ) and
36- state = "128"
37- )
38- or
39- // ASYMMETRIC
40- exists ( MethodAccess ma , JavaSecurityKeyPairGenerator jpg |
41- ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
42- (
43- jpg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( [ "RSA" , "DSA" , "DH" ] ) and
44- DataFlow:: localExprFlow ( jpg , ma .getQualifier ( ) ) and
45- sink .asExpr ( ) = ma .getArgument ( 0 ) and
46- //ma.getArgument(0).(LocalSourceNode).flowsTo(sink) and
47- //ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 2048 and
48- state = "2048"
49- )
50- or
51- jpg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( "EC%" ) and
52- DataFlow:: localExprFlow ( jpg , ma .getQualifier ( ) ) and
53- sink .asExpr ( ) = ma .getArgument ( 0 ) and
54- //ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 256 and
55- state = "256"
56- )
57- or
58- // TODO: combine below three for less duplicated code
59- exists ( ClassInstanceExpr rsaKeyGenParamSpec |
60- rsaKeyGenParamSpec .getConstructedType ( ) instanceof RsaKeyGenParameterSpec and
61- sink .asExpr ( ) = rsaKeyGenParamSpec .getArgument ( 0 ) and
62- state = "2048"
63- )
64- or
65- exists ( ClassInstanceExpr dsaGenParamSpec |
66- dsaGenParamSpec .getConstructedType ( ) instanceof DsaGenParameterSpec and
67- sink .asExpr ( ) = dsaGenParamSpec .getArgument ( 0 ) and
68- state = "2048"
69- )
70- or
71- exists ( ClassInstanceExpr dhGenParamSpec |
72- dhGenParamSpec .getConstructedType ( ) instanceof DhGenParameterSpec and
73- sink .asExpr ( ) = dhGenParamSpec .getArgument ( 0 ) and
74- state = "2048"
75- )
76- or
77- exists ( ClassInstanceExpr ecGenParamSpec |
78- ecGenParamSpec .getConstructedType ( ) instanceof EcGenParameterSpec and
79- sink .asExpr ( ) = ecGenParamSpec .getArgument ( 0 ) and
80- state = "256"
81- )
82- }
83-
84- // ! FlowStates seem to work without even including a step like the below... hmmm
85- override predicate isAdditionalFlowStep (
86- DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
87- DataFlow:: FlowState state2
88- ) {
89- exists ( IntegerLiteral intLiteral |
90- state1 = "" and
91- state2 = intLiteral .toString ( ) and
92- node1 .asExpr ( ) = intLiteral and
93- node2 .asExpr ( ) = intLiteral
94- )
95- }
96- }
97-
987/**
998 * An Asymmetric (RSA, DSA, DH) key length data flow tracking configuration.
1009 */
@@ -110,15 +19,6 @@ class AsymmetricNonECKeyTrackingConfiguration extends DataFlow::Configuration {
11019 ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
11120 jpg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( [ "RSA" , "DSA" , "DH" ] ) and
11221 DataFlow:: localExprFlow ( jpg , ma .getQualifier ( ) ) and
113- // exists(
114- // JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kpgConfig,
115- // DataFlow::PathNode source, DataFlow::PathNode dest
116- // |
117- // jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches(["RSA", "DSA", "DH"]) and
118- // source.getNode().asExpr() = jpg and
119- // dest.getNode().asExpr() = ma.getQualifier() and
120- // kpgConfig.hasFlowPath(source, dest)
121- // ) and
12222 sink .asExpr ( ) = ma .getArgument ( 0 )
12323 )
12424 or
@@ -156,21 +56,11 @@ class AsymmetricECKeyTrackingConfiguration extends DataFlow::Configuration {
15656 ma .getMethod ( ) instanceof KeyPairGeneratorInitMethod and
15757 jpg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) .matches ( "EC%" ) and
15858 DataFlow:: localExprFlow ( jpg , ma .getQualifier ( ) ) and
159- // exists(
160- // JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kpgConfig,
161- // DataFlow::PathNode source, DataFlow::PathNode dest
162- // |
163- // jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches("EC%") and
164- // source.getNode().asExpr() = jpg and
165- // dest.getNode().asExpr() = ma.getQualifier() and
166- // kpgConfig.hasFlowPath(source, dest)
167- // ) and
16859 sink .asExpr ( ) = ma .getArgument ( 0 )
16960 )
17061 or
17162 exists ( ClassInstanceExpr ecGenParamSpec |
17263 ecGenParamSpec .getConstructedType ( ) instanceof EcGenParameterSpec and
173- //getECKeySize(ecGenParamSpec.getArgument(0).(StringLiteral).getValue()) < 256 and
17464 sink .asExpr ( ) = ecGenParamSpec .getArgument ( 0 )
17565 )
17666 }
@@ -191,48 +81,13 @@ class SymmetricKeyTrackingConfiguration extends DataFlow::Configuration {
19181 ma .getMethod ( ) instanceof KeyGeneratorInitMethod and
19282 jcg .getAlgoSpec ( ) .( StringLiteral ) .getValue ( ) .toUpperCase ( ) = "AES" and
19383 DataFlow:: localExprFlow ( jcg , ma .getQualifier ( ) ) and
194- // exists(
195- // JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration kgConfig,
196- // DataFlow::PathNode source, DataFlow::PathNode dest
197- // |
198- // jcg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = "AES" and
199- // source.getNode().asExpr() = jcg and
200- // dest.getNode().asExpr() = ma.getQualifier() and
201- // kgConfig.hasFlowPath(source, dest)
202- // ) and
20384 sink .asExpr ( ) = ma .getArgument ( 0 )
20485 )
20586 }
20687}
20788
20889// ********************** Need the below models for the above configs **********************
20990// todo: move some/all of below to Encryption.qll or elsewhere?
210- // /** A data flow configuration tracking flow from a key generator to an `init` method call. */
211- // private class KeyGeneratorInitConfiguration extends DataFlow::Configuration {
212- // KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
213- // override predicate isSource(DataFlow::Node source) {
214- // source.asExpr() instanceof JavaxCryptoKeyGenerator
215- // }
216- // override predicate isSink(DataFlow::Node sink) {
217- // exists(MethodAccess ma |
218- // ma.getMethod() instanceof KeyGeneratorInitMethod and
219- // sink.asExpr() = ma.getQualifier()
220- // )
221- // }
222- // }
223- // /** A data flow configuration tracking flow from a keypair generator to an `initialize` method call. */
224- // private class KeyPairGeneratorInitConfiguration extends DataFlow::Configuration {
225- // KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
226- // override predicate isSource(DataFlow::Node source) {
227- // source.asExpr() instanceof JavaSecurityKeyPairGenerator
228- // }
229- // override predicate isSink(DataFlow::Node sink) {
230- // exists(MethodAccess ma |
231- // ma.getMethod() instanceof KeyPairGeneratorInitMethod and
232- // sink.asExpr() = ma.getQualifier()
233- // )
234- // }
235- // }
23691/** The Java class `java.security.spec.ECGenParameterSpec`. */
23792private class EcGenParameterSpec extends RefType {
23893 EcGenParameterSpec ( ) { this .hasQualifiedName ( "java.security.spec" , "ECGenParameterSpec" ) }
@@ -288,3 +143,88 @@ private int getECKeySize(string algorithm) {
288143// todo #2: make representation of sink that can be shared across the configs
289144// 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.)
290145// todo #4: refactor to be more like the Python (or C#) version? (or not possible because of lack of DataFlow::Node for void method in Java?)
146+ // ******* SINGLE CONFIG ATTEMPT BELOW *************************************************************************
147+ // /**
148+ // * A key length data flow tracking configuration.
149+ // */
150+ // class KeyTrackingConfiguration extends DataFlow::Configuration {
151+ // KeyTrackingConfiguration() { this = "KeyTrackingConfiguration" }
152+ // override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
153+ // //state instanceof DataFlow::FlowStateEmpty and
154+ // // SYMMETRIC
155+ // source.asExpr().(IntegerLiteral).getIntValue() < 128 and state = "128"
156+ // or
157+ // // ASYMMETRIC
158+ // source.asExpr().(IntegerLiteral).getIntValue() < 2048 and state = "2048"
159+ // or
160+ // source.asExpr().(IntegerLiteral).getIntValue() < 256 and state = "256"
161+ // or
162+ // getECKeySize(source.asExpr().(StringLiteral).getValue()) < 256 and state = "256" // need this for the cases when the key size is embedded in the curve name.
163+ // }
164+ // override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
165+ // // SYMMETRIC
166+ // exists(MethodAccess ma, JavaxCryptoKeyGenerator jcg |
167+ // ma.getMethod() instanceof KeyGeneratorInitMethod and
168+ // jcg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = "AES" and
169+ // DataFlow::localExprFlow(jcg, ma.getQualifier()) and
170+ // sink.asExpr() = ma.getArgument(0) and
171+ // state = "128"
172+ // )
173+ // or
174+ // // ASYMMETRIC
175+ // exists(MethodAccess ma, JavaSecurityKeyPairGenerator jpg |
176+ // ma.getMethod() instanceof KeyPairGeneratorInitMethod and
177+ // (
178+ // jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches(["RSA", "DSA", "DH"]) and
179+ // DataFlow::localExprFlow(jpg, ma.getQualifier()) and
180+ // sink.asExpr() = ma.getArgument(0) and
181+ // //ma.getArgument(0).(LocalSourceNode).flowsTo(sink) and
182+ // //ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 2048 and
183+ // state = "2048"
184+ // )
185+ // or
186+ // jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches("EC%") and
187+ // DataFlow::localExprFlow(jpg, ma.getQualifier()) and
188+ // sink.asExpr() = ma.getArgument(0) and
189+ // //ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 256 and
190+ // state = "256"
191+ // )
192+ // or
193+ // // TODO: combine below three for less duplicated code
194+ // exists(ClassInstanceExpr rsaKeyGenParamSpec |
195+ // rsaKeyGenParamSpec.getConstructedType() instanceof RsaKeyGenParameterSpec and
196+ // sink.asExpr() = rsaKeyGenParamSpec.getArgument(0) and
197+ // state = "2048"
198+ // )
199+ // or
200+ // exists(ClassInstanceExpr dsaGenParamSpec |
201+ // dsaGenParamSpec.getConstructedType() instanceof DsaGenParameterSpec and
202+ // sink.asExpr() = dsaGenParamSpec.getArgument(0) and
203+ // state = "2048"
204+ // )
205+ // or
206+ // exists(ClassInstanceExpr dhGenParamSpec |
207+ // dhGenParamSpec.getConstructedType() instanceof DhGenParameterSpec and
208+ // sink.asExpr() = dhGenParamSpec.getArgument(0) and
209+ // state = "2048"
210+ // )
211+ // or
212+ // exists(ClassInstanceExpr ecGenParamSpec |
213+ // ecGenParamSpec.getConstructedType() instanceof EcGenParameterSpec and
214+ // sink.asExpr() = ecGenParamSpec.getArgument(0) and
215+ // state = "256"
216+ // )
217+ // }
218+ // // ! FlowStates seem to work without even including a step like the below... hmmm
219+ // override predicate isAdditionalFlowStep(
220+ // DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
221+ // DataFlow::FlowState state2
222+ // ) {
223+ // exists(IntegerLiteral intLiteral |
224+ // state1 = "" and
225+ // state2 = intLiteral.toString() and
226+ // node1.asExpr() = intLiteral and
227+ // node2.asExpr() = intLiteral
228+ // )
229+ // }
230+ // }
0 commit comments