Files
codeql/cpp/ql/lib/experimental/Quantum/OpenSSL/EVPCipherAlgorithmSource.qll

102 lines
3.7 KiB
Plaintext

import cpp
import experimental.Quantum.Language
import EVPCipherConsumers
import OpenSSLAlgorithmGetter
/**
* Given a literal `e`, converts this to a cipher family type.
* The literal must be a known literal representing a cipher algorithm.
* If the literal does not represent any known cipher algorithm,
* this predicate will not hold (i.e., it will not bind an unknown to an unknown cipher type)
*/
predicate literalToCipherFamilyType(Literal e, Crypto::TCipherType type) {
exists(string name, string algType | algType.toLowerCase().matches("%encryption") |
resolveAlgorithmFromLiteral(e, name, algType) 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() {
none() // TODO: provider defaults
}
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
override Crypto::TCipherType getCipherFamily() { literalToCipherFamilyType(this, result) }
}