From ee8b5cb4e89ba6775e5c5d71f1c1b720ab6fe2ce Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sat, 27 Nov 2021 14:56:07 +0300 Subject: [PATCH] Remove ECIES and PEM dump functionality --- src/bitcoinrpc.cpp | 5 - src/bitcoinrpc.h | 6 - src/cryptogram.cpp | 65 ------ src/ecies.cpp | 573 ---------------------------------------------- src/ies.h | 44 ---- src/key.cpp | 74 ------ src/key.h | 9 +- src/makefile.bsd | 3 - src/makefile.linux-mingw | 3 - src/makefile.mingw | 3 - src/makefile.osx | 15 +- src/rpccrypt.cpp | 109 --------- src/rpcdump.cpp | 29 --- src/wallet.cpp | 13 - src/wallet.h | 1 - 15 files changed, 7 insertions(+), 945 deletions(-) delete mode 100644 src/cryptogram.cpp delete mode 100644 src/ecies.cpp delete mode 100644 src/ies.h delete mode 100644 src/rpccrypt.cpp diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 863e4fe..255b7ca 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -297,7 +297,6 @@ static const CRPCCommand vRPCCommands[] = { "submitblock", &submitblock, false, false }, { "listsinceblock", &listsinceblock, false, false }, { "dumpprivkey", &dumpprivkey, false, false }, - { "dumppem", &dumppem, true, false }, { "dumpwallet", &dumpwallet, true, false }, { "importwallet", &importwallet, false, false }, { "importprivkey", &importprivkey, false, false }, @@ -323,10 +322,6 @@ static const CRPCCommand vRPCCommands[] = { "listmalleableviews", &listmalleableviews, false, false}, { "dumpmalleablekey", &dumpmalleablekey, false, false}, { "importmalleablekey", &importmalleablekey, true, false }, - { "encryptdata", &encryptdata, false, false }, - { "decryptdata", &decryptdata, false, false }, - { "encryptmessage", &encryptmessage, false, false }, - { "decryptmessage", &decryptmessage, false, false }, { "sendalert", &sendalert, false, false}, }; diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index b8599ac..5f76f6f 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -219,12 +219,6 @@ extern json_spirit::Value adjustmalleablepubkey(const json_spirit::Array& params extern json_spirit::Value listmalleableviews(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value dumpmalleablekey(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value importmalleablekey(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value dumppem(const json_spirit::Array& params, bool fHelp); - -extern json_spirit::Value encryptdata(const json_spirit::Array& params, bool fHelp); // in rpccrypt.cpp -extern json_spirit::Value decryptdata(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value encryptmessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decryptmessage(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); diff --git a/src/cryptogram.cpp b/src/cryptogram.cpp deleted file mode 100644 index c107b44..0000000 --- a/src/cryptogram.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file /cryptron/secure.c - * - * @brief Functions for handling the secure data type. - * - * $Author: Ladar Levison $ - * $Website: http://lavabit.com $ - * - */ - -#include "ies.h" -#define HEADSIZE (sizeof(cryptogram_head_t)) - -size_t cryptogram_key_length(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return head->length.key; -} - -size_t cryptogram_mac_length(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return head->length.mac; -} - -size_t cryptogram_body_length(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return head->length.body; -} - -size_t cryptogram_data_sum_length(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return (head->length.key + head->length.mac + head->length.body); -} - -size_t cryptogram_total_length(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return HEADSIZE + (head->length.key + head->length.mac + head->length.body); -} - -unsigned char * cryptogram_key_data(const cryptogram_t *cryptogram) { - return (unsigned char *)cryptogram + HEADSIZE; -} - -unsigned char * cryptogram_mac_data(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return (unsigned char *)cryptogram + (HEADSIZE + head->length.key + head->length.body); -} - -unsigned char * cryptogram_body_data(const cryptogram_t *cryptogram) { - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - return (unsigned char *)cryptogram + (HEADSIZE + head->length.key); -} - -cryptogram_t * cryptogram_alloc(size_t key, size_t mac, size_t body) { - cryptogram_t *cryptogram = (cryptogram_t *) malloc(HEADSIZE + key + mac + body); - cryptogram_head_t *head = (cryptogram_head_t *)cryptogram; - head->length.key = key; - head->length.mac = mac; - head->length.body = body; - return cryptogram; -} - -void cryptogram_free(cryptogram_t *cryptogram) { - free(cryptogram); - return; -} diff --git a/src/ecies.cpp b/src/ecies.cpp deleted file mode 100644 index dec773f..0000000 --- a/src/ecies.cpp +++ /dev/null @@ -1,573 +0,0 @@ -/** - * @file /cryptron/ecies.c - * - * @brief ECIES encryption/decryption functions. - * - * $Author: Ladar Levison $ - * $Website: http://lavabit.com $ - * - */ - -#include "ies.h" -#include -#include - -#define SET_ERROR(string) \ - sprintf(error, "%s %s:%d", (string), __FILE__, __LINE__) -#define SET_OSSL_ERROR(string) \ - sprintf(error, "%s {error = %s} %s:%d", (string), ERR_error_string(ERR_get_error(), NULL), __FILE__, __LINE__) - -/* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved. - * Taken from openssl/crypto/ecdh/ech_kdf.c in github:openssl/openssl - * ffa08b3242e0f10f1fef3c93ef3f0b51de8c27a9 */ - -/* Key derivation function from X9.62/SECG */ -/* Way more than we will ever need */ -#define ECDH_KDF_MAX (1 << 30) -int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - const unsigned char *sinfo, size_t sinfolen, - const EVP_MD *md) -{ - EVP_MD_CTX mctx; - int rv = 0; - unsigned int i; - size_t mdlen; - unsigned char ctr[4]; - if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX || Zlen > ECDH_KDF_MAX) - return 0; - mdlen = EVP_MD_size(md); - EVP_MD_CTX_init(&mctx); - for (i = 1;;i++) - { - unsigned char mtmp[EVP_MAX_MD_SIZE]; - EVP_DigestInit_ex(&mctx, md, NULL); - ctr[3] = i & 0xFF; - ctr[2] = (i >> 8) & 0xFF; - ctr[1] = (i >> 16) & 0xFF; - ctr[0] = (i >> 24) & 0xFF; - if (!EVP_DigestUpdate(&mctx, Z, Zlen)) - goto err; - if (!EVP_DigestUpdate(&mctx, ctr, sizeof(ctr))) - goto err; - if (!EVP_DigestUpdate(&mctx, sinfo, sinfolen)) - goto err; - if (outlen >= mdlen) - { - if (!EVP_DigestFinal(&mctx, out, NULL)) - goto err; - outlen -= mdlen; - if (outlen == 0) - break; - out += mdlen; - } - else - { - if (!EVP_DigestFinal(&mctx, mtmp, NULL)) - goto err; - memcpy(out, mtmp, outlen); - OPENSSL_cleanse(mtmp, mdlen); - break; - } - } - rv = 1; - err: - EVP_MD_CTX_cleanup(&mctx); - return rv; -} - -static size_t envelope_key_len(const ies_ctx_t *ctx) -{ - return EVP_CIPHER_key_length(ctx->cipher) + EVP_MD_size(ctx->md); -} - -static EC_KEY * ecies_key_create(const EC_KEY *user, char *error) { - - const EC_GROUP *group; - EC_KEY *key = NULL; - - if (!(key = EC_KEY_new())) { - SET_OSSL_ERROR("EC_KEY_new failed"); - return NULL; - } - - if (!(group = EC_KEY_get0_group(user))) { - SET_ERROR("The user key does not have group"); - EC_KEY_free(key); - return NULL; - } - - if (EC_KEY_set_group(key, group) != 1) { - SET_OSSL_ERROR("EC_KEY_set_group failed"); - EC_KEY_free(key); - return NULL; - } - - if (EC_KEY_generate_key(key) != 1) { - SET_OSSL_ERROR("EC_KEY_generate_key failed"); - EC_KEY_free(key); - return NULL; - } - - return key; -} - -static unsigned char *prepare_envelope_key(const ies_ctx_t *ctx, cryptogram_t *cryptogram, char *error) -{ - - const size_t key_buf_len = envelope_key_len(ctx); - const size_t ecdh_key_len = (EC_GROUP_get_degree(EC_KEY_get0_group(ctx->user_key)) + 7) / 8; - unsigned char *envelope_key = NULL, *ktmp = NULL; - EC_KEY *ephemeral = NULL; - size_t written_length; - - /* High-level ECDH via EVP does not allow use of arbitrary KDF function. - * We should use low-level API for KDF2 - * c.f. openssl/crypto/ec/ec_pmeth.c */ - if ((envelope_key = (unsigned char *) OPENSSL_malloc(key_buf_len)) == NULL) { - SET_ERROR("Failed to allocate memory for envelope_key"); - goto err; - } - - if (!(ephemeral = ecies_key_create(ctx->user_key, error))) { - goto err; - } - - /* key agreement and KDF - * reference: openssl/crypto/ec/ec_pmeth.c */ - ktmp = (unsigned char *) OPENSSL_malloc(ecdh_key_len); - if (ktmp == NULL) { - SET_ERROR("No memory for ECDH temporary key"); - goto err; - } - - if (ECDH_compute_key(ktmp, ecdh_key_len, EC_KEY_get0_public_key(ctx->user_key), ephemeral, NULL) - != (int)ecdh_key_len) { - SET_OSSL_ERROR("An error occurred while ECDH_compute_key"); - goto err; - } - - /* equals to ISO 18033-2 KDF2 */ - if (!ECDH_KDF_X9_62(envelope_key, key_buf_len, ktmp, ecdh_key_len, 0, 0, ctx->kdf_md)) { - SET_OSSL_ERROR("Failed to stretch with KDF2"); - goto err; - } - - /* Store the public key portion of the ephemeral key. */ - written_length = EC_POINT_point2oct( - EC_KEY_get0_group(ephemeral), - EC_KEY_get0_public_key(ephemeral), - POINT_CONVERSION_COMPRESSED, - cryptogram_key_data(cryptogram), - ctx->stored_key_length, - NULL); - if (written_length == 0) { - SET_OSSL_ERROR("Error while recording the public portion of the envelope key"); - goto err; - } - if (written_length != ctx->stored_key_length) { - SET_ERROR("Written envelope key length does not match with expected"); - goto err; - } - - EC_KEY_free(ephemeral); - OPENSSL_cleanse(ktmp, ecdh_key_len); - OPENSSL_free(ktmp); - - return envelope_key; - - err: - if (ephemeral) - EC_KEY_free(ephemeral); - if (envelope_key) { - OPENSSL_cleanse(envelope_key, key_buf_len); - OPENSSL_free(envelope_key); - } - if (ktmp) { - OPENSSL_cleanse(ktmp, ecdh_key_len); - OPENSSL_free(ktmp); - } - return NULL; -} - -static int store_cipher_body( - const ies_ctx_t *ctx, - const unsigned char *envelope_key, - const unsigned char *data, - size_t length, - cryptogram_t *cryptogram, - char *error) -{ - int out_len, len_sum = 0; - size_t expected_len = cryptogram_body_length(cryptogram); - unsigned char iv[EVP_MAX_IV_LENGTH]; - EVP_CIPHER_CTX cipher; - unsigned char *body; - - /* For now we use an empty initialization vector. */ - memset(iv, 0, EVP_MAX_IV_LENGTH); - - EVP_CIPHER_CTX_init(&cipher); - body = cryptogram_body_data(cryptogram); - - if (EVP_EncryptInit_ex(&cipher, ctx->cipher, NULL, envelope_key, iv) != 1 - || EVP_EncryptUpdate(&cipher, body, &out_len, data, length) != 1) { - SET_OSSL_ERROR("Error while trying to secure the data using the symmetric cipher"); - EVP_CIPHER_CTX_cleanup(&cipher); - return 0; - } - - if (expected_len < (size_t)out_len) { - SET_ERROR("The symmetric cipher overflowed"); - EVP_CIPHER_CTX_cleanup(&cipher); - return 0; - } - - body += out_len; - len_sum += out_len; - if (EVP_EncryptFinal_ex(&cipher, body, &out_len) != 1) { - SET_OSSL_ERROR("Error while finalizing the data using the symmetric cipher"); - EVP_CIPHER_CTX_cleanup(&cipher); - cryptogram_free(cryptogram); - return 0; - } - - EVP_CIPHER_CTX_cleanup(&cipher); - - if (expected_len < (size_t)len_sum) { - SET_ERROR("The symmetric cipher overflowed"); - return 0; - } - - return 1; -} - -static int store_mac_tag(const ies_ctx_t *ctx, const unsigned char *envelope_key, cryptogram_t *cryptogram, char *error) { - const size_t key_offset = EVP_CIPHER_key_length(ctx->cipher); - const size_t key_length = EVP_MD_size(ctx->md); - const size_t mac_length = cryptogram_mac_length(cryptogram); - unsigned int out_len; - HMAC_CTX hmac; - - HMAC_CTX_init(&hmac); - - /* Generate hash tag using encrypted data */ - if (HMAC_Init_ex(&hmac, envelope_key + key_offset, key_length, ctx->md, NULL) != 1 - || HMAC_Update(&hmac, cryptogram_body_data(cryptogram), cryptogram_body_length(cryptogram)) != 1 - || HMAC_Final(&hmac, cryptogram_mac_data(cryptogram), &out_len) != 1) { - SET_OSSL_ERROR("Unable to generate tag"); - HMAC_CTX_cleanup(&hmac); - return 0; - } - - HMAC_CTX_cleanup(&hmac); - - if (out_len != mac_length) { - SET_ERROR("MAC length expectation does not meet"); - return 0; - } - - return 1; -} - -cryptogram_t * ecies_encrypt(const ies_ctx_t *ctx, const unsigned char *data, size_t length, char *error) { - - if (!ctx || !data || !length) { - SET_ERROR("Invalid arguments"); - return NULL; - } - - const size_t block_length = EVP_CIPHER_block_size(ctx->cipher); - const size_t mac_length = EVP_MD_size(ctx->md); - cryptogram_t *cryptogram = NULL; - unsigned char *envelope_key = NULL; - - if (block_length == 0 || block_length > EVP_MAX_BLOCK_LENGTH) { - SET_ERROR("Derived block size is incorrect"); - return NULL; - } - - cryptogram = cryptogram_alloc(ctx->stored_key_length, - mac_length, - length + (length % block_length ? (block_length - (length % block_length)) : 0)); - if (!cryptogram) { - SET_ERROR("Unable to allocate a cryptogram_t buffer to hold the encrypted result."); - goto err; - } - - if ((envelope_key = prepare_envelope_key(ctx, cryptogram, error)) == NULL) { - goto err; - } - - if (!store_cipher_body(ctx, envelope_key, data, length, cryptogram, error)) { - goto err; - } - - if (!store_mac_tag(ctx, envelope_key, cryptogram, error)) { - goto err; - } - - OPENSSL_cleanse(envelope_key, envelope_key_len(ctx)); - OPENSSL_free(envelope_key); - - return cryptogram; - - err: - if (cryptogram) - cryptogram_free(cryptogram); - if (envelope_key) { - OPENSSL_cleanse(envelope_key, envelope_key_len(ctx)); - OPENSSL_free(envelope_key); - } - return NULL; -} - -static EC_KEY *ecies_key_create_public_octets(EC_KEY *user, unsigned char *octets, size_t length, char *error) { - - EC_KEY *key = NULL; - EC_POINT *point = NULL; - const EC_GROUP *group = NULL; - - if (!(key = EC_KEY_new())) { - SET_OSSL_ERROR("Cannot create instance for ephemeral key"); - return NULL; - } - - if (!(group = EC_KEY_get0_group(user))) { - SET_ERROR("Cannot get group from user key"); - EC_KEY_free(key); - return NULL; - } - - if (EC_KEY_set_group(key, group) != 1) { - SET_OSSL_ERROR("EC_KEY_set_group failed"); - EC_KEY_free(key); - return NULL; - } - - if (!(point = EC_POINT_new(group))) { - SET_OSSL_ERROR("EC_POINT_new failed"); - EC_KEY_free(key); - return NULL; - } - - if (EC_POINT_oct2point(group, point, octets, length, NULL) != 1) { - SET_OSSL_ERROR("EC_POINT_oct2point failed"); - EC_KEY_free(key); - return NULL; - } - - if (EC_KEY_set_public_key(key, point) != 1) { - SET_OSSL_ERROR("EC_KEY_set_public_key failed"); - EC_POINT_free(point); - EC_KEY_free(key); - return NULL; - } - - EC_POINT_free(point); - - if (EC_KEY_check_key(key) != 1) { - SET_OSSL_ERROR("EC_KEY_check_key failed"); - EC_KEY_free(key); - return NULL; - } - - return key; -} - -unsigned char *restore_envelope_key(const ies_ctx_t *ctx, const cryptogram_t *cryptogram, char *error) -{ - - const size_t key_buf_len = envelope_key_len(ctx); - const size_t ecdh_key_len = (EC_GROUP_get_degree(EC_KEY_get0_group(ctx->user_key)) + 7) / 8; - EC_KEY *ephemeral = NULL, *user_copy = NULL; - unsigned char *envelope_key = NULL, *ktmp = NULL; - - if ((envelope_key = (unsigned char *) OPENSSL_malloc(key_buf_len)) == NULL) { - SET_ERROR("Failed to allocate memory for envelope_key"); - goto err; - } - - if (!(user_copy = EC_KEY_new())) { - SET_OSSL_ERROR("Failed to create instance for user key copy"); - goto err; - } - - if (!(EC_KEY_copy(user_copy, ctx->user_key))) { - SET_OSSL_ERROR("Failed to copy user key"); - goto err; - } - - if (!(ephemeral = ecies_key_create_public_octets(user_copy, cryptogram_key_data(cryptogram), cryptogram_key_length(cryptogram), error))) { - goto err; - } - - /* key agreement and KDF - * reference: openssl/crypto/ec/ec_pmeth.c */ - ktmp = (unsigned char *) OPENSSL_malloc(ecdh_key_len); - if (ktmp == NULL) { - SET_ERROR("No memory for ECDH temporary key"); - goto err; - } - - if (ECDH_compute_key(ktmp, ecdh_key_len, EC_KEY_get0_public_key(ephemeral), user_copy, NULL) - != (int)ecdh_key_len) { - SET_OSSL_ERROR("An error occurred while ECDH_compute_key"); - goto err; - } - - /* equals to ISO 18033-2 KDF2 */ - if (!ECDH_KDF_X9_62(envelope_key, key_buf_len, ktmp, ecdh_key_len, 0, 0, ctx->kdf_md)) { - SET_OSSL_ERROR("Failed to stretch with KDF2"); - goto err; - } - - EC_KEY_free(user_copy); - EC_KEY_free(ephemeral); - OPENSSL_cleanse(ktmp, ecdh_key_len); - OPENSSL_free(ktmp); - - return envelope_key; - - err: - if (ephemeral) - EC_KEY_free(ephemeral); - if (user_copy) - EC_KEY_free(user_copy); - if (envelope_key) { - OPENSSL_cleanse(envelope_key, key_buf_len); - OPENSSL_free(envelope_key); - } - if (ktmp) { - OPENSSL_cleanse(ktmp, ecdh_key_len); - OPENSSL_free(ktmp); - } - return NULL; -} - -static int verify_mac(const ies_ctx_t *ctx, const cryptogram_t *cryptogram, const unsigned char * envelope_key, char *error) -{ - const size_t key_offset = EVP_CIPHER_key_length(ctx->cipher); - const size_t key_length = EVP_MD_size(ctx->md); - const size_t mac_length = cryptogram_mac_length(cryptogram); - unsigned int out_len; - HMAC_CTX hmac; - unsigned char md[EVP_MAX_MD_SIZE]; - - HMAC_CTX_init(&hmac); - - /* Generate hash tag using encrypted data */ - if (HMAC_Init_ex(&hmac, envelope_key + key_offset, key_length, ctx->md, NULL) != 1 - || HMAC_Update(&hmac, cryptogram_body_data(cryptogram), cryptogram_body_length(cryptogram)) != 1 - || HMAC_Final(&hmac, md, &out_len) != 1) { - SET_OSSL_ERROR("Unable to generate tag"); - HMAC_CTX_cleanup(&hmac); - return 0; - } - - HMAC_CTX_cleanup(&hmac); - - if (out_len != mac_length) { - SET_ERROR("MAC length expectation does not meet"); - return 0; - } - - if (memcmp(md, cryptogram_mac_data(cryptogram), mac_length) != 0) { - SET_ERROR("MAC tag verification failed"); - return 0; - } - - return 1; -} - -unsigned char *decrypt_body(const ies_ctx_t *ctx, const cryptogram_t *cryptogram, const unsigned char *envelope_key, size_t *length, char *error) -{ - int out_len; - size_t output_sum; - const size_t body_length = cryptogram_body_length(cryptogram); - unsigned char iv[EVP_MAX_IV_LENGTH], *block, *output; - EVP_CIPHER_CTX cipher; - - if (!(output = (unsigned char*)malloc(body_length + 1))) { - SET_ERROR("Failed to allocate memory for clear text"); - return NULL; - } - - /* For now we use an empty initialization vector */ - memset(iv, 0, EVP_MAX_IV_LENGTH); - memset(output, 0, body_length + 1); - - EVP_CIPHER_CTX_init(&cipher); - - block = output; - if (EVP_DecryptInit_ex(&cipher, ctx->cipher, NULL, envelope_key, iv) != 1 - || EVP_DecryptUpdate(&cipher, block, &out_len, cryptogram_body_data(cryptogram), body_length) != 1) { - SET_OSSL_ERROR("Unable to decrypt"); - EVP_CIPHER_CTX_cleanup(&cipher); - free(output); - return NULL; - } - output_sum = out_len; - - block += output_sum; - if (EVP_DecryptFinal_ex(&cipher, block, &out_len) != 1) { - printf("Unable to decrypt the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL)); - EVP_CIPHER_CTX_cleanup(&cipher); - free(output); - return NULL; - } - output_sum += out_len; - - EVP_CIPHER_CTX_cleanup(&cipher); - - *length = output_sum; - - return output; -} - -unsigned char * ecies_decrypt(const ies_ctx_t *ctx, const cryptogram_t *cryptogram, size_t *length, char *error) -{ - unsigned char *envelope_key = NULL, *output = NULL; - - if (!ctx || !cryptogram || !length || !error) { - SET_ERROR("Invalid argument"); - goto err; - } - - envelope_key = restore_envelope_key(ctx, cryptogram, error); - if (envelope_key == NULL) { - goto err; - } - - if (!verify_mac(ctx, cryptogram, envelope_key, error)) { - goto err; - } - - if ((output = decrypt_body(ctx, cryptogram, envelope_key, length, error)) == NULL) { - goto err; - } - - err: - OPENSSL_cleanse(envelope_key, envelope_key_len(ctx)); - OPENSSL_free(envelope_key); - - return output; -} - -ies_ctx_t *create_context(EC_KEY *user_key) -{ - try { - ies_ctx_t* ctx = new ies_ctx_t; - ctx->cipher = EVP_aes_128_cbc(); - ctx->md = EVP_ripemd160(); - ctx->kdf_md = EVP_ripemd160(); - ctx->stored_key_length = 33; - ctx->user_key = user_key; - return ctx; - } - catch (const std::bad_alloc& e) { - printf("Error: %s in %s:%d\n", e.what(), __FILE__, __LINE__); -// TODO: add checking to NULL where necessary - return NULL; - } -} diff --git a/src/ies.h b/src/ies.h deleted file mode 100644 index bf69a82..0000000 --- a/src/ies.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * reference: ecies.h - */ - -#ifndef _IES_H_ -#define _IES_H_ - -#include -#include -#include - -typedef struct { - const EVP_CIPHER *cipher; - const EVP_MD *md; /* for mac tag */ - const EVP_MD *kdf_md; /* for KDF */ - size_t stored_key_length; - const EC_KEY *user_key; -} ies_ctx_t; - -typedef struct { - struct { - size_t key; - size_t mac; - size_t body; - } length; -} cryptogram_head_t; - -typedef unsigned char * cryptogram_t; - -void cryptogram_free(cryptogram_t *cryptogram); -unsigned char * cryptogram_key_data(const cryptogram_t *cryptogram); -unsigned char * cryptogram_mac_data(const cryptogram_t *cryptogram); -unsigned char * cryptogram_body_data(const cryptogram_t *cryptogram); -size_t cryptogram_key_length(const cryptogram_t *cryptogram); -size_t cryptogram_mac_length(const cryptogram_t *cryptogram); -size_t cryptogram_body_length(const cryptogram_t *cryptogram); -size_t cryptogram_data_sum_length(const cryptogram_t *cryptogram); -size_t cryptogram_total_length(const cryptogram_t *cryptogram); -cryptogram_t * cryptogram_alloc(size_t key, size_t mac, size_t body); -cryptogram_t * ecies_encrypt(const ies_ctx_t *ctx, const unsigned char *data, size_t length, char *error); -unsigned char * ecies_decrypt(const ies_ctx_t *ctx, const cryptogram_t *cryptogram, size_t *length, char *error); -ies_ctx_t *create_context(EC_KEY *user_key); - -#endif /* _IES_H_ */ diff --git a/src/key.cpp b/src/key.cpp index 1f42533..8dea4f2 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -6,7 +6,6 @@ #include #include -#include #include "key.h" #include "base58.h" @@ -331,17 +330,6 @@ CSecret CKey::GetSecret(bool &fCompressed) const return vchRet; } -bool CKey::WritePEM(BIO *streamObj, const SecureString &strPassKey) const // dumppem 4KJLA99FyqMMhjjDe7KnRXK4sjtv9cCtNS /tmp/test.pem 123 -{ - EVP_PKEY *evpKey = EVP_PKEY_new(); - if (!EVP_PKEY_assign_EC_KEY(evpKey, pkey)) - return error("CKey::WritePEM() : Error initializing EVP_PKEY instance."); - if(!PEM_write_bio_PKCS8PrivateKey(streamObj, evpKey, EVP_aes_256_cbc(), (char *)&strPassKey[0], strPassKey.size(), NULL, NULL)) - return error("CKey::WritePEM() : Error writing private key data to stream object"); - - return true; -} - CSecret CKey::GetSecret() const { bool fCompressed; @@ -1216,65 +1204,3 @@ bool CMalleableKeyView::IsValid() const { return vchSecretL.size() == 32 && GetMalleablePubKey().IsValid(); } - -//// Asymmetric encryption - -void CPubKey::EncryptData(const std::vector& data, std::vector& encrypted) -{ - ies_ctx_t *ctx; - char error[1024] = "Unknown error"; - cryptogram_t *cryptogram; - - const unsigned char* pbegin = &vbytes[0]; - EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if (!o2i_ECPublicKey(&pkey, &pbegin, size())) - throw key_error("Unable to parse EC key"); - - ctx = create_context(pkey); - if (!EC_KEY_get0_public_key(ctx->user_key)) - throw key_error("Given EC key is not public key"); - - cryptogram = ecies_encrypt(ctx, (unsigned char*)&data[0], data.size(), error); - if (cryptogram == NULL) { - delete ctx; - ctx = NULL; - throw key_error(std::string("Error in encryption: %s") + error); - } - - encrypted.resize(cryptogram_data_sum_length(cryptogram)); - unsigned char *key_data = cryptogram_key_data(cryptogram); - memcpy(&encrypted[0], key_data, encrypted.size()); - cryptogram_free(cryptogram); - delete ctx; -} - -void CKey::DecryptData(const std::vector& encrypted, std::vector& data) -{ - ies_ctx_t *ctx; - char error[1024] = "Unknown error"; - cryptogram_t *cryptogram; - size_t length; - unsigned char *decrypted; - - ctx = create_context(pkey); - if (!EC_KEY_get0_private_key(ctx->user_key)) - throw key_error("Given EC key is not private key"); - - size_t key_length = ctx->stored_key_length; - size_t mac_length = EVP_MD_size(ctx->md); - cryptogram = cryptogram_alloc(key_length, mac_length, encrypted.size() - key_length - mac_length); - - memcpy(cryptogram_key_data(cryptogram), &encrypted[0], encrypted.size()); - - decrypted = ecies_decrypt(ctx, cryptogram, &length, error); - cryptogram_free(cryptogram); - delete ctx; - - if (decrypted == NULL) { - throw key_error(std::string("Error in decryption: %s") + error); - } - - data.resize(length); - memcpy(&data[0], decrypted, length); - free(decrypted); -} diff --git a/src/key.h b/src/key.h index cb5a712..8dd8f16 100644 --- a/src/key.h +++ b/src/key.h @@ -13,9 +13,9 @@ #include "uint256.h" #include "hash.h" #include "bignum.h" -#include "ies.h" #include // for EC_KEY definition +#include // secp160k1 // const unsigned int PRIVATE_KEY_SIZE = 192; @@ -206,9 +206,6 @@ public: // Reserialize to DER static bool ReserealizeSignature(std::vector& vchSig); - - // Encrypt data - void EncryptData(const std::vector& data, std::vector& encrypted); }; // secure_allocator is defined in allocators.h @@ -247,7 +244,6 @@ public: CSecret GetSecret() const; CPrivKey GetPrivKey() const; CPubKey GetPubKey() const; - bool WritePEM(BIO *streamObj, const SecureString &strPassKey) const; bool Sign(uint256 hash, std::vector& vchSig); @@ -261,9 +257,6 @@ public: // Check whether an element of a signature (r or s) is valid. static bool CheckSignatureElement(const unsigned char *vch, int len, bool half); - - // Decrypt data - void DecryptData(const std::vector& encrypted, std::vector& data); }; class CPoint diff --git a/src/makefile.bsd b/src/makefile.bsd index c7a2f24..62f8f07 100644 --- a/src/makefile.bsd +++ b/src/makefile.bsd @@ -121,7 +121,6 @@ OBJS= \ obj/stun.o \ obj/protocol.o \ obj/bitcoinrpc.o \ - obj/rpccrypt.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -136,8 +135,6 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/kernel_worker.o \ - obj/ecies.o \ - obj/cryptogram.o \ obj/ipcollector.o all: novacoind diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index 2837218..ba544fd 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -85,7 +85,6 @@ OBJS= \ obj/stun.o \ obj/protocol.o \ obj/bitcoinrpc.o \ - obj/rpccrypt.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -100,8 +99,6 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/kernel_worker.o \ - obj/ecies.o \ - obj/cryptogram.o \ obj/ipcollector.o all: novacoind.exe diff --git a/src/makefile.mingw b/src/makefile.mingw index c83e234..ccd3995 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -75,7 +75,6 @@ OBJS= \ obj/stun.o \ obj/protocol.o \ obj/bitcoinrpc.o \ - obj/rpccrypt.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -90,8 +89,6 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/kernel_worker.o \ - obj/ecies.o \ - obj/cryptogram.o \ obj/ipcollector.o all: novacoind.exe diff --git a/src/makefile.osx b/src/makefile.osx index fd6f226..0381ddd 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -6,15 +6,15 @@ # Mac OS X makefile for bitcoin # Originally by Laszlo Hanyecz (solar@heliacal.net) -CC=llvm-gcc -CXX=llvm-g++ -DEPSDIR=/opt/local +CC=clang +CXX=clang++ +DEPSDIR=/opt/homebrew INCLUDEPATHS= \ -I"$(CURDIR)" \ -I"$(CURDIR)"/obj \ -I"$(DEPSDIR)/include" \ - -I"$(DEPSDIR)/include/db48" \ + -I"$(DEPSDIR)/Cellar/berkeley-db@4/4.8.30/include" \ -I"$(CURDIR)/additional/stage/usr/include" LIBPATHS= \ @@ -30,7 +30,7 @@ LIBS= -dead_strip ifdef STATIC # Build STATIC if you are redistributing the bitcoind binary LIBS += \ - $(DEPSDIR)/lib/db48/libdb_cxx-4.8.a \ + $(DEPSDIR)/Cellar/berkeley-db@4/4.8.30/lib/libdb_cxx-4.8.a \ $(DEPSDIR)/lib/libboost_system-mt.a \ $(DEPSDIR)/lib/libboost_filesystem-mt.a \ $(DEPSDIR)/lib/libboost_program_options-mt.a \ @@ -64,7 +64,7 @@ CFLAGS = -g -msse2 endif # ppc doesn't work because we don't support big-endian -CFLAGS += -Wall -Wextra -Wformat -Wno-ignored-qualifiers -Wformat-security -Wno-unused-parameter \ +CFLAGS += -std=c++17 -Wall -Wextra -Wformat -Wno-ignored-qualifiers -Wformat-security -Wno-unused-parameter \ $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) OBJS= \ @@ -87,7 +87,6 @@ OBJS= \ obj/stun.o \ obj/protocol.o \ obj/bitcoinrpc.o \ - obj/rpccrypt.o \ obj/rpcdump.o \ obj/rpcnet.o \ obj/rpcmining.o \ @@ -102,8 +101,6 @@ OBJS= \ obj/noui.o \ obj/kernel.o \ obj/kernel_worker.o \ - obj/ecies.o \ - obj/cryptogram.o \ obj/ipcollector.o ifneq (${USE_IPV6}, -) diff --git a/src/rpccrypt.cpp b/src/rpccrypt.cpp deleted file mode 100644 index 91f0302..0000000 --- a/src/rpccrypt.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "wallet.h" -#include "bitcoinrpc.h" -#include "init.h" -#include "base58.h" - -using namespace json_spirit; -using namespace std; - -Value encryptdata(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 2) - throw runtime_error( - "encryptdata \n" - "Encrypt octet stream with provided public key..\n"); - - CPubKey pubKey(ParseHex(params[0].get_str())); - - vector vchEncrypted; - pubKey.EncryptData(ParseHex(params[1].get_str()), vchEncrypted); - - return HexStr(vchEncrypted); -} - -Value decryptdata(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 2) - throw runtime_error( - "decryptdata \n" - "Decrypt octet stream.\n"); - - EnsureWalletIsUnlocked(); - CKey key; - CBitcoinAddress addr(params[0].get_str()); - if (addr.IsValid()) { - CKeyID keyID; - addr.GetKeyID(keyID); - if (!pwalletMain->GetKey(keyID, key)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "We have no private key for this address"); - } - else { - CBitcoinSecret vchSecret; - if (!vchSecret.SetString(params[0].get_str())) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Provided private key is inconsistent."); - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.SetSecret(secret, fCompressed); - } - - vector vchDecrypted; - key.DecryptData(ParseHex(params[1].get_str()), vchDecrypted); - - return HexStr(vchDecrypted); -} - -Value encryptmessage(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 2) - throw runtime_error( - "encryptmessage \n" - "Encrypt message with provided public key.\n"); - - CPubKey pubKey(ParseHex(params[0].get_str())); - - vector vchEncrypted; - string strData = params[1].get_str(); - pubKey.EncryptData(vector(strData.begin(), strData.end()), vchEncrypted); - - return EncodeBase58Check(vchEncrypted); -} - -Value decryptmessage(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 2) - throw runtime_error( - "decryptmessage \n" - "Decrypt message string.\n"); - - EnsureWalletIsUnlocked(); - - CKey key; - CBitcoinAddress addr(params[0].get_str()); - if (addr.IsValid()) { - CKeyID keyID; - addr.GetKeyID(keyID); - if (!pwalletMain->GetKey(keyID, key)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "We have no private key for this address"); - } - else { - CBitcoinSecret vchSecret; - if (!vchSecret.SetString(params[0].get_str())) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Provided private key is inconsistent."); - bool fCompressed; - CSecret secret = vchSecret.GetSecret(fCompressed); - key.SetSecret(secret, fCompressed); - } - - vector vchEncrypted; - if (!DecodeBase58Check(params[1].get_str(), vchEncrypted)) - throw runtime_error("Incorrect string"); - vector vchDecrypted; - key.DecryptData(vchEncrypted, vchDecrypted); - - return std::string((const char*)&vchDecrypted[0], vchDecrypted.size()); -} diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 756863c..01ebf94 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -228,35 +228,6 @@ Value dumpprivkey(const Array& params, bool fHelp) return CBitcoinSecret(vchSecret, fCompressed).ToString(); } -Value dumppem(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 3) - throw runtime_error( - "dumppem \n" - "Dump the key pair corresponding to and store it as encrypted PEM file." - + HelpRequiringPassphrase()); - - EnsureWalletIsUnlocked(); - - string strAddress = params[0].get_str(); - SecureString strPassKey; - strPassKey.reserve(100); - strPassKey = params[2].get_str().c_str(); - - CBitcoinAddress address; - if (!address.SetString(strAddress)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid NovaCoin address"); - if (fWalletUnlockMintOnly) - throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Wallet is unlocked for minting only."); - CKeyID keyID; - if (!address.GetKeyID(keyID)) - throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key"); - if (!pwalletMain->GetPEM(keyID, params[1].get_str(), strPassKey)) - throw JSONRPCError(RPC_WALLET_ERROR, "Error dumping key pair to file"); - - return Value::null; -} - Value dumpwallet(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) diff --git a/src/wallet.cpp b/src/wallet.cpp index c02b6bb..f94240b 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -526,19 +526,6 @@ bool CWallet::DecryptWallet(const SecureString& strWalletPassphrase) return true; } -bool CWallet::GetPEM(const CKeyID &keyID, const std::string &fileName, const SecureString &strPassKey) const -{ - BIO *pemOut = BIO_new_file(fileName.c_str(), "w"); - if (pemOut == NULL) - return error("GetPEM() : failed to create file %s\n", fileName.c_str()); - CKey key; - if (!GetKey(keyID, key)) - return error("GetPEM() : failed to get key for address=%s\n", CBitcoinAddress(keyID).ToString().c_str()); - bool result = key.WritePEM(pemOut, strPassKey); - BIO_free(pemOut); - return result; -} - int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) { int64_t nRet = nOrderPosNext++; diff --git a/src/wallet.h b/src/wallet.h index 26cf745..4925025 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -198,7 +198,6 @@ public: bool DecryptWallet(const SecureString& strWalletPassphrase); void GetAddresses(std::map &mapAddresses) const; - bool GetPEM(const CKeyID &keyID, const std::string &fileName, const SecureString &strPassPhrase) const; /** Increment the next transaction order id -- 1.7.1