Merge branch 'openssl_acronym_normalization' into pawel_signatures_conversion

This commit is contained in:
REDMOND\brodes
2025-06-17 13:03:12 -04:00
39 changed files with 346 additions and 331 deletions

View File

@@ -92,7 +92,7 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
ConstantDataSource() { this instanceof OpenSSLGenericSourceCandidateLiteral }
ConstantDataSource() { this instanceof OpenSslGenericSourceCandidateLiteral }
override DataFlow::Node getOutputNode() { result.asExpr() = this }

View File

@@ -12,15 +12,15 @@ private import PaddingAlgorithmInstance
* overlap with the known algorithm constants.
* Padding consumers (specific padding consumers) are excluded from the set of sinks.
*/
module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof KnownOpenSSLAlgorithmExpr and
source.asExpr() instanceof KnownOpenSslAlgorithmExpr and
// No need to flow direct operations to AVCs
not source.asExpr() instanceof OpenSSLDirectAlgorithmOperationCall
not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall
}
predicate isSink(DataFlow::Node sink) {
exists(OpenSSLAlgorithmValueConsumer c |
exists(OpenSslAlgorithmValueConsumer c |
c.getInputNode() = sink and
// exclude padding algorithm consumers, since
// these consumers take in different constant values
@@ -45,11 +45,11 @@ module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::
}
}
module KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow =
DataFlow::Global<KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig>;
module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow =
DataFlow::Global<KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig>;
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSSLPaddingLiteral }
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral }
predicate isSink(DataFlow::Node sink) {
exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink)
@@ -63,8 +63,8 @@ module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
DataFlow::Global<RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
class OpenSSLAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
OpenSSLAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
override DataFlow::Node getOutput() {
exists(AlgorithmPassthroughCall c | c.getInNode() = this and c.getOutNode() = result)

View File

@@ -7,14 +7,14 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import AlgToAVCFlow
/**
* Given a `KnownOpenSSLBlockModeAlgorithmExpr`, converts this to a block family type.
* Given a `KnownOpenSslBlockModeAlgorithmExpr`, converts this to a block family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSSLConstantToBlockModeFamilyType(
KnownOpenSSLBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type
predicate knownOpenSslConstantToBlockModeFamilyType(
KnownOpenSslBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type
) {
exists(string name |
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("CBC") and type instanceof Crypto::CBC
or
@@ -39,35 +39,35 @@ predicate knownOpenSSLConstantToBlockModeFamilyType(
)
}
class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLBlockModeAlgorithmExpr
class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSslBlockModeAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLBlockModeConstantAlgorithmInstance() {
KnownOpenSslBlockModeConstantAlgorithmInstance() {
// 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override Crypto::TBlockCipherModeOfOperationType getModeType() {
knownOpenSSLConstantToBlockModeFamilyType(this, result)
knownOpenSslConstantToBlockModeFamilyType(this, result)
or
not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
}
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
@@ -78,5 +78,5 @@ class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmIns
result = this.(Call).getTarget().getName()
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
}

View File

@@ -10,14 +10,14 @@ private import AlgToAVCFlow
private import BlockAlgorithmInstance
/**
* Given a `KnownOpenSSLCipherAlgorithmExpr`, converts this to a cipher family type.
* Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSSLConstantToCipherFamilyType(
KnownOpenSSLCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
predicate knownOpenSslConstantToCipherFamilyType(
KnownOpenSslCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
) {
exists(string name |
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("AES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
or
@@ -64,28 +64,28 @@ predicate knownOpenSSLConstantToCipherFamilyType(
)
}
class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLCipherAlgorithmExpr
class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslCipherAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLCipherConstantAlgorithmInstance() {
KnownOpenSslCipherConstantAlgorithmInstance() {
// 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
@@ -110,17 +110,17 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstan
}
override int getKeySizeFixed() {
this.(KnownOpenSSLCipherAlgorithmExpr).getExplicitKeySize() = result
this.(KnownOpenSslCipherAlgorithmExpr).getExplicitKeySize() = result
}
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
knownOpenSSLConstantToCipherFamilyType(this, result)
knownOpenSslConstantToCipherFamilyType(this, result)
or
not knownOpenSSLConstantToCipherFamilyType(this, _) and
not knownOpenSslConstantToCipherFamilyType(this, _) and
result = Crypto::KeyOpAlg::TUnknownKeyOperationAlgorithmType()
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
// TODO: trace to any key size initializer, symmetric and asymmetric

View File

@@ -6,32 +6,32 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
private import AlgToAVCFlow
class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::EllipticCurveInstance instanceof KnownOpenSSLEllipticCurveAlgorithmExpr
class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::EllipticCurveInstance instanceof KnownOpenSslEllipticCurveAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLEllipticCurveConstantAlgorithmInstance() {
KnownOpenSslEllipticCurveConstantAlgorithmInstance() {
// 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override string getRawEllipticCurveName() {
result = this.(Literal).getValue().toString()
@@ -44,11 +44,11 @@ class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorith
}
override string getParsedEllipticCurveName() {
result = this.(KnownOpenSSLAlgorithmExpr).getNormalizedName()
result = this.(KnownOpenSslAlgorithmExpr).getNormalizedName()
}
override int getKeySize() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLAlgorithmExpr)
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
.getNormalizedName(), result, _)
}
}

View File

@@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import AlgToAVCFlow
predicate knownOpenSSLConstantToHashFamilyType(
KnownOpenSSLHashAlgorithmExpr e, Crypto::THashType type
predicate knownOpenSslConstantToHashFamilyType(
KnownOpenSslHashAlgorithmExpr e, Crypto::THashType type
) {
exists(string name |
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
or
@@ -44,37 +44,37 @@ predicate knownOpenSSLConstantToHashFamilyType(
)
}
class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::HashAlgorithmInstance instanceof KnownOpenSSLHashAlgorithmExpr
class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::HashAlgorithmInstance instanceof KnownOpenSslHashAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLHashConstantAlgorithmInstance() {
KnownOpenSslHashConstantAlgorithmInstance() {
// 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::THashType getHashFamily() {
knownOpenSSLConstantToHashFamilyType(this, result)
knownOpenSslConstantToHashFamilyType(this, result)
or
not knownOpenSSLConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
not knownOpenSslConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
}
override string getRawHashAlgorithmName() {
@@ -84,6 +84,6 @@ class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance
}
override int getFixedDigestLength() {
this.(KnownOpenSSLHashAlgorithmExpr).getExplicitDigestLength() = result
this.(KnownOpenSslHashAlgorithmExpr).getExplicitDigestLength() = result
}
}

View File

@@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import AlgToAVCFlow
predicate knownOpenSSLConstantToKeyAgreementFamilyType(
KnownOpenSSLKeyAgreementAlgorithmExpr e, Crypto::TKeyAgreementType type
predicate knownOpenSslConstantToKeyAgreementFamilyType(
KnownOpenSslKeyAgreementAlgorithmExpr e, Crypto::TKeyAgreementType type
) {
exists(string name |
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name = "ECDH" and type = Crypto::ECDH()
or
@@ -22,37 +22,37 @@ predicate knownOpenSSLConstantToKeyAgreementFamilyType(
)
}
class KnownOpenSSLKeyAgreementConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSSLKeyAgreementAlgorithmExpr
class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSslKeyAgreementAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLKeyAgreementConstantAlgorithmInstance() {
KnownOpenSslKeyAgreementConstantAlgorithmInstance() {
// 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::TKeyAgreementType getKeyAgreementType() {
knownOpenSSLConstantToKeyAgreementFamilyType(this, result)
knownOpenSslConstantToKeyAgreementFamilyType(this, result)
or
not knownOpenSSLConstantToKeyAgreementFamilyType(this, _) and
not knownOpenSslConstantToKeyAgreementFamilyType(this, _) and
result = Crypto::OtherKeyAgreementType()
}

View File

@@ -2,28 +2,28 @@ import cpp
import experimental.quantum.OpenSSL.GenericSourceCandidateLiteral
predicate resolveAlgorithmFromExpr(
KnownOpenSSLAlgorithmExpr e, string normalizedName, string algType
KnownOpenSslAlgorithmExpr e, string normalizedName, string algType
) {
normalizedName = e.getNormalizedName() and
algType = e.getAlgType()
}
/**
* An expression that resolves to a known OpenSSL algorithm constant.
* This can be a literal, a call to a known OpenSSL algorithm constant getter,
* An expression that resolves to a known OpenSsl algorithm constant.
* This can be a literal, a call to a known OpenSsl algorithm constant getter,
* or a call to an operation that directly operates on a known algorithm.
*/
abstract class KnownOpenSSLAlgorithmExpr extends Expr {
abstract class KnownOpenSslAlgorithmExpr extends Expr {
abstract string getNormalizedName();
abstract string getAlgType();
}
class OpenSSLAlgorithmLiteral extends KnownOpenSSLAlgorithmExpr instanceof Literal {
class OpenSslAlgorithmLiteral extends KnownOpenSslAlgorithmExpr instanceof Literal {
string normalizedName;
string algType;
OpenSSLAlgorithmLiteral() { resolveAlgorithmFromLiteral(this, normalizedName, algType) }
OpenSslAlgorithmLiteral() { resolveAlgorithmFromLiteral(this, normalizedName, algType) }
override string getNormalizedName() { result = normalizedName }
@@ -31,14 +31,14 @@ class OpenSSLAlgorithmLiteral extends KnownOpenSSLAlgorithmExpr instanceof Liter
}
/**
* A call to either an OpenSSL algorithm constant 'getter', e.g., EVP_MD5()
* A call to either an OpenSsl algorithm constant 'getter', e.g., EVP_MD5()
* or call to an operation that directly operates on a known algorithm, e.g., AES_encrypt
*/
abstract class OpenSSLAlgorithmCall extends KnownOpenSSLAlgorithmExpr instanceof Call { }
abstract class OpenSslAlgorithmCall extends KnownOpenSslAlgorithmExpr instanceof Call { }
/**
* A call to a 'direct algorithm getter', e.g., EVP_MD5()
* This approach to fetching algorithms was used in OpenSSL 1.0.2.
* This approach to fetching algorithms was used in OpenSsl 1.0.2.
* The strategy for resolving these calls is to parse the target name
* and resolve the name as though it were a known literal.
* There are a few exceptions where the name doesn't directly match the
@@ -48,18 +48,18 @@ abstract class OpenSSLAlgorithmCall extends KnownOpenSSLAlgorithmExpr instanceof
* or
* alias = "dss1" and target = "dsaWithSHA1"
*/
class OpenSSLDirectAlgorithmFetchCall extends OpenSSLAlgorithmCall {
class OpenSslDirectAlgorithmFetchCall extends OpenSslAlgorithmCall {
string normalizedName;
string algType;
OpenSSLDirectAlgorithmFetchCall() {
OpenSslDirectAlgorithmFetchCall() {
//ASSUMPTION: these cases will have operands for the call
not exists(this.(Call).getAnArgument()) and
exists(string name, string parsedTargetName |
parsedTargetName =
this.(Call).getTarget().getName().replaceAll("EVP_", "").toLowerCase().replaceAll("_", "-") and
name = resolveAlgorithmAlias(parsedTargetName) and
knownOpenSSLAlgorithmLiteral(name, _, normalizedName, algType)
knownOpenSslAlgorithmLiteral(name, _, normalizedName, algType)
)
}
@@ -69,22 +69,22 @@ class OpenSSLDirectAlgorithmFetchCall extends OpenSSLAlgorithmCall {
}
/**
* A call to an OpenSSL operation that directly operates on a known algorithm.
* A call to an OpenSsl operation that directly operates on a known algorithm.
* An algorithm construct is not generated for these calls, rather, the operation
* is directly performed, and the algorithm is inferred by the operation itself.
*/
class OpenSSLDirectAlgorithmOperationCall extends OpenSSLAlgorithmCall {
class OpenSslDirectAlgorithmOperationCall extends OpenSslAlgorithmCall {
string normalizedName;
string algType;
OpenSSLDirectAlgorithmOperationCall() {
OpenSslDirectAlgorithmOperationCall() {
//TODO: this set will have to be exhaustive, and for each operation
//further modeling will be necessary for each case to map the APIs operands
//ASSUMPTION: these cases must have operands for the call
exists(this.(Call).getAnArgument()) and
//TODO: Each case would be enumerated here. Will likely need an exhaustive mapping much like
// for known constants.
knownOpenSSLAlgorithmOperationCall(this, normalizedName, algType)
knownOpenSslAlgorithmOperationCall(this, normalizedName, algType)
}
override string getNormalizedName() { result = normalizedName }
@@ -92,25 +92,25 @@ class OpenSSLDirectAlgorithmOperationCall extends OpenSSLAlgorithmCall {
override string getAlgType() { result = algType }
}
class KnownOpenSSLCipherAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
class KnownOpenSslCipherAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
string algType;
KnownOpenSSLCipherAlgorithmExpr() {
algType = this.(KnownOpenSSLAlgorithmExpr).getAlgType() and
KnownOpenSslCipherAlgorithmExpr() {
algType = this.(KnownOpenSslAlgorithmExpr).getAlgType() and
algType.matches("%ENCRYPTION")
}
int getExplicitKeySize() {
exists(string name |
name = this.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
resolveAlgorithmFromExpr(this, name, algType) and
result = name.regexpCapture(".*-(\\d*)", 1).toInt()
)
}
}
class KnownOpenSSLPaddingAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLPaddingAlgorithmExpr() {
class KnownOpenSslPaddingAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslPaddingAlgorithmExpr() {
exists(string algType |
resolveAlgorithmFromExpr(this, _, algType) and
algType.matches("%PADDING")
@@ -118,59 +118,59 @@ class KnownOpenSSLPaddingAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgor
}
}
class KnownOpenSSLBlockModeAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLBlockModeAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") }
class KnownOpenSslBlockModeAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslBlockModeAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "BLOCK_MODE") }
}
class KnownOpenSSLHashAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLHashAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "HASH") }
class KnownOpenSslHashAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslHashAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "HASH") }
int getExplicitDigestLength() {
exists(string name |
name = this.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = this.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
resolveAlgorithmFromExpr(this, name, "HASH") and
result = name.regexpCapture(".*-(\\d*)$", 1).toInt()
)
}
}
class KnownOpenSSLMACAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLMACAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "MAC") }
class KnownOpenSslMacAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "MAC") }
}
class KnownOpenSSLHMACAlgorithmExpr extends Expr instanceof KnownOpenSSLMACAlgorithmExpr {
KnownOpenSSLHMACAlgorithmExpr() { resolveAlgorithmFromExpr(this, "HMAC", "MAC") }
class KnownOpenSslHMacAlgorithmExpr extends Expr instanceof KnownOpenSslMacAlgorithmExpr {
KnownOpenSslHMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, "HMAC", "MAC") }
/**
* Gets an explicit cipher algorithm for this MAC algorithm.
* This occurs when the MAC specifies the algorithm at the same time "HMAC-SHA-256"
*/
KnownOpenSSLHashAlgorithmExpr getExplicitHashAlgorithm() { result = this }
KnownOpenSslHashAlgorithmExpr getExplicitHashAlgorithm() { result = this }
}
class KnownOpenSSLCMACAlgorithmExpr extends Expr instanceof KnownOpenSSLMACAlgorithmExpr {
KnownOpenSSLCMACAlgorithmExpr() { resolveAlgorithmFromExpr(this, "CMAC", "MAC") }
class KnownOpenSslCMacAlgorithmExpr extends Expr instanceof KnownOpenSslMacAlgorithmExpr {
KnownOpenSslCMacAlgorithmExpr() { resolveAlgorithmFromExpr(this, "CMAC", "MAC") }
/**
* Gets an explicit cipher algorithm for this MAC algorithm.
* This occurs when the MAC specifies the algorithm at the same time "HMAC-SHA-256"
*/
KnownOpenSSLCipherAlgorithmExpr getExplicitCipherAlgorithm() { result = this }
KnownOpenSslCipherAlgorithmExpr getExplicitCipherAlgorithm() { result = this }
}
class KnownOpenSSLEllipticCurveAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLEllipticCurveAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE") }
class KnownOpenSslEllipticCurveAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslEllipticCurveAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "ELLIPTIC_CURVE") }
}
class KnownOpenSSLSignatureAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLSignatureAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") }
class KnownOpenSslSignatureAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslSignatureAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "SIGNATURE") }
}
class KnownOpenSSLKeyAgreementAlgorithmExpr extends Expr instanceof KnownOpenSSLAlgorithmExpr {
KnownOpenSSLKeyAgreementAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "KEY_AGREEMENT") }
class KnownOpenSslKeyAgreementAlgorithmExpr extends Expr instanceof KnownOpenSslAlgorithmExpr {
KnownOpenSslKeyAgreementAlgorithmExpr() { resolveAlgorithmFromExpr(this, _, "KEY_AGREEMENT") }
}
predicate knownOpenSSLAlgorithmOperationCall(Call c, string normalized, string algType) {
predicate knownOpenSslAlgorithmOperationCall(Call c, string normalized, string algType) {
c.getTarget().getName() in ["EVP_RSA_gen", "RSA_generate_key_ex", "RSA_generate_key", "RSA_new"] and
normalized = "RSA" and
algType = "ASYMMETRIC_ENCRYPTION"
@@ -182,13 +182,13 @@ predicate knownOpenSSLAlgorithmOperationCall(Call c, string normalized, string a
* If this predicate does not hold, then `e` can be interpreted as being of `UNKNOWN` type.
*/
predicate resolveAlgorithmFromLiteral(
OpenSSLGenericSourceCandidateLiteral e, string normalized, string algType
OpenSslGenericSourceCandidateLiteral e, string normalized, string algType
) {
knownOpenSSLAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType)
knownOpenSslAlgorithmLiteral(_, e.getValue().toInt(), normalized, algType)
or
exists(string name |
name = resolveAlgorithmAlias(e.getValue()) and
knownOpenSSLAlgorithmLiteral(name, _, normalized, algType)
knownOpenSslAlgorithmLiteral(name, _, normalized, algType)
)
}
@@ -199,7 +199,7 @@ string resolveAlgorithmAlias(string name) {
result = getAlgorithmAlias(lower)
or
// or the name is itself a known algorithm
knownOpenSSLAlgorithmLiteral(lower, _, _, _) and result = lower
knownOpenSslAlgorithmLiteral(lower, _, _, _) and result = lower
)
}
@@ -222,9 +222,9 @@ predicate customAliases(string target, string alias) {
}
/**
* A hard-coded mapping of known algorithm aliases in OpenSSL.
* A hard-coded mapping of known algorithm aliases in OpenSsl.
* This was derived by applying the same kind of logic foun din `customAliases` to the
* OpenSSL code base directly.
* OpenSsl code base directly.
*
* The `target` and `alias` are converted to lowercase to be of a standard form.
*/
@@ -331,7 +331,7 @@ predicate defaultAliases(string target, string alias) {
* `normalized` is the normalized name of the algorithm (e.g., "AES128" for "aes-128-cbc")
* `algType` is the type of algorithm (e.g., "SYMMETRIC_ENCRYPTION")
*/
predicate knownOpenSSLAlgorithmLiteral(string name, int nid, string normalized, string algType) {
predicate knownOpenSslAlgorithmLiteral(string name, int nid, string normalized, string algType) {
name = "dhKeyAgreement" and nid = 28 and normalized = "DH" and algType = "KEY_AGREEMENT"
or
name = "x9.42 dh" and nid = 29 and normalized = "DH" and algType = "KEY_AGREEMENT"

View File

@@ -6,61 +6,61 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmI
private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations
private import AlgToAVCFlow
class KnownOpenSSLMACConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::MACAlgorithmInstance instanceof KnownOpenSSLMACAlgorithmExpr
class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::MACAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLMACConstantAlgorithmInstance() {
KnownOpenSslMacConstantAlgorithmInstance() {
// 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override string getRawMACAlgorithmName() {
override string getRawMacAlgorithmName() {
result = this.(Literal).getValue().toString()
or
result = this.(Call).getTarget().getName()
}
override Crypto::TMACType getMACType() {
this instanceof KnownOpenSSLHMACAlgorithmExpr and result instanceof Crypto::THMAC
override Crypto::TMACType getMacType() {
this instanceof KnownOpenSslHMacAlgorithmExpr and result instanceof Crypto::THMAC
or
this instanceof KnownOpenSSLCMACAlgorithmExpr and result instanceof Crypto::TCMAC
this instanceof KnownOpenSslCMacAlgorithmExpr and result instanceof Crypto::TCMAC
}
}
class KnownOpenSSLHMACConstantAlgorithmInstance extends Crypto::HMACAlgorithmInstance,
KnownOpenSSLMACConstantAlgorithmInstance
class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HMACAlgorithmInstance,
KnownOpenSslMacConstantAlgorithmInstance
{
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
if exists(this.(KnownOpenSSLHMACAlgorithmExpr).getExplicitHashAlgorithm())
if exists(this.(KnownOpenSslHMacAlgorithmExpr).getExplicitHashAlgorithm())
then
// ASSUMPTION: if there is an explicit hash algorithm, it is already modeled
// and we can simply grab that model's AVC
exists(OpenSSLAlgorithmInstance inst | inst.getAVC() = result and inst = this)
exists(OpenSslAlgorithmInstance inst | inst.getAvc() = result and inst = this)
else
// ASSUMPTION: If no explicit algorithm is given, then it is assumed to be configured by
// a signature operation
exists(Crypto::SignatureOperationInstance s |
s.getHashAlgorithmValueConsumer() = result and
s.getAnAlgorithmValueConsumer() = this.getAVC()
s.getAnAlgorithmValueConsumer() = this.getAvc()
)
}
}

View File

@@ -1,6 +1,6 @@
private import experimental.quantum.Language
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
abstract class OpenSSLAlgorithmInstance extends Crypto::AlgorithmInstance {
abstract OpenSSLAlgorithmValueConsumer getAVC();
abstract class OpenSslAlgorithmInstance extends Crypto::AlgorithmInstance {
abstract OpenSslAlgorithmValueConsumer getAvc();
}

View File

@@ -17,21 +17,21 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
* # define RSA_PKCS1_WITH_TLS_PADDING 7
* # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
*/
class OpenSSLPaddingLiteral extends Literal {
class OpenSslPaddingLiteral extends Literal {
// TODO: we can be more specific about where the literal is in a larger expression
// to avoid literals that are clealy not representing an algorithm, e.g., array indices.
OpenSSLPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
OpenSslPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
}
/**
* Given a `KnownOpenSSLPaddingAlgorithmExpr`, converts this to a padding family type.
* Given a `KnownOpenSslPaddingAlgorithmExpr`, converts this to a padding family type.
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
*/
predicate knownOpenSSLConstantToPaddingFamilyType(
KnownOpenSSLPaddingAlgorithmExpr e, Crypto::TPaddingType type
predicate knownOpenSslConstantToPaddingFamilyType(
KnownOpenSslPaddingAlgorithmExpr e, Crypto::TPaddingType type
) {
exists(string name |
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("OAEP") and type = Crypto::OAEP()
or
@@ -44,44 +44,44 @@ predicate knownOpenSSLConstantToPaddingFamilyType(
)
}
//abstract class OpenSSLPaddingAlgorithmInstance extends OpenSSLAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
//abstract class OpenSslPaddingAlgorithmInstance extends OpenSslAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
// TODO: need to alter this to include known padding constants which don't have the
// same mechanics as those with known nids
class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::PaddingAlgorithmInstance instanceof Expr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
boolean isPaddingSpecificConsumer;
KnownOpenSSLPaddingConstantAlgorithmInstance() {
KnownOpenSslPaddingConstantAlgorithmInstance() {
// three possibilities:
// 1) The source is a 'typical' 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
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
// 3) the source is a padding-specific literal flowing to a padding-specific consumer
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof KnownOpenSSLPaddingAlgorithmExpr and
this instanceof OpenSslAlgorithmLiteral and
this instanceof KnownOpenSslPaddingAlgorithmExpr and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
isPaddingSpecificConsumer = false
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this and
this instanceof KnownOpenSSLPaddingAlgorithmExpr and
this instanceof KnownOpenSslPaddingAlgorithmExpr and
isPaddingSpecificConsumer = false
or
// Possibility 3: padding-specific literal
this instanceof OpenSSLPaddingLiteral and
this instanceof OpenSslPaddingLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a CipherGetterCall
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a padding-specific consumer
@@ -96,7 +96,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
result = this.(Call).getTarget().getName()
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
Crypto::TPaddingType getKnownPaddingType() {
this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5()
@@ -119,7 +119,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
)
or
isPaddingSpecificConsumer = false and
knownOpenSSLConstantToPaddingFamilyType(this, result)
knownOpenSslConstantToPaddingFamilyType(this, result)
}
}
@@ -127,7 +127,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
// // not the same as 'typical' constants found in the set of known algorithm constants
// // they do not have an NID
// // TODO: what about setting the padding directly?
// class KnownRSAPaddingConstant extends OpenSSLPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
// class KnownRSAPaddingConstant extends OpenSslPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
// {
// KnownRSAPaddingConstant() {
// // from rsa.h in openssl:
@@ -162,7 +162,7 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
// }
// }
class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance,
KnownOpenSSLPaddingConstantAlgorithmInstance
KnownOpenSslPaddingConstantAlgorithmInstance
{
OAEPPaddingAlgorithmInstance() {
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = Crypto::OAEP()

View File

@@ -10,11 +10,11 @@ private import AlgToAVCFlow
/**
* Gets the signature algorithm type based on the normalized algorithm name.
*/
private predicate knownOpenSSLConstantToSignatureFamilyType(
KnownOpenSSLSignatureAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
private predicate knownOpenSslConstantToSignatureFamilyType(
KnownOpenSslSignatureAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
) {
exists(string name |
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("RSA%") and type = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA())
or
@@ -30,30 +30,30 @@ private predicate knownOpenSSLConstantToSignatureFamilyType(
}
/**
* A signature algorithm instance derived from an OpenSSL constant.
* A signature algorithm instance derived from an OpenSsl constant.
*/
class KnownOpenSSLSignatureConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLSignatureAlgorithmExpr
class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslSignatureAlgorithmExpr
{
OpenSSLAlgorithmValueConsumer getterCall;
OpenSslAlgorithmValueConsumer getterCall;
KnownOpenSSLSignatureConstantAlgorithmInstance() {
KnownOpenSslSignatureConstantAlgorithmInstance() {
// 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 call, and we know we have an instance immediately from that
// 2) The source is a KnownOpenSslAlgorithm call, and we know we have an instance immediately from that
// Possibility 1:
this instanceof OpenSSLAlgorithmLiteral and
this instanceof OpenSslAlgorithmLiteral and
exists(DataFlow::Node src, DataFlow::Node sink |
// Sink is an argument to a signature getter call
sink = getterCall.getInputNode() and
// Source is `this`
src.asExpr() = this and
// This traces to a getter
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
)
or
// Possibility 2:
this instanceof OpenSSLAlgorithmCall and
this instanceof OpenSslAlgorithmCall and
getterCall = this
}
@@ -68,19 +68,19 @@ class KnownOpenSSLSignatureConstantAlgorithmInstance extends OpenSSLAlgorithmIns
}
override int getKeySizeFixed() {
// TODO: use ellipticCurveNameToKeySizeAndFamilyMapping or KnownOpenSSLEllipticCurveConstantAlgorithmInstance
// TODO: maybe add getExplicitKeySize to KnownOpenSSLSignatureAlgorithmExpr and use it here
// TODO: use ellipticCurveNameToKeySizeAndFamilyMapping or KnownOpenSslEllipticCurveConstantAlgorithmInstance
// TODO: maybe add getExplicitKeySize to KnownOpenSslSignatureAlgorithmExpr and use it here
none()
}
override KeyOpAlg::Algorithm getAlgorithmType() {
knownOpenSSLConstantToSignatureFamilyType(this, result)
knownOpenSslConstantToSignatureFamilyType(this, result)
or
not knownOpenSSLConstantToSignatureFamilyType(this, _) and
not knownOpenSslConstantToSignatureFamilyType(this, _) and
result = KeyOpAlg::TSignature(KeyOpAlg::OtherSignatureAlgorithmType())
}
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
// TODO: trace to any key size initializer

View File

@@ -4,14 +4,14 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import OpenSSLAlgorithmValueConsumerBase
abstract class CipherAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class CipherAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
// https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_fetch.html
class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPCipherAlgorithmValueConsumer() {
EvpCipherAlgorithmValueConsumer() {
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() in [
@@ -30,8 +30,8 @@ class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
// override DataFlow::Node getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
//TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to
// OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set.
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
//TODO: As a potential alternative, for OpenSsl only, add a generic source node for literals and only create flow (flowsTo) to
// OpenSsl AVCs... the unknown literal sources would have to be any literals not in the known set.
}
}

View File

@@ -10,7 +10,7 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
* Also includes operations directly using an algorithm
* like AES_encrypt().
*/
class DirectAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer instanceof OpenSSLAlgorithmCall
class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanceof OpenSslAlgorithmCall
{
/**
* These cases take in no explicit value (the value is implicit)
@@ -22,9 +22,9 @@ class DirectAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer instanc
* created as a result of this call.
*/
override DataFlow::Node getResultNode() {
this instanceof OpenSSLDirectAlgorithmFetchCall and
this instanceof OpenSslDirectAlgorithmFetchCall and
result.asExpr() = this
// NOTE: if instanceof OpenSSLDirectAlgorithmOperationCall then there is no algorithm generated
// NOTE: if instanceof OpenSslDirectAlgorithmOperationCall then there is no algorithm generated
// the algorithm is directly used
}

View File

@@ -4,14 +4,14 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
abstract class EllipticCurveValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class EllipticCurveValueConsumer extends OpenSslAlgorithmValueConsumer { }
//https://docs.openssl.org/3.0/man3/EC_KEY_new/#name
class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
class EvpEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPEllipticCurveAlgorithmConsumer() {
EvpEllipticCurveAlgorithmConsumer() {
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
(
this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and
@@ -25,7 +25,7 @@ class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
}
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
override DataFlow::Node getResultNode() { result = resultNode }

View File

@@ -4,20 +4,20 @@ private import semmle.code.cpp.dataflow.new.DataFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
abstract class HashAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class HashAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
/**
* EVP_Q_Digest directly consumes algorithm constant values
*/
class EVP_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
EVP_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
Evp_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
override Crypto::ConsumerInputDataFlowNode getInputNode() {
result.asExpr() = this.(Call).getArgument(1)
}
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
override DataFlow::Node getResultNode() {
@@ -50,7 +50,7 @@ class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer {
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}
@@ -59,11 +59,11 @@ class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer {
* https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
* https://docs.openssl.org/3.0/man3/EVP_DigestSignInit/#name
*/
class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPDigestAlgorithmValueConsumer() {
EvpDigestAlgorithmValueConsumer() {
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() in [
@@ -84,6 +84,6 @@ class EVPDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}

View File

@@ -4,13 +4,13 @@ private import semmle.code.cpp.dataflow.new.DataFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
abstract class KEMAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class KemAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
class EVPKEMAlgorithmValueConsumer extends KEMAlgorithmValueConsumer {
class EvpKemAlgorithmValueConsumer extends KemAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPKEMAlgorithmValueConsumer() {
EvpKemAlgorithmValueConsumer() {
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() = "EVP_KEM_fetch" and
@@ -23,6 +23,6 @@ class EVPKEMAlgorithmValueConsumer extends KEMAlgorithmValueConsumer {
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}

View File

@@ -4,13 +4,13 @@ private import semmle.code.cpp.dataflow.new.DataFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
abstract class KeyExchangeAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class KeyExchangeAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
class EVPKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer {
class EvpKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPKeyExchangeAlgorithmValueConsumer() {
EvpKeyExchangeAlgorithmValueConsumer() {
resultNode.asExpr() = this and
(
this.(Call).getTarget().getName() = "EVP_KEYEXCH_fetch" and
@@ -23,6 +23,6 @@ class EVPKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueCons
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}

View File

@@ -1,6 +1,6 @@
private import experimental.quantum.Language
abstract class OpenSSLAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
abstract class OpenSslAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
/**
* Returns the node representing the resulting algorithm
*/

View File

@@ -4,13 +4,13 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
abstract class PKeyValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class PKeyValueConsumer extends OpenSslAlgorithmValueConsumer { }
class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer {
class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPPKeyAlgorithmConsumer() {
EvpPKeyAlgorithmConsumer() {
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
(
// NOTE: some of these consumers are themselves key gen operations,
@@ -47,7 +47,7 @@ class EVPPKeyAlgorithmConsumer extends PKeyValueConsumer {
}
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
override DataFlow::Node getResultNode() { result = resultNode }

View File

@@ -4,16 +4,16 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmCon
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import OpenSSLAlgorithmValueConsumerBase
abstract class PaddingAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class PaddingAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
// https://docs.openssl.org/master/man7/EVP_ASYM_CIPHER-RSA/#rsa-asymmetric-cipher-parameters
// TODO: need to handle setting padding through EVP_PKEY_CTX_set_params, where modes like "OSSL_PKEY_RSA_PAD_MODE_OAEP"
// are set.
class EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorithmValueConsumer {
class Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer() {
Evp_PKey_Ctx_set_rsa_padding_AlgorithmValueConsumer() {
resultNode.asExpr() = this and
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_set_rsa_padding" and
valueArgNode.asExpr() = this.(Call).getArgument(1)
@@ -25,8 +25,8 @@ class EVP_PKEY_CTX_set_rsa_padding_AlgorithmValueConsumer extends PaddingAlgorit
// override DataFlow::Node getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
//TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to
// OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set.
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
//TODO: As a potential alternative, for OpenSsl only, add a generic source node for literals and only create flow (flowsTo) to
// OpenSsl AVCs... the unknown literal sources would have to be any literals not in the known set.
}
}

View File

@@ -5,13 +5,13 @@ private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmI
private import OpenSSLAlgorithmValueConsumerBase
private import experimental.quantum.OpenSSL.LibraryDetector
abstract class SignatureAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
abstract class SignatureAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
class EVPSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer {
class EvpSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer {
DataFlow::Node valueArgNode;
DataFlow::Node resultNode;
EVPSignatureAlgorithmValueConsumer() {
EvpSignatureAlgorithmValueConsumer() {
resultNode.asExpr() = this and
(
// EVP_SIGNATURE
@@ -27,6 +27,6 @@ class EVPSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
}
}

View File

@@ -2,11 +2,11 @@ import semmle.code.cpp.dataflow.new.DataFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
/**
* Flows from algorithm values to operations, specific to OpenSSL
* Flows from algorithm values to operations, specific to OpenSsl
*/
module AvcToCallArgConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
exists(OpenSSLAlgorithmValueConsumer c | c.getResultNode() = source)
exists(OpenSslAlgorithmValueConsumer c | c.getResultNode() = source)
}
/**

View File

@@ -193,7 +193,7 @@ class CtxPointerSource extends CtxPointerExpr {
/**
* Flow from any CtxPointerSource to other CtxPointerSource.
*/
module OpenSSLCtxSourceToSourceFlowConfig implements DataFlow::ConfigSig {
module OpenSslCtxSourceToSourceFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { exists(CtxPointerSource s | s.asNode() = source) }
predicate isSink(DataFlow::Node sink) { exists(CtxPointerSource s | s.asNode() = sink) }
@@ -207,14 +207,14 @@ module OpenSSLCtxSourceToSourceFlowConfig implements DataFlow::ConfigSig {
}
}
module OpenSSLCtxSourceToArgumentFlow = DataFlow::Global<OpenSSLCtxSourceToSourceFlowConfig>;
module OpenSslCtxSourceToArgumentFlow = DataFlow::Global<OpenSslCtxSourceToSourceFlowConfig>;
/**
* Holds if there is a context flow from the source to the sink.
*/
predicate ctxSrcToSrcFlow(CtxPointerSource source, CtxPointerSource sink) {
exists(DataFlow::Node a, DataFlow::Node b |
OpenSSLCtxSourceToArgumentFlow::flow(a, b) and
OpenSslCtxSourceToArgumentFlow::flow(a, b) and
a = source.asNode() and
b = sink.asNode()
)

View File

@@ -14,9 +14,9 @@ private class IntLiteral extends Literal {
/**
* Holds if a StringLiteral could conceivably be used in some way for cryptography.
* Note: this predicate should only consider restrictions with respect to strings only.
* General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
* General restrictions are in the OpenSslGenericSourceCandidateLiteral class.
*/
private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s) {
private predicate isOpenSslStringLiteralGenericSourceCandidate(StringLiteral s) {
// 'EC' is a constant that may be used where typical algorithms are specified,
// but EC specifically means set up a default curve container, that will later be
//specified explicitly (or if not a default) curve is used.
@@ -49,9 +49,9 @@ private predicate isOpenSSLStringLiteralGenericSourceCandidate(StringLiteral s)
/**
* Holds if a StringLiteral could conceivably be used in some way for cryptography.
* Note: this predicate should only consider restrictions with respect to integers only.
* General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
* General restrictions are in the OpenSslGenericSourceCandidateLiteral class.
*/
private predicate isOpenSSLIntLiteralGenericSourceCandidate(IntLiteral l) {
private predicate isOpenSslIntLiteralGenericSourceCandidate(IntLiteral l) {
// Ignore integer values of 0, commonly referring to NULL only (no known algorithm 0)
l.getValue().toInt() != 0 and
// ASSUMPTION, no negative numbers are allowed
@@ -102,11 +102,11 @@ private predicate isOpenSSLIntLiteralGenericSourceCandidate(IntLiteral l) {
* "AES" may be a legitimate algorithm literal, but the literal will not be used for an operation directly
* since it is in a equality comparison, hence this case would also be filtered.
*/
class OpenSSLGenericSourceCandidateLiteral extends Literal {
OpenSSLGenericSourceCandidateLiteral() {
class OpenSslGenericSourceCandidateLiteral extends Literal {
OpenSslGenericSourceCandidateLiteral() {
(
isOpenSSLIntLiteralGenericSourceCandidate(this) or
isOpenSSLStringLiteralGenericSourceCandidate(this)
isOpenSslIntLiteralGenericSourceCandidate(this) or
isOpenSslStringLiteralGenericSourceCandidate(this)
) and
// ********* General filters beyond what is filtered for strings and ints *********
// An algorithm literal in a switch case will not be directly applied to an operation.

View File

@@ -5,10 +5,10 @@ private import experimental.quantum.Language
/**
* Flow from key creation to key used in a call
*/
module OpenSSLKeyFlowConfig implements DataFlow::ConfigSig {
module OpenSslKeyFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// NOTE/ASSUMPTION: it is assumed the operation is also an OpenSSLOperation.
// All operations modeled for openssl should be modeled as OpenSSLOperation.
// NOTE/ASSUMPTION: it is assumed the operation is also an OpenSslOperation.
// All operations modeled for openssl should be modeled as OpenSslOperation.
exists(Crypto::KeyCreationOperationInstance keygen | keygen.getOutputKeyArtifact() = source)
}
@@ -16,11 +16,11 @@ module OpenSSLKeyFlowConfig implements DataFlow::ConfigSig {
//TODO: consideration for additional flow steps? Can a key be copied for example?
}
module OpenSSLKeyFlow = TaintTracking::Global<OpenSSLKeyFlowConfig>;
module OpenSslKeyFlow = TaintTracking::Global<OpenSslKeyFlowConfig>;
Crypto::KeyCreationOperationInstance getSourceKeyCreationInstanceFromArg(Expr arg) {
exists(DataFlow::Node src, DataFlow::Node sink |
OpenSSLKeyFlow::flow(src, sink) and
OpenSslKeyFlow::flow(src, sink) and
result.getOutputKeyArtifact() = src and
sink.asExpr() = arg
)

View File

@@ -1,7 +1,7 @@
import cpp
predicate isPossibleOpenSSLFunction(Function f) {
isPossibleOpenSSLLocation(f.getADeclarationLocation())
predicate isPossibleOpenSslFunction(Function f) {
isPossibleOpenSslLocation(f.getADeclarationLocation())
}
predicate isPossibleOpenSSLLocation(Location l) { l.toString().toLowerCase().matches("%openssl%") }
predicate isPossibleOpenSslLocation(Location l) { l.toString().toLowerCase().matches("%openssl%") }

View File

@@ -1,4 +1,4 @@
module OpenSSLModel {
module OpenSslModel {
import AlgorithmInstances.OpenSSLAlgorithmInstances
import AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
import Operations.OpenSSLOperations

View File

@@ -1,10 +1,9 @@
private import experimental.quantum.Language
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
private import OpenSSLOperationBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
private import semmle.code.cpp.dataflow.new.DataFlow
class ECKeyGenOperation extends OpenSSLOperation, Crypto::KeyGenerationOperationInstance {
class ECKeyGenOperation extends OpenSslOperation, Crypto::KeyGenerationOperationInstance {
ECKeyGenOperation() { this.(Call).getTarget().getName() = "EC_KEY_generate_key" }
override Expr getAlgorithmArg() { result = this.(Call).getArgument(0) }

View File

@@ -4,7 +4,7 @@ private import OpenSSLOperationBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
// TODO: need to add key consumer
abstract class EVP_Cipher_Initializer extends EvpKeyOperationSubtypeInitializer,
abstract class Evp_Cipher_Initializer extends EvpKeyOperationSubtypeInitializer,
EvpPrimaryAlgorithmInitializer, EvpKeyInitializer, EvpIVInitializer
{
override CtxPointerSource getContext() { result = this.(Call).getArgument(0) }
@@ -12,7 +12,7 @@ abstract class EVP_Cipher_Initializer extends EvpKeyOperationSubtypeInitializer,
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
}
abstract class EVP_EX_Initializer extends EVP_Cipher_Initializer {
abstract class Evp_EX_Initializer extends Evp_Cipher_Initializer {
override Expr getKeyArg() {
// Null key indicates the key is not actually set
// This pattern can occur during a multi-step initialization
@@ -30,13 +30,13 @@ abstract class EVP_EX_Initializer extends EVP_Cipher_Initializer {
}
}
abstract class EVP_EX2_Initializer extends EVP_Cipher_Initializer {
abstract class Evp_EX2_Initializer extends Evp_Cipher_Initializer {
override Expr getKeyArg() { result = this.(Call).getArgument(2) }
override Expr getIVArg() { result = this.(Call).getArgument(3) }
}
class EvpCipherEXInitCall extends EVP_EX_Initializer {
class EvpCipherEXInitCall extends Evp_EX_Initializer {
EvpCipherEXInitCall() {
this.(Call).getTarget().getName() in [
"EVP_EncryptInit_ex", "EVP_DecryptInit_ex", "EVP_CipherInit_ex"
@@ -56,8 +56,8 @@ class EvpCipherEXInitCall extends EVP_EX_Initializer {
// else
// if this.(Call).getTarget().getName().toLowerCase().matches("%decrypt%")
// then result instanceof Crypto::TDecryptMode
class EVP_Cipher_EX2_or_Simple_Init_Call extends EVP_EX2_Initializer {
EVP_Cipher_EX2_or_Simple_Init_Call() {
class Evp_Cipher_EX2_or_Simple_Init_Call extends Evp_EX2_Initializer {
Evp_Cipher_EX2_or_Simple_Init_Call() {
this.(Call).getTarget().getName() in [
"EVP_EncryptInit_ex2", "EVP_DecryptInit_ex2", "EVP_CipherInit_ex2", "EVP_EncryptInit",
"EVP_DecryptInit", "EVP_CipherInit"
@@ -70,14 +70,14 @@ class EVP_Cipher_EX2_or_Simple_Init_Call extends EVP_EX2_Initializer {
}
}
class EVP_CipherInit_SKEY_Call extends EVP_EX2_Initializer {
EVP_CipherInit_SKEY_Call() { this.(Call).getTarget().getName() in ["EVP_CipherInit_SKEY"] }
class Evp_CipherInit_SKey_Call extends Evp_EX2_Initializer {
Evp_CipherInit_SKey_Call() { this.(Call).getTarget().getName() = "EVP_CipherInit_SKEY" }
override Expr getKeyOperationSubtypeArg() { result = this.(Call).getArgument(5) }
}
class EVP_Cipher_Update_Call extends EvpUpdate {
EVP_Cipher_Update_Call() {
class Evp_Cipher_Update_Call extends EvpUpdate {
Evp_Cipher_Update_Call() {
this.(Call).getTarget().getName() in [
"EVP_EncryptUpdate", "EVP_DecryptUpdate", "EVP_CipherUpdate"
]
@@ -94,7 +94,7 @@ class EVP_Cipher_Update_Call extends EvpUpdate {
* see: https://docs.openssl.org/master/man3/EVP_EncryptInit/#synopsis
* Base configuration for all EVP cipher operations.
*/
abstract class EVP_Cipher_Operation extends EvpOperation, Crypto::KeyOperationInstance {
abstract class Evp_Cipher_Operation extends EvpOperation, Crypto::KeyOperationInstance {
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
@@ -126,8 +126,8 @@ abstract class EVP_Cipher_Operation extends EvpOperation, Crypto::KeyOperationIn
}
}
class EVP_Cipher_Call extends EvpOperation, EVP_Cipher_Operation {
EVP_Cipher_Call() { this.(Call).getTarget().getName() = "EVP_Cipher" }
class Evp_Cipher_Call extends EvpOperation, Evp_Cipher_Operation {
Evp_Cipher_Call() { this.(Call).getTarget().getName() = "EVP_Cipher" }
override Expr getInputArg() { result = this.(Call).getArgument(2) }
@@ -138,8 +138,8 @@ class EVP_Cipher_Call extends EvpOperation, EVP_Cipher_Operation {
override CtxPointerSource getContext() { result = this.(Call).getArgument(0) }
}
class EVP_Cipher_Final_Call extends EVPFinal, EVP_Cipher_Operation {
EVP_Cipher_Final_Call() {
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"
@@ -150,9 +150,9 @@ class EVP_Cipher_Final_Call extends EVPFinal, EVP_Cipher_Operation {
* Output is both from update calls and from the final call.
*/
override Expr getOutputArg() {
result = EVPFinal.super.getOutputArg()
result = EvpFinal.super.getOutputArg()
or
result = EVP_Cipher_Operation.super.getOutputArg()
result = Evp_Cipher_Operation.super.getOutputArg()
}
override Expr getAlgorithmArg() {
@@ -166,7 +166,7 @@ class EVP_Cipher_Final_Call extends EVPFinal, EVP_Cipher_Operation {
* https://docs.openssl.org/3.2/man3/EVP_PKEY_decrypt/
* https://docs.openssl.org/3.2/man3/EVP_PKEY_encrypt
*/
class Evp_PKey_Cipher_Operation extends EVP_Cipher_Operation {
class Evp_PKey_Cipher_Operation extends Evp_Cipher_Operation {
Evp_PKey_Cipher_Operation() {
this.(Call).getTarget().getName() in ["EVP_PKEY_encrypt", "EVP_PKEY_decrypt"]
}

View File

@@ -7,8 +7,8 @@ private import experimental.quantum.OpenSSL.CtxFlow
private import OpenSSLOperationBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
class EVP_DigestInit_Variant_Calls extends EvpPrimaryAlgorithmInitializer {
EVP_DigestInit_Variant_Calls() {
class Evp_DigestInit_Variant_Calls extends EvpPrimaryAlgorithmInitializer {
Evp_DigestInit_Variant_Calls() {
this.(Call).getTarget().getName() in [
"EVP_DigestInit", "EVP_DigestInit_ex", "EVP_DigestInit_ex2"
]
@@ -19,8 +19,8 @@ class EVP_DigestInit_Variant_Calls extends EvpPrimaryAlgorithmInitializer {
override CtxPointerSource getContext() { result = this.(Call).getArgument(0) }
}
class EVP_Digest_Update_Call extends EvpUpdate {
EVP_Digest_Update_Call() { this.(Call).getTarget().getName() = "EVP_DigestUpdate" }
class Evp_Digest_Update_Call extends EvpUpdate {
Evp_Digest_Update_Call() { this.(Call).getTarget().getName() = "EVP_DigestUpdate" }
override Expr getInputArg() { result = this.(Call).getArgument(1) }
@@ -28,8 +28,8 @@ class EVP_Digest_Update_Call extends EvpUpdate {
}
//https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
class EVP_Q_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance {
EVP_Q_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
class Evp_Q_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance {
Evp_Q_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
override Expr getAlgorithmArg() { result = this.(Call).getArgument(1) }
@@ -54,8 +54,8 @@ class EVP_Q_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance
override CtxPointerSource getContext() { result = this.(Call).getArgument(0) }
}
class EVP_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance {
EVP_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Digest" }
class Evp_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance {
Evp_Digest_Operation() { this.(Call).getTarget().getName() = "EVP_Digest" }
// There is no context argument for this function
override CtxPointerSource getContext() { none() }
@@ -81,8 +81,8 @@ class EVP_Digest_Operation extends EvpOperation, Crypto::HashOperationInstance {
}
}
class EVP_Digest_Final_Call extends EVPFinal, Crypto::HashOperationInstance {
EVP_Digest_Final_Call() {
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"
]
@@ -93,11 +93,11 @@ class EVP_Digest_Final_Call extends EVPFinal, Crypto::HashOperationInstance {
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
result = EVPFinal.super.getOutputArtifact()
result = EvpFinal.super.getOutputArtifact()
}
override Crypto::ConsumerInputDataFlowNode getInputConsumer() {
result = EVPFinal.super.getInputConsumer()
result = EvpFinal.super.getInputConsumer()
}
override Expr getAlgorithmArg() {

View File

@@ -3,8 +3,8 @@ private import experimental.quantum.OpenSSL.CtxFlow
private import OpenSSLOperationBase
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
class EVPKeyGenInitialize extends EvpPrimaryAlgorithmInitializer {
EVPKeyGenInitialize() {
class EvpKeyGenInitialize extends EvpPrimaryAlgorithmInitializer {
EvpKeyGenInitialize() {
this.(Call).getTarget().getName() in [
"EVP_PKEY_keygen_init",
"EVP_PKEY_paramgen_init"
@@ -23,10 +23,10 @@ class EVPKeyGenInitialize extends EvpPrimaryAlgorithmInitializer {
override CtxPointerSource getContext() { result = this.(Call).getArgument(0) }
}
class EVPKeyGenOperation extends EvpOperation, Crypto::KeyGenerationOperationInstance {
class EvpKeyGenOperation extends EvpOperation, Crypto::KeyGenerationOperationInstance {
DataFlow::Node keyResultNode;
EVPKeyGenOperation() {
EvpKeyGenOperation() {
this.(Call).getTarget().getName() in ["EVP_RSA_gen", "EVP_PKEY_Q_keygen"] and
keyResultNode.asExpr() = this
or

View File

@@ -19,10 +19,10 @@ private import OpenSSLOperations
* will get all associated initializers for the paramgen
* at the final keygen operation automatically.
*/
class EVPNewKeyCtx extends EvpKeyInitializer {
class EvpNewKeyCtx extends EvpKeyInitializer {
Expr keyArg;
EVPNewKeyCtx() {
EvpNewKeyCtx() {
this.(Call).getTarget().getName() = "EVP_PKEY_CTX_new" and
keyArg = this.(Call).getArgument(0)
or

View File

@@ -59,8 +59,8 @@ class EvpSignaturePrimaryAlgorithmInitializer extends EvpPrimaryAlgorithmInitial
override CtxPointerSource getContext() { result = this.(Call).getArgument(0) }
}
class EVP_Signature_Update_Call extends EvpUpdate {
EVP_Signature_Update_Call() {
class Evp_Signature_Update_Call extends EvpUpdate {
Evp_Signature_Update_Call() {
this.(Call).getTarget().getName() in [
"EVP_DigestSignUpdate", "EVP_SignUpdate", "EVP_PKEY_sign_message_update"
]
@@ -108,7 +108,7 @@ abstract class EvpSignatureOperation extends EvpOperation, Crypto::SignatureOper
}
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
AvcToCallArgFlow::flow(result.(OpenSSLAlgorithmValueConsumer).getResultNode(),
AvcToCallArgFlow::flow(result.(OpenSslAlgorithmValueConsumer).getResultNode(),
DataFlow::exprNode(this.getHashAlgorithmArg()))
}
@@ -132,7 +132,7 @@ abstract class EvpSignatureOperation extends EvpOperation, Crypto::SignatureOper
/**
* Keys provided in the initialization call or in a context are found by this method.
* Keys in explicit arguments are found by overriden methods in extending classes.
* Keys in explicit arguments are found by overridden methods in extending classes.
*/
override Crypto::ConsumerInputDataFlowNode getKeyConsumer() {
result = DataFlow::exprNode(this.getInitCall().(EvpKeyInitializer).getKeyArg())
@@ -152,8 +152,8 @@ abstract class EvpSignatureOperation extends EvpOperation, Crypto::SignatureOper
override Crypto::ConsumerInputDataFlowNode getSignatureConsumer() { none() }
}
class EVP_Signature_Call extends EvpSignatureOperation {
EVP_Signature_Call() { this.(Call).getTarget().getName() in ["EVP_DigestSign", "EVP_PKEY_sign"] }
class Evp_Signature_Call extends EvpSignatureOperation {
Evp_Signature_Call() { this.(Call).getTarget().getName() in ["EVP_DigestSign", "EVP_PKEY_sign"] }
/**
* Output is the signature.
@@ -168,8 +168,8 @@ class EVP_Signature_Call extends EvpSignatureOperation {
override Expr getInputArg() { result = this.(Call).getArgument(3) }
}
class EVP_Signature_Final_Call extends EVPFinal, EvpSignatureOperation {
EVP_Signature_Final_Call() {
class Evp_Signature_Final_Call extends EvpFinal, EvpSignatureOperation {
Evp_Signature_Final_Call() {
this.(Call).getTarget().getName() in [
"EVP_DigestSignFinal",
"EVP_SignFinal_ex",

View File

@@ -4,7 +4,7 @@ private import experimental.quantum.OpenSSL.CtxFlow
private import experimental.quantum.OpenSSL.KeyFlow
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
// Importing these intializers here to ensure the are part of any model that is
// using OpenSSLOperationBase. This futher ensures that initializers are tied to opeartions
// using OpenSslOperationBase. This further ensures that initializers are tied to opeartions
// even if only importing the operation by itself.
import EVPPKeyCtxInitializer
@@ -20,7 +20,7 @@ module EncValToInitEncArgConfig implements DataFlow::ConfigSig {
module EncValToInitEncArgFlow = DataFlow::Global<EncValToInitEncArgConfig>;
private predicate argToAVC(Expr arg, Crypto::AlgorithmValueConsumer avc) {
private predicate argToAvc(Expr arg, Crypto::AlgorithmValueConsumer avc) {
// NOTE: because we trace through keys to their sources we must consider that the arg is an avc
// Consider this example:
// EVP_PKEY *pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, key_len);
@@ -32,14 +32,14 @@ private predicate argToAVC(Expr arg, Crypto::AlgorithmValueConsumer avc) {
// This should only occur due to tracing through keys to find configuration data.
avc.getInputNode().asExpr() = arg
or
AvcToCallArgFlow::flow(avc.(OpenSSLAlgorithmValueConsumer).getResultNode(),
AvcToCallArgFlow::flow(avc.(OpenSslAlgorithmValueConsumer).getResultNode(),
DataFlow::exprNode(arg))
}
/**
* A class for all OpenSSL operations.
* A class for all OpenSsl operations.
*/
abstract class OpenSSLOperation extends Crypto::OperationInstance instanceof Call {
abstract class OpenSslOperation extends Crypto::OperationInstance instanceof Call {
/**
* Gets the argument that specifies the algorithm for the operation.
* This argument might not be immediately present at the specified operation.
@@ -53,7 +53,7 @@ abstract class OpenSSLOperation extends Crypto::OperationInstance instanceof Cal
* Algorithm is specified in initialization call or is implicitly established by the key.
*/
override Crypto::AlgorithmValueConsumer getAnAlgorithmValueConsumer() {
argToAVC(this.getAlgorithmArg(), result)
argToAvc(this.getAlgorithmArg(), result)
}
}
@@ -73,10 +73,16 @@ abstract class EvpInitializer extends Call {
abstract CtxPointerSource getContext();
}
/**
* A call to initialize a key size.
*/
abstract class EvpKeySizeInitializer extends EvpInitializer {
abstract Expr getKeySizeArg();
}
/**
* A call to initialize a key operation subtype.
*/
abstract class EvpKeyOperationSubtypeInitializer extends EvpInitializer {
abstract Expr getKeyOperationSubtypeArg();
@@ -115,10 +121,13 @@ abstract class EvpPrimaryAlgorithmInitializer extends EvpInitializer {
abstract Expr getAlgorithmArg();
Crypto::AlgorithmValueConsumer getAlgorithmValueConsumer() {
argToAVC(this.getAlgorithmArg(), result)
argToAvc(this.getAlgorithmArg(), result)
}
}
/**
* A call to initialize a key.
*/
abstract class EvpKeyInitializer extends EvpInitializer {
abstract Expr getKeyArg();
}
@@ -135,7 +144,7 @@ class EvpInitializerThroughKey extends EvpPrimaryAlgorithmInitializer, EvpKeySiz
override Expr getAlgorithmArg() {
result =
getSourceKeyCreationInstanceFromArg(this.getKeyArg()).(OpenSSLOperation).getAlgorithmArg()
getSourceKeyCreationInstanceFromArg(this.getKeyArg()).(OpenSslOperation).getAlgorithmArg()
}
override Expr getKeySizeArg() {
@@ -175,6 +184,9 @@ abstract class EvpIVInitializer extends EvpInitializer {
abstract Expr getIVArg();
}
/**
* A call to initialize padding.
*/
abstract class EvpPaddingInitializer extends EvpInitializer {
/**
* Gets the padding mode argument.
@@ -183,6 +195,9 @@ abstract class EvpPaddingInitializer extends EvpInitializer {
abstract Expr getPaddingArg();
}
/**
* A call to initialize a salt length.
*/
abstract class EvpSaltLengthInitializer extends EvpInitializer {
/**
* Gets the salt length argument.
@@ -191,11 +206,14 @@ abstract class EvpSaltLengthInitializer extends EvpInitializer {
abstract Expr getSaltLengthArg();
}
/**
* A call to initialize a hash algorithm.
*/
abstract class EvpHashAlgorithmInitializer extends EvpInitializer {
abstract Expr getHashAlgorithmArg();
Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
argToAVC(this.getHashAlgorithmArg(), result)
argToAvc(this.getHashAlgorithmArg(), result)
}
}
@@ -228,7 +246,7 @@ abstract class EvpUpdate extends Call {
* This captures one-shot APIs (with and without an initilizer call) and final calls.
* Provides some default methods for Crypto::KeyOperationInstance class.
*/
abstract class EvpOperation extends OpenSSLOperation {
abstract class EvpOperation extends OpenSslOperation {
/**
* Gets the context argument that ties together initialization, updates and/or final calls.
*/
@@ -269,7 +287,7 @@ abstract class EvpOperation extends OpenSSLOperation {
* e.g., "EVP_DigestFinal", "EVP_EncryptFinal", etc.
* however, this is not a strict rule.
*/
abstract class EVPFinal extends EvpOperation {
abstract class EvpFinal extends EvpOperation {
/**
* All update calls that were executed before this final call.
*/

View File

@@ -4,4 +4,3 @@ import EVPHashOperation
import ECKeyGenOperation
import EVPSignatureOperation
import EVPKeyGenOperation
import EVPPKeyCtxInitializer

View File

@@ -3,11 +3,10 @@ private import experimental.quantum.Language
private import LibraryDetector
private import semmle.code.cpp.dataflow.new.DataFlow
class OpenSSLRandomNumberGeneratorInstance extends Crypto::RandomNumberGenerationInstance instanceof Call
class OpenSslRandomNumberGeneratorInstance extends Crypto::RandomNumberGenerationInstance instanceof Call
{
OpenSSLRandomNumberGeneratorInstance() {
this.(Call).getTarget().getName() in ["RAND_bytes", "RAND_pseudo_bytes"] and
isPossibleOpenSSLFunction(this.(Call).getTarget())
OpenSslRandomNumberGeneratorInstance() {
this.(Call).getTarget().getName() in ["RAND_bytes", "RAND_pseudo_bytes"]
}
override Crypto::DataFlowNode getOutputNode() {