📄 framework-pkcs15.c
字号:
__pkcs15_create_prkey_object(fw_data, key_obj, &key_any_obj); pkcs15_add_object(slot, key_any_obj, phObject); rv = CKR_OK;out: return rv;}static CK_RV pkcs15_create_public_key(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot, struct sc_profile *profile, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject){ struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data; struct sc_pkcs15init_pubkeyargs args; struct pkcs15_any_object *key_any_obj; struct sc_pkcs15_object *key_obj; struct sc_pkcs15_pin_info *pin; CK_KEY_TYPE key_type; struct sc_pkcs15_pubkey_rsa *rsa; int rc, rv; memset(&args, 0, sizeof(args)); /* See if the "slot" is pin protected. If so, get the * PIN id */ if ((pin = slot_data_pin_info(slot->fw_data)) != NULL) args.auth_id = pin->auth_id; /* Get the key type */ rv = attr_find(pTemplate, ulCount, CKA_KEY_TYPE, &key_type, NULL); if (rv != CKR_OK) return rv; if (key_type != CKK_RSA) return CKR_ATTRIBUTE_VALUE_INVALID; args.key.algorithm = SC_ALGORITHM_RSA; rsa = &args.key.u.rsa; rv = CKR_OK; while (ulCount--) { CK_ATTRIBUTE_PTR attr = pTemplate++; sc_pkcs15_bignum_t *bn = NULL; switch (attr->type) { /* Skip attrs we already know or don't care for */ case CKA_CLASS: case CKA_KEY_TYPE: case CKA_MODULUS_BITS: case CKA_PRIVATE: break; case CKA_LABEL: args.label = (char *) attr->pValue; break; case CKA_ID: args.id.len = sizeof(args.id.value); rv = attr_extract(attr, args.id.value, &args.id.len); if (rv != CKR_OK) goto out; break; case CKA_MODULUS: bn = &rsa->modulus; break; case CKA_PUBLIC_EXPONENT: bn = &rsa->exponent; break; default: /* ignore unknown attrs, or flag error? */ continue; } if (bn) { if (attr->ulValueLen > 1024) return CKR_ATTRIBUTE_VALUE_INVALID; bn->len = attr->ulValueLen; bn->data = (u8 *) attr->pValue; } } if (!rsa->modulus.len || !rsa->exponent.len) { rv = CKR_TEMPLATE_INCOMPLETE; goto out; } rc = sc_pkcs15init_store_public_key(fw_data->p15_card, profile, &args, &key_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, p11card->reader); goto out; } /* Create a new pkcs11 object for it */ __pkcs15_create_pubkey_object(fw_data, key_obj, &key_any_obj); pkcs15_add_object(slot, key_any_obj, phObject); rv = CKR_OK;out: return rv;}static CK_RV pkcs15_create_certificate(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot, struct sc_profile *profile, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject){ struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data; struct sc_pkcs15init_certargs args; struct pkcs15_any_object *cert_any_obj; struct sc_pkcs15_object *cert_obj; CK_CERTIFICATE_TYPE cert_type; CK_BBOOL bValue; int rc, rv; memset(&args, 0, sizeof(args)); /* Get the key type */ rv = attr_find(pTemplate, ulCount, CKA_CERTIFICATE_TYPE, &cert_type, NULL); if (rv != CKR_OK) return rv; if (cert_type != CKC_X_509) return CKR_ATTRIBUTE_VALUE_INVALID; rv = CKR_OK; while (ulCount--) { CK_ATTRIBUTE_PTR attr = pTemplate++; switch (attr->type) { /* Skip attrs we already know or don't care for */ case CKA_CLASS: break; case CKA_PRIVATE: rv = attr_extract(attr, &bValue, NULL); if (bValue) { rv = CKR_TEMPLATE_INCONSISTENT; goto out; } break; case CKA_LABEL: args.label = (char *) attr->pValue; break; case CKA_ID: args.id.len = sizeof(args.id.value); rv = attr_extract(attr, args.id.value, &args.id.len); if (rv != CKR_OK) goto out; break; case CKA_VALUE: args.der_encoded.len = attr->ulValueLen; args.der_encoded.value = (u8 *) attr->pValue; break; default: /* ignore unknown attrs, or flag error? */ continue; } } if (args.der_encoded.len == 0) { rv = CKR_TEMPLATE_INCOMPLETE; goto out; } rc = sc_pkcs15init_store_certificate(fw_data->p15_card, profile, &args, &cert_obj); if (rc < 0) { rv = sc_to_cryptoki_error(rc, p11card->reader); goto out; } /* Create a new pkcs11 object for it */ __pkcs15_create_cert_object(fw_data, cert_obj, &cert_any_obj); pkcs15_add_object(slot, cert_any_obj, phObject); rv = CKR_OK;out: return rv;}static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject){ struct sc_profile *profile = NULL; struct pkcs15_slot_data *data; CK_OBJECT_CLASS _class; int rv, rc; rv = attr_find(pTemplate, ulCount, CKA_CLASS, &_class, NULL); if (rv != CKR_OK) return rv; /* Bind the profile */ rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile); if (rc < 0) return sc_to_cryptoki_error(rc, p11card->reader); rc = sc_lock(p11card->card); if (rc < 0) { sc_pkcs15init_unbind(profile); return sc_to_cryptoki_error(rc, p11card->reader); } /* Add the PINs the user presented so far. Some initialization * routines need to present these PINs again because some * card operations may clobber the authentication state * (the GPK for instance) */ data = slot_data(slot->fw_data); if (data->pin[CKU_SO].len) sc_pkcs15init_set_pin_data(profile, SC_PKCS15INIT_SO_PIN, data->pin[CKU_SO].value, data->pin[CKU_SO].len); if (data->pin[CKU_USER].len) sc_pkcs15init_set_pin_data(profile, SC_PKCS15INIT_USER_PIN, data->pin[CKU_USER].value, data->pin[CKU_USER].len); switch (_class) { case CKO_PRIVATE_KEY: rv = pkcs15_create_private_key(p11card, slot, profile, pTemplate, ulCount, phObject); break; case CKO_PUBLIC_KEY: rv = pkcs15_create_public_key(p11card, slot, profile, pTemplate, ulCount, phObject); break; case CKO_CERTIFICATE: rv = pkcs15_create_certificate(p11card, slot, profile, pTemplate, ulCount, phObject); break; default: rv = CKR_FUNCTION_NOT_SUPPORTED; } sc_unlock(p11card->card); sc_pkcs15init_unbind(profile); return rv;}static CK_RVget_X509_usage_privk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x509_usage){ CK_ULONG i; for (i = 0; i < ulCount; i++) { CK_ATTRIBUTE_TYPE typ = pTempl[i].type; CK_BBOOL *val = (CK_BBOOL *) pTempl[i].pValue; if (val == NULL) continue; if (typ == CKA_SIGN && *val) *x509_usage |= 1; if (typ == CKA_UNWRAP && *val) *x509_usage |= 4; if (typ == CKA_DECRYPT && *val) *x509_usage |= 8; if (typ == CKA_DERIVE && *val) *x509_usage |= 16; if (typ == CKA_VERIFY || typ == CKA_WRAP || typ == CKA_ENCRYPT) { sc_debug(context, "get_X509_usage_privk(): invalid typ = 0x%0x\n", typ); return CKR_ATTRIBUTE_TYPE_INVALID; } } return CKR_OK;}static CK_RVget_X509_usage_pubk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x509_usage){ CK_ULONG i; for (i = 0; i < ulCount; i++) { CK_ATTRIBUTE_TYPE typ = pTempl[i].type; CK_BBOOL *val = (CK_BBOOL *) pTempl[i].pValue; if (val == NULL) continue; if (typ == CKA_VERIFY && *val) *x509_usage |= 1; if (typ == CKA_WRAP && *val) *x509_usage |= 4; if (typ == CKA_ENCRYPT && *val) *x509_usage |= 8; if (typ == CKA_DERIVE && *val) *x509_usage |= 16; if (typ == CKA_SIGN || typ == CKA_UNWRAP || typ == CKA_DECRYPT) { sc_debug(context, "get_X509_usage_pubk(): invalid typ = 0x%0x\n", typ); return CKR_ATTRIBUTE_TYPE_INVALID; } } return CKR_OK;}/* FIXME: check for the public exponent in public key template and use this value */CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPubTpl, CK_ULONG ulPubCnt, CK_ATTRIBUTE_PTR pPrivTpl, CK_ULONG ulPrivCnt, CK_OBJECT_HANDLE_PTR phPubKey, CK_OBJECT_HANDLE_PTR phPrivKey) /* gets priv. key handle */{ struct sc_profile *profile = NULL; struct sc_pkcs15_pin_info *pin; struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data; struct pkcs15_slot_data *p15_data = slot_data(slot->fw_data); struct sc_pkcs15_card *p15card = fw_data->p15_card; struct sc_pkcs15init_prkeyargs priv_args; struct sc_pkcs15init_pubkeyargs pub_args; struct sc_pkcs15_object *priv_key_obj; struct sc_pkcs15_object *pub_key_obj; struct pkcs15_any_object *priv_any_obj; struct pkcs15_any_object *pub_any_obj; struct sc_pkcs15_id id; size_t len; CK_KEY_TYPE keytype = CKK_RSA; CK_ULONG keybits; char pub_label[SC_PKCS15_MAX_LABEL_SIZE]; char priv_label[SC_PKCS15_MAX_LABEL_SIZE]; int rc, rv = CKR_OK; sc_debug(context, "Keypair generation, mech = 0x%0x\n", pMechanism->mechanism); if (pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN) return CKR_MECHANISM_INVALID; rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile); if (rc < 0) return sc_to_cryptoki_error(rc, p11card->reader); memset(&priv_args, 0, sizeof(priv_args)); memset(&pub_args, 0, sizeof(pub_args)); rc = sc_lock(p11card->card); if (rc < 0) { sc_pkcs15init_unbind(profile); return sc_to_cryptoki_error(rc, p11card->reader); } /* 1. Convert the pkcs11 attributes to pkcs15init args */ if ((pin = slot_data_pin_info(slot->fw_data)) != NULL) priv_args.auth_id = pub_args.auth_id = pin->auth_id; rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_KEY_TYPE, &keytype, NULL); if (rv == CKR_OK && keytype != CKK_RSA) { rv = CKR_ATTRIBUTE_VALUE_INVALID; goto kpgen_done; } priv_args.key.algorithm = pub_args.key.algorithm = SC_ALGORITHM_RSA; rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_MODULUS_BITS, &keybits, NULL); if (rv != CKR_OK) keybits = 1024; /* Default key size */ /* To do: check allowed values of keybits */ id.len = SC_PKCS15_MAX_ID_SIZE; rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_ID, &id.value, &id.len); if (rv == CKR_OK) priv_args.id = pub_args.id = id; len = sizeof(priv_label); rv = attr_find(pPrivTpl, ulPrivCnt, CKA_LABEL, priv_label, &len); if (rv == CKR_OK) { priv_label[SC_PKCS15_MAX_LABEL_SIZE - 1] = '\0'; priv_args.label = priv_label; } len = sizeof(pub_label); rv = attr_find(pPubTpl, ulPubCnt, CKA_LABEL, pub_label, &len); if (rv == CKR_OK) { pub_label[SC_PKCS15_MAX_LABEL_SIZE - 1] = '\0'; pub_args.label = pub_label; } rv = get_X509_usage_privk(pPrivTpl, ulPrivCnt, &priv_args.x509_usage); if (rv == CKR_OK) rv = get_X509_usage_pubk(pPubTpl, ulPubCnt, &priv_args.x509_usage); if (rv != CKR_OK) goto kpgen_done; pub_args.x509_usage = priv_args.x509_usage; /* 2. Add the PINs the user presented so far. Some initialization * routines need to present these PINs again because some * card operations may clobber the authentication state * (the GPK for instance) */ if (p15_data->pin[CKU_SO].len) sc_pkcs15init_set_pin_data(profile, SC_PKCS15INIT_SO_PIN, p15_data->pin[CKU_SO].value, p15_data->pin[CKU_SO].len); if (p15_data->pin[CKU_USER].len) sc_pkcs15init_set_pin_data(profile, SC_PKCS15INIT_USER_PIN, p15_data->pin[CKU_USER].value, p15_data->pin[CKU_USER].len); /* 3.a Try on-card key pair generation */ rc = sc_pkcs15init_generate_key(fw_data->p15_card, profile, &priv_args, keybits, &priv_key_obj); if (rc >= 0) { id = ((struct sc_pkcs15_prkey_info *) priv_key_obj->data)->id; rc = sc_pkcs15_find_pubkey_by_id(fw_data->p15_card, &id, &pub_key_obj); if (rc != 0) { sc_debug(context, "sc_pkcs15_find_pubkey_by_id returned %d\n", rc); rv = sc_to_cryptoki_error(rc, p11card->reader); goto kpgen_done; } } else if (rc != SC_ERROR_NOT_SUPPORTED) { sc_debug(context, "sc_pkcs15init_generate_key returned %d\n", rc); rv = sc_to_cryptoki_error(rc, p11card->reader); goto kpgen_done; } else { /* 3.b Try key pair generation in software, if allowed */ if (!sc_pkcs11_conf.soft_keygen_allowed) { sc_debug(context, "On card keypair gen not supported, software keypair gen not allowed"); rv = CKR_FUNCTION_FAILED; goto kpgen_done; } sc_debug(context, "Doing key pair generation in software\n"); rv = sc_pkcs11_gen_keypair_soft(keytype, keybits, &priv_args.key, &pub_args.key); if (rv != CKR_OK) { sc_debug(context, "sc_pkcs11_gen_keypair_soft failed: 0x%0x\n", rv); goto kpgen_done; } /* Write the new public and private keys to the pkcs15 files */ rc = sc_pkcs15init_store_private_key(p15card, profile, &priv_args, &priv_key_obj); if (rc >= 0) 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); goto kpgen_done; } } /* 4. Create new pkcs11 public and private key object */ rc = __pkcs15_create_prkey_object(fw_data, priv_key_obj, &priv_any_obj); if (rc == 0) __pkcs15_create_pubkey_object(fw_data, pub_key_obj, &pub_any_obj); if (rc != 0) { sc_debug(context, "__pkcs15_create_pr/pubkey_object returned %d\n", rc); rv = sc_to_cryptoki_error(rc, p11card->reader); goto kpgen_done; } pkcs15_add_object(slot, priv_any_obj, phPrivKey); pkcs15_add_object(slot, pub_any_obj, phPubKey);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -