Merge pull request #11192 from jcogs33/jcogs33/share-key-sizes

Share encryption key sizes between Java and Python
This commit is contained in:
Jami
2022-12-07 08:08:24 -05:00
committed by GitHub
9 changed files with 100 additions and 21 deletions

View File

@@ -580,5 +580,9 @@
"IncompleteMultiCharacterSanitization JS/Ruby": [
"javascript/ql/lib/semmle/javascript/security/IncompleteMultiCharacterSanitizationQuery.qll",
"ruby/ql/lib/codeql/ruby/security/IncompleteMultiCharacterSanitizationQuery.qll"
],
"EncryptionKeySizes Python/Java": [
"python/ql/lib/semmle/python/security/internal/EncryptionKeySizes.qll",
"java/ql/lib/semmle/code/java/security/internal/EncryptionKeySizes.qll"
]
}

View File

@@ -2,6 +2,7 @@
private import semmle.code.java.security.Encryption
private import semmle.code.java.dataflow.DataFlow
private import semmle.code.java.security.internal.EncryptionKeySizes
/** A source for an insufficient key size. */
abstract class InsufficientKeySizeSource extends DataFlow::Node {
@@ -21,39 +22,67 @@ private module Asymmetric {
private module NonEllipticCurve {
/** A source for an insufficient key size used in RSA, DSA, and DH algorithms. */
private class Source extends InsufficientKeySizeSource {
Source() { this.asExpr().(IntegerLiteral).getIntValue() < getMinKeySize() }
string algoName;
override predicate hasState(DataFlow::FlowState state) { state = getMinKeySize().toString() }
Source() { this.asExpr().(IntegerLiteral).getIntValue() < getMinKeySize(algoName) }
override predicate hasState(DataFlow::FlowState state) {
state = getMinKeySize(algoName).toString()
}
}
/** A sink for an insufficient key size used in RSA, DSA, and DH algorithms. */
private class Sink extends InsufficientKeySizeSink {
string algoName;
Sink() {
exists(KeyPairGenInit kpgInit, KeyPairGen kpg |
kpg.getAlgoName().matches(["RSA", "DSA", "DH"]) and
algoName in ["RSA", "DSA", "DH"] and
kpg.getAlgoName() = algoName and
DataFlow::localExprFlow(kpg, kpgInit.getQualifier()) and
this.asExpr() = kpgInit.getKeySizeArg()
)
or
exists(Spec spec | this.asExpr() = spec.getKeySizeArg())
exists(Spec spec | this.asExpr() = spec.getKeySizeArg() and algoName = spec.getAlgoName())
}
override predicate hasState(DataFlow::FlowState state) { state = getMinKeySize().toString() }
override predicate hasState(DataFlow::FlowState state) {
state = getMinKeySize(algoName).toString()
}
}
/** Returns the minimum recommended key size for RSA, DSA, and DH algorithms. */
private int getMinKeySize() { result = 2048 }
private int getMinKeySize(string algoName) {
algoName = "RSA" and
result = minSecureKeySizeRsa()
or
algoName = "DSA" and
result = minSecureKeySizeDsa()
or
algoName = "DH" and
result = minSecureKeySizeDh()
}
/** An instance of an RSA, DSA, or DH algorithm specification. */
private class Spec extends ClassInstanceExpr {
string algoName;
Spec() {
this.getConstructedType() instanceof RsaKeyGenParameterSpec or
this.getConstructedType() instanceof DsaGenParameterSpec or
this.getConstructedType() instanceof DhGenParameterSpec
this.getConstructedType() instanceof RsaKeyGenParameterSpec and
algoName = "RSA"
or
this.getConstructedType() instanceof DsaGenParameterSpec and
algoName = "DSA"
or
this.getConstructedType() instanceof DhGenParameterSpec and
algoName = "DH"
}
/** Gets the `keysize` argument of this instance. */
Argument getKeySizeArg() { result = this.getArgument(0) }
/** Gets the algorithm name of this spec. */
string getAlgoName() { result = algoName }
}
}
@@ -87,7 +116,7 @@ private module Asymmetric {
}
/** Returns the minimum recommended key size for elliptic curve (EC) algorithms. */
private int getMinKeySize() { result = 256 }
private int getMinKeySize() { result = minSecureKeySizeEcc() }
/** Returns the key size from an EC algorithm's curve name string */
bindingset[algorithm]
@@ -168,7 +197,7 @@ private module Symmetric {
}
/** Returns the minimum recommended key size for AES algorithms. */
private int getMinKeySize() { result = 128 }
private int getMinKeySize() { result = minSecureKeySizeAes() }
/** A call to the `init` method declared in `javax.crypto.KeyGenerator`. */
private class KeyGenInit extends MethodAccess {

View File

@@ -0,0 +1,21 @@
/**
* INTERNAL: Do not use.
*
* Provides predicates for recommended encryption key sizes.
* Such that we can share this logic across our CodeQL analysis of different languages.
*/
/** Returns the minimum recommended key size for RSA. */
int minSecureKeySizeRsa() { result = 2048 }
/** Returns the minimum recommended key size for DSA. */
int minSecureKeySizeDsa() { result = 2048 }
/** Returns the minimum recommended key size for DH. */
int minSecureKeySizeDh() { result = 2048 }
/** Returns the minimum recommended key size for elliptic curve cryptography. */
int minSecureKeySizeEcc() { result = 256 }
/** Returns the minimum recommended key size for AES. */
int minSecureKeySizeAes() { result = 128 }

View File

@@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.RemoteFlowSources
private import semmle.python.dataflow.new.TaintTracking
private import semmle.python.Frameworks
private import semmle.python.security.internal.EncryptionKeySizes
/**
* A data-flow node that executes an operating system command,
@@ -1141,21 +1142,21 @@ module Cryptography {
abstract class RsaRange extends Range {
final override string getName() { result = "RSA" }
final override int minimumSecureKeySize() { result = 2048 }
final override int minimumSecureKeySize() { result = minSecureKeySizeRsa() }
}
/** A data-flow node that generates a new DSA key-pair. */
abstract class DsaRange extends Range {
final override string getName() { result = "DSA" }
final override int minimumSecureKeySize() { result = 2048 }
final override int minimumSecureKeySize() { result = minSecureKeySizeDsa() }
}
/** A data-flow node that generates a new ECC key-pair. */
abstract class EccRange extends Range {
final override string getName() { result = "ECC" }
final override int minimumSecureKeySize() { result = 224 }
final override int minimumSecureKeySize() { result = minSecureKeySizeEcc() }
}
}
}

View File

@@ -0,0 +1,21 @@
/**
* INTERNAL: Do not use.
*
* Provides predicates for recommended encryption key sizes.
* Such that we can share this logic across our CodeQL analysis of different languages.
*/
/** Returns the minimum recommended key size for RSA. */
int minSecureKeySizeRsa() { result = 2048 }
/** Returns the minimum recommended key size for DSA. */
int minSecureKeySizeDsa() { result = 2048 }
/** Returns the minimum recommended key size for DH. */
int minSecureKeySizeDh() { result = 2048 }
/** Returns the minimum recommended key size for elliptic curve cryptography. */
int minSecureKeySizeEcc() { result = 256 }
/** Returns the minimum recommended key size for AES. */
int minSecureKeySizeAes() { result = 128 }

View File

@@ -11,13 +11,13 @@ As computational power increases, the ability to break ciphers grows and keys ne
<p>
The three main asymmetric key algorithms currently in use are RivestShamirAdleman (RSA) cryptography, Digital Signature Algorithm (DSA), and Elliptic-curve cryptography (ECC).
With current technology, key sizes of 2048 bits for RSA and DSA,
or 224 bits for ECC, are regarded as unbreakable.
or 256 bits for ECC, are regarded as unbreakable.
</p>
</overview>
<recommendation>
<p>
Increase the key size to the recommended amount or larger. For RSA or DSA this is at least 2048 bits, for ECC this is at least 224 bits.
Increase the key size to the recommended amount or larger. For RSA or DSA this is at least 2048 bits, for ECC this is at least 256 bits.
</p>
</recommendation>
@@ -45,4 +45,3 @@ Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Len
</li>
</references>
</qhelp>

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Bumped the minimum keysize we consider secure for elliptic curve cryptography from 224 to 256 bits, following current best practices. This might effect results from the _Use of weak cryptographic key_ (`py/weak-crypto-key`) query.

View File

@@ -1,8 +1,8 @@
| weak_crypto.py:68:1:68:21 | ControlFlowNode for dsa_gen_key() | Creation of an DSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:16:12:16:15 | ControlFlowNode for IntegerLiteral | 1024 |
| weak_crypto.py:69:1:69:19 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 224 and considered breakable. | weak_crypto.py:22:11:22:22 | ControlFlowNode for Attribute | 163 |
| weak_crypto.py:69:1:69:19 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 256 and considered breakable. | weak_crypto.py:22:11:22:22 | ControlFlowNode for Attribute | 224 |
| weak_crypto.py:70:1:70:28 | ControlFlowNode for rsa_gen_key() | Creation of an RSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:12:12:12:15 | ControlFlowNode for IntegerLiteral | 1024 |
| weak_crypto.py:72:1:72:30 | ControlFlowNode for dsa_gen_key() | Creation of an DSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:16:12:16:15 | ControlFlowNode for IntegerLiteral | 1024 |
| weak_crypto.py:73:1:73:25 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 224 and considered breakable. | weak_crypto.py:22:11:22:22 | ControlFlowNode for Attribute | 163 |
| weak_crypto.py:73:1:73:25 | ControlFlowNode for ec_gen_key() | Creation of an ECC key uses $@ bits, which is below 256 and considered breakable. | weak_crypto.py:22:11:22:22 | ControlFlowNode for Attribute | 224 |
| weak_crypto.py:74:1:74:37 | ControlFlowNode for rsa_gen_key() | Creation of an RSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:12:12:12:15 | ControlFlowNode for IntegerLiteral | 1024 |
| weak_crypto.py:76:1:76:22 | ControlFlowNode for Attribute() | Creation of an DSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:16:12:16:15 | ControlFlowNode for IntegerLiteral | 1024 |
| weak_crypto.py:77:1:77:22 | ControlFlowNode for Attribute() | Creation of an RSA key uses $@ bits, which is below 2048 and considered breakable. | weak_crypto.py:12:12:12:15 | ControlFlowNode for IntegerLiteral | 1024 |

View File

@@ -19,8 +19,8 @@ DSA_STRONG = 3076
BIG = 10000
EC_WEAK = ec.SECT163K1() # has key size of 163
EC_OK = ec.SECP224R1()
EC_WEAK = ec.SECP224R1()
EC_OK = ec.SECP256R1()
EC_STRONG = ec.SECP384R1()
EC_BIG = ec.SECT571R1()