Files
codeql/cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPPKeyCtxInitializer.qll

206 lines
6.6 KiB
Plaintext

/**
* Initializers for EVP PKey
* These are used to create a Pkey context or set properties on a Pkey context
* e.g., key size, hash algorithms, curves, padding schemes, etc.
* Meant to capture more general purpose initializers that aren't necessarily
* tied to a specific operation. If tied to an operation (i.e., in the docs)
* we recommend defining defining all together in the same operation definition qll.
* including:
* https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/
* https://docs.openssl.org/3.0/man3/EVP_EncryptInit/#synopsis
*/
import cpp
private import OpenSSLOperations
/**
* A call to `EVP_PKEY_CTX_new` or `EVP_PKEY_CTX_new_from_pkey`.
* These calls initialize the context from a prior key.
* The key may be generated previously, or merely had it's
* parameters set (e.g., `EVP_PKEY_paramgen`).
*/
class EvpNewKeyCtx extends OperationStep instanceof Call {
Expr keyArg;
EvpNewKeyCtx() {
this.getTarget().getName() = "EVP_PKEY_CTX_new" and
keyArg = this.getArgument(0)
or
this.getTarget().getName() = "EVP_PKEY_CTX_new_from_pkey" and
keyArg = this.getArgument(1)
}
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = keyArg and type = KeyIO()
or
this.getTarget().getName() = "EVP_PKEY_CTX_new_from_pkey" and
result.asIndirectExpr() = this.getArgument(0) and
type = OsslLibContextIO()
}
override DataFlow::Node getOutput(IOType type) {
result.asIndirectExpr() = this and type = ContextIO()
}
override OperationStepType getStepType() { result = ContextCreationStep() }
}
/**
* A call to "EVP_PKEY_CTX_set_ec_paramgen_curve_nid".
*/
class EvpCtxSetEcParamgenCurveNidInitializer extends OperationStep {
EvpCtxSetEcParamgenCurveNidInitializer() {
this.getTarget().getName() = "EVP_PKEY_CTX_set_ec_paramgen_curve_nid"
}
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = this.getArgument(0) and type = ContextIO()
or
result.asIndirectExpr() = this.getArgument(1) and type = PrimaryAlgorithmIO()
}
override DataFlow::Node getOutput(IOType type) {
result.asDefiningArgument() = this.getArgument(0) and type = ContextIO()
}
override OperationStepType getStepType() { result = InitializerStep() }
}
/**
* A call to the following:
* - `EVP_PKEY_CTX_set_signature_md`
* - `EVP_PKEY_CTX_set_rsa_mgf1_md_name`
* - `EVP_PKEY_CTX_set_rsa_mgf1_md`
* - `EVP_PKEY_CTX_set_rsa_oaep_md_name`
* - `EVP_PKEY_CTX_set_rsa_oaep_md`
* - `EVP_PKEY_CTX_set_dsa_paramgen_md`
* - `EVP_PKEY_CTX_set_dh_kdf_md`
* - `EVP_PKEY_CTX_set_ecdh_kdf_md`
*/
class EvpCtxSetHashInitializer extends OperationStep {
boolean isOaep;
boolean isMgf1;
EvpCtxSetHashInitializer() {
this.getTarget().getName() in [
"EVP_PKEY_CTX_set_signature_md", "EVP_PKEY_CTX_set_dsa_paramgen_md",
"EVP_PKEY_CTX_set_dh_kdf_md", "EVP_PKEY_CTX_set_ecdh_kdf_md"
] and
isOaep = false and
isMgf1 = false
or
this.getTarget().getName() in [
"EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_mgf1_md"
] and
isOaep = false and
isMgf1 = true
or
this.getTarget().getName() in [
"EVP_PKEY_CTX_set_rsa_oaep_md_name",
"EVP_PKEY_CTX_set_rsa_oaep_md"
] and
isOaep = true and
isMgf1 = false
}
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = this.getArgument(0) and type = ContextIO()
or
result.asIndirectExpr() = this.getArgument(1) and
type = HashAlgorithmIO() and
isOaep = false and
isMgf1 = false
or
result.asIndirectExpr() = this.getArgument(1) and type = HashAlgorithmOaepIO() and isOaep = true
or
result.asIndirectExpr() = this.getArgument(1) and type = HashAlgorithmMgf1IO() and isMgf1 = true
}
override DataFlow::Node getOutput(IOType type) {
result.asDefiningArgument() = this.getArgument(0) and type = ContextIO()
}
override OperationStepType getStepType() { result = InitializerStep() }
}
/**
* A call to `EVP_PKEY_CTX_set_rsa_keygen_bits`, `EVP_PKEY_CTX_set_dsa_paramgen_bits`,
* or `EVP_CIPHER_CTX_set_key_length`.
*/
class EvpCtxSetKeySizeInitializer extends OperationStep {
EvpCtxSetKeySizeInitializer() {
this.getTarget().getName() in [
"EVP_PKEY_CTX_set_rsa_keygen_bits", "EVP_PKEY_CTX_set_dsa_paramgen_bits",
"EVP_CIPHER_CTX_set_key_length"
]
}
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = this.getArgument(0) and type = ContextIO()
or
result.asExpr() = this.getArgument(1) and type = KeySizeIO()
}
override DataFlow::Node getOutput(IOType type) {
result.asDefiningArgument() = this.getArgument(0) and type = ContextIO()
}
override OperationStepType getStepType() { result = InitializerStep() }
}
class EvpCtxSetMacKeyInitializer extends OperationStep {
EvpCtxSetMacKeyInitializer() { this.getTarget().getName() = "EVP_PKEY_CTX_set_mac_key" }
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = this.getArgument(0) and type = ContextIO()
or
result.asExpr() = this.getArgument(2) and type = KeySizeIO()
or
// the raw key that is configured into the output key
result.asIndirectExpr() = this.getArgument(1) and type = KeyIO()
}
override DataFlow::Node getOutput(IOType type) {
result.asDefiningArgument() = this.getArgument(0) and type = ContextIO()
}
override OperationStepType getStepType() { result = InitializerStep() }
}
class EvpCtxSetPaddingInitializer extends OperationStep {
EvpCtxSetPaddingInitializer() {
this.getTarget().getName() in ["EVP_PKEY_CTX_set_rsa_padding", "EVP_CIPHER_CTX_set_padding"]
}
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = this.getArgument(0) and type = ContextIO()
or
// The algorithm is an int: use asExpr
result.asExpr() = this.getArgument(1) and type = PaddingAlgorithmIO()
}
override DataFlow::Node getOutput(IOType type) {
result.asDefiningArgument() = this.getArgument(0) and type = ContextIO()
}
override OperationStepType getStepType() { result = InitializerStep() }
}
class EvpCtxSetSaltLengthInitializer extends OperationStep {
EvpCtxSetSaltLengthInitializer() {
this.getTarget().getName() = "EVP_PKEY_CTX_set_rsa_pss_saltlen"
}
override DataFlow::Node getInput(IOType type) {
result.asIndirectExpr() = this.getArgument(0) and type = ContextIO()
or
result.asExpr() = this.getArgument(1) and type = SaltLengthIO()
}
override DataFlow::Node getOutput(IOType type) {
result.asDefiningArgument() = this.getArgument(0) and type = ContextIO()
}
override OperationStepType getStepType() { result = InitializerStep() }
}