1313 *
1414 * The classification into strong and weak are based on Wikipedia, OWASP and google (2017).
1515 */
16- private module AlgorithmNames {
16+ module AlgorithmNames {
1717 predicate isStrongBlockMode ( string name ) { name = [ "CCM" , "GCM" ] }
1818
1919 predicate isWeakBlockMode ( string name ) { name = "ECB" }
@@ -59,128 +59,7 @@ private module AlgorithmNames {
5959 predicate isWeakPasswordHashingAlgorithm ( string name ) { name = "EVPKDF" }
6060}
6161
62- bindingset [ algorithmString]
63- private string algorithmRegex ( string algorithmString ) {
64- // Algorithms usually appear in names surrounded by characters that are not
65- // alphabetical characters in the same case. This handles the upper and lower
66- // case cases.
67- result =
68- "((^|.*[^A-Z])(" + algorithmString + ")([^A-Z].*|$))" +
69- // or...
70- "|" +
71- // For lowercase, we want to be careful to avoid being confused by camelCase
72- // hence we require two preceding uppercase letters to be sure of a case switch,
73- // or a preceding non-alphabetic character
74- "((^|.*[A-Z]{2}|.*[^a-zA-Z])(" + algorithmString .toLowerCase ( ) + ")([^a-z].*|$))"
75- }
76-
77- private module OpenSSL {
78- /**
79- * A known `OpenSSL::Cipher`. Supported ciphers depend on the version of
80- * `OpenSSL` installed on a system. In the general case, a name will include
81- * the cipher name, the key length, and the block encryption mode.
82- *
83- * Note that since the cipher name itself always comes first in these names
84- * and always uses a "-" to demark to block mode, we can safely uppercase
85- * these names when checking against an `algorithmRegex`.
86- *
87- * See https://ruby-doc.org/stdlib-3.0.1/libdoc/openssl/rdoc/OpenSSL/Cipher.html
88- */
89- predicate isOpenSSLCipher ( string name ) {
90- name =
91- [
92- "AES-128-CBC" , "AES-128-CBC-HMAC-SHA1" , "AES-128-CFB" , "AES-128-CFB1" , "AES-128-CFB8" ,
93- "AES-128-CTR" , "AES-128-ECB" , "AES-128-OFB" , "AES-128-XTS" , "AES-192-CBC" , "AES-192-CFB" ,
94- "AES-192-CFB1" , "AES-192-CFB8" , "AES-192-CTR" , "AES-192-ECB" , "AES-192-OFB" , "AES-256-CBC" ,
95- "AES-256-CBC-HMAC-SHA1" , "AES-256-CFB" , "AES-256-CFB1" , "AES-256-CFB8" , "AES-256-CTR" ,
96- "AES-256-ECB" , "AES-256-OFB" , "AES-256-XTS" , "AES128" , "AES192" , "AES256" , "BF" , "BF-CBC" ,
97- "BF-CFB" , "BF-ECB" , "BF-OFB" , "CAMELLIA-128-CBC" , "CAMELLIA-128-CFB" , "CAMELLIA-128-CFB1" ,
98- "CAMELLIA-128-CFB8" , "CAMELLIA-128-ECB" , "CAMELLIA-128-OFB" , "CAMELLIA-192-CBC" ,
99- "CAMELLIA-192-CFB" , "CAMELLIA-192-CFB1" , "CAMELLIA-192-CFB8" , "CAMELLIA-192-ECB" ,
100- "CAMELLIA-192-OFB" , "CAMELLIA-256-CBC" , "CAMELLIA-256-CFB" , "CAMELLIA-256-CFB1" ,
101- "CAMELLIA-256-CFB8" , "CAMELLIA-256-ECB" , "CAMELLIA-256-OFB" , "CAMELLIA128" , "CAMELLIA192" ,
102- "CAMELLIA256" , "CAST" , "CAST-cbc" , "CAST5-CBC" , "CAST5-CFB" , "CAST5-ECB" , "CAST5-OFB" ,
103- "ChaCha" , "DES" , "DES-CBC" , "DES-CFB" , "DES-CFB1" , "DES-CFB8" , "DES-ECB" , "DES-EDE" ,
104- "DES-EDE-CBC" , "DES-EDE-CFB" , "DES-EDE-OFB" , "DES-EDE3" , "DES-EDE3-CBC" , "DES-EDE3-CFB" ,
105- "DES-EDE3-CFB1" , "DES-EDE3-CFB8" , "DES-EDE3-OFB" , "DES-OFB" , "DES3" , "DESX" , "DESX-CBC" ,
106- "GOST 28147-89" , "RC2" , "RC2-40-CBC" , "RC2-64-CBC" , "RC2-CBC" , "RC2-CFB" , "RC2-ECB" ,
107- "RC2-OFB" , "RC4" , "RC4-40" , "RC4-HMAC-MD5" , "aes-128-cbc" , "aes-128-cbc-hmac-sha1" ,
108- "aes-128-cfb" , "aes-128-cfb1" , "aes-128-cfb8" , "aes-128-ctr" , "aes-128-ecb" , "aes-128-gcm" ,
109- "aes-128-ofb" , "aes-128-xts" , "aes-192-cbc" , "aes-192-cfb" , "aes-192-cfb1" , "aes-192-cfb8" ,
110- "aes-192-ctr" , "aes-192-ecb" , "aes-192-gcm" , "aes-192-ofb" , "aes-256-cbc" ,
111- "aes-256-cbc-hmac-sha1" , "aes-256-cfb" , "aes-256-cfb1" , "aes-256-cfb8" , "aes-256-ctr" ,
112- "aes-256-ecb" , "aes-256-gcm" , "aes-256-ofb" , "aes-256-xts" , "aes128" , "aes192" , "aes256" ,
113- "bf" , "bf-cbc" , "bf-cfb" , "bf-ecb" , "bf-ofb" , "blowfish" , "camellia-128-cbc" ,
114- "camellia-128-cfb" , "camellia-128-cfb1" , "camellia-128-cfb8" , "camellia-128-ecb" ,
115- "camellia-128-ofb" , "camellia-192-cbc" , "camellia-192-cfb" , "camellia-192-cfb1" ,
116- "camellia-192-cfb8" , "camellia-192-ecb" , "camellia-192-ofb" , "camellia-256-cbc" ,
117- "camellia-256-cfb" , "camellia-256-cfb1" , "camellia-256-cfb8" , "camellia-256-ecb" ,
118- "camellia-256-ofb" , "camellia128" , "camellia192" , "camellia256" , "cast" , "cast-cbc" ,
119- "cast5-cbc" , "cast5-cfb" , "cast5-ecb" , "cast5-ofb" , "chacha" , "des" , "des-cbc" , "des-cfb" ,
120- "des-cfb1" , "des-cfb8" , "des-ecb" , "des-ede" , "des-ede-cbc" , "des-ede-cfb" , "des-ede-ofb" ,
121- "des-ede3" , "des-ede3-cbc" , "des-ede3-cfb" , "des-ede3-cfb1" , "des-ede3-cfb8" ,
122- "des-ede3-ofb" , "des-ofb" , "des3" , "desx" , "desx-cbc" , "gost89" , "gost89-cnt" , "gost89-ecb" ,
123- "id-aes128-GCM" , "id-aes192-GCM" , "id-aes256-GCM" , "rc2" , "rc2-40-cbc" , "rc2-64-cbc" ,
124- "rc2-cbc" , "rc2-cfb" , "rc2-ecb" , "rc2-ofb" , "rc4" , "rc4-40" , "rc4-hmac-md5"
125- ]
126- }
127-
128- predicate isWeakOpenSSLCipher ( string name ) {
129- isOpenSSLCipher ( name ) and
130- name .toUpperCase ( ) .regexpMatch ( getInsecureAlgorithmRegex ( ) )
131- }
132-
133- predicate isStrongOpenSSLCipher ( string name ) {
134- isOpenSSLCipher ( name ) and
135- name .toUpperCase ( ) .regexpMatch ( getSecureAlgorithmRegex ( ) ) and
136- // exclude algorithms that include a weak component
137- not name .toUpperCase ( ) .regexpMatch ( getInsecureAlgorithmRegex ( ) )
138- }
139- }
140-
14162private import AlgorithmNames
142- private import OpenSSL
143-
144- private string rankedInsecureAlgorithm ( int i ) {
145- // In this case we know these are being used for encryption, so we want to match
146- // weak hash algorithms and block modes as well.
147- result =
148- rank [ i ] ( string s |
149- isWeakEncryptionAlgorithm ( s ) or isWeakHashingAlgorithm ( s ) or isWeakBlockMode ( s )
150- )
151- }
152-
153- private string insecureAlgorithmString ( int i ) {
154- i = 1 and result = rankedInsecureAlgorithm ( i )
155- or
156- result = rankedInsecureAlgorithm ( i ) + "|" + insecureAlgorithmString ( i - 1 )
157- }
158-
159- /**
160- * Gets the regular expression used for matching strings that look like they
161- * contain an algorithm that is known to be insecure.
162- */
163- private string getInsecureAlgorithmRegex ( ) {
164- result = algorithmRegex ( insecureAlgorithmString ( max ( int i | exists ( rankedInsecureAlgorithm ( i ) ) ) ) )
165- }
166-
167- private string rankedSecureAlgorithm ( int i ) {
168- result = rank [ i ] ( string s | isStrongEncryptionAlgorithm ( s ) )
169- }
170-
171- private string secureAlgorithmString ( int i ) {
172- i = 1 and result = rankedSecureAlgorithm ( i )
173- or
174- result = rankedSecureAlgorithm ( i ) + "|" + secureAlgorithmString ( i - 1 )
175- }
176-
177- /**
178- * Gets a regular expression for matching strings that look like they
179- * contain an algorithm that is known to be secure.
180- */
181- string getSecureAlgorithmRegex ( ) {
182- result = algorithmRegex ( secureAlgorithmString ( max ( int i | exists ( rankedSecureAlgorithm ( i ) ) ) ) )
183- }
18463
18564/**
18665 * A cryptographic algorithm.
@@ -200,11 +79,6 @@ private newtype TCryptographicAlgorithm =
20079 isStrongPasswordHashingAlgorithm ( name ) and isWeak = false
20180 or
20281 isWeakPasswordHashingAlgorithm ( name ) and isWeak = true
203- } or
204- MkOpenSSLCipher ( string name , boolean isWeak ) {
205- isStrongOpenSSLCipher ( name ) and isWeak = false
206- or
207- isWeakOpenSSLCipher ( name ) and isWeak = true
20882 }
20983
21084/**
@@ -277,18 +151,3 @@ class PasswordHashingAlgorithm extends MkPasswordHashingAlgorithm, Cryptographic
277151
278152 override predicate isWeak ( ) { isWeak = true }
279153}
280-
281- /**
282- * A known OpenSSL cipher. This may include information about the block
283- * encryption mode, which can affect if the cipher is marked as being weak.
284- */
285- class OpenSSLCipher extends MkOpenSSLCipher , CryptographicAlgorithm {
286- string name ;
287- boolean isWeak ;
288-
289- OpenSSLCipher ( ) { this = MkOpenSSLCipher ( name , isWeak ) }
290-
291- override string getName ( ) { result = name }
292-
293- override predicate isWeak ( ) { isWeak = true }
294- }
0 commit comments