Skip to content

Commit 627790f

Browse files
committed
Clean up consumer and instance interfaces
1 parent cf33cf7 commit 627790f

3 files changed

Lines changed: 57 additions & 59 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ module JCAModel {
493493
}
494494
}
495495

496-
class CipherInitCallNonceArgConsumer extends NonceArtifactConsumer instanceof Expr {
496+
class CipherInitCallNonceArgConsumer extends Crypto::NonceArtifactConsumer instanceof Expr {
497497
CipherInitCallNonceArgConsumer() { this = any(CipherInitCall call).getNonceArg() }
498498

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

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

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,6 @@ class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource insta
8383
abstract class RandomnessInstance extends Crypto::RandomNumberGenerationInstance {
8484
override DataFlow::Node getOutputNode() { result.asExpr() = this }
8585

86-
override DataFlow::Node getInputNode() { none() } // TODO: add seed
87-
8886
override predicate flowsTo(Crypto::FlowAwareElement other) {
8987
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
9088
}
@@ -113,40 +111,10 @@ abstract class AdditionalFlowInputStep extends DataFlow::Node {
113111

114112
module ArtifactUniversalFlow = DataFlow::Global<ArtifactUniversalFlowConfig>;
115113

116-
class NonceArtifactConsumer extends Crypto::NonceArtifactInstance instanceof Crypto::NonceArtifactConsumer
117-
{
118-
override predicate flowsTo(Crypto::FlowAwareElement other) {
119-
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
120-
}
121-
122-
override DataFlow::Node getOutputNode() {
123-
result = this.(Crypto::NonceArtifactConsumer).getOutputNode()
124-
}
125-
126-
override DataFlow::Node getInputNode() {
127-
result = this.(Crypto::NonceArtifactConsumer).getInputNode()
128-
}
129-
}
130-
131-
class CipherInputConsumer extends Crypto::CipherInputArtifactInstance instanceof Crypto::CipherInputConsumer
132-
{
133-
override predicate flowsTo(Crypto::FlowAwareElement other) {
134-
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
135-
}
136-
137-
override DataFlow::Node getOutputNode() { none() }
138-
139-
override DataFlow::Node getInputNode() {
140-
result = this.(Crypto::CipherInputArtifactInstance).getInputNode()
141-
}
142-
}
143-
144114
abstract class CipherOutputArtifact extends Crypto::CipherOutputArtifactInstance {
145115
override predicate flowsTo(Crypto::FlowAwareElement other) {
146116
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
147117
}
148-
149-
override DataFlow::Node getInputNode() { none() }
150118
}
151119

152120
/**

shared/cryptography/codeql/cryptography/Model.qll

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,26 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
4545
)
4646
}
4747

48+
NodeBase getPassthroughNodeChild(NodeBase node) {
49+
result = node.(CipherInputNode).getChild(_) or
50+
result = node.(NonceNode).getChild(_)
51+
}
52+
53+
predicate isPassthroughNode(NodeBase node) {
54+
node instanceof CipherInputNode or
55+
node instanceof NonceNode
56+
}
57+
4858
predicate nodes_graph_impl(NodeBase node, string key, string value) {
4959
not node.isExcludedFromGraph() and
60+
not isPassthroughNode(node) and
5061
(
5162
key = "semmle.label" and
5263
value = node.toString()
5364
or
5465
// CodeQL's DGML output does not include a location
5566
key = "Location" and
56-
value = node.getLocation().toString()
67+
value = "<demo>" // node.getLocation().toString()
5768
or
5869
// Known unknown edges should be reported as properties rather than edges
5970
node = node.getChild(key) and
@@ -66,7 +77,14 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
6677

6778
predicate edges_graph_impl(NodeBase source, NodeBase target, string key, string value) {
6879
key = "semmle.label" and
69-
target = source.getChild(value) and
80+
exists(NodeBase directTarget |
81+
directTarget = source.getChild(value) and
82+
// [NodeA] ---Input--> [Passthrough] ---Source---> [NodeB]
83+
// should get reported as [NodeA] ---Input--> [NodeB]
84+
if isPassthroughNode(directTarget)
85+
then target = getPassthroughNodeChild(directTarget)
86+
else target = directTarget
87+
) and
7088
// Known unknowns are reported as properties rather than edges
7189
not source = target
7290
}
@@ -223,22 +241,23 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
223241
* * Instances of nodes do not necessarily have to come from a consumer, allowing additional modelling of an artifact to occur outside of the consumer.
224242
*/
225243
abstract class ArtifactConsumer extends ConsumerElement {
244+
/**
245+
* Use `getAKnownArtifactSource() instead. The behaviour of these two predicates is equivalent.
246+
*/
226247
final override KnownElement getAKnownSource() { result = this.getAKnownArtifactSource() }
227248

228249
final ArtifactElement getAKnownArtifactSource() { result.flowsTo(this) }
229250
}
230251

231-
abstract class NonceArtifactConsumer extends ArtifactConsumer, NonceArtifactInstance {
232-
NonceArtifactInstance asNonce() { result = this }
233-
}
234-
235-
abstract class CipherInputArtifactInstance extends ArtifactElement { }
252+
abstract class ArtifactConsumerAndInstance extends ArtifactConsumer {
253+
final override DataFlowNode getOutputNode() { none() }
236254

237-
abstract class CipherInputConsumer extends ArtifactConsumer, CipherInputArtifactInstance {
238-
CipherInputArtifactInstance asCipherInput() { result = this }
255+
final override predicate flowsTo(FlowAwareElement other) { none() }
239256
}
240257

241-
abstract class CipherOutputArtifactInstance extends ArtifactElement { }
258+
abstract class CipherOutputArtifactInstance extends ArtifactElement {
259+
final override DataFlowNode getInputNode() { none() }
260+
}
242261

243262
abstract class CipherOperationInstance extends OperationElement {
244263
/**
@@ -345,21 +364,33 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
345364

346365
abstract class KeyDerivationAlgorithmInstance extends KnownElement { }
347366

348-
// Artifacts
349-
abstract class DigestArtifactInstance extends ArtifactElement { }
367+
// Artifacts determined solely by the element that produces them
368+
// Implementation guidance: these *do* need to be defined generically at the language-level
369+
// in order for a flowsTo to be defined. At the per-modeling-instance level, extend that language-level class!
370+
abstract class OutputArtifactElement extends ArtifactElement {
371+
final override DataFlowNode getInputNode() { none() }
372+
}
373+
374+
abstract class DigestArtifactInstance extends OutputArtifactElement { }
375+
376+
abstract class RandomNumberGenerationInstance extends OutputArtifactElement { } // TODO: is this an OutputArtifactElement if it takes a seed?
350377

351-
abstract class KeyArtifactInstance extends ArtifactElement { }
378+
// Artifacts determined solely by the consumer that consumes them are defined as consumers
379+
// Implementation guidance: these do not need to be defined generically at the language-level
380+
// Only the sink node needs to be defined per-modeling-instance (e.g., in JCA.qll)
381+
abstract class NonceArtifactConsumer extends ArtifactConsumerAndInstance { }
352382

353-
abstract class NonceArtifactInstance extends ArtifactElement { }
383+
abstract class CipherInputConsumer extends ArtifactConsumerAndInstance { }
354384

355-
abstract class RandomNumberGenerationInstance extends ArtifactElement { }
385+
// Other artifacts
386+
abstract class KeyArtifactInstance extends ArtifactElement { } // TODO: implement and categorize
356387

357388
newtype TNode =
358389
// Artifacts (data that is not an operation or algorithm, e.g., a key)
359390
TDigest(DigestArtifactInstance e) or
360391
TKey(KeyArtifactInstance e) or
361-
TNonce(NonceArtifactInstance e) or
362-
TCipherInput(CipherInputArtifactInstance e) or
392+
TNonce(NonceArtifactConsumer e) or
393+
TCipherInput(CipherInputConsumer e) or
363394
TCipherOutput(CipherOutputArtifactInstance e) or
364395
TRandomNumberGeneration(RandomNumberGenerationInstance e) { e.flowsTo(_) } or
365396
// Operations (e.g., hashing, encryption)
@@ -525,7 +556,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
525556
* A nonce or initialization vector
526557
*/
527558
final class NonceNode extends ArtifactNode, TNonce {
528-
NonceArtifactInstance instance;
559+
NonceArtifactConsumer instance;
529560

530561
NonceNode() { this = TNonce(instance) }
531562

@@ -550,12 +581,12 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
550581
/**
551582
* Input text to a cipher operation
552583
*/
553-
final class CipherMessageNode extends ArtifactNode, TCipherInput {
554-
CipherInputArtifactInstance instance;
584+
final class CipherInputNode extends ArtifactNode, TCipherInput {
585+
CipherInputConsumer instance;
555586

556-
CipherMessageNode() { this = TCipherInput(instance) }
587+
CipherInputNode() { this = TCipherInput(instance) }
557588

558-
final override string getInternalType() { result = "CipherMessage" }
589+
final override string getInternalType() { result = "CipherInput" }
559590

560591
override LocatableElement asElement() { result = instance }
561592
}
@@ -665,12 +696,11 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
665696
}
666697

667698
NonceNode getANonce() {
668-
result.asElement() = this.asElement().(CipherOperationInstance).getNonceConsumer().asNonce()
699+
result.asElement() = this.asElement().(CipherOperationInstance).getNonceConsumer()
669700
}
670701

671-
CipherMessageNode getAnInputArtifact() {
672-
result.asElement() =
673-
this.asElement().(CipherOperationInstance).getInputConsumer().asCipherInput()
702+
CipherInputNode getAnInputArtifact() {
703+
result.asElement() = this.asElement().(CipherOperationInstance).getInputConsumer()
674704
}
675705

676706
CipherOutputNode getAnOutputArtifact() {

0 commit comments

Comments
 (0)