Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bd76b1f

Browse files
Jami CogswellJami Cogswell
authored andcommitted
clean-up and update configurations to have specs as sink
1 parent 0c2cff2 commit bd76b1f

4 files changed

Lines changed: 99 additions & 141 deletions

File tree

Lines changed: 59 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
11
import semmle.code.java.security.Encryption
2-
import semmle.code.java.dataflow.TaintTracking2
3-
import semmle.code.java.dataflow.TaintTracking
42
import semmle.code.java.dataflow.DataFlow
3+
import semmle.code.java.dataflow.DataFlow2
54

6-
// ******* DATAFLOW BELOW *************************************************************************
75
/**
86
* Asymmetric (RSA, DSA, DH) key length data flow tracking configuration.
97
*/
10-
class AsymmetricKeyTrackingConfiguration extends DataFlow2::Configuration {
11-
AsymmetricKeyTrackingConfiguration() { this = "AsymmetricKeyTrackingConfiguration" }
8+
class AsymmetricNonECKeyTrackingConfiguration extends DataFlow2::Configuration {
9+
AsymmetricNonECKeyTrackingConfiguration() { this = "AsymmetricNonECKeyTrackingConfiguration" }
1210

1311
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
16-
exists(ClassInstanceExpr rsaGenParamSpec |
17-
rsaGenParamSpec.getConstructedType() instanceof RSAGenParameterSpec and
18-
rsaGenParamSpec.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 2048 and
19-
source.asExpr() = rsaGenParamSpec
20-
)
21-
or
2212
source.asExpr().(IntegerLiteral).getIntValue() < 2048
2313
}
2414

@@ -34,25 +24,36 @@ class AsymmetricKeyTrackingConfiguration extends DataFlow2::Configuration {
3424
dest.getNode().asExpr() = ma.getQualifier() and
3525
kpgConfig.hasFlowPath(source, dest)
3626
) and
37-
sink.asExpr() = ma.getArgument(0) // ! todo: add spec as a sink
27+
sink.asExpr() = ma.getArgument(0)
28+
)
29+
or
30+
// TODO: combine below three for less duplicated code
31+
exists(ClassInstanceExpr rsaKeyGenParamSpec |
32+
rsaKeyGenParamSpec.getConstructedType() instanceof RSAKeyGenParameterSpec and
33+
sink.asExpr() = rsaKeyGenParamSpec.getArgument(0)
34+
)
35+
or
36+
exists(ClassInstanceExpr dsaGenParamSpec |
37+
dsaGenParamSpec.getConstructedType() instanceof DSAGenParameterSpec and
38+
sink.asExpr() = dsaGenParamSpec.getArgument(0)
39+
)
40+
or
41+
exists(ClassInstanceExpr dhGenParamSpec |
42+
dhGenParamSpec.getConstructedType() instanceof DHGenParameterSpec and
43+
sink.asExpr() = dhGenParamSpec.getArgument(0)
3844
)
3945
}
4046
}
4147

4248
/**
4349
* Asymmetric (EC) key length data flow tracking configuration.
4450
*/
45-
class AsymmetricECCKeyTrackingConfiguration extends DataFlow2::Configuration {
46-
AsymmetricECCKeyTrackingConfiguration() { this = "AsymmetricECCKeyTrackingConfiguration" }
51+
class AsymmetricECKeyTrackingConfiguration extends DataFlow2::Configuration {
52+
AsymmetricECKeyTrackingConfiguration() { this = "AsymmetricECKeyTrackingConfiguration" }
4753

4854
override predicate isSource(DataFlow::Node source) {
49-
// ! may need to change below to still use `keysize` variable as the source, not the spec
50-
exists(ClassInstanceExpr ecGenParamSpec |
51-
getECKeySize(ecGenParamSpec.getArgument(0).(StringLiteral).getValue()) < 256 and
52-
source.asExpr() = ecGenParamSpec
53-
)
54-
or
55-
source.asExpr().(IntegerLiteral).getIntValue() < 256
55+
source.asExpr().(IntegerLiteral).getIntValue() < 256 or
56+
getECKeySize(source.asExpr().(StringLiteral).getValue()) < 256 // need this for the cases when the key size is embedded in the curve name.
5657
}
5758

5859
override predicate isSink(DataFlow::Node sink) {
@@ -69,14 +70,20 @@ class AsymmetricECCKeyTrackingConfiguration extends DataFlow2::Configuration {
6970
) and
7071
sink.asExpr() = ma.getArgument(0)
7172
)
73+
or
74+
exists(ClassInstanceExpr ecGenParamSpec |
75+
ecGenParamSpec.getConstructedType() instanceof ECGenParameterSpec and
76+
//getECKeySize(ecGenParamSpec.getArgument(0).(StringLiteral).getValue()) < 256 and
77+
sink.asExpr() = ecGenParamSpec.getArgument(0)
78+
)
7279
}
7380
}
7481

7582
/**
7683
* Symmetric (AES) key length data flow tracking configuration.
7784
*/
7885
class SymmetricKeyTrackingConfiguration extends DataFlow2::Configuration {
79-
SymmetricKeyTrackingConfiguration() { this = "SymmetricKeyTrackingConfiguration2" }
86+
SymmetricKeyTrackingConfiguration() { this = "SymmetricKeyTrackingConfiguration" }
8087

8188
override predicate isSource(DataFlow::Node source) {
8289
source.asExpr().(IntegerLiteral).getIntValue() < 128
@@ -99,14 +106,9 @@ class SymmetricKeyTrackingConfiguration extends DataFlow2::Configuration {
99106
}
100107
}
101108

102-
// ! below predicate doesn't work
103-
// predicate hasInsufficientKeySize2(DataFlow::PathNode source, DataFlow::PathNode sink) {
104-
// exists(AsymmetricKeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink))
105-
// or
106-
// exists(SymmetricKeyTrackingConfiguration config2 | config2.hasFlowPath(source, sink))
107-
// }
108-
// ******** Need the below models for the above configs ********
109-
/** Taint configuration tracking flow from a key generator to a `init` method call. */
109+
// ********************** Need the below models for the above configs **********************
110+
// todo: move some/all of below to Encryption.qll or elsewhere?
111+
/** Data flow configuration tracking flow from a key generator to an `init` method call. */
110112
private class KeyGeneratorInitConfiguration extends DataFlow::Configuration {
111113
KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
112114

@@ -122,10 +124,7 @@ private class KeyGeneratorInitConfiguration extends DataFlow::Configuration {
122124
}
123125
}
124126

125-
/**
126-
* Taint configuration tracking flow from a keypair generator to
127-
* an `initialize` method call.
128-
*/
127+
/** Data flow configuration tracking flow from a keypair generator to an `initialize` method call. */
129128
private class KeyPairGeneratorInitConfiguration extends DataFlow::Configuration {
130129
KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
131130

@@ -141,28 +140,24 @@ private class KeyPairGeneratorInitConfiguration extends DataFlow::Configuration
141140
}
142141
}
143142

144-
// ! move some/all of below to Encryption.qll or elsewhere?
145143
/** The Java class `java.security.spec.ECGenParameterSpec`. */
146144
private class ECGenParameterSpec extends RefType {
147145
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
148146
}
149147

150-
/** The Java class `java.security.spec.ECGenParameterSpec`. */
151-
private class RSAGenParameterSpec extends RefType {
152-
RSAGenParameterSpec() { this.hasQualifiedName("java.security.spec", "RSAKeyGenParameterSpec") }
148+
/** The Java class `java.security.spec.RSAKeyGenParameterSpec`. */
149+
private class RSAKeyGenParameterSpec extends RefType {
150+
RSAKeyGenParameterSpec() { this.hasQualifiedName("java.security.spec", "RSAKeyGenParameterSpec") }
153151
}
154152

155-
/** Returns the key size in the EC algorithm string */
156-
bindingset[algorithm]
157-
private int getECKeySize(string algorithm) {
158-
algorithm.matches("sec%") and // specification such as "secp256r1"
159-
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
160-
or
161-
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
162-
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
163-
or
164-
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
165-
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
153+
/** The Java class `java.security.spec.DSAGenParameterSpec`. */
154+
private class DSAGenParameterSpec extends RefType {
155+
DSAGenParameterSpec() { this.hasQualifiedName("java.security.spec", "DSAGenParameterSpec") }
156+
}
157+
158+
/** The Java class `javax.crypto.spec.DHGenParameterSpec`. */
159+
private class DHGenParameterSpec extends RefType {
160+
DHGenParameterSpec() { this.hasQualifiedName("javax.crypto.spec", "DHGenParameterSpec") }
166161
}
167162

168163
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
@@ -181,21 +176,21 @@ private class KeyPairGeneratorInitMethod extends Method {
181176
}
182177
}
183178

184-
// ******* DATAFLOW ABOVE *************************************************************************
185-
// ************************************************************************************************
186-
// ************************************************************************************************
187-
// ******* OLD/UNUSED OR EXPERIMENTAL CODE BELOW **************************************************
188-
class UnsafeSymmetricKeySize extends IntegerLiteral {
189-
UnsafeSymmetricKeySize() { this.getIntValue() < 128 }
190-
}
191-
192-
class UnsafeAsymmetricKeySize extends IntegerLiteral {
193-
UnsafeAsymmetricKeySize() { this.getIntValue() < 2048 }
179+
/** Returns the key size in the EC algorithm string */
180+
bindingset[algorithm]
181+
private int getECKeySize(string algorithm) {
182+
algorithm.matches("sec%") and // specification such as "secp256r1"
183+
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
184+
or
185+
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
186+
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
187+
or
188+
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
189+
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
194190
}
191+
// ******* DATAFLOW ABOVE *************************************************************************
195192
// 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?
198193
// todo #1: make representation of source that can be shared across the configs
199194
// todo #2: make representation of sink that can be shared across the configs
200195
// 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?)
196+
// 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?)

java/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,9 @@
1414
import java
1515
import semmle.code.java.security.InsufficientKeySizeQuery
1616

17-
// * Original:
18-
//import DataFlow::PathGraph
19-
// from Expr e, string msg
20-
// where hasInsufficientKeySize(e, msg)
21-
// * Test data-flow config with just Asymmetric:
22-
// select e, msg
23-
// from
24-
// AsymmetricKeyTrackingConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink,
25-
// KeyTrackingConfiguration cfg2 //, DataFlow::PathNode source2, DataFlow::PathNode sink2
26-
// where
27-
// //cfg.hasFlowPath(source, sink) //or
28-
// cfg2.hasFlowPath(source, sink)
29-
// select sink.getNode(), source, sink, "The $@ of an asymmetric key should be at least 2048 bits.",
30-
// sink.getNode(), "size"
31-
// * Data-Flow path-graph with All configs: (but doesn't track algo name properly...)
32-
// from DataFlow::PathNode source, DataFlow::PathNode sink
33-
// where exists(AsymmetricKeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink)) //or
34-
// //exists(AsymmetricECCKeyTrackingConfiguration config2 | config2.hasFlowPath(source, sink)) //or
35-
// //exists(SymmetricKeyTrackingConfiguration config3 | config3.hasFlowPath(source, sink))
36-
// select sink.getNode(), source, sink, "This $@ is too small, and flows to $@.", source.getNode(),
37-
// "key size", sink.getNode(), "here"
38-
// * Taint-tracking with kpg to track algo names
3917
from DataFlow::Node source, DataFlow::Node sink
4018
where
41-
exists(AsymmetricKeyTrackingConfiguration config1 | config1.hasFlow(source, sink)) or
42-
exists(AsymmetricECCKeyTrackingConfiguration config2 | config2.hasFlow(source, sink)) or
19+
exists(AsymmetricNonECKeyTrackingConfiguration config1 | config1.hasFlow(source, sink)) or
20+
exists(AsymmetricECKeyTrackingConfiguration config2 | config2.hasFlow(source, sink)) or
4321
exists(SymmetricKeyTrackingConfiguration config3 | config3.hasFlow(source, sink))
4422
select sink, "This $@ is too small and creates a key $@.", source, "key size", sink, "here"

0 commit comments

Comments
 (0)