Skip to content

Commit 1c8c553

Browse files
committed
openssl signatures - inputs, outputs and algorithms base
1 parent fb35929 commit 1c8c553

File tree

1 file changed

+74
-26
lines changed

1 file changed

+74
-26
lines changed

cpp/ql/lib/experimental/quantum/OpenSSL/Operations/EVPSignatureOperation.qll

Lines changed: 74 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,51 @@ private import experimental.quantum.Language
66
private import OpenSSLOperationBase
77
private import experimental.quantum.OpenSSL.CtxFlow as CTXFlow
88

9-
// TODO: verification
10-
class EVP_Cipher_Initializer extends EVPInitialize {
11-
EVP_Cipher_Initializer() {
9+
// TODO: verification functions
10+
11+
12+
class EVP_Signature_Initializer extends EVPInitialize {
13+
boolean isAlgorithmSpecifiedByKey;
14+
boolean isAlgorithmSpecifiedByCtx;
15+
16+
EVP_Signature_Initializer() {
1217
this.(Call).getTarget().getName() in [
13-
"EVP_DigestSignInit", "EVP_DigestSignInit_ex", "EVP_SignInit", "EVP_SignInit_ex",
14-
"EVP_PKEY_sign_init", "EVP_PKEY_sign_init_ex", "EVP_PKEY_sign_init_ex2",
15-
"EVP_PKEY_sign_message_init"
16-
]
18+
"EVP_DigestSignInit", "EVP_DigestSignInit_ex", "EVP_SignInit", "EVP_SignInit_ex",
19+
"EVP_PKEY_sign_init", "EVP_PKEY_sign_init_ex", "EVP_PKEY_sign_init_ex2",
20+
"EVP_PKEY_sign_message_init"
21+
] and
22+
(
23+
if this.(Call).getTarget().getName().matches("EVP_PKEY_%") then
24+
isAlgorithmSpecifiedByKey = false
25+
else
26+
isAlgorithmSpecifiedByKey = true
27+
)
28+
and
29+
(
30+
if this.(Call).getTarget().getName() in ["EVP_PKEY_sign_init", "EVP_PKEY_sign_init_ex"] then
31+
isAlgorithmSpecifiedByCtx = true
32+
else
33+
isAlgorithmSpecifiedByCtx = false
34+
)
1735
}
1836

37+
/**
38+
* Returns the argument that specifies the algorithm or none if the algorithm is implicit (from context or from key).
39+
* Note that the key may be not provided in the initialization call.
40+
*/
1941
override Expr getAlgorithmArg() {
20-
this.(Call).getTarget().getName() = "EVP_DigestSignInit" and
21-
result = this.(Call).getArgument(1)
22-
or
23-
this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and
24-
result = this.(Call).getArgument(1)
25-
or
26-
this.(Call).getTarget().getName() = "EVP_PKEY_sign_init_ex2" and
27-
result = this.(Call).getArgument(1)
28-
or
29-
this.(Call).getTarget().getName() = "EVP_PKEY_sign_message_init" and
30-
result = this.(Call).getArgument(1)
42+
if isAlgorithmSpecifiedByKey = true or isAlgorithmSpecifiedByCtx = true then
43+
none()
44+
else (
45+
this.(Call).getTarget().getName() in ["EVP_PKEY_sign_init_ex2", "EVP_PKEY_sign_message_init"] and
46+
result = this.(Call).getArgument(1)
47+
)
3148
}
3249

50+
/**
51+
* Returns the key argument if there is one.
52+
* They key could be provided in the context or in a later call (final or one-shot).
53+
*/
3354
override Expr getKeyArg() {
3455
this.(Call).getTarget().getName() = "EVP_DigestSignInit" and
3556
result = this.(Call).getArgument(4)
@@ -38,8 +59,9 @@ class EVP_Cipher_Initializer extends EVPInitialize {
3859
result = this.(Call).getArgument(5)
3960
}
4061

41-
override Expr getIVArg() { none() }
42-
62+
/**
63+
* Signing, verification or unknown.
64+
*/
4365
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
4466
if this.(Call).getTarget().getName().toLowerCase().matches("%sign%")
4567
then result instanceof Crypto::TSignMode
@@ -57,13 +79,23 @@ class EVP_Signature_Update_Call extends EVPUpdate {
5779
]
5880
}
5981

82+
/**
83+
* Input is the message to sign.
84+
*/
6085
override Expr getInputArg() { result = this.(Call).getArgument(1) }
6186
}
6287

88+
/**
89+
* Base configuration for all EVP signature operations.
90+
*/
6391
abstract class EVP_Signature_Operation extends EVPOperation, Crypto::KeyOperationInstance {
6492
EVP_Signature_Operation() { this.(Call).getTarget().getName().matches("EVP_%") }
6593

94+
/**
95+
* Signing, verification or unknown.
96+
*/
6697
override Crypto::KeyOperationSubtype getKeyOperationSubtype() {
98+
// TODO: if this KeyOperationSubtype does not match initialization call's KeyOperationSubtype then we found a bug
6799
if this.(Call).getTarget().getName().toLowerCase().matches("%sign%")
68100
then result instanceof Crypto::TSignMode
69101
else
@@ -72,16 +104,14 @@ abstract class EVP_Signature_Operation extends EVPOperation, Crypto::KeyOperatio
72104
else result instanceof Crypto::TUnknownKeyOperationMode
73105
}
74106

75-
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
76-
77107
override Crypto::ConsumerInputDataFlowNode getNonceConsumer() {
78-
// this.getInitCall().getIVArg() = result.asExpr()
108+
// TODO: some signing operations may have explicit nonce generators
79109
none()
80110
}
81111

82112
override Crypto::ConsumerInputDataFlowNode getKeyConsumer() {
83-
this.getInitCall().getKeyArg() = result.asExpr()
84-
// todo: or track to the EVP_PKEY_CTX_new
113+
result = DataFlow::exprNode(this.getInitCall().getKeyArg())
114+
// TODO: or track to the EVP_PKEY_CTX_new
85115
}
86116

87117
override Crypto::ArtifactOutputDataFlowNode getOutputArtifact() {
@@ -93,9 +123,17 @@ abstract class EVP_Signature_Operation extends EVPOperation, Crypto::KeyOperatio
93123
}
94124
}
95125

96-
class EVP_Signature_Call extends EVPOneShot, EVP_Signature_Operation {
126+
class EVP_Signature_Call extends EVPOperation, EVP_Signature_Operation {
97127
EVP_Signature_Call() { this.(Call).getTarget().getName() in ["EVP_DigestSign", "EVP_PKEY_sign"] }
98128

129+
/**
130+
* Output is the signature.
131+
*/
132+
override Expr getOutputArg() { result = this.(Call).getArgument(1) }
133+
134+
/**
135+
* Input is the message to sign.
136+
*/
99137
override Expr getInputArg() { result = this.(Call).getArgument(3) }
100138
}
101139

@@ -105,4 +143,14 @@ class EVP_Signature_Final_Call extends EVPFinal, EVP_Signature_Operation {
105143
"EVP_DigestSignFinal", "EVP_SignFinal_ex", "EVP_SignFinal", "EVP_PKEY_sign_message_final"
106144
]
107145
}
146+
147+
/**
148+
* Output is the signature.
149+
*/
150+
override Expr getOutputArg() {
151+
if this.(Call).getTarget().getName() = "EVP_SignFinal_ex" then
152+
result = this.(Call).getArgument(2)
153+
else
154+
result = this.(Call).getArgument(1)
155+
}
108156
}

0 commit comments

Comments
 (0)