Skip to content

Commit d3cff2d

Browse files
committed
Crypto: Add support to trace keys, add support to find prior key gen properties that configure downstream operations. Add key size tests
1 parent 7d47994 commit d3cff2d

File tree

5 files changed

+72
-7
lines changed

5 files changed

+72
-7
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import semmle.code.cpp.dataflow.new.DataFlow
2+
private import Operations.OpenSSLOperations
3+
private import experimental.quantum.Language
4+
5+
/**
6+
* Flow from key creation to key used in a call
7+
*/
8+
module OpenSSLKeyFlowConfig implements DataFlow::ConfigSig {
9+
predicate isSource(DataFlow::Node source) {
10+
// NOTE/ASSUMPTION: it is assumed the operation is also an OpenSSLOperation.
11+
// All operations modeled for openssl should be modeled as OpenSSLOperation.
12+
exists(Crypto::KeyCreationOperationInstance keygen | keygen.getOutputKeyArtifact() = source)
13+
}
14+
15+
predicate isSink(DataFlow::Node sink) {
16+
exists(Call call | call.(Call).getAnArgument() = sink.asExpr())
17+
}
18+
//TODO: consideration for additional flow steps? Can a key be copied for example?
19+
}
20+
21+
module OpenSSLKeyFlow = TaintTracking::Global<OpenSSLKeyFlowConfig>;
22+
23+
Crypto::KeyCreationOperationInstance getSourceKeyCreationInstanceFromArg(Expr arg) {
24+
exists(DataFlow::Node src, DataFlow::Node sink |
25+
OpenSSLKeyFlow::flow(src, sink) and
26+
result.getOutputKeyArtifact() = src and
27+
sink.asExpr() = arg
28+
)
29+
}

cpp/ql/lib/experimental/quantum/OpenSSL/Operations/OpenSSLOperationBase.qll

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
private import experimental.quantum.Language
22
private import experimental.quantum.OpenSSL.CtxFlow
3+
private import experimental.quantum.OpenSSL.KeyFlow
34
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
45
// Importing these intializers here to ensure the are part of any model that is
56
// using OpenSSLOperationBase. This futher ensures that initializers are tied to opeartions
@@ -63,13 +64,29 @@ abstract class EvpAlgorithmInitializer extends EvpInitializer {
6364
}
6465

6566
abstract class EvpKeyInitializer extends EvpInitializer {
66-
//, EvpAlgorithmInitializer {
6767
abstract Expr getKeyArg();
68-
// /**
69-
// * Any key arg can potentially be traced to find the algorithm used to generate the key.
70-
// */
71-
// override Expr getAlgorithmArg(){
72-
// }
68+
}
69+
70+
/**
71+
* Any key initializer may initialize the algorithm and the key size through
72+
* the key. Extend any instance of key initializer provide initialization
73+
* of the algorithm and key size from the key.
74+
*/
75+
class EvpInitializerThroughKey extends EvpAlgorithmInitializer, EvpKeySizeInitializer instanceof EvpKeyInitializer
76+
{
77+
//TODO: charpred that traces from creation to key arg, grab creator
78+
override CtxPointerSource getContextArg() { result = EvpKeyInitializer.super.getContextArg() }
79+
80+
override Expr getAlgorithmArg() {
81+
result =
82+
getSourceKeyCreationInstanceFromArg(this.getKeyArg()).(OpenSSLOperation).getAlgorithmArg()
83+
}
84+
85+
override Expr getKeySizeArg() {
86+
result = getSourceKeyCreationInstanceFromArg(this.getKeyArg()).getKeySizeConsumer().asExpr()
87+
}
88+
89+
Expr getKeyArg() { result = EvpKeyInitializer.super.getKeyArg() }
7390
}
7491

7592
abstract class EvpIVInitializer extends EvpInitializer {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| openssl_pkey.c:55:9:55:23 | KeyGeneration | openssl_pkey.c:54:47:54:50 | Constant | openssl_pkey.c:54:47:54:50 | 2048 |
2+
| openssl_signature.c:548:9:548:23 | KeyGeneration | openssl_signature.c:547:51:547:54 | Constant | openssl_signature.c:547:51:547:54 | 2048 |
3+
| openssl_signature.c:578:9:578:23 | KeyGeneration | openssl_signature.c:569:55:569:58 | Constant | openssl_signature.c:569:55:569:58 | 2048 |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import cpp
2+
import experimental.quantum.Language
3+
4+
from Crypto::KeyCreationOperationNode n, Crypto::NodeBase src
5+
where n.getAKeySizeSource() = src
6+
select n, src, src.asElement()

shared/quantum/codeql/quantum/experimental/Model.qll

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,11 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
10511051
digestLength = 512 // TODO: verify
10521052
}
10531053

1054-
abstract private class KeyCreationOperationInstance extends OperationInstance {
1054+
/**
1055+
* Users should not extend this class directly, but instead use
1056+
* `KeyCreationOperationInstance` or `KeyDerivationOperationInstance`.
1057+
*/
1058+
abstract class KeyCreationOperationInstance extends OperationInstance {
10551059
abstract string getKeyCreationTypeDescription();
10561060

10571061
/**
@@ -1732,6 +1736,12 @@ module CryptographyBase<LocationSig Location, InputSig<Location> Input> {
17321736

17331737
override string getInternalType() { result = instance.getKeyCreationTypeDescription() }
17341738

1739+
NodeBase getAKeySizeSource() {
1740+
result = instance.getKeySizeConsumer().getConsumer().getAGenericSourceNode()
1741+
or
1742+
result = instance.getKeySizeConsumer().getConsumer().getAKnownSourceNode()
1743+
}
1744+
17351745
/**
17361746
* Gets the key artifact produced by this operation.
17371747
*/

0 commit comments

Comments
 (0)