/* Tests API in silcpkcs.h */ #include "silc.h" int key_len = 2048; const unsigned char p[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; int p_len = 32; int test() { SilcBool success = FALSE; SilcPKCS pkcs; unsigned char *pk, *prv; char *identifier; SilcUInt32 pk_len = 0, prv_len = 0; SilcPublicKey pubkey, pubkey2; SilcPublicKeyIdentifier ident; SilcPrivateKey privkey; SilcBuffer buf; unsigned char d[4096], d2[4096]; SilcUInt32 dlen, d2len; SilcHash sha1; SILC_LOG_DEBUG(("Registering PKCSs")); if (!silc_pkcs_register_default()) { SILC_LOG_DEBUG(("Registering PKCSs failed")); goto err; } SILC_LOG_DEBUG(("Supported PKCS: %s", silc_pkcs_get_supported())); SILC_LOG_DEBUG(("Allocate rsa PKCS")); if (!silc_pkcs_is_supported("rsa")) { SILC_LOG_DEBUG(("rsa PKCS not supported")); goto err; } if (!silc_pkcs_alloc("rsa", &pkcs)) { SILC_LOG_DEBUG(("Allocate rsa PKCS failed")); goto err; } SILC_LOG_DEBUG(("Generating new key pair")); if (!silc_pkcs_generate_key(pkcs, key_len, NULL)) { SILC_LOG_DEBUG(("Generating new key pair failed")); goto err; } SILC_LOG_DEBUG(("Key length: %d", silc_pkcs_get_key_len(pkcs))); if (silc_pkcs_get_key_len(pkcs) != key_len) { SILC_LOG_DEBUG(("Bad key length: %d != %d", silc_pkcs_get_key_len(pkcs), key_len)); goto err; } SILC_LOG_DEBUG(("PKCS name: %s", silc_pkcs_get_name(pkcs))); SILC_LOG_DEBUG(("------")); SILC_LOG_DEBUG(("------ Testing Public Key Routines")); SILC_LOG_DEBUG(("------")); SILC_LOG_DEBUG(("Get public key from PKCS")); pk = silc_pkcs_get_public_key(pkcs, &pk_len); if (!pk || !pk_len) { SILC_LOG_DEBUG(("Getting public key failed")); goto err; } SILC_LOG_DEBUG(("Making new public key identifier")); identifier = silc_pkcs_encode_identifier("foo", "bar", "foo bar", "foo@bar.com", "bar", "BB"); if (!identifier) { SILC_LOG_DEBUG(("Making new public key identifier failed")); goto err; } SILC_LOG_DEBUG(("Decoding public key identifier")); ident = silc_pkcs_decode_identifier(identifier); if (!ident) { SILC_LOG_DEBUG(("Decoding public key identifier failed")); goto err; } SILC_LOG_DEBUG(("Allocating SilcPublicKey")); pubkey = silc_pkcs_public_key_alloc("rsa", identifier, pk, pk_len); if (!pubkey) { SILC_LOG_DEBUG(("Allocating SilcPublicKey failed")); goto err; } silc_free(pk); SILC_LOG_DEBUG(("Encode SilcPublicKey data")); pk = silc_pkcs_public_key_encode(pubkey, &pk_len); if (!pk) { SILC_LOG_DEBUG(("Encode SilcPublicKey data failed")); goto err; } SILC_LOG_DEBUG(("Decode public key to SilcPublicKey")); if (!silc_pkcs_public_key_decode(pk, pk_len, &pubkey)) { SILC_LOG_DEBUG(("Decode public key to SilcPublicKey failed")); goto err; } SILC_LOG_DEBUG(("Save public key to publickey.pub")); unlink("publickey.pub"); if (!silc_pkcs_save_public_key("publickey.pub", pubkey, SILC_PKCS_FILE_PEM)) { SILC_LOG_DEBUG(("Save public key to publickey.pub failed")); goto err; } SILC_LOG_DEBUG(("Copying public key")); pubkey2 = silc_pkcs_public_key_copy(pubkey); if (!pubkey2) { SILC_LOG_DEBUG(("Copying public key failed")); goto err; } silc_pkcs_public_key_free(pubkey); SILC_LOG_DEBUG(("Load public key")); if (!silc_pkcs_load_public_key("publickey.pub", &pubkey, SILC_PKCS_FILE_PEM)) { SILC_LOG_DEBUG(("Load public key failed")); goto err; } SILC_LOG_DEBUG(("Comparing copied and loaded public keys")); if (!silc_pkcs_public_key_compare(pubkey, pubkey2)) { SILC_LOG_DEBUG(("Comparing copied and loaded public keys failed")); goto err; } SILC_LOG_DEBUG(("Match")); SILC_LOG_DEBUG(("Set public key to PKCS")); if (!silc_pkcs_public_key_set(pkcs, pubkey)) { SILC_LOG_DEBUG(("Set public key to PKCS")); goto err; } SILC_LOG_DEBUG(("Encoding public key payload")); buf = silc_pkcs_public_key_payload_encode(pubkey); if (!buf) { SILC_LOG_DEBUG(("Encoding public key payload failed")); goto err; } silc_pkcs_public_key_free(pubkey2); SILC_LOG_DEBUG(("Decoding public key payload")); if (!silc_pkcs_public_key_payload_decode(buf->data, buf->len, &pubkey2)) { SILC_LOG_DEBUG(("Decoding public key payload failed")); goto err; } SILC_LOG_DEBUG(("Comparing decoded and original public keys")); if (!silc_pkcs_public_key_compare(pubkey2, pubkey)) { SILC_LOG_DEBUG(("Comparing decoded and original public keys failed")); goto err; } SILC_LOG_DEBUG(("Match")); SILC_LOG_DEBUG(("Dumping public key identifier")); silc_show_public_key("publickey.pub"); unlink("publickey.pub"); silc_free(pk); silc_free(identifier); silc_pkcs_free_identifier(ident); silc_pkcs_public_key_free(pubkey); silc_pkcs_public_key_free(pubkey2); SILC_LOG_DEBUG(("------")); SILC_LOG_DEBUG(("------ Testing Private Key Routines")); SILC_LOG_DEBUG(("------")); SILC_LOG_DEBUG(("Get private key from PKCS")); prv = silc_pkcs_get_private_key(pkcs, &prv_len); if (!prv || !prv_len) { SILC_LOG_DEBUG(("Getting private key failed")); goto err; } SILC_LOG_DEBUG(("Allocating SilcPrivateKey")); privkey = silc_pkcs_private_key_alloc("rsa", prv, prv_len); if (!privkey) { SILC_LOG_DEBUG(("Allocating SilcPrivateKey failed")); goto err; } silc_free(prv); SILC_LOG_DEBUG(("Encode SilcPrivateKey data")); prv = silc_pkcs_private_key_encode(privkey, &prv_len); if (!prv) { SILC_LOG_DEBUG(("Encode SilcPrivateKey data failed")); goto err; } SILC_LOG_DEBUG(("Decode private key to SilcPrivateKey")); if (!silc_pkcs_private_key_decode(prv, prv_len, &privkey)) { SILC_LOG_DEBUG(("Decode private key to SilcPrivateKey failed")); goto err; } SILC_LOG_DEBUG(("Save private key to privkey.prv")); unlink("privkey.prv"); if (!silc_pkcs_save_private_key("privkey.prv", privkey, "foobar", 6, SILC_PKCS_FILE_BIN)) { SILC_LOG_DEBUG(("Save private key to priv.pub failed")); goto err; } silc_pkcs_private_key_free(privkey); SILC_LOG_DEBUG(("Load private key")); if (!silc_pkcs_load_private_key("privkey.prv", &privkey, "foobar", 6, SILC_PKCS_FILE_BIN)) { SILC_LOG_DEBUG(("Load private key failed")); goto err; } SILC_LOG_DEBUG(("Set private key to PKCS")); if (!silc_pkcs_private_key_set(pkcs, privkey)) { SILC_LOG_DEBUG(("Set private key to PKCS")); goto err; } unlink("privkey.prv"); silc_free(prv); silc_pkcs_private_key_free(privkey); SILC_LOG_DEBUG(("------")); SILC_LOG_DEBUG(("------ Testing Public Key Cryptography Operations")); SILC_LOG_DEBUG(("------")); memset(d, 0, sizeof(d)); memset(d2, 0, sizeof(d2)); SILC_LOG_DEBUG(("Encrypting data")); if (!silc_pkcs_encrypt(pkcs, (unsigned char *)p, p_len, d, &dlen)) { SILC_LOG_DEBUG(("Encrypting data failed")); goto err; } SILC_LOG_DEBUG(("Decrypting data")); if (!silc_pkcs_decrypt(pkcs, d, dlen, d2, &d2len)) { SILC_LOG_DEBUG(("Decrypting data failed")); goto err; } SILC_LOG_HEXDUMP(("Plaintext"), p, p_len); SILC_LOG_HEXDUMP(("Ciphertext"), d, dlen); SILC_LOG_HEXDUMP(("Decrypted"), d2, d2len); if (memcmp(p, d2, p_len)) { SILC_LOG_DEBUG(("Decryption failed")); goto err; } SILC_LOG_DEBUG(("Decryption successful")); memset(d, 0, sizeof(d)); memset(d2, 0, sizeof(d2)); SILC_LOG_DEBUG(("Signing data")); if (!silc_pkcs_sign(pkcs, (unsigned char *)p, p_len, d, &dlen)) { SILC_LOG_DEBUG(("Signing data failed")); goto err; } SILC_LOG_HEXDUMP(("Data"), p, p_len); SILC_LOG_HEXDUMP(("signature"), d, dlen); SILC_LOG_DEBUG(("Verifying data")); if (!silc_pkcs_verify(pkcs, d, dlen, (unsigned char *)p, p_len)) { SILC_LOG_DEBUG(("Verifying data failed")); goto err; } SILC_LOG_DEBUG(("Verification successful")); silc_hash_alloc("sha1", &sha1); SILC_LOG_DEBUG(("Signing data with hash")); if (!silc_pkcs_sign_with_hash(pkcs, sha1, (unsigned char *)p, p_len, d, &dlen)) { SILC_LOG_DEBUG(("Signing data with hash failed")); goto err; } SILC_LOG_HEXDUMP(("Data"), p, p_len); SILC_LOG_HEXDUMP(("signature"), d, dlen); SILC_LOG_DEBUG(("Verifying data with hash")); if (!silc_pkcs_verify_with_hash(pkcs, sha1, d, dlen, (unsigned char *)p, p_len)) { SILC_LOG_DEBUG(("Verifying data with hash failed")); goto err; } SILC_LOG_DEBUG(("Verification with hash successful")); silc_hash_free(sha1); silc_pkcs_free(pkcs); success = TRUE; err: SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE")); fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE"); return success; } int main(int argc, char **argv) { int success; int i; if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_set_debug_string("*crypt*,*pkcs*,*rsa*,*primegen*"); } silc_hash_register_default(); silc_hmac_register_default(); silc_cipher_register_default(); silc_rng_global_init(NULL); success = test(); for (i = 0; i < 100; i++) { success = test(); if (!success) break; } silc_pkcs_unregister_all(); silc_hash_unregister_all(); silc_hmac_unregister_all(); silc_cipher_unregister_all(); return success; }