END_TEST START_TEST(load_ec_key_file) { char filename[256], *b64key; EC_KEY *result, *key; size_t size; unsigned char *serial; int res; res = _crypto_init(); ck_assert_msg(!res, "Crypto initialization routine failed.\n"); for (size_t i = 0; i < 5; ++i) { key = _generate_ec_keypair(0); snprintf(filename, sizeof(filename), "ec-key-%zu-priv.pem", i + 1); serial = _serialize_ec_privkey(key, &size); b64key = _b64encode(serial, size); free(serial); _write_pem_data(b64key, "EC PRIVATE KEY", filename); free(b64key); snprintf(filename, sizeof(filename), "ec-key-%zu-pub.pem", i + 1); serial = _serialize_ec_pubkey(key, &size); free_ec_key(key); b64key = _b64encode(serial, size); free(serial); _write_pem_data(b64key, "PUBLIC KEY", filename); free(b64key); } for (size_t i = 0; i < 5; i++) { snprintf(filename, sizeof(filename), "ec-key-%zu-priv.pem", i + 1); result = _load_ec_privkey(filename); ck_assert_msg(result != NULL, "load_ec_privkey failed for %s", filename); free_ec_key(result); snprintf(filename, sizeof(filename), "ec-key-%zu-pub.pem", i + 1); result = _load_ec_pubkey(filename); ck_assert_msg(result != NULL, "load_ec_pubkey failed for %s", filename); free_ec_key(result); } fprintf(stderr, "EC key load from file check completed.\n"); }
/** * @brief * Return the base64-encoded string of a data buffer without padding. * @note * This function ensures the smallest possible output length with no trailing * '=' characters. * @param buf * a pointer to the data buffer to be base-64 encoded. * @param len * the length, in bytes, of the buffer to be encoded. * @return * a pointer to a newly allocated null-terminated string containing the * base64-encoded data, or NULL on failure. * @free_using{free} */ char * _b64encode_nopad(unsigned char const *buf, size_t len) { char *result, *ptr; if (!buf || !len) { RET_ERROR_PTR(ERR_BAD_PARAM, NULL); } if (!(result = _b64encode(buf, len))) { RET_ERROR_PTR(ERR_UNSPEC, "could not base64 encode input"); } ptr = result + strlen(result) - 1; while ((ptr >= result) && (*ptr == '=')) { *ptr-- = 0; } return result; }
/** * @brief Creates a keys file with specified signing and encryption keys. * @param type Type of keys file, whether the keys correspond to a user or organizational signet. * @param sign_key Pointer to the specified ed25519 key, the private portion of which will be stored in the keys file as the signing key. * @param enc_key Pointer to the specified elliptic curve key, the private portion of which will be stored in the keys file as the encryption key. * @param filename Pointer to the NULL terminated string containing the filename for the keys file. * @return 0 on success, -1 on failure. */ static int keys_file_create(keys_type_t type, ED25519_KEY *sign_key, EC_KEY *enc_key, const char *filename) { char *b64_keys = NULL; int res; size_t serial_size = 0, enc_size = 0, at = 0;; unsigned char *serial_keys = NULL, *serial_enc = NULL, serial_sign[ED25519_KEY_SIZE], sign_fid, enc_fid; dime_number_t number; if(!sign_key || !enc_key || !filename) { RET_ERROR_INT(ERR_BAD_PARAM, NULL); } switch(type) { case KEYS_TYPE_ORG: number = DIME_ORG_KEYS; sign_fid = KEYS_ORG_PRIVATE_POK; enc_fid = KEYS_ORG_PRIVATE_ENC; break; case KEYS_TYPE_USER: number = DIME_USER_KEYS; sign_fid = KEYS_USER_PRIVATE_SIGN; enc_fid = KEYS_USER_PRIVATE_ENC; break; default: RET_ERROR_INT(ERR_BAD_PARAM, NULL); break; } memcpy(serial_sign, sign_key->private_key, ED25519_KEY_SIZE); if(!(serial_enc = _serialize_ec_privkey(enc_key, &enc_size))) { _secure_wipe(serial_sign, ED25519_KEY_SIZE); RET_ERROR_INT(ERR_UNSPEC, "could not serialize private key"); } serial_size = KEYS_HEADER_SIZE + 1 + 1 + ED25519_KEY_SIZE + 1 + 2 + enc_size; if(!(serial_keys = malloc(serial_size))) { PUSH_ERROR_SYSCALL("malloc"); _secure_wipe(serial_sign, ED25519_KEY_SIZE); _secure_wipe(serial_enc, enc_size); free(serial_enc); RET_ERROR_INT(ERR_NOMEM, NULL); } memset(serial_keys, 0, serial_size); _int_no_put_2b(serial_keys, (uint16_t)number); _int_no_put_3b(serial_keys + 2, (uint32_t)(serial_size - KEYS_HEADER_SIZE)); at = KEYS_HEADER_SIZE; serial_keys[at++] = sign_fid; serial_keys[at++] = ED25519_KEY_SIZE; memcpy(serial_keys + at, serial_sign, ED25519_KEY_SIZE); at += ED25519_KEY_SIZE; _secure_wipe(serial_sign, ED25519_KEY_SIZE); serial_keys[at++] = enc_fid; _int_no_put_2b(serial_keys + at, (uint16_t)enc_size); at += 2; memcpy(serial_keys + at, serial_enc, enc_size); _secure_wipe(serial_enc, enc_size); free(serial_enc); b64_keys = _b64encode(serial_keys, serial_size); _secure_wipe(serial_keys, serial_size); free(serial_keys); if (!b64_keys) { RET_ERROR_INT(ERR_UNSPEC, "could not base64 encode the keys"); } res = _write_pem_data(b64_keys, SIGNET_PRIVATE_KEYCHAIN, filename); _secure_wipe(b64_keys, strlen(b64_keys)); free(b64_keys); if(res < 0) { RET_ERROR_INT(ERR_UNSPEC, "could not store keys in PEM file."); } return 0; }