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

Skip to content

Commit 657e1e6

Browse files
Jami CogswellJami Cogswell
authored andcommitted
start refactoring query logic into lib file
1 parent 3643c9e commit 657e1e6

4 files changed

Lines changed: 151 additions & 136 deletions

File tree

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ string getASecureAlgorithmName() {
249249
result =
250250
[
251251
"RSA", "SHA256", "SHA512", "CCM", "GCM", "AES(?![^a-zA-Z](ECB|CBC/PKCS[57]Padding))",
252-
"Blowfish", "ECIES"
252+
"Blowfish", "ECIES" // ! Blowfish not actually secure based on https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-4426 ??
253+
// ! hmm, other sources imply that it is secure...
254+
// ! also no DH here, etc.?
253255
]
254256
}
255257

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import semmle.code.java.security.Encryption
2+
import semmle.code.java.dataflow.TaintTracking
3+
4+
/** The Java class `java.security.spec.ECGenParameterSpec`. */
5+
class ECGenParameterSpec extends RefType {
6+
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
7+
}
8+
9+
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
10+
class KeyGeneratorInitMethod extends Method {
11+
KeyGeneratorInitMethod() {
12+
this.getDeclaringType() instanceof KeyGenerator and
13+
this.hasName("init")
14+
}
15+
}
16+
17+
/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
18+
class KeyPairGeneratorInitMethod extends Method {
19+
KeyPairGeneratorInitMethod() {
20+
this.getDeclaringType() instanceof KeyPairGenerator and
21+
this.hasName("initialize")
22+
}
23+
}
24+
25+
/** Returns the key size in the EC algorithm string */
26+
bindingset[algorithm]
27+
int getECKeySize(string algorithm) {
28+
algorithm.matches("sec%") and // specification such as "secp256r1"
29+
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
30+
or
31+
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
32+
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
33+
or
34+
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
35+
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
36+
}
37+
38+
/** Taint configuration tracking flow from a key generator to a `init` method call. */
39+
class KeyGeneratorInitConfiguration extends TaintTracking::Configuration {
40+
KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
41+
42+
override predicate isSource(DataFlow::Node source) {
43+
source.asExpr() instanceof JavaxCryptoKeyGenerator
44+
}
45+
46+
override predicate isSink(DataFlow::Node sink) {
47+
exists(MethodAccess ma |
48+
ma.getMethod() instanceof KeyGeneratorInitMethod and
49+
sink.asExpr() = ma.getQualifier()
50+
)
51+
}
52+
}
53+
54+
/** Taint configuration tracking flow from a keypair generator to a `initialize` method call. */
55+
class KeyPairGeneratorInitConfiguration extends TaintTracking::Configuration {
56+
KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
57+
58+
override predicate isSource(DataFlow::Node source) {
59+
source.asExpr() instanceof JavaSecurityKeyPairGenerator
60+
}
61+
62+
override predicate isSink(DataFlow::Node sink) {
63+
exists(MethodAccess ma |
64+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
65+
sink.asExpr() = ma.getQualifier()
66+
)
67+
}
68+
}
69+
70+
/** Holds if a symmetric `KeyGenerator` implementing encryption algorithm `type` and initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
71+
bindingset[type]
72+
predicate hasShortSymmetricKey(MethodAccess ma, string msg, string type) {
73+
ma.getMethod() instanceof KeyGeneratorInitMethod and
74+
exists(
75+
JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration cc, DataFlow::PathNode source,
76+
DataFlow::PathNode dest
77+
|
78+
jcg.getAlgoSpec().(StringLiteral).getValue() = type and
79+
source.getNode().asExpr() = jcg and
80+
dest.getNode().asExpr() = ma.getQualifier() and
81+
cc.hasFlowPath(source, dest)
82+
) and
83+
ma.getArgument(0).(IntegerLiteral).getIntValue() < 128 and
84+
msg = "Key size should be at least 128 bits for " + type + " encryption."
85+
}
86+
87+
/** Holds if an AES `KeyGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
88+
predicate hasShortAESKey(MethodAccess ma, string msg) { hasShortSymmetricKey(ma, msg, "AES") }
89+
90+
/** Holds if an asymmetric `KeyPairGenerator` implementing encryption algorithm `type` and initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
91+
bindingset[type]
92+
predicate hasShortAsymmetricKeyPair(MethodAccess ma, string msg, string type) {
93+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
94+
exists(
95+
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
96+
DataFlow::PathNode source, DataFlow::PathNode dest
97+
|
98+
jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = type and
99+
source.getNode().asExpr() = jpg and
100+
dest.getNode().asExpr() = ma.getQualifier() and
101+
kc.hasFlowPath(source, dest)
102+
) and
103+
ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
104+
msg = "Key size should be at least 2048 bits for " + type + " encryption."
105+
}
106+
107+
/** Holds if a DSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
108+
predicate hasShortDsaKeyPair(MethodAccess ma, string msg) {
109+
hasShortAsymmetricKeyPair(ma, msg, "DSA") or hasShortAsymmetricKeyPair(ma, msg, "DH")
110+
}
111+
112+
/** Holds if a RSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
113+
predicate hasShortRsaKeyPair(MethodAccess ma, string msg) {
114+
hasShortAsymmetricKeyPair(ma, msg, "RSA")
115+
}
116+
117+
/** Holds if an EC `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
118+
predicate hasShortECKeyPair(MethodAccess ma, string msg) {
119+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
120+
exists(
121+
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
122+
DataFlow::PathNode source, DataFlow::PathNode dest, ClassInstanceExpr cie
123+
|
124+
jpg.getAlgoSpec().(StringLiteral).getValue().matches("EC%") and // ECC variants such as ECDH and ECDSA
125+
source.getNode().asExpr() = jpg and
126+
dest.getNode().asExpr() = ma.getQualifier() and
127+
kc.hasFlowPath(source, dest) and
128+
DataFlow::localExprFlow(cie, ma.getArgument(0)) and
129+
ma.getArgument(0).getType() instanceof ECGenParameterSpec and
130+
getECKeySize(cie.getArgument(0).(StringLiteral).getValue()) < 256
131+
) and
132+
msg = "Key size should be at least 256 bits for EC encryption."
133+
}
134+
// ! refactor to something like the below,
135+
// ! need to adjust select clause then...
136+
// ! see C# and C++ queries for ideas
137+
// class EncryptionAlgorithm extends
138+
// predicate hasInsufficientKeySize() {
139+
// exists(Expr e, string msg |
140+
// hasShortAESKey(e, msg) or
141+
// hasShortDsaKeyPair(e, msg) or
142+
// hasShortRsaKeyPair(e, msg) or
143+
// hasShortECKeyPair(e, msg)
144+
// )
145+
// }

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

Lines changed: 2 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @name Use of a cryptographic algorithm with insufficient key size
33
* @description Using cryptographic algorithms with too small a key size can
44
* allow an attacker to compromise security.
5-
* @kind path-problem
5+
* @kind problem
66
* @problem.severity error
77
* @precision high
88
* @id java/insufficient-key-size
@@ -11,139 +11,7 @@
1111
*/
1212

1313
import java
14-
import semmle.code.java.security.Encryption
15-
import semmle.code.java.dataflow.TaintTracking
16-
17-
/** The Java class `java.security.spec.ECGenParameterSpec`. */
18-
class ECGenParameterSpec extends RefType {
19-
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
20-
}
21-
22-
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
23-
class KeyGeneratorInitMethod extends Method {
24-
KeyGeneratorInitMethod() {
25-
this.getDeclaringType() instanceof KeyGenerator and
26-
this.hasName("init")
27-
}
28-
}
29-
30-
/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
31-
class KeyPairGeneratorInitMethod extends Method {
32-
KeyPairGeneratorInitMethod() {
33-
this.getDeclaringType() instanceof KeyPairGenerator and
34-
this.hasName("initialize")
35-
}
36-
}
37-
38-
/** Returns the key size in the EC algorithm string */
39-
bindingset[algorithm]
40-
int getECKeySize(string algorithm) {
41-
algorithm.matches("sec%") and // specification such as "secp256r1"
42-
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
43-
or
44-
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
45-
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
46-
or
47-
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
48-
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
49-
}
50-
51-
/** Taint configuration tracking flow from a key generator to a `init` method call. */
52-
class KeyGeneratorInitConfiguration extends TaintTracking::Configuration {
53-
KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
54-
55-
override predicate isSource(DataFlow::Node source) {
56-
source.asExpr() instanceof JavaxCryptoKeyGenerator
57-
}
58-
59-
override predicate isSink(DataFlow::Node sink) {
60-
exists(MethodAccess ma |
61-
ma.getMethod() instanceof KeyGeneratorInitMethod and
62-
sink.asExpr() = ma.getQualifier()
63-
)
64-
}
65-
}
66-
67-
/** Taint configuration tracking flow from a keypair generator to a `initialize` method call. */
68-
class KeyPairGeneratorInitConfiguration extends TaintTracking::Configuration {
69-
KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
70-
71-
override predicate isSource(DataFlow::Node source) {
72-
source.asExpr() instanceof JavaSecurityKeyPairGenerator
73-
}
74-
75-
override predicate isSink(DataFlow::Node sink) {
76-
exists(MethodAccess ma |
77-
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
78-
sink.asExpr() = ma.getQualifier()
79-
)
80-
}
81-
}
82-
83-
/** Holds if a symmetric `KeyGenerator` implementing encryption algorithm `type` and initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
84-
bindingset[type]
85-
predicate hasShortSymmetricKey(MethodAccess ma, string msg, string type) {
86-
ma.getMethod() instanceof KeyGeneratorInitMethod and
87-
exists(
88-
JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration cc, DataFlow::PathNode source,
89-
DataFlow::PathNode dest
90-
|
91-
jcg.getAlgoSpec().(StringLiteral).getValue() = type and
92-
source.getNode().asExpr() = jcg and
93-
dest.getNode().asExpr() = ma.getQualifier() and
94-
cc.hasFlowPath(source, dest)
95-
) and
96-
ma.getArgument(0).(IntegerLiteral).getIntValue() < 128 and
97-
msg = "Key size should be at least 128 bits for " + type + " encryption."
98-
}
99-
100-
/** Holds if an AES `KeyGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
101-
predicate hasShortAESKey(MethodAccess ma, string msg) { hasShortSymmetricKey(ma, msg, "AES") }
102-
103-
/** Holds if an asymmetric `KeyPairGenerator` implementing encryption algorithm `type` and initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
104-
bindingset[type]
105-
predicate hasShortAsymmetricKeyPair(MethodAccess ma, string msg, string type) {
106-
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
107-
exists(
108-
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
109-
DataFlow::PathNode source, DataFlow::PathNode dest
110-
|
111-
jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = type and
112-
source.getNode().asExpr() = jpg and
113-
dest.getNode().asExpr() = ma.getQualifier() and
114-
kc.hasFlowPath(source, dest)
115-
) and
116-
ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
117-
msg = "Key size should be at least 2048 bits for " + type + " encryption."
118-
}
119-
120-
/** Holds if a DSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
121-
predicate hasShortDsaKeyPair(MethodAccess ma, string msg) {
122-
hasShortAsymmetricKeyPair(ma, msg, "DSA") or hasShortAsymmetricKeyPair(ma, msg, "DH")
123-
}
124-
125-
/** Holds if a RSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
126-
predicate hasShortRsaKeyPair(MethodAccess ma, string msg) {
127-
hasShortAsymmetricKeyPair(ma, msg, "RSA")
128-
}
129-
130-
/** Holds if an EC `KeyPairGenerator` initialized by `ma` uses an insufficient key size. `msg` provides a human-readable description of the problem. */
131-
predicate hasShortECKeyPair(MethodAccess ma, string msg) {
132-
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
133-
exists(
134-
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
135-
DataFlow::PathNode source, DataFlow::PathNode dest, ClassInstanceExpr cie
136-
|
137-
jpg.getAlgoSpec().(StringLiteral).getValue().matches("EC%") and // ECC variants such as ECDH and ECDSA
138-
source.getNode().asExpr() = jpg and
139-
dest.getNode().asExpr() = ma.getQualifier() and
140-
kc.hasFlowPath(source, dest) and
141-
DataFlow::localExprFlow(cie, ma.getArgument(0)) and
142-
ma.getArgument(0).getType() instanceof ECGenParameterSpec and
143-
getECKeySize(cie.getArgument(0).(StringLiteral).getValue()) < 256
144-
) and
145-
msg = "Key size should be at least 256 bits for EC encryption."
146-
}
14+
import semmle.code.java.security.InsufficientKeySizeQuery
14715

14816
from Expr e, string msg
14917
where
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
experimental/Security/CWE/CWE-326/InsufficientKeySize.ql
1+
Security/CWE/CWE-326/InsufficientKeySize.ql

0 commit comments

Comments
 (0)