- get_pin callback now takes additional label argument

- call get_pin for ALL pins, not just those listed in the profile
- add split key support to sc_pkcs15init_generate_key


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1116 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2003-05-15 11:30:46 +00:00
parent a3d81aa980
commit 7b34c2ecf7
2 changed files with 104 additions and 24 deletions

View File

@ -83,6 +83,7 @@ struct sc_pkcs15init_callbacks {
*/ */
int (*get_pin)(struct sc_profile *, int, int (*get_pin)(struct sc_profile *, int,
const struct sc_pkcs15_pin_info *, const struct sc_pkcs15_pin_info *,
const char *label,
u8 *, size_t *); u8 *, size_t *);
/* /*
@ -177,6 +178,11 @@ extern int sc_pkcs15init_store_private_key(struct sc_pkcs15_card *,
struct sc_profile *, struct sc_profile *,
struct sc_pkcs15init_prkeyargs *, struct sc_pkcs15init_prkeyargs *,
struct sc_pkcs15_object **); struct sc_pkcs15_object **);
extern int sc_pkcs15init_store_split_key(struct sc_pkcs15_card *,
struct sc_profile *,
struct sc_pkcs15init_prkeyargs *,
struct sc_pkcs15_object **,
struct sc_pkcs15_object **);
extern int sc_pkcs15init_store_public_key(struct sc_pkcs15_card *, extern int sc_pkcs15init_store_public_key(struct sc_pkcs15_card *,
struct sc_profile *, struct sc_profile *,
struct sc_pkcs15init_pubkeyargs *, struct sc_pkcs15init_pubkeyargs *,
@ -225,7 +231,8 @@ extern int sc_pkcs15init_rmdir(struct sc_card *, struct sc_profile *,
/* Helper function for CardOS */ /* Helper function for CardOS */
extern int sc_pkcs15init_requires_restrictive_usage( extern int sc_pkcs15init_requires_restrictive_usage(
struct sc_pkcs15_card *, struct sc_pkcs15_card *,
struct sc_pkcs15init_prkeyargs *); struct sc_pkcs15init_prkeyargs *,
unsigned int);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -206,15 +206,27 @@ sc_pkcs15init_erase_card_recursively(struct sc_card *card,
struct sc_profile *profile, struct sc_profile *profile,
int so_pin_ref) int so_pin_ref)
{ {
struct sc_pkcs15_card *p15orig = profile->p15_card;
struct sc_pkcs15_pin_info sopin, temp; struct sc_pkcs15_pin_info sopin, temp;
struct sc_file *df = profile->df_info->file, *dir; struct sc_file *df = profile->df_info->file, *dir;
int r; int r;
/* Frob: need to tell the upper layers about the SO PIN id */ /* Frob: need to tell the upper layers about the SO PIN id */
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin); sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin);
temp = sopin; if (so_pin_ref != -1) {
temp.reference = so_pin_ref; temp = sopin;
sc_profile_set_pin_info(profile, SC_PKCS15INIT_SO_PIN, &temp); temp.reference = so_pin_ref;
sc_profile_set_pin_info(profile, SC_PKCS15INIT_SO_PIN, &temp);
} else {
struct sc_pkcs15_card *p15card = NULL;
card->ctx->log_errors = 0;
if (sc_pkcs15_bind(card, &p15card) >= 0) {
set_so_pin_from_card(p15card, profile);
profile->p15_card = p15card;
}
card->ctx->log_errors = 1;
}
/* Delete EF(DIR). This may not be very nice /* Delete EF(DIR). This may not be very nice
* against other applications that use this file, but * against other applications that use this file, but
@ -242,6 +254,10 @@ sc_pkcs15init_erase_card_recursively(struct sc_card *card,
/* Unfrob the SO pin reference, and return */ /* Unfrob the SO pin reference, and return */
out: sc_profile_set_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin); out: sc_profile_set_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin);
if (profile->p15_card != p15orig) {
sc_pkcs15_unbind(profile->p15_card);
profile->p15_card = p15orig;
}
return r; return r;
} }
@ -760,6 +776,35 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card,
return r; return r;
} }
int
sc_pkcs15init_store_split_key(struct sc_pkcs15_card *p15card,
struct sc_profile *profile,
struct sc_pkcs15init_prkeyargs *keyargs,
struct sc_pkcs15_object **prk1_obj,
struct sc_pkcs15_object **prk2_obj)
{
unsigned int usage = keyargs->x509_usage;
int r;
/* keyEncipherment|dataEncipherment|keyAgreement */
keyargs->x509_usage = usage & 0x1C;
r = sc_pkcs15init_store_private_key(p15card, profile,
keyargs, prk1_obj);
if (r >= 0) {
/* digitalSignature|nonRepudiation|certSign|cRLSign */
keyargs->x509_usage = usage & 0x63;
/* Prevent pkcs15init from choking on duplicate ID */
keyargs->flags |= SC_PKCS15INIT_SPLIT_KEY;
r = sc_pkcs15init_store_private_key(p15card, profile,
keyargs, prk2_obj);
}
keyargs->x509_usage = usage;
return r;
}
/* /*
* Store a public key * Store a public key
*/ */
@ -1162,13 +1207,17 @@ check_key_compatibility(struct sc_pkcs15_card *p15card,
int int
sc_pkcs15init_requires_restrictive_usage(struct sc_pkcs15_card *p15card, sc_pkcs15init_requires_restrictive_usage(struct sc_pkcs15_card *p15card,
struct sc_pkcs15init_prkeyargs *keyargs) struct sc_pkcs15init_prkeyargs *keyargs,
unsigned int key_length)
{ {
int res; int res;
if (key_length == 0)
key_length = prkey_bits(&keyargs->key);
res = __check_key_compatibility(p15card, &keyargs->key, res = __check_key_compatibility(p15card, &keyargs->key,
keyargs->x509_usage, keyargs->x509_usage,
prkey_bits(&keyargs->key), 0); key_length, 0);
return res < 0; return res < 0;
} }
@ -1479,7 +1528,7 @@ do_get_and_verify_secret(struct sc_profile *pro, struct sc_card *card,
{ {
struct sc_pkcs15_pin_info pin_info; struct sc_pkcs15_pin_info pin_info;
struct sc_cardctl_default_key data; struct sc_cardctl_default_key data;
const char *ident; const char *ident, *label = NULL;
unsigned int pin_id = (unsigned int) -1; unsigned int pin_id = (unsigned int) -1;
size_t defsize = 0; size_t defsize = 0;
u8 defbuf[32]; u8 defbuf[32];
@ -1488,8 +1537,13 @@ do_get_and_verify_secret(struct sc_profile *pro, struct sc_card *card,
ident = "authentication data"; ident = "authentication data";
if (type == SC_AC_CHV) { if (type == SC_AC_CHV) {
ident = "PIN"; ident = "PIN";
memset(&pin_info, 0, sizeof(pin_info));
if (sc_profile_get_pin_id(pro, reference, &pin_id) >= 0) if (sc_profile_get_pin_id(pro, reference, &pin_id) >= 0)
sc_profile_get_pin_info(pro, pin_id, &pin_info); sc_profile_get_pin_info(pro, pin_id, &pin_info);
else {
/* This is all info we have */
pin_info.reference = reference;
}
} else if (type == SC_AC_PRO) { } else if (type == SC_AC_PRO) {
ident = "secure messaging key"; ident = "secure messaging key";
} else if (type == SC_AC_AUT) { } else if (type == SC_AC_AUT) {
@ -1526,25 +1580,44 @@ do_get_and_verify_secret(struct sc_profile *pro, struct sc_card *card,
goto found; goto found;
} }
/* Okay, nothing in our cache. if (type != SC_AC_CHV) {
* Ask the card driver whether it knows a default key for this one /* Okay, nothing in our cache.
*/ * Ask the card driver whether it knows a default key
data.method = type; * for this one.
data.key_ref = reference; */
data.len = sizeof(defbuf); data.method = type;
data.key_data = defbuf; data.key_ref = reference;
if (sc_card_ctl(card, SC_CARDCTL_GET_DEFAULT_KEY, &data) >= 0) data.len = sizeof(defbuf);
defsize = data.len; data.key_data = defbuf;
if (sc_card_ctl(card, SC_CARDCTL_GET_DEFAULT_KEY, &data) >= 0)
defsize = data.len;
} else if (pro->p15_card) {
/* Get the label, if we have one */
struct sc_pkcs15_object *obj;
int r;
r = sc_pkcs15_find_pin_by_reference(pro->p15_card,
reference, &obj);
if (r >= 0 && obj->label[0])
label = obj->label;
}
if (callbacks) { if (callbacks) {
if (pin_id != -1 && callbacks->get_pin) { switch (type) {
r = callbacks->get_pin(pro, pin_id, &pin_info, case SC_AC_CHV:
pinbuf, pinsize); if (callbacks->get_pin) {
} else r = callbacks->get_pin(pro, pin_id,
if (pin_id == -1 && callbacks->get_key) { &pin_info, label,
r = callbacks->get_key(pro, type, reference, pinbuf, pinsize);
defbuf, defsize, }
pinbuf, pinsize); break;
default:
if (callbacks->get_key) {
r = callbacks->get_key(pro, type, reference,
defbuf, defsize,
pinbuf, pinsize);
}
break;
} }
} }