Skip to content

Commit 3871c6a

Browse files
committed
Adding support for encryption operation detection.
1 parent 8707e4d commit 3871c6a

File tree

2 files changed

+65
-7
lines changed
  • java/ql/lib/experimental/Quantum
  • shared/cryptography/codeql/cryptography

2 files changed

+65
-7
lines changed

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ module JCAModel {
5858
Expr getProviderArg() { result = this.getArgument(1) }
5959
}
6060

61+
class CipherDoFinalCall extends Call {
62+
CipherDoFinalCall() { this.getCallee().hasQualifiedName("javax.crypto", "Cipher", "doFinal") }
63+
}
64+
6165
/**
6266
* Data-flow configuration modelling flow from a cipher string literal to a `CipherGetInstanceCall` argument.
6367
*/
@@ -92,6 +96,57 @@ module JCAModel {
9296
}
9397
}
9498

99+
// TODO: what if encrypt/decrypt mode isn't known
100+
private module CipherGetInstanceToFinalizeConfig implements DataFlow::StateConfigSig {
101+
class FlowState = string;
102+
103+
predicate isSource(DataFlow::Node src, FlowState state) {
104+
state = "UNKNOWN" and
105+
src.asExpr() instanceof CipherGetInstanceCall
106+
}
107+
108+
predicate isSink(DataFlow::Node sink, FlowState state) {
109+
state in ["ENCRYPT", "DECRYPT", "UNKNOWN"] and
110+
exists(CipherDoFinalCall c | c.getQualifier() = sink.asExpr())
111+
}
112+
113+
predicate isAdditionalFlowStep(
114+
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
115+
) {
116+
state1 in ["UNKNOWN", "ENCRYPT", "DECRYPT"] and
117+
exists(CipherInitCall c |
118+
c.getQualifier() = node1.asExpr() and
119+
// TODO: not taking into consideration if the mode traces to this arg
120+
exists(FieldAccess fa |
121+
c.getModeArg() = fa and
122+
(
123+
fa.getField().getName() = "ENCRYPT_MODE" and
124+
state2 = "ENCRYPT"
125+
or
126+
fa.getField().getName() = "DECRYPT_MODE" and
127+
state2 = "DECRYPT"
128+
)
129+
)
130+
) and
131+
node2 = node1
132+
}
133+
}
134+
135+
module CipherGetInstanceToFinalizeFlow =
136+
DataFlow::GlobalWithState<CipherGetInstanceToFinalizeConfig>;
137+
138+
// TODO: what if the mode is UNKNOWN?
139+
class CipherEncryptionOperation extends Crypto::EncryptionOperationInstance instanceof Call {
140+
CipherEncryptionOperation() {
141+
exists(CipherGetInstanceToFinalizeFlow::PathNode sink, CipherDoFinalCall c |
142+
CipherGetInstanceToFinalizeFlow::flowPath(_, sink) and
143+
sink.getNode().asExpr() = c.getQualifier() and
144+
sink.getState() = "ENCRYPT" and
145+
this = c
146+
)
147+
}
148+
}
149+
95150
/**
96151
* A block cipher mode of operation, where the mode is specified in the ALG or ALG/MODE/PADDING format.
97152
*
@@ -272,6 +327,8 @@ module JCAModel {
272327
class CipherInitCall extends MethodCall {
273328
CipherInitCall() { this.getCallee().hasQualifiedName("javax.crypto", "Cipher", "init") }
274329

330+
// TODO: this doesn't account for tracing the mode to this arg if expending this arg to have
331+
// the actual mode directly
275332
Expr getModeArg() { result = this.getArgument(0) }
276333

277334
Expr getKey() {

shared/cryptography/codeql/cryptography/Model.qll

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -689,13 +689,14 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
689689
abstract class EncryptionOperation extends Operation, TEncryptionOperation {
690690
override string getOperationType() { result = "EncryptionOperation" }
691691

692-
/**
693-
* Gets the initialization vector associated with this encryption operation.
694-
*
695-
* This predicate does not need to hold for all encryption operations,
696-
* as the initialization vector is not always required.
697-
*/
698-
abstract InitializationVector getInitializationVector();
692+
abstract override EncryptionAlgorithm getAlgorithm();
693+
// /**
694+
// * Gets the initialization vector associated with this encryption operation.
695+
// *
696+
// * This predicate does not need to hold for all encryption operations,
697+
// * as the initialization vector is not always required.
698+
// */
699+
// abstract InitializationVector getInitializationVector();
699700
}
700701

701702
/**

0 commit comments

Comments
 (0)