📄 pkcs15-lib.c
字号:
if (r >= 0) sc_profile_set_pin_info(profile, SC_PKCS15INIT_USER_PIN, &pin_info); if (r >= 0) r = aodf_add_pin(p15card, profile, &pin_info, args->label); return r;}static intaodf_add_pin(struct sc_pkcs15_card *p15card, struct sc_profile *profile, const struct sc_pkcs15_pin_info *pin, const char *label){ struct sc_pkcs15_pin_info *info; struct sc_pkcs15_object *object; info = (struct sc_pkcs15_pin_info *) calloc(1, sizeof(*info)); *info = *pin; object = (struct sc_pkcs15_object *) calloc(1, sizeof(*object)); object->type = SC_PKCS15_TYPE_AUTH_PIN; object->data = info; object->flags = 0x3; /* XXX */ if (label) strncpy(object->label, label, sizeof(object->label)); return sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_AODF, object);}/* * Prepare private key download, and initialize a prkdf entry */static intsc_pkcs15init_init_prkdf(struct sc_pkcs15init_prkeyargs *keyargs, sc_pkcs15_prkey_t *key, int keybits, struct sc_pkcs15_object **res_obj ){ struct sc_pkcs15_prkey_info *key_info; struct sc_pkcs15_object *object; const char *label; unsigned int usage; int r = 0; if (!keybits && (keybits = prkey_bits(key)) < 0) return keybits; if (keyargs->id.len == 0) { p15init_error("No key ID set for this key."); return SC_ERROR_INVALID_ARGUMENTS; } if ((usage = keyargs->usage) == 0) { usage = SC_PKCS15_PRKEY_USAGE_SIGN; if (keyargs->x509_usage) usage = sc_pkcs15init_map_usage(keyargs->x509_usage, 1); } if ((label = keyargs->label) == NULL) label = "Private Key"; key_info = (struct sc_pkcs15_prkey_info *) calloc(1, sizeof(*key_info)); key_info->id = keyargs->id; key_info->usage = usage; key_info->native = 1; key_info->key_reference = 0; key_info->modulus_length = keybits; /* path set by card driver */ object = (struct sc_pkcs15_object *) calloc(1, sizeof(*object)); object->type = prkey_pkcs15_algo(key); object->data = key_info; object->flags = DEFAULT_PRKEY_FLAGS; object->auth_id = keyargs->auth_id; strncpy(object->label, label, sizeof(object->label)); *res_obj = object; return r;}/* * Generate a new private key */intsc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15init_prkeyargs *keyargs, unsigned int keybits, struct sc_pkcs15_object **res_obj){ struct sc_pkcs15init_pubkeyargs pubkey_args; struct sc_pkcs15_object *object; struct sc_pkcs15_prkey_info *key_info; int r, index; /* For now, we support just RSA key pair generation */ if (!check_key_compatibility(p15card, &keyargs->key, keyargs->x509_usage, keybits, SC_ALGORITHM_ONBOARD_KEY_GEN)) return SC_ERROR_NOT_SUPPORTED; if (profile->ops->generate_key == NULL) return SC_ERROR_NOT_SUPPORTED; /* Set the USER PIN reference from args */ r = set_user_pin_from_authid(p15card, profile, &keyargs->auth_id); if (r < 0) return r; /* Set the SO PIN reference from card */ if ((r = set_so_pin_from_card(p15card, profile)) < 0) return r; /* Select a Key ID if the user didn't specify one, otherwise * make sure it's unique */ if ((r = select_id(p15card, SC_PKCS15_TYPE_PRKEY, &keyargs->id)) < 0) return r; /* Set up the PrKDF object */ if ((r = sc_pkcs15init_init_prkdf(keyargs, &keyargs->key, keybits, &object)) < 0) return r; key_info = (struct sc_pkcs15_prkey_info *) object->data; /* Set up the PuKDF info. The public key will be filled in * by the card driver's generate_key function called below */ memset(&pubkey_args, 0, sizeof(pubkey_args)); pubkey_args.id = keyargs->id; pubkey_args.label = keyargs->label; pubkey_args.usage = keyargs->usage; pubkey_args.x509_usage = keyargs->x509_usage; /* Generate the private key on card */ index = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0); r = profile->ops->generate_key(profile, p15card->card, index, keybits, &pubkey_args.key, key_info); /* update PrKDF entry */ if (r >= 0) { r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object); } if (r >= 0) { r = sc_pkcs15init_store_public_key(p15card, profile, &pubkey_args, NULL); } if (r >= 0 && res_obj) *res_obj = object; sc_pkcs15_erase_pubkey(&pubkey_args.key); return r;}/* * Store private key */intsc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15init_prkeyargs *keyargs, struct sc_pkcs15_object **res_obj){ struct sc_pkcs15_object *object; struct sc_pkcs15_prkey_info *key_info; sc_pkcs15_prkey_t key; int keybits, index, r = 0; /* Create a copy of the key first */ key = keyargs->key; if ((r = prkey_fixup(&key)) < 0) return r; if ((keybits = prkey_bits(&key)) < 0) return keybits; /* Now check whether the card is able to handle this key */ if (!check_key_compatibility(p15card, &key, keyargs->x509_usage, keybits, 0)) { /* Make sure the caller explicitly tells us to store * the key non-natively. */ if (!(keyargs->flags & SC_PKCS15INIT_EXTRACTABLE)) { p15init_error("Card does not support this key."); return SC_ERROR_INCOMPATIBLE_KEY; } if (!keyargs->passphrase && !(keyargs->flags & SC_PKCS15INIT_NO_PASSPHRASE)) { p15init_error("No key encryption passphrase given."); return SC_ERROR_PASSPHRASE_REQUIRED; } } /* Set the USER PIN reference from args */ r = set_user_pin_from_authid(p15card, profile, &keyargs->auth_id); if (r < 0) return r; /* Set the SO PIN reference from card */ if ((r = set_so_pin_from_card(p15card, profile)) < 0) return r; /* Select a Key ID if the user didn't specify one, otherwise * make sure it's unique */ if (keyargs->id.len != 0 && (keyargs->flags & SC_PKCS15INIT_SPLIT_KEY)) { /* Split key; this ID exists already */ } else if ((r = select_id(p15card, SC_PKCS15_TYPE_PRKEY, &keyargs->id)) < 0) return r; /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(keyargs, &key, 0, &object); if (r < 0) return r; key_info = (struct sc_pkcs15_prkey_info *) object->data; /* Get the number of private keys already on this card */ index = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0); if (!(keyargs->flags & SC_PKCS15INIT_EXTRACTABLE)) { r = profile->ops->new_key(profile, p15card->card, &key, index, key_info); if (r < 0) return r; } else { sc_pkcs15_der_t encoded, wrapped, *der = &encoded; struct sc_context *ctx = p15card->card->ctx; key_info->native = 0; object->flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE; object->flags &= ~SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE; /* DER encode the private key */ encoded.value = wrapped.value = NULL; r = sc_pkcs15_encode_prkey(ctx, &key, &encoded.value, &encoded.len); if (r < 0) return r; if (keyargs->passphrase) { r = sc_pkcs15_wrap_data(ctx, keyargs->passphrase, der->value, der->len, &wrapped.value, &wrapped.len); if (r < 0) { free(der->value); return r; } der = &wrapped; } r = sc_pkcs15init_store_data(p15card, profile, SC_PKCS15_TYPE_PRKEY, der, &key_info->path); /* If the key is encrypted, flag the PrKDF entry as * indirect-protected */ if (keyargs->passphrase) key_info->path.type = SC_PATH_TYPE_PATH_PROT; free(encoded.value); free(wrapped.value); if (r < 0) return r; } /* Now update the PrKDF */ r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object); if (r >= 0 && res_obj) *res_obj = object; return r;}intsc_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 */intsc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15init_pubkeyargs *keyargs, struct sc_pkcs15_object **res_obj){ struct sc_pkcs15_object *object; struct sc_pkcs15_pubkey_info *key_info; sc_pkcs15_pubkey_t key; sc_pkcs15_der_t der_encoded; sc_path_t *path; const char *label; unsigned int keybits, type, usage; int r; /* Create a copy of the key first */ key = keyargs->key; switch (key.algorithm) { case SC_ALGORITHM_RSA: keybits = sc_pkcs15init_keybits(&key.u.rsa.modulus); type = SC_PKCS15_TYPE_PUBKEY_RSA; break;#ifdef SC_PKCS15_TYPE_PUBKEY_DSA case SC_ALGORITHM_DSA: keybits = sc_pkcs15init_keybits(&key.u.dsa.q); type = SC_PKCS15_TYPE_PUBKEY_DSA; break;#endif default: p15init_error("Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } /* Select a Key ID if the user didn't specify one, otherwise * make sure it's unique */ if ((r = select_id(p15card, SC_PKCS15_TYPE_PUBKEY, &keyargs->id)) < 0) return r; if ((usage = keyargs->usage) == 0) { usage = SC_PKCS15_PRKEY_USAGE_SIGN; if (keyargs->x509_usage) usage = sc_pkcs15init_map_usage(keyargs->x509_usage, 0); } if ((label = keyargs->label) == NULL) label = "Public Key"; key_info = (struct sc_pkcs15_pubkey_info *) calloc(1, sizeof(*key_info)); key_info->id = keyargs->id; key_info->usage = usage; key_info->modulus_length = keybits; object = (struct sc_pkcs15_object *) calloc(1, sizeof(*object)); object->type = type; object->data = key_info; object->flags = DEFAULT_PUBKEY_FLAGS; strncpy(object->label, label, sizeof(object->label)); /* DER encode public key components */ r = sc_pkcs15_encode_pubkey(p15card->card->ctx, &key, &der_encoded.value, &der_encoded.len); if (r < 0) return r; /* Now create key file and store key */ r = sc_pkcs15init_store_data(p15card, profile, type, &der_encoded, &key_info->path); path = &((struct sc_pkcs15_pubkey_info *) object->data)->path; if (path->count == 0) { path->index = 0; path->count = -1; } /* Update the PuKDF */ if (r >= 0) r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PUKDF, object); if (r >= 0 && res_obj) *res_obj = object; return r;}/* * Store a certificate */intsc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15init_certargs *args, struct sc_pkcs15_object **res_obj){ struct sc_pkcs15_cert_info *cert_info; struct sc_pkcs15_object *object; unsigned int usage; const char *label; int r; usage = SC_PKCS15_PRKEY_USAGE_SIGN; if (args->x509_usage) usage = sc_pkcs15init_map_usage(args->x509_usage, 0); if ((label = args->label) == NULL) label = "Certificate"; /* Select an ID if the user didn't specify one, otherwise * make sure it's unique */ if ((r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id)) < 0) return r; /* If there is a private key corresponding to the ID given * by the user, make sure $PIN references the pin protecting * this key */ if (args->id.len != 0) { sc_pkcs15_object_t *objp; struct sc_pkcs15_pin_info *pin_info; r = sc_pkcs15_find_prkey_by_id(p15card, &args->id, &objp); if (r == 0) { r = sc_pkcs15_find_pin_by_auth_id(p15card, &objp->auth_id, &objp); } if (r < 0) { /* XXX: Fallback to the first PIN object */ r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, &objp, 1); if (r != 1) r = SC_ERROR_OBJECT_NOT_FOUND; } if (r >= 0) { pin_info = (struct sc_pkcs15_pin_info *) objp->data; sc_profile_set_pin_info(profile, SC_PKCS15INIT_USER_PIN, pin_info); } } cert_info = (struct sc_pkcs15_cert_info *) calloc(1, sizeof(*cert_info)); cert_info->id = args->id; cert_info->authority = args->authority; object = (struct sc_pkcs15_object *) calloc(1, sizeof(*object)); object->type = SC_PKCS15_TYPE_CERT_X509; object->data = cert_info; object->flags = DEFAULT_CERT_FLAGS; strncpy(object->label, label, sizeof(object->label)); r = sc_pkcs15init_store_data(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &args->der_encoded, &cert_info->path); /* Now update the CDF */ if (r >= 0) r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_CDF, object); if (r >= 0 && res_obj) *res_obj = object; return r;}/* * Store a data object */intsc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15init_dataargs *args, struct sc_pkcs15_object **res_obj){ struct sc_pkcs15_data_info *data_object_info; struct sc_pkcs15_object *object; const char *label; int r; if ((label = args->label) == NULL) label = "Data Object"; /* Select an ID if the user didn't specify one, otherwise * make sure it's unique */ if ((r = select_id(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &args->id)) < 0) return r; /* Set the USER PIN reference from args */ r = set_user_pin_from_authid(p15card, profile, &args->auth_id); if (r < 0) return r;#ifdef notused if (args->id.len != 0) { sc_pkcs15_object_t *objp; struct sc_pkcs15_pin_info *pin_info; r = sc_pkcs15_find_prkey_by_id(p15card, &args->id, &objp); if (r == 0) { r = sc_pkcs15_find_pin_by_auth_id(p15card, &objp->auth_id, &objp); } if (r < 0) { /* XXX: Fallback to the first PIN object */ r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, &objp, 1); if (r != 1) r = SC_ERROR_OBJECT_NOT_FOUND; } if (r >= 0) { pin_info = (struct sc_pkcs15_pin_info *) objp->data; sc_profile_set_pin_info(profile, SC_PKCS15INIT_SO_PIN, pin_info); } }#endif data_object_info = (struct sc_pkcs15_data_info *) calloc(1, sizeof(*data_object_info)); data_object_info->id = args->id; if (args->app_label != NULL) strncpy(data_object_info->app_label, args->app_label, sizeof(data_object_info->app_label) - 1); data_object_info->app_oid = args->app_oid; object = (struct sc_pkcs15_object *) calloc(1, sizeof(*object)); object->type = SC_PKCS15_TYPE_DATA_OBJECT; object->data = data_object_info; object->flags = DEFAULT_DATA_FLAGS; object->auth_id = args->auth_id; strncpy(object->label, label, sizeof(object->label)); r = sc_pkcs15init_store_data(p15card, profile, SC_PKCS15_TYPE_DATA_OBJECT, &args->der_encoded, &data_object_info->path); /* Now update the DDF */ if (r >= 0) r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_DODF, object); if (r >= 0 && res_obj) *res_obj = object;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -