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

Skip to content

Commit 2daa345

Browse files
Jami CogswellJami Cogswell
authored andcommitted
combine three configs into one
1 parent e0f0d55 commit 2daa345

4 files changed

Lines changed: 79 additions & 141 deletions

File tree

java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,49 @@
33
private import semmle.code.java.security.Encryption
44
private import semmle.code.java.dataflow.DataFlow
55

6+
// TODO: only update key sizes (and key size strings in one place in the code)
67
/** A source for an insufficient key size. */
7-
abstract class InsufficientKeySizeSource extends DataFlow::Node { }
8+
abstract class InsufficientKeySizeSource extends DataFlow::Node {
9+
/** Holds if this source has the specified `state`. */
10+
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
11+
}
812

913
/** A sink for an insufficient key size. */
10-
abstract class InsufficientKeySizeSink extends DataFlow::Node { }
14+
abstract class InsufficientKeySizeSink extends DataFlow::Node {
15+
/** Holds if this sink has the specified `state`. */
16+
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
17+
}
1118

12-
// TODO: Consider if below 3 sources should be private and if it's possible to only use InsufficientKeySizeSource in the configs
13-
// TODO: add QLDocs if keeping non-private
14-
/** A source for an insufficient key size (asymmetric-non-ec). */
15-
class AsymmetricNonECSource extends InsufficientKeySizeSource {
19+
/** A source for an insufficient key size (asymmetric-non-ec: RSA, DSA, DH). */
20+
private class AsymmetricNonECSource extends InsufficientKeySizeSource {
1621
AsymmetricNonECSource() { getNodeIntValue(this) < 2048 }
22+
23+
override predicate hasState(DataFlow::FlowState state) { state = "2048" }
1724
}
1825

19-
/** A source for an insufficient key size (asymmetric-ec). */
20-
class AsymmetricECSource extends InsufficientKeySizeSource {
26+
/** A source for an insufficient key size (asymmetric-ec: EC%). */
27+
private class AsymmetricECSource extends InsufficientKeySizeSource {
2128
AsymmetricECSource() {
2229
getNodeIntValue(this) < 256 or
23-
getECKeySize(this.asExpr().(StringLiteral).getValue()) < 256 // need this for the cases when the key size is embedded in the curve name.
30+
getECKeySize(this.asExpr().(StringLiteral).getValue()) < 256 // for cases when the key size is embedded in the curve name
2431
}
32+
33+
override predicate hasState(DataFlow::FlowState state) { state = "256" }
2534
}
2635

27-
/** A source for an insufficient key size (symmetric). */
28-
class SymmetricSource extends InsufficientKeySizeSource {
36+
/** A source for an insufficient key size (symmetric: AES). */
37+
private class SymmetricSource extends InsufficientKeySizeSource {
2938
SymmetricSource() { getNodeIntValue(this) < 128 }
39+
40+
override predicate hasState(DataFlow::FlowState state) { state = "128" }
3041
}
3142

3243
// TODO: use `typeFlag` like with sinks below to include the size numbers in this predicate?
3344
private int getNodeIntValue(DataFlow::Node node) {
3445
result = node.asExpr().(IntegerLiteral).getIntValue()
3546
}
3647

48+
// TODO: check if any other regex should be added based on some MRVA results.
3749
/** Returns the key size in the EC algorithm string */
3850
bindingset[algorithm]
3951
private int getECKeySize(string algorithm) {
@@ -47,18 +59,17 @@ private int getECKeySize(string algorithm) {
4759
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
4860
}
4961

50-
// TODO: Consider if below 3 sinks should be private and if it's possible to only use InsufficientKeySizeSink in the configs
51-
// TODO: add QLDocs if keeping non-private
5262
/** A sink for an insufficient key size (asymmetric-non-ec). */
53-
class AsymmetricNonECSink extends InsufficientKeySizeSink {
63+
private class AsymmetricNonECSink extends InsufficientKeySizeSink {
5464
AsymmetricNonECSink() {
5565
hasKeySizeInInitMethod(this, "asymmetric-non-ec")
5666
or
5767
hasKeySizeInSpec(this, "asymmetric-non-ec")
5868
}
69+
70+
override predicate hasState(DataFlow::FlowState state) { state = "2048" }
5971
}
6072

61-
// TODO: move to Encryption.qll? or keep here since specific to this query?
6273
private class AsymmetricNonECSpec extends RefType {
6374
AsymmetricNonECSpec() {
6475
this instanceof RsaKeyGenParameterSpec or
@@ -68,17 +79,21 @@ private class AsymmetricNonECSpec extends RefType {
6879
}
6980

7081
/** A sink for an insufficient key size (asymmetric-ec). */
71-
class AsymmetricECSink extends InsufficientKeySizeSink {
82+
private class AsymmetricECSink extends InsufficientKeySizeSink {
7283
AsymmetricECSink() {
7384
hasKeySizeInInitMethod(this, "asymmetric-ec")
7485
or
7586
hasKeySizeInSpec(this, "asymmetric-ec")
7687
}
88+
89+
override predicate hasState(DataFlow::FlowState state) { state = "256" }
7790
}
7891

7992
/** A sink for an insufficient key size (symmetric). */
80-
class SymmetricSink extends InsufficientKeySizeSink {
93+
private class SymmetricSink extends InsufficientKeySizeSink {
8194
SymmetricSink() { hasKeySizeInInitMethod(this, "symmetric") }
95+
96+
override predicate hasState(DataFlow::FlowState state) { state = "128" }
8297
}
8398

8499
// TODO: rethink the predicate name; also think about whether this could/should be a class instead; or a predicate within the sink class so can do sink.predicate()...
@@ -113,7 +128,7 @@ private string getAlgoName(JavaxCryptoAlgoSpec jca) {
113128
}
114129

115130
// TODO: rethink the predicate name; also think about whether this could/should be a class instead; or a predicate within the sink class so can do sink.predicate()...
116-
// TODO: can prbly re-work way using the typeFlag to be better and less repetitive
131+
// TODO: can prbly re-work way using the typeFlag to be better and less repetitive...
117132
private predicate hasKeySizeInSpec(DataFlow::Node node, string typeFlag) {
118133
exists(ClassInstanceExpr paramSpec |
119134
(
@@ -126,7 +141,8 @@ private predicate hasKeySizeInSpec(DataFlow::Node node, string typeFlag) {
126141
node.asExpr() = paramSpec.getArgument(0)
127142
)
128143
}
144+
145+
class SpecWithKeySize extends RefType { }
129146
// TODO:
130147
// todo #0: look into use of specs without keygen objects; should spec not be a sink in these cases?
131148
// 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.)
132-
// todo #4: use flowstate (or even just result predicate) to pass source int size to sink?

java/ql/lib/semmle/code/java/security/InsufficientKeySizeQuery.qll

Lines changed: 34 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -6,120 +6,43 @@ import semmle.code.java.dataflow.TaintTracking
66
import semmle.code.java.security.InsufficientKeySize
77

88
/**
9-
* A data flow configuration for tracking non-elliptic curve asymmetric algorithms
9+
* A data flow configuration for tracking non-elliptic curve asymmetric algorithm
1010
* (RSA, DSA, and DH) key sizes.
1111
*/
12-
class AsymmetricNonECKeyTrackingConfiguration extends DataFlow::Configuration {
13-
AsymmetricNonECKeyTrackingConfiguration() { this = "AsymmetricNonECKeyTrackingConfiguration" }
14-
15-
override predicate isSource(DataFlow::Node source) { source instanceof AsymmetricNonECSource }
16-
17-
override predicate isSink(DataFlow::Node sink) { sink instanceof AsymmetricNonECSink }
18-
}
19-
20-
/**
21-
* A data flow configuration for tracking elliptic curve (EC) asymmetric
22-
* algorithm key sizes.
23-
*/
24-
class AsymmetricECKeyTrackingConfiguration extends DataFlow::Configuration {
25-
AsymmetricECKeyTrackingConfiguration() { this = "AsymmetricECKeyTrackingConfiguration" }
26-
27-
override predicate isSource(DataFlow::Node source) { source instanceof AsymmetricECSource }
28-
29-
override predicate isSink(DataFlow::Node sink) { sink instanceof AsymmetricECSink }
12+
class KeySizeConfiguration extends DataFlow::Configuration {
13+
KeySizeConfiguration() { this = "KeySizeConfiguration" }
14+
15+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
16+
source.(InsufficientKeySizeSource).hasState(state)
17+
//source instanceof InsufficientKeySizeSource
18+
}
19+
20+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
21+
sink.(InsufficientKeySizeSink).hasState(state)
22+
//sink instanceof InsufficientKeySizeSink
23+
}
3024
}
31-
32-
/** A data flow configuration for tracking symmetric algorithm (AES) key sizes. */
33-
class SymmetricKeyTrackingConfiguration extends DataFlow::Configuration {
34-
SymmetricKeyTrackingConfiguration() { this = "SymmetricKeyTrackingConfiguration" }
35-
36-
override predicate isSource(DataFlow::Node source) { source instanceof SymmetricSource }
37-
38-
override predicate isSink(DataFlow::Node sink) { sink instanceof SymmetricSink }
39-
}
40-
// ******* 3 DATAFLOW CONFIGS ABOVE *************************************************************************
41-
// ******* SINGLE CONFIG ATTEMPT BELOW *************************************************************************
4225
// /**
43-
// * A key length data flow tracking configuration.
26+
// * A data flow configuration for tracking non-elliptic curve asymmetric algorithm
27+
// * (RSA, DSA, and DH) key sizes.
4428
// */
45-
// class KeyTrackingConfiguration extends DataFlow::Configuration {
46-
// KeyTrackingConfiguration() { this = "KeyTrackingConfiguration" }
47-
// override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
48-
// //state instanceof DataFlow::FlowStateEmpty and
49-
// // SYMMETRIC
50-
// source.asExpr().(IntegerLiteral).getIntValue() < 128 and state = "128"
51-
// or
52-
// // ASYMMETRIC
53-
// source.asExpr().(IntegerLiteral).getIntValue() < 2048 and state = "2048"
54-
// or
55-
// source.asExpr().(IntegerLiteral).getIntValue() < 256 and state = "256"
56-
// or
57-
// getECKeySize(source.asExpr().(StringLiteral).getValue()) < 256 and state = "256" // need this for the cases when the key size is embedded in the curve name.
58-
// }
59-
// override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
60-
// // SYMMETRIC
61-
// exists(MethodAccess ma, JavaxCryptoKeyGenerator jcg |
62-
// ma.getMethod() instanceof KeyGeneratorInitMethod and
63-
// jcg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = "AES" and
64-
// DataFlow::localExprFlow(jcg, ma.getQualifier()) and
65-
// sink.asExpr() = ma.getArgument(0) and
66-
// state = "128"
67-
// )
68-
// or
69-
// // ASYMMETRIC
70-
// exists(MethodAccess ma, JavaSecurityKeyPairGenerator jpg |
71-
// ma.getMethod() instanceof KeyPairGeneratorInitMethod and
72-
// (
73-
// jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches(["RSA", "DSA", "DH"]) and
74-
// DataFlow::localExprFlow(jpg, ma.getQualifier()) and
75-
// sink.asExpr() = ma.getArgument(0) and
76-
// //ma.getArgument(0).(LocalSourceNode).flowsTo(sink) and
77-
// //ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 2048 and
78-
// state = "2048"
79-
// )
80-
// or
81-
// jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches("EC%") and
82-
// DataFlow::localExprFlow(jpg, ma.getQualifier()) and
83-
// sink.asExpr() = ma.getArgument(0) and
84-
// //ma.getArgument(0).(CompileTimeConstantExpr).getIntValue() < 256 and
85-
// state = "256"
86-
// )
87-
// or
88-
// // TODO: combine below three for less duplicated code
89-
// exists(ClassInstanceExpr rsaKeyGenParamSpec |
90-
// rsaKeyGenParamSpec.getConstructedType() instanceof RsaKeyGenParameterSpec and
91-
// sink.asExpr() = rsaKeyGenParamSpec.getArgument(0) and
92-
// state = "2048"
93-
// )
94-
// or
95-
// exists(ClassInstanceExpr dsaGenParamSpec |
96-
// dsaGenParamSpec.getConstructedType() instanceof DsaGenParameterSpec and
97-
// sink.asExpr() = dsaGenParamSpec.getArgument(0) and
98-
// state = "2048"
99-
// )
100-
// or
101-
// exists(ClassInstanceExpr dhGenParamSpec |
102-
// dhGenParamSpec.getConstructedType() instanceof DhGenParameterSpec and
103-
// sink.asExpr() = dhGenParamSpec.getArgument(0) and
104-
// state = "2048"
105-
// )
106-
// or
107-
// exists(ClassInstanceExpr ecGenParamSpec |
108-
// ecGenParamSpec.getConstructedType() instanceof EcGenParameterSpec and
109-
// sink.asExpr() = ecGenParamSpec.getArgument(0) and
110-
// state = "256"
111-
// )
112-
// }
113-
// // ! FlowStates seem to work without even including a step like the below... hmmm
114-
// override predicate isAdditionalFlowStep(
115-
// DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
116-
// DataFlow::FlowState state2
117-
// ) {
118-
// exists(IntegerLiteral intLiteral |
119-
// state1 = "" and
120-
// state2 = intLiteral.toString() and
121-
// node1.asExpr() = intLiteral and
122-
// node2.asExpr() = intLiteral
123-
// )
124-
// }
29+
// class AsymmetricNonECKeyTrackingConfiguration extends DataFlow::Configuration {
30+
// AsymmetricNonECKeyTrackingConfiguration() { this = "AsymmetricNonECKeyTrackingConfiguration" }
31+
// override predicate isSource(DataFlow::Node source) { source instanceof AsymmetricNonECSource }
32+
// override predicate isSink(DataFlow::Node sink) { sink instanceof AsymmetricNonECSink }
33+
// }
34+
// /**
35+
// * A data flow configuration for tracking elliptic curve (EC) asymmetric
36+
// * algorithm key sizes.
37+
// */
38+
// class AsymmetricECKeyTrackingConfiguration extends DataFlow::Configuration {
39+
// AsymmetricECKeyTrackingConfiguration() { this = "AsymmetricECKeyTrackingConfiguration" }
40+
// override predicate isSource(DataFlow::Node source) { source instanceof AsymmetricECSource }
41+
// override predicate isSink(DataFlow::Node sink) { sink instanceof AsymmetricECSink }
42+
// }
43+
// /** A data flow configuration for tracking symmetric algorithm (AES) key sizes. */
44+
// class SymmetricKeyTrackingConfiguration extends DataFlow::Configuration {
45+
// SymmetricKeyTrackingConfiguration() { this = "SymmetricKeyTrackingConfiguration" }
46+
// override predicate isSource(DataFlow::Node source) { source instanceof SymmetricSource }
47+
// override predicate isSink(DataFlow::Node sink) { sink instanceof SymmetricSink }
12548
// }

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ import semmle.code.java.security.InsufficientKeySizeQuery
1616
import DataFlow::PathGraph
1717

1818
from DataFlow::PathNode source, DataFlow::PathNode sink
19-
where
20-
//exists(KeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink))
21-
//or
22-
exists(AsymmetricNonECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
23-
exists(AsymmetricECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
24-
exists(SymmetricKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink))
19+
where exists(KeySizeConfiguration config1 | config1.hasFlowPath(source, sink))
20+
//or
21+
// exists(AsymmetricNonECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
22+
// exists(AsymmetricECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
23+
// exists(SymmetricKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink))
2524
select sink.getNode(), source, sink, "This $@ is too small.", source.getNode(), "key size"

java/ql/test/query-tests/security/CWE-326/InsufficientKeySizeTest.ql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ class InsufficientKeySizeTest extends InlineExpectationsTest {
1111
override predicate hasActualResult(Location location, string element, string tag, string value) {
1212
tag = "hasInsufficientKeySize" and
1313
exists(DataFlow::PathNode source, DataFlow::PathNode sink |
14-
//exists(KeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink))
15-
//or
16-
exists(AsymmetricNonECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
17-
exists(AsymmetricECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
18-
exists(SymmetricKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink))
14+
exists(KeySizeConfiguration config1 | config1.hasFlowPath(source, sink))
1915
|
16+
//or
17+
// exists(AsymmetricNonECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
18+
// exists(AsymmetricECKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink)) or
19+
// exists(SymmetricKeyTrackingConfiguration cfg | cfg.hasFlowPath(source, sink))
2020
sink.getNode().getLocation() = location and
2121
element = sink.getNode().toString() and
2222
value = ""

0 commit comments

Comments
 (0)