Merge [3758:3783/trunk]

git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3785 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2009-10-22 09:18:16 +00:00
parent 95a5ab0654
commit 56fb57603b
25 changed files with 227 additions and 358 deletions

View File

@ -22,14 +22,13 @@ OBJECTS = \
\
ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj \
\
card-westcos.obj crc_AetB.obj \
card-setcos.obj card-miocos.obj card-flex.obj card-gpk.obj \
card-cardos.obj card-tcos.obj card-emv.obj card-default.obj \
card-mcrd.obj card-starcos.obj card-openpgp.obj card-jcop.obj \
card-oberthur.obj card-belpic.obj card-atrust-acos.obj card-entersafe.obj \
card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \
card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \
card-rtecp.obj card-myeid.obj card-ias.obj \
card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \
\
p15emu-westcos.obj \
pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \

View File

@ -538,7 +538,7 @@ static int entersafe_select_path(sc_card_t *card,
const u8 *path=pathbuf;
size_t pathlen=len;
int bMatch = -1;
int i;
unsigned int i;
int r;
if (pathlen%2 != 0 || pathlen > 6 || pathlen <= 0)

View File

@ -40,7 +40,8 @@ static struct sc_card_operations myeid_ops;
static struct sc_card_driver myeid_drv = {
"MyEID cards with PKCS#15 applet",
"myeid",
&myeid_ops
&myeid_ops,
NULL, 0, NULL
};
static const char *myeid_atrs[] = {
@ -202,7 +203,7 @@ static int myeid_read_binary(struct sc_card *card, unsigned int idx,
static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen)
{
struct sc_apdu apdu;
int r,i;
int r;
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0xA1);
apdu.resp = buf;

View File

@ -887,8 +887,6 @@ static int piv_cache_internal_data(sc_card_t *card, int enumtag)
priv->obj_cache[enumtag].internal_obj_data,
priv->obj_cache[enumtag].internal_obj_len);
ok:
SC_FUNC_RETURN(card->ctx, 1, 0);
}
@ -906,8 +904,6 @@ static int piv_read_binary(sc_card_t *card, unsigned int idx,
int r;
u8 *rbuf = NULL;
size_t rbuflen = 0;
u8 *tag;
size_t taglen;
u8 *body;
size_t bodylen;
@ -950,11 +946,6 @@ static int piv_read_binary(sc_card_t *card, unsigned int idx,
if (r < 0)
goto err;
}
if (tag == NULL) {
r = SC_ERROR_OBJECT_NOT_VALID;
goto err;
}
}
priv->rb_state = 0;
@ -1101,7 +1092,7 @@ static int piv_get_3des_key(sc_card_t *card, u8 *key)
int r;
int f = -1;
char keybuf[24*3-1]; /* 3des key as three sets of xx:xx:xx:xx:xx:xx:xx:xx
char keybuf[24*3]; /* 3des key as three sets of xx:xx:xx:xx:xx:xx:xx:xx
* with a : between which is 71 bytes */
char * keyfilename = NULL;
size_t outlen;
@ -1128,6 +1119,7 @@ static int piv_get_3des_key(sc_card_t *card, u8 *key)
}
keybuf[23] = '\0';
keybuf[47] = '\0';
keybuf[71] = '\0';
outlen = 8;
r = sc_hex_to_bin(keybuf, key, &outlen);
if (r) goto err;

View File

@ -138,7 +138,6 @@ static int rutoken_match_card(sc_card_t *card)
static int token_init(sc_card_t *card, const char *card_name)
{
unsigned int flags;
sc_algorithm_info_t info;
SC_FUNC_CALLED(card->ctx, 3);
@ -155,13 +154,6 @@ static int token_init(sc_card_t *card, const char *card_name)
_sc_card_add_rsa_alg(card, 1024, flags, 0);
_sc_card_add_rsa_alg(card, 2048, flags, 0);
memset(&info, 0, sizeof(info));
info.algorithm = SC_ALGORITHM_GOST;
info.flags = SC_ALGORITHM_GOST_CRYPT_PZ | SC_ALGORITHM_GOST_CRYPT_GAMM
| SC_ALGORITHM_GOST_CRYPT_GAMMOS;
info.key_length = 32;
_sc_card_add_algorithm(card, &info);
SC_FUNC_RETURN(card->ctx, 3, SC_SUCCESS);
}

View File

@ -337,7 +337,8 @@ static int tcos_select_file(sc_card_t *card,
sc_apdu_t apdu;
sc_file_t *file=NULL;
u8 buf[SC_MAX_APDU_BUFFER_SIZE], pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
int i, r, pathlen;
unsigned int i;
int r, pathlen;
assert(card != NULL && in_path != NULL);
ctx=card->ctx;
@ -653,7 +654,7 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len,
if (apdu.sw1==0x90 && apdu.sw2==0x00) {
size_t len= (apdu.resplen>outlen) ? outlen : apdu.resplen;
int offset=0;
unsigned int offset=0;
if(tcos3 && (data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) && apdu.resp[0]==0 && apdu.resp[1]==2){
offset=2; while(offset<len && apdu.resp[offset]!=0) ++offset;
offset=(offset<len-1) ? offset+1 : 0;

View File

@ -39,10 +39,6 @@
#define min(a,b) (((a)<(b))?(a):(b))
#endif
#ifndef min
#define max(a,b) (((a)>(b))?(a):(b))
#endif
#define DEFAULT_TRANSPORT_KEY "6f:59:b0:ed:6e:62:46:4a:5d:25:37:68:23:a8:a2:2d"
#define JAVACARD (0x01)
@ -50,7 +46,7 @@
#ifdef ENABLE_OPENSSL
#define DEBUG_SSL
#ifdef DEBUG_SSL
static void print_openssl_erreur(void)
static void print_openssl_error(void)
{
static int charge = 0;
long r;
@ -276,100 +272,11 @@ static int westcos_init(sc_card_t * card)
static int westcos_select_file(sc_card_t * card, const sc_path_t * in_path,
sc_file_t ** file_out)
{
sc_context_t *ctx;
sc_apdu_t apdu;
u8 buf[SC_MAX_APDU_BUFFER_SIZE];
u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
int r, pathlen;
sc_file_t *file = NULL;
priv_data_t *priv_data = NULL;
if (card->ctx->debug >= 1)
sc_debug(card->ctx, "westcos_select_file\n");
if (card == NULL)
return SC_ERROR_INVALID_ARGUMENTS;
priv_data = (priv_data_t *) card->drv_data;
priv_data->file_id = 0;
ctx = card->ctx;
memcpy(path, in_path->value, in_path->len);
pathlen = (int)in_path->len;
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
switch (in_path->type) {
case SC_PATH_TYPE_FILE_ID:
apdu.p1 = 0;
if (pathlen != 2)
return SC_ERROR_INVALID_ARGUMENTS;
break;
case SC_PATH_TYPE_DF_NAME:
apdu.p1 = 4;
break;
case SC_PATH_TYPE_PATH:
apdu.p1 = 9;
if (pathlen == 2 && memcmp(path, "\x3F\x00", 2) == 0) {
apdu.p1 = 0;
}
priv_data_t *priv_data = (priv_data_t *) card->drv_data;
else if (pathlen > 2 && memcmp(path, "\x3F\x00", 2) == 0) {
apdu.p1 = 8;
pathlen -= 2;
memcpy(path, &in_path->value[2], pathlen);
}
break;
case SC_PATH_TYPE_FROM_CURRENT:
apdu.p1 = 9;
break;
case SC_PATH_TYPE_PARENT:
apdu.p1 = 3;
pathlen = 0;
apdu.cse = SC_APDU_CASE_3_SHORT;
break;
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
apdu.p2 = 0; /* first record, return FCI */
apdu.lc = pathlen;
apdu.data = path;
apdu.datalen = pathlen;
if (file_out != NULL) {
apdu.resp = buf;
apdu.resplen = sizeof(buf);
apdu.le = 255;
} else {
apdu.resplen = 0;
apdu.le = 0;
apdu.cse = SC_APDU_CASE_3_SHORT;
}
r = sc_transmit_apdu(card, &apdu);
if (r)
return (r);
if (file_out == NULL) {
if (apdu.sw1 == 0x61)
return 0;
return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (r)
return (r);
switch (apdu.resp[0]) {
case 0x6F:
file = sc_file_new();
if (file == NULL)
return SC_ERROR_OUT_OF_MEMORY;
file->path = *in_path;
if (card->ops->process_fci == NULL) {
sc_file_free(file);
return SC_ERROR_NOT_SUPPORTED;
}
if (apdu.resp[1] <= apdu.resplen)
card->ops->process_fci(card, file, apdu.resp + 2,
apdu.resp[1]);
*file_out = file;
break;
case 0x00: /* proprietary coding */
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
default:
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
return 0;
assert(iso_ops && iso_ops->select_file);
priv_data->file_id = 0;
return iso_ops->select_file(card, in_path, file_out);
}
static int _westcos2opensc_ac(u8 flag)
@ -616,7 +523,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file)
sc_debug(card->ctx, "westcos_create_file\n");
memset(buf, 0, sizeof(buf));
/* clef de transport */
/* transport key */
r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL);
if (r)
return (r);
@ -638,7 +545,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file)
case SC_FILE_TYPE_WORKING_EF:
switch (file->ef_structure) {
case SC_FILE_EF_TRANSPARENT:
buf[0] |= 0x20; /* pas de support transaction */
buf[0] |= 0x20; /* no transaction support */
buf[1] |= 0;
_convertion_ac_methode(file, HIGH, SC_AC_OP_READ,
&buf[2], &buf[2 + 4]);
@ -652,7 +559,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file)
buf[11] = (u8) ((file->size) % 256);
break;
case SC_FILE_EF_LINEAR_FIXED:
buf[0] |= 0x40; /* pas de support transaction */
buf[0] |= 0x40; /* no transaction support */
buf[1] |= 0;
_convertion_ac_methode(file, HIGH, SC_AC_OP_READ,
&buf[2], &buf[2 + 4]);
@ -664,7 +571,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file)
buf[11] = file->record_length;
break;
case SC_FILE_EF_CYCLIC:
buf[0] |= 0x60; /* pas de support transaction */
buf[0] |= 0x60; /* no transaction support */
buf[1] |= 0;
_convertion_ac_methode(file, HIGH, SC_AC_OP_READ,
&buf[2], &buf[2 + 4]);
@ -765,7 +672,9 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key,
u8 * result, size_t * len)
{
int r;
#ifdef ENABLE_OPENSSL
DES_key_schedule ks1, ks2;
#endif
u8 buf[8];
if ((*len) < sizeof(buf))
return SC_ERROR_INVALID_ARGUMENTS;
@ -773,17 +682,21 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key,
r = sc_get_challenge(card, buf, *len);
if (r)
return r;
#ifdef ENABLE_OPENSSL
DES_set_key((const_DES_cblock *) & key[0], &ks1);
DES_set_key((const_DES_cblock *) & key[8], &ks2);
DES_ecb2_encrypt((const_DES_cblock *)buf, (DES_cblock*)result, &ks1, &ks2, DES_ENCRYPT);
return 0;
return SC_SUCCESS;
#else
return SC_ERROR_NOT_SUPPORTED;
#endif
}
static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data,
int *tries_left)
{
int r;
u8 buf[20]; //, result[20];
u8 buf[20];
sc_apdu_t apdu;
size_t len = 0;
int pad = 0, use_pin_pad = 0, ins, p1 = 0;
@ -953,6 +866,7 @@ static int sc_lock_phase(sc_card_t * card, u8 phase)
static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr)
{
unsigned int i;
int r;
size_t buflen;
u8 buf[256];
@ -1088,9 +1002,9 @@ static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr)
memcpy(temp, ck->key_template, sizeof(temp));
westcos_compute_aetb_crc(CRC_A, ck->new_key.key_value,
ck->new_key.key_len, &temp[5], &temp[6]);
for (r = 0, temp[4] = 0xAA, lrc = 0; r < sizeof(temp);
r++)
lrc += temp[r];
for (i = 0, temp[4] = 0xAA, lrc = 0; i < sizeof(temp);
i++)
lrc += temp[i];
temp[4] = (lrc % 256);
buflen = sizeof(buf);
r = westcos_get_crypte_challenge(card,
@ -1172,11 +1086,12 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
priv_data_t *priv_data = NULL;
int pad;
#ifdef ENABLE_OPENSSL
#ifndef ENABLE_OPENSSL
r = SC_ERROR_NOT_SUPPORTED;
#else
RSA *rsa = NULL;
BIO *mem = BIO_new(BIO_s_mem());
#endif
if (card == NULL)
return SC_ERROR_INVALID_ARGUMENTS;
if (card->ctx->debug >= 1)
@ -1186,10 +1101,6 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
r = SC_ERROR_OUT_OF_MEMORY;
goto out;
}
#ifndef ENABLE_OPENSSL
r = SC_ERROR_NOT_SUPPORTED;
#else
if ((priv_data->env.flags) & SC_ALGORITHM_RSA_PAD_PKCS1)
pad = RSA_PKCS1_PADDING;
@ -1220,13 +1131,13 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
BIO_set_mem_eof_return(mem, -1);
if (!d2i_RSAPrivateKey_bio(mem, &rsa)) {
if (card->ctx->debug >= 5)
sc_debug(card->ctx, "RSA clef invalide, %d\n",
sc_debug(card->ctx, "RSA key invalid, %d\n",
ERR_get_error());
r = SC_ERROR_UNKNOWN;
goto out;
}
/* pkcs11 reroute routine cryptage vers la carte */
/* pkcs11 reset openssl functions */
rsa->meth = RSA_PKCS1_SSLeay();
if (RSA_size(rsa) > outlen) {
if (card->ctx->debug >= 5)
@ -1240,7 +1151,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
if (r == -1) {
#ifdef DEBUG_SSL
print_openssl_erreur();
print_openssl_error();
#endif
if (card->ctx->debug >= 5)
@ -1251,13 +1162,13 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
}
}
else { /* signature */
else { /* sign */
r = RSA_private_encrypt(data_len, data, out, rsa, pad);
if (r == -1) {
#ifdef DEBUG_SSL
print_openssl_erreur();
print_openssl_error();
#endif
if (card->ctx->debug >= 5)
@ -1279,15 +1190,12 @@ static int westcos_sign_decipher(int mode, sc_card_t *card,
r = outlen;
#endif
#endif /* ENABLE_OPENSSL */
out:
#ifdef ENABLE_OPENSSL
out:
if (mem)
BIO_free(mem);
if (rsa)
RSA_free(rsa);
#endif
#endif /* ENABLE_OPENSSL */
if (keyfile)
sc_file_free(keyfile);
return r;

View File

@ -515,7 +515,7 @@ typedef struct {
#define SC_RUTOKEN_DO_ALL_MIN_ID 0x1 /* MIN ID value of All DOs */
#define SC_RUTOKEN_DO_CHV_MAX_ID 0x1F /* MAX ID value of CHV-objects */
#define SC_RUTOKEN_DO_NOCHV_MAX_ID 0xFE /* MAX ID value of All Other DOs */
#define SC_RUTOKEN_DO_NOCHV_MAX_ID 0x7F /* MAX ID value of All Other DOs */
/* DO Default Lengths */
#define SC_RUTOKEN_DEF_LEN_DO_GOST 32

View File

@ -427,10 +427,11 @@ void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bu
apdu->data = buffer;
}
int msc_get_challenge(sc_card_t *card, short dataLength, short seedLength, u8 *seedData, u8* outputData)
int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short seedLength, u8 *seedData, u8 *outputData)
{
sc_apdu_t apdu;
int r, location, cse, len;
int r, location, cse;
size_t len;
u8 *buffer, *ptr;
location = (dataLength < MSC_MAX_READ) ? 1 : 2; /* 1 == APDU, 2 == (seed in 0xFFFFFFFE, out in 0xFFFFFFFF) */

View File

@ -54,7 +54,7 @@ void msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t b
int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength, int *tries);
void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength);
int msc_get_challenge(sc_card_t *card, short dataLength, short seedLength, u8 *seedData, u8* outputData);
int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short seedLength, u8 *seedData, u8 *outputData);
int msc_generate_keypair(sc_card_t *card, int privateKey, int publicKey, int algorithm, int keySize, int options);
int msc_extract_rsa_public_key(sc_card_t *card,

View File

@ -158,10 +158,6 @@ extern "C" {
#define SC_ALGORITHM_MD5 128
#define SC_ALGORITHM_SHA1 129
#define SC_ALGORITHM_GOSTR3411 130
/* FIXME: */
/*
#define SC_ALGORITHM_GOSTHASH 130
*/
/* Key derivation algorithms */
#define SC_ALGORITHM_PBKDF2 192
@ -200,11 +196,6 @@ extern "C" {
#define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00008000
#define SC_ALGORITHM_GOSTR3410_HASHES 0x00008000
/* FIXME: */
#define SC_ALGORITHM_GOST_CRYPT_PZ 0x0
#define SC_ALGORITHM_GOST_CRYPT_GAMM 0x1
#define SC_ALGORITHM_GOST_CRYPT_GAMMOS 0x2
/* Event masks for sc_wait_for_event() */
#define SC_EVENT_CARD_INSERTED 0x0001
#define SC_EVENT_CARD_REMOVED 0x0002

View File

@ -41,10 +41,8 @@ static int entersafe_detect_card( sc_pkcs15_card_t *p15card)
static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card)
{
int r, i;
int r;
char buf[256];
sc_path_t path;
sc_file_t *file = NULL;
sc_card_t *card = p15card->card;
sc_serial_number_t serial;

View File

@ -508,6 +508,10 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
struct pcsc_private_data *priv = GET_PRIV_DATA(reader);
struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
int r;
u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE];
size_t rcount;
DWORD i, feature_len, display_ioctl = 0;
PCSC_TLV_STRUCTURE *pcsc_tlv;
r = refresh_slot_attributes(reader, slot);
if (r)

View File

@ -75,6 +75,7 @@ struct pkcs15_cert_object {
#define cert_p15obj base.p15_object
#define cert_pubkey base.related_pubkey
#define cert_issuer base.related_cert
#define cert_prvkey base.related_privkey
struct pkcs15_prkey_object {
struct pkcs15_any_object base;
@ -84,7 +85,6 @@ struct pkcs15_prkey_object {
#define prv_flags base.base.flags
#define prv_p15obj base.p15_object
#define prv_pubkey base.related_pubkey
#define prv_cert base.related_cert
#define prv_next base.related_privkey
struct pkcs15_pubkey_object {
@ -95,7 +95,7 @@ struct pkcs15_pubkey_object {
};
#define pub_flags base.base.flags
#define pub_p15obj base.p15_object
#define pub_cert base.related_cert
#define pub_genfrom base.related_cert
#define __p15_type(obj) (((obj) && (obj)->p15_object)? ((obj)->p15_object->type) : (unsigned int)-1)
#define is_privkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PRKEY_RSA || __p15_type(obj) == SC_PKCS15_TYPE_PRKEY_GOSTR3410)
@ -350,7 +350,7 @@ __pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data,
} else
obj2->pub_data = NULL; /* will copy from cert when cert is read */
obj2->pub_cert = object;
obj2->pub_genfrom = object;
object->cert_pubkey = obj2;
if (cert_object != NULL)
@ -470,6 +470,9 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_
sc_pkcs15_id_t *id = &pk->prv_info->id;
unsigned int i;
sc_debug(context, "Object is a private key and has id %s",
sc_pkcs15_print_id(id));
for (i = 0; i < fw_data->num_objects; i++) {
struct pkcs15_any_object *obj = fw_data->objects[i];
@ -488,18 +491,12 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_
*pp = (struct pkcs15_prkey_object *) obj;
}
} else
if (is_cert(obj) && !pk->prv_cert) {
struct pkcs15_cert_object *cert;
cert = (struct pkcs15_cert_object *) obj;
if (sc_pkcs15_compare_id(&cert->cert_info->id, id))
pk->prv_cert = cert;
} else
if (is_pubkey(obj) && !pk->prv_pubkey) {
struct pkcs15_pubkey_object *pubkey;
pubkey = (struct pkcs15_pubkey_object *) obj;
if (sc_pkcs15_compare_id(&pubkey->pub_info->id, id)) {
sc_debug(context, "Associating object %d as public key", i);
pk->prv_pubkey = pubkey;
if (pk->prv_info->modulus_length == 0)
pk->prv_info->modulus_length = pubkey->pub_info->modulus_length;
@ -511,25 +508,43 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_
static void
__pkcs15_cert_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_object *cert)
{
struct sc_pkcs15_cert *c1 = cert->cert_data, *c2;
struct sc_pkcs15_cert *c1 = cert->cert_data;
sc_pkcs15_id_t *id = &cert->cert_info->id;
unsigned int i;
/* Loop over all certificates see if we find the certificate of
* the issuer */
sc_debug(context, "Object is a certificate and has id %s",
sc_pkcs15_print_id(id));
/* Loop over all objects to see if we find the certificate of
* the issuer and the associated private key */
for (i = 0; i < fw_data->num_objects; i++) {
struct pkcs15_any_object *obj = fw_data->objects[i];
if (!is_cert(obj) || obj == (struct pkcs15_any_object *) cert)
continue;
if (is_cert(obj) && obj != (struct pkcs15_any_object *) cert) {
struct pkcs15_cert_object *cert2;
struct sc_pkcs15_cert *c2;
c2 = ((struct pkcs15_cert_object *) obj)->cert_data;
cert2 = (struct pkcs15_cert_object *) obj;
c2 = cert2->cert_data;
if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len)
continue;
if (c1->issuer_len == c2->subject_len
&& !memcmp(c1->issuer, c2->subject, c1->issuer_len)) {
cert->cert_issuer = (struct pkcs15_cert_object *) obj;
return;
if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len)
continue;
if (c1->issuer_len == c2->subject_len
&& !memcmp(c1->issuer, c2->subject, c1->issuer_len)) {
sc_debug(context, "Associating object %d (id %s) as issuer",
i, sc_pkcs15_print_id(&cert2->cert_info->id));
cert->cert_issuer = (struct pkcs15_cert_object *) obj;
return;
}
} else
if (is_privkey(obj) && !cert->cert_prvkey) {
struct pkcs15_prkey_object *pk;
pk = (struct pkcs15_prkey_object *) obj;
if (sc_pkcs15_compare_id(&pk->prv_info->id, id)) {
sc_debug(context, "Associating object %d as private key", i);
cert->cert_prvkey = pk;
}
}
}
}
@ -547,6 +562,9 @@ pkcs15_bind_related_objects(struct pkcs15_fw_data *fw_data)
if (obj->base.flags & SC_PKCS11_OBJECT_HIDDEN)
continue;
sc_debug(context, "Looking for objects related to object %d", i);
if (is_privkey(obj)) {
__pkcs15_prkey_bind_related(fw_data, (struct pkcs15_prkey_object *) obj);
} else if (is_cert(obj)) {
@ -578,7 +596,7 @@ check_cert_data_read(struct pkcs15_fw_data *fw_data,
/* update the related public key object */
obj2 = cert->cert_pubkey;
obj2->pub_data = (sc_pkcs15_pubkey_t *)calloc(1, sizeof(sc_pkcs15_pubkey_t));
obj2->pub_data = (sc_pkcs15_pubkey_t *)calloc(1, sizeof(sc_pkcs15_pubkey_t));
if (!obj2->pub_data)
return SC_ERROR_OUT_OF_MEMORY;
memcpy(obj2->pub_data, &cert->cert_data->key, sizeof(sc_pkcs15_pubkey_t));
@ -613,6 +631,9 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot,
struct pkcs15_any_object *obj,
CK_OBJECT_HANDLE_PTR pHandle)
{
unsigned int i;
struct pkcs15_fw_data *card_fw_data;
if (obj == NULL
|| (obj->base.flags & (SC_PKCS11_OBJECT_HIDDEN | SC_PKCS11_OBJECT_RECURS)))
return;
@ -632,14 +653,23 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot,
switch (__p15_type(obj)) {
case SC_PKCS15_TYPE_PRKEY_RSA:
if (obj->related_cert == NULL)
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL);
break;
case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
if (obj->related_cert == NULL)
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL);
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);
card_fw_data = (struct pkcs15_fw_data *) slot->card->fw_data;
for (i = 0; i < card_fw_data->num_objects; i++) {
struct pkcs15_any_object *obj2 = card_fw_data->objects[i];
struct pkcs15_cert_object *cert;
if (!is_cert(obj2))
continue;
cert = (struct pkcs15_cert_object*) obj2;
if ((struct pkcs15_any_object*)(cert->cert_prvkey) != obj)
continue;
pkcs15_add_object(slot, obj2, NULL);
}
break;
case SC_PKCS15_TYPE_CERT_X509:
pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);
@ -818,9 +848,14 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card)
for (j=0; j < fw_data->num_objects; j++) {
struct pkcs15_any_object *obj = fw_data->objects[j];
/* "Fake" objects we've generated */
if (__p15_type(obj) == (unsigned int)-1)
continue;
else if (!sc_pkcs15_compare_id(&pin_info->auth_id, &obj->p15_object->auth_id))
/* Some objects have an auth_id even though they are
* not private. Just ignore those... */
if (!(obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE))
continue;
if (!sc_pkcs15_compare_id(&pin_info->auth_id, &obj->p15_object->auth_id))
continue;
if (is_privkey(obj)) {
@ -1020,7 +1055,7 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile);
if (rc < 0) {
sc_lock(p11card->card);
sc_unlock(p11card->card);
return sc_to_cryptoki_error(rc, p11card->reader);
}
@ -1030,8 +1065,8 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
args.pin_len = ulPinLen;
rc = sc_pkcs15init_store_pin(fw_data->p15_card, profile, &args);
sc_lock(p11card->card);
sc_pkcs15init_unbind(profile);
sc_unlock(p11card->card);
if (rc < 0)
return sc_to_cryptoki_error(rc, p11card->reader);
@ -1769,7 +1804,7 @@ static CK_RV pkcs15_set_attrib(struct sc_pkcs11_session *session,
rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile);
if (rc < 0) {
rc = sc_unlock(p11card->card);
sc_unlock(p11card->card);
return sc_to_cryptoki_error(rc, p11card->reader);
}
@ -2000,25 +2035,43 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
unsigned int usage;
size_t len;
/* will use modulus from cert, or pubkey if possible */
if (prkey->prv_cert && prkey->prv_cert->cert_pubkey) {
/* make sure we have read the cert to get modulus etc but only if needed. */
switch(attr->type) {
case CKA_MODULUS:
case CKA_PUBLIC_EXPONENT:
case CKA_MODULUS_BITS:
if (check_cert_data_read(fw_data, prkey->prv_cert) != 0) {
/* no cert found, maybe we have a pub_key */
if (prkey->prv_pubkey && prkey->prv_pubkey->pub_data)
key = prkey->prv_pubkey->pub_data; /* may be NULL */
} else
key = prkey->prv_cert->cert_pubkey->pub_data;
break;
default:
key = prkey->prv_cert->cert_pubkey->pub_data;
/* PKCS#11 requires us to supply CKA_MODULUS for private keys,
* although that is not generally available from a smart card
* (the key is supposed to be safely locked away after all).
*
* To work around this, we hope that we either have an associated
* public key, or we try to find a certificate with the
* corresponding public key.
*
* Note: We do the same thing for CKA_PUBLIC_EXPONENT as some
* applications assume they can get that from the private
* key, something PKCS#11 doesn't guarantee.
*/
if ((attr->type == CKA_MODULUS) || (attr->type == CKA_PUBLIC_EXPONENT)) {
/* First see if we have a associated public key */
if (prkey->prv_pubkey)
key = prkey->prv_pubkey->pub_data;
else {
/* Try to find a certificate with the public key */
unsigned int i;
for (i = 0; i < fw_data->num_objects; i++) {
struct pkcs15_any_object *obj = fw_data->objects[i];
struct pkcs15_cert_object *cert;
if (!is_cert(obj))
continue;
cert = (struct pkcs15_cert_object*) obj;
if (cert->cert_prvkey != prkey)
continue;
if (check_cert_data_read(fw_data, cert) == 0)
key = cert->cert_pubkey->pub_data;
}
}
} else if (prkey->prv_pubkey)
key = prkey->prv_pubkey->pub_data;
}
switch (attr->type) {
case CKA_CLASS:
@ -2053,7 +2106,7 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
break;
case CKA_KEY_TYPE:
check_attribute_buffer(attr, sizeof(CK_KEY_TYPE));
if (key && key->algorithm == SC_ALGORITHM_GOSTR3410)
if (prkey->prv_p15obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410)
*(CK_KEY_TYPE*)attr->pValue = CKK_GOSTR3410;
else
*(CK_KEY_TYPE*)attr->pValue = CKK_RSA;
@ -2157,9 +2210,6 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
case CKM_RSA_X_509:
flags = SC_ALGORITHM_RSA_RAW;
break;
case CKM_OPENSC_GOST: /* FIXME: */
flags = SC_ALGORITHM_GOST;
break;
case CKM_GOSTR3410:
flags = SC_ALGORITHM_GOSTR3410_HASH_NONE;
break;
@ -2235,10 +2285,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
case CKM_RSA_X_509:
flags |= SC_ALGORITHM_RSA_RAW;
break;
case CKM_OPENSC_GOST:
flags |= SC_ALGORITHM_GOST;
default:
return CKR_MECHANISM_INVALID;
return CKR_MECHANISM_INVALID;
}
rv = sc_lock(ses->slot->card->card);
@ -2336,7 +2384,7 @@ static CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session,
CK_ATTRIBUTE_PTR attr)
{
struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;
struct pkcs15_cert_object *cert = pubkey->pub_cert;
struct pkcs15_cert_object *cert = pubkey->pub_genfrom;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fw_data;
size_t len;
@ -2886,22 +2934,6 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card)
}
if (alg_info->algorithm == SC_ALGORITHM_GOSTR3410)
flags |= alg_info->flags;
#if 0 /* FIXME: */
if (alg_info->algorithm == SC_ALGORITHM_GOST){
mech_info.flags = CKF_HW | CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT;
#ifdef ENABLE_OPENSSL
mech_info.flags |= CKF_VERIFY;
#endif
mech_info.ulMinKeySize = 32;
mech_info.ulMaxKeySize = 32;
mt = sc_pkcs11_new_fw_mechanism(CKM_OPENSC_GOST,
&mech_info, CKK_RSA, NULL);
rc = sc_pkcs11_register_mechanism(p11card, mt);
sc_debug(card->ctx, "register GOST!!! %d", rc);
if(rc < 0)
return rc;
}
#endif
alg_info++;
}

View File

@ -175,7 +175,8 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
#if !defined(_WIN32)
pid_t current_pid = getpid();
#endif
int i, rc, rv;
unsigned int i;
int rc, rv;
sc_context_param_t ctx_opts;
/* Handle fork() exception */
@ -323,7 +324,7 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese
CK_ULONG_PTR pulCount) /* receives the number of slots */
{
CK_SLOT_ID_PTR found = NULL;
int i;
unsigned int i;
CK_ULONG numMatches;
sc_pkcs11_slot_t *slot;
CK_RV rv;

View File

@ -3,8 +3,4 @@
/* OpenSC specific extensions */
#define CKK_OPENSC_GOST (CKK_VENDOR_DEFINED+1)
#define CKA_OPENSC_GOST (CKA_VENDOR_DEFINED+1)
#define CKM_OPENSC_GOST (CKM_VENDOR_DEFINED+1)
#endif

View File

@ -264,10 +264,6 @@ sc_keycache_set_pin_name(const sc_path_t *path, int ref, int name)
s = new_entry(path, SC_AC_CHV, ref);
if (s == NULL)
return SC_ERROR_OUT_OF_MEMORY;
s->len = sc_keycache_get_key(path, SC_AC_CHV, -1, s->value, MAX_SECRET);
if(s->len < 0)
return SC_ERROR_OBJECT_NOT_FOUND;
}
/* Set the pin name */

View File

@ -253,7 +253,7 @@ cardos_store_key(sc_profile_t *profile, sc_card_t *card,
sc_pkcs15_prkey_t *key)
{
sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
int algorithm, r;
int algorithm = 0, r;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
sc_debug(card->ctx, "CardOS supports RSA keys only.");
@ -306,7 +306,7 @@ cardos_generate_key(sc_profile_t *profile, sc_card_t *card,
struct sc_cardctl_cardos_genkey_info args;
struct sc_file *temp;
u8 abignum[256];
int algorithm, r, delete_it = 0, use_ext_rsa = 0;
int algorithm = 0, r, delete_it = 0, use_ext_rsa = 0;
size_t keybits, rsa_max_size;
int pin_id = -1;

View File

@ -232,10 +232,7 @@ static int myeid_generate_store_key(sc_profile_t *profile, sc_card_t *card,
sc_pkcs15_prkey_info_t *info)
{
struct sc_cardctl_myeid_gen_store_key_info args;
struct sc_cardctl_myeid_data_obj data_obj;
unsigned char raw_pubkey[256];
int r;
unsigned int mod_len;
sc_file_t *prkf = NULL;
/* Parameter check */
@ -362,7 +359,7 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card,
data[17] = 0x00;
data[18] = 0x00;
data[19] = 0x00;
data[19] = 0x00; /* FIXME, array is only 0..18 */
data_obj.Data = data;
data_obj.DataLen = 0x10;

View File

@ -32,53 +32,16 @@
#include "profile.h"
#ifdef ENABLE_OPENSSL
#include <openssl/opensslv.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#endif
extern int sc_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2);
#if 0
/*
* Get private and public key file
*/
static int _westcos_get_keyfiles(sc_profile_t *profile, sc_card_t *card,
const sc_path_t *df_path,
sc_file_t **prkf, sc_file_t **pukf)
{
sc_path_t path = *df_path;
int r;
/* Get the private key file */
r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &path, prkf);
if (r < 0) {
char pbuf[SC_MAX_PATH_STRING_SIZE];
r = sc_path_print(pbuf, sizeof(pbuf), &path);
if (r != SC_SUCCESS)
pbuf[0] = '\0';
return r;
}
/* Get the public key file */
path.len -= 2;
sc_append_file_id(&path, 0x1012);
r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &path, pukf);
if (r < 0) {
sc_file_free(*prkf);
return r;
}
return 0;
}
#endif /* currently unused */
static int westcos_pkcs15init_init_card(sc_profile_t *profile,
sc_card_t *card)
{
@ -100,7 +63,6 @@ static int westcos_pkcs15init_create_dir(sc_profile_t *profile,
/* Create the application DF */
r = sc_pkcs15init_create_file(profile, card, df);
//if(r) return r;
r = sc_select_file(card, &df->path, NULL);
if(r) return r;
@ -108,19 +70,6 @@ static int westcos_pkcs15init_create_dir(sc_profile_t *profile,
return 0;
}
#if 0
/*
* Create a PIN domain (i.e. a sub-directory holding a user PIN)
*/
static int westcos_pkcs15init_create_domain(sc_profile_t *profile,
sc_card_t *card,
const sc_pkcs15_id_t *id,
sc_file_t **ret)
{
return SC_ERROR_NOT_SUPPORTED; //sc_pkcs15_create_pin_domain(profile, card, id, ret);
}
#endif /* currently unused */
/*
* Select the PIN reference
*/
@ -151,7 +100,7 @@ static int westcos_pkcs15_create_pin(sc_profile_t *profile,
sc_file_t *file = sc_file_new();
sc_path_t path;
if(pin_len>9 || puk_len>9 || pin_len<0 || puk_len<0)
if(pin_len>9 || puk_len>9)
return SC_ERROR_INVALID_ARGUMENTS;
file->type = SC_FILE_TYPE_INTERNAL_EF;
@ -179,8 +128,6 @@ static int westcos_pkcs15_create_pin(sc_profile_t *profile,
if(r) return (r);
}
//r = sc_pkcs15init_create_file(profile, card, file);
if(file)
sc_file_free(file);
@ -308,24 +255,6 @@ static int westcos_pkcs15init_store_key(sc_profile_t *profile,
sc_pkcs15_prkey_t *key)
{
return SC_ERROR_NOT_SUPPORTED;
#if 0
int r;
sc_file_t *keyfile;
sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
return SC_ERROR_NOT_SUPPORTED;
}
r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &key_info->path, &keyfile);
if (r < 0) return r;
//r = sc_pkcs15init_update_file(profile, card, keyfile, &key->der.data, &key->der.len);
//sc_file_free(keyfile);
return r;
#endif
}
/*
@ -336,41 +265,56 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile,
sc_pkcs15_object_t *obj,
sc_pkcs15_pubkey_t *pubkey)
{
int r = SC_ERROR_UNKNOWN;
#ifndef ENABLE_OPENSSL
return SC_ERROR_NOT_SUPPORTED;
#else
int r = SC_ERROR_UNKNOWN;
long lg;
char *p;
sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
#ifdef ENABLE_OPENSSL
RSA *rsa = RSA_new();
BIGNUM *bn = BN_new();
BIO *mem = BIO_new(BIO_s_mem());
#endif
RSA *rsa = NULL;
BIGNUM *bn = NULL;
BIO *mem = NULL;
#ifndef ENABLE_OPENSSL
r = SC_ERROR_NOT_SUPPORTED;
#else
sc_file_t *prkf = NULL;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
return SC_ERROR_NOT_SUPPORTED;
}
if(/*keyfile == NULL ||*/ rsa == NULL || bn == NULL || mem == NULL)
#if OPENSSL_VERSION_NUMBER>=0x00908000L
rsa = RSA_new();
bn = BN_new();
mem = BIO_new(BIO_s_mem());
if(rsa == NULL || bn == NULL || mem == NULL)
{
r = SC_ERROR_OUT_OF_MEMORY;
goto out;
}
/* pkcs11 re-route routine cryptage vers la carte fixe default to use openssl */
rsa->meth = RSA_PKCS1_SSLeay();
if(!BN_set_word(bn, RSA_F4) ||
!RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL))
#else
mem = BIO_new(BIO_s_mem());
if(mem == NULL)
{
r = SC_ERROR_OUT_OF_MEMORY;
goto out;
}
rsa = RSA_generate_key(key_info->modulus_length, RSA_F4, NULL, NULL);
if (!rsa)
#endif
{
r = SC_ERROR_UNKNOWN;
goto out;
}
rsa->meth = RSA_PKCS1_SSLeay();
if(pubkey != NULL)
{
if(!i2d_RSAPublicKey_bio(mem, rsa))
@ -386,7 +330,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile,
r = sc_pkcs15_decode_pubkey(card->ctx, pubkey, p, lg);
}
BIO_reset(mem);
(void) BIO_reset(mem);
if(!i2d_RSAPrivateKey_bio(mem, rsa))
{
@ -421,9 +365,9 @@ out:
RSA_free(rsa);
if(prkf)
sc_file_free(prkf);
#endif
return r;
#endif
}
static int westcos_pkcs15init_finalize_card(sc_card_t *card)

View File

@ -28,7 +28,7 @@ pkcs15 {
# Default settings.
# This option block will always be processed.
option default_32k {
option default {
macros {
ti-size = 128;
odf-size = 128;
@ -43,8 +43,7 @@ option default_32k {
# This option is for cards with very little memory.
# It sets the size of various PKCS15 directory files
# to 128 or 256, respectively.
#option small {
option default {
option small {
macros {
ti-size = 64;
odf-size = 128;

View File

@ -1563,7 +1563,7 @@ static int do_asn1(int argc, char **argv)
goto err;
}
if ((size_t)r != len) {
printf("expecting %d, got only %d bytes.\n", len, r);
printf("expecting %ld, got only %d bytes.\n", len, r);
goto err;
}

View File

@ -3579,7 +3579,6 @@ static struct mech_info p11_mechanisms[] = {
{ CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL },
{ CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL },
{ CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL },
{ CKM_OPENSC_GOST, "GOST", NULL },
{ NO_MECHANISM, NULL, NULL }
};

View File

@ -51,7 +51,7 @@ int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
return 1;
}
if (reader_id < 0) {
int i;
unsigned int i;
/* Automatically try to skip to a reader with a card if reader not specified */
for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) {
reader = sc_ctx_get_reader(ctx, i);

View File

@ -32,6 +32,7 @@
#include <opensc/pkcs15.h>
#include <opensc/cardctl.h>
#include <openssl/opensslv.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -358,15 +359,9 @@ int main(int argc, char *argv[])
sc_context_t *ctx = NULL;
sc_file_t *file = NULL;
sc_path_t path;
RSA *rsa = RSA_new();
BIGNUM *bn = BN_new();
BIO *mem = BIO_new(BIO_s_mem());
if(rsa == NULL || bn == NULL || mem == NULL)
{
fprintf(stderr,"Not enougth memory.\n");
goto out;
}
RSA *rsa = NULL;
BIGNUM *bn = NULL;
BIO *mem = NULL;
while(i<argc)
{
@ -665,8 +660,31 @@ int main(int argc, char *argv[])
printf("Generate key of length %d.\n", keylen);
#if OPENSSL_VERSION_NUMBER>=0x00908000L
rsa = RSA_new();
bn = BN_new();
mem = BIO_new(BIO_s_mem());
if(rsa == NULL || bn == NULL || mem == NULL)
{
fprintf(stderr,"Not enougth memory.\n");
goto out;
}
if(!BN_set_word(bn, RSA_F4) ||
!RSA_generate_key_ex(rsa, keylen, bn, NULL))
#else
rsa = RSA_generate_key(keylen, RSA_F4, NULL, NULL);
mem = BIO_new(BIO_s_mem());
if(mem == NULL)
{
fprintf(stderr,"Not enougth memory.\n");
goto out;
}
if (!rsa)
#endif
{
fprintf(stderr,
"RSA_generate_key_ex return %d\n", ERR_get_error());