mirror of
https://github.com/github/codeql.git
synced 2025-12-21 11:16:30 +01:00
python: implement getBlockMode for CryptographicOperations
This commit is contained in:
@@ -1226,6 +1226,13 @@ module Cryptography {
|
|||||||
|
|
||||||
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
||||||
DataFlow::Node getAnInput() { result = super.getAnInput() }
|
DataFlow::Node getAnInput() { result = super.getAnInput() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block mode used to perform this cryptographic operation.
|
||||||
|
* This may have no result - for example if the `CryptographicAlgorithm` used
|
||||||
|
* is a stream cipher rather than a block cipher.
|
||||||
|
*/
|
||||||
|
BlockMode getBlockMode() { result = super.getBlockMode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Provides classes for modeling new applications of a cryptographic algorithms. */
|
/** Provides classes for modeling new applications of a cryptographic algorithms. */
|
||||||
@@ -1243,6 +1250,24 @@ module Cryptography {
|
|||||||
|
|
||||||
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
||||||
abstract DataFlow::Node getAnInput();
|
abstract DataFlow::Node getAnInput();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block mode used to perform this cryptographic operation.
|
||||||
|
* This may have no result - for example if the `CryptographicAlgorithm` used
|
||||||
|
* is a stream cipher rather than a block cipher.
|
||||||
|
*/
|
||||||
|
abstract BlockMode getBlockMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cryptographic block cipher mode of operation. This can be used to encrypt
|
||||||
|
* data of arbitrary length using a block encryption algorithm.
|
||||||
|
*/
|
||||||
|
class BlockMode extends string {
|
||||||
|
BlockMode() { this = ["ECB", "CBC", "GCM", "CCM", "CFB", "OFB", "CTR", "OPENPGP"] }
|
||||||
|
|
||||||
|
/** Holds if this block mode is considered to be insecure. */
|
||||||
|
predicate isWeak() { this = "ECB" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,20 +108,20 @@ private module CryptodomeModel {
|
|||||||
DataFlow::CallCfgNode {
|
DataFlow::CallCfgNode {
|
||||||
string methodName;
|
string methodName;
|
||||||
string cipherName;
|
string cipherName;
|
||||||
|
API::CallNode newCall;
|
||||||
|
|
||||||
CryptodomeGenericCipherOperation() {
|
CryptodomeGenericCipherOperation() {
|
||||||
methodName in [
|
methodName in [
|
||||||
"encrypt", "decrypt", "verify", "update", "hexverify", "encrypt_and_digest",
|
"encrypt", "decrypt", "verify", "update", "hexverify", "encrypt_and_digest",
|
||||||
"decrypt_and_verify"
|
"decrypt_and_verify"
|
||||||
] and
|
] and
|
||||||
this =
|
newCall =
|
||||||
API::moduleImport(["Crypto", "Cryptodome"])
|
API::moduleImport(["Crypto", "Cryptodome"])
|
||||||
.getMember("Cipher")
|
.getMember("Cipher")
|
||||||
.getMember(cipherName)
|
.getMember(cipherName)
|
||||||
.getMember("new")
|
.getMember("new")
|
||||||
.getReturn()
|
.getACall() and
|
||||||
.getMember(methodName)
|
this = newCall.getReturn().getMember(methodName).getACall()
|
||||||
.getACall()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(cipherName) }
|
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(cipherName) }
|
||||||
@@ -155,6 +155,20 @@ private module CryptodomeModel {
|
|||||||
this.getArgByName("mac_tag")
|
this.getArgByName("mac_tag")
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() {
|
||||||
|
// `modeName` is of the form "MODE_<BlockMode>"
|
||||||
|
exists(string modeName |
|
||||||
|
newCall.getArg(1) =
|
||||||
|
API::moduleImport(["Crypto", "Cryptodome"])
|
||||||
|
.getMember("Cipher")
|
||||||
|
.getMember(cipherName)
|
||||||
|
.getMember(modeName)
|
||||||
|
.getAUse()
|
||||||
|
|
|
||||||
|
result = modeName.splitAt("_", 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -192,6 +206,8 @@ private module CryptodomeModel {
|
|||||||
result in [this.getArg(1), this.getArgByName("signature")]
|
result in [this.getArg(1), this.getArgByName("signature")]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,5 +231,7 @@ private module CryptodomeModel {
|
|||||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,8 +170,19 @@ private module CryptographyModel {
|
|||||||
.getMember(algorithmName)
|
.getMember(algorithmName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets a reference to a `cryptography.hazmat.primitives.ciphers.modes` Class */
|
||||||
|
API::Node modeClassRef(string modeName) {
|
||||||
|
result =
|
||||||
|
API::moduleImport("cryptography")
|
||||||
|
.getMember("hazmat")
|
||||||
|
.getMember("primitives")
|
||||||
|
.getMember("ciphers")
|
||||||
|
.getMember("modes")
|
||||||
|
.getMember(modeName)
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets a reference to a Cipher instance using algorithm with `algorithmName`. */
|
/** Gets a reference to a Cipher instance using algorithm with `algorithmName`. */
|
||||||
API::Node cipherInstance(string algorithmName) {
|
API::Node cipherInstance(string algorithmName, string modeName) {
|
||||||
exists(API::CallNode call | result = call.getReturn() |
|
exists(API::CallNode call | result = call.getReturn() |
|
||||||
call =
|
call =
|
||||||
API::moduleImport("cryptography")
|
API::moduleImport("cryptography")
|
||||||
@@ -182,7 +193,12 @@ private module CryptographyModel {
|
|||||||
.getACall() and
|
.getACall() and
|
||||||
algorithmClassRef(algorithmName).getReturn().getAUse() in [
|
algorithmClassRef(algorithmName).getReturn().getAUse() in [
|
||||||
call.getArg(0), call.getArgByName("algorithm")
|
call.getArg(0), call.getArgByName("algorithm")
|
||||||
]
|
] and
|
||||||
|
exists(DataFlow::Node modeArg | modeArg in [call.getArg(1), call.getArgByName("mode")] |
|
||||||
|
modeArg = modeClassRef(modeName).getReturn().getAUse()
|
||||||
|
or
|
||||||
|
modeArg.asExpr() instanceof None and modeName = "<none>"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,10 +208,11 @@ private module CryptographyModel {
|
|||||||
class CryptographyGenericCipherOperation extends Cryptography::CryptographicOperation::Range,
|
class CryptographyGenericCipherOperation extends Cryptography::CryptographicOperation::Range,
|
||||||
DataFlow::MethodCallNode {
|
DataFlow::MethodCallNode {
|
||||||
string algorithmName;
|
string algorithmName;
|
||||||
|
string modeName;
|
||||||
|
|
||||||
CryptographyGenericCipherOperation() {
|
CryptographyGenericCipherOperation() {
|
||||||
this =
|
this =
|
||||||
cipherInstance(algorithmName)
|
cipherInstance(algorithmName, modeName)
|
||||||
.getMember(["decryptor", "encryptor"])
|
.getMember(["decryptor", "encryptor"])
|
||||||
.getReturn()
|
.getReturn()
|
||||||
.getMember(["update", "update_into"])
|
.getMember(["update", "update_into"])
|
||||||
@@ -207,6 +224,8 @@ private module CryptographyModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { result = modeName }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,6 +276,8 @@ private module CryptographyModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ private module Rsa {
|
|||||||
override DataFlow::Node getAnInput() {
|
override DataFlow::Node getAnInput() {
|
||||||
result in [this.getArg(0), this.getArgByName("message")]
|
result in [this.getArg(0), this.getArgByName("message")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,6 +56,8 @@ private module Rsa {
|
|||||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
|
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("crypto")] }
|
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("crypto")] }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,6 +83,8 @@ private module Rsa {
|
|||||||
override DataFlow::Node getAnInput() {
|
override DataFlow::Node getAnInput() {
|
||||||
result in [this.getArg(0), this.getArgByName("message")]
|
result in [this.getArg(0), this.getArgByName("message")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,6 +106,8 @@ private module Rsa {
|
|||||||
or
|
or
|
||||||
result in [this.getArg(1), this.getArgByName("signature")]
|
result in [this.getArg(1), this.getArgByName("signature")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,6 +130,8 @@ private module Rsa {
|
|||||||
override DataFlow::Node getAnInput() {
|
override DataFlow::Node getAnInput() {
|
||||||
result in [this.getArg(0), this.getArgByName("message")]
|
result in [this.getArg(0), this.getArgByName("message")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,5 +147,7 @@ private module Rsa {
|
|||||||
override DataFlow::Node getAnInput() {
|
override DataFlow::Node getAnInput() {
|
||||||
result in [this.getArg(0), this.getArgByName("hash_value")]
|
result in [this.getArg(0), this.getArgByName("hash_value")]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2671,6 +2671,8 @@ private module StdlibPrivate {
|
|||||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").getARhs() }
|
override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").getARhs() }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2686,6 +2688,8 @@ private module StdlibPrivate {
|
|||||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||||
|
|
||||||
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper predicate for the `HashLibGenericHashOperation` charpred, to prevent a bad join order. */
|
/** Helper predicate for the `HashLibGenericHashOperation` charpred, to prevent a bad join order. */
|
||||||
@@ -2709,6 +2713,8 @@ private module StdlibPrivate {
|
|||||||
HashlibGenericHashOperation() { hashClass = hashlibMember(hashName) }
|
HashlibGenericHashOperation() { hashClass = hashlibMember(hashName) }
|
||||||
|
|
||||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||||
|
|
||||||
|
override Cryptography::BlockMode getBlockMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user