Skip to content

Commit 3f35697

Browse files
author
Paolo Tranquilli
committed
Merge branch 'main' into redsun82/rust-all-features-by-default
2 parents 702fede + cb59795 commit 3f35697

File tree

50 files changed

+1706
-294
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1706
-294
lines changed

cpp/ql/lib/experimental/quantum/Language.qll

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
private import cpp as Language
2-
import semmle.code.cpp.dataflow.new.DataFlow
2+
import semmle.code.cpp.dataflow.new.TaintTracking
33
import codeql.quantum.experimental.Model
44

55
module CryptoInput implements InputSig<Language::Location> {
@@ -86,6 +86,30 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
8686
}
8787
}
8888

89+
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
90+
91+
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
92+
ConstantDataSource() {
93+
// TODO: this is an API specific workaround for OpenSSL, as 'EC' is a constant that may be used
94+
// where typical algorithms are specified, but EC specifically means set up a
95+
// default curve container, that will later be specified explicitly (or if not a default)
96+
// curve is used.
97+
this.getValue() != "EC" and
98+
// Exclude all 0's as algorithms. Currently we know of no algorithm defined as 0, and
99+
// the typical case is 0 is assigned to represent null.
100+
this.getValue().toInt() != 0
101+
}
102+
103+
override DataFlow::Node getOutputNode() { result.asExpr() = this }
104+
105+
override predicate flowsTo(Crypto::FlowAwareElement other) {
106+
// TODO: separate config to avoid blowing up data-flow analysis
107+
GenericDataSourceFlow::flow(this.getOutputNode(), other.getInputNode())
108+
}
109+
110+
override string getAdditionalDescription() { result = this.toString() }
111+
}
112+
89113
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
90114
predicate isSource(DataFlow::Node source) {
91115
source = any(Crypto::ArtifactInstance artifact).getOutputNode()

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/AlgToAVCFlow.qll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import experimental.quantum.Language
33
private import semmle.code.cpp.dataflow.new.DataFlow
44
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
55
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
6+
private import PaddingAlgorithmInstance
67

78
/**
89
* Traces 'known algorithms' to AVCs, specifically
@@ -19,6 +20,9 @@ module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::
1920
predicate isSink(DataFlow::Node sink) {
2021
exists(OpenSSLAlgorithmValueConsumer c |
2122
c.getInputNode() = sink and
23+
// exclude padding algorithm consumers, since
24+
// these consumers take in different constant values
25+
// not in the typical "known algorithm" set
2226
not c instanceof PaddingAlgorithmValueConsumer
2327
)
2428
}
@@ -43,9 +47,7 @@ module KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow =
4347
DataFlow::Global<KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig>;
4448

4549
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
46-
predicate isSource(DataFlow::Node source) {
47-
source.asExpr() instanceof KnownOpenSSLAlgorithmConstant
48-
}
50+
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSSLPaddingLiteral }
4951

5052
predicate isSink(DataFlow::Node sink) {
5153
exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink)

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/BlockAlgorithmInstance.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ private import AlgToAVCFlow
88

99
/**
1010
* Given a `KnownOpenSSLBlockModeAlgorithmConstant`, converts this to a block family type.
11-
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
11+
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
1212
*/
1313
predicate knownOpenSSLConstantToBlockModeFamilyType(
1414
KnownOpenSSLBlockModeAlgorithmConstant e, Crypto::TBlockCipherModeOfOperationType type

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/CipherAlgorithmInstance.qll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ private import BlockAlgorithmInstance
1111

1212
/**
1313
* Given a `KnownOpenSSLCipherAlgorithmConstant`, converts this to a cipher family type.
14-
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
14+
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
1515
*/
1616
predicate knownOpenSSLConstantToCipherFamilyType(
1717
KnownOpenSSLCipherAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type
@@ -104,11 +104,8 @@ class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstan
104104

105105
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
106106

107-
override string getKeySizeFixed() {
108-
exists(int keySize |
109-
this.(KnownOpenSSLCipherAlgorithmConstant).getExplicitKeySize() = keySize and
110-
result = keySize.toString()
111-
)
107+
override int getKeySizeFixed() {
108+
this.(KnownOpenSSLCipherAlgorithmConstant).getExplicitKeySize() = result
112109
}
113110

114111
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/EllipticCurveAlgorithmInstance.qll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ class KnownOpenSSLEllipticCurveConstantAlgorithmInstance extends OpenSSLAlgorith
3535
override string getRawEllipticCurveName() { result = this.(Literal).getValue().toString() }
3636

3737
override Crypto::TEllipticCurveType getEllipticCurveType() {
38-
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSSLEllipticCurveAlgorithmConstant)
39-
.getNormalizedName(), _, result)
38+
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _, result)
39+
}
40+
41+
override string getParsedEllipticCurveName() {
42+
result = this.(KnownOpenSSLEllipticCurveAlgorithmConstant).getNormalizedName()
4043
}
4144

4245
override int getKeySize() {

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/KnownAlgorithmConstants.qll

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import cpp
2-
private import experimental.quantum.OpenSSL.LibraryDetector
32

43
predicate resolveAlgorithmFromExpr(Expr e, string normalizedName, string algType) {
54
resolveAlgorithmFromCall(e, normalizedName, algType)
@@ -20,7 +19,7 @@ class KnownOpenSSLCipherAlgorithmConstant extends KnownOpenSSLAlgorithmConstant
2019

2120
KnownOpenSSLCipherAlgorithmConstant() {
2221
resolveAlgorithmFromExpr(this, _, algType) and
23-
algType.toLowerCase().matches("%encryption")
22+
algType.matches("%ENCRYPTION")
2423
}
2524

2625
int getExplicitKeySize() {
@@ -37,7 +36,7 @@ class KnownOpenSSLPaddingAlgorithmConstant extends KnownOpenSSLAlgorithmConstant
3736

3837
KnownOpenSSLPaddingAlgorithmConstant() {
3938
resolveAlgorithmFromExpr(this, _, algType) and
40-
algType.toLowerCase().matches("%padding")
39+
algType.matches("%PADDING")
4140
}
4241
}
4342

@@ -46,7 +45,7 @@ class KnownOpenSSLBlockModeAlgorithmConstant extends KnownOpenSSLAlgorithmConsta
4645

4746
KnownOpenSSLBlockModeAlgorithmConstant() {
4847
resolveAlgorithmFromExpr(this, _, algType) and
49-
algType.toLowerCase().matches("%block_mode")
48+
algType.matches("%BLOCK_MODE")
5049
}
5150
}
5251

@@ -55,7 +54,7 @@ class KnownOpenSSLHashAlgorithmConstant extends KnownOpenSSLAlgorithmConstant {
5554

5655
KnownOpenSSLHashAlgorithmConstant() {
5756
resolveAlgorithmFromExpr(this, _, algType) and
58-
algType.toLowerCase().matches("%hash")
57+
algType.matches("%HASH")
5958
}
6059

6160
int getExplicitDigestLength() {
@@ -71,7 +70,7 @@ class KnownOpenSSLEllipticCurveAlgorithmConstant extends KnownOpenSSLAlgorithmCo
7170
KnownOpenSSLEllipticCurveAlgorithmConstant() {
7271
exists(string algType |
7372
resolveAlgorithmFromExpr(this, _, algType) and
74-
algType.toLowerCase().matches("elliptic_curve")
73+
algType.matches("ELLIPTIC_CURVE")
7574
)
7675
}
7776
}
@@ -89,7 +88,6 @@ class KnownOpenSSLEllipticCurveAlgorithmConstant extends KnownOpenSSLAlgorithmCo
8988
* alias = "dss1" and target = "dsaWithSHA1"
9089
*/
9190
predicate resolveAlgorithmFromCall(Call c, string normalized, string algType) {
92-
isPossibleOpenSSLFunction(c.getTarget()) and
9391
exists(string name, string parsedTargetName |
9492
parsedTargetName =
9593
c.getTarget().getName().replaceAll("EVP_", "").toLowerCase().replaceAll("_", "-") and

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmInstances/PaddingAlgorithmInstance.qll

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,26 @@ private import AlgToAVCFlow
66
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
77
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
88

9+
/**
10+
* A class to define padding specific integer values.
11+
* from rsa.h in openssl:
12+
* # define RSA_PKCS1_PADDING 1
13+
* # define RSA_NO_PADDING 3
14+
* # define RSA_PKCS1_OAEP_PADDING 4
15+
* # define RSA_X931_PADDING 5
16+
* # define RSA_PKCS1_PSS_PADDING 6
17+
* # define RSA_PKCS1_WITH_TLS_PADDING 7
18+
* # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
19+
*/
20+
class OpenSSLPaddingLiteral extends Literal {
21+
// TODO: we can be more specific about where the literal is in a larger expression
22+
// to avoid literals that are clealy not representing an algorithm, e.g., array indices.
23+
OpenSSLPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
24+
}
25+
926
/**
1027
* Given a `KnownOpenSSLPaddingAlgorithmConstant`, converts this to a padding family type.
11-
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
28+
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
1229
*/
1330
predicate knownOpenSSLConstantToPaddingFamilyType(
1431
KnownOpenSSLPaddingAlgorithmConstant e, Crypto::TPaddingType type
@@ -60,19 +77,8 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
6077
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
6178
isPaddingSpecificConsumer = false
6279
or
63-
// Possibility 3:
64-
// from rsa.h in openssl:
65-
// # define RSA_PKCS1_PADDING 1
66-
// # define RSA_NO_PADDING 3
67-
// # define RSA_PKCS1_OAEP_PADDING 4
68-
// # define RSA_X931_PADDING 5
69-
// /* EVP_PKEY_ only */
70-
// # define RSA_PKCS1_PSS_PADDING 6
71-
// # define RSA_PKCS1_WITH_TLS_PADDING 7
72-
// /* internal RSA_ only */
73-
// # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
74-
this instanceof Literal and
75-
this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] and
80+
// Possibility 3: padding-specific literal
81+
this instanceof OpenSSLPaddingLiteral and
7682
exists(DataFlow::Node src, DataFlow::Node sink |
7783
// Sink is an argument to a CipherGetterCall
7884
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
@@ -88,24 +94,24 @@ class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInsta
8894

8995
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
9096

97+
Crypto::TPaddingType getKnownPaddingType() {
98+
this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5()
99+
or
100+
this.(Literal).getValue().toInt() = 3 and result = Crypto::NoPadding()
101+
or
102+
this.(Literal).getValue().toInt() = 4 and result = Crypto::OAEP()
103+
or
104+
this.(Literal).getValue().toInt() = 5 and result = Crypto::ANSI_X9_23()
105+
or
106+
this.(Literal).getValue().toInt() = 6 and result = Crypto::PSS()
107+
}
108+
91109
override Crypto::TPaddingType getPaddingType() {
92110
isPaddingSpecificConsumer = true and
93111
(
94-
if this.(Literal).getValue().toInt() in [1, 7, 8]
95-
then result = Crypto::PKCS1_v1_5()
96-
else
97-
if this.(Literal).getValue().toInt() = 3
98-
then result = Crypto::NoPadding()
99-
else
100-
if this.(Literal).getValue().toInt() = 4
101-
then result = Crypto::OAEP()
102-
else
103-
if this.(Literal).getValue().toInt() = 5
104-
then result = Crypto::ANSI_X9_23()
105-
else
106-
if this.(Literal).getValue().toInt() = 6
107-
then result = Crypto::PSS()
108-
else result = Crypto::OtherPadding()
112+
result = this.getKnownPaddingType()
113+
or
114+
not exists(this.getKnownPaddingType()) and result = Crypto::OtherPadding()
109115
)
110116
or
111117
isPaddingSpecificConsumer = false and

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/CipherAlgorithmValueConsumer.qll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import cpp
22
private import experimental.quantum.Language
3-
private import experimental.quantum.OpenSSL.LibraryDetector
43
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
54
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
65
private import OpenSSLAlgorithmValueConsumerBase
@@ -14,7 +13,6 @@ class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
1413

1514
EVPCipherAlgorithmValueConsumer() {
1615
resultNode.asExpr() = this and
17-
isPossibleOpenSSLFunction(this.(Call).getTarget()) and
1816
(
1917
this.(Call).getTarget().getName() in [
2018
"EVP_get_cipherbyname", "EVP_get_cipherbyobj", "EVP_get_cipherbynid"

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/DirectAlgorithmValueConsumer.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ private import experimental.quantum.Language
33
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
44
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
55

6-
// TODO: can self referential to itself, which is also an algorithm (Known algorithm)
76
/**
87
* Cases like EVP_MD5(),
98
* there is no input, rather it directly gets an algorithm

cpp/ql/lib/experimental/quantum/OpenSSL/AlgorithmValueConsumers/EllipticCurveAlgorithmValueConsumer.qll

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import cpp
22
private import experimental.quantum.Language
3-
private import experimental.quantum.OpenSSL.LibraryDetector
43
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
54
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
65
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
@@ -14,7 +13,6 @@ class EVPEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
1413

1514
EVPEllipticCurveAlgorithmConsumer() {
1615
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
17-
isPossibleOpenSSLFunction(this.(Call).getTarget()) and
1816
(
1917
this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and
2018
valueArgNode.asExpr() = this.(Call).getArgument(0)

0 commit comments

Comments
 (0)