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;