Exemplo n.º 1
0
static int iso7816_update_record(sc_card_t *card, unsigned int rec_nr,
				 const u8 *buf, size_t count,
				 unsigned long flags)
{
	sc_apdu_t apdu;
	int r;

	if (count > 256) {
		sc_error(card->ctx, "Trying to send too many bytes\n");
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0);
	apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
	if (flags & SC_RECORD_BY_REC_NR)
		apdu.p2 |= 0x04;
	
	apdu.lc = count;
	apdu.datalen = count;
	apdu.data = buf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");
	SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
		    "Card returned error");
	SC_FUNC_RETURN(card->ctx, 3, count);
}
Exemplo n.º 2
0
/*
 * Erase the card.
 */
static int 
myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_cardctl_myeid_data_obj data_obj;
	struct sc_file *mf = NULL;
	unsigned char data[8];
	int r;
	
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	r = myeid_get_init_applet_data(profile, p15card, data, sizeof(data));
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Get init applet date error");

	/* Select parent DF and verify PINs/key as necessary */
	r = sc_select_file(p15card->card, sc_get_mf_path(), &mf);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

	/* ACLs are not actives if file is not in the operational state */
	if (mf->status == SC_FILE_STATUS_ACTIVATED)
		r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "'DELETE' authentication failed on MF");
	
	data_obj.P1      = 0x01;
	data_obj.P2      = 0xE0;
	data_obj.Data    = data;
	data_obj.DataLen = sizeof(data);

	r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);

	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 3
0
static int iso7816_update_binary(sc_card_t *card,
				 unsigned int idx, const u8 *buf,
				size_t count, unsigned long flags)
{
	sc_apdu_t apdu;
	int r;

	assert(count <= card->max_send_size);

	if (idx > 0x7fff) {
		sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
		return SC_ERROR_OFFSET_TOO_LARGE;
	}

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6,
		       (idx >> 8) & 0x7F, idx & 0xFF);
	apdu.lc = count;
	apdu.datalen = count;
	apdu.data = buf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");
	SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
		    "Card returned error");
	SC_FUNC_RETURN(card->ctx, 3, count);
}
Exemplo n.º 4
0
static int 
sc_awp_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df)
{
	struct sc_context *ctx = p15card->card->ctx;
	unsigned char *buf = NULL;
	size_t buf_len;
	int rv;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (df->type != SC_PKCS15_PRKDF && df->type != SC_PKCS15_DODF)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);

	if (df->enumerated)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);

	rv = sc_oberthur_read_file(p15card, AWP_OBJECTS_LIST_PRV, &buf, &buf_len, 1);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Parse DF: read pribate objects info failed");

	rv = sc_oberthur_parse_privateinfo(p15card, buf, buf_len, 0);

	if (buf)
		free(buf);

	if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);

	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Parse DF: private info parse error");
	df->enumerated = 1;

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, rv);
}
Exemplo n.º 5
0
/*
 * Store a private key
 */
static int
myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object, 
		struct sc_pkcs15_prkey *prkey)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_cardctl_myeid_gen_store_key_info args;
	struct sc_file *file = NULL;
	int r, keybits = key_info->modulus_length;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");

	/* Check that the card supports the requested modulus length */
	if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store MyEID key with ID:%s and path:%s", 
			sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path));

	r = sc_select_file(card, &key_info->path, &file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store MyEID key: select key file failed");
	
	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store MyEID private key");

	if (file) 
		sc_file_free(file);

	/* Fill in data structure */
	memset(&args, 0, sizeof(args));
	args.mod_len = keybits;
	args.op_type    = OP_TYPE_STORE;
	args.pubexp_len = prkey->u.rsa.exponent.len;
	args.pubexp     = prkey->u.rsa.exponent.data;
	args.primep_len = prkey->u.rsa.p.len;
	args.primep     = prkey->u.rsa.p.data;
	args.primeq_len = prkey->u.rsa.q.len;
	args.primeq     = prkey->u.rsa.q.data;

	args.dp1_len    = prkey->u.rsa.dmp1.len;
	args.dp1        = prkey->u.rsa.dmp1.data;
	args.dq1_len    = prkey->u.rsa.dmq1.len;
	args.dq1        = prkey->u.rsa.dmq1.data;
	args.invq_len   = prkey->u.rsa.iqmp.len;
	args.invq       = prkey->u.rsa.iqmp.data;

	args.mod_len    = prkey->u.rsa.modulus.len;
	args.mod        = prkey->u.rsa.modulus.data;		

	/* Store RSA key  */
	r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 6
0
static int gemsafe_compute_signature(struct sc_card *card, const u8 * data,
                                     size_t data_len, u8 * out, size_t outlen)
{
    int r, len;
    struct sc_apdu apdu;
    u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
    u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
    sc_context_t *ctx = card->ctx;

    SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

    if (data_len > 36) {
        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error: input data too long: %lu bytes\n", data_len);
        return SC_ERROR_INVALID_ARGUMENTS;
    }

    /* the Portuguese eID card requires a two-phase exchange */
    if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x90, 0xA0);
    } else {
        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0xAC);
        apdu.cla |= 0x80;
        apdu.resp = rbuf;
        apdu.resplen = sizeof(rbuf);
        apdu.le      = 256;
    }
    /* we sign a digestInfo object => tag 0x90 */
    sbuf[0] = 0x90;
    sbuf[1] = (u8)data_len;
    memcpy(sbuf + 2, data, data_len);
    apdu.data = sbuf;
    apdu.lc   = data_len + 2;
    apdu.datalen = data_len + 2;

    r = sc_transmit_apdu(card, &apdu);
    SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
    if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
        if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
            /* finalize the exchange */
            sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x9E, 0x9A);
            apdu.le = 128; /* 1024 bit keys */
            apdu.resp = rbuf;
            apdu.resplen = sizeof(rbuf);
            r = sc_transmit_apdu(card, &apdu);
            SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
            if(apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
                SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
        }
        len = apdu.resplen > outlen ? outlen : apdu.resplen;

        memcpy(out, apdu.resp, len);
        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len);
    }
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
Exemplo n.º 7
0
/*
 * Create a new PIN
 */
static int
setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
	sc_file_t *df,
	sc_pkcs15_object_t *pin_obj,
	const u8 *pin, size_t pin_len,
	const u8 *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
	sc_file_t *pinfile = NULL;
	int r, ignore_ac = 0;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

        /* Create the global pin file if it doesn't exist yet */
	r = sc_profile_get_file(profile, "pinfile", &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No 'pinfile' template in profile");

	r = sc_select_file(p15card->card, &pinfile->path, &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select 'pinfile'");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "pinfile->status:%X", pinfile->status);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create PIN with reference:%X, flags:%X, path:%s",
			auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path));

	if (pinfile->status == SC_FILE_STATUS_CREATION)
		ignore_ac = 1;

	r = setcos_create_pin_internal(profile, p15card, ignore_ac, auth_info,
			pin, pin_len, puk, puk_len);

	/* If pinfile is in 'Creation' state and SOPIN has been created,
	 * change status of MF and 'pinfile' to 'Operational:Activated'
	 */
	if (ignore_ac && (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))   {
		sc_file_t *mf = profile->mf_info->file;

		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set 'pinfile' into the activated state");

		r = sc_select_file(p15card->card, &mf->path, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set MF into the activated state");
	}

	sc_file_free(pinfile);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 8
0
static int entersafe_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
								  sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey)
{
	int r;
	sc_entersafe_gen_key_data	gendat;
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA)
		return SC_ERROR_NOT_SUPPORTED;

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	/* generate key pair */
	gendat.key_id     = (u8) kinfo->key_reference;
	gendat.key_length = (size_t) kinfo->modulus_length;
	gendat.modulus    = NULL;
	r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "EnterSafe generate RSA key pair failed");

	/* get the modulus via READ PUBLIC KEY */
	if (pubkey) {
		u8 *buf;
		struct sc_pkcs15_pubkey_rsa *rsa = &pubkey->u.rsa;
		/* set the modulus */
		rsa->modulus.data = gendat.modulus;
		rsa->modulus.len  = kinfo->modulus_length >> 3;
		/* set the exponent (always 0x10001) */
		buf = malloc(3);
		if (!buf)
			return SC_ERROR_OUT_OF_MEMORY;
		buf[0] = 0x01;
		buf[1] = 0x00;
		buf[2] = 0x01;
		rsa->exponent.data = buf;
		rsa->exponent.len  = 3;

		pubkey->algorithm = SC_ALGORITHM_RSA;
	} else
Exemplo n.º 9
0
static int incrypto34_list_files(sc_card_t *card, u8 *buf, size_t buflen)
{
	sc_apdu_t apdu;
	u8 rbuf[256];
	int r;
	size_t fids;
	u8 offset;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	fids=0;
	offset=0;

	/* INS 0xFC: SCAN DF*/
	/* P1 0x00: list both DF and EF */
	/* P2 0x00/0x01: first/next element */
	/* LE 0x03*/
	/*
		returns 3 bytes: FILE_TYPE + FID_HI_BYTE + FID_LO_BYTE
	*/

get_next_part:
	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFC, 0x00, offset?0x01:0x00);
	apdu.cla = 0xB0;
	apdu.le = 3;
	apdu.resplen = sizeof(rbuf);
	apdu.resp = rbuf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	if (apdu.sw1 == 0x6a && apdu.sw2 == 0x82)
		goto end; /* no more files */

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "DIRECTORY command returned error");

	if (apdu.resplen >= 3
		&& ((rbuf[0] >= 0x01 && rbuf[0] <= 0x07) || 0x38 == rbuf[0])
		&& fids + 2 >= buflen)
	{
		buf[fids++] = rbuf[1];
		buf[fids++] = rbuf[2];
	}

	++offset;
	goto get_next_part;

end:
	r = fids;

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 10
0
static int iso_rm_sm(struct iso_sm_ctx *sctx, sc_card_t *card,
        sc_apdu_t *sm_apdu, sc_apdu_t *apdu)
{
    if (sctx->post_transmit)
        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->post_transmit(card, sctx, sm_apdu),
                "Could not complete SM specific post transmit routine");
    SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sm_decrypt(sctx, card, sm_apdu, apdu),
            "Could not decrypt APDU");
    if (sctx->finish)
        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sctx->finish(card, sctx, apdu),
                "Could not complete SM specific post transmit routine");

    return SC_SUCCESS;
}
Exemplo n.º 11
0
/*
 * Store a private key
 */
static int
setcos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object,
		struct sc_pkcs15_prkey *prkey)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_cardctl_setcos_gen_store_key_info args;
	struct sc_file *file = NULL;
	int r, keybits = key_info->modulus_length;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");

	/* Parameter check */
	if ( (keybits < 512) || (keybits > 1024) || (keybits & 0x7))
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Invalid key length");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id),
		       	sc_print_path(&key_info->path));

	r = sc_select_file(p15card->card, &key_info->path, &file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store key: select key file failed");

	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store private key");

	/* Fill in data structure */
	memset(&args, 0, sizeof(args));
	args.mod_len = keybits;
	args.op_type = OP_TYPE_STORE;
	args.pubexp_len = prkey->u.rsa.exponent.len * 8;
	args.pubexp = prkey->u.rsa.exponent.data;
	args.primep_len = prkey->u.rsa.p.len * 8;
	args.primep = prkey->u.rsa.p.data;
	args.primeq_len = prkey->u.rsa.q.len * 8;
	args.primeq = prkey->u.rsa.q.data;

	/* Generate/store rsa key  */
	r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_GENERATE_STORE_KEY, &args);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'GENERATE_STORE_KEY' failed");

	if (file)
		sc_file_free(file);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 12
0
int
sc_pkcs15_encode_pubkey_dsa(sc_context_t *ctx,
		struct sc_pkcs15_pubkey_dsa *key,
		u8 **buf, size_t *buflen)
{
	struct sc_asn1_entry asn1_public_key[2];
	struct sc_asn1_entry asn1_dsa_pub_coeff[5];
	int r;
	
	sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
	sc_copy_asn1_entry(c_asn1_dsa_pub_coefficients, asn1_dsa_pub_coeff);

	sc_format_asn1_entry(asn1_public_key + 0, asn1_dsa_pub_coeff, NULL, 1);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 0,
				key->pub.data, &key->pub.len, 1);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 1,
				key->g.data, &key->g.len, 1);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 2,
				key->p.data, &key->p.len, 1);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 3,
				key->q.data, &key->q.len, 1);

	r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 encoding failed");

	return 0;
}
Exemplo n.º 13
0
static int cardos_have_2048bit_package(sc_card_t *card)
{
	sc_apdu_t apdu;
        u8        rbuf[SC_MAX_APDU_BUFFER_SIZE];
        int       r;
	const u8  *p = rbuf, *q;
	size_t    len, tlen = 0, ilen = 0;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88);
	apdu.resp    = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.lc = 0;
	apdu.le = 256;
	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");

	if ((len = apdu.resplen) == 0)
		/* looks like no package has been installed  */
		return 0;

	while (len != 0) {
		p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen);
		if (p == NULL)
			return 0;
		q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen);
		if (q == NULL || ilen != 4)
			return 0;
		if (q[0] == 0x1c)
			return 1;
		p   += tlen;
		len -= tlen + 2;
	}

	return 0;
}
Exemplo n.º 14
0
static int 
sc_oberthur_parse_tokeninfo (struct sc_pkcs15_card *p15card, 
		unsigned char *buff, size_t len, int postpone_allowed)
{
	struct sc_context *ctx = p15card->card->ctx;
	char label[0x21];
	unsigned flags;
	int ii;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (!buff || len < 0x24)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Cannot parse token info");

	memset(label, 0, sizeof(label));

	memcpy(label, buff, 0x20);
	ii = 0x20;
	while (*(label + --ii)==' ' && ii)
		;
	*(label + ii + 1) = '\0';

	flags = *(buff + 0x22) * 0x100 + *(buff + 0x23);
	
	p15card->tokeninfo->label = strdup(label);
	p15card->tokeninfo->manufacturer_id = strdup("Oberthur/OpenSC");

	if (flags & 0x01)
		p15card->tokeninfo->flags |= SC_PKCS15_TOKEN_PRN_GENERATION;

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "label %s", p15card->tokeninfo->label);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "manufacturer_id %s", p15card->tokeninfo->manufacturer_id);
	
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}
Exemplo n.º 15
0
static int iso7816_read_record(sc_card_t *card,
			       unsigned int rec_nr, u8 *buf, size_t count,
			       unsigned long flags)
{
	sc_apdu_t apdu;
	u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
	int r;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, rec_nr, 0);
	apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
	if (flags & SC_RECORD_BY_REC_NR)
		apdu.p2 |= 0x04;
	
	apdu.le = count;
	apdu.resplen = count;
	apdu.resp = recvbuf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");
	if (apdu.resplen == 0)
		SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
	memcpy(buf, recvbuf, apdu.resplen);

	SC_FUNC_RETURN(card->ctx, 3, apdu.resplen);
}
Exemplo n.º 16
0
static int belpic_logout(sc_card_t *card)
{
	sc_apdu_t apdu;
	int r;

	sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE6, 0x00, 0x00);
	apdu.cla = 0x80;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "LOGOFF: APDU transmit failed");

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "LOGOFF returned error");

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 17
0
static int entersafe_read_binary(sc_card_t *card,
								 unsigned int idx, u8 *buf, size_t count,
								 unsigned long flags)
{
	sc_apdu_t apdu;
	u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	assert(count <= card->max_recv_size);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0,
		       (idx >> 8) & 0xFF, idx & 0xFF);

	apdu.cla=idx > 0x7fff ? 0x80:0x00;
	apdu.le = count;
	apdu.resplen = count;
	apdu.resp = recvbuf;

	r = entersafe_transmit_apdu(card, &apdu,0,0,0,0);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	if (apdu.resplen == 0)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
	memcpy(buf, recvbuf, apdu.resplen);

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);
}
Exemplo n.º 18
0
	/* 
	 * We are storing the ec_pointQ as a octet string. 
	 * Thus we will just copy the string. 
	 * But to get the field length we decode it.
	 */
int
sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx,
		struct sc_pkcs15_pubkey_ec *key,
		const u8 *buf, size_t buflen)
{
	int r;
	u8 * ecpoint_data;
	size_t ecpoint_len;
	struct sc_asn1_entry asn1_ec_pointQ[2];

	sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
	sc_format_asn1_entry(asn1_ec_pointQ + 0, &ecpoint_data, &ecpoint_len, 1);
	r = sc_asn1_decode(ctx, asn1_ec_pointQ, buf, buflen, NULL, NULL);
	if (r < 0)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 encoding failed");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"DEE-EC key=%p, buf=%p, buflen=%d", key, buf, buflen);
	key->ecpointQ.value = malloc(buflen);
	if (key->ecpointQ.value == NULL)
		return SC_ERROR_OUT_OF_MEMORY;

	key->ecpointQ.len = buflen;
	memcpy(key->ecpointQ.value, buf, buflen);

	/* An uncompressed ecpoint is of the form 04||x||y 
	 * The 04 indicates uncompressed
	 * x and y are same size, and field_length = sizeof(x) in bits. */
	/* TODO: -DEE  support more then uncompressed */
	key->params.field_length = (ecpoint_len - 1)/2 * 8; 
	if (ecpoint_data)
		free (ecpoint_data);

	return r;
}
Exemplo n.º 19
0
static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len)
{
    int	r;
    u8	buf[SC_MAX_APDU_BUFFER_SIZE];
    struct sc_context *ctx = card->ctx;
    struct sc_apdu    apdu;

    SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00);
    apdu.lc      = aid_len;
    apdu.data    = aid;
    apdu.datalen = aid_len;
    apdu.resp    = buf;
    apdu.le      = 256;
    apdu.resplen = sizeof(buf);

    r = sc_transmit_apdu(card, &apdu);
    SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
    if (r)
        SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);

    return SC_SUCCESS;
}
Exemplo n.º 20
0
static int gemsafe_decipher(struct sc_card *card, const u8 * crgram,
                            size_t crgram_len, u8 *out, size_t outlen)
{
    int r;
    struct sc_apdu apdu;
    u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
    sc_context_t *ctx = card->ctx;

    SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
    if (crgram_len > 255)
        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);

    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x84);
    apdu.cla |= 0x80;
    apdu.resp = rbuf;
    apdu.resplen = sizeof(rbuf);
    apdu.le      = crgram_len;

    apdu.data = crgram;
    apdu.lc   = crgram_len;
    apdu.datalen = crgram_len;
    r = sc_transmit_apdu(card, &apdu);
    SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
    if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
        int len = apdu.resplen > outlen ? outlen : apdu.resplen;

        memcpy(out, apdu.resp, len);
        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, len);
    }
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
Exemplo n.º 21
0
static int encode_dir_record(sc_context_t *ctx, const sc_app_info_t *app,
			     u8 **buf, size_t *buflen)
{
	struct sc_asn1_entry asn1_dirrecord[5], asn1_dir[2];
	sc_app_info_t   tapp = *app;
	int r;
	size_t label_len;

	sc_copy_asn1_entry(c_asn1_dirrecord, asn1_dirrecord);
	sc_copy_asn1_entry(c_asn1_dir, asn1_dir);
	sc_format_asn1_entry(asn1_dir + 0, asn1_dirrecord, NULL, 1);
	sc_format_asn1_entry(asn1_dirrecord + 0, (void *) tapp.aid.value, (void *) &tapp.aid.len, 1);
	if (tapp.label != NULL) {
		label_len = strlen(tapp.label);
		sc_format_asn1_entry(asn1_dirrecord + 1, tapp.label, &label_len, 1);
	}
	if (tapp.path.len)
		sc_format_asn1_entry(asn1_dirrecord + 2, (void *) tapp.path.value,
				     (void *) &tapp.path.len, 1);
	if (tapp.ddo.value != NULL && tapp.ddo.len)
		sc_format_asn1_entry(asn1_dirrecord + 3, (void *) tapp.ddo.value,
				     (void *) &tapp.ddo.len, 1);
	r = sc_asn1_encode(ctx, asn1_dir, buf, buflen);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Encode DIR record error");

	return SC_SUCCESS;
}
Exemplo n.º 22
0
static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data)
{
	int r;
	sc_apdu_t apdu;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	memcpy(data->data.df.init_key, init_key, sizeof(init_key));

	sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xE0,0x00,0x00);
	apdu.cla=0x84;
	apdu.data=(u8*)&data->data.df;
	apdu.datalen=apdu.lc=sizeof(data->data.df);

	switch(card->type)
	{
	case SC_CARD_TYPE_ENTERSAFE_3K:
	{
		 r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1);
	}break;
	case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C:
	{
		 r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1);
	}break;
	default:
	{
		 r = SC_ERROR_INTERNAL;
	}break;
	}

	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
static int entersafe_select_fid(sc_card_t *card,
								unsigned int id_hi, unsigned int id_lo,
								sc_file_t **file_out)
{
	int r;
	sc_file_t *file=0;
	sc_path_t path;

	path.type=SC_PATH_TYPE_FILE_ID;
	path.value[0]=id_hi;
	path.value[1]=id_lo;
	path.len=2;

	r = iso_ops->select_file(card,&path,&file);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");

	/* update cache */
	if (file->type == SC_FILE_TYPE_DF) {
		 card->cache.current_path.type = SC_PATH_TYPE_PATH;
		 card->cache.current_path.value[0] = 0x3f;
		 card->cache.current_path.value[1] = 0x00;
		 if (id_hi == 0x3f && id_lo == 0x00){
			  card->cache.current_path.len = 2;
		 }else{
			  card->cache.current_path.len = 4;
			  card->cache.current_path.value[2] = id_hi;
			  card->cache.current_path.value[3] = id_lo;
		 }
	}
	
	if (file_out)
		 *file_out = file;

	SC_FUNC_RETURN(card->ctx, 2, SC_SUCCESS);
}
Exemplo n.º 24
0
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
							   sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_entersafe_wkey_data data;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (key->algorithm != SC_ALGORITHM_RSA)
		 /* ignore DSA keys */
		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS);

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	data.key_id = (u8) kinfo->key_reference;
	data.usage=0x22;
	data.key_data.rsa=&key->u.rsa;
	return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
}
Exemplo n.º 25
0
static int asepcos_akn_to_fileid(sc_card_t *card, sc_cardctl_asepcos_akn2fileid_t *p)
{
	int r;
	u8  sbuf[32], rbuf[SC_MAX_APDU_BUFFER_SIZE];
	sc_apdu_t apdu;

	sbuf[0] = p->akn & 0xff;
	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x28, 0x02, 0x01);
	apdu.cla    |= 0x80;
	apdu.resp    = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.le      = 256;
	apdu.lc      = 1;
	apdu.datalen = 1;
	apdu.data    = sbuf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

	if (apdu.resplen != 4)
		return SC_ERROR_INTERNAL;

	p->fileid = (apdu.resp[1] << 16) | (apdu.resp[2] << 8) | apdu.resp[3];

	return SC_SUCCESS;
}
static int atrust_acos_logout(struct sc_card *card)
{
	int r;
	struct sc_apdu apdu;
	const u8 mf_buf[2] = {0x3f, 0x00};

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x0C);
	apdu.le = 0;
	apdu.lc = 2;
	apdu.data    = mf_buf;
	apdu.datalen = 2;
	apdu.resplen = 0;
	
	sc_ctx_suppress_errors_on(card->ctx);
	r = sc_transmit_apdu(card, &apdu);
	sc_ctx_suppress_errors_off(card->ctx);
	SC_TEST_RET(card->ctx, r, "APDU re-transmit failed");

	if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85)
		/* the only possible reason for this error here is, afaik,
		 * that no MF exists, but then there's no need to logout
		 * => return SC_SUCCESS
		 */
		return SC_SUCCESS;
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
Exemplo n.º 27
0
static int update_single_record(sc_card_t *card, sc_app_info_t *app)
{
	u8 *rec;
	size_t rec_size;
	int r;
	
	r = encode_dir_record(card->ctx, app, &rec, &rec_size);
	if (r)
		return r;
	if (app->rec_nr > 0)
		r = sc_update_record(card, (unsigned int)app->rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR);
	else if (app->rec_nr == 0) {
		/* create new record entry */
		r = sc_append_record(card, rec, rec_size, 0);
		if (r == SC_ERROR_NOT_SUPPORTED) {
			/* if the card doesn't support APPEND RECORD we try a
			 * UPDATE RECORD on the next unused record (and hope
			 * that there is a record with this index).
			 */
			int rec_nr = 0, i;
			for(i = 0; i < card->app_count; i++)
				if (card->app[i]->rec_nr > rec_nr)
					rec_nr = card->app[i]->rec_nr;
			rec_nr++;
			r = sc_update_record(card, (unsigned int)rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR);
		}
	} else {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid record number\n");
		r = SC_ERROR_INTERNAL;
	}
	free(rec);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to update EF(DIR) record");
	return 0;
}
Exemplo n.º 28
0
static int itacns_add_pubkey(sc_pkcs15_card_t *p15card,
	 const sc_path_t *path, const sc_pkcs15_id_t *id, const char *label,
	int usage, int ref, int obj_flags, int *modulus_len_out)
{
	int r;
	sc_pkcs15_pubkey_info_t info;
	sc_pkcs15_object_t obj;

	SC_FUNC_CALLED(p15card->card->ctx, 1);

	memset(&info, 0, sizeof(info));
	memset(&obj,  0, sizeof(obj));

	info.id  		= *id;
	if (path)
		info.path	= *path;
	info.usage		= usage;
	info.key_reference	= ref;
	strlcpy(obj.label, label, sizeof(obj.label));
	obj.flags		= obj_flags;

	/*
	 * This is hard-coded, unless unforeseen versions of the CNS
	 * turn up sometime.
	 */
	info.modulus_length = 1024;

	*modulus_len_out = info.modulus_length;
	r = sc_pkcs15emu_add_rsa_pubkey(p15card, &obj, &info);
	SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r,
		"Could not add pub key");
	return r;
}
Exemplo n.º 29
0
static int mcrd_match_card(sc_card_t * card)
{
	int i = 0, r = 0;
	sc_apdu_t apdu;

	i = _sc_match_atr(card, mcrd_atrs, &card->type);
	if (i >= 0) {
		card->name = mcrd_atrs[i].name;
		return 1;
	}

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xA4, 0x04, 0x00);
	apdu.lc = sizeof(EstEID_v35_AID);
	apdu.data = EstEID_v35_AID;
	apdu.datalen = sizeof(EstEID_v35_AID);
	apdu.resplen = 0;
	apdu.le = 0;
	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "SELECT AID: %02X%02X", apdu.sw1, apdu.sw2);
	if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
	        sc_log(card->ctx, "AID found");
	        card->type = SC_CARD_TYPE_MCRD_ESTEID_V30;
	        return 1;
	}
	return 0;
}
static int acos_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
{
	int r;
	u8  rbuf[SC_MAX_APDU_BUFFER_SIZE];
	sc_apdu_t apdu;

	if (!serial)
		return SC_ERROR_INVALID_ARGUMENTS;
	/* see if we have cached serial number */
	if (card->serialnr.len) {
		memcpy(serial, &card->serialnr, sizeof(*serial));
		return SC_SUCCESS;
	}
	/* get serial number via GET CARD DATA */
	sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xf6, 0x00, 0x00);
	apdu.cla |= 0x80;
	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);
	apdu.le   = 256;
	apdu.lc   = 0;
	apdu.datalen = 0;
        r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");
	if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
		return SC_ERROR_INTERNAL;
	/* cache serial number */
	memcpy(card->serialnr.value, apdu.resp, apdu.resplen);
	card->serialnr.len = apdu.resplen;
	/* copy and return serial number */
	memcpy(serial, &card->serialnr, sizeof(*serial));
	return SC_SUCCESS;
}