Skip to content

Commit 1e80fa1

Browse files
Jami CogswellJami Cogswell
authored andcommitted
add modules
1 parent 1a12453 commit 1e80fa1

File tree

1 file changed

+154
-146
lines changed

1 file changed

+154
-146
lines changed

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

Lines changed: 154 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -15,175 +15,183 @@ abstract class InsufficientKeySizeSink extends DataFlow::Node {
1515
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
1616
}
1717

18-
/** A source for an insufficient key size used in RSA, DSA, and DH algorithms. */
19-
private class AsymmetricNonEcSource extends InsufficientKeySizeSource {
20-
AsymmetricNonEcSource() {
21-
this.asExpr().(IntegerLiteral).getIntValue() < getMinAsymNonEcKeySize()
18+
private module Asymmetric {
19+
private module NonEllipticCurve {
20+
/** A source for an insufficient key size used in RSA, DSA, and DH algorithms. */
21+
private class AsymmetricNonEcSource extends InsufficientKeySizeSource {
22+
AsymmetricNonEcSource() {
23+
this.asExpr().(IntegerLiteral).getIntValue() < getMinAsymNonEcKeySize()
24+
}
25+
26+
override predicate hasState(DataFlow::FlowState state) {
27+
state = getMinAsymNonEcKeySize().toString()
28+
}
29+
}
30+
31+
/** A sink for an insufficient key size used in RSA, DSA, and DH algorithms. */
32+
private class AsymmetricNonEcSink extends InsufficientKeySizeSink {
33+
AsymmetricNonEcSink() {
34+
exists(AsymmetricInitMethodAccess ma, AsymmetricKeyGenerator kg |
35+
kg.getAlgoName().matches(["RSA", "DSA", "DH"]) and
36+
DataFlow::localExprFlow(kg, ma.getQualifier()) and
37+
this.asExpr() = ma.getKeySizeArg()
38+
)
39+
or
40+
exists(AsymmetricNonEcSpec spec | this.asExpr() = spec.getKeySizeArg())
41+
}
42+
43+
override predicate hasState(DataFlow::FlowState state) {
44+
state = getMinAsymNonEcKeySize().toString()
45+
}
46+
}
47+
48+
/** Returns the minimum recommended key size for RSA, DSA, and DH algorithms. */
49+
private int getMinAsymNonEcKeySize() { result = 2048 }
50+
51+
/** An instance of an RSA, DSA, or DH algorithm specification. */
52+
private class AsymmetricNonEcSpec extends ClassInstanceExpr {
53+
AsymmetricNonEcSpec() {
54+
this.getConstructedType() instanceof RsaKeyGenParameterSpec or
55+
this.getConstructedType() instanceof DsaGenParameterSpec or
56+
this.getConstructedType() instanceof DhGenParameterSpec
57+
}
58+
59+
/** Gets the `keysize` argument of this instance. */
60+
Argument getKeySizeArg() { result = this.getArgument(0) }
61+
}
2262
}
2363

24-
override predicate hasState(DataFlow::FlowState state) {
25-
state = getMinAsymNonEcKeySize().toString()
64+
private module EllipticCurve {
65+
/** A source for an insufficient key size used in elliptic curve (EC) algorithms. */
66+
private class AsymmetricEcSource extends InsufficientKeySizeSource {
67+
AsymmetricEcSource() {
68+
this.asExpr().(IntegerLiteral).getIntValue() < getMinAsymEcKeySize()
69+
or
70+
// the below is needed for cases when the key size is embedded in the curve name
71+
getEcKeySize(this.asExpr().(StringLiteral).getValue()) < getMinAsymEcKeySize()
72+
}
73+
74+
override predicate hasState(DataFlow::FlowState state) {
75+
state = getMinAsymEcKeySize().toString()
76+
}
77+
}
78+
79+
/** A sink for an insufficient key size used in elliptic curve (EC) algorithms. */
80+
private class AsymmetricEcSink extends InsufficientKeySizeSink {
81+
AsymmetricEcSink() {
82+
exists(AsymmetricInitMethodAccess ma, AsymmetricKeyGenerator kg |
83+
kg.getAlgoName().matches("EC%") and
84+
DataFlow::localExprFlow(kg, ma.getQualifier()) and
85+
this.asExpr() = ma.getKeySizeArg()
86+
)
87+
or
88+
exists(AsymmetricEcSpec s | this.asExpr() = s.getKeySizeArg())
89+
}
90+
91+
override predicate hasState(DataFlow::FlowState state) {
92+
state = getMinAsymEcKeySize().toString()
93+
}
94+
}
95+
96+
/** Returns the minimum recommended key size for elliptic curve (EC) algorithms. */
97+
private int getMinAsymEcKeySize() { result = 256 }
98+
99+
/** Returns the key size from an EC algorithm's curve name string */
100+
bindingset[algorithm]
101+
private int getEcKeySize(string algorithm) {
102+
algorithm.matches("sec%") and // specification such as "secp256r1"
103+
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
104+
or
105+
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
106+
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
107+
or
108+
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
109+
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
110+
}
111+
112+
/** An instance of an elliptic curve (EC) algorithm specification. */
113+
private class AsymmetricEcSpec extends ClassInstanceExpr {
114+
AsymmetricEcSpec() { this.getConstructedType() instanceof EcGenParameterSpec }
115+
116+
/** Gets the `keysize` argument of this instance. */
117+
Argument getKeySizeArg() { result = this.getArgument(0) }
118+
}
26119
}
27-
}
28120

29-
/** A source for an insufficient key size used in elliptic curve (EC) algorithms. */
30-
private class AsymmetricEcSource extends InsufficientKeySizeSource {
31-
AsymmetricEcSource() {
32-
this.asExpr().(IntegerLiteral).getIntValue() < getMinAsymEcKeySize()
33-
or
34-
// the below is needed for cases when the key size is embedded in the curve name
35-
getEcKeySize(this.asExpr().(StringLiteral).getValue()) < getMinAsymEcKeySize()
121+
/**
122+
* A call to the `initialize` method declared in `java.security.KeyPairGenerator`
123+
* or to the `init` method declared in `java.security.AlgorithmParameterGenerator`.
124+
*/
125+
private class AsymmetricInitMethodAccess extends MethodAccess {
126+
AsymmetricInitMethodAccess() {
127+
this.getMethod() instanceof KeyPairGeneratorInitMethod or
128+
this.getMethod() instanceof AlgoParamGeneratorInitMethod
129+
}
130+
131+
/** Gets the `keysize` argument of this call. */
132+
Argument getKeySizeArg() { result = this.getArgument(0) }
36133
}
37134

38-
override predicate hasState(DataFlow::FlowState state) {
39-
state = getMinAsymEcKeySize().toString()
135+
/**
136+
* An instance of a `java.security.KeyPairGenerator`
137+
* or of a `java.security.AlgorithmParameterGenerator`.
138+
*/
139+
private class AsymmetricKeyGenerator extends AlgoGeneratorObject {
140+
AsymmetricKeyGenerator() {
141+
this instanceof JavaSecurityKeyPairGenerator or
142+
this instanceof JavaSecurityAlgoParamGenerator
143+
}
144+
145+
override Expr getAlgoSpec() {
146+
result =
147+
[
148+
this.(JavaSecurityKeyPairGenerator).getAlgoSpec(),
149+
this.(JavaSecurityAlgoParamGenerator).getAlgoSpec()
150+
]
151+
}
40152
}
41153
}
42154

43-
/** A source for an insufficient key size used in AES algorithms. */
44-
private class SymmetricSource extends InsufficientKeySizeSource {
45-
SymmetricSource() { this.asExpr().(IntegerLiteral).getIntValue() < getMinSymKeySize() }
46-
47-
override predicate hasState(DataFlow::FlowState state) { state = getMinSymKeySize().toString() }
48-
}
49-
50-
/** Returns the minimum recommended key size for RSA, DSA, and DH algorithms. */
51-
private int getMinAsymNonEcKeySize() { result = 2048 }
52-
53-
/** Returns the minimum recommended key size for elliptic curve (EC) algorithms. */
54-
private int getMinAsymEcKeySize() { result = 256 }
55-
56-
/** Returns the minimum recommended key size for AES algorithms. */
57-
private int getMinSymKeySize() { result = 128 }
58-
59-
/** Returns the key size from an EC algorithm's curve name string */
60-
bindingset[algorithm]
61-
private int getEcKeySize(string algorithm) {
62-
algorithm.matches("sec%") and // specification such as "secp256r1"
63-
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
64-
or
65-
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
66-
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
67-
or
68-
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
69-
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
70-
}
155+
private module Symmetric {
156+
/** A source for an insufficient key size used in AES algorithms. */
157+
private class SymmetricSource extends InsufficientKeySizeSource {
158+
SymmetricSource() { this.asExpr().(IntegerLiteral).getIntValue() < getMinSymKeySize() }
71159

72-
/** A sink for an insufficient key size used in RSA, DSA, and DH algorithms. */
73-
private class AsymmetricNonEcSink extends InsufficientKeySizeSink {
74-
AsymmetricNonEcSink() {
75-
exists(AsymmetricInitMethodAccess ma, AsymmetricKeyGenerator kg |
76-
kg.getAlgoName().matches(["RSA", "DSA", "DH"]) and
77-
DataFlow::localExprFlow(kg, ma.getQualifier()) and
78-
this.asExpr() = ma.getKeySizeArg()
79-
)
80-
or
81-
exists(AsymmetricNonEcSpec spec | this.asExpr() = spec.getKeySizeArg())
160+
override predicate hasState(DataFlow::FlowState state) { state = getMinSymKeySize().toString() }
82161
}
83162

84-
override predicate hasState(DataFlow::FlowState state) {
85-
state = getMinAsymNonEcKeySize().toString()
163+
/** A sink for an insufficient key size used in AES algorithms. */
164+
private class SymmetricSink extends InsufficientKeySizeSink {
165+
SymmetricSink() {
166+
exists(SymmetricInitMethodAccess ma, SymmetricKeyGenerator kg |
167+
kg.getAlgoName() = "AES" and
168+
DataFlow::localExprFlow(kg, ma.getQualifier()) and
169+
this.asExpr() = ma.getKeySizeArg()
170+
)
171+
}
172+
173+
override predicate hasState(DataFlow::FlowState state) { state = getMinSymKeySize().toString() }
86174
}
87-
}
88175

89-
/** A sink for an insufficient key size used in elliptic curve (EC) algorithms. */
90-
private class AsymmetricEcSink extends InsufficientKeySizeSink {
91-
AsymmetricEcSink() {
92-
exists(AsymmetricInitMethodAccess ma, AsymmetricKeyGenerator kg |
93-
kg.getAlgoName().matches("EC%") and
94-
DataFlow::localExprFlow(kg, ma.getQualifier()) and
95-
this.asExpr() = ma.getKeySizeArg()
96-
)
97-
or
98-
exists(AsymmetricEcSpec s | this.asExpr() = s.getKeySizeArg())
99-
}
176+
/** Returns the minimum recommended key size for AES algorithms. */
177+
private int getMinSymKeySize() { result = 128 }
100178

101-
override predicate hasState(DataFlow::FlowState state) {
102-
state = getMinAsymEcKeySize().toString()
103-
}
104-
}
179+
/** A call to the `init` method declared in `javax.crypto.KeyGenerator`. */
180+
private class SymmetricInitMethodAccess extends MethodAccess {
181+
SymmetricInitMethodAccess() { this.getMethod() instanceof KeyGeneratorInitMethod }
105182

106-
/** A sink for an insufficient key size used in AES algorithms. */
107-
private class SymmetricSink extends InsufficientKeySizeSink {
108-
SymmetricSink() {
109-
exists(SymmetricInitMethodAccess ma, SymmetricKeyGenerator kg |
110-
kg.getAlgoName() = "AES" and
111-
DataFlow::localExprFlow(kg, ma.getQualifier()) and
112-
this.asExpr() = ma.getKeySizeArg()
113-
)
183+
/** Gets the `keysize` argument of this call. */
184+
Argument getKeySizeArg() { result = this.getArgument(0) }
114185
}
115186

116-
override predicate hasState(DataFlow::FlowState state) { state = getMinSymKeySize().toString() }
117-
}
118-
119-
/**
120-
* A call to the `initialize` method declared in `java.security.KeyPairGenerator`
121-
* or to the `init` method declared in `java.security.AlgorithmParameterGenerator`.
122-
*/
123-
private class AsymmetricInitMethodAccess extends MethodAccess {
124-
AsymmetricInitMethodAccess() {
125-
this.getMethod() instanceof KeyPairGeneratorInitMethod or
126-
this.getMethod() instanceof AlgoParamGeneratorInitMethod
187+
/** An instance of a `javax.crypto.KeyGenerator`. */
188+
private class SymmetricKeyGenerator extends AlgoGeneratorObject instanceof JavaxCryptoKeyGenerator {
189+
override Expr getAlgoSpec() { result = JavaxCryptoKeyGenerator.super.getAlgoSpec() }
127190
}
128-
129-
/** Gets the `keysize` argument of this call. */
130-
Argument getKeySizeArg() { result = this.getArgument(0) }
131-
}
132-
133-
/** A call to the `init` method declared in `javax.crypto.KeyGenerator`. */
134-
private class SymmetricInitMethodAccess extends MethodAccess {
135-
SymmetricInitMethodAccess() { this.getMethod() instanceof KeyGeneratorInitMethod }
136-
137-
/** Gets the `keysize` argument of this call. */
138-
Argument getKeySizeArg() { result = this.getArgument(0) }
139191
}
140192

141193
/** An instance of a generator that specifies an encryption algorithm. */
142194
abstract private class AlgoGeneratorObject extends CryptoAlgoSpec {
143195
/** Returns an uppercase string representing the algorithm name specified by this generator object. */
144196
string getAlgoName() { result = this.getAlgoSpec().(StringLiteral).getValue().toUpperCase() }
145197
}
146-
147-
/**
148-
* An instance of a `java.security.KeyPairGenerator`
149-
* or of a `java.security.AlgorithmParameterGenerator`.
150-
*/
151-
private class AsymmetricKeyGenerator extends AlgoGeneratorObject {
152-
AsymmetricKeyGenerator() {
153-
this instanceof JavaSecurityKeyPairGenerator or
154-
this instanceof JavaSecurityAlgoParamGenerator
155-
}
156-
157-
override Expr getAlgoSpec() {
158-
result =
159-
[
160-
this.(JavaSecurityKeyPairGenerator).getAlgoSpec(),
161-
this.(JavaSecurityAlgoParamGenerator).getAlgoSpec()
162-
]
163-
}
164-
}
165-
166-
/** An instance of a `javax.crypto.KeyGenerator`. */
167-
private class SymmetricKeyGenerator extends AlgoGeneratorObject instanceof JavaxCryptoKeyGenerator {
168-
override Expr getAlgoSpec() { result = JavaxCryptoKeyGenerator.super.getAlgoSpec() }
169-
}
170-
171-
/** An instance of an RSA, DSA, or DH algorithm specification. */
172-
private class AsymmetricNonEcSpec extends ClassInstanceExpr {
173-
AsymmetricNonEcSpec() {
174-
this.getConstructedType() instanceof RsaKeyGenParameterSpec or
175-
this.getConstructedType() instanceof DsaGenParameterSpec or
176-
this.getConstructedType() instanceof DhGenParameterSpec
177-
}
178-
179-
/** Gets the `keysize` argument of this instance. */
180-
Argument getKeySizeArg() { result = this.getArgument(0) }
181-
}
182-
183-
/** An instance of an elliptic curve (EC) algorithm specification. */
184-
private class AsymmetricEcSpec extends ClassInstanceExpr {
185-
AsymmetricEcSpec() { this.getConstructedType() instanceof EcGenParameterSpec }
186-
187-
/** Gets the `keysize` argument of this instance. */
188-
Argument getKeySizeArg() { result = this.getArgument(0) }
189-
}

0 commit comments

Comments
 (0)