- 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:
parent
a3d81aa980
commit
7b34c2ecf7
|
@ -83,6 +83,7 @@ struct sc_pkcs15init_callbacks {
|
|||
*/
|
||||
int (*get_pin)(struct sc_profile *, int,
|
||||
const struct sc_pkcs15_pin_info *,
|
||||
const char *label,
|
||||
u8 *, size_t *);
|
||||
|
||||
/*
|
||||
|
@ -177,6 +178,11 @@ extern int sc_pkcs15init_store_private_key(struct sc_pkcs15_card *,
|
|||
struct sc_profile *,
|
||||
struct sc_pkcs15init_prkeyargs *,
|
||||
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 *,
|
||||
struct sc_profile *,
|
||||
struct sc_pkcs15init_pubkeyargs *,
|
||||
|
@ -225,7 +231,8 @@ extern int sc_pkcs15init_rmdir(struct sc_card *, struct sc_profile *,
|
|||
/* Helper function for CardOS */
|
||||
extern int sc_pkcs15init_requires_restrictive_usage(
|
||||
struct sc_pkcs15_card *,
|
||||
struct sc_pkcs15init_prkeyargs *);
|
||||
struct sc_pkcs15init_prkeyargs *,
|
||||
unsigned int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -206,15 +206,27 @@ sc_pkcs15init_erase_card_recursively(struct sc_card *card,
|
|||
struct sc_profile *profile,
|
||||
int so_pin_ref)
|
||||
{
|
||||
struct sc_pkcs15_card *p15orig = profile->p15_card;
|
||||
struct sc_pkcs15_pin_info sopin, temp;
|
||||
struct sc_file *df = profile->df_info->file, *dir;
|
||||
int r;
|
||||
|
||||
/* Frob: need to tell the upper layers about the SO PIN id */
|
||||
sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin);
|
||||
temp = sopin;
|
||||
temp.reference = so_pin_ref;
|
||||
sc_profile_set_pin_info(profile, SC_PKCS15INIT_SO_PIN, &temp);
|
||||
if (so_pin_ref != -1) {
|
||||
temp = sopin;
|
||||
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
|
||||
* 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 */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -760,6 +776,35 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card,
|
|||
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
|
||||
*/
|
||||
|
@ -1162,13 +1207,17 @@ check_key_compatibility(struct sc_pkcs15_card *p15card,
|
|||
|
||||
int
|
||||
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;
|
||||
|
||||
if (key_length == 0)
|
||||
key_length = prkey_bits(&keyargs->key);
|
||||
|
||||
res = __check_key_compatibility(p15card, &keyargs->key,
|
||||
keyargs->x509_usage,
|
||||
prkey_bits(&keyargs->key), 0);
|
||||
key_length, 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_cardctl_default_key data;
|
||||
const char *ident;
|
||||
const char *ident, *label = NULL;
|
||||
unsigned int pin_id = (unsigned int) -1;
|
||||
size_t defsize = 0;
|
||||
u8 defbuf[32];
|
||||
|
@ -1488,8 +1537,13 @@ do_get_and_verify_secret(struct sc_profile *pro, struct sc_card *card,
|
|||
ident = "authentication data";
|
||||
if (type == SC_AC_CHV) {
|
||||
ident = "PIN";
|
||||
memset(&pin_info, 0, sizeof(pin_info));
|
||||
if (sc_profile_get_pin_id(pro, reference, &pin_id) >= 0)
|
||||
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) {
|
||||
ident = "secure messaging key";
|
||||
} 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;
|
||||
}
|
||||
|
||||
/* Okay, nothing in our cache.
|
||||
* Ask the card driver whether it knows a default key for this one
|
||||
*/
|
||||
data.method = type;
|
||||
data.key_ref = reference;
|
||||
data.len = sizeof(defbuf);
|
||||
data.key_data = defbuf;
|
||||
if (sc_card_ctl(card, SC_CARDCTL_GET_DEFAULT_KEY, &data) >= 0)
|
||||
defsize = data.len;
|
||||
if (type != SC_AC_CHV) {
|
||||
/* Okay, nothing in our cache.
|
||||
* Ask the card driver whether it knows a default key
|
||||
* for this one.
|
||||
*/
|
||||
data.method = type;
|
||||
data.key_ref = reference;
|
||||
data.len = sizeof(defbuf);
|
||||
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 (pin_id != -1 && callbacks->get_pin) {
|
||||
r = callbacks->get_pin(pro, pin_id, &pin_info,
|
||||
pinbuf, pinsize);
|
||||
} else
|
||||
if (pin_id == -1 && callbacks->get_key) {
|
||||
r = callbacks->get_key(pro, type, reference,
|
||||
defbuf, defsize,
|
||||
pinbuf, pinsize);
|
||||
switch (type) {
|
||||
case SC_AC_CHV:
|
||||
if (callbacks->get_pin) {
|
||||
r = callbacks->get_pin(pro, pin_id,
|
||||
&pin_info, label,
|
||||
pinbuf, pinsize);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (callbacks->get_key) {
|
||||
r = callbacks->get_key(pro, type, reference,
|
||||
defbuf, defsize,
|
||||
pinbuf, pinsize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue