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
This commit is contained in:
Doug Engert 2016-01-06 08:40:59 -06:00
parent 44694a0cf3
commit 5fb4db6373
29 changed files with 955 additions and 402 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -39,8 +39,11 @@
#include "cwa-dnie.h"
#include <openssl/ossl_typ.h>
#include <openssl/bn.h>
#include <openssl/x509.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#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)

View File

@ -36,6 +36,8 @@
#include "opensc.h"
#include "cardctl.h"
#include "internal.h"
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/x509.h>
#include <openssl/des.h>
#include <openssl/rand.h>
@ -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;

View File

@ -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

View File

@ -25,6 +25,7 @@
#ifdef ENABLE_OPENSSL /* empty file without openssl */
#include <string.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
@ -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; */

View File

@ -30,17 +30,25 @@
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef ENABLE_OPENSSL
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#endif
#include "internal.h"
#include "pkcs15.h"
#include "log.h"
#include "cards.h"
#include "itacns.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "common/compat_strlcpy.h"
#include "common/compat_strlcat.h"
#ifdef ENABLE_OPENSSL
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#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);

View File

@ -27,16 +27,15 @@
#include <stdio.h>
#include <assert.h>
#include "internal.h"
#include "asn1.h"
#include "pkcs15.h"
#include "common/compat_strlcpy.h"
#include "aux-data.h"
#ifdef ENABLE_OPENSSL
#include <openssl/opensslv.h>
#include <openssl/bn.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
@ -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;
}

View File

@ -34,11 +34,8 @@
#include <unistd.h>
#endif
#include "internal.h"
#include "asn1.h"
#include "pkcs15.h"
#ifdef ENABLE_OPENSSL
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
@ -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;
}

View File

@ -0,0 +1,240 @@
/*
* sc-ossl-compat.h: OpenSC ecompatability for older OpenSSL versions
*
* Copyright (C) 2016 Douglas E. Engert <deengert@gmail.com>
*
* 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 <openssl/opensslv.h>
#include <openssl/opensslconf.h>
/*
* 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 <openssl/bn.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#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 */

View File

@ -9,6 +9,7 @@
#ifdef ENABLE_OPENSSL /* empty file without openssl */
#include <string.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
@ -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();

View File

@ -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

View File

@ -27,12 +27,13 @@
#include <sys/types.h>
#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:

View File

@ -20,20 +20,15 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pkcs15-oberthur.h"
#include <sys/types.h>
#include <ctype.h>
#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"

View File

@ -9,6 +9,7 @@
#include "config.h"
#ifdef ENABLE_OPENSSL
#include <openssl/opensslv.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -18,6 +19,10 @@
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>
#include "profile.h"
#include "libopensc/opensc.h"
#define COSM_TLV_TAG 0x00
#define TLV_TYPE_V 0

View File

@ -26,6 +26,7 @@
#ifdef ENABLE_OPENSSL
#include <openssl/opensslv.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -33,6 +34,7 @@
#include <openssl/bio.h>
#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)
{

View File

@ -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;

View File

@ -36,6 +36,7 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#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();

View File

@ -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");

View File

@ -45,6 +45,7 @@
#include <openssl/err.h>
#include <openssl/obj_mac.h>
#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);

View File

@ -37,12 +37,15 @@
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#include <openssl/opensslconf.h>
#include <openssl/crypto.h>
#endif
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
#include <openssl/conf.h>
#endif
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/asn1t.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
@ -53,6 +56,7 @@
#include <openssl/err.h>
#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;
}

View File

@ -52,6 +52,7 @@
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#include <openssl/crypto.h>
#include <openssl/opensslconf.h> /* for OPENSSL_NO_EC */
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
@ -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)

View File

@ -32,6 +32,8 @@
#include <sys/stat.h>
/* Requires openssl for dkek import */
#include <openssl/opensslv.h>
#include <openssl/opensslconf.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
@ -39,6 +41,7 @@
#include <openssl/rand.h>
#include <openssl/err.h>
#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;

View File

@ -33,6 +33,7 @@
#include <openssl/x509v3.h>
#include <openssl/bn.h>
#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;