delete experimental files

This commit is contained in:
Jami Cogswell
2022-10-10 16:22:42 -04:00
parent bd76b1fcc0
commit b6a8c27d48
4 changed files with 1 additions and 689 deletions

View File

@@ -249,10 +249,7 @@ string getASecureAlgorithmName() {
result =
[
"RSA", "SHA256", "SHA512", "CCM", "GCM", "AES(?![^a-zA-Z](ECB|CBC/PKCS[57]Padding))",
"Blowfish", "ECIES" // ! Blowfish not actually secure based on https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-4426 ??
// ! hmm, other sources imply that it is secure...
// ! also no DH here, etc.?
// ! also is ECB matched with AES?
"Blowfish", "ECIES"
]
}

View File

@@ -1,264 +0,0 @@
import semmle.code.java.security.Encryption
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.DataFlow
//import DataFlow::PathGraph
/**
* Asymmetric (RSA, DSA, DH) key length data flow tracking configuration.
*/
class AsymmetricKeyTrackingConfiguration extends DataFlow::Configuration {
AsymmetricKeyTrackingConfiguration() { this = "AsymmetricKeyTrackingConfiguration" }
override predicate isSource(DataFlow::Node source) {
exists(IntegerLiteral integer, VarAccess var |
integer.getIntValue() < 2048 and
source.asExpr() = integer
or
var.getVariable().getInitializer().getUnderlyingExpr() instanceof IntegerLiteral and
var.getVariable().getInitializer().getUnderlyingExpr().toString().toInt() < 2048 and
source.asExpr() = var.getVariable().getInitializer()
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
sink.asExpr() = ma.getArgument(0)
)
}
}
/** The Java class `java.security.spec.ECGenParameterSpec`. */
private class ECGenParameterSpec extends RefType {
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
}
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
private class KeyGeneratorInitMethod extends Method {
KeyGeneratorInitMethod() {
this.getDeclaringType() instanceof KeyGenerator and
this.hasName("init")
}
}
/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
private class KeyPairGeneratorInitMethod extends Method {
KeyPairGeneratorInitMethod() {
this.getDeclaringType() instanceof KeyPairGenerator and
this.hasName("initialize")
}
}
/** Returns the key size in the EC algorithm string */
bindingset[algorithm]
private int getECKeySize(string algorithm) {
algorithm.matches("sec%") and // specification such as "secp256r1"
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
or
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
or
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
}
/** Taint configuration tracking flow from a key generator to a `init` method call. */
private class KeyGeneratorInitConfiguration extends TaintTracking::Configuration {
KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof JavaxCryptoKeyGenerator
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyGeneratorInitMethod and
sink.asExpr() = ma.getQualifier()
)
}
}
/**
* Taint configuration tracking flow from a keypair generator to
* an `initialize` method call.
*/
private class KeyPairGeneratorInitConfiguration extends TaintTracking::Configuration {
KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof JavaSecurityKeyPairGenerator
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
sink.asExpr() = ma.getQualifier()
)
}
}
/**
* 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.
*/
bindingset[type]
private predicate hasShortSymmetricKey(MethodAccess ma, string msg, string type) {
ma.getMethod() instanceof KeyGeneratorInitMethod and
// flow needed to correctly determine algorithm type and
// not match to ANY symmetric algorithm (although doesn't really matter since only have AES currently...)
exists(
JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration cc, DataFlow::PathNode source,
DataFlow::PathNode dest
|
jcg.getAlgoSpec().(StringLiteral).getValue() = type and
source.getNode().asExpr() = jcg and
dest.getNode().asExpr() = ma.getQualifier() and
cc.hasFlowPath(source, dest)
) and
(
// VarAccess case needed to handle FN of key-size stored in a variable
// Note: cannot use CompileTimeConstantExpr since will miss cases when variable is not a compile-time constant
// (e.g. not declared `final` in Java)
exists(VarAccess var |
var.getVariable().getInitializer().getUnderlyingExpr() instanceof IntegerLiteral and
var.getVariable().getInitializer().getUnderlyingExpr().toString().toInt() < 128 and
ma.getArgument(0) = var
)
or
// exists(CompileTimeConstantExpr var |
// //var.getUnderlyingExpr() instanceof IntegerLiteral and // can't include this...
// var.getIntValue() < 128 and
// ma.getArgument(0) = var
// )
// or
ma.getArgument(0).(IntegerLiteral).getIntValue() < 128
) and
msg = "Key size should be at least 128 bits for " + type + " encryption."
}
/**
* Holds if an AES `KeyGenerator` initialized by `ma` uses an insufficient key size.
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortAESKey(MethodAccess ma, string msg) {
hasShortSymmetricKey(ma, msg, "AES")
}
/**
* 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.
*/
bindingset[type]
private predicate hasShortAsymmetricKeyPair(MethodAccess ma, string msg, string type) {
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
//ma.getQualifier() instanceof JavaSecurityKeyPairGenerator and
//ma.getQualifier().getBasicBlock() instanceof JavaSecurityKeyPairGenerator and
// * USE BELOW
ma.getQualifier().getBasicBlock().getAPredecessor() instanceof JavaSecurityKeyPairGenerator and
// * USE ABOVE
//ma.getQualifier().getBasicBlock().getNode(2) instanceof JavaSecurityKeyPairGenerator and
// ma.getQualifier()
// .getBasicBlock()
// .getANode()
// .(JavaSecurityKeyPairGenerator)
// .getAlgoSpec()
// .(StringLiteral)
// .getValue()
// .toUpperCase() = type and
//ma.getQualifier().getBasicBlock().getAPredecessor() instanceof JavaSecurityKeyPairGenerator and
// * USE BELOW
ma.getQualifier()
.getBasicBlock()
.getAPredecessor()
.(JavaSecurityKeyPairGenerator)
.getAlgoSpec()
.(StringLiteral)
.getValue()
.toUpperCase() = type and
// * USE ABOVE
// flow needed to correctly determine algorithm type and
// not match to ANY asymmetric algorithm
// * REMOVE BELOW
// exists(
// JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
// DataFlow::PathNode source, DataFlow::PathNode dest
// |
// jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = type and
// source.getNode().asExpr() = jpg and
// dest.getNode().asExpr() = ma.getQualifier() and
// kc.hasFlowPath(source, dest)
// ) and
// * REMOVE ABOVE
// VarAccess case needed to handle FN of key-size stored in a variable
// Note: cannot use CompileTimeConstantExpr since will miss cases when variable is not a compile-time constant
// (e.g. not declared `final` in Java)
(
exists(VarAccess var |
var.getVariable().getInitializer().getUnderlyingExpr() instanceof IntegerLiteral and
var.getVariable().getInitializer().getUnderlyingExpr().toString().toInt() < 2048 and
ma.getArgument(0) = var
)
or
ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048
// or
// exists(
// AsymmetricKeyTrackingConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
// |
// cfg.hasFlowPath(source, sink)
// )
) and
msg = "Key size should be at least 2048 bits for " + type + " encryption."
}
/**
* Holds if a DSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size.
*
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortDsaKeyPair(MethodAccess ma, string msg) {
hasShortAsymmetricKeyPair(ma, msg, "DSA") or
hasShortAsymmetricKeyPair(ma, msg, "DH")
}
/**
* Holds if a RSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size.
*
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortRsaKeyPair(MethodAccess ma, string msg) {
hasShortAsymmetricKeyPair(ma, msg, "RSA")
}
/**
* Holds if an EC `KeyPairGenerator` initialized by `ma` uses an insufficient key size.
*
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortECKeyPair(MethodAccess ma, string msg) {
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
exists(
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
DataFlow::PathNode source, DataFlow::PathNode dest, ClassInstanceExpr cie
|
jpg.getAlgoSpec().(StringLiteral).getValue().matches("EC%") and // ECC variants such as ECDH and ECDSA
source.getNode().asExpr() = jpg and
dest.getNode().asExpr() = ma.getQualifier() and
kc.hasFlowPath(source, dest) and
DataFlow::localExprFlow(cie, ma.getArgument(0)) and
ma.getArgument(0).getType() instanceof ECGenParameterSpec and
getECKeySize(cie.getArgument(0).(StringLiteral).getValue()) < 256
) and
msg = "Key size should be at least 256 bits for EC encryption."
}
// ! refactor this so can use 'path-problem' select clause instead?
predicate hasInsufficientKeySize(Expr e, string msg) {
hasShortAESKey(e, msg) or
hasShortDsaKeyPair(e, msg) or
hasShortRsaKeyPair(e, msg) or
hasShortECKeyPair(e, msg)
}

View File

@@ -1,239 +0,0 @@
import semmle.code.java.security.Encryption
import semmle.code.java.dataflow.TaintTracking2
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.DataFlow
// TODO:
// todo #0: find a better way to combine the two needed taint-tracking configs so can go back to having a path-graph...
// todo #1: make representation of source that can be shared across the configs
// todo #2: make representation of sink that can be shared across the configs
// 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.)
// todo #4: refactor to be more like the Python version? (or not possible because of lack of DataFlow::Node for void method in Java?)
// ******* DATAFLOW BELOW *************************************************************************
/**
* Asymmetric (RSA, DSA, DH) key length data flow tracking configuration.
*/
class AsymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
AsymmetricKeyTrackingConfiguration() { this = "AsymmetricKeyTrackingConfiguration" }
override predicate isSource(DataFlow::Node source) {
exists(ClassInstanceExpr rsaGenParamSpec |
rsaGenParamSpec.getConstructedType() instanceof RSAGenParameterSpec and // ! double-check if should just use getType() instead
rsaGenParamSpec.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
source.asExpr() = rsaGenParamSpec
)
or
source.asExpr().(IntegerLiteral).getIntValue() < 2048
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma, VarAccess va |
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
//ma.getFile().getBaseName().matches("SignatureTest.java") and
// va.getVariable()
// .getAnAssignedValue()
// .(JavaSecurityKeyPairGenerator)
// .getAlgoSpec()
// .(StringLiteral)
// .getValue()
// .toUpperCase()
// .matches(["RSA", "DSA", "DH"]) and
// ma.getQualifier() = va and
exists(
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kpgConfig,
DataFlow::PathNode source, DataFlow::PathNode dest
|
jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches(["RSA", "DSA", "DH"]) and
source.getNode().asExpr() = jpg and
dest.getNode().asExpr() = ma.getQualifier() and
kpgConfig.hasFlowPath(source, dest)
) and
sink.asExpr() = ma.getArgument(0)
)
}
}
// predicate hasInsufficientKeySize(string msg) { hasShortAsymmetricKeyPair(msg) }
// predicate hasShortAsymmetricKeyPair(string msg) {
// exists(AsymmetricKeyTrackingConfiguration config1, DataFlow::Node source, DataFlow::Node sink |
// config1.hasFlow(source, sink)
// ) and
// msg = "Key size should be at least 2048 bits for " + "___" + " encryption."
// }
/**
* Asymmetric (EC) key length data flow tracking configuration.
*/
class AsymmetricECCKeyTrackingConfiguration extends TaintTracking2::Configuration {
AsymmetricECCKeyTrackingConfiguration() { this = "AsymmetricECCKeyTrackingConfiguration" }
override predicate isSource(DataFlow::Node source) {
exists(ClassInstanceExpr ecGenParamSpec |
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)
source.asExpr() = ecGenParamSpec
)
or
source.asExpr().(IntegerLiteral).getIntValue() < 256
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma, VarAccess va |
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
//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)
// va.getVariable()
// .getAnAssignedValue()
// .(JavaSecurityKeyPairGenerator)
// .getAlgoSpec()
// .(StringLiteral)
// .getValue()
// .toUpperCase()
// .matches(["EC%"]) and
// ma.getQualifier() = va and
exists(
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kpgConfig,
DataFlow::PathNode source, DataFlow::PathNode dest
|
jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches("EC%") and
source.getNode().asExpr() = jpg and
dest.getNode().asExpr() = ma.getQualifier() and
kpgConfig.hasFlowPath(source, dest)
) and
sink.asExpr() = ma.getArgument(0)
)
}
}
/**
* Symmetric (AES) key length data flow tracking configuration.
*/
class SymmetricKeyTrackingConfiguration extends TaintTracking2::Configuration {
SymmetricKeyTrackingConfiguration() { this = "SymmetricKeyTrackingConfiguration2" }
override predicate isSource(DataFlow::Node source) {
source.asExpr().(IntegerLiteral).getIntValue() < 128
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma, VarAccess va |
ma.getMethod() instanceof KeyGeneratorInitMethod and
// va.getVariable()
// .getAnAssignedValue()
// .(JavaxCryptoKeyGenerator)
// .getAlgoSpec()
// .(StringLiteral)
// .getValue()
// .toUpperCase()
// .matches(["AES"]) and
// ma.getQualifier() = va and
exists(
JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration kgConfig,
DataFlow::PathNode source, DataFlow::PathNode dest
|
jcg.getAlgoSpec().(StringLiteral).getValue().toUpperCase().matches("AES") and
source.getNode().asExpr() = jcg and
dest.getNode().asExpr() = ma.getQualifier() and
kgConfig.hasFlowPath(source, dest)
) and
sink.asExpr() = ma.getArgument(0)
)
}
}
// ! below doesn't work for some reason...
// predicate hasInsufficientKeySize2(DataFlow::PathNode source, DataFlow::PathNode sink) {
// exists(AsymmetricKeyTrackingConfiguration config1 | config1.hasFlowPath(source, sink))
// or
// exists(SymmetricKeyTrackingConfiguration config2 | config2.hasFlowPath(source, sink))
// }
// ******** Need the below for the above ********
// ! move to Encryption.qll?
/** The Java class `java.security.spec.ECGenParameterSpec`. */
private class ECGenParameterSpec extends RefType {
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
}
/** The Java class `java.security.spec.ECGenParameterSpec`. */
private class RSAGenParameterSpec extends RefType {
RSAGenParameterSpec() { this.hasQualifiedName("java.security.spec", "RSAKeyGenParameterSpec") }
}
// ! move to Encryption.qll?
/** Returns the key size in the EC algorithm string */
bindingset[algorithm]
private int getECKeySize(string algorithm) {
algorithm.matches("sec%") and // specification such as "secp256r1"
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
or
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
or
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
}
// ! move to Encryption.qll?
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
private class KeyGeneratorInitMethod extends Method {
KeyGeneratorInitMethod() {
this.getDeclaringType() instanceof KeyGenerator and
this.hasName("init")
}
}
// ! move to Encryption.qll?
/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
private class KeyPairGeneratorInitMethod extends Method {
KeyPairGeneratorInitMethod() {
this.getDeclaringType() instanceof KeyPairGenerator and
this.hasName("initialize")
}
}
// ******* DATAFLOW ABOVE *************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ************************************************************************************************
// ******* OLD/UNUSED OR EXPERIMENTAL CODE BELOW **************************************************
class UnsafeSymmetricKeySize extends IntegerLiteral {
UnsafeSymmetricKeySize() { this.getIntValue() < 128 }
}
class UnsafeAsymmetricKeySize extends IntegerLiteral {
UnsafeAsymmetricKeySize() { this.getIntValue() < 2048 }
}
/** Taint configuration tracking flow from a key generator to a `init` method call. */
private class KeyGeneratorInitConfiguration extends TaintTracking::Configuration {
KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof JavaxCryptoKeyGenerator
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyGeneratorInitMethod and
sink.asExpr() = ma.getQualifier()
)
}
}
/**
* Taint configuration tracking flow from a keypair generator to
* an `initialize` method call.
*/
private class KeyPairGeneratorInitConfiguration extends TaintTracking::Configuration {
KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof JavaSecurityKeyPairGenerator
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
sink.asExpr() = ma.getQualifier()
)
}
}

View File

@@ -1,182 +0,0 @@
import semmle.code.java.security.Encryption
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.DataFlow3
/** The Java class `java.security.spec.ECGenParameterSpec`. */
private class ECGenParameterSpec extends RefType {
ECGenParameterSpec() { this.hasQualifiedName("java.security.spec", "ECGenParameterSpec") }
}
/** The `init` method declared in `javax.crypto.KeyGenerator`. */
private class KeyGeneratorInitMethod extends Method {
KeyGeneratorInitMethod() {
this.getDeclaringType() instanceof KeyGenerator and
this.hasName("init")
}
}
/** The `initialize` method declared in `java.security.KeyPairGenerator`. */
private class KeyPairGeneratorInitMethod extends Method {
KeyPairGeneratorInitMethod() {
this.getDeclaringType() instanceof KeyPairGenerator and
this.hasName("initialize")
}
}
/** Returns the key size in the EC algorithm string */
bindingset[algorithm]
private int getECKeySize(string algorithm) {
algorithm.matches("sec%") and // specification such as "secp256r1"
result = algorithm.regexpCapture("sec[p|t](\\d+)[a-zA-Z].*", 1).toInt()
or
algorithm.matches("X9.62%") and //specification such as "X9.62 prime192v2"
result = algorithm.regexpCapture("X9\\.62 .*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
or
(algorithm.matches("prime%") or algorithm.matches("c2tnb%")) and //specification such as "prime192v2"
result = algorithm.regexpCapture(".*[a-zA-Z](\\d+)[a-zA-Z].*", 1).toInt()
}
/** Taint configuration tracking flow from a key generator to a `init` method call. */
private class KeyGeneratorInitConfiguration extends TaintTracking::Configuration {
KeyGeneratorInitConfiguration() { this = "KeyGeneratorInitConfiguration" }
override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof JavaxCryptoKeyGenerator
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyGeneratorInitMethod and
sink.asExpr() = ma.getQualifier()
)
}
}
/**
* Taint configuration tracking flow from a keypair generator to
* an `initialize` method call.
*/
private class KeyPairGeneratorInitConfiguration extends TaintTracking::Configuration {
KeyPairGeneratorInitConfiguration() { this = "KeyPairGeneratorInitConfiguration" }
override predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof JavaSecurityKeyPairGenerator
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
sink.asExpr() = ma.getQualifier()
)
}
}
/**
* 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.
*/
bindingset[type]
private predicate hasShortSymmetricKey(MethodAccess ma, string msg, string type) {
ma.getMethod() instanceof KeyGeneratorInitMethod and
exists(
JavaxCryptoKeyGenerator jcg, KeyGeneratorInitConfiguration cc, DataFlow::PathNode source,
DataFlow::PathNode dest
|
jcg.getAlgoSpec().(StringLiteral).getValue() = type and
source.getNode().asExpr() = jcg and
dest.getNode().asExpr() = ma.getQualifier() and
//ma.getArgument(0) = var and // ! me
//var.getVariable().getInitializer().getUnderlyingExpr() instanceof IntegerLiteral and // ! me
cc.hasFlowPath(source, dest) //and
//var.getVariable().getInitializer().getUnderlyingExpr().toString().toInt() < 128 // ! me
) and
exists(VarAccess var |
var.getVariable().getInitializer().getUnderlyingExpr() instanceof IntegerLiteral and
var.getVariable().getInitializer().getUnderlyingExpr().toString().toInt() < 128 and
//DataFlow3::localExprFlow(var, ma.getArgument(0)) and
ma.getArgument(0) = var
//ma.getArgument(0).(IntegerLiteral).getIntValue() < 128
) and
msg = "Key size should be at least 128 bits for " + type + " encryption."
}
/**
* Holds if an AES `KeyGenerator` initialized by `ma` uses an insufficient key size.
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortAESKey(MethodAccess ma, string msg) {
hasShortSymmetricKey(ma, msg, "AES")
}
/**
* 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.
*/
bindingset[type]
private predicate hasShortAsymmetricKeyPair(MethodAccess ma, string msg, string type) {
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
exists(
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
DataFlow::PathNode source, DataFlow::PathNode dest
|
jpg.getAlgoSpec().(StringLiteral).getValue().toUpperCase() = type and
source.getNode().asExpr() = jpg and
dest.getNode().asExpr() = ma.getQualifier() and
kc.hasFlowPath(source, dest)
) and
ma.getArgument(0).(IntegerLiteral).getIntValue() < 2048 and
msg = "Key size should be at least 2048 bits for " + type + " encryption."
}
/**
* Holds if a DSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size.
*
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortDsaKeyPair(MethodAccess ma, string msg) {
hasShortAsymmetricKeyPair(ma, msg, "DSA") or
hasShortAsymmetricKeyPair(ma, msg, "DH")
}
/**
* Holds if a RSA `KeyPairGenerator` initialized by `ma` uses an insufficient key size.
*
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortRsaKeyPair(MethodAccess ma, string msg) {
hasShortAsymmetricKeyPair(ma, msg, "RSA")
}
/**
* Holds if an EC `KeyPairGenerator` initialized by `ma` uses an insufficient key size.
*
* `msg` provides a human-readable description of the problem.
*/
private predicate hasShortECKeyPair(MethodAccess ma, string msg) {
ma.getMethod() instanceof KeyPairGeneratorInitMethod and
exists(
JavaSecurityKeyPairGenerator jpg, KeyPairGeneratorInitConfiguration kc,
DataFlow::PathNode source, DataFlow::PathNode dest, ClassInstanceExpr cie
|
jpg.getAlgoSpec().(StringLiteral).getValue().matches("EC%") and // ECC variants such as ECDH and ECDSA
source.getNode().asExpr() = jpg and
dest.getNode().asExpr() = ma.getQualifier() and
kc.hasFlowPath(source, dest) and
DataFlow::localExprFlow(cie, ma.getArgument(0)) and
ma.getArgument(0).getType() instanceof ECGenParameterSpec and
getECKeySize(cie.getArgument(0).(StringLiteral).getValue()) < 256
) and
msg = "Key size should be at least 256 bits for EC encryption."
}
// ! refactor this so can use 'path-problem' select clause instead?
predicate hasInsufficientKeySize(Expr e, string msg) {
hasShortAESKey(e, msg) or
hasShortDsaKeyPair(e, msg) or
hasShortRsaKeyPair(e, msg) or
hasShortECKeyPair(e, msg)
}