static void show_initial_puk(sc_card_t *card)
{
	sc_path_t p;
	sc_file_t *f;
	struct sc_apdu a;
	u8 buf1[128], buf2[128];
	int i;

	printf("\nReading crypted Initial-PUK-file: ");
	sc_format_path("3F004350",&p);
	if((i=sc_select_file(card,&p,&f))<0){
		printf("Cannot select crypted Initial-PUK-file, %s\n", sc_strerror(i));
		return;
	}
	if((i=sc_read_binary(card,0,buf1,128,0))!=128){
		printf("Cannot read crypted Initial-PUK-file, %s\n", sc_strerror(i));
		return;
	}

	printf("OK\nDecrypting crypted Initial-PUK-file: ");
	sc_format_path("3F00DF01",&p);
	if((i=sc_select_file(card,&p,&f))<0){
		printf("Cannot select DF01, %s\n", sc_strerror(i));
		return;
	}
	sc_format_apdu(card, &a, SC_APDU_CASE_3_SHORT, 0x22, 0xC1, 0xB8);
	buf2[0]=0x80, buf2[1]=0x01, buf2[2]=0x10, buf2[3]=0x84, buf2[4]=0x01, buf2[5]=0x81;
	a.data=buf2, a.lc=a.datalen=6;
	if((i=sc_transmit_apdu(card, &a))<0){
		printf("sc_transmit_apdu(MSE) failed, %s\n", sc_strerror(i));
		return;
	}
	if(a.sw1!=0x90 && a.sw2!=0x00){
		printf("MSE=%02X%02X\n", a.sw1, a.sw2);
		return;
	}
	sc_format_apdu(card, &a, SC_APDU_CASE_4_SHORT, 0x2A, 0x84, 0x80);
	a.data=buf1, a.lc=a.datalen=128;
	a.resp=buf2, a.le=a.resplen=128;
	if((i=sc_transmit_apdu(card, &a))<0){
		printf("sc_transmit_apdu(PSO) failed, %s\n", sc_strerror(i));
		return;
	}
	if(a.sw1!=0x90 && a.sw2!=0x00){
		printf("PSO=%02X%02X\n", a.sw1, a.sw2);
		return;
	}
	printf("OK ==> Initial-PUK:"); for(i=120;i<128;++i) printf("%c",buf2[i]); printf("\n");
}
Ejemplo n.º 2
0
int sc_read_binary(sc_card_t *card, unsigned int idx,
		   unsigned char *buf, size_t count, unsigned long flags)
{
	size_t max_le = card->max_recv_size;
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_log(card->ctx, "called; %d bytes at index %d", count, idx);
	if (count == 0)
		return 0;

#ifdef ENABLE_SM
	if (card->sm_ctx.ops.read_binary)   {
		r = card->sm_ctx.ops.read_binary(card, idx, buf, count);
		if (r)
			LOG_FUNC_RETURN(card->ctx, r);
	}
#endif
	if (card->ops->read_binary == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	if (count > max_le) {
		int bytes_read = 0;
		unsigned char *p = buf;

		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_le ? max_le : count;
			r = sc_read_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				LOG_TEST_RET(card->ctx, r, "sc_read_binary() failed");
			}
			p += r;
			idx += r;
			bytes_read += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				LOG_FUNC_RETURN(card->ctx, bytes_read);
			}
		}
		sc_unlock(card);
		LOG_FUNC_RETURN(card->ctx, bytes_read);
	}
	r = card->ops->read_binary(card, idx, buf, count, flags);
	LOG_FUNC_RETURN(card->ctx, r);
}
/*
 * This function pretty much follows what find_tlv in the GNUpg
 * code does.
 */
static int
read_file(sc_card_t *card, const char *path_name, void *buf, size_t len)
{
	sc_path_t	path;
	sc_file_t	*file;
	int		r;

	sc_format_path(path_name, &path);
	if ((r = sc_select_file(card, &path, &file)) < 0)
		return r;

	if (file->size < len)
		len = file->size;
	return sc_read_binary(card, 0, (u8 *) buf, len, 0);
}
Ejemplo n.º 4
0
static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t *key_info, char *label) {
	sc_card_t *card = p15card->card;
	sc_pkcs15_pubkey_info_t pubkey_info;
	sc_pkcs15_object_t pubkey_obj;
	struct sc_pkcs15_pubkey pubkey;
	u8 efbin[1024];
	sc_cvc_t cvc;
	u8 *cvcpo;
	size_t cvclen;
	int r;

	// EF.CERT is selected
	r = sc_read_binary(p15card->card, 0, efbin, sizeof(efbin), 0);
	LOG_TEST_RET(card->ctx, r, "Could not read CSR from EF");

	cvcpo = efbin;
	cvclen = r;

	memset(&cvc, 0, sizeof(cvc));
	r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&cvcpo, &cvclen, &cvc);
	LOG_TEST_RET(card->ctx, r, "Could decode certificate signing request");

	if (cvc.publicPoint || cvc.publicPointlen) {
		// ToDo implement support for EC Public Keys
		return SC_SUCCESS;
	} else {
		pubkey.algorithm = SC_ALGORITHM_RSA;
		pubkey.u.rsa.modulus.data = cvc.primeOrModulus;
		pubkey.u.rsa.modulus.len = cvc.primeOrModuluslen;
		pubkey.u.rsa.exponent.data = cvc.coefficientAorExponent;
		pubkey.u.rsa.exponent.len = cvc.coefficientAorExponentlen;
	}

	memset(&pubkey_info, 0, sizeof(pubkey_info));
	memset(&pubkey_obj, 0, sizeof(pubkey_obj));

	sc_pkcs15_encode_pubkey(p15card->card->ctx, &pubkey, &pubkey_obj.content.value, &pubkey_obj.content.len);

	pubkey_info.id = key_info->id;
	strlcpy(pubkey_obj.label, label, sizeof(pubkey_obj.label));

	r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
	LOG_TEST_RET(card->ctx, r, "Could not add public key");

	sc_pkcs15emu_sc_hsm_free_cvc(&cvc);

	return SC_SUCCESS;
}
Ejemplo n.º 5
0
static
int dump_ef(sc_card_t * card, const char *path, u8 * buf, size_t * buf_len)
{
	int rv;
	sc_file_t *file = sc_file_new();
	sc_format_path(path, &file->path);
	sc_select_file(card, &file->path, &file);
	if (file->size > *buf_len)
		return SC_ERROR_BUFFER_TOO_SMALL;
	rv = sc_read_binary(card, 0, buf, file->size, 0);
	if (rv < 0)
		return rv;
	*buf_len = rv;

	return SC_SUCCESS;
}
Ejemplo n.º 6
0
/* Select and read a transparent EF */
static int read_transp(sc_card_t *card, const char *pathstring, unsigned char *buf, int buflen)
{
	sc_path_t path;
	int r;

	sc_format_path(pathstring, &path);
	r = sc_select_file(card, &path, NULL);
	if (r < 0)
		fprintf(stderr, "\nFailed to select file %s: %s\n", pathstring, sc_strerror(r));
	else {
		r = sc_read_binary(card, 0, buf, buflen, 0);
		if (r < 0)
			fprintf(stderr, "\nFailed to read %s: %s\n", pathstring, sc_strerror(r));
	}

	return r;
}
Ejemplo n.º 7
0
static int do_userinfo(sc_card_t *card)
{
	int i;
	/* FIXME there are no length checks on buf. */
	unsigned char buf[2048];

	for (i = 0; openpgp_data[i].ef != NULL; i++) {
		sc_path_t path;
		sc_file_t *file;
		size_t count;
		int r;

		sc_format_path(openpgp_data[i].ef, &path);
		r = sc_select_file(card, &path, &file);
		if (r) {
			fprintf(stderr, "Failed to select EF %s: %s\n", openpgp_data[i].ef, sc_strerror(r));
			return EXIT_FAILURE;
		}

		count = file->size;
		if (!count)
			continue;

		if (count > sizeof(buf) - 1) {
			fprintf(stderr, "Too small buffer to read the OpenPGP data\n");
			return EXIT_FAILURE;
		}

		r = sc_read_binary(card, 0, buf, count, 0);
		if (r < 0) {
			fprintf(stderr, "%s: read failed - %s\n", openpgp_data[i].ef, sc_strerror(r));
			return EXIT_FAILURE;
		}
		if (r != (signed)count) {
			fprintf(stderr, "%s: expecting %"SC_FORMAT_LEN_SIZE_T"d, got only %d bytes\n",
				openpgp_data[i].ef, count, r);
			return EXIT_FAILURE;
		}

		buf[count] = '\0';

		display_data(openpgp_data + i, (char *) buf);
	}

	return EXIT_SUCCESS;
}
Ejemplo n.º 8
0
static int get_cert_len(sc_card_t *card, sc_path_t *path)
{
	int r;
	u8  buf[8];

	r = sc_select_file(card, path, NULL);
	if (r < 0)
		return 0;
	r = sc_read_binary(card, 0, buf, sizeof(buf), 0);
	if (r < 0)	
		return 0;
	if (buf[0] != 0x30 || buf[1] != 0x82)
		return 0;
	path->index = 0;
	path->count = ((((size_t) buf[2]) << 8) | buf[3]) + 4;
	return 1;
} 
static void show_certs(sc_card_t *card)
{
	sc_path_t p;
	sc_file_t *f;
	X509 *c;
	u8 buf[2000];
	const u8 *q;
	int j;
	size_t i;

	printf("\n");
	for(i=0;i<sizeof(certlist)/sizeof(certlist[0]);++i){
		printf("Certificate %lu: %s",
			(unsigned long) i, certlist[i].label); fflush(stdout);

		sc_format_path(certlist[i].path,&p);
		if((j=sc_select_file(card,&p,&f))<0){
			printf(", Cannot select Cert-file %s, is this a NetKey-Card ??\n",
				certlist[i].path
			);
			continue;
		}
		if(f->type!=SC_FILE_TYPE_WORKING_EF || f->ef_structure!=SC_FILE_EF_TRANSPARENT){
			printf(", Invald Cert-file: Type=%d, EF-Structure=%d\n", f->type, f->ef_structure);
			continue;
		}
		if((j=sc_read_binary(card,0,buf,f->size,0))<0){
			printf(", Cannot read Cert-file, %s\n", sc_strerror(j));
			continue;
		}
		printf(", Maxlen=%lu", (unsigned long) f->size);
		q=buf;
		if(q[0]==0x30 && q[1]==0x82){
			if(q[4]==6 && q[5]<10 && q[q[5]+6]==0x30 && q[q[5]+7]==0x82) q+=q[5]+6;
			printf(", Len=%d\n", (q[2]<<8)|q[3]);
			if((c=d2i_X509(NULL,&q,f->size))){
				char buf2[2000];
				X509_NAME_get_text_by_NID(c->cert_info->subject, NID_commonName, buf2,sizeof(buf2));
				printf("  Subject-CN: %s\n", buf2);
				X509_NAME_get_text_by_NID(c->cert_info->issuer, NID_commonName, buf2,sizeof(buf2));
				printf("  Issuer-CN:  %s\n", buf2);
				X509_free(c);
			} else printf("  Invalid Certificate-Data\n");
		} else printf(", empty\n");
	}
}
Ejemplo n.º 10
0
/*
 * Add a unrelated certificate object and description in PKCS#15 format to the framework
 */
static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) {

    sc_card_t *card = p15card->card;
    sc_pkcs15_cert_info_t *cert_info;
    sc_pkcs15_object_t obj;
    sc_file_t *file = NULL;
    sc_path_t path;
    u8 fid[2];
    u8 efbin[512];
    const u8 *ptr;
    size_t len;
    int r;

    fid[0] = CD_PREFIX;
    fid[1] = id;

    /* Try to select a related EF containing the PKCS#15 description of the data */
    sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, sizeof(fid), 0, 0);
    r = sc_select_file(card, &path, &file);

    if (r != SC_SUCCESS) {
        return SC_SUCCESS;
    }

    sc_file_free(file);
    r = sc_read_binary(p15card->card, 0, efbin, sizeof(efbin), 0);
    LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD");

    memset(&obj, 0, sizeof(obj));
    ptr = efbin;
    len = r;

    r = sc_pkcs15_decode_cdf_entry(p15card, &obj, &ptr, &len);
    LOG_TEST_RET(card->ctx, r, "Could not decode EF.CD");

    cert_info = (sc_pkcs15_cert_info_t *)obj.data;

    r = sc_pkcs15emu_add_x509_cert(p15card, &obj, cert_info);

    LOG_TEST_RET(card->ctx, r, "Could not add data object to framework");

    return SC_SUCCESS;
}
Ejemplo n.º 11
0
int sc_read_binary(sc_card_t *card, unsigned int idx,
		   unsigned char *buf, size_t count, unsigned long flags)
{
	size_t max_le = card->max_recv_size > 0 ? card->max_recv_size : 256;
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		"called; %d bytes at index %d\n", count, idx);
	if (count == 0)
		return 0;
	if (card->ops->read_binary == NULL)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
	if (count > max_le) {
		int bytes_read = 0;
		unsigned char *p = buf;

		r = sc_lock(card);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_le ? max_le : count;
			r = sc_read_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_read_binary() failed");
			}
			p += r;
			idx += r;
			bytes_read += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_read);
			}
		}
		sc_unlock(card);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_read);
	}
	r = card->ops->read_binary(card, idx, buf, count, flags);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Ejemplo n.º 12
0
static int acos_detect_card(sc_pkcs15_card_t *p15card)
{
	int       r;
	u8        buf[128];
	sc_path_t path;
	sc_card_t *card = p15card->card;

	/* check if we have the correct card OS */
	if (strncmp(card->name, "A-TRUST ACOS", strlen("A-TRUST ACOS")))
		return SC_ERROR_WRONG_CARD;
	/* read EF_CIN_CSN file */
	sc_format_path("DF71D001", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;
	r = sc_read_binary(card, 0, buf, 8, 0);
	if (r != 8)
		return SC_ERROR_WRONG_CARD;

	return SC_SUCCESS;
}
Ejemplo n.º 13
0
static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	sc_path_t path;
	int r;
	u8 efbin[512];

	LOG_FUNC_CALLED(card->ctx);

	/* Read token info */
	sc_path_set(&path, SC_PATH_TYPE_FILE_ID, (u8 *) "\x2F\x03", 2, 0, 0);
	r = sc_select_file(card, &path, NULL);
	LOG_TEST_RET(card->ctx, r, "Could not select EF.TokenInfo");

	r = sc_read_binary(p15card->card, 0, efbin, sizeof(efbin), 0);
	LOG_TEST_RET(card->ctx, r, "Could not read EF.TokenInfo");

	r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, r);
	LOG_TEST_RET(card->ctx, r, "Could not decode EF.TokenInfo");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
Ejemplo n.º 14
0
static int starcert_detect_card(sc_pkcs15_card_t *p15card)
{
	int       r;
	u8        buf[128];
	sc_path_t path;
	sc_card_t *card = p15card->card;

	/* check if we have the correct card OS */
	if (strcmp(card->name, "STARCOS SPK 2.3"))
		return SC_ERROR_WRONG_CARD;
	/* read EF_Info file */
	sc_format_path("3F00FE13", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;
	r = sc_read_binary(card, 0, buf, 64, 0);
	if (r != 64)
		return SC_ERROR_WRONG_CARD;
	if (memcmp(buf + 24, STARCERT, strlen(STARCERT))) 
		return SC_ERROR_WRONG_CARD;

	return SC_SUCCESS;
}
Ejemplo n.º 15
0
static void handle_readcert(sc_card_t *card, int cert, char *file)
{
	sc_path_t p;
	sc_file_t *f;
	FILE *fp;
	X509 *c;
	u8 buf[1536];
	const u8 *q;
	int i, len;

	printf("\nReading Card-Certificate %d: ", cert); fflush(stdout);

	sc_format_path(certlist[cert].path,&p);
	if((i=sc_select_file(card,&p,&f))<0){
		printf("cannot select certfile, %s\n", sc_strerror(i));
		return;
	}
	if((len=sc_read_binary(card,0,buf,f->size,0))<0){
		printf("Cannot read Cert, %s\n", sc_strerror(len));
		return;
	}
	q=buf;
	if(q[0]==0x30 && q[1]==0x82 && q[4]==6 && q[5]<10 && q[q[5]+6]==0x30 && q[q[5]+7]==0x82) q+=q[5]+6;
	if((c=d2i_X509(NULL,&q,len))==NULL){
		printf("cardfile contains %d bytes which are not a certificate\n", len);
		return;
	}
	printf("Writing Cert to %s: ", file); fflush(stdout);
	if((fp=fopen(file,"w"))==NULL) printf("Cannot open file, %s\n", strerror(errno));
	else {
		fprintf(fp,"Certificate %d from Netkey E4 card\n\n", cert);
		PEM_write_X509(fp,c);
		printf("OK\n");
	}
	X509_free(c);
}
Ejemplo n.º 16
0
int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
{
	int r;
	sc_cardctl_openpgp_keygen_info_t key_info;
	u8 fingerprints[60];
	sc_path_t path;
	sc_file_t *file;

	if (key_id < 1 || key_id > 3) {
		printf("Unknown key ID %d.\n", key_id);
		return 1;
	}
	memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t));
	key_info.keytype = key_id;
	key_info.modulus_len = key_len;
	key_info.modulus = malloc(key_len/8);
	r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
	free(key_info.modulus);
	if (r < 0) {
		printf("Failed to generate key. Error %s.\n", sc_strerror(r));
		return 1;
	}
	sc_format_path("006E007300C5", &path);
	r = sc_select_file(card, &path, &file);
	if (r < 0) {
		printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r));
		return 1;
	}
	r = sc_read_binary(card, 0, fingerprints, 60, 0);
	if (r < 0) {
		printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r));
		return 1;
	}
	printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20));
	return 0;
}
Ejemplo n.º 17
0
static int do_get(int argc, char **argv)
{
	u8 buf[256];
	int r, err = 1;
	size_t count = 0;
	unsigned int idx = 0;
	sc_path_t path;
	sc_file_t *file = NULL;
	char *filename;
	FILE *outf = NULL;

	if (argc < 1 || argc > 2)
		return usage(do_get);
	if (arg_to_path(argv[0], &path, 0) != 0)
		return usage(do_get);

	filename = (argc == 2) ? argv[1] : path_to_filename(&path, '_');
	outf = (strcmp(filename, "-") == 0)
		? stdout
		: fopen(filename, "wb");
	if (outf == NULL) {
		perror(filename);
		goto err;
	}
	r = sc_select_file(card, &path, &file);
	if (r) {
		check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
		goto err;
	}
	if (file->type != SC_FILE_TYPE_WORKING_EF) {
		printf("only working EFs may be read\n");
		goto err;
	}
	count = file->size;
	while (count) {
		int c = count > sizeof(buf) ? sizeof(buf) : count;

		r = sc_read_binary(card, idx, buf, c, 0);
		if (r < 0) {
			check_ret(r, SC_AC_OP_READ, "read failed", file);
			goto err;
		}
		if ((r != c) && (card->type != SC_CARD_TYPE_BELPIC_EID)) {
			printf("expecting %d, got only %d bytes.\n", c, r);
			goto err;
		}
		if ((r == 0) && (card->type == SC_CARD_TYPE_BELPIC_EID))
			break;
		fwrite(buf, r, 1, outf);
		idx += r;
		count -= r;
	}
	if (outf == stdout) {
		fwrite("\n", 1, 1, outf);
	}
	else {
		printf("Total of %d bytes read from %s and saved to %s.\n",
		       idx, argv[0], filename);
	}

	err = 0;
err:
	if (file)
		sc_file_free(file);
	if (outf != NULL && outf != stdout)
		fclose(outf);
	select_current_path_or_die();
	return -err;
}
Ejemplo n.º 18
0
static int do_asn1(int argc, char **argv)
{
	int r, err = 1;
	sc_path_t path;
	sc_file_t *file = NULL;
	int not_current = 1;
	size_t len;
	unsigned char *buf = NULL;

	if (argc > 1)
		return usage(do_asn1);

	/* select file */
	if (argc) {
		if (arg_to_path(argv[0], &path, 0) != 0) {
			puts("Invalid file path");
			return -1;
		}
		r = sc_select_file(card, &path, &file);
		if (r) {
			check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
			goto err;
		}
	} else {
		path = current_path;
		file = current_file;
		not_current = 0;
	}
	if (file->type != SC_FILE_TYPE_WORKING_EF) {
		printf("only working EFs may be read\n");
		goto err;
	}

	/* read */
	if (file->ef_structure != SC_FILE_EF_TRANSPARENT) {
		printf("only transparent file type is supported at the moment\n");
		goto err;
	}
	len = file->size;
	buf = calloc(1, len);
	if (!buf) {
		goto err;
	}
	r = sc_read_binary(card, 0, buf, len, 0);
	if (r < 0) {
		check_ret(r, SC_AC_OP_READ, "read failed", file);
		goto err;
	}
	if ((size_t)r != len) {
		printf("expecting %lu, got only %d bytes.\n", (unsigned long) len, r);
		goto err;
	}

	/* asn1 dump */
	sc_asn1_print_tags(buf, len);

	err = 0;
err:
	if (buf)
		free(buf);
	if (not_current) {
		if (file)
			sc_file_free(file);
		select_current_path_or_die();
	}
	return -err;
}
Ejemplo n.º 19
0
static void wrap_key(sc_card_t *card, u8 keyid, const char *outf, const char *pin)
{
	sc_cardctl_sc_hsm_wrapped_key_t wrapped_key;
	struct sc_pin_cmd_data data;
	sc_file_t *file = NULL;
	sc_path_t path;
	FILE *out = NULL;
	u8 fid[2];
	u8 ef_prkd[MAX_PRKD];
	u8 ef_cert[MAX_CERT];
	u8 keyblob[MAX_WRAPPED_KEY];
	u8 *key;
	u8 *ptr;
	char *lpin = NULL;
	size_t key_len;
	int r, ef_prkd_len, ef_cert_len;

	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);
	}

	wrapped_key.key_id = keyid;

	r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_WRAP_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_WRAP_KEY, *) failed with %s\n", sc_strerror(r));
		return;
	}


	fid[0] = PRKD_PREFIX;
	fid[1] = keyid;
	ef_prkd_len = 0;

	/* 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) {
		ef_prkd_len = sc_read_binary(card, 0, ef_prkd, sizeof(ef_prkd), 0);

		if (ef_prkd_len < 0) {
			fprintf(stderr, "Error reading PRKD file %s. Skipping.\n", sc_strerror(ef_prkd_len));
			ef_prkd_len = 0;
		} else {
			ef_prkd_len = determineLength(ef_prkd, ef_prkd_len);
		}
	}

	fid[0] = EE_CERTIFICATE_PREFIX;
	fid[1] = keyid;
	ef_cert_len = 0;

	/* Try to select a related EF containing the certificate for 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) {
		ef_cert_len = sc_read_binary(card, 0, ef_cert, sizeof(ef_cert), 0);

		if (ef_cert_len < 0) {
			fprintf(stderr, "Error reading certificate %s. Skipping\n", sc_strerror(ef_cert_len));
			ef_cert_len = 0;
		} else {
			ef_cert_len = determineLength(ef_cert, ef_cert_len);
		}
	}


	ptr = keyblob;

	// Encode key in octet string object
	sc_asn1_write_element(card->ctx, SC_ASN1_OCTET_STRING,
			wrapped_key.wrapped_key, wrapped_key.wrapped_key_length,
			&key, &key_len);

	memcpy(ptr, key, key_len);
	ptr += key_len;
	free(key);

	// Add private key description
	if (ef_prkd_len > 0) {
		memcpy(ptr, ef_prkd, ef_prkd_len);
		ptr += ef_prkd_len;
	}

	// Add certificate
	if (ef_cert_len > 0) {
		memcpy(ptr, ef_cert, ef_cert_len);
		ptr += ef_cert_len;
	}

	// Encode key in octet string object
	sc_asn1_write_element(card->ctx, SC_ASN1_SEQUENCE|SC_ASN1_CONS,
			keyblob, ptr - keyblob,
			&key, &key_len);

	out = fopen(outf, "wb");

	if (out == NULL) {
		perror(outf);
		free(key);
		return;
	}

	if (fwrite(key, 1, key_len, out) != key_len) {
		perror(outf);
		free(key);
		return;
	}

	free(key);
	fclose(out);
}
Ejemplo n.º 20
0
static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
{
	unsigned char *buf = NULL;
	int    err, ok = 0;
	size_t len;
	sc_path_t tmppath;
	sc_card_t    *card = p15card->card;
	sc_context_t *ctx  = card->ctx;
	sc_pkcs15_tokeninfo_t tokeninfo;

	if (ctx->debug > 4)
		sc_debug(ctx, "trying normal pkcs15 processing\n");

	/* Enumerate apps now */
	if (card->app_count < 0) {
		err = sc_enum_apps(card);
		if (err < 0 && err != SC_ERROR_FILE_NOT_FOUND) {
			sc_error(ctx, "unable to enumerate apps: %s\n", sc_strerror(err));
			goto end;
		}
	}
	p15card->file_app = sc_file_new();
	if (p15card->file_app == NULL) {
		err = SC_ERROR_OUT_OF_MEMORY;
		goto end;
	}
	sc_format_path("3F005015", &p15card->file_app->path);
	if (card->app_count > 0) {
		const sc_app_info_t *info;
		
		info = sc_find_pkcs15_app(card);
		if (info != NULL) {
			if (info->path.len)
				p15card->file_app->path = info->path;
			if (info->ddo != NULL)
				parse_ddo(p15card, info->ddo, info->ddo_len);
		}
	}

	/* Check if pkcs15 directory exists */
	sc_ctx_suppress_errors_on(card->ctx);
	err = sc_select_file(card, &p15card->file_app->path, NULL);
#if 1
	/* If the above test failed on cards without EF(DIR),
	 * try to continue read ODF from 3F005031. -aet
	 */
	if ((err == SC_ERROR_FILE_NOT_FOUND) &&
	    (card->app_count < 1)) {
		sc_format_path("3F00", &p15card->file_app->path);
		err = SC_NO_ERROR;
	}
#endif
	sc_ctx_suppress_errors_off(card->ctx);
	if (err < 0)
		goto end;

	if (p15card->file_odf == NULL) {
		/* check if an ODF is present; suppress errors as we
		 * don't know yet whether we have a pkcs15 card */
		tmppath = p15card->file_app->path;
		sc_append_path_id(&tmppath, (const u8 *) "\x50\x31", 2);
		sc_ctx_suppress_errors_on(card->ctx);
		err = sc_select_file(card, &tmppath, &p15card->file_odf);
		sc_ctx_suppress_errors_off(card->ctx);
		
	} else {
		tmppath = p15card->file_odf->path;
		sc_file_free(p15card->file_odf);
		p15card->file_odf = NULL;
		err = sc_select_file(card, &tmppath, &p15card->file_odf);
	}
	if (err != SC_SUCCESS) {
		char pbuf[SC_MAX_PATH_STRING_SIZE];

		int r = sc_path_print(pbuf, sizeof(pbuf), &tmppath);
		if (r != SC_SUCCESS)
			pbuf[0] = '\0';

		sc_debug(ctx, "EF(ODF) not found in '%s'\n", pbuf);
		goto end;
	}

	if ((len = p15card->file_odf->size) == 0) {
		sc_error(card->ctx, "EF(ODF) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if(buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	err = sc_read_binary(card, 0, buf, len, 0);
	if (err < 0)
		goto end;
	if (err < 2) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}
	len = err;
	if (parse_odf(buf, len, p15card)) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		sc_error(card->ctx, "Unable to parse ODF\n");
		goto end;
	}
	free(buf);
	buf = NULL;

	if (card->ctx->debug) {
		sc_pkcs15_df_t *df;

		sc_debug(card->ctx, "The following DFs were found:\n");
		for (df = p15card->df_list; df; df = df->next) {
			char pbuf[SC_MAX_PATH_STRING_SIZE];

			int r = sc_path_print(pbuf, sizeof(pbuf), &df->path);
			if (r != SC_SUCCESS)
				pbuf[0] = '\0';

			sc_debug(card->ctx,
				"  DF type %u, path %s, index %u, count %d\n",
				df->type, pbuf, df->path.index, df->path.count);
		}
	}

	if (p15card->file_tokeninfo == NULL) {
		tmppath = p15card->file_app->path;
		sc_append_path_id(&tmppath, (const u8 *) "\x50\x32", 2);
	} else {
		tmppath = p15card->file_tokeninfo->path;
		sc_file_free(p15card->file_tokeninfo);
		p15card->file_tokeninfo = NULL;
	}
	err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
	if (err)
		goto end;

	if ((len = p15card->file_tokeninfo->size) == 0) {
		sc_error(card->ctx, "EF(TokenInfo) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if(buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	err = sc_read_binary(card, 0, buf, len, 0);
	if (err < 0)
		goto end;
	if (err <= 2) {
		err = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}

	memset(&tokeninfo, 0, sizeof(tokeninfo));
	err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
	if (err != SC_SUCCESS)
		goto end;
	p15card->version         = tokeninfo.version;
	p15card->label           = tokeninfo.label;
	p15card->serial_number   = tokeninfo.serial_number;
	p15card->manufacturer_id = tokeninfo.manufacturer_id;
	p15card->last_update     = tokeninfo.last_update;
	p15card->flags           = tokeninfo.flags;
	p15card->preferred_language = tokeninfo.preferred_language;
	p15card->seInfo          = tokeninfo.seInfo;
	p15card->num_seInfo      = tokeninfo.num_seInfo;

	/* for cardos cards initialized by Siemens: sign with decrypt */
	if (strcmp(p15card->card->driver->short_name,"cardos") == 0
                && ( strcmp(p15card->manufacturer_id,"Siemens AG (C)") == 0
			|| strcmp(p15card->manufacturer_id,"Prime") == 0 ))
		p15card->flags |= SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT;

	ok = 1;
end:
	if(buf != NULL)
		free(buf);
	if (!ok) {
		sc_pkcs15_card_clear(p15card);
		return err;
	}

	return SC_SUCCESS;
}
Ejemplo n.º 21
0
static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card)
{
	const cdata certs[] = {
		{"C.CH.EKEY", 0, "DF71C001","1", 0},/* Decryption Certificate */
		{NULL, 0, NULL, NULL, 0}
	};

	const pindata pins[] = {
		{ "01", "PIN.DEC", "3F00DF71", 0x81, /* Decryption PIN */
		  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
		  4, 4, 8, SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
		  SC_PKCS15_PIN_FLAG_LOCAL, -1, 0x00,
		  SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE },
		{ NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0} 
	};

	const prdata prkeys[] = {
		{ "01", "SK.CH.EKEY", 1536,
			SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
		  "", /* do not specify file here to prevent reset of security state */
		  0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE},
		{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
	};

	int    r, i;
	u8     buf[256];
	char   buf2[256];
	sc_path_t path;
	sc_file_t *file = NULL;
	sc_card_t *card = p15card->card;

	/* get serial number */

	/* read EF_CIN_CSN file */
	sc_format_path("DF71D001", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return SC_ERROR_INTERNAL;
	r = sc_read_binary(card, 0, buf, 8, 0);
	if (r != 8)
		return SC_ERROR_INTERNAL;
	r = sc_bin_to_hex(buf, 8, buf2, sizeof(buf2), 0);
	if (r != SC_SUCCESS)
		return SC_ERROR_INTERNAL;
	if (p15card->tokeninfo->serial_number)
		free(p15card->tokeninfo->serial_number);
	p15card->tokeninfo->serial_number = malloc(strlen(buf2) + 1);
	if (!p15card->tokeninfo->serial_number)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->serial_number, buf2);

	/* manufacturer ID */
	if (p15card->tokeninfo->manufacturer_id)
		free(p15card->tokeninfo->manufacturer_id);
	p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1);
	if (!p15card->tokeninfo->manufacturer_id)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID);

	/* card label */
	if (p15card->tokeninfo->label)
		free(p15card->tokeninfo->label);
	p15card->tokeninfo->label = malloc(strlen(CARD_LABEL) + 1);
	if (!p15card->tokeninfo->label)
		return SC_ERROR_INTERNAL;
	strcpy(p15card->tokeninfo->label, CARD_LABEL);

	/* set certs */
	for (i = 0; certs[i].label; i++) {
		struct sc_pkcs15_cert_info cert_info;
		struct sc_pkcs15_object    cert_obj;

		memset(&cert_info, 0, sizeof(cert_info));
		memset(&cert_obj,  0, sizeof(cert_obj));

		sc_pkcs15_format_id(certs[i].id, &cert_info.id);
		cert_info.authority = certs[i].authority;
		sc_format_path(certs[i].path, &cert_info.path);
		if (!get_cert_len(card, &cert_info.path))
			/* skip errors */
			continue;

		strlcpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label));
		cert_obj.flags = certs[i].obj_flags;

		r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
		if (r < 0)
			return SC_ERROR_INTERNAL;
	}
	/* set pins */
	for (i = 0; pins[i].label; i++) {
		struct sc_pkcs15_auth_info pin_info;
		struct sc_pkcs15_object   pin_obj;

		memset(&pin_info, 0, sizeof(pin_info));
		memset(&pin_obj,  0, sizeof(pin_obj));

		sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
		pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
		pin_info.attrs.pin.reference     = pins[i].ref;
		pin_info.attrs.pin.flags         = pins[i].flags;
		pin_info.attrs.pin.type          = pins[i].type;
		pin_info.attrs.pin.min_length    = pins[i].minlen;
		pin_info.attrs.pin.stored_length = pins[i].storedlen;
		pin_info.attrs.pin.max_length    = pins[i].maxlen;
		pin_info.attrs.pin.pad_char      = pins[i].pad_char;
		sc_format_path(pins[i].path, &pin_info.path);
		pin_info.tries_left    = -1;

		strlcpy(pin_obj.label, pins[i].label, sizeof(pin_obj.label));
		pin_obj.flags = pins[i].obj_flags;

		r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
		if (r < 0)
			return SC_ERROR_INTERNAL;
	}
	/* set private keys */
	for (i = 0; prkeys[i].label; i++) {
		struct sc_pkcs15_prkey_info prkey_info;
		struct sc_pkcs15_object     prkey_obj;

		memset(&prkey_info, 0, sizeof(prkey_info));
		memset(&prkey_obj,  0, sizeof(prkey_obj));

		sc_pkcs15_format_id(prkeys[i].id, &prkey_info.id);
		prkey_info.usage         = prkeys[i].usage;
		prkey_info.native        = 1;
		prkey_info.key_reference = prkeys[i].ref;
		prkey_info.modulus_length= prkeys[i].modulus_len;
		sc_format_path(prkeys[i].path, &prkey_info.path);

		strlcpy(prkey_obj.label, prkeys[i].label, sizeof(prkey_obj.label));
		prkey_obj.flags = prkeys[i].obj_flags;
		if (prkeys[i].auth_id)
			sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id);

		r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
		if (r < 0)
			return SC_ERROR_INTERNAL;
	}
		
	/* select the application DF */
	sc_format_path("DF71", &path);
	r = sc_select_file(card, &path, &file);
	if (r != SC_SUCCESS || !file)
		return SC_ERROR_INTERNAL;
	/* set the application DF */
	if (p15card->file_app)
		free(p15card->file_app);
	p15card->file_app = file;

	return SC_SUCCESS;
}
static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card)
{
	static int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
	static int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN
	    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
	    | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT;

	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_pkcs15_id_t id, auth_id;
	unsigned char certlen[2];
	unsigned char *certi = NULL;
	int index_cert[4];
	int count_cert[4];
	int flags;
	int authority;
	size_t i, count;
	int r;
	int o = 0;

	const char *label = "User Non-repudiation Certificate";
	const char *calabel = "CA Certificate";
	const char *catmslabel = "CA TimeStamper Certificate";
	const char *authlabel = "User Authentication Certificate";

	const char *postecert_auth_cert_path = "504B0001";

	const char *authPIN = "Authentication PIN";
	const char *nonrepPIN = "Non-repudiation PIN";

	const char *authPRKEY = "Authentication Key";
	const char *nonrepPRKEY = "Non repudiation Key";

	/* Get the non-repudiation certificate length */
	sc_format_path(postecert_auth_cert_path, &path);

	if (sc_select_file(card, &path, NULL) < 0) {
		r = SC_ERROR_WRONG_CARD;
		goto failed;
	}

	set_string(&p15card->label, "Postecert & Cnipa Card");
	set_string(&p15card->manufacturer_id, "Postecert");
	set_string(&p15card->serial_number, "0000");

	sc_read_binary(card, 0, certlen, 2, 0);

	/* Now set the certificate offset/len */
	count = (certlen[0] << 8) + certlen[1];
	if (count < 256)
		return SC_ERROR_INTERNAL;

	certi = (unsigned char *) malloc(count);

	if (!certi)
		return SC_ERROR_OUT_OF_MEMORY;

	sc_read_binary(card, 0, certi, count - 500, 0);

	for (i = 2; i < (count - 256); i++) {
		/* this file contain more than one certificate */
		if (*(certi + i) == 0x30 && *(certi + i + 1) == 0x82
		    && *(certi + i + 4) == 0x30 && *(certi + i + 5) == 0x82
		    && *(certi + i + 2) > 1 && *(certi + i + 2) < 8
		    && *(certi + i + 6) <= *(certi + i + 2)) {
			index_cert[o] = i;
			count_cert[o] =
			    (*(certi + i + 2) << 8) + *(certi + i + 3) + 4;
			o++;
			if (o > 4)
				break;
			i += (*(certi + i + 2) << 8) + *(certi + i + 3);
		}
	}

	free(certi);

	path.index = index_cert[0];
	path.count = count_cert[0];

	id.value[0] = 1;
	id.len = 1;

	authority = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, calabel, SC_PKCS15_CO_FLAG_MODIFIABLE);

	path.index = index_cert[1];
	path.count = count_cert[1];

	id.value[0] = 2;
	id.len = 1;

	authority = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, catmslabel, SC_PKCS15_CO_FLAG_MODIFIABLE);

	path.index = index_cert[2];
	path.count = count_cert[2];

	id.value[0] = 3;
	id.len = 1;

	authority = 0;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, label, SC_PKCS15_CO_FLAG_MODIFIABLE);

	path.index = index_cert[3];
	path.count = count_cert[3];

	id.value[0] = 4;
	id.len = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, authority,
			      &path, &id, authlabel, SC_PKCS15_CO_FLAG_MODIFIABLE);


	flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING;

	/* add authentication PIN */
	sc_format_path("3F00504B", &path);
	id.value[0] = 1;
	sc_pkcs15emu_add_pin(p15card, &id,
			     authPIN, &path, 0x82,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     6, 14, flags, 3, 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);

	/* add authentication private key */
	id.value[0] = 4;
	auth_id.value[0] = 1;
	auth_id.len = 1;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       authPRKEY,
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, authprkey_usage,
			       &path, 0x06, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);

	/* add non repudiation PIN */
	sc_format_path("3F00504B", &path);
	id.value[0] = 2;
	sc_pkcs15emu_add_pin(p15card, &id,
			     nonrepPIN, &path, 0x82,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     6, 14, flags, 3, 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);


	/* add non repudiation private key */
	id.value[0] = 3;
	auth_id.value[0] = 2;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       nonrepPRKEY,
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, prkey_usage,
			       &path, 0x01, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);

	/* return to MF */
	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return r;

	{
		/* save old signature funcs */
		set_security_env = card->ops->set_security_env;
		/* set new one              */
		card->ops->set_security_env  = set_sec_env;
		card->ops->compute_signature = do_sign;
	}
	return 0;

failed:
	sc_error(card->ctx,
		 "Failed to initialize Postecert and Cnipa emulation: %s\n",
		 sc_strerror(r));
	return r;
}
Ejemplo n.º 23
0
static int print_file(sc_card_t *in_card, const sc_file_t *file,
	const sc_path_t *path, int depth)
{
	int r;
	const char *tmps;
	const char *ac_ops_df[] = {
		"select", "lock", "delete", "create", "rehab", "inval",
		"list"
	};
	const char *ac_ops_ef[] = {
		"read", "update", "write", "erase", "rehab", "inval"
	};
	
	for (r = 0; r < depth; r++)
		printf("  ");
	printf("%s ", sc_print_path(path));
	if (file->namelen) {
		printf("[");
		print_binary(stdout, file->name, file->namelen);
		printf("] ");
	}
	switch (file->type) {
	case SC_FILE_TYPE_WORKING_EF:
		tmps = "wEF";
		break;
	case SC_FILE_TYPE_INTERNAL_EF:
		tmps = "iEF";
		break;
	case SC_FILE_TYPE_DF:
		tmps = " DF";
		break;
	default:
		tmps = "unknown";
		break;
	}
	printf("type: %-3s, ", tmps);
	if (file->type != SC_FILE_TYPE_DF) {
		const char *structs[] = {
			"unknown", "transpnt", "linrfix", "linrfix(TLV)",
			"linvar", "linvar(TLV)", "lincyc", "lincyc(TLV)"
		};
		int ef_type = file->ef_structure;
		if (ef_type < 0 || ef_type > 7)
			ef_type = 0;	/* invalid or unknow ef type */
		printf("ef structure: %s, ", structs[ef_type]);
	}
	printf("size: %lu\n", (unsigned long) file->size);
	for (r = 0; r < depth; r++)
		printf("  ");
	if (file->type == SC_FILE_TYPE_DF)
		for (r = 0; r < (int) (sizeof(ac_ops_df)/sizeof(ac_ops_df[0])); r++)
			printf("%s[%s] ", ac_ops_df[r], acl_to_str(sc_file_get_acl_entry(file, r)));
	else
		for (r = 0; r < (int) (sizeof(ac_ops_ef)/sizeof(ac_ops_ef[0])); r++)
			printf("%s[%s] ", ac_ops_ef[r], acl_to_str(sc_file_get_acl_entry(file, r)));

	if (file->sec_attr_len) {
		printf("sec: ");
		/* Octets are as follows:
		 *   DF: select, lock, delete, create, rehab, inval
		 *   EF: read, update, write, erase, rehab, inval
		 * 4 MSB's of the octet mean:			 
		 *  0 = ALW, 1 = PIN1, 2 = PIN2, 4 = SYS,
		 * 15 = NEV */
		hex_dump(stdout, file->sec_attr, file->sec_attr_len, ":");
	}
	if (file->prop_attr_len) {
		printf("\n");
		for (r = 0; r < depth; r++)
			printf("  ");
		printf("prop: ");
		hex_dump(stdout, file->prop_attr, file->prop_attr_len, ":");
	}
	printf("\n\n");

	if (file->type == SC_FILE_TYPE_DF)
		return 0;

	if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
		unsigned char *buf;
		
		if (!(buf = (unsigned char *) malloc(file->size))) {
			fprintf(stderr, "out of memory");
			return 1;
		}

		r = sc_read_binary(in_card, 0, buf, file->size, 0);
		if (r > 0)
			hex_dump_asc(stdout, buf, r, 0);
		free(buf);
	} else {
		unsigned char buf[256];
		int i;

		for (i=0; i < file->record_count; i++) {
			printf("Record %d\n", i);
			r = sc_read_record(in_card, i, buf, 256, 0);
			if (r > 0)
				hex_dump_asc(stdout, buf, r, 0);
		}
	}
	return 0;
}
Ejemplo n.º 24
0
static int
jpki_select_file(struct sc_card *card,
		 const struct sc_path *path, struct sc_file **file_out)
{
	struct jpki_private_data *drvdata = JPKI_DRVDATA(card);
	int rc;
	sc_apdu_t apdu;
	struct sc_file *file = NULL;

	LOG_FUNC_CALLED(card->ctx);
	sc_log(card->ctx,
	       "jpki_select_file: path=%s, len=%"SC_FORMAT_LEN_SIZE_T"u",
	       sc_print_path(path), path->len);
	if (path->len == 2 && memcmp(path->value, "\x3F\x00", 2) == 0) {
		drvdata->selected = SELECT_MF;
		if (file_out) {
			sc_file_dup(file_out, drvdata->mf);
			if (*file_out == NULL) {
				LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
			}
		}
		return 0;
	}

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0, 0);
	switch (path->type) {
	case SC_PATH_TYPE_FILE_ID:
		apdu.p1 = 2;
		break;
	case SC_PATH_TYPE_DF_NAME:
		apdu.p1 = 4;
		break;
	default:
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
	}
	apdu.p2 = 0x0C;
	apdu.data = path->value;
	apdu.datalen = path->len;
	apdu.lc = path->len;

	rc = sc_transmit_apdu(card, &apdu);
	LOG_TEST_RET(card->ctx, rc, "APDU transmit failed");
	rc = sc_check_sw(card, apdu.sw1, apdu.sw2);
	LOG_TEST_RET(card->ctx, rc, "SW Check failed");
	if (!file_out) {
		LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
	}

	/* read certificate file size */
	if (path->len == 2 && (
		    memcmp(path->value, "\x00\x0A", 2) == 0 ||
		    memcmp(path->value, "\x00\x01", 2) == 0 ||
		    memcmp(path->value, "\x00\x0B", 2) == 0 ||
		    memcmp(path->value, "\x00\x02", 2) == 0 )
		) {
		u8 buf[4];
		rc = sc_read_binary(card, 0, buf, 4, 0);
		LOG_TEST_RET(card->ctx, rc, "SW Check failed");
		file = sc_file_new();
		if (!file) {
			LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
		}
		file->path = *path;
		file->size = (buf[2] << 8 | buf[3]) + 4;
		*file_out = file;
	}
	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
Ejemplo n.º 25
0
static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card)
{
	int r, i, 				type;
	unsigned char 			*buf = NULL;
	size_t 					len;
	sc_pkcs15_tokeninfo_t 	tokeninfo;
	sc_path_t 				tmppath;
	sc_card_t 				*card = p15card->card;
	sc_context_t 			*ctx = card->ctx;

	/* Parse the TokenInfo EF */
	sc_format_path("3f004f005032", &tmppath);
	r = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
	if (r)
		goto end;
	if ( (len = p15card->file_tokeninfo->size) == 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "EF(TokenInfo) is empty\n");
		goto end;
	}
	buf = malloc(len);
	if (buf == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	r = sc_read_binary(card, 0, buf, len, 0);
	if (r < 0)
		goto end;
	if (r <= 2) {
		r = SC_ERROR_PKCS15_APP_NOT_FOUND;
		goto end;
	}
	memset(&tokeninfo, 0, sizeof(tokeninfo));
	r = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t) r);
	if (r != SC_SUCCESS)
		goto end;

	*(p15card->tokeninfo) = tokeninfo;

	/* Card type detection */
	if (card->type == SC_CARD_TYPE_IAS_PTEID)
		type = IAS_CARD;
	else if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID)
		type = GEMSAFE_CARD;
	else {
		r = SC_ERROR_INTERNAL;
		goto end;
	}

	p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION
				  | SC_PKCS15_TOKEN_EID_COMPLIANT
				  | SC_PKCS15_TOKEN_READONLY;

	/* TODO: Use the cardholder's name?  */
	/* TODO: Use Portuguese descriptions? */
	
	/* Add X.509 Certificates */
	for (i = 0; i < 4; i++) {
		static const char *pteid_cert_names[4] = {
				"AUTHENTICATION CERTIFICATE",
				"SIGNATURE CERTIFICATE",
				"SIGNATURE SUB CA",
				"AUTHENTICATION SUB CA"
		};
		/* X.509 Certificate Paths */
		static const char *pteid_cert_paths[4] = {
			"3f005f00ef09", /* Authentication Certificate path */
			"3f005f00ef08", /* Digital Signature Certificate path */
			"3f005f00ef0f", /* Signature sub CA path */
			"3f005f00ef10"	/* Authentication sub CA path */
		};
		/* X.509 Certificate IDs */
		static const int pteid_cert_ids[4] = {0x45, 0x46, 0x51, 0x52};
		struct sc_pkcs15_cert_info cert_info;
		struct sc_pkcs15_object cert_obj;

		memset(&cert_info, 0, sizeof(cert_info));
		memset(&cert_obj, 0, sizeof(cert_obj));

		cert_info.id.value[0] = pteid_cert_ids[i];
		cert_info.id.len = 1;
		sc_format_path(pteid_cert_paths[i], &cert_info.path);
		strlcpy(cert_obj.label, pteid_cert_names[i], sizeof(cert_obj.label));
		r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
		if (r < 0) {
			r = SC_ERROR_INTERNAL;
			goto end;
		}
	}
	
	/* Add PINs */
	for (i = 0; i < 3; i++) {
		static const char *pteid_pin_names[3] = {
			"Auth PIN",
			"Sign PIN",
			"Address PIN"
		};
		/* PIN References */
		static const int pteid_pin_ref[2][3] = { {1, 130, 131}, {129, 130, 131} };
		/* PIN Authentication IDs */
		static const int pteid_pin_authid[3] = {1, 2, 3};
		/* PIN Paths */
		static const char *pteid_pin_paths[2][3] = { {NULL, "3f005f00", "3f005f00"},
													 {NULL, NULL, NULL} };
		struct sc_pkcs15_auth_info pin_info;
		struct sc_pkcs15_object pin_obj;

		memset(&pin_info, 0, sizeof(pin_info));
		memset(&pin_obj, 0, sizeof(pin_obj));

		pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
		pin_info.auth_id.len = 1;
		pin_info.auth_id.value[0] = pteid_pin_authid[i];
		pin_info.attrs.pin.reference = pteid_pin_ref[type][i];
		pin_info.attrs.pin.flags = SC_PKCS15_PIN_FLAG_NEEDS_PADDING
						 | SC_PKCS15_PIN_FLAG_INITIALIZED
						 | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE;
		pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
		pin_info.attrs.pin.min_length = 4;
		pin_info.attrs.pin.stored_length = 8;
		pin_info.attrs.pin.max_length = 8;
		pin_info.attrs.pin.pad_char = type == IAS_CARD ? 0x2F : 0xFF;
		pin_info.tries_left = -1;
		if (pteid_pin_paths[type][i] != NULL)
			sc_format_path(pteid_pin_paths[type][i], &pin_info.path);
		strlcpy(pin_obj.label, pteid_pin_names[i], sizeof(pin_obj.label));
		pin_obj.flags = 0;
		r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
		if (r < 0) {
			r = SC_ERROR_INTERNAL;
			goto end;
		}
	}

	/* Add Private Keys */
	for (i = 0; i < 2; i++) {
		/* Key reference */
		static const int pteid_prkey_keyref[2][2] = { {1, 130}, {2, 1} };
		/* RSA Private Key usage */
		static int pteid_prkey_usage[2] = {
			SC_PKCS15_PRKEY_USAGE_SIGN,
			SC_PKCS15_PRKEY_USAGE_NONREPUDIATION};
		/* RSA Private Key IDs */
		static const int pteid_prkey_ids[2] = {0x45, 0x46};
		static const char *pteid_prkey_names[2] = {
				"CITIZEN AUTHENTICATION KEY",
				"CITIZEN SIGNATURE KEY"};
		/* RSA Private Key Paths */
		static const char *pteid_prkey_paths[2][2] = { {NULL, "3f005f00"}, {NULL, NULL} };
		struct sc_pkcs15_prkey_info prkey_info;
		struct sc_pkcs15_object prkey_obj;

		memset(&prkey_info, 0, sizeof(prkey_info));
		memset(&prkey_obj, 0, sizeof(prkey_obj));

		prkey_info.id.len = 1;
		prkey_info.id.value[0] = pteid_prkey_ids[i];
		prkey_info.usage = pteid_prkey_usage[i];
		prkey_info.native = 1;
		prkey_info.key_reference = pteid_prkey_keyref[type][i];
		prkey_info.modulus_length = 1024;
		if (pteid_prkey_paths[type][i] != NULL)
			sc_format_path(pteid_prkey_paths[type][i], &prkey_info.path);
		strlcpy(prkey_obj.label, pteid_prkey_names[i], sizeof(prkey_obj.label));
		prkey_obj.auth_id.len = 1;
		prkey_obj.auth_id.value[0] = i + 1;
		prkey_obj.user_consent = (i == 1) ? 1 : 0;
		prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE;

		r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
		if (r < 0) {
			r = SC_ERROR_INTERNAL;
			goto end;
		}
	}

	/* Add objects */
	for (i = 0; i < 3; i++) {
		static const char *object_ids[3] = {"1", "2", "3"};
		static const char *object_oids[3] = {"-1", "-1", "-1"};
		static const char *object_labels[3] = {"Citizen Data",
											   "Citizen Address Data",
											   "Citizen Notepad"};
		static const char *object_authids[3] = {NULL, "3", "1"};
		static const char *object_paths[3] = {"3f005f00ef02",
											  "3f005f00ef05",
											  "3f005f00ef07"};
		static const int object_flags[3] = {0,
											SC_PKCS15_CO_FLAG_PRIVATE,
											SC_PKCS15_CO_FLAG_MODIFIABLE};
		struct sc_pkcs15_data_info obj_info;
		struct sc_pkcs15_object obj_obj;

		memset(&obj_info, 0, sizeof(obj_info));
		memset(&obj_obj, 0, sizeof(obj_obj));

		sc_pkcs15_format_id(object_ids[i], &obj_info.id);
		sc_format_path(object_paths[i], &obj_info.path);
		r = sc_format_oid(&obj_info.app_oid, object_oids[i]);
		if (r != SC_SUCCESS)
			goto end;
		strlcpy(obj_info.app_label, object_labels[i], SC_PKCS15_MAX_LABEL_SIZE);
		if (object_authids[i] != NULL)
			sc_pkcs15_format_id(object_authids[i], &obj_obj.auth_id);
		strlcpy(obj_obj.label, object_labels[i], SC_PKCS15_MAX_LABEL_SIZE);
		obj_obj.flags = object_flags[i];

		r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info);
		if (r < 0)
			goto end;
	}
end:
	if (buf != NULL) {
		free(buf);
		buf = NULL;
	}
	if (r)
		return r;

	return SC_SUCCESS;
}
static int infocamere_1400_init(sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_pkcs15_id_t id, auth_id;
	unsigned char serial[16];
	int flags;
	int r;
	int hasAuthCert = 0;

	const char *certLabel[] = { "User Non-repudiation Certificate",
		"User Authentication Certificate",
		"CA Certificate"
	};

	const char *certPath[] =
	    { "300060000000", "300060000001", "300060000002" };

	const char *pinLabel[] =
	    { "Non-repudiation PIN", "Authentication PIN" };
	int retries[] = { 3, -1 };

	const char *keyPath[] = { "30004000001", "30004000002" };
	const char *keyLabel[] =
	    { "Non repudiation Key", "Authentication Key" };
	static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
		SC_PKCS15_PRKEY_USAGE_SIGN
		    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
		    | SC_PKCS15_PRKEY_USAGE_ENCRYPT
		    | SC_PKCS15_PRKEY_USAGE_DECRYPT
	};

	auth_id.len = 1;
	id.len = 1;

	/* OpenSC doesn't define constants to identify BSOs for
	 * restoring security environment, so we overload
	 * the set_security_env function to support restore_sec_env */
	set_security_env = card->ops->set_security_env;
	card->ops->set_security_env = infocamere_1400_set_sec_env;
	card->ops->compute_signature = do_sign;
	p15card->opts.use_cache = 1;

	sc_format_path("30000001", &path);

	r = sc_select_file(card, &path, NULL);
	
	if (r != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	sc_read_binary(card, 15, serial, 15, 0);
	serial[15] = '\0';

	set_string(&p15card->serial_number, (char *)serial);
	set_string(&p15card->label, "Infocamere 1400 Card");
	set_string(&p15card->manufacturer_id, "Infocamere");

	if ((r = loadCertificate(p15card, 0, certPath[0], certLabel[0])) !=
	    SC_SUCCESS) {
		sc_error(p15card->card->ctx, "%s", sc_strerror(r));
		return SC_ERROR_WRONG_CARD;
	}

	hasAuthCert =
	    loadCertificate(p15card, 1, certPath[1],
			    certLabel[1]) == SC_SUCCESS;
	loadCertificate(p15card, 2, certPath[2], certLabel[2]);

	flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED |
	    SC_PKCS15_PIN_FLAG_NEEDS_PADDING;

	/* adding PINs & private keys */

	sc_format_path("30004000", &path);
	id.value[0] = 1;

	sc_pkcs15emu_add_pin(p15card, &id,
			     pinLabel[0], &path, 1,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     5, 8, flags, retries[0], 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);

	sc_format_path(keyPath[0], &path);
	auth_id.value[0] = 1;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       keyLabel[0],
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, usage[0],
			       &path, 1,
			       &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);


	if (hasAuthCert) {
		sc_format_path("30004000", &path);
		id.value[0] = 2;

		sc_pkcs15emu_add_pin(p15card, &id,
				     pinLabel[1], &path, 2,
				     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
				     5, 8, flags, retries[1], 0,
				     SC_PKCS15_CO_FLAG_MODIFIABLE |
				     SC_PKCS15_CO_FLAG_PRIVATE);

		sc_format_path(keyPath[1], &path);
		auth_id.value[0] = 2;
		sc_pkcs15emu_add_prkey(p15card, &id,
				       keyLabel[1],
				       SC_PKCS15_TYPE_PRKEY_RSA,
				       1024, usage[1],
				       &path, 2,
				       &auth_id,
				       SC_PKCS15_CO_FLAG_PRIVATE);
	}

	/* return to MF */
	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);
	return r;
	}
static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
{
	const int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
	const int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN
	    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
	    | SC_PKCS15_PRKEY_USAGE_ENCRYPT
	    | SC_PKCS15_PRKEY_USAGE_DECRYPT;

	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_file_t *file;
	sc_pkcs15_id_t id, auth_id;
	unsigned char buffer[256];
	unsigned char ef_gdo[256];
	char serial[256];
	unsigned char certlen[2];
	int authority, change_sign = 0;
	struct sc_pkcs15_cert_info cert_info;
        struct sc_pkcs15_object    cert_obj;

	const char *label = "User Non-repudiation Certificate";
	const char *calabel = "CA Certificate";
	const char *authlabel = "User Authentication Certificate";

	const char *infocamere_cert_path[2] = {
		"DF01C000",
		"3F00000011111A02"
	};

	const char *infocamere_auth_certpath[2] = {
		"11111A02",
		"000011111B02"
	};

	const char *infocamere_cacert_path[2] = {
		"DF01C008",
		"000011114101"
	};

	const char *infocamere_auth_path[2] = {
		"3F001111",
		"3F0000001111"
	};

	const char *infocamere_nrepud_path[2] = {
		"3F00DF01",
		"3F0000001111"
	};

	const int infocamere_idpin_auth_obj[2] = {
		0x95,
		0x81
	};

	const int infocamere_idpin_nrepud_obj[2] = {
		0x99,
		0x81
	};

	const int infocamere_idprkey_auth_obj[2] = {
		0x9B,
		0x01
	};

	const int infocamere_idprkey_nrepud_obj[2] = {
		0x84,
		0x01
	};

	const char *authPIN = "Authentication PIN";
	const char *nonrepPIN = "Non-repudiation PIN";

	const char *authPRKEY = "Authentication Key";
	const char *nonrepPRKEY = "Non repudiation Key";

	const int flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED |
	    SC_PKCS15_PIN_FLAG_NEEDS_PADDING;

	int r, len_iccsn, len_chn;

	sc_format_path("3F002F02", &path);

	sc_ctx_suppress_errors_on(card->ctx);
	r = sc_select_file(card, &path, &file);
	sc_ctx_suppress_errors_off(card->ctx);
	
	if (r != SC_SUCCESS || file->size > 255) {
		/* Not EF.GDO */
		return SC_ERROR_WRONG_CARD;
	}

	sc_read_binary(card, 0, ef_gdo, file->size, 0);

	if (ef_gdo[0] != 0x5A || file->size < 3) {
		/* Not EF.GDO */
		return SC_ERROR_WRONG_CARD;
	}

	len_iccsn = ef_gdo[1];

	memcpy(buffer, ef_gdo + 2, len_iccsn);

	sc_bin_to_hex(buffer, len_iccsn, serial, sizeof(serial), 0);

	if (file->size < (size_t) (len_iccsn + 5)) {
		/* Not CHN */
		return SC_ERROR_WRONG_CARD;
	}

	if (!
	    (ef_gdo[len_iccsn + 2] == 0x5F
	     && ef_gdo[len_iccsn + 3] == 0x20)) {
		/* Not CHN */
		return SC_ERROR_WRONG_CARD;
	}

	len_chn = ef_gdo[len_iccsn + 4];

	if (len_chn < 2 || len_chn > 8) {
		/* Length CHN incorrect */
		return SC_ERROR_WRONG_CARD;
	}

	if (!
	    (ef_gdo[len_iccsn + 5] == 0x12
	     && (ef_gdo[len_iccsn + 6] == 0x02
		 || ef_gdo[len_iccsn + 6] == 0x03))) {
		/* Not Infocamere Card */
		return SC_ERROR_WRONG_CARD;
	}

	set_string(&p15card->serial_number, serial);

	if (ef_gdo[len_iccsn + 6] == 0x02)
		set_string(&p15card->label, "Infocamere 1202 Card");
	else {
		set_string(&p15card->label, "Infocamere 1203 Card");
		change_sign = 1;
	}

	set_string(&p15card->manufacturer_id, "Infocamere");

	authority = 0;

	/* Get the authentication certificate length */

	sc_format_path(infocamere_auth_certpath[ef_gdo[len_iccsn+6]-2], &path);

	sc_ctx_suppress_errors_on(card->ctx);
	r = sc_select_file(card, &path, NULL);
	sc_ctx_suppress_errors_off(card->ctx);

	if (r >= 0) {

		sc_read_binary(card, 0, certlen, 2, 0);

		/* Now set the certificate offset/len */

		path.index = 2;
		path.count = (certlen[1] << 8) + certlen[0];

		memset(&cert_info, 0, sizeof(cert_info));
                memset(&cert_obj,  0, sizeof(cert_obj));

		sc_pkcs15_format_id("1", &cert_info.id);
        	cert_info.authority = authority;
        	cert_info.path = path;
		strlcpy(cert_obj.label, authlabel, sizeof(cert_obj.label));
	        cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;

		r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
        	if (r < 0)
        		return SC_ERROR_INTERNAL;

		/* XXX: the IDs for the key/pin in case of the 1203 type 
		 * are wrong, therefore I disable them for now -- Nils */
		if (!change_sign) {    
		/* add authentication PIN */

                sc_format_path(infocamere_auth_path[ef_gdo[len_iccsn+6]-2], &path);
                
		sc_pkcs15_format_id("1", &id);
		sc_pkcs15emu_add_pin(p15card, &id,
                                authPIN, &path, infocamere_idpin_auth_obj[ef_gdo[len_iccsn+6]-2],
                                SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
                                5, 8, flags, 3, 0, 
				SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE);

		/* add authentication private key */

		auth_id.value[0] = 1;
		auth_id.len = 1;

		sc_pkcs15emu_add_prkey(p15card, &id,
				authPRKEY,
				SC_PKCS15_TYPE_PRKEY_RSA, 
				1024, authprkey_usage,
				&path, infocamere_idprkey_auth_obj[ef_gdo[len_iccsn+6]-2],
				&auth_id, SC_PKCS15_CO_FLAG_PRIVATE);
		}

	}

	/* Get the non-repudiation certificate length */

	sc_format_path(infocamere_cert_path[ef_gdo[len_iccsn+6]-2], &path);

	if (sc_select_file(card, &path, NULL) < 0)
		{
		return SC_ERROR_INTERNAL;
		}

	sc_read_binary(card, 0, certlen, 2, 0);

	/* Now set the certificate offset/len */
	path.index = 2;
	path.count = (certlen[1] << 8) + certlen[0];
	
        memset(&cert_info, 0, sizeof(cert_info));
        memset(&cert_obj,  0, sizeof(cert_obj));

	sc_pkcs15_format_id("2", &cert_info.id);

        cert_info.authority = authority;
        cert_info.path = path;
        strlcpy(cert_obj.label, label, sizeof(cert_obj.label));
        cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;

	r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
        if (r < 0)
        	return SC_ERROR_INTERNAL;

	/* Get the CA certificate length */

	authority = 1;

	sc_format_path(infocamere_cacert_path[ef_gdo[len_iccsn+6]-2], &path);

	sc_ctx_suppress_errors_on(card->ctx);
	r = sc_select_file(card, &path, NULL);
	sc_ctx_suppress_errors_off(card->ctx);

	if (r >= 0) {
		size_t len;

		sc_read_binary(card, 0, certlen, 2, 0);

		len = (certlen[1] << 8) + certlen[0];

		if (len != 0) {
			/* Now set the certificate offset/len */
			path.index = 2;
			path.count = len;

			memset(&cert_info, 0, sizeof(cert_info));
	                memset(&cert_obj,  0, sizeof(cert_obj));

			sc_pkcs15_format_id("3", &cert_info.id);
	        	cert_info.authority = authority;
	        	cert_info.path = path;
	        	strlcpy(cert_obj.label, calabel, sizeof(cert_obj.label));
		        cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;

			r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
        		if (r < 0)
        		return SC_ERROR_INTERNAL;
		}
	}

        /* add non repudiation PIN */

	sc_format_path(infocamere_nrepud_path[ef_gdo[len_iccsn+6]-2], &path);

	sc_pkcs15_format_id("2", &id);
	sc_pkcs15emu_add_pin(p15card, &id,
		nonrepPIN, &path, infocamere_idpin_nrepud_obj[ef_gdo[len_iccsn+6]-2],
		SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, 3, 0,
		SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE);


	/* add non repudiation private key */

	auth_id.value[0] = 2;
	auth_id.len = 1;

	sc_pkcs15emu_add_prkey(p15card, &id, nonrepPRKEY,
			       SC_PKCS15_TYPE_PRKEY_RSA, 
                               1024, prkey_usage,
                               &path, infocamere_idprkey_nrepud_obj[ef_gdo[len_iccsn+6]-2],
                               &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);


	/* return to MF */
	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);
	if (r != SC_SUCCESS)
		return r;

	if (change_sign) {
		/* save old signature funcs */
		set_security_env = card->ops->set_security_env;
		/* set new one */
		card->ops->set_security_env = set_sec_env;
		card->ops->compute_signature = do_sign;
	}

	return SC_SUCCESS;
}
Ejemplo n.º 28
0
/**
 * Select a file from card, process fci and read data
 * This is done by mean of iso_select_file() and iso_read_binary()
 *@param card pointer to sc_card data
 *@param path pathfile
 *@param file pointer to resulting file descriptor
 *@param buffer pointer to buffer where to store file contents
 *@param length length of buffer data
 *@return SC_SUCCESS if ok; else error code
 */
int dnie_read_file(sc_card_t * card,
		   const sc_path_t * path,
		   sc_file_t ** file, u8 ** buffer, size_t * length)
{
	u8 *data;
	char *msg = NULL;
	int res = SC_SUCCESS;
	unsigned int fsize = 0;	/* file size */
	sc_context_t *ctx = NULL;

	if (!card || !card->ctx)
		return SC_ERROR_INVALID_ARGUMENTS;
	ctx = card->ctx;
	LOG_FUNC_CALLED(card->ctx);
	if (!buffer || !length || !path)	/* check received arguments */
		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
	/* select file by mean of iso7816 ops */
	res = card->ops->select_file(card, path, file);
	if (res != SC_SUCCESS) {
		msg = "select_file failed";
		goto dnie_read_file_err;
	}
	/* iso's select file calls if needed process_fci, so arriving here
	 * we have file structure filled.
	 */
	if ((*file)->type == SC_FILE_TYPE_DF) {
		/* just a DF, no need to read_binary() */
		*buffer = NULL;
		*length = 0;
		res = SC_SUCCESS;
		msg = "File is a DF: no need to read_binary()";
		goto dnie_read_file_end;
	}
	fsize = (*file)->size;
	/* reserve enought space to read data from card */
	if (fsize <= 0) {
		res = SC_ERROR_FILE_TOO_SMALL;
		msg = "provided buffer size is too small";
		goto dnie_read_file_err;
	}
	data = calloc(fsize, sizeof(u8));
	if (data == NULL) {
		res = SC_ERROR_OUT_OF_MEMORY;
		msg = "cannot reserve requested buffer size";
		goto dnie_read_file_err;
	}
	/* call sc_read_binary() to retrieve data */
	sc_log(ctx, "read_binary(): expected '%d' bytes", fsize);
	res = sc_read_binary(card, 0, data, fsize, 0L);
	if (res < 0) {		/* read_binary returns number of bytes readed */
		res = SC_ERROR_CARD_CMD_FAILED;
		msg = "read_binary() failed";
		goto dnie_read_file_err;
	}
	*buffer = data;
	*length = res;
	/* arriving here means success */
	res = SC_SUCCESS;
	goto dnie_read_file_end;
 dnie_read_file_err:
	if (*file)
		sc_file_free(*file);
 dnie_read_file_end:
	if (msg)
		sc_log(ctx, msg);
	LOG_FUNC_RETURN(ctx, res);
}
static int infocamere_1600_init(sc_pkcs15_card_t * p15card)
{
	sc_card_t *card = p15card->card;
	sc_path_t path;
	sc_pkcs15_id_t id, auth_id;
	unsigned char serial[17];
	int flags;
	int r;
	int hasAuthCert = 0;

	const char *certLabel[] = { "User Non-repudiation Certificate",
		"User Authentication Certificate"
	};

	const char *certPath[] = { "200020010008", "20002001000E" };

	const char *pinLabel[] =
	    { "Non-repudiation PIN", "Authentication PIN" };
	int retries[] = { 3, -1 };

	const char *keyPath[] = { "200020010004", "20002001000A" };
	const char *keyLabel[] =
	    { "Non repudiation Key", "Authentication Key" };
	static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
		SC_PKCS15_PRKEY_USAGE_SIGN
		    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
		    | SC_PKCS15_PRKEY_USAGE_ENCRYPT
		    | SC_PKCS15_PRKEY_USAGE_DECRYPT
	};

	auth_id.len = 1;
	id.len = 1;

	/* OpenSC doesn't define constants to identify BSOs for
	 * restoring security environment, so we overload
	 * the set_security_env function to support restore_sec_env */
	set_security_env = card->ops->set_security_env;
	card->ops->set_security_env = infocamere_1400_set_sec_env;
	card->ops->compute_signature = do_sign;

	sc_format_path("200020012002", &path);

	r = sc_select_file(card, &path, NULL);

	if (r != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	sc_read_binary(card, 30, serial, 16, 0);
	serial[16] = '\0';

	set_string(&p15card->serial_number, (char *) serial);
	set_string(&p15card->label, "Infocamere 1600 Card");
	set_string(&p15card->manufacturer_id, "Infocamere");

	/* Adding certificates.
	 * Certificates are stored in a ZLib compressed form with
	 * a 4 byte header, so we extract, decompress and cache
	 * them.
	 */
	sc_format_path(certPath[0], &path);
	if (sc_select_file(card, &path, NULL) != SC_SUCCESS)
		return SC_ERROR_WRONG_CARD;

	id.value[0] = 1;

	sc_pkcs15emu_add_cert(p15card,
			      SC_PKCS15_TYPE_CERT_X509, 0,
			      &path, &id, certLabel[0],
			      SC_PKCS15_CO_FLAG_MODIFIABLE);

	sc_format_path(certPath[1], &path);
	if (sc_select_file(card, &path, NULL) == SC_SUCCESS) {
		hasAuthCert = 1;

		id.value[0] = 2;

		sc_pkcs15emu_add_cert(p15card,
				      SC_PKCS15_TYPE_CERT_X509, 1,
				      &path, &id, certLabel[1],
				      SC_PKCS15_CO_FLAG_MODIFIABLE);
	}

	flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
	    SC_PKCS15_PIN_FLAG_INITIALIZED |
	    SC_PKCS15_PIN_FLAG_NEEDS_PADDING;

	/* adding PINs & private keys */
	sc_format_path("2000", &path);
	id.value[0] = 1;

	sc_pkcs15emu_add_pin(p15card, &id,
			     pinLabel[0], &path, 1,
			     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
			     5, 8, flags, retries[0], 0,
			     SC_PKCS15_CO_FLAG_MODIFIABLE |
			     SC_PKCS15_CO_FLAG_PRIVATE);

	sc_format_path(keyPath[0], &path);
	auth_id.value[0] = 1;
	sc_pkcs15emu_add_prkey(p15card, &id,
			       keyLabel[0],
			       SC_PKCS15_TYPE_PRKEY_RSA,
			       1024, usage[0],
			       &path, 1,
			       &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);

	if (hasAuthCert) {
		id.value[0] = 2;

		sc_pkcs15emu_add_pin(p15card, &id,
				     pinLabel[1], &path, 2,
				     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
				     5, 8, flags, retries[1], 0,
				     SC_PKCS15_CO_FLAG_MODIFIABLE |
				     SC_PKCS15_CO_FLAG_PRIVATE);

		sc_format_path(keyPath[1], &path);
		auth_id.value[0] = 2;
		sc_pkcs15emu_add_prkey(p15card, &id,
				       keyLabel[1],
				       SC_PKCS15_TYPE_PRKEY_RSA,
				       1024, usage[1],
				       &path, 2,
				       &auth_id,
				       SC_PKCS15_CO_FLAG_PRIVATE);
	}

	/* return to MF */
	sc_format_path("3F00", &path);
	r = sc_select_file(card, &path, NULL);

	return SC_SUCCESS;
}
Ejemplo n.º 30
0
static int 
sc_oberthur_read_file(struct sc_pkcs15_card *p15card, const char *in_path, 
		unsigned char **out, size_t *out_len,
		int verify_pin)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_file *file = NULL;
	struct sc_path path;
	size_t sz;
	int rv;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (!in_path || !out || !out_len)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Cannot read oberthur file");
		
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "read file '%s'; verify_pin:%i", in_path, verify_pin);
	
	*out = NULL;
	*out_len = 0;
	
	sc_format_path(in_path, &path);
	rv = sc_select_file(card, &path, &file);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot select oberthur file to read");

	if (file->ef_structure == SC_FILE_EF_TRANSPARENT)
		sz = file->size;
	else
		sz = (file->record_length + 2) * file->record_count;
	
	*out = calloc(sz, 1);
	if (*out == NULL)
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_MEMORY_FAILURE, "Cannot read oberthur file");

	if (file->ef_structure == SC_FILE_EF_TRANSPARENT)   {
		rv = sc_read_binary(card, 0, *out, sz, 0);
	}
	else	{
		int rec;
		int offs = 0;
		int rec_len = file->record_length;
		
		for (rec = 1; ; rec++)   {
			rv = sc_read_record(card, rec, *out + offs + 2, rec_len, SC_RECORD_BY_REC_NR);
			if (rv == SC_ERROR_RECORD_NOT_FOUND)   {
				rv = 0;
				break;
			}
			else if (rv < 0)   {
				break;
			}

			rec_len = rv; 
				
			*(*out + offs) = 'R';
			*(*out + offs + 1) = rv;
			
			offs += rv + 2;
		}

		sz = offs;
	}

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "read oberthur file result %i", rv);
	if (verify_pin && rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)   {
		struct sc_pkcs15_object *objs[0x10], *pin_obj = NULL;
		const struct sc_acl_entry *acl = sc_file_get_acl_entry(file, SC_AC_OP_READ);
		int ii;

		rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 0x10);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot read oberthur file: get AUTH objects error");

		for (ii=0; ii<rv; ii++)   {
			struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *) objs[ii]->data;
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "compare PIN/ACL refs:%i/%i, method:%i/%i", 
					auth_info->attrs.pin.reference, acl->key_ref, auth_info->auth_method, acl->method);
			if (auth_info->attrs.pin.reference == (int)acl->key_ref && auth_info->auth_method == (unsigned)acl->method)   {
				pin_obj = objs[ii];
				break;
			}
		}

		if (!pin_obj || !pin_obj->content.value)    {
			rv = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
		}
		else    {
			rv = sc_pkcs15_verify_pin(p15card, pin_obj, pin_obj->content.value, pin_obj->content.len);
			if (!rv)
				rv = sc_oberthur_read_file(p15card, in_path, out, out_len, 0);
		}
	};
			
	sc_file_free(file);

	if (rv < 0)   {
		free(*out);
		*out = NULL;
		*out_len = 0;
	}

	*out_len = sz;

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, rv);
}