From 5fb4db63739915399ed9f0d4499b79a1cc9e0139 Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 6 Jan 2016 08:40:59 -0600 Subject: [PATCH] Use OpenSSL versions OpenSSL-0.9.7 to 1.1.0a for OpenSC OpenSSL-1.1.0 was released 8/25/2016 OpenSSL-1.1.0a was released 9/22/2016 https://www.openssl.org/news/openssl-1.1.0-notes.html Changes to allow the OpenSC code base to work with OpenSSL versions from 0.9.7 to 1.1.0 with few changes. This is an update and rebased version of my prep-openssl-1.1.0-pre6 branch. No attempt was made to back port any OpenSSL features. These changes just allow an updated OpenSC code base to use what is in the various OpenSSL releases. A new header libopensc/sc-ossl-compat.h contains extra defines to reduce the need for so many #if OPENSSL_VERSION_NUMBER statements in the source code. The OpenSC source can now use the OpenSSL 1.1 API. The libopensc/sc-ossl-compat.h has defines for the new API for use with older versions of OpenSSL. sc-ossl-compat.h is included by libopensc/internal.h so all OpenSC library routines can take advantage of it. For the tools, which do not use libopensc/internal.h, libopensc/sc-ossl-compat.h is included by the tools. The OpenSC source has been modified to use OpenSSL functions to access hidden structures, such X509, BIGNUM, EVP_CIPHER_CTX, and use XXX_new functions to allocate structures which must use pointer such as BIGNUM and EVP_CIPHER_CTX. For backward compatability sc-ossl-compat.h now defines inline routines to emulate the RSA and DSA access routines in OpenSSL-1.1.0. Thus the same OpenSC source code can be used with openSSL versions from 0.9.7 to 1.1.0. Inline routines were chosen, because using macros does not work on all platforms. Having OpenSC versions of these routines in libopensc would be a posibility, but they are only used for older version of OpenSSL, and could be removed in the future. Changes to be committed: modified: src/libopensc/card-entersafe.c modified: src/libopensc/card-epass2003.c modified: src/libopensc/card-gids.c modified: src/libopensc/card-gpk.c modified: src/libopensc/card-oberthur.c modified: src/libopensc/card-piv.c modified: src/libopensc/card-westcos.c modified: src/libopensc/cwa-dnie.c modified: src/libopensc/cwa14890.c modified: src/libopensc/internal.h modified: src/libopensc/p15card-helper.c modified: src/libopensc/pkcs15-itacns.c modified: src/libopensc/pkcs15-prkey.c modified: src/libopensc/pkcs15-pubkey.c new file: src/libopensc/sc-ossl-compat.h modified: src/pkcs11/openssl.c modified: src/pkcs15init/pkcs15-lib.c modified: src/pkcs15init/pkcs15-oberthur-awp.c modified: src/pkcs15init/pkcs15-oberthur.c modified: src/pkcs15init/pkcs15-oberthur.h modified: src/pkcs15init/pkcs15-westcos.c modified: src/tools/cryptoflex-tool.c modified: src/tools/gids-tool.c modified: src/tools/netkey-tool.c modified: src/tools/piv-tool.c modified: src/tools/pkcs11-tool.c modified: src/tools/pkcs15-init.c modified: src/tools/sc-hsm-tool.c modified: src/tools/westcos-tool.c --- src/libopensc/card-entersafe.c | 46 ++--- src/libopensc/card-epass2003.c | 72 ++++---- src/libopensc/card-gids.c | 27 +-- src/libopensc/card-gpk.c | 67 +++++--- src/libopensc/card-oberthur.c | 16 +- src/libopensc/card-piv.c | 50 +++--- src/libopensc/card-westcos.c | 3 +- src/libopensc/cwa-dnie.c | 44 +++-- src/libopensc/cwa14890.c | 18 +- src/libopensc/internal.h | 4 + src/libopensc/p15card-helper.c | 8 +- src/libopensc/pkcs15-itacns.c | 21 ++- src/libopensc/pkcs15-prkey.c | 58 ++++--- src/libopensc/pkcs15-pubkey.c | 31 ++-- src/libopensc/sc-ossl-compat.h | 240 +++++++++++++++++++++++++++ src/pkcs11/openssl.c | 12 +- src/pkcs15init/pkcs15-lib.c | 52 +++--- src/pkcs15init/pkcs15-oberthur-awp.c | 28 +++- src/pkcs15init/pkcs15-oberthur.c | 7 +- src/pkcs15init/pkcs15-oberthur.h | 5 + src/pkcs15init/pkcs15-westcos.c | 4 +- src/tools/cryptoflex-tool.c | 61 ++++--- src/tools/gids-tool.c | 5 +- src/tools/netkey-tool.c | 4 +- src/tools/piv-tool.c | 16 +- src/tools/pkcs11-tool.c | 186 ++++++++++++++------- src/tools/pkcs15-init.c | 60 +++++-- src/tools/sc-hsm-tool.c | 194 +++++++++++----------- src/tools/westcos-tool.c | 18 +- 29 files changed, 955 insertions(+), 402 deletions(-) create mode 100644 src/libopensc/sc-ossl-compat.h diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 7311e5de..a8cdf6b2 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -194,7 +194,7 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *key, size_t keylen, u8 *buff, size_t buffsize) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; u8 iv[8]={0}; int len; @@ -211,27 +211,26 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, memcpy(buff+1,apdu->data,apdu->lc); buff[apdu->lc+1]=0x80; - EVP_CIPHER_CTX_init(&ctx); - EVP_CIPHER_CTX_set_padding(&ctx,0); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY); + EVP_CIPHER_CTX_set_padding(ctx,0); if(keylen == 8) - EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, key, iv); + EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, key, iv); else if (keylen == 16) - EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, key, iv); + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, iv); else SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); len = apdu->lc; - if(!EVP_EncryptUpdate(&ctx, buff, &len, buff, buffsize)){ + if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error."); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } apdu->lc = len; - if (!EVP_CIPHER_CTX_cleanup(&ctx)){ - sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "entersafe encryption error."); - SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); - } + EVP_CIPHER_CTX_free(ctx); if(apdu->lc!=buffsize) { @@ -254,7 +253,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *tmp=0,*tmp_rounded=NULL; size_t tmpsize=0,tmpsize_rounded=0; int outl=0; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); @@ -292,12 +291,16 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, tmp_rounded[tmpsize]=0x80; /* block_size-1 blocks*/ - EVP_CIPHER_CTX_init(&ctx); - EVP_CIPHER_CTX_set_padding(&ctx,0); - EVP_EncryptInit_ex(&ctx, EVP_des_cbc(), NULL, key, iv); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + EVP_CIPHER_CTX_set_padding(ctx,0); + EVP_EncryptInit_ex(ctx, EVP_des_cbc(), NULL, key, iv); if(tmpsize_rounded>8){ - if(!EVP_EncryptUpdate(&ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){ + if(!EVP_EncryptUpdate(ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){ r = SC_ERROR_INTERNAL; goto out; } @@ -305,25 +308,20 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, /* last block */ if(keylen==8) { - if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ + if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ r = SC_ERROR_INTERNAL; goto out; } } else { - EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8); - if(!EVP_EncryptUpdate(&ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ + EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key,tmp_rounded+outl-8); + if(!EVP_EncryptUpdate(ctx,tmp_rounded+outl,&outl,tmp_rounded+outl,8)){ r = SC_ERROR_INTERNAL; goto out; } } - if (!EVP_CIPHER_CTX_cleanup(&ctx)){ - r = SC_ERROR_INTERNAL; - goto out; - } - memcpy(buff,apdu->data,apdu->lc); /* use first 4 bytes of last block as mac value*/ memcpy(buff+apdu->lc,tmp_rounded+tmpsize_rounded-8,4); @@ -336,6 +334,8 @@ out: free(tmp); if(tmp_rounded) free(tmp_rounded); + if (ctx) + EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); } diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c index 1727f256..c7bca949 100644 --- a/src/libopensc/card-epass2003.c +++ b/src/libopensc/card-epass2003.c @@ -127,27 +127,28 @@ openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned const unsigned char *input, size_t length, unsigned char *output) { int r = SC_ERROR_INTERNAL; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; int outl = 0; int outl_tmp = 0; unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 }; memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH); - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv_tmp); - EVP_CIPHER_CTX_set_padding(&ctx, 0); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + goto out; + EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp); + EVP_CIPHER_CTX_set_padding(ctx, 0); - if (!EVP_EncryptUpdate(&ctx, output, &outl, input, length)) + if (!EVP_EncryptUpdate(ctx, output, &outl, input, length)) goto out; - if (!EVP_EncryptFinal_ex(&ctx, output + outl, &outl_tmp)) - goto out; - - if (!EVP_CIPHER_CTX_cleanup(&ctx)) + if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp)) goto out; r = SC_SUCCESS; out: + if (ctx) + EVP_CIPHER_CTX_free(ctx); return r; } @@ -156,27 +157,28 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned const unsigned char *input, size_t length, unsigned char *output) { int r = SC_ERROR_INTERNAL; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; int outl = 0; int outl_tmp = 0; unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = { 0 }; memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH); - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, cipher, NULL, key, iv_tmp); - EVP_CIPHER_CTX_set_padding(&ctx, 0); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + goto out; + EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp); + EVP_CIPHER_CTX_set_padding(ctx, 0); - if (!EVP_DecryptUpdate(&ctx, output, &outl, input, length)) + if (!EVP_DecryptUpdate(ctx, output, &outl, input, length)) goto out; - if (!EVP_DecryptFinal_ex(&ctx, output + outl, &outl_tmp)) - goto out; - - if (!EVP_CIPHER_CTX_cleanup(&ctx)) + if (!EVP_DecryptFinal_ex(ctx, output + outl, &outl_tmp)) goto out; r = SC_SUCCESS; out: + if (ctx) + EVP_CIPHER_CTX_free(ctx); return r; } @@ -280,21 +282,33 @@ static int openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length, unsigned char *output) { - EVP_MD_CTX ctx; + int r = 0; + EVP_MD_CTX *ctx = NULL; unsigned outl = 0; - EVP_MD_CTX_init(&ctx); - EVP_DigestInit_ex(&ctx, digest, NULL); - if (!EVP_DigestUpdate(&ctx, input, length)) - return SC_ERROR_INTERNAL; + ctx = EVP_MD_CTX_create(); + if (ctx == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + + EVP_MD_CTX_init(ctx); + EVP_DigestInit_ex(ctx, digest, NULL); + if (!EVP_DigestUpdate(ctx, input, length)) { + r = SC_ERROR_INTERNAL; + goto err; + } - if (!EVP_DigestFinal_ex(&ctx, output, &outl)) - return SC_ERROR_INTERNAL; + if (!EVP_DigestFinal_ex(ctx, output, &outl)) { + r = SC_ERROR_INTERNAL; + goto err; + } + r = SC_SUCCESS; +err: + if (ctx) + EVP_MD_CTX_destroy(ctx); - if (!EVP_MD_CTX_cleanup(&ctx)) - return SC_ERROR_INTERNAL; - - return SC_SUCCESS; + return r; } diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c index d7e85692..51db9afb 100644 --- a/src/libopensc/card-gids.c +++ b/src/libopensc/card-gids.c @@ -1860,7 +1860,7 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { #ifndef ENABLE_OPENSSL SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED); #else - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = NULL; int r; u8 apduSetRandom[20] = {0x7C,0x12,0x81,0x10,0}; u8* randomR1 = apduSetRandom + 4; @@ -1878,8 +1878,6 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { const EVP_CIPHER *cipher; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - // init crypto - EVP_CIPHER_CTX_init(&ctx); // this is CBC instead of ECB cipher = EVP_des_ede3_cbc(); if (!cipher) { @@ -1920,21 +1918,28 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { memcpy(buffer, randomR2, 16); memcpy(buffer+16, randomR1, 16); memcpy(buffer+32, z1, sizeof(z1)); - if (!EVP_EncryptInit(&ctx, cipher, key, NULL)) { - EVP_CIPHER_CTX_cleanup(&ctx); + // init crypto + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); + } + + if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { + EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } - EVP_CIPHER_CTX_set_padding(&ctx,0); - if (!EVP_EncryptUpdate(&ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) { - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_set_padding(ctx,0); + if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) { + EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } - if(!EVP_EncryptFinal(&ctx, buffer2+buffer2size, &buffer2size)) { - EVP_CIPHER_CTX_cleanup(&ctx); + if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) { + EVP_CIPHER_CTX_free(ctx); SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL); } - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; // send it to the card sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00); apdu.lc = sizeof(apduSendReponse); diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 3480f023..1e6dcea2 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -731,7 +731,12 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, u8 in[8], out[8], block[64]; unsigned int len = 0, i; int r = SC_SUCCESS, outl; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = NULL; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return SC_ERROR_INTERNAL; + /* Fill block with 0x00 and then with the data. */ memset(block, 0x00, sizeof(block)); @@ -748,16 +753,14 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, /* Set IV */ memset(in, 0x00, 8); - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_des_ede_cbc(), NULL, priv->key, in); + EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, priv->key, in); for (i = 0; i < len; i += 8) { - if (!EVP_EncryptUpdate(&ctx, out, &outl, &block[i], 8)) { + if (!EVP_EncryptUpdate(ctx, out, &outl, &block[i], 8)) { r = SC_ERROR_INTERNAL; break; } } - if (!EVP_CIPHER_CTX_cleanup(&ctx)) - r = SC_ERROR_INTERNAL; + EVP_CIPHER_CTX_free(ctx); memcpy((u8 *) (apdu->data + apdu->datalen), out + 5, 3); apdu->datalen += 3; @@ -883,25 +886,29 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, const u8 *r_rn, u8 *kats) { int r = SC_SUCCESS, outl; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; u8 out[16]; memcpy(out, key+8, 8); memcpy(out+8, key, 8); - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, key, NULL); - if (!EVP_EncryptUpdate(&ctx, kats, &outl, r_rn+4, 8)) + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return SC_ERROR_INTERNAL; + + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, NULL); + if (!EVP_EncryptUpdate(ctx, kats, &outl, r_rn+4, 8)) r = SC_ERROR_INTERNAL; - if (!EVP_CIPHER_CTX_cleanup(&ctx)) + + if (!EVP_CIPHER_CTX_cleanup(ctx)) r = SC_ERROR_INTERNAL; if (r == SC_SUCCESS) { - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, out, NULL); - if (!EVP_EncryptUpdate(&ctx, kats+8, &outl, r_rn+4, 8)) - r = SC_ERROR_INTERNAL; - if (!EVP_CIPHER_CTX_cleanup(&ctx)) + EVP_CIPHER_CTX_init(ctx); + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, out, NULL); + if (!EVP_EncryptUpdate(ctx, kats+8, &outl, r_rn+4, 8)) r = SC_ERROR_INTERNAL; + if (!EVP_CIPHER_CTX_cleanup(ctx)) + r = SC_ERROR_INTERNAL; } memset(out, 0, sizeof(out)); @@ -910,16 +917,17 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, * here? INVALID_ARGS doesn't seem quite right */ if (r == SC_SUCCESS) { - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, kats, NULL); - if (!EVP_EncryptUpdate(&ctx, out, &outl, challenge, 8)) - r = SC_ERROR_INTERNAL; - if (!EVP_CIPHER_CTX_cleanup(&ctx)) + EVP_CIPHER_CTX_init(ctx); + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, kats, NULL); + if (!EVP_EncryptUpdate(ctx, out, &outl, challenge, 8)) r = SC_ERROR_INTERNAL; if (memcmp(r_rn, out+4, 4) != 0) r = SC_ERROR_INVALID_ARGUMENTS; } + if (ctx) + EVP_CIPHER_CTX_free(ctx); + sc_mem_clear(out, sizeof(out)); return r; } @@ -941,7 +949,7 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen) return SC_ERROR_INVALID_ARGUMENTS; /* now do the SelFk */ - RAND_pseudo_bytes(rnd, sizeof(rnd)); + RAND_bytes(rnd, sizeof(rnd)); memset(&apdu, 0, sizeof(apdu)); apdu.cla = 0x80; apdu.cse = SC_APDU_CASE_4_SHORT; @@ -1509,11 +1517,15 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) unsigned int n; u8 temp[256]; int r = SC_SUCCESS, outl; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx; sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "gpk_pkfile_load(fid=%04x, len=%d, datalen=%d)\n", args->file->id, args->len, args->datalen); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + return SC_ERROR_INTERNAL; + if (0) { char buf[2048]; @@ -1539,15 +1551,16 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, priv->key, NULL); + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, priv->key, NULL); for (n = 0; n < args->datalen; n += 8) { - if (!EVP_EncryptUpdate(&ctx, temp+n, &outl, args->data + n, 8)) { + if (!EVP_EncryptUpdate(ctx, temp+n, &outl, args->data + n, 8)) { r = SC_ERROR_INTERNAL; break; } } - if (!EVP_CIPHER_CTX_cleanup(&ctx) || r != SC_SUCCESS) + if (ctx) + EVP_CIPHER_CTX_free(ctx); + if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; apdu.data = temp; diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 52dfb4b1..fa6c9689 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1340,19 +1340,23 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a int outl; const unsigned char in[8] = {0,0,0,0,0,0,0,0}; unsigned char out[8]; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; if (args->len!=8 && args->len!=24) LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL,SC_ERROR_OUT_OF_MEMORY); + p2 = 0; - EVP_CIPHER_CTX_init(&ctx); if (args->len == 24) - EVP_EncryptInit_ex(&ctx, EVP_des_ede(), NULL, args->data, NULL); + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, args->data, NULL); else - EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, args->data, NULL); - rv = EVP_EncryptUpdate(&ctx, out, &outl, in, 8); - if (!EVP_CIPHER_CTX_cleanup(&ctx) || rv == 0) { + EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, args->data, NULL); + rv = EVP_EncryptUpdate(ctx, out, &outl, in, 8); + EVP_CIPHER_CTX_free(ctx); + if (rv == 0) { sc_log(card->ctx, "OpenSSL encryption error."); LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); } diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index e3ad4da5..e883c748 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -1582,14 +1582,19 @@ static int piv_general_mutual_authenticate(sc_card_t *card, size_t challenge_response_len; u8 *decrypted_reponse = NULL; size_t decrypted_reponse_len; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; u8 sbuf[255]; const EVP_CIPHER *cipher; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - EVP_CIPHER_CTX_init(&ctx); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } + cipher = get_cipher_for_algo(alg_id); if(!cipher) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); @@ -1648,22 +1653,22 @@ static int piv_general_mutual_authenticate(sc_card_t *card, } /* decrypt the data from the card */ - if (!EVP_DecryptInit(&ctx, cipher, key, NULL)) { + if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { /* may fail if des parity of key is wrong. depends on OpenSSL options */ r = SC_ERROR_INTERNAL; goto err; } - EVP_CIPHER_CTX_set_padding(&ctx,0); + EVP_CIPHER_CTX_set_padding(ctx,0); p = plain_text; - if (!EVP_DecryptUpdate(&ctx, p, &N, witness_data, witness_len)) { + if (!EVP_DecryptUpdate(ctx, p, &N, witness_data, witness_len)) { r = SC_ERROR_INTERNAL; goto err; } plain_text_len = tmplen = N; p += tmplen; - if(!EVP_DecryptFinal(&ctx, p, &N)) { + if(!EVP_DecryptFinal(ctx, p, &N)) { r = SC_ERROR_INTERNAL; goto err; } @@ -1772,24 +1777,23 @@ static int piv_general_mutual_authenticate(sc_card_t *card, goto err; } - EVP_CIPHER_CTX_cleanup(&ctx); - EVP_CIPHER_CTX_init(&ctx); + EVP_CIPHER_CTX_cleanup(ctx); - if (!EVP_DecryptInit(&ctx, cipher, key, NULL)) { + if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { r = SC_ERROR_INTERNAL; goto err; } - EVP_CIPHER_CTX_set_padding(&ctx,0); + EVP_CIPHER_CTX_set_padding(ctx,0); tmp = decrypted_reponse; - if (!EVP_DecryptUpdate(&ctx, tmp, &N, challenge_response, challenge_response_len)) { + if (!EVP_DecryptUpdate(ctx, tmp, &N, challenge_response, challenge_response_len)) { r = SC_ERROR_INTERNAL; goto err; } decrypted_reponse_len = tmplen = N; tmp += tmplen; - if(!EVP_DecryptFinal(&ctx, tmp, &N)) { + if(!EVP_DecryptFinal(ctx, tmp, &N)) { r = SC_ERROR_INTERNAL; goto err; } @@ -1805,7 +1809,8 @@ static int piv_general_mutual_authenticate(sc_card_t *card, r = SC_SUCCESS; err: - EVP_CIPHER_CTX_cleanup(&ctx); + if (ctx) + EVP_CIPHER_CTX_free(ctx); if (locked) sc_unlock(card); if (rbuf) @@ -1853,12 +1858,16 @@ static int piv_general_external_authenticate(sc_card_t *card, size_t keylen = 0; size_t cypher_text_len = 0; u8 sbuf[255]; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX * ctx = NULL; const EVP_CIPHER *cipher; SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); - EVP_CIPHER_CTX_init(&ctx); + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto err; + } sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id); @@ -1924,7 +1933,7 @@ static int piv_general_external_authenticate(sc_card_t *card, tmplen = challenge_len; /* Encrypt the challenge with the secret */ - if (!EVP_EncryptInit(&ctx, cipher, key, NULL)) { + if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt fail\n"); r = SC_ERROR_INTERNAL; goto err; @@ -1937,15 +1946,15 @@ static int piv_general_external_authenticate(sc_card_t *card, goto err; } - EVP_CIPHER_CTX_set_padding(&ctx,0); - if (!EVP_EncryptUpdate(&ctx, cypher_text, &outlen, challenge_data, challenge_len)) { + EVP_CIPHER_CTX_set_padding(ctx,0); + if (!EVP_EncryptUpdate(ctx, cypher_text, &outlen, challenge_data, challenge_len)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt update fail\n"); r = SC_ERROR_INTERNAL; goto err; } cypher_text_len += outlen; - if (!EVP_EncryptFinal(&ctx, cypher_text + cypher_text_len, &outlen)) { + if (!EVP_EncryptFinal(ctx, cypher_text + cypher_text_len, &outlen)) { sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Final fail\n"); r = SC_ERROR_INTERNAL; goto err; @@ -2005,7 +2014,8 @@ static int piv_general_external_authenticate(sc_card_t *card, sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Got response challenge\n"); err: - EVP_CIPHER_CTX_cleanup(&ctx); + if (ctx) + EVP_CIPHER_CTX_free(ctx); if (locked) sc_unlock(card); diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 5c2e2cf0..9062fafd 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -1182,7 +1182,8 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, } /* pkcs11 reset openssl functions */ - rsa->meth = RSA_PKCS1_SSLeay(); + RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); + if ((size_t)RSA_size(rsa) > outlen) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Buffer too small\n"); r = SC_ERROR_OUT_OF_MEMORY; diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c index 311d499a..6023fe11 100644 --- a/src/libopensc/cwa-dnie.c +++ b/src/libopensc/cwa-dnie.c @@ -39,8 +39,11 @@ #include "cwa-dnie.h" +#include +#include #include #include +#include #define MAX_RESP_BUFFER_SIZE 2048 @@ -344,6 +347,7 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) { int res=SC_SUCCESS; RSA *root_ca_rsa=NULL; + BIGNUM *root_ca_rsa_n, *root_ca_rsa_e; LOG_FUNC_CALLED(card->ctx); /* compose root_ca_public key with data provided by Dnie Manual */ @@ -353,11 +357,20 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) sc_log(card->ctx, "Cannot create data for root CA public key"); return SC_ERROR_OUT_OF_MEMORY; } - root_ca_rsa->n = BN_bin2bn(icc_root_ca_modulus, - sizeof(icc_root_ca_modulus), root_ca_rsa->n); - root_ca_rsa->e = BN_bin2bn(icc_root_ca_public_exponent, - sizeof(icc_root_ca_public_exponent), - root_ca_rsa->e); + + root_ca_rsa_n = BN_bin2bn(icc_root_ca_modulus, sizeof(icc_root_ca_modulus), NULL); + root_ca_rsa_e = BN_bin2bn(icc_root_ca_public_exponent, sizeof(icc_root_ca_public_exponent), NULL); + if (RSA_set0_key(root_ca_rsa, root_ca_rsa_n, root_ca_rsa_e, NULL) != 1) { + BN_free(root_ca_rsa_n); + BN_free(root_ca_rsa_e); + if (*root_ca_key) + EVP_PKEY_free(*root_ca_key); + if (root_ca_rsa) + RSA_free(root_ca_rsa); + sc_log(card->ctx, "Cannot set RSA valuses for CA public key"); + return SC_ERROR_INTERNAL; + } + res = EVP_PKEY_assign_RSA(*root_ca_key, root_ca_rsa); if (!res) { if (*root_ca_key) @@ -428,6 +441,7 @@ static int dnie_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert, size_t * length) static int dnie_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey) { RSA *ifd_rsa=NULL; + BIGNUM *ifd_rsa_n, *ifd_rsa_e, *ifd_rsa_d = NULL; int res=SC_SUCCESS; LOG_FUNC_CALLED(card->ctx); @@ -439,13 +453,19 @@ static int dnie_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey) sc_log(card->ctx, "Cannot create data for IFD private key"); return SC_ERROR_OUT_OF_MEMORY; } - ifd_rsa->n = BN_bin2bn(ifd_modulus, sizeof(ifd_modulus), ifd_rsa->n); - ifd_rsa->e = - BN_bin2bn(ifd_public_exponent, sizeof(ifd_public_exponent), - ifd_rsa->e); - ifd_rsa->d = - BN_bin2bn(ifd_private_exponent, sizeof(ifd_private_exponent), - ifd_rsa->d); + ifd_rsa_n = BN_bin2bn(ifd_modulus, sizeof(ifd_modulus), NULL); + ifd_rsa_e = BN_bin2bn(ifd_public_exponent, sizeof(ifd_public_exponent), NULL); + ifd_rsa_d = BN_bin2bn(ifd_private_exponent, sizeof(ifd_private_exponent), NULL); + if (RSA_set0_key(ifd_rsa, ifd_rsa_n, ifd_rsa_e, ifd_rsa_d) != 1) { + BN_free(ifd_rsa_n); + BN_free(ifd_rsa_e); + BN_free(ifd_rsa_d); + RSA_free(ifd_rsa); + EVP_PKEY_free(*ifd_privkey); + sc_log(card->ctx, "Cannot set RSA values for IFD private key"); + return SC_ERROR_INTERNAL; + } + res = EVP_PKEY_assign_RSA(*ifd_privkey, ifd_rsa); if (!res) { if (*ifd_privkey) diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c index 46594ddc..62a847cd 100644 --- a/src/libopensc/cwa14890.c +++ b/src/libopensc/cwa14890.c @@ -36,6 +36,8 @@ #include "opensc.h" #include "cardctl.h" #include "internal.h" +#include +#include #include #include #include @@ -588,6 +590,7 @@ static int cwa_prepare_external_auth(sc_card_t * card, BIGNUM *bnsub = NULL; BIGNUM *bnres = NULL; sc_context_t *ctx = NULL; + const BIGNUM *ifd_privkey_n, *ifd_privkey_e, *ifd_privkey_d; /* safety check */ if (!card || !card->ctx) @@ -641,7 +644,8 @@ static int cwa_prepare_external_auth(sc_card_t * card, res = SC_ERROR_INTERNAL; goto prepare_external_auth_end; } - res = BN_sub(bnsub, ifd_privkey->n, bn); /* eval N.IFD-SIG */ + RSA_get0_key(ifd_privkey, &ifd_privkey_n, &ifd_privkey_e, &ifd_privkey_d); + res = BN_sub(bnsub, ifd_privkey_n, bn); /* eval N.IFD-SIG */ if (res == 0) { /* 1:success 0 fail */ msg = "Prepare external auth: BN sigmin evaluation failed"; res = SC_ERROR_INTERNAL; @@ -889,6 +893,7 @@ static int cwa_verify_internal_auth(sc_card_t * card, BIGNUM *bn = NULL; BIGNUM *sigbn = NULL; sc_context_t *ctx = NULL; + const BIGNUM *icc_pubkey_n, *icc_pubkey_e, *icc_pubkey_d; if (!card || !card->ctx) return SC_ERROR_INVALID_ARGUMENTS; @@ -959,7 +964,8 @@ static int cwa_verify_internal_auth(sc_card_t * card, res = SC_ERROR_OUT_OF_MEMORY; goto verify_internal_done; } - res = BN_sub(sigbn, icc_pubkey->n, bn); /* eval N.ICC-SIG */ + RSA_get0_key(icc_pubkey, &icc_pubkey_n, &icc_pubkey_e, &icc_pubkey_d); + res = BN_sub(sigbn, icc_pubkey_n, bn); /* eval N.ICC-SIG */ if (!res) { msg = "Verify Signature: evaluation of N.ICC-SIG failed"; res = SC_ERROR_INTERNAL; @@ -1319,8 +1325,8 @@ int cwa_create_secure_channel(sc_card_t * card, /* verify received signature */ sc_log(ctx, "Verify Internal Auth command response"); - res = cwa_verify_internal_auth(card, icc_pubkey->pkey.rsa, /* evaluated icc public key */ - ifd_privkey->pkey.rsa, /* evaluated from DGP's Manual Annex 3 Data */ + res = cwa_verify_internal_auth(card, EVP_PKEY_get0_RSA(icc_pubkey), /* evaluated icc public key */ + EVP_PKEY_get0_RSA(ifd_privkey), /* evaluated from DGP's Manual Annex 3 Data */ rndbuf, /* RND.IFD || SN.IFD */ 16, /* rndbuf length; should be 16 */ sm /* sm data */ @@ -1340,8 +1346,8 @@ int cwa_create_secure_channel(sc_card_t * card, /* compose signature data for external auth */ res = cwa_prepare_external_auth(card, - icc_pubkey->pkey.rsa, - ifd_privkey->pkey.rsa, sn_icc, sm); + EVP_PKEY_get0_RSA(icc_pubkey), + EVP_PKEY_get0_RSA(ifd_privkey), sn_icc, sm); if (res != SC_SUCCESS) { msg = "Prepare external auth failed"; goto csc_end; diff --git a/src/libopensc/internal.h b/src/libopensc/internal.h index 0ccc13a2..98a42374 100644 --- a/src/libopensc/internal.h +++ b/src/libopensc/internal.h @@ -40,6 +40,10 @@ extern "C" { #include "libopensc/log.h" #include "libopensc/cards.h" +#ifdef ENABLE_OPENSSL +#include "libopensc/sc-ossl-compat.h" +#endif + #define SC_FILE_MAGIC 0x14426950 #ifndef _WIN32 diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c index 1a16da7d..94f9fe28 100644 --- a/src/libopensc/p15card-helper.c +++ b/src/libopensc/p15card-helper.c @@ -25,6 +25,7 @@ #ifdef ENABLE_OPENSSL /* empty file without openssl */ #include #include +#include #include #include #include @@ -142,6 +143,7 @@ CERT_HANDLE_FUNCTION(default_cert_handle) { int r; X509 *cert_data = NULL; EVP_PKEY *pkey = NULL; + RSA * rsa = NULL; int certtype = 0; int modulus_len = 0; const prdata* key = get_prkey_by_cert(items, cert); @@ -169,13 +171,15 @@ CERT_HANDLE_FUNCTION(default_cert_handle) { r = SC_ERROR_INTERNAL; goto err; } - if(pkey->pkey.rsa->n == NULL) { + rsa = EVP_PKEY_get0_RSA(pkey); + if( rsa == NULL) { sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Error: no modulus associated with the certificate"); r = SC_ERROR_INTERNAL; goto err; } - modulus_len = 8 * BN_num_bytes(pkey->pkey.rsa->n); /* converting to bits */ + modulus_len = RSA_bits(rsa); + /* printf("Key Size: %d bits\n\n", modulus_len); */ /* cached_cert->modulusLength = modulus_len; */ diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c index 50b92173..53aa2b0a 100644 --- a/src/libopensc/pkcs15-itacns.c +++ b/src/libopensc/pkcs15-itacns.c @@ -30,17 +30,25 @@ #include #endif +#include +#include +#include + +#ifdef ENABLE_OPENSSL +#include +#include +#endif + +#include "internal.h" #include "pkcs15.h" #include "log.h" #include "cards.h" #include "itacns.h" -#include -#include -#include #include "common/compat_strlcpy.h" #include "common/compat_strlcat.h" #ifdef ENABLE_OPENSSL +#include #include #endif @@ -241,10 +249,11 @@ static int itacns_add_cert(sc_pkcs15_card_t *p15card, sc_pkcs15_free_certificate(cert); if (!x509) return SC_SUCCESS; X509_check_purpose(x509, -1, 0); - if(x509->ex_flags & EXFLAG_KUSAGE) { + + if(X509_get_extension_flags(x509) & EXFLAG_KUSAGE) { *ext_info_ok = 1; - *key_usage = x509->ex_kusage; - *x_key_usage = x509->ex_xkusage; + *key_usage = X509_get_key_usage(x509); + *x_key_usage = X509_get_extended_key_usage(x509); } OPENSSL_free(x509); diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index f199aeae..f557bc16 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -27,16 +27,15 @@ #include #include -#include "internal.h" -#include "asn1.h" -#include "pkcs15.h" -#include "common/compat_strlcpy.h" -#include "aux-data.h" - #ifdef ENABLE_OPENSSL +#include +#include #include #include #include +#include +#include +#include #if OPENSSL_VERSION_NUMBER >= 0x10000000L #ifndef OPENSSL_NO_EC #include @@ -44,6 +43,12 @@ #endif #endif +#include "internal.h" +#include "asn1.h" +#include "pkcs15.h" +#include "common/compat_strlcpy.h" +#include "aux-data.h" + /* * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS defined as 8 */ @@ -625,23 +630,30 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) { #ifdef ENABLE_OPENSSL EVP_PKEY *pk = (EVP_PKEY *)evp_key; + int pk_type; + pk_type = EVP_PKEY_base_id(pk); - switch (pk->type) { + switch (pk_type) { case EVP_PKEY_RSA: { struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa; RSA *src = EVP_PKEY_get1_RSA(pk); + const BIGNUM *src_n, *src_e, *src_d, *src_p, *src_q, *src_iqmp, *src_dmp1, *src_dmq1; + + RSA_get0_key(src, &src_n, &src_e, &src_d); + RSA_get0_factors(src, &src_p, &src_q); + RSA_get0_crt_params(src, &src_dmp1, &src_dmq1, &src_iqmp); pkcs15_key->algorithm = SC_ALGORITHM_RSA; - if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n) - || !sc_pkcs15_convert_bignum(&dst->exponent, src->e) - || !sc_pkcs15_convert_bignum(&dst->d, src->d) - || !sc_pkcs15_convert_bignum(&dst->p, src->p) - || !sc_pkcs15_convert_bignum(&dst->q, src->q)) + if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) + || !sc_pkcs15_convert_bignum(&dst->exponent, src_e) + || !sc_pkcs15_convert_bignum(&dst->d, src_d) + || !sc_pkcs15_convert_bignum(&dst->p, src_p) + || !sc_pkcs15_convert_bignum(&dst->q, src_q)) return SC_ERROR_NOT_SUPPORTED; - if (src->iqmp && src->dmp1 && src->dmq1) { - sc_pkcs15_convert_bignum(&dst->iqmp, src->iqmp); - sc_pkcs15_convert_bignum(&dst->dmp1, src->dmp1); - sc_pkcs15_convert_bignum(&dst->dmq1, src->dmq1); + if (src_iqmp && src_dmp1 && src_dmq1) { + sc_pkcs15_convert_bignum(&dst->iqmp, src_iqmp); + sc_pkcs15_convert_bignum(&dst->dmp1, src_dmp1); + sc_pkcs15_convert_bignum(&dst->dmq1, src_dmq1); } RSA_free(src); break; @@ -649,13 +661,17 @@ sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key) case EVP_PKEY_DSA: { struct sc_pkcs15_prkey_dsa *dst = &pkcs15_key->u.dsa; DSA *src = EVP_PKEY_get1_DSA(pk); + const BIGNUM *src_pub_key, *src_p, *src_q, *src_g, *src_priv_key; + + DSA_get0_key(src, &src_pub_key, &src_priv_key); + DSA_get0_pqg(src, &src_p, &src_q, &src_g); pkcs15_key->algorithm = SC_ALGORITHM_DSA; - sc_pkcs15_convert_bignum(&dst->pub, src->pub_key); - sc_pkcs15_convert_bignum(&dst->p, src->p); - sc_pkcs15_convert_bignum(&dst->q, src->q); - sc_pkcs15_convert_bignum(&dst->g, src->g); - sc_pkcs15_convert_bignum(&dst->priv, src->priv_key); + sc_pkcs15_convert_bignum(&dst->pub, src_pub_key); + sc_pkcs15_convert_bignum(&dst->p, src_p); + sc_pkcs15_convert_bignum(&dst->q, src_q); + sc_pkcs15_convert_bignum(&dst->g, src_g); + sc_pkcs15_convert_bignum(&dst->priv, src_priv_key); DSA_free(src); break; } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 92cc7625..d121776b 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -34,11 +34,8 @@ #include #endif -#include "internal.h" -#include "asn1.h" -#include "pkcs15.h" - #ifdef ENABLE_OPENSSL +#include #include #include #include @@ -50,6 +47,11 @@ #endif #endif +#include "internal.h" +#include "asn1.h" +#include "pkcs15.h" + + #define C_ASN1_PKINFO_ATTR_SIZE 3 static const struct sc_asn1_entry c_asn1_pkinfo[C_ASN1_PKINFO_ATTR_SIZE] = { { "algorithm", SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, @@ -1544,14 +1546,19 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) { #ifdef ENABLE_OPENSSL EVP_PKEY *pk = (EVP_PKEY *)evp_key; + int pk_type; + pk_type = EVP_PKEY_base_id(pk); - switch (pk->type) { + switch (pk_type) { case EVP_PKEY_RSA: { struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa; RSA *src = EVP_PKEY_get1_RSA(pk); + const BIGNUM *src_n, *src_e; + + RSA_get0_key(src, &src_n, &src_e, NULL); pkcs15_key->algorithm = SC_ALGORITHM_RSA; - if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n) || !sc_pkcs15_convert_bignum(&dst->exponent, src->e)) + if (!sc_pkcs15_convert_bignum(&dst->modulus, src_n) || !sc_pkcs15_convert_bignum(&dst->exponent, src_e)) return SC_ERROR_INVALID_DATA; RSA_free(src); break; @@ -1559,12 +1566,16 @@ sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key) case EVP_PKEY_DSA: { struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa; DSA *src = EVP_PKEY_get1_DSA(pk); + const BIGNUM *src_pub_key, *src_priv_key, *src_p, *src_q, *src_g; + + DSA_get0_key(src, &src_pub_key, &src_priv_key); + DSA_get0_pqg(src, &src_p, &src_q, &src_g); pkcs15_key->algorithm = SC_ALGORITHM_DSA; - sc_pkcs15_convert_bignum(&dst->pub, src->pub_key); - sc_pkcs15_convert_bignum(&dst->p, src->p); - sc_pkcs15_convert_bignum(&dst->q, src->q); - sc_pkcs15_convert_bignum(&dst->g, src->g); + sc_pkcs15_convert_bignum(&dst->pub, src_pub_key); + sc_pkcs15_convert_bignum(&dst->p, src_p); + sc_pkcs15_convert_bignum(&dst->q, src_q); + sc_pkcs15_convert_bignum(&dst->g, src_g); DSA_free(src); break; } diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h new file mode 100644 index 00000000..42f0ca6b --- /dev/null +++ b/src/libopensc/sc-ossl-compat.h @@ -0,0 +1,240 @@ +/* + * sc-ossl-compat.h: OpenSC ecompatability for older OpenSSL versions + * + * Copyright (C) 2016 Douglas E. Engert + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _SC_OSSL_COMPAT_H +#define _SC_OSSL_COMPAT_H + +#ifdef ENABLE_OPENSSL + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +/* + * Provide backward compatability to older versions of OpenSSL + * while using most of OpenSSL 1.1 API + */ + +/* + * EVP_CIPHER_CTX functions: + * EVP_CIPHER_CTX_new not in 0.9.7 + * EVP_CIPHER_CTX_free not in 0.9.7 + * EVP_CIPHER_CTX_init in 0.9.7 to 1.0.2. defined in 1.1 as EVP_CIPHER_CTX_reset + * EVP_CIPHER_CTX_cleanup in 0.9.7 to 1.0.2, defined in 1.1 as EVP_CIPHER_CTX_reset + * EVP_CIPHER_CTX_reset only in 1.1 + * + * EVP_CIPHER_CTX_new does a EVP_CIPHER_CTX_init + * EVP_CIPHER_CTX_free does a EVP_CIPHER_CTX_cleanup + * EVP_CIPHER_CTX_cleanup does equivelent of a EVP_CIPHER_CTX_init + * Use EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_free, and EVP_CIPHER_CTX_cleanup between operations + */ + +#if OPENSSL_VERSION_NUMBER <= 0x009070dfL + +/* in 0.9.7 EVP_CIPHER_CTX was always allocated inline or in other structures */ + +#define EVP_CIPHER_CTX_new() ({ \ + EVP_CIPHER_CTX * tmp = NULL; \ + tmp = OPENSSL_malloc(sizeof(struct evp_cipher_ctx_st)); \ + if (tmp) { \ + EVP_CIPHER_CTX_init(tmp); \ + } \ + tmp; \ + }) + +#define EVP_CIPHER_CTX_free(x) ({ \ + if (x) { \ + EVP_CIPHER_CTX_cleanup(x); \ + OPENSSL_free(x); \ + } \ + }) +#endif /* OPENSSL_VERSION_NUMBER =< 0x00907000L */ + +/* + * 1.1 renames RSA_PKCS1_SSLeay to RSA_PKCS1_OpenSSL + * use RSA_PKCS1_OpenSSL + * Previous versions are missing a number of functions to access + * some hidden structures. Define them here: + */ + +/* EVP_PKEY_base_id introduced in 1.0.1 */ +#if OPENSSL_VERSION_NUMBER < 0x10001000L +#define EVP_PKEY_base_id(x) (x->type) +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +#define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay +#define OPENSSL_malloc_init CRYPTO_malloc_init + +#define EVP_PKEY_get0_RSA(x) (x->pkey.rsa) +#define EVP_PKEY_get0_DSA(x) (x->pkey.dsa) +#define X509_get_extension_flags(x) (x->ex_flags) +#define X509_get_key_usage(x) (x->ex_kusage) +#define X509_get_extended_key_usage(x) (x->ex_xkusage) +#define EVP_PKEY_up_ref(user_key) CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY) +#define X509_up_ref(cert) CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509) +#endif + +/* + * OpenSSL-1.1.0-pre5 has hidden the RSA and DSA structures + * One can no longer use statements like rsa->n = ... + * Macros and defines don't work on all systems, so use inline versions + * If that is not good enough, versions could be added to libopensc + */ + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +/* based on OpenSSL-1.1.0 e_os2.h */ +/* sc_ossl_inline: portable inline definition usable in public headers */ +# if !defined(inline) && !defined(__cplusplus) +# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L + /* just use inline */ +# define sc_ossl_inline inline +# elif defined(__GNUC__) && __GNUC__>=2 +# define sc_ossl_inline __inline__ +# elif defined(_MSC_VER) +# define sc_ossl_inline __inline +# else +# define sc_ossl_inline +# endif +# else +# define sc_ossl_inline inline +# endif +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#define RSA_bits(R) (BN_num_bits(R->n)) + +#include +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif + +#ifndef OPENSSL_NO_RSA +static sc_ossl_inline int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + /* d is the private component and may be NULL */ + if (n == NULL || e == NULL) + return 0; + + BN_free(r->n); + BN_free(r->e); + BN_free(r->d); + r->n = n; + r->e = e; + r->d = d; + + return 1; +} + +static sc_ossl_inline int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + if (p == NULL || q == NULL) + return 0; + + BN_free(r->p); + BN_free(r->q); + r->p = p; + r->q = q; + + return 1; +} + +static sc_ossl_inline int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + if (dmp1 == NULL || dmq1 == NULL || iqmp == NULL) + return 0; + + BN_free(r->dmp1); + BN_free(r->dmq1); + BN_free(r->iqmp); + r->dmp1 = dmp1; + r->dmq1 = dmq1; + r->iqmp = iqmp; + + return 1; +} + +static sc_ossl_inline void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} + +static sc_ossl_inline void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} + +static sc_ossl_inline void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} + +#endif /* OPENSSL_NO_RSA */ + +#ifndef OPENSSL_NO_DSA +static sc_ossl_inline void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} + +static sc_ossl_inline void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} + +/* NOTE: DSA_set0_* functions not defined because they are not currently used in OpenSC */ +#endif /* OPENSSL_NO_DSA */ + +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ENABLE_OPENSSL */ +#endif /* _SC_OSSL_COMPAT_H */ diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 4431e69b..a6254327 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -9,6 +9,7 @@ #ifdef ENABLE_OPENSSL /* empty file without openssl */ #include +#include #include #include #include @@ -170,18 +171,25 @@ void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) { #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_ENGINE) - void (*locking_cb)(int, int, const char *, int); ENGINE *e; +/* crypto locking removed in 1.1 */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L + void (*locking_cb)(int, int, const char *, int); locking_cb = CRYPTO_get_locking_callback(); if (locking_cb) CRYPTO_set_locking_callback(NULL); +#endif e = ENGINE_by_id("gost"); if (!e) { #if !defined(OPENSSL_NO_STATIC_ENGINE) && !defined(OPENSSL_NO_GOST) && !defined(LIBRESSL_VERSION_NUMBER) + +/* ENGINE_load_gost removed in 1.1 */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L ENGINE_load_gost(); +#endif e = ENGINE_by_id("gost"); #else /* try to load dynamic gost engine */ @@ -202,8 +210,10 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) ENGINE_free(e); } +#if OPENSSL_VERSION_NUMBER < 0x10100000L if (locking_cb) CRYPTO_set_locking_callback(locking_cb); +#endif #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_ENGINE) */ openssl_sha1_mech.mech_data = EVP_sha1(); diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 942f9bfa..72a4b4a2 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -2175,44 +2175,52 @@ prkey_fixup_rsa(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey_rsa *key) * The cryptoflex does not seem to be able to do any sort * of RSA without the full set of CRT coefficients either */ + /* We don't really need an RSA structure, only the BIGNUMs */ + if (!key->dmp1.len || !key->dmq1.len || !key->iqmp.len) { static u8 dmp1[256], dmq1[256], iqmp[256]; - RSA *rsa; BIGNUM *aux; BN_CTX *bn_ctx; + BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp; - rsa = RSA_new(); - rsa->n = BN_bin2bn(key->modulus.data, key->modulus.len, NULL); - rsa->e = BN_bin2bn(key->exponent.data, key->exponent.len, NULL); - rsa->d = BN_bin2bn(key->d.data, key->d.len, NULL); - rsa->p = BN_bin2bn(key->p.data, key->p.len, NULL); - rsa->q = BN_bin2bn(key->q.data, key->q.len, NULL); - if (!rsa->dmp1) - rsa->dmp1 = BN_new(); - if (!rsa->dmq1) - rsa->dmq1 = BN_new(); - if (!rsa->iqmp) - rsa->iqmp = BN_new(); + rsa_n = BN_bin2bn(key->modulus.data, key->modulus.len, NULL); + rsa_e = BN_bin2bn(key->exponent.data, key->exponent.len, NULL); + rsa_d = BN_bin2bn(key->d.data, key->d.len, NULL); + rsa_p = BN_bin2bn(key->p.data, key->p.len, NULL); + rsa_q = BN_bin2bn(key->q.data, key->q.len, NULL); + rsa_dmp1 = BN_new(); + rsa_dmq1 = BN_new(); + rsa_iqmp = BN_new(); aux = BN_new(); bn_ctx = BN_CTX_new(); - BN_sub(aux, rsa->q, BN_value_one()); - BN_mod(rsa->dmq1, rsa->d, aux, bn_ctx); + BN_sub(aux, rsa_q, BN_value_one()); + BN_mod(rsa_dmq1, rsa_d, aux, bn_ctx); - BN_sub(aux, rsa->p, BN_value_one()); - BN_mod(rsa->dmp1, rsa->d, aux, bn_ctx); + BN_sub(aux, rsa_p, BN_value_one()); + BN_mod(rsa_dmp1, rsa_d, aux, bn_ctx); - BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, bn_ctx); + BN_mod_inverse(rsa_iqmp, rsa_q, rsa_p, bn_ctx); BN_clear_free(aux); BN_CTX_free(bn_ctx); /* Not thread safe, but much better than a memory leak */ - GETBN(key->dmp1, rsa->dmp1, dmp1); - GETBN(key->dmq1, rsa->dmq1, dmq1); - GETBN(key->iqmp, rsa->iqmp, iqmp); - RSA_free(rsa); + /* TODO put on stack, or allocate and clear and then free */ + GETBN(key->dmp1, rsa_dmp1, dmp1); + GETBN(key->dmq1, rsa_dmq1, dmq1); + GETBN(key->iqmp, rsa_iqmp, iqmp); + + BN_clear_free(rsa_n); + BN_clear_free(rsa_e); + BN_clear_free(rsa_d); + BN_clear_free(rsa_p); + BN_clear_free(rsa_q); + BN_clear_free(rsa_dmp1); + BN_clear_free(rsa_dmq1); + BN_clear_free(rsa_iqmp); + } #undef GETBN #endif diff --git a/src/pkcs15init/pkcs15-oberthur-awp.c b/src/pkcs15init/pkcs15-oberthur-awp.c index cda907a1..48797e46 100644 --- a/src/pkcs15init/pkcs15-oberthur-awp.c +++ b/src/pkcs15init/pkcs15-oberthur-awp.c @@ -27,12 +27,13 @@ #include #include "config.h" +#include "pkcs15-oberthur.h" + #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/log.h" #include "profile.h" #include "pkcs15-init.h" -#include "pkcs15-oberthur.h" #include "libopensc/asn1.h" #ifdef ENABLE_OPENSSL @@ -996,6 +997,30 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob /* * serial number */ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + + /* TODO the der encoding of a ANS1_INTEGER is a TLV, the original code only as using the + * i2c_ASN1_INTEGER which is not in OpenSSL 1.1 + * It was adding the tag V_ASN1_INTEGER and the one byte length back in in effect creating + * a DER encoded ASN1_INTEGER + * So we can simplifty the code and make compatable with OpenSSL 1.1. This needs to be tested + */ + ci->serial.len = 0; + ci->serial.value = NULL; + /* get length */ + ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL); + if (ci->serial.len > 0) { + if (!(ci->serial.value = malloc(ci->serial.len))) { + ci->serial.len = 0; + r = SC_ERROR_OUT_OF_MEMORY; + goto done; + } + ci->serial.len = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &ci->serial.value); + } + /* if len == 0, and value == NULL, then the cert did not have a serial number.*/ + sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cert. serial encoded length %i", ci->serial.len); + +#else do { int encoded_len; unsigned char encoded[0x40], *encoded_ptr; @@ -1015,6 +1040,7 @@ awp_encode_cert_info(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *ob sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "cert. serial encoded length %i", encoded_len); } while (0); +#endif ci->x509 = X509_dup(x); done: diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 200f1102..8ecc9c64 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -20,20 +20,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include +#include "pkcs15-oberthur.h" #include #include -#include "config.h" #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/log.h" #include "profile.h" #include "pkcs15-init.h" -#include "pkcs15-oberthur.h" #define COSM_TITLE "OberthurAWP" diff --git a/src/pkcs15init/pkcs15-oberthur.h b/src/pkcs15init/pkcs15-oberthur.h index 0b0b7753..6528e595 100644 --- a/src/pkcs15init/pkcs15-oberthur.h +++ b/src/pkcs15init/pkcs15-oberthur.h @@ -9,6 +9,7 @@ #include "config.h" #ifdef ENABLE_OPENSSL +#include #include #include #include @@ -18,6 +19,10 @@ #include #include +#include "profile.h" +#include "libopensc/opensc.h" + + #define COSM_TLV_TAG 0x00 #define TLV_TYPE_V 0 diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 023ede60..f666c718 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -26,6 +26,7 @@ #ifdef ENABLE_OPENSSL #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #endif +#include "libopensc/sc-ossl-compat.h" #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "pkcs15-init.h" @@ -255,7 +257,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, goto out; } - rsa->meth = RSA_PKCS1_SSLeay(); + RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); if(pubkey != NULL) { diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 109aa35a..d9e86745 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -217,8 +217,8 @@ static int parse_public_key(const u8 *key, size_t keysize, RSA *rsa) if (e == NULL) return -1; cf2bn(p, 4, e); - rsa->n = n; - rsa->e = e; + if (RSA_set0_key(rsa, n, e, NULL) != 1) + return -1; return 0; } @@ -226,6 +226,8 @@ static int gen_d(RSA *rsa) { BN_CTX *bnctx; BIGNUM *r0, *r1, *r2; + const BIGNUM *rsa_p, *rsa_q, *rsa_n, *rsa_e, *rsa_d; + BIGNUM *rsa_n_new, *rsa_e_new, *rsa_d_new; bnctx = BN_CTX_new(); if (bnctx == NULL) @@ -234,13 +236,25 @@ static int gen_d(RSA *rsa) r0 = BN_CTX_get(bnctx); r1 = BN_CTX_get(bnctx); r2 = BN_CTX_get(bnctx); - BN_sub(r1, rsa->p, BN_value_one()); - BN_sub(r2, rsa->q, BN_value_one()); + RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); + RSA_get0_factors(rsa, &rsa_p, &rsa_q); + + BN_sub(r1, rsa_p, BN_value_one()); + BN_sub(r2, rsa_q, BN_value_one()); BN_mul(r0, r1, r2, bnctx); - if ((rsa->d = BN_mod_inverse(NULL, rsa->e, r0, bnctx)) == NULL) { + if ((rsa_d_new = BN_mod_inverse(NULL, rsa_e, r0, bnctx)) == NULL) { fprintf(stderr, "BN_mod_inverse() failed.\n"); return -1; } + + /* RSA_set0_key will free previous value, and replace with new value + * Thus the need to copy the contents of rsa_n and rsa_e + */ + rsa_n_new = BN_dup(rsa_n); + rsa_e_new = BN_dup(rsa_e); + if (RSA_set0_key(rsa, rsa_n_new, rsa_e_new, rsa_d_new) != 1) + return -1; + BN_CTX_end(bnctx); BN_CTX_free(bnctx); return 0; @@ -288,11 +302,11 @@ static int parse_private_key(const u8 *key, size_t keysize, RSA *rsa) cf2bn(p, base, dmq1); p += base; - rsa->p = bn_p; - rsa->q = q; - rsa->dmp1 = dmp1; - rsa->dmq1 = dmq1; - rsa->iqmp = iqmp; + + if (RSA_set0_factors(rsa, bn_p, q) != 1) + return -1; + if (RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) != 1) + return -1; if (gen_d(rsa)) return -1; @@ -648,8 +662,9 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) u8 bnbuf[256]; int base = 0; int r; + const BIGNUM *rsa_p, *rsa_q, *rsa_dmp1, *rsa_dmq1, *rsa_iqmp; - switch (BN_num_bits(rsa->n)) { + switch (RSA_bits(rsa)) { case 512: base = 32; break; @@ -670,7 +685,10 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) *p++ = (5 * base + 3) >> 8; *p++ = (5 * base + 3) & 0xFF; *p++ = opt_key_num; - r = bn2cf(rsa->p, bnbuf); + + RSA_get0_factors(rsa, &rsa_p, &rsa_q); + + r = bn2cf(rsa_p, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); return 2; @@ -678,7 +696,7 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) memcpy(p, bnbuf, base); p += base; - r = bn2cf(rsa->q, bnbuf); + r = bn2cf(rsa_q, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); return 2; @@ -686,7 +704,9 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) memcpy(p, bnbuf, base); p += base; - r = bn2cf(rsa->iqmp, bnbuf); + RSA_get0_crt_params(rsa, &rsa_dmp1, &rsa_dmq1, &rsa_iqmp); + + r = bn2cf(rsa_iqmp, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); return 2; @@ -694,7 +714,7 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) memcpy(p, bnbuf, base); p += base; - r = bn2cf(rsa->dmp1, bnbuf); + r = bn2cf(rsa_dmp1, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); return 2; @@ -702,7 +722,7 @@ static int encode_private_key(RSA *rsa, u8 *key, size_t *keysize) memcpy(p, bnbuf, base); p += base; - r = bn2cf(rsa->dmq1, bnbuf); + r = bn2cf(rsa_dmq1, bnbuf); if (r != base) { fprintf(stderr, "Invalid private key.\n"); return 2; @@ -722,8 +742,9 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) u8 bnbuf[256]; int base = 0; int r; + const BIGNUM *rsa_n, *rsa_e; - switch (BN_num_bits(rsa->n)) { + switch (RSA_bits(rsa)) { case 512: base = 32; break; @@ -744,7 +765,9 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) *p++ = (5 * base + 7) >> 8; *p++ = (5 * base + 7) & 0xFF; *p++ = opt_key_num; - r = bn2cf(rsa->n, bnbuf); + + RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); + r = bn2cf(rsa_n, bnbuf); if (r != 2*base) { fprintf(stderr, "Invalid public key.\n"); return 2; @@ -758,7 +781,7 @@ static int encode_public_key(RSA *rsa, u8 *key, size_t *keysize) memset(bnbuf, 0, 2*base); memcpy(p, bnbuf, 2*base); p += 2*base; - r = bn2cf(rsa->e, bnbuf); + r = bn2cf(rsa_e, bnbuf); memcpy(p, bnbuf, 4); p += 4; diff --git a/src/tools/gids-tool.c b/src/tools/gids-tool.c index f3febe64..029c53ff 100644 --- a/src/tools/gids-tool.c +++ b/src/tools/gids-tool.c @@ -36,6 +36,7 @@ #include #include +#include "libopensc/sc-ossl-compat.h" #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/card-gids.h" @@ -521,7 +522,9 @@ int main(int argc, char * const argv[]) } } - CRYPTO_malloc_init(); + /* OpenSSL magic */ + OPENSSL_malloc_init(); + ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); diff --git a/src/tools/netkey-tool.c b/src/tools/netkey-tool.c index 6aef6443..2c52d672 100644 --- a/src/tools/netkey-tool.c +++ b/src/tools/netkey-tool.c @@ -144,9 +144,9 @@ static void show_certs(sc_card_t *card) printf(", Len=%d\n", (q[2]<<8)|q[3]); if((c=d2i_X509(NULL,&q,f->size))){ char buf2[2000]; - X509_NAME_get_text_by_NID(c->cert_info->subject, NID_commonName, buf2,sizeof(buf2)); + X509_NAME_get_text_by_NID(X509_get_subject_name(c), NID_commonName, buf2,sizeof(buf2)); printf(" Subject-CN: %s\n", buf2); - X509_NAME_get_text_by_NID(c->cert_info->issuer, NID_commonName, buf2,sizeof(buf2)); + X509_NAME_get_text_by_NID(X509_get_issuer_name(c), NID_commonName, buf2,sizeof(buf2)); printf(" Issuer-CN: %s\n", buf2); X509_free(c); } else printf(" Invalid Certificate-Data\n"); diff --git a/src/tools/piv-tool.c b/src/tools/piv-tool.c index 647a432d..422004cb 100644 --- a/src/tools/piv-tool.c +++ b/src/tools/piv-tool.c @@ -45,6 +45,7 @@ #include #include +#include "libopensc/sc-ossl-compat.h" #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/asn1.h" @@ -329,19 +330,25 @@ static int gen_key(const char * key_info) if (keydata.key_bits > 0) { /* RSA key */ RSA * newkey = NULL; + BIGNUM *newkey_n, *newkey_e; newkey = RSA_new(); if (newkey == NULL) { fprintf(stderr, "gen_key RSA_new failed %d\n",r); return -1; } - newkey->n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, newkey->n); + newkey_n = BN_bin2bn(keydata.pubkey, keydata.pubkey_len, NULL); expl = keydata.exponent; expc[3] = (u8) expl & 0xff; expc[2] = (u8) (expl >>8) & 0xff; expc[1] = (u8) (expl >>16) & 0xff; expc[0] = (u8) (expl >>24) & 0xff; - newkey->e = BN_bin2bn(expc, 4, newkey->e); + newkey_e = BN_bin2bn(expc, 4, NULL); + + if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1) { + fprintf(stderr, "gen_key unable to set RSA values"); + return -1; + } if (verbose) RSA_print_fp(stdout, newkey,0); @@ -534,14 +541,15 @@ int main(int argc, char * const argv[]) if (action_count == 0) util_print_usage_and_die(app_name, options, option_help, NULL); - CRYPTO_malloc_init(); + OPENSSL_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); if (out_file) { bp = BIO_new(BIO_s_file()); - BIO_write_filename(bp, (char *)out_file); + if (!BIO_write_filename(bp, (char *)out_file)) + goto end; } else { bp = BIO_new(BIO_s_file()); BIO_set_fp(bp,stdout,BIO_NOCLOSE); diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 0587db1b..2d9b6101 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -37,12 +37,15 @@ #include #if OPENSSL_VERSION_NUMBER >= 0x10000000L #include +#include #endif #if OPENSSL_VERSION_NUMBER >= 0x00907000L #include #endif #include #include +#include +#include #include #include #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA) @@ -53,6 +56,7 @@ #include #endif +#include "libopensc/sc-ossl-compat.h" #include "pkcs11/pkcs11.h" #include "pkcs11/pkcs11-opensc.h" #include "libopensc/asn1.h" @@ -456,12 +460,20 @@ int main(int argc, char * argv[]) #endif #ifdef ENABLE_OPENSSL -#if OPENSSL_VERSION_NUMBER >= 0x00907000L +#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L OPENSSL_config(NULL); #endif +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS + | OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS + | OPENSSL_INIT_LOAD_CONFIG, + NULL); +#else /* OpenSSL magic */ - SSLeay_add_all_algorithms(); - CRYPTO_malloc_init(); + OpenSSL_add_all_algorithms(); + OPENSSL_malloc_init(); +#endif #endif while (1) { c = getopt_long(argc, argv, "ILMOTa:bd:e:hi:klm:o:p:scvf:ty:w:z:r", @@ -1960,36 +1972,37 @@ static void parse_certificate(struct x509cert_info *cert, util_fatal("OpenSSL error during X509 certificate parsing"); } /* check length first */ - n = i2d_X509_NAME(x->cert_info->subject, NULL); + n = i2d_X509_NAME(X509_get_subject_name(x), NULL); if (n < 0) util_fatal("OpenSSL error while encoding subject name"); if (n > (int)sizeof (cert->subject)) util_fatal("subject name too long"); /* green light, actually do it */ p = cert->subject; - n = i2d_X509_NAME(x->cert_info->subject, &p); + n = i2d_X509_NAME(X509_get_subject_name(x), &p); cert->subject_len = n; /* check length first */ - n = i2d_X509_NAME(x->cert_info->issuer, NULL); + n = i2d_X509_NAME(X509_get_issuer_name(x), NULL); if (n < 0) util_fatal("OpenSSL error while encoding issuer name"); if (n > (int)sizeof (cert->issuer)) util_fatal("issuer name too long"); /* green light, actually do it */ p = cert->issuer; - n = i2d_X509_NAME(x->cert_info->issuer, &p); + n =i2d_X509_NAME(X509_get_issuer_name(x), &p); cert->issuer_len = n; /* check length first */ - n = i2d_ASN1_INTEGER(x->cert_info->serialNumber, NULL); + n = 0; + n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), NULL); if (n < 0) util_fatal("OpenSSL error while encoding serial number"); if (n > (int)sizeof (cert->serialnum)) util_fatal("serial number too long"); /* green light, actually do it */ p = cert->serialnum; - n = i2d_ASN1_INTEGER(x->cert_info->serialNumber, &p); + n = i2d_ASN1_INTEGER(X509_get_serialNumber(x), &p); cert->serialnum_len = n; } @@ -2023,16 +2036,24 @@ do_read_key(unsigned char *data, size_t data_len, int private, EVP_PKEY **key) #define RSA_GET_BN(RSA, LOCALNAME, BNVALUE) \ do { \ - RSA->LOCALNAME = malloc(BN_num_bytes(BNVALUE)); \ - if (!RSA->LOCALNAME) \ - util_fatal("malloc() failure"); \ - RSA->LOCALNAME##_len = BN_bn2bin(BNVALUE, RSA->LOCALNAME); \ + if (BNVALUE) { \ + RSA->LOCALNAME = malloc(BN_num_bytes(BNVALUE)); \ + if (!RSA->LOCALNAME) \ + util_fatal("malloc() failure\n"); \ + RSA->LOCALNAME##_len = BN_bn2bin(BNVALUE, RSA->LOCALNAME); \ + } else { \ + RSA->LOCALNAME##_len = 0; \ + RSA->LOCALNAME = NULL; \ + } \ } while (0) static int parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) { RSA *r; + const BIGNUM *r_n, *r_e, *r_d; + const BIGNUM *r_p, *r_q; + const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp; r = EVP_PKEY_get1_RSA(pkey); if (!r) { @@ -2042,15 +2063,22 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) util_fatal("OpenSSL error during RSA public key parsing"); } - RSA_GET_BN(rsa, modulus, r->n); - RSA_GET_BN(rsa, public_exponent, r->e); + RSA_get0_key(r, &r_n, &r_e, NULL); + RSA_GET_BN(rsa, modulus, r_n); + RSA_GET_BN(rsa, public_exponent, r_e); + if (private) { - RSA_GET_BN(rsa, private_exponent, r->d); - RSA_GET_BN(rsa, prime_1, r->p); - RSA_GET_BN(rsa, prime_2, r->q); - RSA_GET_BN(rsa, exponent_1, r->dmp1); - RSA_GET_BN(rsa, exponent_2, r->dmq1); - RSA_GET_BN(rsa, coefficient, r->iqmp); + RSA_get0_key(r, NULL, NULL, &r_d); + RSA_GET_BN(rsa, private_exponent, r_d); + + RSA_get0_factors(r, &r_p, &r_q); + RSA_GET_BN(rsa, prime_1, r_p); + RSA_GET_BN(rsa, prime_2, r_q); + + RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp); + RSA_GET_BN(rsa, exponent_1, r_dmp1); + RSA_GET_BN(rsa, exponent_2, r_dmq1); + RSA_GET_BN(rsa, coefficient, r_iqmp); } RSA_free(r); @@ -2200,6 +2228,7 @@ static int write_object(CK_SESSION_HANDLE session) struct rsakey_info rsa; struct gostkey_info gost; EVP_PKEY *evp_key = NULL; + int pk_type; memset(&cert, 0, sizeof(cert)); memset(&rsa, 0, sizeof(rsa)); @@ -2253,20 +2282,22 @@ static int write_object(CK_SESSION_HANDLE session) util_fatal("Cannot read public key"); } - if (evp_key->type == EVP_PKEY_RSA) { + pk_type = EVP_PKEY_base_id(evp_key); + + if (pk_type == EVP_PKEY_RSA) { rv = parse_rsa_pkey(evp_key, is_private, &rsa); } #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) - else if (evp_key->type == NID_id_GostR3410_2001) { + else if (pk_type == NID_id_GostR3410_2001) { rv = parse_gost_pkey(evp_key, is_private, &gost); type = CKK_GOSTR3410; - } else if (evp_key->type == EVP_PKEY_EC) { + } else if (pk_type == EVP_PKEY_EC) { rv = parse_ec_pkey(evp_key, is_private, &gost); type = CKK_EC; } #endif else - util_fatal("Unsupported key type: 0x%X", evp_key->type); + util_fatal("Unsupported key type: 0x%X", pk_type); if (rv) util_fatal("Cannot parse key"); @@ -2344,9 +2375,12 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(privkey_templ[n_privkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len); n_privkey_attr++; } - FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); - n_privkey_attr++; - if (evp_key->type == EVP_PKEY_RSA) { + pk_type = EVP_PKEY_base_id(evp_key); + + if (pk_type == EVP_PKEY_RSA) { + type = CKK_RSA; + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_MODULUS, rsa.modulus, rsa.modulus_len); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len); @@ -2365,13 +2399,21 @@ static int write_object(CK_SESSION_HANDLE session) n_privkey_attr++; } #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) - else if (evp_key->type == EVP_PKEY_EC) { + else if (pk_type == EVP_PKEY_EC) { + type = CKK_EC; + + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); n_privkey_attr++; } - else if (evp_key->type == NID_id_GostR3410_2001) { + else if (pk_type == NID_id_GostR3410_2001) { + type = CKK_GOSTR3410; + + FILL_ATTR(privkey_templ[n_privkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len); n_privkey_attr++; FILL_ATTR(privkey_templ[n_privkey_attr], CKA_VALUE, gost.private.value, gost.private.len); @@ -2389,16 +2431,17 @@ static int write_object(CK_SESSION_HANDLE session) if (opt_object_class == CKO_PUBLIC_KEY) { clazz = CKO_PUBLIC_KEY; #ifdef ENABLE_OPENSSL - if (evp_key->type == EVP_PKEY_RSA) + pk_type = EVP_PKEY_base_id(evp_key); + if (pk_type == EVP_PKEY_RSA) type = CKK_RSA; #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) - else if (evp_key->type == EVP_PKEY_EC) + else if (pk_type == EVP_PKEY_EC) type = CKK_EC; - else if (evp_key->type == NID_id_GostR3410_2001) + else if (pk_type == NID_id_GostR3410_2001) type = CKK_GOSTR3410; #endif else - util_fatal("Unsupported public key type: 0x%X", evp_key->type); + util_fatal("Unsupported public key type: 0x%X", pk_type); #endif n_pubkey_attr = 0; @@ -2444,22 +2487,34 @@ static int write_object(CK_SESSION_HANDLE session) FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_SUBJECT, cert.subject, cert.subject_len); n_pubkey_attr++; } - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); - n_pubkey_attr++; - if (evp_key->type == EVP_PKEY_RSA) { - FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS, rsa.modulus, rsa.modulus_len); + pk_type = EVP_PKEY_base_id(evp_key); + + if (pk_type == EVP_PKEY_RSA) { + type = CKK_RSA; + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_pubkey_attr++; + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_MODULUS, + rsa.modulus, rsa.modulus_len); n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_PUBLIC_EXPONENT, rsa.public_exponent, rsa.public_exponent_len); n_pubkey_attr++; } #if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) - else if (evp_key->type == EVP_PKEY_EC) { + else if (pk_type == EVP_PKEY_EC) { + type = CKK_EC; + + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_PARAMS, gost.param_oid.value, gost.param_oid.len); n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_EC_POINT, gost.public.value, gost.public.len); n_pubkey_attr++; } - else if (evp_key->type == NID_id_GostR3410_2001) { + else if (pk_type == NID_id_GostR3410_2001) { + type = CKK_GOSTR3410; + + FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_KEY_TYPE, &type, sizeof(type)); + n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_GOSTR3410_PARAMS, gost.param_oid.value, gost.param_oid.len); n_pubkey_attr++; FILL_ATTR(pubkey_templ[n_pubkey_attr], CKA_VALUE, gost.public.value, gost.public.len); @@ -3446,25 +3501,31 @@ static int read_object(CK_SESSION_HANDLE session) type = getKEY_TYPE(session, obj); if (type == CKK_RSA) { RSA *rsa; + BIGNUM *rsa_n = NULL; + BIGNUM *rsa_e = NULL; + rsa = RSA_new(); if (rsa == NULL) util_fatal("out of memory"); if ((value = getMODULUS(session, obj, &len))) { - if (!(rsa->n = BN_bin2bn(value, len, rsa->n))) + if (!(rsa_n = BN_bin2bn(value, len, NULL))) util_fatal("cannot parse MODULUS"); free(value); } else util_fatal("cannot obtain MODULUS"); if ((value = getPUBLIC_EXPONENT(session, obj, &len))) { - if (!(rsa->e = BN_bin2bn(value, len, rsa->e))) + if (!(rsa_e = BN_bin2bn(value, len, NULL))) util_fatal("cannot parse PUBLIC_EXPONENT"); free(value); } else util_fatal("cannot obtain PUBLIC_EXPONENT"); + if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1) + util_fatal("cannot set RSA values"); + if (!i2d_RSA_PUBKEY_bio(pout, rsa)) util_fatal("cannot convert RSA public key to DER"); RSA_free(rsa); @@ -3802,6 +3863,7 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv CK_ULONG pubkeyLen; EVP_PKEY *pkey; RSA *rsa; + BIGNUM *rsa_n, *rsa_e; id = NULL; id = getID(session, privKeyObject, &idLen); @@ -3835,8 +3897,11 @@ static EVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv free(exp); return NULL; } - rsa->n = BN_bin2bn(mod, modLen, NULL); - rsa->e = BN_bin2bn(exp, expLen, NULL); + rsa_n = BN_bin2bn(mod, modLen, NULL); + rsa_e = BN_bin2bn(exp, expLen, NULL); + if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) != 1) + return NULL; + EVP_PKEY_assign_RSA(pkey, rsa); free(mod); free(exp); @@ -4410,7 +4475,7 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE cipherKeyObject; CK_RV rv; EVP_PKEY *pkey; - EVP_CIPHER_CTX seal_ctx; + EVP_CIPHER_CTX * seal_ctx; unsigned char keybuf[512], *key = keybuf; int key_len; unsigned char iv[32], ciphered[1024], cleartext[1024]; @@ -4426,7 +4491,13 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, printf(" %s: ", OBJ_nid2sn(EVP_CIPHER_nid(algo))); - if (!EVP_SealInit(&seal_ctx, algo, + seal_ctx = EVP_CIPHER_CTX_new(); + if (seal_ctx == NULL) { + printf("Internal error.\n"); + return 1; + } + + if (!EVP_SealInit(seal_ctx, algo, &key, &key_len, iv, &pkey, 1)) { fprintf(stderr, "Internal error.\n"); @@ -4435,15 +4506,15 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, /* Encrypt something */ len = sizeof(ciphered); - if (!EVP_SealUpdate(&seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11)) { - fprintf(stderr, "Internal error.\n"); + if (!EVP_SealUpdate(seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11)) { + printf("Internal error.\n"); return 1; } ciphered_len = len; len = sizeof(ciphered) - ciphered_len; - if (!EVP_SealFinal(&seal_ctx, ciphered + ciphered_len, &len)) { - fprintf(stderr, "Internal error.\n"); + if (!EVP_SealFinal(seal_ctx, ciphered + ciphered_len, &len)) { + printf("Internal error.\n"); return 1; } ciphered_len += len; @@ -4479,21 +4550,21 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, return 1; } - if (!EVP_DecryptInit(&seal_ctx, algo, key, iv)) { - fprintf(stderr, "Internal error.\n"); + if (!EVP_DecryptInit(seal_ctx, algo, key, iv)) { + printf("Internal error.\n"); return 1; } len = sizeof(cleartext); - if (!EVP_DecryptUpdate(&seal_ctx, cleartext, &len, ciphered, ciphered_len)) { - fprintf(stderr, "Internal error.\n"); + if (!EVP_DecryptUpdate(seal_ctx, cleartext, &len, ciphered, ciphered_len)) { + printf("Internal error.\n"); return 1; } cleartext_len = len; len = sizeof(cleartext) - len; - if (!EVP_DecryptFinal(&seal_ctx, cleartext + cleartext_len, &len)) { - fprintf(stderr, "Internal error.\n"); + if (!EVP_DecryptFinal(seal_ctx, cleartext + cleartext_len, &len)) { + printf("Internal error.\n"); return 1; } cleartext_len += len; @@ -4504,6 +4575,9 @@ static int wrap_unwrap(CK_SESSION_HANDLE session, return 1; } + if (seal_ctx) + EVP_CIPHER_CTX_free(seal_ctx); + printf("OK\n"); return 0; } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 6d8487ee..3652f96c 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -52,6 +52,7 @@ #include #include #if OPENSSL_VERSION_NUMBER >= 0x10000000L +#include #include /* for OPENSSL_NO_EC */ #ifndef OPENSSL_NO_EC #include @@ -59,6 +60,7 @@ #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ #include "common/compat_strlcpy.h" +#include "libopensc/sc-ossl-compat.h" #include "libopensc/cardctl.h" #include "libopensc/pkcs15.h" #include "libopensc/log.h" @@ -434,12 +436,22 @@ main(int argc, char **argv) unsigned int n; int r = 0; -#if OPENSSL_VERSION_NUMBER >= 0x00907000L +#if OPENSSL_VERSION_NUMBER >= 0x00907000L && OPENSSL_VERSION_NUMBER < 0x10100000L OPENSSL_config(NULL); #endif +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + /* Openssl 1.1.0 magic */ + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS + | OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS + | OPENSSL_INIT_LOAD_CONFIG, + NULL); +#else /* OpenSSL magic */ - SSLeay_add_all_algorithms(); - CRYPTO_malloc_init(); + OpenSSL_add_all_algorithms(); + OPENSSL_malloc_init(); +#endif + #ifdef RANDOM_POOL if (!RAND_load_file(RANDOM_POOL, 32)) util_fatal("Unable to seed random number pool for key generation"); @@ -909,7 +921,7 @@ do_store_private_key(struct sc_profile *profile) printf("Importing %d certificates:\n", opt_ignore_ca_certs ? 1 : ncerts); for (i = 0; i < ncerts && !(i && opt_ignore_ca_certs); i++) - printf(" %d: %s\n", i, X509_NAME_oneline(cert[i]->cert_info->subject, + printf(" %d: %s\n", i, X509_NAME_oneline(X509_get_subject_name(cert[i]), namebuf, sizeof(namebuf))); } @@ -923,7 +935,7 @@ do_store_private_key(struct sc_profile *profile) /* tell openssl to cache the extensions */ X509_check_purpose(cert[0], -1, -1); - usage = cert[0]->ex_kusage; + usage = X509_get_extended_key_usage(cert[0]); /* No certificate usage? Assume ordinary * user cert */ @@ -973,10 +985,11 @@ do_store_private_key(struct sc_profile *profile) return r; X509_check_purpose(cert[i], -1, -1); - cargs.x509_usage = cert[i]->ex_kusage; + cargs.x509_usage = X509_get_extended_key_usage(cert[i]); + cargs.label = cert_common_name(cert[i]); if (!cargs.label) - cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject, namebuf, sizeof(namebuf)); + cargs.label = X509_NAME_oneline(X509_get_subject_name(cert[i]), namebuf, sizeof(namebuf)); /* Just the first certificate gets the same ID * as the private key. All others get @@ -1116,6 +1129,7 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, { X509 *oldcert, *newcert; EVP_PKEY *oldpk, *newpk; + int oldpk_type, newpk_type; const u8 *ptr; int r; @@ -1136,19 +1150,30 @@ do_read_check_certificate(sc_pkcs15_cert_t *sc_oldcert, oldpk = X509_get_pubkey(oldcert); newpk = X509_get_pubkey(newcert); + oldpk_type = EVP_PKEY_base_id(oldpk); + newpk_type = EVP_PKEY_base_id(newpk); + /* Compare the public keys, there's no high level openssl function for this(?) */ + /* Yes there is in 1.0.2 and above EVP_PKEY_cmp */ + + r = SC_ERROR_INVALID_ARGUMENTS; - if (oldpk->type == newpk->type) + if (oldpk_type == newpk_type) { - if ((oldpk->type == EVP_PKEY_DSA) && - !BN_cmp(oldpk->pkey.dsa->p, newpk->pkey.dsa->p) && - !BN_cmp(oldpk->pkey.dsa->q, newpk->pkey.dsa->q) && - !BN_cmp(oldpk->pkey.dsa->g, newpk->pkey.dsa->g)) +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + if (EVP_PKEY_cmp(oldpk, newpk) == 1) + r = 0; +#else + if ((oldpk_type == EVP_PKEY_DSA) && + !BN_cmp(EVP_PKEY_get0_DSA(oldpk)->p, EVP_PKEY_get0_DSA(newpk)->p) && + !BN_cmp(EVP_PKEY_get0_DSA(oldpk)->q, EVP_PKEY_get0_DSA(newpk)->q) && + !BN_cmp(EVP_PKEY_get0_DSA(oldpk)->g, EVP_PKEY_get0_DSA(newpk)->g)) r = 0; - else if ((oldpk->type == EVP_PKEY_RSA) && - !BN_cmp(oldpk->pkey.rsa->n, newpk->pkey.rsa->n) && - !BN_cmp(oldpk->pkey.rsa->e, newpk->pkey.rsa->e)) + else if ((oldpk_type == EVP_PKEY_RSA) && + !BN_cmp(EVP_PKEY_get0_RSA(oldpk)->n, EVP_PKEY_get0_RSA(newpk)->n) && + !BN_cmp(EVP_PKEY_get0_RSA(oldpk)->e, EVP_PKEY_get0_RSA(newpk)->e)) r = 0; +#endif } EVP_PKEY_free(newpk); @@ -2004,7 +2029,8 @@ do_read_pkcs12_private_key(const char *filename, const char *passphrase, return SC_ERROR_CANNOT_LOAD_KEY; } - CRYPTO_add(&user_key->references, 1, CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_up_ref(user_key); + if (user_cert && max_certs) certs[ncerts++] = user_cert; @@ -2014,7 +2040,7 @@ do_read_pkcs12_private_key(const char *filename, const char *passphrase, /* bump reference counts for certificates */ for (i = 0; i < ncerts; i++) { - CRYPTO_add(&certs[i]->references, 1, CRYPTO_LOCK_X509); + X509_up_ref(certs[i]); } if (cacerts) diff --git a/src/tools/sc-hsm-tool.c b/src/tools/sc-hsm-tool.c index a36902f6..4efc1b12 100644 --- a/src/tools/sc-hsm-tool.c +++ b/src/tools/sc-hsm-tool.c @@ -32,6 +32,8 @@ #include /* Requires openssl for dkek import */ +#include + #include #include #include @@ -39,6 +41,7 @@ #include #include +#include "libopensc/sc-ossl-compat.h" #include "libopensc/opensc.h" #include "libopensc/cardctl.h" #include "libopensc/asn1.h" @@ -123,8 +126,8 @@ static const char *option_help[] = { }; typedef struct { - BIGNUM x; - BIGNUM y; + BIGNUM * x; + BIGNUM * y; } secret_share_t; static sc_context_t *ctx = NULL; @@ -157,7 +160,11 @@ static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigne do { // Generate random prime +#if OPENSSL_VERSION_NUMBER >= 0x00908000L /* last parm is BN_GENCB which is null in our case */ + BN_generate_prime_ex(prime, bits, 1, NULL, NULL, NULL); +#else BN_generate_prime(prime, bits, 1, NULL, NULL, NULL, NULL ); +#endif } while ((BN_ucmp(prime, s) == -1) && (max_rounds-- > 0)); // If prime < s or not reached 1000 tries @@ -179,21 +186,20 @@ static int generatePrime(BIGNUM *prime, const BIGNUM *s, const int bits, unsigne * @param prime Prime for finite field arithmetic * @param y Pointer for storage of calculated y-value */ -static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const unsigned char t, const BIGNUM prime, BIGNUM *y) +static void calculatePolynomialValue(const BIGNUM *x, BIGNUM **polynomial, const unsigned char t, const BIGNUM *prime, BIGNUM *y) { BIGNUM **pp; - BIGNUM temp; - BIGNUM exponent; + BIGNUM *temp; + BIGNUM *exponent; unsigned long exp; BN_CTX *ctx; // Create context for temporary variables of OpenSSL engine ctx = BN_CTX_new(); - BN_CTX_init(ctx); - BN_init(&temp); - BN_init(&exponent); + temp = BN_new(); + exponent = BN_new(); // Set y to ZERO BN_zero(y); @@ -206,21 +212,21 @@ static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const for (exp = 1; exp < t; exp++) { - BN_copy(&temp, &x); + BN_copy(temp, x); - BN_set_word(&exponent, exp); + BN_set_word(exponent, exp); // temp = x^exponent mod prime - BN_mod_exp(&temp, &x, &exponent, &prime, ctx); + BN_mod_exp(temp, x, exponent, prime, ctx); // exponent = temp * a = a * x^exponent mod prime - BN_mod_mul(&exponent, &temp, *pp, &prime, ctx); + BN_mod_mul(exponent, temp, *pp, prime, ctx); // add the temp value from exponent to y - BN_copy(&temp, y); - BN_mod_add(y, &temp, &exponent, &prime, ctx); + BN_copy(temp, y); + BN_mod_add(y, temp, exponent, prime, ctx); pp++; } - BN_clear_free(&temp); - BN_clear_free(&exponent); + BN_clear_free(temp); + BN_clear_free(exponent); BN_CTX_free(ctx); } @@ -236,7 +242,7 @@ static void calculatePolynomialValue(const BIGNUM x, BIGNUM **polynomial, const * @param prime Prime for finite field arithmetic * @param shares Pointer for storage of calculated shares (must be big enough to hold n shares) */ -static int createShares(const BIGNUM *s, const unsigned char t, const unsigned char n, const BIGNUM prime, secret_share_t *shares) +static int createShares(const BIGNUM *s, const unsigned char t, const unsigned char n, const BIGNUM *prime, secret_share_t *shares) { // Array representing the polynomial a(x) = s + a_1 * x + ... + a_n-1 * x^n-1 mod p BIGNUM **polynomial = malloc(n * sizeof(BIGNUM *)); @@ -247,26 +253,23 @@ static int createShares(const BIGNUM *s, const unsigned char t, const unsigned c // Set the secret value as the constant part of the polynomial pp = polynomial; *pp = BN_new(); - BN_init(*pp); BN_copy(*pp, s); pp++; // Initialize and generate some random values for coefficients a_x in the remaining polynomial for (i = 1; i < t; i++) { *pp = BN_new(); - BN_init(*pp); - BN_rand_range(*pp, &prime); + BN_rand_range(*pp, prime); pp++; } sp = shares; // Now calculate n secret shares for (i = 1; i <= n; i++) { - BN_init(&(sp->x)); - BN_init(&(sp->y)); - - BN_set_word(&(sp->x), i); - calculatePolynomialValue(sp->x, polynomial, t, prime, &(sp->y)); + sp->x = BN_new(); + sp->y = BN_new(); + BN_set_word((sp->x), i); + calculatePolynomialValue(sp->x, polynomial, t, prime, (sp->y)); sp++; } @@ -292,7 +295,7 @@ static int createShares(const BIGNUM *s, const unsigned char t, const unsigned c * @param prime Prime for finite field arithmetic * @param s Pointer for storage of calculated secred */ -static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGNUM prime, BIGNUM *s) +static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGNUM *prime, BIGNUM *s) { unsigned char i; unsigned char j; @@ -300,9 +303,9 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN // Array representing the polynomial a(x) = s + a_1 * x + ... + a_n-1 * x^n-1 mod p BIGNUM **bValue = malloc(t * sizeof(BIGNUM *)); BIGNUM **pbValue; - BIGNUM numerator; - BIGNUM denominator; - BIGNUM temp; + BIGNUM * numerator; + BIGNUM * denominator; + BIGNUM * temp; secret_share_t *sp_i; secret_share_t *sp_j; BN_CTX *ctx; @@ -311,24 +314,22 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN pbValue = bValue; for (i = 0; i < t; i++) { *pbValue = BN_new(); - BN_init(*pbValue); pbValue++; } - BN_init(&numerator); - BN_init(&denominator); - BN_init(&temp); + numerator = BN_new(); + denominator = BN_new(); + temp = BN_new(); // Create context for temporary variables of engine ctx = BN_CTX_new(); - BN_CTX_init(ctx); pbValue = bValue; sp_i = shares; for (i = 0; i < t; i++) { - BN_one(&numerator); - BN_one(&denominator); + BN_one(numerator); + BN_one(denominator); sp_j = shares; @@ -339,9 +340,9 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN continue; } - BN_mul(&numerator, &numerator, &(sp_j->x), ctx); - BN_sub(&temp, &(sp_j->x), &(sp_i->x)); - BN_mul(&denominator, &denominator, &temp, ctx); + BN_mul(numerator, numerator, (sp_j->x), ctx); + BN_sub(temp, (sp_j->x), (sp_i->x)); + BN_mul(denominator, denominator, temp, ctx); sp_j++; } @@ -350,12 +351,12 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN * Use the modular inverse value of the denominator for the * multiplication */ - if (BN_mod_inverse(&denominator, &denominator, &prime, ctx) == NULL ) { + if (BN_mod_inverse(denominator, denominator, prime, ctx) == NULL ) { free(bValue); return -1; } - BN_mod_mul(*pbValue, &numerator, &denominator, &prime, ctx); + BN_mod_mul(*pbValue, numerator, denominator, prime, ctx); pbValue++; sp_i++; @@ -370,19 +371,19 @@ static int reconstructSecret(secret_share_t *shares, unsigned char t, const BIGN BN_zero(s); for (i = 0; i < t; i++) { - BN_mul(&temp, &(sp_i->y), *pbValue, ctx); - BN_add(s, s, &temp); + BN_mul(temp, (sp_i->y), *pbValue, ctx); + BN_add(s, s, temp); pbValue++; sp_i++; } // Perform modulo operation and copy result - BN_nnmod(&temp, s, &prime, ctx); - BN_copy(s, &temp); + BN_nnmod(temp, s, prime, ctx); + BN_copy(s, temp); - BN_clear_free(&numerator); - BN_clear_free(&denominator); - BN_clear_free(&temp); + BN_clear_free(numerator); + BN_clear_free(denominator); + BN_clear_free(temp); BN_CTX_free(ctx); @@ -413,8 +414,8 @@ static int cleanUpShares(secret_share_t *shares, unsigned char n) sp = shares; for (i = 0; i < n; i++) { - BN_clear_free(&(sp->x)); - BN_clear_free(&(sp->y)); + BN_clear_free((sp->x)); + BN_clear_free((sp->y)); sp++; } @@ -640,8 +641,8 @@ static int initialize(sc_card_t *card, const char *so_pin, const char *user_pin, static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_password_shares) { int r, i; - BIGNUM prime; - BIGNUM secret; + BIGNUM *prime; + BIGNUM *secret; BIGNUM *p; char inbuf[64]; unsigned char bin[64]; @@ -658,8 +659,8 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas /* * Initialize prime and secret */ - BN_init(&prime); - BN_init(&secret); + prime = BN_new(); + secret = BN_new(); // Allocate data buffer for the shares shares = malloc(num_of_password_shares * sizeof(secret_share_t)); @@ -676,7 +677,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas } binlen = 64; sc_hex_to_bin(inbuf, bin, &binlen); - BN_bin2bn(bin, binlen, &prime); + BN_bin2bn(bin, binlen, prime); sp = shares; for (i = 0; i < num_of_password_shares; i++) { @@ -687,8 +688,8 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas clearScreen(); - BN_init(&(sp->x)); - BN_init(&(sp->y)); + sp->x = BN_new(); + sp->y = BN_new(); printf("Share %i of %i\n\n", i + 1, num_of_password_shares); @@ -698,7 +699,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas fprintf(stderr, "Input aborted\n"); return -1; } - p = &(sp->x); + p = (sp->x); BN_hex2bn(&p, inbuf); printf("Please enter share value: "); @@ -709,14 +710,14 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas } binlen = 64; sc_hex_to_bin(inbuf, bin, &binlen); - BN_bin2bn(bin, binlen, &(sp->y)); + BN_bin2bn(bin, binlen, (sp->y)); sp++; } clearScreen(); - r = reconstructSecret(shares, num_of_password_shares, prime, &secret); + r = reconstructSecret(shares, num_of_password_shares, prime, secret); if (r < 0) { printf("\nError during reconstruction of secret. Wrong shares?\n"); @@ -728,14 +729,14 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas * Encode the secret value */ ip = (unsigned char *) inbuf; - *pwdlen = BN_bn2bin(&secret, ip); + *pwdlen = BN_bn2bin(secret, ip); *pwd = calloc(1, *pwdlen); memcpy(*pwd, ip, *pwdlen); cleanUpShares(shares, num_of_password_shares); - BN_clear_free(&prime); - BN_clear_free(&secret); + BN_clear_free(prime); + BN_clear_free(secret); return 0; } @@ -745,7 +746,7 @@ static int recreate_password_from_shares(char **pwd, int *pwdlen, int num_of_pas static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const char *password, int num_of_password_shares) { sc_cardctl_sc_hsm_dkek_t dkekinfo; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = NULL; FILE *in = NULL; u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64]; char *pwd = NULL; @@ -803,14 +804,14 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c free(pwd); } - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_DecryptUpdate(&ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { + ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); + if (!EVP_DecryptUpdate(ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } - if (!EVP_DecryptFinal_ex(&ctx, outbuff + outlen, &r)) { + if (!EVP_DecryptFinal_ex(ctx, outbuff + outlen, &r)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } @@ -824,7 +825,7 @@ static int import_dkek_share(sc_card_t *card, const char *inf, int iter, const c r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE, (void *)&dkekinfo); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Not supported by card or card not initialized for key share usage\n"); @@ -845,7 +846,7 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch // hex output can be used in the SCSH shell with the // decrypt_keyblob.js file sc_cardctl_sc_hsm_dkek_t dkekinfo; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = NULL; FILE *in = NULL; u8 filebuff[64],key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH],outbuff[64]; char *pwd = NULL; @@ -904,14 +905,14 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch free(pwd); } - EVP_CIPHER_CTX_init(&ctx); - EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_DecryptUpdate(&ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { + ctx = EVP_CIPHER_CTX_new(); + EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); + if (!EVP_DecryptUpdate(ctx, outbuff, &outlen, filebuff + 16, sizeof(filebuff) - 16)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } - if (!EVP_DecryptFinal_ex(&ctx, outbuff + outlen, &r)) { + if (!EVP_DecryptFinal_ex(ctx, outbuff + outlen, &r)) { fprintf(stderr, "Error decrypting DKEK share. Password correct ?\n"); return -1; } @@ -931,7 +932,7 @@ static int print_dkek_share(sc_card_t *card, const char *inf, int iter, const ch printf("\n\n"); OPENSSL_cleanse(&dkekinfo.dkek_share, sizeof(dkekinfo.dkek_share)); - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares fprintf(stderr, "Not supported by card or card not initialized for key share usage\n"); @@ -987,8 +988,8 @@ static void ask_for_password(char **pwd, int *pwdlen) static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int password_shares_threshold, int password_shares_total) { int r, i; - BIGNUM prime; - BIGNUM secret; + BIGNUM *prime; + BIGNUM *secret; unsigned char buf[64]; char hex[64]; int l; @@ -1044,13 +1045,13 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas /* * Initialize prime and secret */ - BN_init(&prime); - BN_init(&secret); + prime = BN_new(); + secret = BN_new(); /* * Encode the secret value */ - BN_bin2bn((unsigned char *)*pwd, *pwdlen, &secret); + BN_bin2bn((unsigned char *)*pwd, *pwdlen, secret); /* * Generate seed and calculate a prime depending on the size of the secret @@ -1063,7 +1064,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas return r; } - r = generatePrime(&prime, &secret, 64, rngseed, SEED_LENGTH); + r = generatePrime(prime, secret, 64, rngseed, SEED_LENGTH); if (r < 0) { printf("Error generating valid prime number. Please try again."); OPENSSL_cleanse(*pwd, *pwdlen); @@ -1074,7 +1075,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas // Allocate data buffer for the generated shares shares = malloc(password_shares_total * sizeof(secret_share_t)); - createShares(&secret, password_shares_threshold, password_shares_total, prime, shares); + createShares(secret, password_shares_threshold, password_shares_total, prime, shares); sp = shares; for (i = 0; i < password_shares_total; i++) { @@ -1087,12 +1088,12 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas printf("Share %i of %i\n\n", i + 1, password_shares_total); - l = BN_bn2bin(&prime, buf); + l = BN_bn2bin(prime, buf); sc_bin_to_hex(buf, l, hex, 64, ':'); printf("\nPrime : %s\n", hex); - printf("Share ID : %s\n", BN_bn2dec(&(sp->x))); - l = BN_bn2bin(&(sp->y), buf); + printf("Share ID : %s\n", BN_bn2dec((sp->x))); + l = BN_bn2bin((sp->y), buf); sc_bin_to_hex(buf, l, hex, 64, ':'); printf("Share value : %s\n", hex); @@ -1106,8 +1107,8 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas cleanUpShares(shares, password_shares_total); - BN_clear_free(&prime); - BN_clear_free(&secret); + BN_clear_free(prime); + BN_clear_free(secret); return 0; } @@ -1116,7 +1117,7 @@ static int generate_pwd_shares(sc_card_t *card, char **pwd, int *pwdlen, int pas static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const char *password, int password_shares_threshold, int password_shares_total) { - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx = NULL; FILE *out = NULL; u8 filebuff[64], key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; u8 dkek_share[32]; @@ -1167,14 +1168,14 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const return -1; } - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, key, iv); - if (!EVP_EncryptUpdate(&ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) { + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv); + if (!EVP_EncryptUpdate(ctx, filebuff + 16, &outlen, dkek_share, sizeof(dkek_share))) { fprintf(stderr, "Error encrypting DKEK share\n"); return -1; } - if (!EVP_EncryptFinal_ex(&ctx, filebuff + 16 + outlen, &r)) { + if (!EVP_EncryptFinal_ex(ctx, filebuff + 16 + outlen, &r)) { fprintf(stderr, "Error encrypting DKEK share\n"); return -1; } @@ -1195,7 +1196,7 @@ static int create_dkek_share(sc_card_t *card, const char *outf, int iter, const fclose(out); OPENSSL_cleanse(filebuff, sizeof(filebuff)); - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); printf("DKEK share created and saved to %s\n", outf); return 0; @@ -1744,9 +1745,16 @@ int main(int argc, char * const argv[]) } } +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS + | OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS, + NULL); +#else CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); +#endif memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 24136fbb..29b75dda 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -33,6 +33,7 @@ #include #include +#include "libopensc/sc-ossl-compat.h" #include "libopensc/opensc.h" #include "libopensc/errors.h" #include "libopensc/pkcs15.h" @@ -102,7 +103,7 @@ static int unlock = 0; static char *get_filename = NULL; static char *put_filename = NULL; -static int do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src) +static int do_convert_bignum(sc_pkcs15_bignum_t *dst, const BIGNUM *src) { if (src == 0) return 0; dst->len = BN_num_bytes(src); @@ -617,7 +618,7 @@ int main(int argc, char *argv[]) goto out; } - rsa->meth = RSA_PKCS1_SSLeay(); + RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); if(!i2d_RSAPrivateKey_bio(mem, rsa)) { @@ -681,9 +682,16 @@ int main(int argc, char *argv[]) r = create_file_cert(card); if(r) goto out; - if (!do_convert_bignum(&dst->modulus, rsa->n) - || !do_convert_bignum(&dst->exponent, rsa->e)) - goto out; + { + const BIGNUM *rsa_n, *rsa_e; + + RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); + + if (!do_convert_bignum(&dst->modulus, rsa_n) + || !do_convert_bignum(&dst->exponent, rsa_e)) + goto out; + + } r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg); if(r) goto out;