@@ -3,27 +3,24 @@ private import semmle.code.cpp.models.Models
3
3
private import semmle.code.cpp.models.interfaces.FormattingFunction
4
4
5
5
/**
6
- * Holds if a StringLiteral could be an algorithm literal .
6
+ * Holds if a StringLiteral could conceivably be used in some way for cryptography .
7
7
* Note: this predicate should only consider restrictions with respect to strings only.
8
- * General restrictions are in the OpenSSLAlgorithmCandidateLiteral class.
8
+ * General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
9
9
*/
10
- private predicate isOpenSSLStringLiteralAlgorithmCandidate ( StringLiteral s ) {
10
+ private predicate isOpenSSLStringLiteralGenericSourceCandidate ( StringLiteral s ) {
11
11
// 'EC' is a constant that may be used where typical algorithms are specified,
12
12
// but EC specifically means set up a default curve container, that will later be
13
13
//specified explicitly (or if not a default) curve is used.
14
14
s .getValue ( ) != "EC" and
15
15
// Ignore empty strings
16
16
s .getValue ( ) != "" and
17
- // ignore strings that represent integers, it is possible this could be used for actual
18
- // algorithms but assuming this is not the common case
19
- // NOTE: if we were to revert this restriction, we should still consider filtering "0"
20
- // to be consistent with filtering integer 0
21
- not exists ( s .getValue ( ) .toInt ( ) ) and
22
17
// Filter out strings with "%", to filter out format strings
23
18
not s .getValue ( ) .matches ( "%\\%%" ) and
24
- // Filter out strings in brackets or braces
19
+ // Filter out strings in brackets or braces (commonly seen strings not relevant for crypto)
25
20
not s .getValue ( ) .matches ( [ "[%]" , "(%)" ] ) and
26
21
// Filter out all strings of length 1, since these are not algorithm names
22
+ // NOTE/ASSUMPTION: If a user legitimately passes a string of length 1 to some configuration
23
+ // we will assume this is generally unknown. We may need to reassess this in the future.
27
24
s .getValue ( ) .length ( ) > 1 and
28
25
// Ignore all strings that are in format string calls outputing to a stream (e.g., stdout)
29
26
not exists ( FormattingFunctionCall f |
@@ -43,15 +40,14 @@ private predicate isOpenSSLStringLiteralAlgorithmCandidate(StringLiteral s) {
43
40
/**
44
41
* Holds if an IntLiteral could be an algorithm literal.
45
42
* Note: this predicate should only consider restrictions with respect to integers only.
46
- * General restrictions are in the OpenSSLAlgorithmCandidateLiteral class.
43
+ * General restrictions are in the OpenSSLGenericSourceCandidateLiteral class.
47
44
*/
48
- private predicate isOpenSSLIntLiteralAlgorithmCandidate ( Literal l ) {
45
+ private predicate isOpenSSLIntLiteralGenericSourceCandidate ( Literal l ) {
49
46
exists ( l .getValue ( ) .toInt ( ) ) and
50
47
// Ignore char literals
51
48
not l instanceof CharLiteral and
52
49
not l instanceof StringLiteral and
53
50
// Ignore integer values of 0, commonly referring to NULL only (no known algorithm 0)
54
- // Also ignore integer values greater than 5000
55
51
l .getValue ( ) .toInt ( ) != 0 and
56
52
// ASSUMPTION, no negative numbers are allowed
57
53
// RATIONALE: this is a performance improvement to avoid having to trace every number
@@ -63,10 +59,9 @@ private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
63
59
r .getExpr ( ) = l and
64
60
r .getEnclosingFunction ( ) .getType ( ) .getUnspecifiedType ( ) instanceof DerivedType
65
61
) and
66
- // A literal as an array index should never be an algorithm
62
+ // A literal as an array index should not be relevant for crypo
67
63
not exists ( ArrayExpr op | op .getArrayOffset ( ) = l ) and
68
- // A literal used in a bitwise operation may be an algorithm, but not a candidate
69
- // for the purposes of finding applied algorithms
64
+ // A literal used in a bitwise should not be relevant for crypto
70
65
not exists ( BinaryBitwiseOperation op | op .getAnOperand ( ) = l ) and
71
66
not exists ( AssignBitwiseOperation op | op .getAnOperand ( ) = l ) and
72
67
//Filter out cases where an int is assigned or initialized into a pointer, e.g., char* x = NULL;
@@ -81,7 +76,13 @@ private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
81
76
// Filter out cases where the literal is used in any kind of arithmetic operation
82
77
not exists ( BinaryArithmeticOperation op | op .getAnOperand ( ) = l ) and
83
78
not exists ( UnaryArithmeticOperation op | op .getOperand ( ) = l ) and
84
- not exists ( AssignArithmeticOperation op | op .getAnOperand ( ) = l )
79
+ not exists ( AssignArithmeticOperation op | op .getAnOperand ( ) = l ) and
80
+ // If a literal has no parent ignore it, this is a workaround for the current inability
81
+ // to find a literal in an array declaration: int x[100];
82
+ // NOTE/ASSUMPTION: this value might actually be relevant for finding hard coded sizes
83
+ // consider size as inferred through the allocation of a buffer.
84
+ // In these cases, we advise that the source is not generic and must be traced explicitly.
85
+ exists ( l .getParent ( ) )
85
86
}
86
87
87
88
/**
@@ -96,11 +97,11 @@ private predicate isOpenSSLIntLiteralAlgorithmCandidate(Literal l) {
96
97
* "AES" may be a legitimate algorithm literal, but the literal will not be used for an operation directly
97
98
* since it is in a equality comparison, hence this case would also be filtered.
98
99
*/
99
- class OpenSSLAlgorithmCandidateLiteral extends Literal {
100
- OpenSSLAlgorithmCandidateLiteral ( ) {
100
+ class OpenSSLGenericSourceCandidateLiteral extends Literal {
101
+ OpenSSLGenericSourceCandidateLiteral ( ) {
101
102
(
102
- isOpenSSLIntLiteralAlgorithmCandidate ( this ) or
103
- isOpenSSLStringLiteralAlgorithmCandidate ( this )
103
+ isOpenSSLIntLiteralGenericSourceCandidate ( this ) or
104
+ isOpenSSLStringLiteralGenericSourceCandidate ( this )
104
105
) and
105
106
// ********* General filters beyond what is filtered for strings and ints *********
106
107
// An algorithm literal in a switch case will not be directly applied to an operation.
0 commit comments