Skip to content

Commit 8707e4d

Browse files
committed
Continue Artifact data-flow WIP
1 parent df01fa7 commit 8707e4d

File tree

3 files changed

+141
-34
lines changed

3 files changed

+141
-34
lines changed

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

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -244,24 +244,29 @@ module JCAModel {
244244
/**
245245
* Initialiation vectors
246246
*/
247-
abstract class IVParameterInstantiation extends ClassInstanceExpr {
248-
abstract Expr getIV();
247+
abstract class IVParameterInstantiation extends Crypto::InitializationVectorArtifactInstance instanceof ClassInstanceExpr
248+
{
249+
abstract Expr getInput();
249250
}
250251

251252
class IvParameterSpecInstance extends IVParameterInstantiation {
252253
IvParameterSpecInstance() {
253-
this.getConstructedType().hasQualifiedName("javax.crypto.spec", "IvParameterSpec")
254+
this.(ClassInstanceExpr)
255+
.getConstructedType()
256+
.hasQualifiedName("javax.crypto.spec", "IvParameterSpec")
254257
}
255258

256-
override Expr getIV() { result = super.getArgument(0) }
259+
override Expr getInput() { result = this.(ClassInstanceExpr).getArgument(0) }
257260
}
258261

259262
class GCMParameterSpecInstance extends IVParameterInstantiation {
260263
GCMParameterSpecInstance() {
261-
this.getConstructedType().hasQualifiedName("javax.crypto.spec", "GCMParameterSpec")
264+
this.(ClassInstanceExpr)
265+
.getConstructedType()
266+
.hasQualifiedName("javax.crypto.spec", "GCMParameterSpec")
262267
}
263268

264-
override Expr getIV() { result = super.getArgument(1) }
269+
override Expr getInput() { result = this.(ClassInstanceExpr).getArgument(1) }
265270
}
266271

267272
class CipherInitCall extends MethodCall {
@@ -280,18 +285,24 @@ module JCAModel {
280285
}
281286

282287
// TODO: cipher.getParameters().getParameterSpec(GCMParameterSpec.class);
283-
class InitializationVectorExpr extends Crypto::InitializationVectorArtifactInstance instanceof Expr
284-
{
285-
CipherInitCall call; // TODO: add origin to known sources (e.g. RNG, etc.)
286-
287-
InitializationVectorExpr() { this = call.getIV() }
288-
}
288+
/*
289+
* class InitializationVectorArg extends Crypto::InitializationVectorArtifactInstance instanceof Expr
290+
* {
291+
* IVParameterInstantiation creation;
292+
*
293+
* InitializationVectorArg() { this = creation.getInput() }
294+
* }
295+
*/
289296

290297
class InitializationVector extends Crypto::InitializationVector {
291-
InitializationVectorExpr instance;
298+
IVParameterInstantiation instance;
292299

293300
InitializationVector() { this = Crypto::TInitializationVector(instance) }
294301

295302
override Location getLocation() { result = instance.getLocation() }
303+
304+
override Crypto::DataFlowNode asOutputData() { result.asExpr() = instance }
305+
306+
override Crypto::DataFlowNode getInputData() { result.asExpr() = instance.getInput() }
296307
}
297308
}
Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,84 @@
11
private import codeql.cryptography.Model
2-
private import java as Lang
2+
private import java as Language
3+
private import semmle.code.java.security.InsecureRandomnessQuery
4+
private import semmle.code.java.security.RandomQuery
5+
6+
private class UnknownLocation extends Language::Location {
7+
UnknownLocation() { this.getFile().getAbsolutePath() = "" }
8+
}
39

410
/**
511
* A dummy location which is used when something doesn't have a location in
612
* the source code but needs to have a `Location` associated with it. There
713
* may be several distinct kinds of unknown locations. For example: one for
814
* expressions, one for statements and one for other program elements.
915
*/
10-
class UnknownLocation extends Location {
11-
UnknownLocation() { this.getFile().getAbsolutePath() = "" }
16+
private class UnknownDefaultLocation extends UnknownLocation {
17+
UnknownDefaultLocation() { locations_default(this, _, 0, 0, 0, 0) }
18+
}
19+
20+
module CryptoInput implements InputSig<Language::Location> {
21+
class DataFlowNode = DataFlow::Node;
22+
23+
class LocatableElement = Language::Element;
24+
25+
class UnknownLocation = UnknownDefaultLocation;
26+
27+
predicate rngToIvFlow(DataFlowNode rng, DataFlowNode iv) { none() }
1228
}
1329

1430
/**
15-
* A dummy location which is used when something doesn't have a location in
16-
* the source code but needs to have a `Location` associated with it.
31+
* Instantiate the model
1732
*/
18-
class UnknownDefaultLocation extends UnknownLocation {
19-
UnknownDefaultLocation() { locations_default(this, _, 0, 0, 0, 0) }
33+
module Crypto = CryptographyBase<Language::Location, CryptoInput>;
34+
35+
/**
36+
* Random number generation, where each instance is modelled as the expression
37+
* tied to an output node (i.e., the result of the source of randomness)
38+
*/
39+
abstract class RandomnessInstance extends Crypto::RandomNumberGenerationInstance {
40+
abstract Crypto::RNGSourceSecurity getSourceSecurity();
41+
42+
Crypto::TRNGSeedSecurity getSeedSecurity(Location location) { none() }
2043
}
2144

22-
module CryptoInput implements InputSig<Lang::Location> {
23-
class LocatableElement = Lang::Element;
45+
class SecureRandomnessInstance extends RandomnessInstance {
46+
SecureRandomnessInstance() {
47+
exists(RandomDataSource s | this = s.getOutput() |
48+
s.getSourceOfRandomness() instanceof SecureRandomNumberGenerator
49+
)
50+
}
2451

25-
class UnknownLocation = UnknownDefaultLocation;
52+
override Crypto::RNGSourceSecurity getSourceSecurity() {
53+
result instanceof Crypto::RNGSourceSecure
54+
}
55+
}
56+
57+
class InsecureRandomnessInstance extends RandomnessInstance {
58+
InsecureRandomnessInstance() { exists(InsecureRandomnessSource node | this = node.asExpr()) }
59+
60+
override Crypto::RNGSourceSecurity getSourceSecurity() {
61+
result instanceof Crypto::RNGSourceInsecure
62+
}
2663
}
2764

28-
module Crypto = CryptographyBase<Lang::Location, CryptoInput>;
65+
class RandomnessArtifact extends Crypto::RandomNumberGeneration {
66+
RandomnessInstance instance;
67+
68+
RandomnessArtifact() { this = Crypto::TRandomNumberGeneration(instance) }
69+
70+
override Location getLocation() { result = instance.getLocation() }
71+
72+
override Crypto::RNGSourceSecurity getSourceSecurity() { result = instance.getSourceSecurity() }
73+
74+
override Crypto::TRNGSeedSecurity getSeedSecurity(Location location) {
75+
result = instance.getSeedSecurity(location)
76+
}
77+
78+
override Crypto::DataFlowNode asOutputData() { result.asExpr() = instance }
79+
80+
override Crypto::DataFlowNode getInputData() { none() }
81+
}
2982

83+
// Import library-specific modeling
3084
import JCA

shared/cryptography/codeql/cryptography/Model.qll

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,24 @@ signature module InputSig<LocationSig Location> {
1212
string toString();
1313
}
1414

15+
class DataFlowNode {
16+
Location getLocation();
17+
18+
string toString();
19+
}
20+
1521
class UnknownLocation instanceof Location;
22+
23+
predicate rngToIvFlow(DataFlowNode rng, DataFlowNode iv);
1624
}
1725

1826
module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
1927
final class LocatableElement = Input::LocatableElement;
2028

2129
final class UnknownLocation = Input::UnknownLocation;
2230

31+
final class DataFlowNode = Input::DataFlowNode;
32+
2333
final class UnknownPropertyValue extends string {
2434
UnknownPropertyValue() { this = "<unknown>" }
2535
}
@@ -93,12 +103,15 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
93103

94104
abstract class NonceArtifactInstance extends LocatableElement { }
95105

106+
abstract class RandomNumberGenerationInstance extends LocatableElement { }
107+
96108
newtype TNode =
97109
// Artifacts (data that is not an operation or algorithm, e.g., a key)
98110
TDigest(DigestArtifactInstance e) or
99111
TKey(KeyArtifactInstance e) or
100112
TInitializationVector(InitializationVectorArtifactInstance e) or
101113
TNonce(NonceArtifactInstance e) or
114+
TRandomNumberGeneration(RandomNumberGenerationInstance e) or
102115
// Operations (e.g., hashing, encryption)
103116
THashOperation(HashOperationInstance e) or
104117
TKeyDerivationOperation(KeyDerivationOperationInstance e) or
@@ -115,7 +128,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
115128
TPaddingAlgorithm(PaddingAlgorithmInstance e) or
116129
// Composite and hybrid cryptosystems (e.g., RSA-OAEP used with AES, post-quantum hybrid cryptosystems)
117130
// These nodes are always parent nodes and are not modeled but rather defined via library-agnostic patterns.
118-
TKemDemHybridCryptosystem(EncryptionAlgorithmInstance dem) or // TODO, change this relation and the below ones
131+
TKemDemHybridCryptosystem(EncryptionAlgorithm dem) or // TODO, change this relation and the below ones
119132
TKeyAgreementHybridCryptosystem(EncryptionAlgorithmInstance ka) or
120133
TAsymmetricEncryptionMacHybridCryptosystem(EncryptionAlgorithmInstance enc) or
121134
TPostQuantumHybridCryptosystem(EncryptionAlgorithmInstance enc)
@@ -127,9 +140,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
127140
*/
128141
abstract class NodeBase extends TNode {
129142
/**
130-
* Returns a string representation of this node, usually the name of the operation/algorithm/property.
143+
* Returns a string representation of this node.
131144
*/
132-
abstract string toString();
145+
string toString() { result = this.getInternalType() }
133146

134147
/**
135148
* Returns a string representation of the internal type of this node, usually the name of the class.
@@ -172,15 +185,48 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
172185

173186
class Asset = NodeBase;
174187

175-
class Artifact = NodeBase;
188+
abstract class Artifact extends NodeBase {
189+
abstract DataFlowNode asOutputData();
190+
191+
abstract DataFlowNode getInputData();
192+
}
176193

177194
/**
178195
* An initialization vector
179196
*/
180-
abstract class InitializationVector extends Asset, TInitializationVector {
197+
abstract class InitializationVector extends Artifact, TInitializationVector {
181198
final override string getInternalType() { result = "InitializationVector" }
182199

183-
final override string toString() { result = this.getInternalType() }
200+
RandomNumberGeneration getRNGSource() {
201+
Input::rngToIvFlow(result.asOutputData(), this.getInputData())
202+
}
203+
}
204+
205+
newtype TRNGSourceSecurity =
206+
RNGSourceSecure() or // Secure RNG source (unrelated to seed)
207+
RNGSourceInsecure() // Insecure RNG source (unrelated to seed)
208+
209+
class RNGSourceSecurity extends TRNGSourceSecurity {
210+
string toString() {
211+
this instanceof RNGSourceSecure and result = "Secure RNG Source"
212+
or
213+
this instanceof RNGSourceInsecure and result = "Insecure RNG Source"
214+
}
215+
}
216+
217+
newtype TRNGSeedSecurity =
218+
RNGSeedSecure() or
219+
RNGSeedInsecure()
220+
221+
/**
222+
* A source of random number generation
223+
*/
224+
abstract class RandomNumberGeneration extends Artifact, TRandomNumberGeneration {
225+
final override string getInternalType() { result = "RandomNumberGeneration" }
226+
227+
abstract RNGSourceSecurity getSourceSecurity();
228+
229+
abstract TRNGSeedSecurity getSeedSecurity(Location location);
184230
}
185231

186232
/**
@@ -197,8 +243,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
197243
*/
198244
abstract string getOperationType();
199245

200-
final override string toString() { result = this.getOperationType() }
201-
202246
final override string getInternalType() { result = this.getOperationType() }
203247

204248
override NodeBase getChild(string edgeName) {
@@ -210,8 +254,6 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
210254
}
211255

212256
abstract class Algorithm extends Asset {
213-
final override string toString() { result = this.getAlgorithmType() }
214-
215257
final override string getInternalType() { result = this.getAlgorithmType() }
216258

217259
/**

0 commit comments

Comments
 (0)