Merged [3783:3794/trunk]

git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3795 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2009-10-25 20:22:11 +00:00
parent 56fb57603b
commit 30ab50600b
9 changed files with 534 additions and 243 deletions

View File

@ -25,23 +25,19 @@
#include <string.h>
#include <stdlib.h>
static enum LOAD_KEY {
LOAD_KEY_MODULUS = 0x80,
LOAD_KEY_PUBLIC_EXPONENT = 0x81,
LOAD_KEY_PRIME_P = 0x83,
LOAD_KEY_PRIME_Q = 0x84,
LOAD_KEY_DP1 = 0x85,
LOAD_KEY_DQ1 = 0x86,
LOAD_KEY_INVQ = 0x87
};
#define LOAD_KEY_MODULUS 0x80
#define LOAD_KEY_PUBLIC_EXPONENT 0x81
#define LOAD_KEY_PRIME_P 0x83
#define LOAD_KEY_PRIME_Q 0x84
#define LOAD_KEY_DP1 0x85
#define LOAD_KEY_DQ1 0x86
#define LOAD_KEY_INVQ 0x87
static struct sc_card_operations myeid_ops;
static struct sc_card_driver myeid_drv = {
"MyEID cards with PKCS#15 applet",
"myeid",
&myeid_ops,
NULL, 0, NULL
&myeid_ops
};
static const char *myeid_atrs[] = {
@ -93,6 +89,7 @@ static int myeid_init(struct sc_card *card)
/* State that we have an RNG */
card->caps |= SC_CARD_CAP_RNG;
SC_FUNC_CALLED(card->ctx, 1);
return 0;
}
@ -107,9 +104,9 @@ static int acl_to_byte(const struct sc_acl_entry *e)
case SC_AC_TERM:
case SC_AC_AUT:
if (e->key_ref == SC_AC_KEY_REF_NONE)
return -1;
return 0x00;
if (e->key_ref < 1 || e->key_ref > 14)
return -1;
return 0x00;
return e->key_ref;
case SC_AC_NEVER:
return 0x0F;
@ -182,28 +179,28 @@ static int myeid_select_file(struct sc_card *card, const struct sc_path *in_path
struct sc_file **file)
{
int r;
SC_FUNC_CALLED(card->ctx, 1);
r = iso_ops->select_file(card, in_path, file);
if (r)
return r;
if (file != NULL) {
if (r == 0 && file != NULL) {
parse_sec_attr(*file, (*file)->sec_attr, (*file)->sec_attr_len);
}
return 0;
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_read_binary(struct sc_card *card, unsigned int idx,
u8 * buf, size_t count, unsigned long flags)
{
return iso_ops->read_binary(card, idx, buf, count, flags);
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->read_binary(card, idx, buf, count, flags));
}
static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen)
{
struct sc_apdu apdu;
int r;
int r,i;
SC_FUNC_CALLED(card->ctx, 1);
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0xA1);
apdu.resp = buf;
@ -225,9 +222,10 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
const u8 *tag = NULL;
int r ;
SC_FUNC_CALLED(card->ctx, 1);
r = iso_ops->process_fci(card, file, buf, buflen);
if (r < 0)
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
if(file->type == SC_FILE_EF_UNKNOWN)
{
@ -237,16 +235,23 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
file->type = SC_FILE_TYPE_INTERNAL_EF;
}
}
if(file->sec_attr_len >= 3)
{
sc_debug(card->ctx, "id (%X) sec_attr (%X %X %X) \n", file->id,
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
}
return 0;
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
u8 *out, size_t *outlen)
{
const sc_acl_entry_t *read, *update, *delete;
u8 buf[40];
int i;
SC_FUNC_CALLED(card->ctx, 1);
/* PrivateKey
* 0E0000019 6217 81020400 820111 83024B01 8603000000 85028000 8A0100 RESULT 6984
* 6217 81020400 820111 83024B01 8603000000 85021000 8A0100 */
@ -283,6 +288,41 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
buf[15] = file->sec_attr[0];
buf[16] = file->sec_attr[1];
buf[17] = file->sec_attr[2];
sc_debug(card->ctx, "id (%X), sec_attr %X %X %X\n", file->id,
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
}
else
{
delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
switch (file->type) {
case SC_FILE_TYPE_WORKING_EF:
read = sc_file_get_acl_entry(file, SC_AC_OP_READ);
update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE);
buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update);
buf[16] = (acl_to_byte(delete)<< 4) | 0x0F;
break;
case SC_FILE_TYPE_INTERNAL_EF:
read = sc_file_get_acl_entry(file, SC_AC_OP_CRYPTO);
update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE);
buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update);
buf[16] = (acl_to_byte(delete)<< 4) | 0x0F;
break;
case SC_FILE_TYPE_DF:
update = sc_file_get_acl_entry(file, SC_AC_OP_CREATE);
buf[15] = (acl_to_byte(update) << 4) | acl_to_byte(update);
buf[16] = (acl_to_byte(delete) << 4) | 0x0F;
break;
default:
break;
}
}
/* Proprietary Information */
@ -312,10 +352,10 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
{
buf[25] = 0x84;
buf[26] = (u8)file->namelen;
for(i=0;i < (int)file->namelen;i++)
{
buf[i + 26] = file->name[i];
}
buf[1] = 0x19 + file->namelen + 2;
}
break;
@ -327,7 +367,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
*outlen = buf[1]+2;
memcpy(out, buf, *outlen);
return 0;
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int myeid_create_file(struct sc_card *card, struct sc_file *file)
@ -337,9 +377,12 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file)
size_t buflen;
int r;
SC_FUNC_CALLED(card->ctx, 1);
r = encode_file_structure(card, file, sbuf, &buflen);
if (r)
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
apdu.data = sbuf;
apdu.datalen = buflen;
@ -348,44 +391,48 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file)
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89)
return SC_ERROR_FILE_ALREADY_EXISTS;
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_FILE_ALREADY_EXISTS);
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
SC_TEST_RET(card->ctx, r, "Card returned error");
return 0;
}
/* no record oriented file services */
static int myeid_read_record_unsupp(struct sc_card *card, unsigned int rec_nr,
u8 *buf, size_t count, unsigned long flags)
{
return SC_ERROR_NOT_SUPPORTED;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
static int myeid_wrupd_record_unsupp(struct sc_card *card, unsigned int rec_nr,
const u8 *buf, size_t count, unsigned long flags)
{
return SC_ERROR_NOT_SUPPORTED;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
static int myeid_append_record_unsupp(struct sc_card *card, const u8 *buf,
size_t count, unsigned long flags)
{
return SC_ERROR_NOT_SUPPORTED;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
static int myeid_write_binary(struct sc_card *card, unsigned int idx,
const u8 *buf, size_t count, unsigned long flags)
{
return iso_ops->write_binary(card, idx, buf, count, flags);
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->write_binary(card, idx, buf, count, flags));
}
static int myeid_update_binary(struct sc_card *card, unsigned int idx,
const u8 *buf, size_t count, unsigned long flags)
{
return iso_ops->update_binary(card, idx, buf, count, flags);
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->update_binary(card, idx, buf, count, flags));
}
static int myeid_delete_file(struct sc_card *card, const struct sc_path *path)
@ -408,9 +455,33 @@ static int myeid_delete_file(struct sc_card *card, const struct sc_path *path)
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
return sc_check_sw(card, apdu.sw1, apdu.sw2);
SC_FUNC_RETURN(card->ctx, 1, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
int *tries_left)
{
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "ref (%d), pin1 len(%d), pin2 len (%d)\n",
data->pin_reference, data->pin1.len, data->pin2.len);
if(data->pin1.len > 8 || data->pin2.len > 8)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_PIN_LENGTH);
data->flags |= SC_PIN_CMD_NEED_PADDING;
if(data->cmd == SC_PIN_CMD_VERIFY)
{
u8 buf[8];
memset(buf, 0xFF, sizeof(buf));
memcpy(&buf[0], (u8 *)data->pin1.data, data->pin1.len); /* copy pin*/
data->pin1.data = buf;
data->pin1.len = 8;
}
SC_FUNC_RETURN(card->ctx, 1, iso_ops->pin_cmd(card, data, tries_left));
}
static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env,
int se_num)
@ -421,7 +492,7 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env
int r, locked = 0;
assert(card != NULL && env != NULL);
SC_FUNC_CALLED(card->ctx, 1);
if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC)
{
@ -504,12 +575,14 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env
err:
if (locked)
sc_unlock(card);
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_set_security_env(struct sc_card *card,
const struct sc_security_env *env, int se_num)
{
SC_FUNC_CALLED(card->ctx, 1);
if (env->flags & SC_SEC_ENV_ALG_PRESENT)
{
sc_security_env_t tmp;
@ -543,6 +616,8 @@ static int myeid_compute_signature(struct sc_card *card, const u8 * data,
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
SC_FUNC_CALLED(card->ctx, 1);
assert(card != NULL && data != NULL && out != NULL);
if (datalen > 256)
SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
@ -591,6 +666,8 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
SC_FUNC_CALLED(card->ctx, 1);
assert(card != NULL && crgram != NULL && out != NULL);
SC_FUNC_CALLED(card->ctx, 2);
if (crgram_len > 256)
@ -733,6 +810,7 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len)
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
int r, len;
SC_FUNC_CALLED(card->ctx, 1);
len = 0;
if(value_len == 0 || value == NULL)
return 0;
@ -795,7 +873,6 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len)
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
SC_FUNC_RETURN(card->ctx, 1, r);
}
/* Generate or store a key */
@ -804,8 +881,9 @@ static int myeid_generate_store_key(struct sc_card *card,
{
struct sc_apdu apdu;
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
int r,len;
int r=0,len;
SC_FUNC_CALLED(card->ctx, 1);
/* Setup key-generation paramters */
if (data->op_type == OP_TYPE_GENERATE)
{
@ -831,8 +909,6 @@ static int myeid_generate_store_key(struct sc_card *card,
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
SC_TEST_RET(card->ctx, r, "GENERATE_KEY returned error");
SC_FUNC_RETURN(card->ctx, 1, r);
}
else
{
@ -850,10 +926,10 @@ static int myeid_generate_store_key(struct sc_card *card,
data->mod, data->mod_len)) >= 0 &&
(r=myeid_loadkey(card, LOAD_KEY_PUBLIC_EXPONENT,
data->pubexp, data->pubexp_len)) >= 0)
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
}
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_activate_card(struct sc_card *card)
@ -862,6 +938,7 @@ static int myeid_activate_card(struct sc_card *card)
u8 sbuf[] ="\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35";
sc_apdu_t apdu;
SC_FUNC_CALLED(card->ctx, 1);
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x44, 0x04, 0x00);
apdu.cla = 0x00;
apdu.data = sbuf;
@ -883,6 +960,7 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
sc_apdu_t apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
SC_FUNC_CALLED(card->ctx, 1);
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xA0);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
@ -907,28 +985,38 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
/* copy and return serial number */
memcpy(serial, &card->serialnr, sizeof(*serial));
return SC_SUCCESS;
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
{
int r = SC_ERROR_NOT_SUPPORTED;
SC_FUNC_CALLED(card->ctx, 1);
switch(cmd) {
case SC_CARDCTL_MYEID_PUTDATA:
return myeid_putdata(card,
r = myeid_putdata(card,
(struct sc_cardctl_myeid_data_obj*) ptr);
break;
case SC_CARDCTL_MYEID_GETDATA:
return myeid_getdata(card,
r = myeid_getdata(card,
(struct sc_cardctl_myeid_data_obj*) ptr);
break;
case SC_CARDCTL_MYEID_GENERATE_KEY:
return myeid_generate_store_key(card,
r = myeid_generate_store_key(card,
(struct sc_cardctl_myeid_gen_store_key_info *) ptr);
break;
case SC_CARDCTL_MYEID_ACTIVATE_CARD:
return myeid_activate_card(card);
r = myeid_activate_card(card);
break;
case SC_CARDCTL_GET_SERIALNR:
return myeid_get_serialnr(card, (sc_serial_number_t *)ptr);
r = myeid_get_serialnr(card, (sc_serial_number_t *)ptr);
break;
case SC_CARDCTL_LIFECYCLE_SET:
case SC_CARDCTL_LIFECYCLE_GET:
break;
}
return SC_ERROR_NOT_SUPPORTED;
SC_FUNC_RETURN(card->ctx, 1, r);
}
/* "The PINs are "global" in a PKCS#15 sense, meaning that they remain valid
@ -938,7 +1026,8 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
*/
static int myeid_logout(struct sc_card *card)
{
return 0; /* Can't */
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static struct sc_card_driver * sc_get_driver(void)
@ -968,7 +1057,7 @@ static struct sc_card_driver * sc_get_driver(void)
myeid_ops.logout = myeid_logout;
myeid_ops.process_fci = myeid_process_fci;
myeid_ops.card_ctl = myeid_card_ctl;
myeid_ops.pin_cmd = myeid_pin_cmd;
return &myeid_drv;
}

View File

@ -144,19 +144,12 @@ static int westcos_check_sw(sc_card_t * card, unsigned int sw1,
return iso_ops->check_sw(card, sw1, sw2);
}
typedef struct mon_atr {
size_t len;
int flags;
u8 *atr, *mask;
} mon_atr_t;
static mon_atr_t atrs[] = {
{13, 0x00,
"\x3f\x69\x00\x00\x00\x64\x01\x00\x00\x00\x80\x90\x00",
"\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\xf0\xff\xff"},
{12, JAVACARD,
"\x3b\x95\x94\x80\x1F\xC3\x80\x73\xC8\x21\x13\x54",
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"}
static struct sc_atr_table westcos_atrs[] = {
/* westcos 2ko */
{ "3F:69:00:00:00:64:01:00:00:00:80:90:00", "ff:ff:ff:ff:ff:ff:ff:00:00:00:f0:ff:ff", NULL, 0x00, 0, NULL },
/* westcos applet */
{ "3B:95:94:80:1F:C3:80:73:C8:21:13:54", "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff", NULL, JAVACARD, 0, NULL },
{ NULL, NULL, NULL, 0, 0, NULL }
};
static int westcos_finish(sc_card_t * card)
@ -172,59 +165,35 @@ static int westcos_finish(sc_card_t * card)
static int westcos_match_card(sc_card_t * card)
{
u8 *p, j;
size_t i;
mon_atr_t *matr;
if (card->ctx->debug >= 1)
sc_debug(card->ctx, "westcos_match_card %d, %X:%X:%X\n",
card->atr_len, card->atr[0], card->atr[1],
card->atr[2]);
for (i = 0; i < sizeof(atrs) / sizeof(*atrs); i++) {
matr = &atrs[i];
if (matr->len != card->atr_len)
continue;
p = card->atr;
for (j = 0; j < card->atr_len; j++) {
if (((matr->mask[j]) & (*p)) != (matr->atr[j]))
break;
p++;
if (*p == ':')
p++;
}
if (j >= card->atr_len) {
if (matr->flags & JAVACARD) {
int r;
sc_apdu_t apdu;
u8 aid[] = {
0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01
};
sc_format_apdu(card, &apdu,
SC_APDU_CASE_3_SHORT, 0xA4, 0x04,
0);
apdu.cla = 0x00;
apdu.lc = sizeof(aid);
apdu.datalen = sizeof(aid);
apdu.data = aid;
r = sc_transmit_apdu(card, &apdu);
if (r)
continue;
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (r)
continue;
}
card->drv_data = malloc(sizeof(priv_data_t));
if (card->drv_data == NULL)
return SC_ERROR_OUT_OF_MEMORY;
memset(card->drv_data, 0, sizeof(card->drv_data));
if (matr->flags & JAVACARD) {
priv_data_t *priv_data =
(priv_data_t *) card->drv_data;
priv_data->flags |= JAVACARD;
}
return 1;
}
int i;
i = _sc_match_atr(card, westcos_atrs, &card->type);
if (i < 0)
return 0;
/* JAVACARD, look for westcos applet */
if (i == 1) {
int r;
sc_apdu_t apdu;
u8 aid[] = {
0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01
};
sc_format_apdu(card, &apdu,
SC_APDU_CASE_3_SHORT, 0xA4, 0x04,
0);
apdu.cla = 0x00;
apdu.lc = sizeof(aid);
apdu.datalen = sizeof(aid);
apdu.data = aid;
r = sc_transmit_apdu(card, &apdu);
if (r)
return 0;
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (r)
return 0;
}
return 0;
return 1;
}
static int westcos_init(sc_card_t * card)
@ -232,8 +201,19 @@ static int westcos_init(sc_card_t * card)
int r;
const char *default_key;
unsigned long exponent, flags;
if (card == NULL || card->drv_data == NULL)
if (card == NULL)// || card->drv_data == NULL)
return SC_ERROR_INVALID_ARGUMENTS;
card->drv_data = malloc(sizeof(priv_data_t));
if (card->drv_data == NULL)
return SC_ERROR_OUT_OF_MEMORY;
memset(card->drv_data, 0, sizeof(card->drv_data));
if (card->type & JAVACARD) {
priv_data_t *priv_data =
(priv_data_t *) card->drv_data;
priv_data->flags |= JAVACARD;
}
card->cla = 0x00;
card->max_send_size = 240;
card->max_recv_size = 240;
@ -260,9 +240,9 @@ static int westcos_init(sc_card_t * card)
priv_data_t *priv_data = (priv_data_t *) (card->drv_data);
priv_data->default_key.key_reference = 0;
priv_data->default_key.key_len =
sizeof(priv_data->default_key.key_value);
sizeof(priv_data->default_key.key_value);
r = sc_hex_to_bin(default_key, priv_data->default_key.key_value,
&(priv_data->default_key.key_len));
&(priv_data->default_key.key_len));
if (r)
return (r);
}

View File

@ -488,8 +488,8 @@ typedef struct sc_cardctl_asepcos_activate_file {
typedef struct {
int key_reference;
int key_len; //8, 16 or 24
u8 key_value[24];
size_t key_len; //8, 16 or 24
u8 key_value[24];
}sc_autkey_t;
typedef struct {

View File

@ -32,7 +32,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
{
int i, r;
int modulus_length = 0, usage = 0;
u8 buf[256];
char buf[256];
sc_card_t *card = p15card->card;
sc_context_t *ctx = card->ctx;
sc_serial_number_t serial;

View File

@ -14,8 +14,11 @@
#include <openssl/rsa.h>
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#include <openssl/ec.h>
#include <openssl/conf.h>
#include <openssl/opensslconf.h> /* for OPENSSL_NO_EC */
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif /* OPENSSL_NO_EC */
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */
static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *);
@ -248,7 +251,7 @@ sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits,
return CKR_OK;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
static void reverse(unsigned char *buf, size_t len)
{
@ -328,7 +331,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len,
return CKR_GENERAL_ERROR;
return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
/* If no hash function was used, finish with RSA_public_decrypt().
* If a hash function was used, we can make a big shortcut by
@ -346,11 +349,12 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len,
if (mech == CKM_GOSTR3410)
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
return gostr3410_verify_data(pubkey, pubkey_len,
pubkey_params, pubkey_params_len,
data, data_len, signat, signat_len);
#else
(void)pubkey_params, (void)pubkey_params_len; /* no warning */
return CKR_FUNCTION_NOT_SUPPORTED;
#endif
}

View File

@ -1,20 +1,77 @@
#
# PKCS15 r/w profile for MyEID cards
#
cardinfo {
label = "MyEID";
manufacturer = "Aventra Ltd.";
min-pin-length = 4;
max-pin-length = 8;
pin-encoding = ascii-numeric;
pin-pad-char = 0x00;
pin-pad-char = 0xFF;
}
#
# The following controls some aspects of the PKCS15 we put onto
# the card.
#
pkcs15 {
# Put certificates into the CDF itself?
direct-certificates = no;
# Put the DF length into the ODF file?
encode-df-length = no;
# Have a lastUpdate field in the EF(TokenInfo)?
do-last-update = no;
}
option default {
macros {
#protected = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
#unprotected = READ=NONE, UPDATE=CHV1, DELETE=CHV1;
unusedspace-size = 512;
odf-size = 256;
aodf-size = 384;
cdf-size = 512;
prkdf-size = 1485;
pukdf-size = 1200;
dodf-size = 256;
}
}
# Define reasonable limits for PINs and PUK
# Note that we do not set a file path or reference
# here; that is done dynamically.
PIN user-pin {
reference = 1;
auth-id = 1;
min-length = 4;
max-length = 8;
attempts = 3;
flags = initialized, needs-padding;
}
PIN user-puk {
min-length = 4;
max-length = 8;
attempts = 10;
flags = needs-padding;
}
PIN so-pin {
reference = 2;
auth-id = 2;
min-length = 4;
max-length = 8;
attempts = 4;
flags = initialized, soPin, needs-padding;
}
PIN so-puk {
min-length = 4;
max-length = 8;
attempts = 9;
flags = needs-padding;
}
# Additional filesystem info.
@ -22,32 +79,114 @@ PIN user-puk {
# main profile.
filesystem {
DF MF {
path = 3F00;
type = DF;
acl = DELETE=CHV2; #Erase PIN
# This is the DIR file
EF DIR {
file-id = 2F00;
structure = transparent;
size = 128;
acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
DF PKCS15-AppDF {
type = DF;
file-id = 5015;
acl = DELETE=NONE, CREATE=CHV1;
EF PKCS15-ODF {
file-id = 5031;
structure = transparent;
size = $odf-size;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-TokenInfo {
file-id = 5032;
structure = transparent;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-UnusedSpace {
file-id = 5033;
structure = transparent;
size = $unusedspace-size;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-AODF {
file-id = 4401;
structure = transparent;
size = $aodf-size;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-PrKDF {
file-id = 4402;
structure = transparent;
size = $prkdf-size;
acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-PuKDF {
file-id = 4403;
structure = transparent;
size = $pukdf-size;
acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-CDF {
file-id = 4404;
structure = transparent;
size = $cdf-size;
acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF PKCS15-DODF {
file-id = 4405;
structure = transparent;
size = $dodf-size;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF template-private-key {
type = internal-ef;
file-id = 4B01; # This is the base FileID
size = 266; # 266 is enough for 1024-bit keys
ACL = *=NEVER, CRYPTO=$PIN, UPDATE=$PIN;
file-id = 4B01;
size = 1024;
ACL = CRYPTO=CHV1, UPDATE=CHV1, DELETE=CHV2;
}
EF template-public-key {
structure = transparent;
file-id = 5501;
ACL = *=NEVER, READ=NONE, UPDATE=$PIN;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF template-certificate {
file-id = 4301;
ACL = *=NEVER, READ=NONE, UPDATE=$PIN;
structure = transparent;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
template key-domain {
# This is a dummy entry - pkcs15-init insists that
# this is present
EF private-key {
file-id = 4B00;
type = internal-ef;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF public-key {
file-id = 4300;
structure = transparent;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
# Certificate template
EF certificate {
file-id = 5300;
structure = transparent;
ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2;
}
EF template-extractable-key {
file-id = 7000;
ACL = *=NEVER, READ=$PIN, UPDATE=$PIN;
}
}
}
}
# Define an SO pin
# This PIN is not used yet.
#PIN sopin {
# file = sopinfile;
# reference = 0;
#}

View File

@ -21,6 +21,7 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@ -31,7 +32,7 @@
#include "keycache.h"
#include "profile.h"
#define MYEID_MAX_PINS 5
#define MYEID_MAX_PINS 14
unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01};
#define MYEID_DEFAULT_PUBKEY_LEN sizeof(MYEID_DEFAULT_PUBKEY)
@ -44,7 +45,26 @@ static int myeid_create_pin_internal(sc_profile_t *, sc_card_t *,
int, sc_pkcs15_pin_info_t *, const u8 *, size_t,
const u8 *, size_t);
static int myeid_puk_retries(sc_profile_t *, int);
static int myeid_puk_retries(sc_profile_t *profile, sc_pkcs15_pin_info_t *pin_info);
static int acl_to_byte(const struct sc_acl_entry *e)
{
switch (e->method) {
case SC_AC_NONE:
return 0x00;
case SC_AC_CHV:
case SC_AC_TERM:
case SC_AC_AUT:
if (e->key_ref == SC_AC_KEY_REF_NONE)
return 0x00;
if (e->key_ref < 1 || e->key_ref > MYEID_MAX_PINS)
return 0x00;
return e->key_ref;
case SC_AC_NEVER:
return 0x0F;
}
return 0x00;
}
/*
* Erase the card.
@ -52,17 +72,17 @@ static int myeid_puk_retries(sc_profile_t *, int);
static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card)
{
struct sc_cardctl_myeid_data_obj data_obj;
sc_pkcs15_pin_info_t pin_info;
sc_pkcs15_pin_info_t sopin_info, pin_info;
u8 data[8];
int r;
/* Just delete the entire MF */
SC_FUNC_CALLED(card->ctx, 1);
/* The SO pin has pin reference 1 -- not that it matters much
* because pkcs15-init will ask to enter all pins, even if we
* did a --so-pin on the command line. */
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info);
sc_keycache_set_pin_name(NULL, pin_info.reference, SC_PKCS15INIT_SO_PIN);
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin_info);
/* Select parent DF and verify PINs/key as necessary */
r = sc_pkcs15init_authenticate(profile, card, profile->mf_info->file, SC_AC_OP_DELETE);
@ -71,23 +91,72 @@ static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card)
data[0]= 0xFF;
data[1]= 0xFF;
data[2]= 0x33;
data[2]= 0x11;
data[3]= 0x3F;
data[4]= 0xFF;
data[5]= 0x33;
data[6]= 0x3F;
data[5]= 0x11;
data[6]= 0xFF;
data[7]= 0xFF;
sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &pin_info);
if(pin_info.reference > 0 && pin_info.reference <= MYEID_MAX_PINS &&
sopin_info.reference > 0 && sopin_info.reference <= MYEID_MAX_PINS)
{
data[2] = (pin_info.reference << 4)| pin_info.reference;
data[3] = (sopin_info.reference << 4) | 0x0F;
data[5] = data[2];
}
data_obj.P1 = 0x01;
data_obj.P2 = 0xE0;
data_obj.Data = data;
data_obj.DataLen = 0x08;
sc_debug(card->ctx, "so_pin(%d), user pin (%d)\n",
sopin_info.reference, pin_info.reference);
r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_init_card(sc_profile_t *profile,
sc_card_t *card)
{
struct sc_path path;
sc_file_t *file;
int r;
SC_FUNC_CALLED(card->ctx, 1);
sc_format_path("3F00", &path);
r = sc_select_file(card, &path, NULL);
SC_FUNC_RETURN(card->ctx, 1, r);
}
/*
* Create a DF
*/
static int myeid_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df)
{
int r=0;
struct sc_file *file;
SC_FUNC_CALLED(card->ctx, 1);
if (!profile || !card || !df)
return SC_ERROR_INVALID_ARGUMENTS;
sc_debug(card->ctx, "id (%x)\n",df->id);
if(df->id == 0x5015)
{
sc_debug(card->ctx, "only Select (%x)\n",df->id);
r = sc_select_file(card, &df->path, NULL);
}
SC_FUNC_RETURN(card->ctx, 1, r);
}
/*
* Select the PIN reference
*/
@ -95,20 +164,27 @@ static int myeid_select_pin_reference(sc_profile_t *profile, sc_card_t *card,
sc_pkcs15_pin_info_t *pin_info)
{
sc_pkcs15_pin_info_t pin_info_prof;
int type;
pin_info_prof.reference = 1; /* Default SO PIN ref. */
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info_prof);
/* For the SO pin, we take the first available pin reference = 1 */
SC_FUNC_CALLED(card->ctx, 1);
if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
pin_info->reference = pin_info_prof.reference;
/* sc_pkcs15init_create_pin() starts checking if 0 is an acceptable
* pin reference, which isn't for the myeid cards. And since the
* value 1 has been assigned to the SO pin, we'll jump to 2. */
else if (pin_info->reference == 0)
pin_info->reference = pin_info_prof.reference + 1;
{
type = SC_PKCS15INIT_SO_PIN;
sc_debug(card->ctx, "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)\n",
pin_info->reference,pin_info->tries_left);
}
else
{
type = SC_PKCS15INIT_USER_PIN;
sc_debug(card->ctx, "PIN_FLAG_PIN, ref (%d), tries_left (%d)\n",
pin_info->reference, pin_info->tries_left);
return 0;
}
if (pin_info->reference <= 0 || pin_info->reference > MYEID_MAX_PINS)
pin_info->reference = 1;
SC_FUNC_RETURN(card->ctx, 1, 0);
}
/*
@ -138,6 +214,7 @@ static int myeid_new_file(sc_profile_t *profile, sc_card_t *card,
char name[64], *tag;
int r;
SC_FUNC_CALLED(card->ctx, 1);
if (type == SC_PKCS15_TYPE_PRKEY_RSA)
tag = "private-key";
else if (type == SC_PKCS15_TYPE_PUBKEY_RSA)
@ -178,21 +255,23 @@ static int myeid_new_file(sc_profile_t *profile, sc_card_t *card,
}
*out = file;
return 0;
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int myeid_encode_private_key(sc_profile_t *profile, sc_card_t *card,
struct sc_pkcs15_prkey_rsa *rsa, u8 *key,
size_t *keysize, int key_ref)
{
return 0;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card,
struct sc_pkcs15_prkey_rsa *rsa, u8 *key,
size_t *keysize, int key_ref)
{
return 0;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, 0);
}
/*
@ -232,9 +311,13 @@ 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;
SC_FUNC_CALLED(card->ctx, 1);
/* Parameter check */
if ( (keybits < 1024) || (keybits > 2048) || (keybits & 0X7)) {
sc_debug(card->ctx,
@ -303,7 +386,7 @@ done:
if (prkf)
sc_file_free(prkf);
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
}
/*
@ -314,36 +397,30 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card,
const u8 *pin, size_t pin_len,
const u8 *puk, size_t puk_len)
{
u8 data[19];
u8 data[20];
int so_pin_ref;
int r;
int r,type, puk_tries;
struct sc_cardctl_myeid_data_obj data_obj;
sc_file_t *pinfile = NULL;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n",
pin_info->reference, pin_len, puk_len);
if (pin_info->reference >= MYEID_MAX_PINS)
return SC_ERROR_INVALID_ARGUMENTS;
if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
return SC_ERROR_INVALID_PIN_LENGTH;
/* Verify required access rights if needed (i.e. if the
* pin file isn't in the CREATE life cycle state). */
if (!ignore_ac)
{
/* Re-ink the SO pin to the MF because there is the pin file */
so_pin_ref = sc_keycache_find_named_pin(&profile->df_info->file->path,
SC_PKCS15INIT_SO_PIN);
if (so_pin_ref >= 0)
sc_keycache_set_pin_name(&profile->mf_info->file->path,
so_pin_ref, SC_PKCS15INIT_SO_PIN);
if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
type = SC_PKCS15INIT_SO_PIN;
else
type = SC_PKCS15INIT_USER_PIN;
r = sc_profile_get_file(profile, "pinfile", &pinfile);
if (r >= 0)
r = sc_pkcs15init_authenticate(profile, card, pinfile, SC_AC_OP_UPDATE);
sc_file_free(pinfile);
if (r < 0)
return r;
}
sc_debug(card->ctx, "pin type (%s)\n",
(type == SC_PKCS15INIT_SO_PIN) ? "SO_PIN": "USER_PIN");
memset(data, 0xFF, sizeof(data));
/* Make command to add a pin-record */
data_obj.P1 = 01;
data_obj.P2 = pin_info->reference; /* myeid pin number */
@ -351,40 +428,40 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card,
memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin*/
memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */
/* Optional PIN locking
* data[17] = pin_info->tries_left & 0x0F;
* data[18] = myeid_puk_retries(profile, pin_info->reference) & 0x0F;
*/
data[16] = 0x00;
data[17] = 0x00;
data[18] = 0x00;
data[19] = 0x00; /* FIXME, array is only 0..18 */
data_obj.Data = data;
data_obj.DataLen = 0x10;
data_obj.DataLen = 16;
puk_tries = myeid_puk_retries(profile, pin_info);
if(pin_info->tries_left > 0 && pin_info->tries_left < 15 &&
puk_tries > 0 && puk_tries < 15)
{
/* Optional PIN locking */
data[16] = (pin_info->tries_left & 0x0F);
data[17] = (puk_tries & 0x0F);
data_obj.DataLen = 19;
}
r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);
return r;
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_puk_retries(sc_profile_t *profile, int pin_ref)
static int myeid_puk_retries(sc_profile_t *profile, sc_pkcs15_pin_info_t *pin_info)
{
sc_pkcs15_pin_info_t pin_info;
sc_pkcs15_pin_info_t puk_info;
pin_info.reference = 1; /* Default SO PIN ref. */
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info);
/* If pin_ref is the SO PIN, get the SO PUK info, otherwise the User PUK info */
sc_profile_get_pin_info(profile,
pin_ref == pin_info.reference ?
(pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) ?
SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK,
&pin_info);
&puk_info);
if ((pin_info.tries_left < 0) || (pin_info.tries_left > 15))
return 3; /* Little extra safety */
return pin_info.tries_left;
if ((puk_info.tries_left < 0) || (puk_info.tries_left >= 15))
return -1;
return puk_info.tries_left;
}
/* For Myeid, all objects are files that can be deleted in any order */
@ -392,13 +469,14 @@ static int myeid_delete_object(struct sc_profile *profile,
struct sc_card *card, unsigned int type,
const void *data, const sc_path_t *path)
{
SC_FUNC_CALLED(card->ctx, 1);
return sc_pkcs15init_delete_by_path(profile, card, path);
}
static struct sc_pkcs15init_operations sc_pkcs15init_myeid_operations = {
myeid_erase_card,
NULL, /* init_card */
NULL, /* create_dir */
myeid_init_card, /* init_card */
myeid_create_dir, /* create_dir */
NULL, /* create_domain */
myeid_select_pin_reference,
myeid_create_pin,

View File

@ -268,9 +268,9 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile,
#ifndef ENABLE_OPENSSL
return SC_ERROR_NOT_SUPPORTED;
#else
int r = SC_ERROR_UNKNOWN;
long lg;
char *p;
int r = SC_ERROR_UNKNOWN;
long lg;
u8 *p;
sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
RSA *rsa = NULL;
BIGNUM *bn = NULL;

View File

@ -62,9 +62,7 @@ static int new_pin = 0;
static int debloque = 0;
static char *get_filename = NULL;
static char *get_path = NULL;
static char *put_filename = NULL;
static char *put_path = NULL;
static int do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src)
{
@ -90,7 +88,7 @@ static void print_openssl_erreur(void)
fprintf(stderr, "%s\n", ERR_error_string(r, NULL));
}
static verify_pin(sc_card_t *card, int pin_reference, char *pin_value)
static int verify_pin(sc_card_t *card, int pin_reference, char *pin_value)
{
int r, tries_left = -1;
struct sc_pin_cmd_data data;
@ -117,7 +115,7 @@ static verify_pin(sc_card_t *card, int pin_reference, char *pin_value)
return SC_ERROR_INVALID_ARGUMENTS;
}
data.pin1.data = pin_value;
data.pin1.data = (u8*)pin_value;
data.pin1.len = strlen(pin_value);
}
@ -140,7 +138,7 @@ static verify_pin(sc_card_t *card, int pin_reference, char *pin_value)
return 0;
}
static change_pin(sc_card_t *card,
static int change_pin(sc_card_t *card,
int pin_reference,
char *pin_value1,
char *pin_value2)
@ -170,10 +168,10 @@ static change_pin(sc_card_t *card,
return SC_ERROR_INVALID_ARGUMENTS;
}
data.pin1.data = pin_value1;
data.pin1.data = (u8*)pin_value1;
data.pin1.len = strlen(pin_value1);
data.pin2.data = pin_value2;
data.pin2.data = (u8*)pin_value2;
data.pin2.len = strlen(pin_value2);
}
@ -198,7 +196,7 @@ static change_pin(sc_card_t *card,
return 0;
}
static debloque_pin(sc_card_t *card,
static int debloque_pin(sc_card_t *card,
int pin_reference,
char *puk_value,
char *pin_value)
@ -228,10 +226,10 @@ static debloque_pin(sc_card_t *card,
return SC_ERROR_INVALID_ARGUMENTS;
}
data.pin1.data = puk_value;
data.pin1.data = (u8*)puk_value;
data.pin1.len = strlen(puk_value);
data.pin2.data = pin_value;
data.pin2.data = (u8*)pin_value;
data.pin2.len = strlen(pin_value);
}
@ -351,7 +349,7 @@ int main(int argc, char *argv[])
{
int r;
int i = 1;
u8 *p;
char *p;
int card_presente = 0;
sc_context_param_t ctx_param;
sc_reader_t *lecteur = NULL;
@ -589,7 +587,7 @@ int main(int argc, char *argv[])
pin_cmd.encoding = SC_PIN_ENCODING_GLP;
pin_cmd.len = strlen(pin);
pin_cmd.data = pin;
pin_cmd.data = (u8*)pin;
pin_cmd.max_length = 8;
ck.new_key.key_len = sc_build_pin(ck.new_key.key_value,
@ -613,7 +611,7 @@ int main(int argc, char *argv[])
puk_cmd.encoding = SC_PIN_ENCODING_GLP;
puk_cmd.len = strlen(puk);
puk_cmd.data = puk;
puk_cmd.data = (u8*)puk;
puk_cmd.max_length = 8;
ck.new_key.key_len = sc_build_pin(ck.new_key.key_value,
@ -651,10 +649,11 @@ int main(int argc, char *argv[])
if(keylen)
{
int lg;
size_t lg;
struct sc_pkcs15_pubkey key;
struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa);
u8 *pdata;
memset(&key, 0, sizeof(key));
key.algorithm = SC_ALGORITHM_RSA;
@ -687,7 +686,7 @@ int main(int argc, char *argv[])
#endif
{
fprintf(stderr,
"RSA_generate_key_ex return %d\n", ERR_get_error());
"RSA_generate_key_ex return %ld\n", ERR_get_error());
goto out;
}
@ -696,11 +695,11 @@ int main(int argc, char *argv[])
if(!i2d_RSAPrivateKey_bio(mem, rsa))
{
fprintf(stderr,
"i2d_RSAPrivateKey_bio return %d\n", ERR_get_error());
"i2d_RSAPrivateKey_bio return %ld\n", ERR_get_error());
goto out;
}
lg = BIO_get_mem_data(mem, &p);
lg = BIO_get_mem_data(mem, &pdata);
sc_format_path("0001", &path);
r = sc_select_file(card, &path, NULL);
@ -750,7 +749,7 @@ int main(int argc, char *argv[])
printf("Private key length is %d\n", lg);
printf("Write private key.\n");
r = sc_update_binary(card,0,p,lg,0);
r = sc_update_binary(card,0,pdata,lg,0);
if(r<0) goto out;
printf("Private key correctly written.\n");
@ -761,7 +760,7 @@ int main(int argc, char *argv[])
|| !do_convert_bignum(&dst->exponent, rsa->e))
goto out;
r = sc_pkcs15_encode_pubkey(ctx, &key, &p, &lg);
r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg);
if(r) goto out;
printf("Public key length %d\n", lg);
@ -771,7 +770,7 @@ int main(int argc, char *argv[])
if(r) goto out;
printf("Write public key.\n");
r = sc_update_binary(card,0,p,lg,0);
r = sc_update_binary(card,0,pdata,lg,0);
if(r<0) goto out;
printf("Public key correctly written.\n");
@ -779,9 +778,10 @@ int main(int argc, char *argv[])
if(cert)
{
BIO *bio;
X509 *xp;
BIO *bio;
X509 *xp;
u8 *pdata;
bio = BIO_new(BIO_s_file());
if (BIO_read_filename(bio, cert) <= 0)
{
@ -798,7 +798,7 @@ int main(int argc, char *argv[])
}
else
{
int lg = cert2der(xp, &p);
int lg = cert2der(xp, &pdata);
sc_format_path("0002", &path);
r = sc_select_file(card, &path, NULL);
@ -807,14 +807,14 @@ int main(int argc, char *argv[])
/* FIXME: verifier taille fichier compatible... */
printf("Write certificate %s.\n", cert);
r = sc_update_binary(card,0,p,lg,0);
r = sc_update_binary(card,0,pdata,lg,0);
if(r<0)
{
if(p) free(p);
if(pdata) free(pdata);
goto out;
}
if(xp) X509_free(xp);
if(p) free(p);
if(pdata) free(pdata);
printf("Certificate correctly written.\n");
}
@ -950,5 +950,6 @@ out:
if (ctx)
sc_release_context(ctx);
return EXIT_SUCCESS;
}