Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0354afc

Browse files
committed
Make ArtifactConsumers instances of some Artifacts
TODO: refactor the interfaces
1 parent ef0614a commit 0354afc

3 files changed

Lines changed: 68 additions & 40 deletions

File tree

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

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ module JCAModel {
346346

347347
override Crypto::CipherOperationSubtype getCipherOperationSubtype() { result = mode }
348348

349-
override Crypto::ArtifactConsumer getNonceConsumer() {
349+
override Crypto::NonceArtifactConsumer getNonceConsumer() {
350350
result = sink.getState().(InitializedCipherModeFlowState).getInitCall().getNonceArg()
351351
}
352352

@@ -360,9 +360,10 @@ module JCAModel {
360360
/**
361361
* Initialization vectors and other nonce artifacts
362362
*/
363-
abstract class NonceParameterInstantiation extends NonceArtifactInstance instanceof ClassInstanceExpr
364-
{
365-
override DataFlow::Node getOutputNode() { result.asExpr() = this }
363+
abstract class NonceParameterInstantiation extends ClassInstanceExpr {
364+
DataFlow::Node getOutputNode() { result.asExpr() = this }
365+
366+
abstract DataFlow::Node getInputNode();
366367
}
367368

368369
class IvParameterSpecInstance extends NonceParameterInstantiation {
@@ -396,32 +397,25 @@ module JCAModel {
396397
}
397398
}
398399

399-
module NonceArtifactToCipherInitCallConfig implements DataFlow::ConfigSig {
400-
predicate isSource(DataFlow::Node src) {
401-
exists(NonceParameterInstantiation n |
402-
src = n.getOutputNode() and
403-
not exists(IvParameterSpecGetIvCall m | n.getInputNode().asExpr() = m)
404-
)
405-
}
400+
predicate additionalFlowSteps(DataFlow::Node node1, DataFlow::Node node2) {
401+
exists(IvParameterSpecGetIvCall m |
402+
node1.asExpr() = m.getQualifier() and
403+
node2.asExpr() = m
404+
)
405+
or
406+
exists(NonceParameterInstantiation n |
407+
node1 = n.getInputNode() and
408+
node2 = n.getOutputNode()
409+
)
410+
}
406411

407-
predicate isSink(DataFlow::Node sink) {
408-
exists(CipherInitCall c | c.getNonceArg() = sink.asExpr())
409-
}
412+
class NonceAdditionalFlowInputStep extends AdditionalFlowInputStep {
413+
DataFlow::Node output;
410414

411-
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
412-
exists(IvParameterSpecGetIvCall m |
413-
node1.asExpr() = m.getQualifier() and
414-
node2.asExpr() = m
415-
)
416-
or
417-
exists(NonceParameterInstantiation n |
418-
node1 = n.getInputNode() and
419-
node2.asExpr() = n
420-
)
421-
}
422-
}
415+
NonceAdditionalFlowInputStep() { additionalFlowSteps(this, output) }
423416

424-
module NonceArtifactToCipherInitCallFlow = DataFlow::Global<NonceArtifactToCipherInitCallConfig>;
417+
override DataFlow::Node getOutput() { result = output }
418+
}
425419

426420
/**
427421
* A data-flow configuration to track flow from a mode field access to
@@ -487,7 +481,7 @@ module JCAModel {
487481
}
488482
}
489483

490-
class CipherInitCallNonceArgConsumer extends Crypto::ArtifactConsumer instanceof Expr {
484+
class CipherInitCallNonceArgConsumer extends Crypto::NonceArtifactConsumer instanceof Expr {
491485
CipherInitCallNonceArgConsumer() { this = any(CipherInitCall call).getNonceArg() }
492486

493487
override DataFlow::Node getInputNode() { result.asExpr() = this }

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ class GenericRemoteDataSource extends Crypto::GenericRemoteDataSource {
6565
override string getAdditionalDescription() { result = this.toString() }
6666
}
6767

68+
class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource instanceof Literal {
69+
override DataFlow::Node getOutputNode() { result.asExpr() = this }
70+
71+
override predicate flowsTo(Crypto::FlowAwareElement other) {
72+
other instanceof NonceArtifactInstance and
73+
// limit to only nonces for now
74+
// TODO: separate config to avoid blowing up data-flow analysis
75+
GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
76+
}
77+
78+
override string getAdditionalDescription() { result = this.toString() }
79+
}
80+
6881
/**
6982
* Random number generation, where each instance is modelled as the expression
7083
* tied to an output node (i.e., the result of the source of randomness)
@@ -94,6 +107,12 @@ class InsecureRandomnessInstance extends RandomnessInstance {
94107
/**
95108
* Artifact output to node input configuration
96109
*/
110+
abstract class AdditionalFlowInputStep extends DataFlow::Node {
111+
abstract DataFlow::Node getOutput();
112+
113+
final DataFlow::Node getInput() { result = this }
114+
}
115+
97116
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
98117
predicate isSource(DataFlow::Node source) {
99118
source = any(Crypto::ArtifactElement artifact).getOutputNode()
@@ -106,14 +125,28 @@ module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
106125
predicate isBarrierIn(DataFlow::Node node) {
107126
node = any(Crypto::FlowAwareElement element).getOutputNode()
108127
}
128+
129+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
130+
node1.(AdditionalFlowInputStep).getOutput() = node2
131+
}
109132
}
110133

111134
module ArtifactUniversalFlow = DataFlow::Global<ArtifactUniversalFlowConfig>;
112135

113-
abstract class NonceArtifactInstance extends Crypto::NonceArtifactInstance {
136+
class NonceArtifactInstance extends Crypto::NonceArtifactInstance {
137+
NonceArtifactInstance() { this instanceof Crypto::NonceArtifactConsumer }
138+
114139
override predicate flowsTo(Crypto::FlowAwareElement other) {
115140
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
116141
}
142+
143+
override DataFlow::Node getOutputNode() {
144+
result = this.(Crypto::NonceArtifactConsumer).getOutputNode()
145+
}
146+
147+
override DataFlow::Node getInputNode() {
148+
result = this.(Crypto::NonceArtifactConsumer).getInputNode()
149+
}
117150
}
118151

119152
/**
@@ -131,6 +164,10 @@ module GenericDataSourceUniversalFlowConfig implements DataFlow::ConfigSig {
131164
predicate isBarrierIn(DataFlow::Node node) {
132165
node = any(Crypto::FlowAwareElement element).getOutputNode()
133166
}
167+
168+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
169+
node1.(AdditionalFlowInputStep).getOutput() = node2
170+
}
134171
}
135172

136173
module GenericDataSourceUniversalFlow = DataFlow::Global<GenericDataSourceUniversalFlowConfig>;

shared/cryptography/codeql/cryptography/Model.qll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,16 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
205205
abstract AlgorithmElement getAKnownAlgorithmSource();
206206
}
207207

208-
abstract class ArtifactConsumer extends ConsumerElement {
208+
abstract class ArtifactConsumer extends ConsumerElement, ArtifactElement {
209209
final override KnownElement getAKnownSource() { result = this.getAKnownArtifactSource() }
210210

211211
final ArtifactElement getAKnownArtifactSource() { result.flowsTo(this) }
212212
}
213213

214+
abstract class NonceArtifactConsumer extends ArtifactConsumer {
215+
NonceArtifactInstance asNonce() { result = this }
216+
}
217+
214218
abstract class CipherOperationInstance extends OperationElement {
215219
/**
216220
* Gets the subtype of this cipher operation, distinguishing encryption, decryption, key wrapping, and key unwrapping.
@@ -220,7 +224,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
220224
/**
221225
* Gets the consumer of nonces/IVs associated with this cipher operation.
222226
*/
223-
abstract ArtifactConsumer getNonceConsumer();
227+
abstract NonceArtifactConsumer getNonceConsumer();
224228

225229
/**
226230
* Gets the consumer of plaintext or ciphertext input associated with this cipher operation.
@@ -586,13 +590,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
586590
result = instance.getCipherOperationSubtype()
587591
}
588592

589-
NodeBase getANonceOrUnknown() {
590-
result =
591-
this.asElement().(CipherOperationInstance).getNonceConsumer().getAKnownOrUnknownSourceNode()
592-
}
593-
594593
NonceNode getANonce() {
595-
result = this.asElement().(CipherOperationInstance).getNonceConsumer().getAKnownSourceNode()
594+
result.asElement() = this.asElement().(CipherOperationInstance).getNonceConsumer().asNonce()
596595
}
597596

598597
NodeBase getAMessageOrUnknown() {
@@ -614,9 +613,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
614613
or
615614
// [KNOWN_OR_UNKNOWN]
616615
key = "Nonce" and
617-
if exists(this.getANonceOrUnknown())
618-
then result = this.getANonceOrUnknown()
619-
else result = this
616+
if exists(this.getANonce()) then result = this.getANonce() else result = this
620617
or
621618
// [KNOWN_OR_UNKNOWN]
622619
key = "Message" and

0 commit comments

Comments
 (0)