Skip to content

Commit 952bc26

Browse files
committed
Crypto: Added Signature algorithm instance and consumer
1 parent 39583ab commit 952bc26

File tree

4 files changed

+137
-5
lines changed

4 files changed

+137
-5
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import cpp
2+
private import experimental.quantum.Language
3+
private import KnownAlgorithmConstants
4+
private import Crypto::KeyOpAlg as KeyOpAlg
5+
private import OpenSSLAlgorithmInstanceBase
6+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
7+
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
8+
private import AlgToAVCFlow
9+
10+
/**
11+
* Gets the signature algorithm type based on the normalized algorithm name.
12+
*/
13+
private predicate knownOpenSSLConstantToSignatureFamilyType(
14+
KnownOpenSSLSignatureAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
15+
) {
16+
exists(string name |
17+
name = e.(KnownOpenSSLAlgorithmExpr).getNormalizedName() and
18+
(
19+
name.matches("RSA%") and type = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA())
20+
or
21+
name.matches("DSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::DSA())
22+
or
23+
name.matches("ECDSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::ECDSA())
24+
or
25+
name.matches("ED25519%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA())
26+
or
27+
name.matches("ED448%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA())
28+
)
29+
)
30+
}
31+
32+
/**
33+
* A signature algorithm instance derived from an OpenSSL constant.
34+
*/
35+
class KnownOpenSSLSignatureConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
36+
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLSignatureAlgorithmExpr
37+
{
38+
OpenSSLAlgorithmValueConsumer getterCall;
39+
40+
KnownOpenSSLSignatureConstantAlgorithmInstance() {
41+
// Two possibilities:
42+
// 1) The source is a literal and flows to a getter, then we know we have an instance
43+
// 2) The source is a KnownOpenSSLAlgorithm call, and we know we have an instance immediately from that
44+
// Possibility 1:
45+
this instanceof KnownOpenSSLPaddingAlgorithmExpr and
46+
exists(DataFlow::Node src, DataFlow::Node sink |
47+
// Sink is an argument to a signature getter call
48+
sink = getterCall.getInputNode() and
49+
// Source is `this`
50+
src.asExpr() = this and
51+
// This traces to a getter
52+
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
53+
)
54+
or
55+
// Possibility 2:
56+
this instanceof OpenSSLAlgorithmCall and
57+
getterCall = this
58+
}
59+
60+
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
61+
62+
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
63+
64+
override string getRawAlgorithmName() {
65+
result = this.(Literal).getValue().toString()
66+
or
67+
result = this.(Call).getTarget().getName()
68+
}
69+
70+
override int getKeySizeFixed() {
71+
// TODO: use ellipticCurveNameToKeySizeAndFamilyMapping or KnownOpenSSLEllipticCurveConstantAlgorithmInstance
72+
// TODO: maybe add getExplicitKeySize to KnownOpenSSLSignatureAlgorithmExpr and use it here
73+
none()
74+
}
75+
76+
override KeyOpAlg::Algorithm getAlgorithmType() {
77+
knownOpenSSLConstantToSignatureFamilyType(this, result)
78+
or
79+
not knownOpenSSLConstantToSignatureFamilyType(this, _) and
80+
result = KeyOpAlg::TSignature(KeyOpAlg::OtherSignatureAlgorithmType())
81+
}
82+
83+
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
84+
85+
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
86+
// TODO: trace to any key size initializer
87+
// probably PKeyAlgorithmValueConsumer and SignatureAlgorithmValueConsumer
88+
none()
89+
}
90+
91+
/**
92+
* No mode for signatures.
93+
*/
94+
override predicate shouldHaveModeOfOperation() { none() }
95+
96+
/**
97+
* Padding only for RSA.
98+
*/
99+
override predicate shouldHavePaddingScheme() {
100+
this.getAlgorithmType() instanceof KeyOpAlg::TAsymmetricCipher
101+
}
102+
}

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/OpenSSLAlgorithmValueConsumers.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ import PaddingAlgorithmValueConsumer
55
import HashAlgorithmValueConsumer
66
import EllipticCurveAlgorithmValueConsumer
77
import PKeyAlgorithmValueConsumer
8+
import SignatureAlgorithmValueConsumer
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import cpp
2+
private import experimental.quantum.Language
3+
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
4+
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
5+
private import OpenSSLAlgorithmValueConsumerBase
6+
private import experimental.quantum.OpenSSL.LibraryDetector
7+
8+
abstract class SignatureAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
9+
10+
class EVPSignatureAlgorithmValueConsumer extends SignatureAlgorithmValueConsumer {
11+
DataFlow::Node valueArgNode;
12+
DataFlow::Node resultNode;
13+
14+
EVPSignatureAlgorithmValueConsumer() {
15+
resultNode.asExpr() = this and
16+
(
17+
// EVP_SIGNATURE
18+
this.(Call).getTarget().getName() = "EVP_SIGNATURE_fetch" and
19+
valueArgNode.asExpr() = this.(Call).getArgument(1)
20+
// EVP_PKEY_get1_DSA, EVP_PKEY_get1_RSA
21+
// DSA_SIG_new, DSA_SIG_get0, RSA_sign ?
22+
)
23+
}
24+
25+
override DataFlow::Node getResultNode() { result = resultNode }
26+
27+
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
28+
29+
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
30+
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
31+
}
32+
}

shared/quantum/codeql/quantum/experimental/Model.qll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -597,8 +597,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
597597
newtype TSignatureAlgorithmType =
598598
DSA() or
599599
ECDSA() or
600-
Ed25519() or
601-
Ed448() or
600+
EDDSA() or // e.g., ED25519 or ED448
602601
OtherSignatureAlgorithmType()
603602

604603
newtype TKEMAlgorithmType =
@@ -703,9 +702,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
703702
or
704703
type = TSignature(ECDSA()) and name = "ECDSA"
705704
or
706-
type = TSignature(Ed25519()) and name = "Ed25519"
707-
or
708-
type = TSignature(Ed448()) and name = "Ed448"
705+
type = TSignature(EDDSA()) and name = "EDSA"
709706
or
710707
type = TSignature(OtherSignatureAlgorithmType()) and name = "UnknownSignature"
711708
or

0 commit comments

Comments
 (0)