diff --git a/go/ql/lib/semmle/go/Concepts.qll b/go/ql/lib/semmle/go/Concepts.qll index ffa48ea9654d..c33fb0ae6bb0 100644 --- a/go/ql/lib/semmle/go/Concepts.qll +++ b/go/ql/lib/semmle/go/Concepts.qll @@ -574,19 +574,17 @@ module Cryptography { * is one) have been initialized separately. */ abstract class EncryptionOperation extends CryptographicOperation::Range { - DataFlow::Node encryptionFlowTarget; - DataFlow::Node inputNode; + /** Gets the target node for the encryption flow. */ + abstract DataFlow::Node getEncryptionFlowTarget(); override DataFlow::Node getInitialization() { - EncryptionFlow::flow(result, encryptionFlowTarget) + EncryptionFlow::flow(result, this.getEncryptionFlowTarget()) } override EncryptionAlgorithm getAlgorithm() { result = this.getInitialization().(EncryptionAlgorithmInit).getAlgorithm() } - override DataFlow::Node getAnInput() { result = inputNode } - override BlockMode getBlockMode() { result = this.getInitialization().(BlockModeInit).getMode() } @@ -601,8 +599,12 @@ module Cryptography { int inputArg; EncryptionMethodCall() { - encryptionFlowTarget = super.getReceiver() and - inputNode = super.getArgument(inputArg) + exists(super.getReceiver()) and + exists(super.getArgument(inputArg)) } + + override DataFlow::Node getEncryptionFlowTarget() { result = super.getReceiver() } + + override DataFlow::Node getAnInput() { result = super.getArgument(inputArg) } } } diff --git a/go/ql/lib/semmle/go/frameworks/CryptoLibraries.qll b/go/ql/lib/semmle/go/frameworks/CryptoLibraries.qll index 7f0e52b449a2..f8714e8602ad 100644 --- a/go/ql/lib/semmle/go/frameworks/CryptoLibraries.qll +++ b/go/ql/lib/semmle/go/frameworks/CryptoLibraries.qll @@ -381,19 +381,26 @@ private module Crypto { } private class StreamReader extends EncryptionOperation { + DataFlow::Node encryptionFlowTarget; + DataFlow::Node inputNode; + StreamReader() { lookThroughPointerType(this.getType()).hasQualifiedName("crypto/cipher", "StreamReader") and - exists(DataFlow::Write w, DataFlow::Node base, Field f | - f.hasQualifiedName("crypto/cipher", "StreamReader", "S") and - w.writesField(base, f, encryptionFlowTarget) and - DataFlow::localFlow(base, this) + exists(DataFlow::Write wS, DataFlow::Node baseS, Field fS | + fS.hasQualifiedName("crypto/cipher", "StreamReader", "S") and + wS.writesField(baseS, fS, encryptionFlowTarget) and + DataFlow::localFlow(baseS, this) ) and - exists(DataFlow::Write w, DataFlow::Node base, Field f | - f.hasQualifiedName("crypto/cipher", "StreamReader", "R") and - w.writesField(base, f, inputNode) and - DataFlow::localFlow(base, this) + exists(DataFlow::Write wR, DataFlow::Node baseR, Field fR | + fR.hasQualifiedName("crypto/cipher", "StreamReader", "R") and + wR.writesField(baseR, fR, inputNode) and + DataFlow::localFlow(baseR, this) ) } + + override DataFlow::Node getEncryptionFlowTarget() { result = encryptionFlowTarget } + + override DataFlow::Node getAnInput() { result = inputNode } } /** @@ -402,9 +409,10 @@ private module Crypto { * so it only works within one function. */ private class StreamWriter extends EncryptionOperation { + DataFlow::Node encryptionFlowTarget; + StreamWriter() { lookThroughPointerType(this.getType()).hasQualifiedName("crypto/cipher", "StreamWriter") and - inputNode = this and exists(DataFlow::Write w, DataFlow::Node base, Field f | w.writesField(base, f, encryptionFlowTarget) and f.hasQualifiedName("crypto/cipher", "StreamWriter", "S") @@ -413,6 +421,10 @@ private module Crypto { TaintTracking::localTaint(base, this.(DataFlow::PostUpdateNode).getPreUpdateNode()) ) } + + override DataFlow::Node getEncryptionFlowTarget() { result = encryptionFlowTarget } + + override DataFlow::Node getAnInput() { result = this } } } }