📄 framework-pkcs15.c
字号:
return sc_to_cryptoki_error(rv, ses->slot->card->reader); rv = revalidate_pin(data, ses); if (rv == 0) rv = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags, pData, ulDataLen, pSignature, *pulDataLen); sc_unlock(ses->slot->card->card); } sc_debug(context, "Sign complete. Result %d.\n", rv); if (rv > 0) { *pulDataLen = rv; return CKR_OK; } return sc_to_cryptoki_error(rv, ses->slot->card->reader);}static CK_RVpkcs15_prkey_unwrap(struct sc_pkcs11_session *ses, void *obj, CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, void **result){ struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data; struct pkcs15_prkey_object *prkey; struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data); u8 unwrapped_key[256]; int rv; sc_debug(context, "Initiating key unwrap.\n"); /* See which of the alternative keys supports unwrap */ prkey = (struct pkcs15_prkey_object *) obj; while (prkey && !(prkey->prv_info->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP))) prkey = prkey->prv_next; if (prkey == NULL) return CKR_KEY_FUNCTION_NOT_PERMITTED; if (pMechanism->mechanism != CKM_RSA_PKCS) return CKR_MECHANISM_INVALID; rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, SC_ALGORITHM_RSA_PAD_PKCS1, pData, ulDataLen, unwrapped_key, sizeof(unwrapped_key)); /* Do we have to try a re-login and then try to decrypt again? */ if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { /* Ensure that revalidate_pin() doesn't do a final sc_unlock() that would clear the card's current_path */ rv = sc_lock(ses->slot->card->card); if (rv < 0) return sc_to_cryptoki_error(rv, ses->slot->card->reader); rv = revalidate_pin(data, ses); if (rv == 0) rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, SC_ALGORITHM_RSA_PAD_PKCS1, pData, ulDataLen, unwrapped_key, sizeof(unwrapped_key)); sc_unlock(ses->slot->card->card); } sc_debug(context, "Key unwrap complete. Result %d.\n", rv); if (rv < 0) return sc_to_cryptoki_error(rv, ses->slot->card->reader); return sc_pkcs11_create_secret_key(ses, unwrapped_key, rv, pTemplate, ulAttributeCount, (struct sc_pkcs11_object **) result);}struct sc_pkcs11_object_ops pkcs15_prkey_ops = { pkcs15_prkey_release, pkcs15_prkey_set_attribute, pkcs15_prkey_get_attribute, sc_pkcs11_any_cmp_attribute, NULL, NULL, pkcs15_prkey_sign, pkcs15_prkey_unwrap};/* * PKCS#15 RSA Public Key Object */void pkcs15_pubkey_release(void *object){ struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object; struct sc_pkcs15_pubkey *key_data = pubkey->pub_data; if (__pkcs15_release_object((struct pkcs15_any_object *) object) == 0) sc_pkcs15_free_pubkey(key_data);}CK_RV pkcs15_pubkey_set_attribute(struct sc_pkcs11_session *session, void *object, CK_ATTRIBUTE_PTR attr){ struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object; return pkcs15_set_attrib(session, pubkey->base.p15_object, attr);}CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ATTRIBUTE_PTR attr){ struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object; struct pkcs15_cert_object *cert = pubkey->pub_cert; size_t len; switch (attr->type) { case CKA_CLASS: check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS)); *(CK_OBJECT_CLASS*)attr->pValue = CKO_PUBLIC_KEY; break; case CKA_TOKEN: case CKA_LOCAL: case CKA_SENSITIVE: case CKA_ALWAYS_SENSITIVE: case CKA_NEVER_EXTRACTABLE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = TRUE; break; case CKA_PRIVATE: case CKA_MODIFIABLE: case CKA_EXTRACTABLE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = FALSE; break; case CKA_LABEL: if (pubkey->pub_p15obj) { len = strlen(pubkey->pub_p15obj->label); check_attribute_buffer(attr, len); memcpy(attr->pValue, pubkey->pub_p15obj->label, len); } else if (cert && cert->cert_p15obj) { len = strlen(cert->cert_p15obj->label); check_attribute_buffer(attr, len); memcpy(attr->pValue, cert->cert_p15obj->label, len); } else { return CKR_ATTRIBUTE_TYPE_INVALID; } break; case CKA_KEY_TYPE: check_attribute_buffer(attr, sizeof(CK_KEY_TYPE)); *(CK_KEY_TYPE*)attr->pValue = CKK_RSA; break; case CKA_ID: if (pubkey->pub_info) { check_attribute_buffer(attr, pubkey->pub_info->id.len); memcpy(attr->pValue, pubkey->pub_info->id.value, pubkey->pub_info->id.len); } else if (cert && cert->cert_info) { check_attribute_buffer(attr, cert->cert_info->id.len); memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len); } else { return CKR_ATTRIBUTE_TYPE_INVALID; } break; case CKA_KEY_GEN_MECHANISM: check_attribute_buffer(attr, sizeof(CK_MECHANISM_TYPE)); *(CK_MECHANISM_TYPE*)attr->pValue = CK_UNAVAILABLE_INFORMATION; break; case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_SIGN: case CKA_SIGN_RECOVER: case CKA_WRAP: case CKA_UNWRAP: case CKA_VERIFY: case CKA_VERIFY_RECOVER: case CKA_DERIVE: if (pubkey->pub_info) { return get_usage_bit(pubkey->pub_info->usage, attr); } else { return get_usage_bit(SC_PKCS15_PRKEY_USAGE_ENCRYPT |SC_PKCS15_PRKEY_USAGE_VERIFY |SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER, attr); } case CKA_MODULUS: return get_modulus(pubkey->pub_data, attr); case CKA_MODULUS_BITS: return get_modulus_bits(pubkey->pub_data, attr); case CKA_PUBLIC_EXPONENT: return get_public_exponent(pubkey->pub_data, attr); case CKA_VALUE: if (pubkey->pub_data) { check_attribute_buffer(attr, pubkey->pub_data->data.len); memcpy(attr->pValue, pubkey->pub_data->data.value, pubkey->pub_data->data.len); } else if (cert && cert->cert_data) { check_attribute_buffer(attr, cert->cert_data->data_len); memcpy(attr->pValue, cert->cert_data->data, cert->cert_data->data_len); } break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } return CKR_OK;}struct sc_pkcs11_object_ops pkcs15_pubkey_ops = { pkcs15_pubkey_release, pkcs15_pubkey_set_attribute, pkcs15_pubkey_get_attribute, sc_pkcs11_any_cmp_attribute, NULL, NULL, NULL};/* * get_attribute helpers */static CK_RVget_bignum(sc_pkcs15_bignum_t *bn, CK_ATTRIBUTE_PTR attr){ check_attribute_buffer(attr, bn->len); memcpy(attr->pValue, bn->data, bn->len); return CKR_OK;}static CK_RVget_bignum_bits(sc_pkcs15_bignum_t *bn, CK_ATTRIBUTE_PTR attr){ CK_ULONG bits, mask; bits = bn->len * 8; for (mask = 0x80; mask; mask >>= 1, bits--) { if (bn->data[0] & mask) break; } check_attribute_buffer(attr, sizeof(bits)); *(CK_ULONG *) attr->pValue = bits; return CKR_OK;}static CK_RVget_modulus(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr){ if (key == NULL) return CKR_ATTRIBUTE_TYPE_INVALID; switch (key->algorithm) { case SC_ALGORITHM_RSA: return get_bignum(&key->u.rsa.modulus, attr); } return CKR_ATTRIBUTE_TYPE_INVALID;}static CK_RVget_modulus_bits(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr){ if (key == NULL) return CKR_ATTRIBUTE_TYPE_INVALID; switch (key->algorithm) { case SC_ALGORITHM_RSA: return get_bignum_bits(&key->u.rsa.modulus, attr); } return CKR_ATTRIBUTE_TYPE_INVALID;}static CK_RVget_public_exponent(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr){ if (key == NULL) return CKR_ATTRIBUTE_TYPE_INVALID; switch (key->algorithm) { case SC_ALGORITHM_RSA: return get_bignum(&key->u.rsa.exponent, attr); } return CKR_ATTRIBUTE_TYPE_INVALID;}/* * Map pkcs15 usage bits to pkcs11 usage attributes. * * It's not totally clear to me whether SC_PKCS15_PRKEY_USAGE_NONREPUDIATION should * be treated as being equivalent with CKA_SIGN or not... */static CK_RVget_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr){ static struct { CK_ATTRIBUTE_TYPE type; unsigned int flag; } flag_mapping[] = { { CKA_ENCRYPT, SC_PKCS15_PRKEY_USAGE_ENCRYPT }, { CKA_DECRYPT, SC_PKCS15_PRKEY_USAGE_DECRYPT }, { CKA_SIGN, SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_NONREPUDIATION }, { CKA_SIGN_RECOVER, SC_PKCS15_PRKEY_USAGE_SIGNRECOVER }, { CKA_WRAP, SC_PKCS15_PRKEY_USAGE_WRAP }, { CKA_UNWRAP, SC_PKCS15_PRKEY_USAGE_UNWRAP }, { CKA_VERIFY, SC_PKCS15_PRKEY_USAGE_VERIFY }, { CKA_VERIFY_RECOVER, SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER }, { CKA_DERIVE, SC_PKCS15_PRKEY_USAGE_DERIVE }, { 0, 0 } }; unsigned int mask = 0, j; for (j = 0; (mask = flag_mapping[j].flag) != 0; j++) { if (flag_mapping[j].type == attr->type) break; } if (mask == 0) return CKR_ATTRIBUTE_TYPE_INVALID; check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = (usage & mask)? TRUE : FALSE; return CKR_OK;}static CK_RVasn1_sequence_wrapper(const u8 *data, size_t len, CK_ATTRIBUTE_PTR attr){ u8 *dest; unsigned int n; size_t len2; len2 = len; check_attribute_buffer(attr, len + 1 + sizeof(len)); dest = (u8 *) attr->pValue; *dest++ = 0x30; /* SEQUENCE tag */ if (len <= 127) { *dest++ = len; } else { for (n = 4; (len & 0xFF000000) == 0; n--) len <<= 8; *dest++ = 0x80 + n; while (n--) { *dest++ = len >> 24; len <<= 8; } } memcpy(dest, data, len2); attr->ulValueLen = (dest - (u8 *) attr->pValue) + len2; return CKR_OK;}static voidcache_pin(void *p, int user, const void *pin, size_t len){ struct pkcs15_slot_data *data = (struct pkcs15_slot_data *) p; if ((user != 0 && user != 1) || !sc_pkcs11_conf.cache_pins) return; memset(data->pin + user, 0, sizeof(data->pin[user])); if (len && len <= MAX_CACHE_PIN) { memcpy(data->pin[user].value, pin, len); data->pin[user].len = len; }}static intrevalidate_pin(struct pkcs15_slot_data *data, struct sc_pkcs11_session *ses){ int rv; u8 value[MAX_CACHE_PIN]; sc_debug(context, "revalidate_pin called\n"); if (!sc_pkcs11_conf.cache_pins && !(ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; if (ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER, NULL, 0); else { memcpy(value, data->pin[CKU_USER].value, data->pin[CKU_USER].len); rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER, value, data->pin[CKU_USER].len); } if (rv != CKR_OK) sc_debug(context, "Re-login failed: 0x%0x (%d)\n", rv, rv); return rv;}/* * Mechanism handling * FIXME: We should consult the card's algorithm list to * find out what operations it supports */intregister_mechanisms(struct sc_pkcs11_card *p11card){ sc_card_t *card = p11card->card; sc_algorithm_info_t *alg_info; CK_MECHANISM_INFO mech_info; sc_pkcs11_mechanism_type_t *mt; unsigned int num; int rc, flags = 0; /* Register generic mechanisms */ sc_pkcs11_register_generic_mechanisms(p11card); mech_info.flags = CKF_HW | CKF_SIGN | CKF_UNWRAP;#ifdef HAVE_OPENSSL mech_info.flags |= CKF_VERIFY;#endif mech_info.ulMinKeySize = ~0; mech_info.ulMaxKeySize = 0; /* For now, we just OR all the algorithm specific * flags, based on the assumption that cards don't * support different modes for different key sizes */ num = card->algorithm_count; alg_info = card->algorithms; while (num--) { if (alg_info->algorithm != SC_ALGORITHM_RSA) continue; if (alg_info->key_length < mech_info.ulMinKeySize) mech_info.ulMinKeySize = alg_info->key_length; if (alg_info->key_length > mech_info.ulMaxKeySize) mech_info.ulMaxKeySize = alg_info->key_length; flags |= alg_info->flags; alg_info++; } /* Check if we support raw RSA */ if (flags & SC_ALGORITHM_RSA_RAW) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL); rc = sc_pkcs11_register_mechanism(p11card, mt); if (rc != CKR_OK) return rc; /* If the card supports RAW, it should
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -