@@ -22,6 +22,45 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
22
22
UnknownPropertyValue ( ) { this = "<unknown>" }
23
23
}
24
24
25
+ private string getPropertyAsGraphString ( NodeBase node , string key ) {
26
+ result =
27
+ strictconcat ( any ( string value , Location location , string parsed |
28
+ node .properties ( key , value , location ) and
29
+ parsed = "(" + value + "," + location .toString ( ) + ")"
30
+ |
31
+ parsed
32
+ ) , ","
33
+ )
34
+ }
35
+
36
+ predicate nodes_graph_impl ( NodeBase node , string key , string value ) {
37
+ key = "semmle.label" and
38
+ value = node .toString ( )
39
+ or
40
+ // CodeQL's DGML output does not include a location
41
+ key = "Location" and
42
+ value = node .getLocation ( ) .toString ( )
43
+ or
44
+ // Known unknown edges should be reported as properties rather than edges
45
+ node = node .getChild ( key ) and
46
+ value = "<unknown>"
47
+ or
48
+ // Report properties
49
+ value = getPropertyAsGraphString ( node , key )
50
+ }
51
+
52
+ predicate edges_graph_impl ( NodeBase source , NodeBase target , string key , string value ) {
53
+ key = "semmle.label" and
54
+ target = source .getChild ( value ) and
55
+ // Known unknowns are reported as properties rather than edges
56
+ not source = target
57
+ }
58
+
59
+ /**
60
+ * The base class for all cryptographic assets, such as operations and algorithms.
61
+ *
62
+ * Each `NodeBase` is a node in a graph of cryptographic operations, where the edges are the relationships between the nodes.
63
+ */
25
64
abstract class NodeBase instanceof LocatableElement {
26
65
/**
27
66
* Returns a string representation of this node, usually the name of the operation/algorithm/property.
@@ -104,6 +143,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
104
143
105
144
/**
106
145
* A hashing operation that processes data to generate a hash value.
146
+ *
107
147
* This operation takes an input message of arbitrary content and length and produces a fixed-size
108
148
* hash value as the output using a specified hashing algorithm.
109
149
*/
@@ -113,19 +153,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
113
153
override string getOperationName ( ) { result = "HASH" }
114
154
}
115
155
116
- // Rule: no newtype representing a type of algorithm should be modelled with multiple interfaces
117
- //
118
- // Example: HKDF and PKCS12KDF are both key derivation algorithms.
119
- // However, PKCS12KDF also has a property: the iteration count.
120
- //
121
- // If we have HKDF and PKCS12KDF under TKeyDerivationType,
122
- // someone modelling a library might try to make a generic identification of both of those algorithms.
123
- //
124
- // They will therefore not use the specialized type for PKCS12KDF,
125
- // meaning "from PKCS12KDF algo select algo" will have no results.
126
- //
127
156
newtype THashType =
128
- // We're saying by this that all of these have an identical interface / properties / edges
129
157
MD5 ( ) or
130
158
SHA1 ( ) or
131
159
SHA256 ( ) or
@@ -197,8 +225,28 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
197
225
}
198
226
}
199
227
200
- newtype TEllipticCurveFamilyType =
201
- // We're saying by this that all of these have an identical interface / properties / edges
228
+ /*
229
+ * TODO:
230
+ *
231
+ * Rule: No newtype representing a type of algorithm should be modelled with multiple interfaces
232
+ *
233
+ * Example 1: HKDF and PKCS12KDF are both key derivation algorithms.
234
+ * However, PKCS12KDF also has a property: the iteration count.
235
+ *
236
+ * If we have HKDF and PKCS12KDF under TKeyDerivationType,
237
+ * someone modelling a library might try to make a generic identification of both of those algorithms.
238
+ *
239
+ * They will therefore not use the specialized type for PKCS12KDF,
240
+ * meaning "from PKCS12KDF algo select algo" will have no results.
241
+ *
242
+ * Example 2: Each type below represents a common family of elliptic curves, with a shared interface, i.e.,
243
+ * predicates for library modellers to implement as well as the properties and edges reported.
244
+ */
245
+
246
+ /**
247
+ * Elliptic curve algorithms
248
+ */
249
+ newtype TEllipticCurveFamily =
202
250
NIST ( ) or
203
251
SEC ( ) or
204
252
NUMS ( ) or
@@ -211,13 +259,10 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
211
259
ES ( ) or
212
260
OtherEllipticCurveFamilyType ( )
213
261
214
- /**
215
- * Elliptic curve algorithm
216
- */
217
262
abstract class EllipticCurve extends Algorithm {
218
263
abstract string getKeySize ( Location location ) ;
219
264
220
- abstract TEllipticCurveFamilyType getCurveFamilyType ( ) ;
265
+ abstract TEllipticCurveFamily getCurveFamilyType ( ) ;
221
266
222
267
override predicate properties ( string key , string value , Location location ) {
223
268
super .properties ( key , value , location )
@@ -236,8 +281,10 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
236
281
/**
237
282
* Mandating that for Elliptic Curves specifically, users are responsible
238
283
* for providing as the 'raw' name, the official name of the algorithm.
284
+ *
239
285
* Casing doesn't matter, we will enforce further naming restrictions on
240
286
* `getAlgorithmName` by default.
287
+ *
241
288
* Rationale: elliptic curve names can have a lot of variation in their components
242
289
* (e.g., "secp256r1" vs "P-256"), trying to produce generalized set of properties
243
290
* is possible to capture all cases, but such modeling is likely not necessary.
@@ -256,17 +303,20 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
256
303
override string getOperationName ( ) { result = "ENCRYPTION" }
257
304
}
258
305
306
+ /**
307
+ * Block cipher modes of operation algorithms
308
+ */
259
309
newtype TModeOperation =
260
310
ECB ( ) or
261
311
CBC ( ) or
262
312
OtherMode ( )
263
313
264
314
abstract class ModeOfOperation extends Algorithm {
265
- string getValue ( ) { result = "" }
266
-
267
315
final private predicate modeToNameMapping ( TModeOperation type , string name ) {
268
316
type instanceof ECB and name = "ECB"
269
317
or
318
+ type instanceof CBC and name = "CBC"
319
+ or
270
320
type instanceof OtherMode and name = this .getRawAlgorithmName ( )
271
321
}
272
322
@@ -275,17 +325,20 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
275
325
override string getAlgorithmName ( ) { this .modeToNameMapping ( this .getModeType ( ) , result ) }
276
326
}
277
327
328
+ /**
329
+ * A helper type for distinguishing between block and stream ciphers.
330
+ */
278
331
newtype TCipherStructure =
279
332
Block ( ) or
280
333
Stream ( )
281
334
282
- newtype TSymmetricCipherFamilyType =
283
- // We're saying by this that all of these have an identical interface / properties / edges
284
- AES ( )
285
-
286
335
/**
287
336
* Symmetric algorithms
288
337
*/
338
+ newtype TSymmetricCipherFamilyType =
339
+ AES ( ) or
340
+ OtherSymmetricCipherFamilyType ( )
341
+
289
342
abstract class SymmetricAlgorithm extends Algorithm {
290
343
abstract TSymmetricCipherFamilyType getSymmetricCipherFamilyType ( ) ;
291
344
0 commit comments