Skip to content

Commit e027b0e

Browse files
committed
WIP: add properties
1 parent 7836234 commit e027b0e

File tree

5 files changed

+114
-27
lines changed

5 files changed

+114
-27
lines changed

cpp/ql/lib/experimental/Quantum/Base.qll

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,19 @@ signature module InputSig<LocationSig Location> {
99
class LocatableElement {
1010
Location getLocation();
1111
}
12+
13+
class UnknownLocation instanceof Location;
1214
}
1315

1416
module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
1517
final class LocatableElement = Input::LocatableElement;
1618

19+
final class UnknownLocation = Input::UnknownLocation;
20+
21+
final class UnknownPropertyValue extends string {
22+
UnknownPropertyValue() { this = "<unknown>" }
23+
}
24+
1725
abstract class NodeBase instanceof LocatableElement {
1826
/**
1927
* Returns a string representation of this node, usually the name of the operation/algorithm/property.
@@ -25,17 +33,26 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
2533
*/
2634
Location getLocation() { result = super.getLocation() }
2735

36+
/**
37+
* Gets the origin of this node, e.g., a string literal in source describing it.
38+
*/
39+
LocatableElement getOrigin(string value) { none() }
40+
2841
/**
2942
* Returns the child of this node with the given edge name.
3043
*
3144
* This predicate is used by derived classes to construct the graph of cryptographic operations.
3245
*/
33-
NodeBase getChild(string edgeName) { edgeName = "origin" and result = this.getOrigin() }
46+
NodeBase getChild(string edgeName) { none() }
3447

3548
/**
36-
* Gets the origin of this node, e.g., a string literal in source describing it.
49+
* Defines properties of this node by name and either a value or location or both.
50+
*
51+
* This predicate is used by derived classes to construct the graph of cryptographic operations.
3752
*/
38-
NodeBase getOrigin() { none() }
53+
predicate properties(string key, string value, Location location) {
54+
key = "origin" and location = this.getOrigin(value).getLocation()
55+
}
3956

4057
/**
4158
* Returns the parent of this node.
@@ -86,7 +103,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
86103
abstract class HashOperation extends Operation {
87104
abstract override HashAlgorithm getAlgorithm();
88105

89-
override string getOperationName() { result = "hash" }
106+
override string getOperationName() { result = "HASH" }
90107
}
91108

92109
// Rule: no newtype representing a type of algorithm should be modelled with multiple interfaces
@@ -105,34 +122,40 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
105122
MD5() or
106123
SHA1() or
107124
SHA256() or
108-
SHA512()
109-
110-
class HashAlgorithmType extends THashType {
111-
string toString() { hashTypeToNameMapping(this, result) }
112-
}
113-
114-
predicate hashTypeToNameMapping(THashType type, string name) {
115-
type instanceof SHA1 and name = "SHA-1"
116-
or
117-
type instanceof SHA256 and name = "SHA-256"
118-
or
119-
type instanceof SHA512 and name = "SHA-512"
120-
}
125+
SHA512() or
126+
OtherHashType()
121127

122128
/**
123129
* A hashing algorithm that transforms variable-length input into a fixed-size hash value.
124130
*/
125131
abstract class HashAlgorithm extends Algorithm {
126-
abstract HashAlgorithmType getHashType();
132+
final predicate hashTypeToNameMapping(THashType type, string name) {
133+
type instanceof MD5 and name = "MD5"
134+
or
135+
type instanceof SHA1 and name = "SHA-1"
136+
or
137+
type instanceof SHA256 and name = "SHA-256"
138+
or
139+
type instanceof SHA512 and name = "SHA-512"
140+
or
141+
type instanceof OtherHashType and name = this.getRawAlgorithmName()
142+
}
143+
144+
abstract THashType getHashType();
145+
146+
override string getAlgorithmName() { this.hashTypeToNameMapping(this.getHashType(), result) }
127147

128-
override string getAlgorithmName() { hashTypeToNameMapping(this.getHashType(), result) }
148+
/**
149+
* Gets the raw name of this hash algorithm from source.
150+
*/
151+
abstract string getRawAlgorithmName();
129152
}
130153

131154
/**
132155
* An operation that derives one or more keys from an input value.
133156
*/
134157
abstract class KeyDerivationOperation extends Operation {
135-
override string getOperationName() { result = "key derivation" }
158+
override string getOperationName() { result = "KEY_DERIVATION" }
136159
}
137160

138161
/**
@@ -143,7 +166,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
143166
}
144167

145168
/**
146-
* HKDF Extract+Expand key derivation function.
169+
* HKDF key derivation function
147170
*/
148171
abstract class HKDF extends KeyDerivationAlgorithm {
149172
final override string getAlgorithmName() { result = "HKDF" }
@@ -157,6 +180,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
157180
}
158181
}
159182

183+
/**
184+
* PKCS #12 key derivation function
185+
*/
160186
abstract class PKCS12KDF extends KeyDerivationAlgorithm {
161187
final override string getAlgorithmName() { result = "PKCS12KDF" }
162188

@@ -168,4 +194,31 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
168194
edgeName = "digest" and result = this.getHashAlgorithm()
169195
}
170196
}
197+
198+
/**
199+
* Elliptic curve algorithm
200+
*/
201+
abstract class EllipticCurve extends Algorithm {
202+
abstract string getVersion(Location location);
203+
204+
abstract string getKeySize(Location location);
205+
206+
override predicate properties(string key, string value, Location location) {
207+
super.properties(key, value, location)
208+
or
209+
key = "version" and
210+
if exists(this.getVersion(location))
211+
then value = this.getVersion(location)
212+
else (
213+
value instanceof UnknownPropertyValue and location instanceof UnknownLocation
214+
)
215+
or
216+
key = "key_size" and
217+
if exists(this.getKeySize(location))
218+
then value = this.getKeySize(location)
219+
else (
220+
value instanceof UnknownPropertyValue and location instanceof UnknownLocation
221+
)
222+
}
223+
}
171224
}

cpp/ql/lib/experimental/Quantum/Language.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ private import cpp as Lang
33

44
module CryptoInput implements InputSig<Lang::Location> {
55
class LocatableElement = Lang::Locatable;
6+
7+
class UnknownLocation = Lang::UnknownDefaultLocation;
68
}
79

810
module Crypto = CryptographyBase<Lang::Location, CryptoInput>;

cpp/ql/lib/experimental/Quantum/OpenSSL.qll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ module OpenSSLModel {
99
class SHA1Algo extends Crypto::HashAlgorithm instanceof MacroAccess {
1010
SHA1Algo() { this.getMacro().getName() = "SN_sha1" }
1111

12-
override Crypto::HashAlgorithmType getHashType() { result instanceof Crypto::SHA1 }
12+
override string getRawAlgorithmName() { result = "SN_sha1" }
13+
14+
override Crypto::THashType getHashType() { result instanceof Crypto::SHA1 }
1315
}
1416

1517
module AlgorithmToEVPKeyDeriveConfig implements DataFlow::ConfigSig {
@@ -77,7 +79,9 @@ module OpenSSLModel {
7779

7880
override Crypto::HashAlgorithm getHashAlgorithm() { none() }
7981

80-
override Crypto::NodeBase getOrigin() { result = origin }
82+
override Crypto::LocatableElement getOrigin(string name) {
83+
result = origin and name = origin.toString()
84+
}
8185
}
8286

8387
class TestKeyDerivationOperationHacky extends KeyDerivationOperation instanceof FunctionCall {
@@ -97,6 +101,8 @@ module OpenSSLModel {
97101

98102
override Crypto::HashAlgorithm getHashAlgorithm() { none() }
99103

100-
override Crypto::NodeBase getOrigin() { result = origin }
104+
override Crypto::NodeBase getOrigin(string name) {
105+
result = origin and name = origin.toString()
106+
}
101107
}
102108
}

cpp/ql/src/experimental/Quantum/Test.ql

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,33 @@
55

66
import experimental.Quantum.Language
77

8-
query predicate nodes(Crypto::NodeBase node) { any() }
8+
string getValueAndLocationPairs(Crypto::NodeBase node, string key) {
9+
exists(string value, Location location |
10+
node.properties(key, value, location) and
11+
result = "(" + value + "," + location.toString() + ")"
12+
)
13+
}
14+
15+
string properties(Crypto::NodeBase node) {
16+
forex(string key | node.properties(key, _, _) |
17+
result = key + ":" + strictconcat(getValueAndLocationPairs(node, key), ",")
18+
)
19+
}
20+
21+
string getLabel(Crypto::NodeBase node) {
22+
result =
23+
"[" + node.toString() + "]" +
24+
any(string prop |
25+
if exists(properties(node)) then prop = " " + properties(node) else prop = ""
26+
|
27+
prop
28+
)
29+
}
30+
31+
query predicate nodes(Crypto::NodeBase node, string key, string value) {
32+
key = "semmle.label" and
33+
value = getLabel(node)
34+
}
935

1036
query predicate edges(Crypto::NodeBase source, Crypto::NodeBase target, string key, string value) {
1137
target = source.getChild(value) and

cpp/ql/src/experimental/Quantum/Test2.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
import experimental.Quantum.Language
66

7-
from Crypto::KeyDerivationAlgorithm n
8-
select n
7+
from Crypto::NodeBase node
8+
select node

0 commit comments

Comments
 (0)