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

Skip to content

Commit cf33cf7

Browse files
committed
Add input and output nodes and fix cross product
1 parent 0354afc commit cf33cf7

3 files changed

Lines changed: 193 additions & 62 deletions

File tree

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

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,22 @@ module JCAModel {
5959
Expr getProviderArg() { result = this.getArgument(1) }
6060
}
6161

62-
private class JCACipherOperationCall extends Call {
63-
JCACipherOperationCall() {
62+
private class CipherOperationCall extends MethodCall {
63+
CipherOperationCall() {
6464
exists(string s | s in ["doFinal", "wrap", "unwrap"] |
65-
this.getCallee().hasQualifiedName("javax.crypto", "Cipher", s)
65+
this.getMethod().hasQualifiedName("javax.crypto", "Cipher", s)
6666
)
6767
}
6868

69-
DataFlow::Node getMessageArg() { result.asExpr() = this.getArgument(0) }
69+
Expr getInput() { result = this.getArgument(0) }
70+
71+
Expr getOutput() {
72+
result = this.getArgument(3)
73+
or
74+
this.getMethod().getReturnType().hasName("byte[]") and result = this
75+
}
76+
77+
DataFlow::Node getMessageArg() { result.asExpr() = this.getInput() }
7078
}
7179

7280
/**
@@ -304,7 +312,7 @@ module JCAModel {
304312
predicate isSink(DataFlow::Node sink, FlowState state) { none() }
305313

306314
predicate isSink(DataFlow::Node sink) {
307-
exists(JCACipherOperationCall c | c.getQualifier() = sink.asExpr())
315+
exists(CipherOperationCall c | c.getQualifier() = sink.asExpr())
308316
}
309317

310318
predicate isAdditionalFlowStep(
@@ -330,7 +338,7 @@ module JCAModel {
330338
class CipherOperationInstance extends Crypto::CipherOperationInstance instanceof Call {
331339
Crypto::CipherOperationSubtype mode;
332340
CipherGetInstanceToCipherOperationFlow::PathNode sink;
333-
JCACipherOperationCall doFinalize;
341+
CipherOperationCall doFinalize;
334342
CipherGetInstanceAlgorithmArg consumer;
335343

336344
CipherOperationInstance() {
@@ -350,11 +358,15 @@ module JCAModel {
350358
result = sink.getState().(InitializedCipherModeFlowState).getInitCall().getNonceArg()
351359
}
352360

353-
override Crypto::ArtifactConsumer getMessageConsumer() {
361+
override Crypto::CipherInputConsumer getInputConsumer() {
354362
result = doFinalize.getMessageArg().asExpr()
355363
}
356364

357365
override Crypto::AlgorithmConsumer getAlgorithmConsumer() { result = consumer }
366+
367+
override Crypto::CipherOutputArtifactInstance getOutputArtifact() {
368+
result = doFinalize.getOutput()
369+
}
358370
}
359371

360372
/**
@@ -481,15 +493,27 @@ module JCAModel {
481493
}
482494
}
483495

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

487499
override DataFlow::Node getInputNode() { result.asExpr() = this }
488500
}
489501

490-
class CipherInitCallKeyConsumer extends Crypto::ArtifactConsumer instanceof Expr {
502+
class CipherInitCallKeyConsumer extends Crypto::ArtifactConsumer {
491503
CipherInitCallKeyConsumer() { this = any(CipherInitCall call).getKeyArg() }
492504

493505
override DataFlow::Node getInputNode() { result.asExpr() = this }
494506
}
507+
508+
class CipherMessageInputConsumer extends Crypto::CipherInputConsumer {
509+
CipherMessageInputConsumer() { this = any(CipherOperationCall call).getMessageArg().asExpr() }
510+
511+
override DataFlow::Node getInputNode() { result.asExpr() = this }
512+
}
513+
514+
class CipherOperationCallOutput extends CipherOutputArtifact {
515+
CipherOperationCallOutput() { this = any(CipherOperationCall call).getOutput() }
516+
517+
override DataFlow::Node getOutputNode() { result.asExpr() = this }
518+
}
495519
}

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

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource insta
6969
override DataFlow::Node getOutputNode() { result.asExpr() = this }
7070

7171
override predicate flowsTo(Crypto::FlowAwareElement other) {
72-
other instanceof NonceArtifactInstance and
73-
// limit to only nonces for now
7472
// TODO: separate config to avoid blowing up data-flow analysis
7573
GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
7674
}
@@ -113,40 +111,42 @@ abstract class AdditionalFlowInputStep extends DataFlow::Node {
113111
final DataFlow::Node getInput() { result = this }
114112
}
115113

116-
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
117-
predicate isSource(DataFlow::Node source) {
118-
source = any(Crypto::ArtifactElement artifact).getOutputNode()
119-
}
114+
module ArtifactUniversalFlow = DataFlow::Global<ArtifactUniversalFlowConfig>;
120115

121-
predicate isSink(DataFlow::Node sink) {
122-
sink = any(Crypto::FlowAwareElement other).getInputNode()
116+
class NonceArtifactConsumer extends Crypto::NonceArtifactInstance instanceof Crypto::NonceArtifactConsumer
117+
{
118+
override predicate flowsTo(Crypto::FlowAwareElement other) {
119+
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
123120
}
124121

125-
predicate isBarrierIn(DataFlow::Node node) {
126-
node = any(Crypto::FlowAwareElement element).getOutputNode()
122+
override DataFlow::Node getOutputNode() {
123+
result = this.(Crypto::NonceArtifactConsumer).getOutputNode()
127124
}
128125

129-
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
130-
node1.(AdditionalFlowInputStep).getOutput() = node2
126+
override DataFlow::Node getInputNode() {
127+
result = this.(Crypto::NonceArtifactConsumer).getInputNode()
131128
}
132129
}
133130

134-
module ArtifactUniversalFlow = DataFlow::Global<ArtifactUniversalFlowConfig>;
135-
136-
class NonceArtifactInstance extends Crypto::NonceArtifactInstance {
137-
NonceArtifactInstance() { this instanceof Crypto::NonceArtifactConsumer }
138-
131+
class CipherInputConsumer extends Crypto::CipherInputArtifactInstance instanceof Crypto::CipherInputConsumer
132+
{
139133
override predicate flowsTo(Crypto::FlowAwareElement other) {
140134
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
141135
}
142136

143-
override DataFlow::Node getOutputNode() {
144-
result = this.(Crypto::NonceArtifactConsumer).getOutputNode()
145-
}
137+
override DataFlow::Node getOutputNode() { none() }
146138

147139
override DataFlow::Node getInputNode() {
148-
result = this.(Crypto::NonceArtifactConsumer).getInputNode()
140+
result = this.(Crypto::CipherInputArtifactInstance).getInputNode()
141+
}
142+
}
143+
144+
abstract class CipherOutputArtifact extends Crypto::CipherOutputArtifactInstance {
145+
override predicate flowsTo(Crypto::FlowAwareElement other) {
146+
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
149147
}
148+
149+
override DataFlow::Node getInputNode() { none() }
150150
}
151151

152152
/**
@@ -161,6 +161,32 @@ module GenericDataSourceUniversalFlowConfig implements DataFlow::ConfigSig {
161161
sink = any(Crypto::FlowAwareElement other).getInputNode()
162162
}
163163

164+
predicate isBarrierOut(DataFlow::Node node) {
165+
node = any(Crypto::FlowAwareElement element).getInputNode()
166+
}
167+
168+
predicate isBarrierIn(DataFlow::Node node) {
169+
node = any(Crypto::FlowAwareElement element).getOutputNode()
170+
}
171+
172+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
173+
node1.(AdditionalFlowInputStep).getOutput() = node2
174+
}
175+
}
176+
177+
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
178+
predicate isSource(DataFlow::Node source) {
179+
source = any(Crypto::ArtifactElement artifact).getOutputNode()
180+
}
181+
182+
predicate isSink(DataFlow::Node sink) {
183+
sink = any(Crypto::FlowAwareElement other).getInputNode()
184+
}
185+
186+
predicate isBarrierOut(DataFlow::Node node) {
187+
node = any(Crypto::FlowAwareElement element).getInputNode()
188+
}
189+
164190
predicate isBarrierIn(DataFlow::Node node) {
165191
node = any(Crypto::FlowAwareElement element).getOutputNode()
166192
}

0 commit comments

Comments
 (0)