Skip to content

Commit 60d931a

Browse files
committed
Update progress on JCA
1 parent 2e12bb5 commit 60d931a

File tree

2 files changed

+136
-58
lines changed

2 files changed

+136
-58
lines changed

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

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
}
1212

1313
class UnknownLocation instanceof Location;
14+
15+
1416
}
1517

1618
module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
@@ -91,6 +93,11 @@
9193
* Gets the name of this algorithm, e.g., "AES" or "SHA".
9294
*/
9395
abstract string getAlgorithmName();
96+
97+
/**
98+
* Gets the raw name of this algorithm from source (no parsing or formatting)
99+
*/
100+
abstract string getRawAlgorithmName();
94101

95102
final override string toString() { result = this.getAlgorithmName() }
96103
}
@@ -148,7 +155,7 @@
148155
/**
149156
* Gets the raw name of this hash algorithm from source.
150157
*/
151-
abstract string getRawAlgorithmName();
158+
override abstract string getRawAlgorithmName();
152159
}
153160

154161
/**
@@ -231,5 +238,90 @@
231238

232239
override string getOperationName() { result = "ENCRYPTION" }
233240
}
241+
242+
// newtype TBlockCipherFamilyType =
243+
// // We're saying by this that all of these have an identical interface / properties / edges
244+
// CBC() or ECB()
245+
246+
247+
// abstract class BlockCiper extends Algorithm {
248+
249+
// abstract string getKeySize(Location location);
250+
251+
// abstract TBlockCipherFamilyType getBlockCipherFamilyType();
252+
253+
// override predicate properties(string key, string value, Location location) {
254+
// super.properties(key, value, location)
255+
// or
256+
// key = "key_size" and
257+
// if exists(this.getKeySize(location))
258+
// then value = this.getKeySize(location)
259+
// else (
260+
// value instanceof UnknownPropertyValue and location instanceof UnknownLocation
261+
// )
262+
// // other properties, like field type are possible, but not modeled until considered necessary
263+
// }
264+
265+
// override string getAlgorithmName() { result = this.getRawAlgorithmName().toUpperCase()}
266+
267+
// override abstract string getRawAlgorithmName();
268+
// }
269+
270+
newtype TModeOperation =
271+
ECB() or OtherMode()
272+
273+
abstract class ModeOfOperation extends Algorithm {
274+
string getValue() {result = ""}
275+
276+
final private predicate modeToNameMapping(TModeOperation type, string name) {
277+
type instanceof ECB and name = "ECB"
278+
or
279+
type instanceof OtherMode and name = this.getRawAlgorithmName()
280+
}
281+
282+
abstract TModeOperation getModeType();
283+
284+
override string getAlgorithmName() { this.modeToNameMapping(this.getModeType(), result) }
285+
286+
}
287+
288+
newtype TCipherStructure =
289+
Block() or Stream()
290+
291+
newtype TSymmetricCipherFamilyType =
292+
// We're saying by this that all of these have an identical interface / properties / edges
293+
AES()
294+
295+
/**
296+
* Symmetric algorithms
297+
*/
298+
abstract class SymmetricAlgorithm extends Algorithm {
299+
300+
301+
abstract TSymmetricCipherFamilyType getSymmetricCipherFamilyType();
302+
303+
abstract string getKeySize(Location location);
304+
305+
abstract TCipherStructure getCipherType();
306+
307+
308+
//mode, padding scheme, keysize, block/stream, auth'd
309+
//nodes = mode, padding scheme
310+
//properties = keysize, block/stream, auth'd
311+
//leave authd to lang specific
312+
override predicate properties(string key, string value, Location location) {
313+
super.properties(key, value, location)
314+
or
315+
key = "key_size" and
316+
if exists(this.getKeySize(location))
317+
then value = this.getKeySize(location)
318+
else (
319+
value instanceof UnknownPropertyValue and location instanceof UnknownLocation
320+
)
321+
//add more keys to index props
322+
}
323+
324+
abstract ModeOfOperation getModeOfOperation();
325+
}
234326
}
235327

java/ql/lib/experimental/Quantum/JCA.qll

Lines changed: 43 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -14,41 +14,6 @@ predicate cipher_modes(string mode) {mode = ["NONE", "CBC", "CCM", "CFB", "CFBx"
1414
predicate cipher_padding(string padding) {padding = ["NoPadding", "ISO10126Padding", "OAEPPadding", "OAEPWith", "PKCS1Padding", "PKCS5Padding", "SSL3Padding"]}
1515

1616

17-
abstract class BlockCiper extends Crypto::Algorithm {
18-
CipherAlgorithmStringLiteral alg;
19-
CipherAlgorithmMode mode;
20-
CipherAlgorithmPadding padding;
21-
22-
23-
CipherAlgorithmStringLiteral getAlg() {result = alg }
24-
CipherAlgorithmMode getMode() {result = mode }
25-
26-
CipherAlgorithmPadding getPadding() {result =padding}
27-
}
28-
/**
29-
* Symmetric algorithms
30-
*/
31-
abstract class SymmetricAlgorithm extends Crypto::Algorithm {
32-
33-
34-
//TODO figure out how to get this from the Cipher interface, is it explicit?
35-
//abstract string getKeySize(Location location);
36-
37-
// override predicate properties(string key, string value, Location location) {
38-
// super.properties(key, value, location)
39-
// or
40-
// key = "key_size" and
41-
// if exists(this.getKeySize(location))
42-
// then value = this.getKeySize(location)
43-
// else (
44-
// value instanceof Crypto::UnknownPropertyValue and location instanceof UnknownLocation
45-
// )
46-
// // other properties, like field type are possible, but not modeled until considered necessary
47-
// }
48-
49-
abstract override string getAlgorithmName();
50-
}
51-
5217
////cipher specifics ----------------------------------------
5318

5419
class CipherInstance extends Call {
@@ -60,24 +25,26 @@ class CipherInstance extends Call {
6025
/**
6126
* this may be specified either in the ALG/MODE/PADDING or just ALG format
6227
*/
63-
class CipherAlgorithmStringLiteral extends Crypto::NodeBase instanceof StringLiteral {
28+
class CipherAlgorithmStringLiteral extends StringLiteral {
6429
CipherAlgorithmStringLiteral() { cipher_names(this.getValue().splitAt("/"))}
65-
66-
override string toString() { result = this.(StringLiteral).toString() }
67-
68-
string getValue() { result = this.(StringLiteral).getValue() }
6930
}
7031

71-
abstract class CipherAlgorithmMode extends Crypto::NodeBase {
72-
string getValue() {result = ""}
73-
}
7432

75-
class CipherAlgorithmModeStringLiteral extends CipherAlgorithmMode instanceof StringLiteral {
76-
CipherAlgorithmModeStringLiteral() { cipher_modes(this.(StringLiteral).getValue().splitAt("/"))}
33+
class ModeOfOperationStringLiteral extends Crypto::ModeOfOperation instanceof StringLiteral {
34+
ModeOfOperationStringLiteral() { cipher_modes(this.(StringLiteral).getValue().splitAt("/"))}
7735

78-
override string toString() { result = this.(StringLiteral).toString() }
36+
override string getRawAlgorithmName() { result = this.(StringLiteral).getValue().regexpCapture(".*/(.*)/.*",1) }
7937

8038
override string getValue() { result = this.(StringLiteral).getValue().regexpCapture(".*/(.*)/.*",1) }
39+
40+
41+
predicate modeToNameMapping(Crypto::TModeOperation type, string name) {
42+
name = "ECB" and type instanceof Crypto::ECB
43+
}
44+
45+
override Crypto::TModeOperation getModeType(){
46+
modeToNameMapping(result, this.getRawAlgorithmName())
47+
}
8148
}
8249

8350
abstract class CipherAlgorithmPadding extends Crypto::NodeBase {
@@ -102,32 +69,51 @@ abstract class CipherAlgorithmMode extends Crypto::NodeBase {
10269

10370
module AlgorithmStringToFetchFlow = DataFlow::Global<AlgorithmStringToFetchConfig>;
10471

105-
predicate algorithmStringToCipherInstanceArgFlow(string name, CipherAlgorithmStringLiteral origin, CipherAlgorithmModeStringLiteral mode, CipherAlgorithmPaddingStringLiteral padding, Expr arg) {
72+
predicate algorithmStringToCipherInstanceArgFlow(string name, CipherAlgorithmStringLiteral origin, Expr arg) {
10673
exists(CipherInstance sinkCall |
10774
origin.getValue().splitAt("/") = name and
108-
origin = mode and
109-
origin = padding and
11075
arg = sinkCall.getAlgorithmArg() and
11176
AlgorithmStringToFetchFlow::flow(DataFlow::exprNode(origin), DataFlow::exprNode(arg))
11277
)
11378
}
11479

80+
81+
predicate modeStringToCipherInstanceArgFlow(string name, ModeOfOperationStringLiteral mode, Expr arg) {
82+
exists(CipherInstance sinkCall |
83+
mode.getRawAlgorithmName() = name and
84+
arg = sinkCall.getAlgorithmArg() and
85+
AlgorithmStringToFetchFlow::flow(DataFlow::exprNode(mode), DataFlow::exprNode(arg))
86+
)
87+
}
88+
11589
/**
11690
* A class to represent when AES is used AND it has literal mode and padding provided
11791
* this does not capture the use without
11892
*/
119-
class AESLiteral extends SymmetricAlgorithm, BlockCiper instanceof Expr {
93+
// class AESLiteral extends Crypto::SymmetricAlgorithm instanceof Expr {
94+
// CipherAlgorithmStringLiteral alg;
95+
// AESLiteral() { algorithmStringToCipherInstanceArgFlow("AES", alg, this)
96+
// }
12097

98+
// override Crypto::ModeOfOperation getModeOfOperation(){ modeStringToCipherInstanceArgFlow(result.getAlgorithmName(), result, this)}
12199

122-
AESLiteral() { algorithmStringToCipherInstanceArgFlow("AES", alg, mode, padding, this)
123-
}
100+
// override Crypto::LocatableElement getOrigin(string name) {
101+
// result = alg and name = alg.toString()
102+
// }
124103

125-
override Crypto::LocatableElement getOrigin(string name) {
126-
result = alg and name = alg.toString()
127-
}
104+
// override string getAlgorithmName(){ result = "AES" }
128105

129-
override string getAlgorithmName(){ result = alg.getValue()}
130-
}
106+
// override string getRawAlgorithmName(){ result = alg.getValue()}
107+
108+
// override Crypto::TSymmetricCipherFamilyType getSymmetricCipherFamilyType() { result instanceof Crypto::AES}
109+
110+
// //temp hacks for testing
111+
// override string getKeySize(Location location){
112+
// result = ""
113+
// }
114+
115+
// override Crypto::TCipherStructure getCipherType(){ none()}
116+
// }
131117

132118

133119
}

0 commit comments

Comments
 (0)