Merge [3804:3822/trunk]
git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3824 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
36f26b6357
commit
3ea5bb7987
File diff suppressed because it is too large
Load Diff
|
@ -97,7 +97,8 @@ static struct sc_card_driver rutoken_drv = {
|
|||
};
|
||||
|
||||
static struct sc_atr_table rutoken_atrs[] = {
|
||||
{ "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL },
|
||||
{ "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv Rutoken S */
|
||||
{ "3b:6f:00:ff:00:56:75:61:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv uaToken S */
|
||||
{ NULL, NULL, NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -162,7 +163,11 @@ static int rutoken_init(sc_card_t *card)
|
|||
int ret;
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, 1);
|
||||
ret = token_init(card, "Rutoken card");
|
||||
/* &rutoken_atrs[1] : { uaToken S ATR, NULL ATR } */
|
||||
if (_sc_match_atr(card, &rutoken_atrs[1], &card->type) >= 0)
|
||||
ret = token_init(card, "uaToken S card");
|
||||
else
|
||||
ret = token_init(card, "Rutoken S card");
|
||||
SC_FUNC_RETURN(card->ctx, 1, ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,8 @@ sc_pkcs15_read_data_object
|
|||
sc_pkcs15_read_file
|
||||
sc_pkcs15_read_prkey
|
||||
sc_pkcs15_read_pubkey
|
||||
sc_pkcs15_pubkey_from_prvkey
|
||||
sc_pkcs15_pubkey_from_cert
|
||||
sc_pkcs15_remove_df
|
||||
sc_pkcs15_remove_object
|
||||
sc_pkcs15_remove_unusedspace
|
||||
|
|
|
@ -111,6 +111,12 @@ extern "C" {
|
|||
#define SC_AC_OP_WRITE 3
|
||||
/* rehab and invalidate are the same as in DF case */
|
||||
|
||||
/* Special 'Oberthur IdOne AuthentIC's case:
|
||||
* re-use the existing DF ACLs that are not relevant to this card. */
|
||||
#define SC_AC_OP_PIN_DEFINE SC_AC_OP_LOCK
|
||||
#define SC_AC_OP_PIN_CHANGE SC_AC_OP_REHABILITATE
|
||||
#define SC_AC_OP_PIN_RESET SC_AC_OP_DELETE_SELF
|
||||
|
||||
/* various maximum values */
|
||||
#define SC_MAX_READER_DRIVERS 6
|
||||
#define SC_MAX_READERS 16
|
||||
|
|
|
@ -26,6 +26,12 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ENABLE_OPENSSL
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#endif
|
||||
|
||||
|
||||
static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
|
||||
{ "iD", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
|
||||
{ "usage", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
|
||||
|
@ -556,25 +562,167 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sc_pkcs15_dup_bignum (struct sc_pkcs15_bignum *dst, struct sc_pkcs15_bignum *src)
|
||||
{
|
||||
assert(dst && src);
|
||||
|
||||
if (src->data && src->len) {
|
||||
dst->data = calloc(1, src->len);
|
||||
if (!dst->data)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
memcpy(dst->data, src->data, src->len);
|
||||
dst->len = src->len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx,
|
||||
struct sc_pkcs15_prkey *prvkey, struct sc_pkcs15_pubkey **out)
|
||||
{
|
||||
struct sc_pkcs15_pubkey *pubkey;
|
||||
int rv = SC_SUCCESS;
|
||||
|
||||
assert(prvkey && out);
|
||||
|
||||
*out = NULL;
|
||||
pubkey = (struct sc_pkcs15_pubkey *) calloc(1, sizeof(struct sc_pkcs15_pubkey));
|
||||
if (!pubkey)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pubkey->algorithm = prvkey->algorithm;
|
||||
switch (prvkey->algorithm) {
|
||||
case SC_ALGORITHM_RSA:
|
||||
rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.modulus, &prvkey->u.rsa.modulus);
|
||||
if (!rv)
|
||||
rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &prvkey->u.rsa.exponent);
|
||||
break;
|
||||
case SC_ALGORITHM_DSA:
|
||||
rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &prvkey->u.dsa.pub);
|
||||
if (!rv)
|
||||
rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &prvkey->u.dsa.p);
|
||||
if (!rv)
|
||||
rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &prvkey->u.dsa.q);
|
||||
if (!rv)
|
||||
rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &prvkey->u.dsa.g);
|
||||
break;
|
||||
case SC_ALGORITHM_GOSTR3410:
|
||||
break;
|
||||
default:
|
||||
sc_debug(ctx, "Unsupported private key algorithm");
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (rv)
|
||||
sc_pkcs15_free_pubkey(pubkey);
|
||||
else
|
||||
*out = pubkey;
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_pkcs15_pubkey_from_cert(struct sc_context *ctx,
|
||||
struct sc_pkcs15_der *cert_blob, struct sc_pkcs15_pubkey **out)
|
||||
{
|
||||
#ifndef ENABLE_OPENSSL
|
||||
SC_FUNC_RETURN(ctx, 1, SC_ERROR_NOT_SUPPORTED);
|
||||
#else
|
||||
EVP_PKEY *pkey = NULL;
|
||||
X509 *x = NULL;
|
||||
BIO *mem = NULL;
|
||||
struct sc_pkcs15_pubkey *pubkey = NULL;
|
||||
int rv = 0;
|
||||
|
||||
assert(cert_blob && out);
|
||||
|
||||
pubkey = (struct sc_pkcs15_pubkey *) calloc(1, sizeof(struct sc_pkcs15_pubkey));
|
||||
if (!pubkey)
|
||||
SC_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate pubkey");
|
||||
|
||||
pubkey->algorithm = SC_ALGORITHM_RSA;
|
||||
do {
|
||||
rv = SC_ERROR_INVALID_DATA;
|
||||
mem = BIO_new_mem_buf(cert_blob->value, cert_blob->len);
|
||||
if (!mem)
|
||||
break;
|
||||
|
||||
x = d2i_X509_bio(mem, NULL);
|
||||
if (!x)
|
||||
break;
|
||||
|
||||
pkey=X509_get_pubkey(x);
|
||||
if (!pkey || pkey->type != EVP_PKEY_RSA)
|
||||
break;
|
||||
|
||||
pubkey->u.rsa.modulus.len = BN_num_bytes(pkey->pkey.rsa->n);
|
||||
pubkey->u.rsa.modulus.data = calloc(1, pubkey->u.rsa.modulus.len);
|
||||
|
||||
pubkey->u.rsa.exponent.len = BN_num_bytes(pkey->pkey.rsa->e);
|
||||
pubkey->u.rsa.exponent.data = calloc(1, pubkey->u.rsa.exponent.len);
|
||||
|
||||
rv = SC_ERROR_OUT_OF_MEMORY;
|
||||
if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.exponent.data)
|
||||
break;
|
||||
|
||||
BN_bn2bin(pkey->pkey.rsa->n, pubkey->u.rsa.modulus.data);
|
||||
BN_bn2bin(pkey->pkey.rsa->e, pubkey->u.rsa.exponent.data);
|
||||
|
||||
rv = SC_SUCCESS;
|
||||
} while (0);
|
||||
|
||||
if (pkey)
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
if (x)
|
||||
X509_free(x);
|
||||
|
||||
if (mem)
|
||||
BIO_free(mem);
|
||||
|
||||
if (rv) {
|
||||
sc_pkcs15_free_pubkey(pubkey);
|
||||
pubkey = NULL;
|
||||
}
|
||||
|
||||
*out = pubkey;
|
||||
|
||||
SC_FUNC_RETURN(ctx, 1, rv);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
|
||||
{
|
||||
assert(key != NULL);
|
||||
switch (key->algorithm) {
|
||||
case SC_ALGORITHM_RSA:
|
||||
if (key->u.rsa.modulus.data)
|
||||
free(key->u.rsa.modulus.data);
|
||||
if (key->u.rsa.exponent.data)
|
||||
free(key->u.rsa.exponent.data);
|
||||
break;
|
||||
case SC_ALGORITHM_DSA:
|
||||
if (key->u.dsa.pub.data)
|
||||
free(key->u.dsa.pub.data);
|
||||
if (key->u.dsa.g.data)
|
||||
free(key->u.dsa.g.data);
|
||||
if (key->u.dsa.p.data)
|
||||
free(key->u.dsa.p.data);
|
||||
if (key->u.dsa.q.data)
|
||||
free(key->u.dsa.q.data);
|
||||
break;
|
||||
case SC_ALGORITHM_GOSTR3410:
|
||||
if (key->u.gostr3410.x.data)
|
||||
free(key->u.gostr3410.x.data);
|
||||
if (key->u.gostr3410.y.data)
|
||||
free(key->u.gostr3410.y.data);
|
||||
break;
|
||||
}
|
||||
if (key->data.value)
|
||||
free(key->data.value);
|
||||
sc_mem_clear(key, sizeof(*key));
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (builtin_enabled) {
|
||||
else if (builtin_enabled) {
|
||||
sc_debug(ctx, "no emulator list in config file, trying all builtin emulators\n");
|
||||
for (i = 0; builtin_emulators[i].name; i++) {
|
||||
sc_debug(ctx, "trying %s\n", builtin_emulators[i].name);
|
||||
|
|
|
@ -759,8 +759,8 @@ done:
|
|||
if (strcmp(p15card->card->driver->short_name,"cardos") == 0) {
|
||||
|
||||
/* D-Trust cards (D-TRUST, D-SIGN) */
|
||||
if (strstr(p15card->label,"D-TRUST") == 0
|
||||
|| strstr(p15card->label,"D-SIGN") == 0) {
|
||||
if (strstr(p15card->label,"D-TRUST") != NULL
|
||||
|| strstr(p15card->label,"D-SIGN") != NULL) {
|
||||
|
||||
/* D-TRUST Card 2.0 2cc (standard cards, which always add
|
||||
* SHA1 prefix itself */
|
||||
|
|
|
@ -440,6 +440,8 @@ typedef struct sc_pkcs15_card {
|
|||
#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
|
||||
|
@ -475,16 +477,16 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
unsigned long alg_flags, const u8 *in,
|
||||
size_t inlen, u8 *out, size_t outlen);
|
||||
|
||||
int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *card,
|
||||
const struct sc_pkcs15_object *obj,
|
||||
struct sc_pkcs15_pubkey **out);
|
||||
int sc_pkcs15_decode_pubkey_rsa(struct sc_context *ctx,
|
||||
struct sc_pkcs15_pubkey_rsa *pubkey,
|
||||
int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *,
|
||||
const struct sc_pkcs15_object *,
|
||||
struct sc_pkcs15_pubkey **);
|
||||
int sc_pkcs15_decode_pubkey_rsa(struct sc_context *,
|
||||
struct sc_pkcs15_pubkey_rsa *,
|
||||
const u8 *, size_t);
|
||||
int sc_pkcs15_encode_pubkey_rsa(struct sc_context *,
|
||||
struct sc_pkcs15_pubkey_rsa *, u8 **, size_t *);
|
||||
int sc_pkcs15_decode_pubkey_dsa(struct sc_context *ctx,
|
||||
struct sc_pkcs15_pubkey_dsa *pubkey,
|
||||
int sc_pkcs15_decode_pubkey_dsa(struct sc_context *,
|
||||
struct sc_pkcs15_pubkey_dsa *,
|
||||
const u8 *, size_t);
|
||||
int sc_pkcs15_encode_pubkey_dsa(struct sc_context *,
|
||||
struct sc_pkcs15_pubkey_dsa *, u8 **, size_t *);
|
||||
|
@ -492,13 +494,16 @@ int sc_pkcs15_decode_pubkey(struct sc_context *,
|
|||
struct sc_pkcs15_pubkey *, const u8 *, size_t);
|
||||
int sc_pkcs15_encode_pubkey(struct sc_context *,
|
||||
struct sc_pkcs15_pubkey *, u8 **, size_t *);
|
||||
void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *pubkey);
|
||||
void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *pubkey);
|
||||
|
||||
int sc_pkcs15_read_prkey(struct sc_pkcs15_card *card,
|
||||
const struct sc_pkcs15_object *obj,
|
||||
void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *);
|
||||
void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *);
|
||||
int sc_pkcs15_pubkey_from_prvkey(struct sc_context *, struct sc_pkcs15_prkey *,
|
||||
struct sc_pkcs15_pubkey **);
|
||||
int sc_pkcs15_pubkey_from_cert(struct sc_context *, struct sc_pkcs15_der *,
|
||||
struct sc_pkcs15_pubkey **);
|
||||
int sc_pkcs15_read_prkey(struct sc_pkcs15_card *,
|
||||
const struct sc_pkcs15_object *,
|
||||
const char *passphrase,
|
||||
struct sc_pkcs15_prkey **out);
|
||||
struct sc_pkcs15_prkey **);
|
||||
int sc_pkcs15_decode_prkey(struct sc_context *,
|
||||
struct sc_pkcs15_prkey *,
|
||||
const u8 *, size_t);
|
||||
|
|
|
@ -1736,11 +1736,22 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card,
|
|||
}
|
||||
|
||||
/* Write the new public and private keys to the pkcs15 files */
|
||||
rc = sc_pkcs15init_store_private_key(p15card, profile,
|
||||
&keygen_args.prkey_args, &priv_key_obj);
|
||||
if (rc >= 0)
|
||||
rc = sc_pkcs15init_store_public_key(p15card, profile,
|
||||
&pub_args, &pub_key_obj);
|
||||
/* To support smartcards that require different keybobjects for signing and encryption */
|
||||
if (sc_pkcs15init_requires_restrictive_usage(p15card, &keygen_args.prkey_args, 0)) {
|
||||
sc_debug(context, "store split key required for this card", rv);
|
||||
/* second key is the signature keyobject */
|
||||
rc = sc_pkcs15init_store_split_key(p15card, profile, &keygen_args.prkey_args, NULL, &priv_key_obj);
|
||||
}
|
||||
else {
|
||||
rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj);
|
||||
}
|
||||
|
||||
if (rc >= 0) {
|
||||
/* copy ID from private key(s) here to avoid bad link between private and public key */
|
||||
memcpy(&pub_args.id.value, &keygen_args.prkey_args.id.value, keygen_args.prkey_args.id.len);
|
||||
pub_args.id.len = keygen_args.prkey_args.id.len;
|
||||
rc = sc_pkcs15init_store_public_key(p15card, profile, &pub_args, &pub_key_obj);
|
||||
}
|
||||
if (rc < 0) {
|
||||
sc_debug(context, "private/public keys not stored: %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
|
|
|
@ -54,7 +54,8 @@ filesystem {
|
|||
DF OberthurAWP-AppDF {
|
||||
ACL = *=NONE;
|
||||
#ACL = CREATE=CHV4, CRYPTO=NEVER, PIN_SET=CHV4, PIN_RESET=PRO0x78;
|
||||
ACL = CREATE=CHV4, CRYPTO=NEVER;
|
||||
ACL = CREATE=CHV4, CRYPTO=NEVER, PIN-DEFINE=CHV4, PIN-RESET=CHV4;
|
||||
#ACL = CREATE=CHV4, CRYPTO=NEVER;
|
||||
file-id = 5011;
|
||||
size = 40;
|
||||
|
||||
|
|
|
@ -175,6 +175,10 @@ struct sc_pkcs15init_operations {
|
|||
};
|
||||
|
||||
/* Do not change these or reorder these */
|
||||
#define SC_PKCS15INIT_ID_STYLE_NATIVE 0
|
||||
#define SC_PKCS15INIT_ID_STYLE_MOZILLA 1
|
||||
#define SC_PKCS15INIT_ID_STYLE_RFC2459 2
|
||||
|
||||
#define SC_PKCS15INIT_SO_PIN 0
|
||||
#define SC_PKCS15INIT_SO_PUK 1
|
||||
#define SC_PKCS15INIT_USER_PIN 2
|
||||
|
|
|
@ -119,6 +119,8 @@ static int check_key_compatibility(struct sc_pkcs15_card *,
|
|||
static int prkey_fixup(sc_pkcs15_card_t *, sc_pkcs15_prkey_t *);
|
||||
static int prkey_bits(sc_pkcs15_card_t *, sc_pkcs15_prkey_t *);
|
||||
static int prkey_pkcs15_algo(sc_pkcs15_card_t *, sc_pkcs15_prkey_t *);
|
||||
static int select_intrinsic_id(sc_pkcs15_card_t *, struct sc_profile *,
|
||||
int, sc_pkcs15_id_t *, void *);
|
||||
static int select_id(sc_pkcs15_card_t *, int, sc_pkcs15_id_t *,
|
||||
int (*)(const sc_pkcs15_object_t *, void *), void *,
|
||||
sc_pkcs15_object_t **);
|
||||
|
@ -1220,8 +1222,8 @@ sc_pkcs15init_init_prkdf(sc_pkcs15_card_t *p15card,
|
|||
/* Split key; this ID exists already, don't check for
|
||||
* the pkcs15 object */
|
||||
} else {
|
||||
/* Select a Key ID if the user didn't specify one, otherwise
|
||||
* make sure it's compatible with our intended use */
|
||||
/* Select a Key ID if the user didn't specify one,
|
||||
* otherwise make sure it's compatible with our intended use */
|
||||
r = select_id(p15card, SC_PKCS15_TYPE_PRKEY, &keyargs->id,
|
||||
can_reuse_prkey_obj, object, res_obj);
|
||||
if (r < 0)
|
||||
|
@ -1302,7 +1304,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
|||
struct sc_pkcs15init_pubkeyargs pubkey_args;
|
||||
struct sc_pkcs15_object *object;
|
||||
struct sc_pkcs15_prkey_info *key_info;
|
||||
int r;
|
||||
int r, caller_supplied_id = 0;
|
||||
|
||||
/* check supported key size */
|
||||
r = check_key_size(p15card->card, keygen_args->prkey_args.key.algorithm, keybits);
|
||||
|
@ -1328,6 +1330,8 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
|||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
||||
return r;
|
||||
|
||||
caller_supplied_id = keygen_args->prkey_args.id.len != 0;
|
||||
|
||||
/* Set up the PrKDF object */
|
||||
r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args,
|
||||
&keygen_args->prkey_args.key, keybits, &object);
|
||||
|
@ -1342,7 +1346,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
|||
#if 0
|
||||
pubkey_args.auth_id = keygen_args->prkey_args.auth_id;
|
||||
#endif
|
||||
pubkey_args.label = keygen_args->pubkey_label;
|
||||
pubkey_args.label = keygen_args->pubkey_label ? keygen_args->pubkey_label : object->label;
|
||||
pubkey_args.usage = keygen_args->prkey_args.usage;
|
||||
pubkey_args.x509_usage = keygen_args->prkey_args.x509_usage;
|
||||
pubkey_args.gost_params = keygen_args->prkey_args.gost_params;
|
||||
|
@ -1368,8 +1372,23 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
|||
|
||||
/* update PrKDF entry */
|
||||
if (r >= 0) {
|
||||
r = sc_pkcs15init_add_object(p15card, profile,
|
||||
SC_PKCS15_PRKDF, object);
|
||||
if (!caller_supplied_id) {
|
||||
struct sc_pkcs15_id iid;
|
||||
|
||||
/* Caller not supplied ID, so,
|
||||
* if intrinsic ID can be calculated -- overwrite the native one */
|
||||
memset(&iid, 0, sizeof(iid));
|
||||
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (iid.len) {
|
||||
key_info->id = iid;
|
||||
pubkey_args.id = iid;
|
||||
}
|
||||
}
|
||||
|
||||
r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object);
|
||||
}
|
||||
|
||||
if (r >= 0) {
|
||||
|
@ -1439,6 +1458,11 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card,
|
|||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
||||
return r;
|
||||
|
||||
/* Select a intrinsic Key ID if user didn't specify one */
|
||||
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PRKEY, &keyargs->id, &keyargs->key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Set up the PrKDF object */
|
||||
r = sc_pkcs15init_init_prkdf(p15card, profile, keyargs, &key, keybits, &object);
|
||||
if (r < 0)
|
||||
|
@ -1649,9 +1673,14 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
|
|||
keyinfo_gostparams->gost28147 = keyargs->gost_params.gost28147;
|
||||
}
|
||||
|
||||
/* Select a Key ID if the user didn't specify one, otherwise
|
||||
* make sure it's unique */
|
||||
*res_obj = NULL;
|
||||
/* Select a intrinsic Key ID if the user didn't specify one */
|
||||
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &keyargs->id, &key);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Select a Key ID if the user didn't specify one and there is no intrinsic ID,
|
||||
* otherwise make sure it's unique */
|
||||
r = select_id(p15card, SC_PKCS15_TYPE_PUBKEY, &keyargs->id,
|
||||
can_reuse_pubkey_obj, object, res_obj);
|
||||
if (r < 0)
|
||||
|
@ -1728,6 +1757,10 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
|||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
||||
return r;
|
||||
|
||||
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &args->id, &args->der_encoded);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Select an ID if the user didn't specify one, otherwise
|
||||
* make sure it's unique */
|
||||
if ((r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id, NULL, NULL, NULL)) < 0)
|
||||
|
@ -1992,7 +2025,7 @@ static size_t sc_pkcs15init_keybits(sc_pkcs15_bignum_t *bn)
|
|||
if (!bn || !bn->len)
|
||||
return 0;
|
||||
bits = bn->len << 3;
|
||||
for (mask = 0x80; !(bn->data[0] & mask); mask >>= 1)
|
||||
for (mask = 0x80; mask && !(bn->data[0] & mask); mask >>= 1)
|
||||
bits--;
|
||||
return bits;
|
||||
}
|
||||
|
@ -2247,6 +2280,102 @@ find_df_by_type(struct sc_pkcs15_card *p15card, unsigned int type)
|
|||
return df;
|
||||
}
|
||||
|
||||
static int select_intrinsic_id(sc_pkcs15_card_t *p15card, struct sc_profile *profile,
|
||||
int type, sc_pkcs15_id_t *id, void *data)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_pubkey *pubkey = NULL;
|
||||
unsigned id_style = profile->id_style;
|
||||
int rv, allocated = 0;
|
||||
|
||||
SC_FUNC_CALLED(ctx, 1);
|
||||
#ifndef ENABLE_OPENSSL
|
||||
SC_FUNC_RETURN(ctx, 1, 0);
|
||||
#else
|
||||
/* ID already exists */
|
||||
if (id->len)
|
||||
SC_FUNC_RETURN(ctx, 1, 0);
|
||||
|
||||
/* Native ID style is not an intrisic one */
|
||||
if (profile->id_style == SC_PKCS15INIT_ID_STYLE_NATIVE)
|
||||
SC_FUNC_RETURN(ctx, 1, 0);
|
||||
|
||||
/* Get PKCS15 public key */
|
||||
switch(type) {
|
||||
case SC_PKCS15_TYPE_CERT_X509:
|
||||
rv = sc_pkcs15_pubkey_from_cert(ctx, (struct sc_pkcs15_der *)data, &pubkey);
|
||||
SC_TEST_RET(ctx, rv, "X509 parse error");
|
||||
|
||||
allocated = 1;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_PRKEY:
|
||||
rv = sc_pkcs15_pubkey_from_prvkey(ctx, (struct sc_pkcs15_prkey *)data, &pubkey);
|
||||
SC_TEST_RET(ctx, rv, "Cannot get public key");
|
||||
|
||||
allocated = 1;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_PUBKEY:
|
||||
pubkey = (struct sc_pkcs15_pubkey *)data;
|
||||
|
||||
allocated = 0;
|
||||
break;
|
||||
default:
|
||||
sc_debug(ctx, "Intrinsic ID is not implemented for the object type 0x%X\n", type);
|
||||
SC_FUNC_RETURN(ctx, 1, 0);
|
||||
}
|
||||
|
||||
/* Skip silently if key is not inintialized. */
|
||||
if (pubkey->algorithm == SC_ALGORITHM_RSA && !pubkey->u.rsa.modulus.len)
|
||||
goto done;
|
||||
else if (pubkey->algorithm == SC_ALGORITHM_DSA && !pubkey->u.dsa.pub.data)
|
||||
goto done;
|
||||
else if (pubkey->algorithm == SC_ALGORITHM_GOSTR3410 &&
|
||||
(!pubkey->u.gostr3410.x.data || !pubkey->u.gostr3410.y.data))
|
||||
goto done;
|
||||
|
||||
/* In Mozilla 'GOST R 34.10' is not yet supported.
|
||||
* So, switch to the ID recommended by RFC2459 */
|
||||
if (pubkey->algorithm == SC_ALGORITHM_GOSTR3410 && id_style == SC_PKCS15INIT_ID_STYLE_MOZILLA)
|
||||
id_style = SC_PKCS15INIT_ID_STYLE_RFC2459;
|
||||
|
||||
if (id_style == SC_PKCS15INIT_ID_STYLE_MOZILLA) {
|
||||
if (pubkey->algorithm == SC_ALGORITHM_RSA)
|
||||
SHA1(pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len, id->value);
|
||||
else if (pubkey->algorithm == SC_ALGORITHM_DSA)
|
||||
SHA1(pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len, id->value);
|
||||
else
|
||||
goto done;
|
||||
|
||||
id->len = SHA_DIGEST_LENGTH;
|
||||
}
|
||||
else if (id_style == SC_PKCS15INIT_ID_STYLE_RFC2459) {
|
||||
unsigned char *id_data = NULL;
|
||||
size_t id_data_len = 0;
|
||||
|
||||
rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &id_data, &id_data_len);
|
||||
SC_TEST_RET(ctx, rv, "Encoding public key error");
|
||||
|
||||
if (!id_data || !id_data_len)
|
||||
SC_TEST_RET(ctx, SC_ERROR_INTERNAL, "Encoding public key error");
|
||||
|
||||
SHA1(id_data, id_data_len, id->value);
|
||||
id->len = SHA_DIGEST_LENGTH;
|
||||
|
||||
free(id_data);
|
||||
}
|
||||
else {
|
||||
sc_debug(ctx, "Unsupported ID style: %i", profile->id_style);
|
||||
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Non supported ID style");
|
||||
}
|
||||
|
||||
done:
|
||||
if (allocated)
|
||||
sc_pkcs15_free_pubkey(pubkey);
|
||||
|
||||
SC_FUNC_RETURN(ctx, 1, id->len);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int select_id(sc_pkcs15_card_t *p15card, int type, sc_pkcs15_id_t *id,
|
||||
int (*can_reuse)(const sc_pkcs15_object_t *, void *),
|
||||
void *data, sc_pkcs15_object_t **reuse_obj)
|
||||
|
|
|
@ -56,19 +56,133 @@
|
|||
#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,
|
||||
struct sc_pkcs15_pin_info *info, const u8 *pin, size_t pin_len,
|
||||
const u8 *puk, size_t puk_len);
|
||||
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);
|
||||
|
||||
int cosm_delete_file(sc_card_t *card, struct sc_profile *profile,
|
||||
sc_file_t *df)
|
||||
|
||||
static int
|
||||
cosm_write_tokeninfo (struct sc_card *card, struct sc_profile *profile,
|
||||
char *label, unsigned p15_flags)
|
||||
{
|
||||
sc_path_t path;
|
||||
sc_file_t *parent;
|
||||
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,
|
||||
unsigned char *data, size_t data_len)
|
||||
{
|
||||
struct sc_pkcs15_pin_info profile_puk;
|
||||
struct sc_file *file = NULL;
|
||||
int rv, sz, flags = 0;
|
||||
unsigned char buffer[16];
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, 1);
|
||||
if (!data || data_len > 16)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &profile_puk);
|
||||
if (profile_puk.max_length > 16)
|
||||
SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Invalid PUK settings");
|
||||
|
||||
if (sc_profile_get_file(profile, COSM_TITLE"-puk-file", &file))
|
||||
SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find PUKFILE");
|
||||
|
||||
memset(buffer, profile_puk.pad_char, 16);
|
||||
memcpy(buffer, data, data_len);
|
||||
|
||||
rv = sc_pkcs15init_update_file(profile, card, file, buffer, sizeof(buffer));
|
||||
if (rv > 0)
|
||||
rv = 0;
|
||||
|
||||
SC_FUNC_RETURN(card->ctx, 1, rv);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cosm_delete_file(struct sc_card *card, struct sc_profile *profile,
|
||||
struct sc_file *df)
|
||||
{
|
||||
struct sc_path path;
|
||||
struct sc_file *parent;
|
||||
int rv = 0;
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, 1);
|
||||
|
@ -104,9 +218,10 @@ int cosm_delete_file(sc_card_t *card, struct sc_profile *profile,
|
|||
/*
|
||||
* Erase the card
|
||||
*/
|
||||
static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card)
|
||||
static int
|
||||
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);
|
||||
|
@ -150,6 +265,7 @@ static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card)
|
|||
sc_file_free(dir);
|
||||
}
|
||||
|
||||
sc_free_apps(card);
|
||||
done:
|
||||
sc_keycache_forget_key(NULL, -1, -1);
|
||||
|
||||
|
@ -164,14 +280,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 u8 *pin, size_t pin_len,
|
||||
const u8 *puk, size_t puk_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",
|
||||
|
@ -192,7 +308,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 */
|
||||
|
@ -206,22 +322,43 @@ 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,
|
||||
|
||||
static int
|
||||
cosm_create_reference_data(struct sc_profile *profile, struct sc_card *card,
|
||||
struct sc_pkcs15_pin_info *pinfo,
|
||||
const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len )
|
||||
const unsigned char *pin, size_t pin_len,
|
||||
const unsigned char *puk, size_t puk_len )
|
||||
{
|
||||
int rv;
|
||||
int puk_buff_len = 0;
|
||||
unsigned char *puk_buff = NULL;
|
||||
sc_pkcs15_pin_info_t profile_pin;
|
||||
sc_pkcs15_pin_info_t profile_puk;
|
||||
struct sc_pkcs15_pin_info profile_pin;
|
||||
struct sc_pkcs15_pin_info profile_puk;
|
||||
struct sc_cardctl_oberthur_createpin_info args;
|
||||
unsigned char *puk_buff = NULL;
|
||||
int rv, puk_buff_len = 0;
|
||||
|
||||
SC_FUNC_CALLED(card->ctx, 1);
|
||||
sc_debug(card->ctx, "pin lens %i/%i\n", pin_len, puk_len);
|
||||
|
@ -233,9 +370,14 @@ static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *car
|
|||
rv = sc_select_file(card, &pinfo->path, NULL);
|
||||
SC_TEST_RET(card->ctx, rv, "Cannot select file");
|
||||
|
||||
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;
|
||||
|
@ -278,6 +420,12 @@ static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *car
|
|||
args.puk_tries = profile_puk.tries_left;
|
||||
|
||||
rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_CREATE_PIN, &args);
|
||||
SC_TEST_RET(card->ctx, rv, "'CREATE_PIN' card specific command failed");
|
||||
|
||||
if (puk_buff_len == 16) {
|
||||
rv = cosm_update_pukfile (card, profile, puk_buff, puk_buff_len);
|
||||
SC_TEST_RET(card->ctx, rv, "Failed to update pukfile");
|
||||
}
|
||||
|
||||
if (puk_buff)
|
||||
free(puk_buff);
|
||||
|
@ -288,42 +436,49 @@ static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *car
|
|||
/*
|
||||
* Update PIN
|
||||
*/
|
||||
static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card,
|
||||
struct sc_pkcs15_pin_info *pinfo, const u8 *pin, size_t pin_len,
|
||||
const u8 *puk, size_t puk_len )
|
||||
static int
|
||||
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_debug(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_debug(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);
|
||||
|
@ -348,25 +503,24 @@ 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,
|
||||
sc_pkcs15_object_t *pin_obj,
|
||||
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_debug(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);
|
||||
|
@ -375,22 +529,19 @@ 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_debug(card->ctx, "return %i\n", rv);
|
||||
|
||||
sc_keycache_set_pin_name(&pinfo->path, pinfo->reference, type);
|
||||
pinfo->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL;
|
||||
|
@ -403,15 +554,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:
|
||||
|
@ -457,11 +608,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_debug(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);
|
||||
|
@ -470,7 +621,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;
|
||||
|
||||
|
@ -482,9 +633,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;
|
||||
|
@ -493,17 +644,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_debug(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. */
|
||||
|
@ -511,27 +660,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;
|
||||
|
@ -539,18 +682,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;
|
||||
|
@ -559,49 +694,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 = (u8 *) malloc(keybits / 8);
|
||||
if (!pubkey->u.rsa.modulus.data) {
|
||||
rv = SC_ERROR_MEMORY_FAILURE;
|
||||
goto failed;
|
||||
}
|
||||
pubkey->u.rsa.modulus.data = (unsigned char *) malloc(keybits / 8);
|
||||
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 = (u8 *) malloc(3);
|
||||
if (!pubkey->u.rsa.exponent.data) {
|
||||
rv = SC_ERROR_MEMORY_FAILURE;
|
||||
goto failed;
|
||||
}
|
||||
pubkey->u.rsa.exponent.data = (unsigned char *) malloc(3);
|
||||
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);
|
||||
}
|
||||
|
@ -611,7 +734,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)
|
||||
{
|
||||
|
@ -653,6 +776,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 */
|
||||
if (!info->id.len) {
|
||||
SHA1(rsa->modulus.data, rsa->modulus.len, info->id.value);
|
||||
info->id.len = SHA_DIGEST_LENGTH;
|
||||
|
|
|
@ -22,6 +22,12 @@ pkcs15 {
|
|||
encode-df-length = no;
|
||||
# Have a lastUpdate field in the EF(TokenInfo)?
|
||||
do-last-update = yes;
|
||||
# Method to calculate ID of the crypto objects
|
||||
# mozilla: SHA1(modulus) for RSA, SHA1(pub) for DSA
|
||||
# rfc2459: SHA1(SequenceASN1 of public key components as ASN1 integers)
|
||||
# native: 'E' + number_of_present_objects_of_the_same_type
|
||||
# default value: 'native'
|
||||
# pkcs15-id-style = mozilla;
|
||||
}
|
||||
|
||||
# Default settings.
|
||||
|
|
|
@ -105,6 +105,9 @@ static struct map fileOpNames[] = {
|
|||
{ "WRITE", SC_AC_OP_WRITE },
|
||||
{ "ERASE", SC_AC_OP_ERASE },
|
||||
{ "CRYPTO", SC_AC_OP_CRYPTO },
|
||||
{ "PIN-DEFINE", SC_AC_OP_PIN_DEFINE },
|
||||
{ "PIN-CHANGE", SC_AC_OP_PIN_CHANGE },
|
||||
{ "PIN-RESET", SC_AC_OP_PIN_RESET },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
static struct map fileTypeNames[] = {
|
||||
|
@ -169,6 +172,12 @@ static struct map pinFlagNames[] = {
|
|||
{ "exchangeRefData", 0x0800 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
static struct map idStyleNames[] = {
|
||||
{ "native", SC_PKCS15INIT_ID_STYLE_NATIVE },
|
||||
{ "mozilla", SC_PKCS15INIT_ID_STYLE_MOZILLA },
|
||||
{ "rfc2459", SC_PKCS15INIT_ID_STYLE_RFC2459 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
static struct {
|
||||
const char * name;
|
||||
struct map * addr;
|
||||
|
@ -280,6 +289,7 @@ sc_profile_new(void)
|
|||
pro->pin_minlen = 4;
|
||||
pro->pin_maxlen = 8;
|
||||
pro->keep_public_key = 1;
|
||||
pro->id_style = SC_PKCS15INIT_ID_STYLE_NATIVE;
|
||||
|
||||
return pro;
|
||||
}
|
||||
|
@ -780,6 +790,12 @@ do_encode_update_field(struct state *cur, int argc, char **argv)
|
|||
return get_bool(cur, argv[0], &cur->profile->pkcs15.do_last_update);
|
||||
}
|
||||
|
||||
static int
|
||||
do_pkcs15_id_style(struct state *cur, int argc, char **argv)
|
||||
{
|
||||
return map_str2int(cur, argv[0], &cur->profile->id_style, idStyleNames);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process an option block
|
||||
*/
|
||||
|
@ -1525,6 +1541,7 @@ static struct command p15_commands[] = {
|
|||
{ "direct-certificates", 1, 1, do_direct_certificates },
|
||||
{ "encode-df-length", 1, 1, do_encode_df_length },
|
||||
{ "do-last-update", 1, 1, do_encode_update_field },
|
||||
{ "pkcs15-id-style", 1, 1, do_pkcs15_id_style },
|
||||
{ NULL, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -120,6 +120,9 @@ struct sc_profile {
|
|||
* needs to be updated (in other words: if the card content
|
||||
* has been changed) */
|
||||
int dirty;
|
||||
|
||||
/* PKCS15 object ID style */
|
||||
unsigned int id_style;
|
||||
};
|
||||
|
||||
struct sc_profile *sc_profile_new(void);
|
||||
|
|
|
@ -68,7 +68,7 @@ enum {
|
|||
#endif
|
||||
OPT_PIN,
|
||||
OPT_NEWPIN,
|
||||
OPT_PUK,
|
||||
OPT_PUK
|
||||
};
|
||||
|
||||
#define NELEMENTS(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
@ -119,7 +119,9 @@ static const char *option_help[] = {
|
|||
"Lists private keys",
|
||||
"Lists public keys",
|
||||
"Reads public key with ID <arg>",
|
||||
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
|
||||
"Reads public key with ID <arg>, outputs ssh format",
|
||||
#endif
|
||||
"Test if the card needs a security update",
|
||||
"Update the card with a security update",
|
||||
"Uses reader number <arg>",
|
||||
|
@ -402,6 +404,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj)
|
|||
{
|
||||
unsigned int i;
|
||||
struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data;
|
||||
const char *types[] = { "", "RSA", "DSA", "GOSTR3410" };
|
||||
const char *usages[] = {
|
||||
"encrypt", "decrypt", "sign", "signRecover",
|
||||
"wrap", "unwrap", "verify", "verifyRecover",
|
||||
|
@ -414,7 +417,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj)
|
|||
};
|
||||
const unsigned int af_count = NELEMENTS(access_flags);
|
||||
|
||||
printf("Private RSA Key [%s]\n", obj->label);
|
||||
printf("Private %s Key [%s]\n", types[3 & obj->type], obj->label);
|
||||
printf("\tCom. Flags : %X\n", obj->flags);
|
||||
printf("\tUsage : [0x%X]", prkey->usage);
|
||||
for (i = 0; i < usage_count; i++)
|
||||
|
@ -442,7 +445,7 @@ static int list_private_keys(void)
|
|||
int r, i;
|
||||
struct sc_pkcs15_object *objs[32];
|
||||
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32);
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, objs, 32);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
|
@ -460,6 +463,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj)
|
|||
{
|
||||
unsigned int i;
|
||||
const struct sc_pkcs15_pubkey_info *pubkey = (const struct sc_pkcs15_pubkey_info *) obj->data;
|
||||
const char *types[] = { "", "RSA", "DSA", "GOSTR3410" };
|
||||
const char *usages[] = {
|
||||
"encrypt", "decrypt", "sign", "signRecover",
|
||||
"wrap", "unwrap", "verify", "verifyRecover",
|
||||
|
@ -472,7 +476,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj)
|
|||
};
|
||||
const unsigned int af_count = NELEMENTS(access_flags);
|
||||
|
||||
printf("Public RSA Key [%s]\n", obj->label);
|
||||
printf("Public %s Key [%s]\n", types[3 & obj->type], obj->label);
|
||||
printf("\tCom. Flags : %X\n", obj->flags);
|
||||
printf("\tUsage : [0x%X]", pubkey->usage);
|
||||
for (i = 0; i < usage_count; i++)
|
||||
|
@ -499,7 +503,7 @@ static int list_public_keys(void)
|
|||
int r, i;
|
||||
struct sc_pkcs15_object *objs[32];
|
||||
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, objs, 32);
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY, objs, 32);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
|
@ -906,7 +910,7 @@ static void print_pin_info(const struct sc_pkcs15_object *obj)
|
|||
(unsigned long)pin->stored_length);
|
||||
printf("\tPad char : 0x%02X\n", pin->pad_char);
|
||||
printf("\tReference : %d\n", pin->reference);
|
||||
if (pin->type >= 0 && pin->type < sizeof(pin_types)/sizeof(pin_types[0]))
|
||||
if (pin->type < sizeof(pin_types)/sizeof(pin_types[0]))
|
||||
printf("\tType : %s\n", pin_types[pin->type]);
|
||||
else
|
||||
printf("\tType : [encoding %d]\n", pin->type);
|
||||
|
@ -1146,7 +1150,7 @@ static int learn_card(void)
|
|||
return 1;
|
||||
}
|
||||
cert_count = r;
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, NULL, 0);
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r));
|
||||
return 1;
|
||||
|
@ -1241,7 +1245,7 @@ static int test_update(sc_card_t *in_card)
|
|||
}
|
||||
|
||||
{
|
||||
int i=0;
|
||||
size_t i=0;
|
||||
while(i < rbuf[1]) {
|
||||
if (rbuf[2+i] == 0x86) { /* found our buffer */
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue