int do_delete_key(sc_card_t *card, u8 in_key_id) { sc_path_t path; int r = SC_SUCCESS; /* Currently, only Gnuk supports deleting keys */ if (card->type != SC_CARD_TYPE_OPENPGP_GNUK) { util_error("only Gnuk supports deleting keys. General OpenPGP doesn't"); return SC_ERROR_NOT_SUPPORTED; } if (in_key_id < 1 || (in_key_id > 3 && in_key_id != 'a')) { util_error("invalid key id %d", in_key_id); return SC_ERROR_INVALID_ARGUMENTS; } if (in_key_id == 1 || in_key_id == 'a') { sc_format_path("B601", &path); r |= sc_delete_file(card, &path); } if (in_key_id == 2 || in_key_id == 'a') { sc_format_path("B801", &path); r |= sc_delete_file(card, &path); } if (in_key_id == 3 || in_key_id == 'a') { sc_format_path("A401", &path); r |= sc_delete_file(card, &path); } return r; }
static int cflex_delete_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) { sc_path_t path; sc_file_t *parent; int r = 0; /* Select the parent DF */ path = df->path; path.len -= 2; r = sc_select_file(p15card->card, &path, &parent); if (r < 0) return r; r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_DELETE); sc_file_free(parent); if (r < 0) return r; /* cryptoflex has no ERASE AC */ memset(&path, 0, sizeof(path)); path.type = SC_PATH_TYPE_FILE_ID; path.value[0] = df->id >> 8; path.value[1] = df->id & 0xFF; path.len = 2; r = sc_delete_file(p15card->card, &path); return r; }
static int sc_hsm_emu_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *object, const struct sc_path *path) { struct sc_context *ctx = p15card->card->ctx; int r; LOG_FUNC_CALLED(ctx); switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) { case SC_PKCS15_TYPE_PRKEY: r = sc_hsm_delete_ef(p15card, KEY_PREFIX, ((struct sc_pkcs15_prkey_info *)object->data)->key_reference); break; case SC_PKCS15_TYPE_CERT: r = sc_hsm_emu_delete_cert(p15card, profile, object); break; case SC_PKCS15_TYPE_DATA_OBJECT: r = sc_delete_file(p15card->card, path); break; case SC_PKCS15_TYPE_PUBKEY: r = SC_SUCCESS; break; default: r = SC_ERROR_NOT_IMPLEMENTED; break; } LOG_FUNC_RETURN(ctx, r); }
static int muscle_erase_card(sc_profile_t *profile, sc_card_t *card) { int r; struct sc_file *file; struct sc_path path; memset(&file, 0, sizeof(file)); sc_format_path("3F00", &path); if ((r = sc_select_file(card, &path, &file)) < 0) return r; if ((r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_ERASE)) < 0) return r; if ((r = sc_delete_file(card, &path)) < 0) return r; return 0; }
static int sc_hsm_delete_ef(sc_pkcs15_card_t *p15card, u8 prefix, u8 id) { sc_card_t *card = p15card->card; sc_path_t path; u8 fid[2]; int r; fid[0] = prefix; fid[1] = id; sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, -1); r = sc_delete_file(card, &path); LOG_TEST_RET(card->ctx, r, "Could not delete file"); LOG_FUNC_RETURN(card->ctx, r); }
static int do_delete(int argc, char **argv) { sc_path_t path; int r; if (argc != 1) return usage(do_delete); if (arg_to_path(argv[0], &path, 1) != 0) return usage(do_delete); if (path.len != 2) return usage(do_delete); path.type = SC_PATH_TYPE_FILE_ID; r = sc_delete_file(card, &path); if (r) { check_ret(r, SC_AC_OP_DELETE, "DELETE FILE failed", current_file); return -1; } return 0; }
/* * Erase the card. */ static int setcos_erase_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card) { sc_path_t path; int r; /* Just delete the entire MF */ /* Select parent DF and verify PINs/key as necessary */ r = sc_pkcs15init_authenticate(profile, p15card, profile->mf_info->file, SC_AC_OP_DELETE); if (r < 0) return r == SC_ERROR_FILE_NOT_FOUND ? 0 : r; /* Empty path -> we have to to delete the current DF (= the MF) */ memset(&path, 0, sizeof(sc_path_t)); r = sc_delete_file(p15card->card, &path) ; if (r) return r; sc_free_apps(p15card->card); return 0; }
static int update_ef(sc_card_t *card, u8 prefix, u8 id, int erase, const u8 *buf, size_t buflen) { sc_file_t *file = NULL; sc_file_t newfile; sc_path_t path; u8 fid[2]; int r; fid[0] = prefix; fid[1] = id; sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, -1); r = sc_select_file(card, &path, NULL); if ((r == SC_SUCCESS) && erase) { r = sc_delete_file(card, &path); r = SC_ERROR_FILE_NOT_FOUND; } if (r == SC_ERROR_FILE_NOT_FOUND) { file = sc_file_new(); file->id = (path.value[0] << 8) | path.value[1]; file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->size = (size_t) 0; file->status = SC_FILE_STATUS_ACTIVATED; r = sc_create_file(card, file); sc_file_free(file); if (r < 0) { return r; } } r = sc_update_binary(card, 0, buf, buflen, 0); return r; }
static int sc_hsm_update_ef(sc_pkcs15_card_t *p15card, u8 prefix, u8 id, int erase, u8 *buf, size_t buflen) { sc_card_t *card = p15card->card; sc_file_t *file = NULL; sc_file_t newfile; sc_path_t path; u8 fid[2]; int r; fid[0] = prefix; fid[1] = id; sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, -1); r = sc_select_file(card, &path, NULL); if ((r == SC_SUCCESS) && erase) { r = sc_delete_file(card, &path); LOG_TEST_RET(card->ctx, r, "Could not delete file"); r = SC_ERROR_FILE_NOT_FOUND; } if (r == SC_ERROR_FILE_NOT_FOUND) { file = sc_file_new(); file->id = (path.value[0] << 8) | path.value[1]; file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->size = (size_t) 0; file->status = SC_FILE_STATUS_ACTIVATED; r = sc_create_file(card, file); sc_file_free(file); LOG_TEST_RET(card->ctx, r, "Could not create file"); } r = sc_update_binary(card, 0, buf, buflen, 0); LOG_FUNC_RETURN(card->ctx, r); }
static void unwrap_key(sc_card_t *card, u8 keyid, const char *inf, const char *pin, int force) { sc_cardctl_sc_hsm_wrapped_key_t wrapped_key; struct sc_pin_cmd_data data; u8 keyblob[MAX_WRAPPED_KEY]; const u8 *ptr,*prkd,*cert; FILE *in = NULL; sc_path_t path; u8 fid[2]; char *lpin = NULL; unsigned int cla, tag; int r, keybloblen; size_t len, olen, prkd_len, cert_len; in = fopen(inf, "rb"); if (in == NULL) { perror(inf); return; } if ((keybloblen = fread(keyblob, 1, sizeof(keyblob), in)) < 0) { perror(inf); return; } fclose(in); ptr = keyblob; if ((sc_asn1_read_tag(&ptr, keybloblen, &cla, &tag, &len) != SC_SUCCESS) || ((cla & SC_ASN1_TAG_CONSTRUCTED) != SC_ASN1_TAG_CONSTRUCTED) || ((tag != SC_ASN1_TAG_SEQUENCE)) ){ fprintf(stderr, "Invalid wrapped key format (Outer sequence).\n"); return; } if ((sc_asn1_read_tag(&ptr, len, &cla, &tag, &olen) != SC_SUCCESS) || (cla & SC_ASN1_TAG_CONSTRUCTED) || ((tag != SC_ASN1_TAG_OCTET_STRING)) ){ fprintf(stderr, "Invalid wrapped key format (Key binary).\n"); return; } wrapped_key.wrapped_key = (u8 *)ptr; wrapped_key.wrapped_key_length = olen; ptr += olen; prkd = ptr; prkd_len = determineLength(ptr, keybloblen - (ptr - keyblob)); ptr += prkd_len; cert = ptr; cert_len = determineLength(ptr, keybloblen - (ptr - keyblob)); printf("Wrapped key contains:\n"); printf(" Key blob\n"); if (prkd_len > 0) { printf(" Private Key Description (PRKD)\n"); } if (cert_len > 0) { printf(" Certificate\n"); } if ((prkd_len > 0) && !force) { fid[0] = PRKD_PREFIX; fid[1] = keyid; /* Try to select a related EF containing the PKCS#15 description of the key */ sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0); r = sc_select_file(card, &path, NULL); if (r == SC_SUCCESS) { fprintf(stderr, "Found existing private key description in EF with fid %02x%02x. Please remove key first, select unused key reference or use --force.\n", fid[0], fid[1]); return; } } if ((cert_len > 0) && !force) { fid[0] = EE_CERTIFICATE_PREFIX; fid[1] = keyid; /* Try to select a related EF containing the certificate */ sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0); r = sc_select_file(card, &path, NULL); if (r == SC_SUCCESS) { fprintf(stderr, "Found existing certificate in EF with fid %02x%02x. Please remove certificate first, select unused key reference or use --force.\n", fid[0], fid[1]); return; } } if (pin == NULL) { printf("Enter User PIN : "); util_getpass(&lpin, NULL, stdin); printf("\n"); } else { lpin = (u8 *)pin; } memset(&data, 0, sizeof(data)); data.cmd = SC_PIN_CMD_VERIFY; data.pin_type = SC_AC_CHV; data.pin_reference = ID_USER_PIN; data.pin1.data = lpin; data.pin1.len = strlen(lpin); r = sc_pin_cmd(card, &data, NULL); if (r < 0) { fprintf(stderr, "PIN verification failed with %s\n", sc_strerror(r)); return; } if (pin == NULL) { free(lpin); } if (force) { fid[0] = KEY_PREFIX; fid[1] = keyid; sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, -1); sc_delete_file(card, &path); } wrapped_key.key_id = keyid; r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_UNWRAP_KEY, (void *)&wrapped_key); if (r == SC_ERROR_INS_NOT_SUPPORTED) { // Not supported or not initialized for key shares return; } if (r < 0) { fprintf(stderr, "sc_card_ctl(*, SC_CARDCTL_SC_HSM_UNWRAP_KEY, *) failed with %s\n", sc_strerror(r)); return; } if (prkd_len > 0) { r = update_ef(card, PRKD_PREFIX, keyid, force, prkd, prkd_len); if (r < 0) { fprintf(stderr, "Updating private key description failed with %s\n", sc_strerror(r)); return; } } if (cert_len > 0) { r = update_ef(card, EE_CERTIFICATE_PREFIX, keyid, force, cert, cert_len); if (r < 0) { fprintf(stderr, "Updating certificate failed with %s\n", sc_strerror(r)); return; } } printf("Key successfully imported\n"); }