Oberthur pkcs15init: update Oberthur's 'token info' file

when initializing token or creating user PIN


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3808 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
viktor.tarasov 2009-11-07 19:38:15 +00:00
parent 004f23f102
commit 8681d963ab
2 changed files with 195 additions and 112 deletions

View File

@ -423,12 +423,14 @@ typedef struct sc_pkcs15_card {
char *preferred_language;
} sc_pkcs15_card_t;
#define SC_PKCS15_CARD_FLAG_READONLY 0x01
#define SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED 0x02
#define SC_PKCS15_CARD_FLAG_PRN_GENERATION 0x04
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
#define SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT 0x10
#define SC_PKCS15_CARD_FLAG_EMULATED 0x20
#define SC_PKCS15_CARD_FLAG_READONLY 0x01
#define SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED 0x02
#define SC_PKCS15_CARD_FLAG_PRN_GENERATION 0x04
#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08
#define SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT 0x10
#define SC_PKCS15_CARD_FLAG_EMULATED 0x20
#define SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED 0x40
#define SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED 0x80
/* sc_pkcs15_bind: Binds a card object to a PKCS #15 card object
* and initializes a new PKCS #15 card object. Will return

View File

@ -46,8 +46,8 @@
#define COSM_TITLE "OberthurAWP"
#define TLV_TYPE_V 0
#define TLV_TYPE_LV 1
#define TLV_TYPE_V 0
#define TLV_TYPE_LV 1
#define TLV_TYPE_TLV 2
/* Should be greater then SC_PKCS15_TYPE_CLASS_MASK */
@ -56,13 +56,95 @@
#define COSM_TYPE_PRKEY_RSA (SC_DEVICE_SPECIFIC_TYPE | SC_PKCS15_TYPE_PRKEY_RSA)
#define COSM_TYPE_PUBKEY_RSA (SC_DEVICE_SPECIFIC_TYPE | SC_PKCS15_TYPE_PUBKEY_RSA)
#define COSM_TOKEN_FLAG_PRN_GENERATION 0x01
#define COSM_TOKEN_FLAG_LOGIN_REQUIRED 0x04
#define COSM_TOKEN_FLAG_USER_PIN_INITIALIZED 0x08
#define COSM_TOKEN_FLAG_TOKEN_INITIALIZED 0x0400
static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card,
static int cosm_create_reference_data(struct sc_profile *, struct sc_card *,
struct sc_pkcs15_pin_info *,
const unsigned char *pin, size_t pin_len,
const unsigned char *puk, size_t puk_len);
static int cosm_update_pin(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_pin_info *info, const unsigned char *pin, size_t pin_len,
const unsigned char *puk, size_t puk_len);
int cosm_delete_file(sc_card_t *card, struct sc_profile *profile,
sc_file_t *df);
int cosm_delete_file(struct sc_card *card, struct sc_profile *profile,
struct sc_file *df);
static int
cosm_write_tokeninfo (struct sc_card *card, struct sc_profile *profile,
char *label, unsigned p15_flags)
{
struct sc_file *file = NULL;
unsigned mask = SC_PKCS15_CARD_FLAG_PRN_GENERATION
| SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED
| SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED
| SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED;
int rv, sz, flags = 0;
char *buffer = NULL;
if (!card || !profile)
return SC_ERROR_INVALID_ARGUMENTS;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "cosm_write_tokeninfo() label '%s'; flags 0x%X\n", label, p15_flags);
if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file))
SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find "COSM_TITLE"-token-info");
if (file->size < 16)
SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Unsufficient size of the "COSM_TITLE"-token-info file");
buffer = calloc(1, file->size);
if (!buffer)
SC_TEST_RET(card->ctx, SC_ERROR_MEMORY_FAILURE, "Allocation error in cosm_write_tokeninfo()");
if (label)
strncpy(buffer, label, file->size - 4);
else if (profile->p15_data && profile->p15_data->label)
snprintf(buffer, file->size - 4, profile->p15_data->label);
else if (profile->p15_spec && profile->p15_spec->label)
snprintf(buffer, file->size - 4, profile->p15_spec->label);
else
snprintf(buffer, file->size - 4, "OpenSC-Token");
sz = strlen(buffer);
if (sz < file->size - 4)
memset(buffer + sz, ' ', file->size - sz);
if (p15_flags & SC_PKCS15_CARD_FLAG_PRN_GENERATION)
flags |= COSM_TOKEN_FLAG_PRN_GENERATION;
if (p15_flags & SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED)
flags |= COSM_TOKEN_FLAG_LOGIN_REQUIRED;
if (p15_flags & SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED)
flags |= COSM_TOKEN_FLAG_USER_PIN_INITIALIZED;
if (p15_flags & SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED)
flags |= COSM_TOKEN_FLAG_TOKEN_INITIALIZED;
sc_debug(card->ctx, "cosm_write_tokeninfo() token label '%s'; oberthur flags 0x%X\n", buffer, flags);
memset(buffer + file->size - 4, 0, 4);
*(buffer + file->size - 1) = flags & 0xFF;
*(buffer + file->size - 2) = (flags >> 8) & 0xFF;
rv = sc_pkcs15init_update_file(profile, card, file, buffer, file->size);
if (rv > 0)
rv = 0;
if (profile->p15_data)
profile->p15_data->flags = (profile->p15_data->flags & ~mask) | p15_flags;
if (profile->p15_spec)
profile->p15_spec->flags = (profile->p15_spec->flags & ~mask) | p15_flags;
free(buffer);
SC_FUNC_RETURN(card->ctx, 1, rv);
}
static int
cosm_update_pukfile (struct sc_card *card, struct sc_profile *profile,
@ -137,9 +219,9 @@ cosm_delete_file(struct sc_card *card, struct sc_profile *profile,
* Erase the card
*/
static int
cosm_erase_card(struct sc_profile *profile, sc_card_t *card)
cosm_erase_card(struct sc_profile *profile, struct sc_card *card)
{
sc_file_t *df = profile->df_info->file, *dir;
struct sc_file *df = profile->df_info->file, *dir;
int rv;
SC_FUNC_CALLED(card->ctx, 1);
@ -199,14 +281,14 @@ done:
* Initialize the Application DF
*/
static int
cosm_init_app(struct sc_profile *profile, sc_card_t *card,
cosm_init_app(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_pin_info *pinfo,
const unsigned char *pin, size_t pin_len,
const unsigned char *pin, size_t pin_len,
const unsigned char *puk, size_t puk_len)
{
int rv;
struct sc_file *file = NULL;
size_t ii;
sc_file_t *file = NULL;
int rv;
static const char *create_dfs[] = {
COSM_TITLE"-AppDF",
"private-DF",
@ -227,7 +309,7 @@ cosm_init_app(struct sc_profile *profile, sc_card_t *card,
};
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "pin_len %i; puk_len %i\n", pin_len, puk_len);
sc_debug(card->ctx, "cosm_init_app() pin_len %i; puk_len %i\n", pin_len, puk_len);
/* Oberthur AWP file system is expected.*/
/* Create private objects DF */
@ -241,15 +323,34 @@ cosm_init_app(struct sc_profile *profile, sc_card_t *card,
sc_debug(card->ctx, "rv %i\n", rv);
sc_file_free(file);
if (rv && rv!=SC_ERROR_FILE_ALREADY_EXISTS)
SC_TEST_RET(card->ctx, rv, "sc_pkcs15init_create_file() failed");
SC_TEST_RET(card->ctx, rv, "cosm_init_app() sc_pkcs15init_create_file failed");
}
SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS);
rv = cosm_write_tokeninfo(card, profile, NULL,
SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED | SC_PKCS15_CARD_FLAG_PRN_GENERATION);
if (pin && pin_len) {
/* Create local SOPIN */
struct sc_pkcs15_pin_info pin_info;
sc_profile_get_file(profile, COSM_TITLE"-AppDF", &file);
pin_info.flags = SC_PKCS15_PIN_FLAG_SO_PIN;
pin_info.reference = 4;
memcpy(&pin_info.path, &file->path, sizeof(pin_info.path));
sc_file_free(file);
rv = cosm_create_reference_data(profile, card, &pin_info, pin, pin_len, NULL, 0);
SC_TEST_RET(card->ctx, rv, "cosm_init_app() cosm_update_pin failed");
}
SC_FUNC_RETURN(card->ctx, 1, rv);
}
static int
cosm_create_reference_data(struct sc_profile *profile, sc_card_t *card,
cosm_create_reference_data(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_pin_info *pinfo,
const unsigned char *pin, size_t pin_len,
const unsigned char *puk, size_t puk_len )
@ -270,9 +371,14 @@ cosm_create_reference_data(struct sc_profile *profile, sc_card_t *card,
rv = sc_select_file(card, &pinfo->path, NULL);
SC_TEST_RET(card->ctx, rv, "Cannot select file");
sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_pin);
if (pinfo->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &profile_pin);
else
sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_pin);
if (profile_pin.max_length > 0x100)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCONSISTENT_PROFILE);
SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Invalid (SO)PIN profile settings");
if (puk) {
int ii, jj;
@ -332,42 +438,48 @@ cosm_create_reference_data(struct sc_profile *profile, sc_card_t *card,
* Update PIN
*/
static int
cosm_update_pin(struct sc_profile *profile, sc_card_t *card,
cosm_update_pin(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_pin_info *pinfo, const unsigned char *pin, size_t pin_len,
const unsigned char *puk, size_t puk_len )
{
int rv;
int tries_left = -1;
int rv, tries_left = -1;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "ref %i; flags %X\n", pinfo->reference, pinfo->flags);
if (pinfo->flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
sc_error(card->ctx,"Pin references should be only in the profile"
"and in the card-oberthur.\n");
if (pinfo->reference != 4)
return SC_ERROR_INVALID_PIN_REFERENCE;
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "cosm_update_pin() invalid SOPIN reference");
rv = sc_change_reference_data(card, SC_AC_CHV, pinfo->reference, puk, puk_len,
pin, pin_len, &tries_left);
sc_debug(card->ctx, "return value %X; tries left %i\n", rv, tries_left);
if (tries_left != -1)
sc_error(card->ctx, "Failed to change reference data for soPin: rv %X", rv);
SC_TEST_RET(card->ctx, rv, "cosm_update_pin() failed to change SOPIN");
if (tries_left != -1)
SC_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "cosm_update_pin() failed to change SOPIN");
}
else {
rv = cosm_create_reference_data(profile, card, pinfo,
pin, pin_len, puk, puk_len);
SC_TEST_RET(card->ctx, rv, "cosm_update_pin() failed to change PIN");
rv = cosm_write_tokeninfo(card, profile, NULL,
SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED
| SC_PKCS15_CARD_FLAG_PRN_GENERATION
| SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED
| SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED);
SC_TEST_RET(card->ctx, rv, "cosm_update_pin() failed to update tokeninfo");
}
SC_FUNC_RETURN(card->ctx, 1, rv);
}
static int
cosm_select_pin_reference(sc_profile_t *profile, sc_card_t *card,
sc_pkcs15_pin_info_t *pin_info)
cosm_select_pin_reference(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_pin_info *pin_info)
{
sc_file_t *pinfile;
struct sc_file *pinfile;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "ref %i; flags %X\n", pin_info->reference, pin_info->flags);
@ -392,26 +504,25 @@ cosm_select_pin_reference(sc_profile_t *profile, sc_card_t *card,
SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS);
}
/*
* Store a PIN
*/
static int
cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df,
cosm_create_pin(struct sc_profile *profile, struct sc_card *card, struct sc_file *df,
struct sc_pkcs15_object *pin_obj,
const unsigned char *pin, size_t pin_len,
const unsigned char *puk, size_t puk_len)
{
sc_pkcs15_pin_info_t *pinfo = (sc_pkcs15_pin_info_t *) pin_obj->data;
sc_file_t *pinfile;
struct sc_pkcs15_pin_info *pinfo = (struct sc_pkcs15_pin_info *) pin_obj->data;
struct sc_file *pinfile;
int rv = 0, type;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "ref %i; flags %X\n", pinfo->reference, pinfo->flags);
if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) {
sc_error(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF");
return SC_ERROR_INCONSISTENT_PROFILE;
}
if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0)
SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "\""COSM_TITLE"-AppDF\" not defined");
pinfo->path = pinfile->path;
sc_file_free(pinfile);
@ -419,22 +530,20 @@ cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df,
type = SC_PKCS15INIT_SO_PIN;
if (pinfo->reference != 4)
return SC_ERROR_INVALID_ARGUMENTS;
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid SOPIN reference");
}
else {
type = SC_PKCS15INIT_USER_PIN;
if (pinfo->reference !=1 && pinfo->reference != 2)
return SC_ERROR_INVALID_PIN_REFERENCE;
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid PIN reference");
}
if (pin && pin_len) {
rv = cosm_update_pin(profile, card, pinfo, pin, pin_len, puk, puk_len);
SC_TEST_RET(card->ctx, rv, "Update PIN failed");
}
else {
sc_debug(card->ctx, "User PIN not updated");
}
sc_keycache_set_pin_name(&pinfo->path, pinfo->reference, type);
pinfo->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL;
@ -446,15 +555,15 @@ cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df,
* Allocate a file
*/
static int
cosm_new_file(struct sc_profile *profile, sc_card_t *card,
unsigned int type, unsigned int num, sc_file_t **out)
cosm_new_file(struct sc_profile *profile, struct sc_card *card,
unsigned int type, unsigned int num, struct sc_file **out)
{
struct sc_file *file;
const char *_template = NULL, *desc = NULL;
unsigned int structure = 0xFFFFFFFF;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "type %X; num %i\n",type, num);
sc_debug(card->ctx, "cosm_new_file() type %X; num %i\n",type, num);
while (1) {
switch (type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
@ -500,11 +609,11 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card,
type &= SC_PKCS15_TYPE_CLASS_MASK;
}
sc_debug(card->ctx, "template %s; num %i\n",_template, num);
sc_debug(card->ctx, "cosm_new_file() template %s; num %i\n",_template, num);
if (sc_profile_get_file(profile, _template, &file) < 0) {
sc_error(card->ctx, "Profile doesn't define %s template '%s'\n",
desc, _template);
return SC_ERROR_NOT_SUPPORTED;
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
file->id |= (num & 0xFF);
@ -513,7 +622,7 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card,
file->ef_structure = structure;
}
sc_debug(card->ctx, "file size %i; ef type %i/%i; id %04X\n",file->size,
sc_debug(card->ctx, "cosm_new_file() file size %i; ef type %i/%i; id %04X\n",file->size,
file->type, file->ef_structure, file->id);
*out = file;
@ -525,9 +634,9 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card,
* RSA key generation
*/
static int
cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card,
cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card,
unsigned int idx, unsigned int keybits,
sc_pkcs15_pubkey_t *pubkey,
struct sc_pkcs15_pubkey *pubkey,
struct sc_pkcs15_prkey_info *info)
{
struct sc_cardctl_oberthur_genkey_info args;
@ -536,17 +645,15 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card,
int rv;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "index %i; nn %i\n", idx, keybits);
sc_debug(card->ctx, "cosm_generate_key() index %i; nn %i\n", idx, keybits);
if (keybits < 512 || keybits > 2048 || (keybits%0x20)) {
sc_error(card->ctx, "Unsupported key size %u\n", keybits);
return SC_ERROR_INVALID_ARGUMENTS;
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size");
}
/* Get private key file from profile. */
if ((rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx,
&prkf)) < 0)
goto failed;
sc_debug(card->ctx, "prv ef type 0x%X\n",prkf->ef_structure);
rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &prkf);
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() cannot allocate new file SC_PKCS15_TYPE_PRKEY_RSA");
prkf->size = keybits;
/* Access condition of private object DF. */
@ -554,27 +661,21 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card,
path.len -= 2;
rv = sc_select_file(card, &path, &tmpf);
SC_TEST_RET(card->ctx, rv, "Generate RSA: no private object DF");
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() no private object DF");
rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CRYPTO);
sc_debug(card->ctx, "rv %i\n",rv);
if (rv < 0)
goto failed;
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed");
rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CREATE);
sc_debug(card->ctx, "rv %i\n",rv);
if (rv < 0)
goto failed;
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() pkcs15init_authenticate(SC_AC_OP_CREATE) failed");
sc_file_free(tmpf);
/* In the private key DF create the temporary public RSA file. */
sc_debug(card->ctx, "ready to create public key\n");
sc_debug(card->ctx, "cosm_generate_key() ready to create temporary public key\n");
sc_file_dup(&tmpf, prkf);
if (tmpf == NULL) {
rv = SC_ERROR_OUT_OF_MEMORY;
goto failed;
}
if (!tmpf)
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot duplicate private key file");
tmpf->type = SC_FILE_TYPE_INTERNAL_EF;
tmpf->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
tmpf->id = 0x1012;
@ -582,18 +683,10 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card,
tmpf->path.value[tmpf->path.len - 1] = 0x12;
rv = sc_pkcs15init_create_file(profile, card, prkf);
sc_debug(card->ctx, "rv %i\n",rv);
if (rv) {
sc_debug(card->ctx, "prkf create file failed\n");
goto failed;
}
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create private key EF");
rv = sc_pkcs15init_create_file(profile, card, tmpf);
sc_debug(card->ctx, "rv %i\n",rv);
if (rv) {
sc_debug(card->ctx, "pubf create failed\n");
goto failed;
}
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create temporary public key EF");
memset(&args, 0, sizeof(args));
args.id_prv = prkf->id;
@ -602,49 +695,37 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card,
args.key_bits = keybits;
args.pubkey_len = keybits/8;
args.pubkey = (unsigned char *) malloc(keybits/8);
if (!args.pubkey) {
rv = SC_ERROR_OUT_OF_MEMORY;
goto failed;
}
if (!args.pubkey)
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey");
rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_GENERATE_KEY, &args);
if (rv < 0)
goto failed;
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() CARDCTL_OBERTHUR_GENERATE_KEY failed");
/* extract public key */
pubkey->algorithm = SC_ALGORITHM_RSA;
pubkey->u.rsa.modulus.len = keybits / 8;
pubkey->u.rsa.modulus.data = (unsigned char *) malloc(keybits / 8);
if (!pubkey->u.rsa.modulus.data) {
rv = SC_ERROR_MEMORY_FAILURE;
goto failed;
}
if (!pubkey->u.rsa.modulus.data)
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf");
/* FIXME and if the exponent length is not 3? */
pubkey->u.rsa.exponent.len = 3;
pubkey->u.rsa.exponent.data = (unsigned char *) malloc(3);
if (!pubkey->u.rsa.exponent.data) {
rv = SC_ERROR_MEMORY_FAILURE;
goto failed;
}
if (!pubkey->u.rsa.exponent.data)
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate exponent buf");
memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3);
memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len);
info->key_reference = 1;
info->path = prkf->path;
if (rv) {
sc_debug(card->ctx, "rv %i\n", rv);
goto failed;
}
sc_debug(card->ctx, "cosm_generate_key() now delete temporary public key\n");
rv = cosm_delete_file(card, profile, tmpf);
sc_debug(card->ctx, "delete temporary public key\n");
if ((rv = cosm_delete_file(card, profile, tmpf)))
goto failed;
failed:
if (tmpf) sc_file_free(tmpf);
if (prkf) sc_file_free(prkf);
if (tmpf)
sc_file_free(tmpf);
if (prkf)
sc_file_free(prkf);
SC_FUNC_RETURN(card->ctx, 1, rv);
}
@ -654,7 +735,7 @@ failed:
* Store a private key
*/
static int
cosm_new_key(struct sc_profile *profile, sc_card_t *card,
cosm_new_key(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_prkey *key, unsigned int idx,
struct sc_pkcs15_prkey_info *info)
{
@ -696,7 +777,7 @@ cosm_new_key(struct sc_profile *profile, sc_card_t *card,
SC_TEST_RET(card->ctx, rv, "Update RSA: no authorisation");
#ifdef ENABLE_OPENSSL
/* Mozilla style ID */
/* Mozilla style ID */
if (!info->id.len) {
SHA1(rsa->modulus.data, rsa->modulus.len, info->id.value);
info->id.len = SHA_DIGEST_LENGTH;