0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 18:21:54 +00:00
bird/proto/bgp/bgpsec/tests.c

288 lines
12 KiB
C
Raw Normal View History

#include "validate.h"
#include <sys/param.h>
#include <openssl/ec.h>
#define HEADER(msg) printf("--------------- " msg "\n");
#define HEADER1(msg, arg) printf("--------------- " msg "\n", arg);
#define RESULT(test, is_success) { \
printf("%7.7s: ", ((is_success) ? "ok" : "not ok")); \
printf("%4d: ", __LINE__); \
printf test; \
printf("\n"); \
if (is_success) good++; \
else bad++; \
}
#define DIE(msg) do { fprintf(stderr, "CRITICAL FAIL: %s\n", msg); exit(1); } while(1);
#define DUMMYCERTFILE "router-key.15708"
#define TEST_KEY_REPO_PATH "/tmp/bgpsec-keys-testrepo"
int main(int argc, char **argv) {
byte signature[1024];
int signature_len = sizeof(signature);
char strBuffer[1024];
bgpsec_key_data key_data;
char ski[1024];
char filePrefix[MAXPATHLEN];
char fileName[MAXPATHLEN];
int signature_algorithms[] = { BGPSEC_ALGORITHM_SHA256_ECDSA_P_256, -1 };
byte data_to_sign[] = { 1,2,3,4,5,6,7,8 };
struct bgp_config bgpconfig;
bgpconfig.bgpsec_key_repo_path = TEST_KEY_REPO_PATH;
bgpconfig.bgpsec_save_binary_keys = 1;
BIGNUM newbignum;
EC_POINT *new_point;
FILE *fp;
printf("Testing:\n");
int good = 0, bad = 0;
/* test whether we can sign a block of text */
int ret;
int curveId;
int bin_save;
for(bin_save = 0; bin_save < 2; bin_save++) {
HEADER1("starting test with binary_keys = %d", bin_save);
int algorithm_count = 0;
bgpconfig.bgpsec_save_binary_keys = bin_save;
/* create a dummy certificate to use */
system("../proto/bgp/bgpsec/gen-router-key -d " TEST_KEY_REPO_PATH " -c ../proto/bgp/bgpsec/router-key.cnf -p > ski.txt");
fp = fopen("ski.txt", "r");
if (NULL == fp)
DIE("failed to open the ski.txt file that should have been created");
ski[sizeof(ski)-1] = '\0';
if (NULL == fgets(ski, sizeof(ski)-1, fp))
DIE("Couldn't read the SKI from the ski.txt file");
ski[strlen(ski)-1] = '\0'; /* chomp the LF off */
fclose(fp);
/* now define all the file names based on it the new cert */
filePrefix[sizeof(filePrefix)-1] = '\0';
snprintf(filePrefix, sizeof(filePrefix)-1, "%s/%s", TEST_KEY_REPO_PATH, ski);
generate_ski_filename(filePrefix, sizeof(filePrefix), TEST_KEY_REPO_PATH,
ski, strlen(ski));
while(signature_algorithms[algorithm_count] > 0) {
HEADER1("-- starting test with sig alg = %d",
signature_algorithms[algorithm_count]);
bgpsec_key_data key_data;
curveId = signature_algorithms[algorithm_count];
ret = bgpsec_load_key(&bgpconfig, filePrefix, &key_data,
curveId, 1);
RESULT(("cert sign: loaded the router key from tmp file: %s",
filePrefix),
ret == BGPSEC_SUCCESS);
/* generate a signature using a certificate */
signature_len =
bgpsec_sign_data_with_key(&bgpconfig,
data_to_sign, sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, sizeof(signature));
RESULT(("cert sign: algorithm %d, signature length (%d) is not negative",
signature_algorithms[algorithm_count], signature_len),
signature_len > -1);
RESULT(("cert sign: algorithm %d, signature length (%d) has at least a byte", signature_algorithms[algorithm_count], signature_len), signature_len > 0);
/* modify the private key so it can't be part of the verification */
BN_init(&newbignum);
EC_KEY_set_private_key(key_data.ecdsa_key, &newbignum);
/* verify that the signature matches */
ret = bgpsec_verify_signature_with_key(&bgpconfig, data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify signature result: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
/* verify that the signature matches */
ret = bgpsec_verify_signature_with_key(&bgpconfig, data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify signature result2: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
/* modify the public key so it can't be part of the verification */
/* (which should make the verification fail now) */
new_point = EC_POINT_new(EC_GROUP_new_by_curve_name(curveId));
EC_KEY_set_public_key(key_data.ecdsa_key, new_point);
EC_POINT_free(new_point);
/* verify that the signature no longer matches */
ret = bgpsec_verify_signature_with_key(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify signature fail result: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MISMATCH),
ret == BGPSEC_SIGNATURE_MISMATCH);
/* completely get rid of the current key */
EC_KEY_free(key_data.ecdsa_key);
key_data.ecdsa_key = NULL;
/* now reload the key from the files and use them to verify it */
/* NOTE: this should reload the previously saved binary key */
ret = bgpsec_load_key(&bgpconfig, filePrefix, &key_data, curveId, 1);
RESULT(("cert sign: loading key function returned: %d (should be %d)",
ret, BGPSEC_SUCCESS), ret == BGPSEC_SUCCESS);
/* verify that the signature matches again with the loaded key */
ret = bgpsec_verify_signature_with_key(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify signature result of generated bin key: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
/* Nuke the binary version of the key, and make sure the x.509
gets reloaded again */
snprintf(fileName, sizeof(fileName), "%s.bin_pub", filePrefix);
unlink(fileName);
ret = bgpsec_load_key(&bgpconfig, filePrefix, &key_data, curveId, 1);
RESULT(("cert sign: loading key function returned: %d (should be %d)",
ret, BGPSEC_SUCCESS), ret == BGPSEC_SUCCESS);
/* verify that the signature matches again with the loaded key */
ret = bgpsec_verify_signature_with_key(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify signature result of non-bin: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
/* completely get rid of the current key */
EC_KEY_free(key_data.ecdsa_key);
key_data.ecdsa_key = NULL;
/* now reload just the public part of the key and test just it */
ret = bgpsec_load_key(&bgpconfig, filePrefix, &key_data, curveId, 0);
RESULT(("cert sign: loading public key function returned: %d (should be %d)",
ret, BGPSEC_SUCCESS), ret == BGPSEC_SUCCESS);
/* verify that the signature matches again with the public key */
ret = bgpsec_verify_signature_with_key(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify (pub) signature result: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
/* generate a signature using a fingerprint */
/* XXX: set test directory to search for matching ski->certs */
signature_len =
bgpsec_sign_data_with_ascii_ski(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
ski, strlen(ski)+1,
signature_algorithms[algorithm_count],
signature, sizeof(signature));
RESULT(("ski sign: algorithm %d, signature length (%d) is not negative",
signature_algorithms[algorithm_count], signature_len),
signature_len > -1);
RESULT(("ski sign: algorithm %d, signature length (%d) has at least a byte", signature_algorithms[algorithm_count], signature_len), signature_len > 0);
/* verify that the signature matches */
ret = bgpsec_verify_signature_with_ascii_ski(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
ski, strlen(ski)+1,
signature_algorithms[algorithm_count],
signature, sizeof(signature));
RESULT(("ski sign: verify signature result: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
if (bin_save) {
/* Nuke the x.509 certificate version of the key, and make
sure the binary version can be loaded by itself. */
snprintf(fileName, sizeof(fileName), "%s.pub", filePrefix);
unlink(fileName);
snprintf(fileName, sizeof(fileName), "%s.private", filePrefix);
unlink(fileName);
/* verify that the signature matches with an ski */
ret = bgpsec_verify_signature_with_ascii_ski(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
ski, strlen(ski)+1,
signature_algorithms[algorithm_count],
signature, sizeof(signature));
RESULT(("ski sign: verify signature result of binary only: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
/* verify that the signature matches with the key */
ret = bgpsec_load_key(&bgpconfig, filePrefix, &key_data, curveId, 1);
RESULT(("cert sign: loading binary-only key function returned: %d (should be %d)",
ret, BGPSEC_SUCCESS), ret == BGPSEC_SUCCESS);
/* verify that the signature matches again with the loaded key */
ret = bgpsec_verify_signature_with_key(&bgpconfig,
data_to_sign,
sizeof(data_to_sign),
key_data,
signature_algorithms[algorithm_count],
signature, signature_len);
RESULT(("cert sign: verify signature result of binary-only: %d (should be %d)",
ret, BGPSEC_SIGNATURE_MATCH),
ret == BGPSEC_SIGNATURE_MATCH);
}
/* move on to the next algorithm */
algorithm_count++;
}
}
printf("\nResults:\n");
printf(" Good: %d\n", good);
printf(" Bad: %d\n", bad);
return 0;
}