@@ -47,8 +47,9 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
4747
4848 predicate nodes_graph_impl ( NodeBase node , string key , string value ) {
4949 not (
50- // exclude Artifact nodes with no edges to or from them
51- node instanceof Artifact and
50+ // exclude certain Artifact nodes with no edges to or from them
51+ node instanceof RandomNumberGeneration and
52+ // TODO: performance?
5253 not ( edges_graph_impl ( node , _, _, _) or edges_graph_impl ( _, node , _, _) )
5354 ) and
5455 (
@@ -110,17 +111,47 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
110111 abstract class PaddingAlgorithmInstance extends LocatableElement { }
111112
112113 // Artifacts
113- abstract private class ArtifactLocatableElement extends LocatableElement {
114+ abstract class ArtifactLocatableElement extends LocatableElement {
115+ /**
116+ * Gets the output node for this artifact, which should usually be the same as `this`.
117+ */
114118 abstract DataFlowNode asOutputData ( ) ;
115119
120+ /**
121+ * Gets the input node for this artifact.
122+ *
123+ * If `getInput` is implemented as `none()`, the artifact will not have inbound flow analysis.
124+ */
116125 abstract DataFlowNode getInput ( ) ;
126+
127+ /**
128+ * Holds if this artifact flows to `other`.
129+ *
130+ * This predicate should be defined generically per-language with library-specific extension support.
131+ * The expected implementation is to perform flow analysis from this artifact's output to another artifact's input.
132+ * The `other` argument should be one or more `ArtifactLocatableElement` that are sinks of the flow.
133+ *
134+ * If `flowsTo` is implemented as `none()`, the artifact will not have outbound flow analysis.
135+ */
136+ abstract predicate flowsTo ( ArtifactLocatableElement other ) ;
117137 }
118138
139+ newtype TGenericDataSourceType =
140+ FilesystemDataSource ( ) or
141+ ExternalLibraryDataSource ( ) or
142+ MemoryAllocationDataSource ( ) or
143+ ConstantDataSource ( )
144+
145+ abstract class GenericDataSourceInstance extends ArtifactLocatableElement { }
146+
119147 abstract class DigestArtifactInstance extends ArtifactLocatableElement { }
120148
121149 abstract class KeyArtifactInstance extends ArtifactLocatableElement { }
122150
123- abstract class NonceArtifactInstance extends ArtifactLocatableElement { }
151+ abstract class NonceArtifactInstance extends ArtifactLocatableElement {
152+ // no implicit outbound data-flow (only modelled in cipher operations)
153+ override predicate flowsTo ( ArtifactLocatableElement other ) { none ( ) }
154+ }
124155
125156 abstract class RandomNumberGenerationInstance extends ArtifactLocatableElement {
126157 final override DataFlowNode getInput ( ) { none ( ) }
@@ -206,10 +237,30 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
206237
207238 class Asset = NodeBase ;
208239
240+ /**
241+ * An artifact is an instance of data that is used in a cryptographic operation or produced by one.
242+ */
209243 abstract class Artifact extends NodeBase {
210- abstract DataFlowNode asOutputData ( ) ;
244+ /**
245+ * Gets the artifact locatable element associated with this artifact.
246+ *
247+ * *Implementation note*: to avoid cross-products, the result *must* only bind to the
248+ * `ArtifactLocatableElement` that is already associated with the node instance.
249+ */
250+ abstract ArtifactLocatableElement asArtifactLocatableElement ( ) ;
211251
212- abstract DataFlowNode getInputData ( ) ;
252+ final Artifact getSourceArtifact ( ) {
253+ not result = this and
254+ result .asArtifactLocatableElement ( ) .flowsTo ( this .asArtifactLocatableElement ( ) )
255+ }
256+
257+ override NodeBase getChild ( string edgeName ) {
258+ result = super .getChild ( edgeName )
259+ or
260+ // [ONLY_KNOWN] - TODO: unknown case handled by reporting a generic source type or unknown as a property
261+ edgeName = "source" and
262+ result = this .getSourceArtifact ( )
263+ }
213264 }
214265
215266 /**
@@ -224,9 +275,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
224275
225276 override Location getLocation ( ) { result = instance .getLocation ( ) }
226277
227- override DataFlowNode asOutputData ( ) { result = instance .asOutputData ( ) }
228-
229- override DataFlowNode getInputData ( ) { result = instance .getInput ( ) }
278+ override ArtifactLocatableElement asArtifactLocatableElement ( ) { result = instance }
230279 }
231280
232281 final class Nonce = NonceImpl ;
@@ -243,9 +292,7 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
243292
244293 override Location getLocation ( ) { result = instance .getLocation ( ) }
245294
246- override DataFlowNode asOutputData ( ) { result = instance .asOutputData ( ) }
247-
248- override DataFlowNode getInputData ( ) { result = instance .getInput ( ) }
295+ override ArtifactLocatableElement asArtifactLocatableElement ( ) { result = instance }
249296 }
250297
251298 final class RandomNumberGeneration = RandomNumberGenerationImpl ;
0 commit comments