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

Skip to content

Commit cfc950f

Browse files
committed
Query for weak encryption: Insufficient key size
1 parent 0addce5 commit cfc950f

7 files changed

Lines changed: 283 additions & 0 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
public class InsufficientKeySize {
2+
public void CryptoMethod() {
3+
KeyGenerator keyGen1 = KeyGenerator.getInstance("AES");
4+
// BAD: Key size is less than 128
5+
keyGen1.init(64);
6+
7+
KeyGenerator keyGen2 = KeyGenerator.getInstance("AES");
8+
// GOOD: Key size is no less than 128
9+
keyGen2.init(128);
10+
11+
KeyPairGenerator keyPairGen1 = KeyPairGenerator.getInstance("RSA");
12+
// BAD: Key size is less than 2048
13+
keyPairGen1.initialize(1024);
14+
15+
KeyPairGenerator keyPairGen2 = KeyPairGenerator.getInstance("RSA");
16+
// GOOD: Key size is no less than 2048
17+
keyPairGen2.initialize(2048);
18+
19+
KeyPairGenerator keyPairGen3 = KeyPairGenerator.getInstance("DSA");
20+
// BAD: Key size is less than 2048
21+
keyPairGen3.initialize(1024);
22+
23+
KeyPairGenerator keyPairGen4 = KeyPairGenerator.getInstance("DSA");
24+
// GOOD: Key size is no less than 2048
25+
keyPairGen4.initialize(2048);
26+
27+
KeyPairGenerator keyPairGen5 = KeyPairGenerator.getInstance("EC");
28+
// BAD: Key size is less than 224
29+
ECGenParameterSpec ecSpec1 = new ECGenParameterSpec("secp112r1");
30+
keyPairGen5.initialize(ecSpec1);
31+
32+
KeyPairGenerator keyPairGen6 = KeyPairGenerator.getInstance("EC");
33+
// GOOD: Key size is no less than 224
34+
ECGenParameterSpec ecSpec2 = new ECGenParameterSpec("secp256r1");
35+
keyPairGen6.initialize(ecSpec2);
36+
}
37+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
<overview>
4+
<p>This rule finds uses of encryption algorithms with too small a key size. Encryption algorithms
5+
are vulnerable to brute force attack when too small a key size is used.</p>
6+
</overview>
7+
8+
<recommendation>
9+
<p>The key should be at least 2048-bit long when using RSA and DSA encryption, 224-bit long when using EC encryption, and 128-bit long when using
10+
symmetric encryption.</p>
11+
</recommendation>
12+
13+
<references>
14+
15+
<li>
16+
Wikipedia.
17+
<a href="http://en.wikipedia.org/wiki/Key_size">Key size</a>
18+
</li>
19+
<li>
20+
SonarSource.
21+
<a href="https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-4426">Cryptographic keys should be robust</a>
22+
</li>
23+
<li>
24+
CWE.
25+
<a href="https://cwe.mitre.org/data/definitions/326.html">CWE-326: Inadequate Encryption Strength</a>
26+
</li>
27+
<li>
28+
C# implementation of CodeQL
29+
<a href="https://github.com/github/codeql/blob/df29a1636555465527d17668c19c202e365cf502/csharp/ql/src/Security%20Features/InsufficientKeySize.ql">codeql/csharp/ql/src/Security Features/InsufficientKeySize.ql</a>
30+
</li>
31+
32+
</references>
33+
</qhelp>
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* @name Weak encryption: Insufficient key size
3+
* @description Finds uses of encryption algorithms with too small a key size
4+
* @kind problem
5+
* @id java/insufficient-key-size
6+
* @tags security
7+
* external/cwe/cwe-326
8+
*/
9+
10+
import java
11+
import semmle.code.java.security.Encryption
12+
import semmle.code.java.dataflow.TaintTracking
13+
14+
/** The Java class `javax.crypto.KeyGenerator`. */
15+
class KeyGenerator extends RefType {
16+
KeyGenerator() { this.hasQualifiedName("javax.crypto", "KeyGenerator") }
17+
}
18+
19+
/** The Java class `javax.crypto.KeyGenerator`. */
20+
class KeyPairGenerator extends RefType {
21+
KeyPairGenerator() { this.hasQualifiedName("java.security", "KeyPairGenerator") }
22+
}
23+
24+
/** The Java class `java.security.spec.ECGenParameterSpec`. */
25+
class ECGenParameterSpec extends RefType {
26+
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
27+
}
28+
29+
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
30+
class KeyGeneratorInitMethod extends Method {
31+
KeyGeneratorInitMethod() {
32+
getDeclaringType() instanceof KeyGenerator and
33+
hasName("init")
34+
}
35+
}
36+
37+
/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
38+
class KeyPairGeneratorInitMethod extends Method {
39+
KeyPairGeneratorInitMethod() {
40+
getDeclaringType() instanceof KeyPairGenerator and
41+
hasName("initialize")
42+
}
43+
}
44+
45+
/** Taint configuration tracking flow from a key generator to a `init` method call. */
46+
class CryptoKeyGeneratorConfiguration extends TaintTracking::Configuration {
47+
CryptoKeyGeneratorConfiguration() { this = "CryptoKeyGeneratorConfiguration" }
48+
49+
override predicate isSource(DataFlow::Node source) {
50+
exists(JavaxCryptoKeyGenerator jcg | jcg = source.asExpr())
51+
}
52+
53+
override predicate isSink(DataFlow::Node sink) {
54+
exists(MethodAccess ma |
55+
ma.getMethod() instanceof KeyGeneratorInitMethod and
56+
sink.asExpr() = ma.getQualifier()
57+
)
58+
}
59+
}
60+
61+
/** Taint configuration tracking flow from a keypair generator to a `initialize` method call. */
62+
class KeyPairGeneratorConfiguration extends TaintTracking::Configuration {
63+
KeyPairGeneratorConfiguration() { this = "KeyPairGeneratorConfiguration" }
64+
65+
override predicate isSource(DataFlow::Node source) {
66+
exists(JavaSecurityKeyPairGenerator jkg | jkg = source.asExpr())
67+
}
68+
69+
override predicate isSink(DataFlow::Node sink) {
70+
exists(MethodAccess ma |
71+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
72+
sink.asExpr() = ma.getQualifier()
73+
)
74+
}
75+
}
76+
77+
/** Holds if an AES `KeyGenerator` is initialized with an insufficient key size. */
78+
predicate incorrectUseOfAES(MethodAccess ma, string msg) {
79+
ma.getMethod() instanceof KeyGeneratorInitMethod and
80+
exists(
81+
JavaxCryptoKeyGenerator jcg, CryptoKeyGeneratorConfiguration cc, DataFlow::PathNode source,
82+
DataFlow::PathNode dest
83+
|
84+
jcg.getAlgoSpec().(StringLiteral).getValue() = "AES" and
85+
source.getNode().asExpr() = jcg and
86+
dest.getNode().asExpr() = ma.getQualifier() and
87+
cc.hasFlowPath(source, dest)
88+
) and
89+
ma.getArgument(0).(IntegerLiteral).getIntValue() < 128 and
90+
msg = "Key size should be at least 128 bits for AES encryption."
91+
}
92+
93+
/** Holds if a DSA `KeyPairGenerator` is initialized with an insufficient key size. */
94+
predicate incorrectUseOfDSA(MethodAccess ma, string msg) {
95+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
96+
exists(
97+
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorConfiguration kc, DataFlow::PathNode source,
98+
DataFlow::PathNode dest
99+
|
100+
jpg.getAlgoSpec().(StringLiteral).getValue() = "DSA" and
101+
source.getNode().asExpr() = jpg and
102+
dest.getNode().asExpr() = ma.getQualifier() and
103+
kc.hasFlowPath(source, dest)
104+
) and
105+
ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
106+
msg = "Key size should be at least 2048 bits for DSA encryption."
107+
}
108+
109+
/** Holds if a RSA `KeyPairGenerator` is initialized with an insufficient key size. */
110+
predicate incorrectUseOfRSA(MethodAccess ma, string msg) {
111+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
112+
exists(
113+
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorConfiguration kc, DataFlow::PathNode source,
114+
DataFlow::PathNode dest
115+
|
116+
jpg.getAlgoSpec().(StringLiteral).getValue() = "RSA" and
117+
source.getNode().asExpr() = jpg and
118+
dest.getNode().asExpr() = ma.getQualifier() and
119+
kc.hasFlowPath(source, dest)
120+
) and
121+
ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
122+
msg = "Key size should be at least 2048 bits for RSA encryption."
123+
}
124+
125+
/** Holds if an EC `KeyPairGenerator` is initialized with an insufficient key size. */
126+
predicate incorrectUseOfEC(MethodAccess ma, string msg) {
127+
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
128+
exists(
129+
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorConfiguration kc, DataFlow::PathNode source,
130+
DataFlow::PathNode dest, ClassInstanceExpr cie
131+
|
132+
jpg.getAlgoSpec().(StringLiteral).getValue().matches("EC%") and //ECC variants such as ECDH and ECDSA
133+
source.getNode().asExpr() = jpg and
134+
dest.getNode().asExpr() = ma.getQualifier() and
135+
kc.hasFlowPath(source, dest) and
136+
exists(VariableAssign va |
137+
ma.getArgument(0).(VarAccess).getVariable() = va.getDestVar() and
138+
va.getSource() = cie and
139+
cie.getArgument(0)
140+
.(StringLiteral)
141+
.getRepresentedString()
142+
.regexpCapture(".*[a-zA-Z]+([0-9]+)[a-zA-Z]+.*", 1)
143+
.toInt() < 224
144+
)
145+
) and
146+
msg = "Key size should be at least 224 bits for EC encryption."
147+
}
148+
149+
from Expr e, string msg
150+
where
151+
incorrectUseOfAES(e, msg) or
152+
incorrectUseOfDSA(e, msg) or
153+
incorrectUseOfRSA(e, msg) or
154+
incorrectUseOfEC(e, msg)
155+
select e, msg

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,3 +304,15 @@ class JavaSecuritySignature extends JavaSecurityAlgoSpec {
304304

305305
override Expr getAlgoSpec() { result = this.(ConstructorCall).getArgument(0) }
306306
}
307+
308+
/** Method call to the Java class `java.security.KeyPairGenerator`. */
309+
class JavaSecurityKeyPairGenerator extends JavaxCryptoAlgoSpec {
310+
JavaSecurityKeyPairGenerator() {
311+
exists(Method m | m.getAReference() = this |
312+
m.getDeclaringType().getQualifiedName() = "java.security.KeyPairGenerator" and
313+
m.getName() = "getInstance"
314+
)
315+
}
316+
317+
override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) }
318+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| InsufficientKeySize.java:9:9:9:24 | init(...) | Key size should be at least 128 bits for AES encryption. |
2+
| InsufficientKeySize.java:17:9:17:36 | initialize(...) | Key size should be at least 2048 bits for RSA encryption. |
3+
| InsufficientKeySize.java:25:9:25:36 | initialize(...) | Key size should be at least 2048 bits for DSA encryption. |
4+
| InsufficientKeySize.java:34:9:34:39 | initialize(...) | Key size should be at least 224 bits for EC encryption. |
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.security.KeyPairGenerator;
2+
import java.security.spec.ECGenParameterSpec;
3+
import javax.crypto.KeyGenerator;
4+
5+
public class InsufficientKeySize {
6+
public void CryptoMethod() {
7+
KeyGenerator keyGen1 = KeyGenerator.getInstance("AES");
8+
// BAD: Key size is less than 128
9+
keyGen1.init(64);
10+
11+
KeyGenerator keyGen2 = KeyGenerator.getInstance("AES");
12+
// GOOD: Key size is no less than 128
13+
keyGen2.init(128);
14+
15+
KeyPairGenerator keyPairGen1 = KeyPairGenerator.getInstance("RSA");
16+
// BAD: Key size is less than 2048
17+
keyPairGen1.initialize(1024);
18+
19+
KeyPairGenerator keyPairGen2 = KeyPairGenerator.getInstance("RSA");
20+
// GOOD: Key size is no less than 2048
21+
keyPairGen2.initialize(2048);
22+
23+
KeyPairGenerator keyPairGen3 = KeyPairGenerator.getInstance("DSA");
24+
// BAD: Key size is less than 2048
25+
keyPairGen3.initialize(1024);
26+
27+
KeyPairGenerator keyPairGen4 = KeyPairGenerator.getInstance("DSA");
28+
// GOOD: Key size is no less than 2048
29+
keyPairGen4.initialize(2048);
30+
31+
KeyPairGenerator keyPairGen5 = KeyPairGenerator.getInstance("EC");
32+
// BAD: Key size is less than 224
33+
ECGenParameterSpec ecSpec1 = new ECGenParameterSpec("secp112r1");
34+
keyPairGen5.initialize(ecSpec1);
35+
36+
KeyPairGenerator keyPairGen6 = KeyPairGenerator.getInstance("EC");
37+
// GOOD: Key size is no less than 224
38+
ECGenParameterSpec ecSpec2 = new ECGenParameterSpec("secp256r1");
39+
keyPairGen6.initialize(ecSpec2);
40+
}
41+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
experimental/Security/CWE/CWE-326/InsufficientKeySize.ql

0 commit comments

Comments
 (0)