static int get_key(unsigned int usage, sc_pkcs15_object_t **result) { sc_pkcs15_object_t *key, *pin; const char *usage_name; sc_pkcs15_id_t id; int r; usage_name = (usage & SC_PKCS15_PRKEY_USAGE_SIGN)? "signature" : "decryption"; if (opt_key_id != NULL) { sc_pkcs15_hex_string_to_id(opt_key_id, &id); r = sc_pkcs15_find_prkey_by_id_usage(p15card, &id, usage, &key); if (r < 0) { fprintf(stderr, "Unable to find private %s key '%s': %s\n", usage_name, opt_key_id, sc_strerror(r)); return 2; } } else { r = sc_pkcs15_find_prkey_by_id_usage(p15card, NULL, usage, &key); if (r < 0) { fprintf(stderr, "Unable to find any private %s key: %s\n", usage_name, sc_strerror(r)); return 2; } } *result = key; if (key->auth_id.len) { static sc_pkcs15_object_t *prev_pin = NULL; char *pincode; r = sc_pkcs15_find_pin_by_auth_id(p15card, &key->auth_id, &pin); if (r) { fprintf(stderr, "Unable to find PIN code for private key: %s\n", sc_strerror(r)); return 1; } /* Pin already verified previously */ if (pin == prev_pin) return 0; pincode = get_pin(pin); if (((pincode == NULL || *pincode == '\0')) && !(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)) return 5; r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0); if (r) { fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r)); return 5; } free(pincode); if (verbose) fprintf(stderr, "PIN code correct.\n"); prev_pin = pin; } return 0; }
static int sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out, unsigned int usage) { int r; struct sc_priv_data *priv; struct sc_pkcs15_object *key_obj; struct sc_pkcs15_prkey_info *key; struct sc_pkcs15_object *pin_obj; struct sc_pkcs15_pin_info *pin; priv = (struct sc_priv_data *) RSA_get_app_data(rsa); if (priv == NULL) return -1; if (p15card == NULL) { sc_close(); r = sc_init(); if (r) { error("SmartCard init failed: %s", sc_strerror(r)); goto err; } } r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, usage, &key_obj); if (r) { error("Unable to find private key from SmartCard: %s", sc_strerror(r)); goto err; } key = key_obj->data; r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, &pin_obj); if (r == SC_ERROR_OBJECT_NOT_FOUND) { /* no pin required */ r = sc_lock(card); if (r) { error("Unable to lock smartcard: %s", sc_strerror(r)); goto err; } *key_obj_out = key_obj; return 0; } else if (r) { error("Unable to find PIN object from SmartCard: %s", sc_strerror(r)); goto err; } pin = pin_obj->data; r = sc_lock(card); if (r) { error("Unable to lock smartcard: %s", sc_strerror(r)); goto err; } if (sc_pin != NULL) { r = sc_pkcs15_verify_pin(p15card, pin, sc_pin, strlen(sc_pin)); if (r) { sc_unlock(card); error("PIN code verification failed: %s", sc_strerror(r)); goto err; } } *key_obj_out = key_obj; return 0; err: sc_close(); return -1; }