mirror of
https://github.com/github/codeql.git
synced 2026-04-12 18:44:00 +02:00
182 lines
6.7 KiB
Plaintext
182 lines
6.7 KiB
Plaintext
import cpp
|
|
import experimental.Quantum.Language
|
|
import EVPCipherConsumers
|
|
import OpenSSLAlgorithmGetter
|
|
|
|
/**
|
|
* Given a `KnownOpenSSLAlgorithmConstant`, converts this to a cipher family type.
|
|
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
|
|
*/
|
|
predicate knownOpenSSLConstantToCipherFamilyType(
|
|
KnownOpenSSLAlgorithmConstant e, Crypto::TCipherType type
|
|
) {
|
|
exists(string name | e.getAlgType().toLowerCase().matches("%encryption") |
|
|
name = e.getNormalizedName() and
|
|
(
|
|
name.matches("AES%") and type instanceof Crypto::AES
|
|
or
|
|
name.matches("ARIA") and type instanceof Crypto::ARIA
|
|
or
|
|
name.matches("BLOWFISH") and type instanceof Crypto::BLOWFISH
|
|
or
|
|
name.matches("BF") and type instanceof Crypto::BLOWFISH
|
|
or
|
|
name.matches("CAMELLIA%") and type instanceof Crypto::CAMELLIA
|
|
or
|
|
name.matches("CHACHA20") and type instanceof Crypto::CHACHA20
|
|
or
|
|
name.matches("CAST5") and type instanceof Crypto::CAST5
|
|
or
|
|
name.matches("2DES") and type instanceof Crypto::DoubleDES
|
|
or
|
|
name.matches(["3DES", "TRIPLEDES"]) and type instanceof Crypto::TripleDES
|
|
or
|
|
name.matches("DES") and type instanceof Crypto::DES
|
|
or
|
|
name.matches("DESX") and type instanceof Crypto::DESX
|
|
or
|
|
name.matches("GOST%") and type instanceof Crypto::GOST
|
|
or
|
|
name.matches("IDEA") and type instanceof Crypto::IDEA
|
|
or
|
|
name.matches("KUZNYECHIK") and type instanceof Crypto::KUZNYECHIK
|
|
or
|
|
name.matches("MAGMA") and type instanceof Crypto::MAGMA
|
|
or
|
|
name.matches("RC2") and type instanceof Crypto::RC2
|
|
or
|
|
name.matches("RC4") and type instanceof Crypto::RC4
|
|
or
|
|
name.matches("RC5") and type instanceof Crypto::RC5
|
|
or
|
|
name.matches("RSA") and type instanceof Crypto::RSA
|
|
or
|
|
name.matches("SEED") and type instanceof Crypto::SEED
|
|
or
|
|
name.matches("SM4") and type instanceof Crypto::SM4
|
|
)
|
|
)
|
|
}
|
|
|
|
class KnownOpenSSLCipherConstantAlgorithmInstance extends Crypto::CipherAlgorithmInstance instanceof KnownOpenSSLAlgorithmConstant
|
|
{
|
|
OpenSSLAlgorithmGetterCall getterCall;
|
|
|
|
KnownOpenSSLCipherConstantAlgorithmInstance() {
|
|
// Not just any known value, but specifically a known cipher operation
|
|
this.(KnownOpenSSLAlgorithmConstant).getAlgType().toLowerCase().matches("%encryption") 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::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
|
|
// if there is a block mode associated with the same element, then that's the block mode
|
|
// note, if none are associated, we may need to parse if the cipher is a block cipher
|
|
// to determine if this is an unknown vs not relevant.
|
|
result = this
|
|
}
|
|
|
|
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
|
|
|
|
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
|
|
|
|
override Crypto::TCipherType getCipherFamily() {
|
|
knownOpenSSLConstantToCipherFamilyType(this, result)
|
|
or
|
|
not knownOpenSSLConstantToCipherFamilyType(this, _) and result = Crypto::OtherCipherType()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Given a `KnownOpenSSLAlgorithmConstant`, converts this to a cipher family type.
|
|
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
|
|
*/
|
|
predicate knownOpenSSLConstantToBlockModeFamilyType(
|
|
KnownOpenSSLAlgorithmConstant e, Crypto::TBlockCipherModeOperationType type
|
|
) {
|
|
exists(string name | e.getAlgType().toLowerCase().matches("block_mode") |
|
|
name = e.getNormalizedName() and
|
|
(
|
|
name.matches("CBC") and type instanceof Crypto::CBC
|
|
or
|
|
name.matches("CFB%") and type instanceof Crypto::CFB
|
|
or
|
|
name.matches("CTR") and type instanceof Crypto::CTR
|
|
or
|
|
name.matches("GCM") and type instanceof Crypto::GCM
|
|
or
|
|
name.matches("OFB") and type instanceof Crypto::OFB
|
|
or
|
|
name.matches("XTS") and type instanceof Crypto::XTS
|
|
or
|
|
name.matches("CCM") and type instanceof Crypto::CCM
|
|
or
|
|
name.matches("GCM") and type instanceof Crypto::GCM
|
|
or
|
|
name.matches("CCM") and type instanceof Crypto::CCM
|
|
or
|
|
name.matches("ECB") and type instanceof Crypto::ECB
|
|
)
|
|
)
|
|
}
|
|
|
|
class KnownOpenSSLBlockModeConstantAlgorithmInstance extends Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLAlgorithmConstant
|
|
{
|
|
OpenSSLAlgorithmGetterCall getterCall;
|
|
|
|
KnownOpenSSLBlockModeConstantAlgorithmInstance() {
|
|
// Not just any known value, but specifically a known cipher operation
|
|
this.(KnownOpenSSLAlgorithmConstant).getAlgType().toLowerCase().matches("block_mode") 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
|
|
)
|
|
}
|
|
|
|
override Crypto::TBlockCipherModeOperationType getModeType() {
|
|
knownOpenSSLConstantToBlockModeFamilyType(this, result)
|
|
or
|
|
not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
|
|
}
|
|
|
|
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
|
|
// the same as the raw name for now.
|
|
override string getRawModeAlgorithmName() { result = this.(Literal).getValue().toString() }
|
|
|
|
override string getRawAlgorithmName() { result = this.getRawModeAlgorithmName() }
|
|
}
|