mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
refactor EVP common classes
add initial work for openssl signatures add basic C test files for ciphers and signatures more signature classes, comments for evp base classes more signature tests fix super calls for input consumers fix getOutputArtifact for tests formatting delete redundant test files move algorithm methods to OpenSSLOperation refactor ECKeyGenOperation for new EVP classes formatting fix getOutputArtifact fix cipher and digest operation test results mv openssl signature to another PR
This commit is contained in:
@@ -4,42 +4,15 @@ private import OpenSSLOperationBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(ECKeyGenOperation c | c.getAlgorithmArg() = sink.asExpr())
|
||||
}
|
||||
}
|
||||
|
||||
private module AlgGetterToAlgConsumerFlow = DataFlow::Global<AlgGetterToAlgConsumerConfig>;
|
||||
|
||||
class ECKeyGenOperation extends OpenSSLOperation, Crypto::KeyGenerationOperationInstance {
|
||||
ECKeyGenOperation() { this.(Call).getTarget().getName() = "EC_KEY_generate_key" }
|
||||
|
||||
override Expr getOutputArg() {
|
||||
result = this.(Call) // return value of call
|
||||
}
|
||||
|
||||
Expr getAlgorithmArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
override Expr getInputArg() {
|
||||
// there is no 'input', in the sense that no data is being manipulated by the operation.
|
||||
// There is an input of an algorithm, but that is not the intention of the operation input arg.
|
||||
none()
|
||||
}
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
override Crypto::KeyArtifactType getOutputKeyType() { result = Crypto::TAsymmetricKeyType() }
|
||||
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputKeyArtifact() {
|
||||
result = this.getOutputNode()
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
|
||||
AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
|
||||
DataFlow::exprNode(this.getAlgorithmArg()))
|
||||
result.asExpr() = this.(Call).getArgument(0)
|
||||
}
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
|
||||
private import OpenSSLOperationBase
|
||||
|
||||
module EncValToInitEncArgConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr().getValue().toInt() in [0, 1] }
|
||||
@@ -34,19 +35,12 @@ Crypto::KeyOperationSubtype intToCipherOperationSubtype(int i) {
|
||||
}
|
||||
|
||||
// TODO: need to add key consumer
|
||||
abstract class EVP_Cipher_Initializer extends Call {
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
abstract class EVP_Cipher_Initializer extends EVPInitialize {
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
abstract Expr getKeyArg();
|
||||
|
||||
abstract Expr getIVArg();
|
||||
|
||||
// abstract Crypto::CipherOperationSubtype getCipherOperationSubtype();
|
||||
abstract Expr getOperationSubtypeArg();
|
||||
|
||||
Crypto::KeyOperationSubtype getCipherOperationSubtype() {
|
||||
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
|
||||
if this.(Call).getTarget().getName().toLowerCase().matches("%encrypt%")
|
||||
then result instanceof Crypto::TEncryptMode
|
||||
else
|
||||
|
||||
@@ -4,36 +4,21 @@ private import EVPCipherInitializer
|
||||
private import OpenSSLOperationBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
|
||||
private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source)
|
||||
class EVP_Cipher_Update_Call extends EVPUpdate {
|
||||
EVP_Cipher_Update_Call() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_EncryptUpdate", "EVP_DecryptUpdate", "EVP_CipherUpdate"
|
||||
]
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(EVP_Cipher_Operation c | c.getAlgorithmArg() = sink.asExpr())
|
||||
}
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(3) }
|
||||
}
|
||||
|
||||
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 }
|
||||
// }
|
||||
//
|
||||
/**
|
||||
* see: https://docs.openssl.org/master/man3/EVP_EncryptInit/#synopsis
|
||||
* Base configuration for all EVP cipher operations.
|
||||
* NOTE: cannot extend instance of OpenSSLOperation, as we need to override
|
||||
* elements of OpenSSLOperation (i.e., we are creating an instance)
|
||||
*/
|
||||
abstract class EVP_Cipher_Operation extends OpenSSLOperation, Crypto::KeyOperationInstance {
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
Expr getAlgorithmArg() { this.getInitCall().getAlgorithmArg() = result }
|
||||
|
||||
abstract class EVP_Cipher_Operation extends EVPOperation, Crypto::KeyOperationInstance {
|
||||
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
|
||||
@@ -43,81 +28,39 @@ abstract class EVP_Cipher_Operation extends OpenSSLOperation, Crypto::KeyOperati
|
||||
result instanceof Crypto::TDecryptMode and
|
||||
this.(Call).getTarget().getName().toLowerCase().matches("%decrypt%")
|
||||
or
|
||||
result = this.getInitCall().getCipherOperationSubtype() and
|
||||
result = this.getInitCall().getKeyOperationSubtype() and
|
||||
this.(Call).getTarget().getName().toLowerCase().matches("%cipher%")
|
||||
}
|
||||
|
||||
EVP_Cipher_Initializer getInitCall() {
|
||||
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getNonceConsumer() {
|
||||
this.getInitCall().getIVArg() = result.asExpr()
|
||||
}
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getKeyConsumer() {
|
||||
this.getInitCall().getKeyArg() = result.asExpr()
|
||||
// todo: or track to the EVP_PKEY_CTX_new
|
||||
}
|
||||
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { result = this.getOutputNode() }
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
|
||||
result = EVPOperation.super.getOutputArtifact()
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
|
||||
AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
|
||||
DataFlow::exprNode(this.getInitCall().getAlgorithmArg()))
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
|
||||
result = EVPOperation.super.getInputConsumer()
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Cipher_Call extends EVP_Cipher_Operation {
|
||||
class EVP_Cipher_Call extends EVPOneShot, EVP_Cipher_Operation {
|
||||
EVP_Cipher_Call() { this.(Call).getTarget().getName() = "EVP_Cipher" }
|
||||
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(2) }
|
||||
}
|
||||
|
||||
// NOTE: not modeled as cipher operations, these are intermediate calls
|
||||
class EVP_Cipher_Update_Call extends Call {
|
||||
EVP_Cipher_Update_Call() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_EncryptUpdate", "EVP_DecryptUpdate", "EVP_CipherUpdate"
|
||||
]
|
||||
}
|
||||
|
||||
Expr getInputArg() { result = this.(Call).getArgument(3) }
|
||||
|
||||
DataFlow::Node getInputNode() { result.asExpr() = this.getInputArg() }
|
||||
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
}
|
||||
|
||||
class EVP_Cipher_Final_Call extends EVP_Cipher_Operation {
|
||||
class EVP_Cipher_Final_Call extends EVPFinal, EVP_Cipher_Operation {
|
||||
EVP_Cipher_Final_Call() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_EncryptFinal_ex", "EVP_DecryptFinal_ex", "EVP_CipherFinal_ex", "EVP_EncryptFinal",
|
||||
"EVP_DecryptFinal", "EVP_CipherFinal"
|
||||
]
|
||||
}
|
||||
|
||||
EVP_Cipher_Update_Call getUpdateCalls() {
|
||||
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
|
||||
override Expr getInputArg() { result = this.getUpdateCalls().getInputArg() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() }
|
||||
}
|
||||
|
||||
class EVP_PKEY_Operation extends EVP_Cipher_Operation {
|
||||
EVP_PKEY_Operation() {
|
||||
this.(Call).getTarget().getName() in ["EVP_PKEY_decrypt", "EVP_PKEY_encrypt"]
|
||||
}
|
||||
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(3) }
|
||||
// TODO: how PKEY is initialized is different that symmetric cipher
|
||||
// Consider making an entirely new class for this and specializing
|
||||
// the get init call
|
||||
}
|
||||
|
||||
class EVPCipherInputArgument extends Expr {
|
||||
EVPCipherInputArgument() { exists(EVP_Cipher_Operation op | op.getInputArg() = this) }
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import cpp
|
||||
private import OpenSSLOperationBase
|
||||
|
||||
abstract class EVP_Hash_Initializer extends Call {
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
abstract Expr getAlgorithmArg();
|
||||
}
|
||||
abstract class EVP_Hash_Initializer extends EVPInitialize { }
|
||||
|
||||
class EVP_DigestInit_Variant_Calls extends EVP_Hash_Initializer {
|
||||
EVP_DigestInit_Variant_Calls() {
|
||||
|
||||
@@ -8,118 +8,78 @@ private import OpenSSLOperationBase
|
||||
private import EVPHashInitializer
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
|
||||
// import EVPHashConsumers
|
||||
abstract class EVP_Hash_Operation extends OpenSSLOperation, Crypto::HashOperationInstance {
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
class EVP_Digest_Update_Call extends EVPUpdate {
|
||||
EVP_Digest_Update_Call() { this.(Call).getTarget().getName() in ["EVP_DigestUpdate"] }
|
||||
|
||||
Expr getAlgorithmArg() { result = this.getInitCall().getAlgorithmArg() }
|
||||
|
||||
EVP_Hash_Initializer getInitCall() {
|
||||
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, the algorithm value comes from the init call.
|
||||
* There are variants where this isn't true, in which case the
|
||||
* subclass should override this method.
|
||||
*/
|
||||
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
|
||||
AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
|
||||
DataFlow::exprNode(this.getAlgorithmArg()))
|
||||
}
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(1) }
|
||||
}
|
||||
|
||||
private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(EVP_Hash_Operation c | c.getAlgorithmArg() = sink.asExpr())
|
||||
}
|
||||
}
|
||||
|
||||
private module AlgGetterToAlgConsumerFlow = DataFlow::Global<AlgGetterToAlgConsumerConfig>;
|
||||
|
||||
//https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
|
||||
class EVP_Q_Digest_Operation extends EVP_Hash_Operation {
|
||||
class EVP_Q_Digest_Operation extends EVPOneShot, Crypto::HashOperationInstance {
|
||||
EVP_Q_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
|
||||
|
||||
//override Crypto::AlgorithmConsumer getAlgorithmConsumer() { }
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
override EVP_Hash_Initializer getInitCall() {
|
||||
// This variant of digest does not use an init
|
||||
// and even if it were used, the init would be ignored/undefined
|
||||
none()
|
||||
}
|
||||
|
||||
override Expr getOutputArg() { result = this.(Call).getArgument(5) }
|
||||
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(3) }
|
||||
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { result = this.getOutputNode() }
|
||||
override Expr getOutputArg() { result = this.(Call).getArgument(5) }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() }
|
||||
|
||||
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
|
||||
// The operation is a direct algorithm consumer
|
||||
// NOTE: the operation itself is already modeld as a value consumer, so we can
|
||||
// simply return 'this', see modeled hash algorithm consuers for EVP_Q_Digest
|
||||
this = result
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
|
||||
result = EVPOneShot.super.getOutputArtifact()
|
||||
}
|
||||
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
|
||||
result = EVPOneShot.super.getInputConsumer()
|
||||
}
|
||||
}
|
||||
|
||||
class EVP_Digest_Operation extends EVP_Hash_Operation {
|
||||
class EVP_Digest_Operation extends EVPOneShot, Crypto::HashOperationInstance {
|
||||
EVP_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Digest" }
|
||||
|
||||
// There is no context argument for this function
|
||||
override Expr getContextArg() { none() }
|
||||
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(4) }
|
||||
|
||||
override EVP_Hash_Initializer getInitCall() {
|
||||
// This variant of digest does not use an init
|
||||
// and even if it were used, the init would be ignored/undefined
|
||||
none()
|
||||
}
|
||||
|
||||
override Expr getAlgorithmArg() { result = this.(Call).getArgument(4) }
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
override Expr getOutputArg() { result = this.(Call).getArgument(2) }
|
||||
|
||||
override Expr getInputArg() { result = this.(Call).getArgument(0) }
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
|
||||
result = EVPOneShot.super.getOutputArtifact()
|
||||
}
|
||||
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { result = this.getOutputNode() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() }
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
|
||||
result = EVPOneShot.super.getInputConsumer()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: not modeled as hash operations, these are intermediate calls
|
||||
class EVP_Digest_Update_Call extends Call {
|
||||
EVP_Digest_Update_Call() { this.(Call).getTarget().getName() in ["EVP_DigestUpdate"] }
|
||||
|
||||
Expr getInputArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
DataFlow::Node getInputNode() { result.asExpr() = this.getInputArg() }
|
||||
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
}
|
||||
|
||||
class EVP_Digest_Final_Call extends EVP_Hash_Operation {
|
||||
class EVP_Digest_Final_Call extends EVPFinal, Crypto::HashOperationInstance {
|
||||
EVP_Digest_Final_Call() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_DigestFinal", "EVP_DigestFinal_ex", "EVP_DigestFinalXOF"
|
||||
]
|
||||
}
|
||||
|
||||
EVP_Digest_Update_Call getUpdateCalls() {
|
||||
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
|
||||
override Expr getInputArg() { result = this.getUpdateCalls().getInputArg() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() { result = this.getInputNode() }
|
||||
|
||||
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
|
||||
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() { result = this.getOutputNode() }
|
||||
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
|
||||
result = EVPFinal.super.getOutputArtifact()
|
||||
}
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
|
||||
result = EVPFinal.super.getInputConsumer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,157 @@
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
|
||||
/**
|
||||
* All OpenSSL operations.
|
||||
*/
|
||||
abstract class OpenSSLOperation extends Crypto::OperationInstance instanceof Call {
|
||||
/**
|
||||
* Expression that specifies the algorithm for the operation.
|
||||
* Will be an argument of the operation in the simplest case.
|
||||
*/
|
||||
abstract Expr getAlgorithmArg();
|
||||
|
||||
/**
|
||||
* Algorithm is specified in initialization call or is implicitly established by the key.
|
||||
*/
|
||||
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
|
||||
AlgGetterToAlgConsumerFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
|
||||
DataFlow::exprNode(this.getAlgorithmArg()))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls to initialization functions of EVP API.
|
||||
* These are not operations in the sense of Crypto::OperationInstance,
|
||||
* but they are used to initialize the context for the operation.
|
||||
*/
|
||||
abstract class EVPInitialize extends Call {
|
||||
/**
|
||||
* The context argument that ties together initialization, updates and/or final calls.
|
||||
*/
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
/**
|
||||
* The type of key operation, none if not applicable.
|
||||
*/
|
||||
Crypto::KeyOperationSubtype getKeyOperationSubtype() { none() }
|
||||
|
||||
/**
|
||||
* Explicitly specified algorithm or none if implicit (e.g., established by the key).
|
||||
* None if not applicable.
|
||||
*/
|
||||
Expr getAlgorithmArg() { none() }
|
||||
|
||||
/**
|
||||
* The key for the operation, none if not applicable.
|
||||
*/
|
||||
Expr getKeyArg() { none() }
|
||||
|
||||
/**
|
||||
* The IV/nonce, none if not applicable.
|
||||
*/
|
||||
Expr getIVArg() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls to update functions of EVP API.
|
||||
* These are not operations in the sense of Crypto::OperationInstance,
|
||||
* but they are used to update the context for the operation.
|
||||
*/
|
||||
abstract class EVPUpdate extends Call {
|
||||
/**
|
||||
* The context argument that ties together initialization, updates and/or final calls.
|
||||
*/
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
/**
|
||||
* Update calls always have some input data like plaintext or message digest.
|
||||
*/
|
||||
abstract Expr getInputArg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flows from algorithm values to operations, specific to OpenSSL
|
||||
*/
|
||||
private module AlgGetterToAlgConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(EVPOperation c | c.getAlgorithmArg() = sink.asExpr())
|
||||
}
|
||||
}
|
||||
|
||||
private module AlgGetterToAlgConsumerFlow = DataFlow::Global<AlgGetterToAlgConsumerConfig>;
|
||||
|
||||
/**
|
||||
* Base class for all operations of the EVP API.
|
||||
* Currently final calls and one-shot calls are implemented.
|
||||
* Provides some default methods for Crypto::KeyOperationInstance class
|
||||
*/
|
||||
abstract class EVPOperation extends OpenSSLOperation {
|
||||
/**
|
||||
* The context argument that ties together initialization, updates and/or final calls.
|
||||
*/
|
||||
Expr getContextArg() { result = this.(Call).getArgument(0) }
|
||||
|
||||
/**
|
||||
* Some input data like plaintext or message digest.
|
||||
* Either argument provided direcly in the call or all arguments that were provided in update calls.
|
||||
*/
|
||||
abstract Expr getInputArg();
|
||||
|
||||
/**
|
||||
* Can be an argument of a call or a return value of a function.
|
||||
* Some output data like ciphertext or signature.
|
||||
* Always produced directly by this operation.
|
||||
* Assumption: output is provided as an argument to the call, never as return value.
|
||||
*/
|
||||
abstract Expr getOutputArg();
|
||||
|
||||
DataFlow::Node getInputNode() {
|
||||
// Assumed to be default to asExpr
|
||||
result.asExpr() = this.getInputArg()
|
||||
/**
|
||||
* Overwrite with an explicitly specified algorithm or leave base implementation to find it in the initialization call.
|
||||
*/
|
||||
override Expr getAlgorithmArg() {
|
||||
if exists(this.getInitCall()) then result = this.getInitCall().getAlgorithmArg() else none()
|
||||
}
|
||||
|
||||
DataFlow::Node getOutputNode() {
|
||||
if exists(Call c | c.getAnArgument() = this)
|
||||
then result.asDefiningArgument() = this
|
||||
else result.asExpr() = this
|
||||
/**
|
||||
* Finds the initialization call, may be none.
|
||||
*/
|
||||
EVPInitialize getInitCall() {
|
||||
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
|
||||
Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
|
||||
result.asExpr() = this.getOutputArg()
|
||||
}
|
||||
|
||||
/**
|
||||
* Input consumer is the input argument of the call.
|
||||
*/
|
||||
Crypto::ConsumerInputDataFlowNode getInputConsumer() { result.asExpr() = this.getInputArg() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Final calls of EVP API.
|
||||
*/
|
||||
abstract class EVPFinal extends EVPOperation {
|
||||
/**
|
||||
* All update calls that were executed before this final call.
|
||||
*/
|
||||
EVPUpdate getUpdateCalls() {
|
||||
CTXFlow::ctxArgFlowsToCtxArg(result.getContextArg(), this.getContextArg())
|
||||
}
|
||||
|
||||
/**
|
||||
* The input data was provided to all update calls.
|
||||
*/
|
||||
override Expr getInputArg() { result = this.getUpdateCalls().getInputArg() }
|
||||
}
|
||||
|
||||
/**
|
||||
* One-shot calls of EVP API.
|
||||
*/
|
||||
abstract class EVPOneShot extends EVPOperation { }
|
||||
|
||||
@@ -2,3 +2,4 @@ import OpenSSLOperationBase
|
||||
import EVPCipherOperation
|
||||
import EVPHashOperation
|
||||
import ECKeyGenOperation
|
||||
import EVPSignatureOperation
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:13:40:31 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:13:40:31 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:13:40:31 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:13:40:31 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:11:90:29 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:11:90:29 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:11:90:29 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:11:90:29 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:23:62:23:65 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:23:68:23:71 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:40:13:40:31 | EncryptOperation | openssl_basic.c:35:54:35:62 | Message | openssl_basic.c:40:38:40:53 | KeyOperationOutput | openssl_basic.c:31:49:31:51 | Key | openssl_basic.c:31:54:31:55 | Nonce | openssl_basic.c:23:37:23:51 | KeyOperationAlgorithm | Encrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:69:58:69:61 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:69:64:69:67 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
| openssl_basic.c:90:11:90:29 | DecryptOperation | openssl_basic.c:81:49:81:58 | Message | openssl_basic.c:90:36:90:50 | KeyOperationOutput | openssl_basic.c:77:45:77:47 | Key | openssl_basic.c:77:50:77:51 | Nonce | openssl_basic.c:69:33:69:47 | KeyOperationAlgorithm | Decrypt |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| openssl_basic.c:124:13:124:30 | HashOperation | openssl_basic.c:124:13:124:30 | Digest | openssl_basic.c:116:38:116:47 | HashAlgorithm | openssl_basic.c:120:37:120:43 | Message |
|
||||
| openssl_basic.c:144:13:144:22 | HashOperation | openssl_basic.c:144:13:144:22 | Digest | openssl_basic.c:144:67:144:73 | HashAlgorithm | openssl_basic.c:144:24:144:30 | Message |
|
||||
| openssl_basic.c:124:13:124:30 | HashOperation | openssl_basic.c:124:39:124:44 | Digest | openssl_basic.c:116:38:116:47 | HashAlgorithm | openssl_basic.c:120:37:120:43 | Message |
|
||||
| openssl_basic.c:144:13:144:22 | HashOperation | openssl_basic.c:144:46:144:51 | Digest | openssl_basic.c:144:67:144:73 | HashAlgorithm | openssl_basic.c:144:24:144:30 | Message |
|
||||
|
||||
Reference in New Issue
Block a user