Skip to content

Commit 1cf4918

Browse files
committed
Update coverage threshold to 75 and add parameter validation tests for encryption functions
1 parent 67f5ecd commit 1cf4918

2 files changed

Lines changed: 236 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ jobs:
246246
echo "Functions: ${FUNC_COV}%"
247247
echo "Branches: ${BRANCH_COV}%"
248248
249-
# Set coverage threshold based on current achievable coverage
250-
THRESHOLD=72
249+
# Set coverage threshold
250+
THRESHOLD=75
251251
252252
# Check thresholds using bc for floating point comparison
253253
if command -v bc >/dev/null 2>&1; then

tests/unit/test_encrypt.c

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,234 @@ static int test_encrypt_simple_coverage(void) {
961961
return 0;
962962
}
963963

964+
// Test parameter validation in key functions
965+
static int test_encrypt_parameter_validation(void) {
966+
#ifdef BFC_WITH_SODIUM
967+
bfc_encrypt_key_t key;
968+
uint8_t salt[BFC_ENC_SALT_SIZE] = {0};
969+
970+
// Test NULL password in bfc_encrypt_key_from_password
971+
int result = bfc_encrypt_key_from_password(NULL, 10, salt, &key);
972+
assert(result == BFC_E_INVAL);
973+
974+
// Test NULL key in bfc_encrypt_key_from_password
975+
result = bfc_encrypt_key_from_password("password", 8, salt, NULL);
976+
assert(result == BFC_E_INVAL);
977+
978+
// Test NULL key in bfc_encrypt_key_from_bytes
979+
uint8_t raw_key[BFC_ENC_KEY_SIZE] = {0};
980+
result = bfc_encrypt_key_from_bytes(raw_key, NULL);
981+
assert(result == BFC_E_INVAL);
982+
983+
// Test NULL raw_key in bfc_encrypt_key_from_bytes
984+
result = bfc_encrypt_key_from_bytes(NULL, &key);
985+
assert(result == BFC_E_INVAL);
986+
987+
// Test NULL salt in bfc_encrypt_generate_salt
988+
result = bfc_encrypt_generate_salt(NULL);
989+
assert(result == BFC_E_INVAL);
990+
#endif
991+
return 0;
992+
}
993+
994+
// Test encryption data function parameter validation
995+
static int test_encrypt_data_parameter_validation(void) {
996+
#ifdef BFC_WITH_SODIUM
997+
bfc_encrypt_key_t key;
998+
const char* password = "testpass";
999+
uint8_t salt[BFC_ENC_SALT_SIZE] = {0};
1000+
int result = bfc_encrypt_key_from_password(password, strlen(password), salt, &key);
1001+
assert(result == BFC_OK);
1002+
1003+
const char* test_data = "test";
1004+
const char* path = "test/path";
1005+
1006+
// Test NULL key in bfc_encrypt_data
1007+
bfc_encrypt_result_t enc_result =
1008+
bfc_encrypt_data(NULL, test_data, strlen(test_data), path, strlen(path));
1009+
assert(enc_result.error == BFC_E_INVAL);
1010+
assert(enc_result.data == NULL);
1011+
1012+
// Test NULL input in bfc_encrypt_data
1013+
enc_result = bfc_encrypt_data(&key, NULL, 10, path, strlen(path));
1014+
assert(enc_result.error == BFC_E_INVAL);
1015+
assert(enc_result.data == NULL);
1016+
1017+
// Test zero input_size in bfc_encrypt_data - this should actually succeed
1018+
enc_result = bfc_encrypt_data(&key, test_data, 0, path, strlen(path));
1019+
assert(enc_result.error == BFC_OK); // Zero-length encryption is allowed
1020+
free(enc_result.data);
1021+
1022+
// Test similar for decrypt function
1023+
bfc_decrypt_result_t dec_result =
1024+
bfc_decrypt_data(NULL, test_data, strlen(test_data), path, strlen(path), 100);
1025+
assert(dec_result.error == BFC_E_INVAL);
1026+
assert(dec_result.data == NULL);
1027+
1028+
dec_result = bfc_decrypt_data(&key, NULL, 10, path, strlen(path), 100);
1029+
assert(dec_result.error == BFC_E_INVAL);
1030+
assert(dec_result.data == NULL);
1031+
1032+
// Test zero input_size in bfc_decrypt_data - this might also be allowed
1033+
dec_result = bfc_decrypt_data(&key, test_data, 0, path, strlen(path), 100);
1034+
// Don't assert specific error - it depends on implementation
1035+
1036+
bfc_encrypt_key_clear(&key);
1037+
#endif
1038+
return 0;
1039+
}
1040+
1041+
// Test encryption context parameter validation
1042+
static int test_encrypt_context_parameter_validation(void) {
1043+
#ifdef BFC_WITH_SODIUM
1044+
bfc_encrypt_key_t key;
1045+
const char* password = "testpass";
1046+
uint8_t salt[BFC_ENC_SALT_SIZE] = {0};
1047+
int result = bfc_encrypt_key_from_password(password, strlen(password), salt, &key);
1048+
assert(result == BFC_OK);
1049+
1050+
const char* path = "test/path";
1051+
1052+
// Test NULL key in bfc_encrypt_ctx_create
1053+
bfc_encrypt_ctx_t* ctx = bfc_encrypt_ctx_create(NULL, path, strlen(path));
1054+
assert(ctx == NULL);
1055+
1056+
bfc_encrypt_key_clear(&key);
1057+
#endif
1058+
return 0;
1059+
}
1060+
1061+
// Test context utility functions
1062+
static int test_encrypt_context_utilities(void) {
1063+
#ifdef BFC_WITH_SODIUM
1064+
bfc_encrypt_key_t key;
1065+
const char* password = "testpass";
1066+
uint8_t salt[BFC_ENC_SALT_SIZE] = {0};
1067+
int result = bfc_encrypt_key_from_password(password, strlen(password), salt, &key);
1068+
assert(result == BFC_OK);
1069+
1070+
const char* path = "test/path";
1071+
1072+
// Test creating context with valid parameters
1073+
bfc_encrypt_ctx_t* ctx = bfc_encrypt_ctx_create(&key, path, strlen(path));
1074+
assert(ctx != NULL);
1075+
1076+
// Test getting nonce from context
1077+
uint8_t nonce[BFC_ENC_NONCE_SIZE];
1078+
result = bfc_encrypt_ctx_get_nonce(ctx, nonce);
1079+
// This might fail if not initialized, which is expected
1080+
1081+
// Test destroying context
1082+
bfc_encrypt_ctx_destroy(ctx);
1083+
1084+
// Test destroying NULL context (should not crash)
1085+
bfc_encrypt_ctx_destroy(NULL);
1086+
1087+
bfc_encrypt_key_clear(&key);
1088+
#endif
1089+
return 0;
1090+
}
1091+
1092+
// Test cryptographic edge cases
1093+
static int test_encrypt_crypto_edge_cases(void) {
1094+
#ifdef BFC_WITH_SODIUM
1095+
bfc_encrypt_key_t key;
1096+
const char* password = "testpass";
1097+
uint8_t salt[BFC_ENC_SALT_SIZE] = {0};
1098+
int result = bfc_encrypt_key_from_password(password, strlen(password), salt, &key);
1099+
assert(result == BFC_OK);
1100+
1101+
// Test encryption with empty associated data
1102+
const char* test_data = "test data";
1103+
bfc_encrypt_result_t enc_result = bfc_encrypt_data(&key, test_data, strlen(test_data), NULL, 0);
1104+
assert(enc_result.error == BFC_OK);
1105+
assert(enc_result.data != NULL);
1106+
1107+
// Test decryption with empty associated data
1108+
bfc_decrypt_result_t dec_result = bfc_decrypt_data(
1109+
&key, enc_result.data, enc_result.encrypted_size, NULL, 0, strlen(test_data));
1110+
assert(dec_result.error == BFC_OK);
1111+
assert(dec_result.decrypted_size == strlen(test_data));
1112+
assert(memcmp(dec_result.data, test_data, strlen(test_data)) == 0);
1113+
1114+
free(enc_result.data);
1115+
free(dec_result.data);
1116+
1117+
// Test with very long associated data
1118+
char long_path[1000];
1119+
memset(long_path, 'A', sizeof(long_path) - 1);
1120+
long_path[sizeof(long_path) - 1] = '\0';
1121+
1122+
enc_result = bfc_encrypt_data(&key, test_data, strlen(test_data), long_path, strlen(long_path));
1123+
assert(enc_result.error == BFC_OK);
1124+
assert(enc_result.data != NULL);
1125+
1126+
dec_result = bfc_decrypt_data(&key, enc_result.data, enc_result.encrypted_size, long_path,
1127+
strlen(long_path), strlen(test_data));
1128+
assert(dec_result.error == BFC_OK);
1129+
assert(dec_result.decrypted_size == strlen(test_data));
1130+
assert(memcmp(dec_result.data, test_data, strlen(test_data)) == 0);
1131+
1132+
free(enc_result.data);
1133+
free(dec_result.data);
1134+
1135+
bfc_encrypt_key_clear(&key);
1136+
#endif
1137+
return 0;
1138+
}
1139+
1140+
// Test corrupted ciphertext handling
1141+
static int test_encrypt_corruption_handling(void) {
1142+
#ifdef BFC_WITH_SODIUM
1143+
bfc_encrypt_key_t key;
1144+
const char* password = "testpass";
1145+
uint8_t salt[BFC_ENC_SALT_SIZE] = {0};
1146+
int result = bfc_encrypt_key_from_password(password, strlen(password), salt, &key);
1147+
assert(result == BFC_OK);
1148+
1149+
const char* test_data = "test data for corruption test";
1150+
const char* path = "test/file/path";
1151+
1152+
// First encrypt normally
1153+
bfc_encrypt_result_t enc_result =
1154+
bfc_encrypt_data(&key, test_data, strlen(test_data), path, strlen(path));
1155+
assert(enc_result.error == BFC_OK);
1156+
assert(enc_result.data != NULL);
1157+
1158+
// Test with corrupted ciphertext - flip a bit in the middle
1159+
if (enc_result.encrypted_size > 32) {
1160+
uint8_t* corrupted = malloc(enc_result.encrypted_size);
1161+
memcpy(corrupted, enc_result.data, enc_result.encrypted_size);
1162+
corrupted[enc_result.encrypted_size / 2] ^= 0x01; // Flip a bit
1163+
1164+
bfc_decrypt_result_t dec_result = bfc_decrypt_data(&key, corrupted, enc_result.encrypted_size,
1165+
path, strlen(path), strlen(test_data));
1166+
assert(dec_result.error != BFC_OK); // Should fail authentication
1167+
assert(dec_result.data == NULL);
1168+
1169+
free(corrupted);
1170+
}
1171+
1172+
// Test with wrong path (different associated data)
1173+
bfc_decrypt_result_t dec_result = bfc_decrypt_data(
1174+
&key, enc_result.data, enc_result.encrypted_size, "wrong/path", 10, strlen(test_data));
1175+
assert(dec_result.error != BFC_OK); // Should fail authentication
1176+
assert(dec_result.data == NULL);
1177+
1178+
// Test with truncated ciphertext
1179+
if (enc_result.encrypted_size > 16) {
1180+
dec_result = bfc_decrypt_data(&key, enc_result.data, enc_result.encrypted_size - 10, path,
1181+
strlen(path), strlen(test_data));
1182+
assert(dec_result.error != BFC_OK); // Should fail
1183+
assert(dec_result.data == NULL);
1184+
}
1185+
1186+
free(enc_result.data);
1187+
bfc_encrypt_key_clear(&key);
1188+
#endif
1189+
return 0;
1190+
}
1191+
9641192
int test_encrypt(void) {
9651193
int result = 0;
9661194

@@ -979,6 +1207,12 @@ int test_encrypt(void) {
9791207
result += test_additional_encryption_coverage();
9801208
result += test_encryption_key_edge_cases();
9811209
result += test_encrypt_simple_coverage();
1210+
result += test_encrypt_parameter_validation();
1211+
result += test_encrypt_data_parameter_validation();
1212+
result += test_encrypt_context_parameter_validation();
1213+
result += test_encrypt_context_utilities();
1214+
result += test_encrypt_crypto_edge_cases();
1215+
result += test_encrypt_corruption_handling();
9821216

9831217
return result;
9841218
}

0 commit comments

Comments
 (0)