mirror of
https://github.com/github/codeql.git
synced 2026-04-24 16:25:15 +02:00
Make ArtifactConsumers instances of some Artifacts
TODO: refactor the interfaces
This commit is contained in:
@@ -346,7 +346,7 @@ module JCAModel {
|
||||
|
||||
override Crypto::CipherOperationSubtype getCipherOperationSubtype() { result = mode }
|
||||
|
||||
override Crypto::ArtifactConsumer getNonceConsumer() {
|
||||
override Crypto::NonceArtifactConsumer getNonceConsumer() {
|
||||
result = sink.getState().(InitializedCipherModeFlowState).getInitCall().getNonceArg()
|
||||
}
|
||||
|
||||
@@ -360,9 +360,10 @@ module JCAModel {
|
||||
/**
|
||||
* Initialization vectors and other nonce artifacts
|
||||
*/
|
||||
abstract class NonceParameterInstantiation extends NonceArtifactInstance instanceof ClassInstanceExpr
|
||||
{
|
||||
override DataFlow::Node getOutputNode() { result.asExpr() = this }
|
||||
abstract class NonceParameterInstantiation extends ClassInstanceExpr {
|
||||
DataFlow::Node getOutputNode() { result.asExpr() = this }
|
||||
|
||||
abstract DataFlow::Node getInputNode();
|
||||
}
|
||||
|
||||
class IvParameterSpecInstance extends NonceParameterInstantiation {
|
||||
@@ -396,32 +397,25 @@ module JCAModel {
|
||||
}
|
||||
}
|
||||
|
||||
module NonceArtifactToCipherInitCallConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
exists(NonceParameterInstantiation n |
|
||||
src = n.getOutputNode() and
|
||||
not exists(IvParameterSpecGetIvCall m | n.getInputNode().asExpr() = m)
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(CipherInitCall c | c.getNonceArg() = sink.asExpr())
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(IvParameterSpecGetIvCall m |
|
||||
node1.asExpr() = m.getQualifier() and
|
||||
node2.asExpr() = m
|
||||
)
|
||||
or
|
||||
exists(NonceParameterInstantiation n |
|
||||
node1 = n.getInputNode() and
|
||||
node2.asExpr() = n
|
||||
)
|
||||
}
|
||||
predicate additionalFlowSteps(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
exists(IvParameterSpecGetIvCall m |
|
||||
node1.asExpr() = m.getQualifier() and
|
||||
node2.asExpr() = m
|
||||
)
|
||||
or
|
||||
exists(NonceParameterInstantiation n |
|
||||
node1 = n.getInputNode() and
|
||||
node2 = n.getOutputNode()
|
||||
)
|
||||
}
|
||||
|
||||
module NonceArtifactToCipherInitCallFlow = DataFlow::Global<NonceArtifactToCipherInitCallConfig>;
|
||||
class NonceAdditionalFlowInputStep extends AdditionalFlowInputStep {
|
||||
DataFlow::Node output;
|
||||
|
||||
NonceAdditionalFlowInputStep() { additionalFlowSteps(this, output) }
|
||||
|
||||
override DataFlow::Node getOutput() { result = output }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow configuration to track flow from a mode field access to
|
||||
@@ -487,7 +481,7 @@ module JCAModel {
|
||||
}
|
||||
}
|
||||
|
||||
class CipherInitCallNonceArgConsumer extends Crypto::ArtifactConsumer instanceof Expr {
|
||||
class CipherInitCallNonceArgConsumer extends Crypto::NonceArtifactConsumer instanceof Expr {
|
||||
CipherInitCallNonceArgConsumer() { this = any(CipherInitCall call).getNonceArg() }
|
||||
|
||||
override DataFlow::Node getInputNode() { result.asExpr() = this }
|
||||
|
||||
@@ -65,6 +65,19 @@ class GenericRemoteDataSource extends Crypto::GenericRemoteDataSource {
|
||||
override string getAdditionalDescription() { result = this.toString() }
|
||||
}
|
||||
|
||||
class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource instanceof Literal {
|
||||
override DataFlow::Node getOutputNode() { result.asExpr() = this }
|
||||
|
||||
override predicate flowsTo(Crypto::FlowAwareElement other) {
|
||||
other instanceof NonceArtifactInstance and
|
||||
// limit to only nonces for now
|
||||
// TODO: separate config to avoid blowing up data-flow analysis
|
||||
GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
|
||||
}
|
||||
|
||||
override string getAdditionalDescription() { result = this.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Random number generation, where each instance is modelled as the expression
|
||||
* tied to an output node (i.e., the result of the source of randomness)
|
||||
@@ -94,6 +107,12 @@ class InsecureRandomnessInstance extends RandomnessInstance {
|
||||
/**
|
||||
* Artifact output to node input configuration
|
||||
*/
|
||||
abstract class AdditionalFlowInputStep extends DataFlow::Node {
|
||||
abstract DataFlow::Node getOutput();
|
||||
|
||||
final DataFlow::Node getInput() { result = this }
|
||||
}
|
||||
|
||||
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source = any(Crypto::ArtifactElement artifact).getOutputNode()
|
||||
@@ -106,14 +125,28 @@ module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
node = any(Crypto::FlowAwareElement element).getOutputNode()
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
node1.(AdditionalFlowInputStep).getOutput() = node2
|
||||
}
|
||||
}
|
||||
|
||||
module ArtifactUniversalFlow = DataFlow::Global<ArtifactUniversalFlowConfig>;
|
||||
|
||||
abstract class NonceArtifactInstance extends Crypto::NonceArtifactInstance {
|
||||
class NonceArtifactInstance extends Crypto::NonceArtifactInstance {
|
||||
NonceArtifactInstance() { this instanceof Crypto::NonceArtifactConsumer }
|
||||
|
||||
override predicate flowsTo(Crypto::FlowAwareElement other) {
|
||||
ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode())
|
||||
}
|
||||
|
||||
override DataFlow::Node getOutputNode() {
|
||||
result = this.(Crypto::NonceArtifactConsumer).getOutputNode()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInputNode() {
|
||||
result = this.(Crypto::NonceArtifactConsumer).getInputNode()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,6 +164,10 @@ module GenericDataSourceUniversalFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
node = any(Crypto::FlowAwareElement element).getOutputNode()
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
node1.(AdditionalFlowInputStep).getOutput() = node2
|
||||
}
|
||||
}
|
||||
|
||||
module GenericDataSourceUniversalFlow = DataFlow::Global<GenericDataSourceUniversalFlowConfig>;
|
||||
|
||||
@@ -205,12 +205,16 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
abstract AlgorithmElement getAKnownAlgorithmSource();
|
||||
}
|
||||
|
||||
abstract class ArtifactConsumer extends ConsumerElement {
|
||||
abstract class ArtifactConsumer extends ConsumerElement, ArtifactElement {
|
||||
final override KnownElement getAKnownSource() { result = this.getAKnownArtifactSource() }
|
||||
|
||||
final ArtifactElement getAKnownArtifactSource() { result.flowsTo(this) }
|
||||
}
|
||||
|
||||
abstract class NonceArtifactConsumer extends ArtifactConsumer {
|
||||
NonceArtifactInstance asNonce() { result = this }
|
||||
}
|
||||
|
||||
abstract class CipherOperationInstance extends OperationElement {
|
||||
/**
|
||||
* 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> {
|
||||
/**
|
||||
* Gets the consumer of nonces/IVs associated with this cipher operation.
|
||||
*/
|
||||
abstract ArtifactConsumer getNonceConsumer();
|
||||
abstract NonceArtifactConsumer getNonceConsumer();
|
||||
|
||||
/**
|
||||
* Gets the consumer of plaintext or ciphertext input associated with this cipher operation.
|
||||
@@ -586,13 +590,8 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
result = instance.getCipherOperationSubtype()
|
||||
}
|
||||
|
||||
NodeBase getANonceOrUnknown() {
|
||||
result =
|
||||
this.asElement().(CipherOperationInstance).getNonceConsumer().getAKnownOrUnknownSourceNode()
|
||||
}
|
||||
|
||||
NonceNode getANonce() {
|
||||
result = this.asElement().(CipherOperationInstance).getNonceConsumer().getAKnownSourceNode()
|
||||
result.asElement() = this.asElement().(CipherOperationInstance).getNonceConsumer().asNonce()
|
||||
}
|
||||
|
||||
NodeBase getAMessageOrUnknown() {
|
||||
@@ -614,9 +613,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
|
||||
or
|
||||
// [KNOWN_OR_UNKNOWN]
|
||||
key = "Nonce" and
|
||||
if exists(this.getANonceOrUnknown())
|
||||
then result = this.getANonceOrUnknown()
|
||||
else result = this
|
||||
if exists(this.getANonce()) then result = this.getANonce() else result = this
|
||||
or
|
||||
// [KNOWN_OR_UNKNOWN]
|
||||
key = "Message" and
|
||||
|
||||
Reference in New Issue
Block a user