Skip to content

Openssl acronym normalization #19785

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
39583ab
Crypto: Update KnownAlgoirthmConstants to make a distinction between …
bdrodes Jun 4, 2025
952bc26
Crypto: Added Signature algorithm instance and consumer
bdrodes Jun 4, 2025
33e239d
Crypto: Collapse initializer qll's into operations.
bdrodes Jun 4, 2025
f952f90
Crypto: Update CtxFlow to flow from any "source ctx" which is any ctx…
bdrodes Jun 4, 2025
98aae6a
Crypto: Add EVP key gen and signature operation (work in progress). A…
bdrodes Jun 5, 2025
4f2045b
Crypto: CtxFlow now uses an interface for additional steps. Add CTX s…
bdrodes Jun 9, 2025
729467c
Crypto: Separate out CTX parameter initialization, and add additional…
bdrodes Jun 9, 2025
7d47994
Crypto: Nop out signature operations for now until complete. Minor mo…
bdrodes Jun 10, 2025
d3cff2d
Crypto: Add support to trace keys, add support to find prior key gen …
bdrodes Jun 11, 2025
8f25380
Crypto: Consolidate tests to use node, edges, and properties.
bdrodes Jun 11, 2025
20e2c7c
Crypto: Overhaul/refactor of EVPInitialzers. Update cipher operation …
bdrodes Jun 12, 2025
eb20955
Crypto: Further simplify test caes to only use edges/nodes/properties…
bdrodes Jun 12, 2025
cf2f0f1
Crypto: Initial model of signatures. Still incomplete for verificatio…
bdrodes Jun 13, 2025
fb495bf
Crypto: Update expected files. There are failures, but accepting them…
bdrodes Jun 13, 2025
1882db7
Crypto: EVP Signature Operation cleanup.
bdrodes Jun 13, 2025
db0bc47
Merge branch 'main' into pawel_signatures_conversion
nicolaswill Jun 15, 2025
f975428
Merge branch 'main' into pawel_signatures_conversion
nicolaswill Jun 16, 2025
45fa2c9
Crypto: Code review cleanup.
bdrodes Jun 16, 2025
90e480b
Merge branch 'pawel_signatures_conversion' of https://github.com/bdro…
bdrodes Jun 16, 2025
790a607
Crypto: Acronym change from OpenSSL to OpenSsl, AVC to Avc and EVP to…
bdrodes Jun 16, 2025
7c18686
Crypto: Further ql-for-ql alert alert fixes.
bdrodes Jun 16, 2025
2b6a832
Crypto: Update JCA model to account for Model.qll changes.
bdrodes Jun 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions cpp/ql/lib/experimental/quantum/Language.qll
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
LocatableElement dfn_to_element(DataFlow::Node node) {
result = node.asExpr() or
result = node.asParameter() or
result = node.asVariable()
result = node.asVariable() or
result = node.asDefiningArgument()
// TODO: do we need asIndirectExpr()?
}

string locationToFileBaseNameAndLineNumberString(Location location) {
Expand Down Expand Up @@ -87,10 +89,10 @@
}
}

module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;

Check warning

Code scanning / CodeQL

Suggest using non-extending subtype relationships. Warning

Consider defining this class as non-extending subtype of
OpenSSLGenericSourceCandidateLiteral
.

private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
ConstantDataSource() { this instanceof OpenSSLGenericSourceCandidateLiteral }
ConstantDataSource() { this instanceof OpenSslGenericSourceCandidateLiteral }

override DataFlow::Node getOutputNode() { result.asExpr() = this }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +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 KnownOpenSSLAlgorithmConstant
source.asExpr() instanceof KnownOpenSslAlgorithmExpr and
// No need to flow direct operations to AVCs
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
Expand All @@ -43,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)
Expand All @@ -61,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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import AlgToAVCFlow

/**
* Given a `KnownOpenSSLBlockModeAlgorithmConstant`, 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(
KnownOpenSSLBlockModeAlgorithmConstant e, Crypto::TBlockCipherModeOfOperationType type
predicate knownOpenSslConstantToBlockModeFamilyType(
KnownOpenSslBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type
) {
exists(string name |
name = e.getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("CBC") and type instanceof Crypto::CBC
or
Expand All @@ -39,34 +39,35 @@ predicate knownOpenSSLConstantToBlockModeFamilyType(
)
}

class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLBlockModeAlgorithmConstant
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 Literal 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 DirectAlgorithmValueConsumer and getterCall = this
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
Expand All @@ -77,5 +78,5 @@ class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmIns
result = this.(Call).getTarget().getName()
}

override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ private import AlgToAVCFlow
private import BlockAlgorithmInstance

/**
* Given a `KnownOpenSSLCipherAlgorithmConstant`, 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(
KnownOpenSSLCipherAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type
predicate knownOpenSslConstantToCipherFamilyType(
KnownOpenSslCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
) {
exists(string name |
name = e.getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("AES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
or
Expand Down Expand Up @@ -64,28 +64,29 @@ predicate knownOpenSSLConstantToCipherFamilyType(
)
}

class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLCipherAlgorithmConstant
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 Literal 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 DirectAlgorithmValueConsumer and getterCall = this
this instanceof OpenSslAlgorithmCall and
getterCall = this
}

override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
Expand All @@ -109,17 +110,17 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstan
}

override int getKeySizeFixed() {
this.(KnownOpenSSLCipherAlgorithmConstant).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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +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 KnownOpenSSLEllipticCurveAlgorithmConstant
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 Literal 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 DirectAlgorithmValueConsumer and getterCall = this
this instanceof OpenSslAlgorithmCall and
getterCall = this
}

override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }

override string getRawEllipticCurveName() {
result = this.(Literal).getValue().toString()
Expand All @@ -43,11 +44,11 @@ class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorith
}

override string getParsedEllipticCurveName() {
result = this.(KnownOpenSSLEllipticCurveAlgorithmConstant).getNormalizedName()
result = this.(KnownOpenSslAlgorithmExpr).getNormalizedName()
}

override int getKeySize() {
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant)
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
.getNormalizedName(), result, _)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgor
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
private import AlgToAVCFlow

predicate knownOpenSSLConstantToHashFamilyType(
KnownOpenSSLHashAlgorithmConstant e, Crypto::THashType type
predicate knownOpenSslConstantToHashFamilyType(
KnownOpenSslHashAlgorithmExpr e, Crypto::THashType type
) {
exists(string name |
name = e.getNormalizedName() and
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
(
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
or
Expand All @@ -29,7 +29,7 @@ predicate knownOpenSSLConstantToHashFamilyType(
or
name.matches(["SHA", "SHA1"]) and type instanceof Crypto::SHA1
or
name.matches("SHA+%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
name.matches("SHA_%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
or
name.matches("SHA3-%") and type instanceof Crypto::SHA3
or
Expand All @@ -44,36 +44,37 @@ predicate knownOpenSSLConstantToHashFamilyType(
)
}

class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
Crypto::HashAlgorithmInstance instanceof KnownOpenSSLHashAlgorithmConstant
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 Literal 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 DirectAlgorithmValueConsumer and getterCall = this
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() {
Expand All @@ -83,6 +84,6 @@ class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance
}

override int getFixedDigestLength() {
this.(KnownOpenSSLHashAlgorithmConstant).getExplicitDigestLength() = result
this.(KnownOpenSslHashAlgorithmExpr).getExplicitDigestLength() = result
}
}
Loading
Loading