private import codeql.cryptography.Model import semmle.code.cpp.ir.IR import semmle.code.cpp.security.FlowSources as FlowSources private import cpp as Lang module CryptoInput implements InputSig { class DataFlowNode = DataFlow::Node; class LocatableElement = Lang::Locatable; class UnknownLocation = Lang::UnknownDefaultLocation; } module Crypto = CryptographyBase; /** * Artifact output to node input configuration */ abstract class AdditionalFlowInputStep extends DataFlow::Node { abstract DataFlow::Node getOutput(); final DataFlow::Node getInput() { result = this } } // /** // * Generic data source to node input configuration // */ // module GenericDataSourceUniversalFlowConfig implements DataFlow::ConfigSig { // predicate isSource(DataFlow::Node source) { // source = any(Crypto::GenericDataSourceInstance i).getOutputNode() // } // predicate isSink(DataFlow::Node sink) { // sink = any(Crypto::FlowAwareElement other).getInputNode() // } // predicate isBarrierOut(DataFlow::Node node) { // node = any(Crypto::FlowAwareElement element).getInputNode() // } // predicate isBarrierIn(DataFlow::Node node) { // node = any(Crypto::FlowAwareElement element).getOutputNode() // } // predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // node1.(AdditionalFlowInputStep).getOutput() = node2 // } // } // // // TODO: I think this will be inefficient, no? // // class ConstantDataSource extends Crypto::GenericConstantOrAllocationSource instanceof Literal { // // override DataFlow::Node getOutputNode() { // // result.asExpr() = this // // } // // override predicate flowsTo(Crypto::FlowAwareElement other) { // // // TODO: separate config to avoid blowing up data-flow analysis // // GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode()) // // } // // override string getAdditionalDescription() { result = this.toString() } // // } // /** // * Definitions of various generic data sources // */ // // final class DefaultFlowSource = SourceNode; // // final class DefaultRemoteFlowSource = RemoteFlowSource; // // class GenericLocalDataSource extends Crypto::GenericLocalDataSource { // // GenericLocalDataSource() { // // any(DefaultFlowSource src | not src instanceof DefaultRemoteFlowSource).asExpr() = this // // } // // override DataFlow::Node getOutputNode() { result.asExpr() = this } // // override predicate flowsTo(Crypto::FlowAwareElement other) { // // GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode()) // // } // // override string getAdditionalDescription() { result = this.toString() } // // } // // class GenericRemoteDataSource extends Crypto::GenericRemoteDataSource { // // GenericRemoteDataSource() { any(DefaultRemoteFlowSource src).asExpr() = this } // // override DataFlow::Node getOutputNode() { result.asExpr() = this } // // override predicate flowsTo(Crypto::FlowAwareElement other) { // // GenericDataSourceUniversalFlow::flow(this.getOutputNode(), other.getInputNode()) // // } // // override string getAdditionalDescription() { result = this.toString() } // // } // module GenericDataSourceUniversalFlow = DataFlow::Global; module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source = any(Crypto::ArtifactElement artifact).getOutputNode() } predicate isSink(DataFlow::Node sink) { sink = any(Crypto::FlowAwareElement other).getInputNode() } predicate isBarrierOut(DataFlow::Node node) { node = any(Crypto::FlowAwareElement element).getInputNode() } 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; abstract class CipherOutputArtifact extends Crypto::CipherOutputArtifactInstance { override predicate flowsTo(Crypto::FlowAwareElement other) { ArtifactUniversalFlow::flow(this.getOutputNode(), other.getInputNode()) } } import OpenSSL.OpenSSL