Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions go/ql/lib/semmle/go/Concepts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand All @@ -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) }
}
}
3 changes: 2 additions & 1 deletion go/ql/lib/semmle/go/Decls.qll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Provides classes for working with declarations.
*/
overlay[local]
overlay[local?]
module;

import go
Expand Down Expand Up @@ -137,6 +137,7 @@ class FuncDef extends @funcdef, StmtParent, ExprParent {
/**
* Gets a call to this function.
*/
overlay[global]
DataFlow::CallNode getACall() { result.getACallee() = this }

/** Holds if this function is variadic. */
Expand Down
3 changes: 2 additions & 1 deletion go/ql/lib/semmle/go/Scopes.qll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Provides classes for working with scopes and declared objects.
*/
overlay[local]
overlay[local?]
module;

import go
Expand Down Expand Up @@ -418,6 +418,7 @@ class Function extends ValueEntity, @functionobject {
* This includes calls that target this function indirectly, by calling an
* interface method that this function implements.
*/
overlay[global]
pragma[nomagic]
DataFlow::CallNode getACall() { this = result.getACalleeIncludingExternals().asFunction() }

Expand Down
4 changes: 3 additions & 1 deletion go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
overlay[local]
overlay[local?]
module;

private import go
Expand Down Expand Up @@ -488,6 +488,7 @@ module Public {
* For virtual calls, we look up possible targets in all types that implement the receiver
* interface type.
*/
overlay[global]
Callable getACalleeIncludingExternals() {
result = this.getACalleeWithoutVirtualDispatch()
or
Expand All @@ -504,6 +505,7 @@ module Public {
* As `getACalleeIncludingExternals`, except excluding external functions (those for which
* we lack a definition, such as standard library functions).
*/
overlay[global]
pragma[nomagic]
FuncDef getACallee() { result = this.getACalleeIncludingExternals().getFuncDef() }

Expand Down
30 changes: 21 additions & 9 deletions go/ql/lib/semmle/go/frameworks/CryptoLibraries.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}

/**
Expand All @@ -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")
Expand All @@ -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 }
}
}
}
Expand Down
Loading