mirror of
https://github.com/github/codeql.git
synced 2026-04-24 00:05:14 +02:00
Intermediate progress towards getting hashing upgraded. Still need to handle the final and update mechanics, matching the JCA. Similarly need to update cipher to follow the JCA for update/final as well.
This commit is contained in:
@@ -2,3 +2,4 @@ import OpenSSLAlgorithmInstanceBase
|
||||
import CipherAlgorithmInstance
|
||||
import PaddingAlgorithmInstance
|
||||
import BlockAlgorithmInstance
|
||||
import HashAlgorithmInstance
|
||||
|
||||
@@ -2,3 +2,4 @@ import OpenSSLAlgorithmValueConsumerBase
|
||||
import CipherAlgorithmValueConsumer
|
||||
import DirectAlgorithmValueConsumer
|
||||
import PaddingAlgorithmValueConsumer
|
||||
import HashAlgorithmValueConsumer
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import EVPCipherInitializer
|
||||
import EVPCipherOperation
|
||||
import EVPCipherAlgorithmSource
|
||||
|
||||
class EVP_Cipher_Initializer_Algorithm_Consumer extends Crypto::AlgorithmConsumer instanceof EVPCipherInitializerAlgorithmArgument
|
||||
{
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
result.(KnownOpenSSLCipherConstantAlgorithmInstance).getConsumer() = this
|
||||
}
|
||||
}
|
||||
|
||||
// //TODO: need a key consumer
|
||||
// class EVP_Initializer_Key_Consumer extends Crypto::KeyConsumer instanceof EVP_Cipher_Inititalizer isntanceof InitializerKeyArgument{
|
||||
// }
|
||||
class EVP_Cipher_Initializer_IV_Consumer extends Crypto::NonceArtifactConsumer instanceof EVPCipherInitializerIVArgument
|
||||
{
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
}
|
||||
|
||||
class EVP_Cipher_Input_Consumer extends Crypto::CipherInputConsumer instanceof EVPCipherInputArgument
|
||||
{
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
import cpp
|
||||
import experimental.Quantum.Language
|
||||
import OpenSSLAlgorithmGetter
|
||||
|
||||
predicate knownOpenSSLConstantToHashFamilyType(KnownOpenSSLAlgorithmConstant e, Crypto::THashType type) {
|
||||
exists(string name | e.getAlgType().toLowerCase().matches("hash") |
|
||||
name = e.getNormalizedName() and
|
||||
(
|
||||
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
|
||||
or
|
||||
name.matches("BLAKE2S") and type instanceof Crypto::BLAKE2S
|
||||
or
|
||||
name.matches("GOST%") and type instanceof Crypto::GOSTHash
|
||||
or
|
||||
name.matches("MD2") and type instanceof Crypto::MD2
|
||||
or
|
||||
name.matches("MD4") and type instanceof Crypto::MD4
|
||||
or
|
||||
name.matches("MD5") and type instanceof Crypto::MD5
|
||||
or
|
||||
name.matches("MDC2") and type instanceof Crypto::MDC2
|
||||
or
|
||||
name.matches("POLY1305") and type instanceof Crypto::POLY1305
|
||||
or
|
||||
name.matches(["SHA", "SHA1"]) and type instanceof Crypto::SHA1
|
||||
or
|
||||
name.matches("SHA+%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
|
||||
or
|
||||
name.matches("SHA3-%") and type instanceof Crypto::SHA3
|
||||
or
|
||||
name.matches(["SHAKE"]) and type instanceof Crypto::SHAKE
|
||||
or
|
||||
name.matches("SM3") and type instanceof Crypto::SM3
|
||||
or
|
||||
name.matches("RIPEMD160") and type instanceof Crypto::RIPEMD160
|
||||
or
|
||||
name.matches("WHIRLPOOL") and type instanceof Crypto::WHIRLPOOL
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSSLHashConstantAlgorithmInstance extends Crypto::HashAlgorithmInstance instanceof KnownOpenSSLAlgorithmConstant
|
||||
{
|
||||
OpenSSLAlgorithmGetterCall getterCall;
|
||||
|
||||
KnownOpenSSLHashConstantAlgorithmInstance() {
|
||||
// Not just any known value, but specifically a known hash
|
||||
this.(KnownOpenSSLAlgorithmConstant).getAlgType().toLowerCase().matches("hash") and
|
||||
(
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof Literal and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.(OpenSSLAlgorithmGetterCall).getValueArgNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSSLAlgorithmToAlgorithmGetterFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof DirectGetterCall and getterCall = this
|
||||
)
|
||||
}
|
||||
|
||||
Crypto::AlgorithmConsumer getConsumer() {
|
||||
AlgGetterToAlgConsumerFlow::flow(getterCall.getResultNode(), DataFlow::exprNode(result))
|
||||
}
|
||||
|
||||
override Crypto::THashType getHashFamily() {
|
||||
knownOpenSSLConstantToHashFamilyType(this, result) or
|
||||
not knownOpenSSLConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
|
||||
}
|
||||
|
||||
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
|
||||
|
||||
// override int getHashSize() { none() } //TODO
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import EVPHashInitializer
|
||||
import EVPHashOperation
|
||||
import EVPHashAlgorithmSource
|
||||
|
||||
class EVP_Digest_Initializer_Algorithm_Consumer extends Crypto::AlgorithmValueConsumer instanceof EVPDigestInitializerAlgorithmArgument
|
||||
{
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
result.(KnownOpenSSLHashConstantAlgorithmInstance).getConsumer() = this
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Q_Digest_Algorithm_Consumer extends Crypto::AlgorithmValueConsumer instanceof EVP_Q_Digest_Algorithm_Argument
|
||||
{
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
result.(KnownOpenSSLHashConstantAlgorithmInstance).getConsumer() = this
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Digest_Algorithm_Consumer extends Crypto::AlgorithmValueConsumer instanceof EVP_Digest_Algorithm_Argument
|
||||
{
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
result.(KnownOpenSSLHashConstantAlgorithmInstance).getConsumer() = this
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import cpp
|
||||
|
||||
abstract class EVP_Hash_Inititalizer extends Call {
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
abstract Expr getAlgorithmArg();
|
||||
}
|
||||
|
||||
class EVP_DigestInit_Variant_Calls extends EVP_Hash_Inititalizer {
|
||||
EVP_DigestInit_Variant_Calls() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_DigestInit", "EVP_DigestInit_ex", "EVP_DigestInit_ex2"
|
||||
]
|
||||
}
|
||||
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
}
|
||||
|
||||
|
||||
class EVPDigestInitializerAlgorithmArgument extends Expr {
|
||||
EVPDigestInitializerAlgorithmArgument() {
|
||||
exists(EVP_Hash_Inititalizer initCall | this = initCall.getAlgorithmArg())
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
import experimental.Quantum.Language
|
||||
import CtxFlow as CTXFlow
|
||||
import LibraryDetector
|
||||
import EVPHashInitializer
|
||||
import EVPHashConsumers
|
||||
|
||||
abstract class EVP_Hash_Operation extends Crypto::HashOperationInstance instanceof Call {
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
EVP_Hash_Inititalizer getInitCall() {
|
||||
CTXFlow::ctxFlowsTo(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
}
|
||||
|
||||
//https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
|
||||
class EVP_Q_Digest_Operation extends EVP_Hash_Operation {
|
||||
EVP_Q_Digest_Operation() {
|
||||
this.(Call).getTarget().getName() = "EVP_Q_digest" and
|
||||
isPossibleOpenSSLFunction(this.(Call).getTarget())
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmConsumer getAlgorithmConsumer() { this.(Call).getArgument(1) = result }
|
||||
|
||||
override EVP_Hash_Inititalizer getInitCall() {
|
||||
// This variant of digest does not use an init
|
||||
// and even if it were used, the init would be ignored/undefined
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Q_Digest_Algorithm_Argument extends Expr {
|
||||
EVP_Q_Digest_Algorithm_Argument() {
|
||||
exists(EVP_Q_Digest_Operation op | this = op.(Call).getArgument(1))
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Digest_Operation extends EVP_Hash_Operation {
|
||||
EVP_Digest_Operation() {
|
||||
this.(Call).getTarget().getName() = "EVP_Digest" and
|
||||
isPossibleOpenSSLFunction(this.(Call).getTarget())
|
||||
}
|
||||
|
||||
// There is no context argument for this function
|
||||
override Expr getContextArg() { none() }
|
||||
|
||||
override Crypto::AlgorithmConsumer getAlgorithmConsumer() { this.(Call).getArgument(4) = result }
|
||||
|
||||
override EVP_Hash_Inititalizer getInitCall() {
|
||||
// This variant of digest does not use an init
|
||||
// and even if it were used, the init would be ignored/undefined
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Digest_Algorithm_Argument extends Expr {
|
||||
EVP_Digest_Algorithm_Argument() {
|
||||
exists(EVP_Digest_Operation op | this = op.(Call).getArgument(4))
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_DigestUpdate_Operation extends EVP_Hash_Operation {
|
||||
EVP_DigestUpdate_Operation() {
|
||||
this.(Call).getTarget().getName() = "EVP_DigestUpdate" and
|
||||
isPossibleOpenSSLFunction(this.(Call).getTarget())
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmConsumer getAlgorithmConsumer() {
|
||||
this.getInitCall().getAlgorithmArg() = result
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_DigestFinal_Variants_Operation extends EVP_Hash_Operation {
|
||||
EVP_DigestFinal_Variants_Operation() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_DigestFinal", "EVP_DigestFinal_ex", "EVP_DigestFinalXOF"
|
||||
] and
|
||||
isPossibleOpenSSLFunction(this.(Call).getTarget())
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmConsumer getAlgorithmConsumer() {
|
||||
this.getInitCall().getAlgorithmArg() = result
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,7 @@ import EVPCipherInitializer
|
||||
import OpenSSLOperationBase
|
||||
import experimental.Quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
|
||||
// import experimental.Quantum.OpenSSL.AlgorithmValueConsumers.AlgorithmValueConsumers
|
||||
// import OpenSSLOperation
|
||||
module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source)
|
||||
}
|
||||
@@ -16,8 +14,10 @@ module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
}
|
||||
|
||||
module AlgGetterToAlgConsumerFlow = DataFlow::Global<AlgGetterToAlgConsumerConfig>;
|
||||
private module AlgGetterToAlgConsumerFlow = DataFlow::Global<AlgGetterToAlgConsumerConfig>;
|
||||
|
||||
// import experimental.Quantum.OpenSSL.AlgorithmValueConsumers.AlgorithmValueConsumers
|
||||
// import OpenSSLOperation
|
||||
// class EVPCipherOutput extends CipherOutputArtifact {
|
||||
// EVPCipherOutput() { exists(EVP_Cipher_Operation op | op.getOutputArg() = this) }
|
||||
// override DataFlow::Node getOutputNode() { result.asDefiningArgument() = this }
|
||||
@@ -81,6 +81,8 @@ class EVP_Cipher_Call extends EVP_Cipher_Operation {
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(2) }
|
||||
}
|
||||
|
||||
// ******* TODO NEED to model UPDATE but not as the coree operation, rather a step towards final,
|
||||
// see the JCA
|
||||
// class EVP_Encrypt_Decrypt_or_Cipher_Update_Call extends EVP_Update_Call {
|
||||
// EVP_Encrypt_Decrypt_or_Cipher_Update_Call() {
|
||||
// this.(Call).getTarget().getName() in [
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
import OpenSSLOperationBase
|
||||
import EVPCipherOperation
|
||||
import EVPHashOperation
|
||||
|
||||
Reference in New Issue
Block a user