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

Skip to content

Commit cdac0e2

Browse files
Jami CogswellJami Cogswell
authored andcommitted
add local algo name tracking, still need to add ability to track algo name when KeyGen obj is param to other method
1 parent c414ee0 commit cdac0e2

3 files changed

Lines changed: 68 additions & 14 deletions

File tree

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

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ import semmle.code.java.security.Encryption
22
import semmle.code.java.dataflow.TaintTracking
33
import semmle.code.java.dataflow.DataFlow
44

5+
// TODO:
6+
// todo #1: make representation of source that can be shared across the configs
7+
// todo #2: make representation of sink that can be shared across the configs
8+
// todo #3: finish adding tracking for algo type/name... need flow/taint-tracking for across methods??
9+
// todo #3a: 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.)
510
// ******* DATAFLOW BELOW *************************************************************************
611
/**
712
* Asymmetric (RSA, DSA, DH) key length data flow tracking configuration.
@@ -10,13 +15,27 @@ class AsymmetricKeyTrackingConfiguration extends DataFlow::Configuration {
1015
AsymmetricKeyTrackingConfiguration() { this = "AsymmetricKeyTrackingConfiguration" }
1116

1217
override predicate isSource(DataFlow::Node source) {
13-
source.asExpr() instanceof IntegerLiteral and // ! this works with current test cases, but reconsider IntegerLiteral when variables are used
14-
source.toString().toInt() < 2048
18+
exists(ClassInstanceExpr rsaGenParamSpec |
19+
rsaGenParamSpec.getConstructedType() instanceof RSAGenParameterSpec and // ! double-check if should just use getType() instead
20+
rsaGenParamSpec.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
21+
source.asExpr() = rsaGenParamSpec
22+
)
23+
or
24+
source.asExpr().(IntegerLiteral).getIntValue() < 2048
1525
}
1626

1727
override predicate isSink(DataFlow::Node sink) {
18-
exists(MethodAccess ma |
28+
exists(MethodAccess ma, VarAccess va |
1929
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
30+
va.getVariable()
31+
.getAnAssignedValue()
32+
.(JavaSecurityKeyPairGenerator)
33+
.getAlgoSpec()
34+
.(StringLiteral)
35+
.getValue()
36+
.toUpperCase()
37+
.matches(["RSA", "DSA", "DH"]) and
38+
ma.getQualifier() = va and
2039
sink.asExpr() = ma.getArgument(0)
2140
)
2241
}
@@ -30,15 +49,26 @@ class AsymmetricECCKeyTrackingConfiguration extends DataFlow::Configuration {
3049

3150
override predicate isSource(DataFlow::Node source) {
3251
exists(ClassInstanceExpr ecGenParamSpec |
33-
getECKeySize(ecGenParamSpec.getArgument(0).(StringLiteral).getValue()) < 256 and
52+
getECKeySize(ecGenParamSpec.getArgument(0).(StringLiteral).getValue()) < 256 and // ! can generate EC with just the keysize and not the curve apparently... (based on netty/netty FP example)
3453
source.asExpr() = ecGenParamSpec
3554
)
55+
or
56+
source.asExpr().(IntegerLiteral).getIntValue() < 256
3657
}
3758

3859
override predicate isSink(DataFlow::Node sink) {
39-
exists(MethodAccess ma |
60+
exists(MethodAccess ma, VarAccess va |
4061
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
41-
ma.getArgument(0).getType() instanceof ECGenParameterSpec and
62+
//ma.getArgument(0).getType() instanceof ECGenParameterSpec and // ! can generate EC with just the keysize and not the curve apparently... (based on netty/netty FP example)
63+
va.getVariable()
64+
.getAnAssignedValue()
65+
.(JavaSecurityKeyPairGenerator)
66+
.getAlgoSpec()
67+
.(StringLiteral)
68+
.getValue()
69+
.toUpperCase()
70+
.matches(["EC%"]) and
71+
ma.getQualifier() = va and
4272
sink.asExpr() = ma.getArgument(0)
4373
)
4474
}
@@ -51,13 +81,21 @@ class SymmetricKeyTrackingConfiguration extends DataFlow::Configuration {
5181
SymmetricKeyTrackingConfiguration() { this = "SymmetricKeyTrackingConfiguration2" }
5282

5383
override predicate isSource(DataFlow::Node source) {
54-
source.asExpr() instanceof IntegerLiteral and // ! this works with current test cases, but reconsider IntegerLiteral when variables are used
55-
source.toString().toInt() < 128
84+
source.asExpr().(IntegerLiteral).getIntValue() < 128
5685
}
5786

5887
override predicate isSink(DataFlow::Node sink) {
59-
exists(MethodAccess ma |
88+
exists(MethodAccess ma, VarAccess va |
6089
ma.getMethod() instanceof KeyGeneratorInitMethod and
90+
va.getVariable()
91+
.getAnAssignedValue()
92+
.(JavaxCryptoKeyGenerator)
93+
.getAlgoSpec()
94+
.(StringLiteral)
95+
.getValue()
96+
.toUpperCase()
97+
.matches(["AES"]) and
98+
ma.getQualifier() = va and
6199
sink.asExpr() = ma.getArgument(0)
62100
)
63101
}
@@ -77,6 +115,11 @@ private class ECGenParameterSpec extends RefType {
77115
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
78116
}
79117

118+
/** The Java class `java.security.spec.ECGenParameterSpec`. */
119+
private class RSAGenParameterSpec extends RefType {
120+
RSAGenParameterSpec() { this.hasQualifiedName("java.security.spec", "RSAKeyGenParameterSpec") }
121+
}
122+
80123
// ! move to Encryption.qll?
81124
/** Returns the key size in the EC algorithm string */
82125
bindingset[algorithm]

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import DataFlow::PathGraph
2828
// sink.getNode(), "size"
2929
from DataFlow::PathNode source, DataFlow::PathNode sink
3030
where
31-
//hasInsufficientKeySize2(source, sink)
3231
exists(AsymmetricKeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink)) or
3332
exists(AsymmetricECCKeyTrackingConfiguration config2 | config2.hasFlowPath(source, sink)) or
3433
exists(SymmetricKeyTrackingConfiguration config3 | config3.hasFlowPath(source, sink))

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import java.security.KeyPairGenerator;
22
import java.security.spec.ECGenParameterSpec;
3+
import java.security.spec.RSAKeyGenParameterSpec;
34
import javax.crypto.KeyGenerator;
45

56
public class InsufficientKeySizeTest {
@@ -27,6 +28,16 @@ public void keySizeTesting() throws java.security.NoSuchAlgorithmException, java
2728
// GOOD: Key size is no less than 2048
2829
KeyPairGenerator keyPairGen2 = KeyPairGenerator.getInstance("RSA");
2930
keyPairGen2.initialize(2048); // Safe
31+
32+
// test with spec
33+
// BAD: Key size is less than 2048
34+
KeyPairGenerator keyPairGen3 = KeyPairGenerator.getInstance("RSA");
35+
RSAKeyGenParameterSpec rsaSpec = new RSAKeyGenParameterSpec(1024, null);
36+
keyPairGen3.initialize(rsaSpec); // $ hasInsufficientKeySize
37+
38+
// BAD: Key size is less than 2048
39+
KeyPairGenerator keyPairGen4 = KeyPairGenerator.getInstance("RSA");
40+
keyPairGen4.initialize(new RSAKeyGenParameterSpec(1024, null)); // $ hasInsufficientKeySize
3041
}
3142

3243
// DSA (Asymmetric)
@@ -145,23 +156,24 @@ public void keySizeTesting() throws java.security.NoSuchAlgorithmException, java
145156
int size = 64; // test integer variable
146157
KeyGenerator keyGen = KeyGenerator.getInstance("AES"); // test KeyGenerator variable
147158
testSymmetric(size, keyGen); // test with variable as key size
148-
testSymmetric2(64); // test with int constant as key size
159+
testSymmetric2(64); // test with int literal as key size
149160
}
150161

151162

152163
// Test variables passed to other method(s) - Asymmetric, Not EC
153164
{
154165
int size = 1024; // test integer variable
155166
KeyPairGenerator keyPairGen21 = KeyPairGenerator.getInstance("RSA"); // test KeyPairGenerator variable
156-
testAsymmetricNonEC(size, keyPairGen21);
167+
testAsymmetricNonEC(size, keyPairGen21); // test with variable as key size
168+
testAsymmetricNonEC2(1024); // test with int literal as key size
157169
}
158170

159171
// Test variable passed to other method(s) - Asymmetric, EC
160172
{
161173
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp112r1"); // test ECGenParameterSpec variable
162174
KeyPairGenerator keyPairGen22 = KeyPairGenerator.getInstance("EC"); // test KeyPairGenerator variable
163-
testAsymmetricEC(ecSpec, keyPairGen22); // test with variable as key size
164-
testAsymmetricNonEC2(1024); // test with int constant as key size
175+
testAsymmetricEC(ecSpec, keyPairGen22);
176+
165177
}
166178

167179
}

0 commit comments

Comments
 (0)