C++: Add test cases for BrokenCryptoAlgorithm.ql.

This commit is contained in:
Geoffrey White
2021-05-12 13:54:07 +01:00
parent 7974e3ad38
commit 109fa4d38e
4 changed files with 393 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
| test2.cpp:25:2:25:9 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test2.cpp:33:7:33:14 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test2.cpp:47:7:47:14 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test2.cpp:49:4:49:24 | call to my_des_implementation | This function call specifies a broken or weak cryptographic algorithm. |
| test2.cpp:62:33:62:40 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test2.cpp:124:4:124:24 | call to my_des_implementation | This function call specifies a broken or weak cryptographic algorithm. |
| test2.cpp:172:28:172:35 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test2.cpp:182:38:182:45 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test2.cpp:192:26:192:33 | ALGO_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:38:2:38:31 | ENCRYPT_WITH_DES(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:39:2:39:31 | ENCRYPT_WITH_RC2(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:41:2:41:32 | ENCRYPT_WITH_3DES(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:42:2:42:38 | ENCRYPT_WITH_TRIPLE_DES(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:43:2:43:32 | ENCRYPT_WITH_RC20(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:44:2:44:39 | ENCRYPT_WITH_DES_REMOVED(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:49:2:49:26 | DES3ENCRYPT(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:51:2:51:32 | DES_DO_ENCRYPTION(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:52:2:52:31 | RUN_DES_ENCODING(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:53:2:53:25 | DES_ENCODE(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:54:2:54:26 | DES_SET_KEY(data,amount) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:56:2:56:9 | DES(str) | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:59:12:59:25 | SORT_ORDER_DES | This macro invocation specifies a broken or weak cryptographic algorithm. |
| test.cpp:88:2:88:11 | call to encryptDES | This function call specifies a broken or weak cryptographic algorithm. |
| test.cpp:89:2:89:11 | call to encryptRC2 | This function call specifies a broken or weak cryptographic algorithm. |
| test.cpp:91:2:91:12 | call to encrypt3DES | This function call specifies a broken or weak cryptographic algorithm. |
| test.cpp:92:2:92:17 | call to encryptTripleDES | This function call specifies a broken or weak cryptographic algorithm. |
| test.cpp:97:2:97:12 | call to DES3Encrypt | This function call specifies a broken or weak cryptographic algorithm. |
| test.cpp:101:2:101:15 | call to do_des_encrypt | This function call specifies a broken or weak cryptographic algorithm. |
| test.cpp:102:2:102:12 | call to DES_Set_Key | This function call specifies a broken or weak cryptographic algorithm. |

View File

@@ -0,0 +1 @@
Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql

View File

@@ -0,0 +1,109 @@
typedef unsigned long size_t;
// --- simple encryption macro invocations ---
void my_implementation1(void *data, size_t amount);
void my_implementation2(void *data, size_t amount);
void my_implementation3(void *data, size_t amount);
void my_implementation4(void *data, size_t amount);
void my_implementation5(void *data, size_t amount);
void my_implementation6(const char *str);
#define ENCRYPT_WITH_DES(data, amount) my_implementation1(data, amount)
#define ENCRYPT_WITH_RC2(data, amount) my_implementation2(data, amount)
#define ENCRYPT_WITH_AES(data, amount) my_implementation3(data, amount)
#define ENCRYPT_WITH_3DES(data, amount) my_implementation4(data, amount)
#define ENCRYPT_WITH_TRIPLE_DES(data, amount) my_implementation4(data, amount)
#define ENCRYPT_WITH_RC20(data, amount) my_implementation5(data, amount)
#define ENCRYPT_WITH_DES_REMOVED(data, amount)
#define DESENCRYPT(data, amount) my_implementation1(data, amount)
#define RC2ENCRYPT(data, amount) my_implementation2(data, amount)
#define AESENCRYPT(data, amount) my_implementation3(data, amount)
#define DES3ENCRYPT(data, amount) my_implementation4(data, amount)
#define DES_DO_ENCRYPTION(data, amount) my_implementation1(data, amount)
#define RUN_DES_ENCODING(data, amount) my_implementation1(data, amount)
#define DES_ENCODE(data, amount) my_implementation1(data, amount)
#define DES_SET_KEY(data, amount) my_implementation1(data, amount)
#define DES(str) my_implementation6(str)
#define DESMOND(str) my_implementation6(str)
#define ANODES(str) my_implementation6(str)
#define SORT_ORDER_DES (1)
void test_macros(void *data, size_t amount, const char *str)
{
ENCRYPT_WITH_DES(data, amount); // BAD
ENCRYPT_WITH_RC2(data, amount); // BAD
ENCRYPT_WITH_AES(data, amount); // GOOD (good algorithm)
ENCRYPT_WITH_3DES(data, amount); // GOOD (good enough algorithm) [FALSE POSITIVE]
ENCRYPT_WITH_TRIPLE_DES(data, amount); // GOOD (good enough algorithm) [FALSE POSITIVE]
ENCRYPT_WITH_RC20(data, amount); // GOOD (if there ever is an RC20 algorithm, we have no reason to believe it's weak) [FALSE POSITIVE]
ENCRYPT_WITH_DES_REMOVED(data, amount); // GOOD (implementation has been deleted) [FALSE POSITIVE]
DESENCRYPT(data, amount); // BAD [NOT DETECTED]
RC2ENCRYPT(data, amount); // BAD [NOT DETECTED]
AESENCRYPT(data, amount); // GOOD (good algorithm)
DES3ENCRYPT(data, amount); // GOOD (good enough algorithm) [FALSE POSITIVE]
DES_DO_ENCRYPTION(data, amount); // BAD
RUN_DES_ENCODING(data, amount); // BAD
DES_ENCODE(data, amount); // BAD
DES_SET_KEY(data, amount); // BAD
DES(str); // GOOD (probably nothing to do with encryption) [FALSE POSITIVE]
DESMOND(str); // GOOD (probably nothing to do with encryption)
ANODES(str); // GOOD (probably nothing to do with encryption)
int ord = SORT_ORDER_DES; // GOOD (probably nothing to do with encryption) [FALSE POSITIVE]
}
// --- simple encryption function calls ---
void encryptDES(void *data, size_t amount);
void encryptRC2(void *data, size_t amount);
void encryptAES(void *data, size_t amount);
void encrypt3DES(void *data, size_t amount);
void encryptTripleDES(void *data, size_t amount);
void DESEncrypt(void *data, size_t amount);
void RC2Encrypt(void *data, size_t amount);
void AESEncrypt(void *data, size_t amount);
void DES3Encrypt(void *data, size_t amount);
void DoDESEncryption(void *data, size_t amount);
void encryptDes(void *data, size_t amount);
void do_des_encrypt(void *data, size_t amount);
void DES_Set_Key(const char *key);
void DESSetKey(const char *key);
int Des();
void Desmond(const char *str);
void Anodes(int i);
void ConDes();
void test_functions(void *data, size_t amount, const char *str)
{
encryptDES(data, amount); // BAD
encryptRC2(data, amount); // BAD
encryptAES(data, amount); // GOOD (good algorithm)
encrypt3DES(data, amount); // GOOD (good enough algorithm) [FALSE POSITIVE]
encryptTripleDES(data, amount); // GOOD (good enough algorithm) [FALSE POSITIVE]
DESEncrypt(data, amount); // BAD
RC2Encrypt(data, amount); // BAD
AESEncrypt(data, amount); // GOOD (good algorithm)
DES3Encrypt(data, amount); // GOOD (good enough algorithm) [FALSE POSITIVE]
DoDESEncryption(data, amount); // BAD [NOT DETECTED]
encryptDes(data, amount); // BAD [NOT DETECTED]
do_des_encrypt(data, amount); // BAD
DES_Set_Key(str); // BAD
DESSetKey(str); // BAD [NOT DETECTED]
Des(); // GOOD (probably nothing to do with encryption)
Desmond(str); // GOOD (probably nothing to do with encryption)
Anodes(1); // GOOD (probably nothing to do with encryption)
ConDes(); // GOOD (probably nothing to do with encryption)
}

View File

@@ -0,0 +1,254 @@
typedef unsigned long size_t;
int strcmp(const char *s1, const char *s2);
void abort(void);
struct keytype
{
char data[16];
};
void my_des_implementation(char *data, size_t amount, keytype key);
void my_rc2_implementation(char *data, size_t amount, keytype key);
void my_aes_implementation(char *data, size_t amount, keytype key);
void my_3des_implementation(char *data, size_t amount, keytype key);
typedef void (*implementation_fn_ptr)(char *data, size_t amount, keytype key);
// --- more involved C-style example ---
#define ALGO_DES (1)
#define ALGO_AES (2)
int all_algos[] = {
ALGO_DES, // [FALSE POSITIVE]
ALGO_AES
};
void encrypt_good(char *data, size_t amount, keytype key, int algo)
{
switch (algo)
{
case ALGO_DES: // [FALSE POSITIVE]
abort();
case ALGO_AES:
{
my_aes_implementation(data, amount, key); // GOOD
} break;
}
};
void encrypt_bad(char *data, size_t amount, keytype key, int algo)
{
switch (algo)
{
case ALGO_DES:
{
my_des_implementation(data, amount, key); // BAD
} break;
case ALGO_AES:
{
my_aes_implementation(data, amount, key); // GOOD
} break;
}
};
void do_encrypts(char *data, size_t amount, keytype key)
{
encrypt_good(data, amount, key, ALGO_AES); // GOOD
encrypt_bad(data, amount, key, ALGO_DES); // BAD
}
// --- more involved CPP-style example ---
enum algorithm
{
DES,
AES
};
algorithm all_algorithms[] = {
DES,
AES
};
class MyGoodEncryptor
{
public:
MyGoodEncryptor(keytype _key, algorithm _algo) : key(_key), algo(_algo) {};
void encrypt(char *data, size_t amount);
private:
keytype key;
algorithm algo;
};
void MyGoodEncryptor :: encrypt(char *data, size_t amount)
{
switch (algo)
{
case DES:
{
throw "DES is not a good choice of encryption algorithm!";
} break;
case AES:
{
my_aes_implementation(data, amount, key); // GOOD
} break;
}
}
class MyBadEncryptor
{
public:
MyBadEncryptor(keytype _key, algorithm _algo) : key(_key), algo(_algo) {};
void encrypt(char *data, size_t amount);
private:
keytype key;
algorithm algo;
};
void MyBadEncryptor :: encrypt(char *data, size_t amount)
{
switch (algo)
{
case DES:
{
my_des_implementation(data, amount, key); // BAD
} break;
case AES:
{
my_aes_implementation(data, amount, key); // GOOD
} break;
}
}
void do_class_encrypts(char *data, size_t amount, keytype key)
{
{
MyGoodEncryptor mge(key, AES); // GOOD
mge.encrypt(data, amount);
}
{
MyBadEncryptor mbe(key, DES); // BAD [NOT DETECTED]
mbe.encrypt(data, amount);
}
}
// --- unseen implementation ---
enum use_algorithm
{
USE_DES,
USE_AES
};
void set_encryption_algorithm1(int algorithm);
void set_encryption_algorithm2(use_algorithm algorithm);
void set_encryption_algorithm3(const char *algorithm_str);
void encryption_with1(char *data, size_t amount, keytype key, int algorithm);
void encryption_with2(char *data, size_t amount, keytype key, use_algorithm algorithm);
void encryption_with3(char *data, size_t amount, keytype key, const char *algorithm_str);
int get_algorithm1();
use_algorithm get_algorithm2();
const char *get_algorithm3();
void do_unseen_encrypts(char *data, size_t amount, keytype key)
{
set_encryption_algorithm1(ALGO_DES); // BAD
set_encryption_algorithm1(ALGO_AES); // GOOD
set_encryption_algorithm2(USE_DES); // BAD [NOT DETECTED]
set_encryption_algorithm2(USE_AES); // GOOD
set_encryption_algorithm3("DES"); // BAD [NOT DETECTED]
set_encryption_algorithm3("AES"); // GOOD
set_encryption_algorithm3("AES-256"); // GOOD
encryption_with1(data, amount, key, ALGO_DES); // BAD
encryption_with1(data, amount, key, ALGO_AES); // GOOD
encryption_with2(data, amount, key, USE_DES); // BAD [NOT DETECTED]
encryption_with2(data, amount, key, USE_AES); // GOOD
encryption_with3(data, amount, key, "DES"); // BAD [NOT DETECTED]
encryption_with3(data, amount, key, "AES"); // GOOD
encryption_with3(data, amount, key, "AES-256"); // GOOD
if (get_algorithm1() == ALGO_DES) // GOOD [FALSE POSITIVE]
{
throw "DES is not a good choice of encryption algorithm!";
}
if (get_algorithm2() == USE_DES) // GOOD
{
throw "DES is not a good choice of encryption algorithm!";
}
if (strcmp(get_algorithm3(), "DES") == 0) // GOOD
{
throw "DES is not a good choice of encryption algorithm!";
}
}
// --- classes ---
class desEncrypt
{
public:
static void encrypt(const char *data);
};
class aes256Encrypt
{
public:
static void encrypt(const char *data);
};
class desCipher
{
public:
void encrypt(const char *data);
};
class aesCipher
{
public:
void encrypt(const char *data);
};
void do_classes(const char *data)
{
desEncrypt::encrypt(data); // BAD [NOT DETECTED]
aes256Encrypt::encrypt(data); // GOOD
desCipher dc;
aesCipher ac;
dc.encrypt(data); // BAD [NOT DETECTED]
ac.encrypt(data); // GOOD
}
// --- function pointer ---
void do_fn_ptr(char *data, size_t amount, keytype key)
{
implementation_fn_ptr impl;
impl = &my_des_implementation; // BAD [NOT DETECTED]
impl(data, amount, key);
impl = &my_aes_implementation; // GOOD
impl(data, amount, key);
}