Merge remote branch 'upstream/master'
This commit is contained in:
commit
40cb1c9e35
|
@ -70,26 +70,33 @@ typedef struct sc_pkcs15_id sc_pkcs15_id_t;
|
|||
#define SC_PKCS15_PIN_TYPE_ISO9564_1 4
|
||||
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_PIN 0
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_AUTH_KEY 1
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_SM_KEY 2
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_BIOMETRIC 1
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_AUTH_KEY 2
|
||||
#define SC_PKCS15_PIN_AUTH_TYPE_SM_KEY 3
|
||||
|
||||
/* PinAttributes as they defined in PKCS#15 v1.1 for PIN authentication object */
|
||||
struct sc_pkcs15_pin_attributes {
|
||||
unsigned int flags, type;
|
||||
size_t min_length, stored_length, max_length;
|
||||
int reference;
|
||||
u8 pad_char;
|
||||
};
|
||||
/* AuthKeyAttributes of the authKey authentication object */
|
||||
struct sc_pkcs15_authkey_attributes {
|
||||
int derived;
|
||||
struct sc_pkcs15_id skey_id;
|
||||
};
|
||||
/* BiometricAttributes of the biometricTemplate authentication object */
|
||||
struct sc_pkcs15_biometric_attributes {
|
||||
unsigned int flags;
|
||||
struct sc_object_id template_id;
|
||||
/* ... */
|
||||
};
|
||||
struct sc_pkcs15_auth_info {
|
||||
/* CommonAuthenticationObjectAttributes */
|
||||
struct sc_pkcs15_id auth_id;
|
||||
|
||||
/* AuthObjectAttributes */
|
||||
struct sc_path path;
|
||||
unsigned auth_type;
|
||||
union {
|
||||
|
@ -97,7 +104,10 @@ struct sc_pkcs15_auth_info {
|
|||
struct sc_pkcs15_biometric_attributes bio;
|
||||
struct sc_pkcs15_authkey_attributes authkey;
|
||||
} attrs;
|
||||
|
||||
/* authentication method: CHV, SEN, SYMBOLIC, ... */
|
||||
unsigned int auth_method;
|
||||
|
||||
int tries_left, max_tries;
|
||||
};
|
||||
typedef struct sc_pkcs15_auth_info sc_pkcs15_auth_info_t;
|
||||
|
|
|
@ -1411,6 +1411,18 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
|
|||
return CKR_OK;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
pkcs15_check_bool_cka(CK_ATTRIBUTE_PTR attr, unsigned long flag)
|
||||
{
|
||||
if (attr->ulValueLen != sizeof(CK_BBOOL) || !attr->pValue)
|
||||
return 0;
|
||||
|
||||
if (*((CK_BBOOL *)attr->pValue))
|
||||
return flag;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,
|
||||
struct sc_pkcs11_slot *slot,
|
||||
struct sc_profile *profile,
|
||||
|
@ -1493,7 +1505,21 @@ static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,
|
|||
if (key_type == CKK_GOSTR3410)
|
||||
bn = &gost->d;
|
||||
break;
|
||||
|
||||
case CKA_SIGN:
|
||||
args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_SIGN);
|
||||
break;
|
||||
case CKA_SIGN_RECOVER:
|
||||
args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_SIGNRECOVER);
|
||||
break;
|
||||
case CKA_DECRYPT:
|
||||
args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_DECRYPT);
|
||||
break;
|
||||
case CKA_UNWRAP:
|
||||
args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_UNWRAP);
|
||||
break;
|
||||
case OPENSC_CKA_NON_REPUDIATION:
|
||||
args.usage |= pkcs15_check_bool_cka(attr, SC_PKCS15_PRKEY_USAGE_NONREPUDIATION);
|
||||
break;
|
||||
default:
|
||||
/* ignore unknown attrs, or flag error? */
|
||||
continue;
|
||||
|
|
|
@ -2,5 +2,11 @@
|
|||
#define PKCS11_OPENSC_H
|
||||
|
||||
/* OpenSC specific extensions */
|
||||
/*
|
||||
* In PKCS#11 there is no CKA_ attribute dedicated to the NON-REPUDIATION flag.
|
||||
* We need this flag in PKCS#15/libopensc to make dinstinction between
|
||||
* 'signature' and 'qualified signature' key slots.
|
||||
*/
|
||||
#define OPENSC_CKA_NON_REPUDIATION (CKA_VENDOR_DEFINED | 1UL)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,6 +62,7 @@ static int cardos_extract_pubkey(sc_card_t *, sc_pkcs15_pubkey_t *,
|
|||
sc_file_t *, int);
|
||||
static int do_cardos_extract_pubkey(sc_card_t *card, int nr, u8 tag,
|
||||
sc_pkcs15_bignum_t *bn);
|
||||
static int cardos_have_verifyrc_package(sc_card_t *card);
|
||||
|
||||
/* Object IDs for PIN objects.
|
||||
* SO PIN = 0x01, SO PUK = 0x02
|
||||
|
@ -413,7 +414,7 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card,
|
|||
unsigned char pinpadded[256];
|
||||
struct tlv tlv;
|
||||
unsigned int attempts, minlen, maxlen;
|
||||
int r;
|
||||
int r, hasverifyrc;
|
||||
|
||||
if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
|
||||
return SC_ERROR_OBJECT_NOT_VALID;
|
||||
|
@ -445,6 +446,10 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card,
|
|||
/* parameters */
|
||||
tlv_next(&tlv, 0x85);
|
||||
tlv_add(&tlv, 0x02); /* options byte */
|
||||
hasverifyrc = cardos_have_verifyrc_package(card);
|
||||
if (hasverifyrc == 1)
|
||||
/* Use 9 byte OCI parameters to be able to set VerifyRC bit */
|
||||
tlv_add(&tlv, 0x04); /* options_2 byte with bit 2 set to return CurrentErrorCounter */
|
||||
tlv_add(&tlv, attempts & 0xf); /* flags byte */
|
||||
tlv_add(&tlv, CARDOS_ALGO_PIN); /* algorithm = pin-test */
|
||||
tlv_add(&tlv, attempts & 0xf); /* errcount = attempts */
|
||||
|
@ -786,6 +791,56 @@ static int cardos_extract_pubkey(sc_card_t *card, sc_pkcs15_pubkey_t *pubkey,
|
|||
return r;
|
||||
}
|
||||
|
||||
static int cardos_have_verifyrc_package(sc_card_t *card)
|
||||
{
|
||||
sc_apdu_t apdu;
|
||||
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
|
||||
int r;
|
||||
const u8 *p = rbuf, *q;
|
||||
size_t len, tlen = 0, ilen = 0;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88);
|
||||
apdu.resp = rbuf;
|
||||
apdu.resplen = sizeof(rbuf);
|
||||
apdu.lc = 0;
|
||||
apdu.le = 256;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
|
||||
|
||||
if ((len = apdu.resplen) == 0)
|
||||
/* looks like no package has been installed */
|
||||
return 0;
|
||||
|
||||
while (len != 0) {
|
||||
p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
if (card->type == SC_CARD_TYPE_CARDOS_M4_3) {
|
||||
/* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */
|
||||
/* and Package Number 0x07 */
|
||||
q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen);
|
||||
if (q == NULL || ilen != 4)
|
||||
return 0;
|
||||
if (q[0] == 0x07)
|
||||
return 1;
|
||||
} else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) {
|
||||
/* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03 */
|
||||
/* and Package Number 0x02 */
|
||||
q = sc_asn1_find_tag(card->ctx, p, tlen, 0x03, &ilen);
|
||||
if (q == NULL || ilen != 4)
|
||||
return 0;
|
||||
if (q[0] == 0x02)
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
p += tlen;
|
||||
len -= tlen + 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sc_pkcs15init_operations sc_pkcs15init_cardos_operations = {
|
||||
cardos_erase,
|
||||
NULL, /* init_card */
|
||||
|
|
Loading…
Reference in New Issue