Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
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);
}
Exemplo n.º 10
0
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");
}