Exemplo n.º 1
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.º 2
0
int
sc_pkcs15_decode_pubkey_dsa(sc_context_t *ctx,
		struct sc_pkcs15_pubkey_dsa *key,
		const 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, 0);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 1,
				&key->g.data, &key->g.len, 0);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 2,
				&key->p.data, &key->p.len, 0);
	sc_format_asn1_entry(asn1_dsa_pub_coeff + 3,
				&key->q.data, &key->q.len, 0);

	r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen,
				NULL, NULL);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");

	return 0;
}
Exemplo n.º 3
0
/*
 * We are storing the ec_pointQ as u8 string. not as DER
 */
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[C_ASN1_EC_POINTQ_SIZE];

	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)
		LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");

	sc_log(ctx, "decode-EC key=%p, buf=%p, buflen=%d", key, buf, buflen);

	key->ecpointQ.len = ecpoint_len;
	key->ecpointQ.value = ecpoint_data; 

	/* 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;

	return r;
}
Exemplo n.º 4
0
int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card,
			       struct sc_pkcs15_object *obj,
			       const u8 ** buf, size_t *buflen)
{
        sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_cert_info info;
	struct sc_asn1_entry	asn1_cred_ident[3], asn1_com_cert_attr[4],
				asn1_x509_cert_attr[2], asn1_type_cert_attr[2],
				asn1_cert[2], asn1_x509_cert_value_choice[3];
	struct sc_asn1_pkcs15_object cert_obj = { obj, asn1_com_cert_attr, NULL,
					     asn1_type_cert_attr };
	sc_pkcs15_der_t *der = &info.value;
	u8 id_value[128];
	int id_type;
	size_t id_value_len = sizeof(id_value);
	int r;

	sc_copy_asn1_entry(c_asn1_cred_ident, asn1_cred_ident);
	sc_copy_asn1_entry(c_asn1_com_cert_attr, asn1_com_cert_attr);
	sc_copy_asn1_entry(c_asn1_x509_cert_attr, asn1_x509_cert_attr);
	sc_copy_asn1_entry(c_asn1_x509_cert_value_choice, asn1_x509_cert_value_choice);
	sc_copy_asn1_entry(c_asn1_type_cert_attr, asn1_type_cert_attr);
	sc_copy_asn1_entry(c_asn1_cert, asn1_cert);
	
	sc_format_asn1_entry(asn1_cred_ident + 0, &id_type, NULL, 0);
	sc_format_asn1_entry(asn1_cred_ident + 1, &id_value, &id_value_len, 0);
	sc_format_asn1_entry(asn1_com_cert_attr + 0, &info.id, NULL, 0);
	sc_format_asn1_entry(asn1_com_cert_attr + 1, &info.authority, NULL, 0);
	sc_format_asn1_entry(asn1_com_cert_attr + 2, asn1_cred_ident, NULL, 0);
	sc_format_asn1_entry(asn1_x509_cert_attr + 0, asn1_x509_cert_value_choice, NULL, 0);
	sc_format_asn1_entry(asn1_x509_cert_value_choice + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_x509_cert_value_choice + 1, &der->value, &der->len, 0);
	sc_format_asn1_entry(asn1_type_cert_attr + 0, asn1_x509_cert_attr, NULL, 0);
	sc_format_asn1_entry(asn1_cert + 0, &cert_obj, NULL, 0);

        /* Fill in defaults */
        memset(&info, 0, sizeof(info));
	info.authority = 0;
	
	r = sc_asn1_decode(ctx, asn1_cert, *buf, *buflen, buf, buflen);
	/* In case of error, trash the cert value (direct coding) */
	if (r < 0 && der->value)
		free(der->value);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");
	r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
	if (r < 0)
		return r;
	obj->type = SC_PKCS15_TYPE_CERT_X509;
	obj->data = malloc(sizeof(info));
	if (obj->data == NULL)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	memcpy(obj->data, &info, sizeof(info));

	return 0;
}
int
sc_pkcs15_decode_enveloped_data(sc_context_t *ctx,
				struct sc_pkcs15_enveloped_data *result,
				const u8 *buf, size_t buflen)
{
	struct sc_asn1_entry	asn1_enveloped_data_attr[5],
				asn1_content_attr[4],
				asn1_encr_content[2],
				asn1_recipients_attr[2],
				asn1_kekri_attr[5],
				asn1_kek_attr[4];
	struct sc_pkcs15_enveloped_data data;
	int r;

	sc_copy_asn1_entry(c_asn1_enveloped_data_attr, asn1_enveloped_data_attr);
	sc_copy_asn1_entry(c_asn1_content_attr, asn1_content_attr);
	sc_copy_asn1_entry(c_asn1_encr_content, asn1_encr_content);
	sc_copy_asn1_entry(c_asn1_recipients_attr, asn1_recipients_attr);
	sc_copy_asn1_entry(c_asn1_kekri_attr, asn1_kekri_attr);
	sc_copy_asn1_entry(c_asn1_kek_attr, asn1_kek_attr);

	sc_format_asn1_entry(asn1_enveloped_data_attr + 2,
				asn1_recipients_attr, NULL, 0);
	sc_format_asn1_entry(asn1_enveloped_data_attr + 3,
				asn1_content_attr, NULL, 0);

	sc_format_asn1_entry(asn1_content_attr + 1, &data.ce_alg, NULL, 0);
	sc_format_asn1_entry(asn1_content_attr + 2,
			asn1_encr_content, NULL, 0);
	sc_format_asn1_entry(asn1_encr_content + 0,
			&data.content, &data.content_len, 0);

	sc_format_asn1_entry(asn1_recipients_attr + 0,
			asn1_kekri_attr, NULL, 0);

	sc_format_asn1_entry(asn1_kekri_attr + 1,
			asn1_kek_attr, NULL, 0);
	sc_format_asn1_entry(asn1_kekri_attr + 2,
			&data.ke_alg, NULL, 0);
	sc_format_asn1_entry(asn1_kekri_attr + 3,
			&data.key, &data.key_len, 0);

	sc_format_asn1_entry(asn1_kek_attr + 0,
			&data.id, &data.id.len, 0);

	memset(&data, 0, sizeof(data));

	r = sc_asn1_decode(ctx, asn1_enveloped_data_attr, buf, buflen, NULL, NULL);
	if (r >= 0)
		*result = data;
	return r;
}
Exemplo n.º 6
0
int sc_pkcs15_parse_unusedspace(const u8 * buf, size_t buflen, struct sc_pkcs15_card *card)
{
	const u8 *p = buf;
	size_t left = buflen;
	int r;
	sc_path_t path, dummy_path;
	sc_pkcs15_id_t auth_id;
	struct sc_asn1_entry asn1_unusedspace[] = {
		{ "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
		{ NULL, 0, 0, 0, NULL, NULL }
	};
	struct sc_asn1_entry asn1_unusedspace_values[] = {
		{ "path", SC_ASN1_PATH,	SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
		{ "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
		{ NULL, 0, 0, 0, NULL, NULL }
	};

	/* Clean the list if already present */
	while (card->unusedspace_list)
		sc_pkcs15_remove_unusedspace(card, card->unusedspace_list);

	sc_format_path("3F00", &dummy_path);
	dummy_path.index = dummy_path.count = 0;

	sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1);
	sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1);
	sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0);

	while (left > 0) {
		memset(&auth_id, 0, sizeof(auth_id));
		r = sc_asn1_decode(card->card->ctx, asn1_unusedspace, p, left, &p, &left);
		if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
			break;
		if (r < 0)
			return r;
		/* If the path length is 0, it's a dummy path then don't add it.
		 * If the path length isn't included (-1) then it's against the standard
		 *   but we'll just ignore it instead of returning an error. */
		if (path.count > 0) {
			r = sc_pkcs15_make_absolute_path(&card->file_app->path, &path);
			if (r < 0)
				return r;
			r = sc_pkcs15_add_unusedspace(card, &path, &auth_id);
			if (r)
				return r;
		}
	}

	card->unusedspace_read = 1;

	return 0;
}
static int
sc_pkcs15_decode_prkey_dsa(sc_context_t *ctx,
		struct sc_pkcs15_prkey_dsa *key,
		const u8 *buf, size_t buflen)
{
	struct sc_asn1_entry	asn1_dsa_prkey_obj[2];

	sc_copy_asn1_entry(c_asn1_dsa_prkey_obj, asn1_dsa_prkey_obj);
	sc_format_asn1_entry(asn1_dsa_prkey_obj + 0,
			&key->priv.data, &key->priv.len, 0);

	return sc_asn1_decode(ctx, asn1_dsa_prkey_obj, buf, buflen, NULL, NULL);
}
Exemplo n.º 8
0
static int parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen)
{
	struct sc_asn1_entry asn1_ddo[5];
	sc_path_t odf_path, ti_path, us_path;
	int r;

	sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo);
	sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0);
	sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0);
	sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0);

	r = sc_asn1_decode(p15card->card->ctx, asn1_ddo, buf, buflen, NULL, NULL);
	if (r) {
		sc_error(p15card->card->ctx, "DDO parsing failed: %s\n",
		      sc_strerror(r));
		return r;
	}
	if (asn1_ddo[1].flags & SC_ASN1_PRESENT) {
		p15card->file_odf = sc_file_new();
		if (p15card->file_odf == NULL)
			goto mem_err;
		p15card->file_odf->path = odf_path;
	}
	if (asn1_ddo[2].flags & SC_ASN1_PRESENT) {
		p15card->file_tokeninfo = sc_file_new();
		if (p15card->file_tokeninfo == NULL)
			goto mem_err;
		p15card->file_tokeninfo->path = ti_path;
	}
	if (asn1_ddo[3].flags & SC_ASN1_PRESENT) {
		p15card->file_unusedspace = sc_file_new();
		if (p15card->file_unusedspace == NULL)
			goto mem_err;
		p15card->file_unusedspace->path = us_path;
	}
	return 0;
mem_err:
	if (p15card->file_odf != NULL) {
		sc_file_free(p15card->file_odf);
		p15card->file_odf = NULL;
	}
	if (p15card->file_tokeninfo != NULL) {
		sc_file_free(p15card->file_tokeninfo);
		p15card->file_tokeninfo = NULL;
	}
	if (p15card->file_unusedspace != NULL) {
		sc_file_free(p15card->file_unusedspace);
		p15card->file_unusedspace = NULL;
	}
	return SC_ERROR_OUT_OF_MEMORY;
}
Exemplo n.º 9
0
int sc_pkcs15_decode_dodf_entry(struct sc_pkcs15_card *p15card,
			       struct sc_pkcs15_object *obj,
			       const u8 ** buf, size_t *buflen)
{
        sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_data_info info;
	struct sc_asn1_entry	asn1_com_data_attr[3],
				asn1_type_data_attr[2],
				asn1_data[2];
	struct sc_asn1_pkcs15_object data_obj = { obj, asn1_com_data_attr, NULL,
					     asn1_type_data_attr };
	size_t label_len = sizeof(info.app_label);
	int r;

	sc_copy_asn1_entry(c_asn1_com_data_attr, asn1_com_data_attr);
	sc_copy_asn1_entry(c_asn1_type_data_attr, asn1_type_data_attr);
	sc_copy_asn1_entry(c_asn1_data, asn1_data);

	sc_format_asn1_entry(asn1_com_data_attr + 0, &info.app_label, &label_len, 0);
	sc_format_asn1_entry(asn1_com_data_attr + 1, &info.app_oid, NULL, 0);
	sc_format_asn1_entry(asn1_type_data_attr + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_data + 0, &data_obj, NULL, 0);

	/* Fill in defaults */
	memset(&info, 0, sizeof(info));
	sc_init_oid(&info.app_oid);

	r = sc_asn1_decode(ctx, asn1_data, *buf, *buflen, buf, buflen);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");

	if (!p15card->app || !p15card->app->ddo.aid.len)   {
		r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
		if (r < 0)
			return r;
	}
	else   {
		info.path.aid = p15card->app->ddo.aid;
	}

	obj->type = SC_PKCS15_TYPE_DATA_OBJECT;
	obj->data = malloc(sizeof(info));
	if (obj->data == NULL)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	memcpy(obj->data, &info, sizeof(info));

	return SC_SUCCESS;
}
Exemplo n.º 10
0
int
sc_pkcs15_pubkey_from_spki_object(sc_context_t *ctx, const u8 *buf, size_t buflen,
		sc_pkcs15_pubkey_t ** outpubkey)
{
	int r;
	sc_pkcs15_pubkey_t * pubkey = NULL;
	struct sc_asn1_entry asn1_spki[] = {
			{ "PublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki, &pubkey},
			{ NULL, 0, 0, 0, NULL, NULL } };

	*outpubkey = NULL;

	r = sc_asn1_decode(ctx, asn1_spki, buf, buflen, NULL, NULL);

	*outpubkey = pubkey;
	return r;
}
Exemplo n.º 11
0
int
sc_sm_parse_answer(struct sc_card *card, unsigned char *resp_data, size_t resp_len,
		struct sm_card_response *out)
{
	struct sc_asn1_entry asn1_sm_response[4];
	unsigned char data[SC_MAX_APDU_BUFFER_SIZE];
	size_t data_len = sizeof(data);
	unsigned char status[2] = {0, 0};
	size_t status_len = sizeof(status);
	unsigned char mac[8];
	size_t mac_len = sizeof(mac);
	int rv;

	if (!resp_data || !resp_len || !out)
		return SC_ERROR_INVALID_ARGUMENTS;

	sc_copy_asn1_entry(c_asn1_sm_response, asn1_sm_response);

	sc_format_asn1_entry(asn1_sm_response + 0, data, &data_len, 0);
	sc_format_asn1_entry(asn1_sm_response + 1, status, &status_len, 0);
	sc_format_asn1_entry(asn1_sm_response + 2, mac, &mac_len, 0);

	rv = sc_asn1_decode(card->ctx, asn1_sm_response, resp_data, resp_len, NULL, NULL);
	if (rv)
		return rv;

	if (asn1_sm_response[0].flags & SC_ASN1_PRESENT)   {
		if (data_len > sizeof(out->data))
			return SC_ERROR_BUFFER_TOO_SMALL;
		memcpy(out->data, data, data_len);
		out->data_len = data_len;
	}
	if (asn1_sm_response[1].flags & SC_ASN1_PRESENT)   {
		if (!status[0])
			return SC_ERROR_INVALID_DATA;
		out->sw1 = status[0];
		out->sw2 = status[1];
	}
	if (asn1_sm_response[2].flags & SC_ASN1_PRESENT)   {
		memcpy(out->mac, mac, mac_len);
		out->mac_len = mac_len;
	}

	return SC_SUCCESS;
}
Exemplo n.º 12
0
int
sc_pkcs15_decode_pubkey_gostr3410(sc_context_t *ctx, struct sc_pkcs15_pubkey_gostr3410 *key,
		const u8 *buf, size_t buflen)
{
	struct sc_asn1_entry asn1_gostr3410_pub_coeff[C_ASN1_GOSTR3410_PUB_COEFFICIENTS_SIZE];
	int r;
	struct sc_object_id param_key = {{ 1, 2, 643, 2, 2, 35, 1, -1}};
	struct sc_object_id param_hash = {{ 1, 2, 643, 2, 2, 30, 1, -1}};

	sc_copy_asn1_entry(c_asn1_gostr3410_pub_coefficients, asn1_gostr3410_pub_coeff);
	sc_format_asn1_entry(asn1_gostr3410_pub_coeff + 0, &key->xy.data, &key->xy.len, 0);

	r = sc_asn1_decode(ctx, asn1_gostr3410_pub_coeff, buf, buflen, NULL, NULL);
	LOG_TEST_RET(ctx, r, "ASN.1 parsing of public key failed");

	key->params.key = param_key;
	key->params.hash = param_hash;

	return 0;
}
Exemplo n.º 13
0
int
sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key,
		const u8 *buf, size_t buflen)
{
	struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE];
	struct sc_asn1_entry asn1_rsa_pub_coefficients[C_ASN1_RSA_PUB_COEFFICIENTS_SIZE];
	int r;

	sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
	sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_pub_coefficients, NULL, 0);

	sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_pub_coefficients);
	sc_format_asn1_entry(asn1_rsa_pub_coefficients + 0, &key->modulus.data, &key->modulus.len, 0);
	sc_format_asn1_entry(asn1_rsa_pub_coefficients + 1, &key->exponent.data, &key->exponent.len, 0);

	r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL);
	LOG_TEST_RET(ctx, r, "ASN.1 parsing of public key failed");

	return SC_SUCCESS;
}
Exemplo n.º 14
0
/*
 *  Get an extension whose value is a bit string. These include keyUsage and extendedKeyUsage.
 *  See above for the other parameters.
 */
int
sc_pkcs15_get_bitstring_extension(struct sc_context *ctx,
	struct sc_pkcs15_cert *cert, const struct sc_object_id *type,
	unsigned long long *value, int *is_critical)
{
	int r;
	u8 *bit_string = NULL;
	size_t bit_string_len=0, val_len = sizeof(*value);
	struct sc_asn1_entry asn1_bit_string[] = {
		{ "bitString", SC_ASN1_BIT_STRING, SC_ASN1_TAG_BIT_STRING, 0, value, &val_len },
		{ NULL, 0, 0, 0, NULL, NULL }
	};

	r = sc_pkcs15_get_extension(ctx, cert, type, &bit_string, &bit_string_len, is_critical);
	LOG_TEST_RET(ctx, r, "Get extension error");

	r = sc_asn1_decode(ctx, asn1_bit_string, bit_string, bit_string_len, NULL, NULL);
	LOG_TEST_RET(ctx, r, "Decoding extension bit string");

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Exemplo n.º 15
0
int
sc_pkcs15_decode_pubkey_dsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_dsa *key,
		const u8 *buf, size_t buflen)
{
	struct sc_asn1_entry asn1_public_key[C_ASN1_PUBLIC_KEY_SIZE];
	struct sc_asn1_entry asn1_dsa_pub_coefficients[C_ASN1_DSA_PUB_COEFFICIENTS_SIZE];
	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_coefficients);

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

	r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL);
	LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");

	return 0;
}
Exemplo n.º 16
0
Arquivo: apdu.c Projeto: pawmas/opensc
static int
sc_sm_parse_answer(struct sc_context *ctx, unsigned char *resp_data, size_t resp_len,
		struct sm_card_response *out)
{
	struct sc_asn1_entry asn1_sm_response[4];
	unsigned char data[SC_MAX_APDU_BUFFER_SIZE];
	size_t data_len = sizeof(data);
	unsigned char status[2] = {0, 0};
	size_t status_len = sizeof(status);
	unsigned char mac[8];
	size_t mac_len = sizeof(mac);
	int r;

	if (!resp_data || !resp_len || !out)
		return SC_ERROR_INVALID_ARGUMENTS;

	sc_copy_asn1_entry(c_asn1_sm_response, asn1_sm_response);

	sc_format_asn1_entry(asn1_sm_response + 0, data, &data_len, 0);
	sc_format_asn1_entry(asn1_sm_response + 1, status, &status_len, 0);
	sc_format_asn1_entry(asn1_sm_response + 2, mac, &mac_len, 0);

	r = sc_asn1_decode(ctx, asn1_sm_response, resp_data, resp_len, NULL, NULL);
	if (r)
		return r;

	if (asn1_sm_response[1].flags & SC_ASN1_PRESENT)   {
		out->sw1 = status[0];
		out->sw2 = status[1];
	}

	if (asn1_sm_response[2].flags & SC_ASN1_PRESENT)   {
		memcpy(out->mac, mac, mac_len);
		out->mac_len = mac_len;
	}
	/* TODO: to be continued ... */

	return SC_SUCCESS;
}
Exemplo n.º 17
0
int
sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx,
			struct sc_pkcs15_pubkey_rsa *key,
			const u8 *buf, size_t buflen)
{
	struct sc_asn1_entry asn1_public_key[2];
	struct sc_asn1_entry asn1_rsa_coeff[3];
	int r;
	
	sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key);
	sc_format_asn1_entry(asn1_public_key + 0, asn1_rsa_coeff, NULL, 0);

	sc_copy_asn1_entry(c_asn1_rsa_pub_coefficients, asn1_rsa_coeff);
	sc_format_asn1_entry(asn1_rsa_coeff + 0,
				&key->modulus.data, &key->modulus.len, 0);
	sc_format_asn1_entry(asn1_rsa_coeff + 1,
				&key->exponent.data, &key->exponent.len, 0);

	r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 parsing of public key failed");

	return 0;
}
Exemplo n.º 18
0
int
sc_pkcs15_pubkey_from_spki_filename(sc_context_t *ctx, char * filename,
		sc_pkcs15_pubkey_t ** outpubkey)
{
	int r;
	u8 * buf = NULL;
	size_t buflen = 0;
	sc_pkcs15_pubkey_t * pubkey = NULL;
	struct sc_asn1_entry asn1_spki[] = {
		{ "PublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki, &pubkey},
		{ NULL, 0, 0, 0, NULL, NULL } };

	*outpubkey = NULL;
	r = sc_pkcs15_read_der_file(ctx, filename, &buf, &buflen);
	if (r < 0)
		return r;

	r = sc_asn1_decode(ctx, asn1_spki, buf, buflen, NULL, NULL);

	if (buf)
		free(buf);
	*outpubkey = pubkey;
	return r;
}
Exemplo n.º 19
0
int
sm_gp_decode_card_answer(struct sc_context *ctx, struct sc_remote_data *rdata, unsigned char *out, size_t out_len)
{
#if 0
	struct sc_asn1_entry asn1_authentic_card_response[4], asn1_card_response[2];
	struct sc_hash *hash = NULL;
	unsigned char *hex = NULL;
	size_t hex_len;
	int rv, offs;
	unsigned char card_data[SC_MAX_APDU_BUFFER_SIZE];
	size_t card_data_len = sizeof(card_data), len_left = 0;

	LOG_FUNC_CALLED(ctx);

	if (!out || !out_len)
		LOG_FUNC_RETURN(ctx, 0);
	if (strstr(str_data, "DATA="))   {
		rv = sc_hash_parse(ctx, str_data, strlen(str_data), &hash);
		LOG_TEST_RET(ctx, rv, "SM GP decode card answer: parse input data error");

		str_data = sc_hash_get(hash, "DATA");
	}

	if (!strlen(str_data))
		LOG_FUNC_RETURN(ctx, 0);

	hex_len = strlen(str_data) / 2;
	hex = calloc(1, hex_len);
	if (!hex)
		LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SM GP decode card answer: hex allocate error");

	sc_log(ctx, "SM GP decode card answer: hex length %i", hex_len);
	rv = sc_hex_to_bin(str_data, hex, &hex_len);
	LOG_TEST_RET(ctx, rv, "SM GP decode card answer: data 'HEX to BIN' conversion error");
	sc_log(ctx, "SM GP decode card answer: hex length %i", hex_len);

	if (hash)
		sc_hash_free(hash);

	for (offs = 0, len_left = hex_len; len_left; )   {
		int num, status;

		sc_copy_asn1_entry(c_asn1_authentic_card_response, asn1_authentic_card_response);
		sc_copy_asn1_entry(c_asn1_card_response, asn1_card_response);
		sc_format_asn1_entry(asn1_authentic_card_response + 0, &num, NULL, 0);
		sc_format_asn1_entry(asn1_authentic_card_response + 1, &status, NULL, 0);
		card_data_len = sizeof(card_data);
		sc_format_asn1_entry(asn1_authentic_card_response + 2, &card_data, &card_data_len, 0);
		sc_format_asn1_entry(asn1_card_response + 0, asn1_authentic_card_response, NULL, 0);

		rv = sc_asn1_decode(ctx, asn1_card_response, hex + hex_len - len_left, len_left, NULL, &len_left);
		if (rv) {
			sc_log(ctx, "SM GP decode card answer: ASN.1 parse error: %s", sc_strerror(rv));
			return rv;
		}
		if (status != 0x9000)
			continue;

		if (asn1_authentic_card_response[2].flags & SC_ASN1_PRESENT)   {
			sc_log(ctx, "SM GP decode card answer: card_data_len %i", card_data_len);
			if (out_len < offs + card_data_len)
				LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "SM GP decode card answer: buffer too small");

			memcpy(out + offs, card_data, card_data_len);
			offs += card_data_len;
		}

		sc_log(ctx, "SM GP decode card answer: offs:%i,left:%i", offs, len_left);
	}

	free(hex);
	LOG_FUNC_RETURN(ctx, offs);
#else
	LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
#endif
}
Exemplo n.º 20
0
int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card,
				 struct sc_pkcs15_object *obj,
				 const u8 ** buf, size_t *buflen)
{
	sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_pubkey_info info;
	int r, gostr3410_params[3];
	struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
	size_t usage_len = sizeof(info.usage);
	size_t af_len = sizeof(info.access_flags);
	struct sc_pkcs15_der *der = &obj->content;
	struct sc_asn1_entry asn1_com_key_attr[C_ASN1_COM_KEY_ATTR_SIZE];
	struct sc_asn1_entry asn1_com_pubkey_attr[C_ASN1_COM_PUBKEY_ATTR_SIZE];
	struct sc_asn1_entry asn1_rsakey_value_choice[C_ASN1_RSAKEY_VALUE_CHOICE_SIZE];
	struct sc_asn1_entry asn1_rsakey_attr[C_ASN1_RSAKEY_ATTR_SIZE];
	struct sc_asn1_entry asn1_rsa_type_attr[C_ASN1_RSA_TYPE_ATTR_SIZE];
	struct sc_asn1_entry asn1_eckey_value_choice[C_ASN1_ECKEY_VALUE_CHOICE_SIZE];
	struct sc_asn1_entry asn1_eckey_attr[C_ASN1_ECKEY_ATTR_SIZE];
	struct sc_asn1_entry asn1_ec_type_attr[C_ASN1_EC_TYPE_ATTR_SIZE];
	struct sc_asn1_entry asn1_dsakey_attr[C_ASN1_DSAKEY_ATTR_SIZE];
	struct sc_asn1_entry asn1_dsa_type_attr[C_ASN1_DSA_TYPE_ATTR_SIZE];
	struct sc_asn1_entry asn1_gostr3410key_attr[C_ASN1_GOST3410KEY_ATTR_SIZE];
	struct sc_asn1_entry asn1_gostr3410_type_attr[C_ASN1_GOST3410_TYPE_ATTR_SIZE];
	struct sc_asn1_entry asn1_pubkey_choice[C_ASN1_PUBKEY_CHOICE_SIZE];
	struct sc_asn1_entry asn1_pubkey[C_ASN1_PUBKEY_SIZE];
	struct sc_asn1_pkcs15_object rsakey_obj = { obj, asn1_com_key_attr,
						    asn1_com_pubkey_attr, asn1_rsa_type_attr };
	struct sc_asn1_pkcs15_object eckey_obj = { obj, asn1_com_key_attr,
						    asn1_com_pubkey_attr, asn1_ec_type_attr };
	struct sc_asn1_pkcs15_object dsakey_obj = { obj, asn1_com_key_attr,
						    asn1_com_pubkey_attr, asn1_dsa_type_attr };
	struct sc_asn1_pkcs15_object gostr3410key_obj =  { obj, asn1_com_key_attr,
						    asn1_com_pubkey_attr, asn1_gostr3410_type_attr };

	sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey);
	sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice);
	sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr);
	sc_copy_asn1_entry(c_asn1_rsakey_value_choice, asn1_rsakey_value_choice);
	sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
	sc_copy_asn1_entry(c_asn1_ec_type_attr, asn1_ec_type_attr);
	sc_copy_asn1_entry(c_asn1_eckey_value_choice, asn1_eckey_value_choice);
	sc_copy_asn1_entry(c_asn1_eckey_attr, asn1_eckey_attr);
	sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr);
	sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr);
	sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr);
	sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
	sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr);
	sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);

	sc_format_asn1_entry(asn1_com_pubkey_attr + 0, &info.subject.value, &info.subject.len, 0);

	sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 0);
	sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 0);
	sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 0);
	sc_format_asn1_entry(asn1_pubkey_choice + 3, &eckey_obj, NULL, 0);

	sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 0);

	sc_format_asn1_entry(asn1_rsakey_value_choice + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_rsakey_value_choice + 1, &der->value, &der->len, 0);

	sc_format_asn1_entry(asn1_rsakey_attr + 0, asn1_rsakey_value_choice, NULL, 0);
	sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0);

	sc_format_asn1_entry(asn1_ec_type_attr + 0, asn1_eckey_attr, NULL, 0);

	sc_format_asn1_entry(asn1_eckey_value_choice + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_eckey_value_choice + 1, &der->value, &der->len, 0);

	sc_format_asn1_entry(asn1_eckey_attr + 0, asn1_eckey_value_choice, NULL, 0);
	sc_format_asn1_entry(asn1_eckey_attr + 1, &info.field_length, NULL, 0);

	sc_format_asn1_entry(asn1_dsa_type_attr + 0, asn1_dsakey_attr, NULL, 0);

	sc_format_asn1_entry(asn1_dsakey_attr + 0, &info.path, NULL, 0);

	sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 0);

	sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0);
	sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0);
	sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0);

	sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0);
	sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0);
	sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0);
	sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0);
	sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0);

	sc_format_asn1_entry(asn1_pubkey + 0, asn1_pubkey_choice, NULL, 0);

	/* Fill in defaults */
	memset(&info, 0, sizeof(info));
	info.key_reference = -1;
	info.native = 1;
	memset(gostr3410_params, 0, sizeof(gostr3410_params));

	r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	LOG_TEST_RET(ctx, r, "ASN.1 decoding failed");
	if (asn1_pubkey_choice[0].flags & SC_ASN1_PRESENT) {
		obj->type = SC_PKCS15_TYPE_PUBKEY_RSA;
	} else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) {
		obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410;
		assert(info.modulus_length == 0);
		info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE;
		assert(info.params.len == 0);
		info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams);
		info.params.data = malloc(info.params.len);
		if (info.params.data == NULL)
			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
		assert(sizeof(*keyinfo_gostparams) == info.params.len);
		keyinfo_gostparams = info.params.data;
		keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0];
		keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1];
		keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2];
	} 
	else if (asn1_pubkey_choice[3].flags & SC_ASN1_PRESENT) {
		obj->type = SC_PKCS15_TYPE_PUBKEY_EC;
	}
	else {
		obj->type = SC_PKCS15_TYPE_PUBKEY_DSA;
	}
	if (!p15card->app || !p15card->app->ddo.aid.len)   {
		r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
		if (r < 0) {
			sc_pkcs15_free_key_params(&info.params);
			return r;
		}
	}
	else   {
		info.path.aid = p15card->app->ddo.aid;
	}
	sc_log(ctx, "PubKey path '%s'", sc_print_path(&info.path));

        /* OpenSC 0.11.4 and older encoded "keyReference" as a negative
           value. Fixed in 0.11.5 we need to add a hack, so old cards
           continue to work. */
	if (info.key_reference < -1)
		info.key_reference += 256;

	obj->data = malloc(sizeof(info));
	if (obj->data == NULL) {
		sc_pkcs15_free_key_params(&info.params);
		LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
	}
	memcpy(obj->data, &info, sizeof(info));

	return 0;
}
Exemplo n.º 21
0
int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
	sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen)
{
	int r;
	u8 serial[128];
	size_t i;
	size_t serial_len = sizeof(serial);
	u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE];
	size_t mnfid_len  = sizeof(mnfid);
	u8 label[SC_PKCS15_MAX_LABEL_SIZE];
	size_t label_len = sizeof(label);
	u8 last_update[32];
	size_t lupdate_len = sizeof(last_update) - 1;
	size_t flags_len   = sizeof(ti->flags);
	struct sc_asn1_entry asn1_toki[14], asn1_tokeninfo[3], asn1_twlabel[3];
	u8 preferred_language[3];
	size_t lang_length = sizeof(preferred_language);

	memset(last_update, 0, sizeof(last_update));
	sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel);
	sc_copy_asn1_entry(c_asn1_toki, asn1_toki);
	sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
	sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0);
	sc_format_asn1_entry(asn1_toki + 0, &ti->version, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 1, serial, &serial_len, 0);
	sc_format_asn1_entry(asn1_toki + 2, mnfid, &mnfid_len, 0);
	sc_format_asn1_entry(asn1_toki + 3, label, &label_len, 0);
	sc_format_asn1_entry(asn1_toki + 4, asn1_twlabel, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 5, &ti->flags, &flags_len, 0);
	sc_format_asn1_entry(asn1_toki + 6, &ti->seInfo, &ti->num_seInfo, 0);
	sc_format_asn1_entry(asn1_toki + 7, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 8, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 9, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 10, NULL, NULL, 0);
	sc_format_asn1_entry(asn1_toki + 11, last_update, &lupdate_len, 0);
	sc_format_asn1_entry(asn1_toki + 12, preferred_language, &lang_length, 0);
	sc_format_asn1_entry(asn1_tokeninfo, asn1_toki, NULL, 0);
	
	r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL);
	if (r) {
		sc_error(ctx, "ASN.1 parsing of EF(TokenInfo) failed: %s\n",
			sc_strerror(r));
		return r;
	}
	ti->version += 1;
	ti->serial_number = (char *) malloc(serial_len * 2 + 1);
	if (ti->serial_number == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	ti->serial_number[0] = 0;
	for (i = 0; i < serial_len; i++) {
		char byte[3];

		sprintf(byte, "%02X", serial[i]);
		strcat(ti->serial_number, byte);
	}
	if (ti->manufacturer_id == NULL) {
		if (asn1_toki[2].flags & SC_ASN1_PRESENT)
			ti->manufacturer_id = strdup((char *) mnfid);
		else
			ti->manufacturer_id = strdup("(unknown)");
		if (ti->manufacturer_id == NULL)
			return SC_ERROR_OUT_OF_MEMORY;
	}
	if (ti->label == NULL) {
		if (asn1_toki[3].flags & SC_ASN1_PRESENT ||
		    asn1_toki[4].flags & SC_ASN1_PRESENT)
			ti->label = strdup((char *) label);
		else
			ti->label = strdup("(unknown)");
		if (ti->label == NULL)
			return SC_ERROR_OUT_OF_MEMORY;
	}
	if (asn1_toki[11].flags & SC_ASN1_PRESENT) {
		ti->last_update = strdup((char *)last_update);
		if (ti->last_update == NULL)
			return SC_ERROR_OUT_OF_MEMORY;
	}
	if (asn1_toki[12].flags & SC_ASN1_PRESENT) {
		preferred_language[2] = 0;
		ti->preferred_language = strdup((char *)preferred_language);
		if (ti->preferred_language == NULL)
			return SC_ERROR_OUT_OF_MEMORY;
	}
	return SC_SUCCESS;
}
Exemplo n.º 22
0
int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card,
				struct sc_pkcs15_object *obj,
				const u8 ** buf, size_t *buflen)
{
	sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_auth_info info;
	int r;
	size_t flags_len = sizeof(info.attrs.pin.flags);
	size_t padchar_len = 1;
	struct sc_asn1_entry asn1_com_ao_attr[2], asn1_pin_attr[10], asn1_type_pin_attr[2];
	struct sc_asn1_entry asn1_pin[2];
	struct sc_asn1_pkcs15_object pin_obj = { obj, asn1_com_ao_attr, NULL, asn1_type_pin_attr };
	
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_ASN1);
	sc_copy_asn1_entry(c_asn1_pin, asn1_pin);
	sc_copy_asn1_entry(c_asn1_type_pin_attr, asn1_type_pin_attr);
	sc_copy_asn1_entry(c_asn1_pin_attr, asn1_pin_attr);
	sc_copy_asn1_entry(c_asn1_com_ao_attr, asn1_com_ao_attr);

	sc_format_asn1_entry(asn1_pin + 0, &pin_obj, NULL, 0);

	sc_format_asn1_entry(asn1_type_pin_attr + 0, asn1_pin_attr, NULL, 0);

	sc_format_asn1_entry(asn1_pin_attr + 0, &info.attrs.pin.flags, &flags_len, 0);
	sc_format_asn1_entry(asn1_pin_attr + 1, &info.attrs.pin.type, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 2, &info.attrs.pin.min_length, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 3, &info.attrs.pin.stored_length, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 4, &info.attrs.pin.max_length, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 5, &info.attrs.pin.reference, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 6, &info.attrs.pin.pad_char, &padchar_len, 0);
	/* We don't support lastPinChange yet. */
	sc_format_asn1_entry(asn1_pin_attr + 8, &info.path, NULL, 0);

	sc_format_asn1_entry(asn1_com_ao_attr + 0, &info.auth_id, NULL, 0);

	/* Fill in defaults */
	memset(&info, 0, sizeof(info));
	info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
	info.tries_left = -1;

	r = sc_asn1_decode(ctx, asn1_pin, *buf, *buflen, buf, buflen);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");

	obj->type = SC_PKCS15_TYPE_AUTH_PIN;
	obj->data = malloc(sizeof(info));
	if (obj->data == NULL)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);

	if (info.attrs.pin.max_length == 0) {
		if (p15card->card->max_pin_len != 0)
			info.attrs.pin.max_length = p15card->card->max_pin_len;
		else if (info.attrs.pin.stored_length != 0)
			info.attrs.pin.max_length = info.attrs.pin.type != SC_PKCS15_PIN_TYPE_BCD ?
				info.attrs.pin.stored_length : 2 * info.attrs.pin.stored_length;
		else
			info.attrs.pin.max_length = 8; /* shouldn't happen */
	}

	/* OpenSC 0.11.4 and older encoded "pinReference" as a negative
	   value. Fixed in 0.11.5 we need to add a hack, so old cards
	   continue to work. 
	   The same invalid encoding has some models of the proprietary PKCS#15 cards.
	*/
	if (info.attrs.pin.reference < 0)
		info.attrs.pin.reference += 256;

	info.auth_method = SC_AC_CHV;

	if (info.attrs.pin.flags & SC_PKCS15_PIN_FLAG_LOCAL)   {
		/* In OpenSC pkcs#15 framework 'path' is mandatory for the 'Local' PINs. 
		 * If 'path' do not present in PinAttributes, 
		 * 	derive it from the PKCS#15 context. */
		if (!info.path.len)   {
			/* Give priority to AID defined in the application DDO */
			if (p15card->app && p15card->app->ddo.aid.len)
				info.path.aid = p15card->app->ddo.aid;
			else if (p15card->file_app->path.len)
				info.path = p15card->file_app->path;
		}
	}
	sc_debug(ctx, SC_LOG_DEBUG_ASN1, "decoded PIN(ref:%X,path:%s)", info.attrs.pin.reference, sc_print_path(&info.path));

	memcpy(obj->data, &info, sizeof(info));
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_SUCCESS);
}
Exemplo n.º 23
0
static void do_belpic(sc_card_t *card)
{
	/* Contents of the ID file (3F00\DF01\4031) */
	struct {
		char cardnumber[12 + 1];
		char chipnumber[2 * 16 + 1];
		char validfrom[10 + 1];
		char validtill[10 + 1];
		char deliveringmunicipality[50 + 1];  /* UTF8 */
		char nationalnumber[12 + 1];
		char name[90 + 1]; /* UTF8 */
		char firstnames[75 + 1]; /* UTF8 */
		char initial[3 + 1]; /* UTF8 */
		char nationality[65 + 1]; /* UTF8 */
		char birthlocation[60 + 1]; /* UTF8 */
		char birthdate[12 + 1];
		char sex[1 + 1];
		char noblecondition[30 + 1]; /* UTF8 */
		char documenttype[5 + 1];
		char specialstatus[5 + 1];
	} id_data;
	int cardnumberlen = sizeof(id_data.cardnumber);
	int chipnumberlen = sizeof(id_data.chipnumber);
	int validfromlen = sizeof(id_data.validfrom);
	int validtilllen = sizeof(id_data.validtill);
	int deliveringmunicipalitylen = sizeof(id_data.deliveringmunicipality);
	int nationalnumberlen = sizeof(id_data.nationalnumber);
	int namelen = sizeof(id_data.name);
	int firstnameslen = sizeof(id_data.firstnames);
	int initiallen = sizeof(id_data.initial);
	int nationalitylen = sizeof(id_data.nationality);
	int birthlocationlen = sizeof(id_data.birthlocation);
	int birthdatelen = sizeof(id_data.birthdate);
	int sexlen = sizeof(id_data.sex);
	int nobleconditionlen = sizeof(id_data.noblecondition);
	int documenttypelen = sizeof(id_data.documenttype);
	int specialstatuslen = sizeof(id_data.specialstatus);

	struct sc_asn1_entry id[] = {
		{"cardnumber", SC_ASN1_UTF8STRING, 1, 0, id_data.cardnumber, &cardnumberlen},
		{"chipnumber", SC_ASN1_OCTET_STRING, 2, 0, id_data.chipnumber, &chipnumberlen},
		{"validfrom", SC_ASN1_UTF8STRING, 3, 0, id_data.validfrom, &validfromlen},
		{"validtill", SC_ASN1_UTF8STRING, 4, 0, id_data.validtill, &validtilllen},
		{"deliveringmunicipality", SC_ASN1_UTF8STRING, 5, 0, id_data.deliveringmunicipality, &deliveringmunicipalitylen},
		{"nationalnumber", SC_ASN1_UTF8STRING, 6, 0, id_data.nationalnumber, &nationalnumberlen},
		{"name", SC_ASN1_UTF8STRING, 7, 0, id_data.name, &namelen},
		{"firstname(s)", SC_ASN1_UTF8STRING, 8, 0, id_data.firstnames, &firstnameslen},
		{"initial", SC_ASN1_UTF8STRING, 9, 0, id_data.initial, &initiallen},
		{"nationality", SC_ASN1_UTF8STRING, 10, 0, id_data.nationality, &nationalitylen},
		{"birthlocation", SC_ASN1_UTF8STRING, 11, 0, id_data.birthlocation, &birthlocationlen},
		{"birthdate", SC_ASN1_UTF8STRING, 12, 0, id_data.birthdate, &birthdatelen},
		{"sex", SC_ASN1_UTF8STRING, 13, 0, id_data.sex, &sexlen},
		{"noblecondition", SC_ASN1_UTF8STRING, 14, 0, id_data.noblecondition, &nobleconditionlen},
		{"documenttype", SC_ASN1_UTF8STRING, 15, 0, id_data.documenttype, &documenttypelen},
		{"specialstatus", SC_ASN1_UTF8STRING, 16, 0, id_data.specialstatus, &specialstatuslen},
		{NULL, 0, 0, 0, NULL, NULL}
	};

	/* Contents of the Address file (3F00\DF01\4033) */
	struct {
		char streetandnumber[63 + 1]; /* UTF8 */
		char zipcode[4 + 1];
		char municipality[40 + 1]; /* UTF8 */
	} address_data;
	int streetandnumberlen = sizeof(address_data.streetandnumber);
	int zipcodelen = sizeof(address_data.zipcode);
	int municipalitylen = sizeof(address_data.municipality);
	struct sc_asn1_entry address[] = {
		{"streetandnumber", SC_ASN1_UTF8STRING, 1, 0, address_data.streetandnumber, &streetandnumberlen},
		{"zipcode", SC_ASN1_UTF8STRING, 2, 0, address_data.zipcode, &zipcodelen},
		{"municipal", SC_ASN1_UTF8STRING, 3, 0, address_data.municipality, &municipalitylen},
		{NULL, 0, 0, 0, NULL, NULL}};

	unsigned char buff[512];
	int r;

	r = read_transp(card, "3f00df014031", buff, sizeof(buff));
	if (r < 0)
		goto out;

	memset(&id_data, 0, sizeof(id_data));

	r = sc_asn1_decode(card->ctx, id, buff, r, NULL, NULL);
	if (r < 0) {
		fprintf(stderr, "\nFailed to decode the ID file: %s\n", sc_strerror(r));
		goto out;
	}

	exportprint("BELPIC_CARDNUMBER", id_data.cardnumber);
	bintohex(id_data.chipnumber, chipnumberlen);
	exportprint("BELPIC_CHIPNUMBER", id_data.chipnumber);
	exportprint("BELPIC_VALIDFROM", id_data.validfrom);
	exportprint("BELPIC_VALIDTILL", id_data.validtill);
	exportprint("BELPIC_DELIVERINGMUNICIPALITY", id_data.deliveringmunicipality);
	exportprint("BELPIC_NATIONALNUMBER", id_data.nationalnumber);
	exportprint("BELPIC_NAME", id_data.name);
	exportprint("BELPIC_FIRSTNAMES", id_data.firstnames);
	exportprint("BELPIC_INITIAL", id_data.initial);
	exportprint("BELPIC_NATIONALITY", id_data.nationality);
	exportprint("BELPIC_BIRTHLOCATION", id_data.birthlocation);
	exportprint("BELPIC_BIRTHDATE", id_data.birthdate);
	exportprint("BELPIC_SEX", id_data.sex);
	exportprint("BELPIC_NOBLECONDITION", id_data.noblecondition);
	exportprint("BELPIC_DOCUMENTTYPE", id_data.documenttype);
	exportprint("BELPIC_SPECIALSTATUS", id_data.specialstatus);

	r = read_transp(card, "3f00df014033", buff, sizeof(buff));
	if (r < 0)
		goto out;

	memset(&address_data, 0, sizeof(address_data));

	r = sc_asn1_decode(card->ctx, address, buff, r, NULL, NULL);
	if (r < 0) {
		fprintf(stderr, "\nFailed to decode the Address file: %s\n", sc_strerror(r));
		goto out;
	}

	exportprint("BELPIC_STREETANDNUMBER", address_data.streetandnumber);
	exportprint("BELPIC_ZIPCODE", address_data.zipcode);
	exportprint("BELPIC_MUNICIPALITY", address_data.municipality);

out:
	return;
}
Exemplo n.º 24
0
/*
 * Decode a card verifiable certificate as defined in TR-03110.
 */
int sc_pkcs15emu_sc_hsm_decode_cvc(sc_pkcs15_card_t * p15card,
											const u8 ** buf, size_t *buflen,
											sc_cvc_t *cvc)
{
	sc_card_t *card = p15card->card;
	struct sc_asn1_entry asn1_req[C_ASN1_REQ_SIZE];
	struct sc_asn1_entry asn1_authreq[C_ASN1_AUTHREQ_SIZE];
	struct sc_asn1_entry asn1_cvc[C_ASN1_CVC_SIZE];
	struct sc_asn1_entry asn1_cvcert[C_ASN1_CVCERT_SIZE];
	struct sc_asn1_entry asn1_cvc_body[C_ASN1_CVC_BODY_SIZE];
	struct sc_asn1_entry asn1_cvc_pubkey[C_ASN1_CVC_PUBKEY_SIZE];
	unsigned int cla,tag;
	size_t taglen;
	size_t lenchr = sizeof(cvc->chr);
	size_t lencar = sizeof(cvc->car);
	size_t lenoutercar = sizeof(cvc->outer_car);
	const u8 *tbuf;
	int r;

	memset(cvc, 0, sizeof(*cvc));
	sc_copy_asn1_entry(c_asn1_req, asn1_req);
	sc_copy_asn1_entry(c_asn1_authreq, asn1_authreq);
	sc_copy_asn1_entry(c_asn1_cvc, asn1_cvc);
	sc_copy_asn1_entry(c_asn1_cvcert, asn1_cvcert);
	sc_copy_asn1_entry(c_asn1_cvc_body, asn1_cvc_body);
	sc_copy_asn1_entry(c_asn1_cvc_pubkey, asn1_cvc_pubkey);

	sc_format_asn1_entry(asn1_cvc_pubkey    , &cvc->pukoid, NULL, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 1, &cvc->primeOrModulus, &cvc->primeOrModuluslen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 2, &cvc->coefficientAorExponent, &cvc->coefficientAorExponentlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 3, &cvc->coefficientB, &cvc->coefficientBlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 4, &cvc->basePointG, &cvc->basePointGlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 5, &cvc->order, &cvc->orderlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 6, &cvc->publicPoint, &cvc->publicPointlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 7, &cvc->cofactor, &cvc->cofactorlen, 0);
	sc_format_asn1_entry(asn1_cvc_pubkey + 8, &cvc->modulusSize, NULL, 0);

	sc_format_asn1_entry(asn1_cvc_body    , &cvc->cpi, NULL, 0);
	sc_format_asn1_entry(asn1_cvc_body + 1, &cvc->car, &lencar, 0);
	sc_format_asn1_entry(asn1_cvc_body + 2, &asn1_cvc_pubkey, NULL, 0);
	sc_format_asn1_entry(asn1_cvc_body + 3, &cvc->chr, &lenchr, 0);

	sc_format_asn1_entry(asn1_cvcert    , &asn1_cvc_body, NULL, 0);
	sc_format_asn1_entry(asn1_cvcert + 1, &cvc->signature, &cvc->signatureLen, 0);

	sc_format_asn1_entry(asn1_cvc , &asn1_cvcert, NULL, 0);

	sc_format_asn1_entry(asn1_authreq    , &asn1_cvcert, NULL, 0);
	sc_format_asn1_entry(asn1_authreq + 1, &cvc->outer_car, &lenoutercar, 0);
	sc_format_asn1_entry(asn1_authreq + 2, &cvc->outerSignature, &cvc->outerSignatureLen, 0);

	sc_format_asn1_entry(asn1_req , &asn1_authreq, NULL, 0);

/*	sc_asn1_print_tags(*buf, *buflen); */

	tbuf = *buf;
	r = sc_asn1_read_tag(&tbuf, *buflen, &cla, &tag, &taglen);
	LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate");

	/*  Determine if we deal with an authenticated request, plain request or certificate */
	if ((cla == (SC_ASN1_TAG_APPLICATION|SC_ASN1_TAG_CONSTRUCTED)) && (tag == 7)) {
		r = sc_asn1_decode(card->ctx, asn1_req, *buf, *buflen, buf, buflen);
	} else {
		r = sc_asn1_decode(card->ctx, asn1_cvc, *buf, *buflen, buf, buflen);
	}

	LOG_TEST_RET(card->ctx, r, "Could not decode card verifiable certificate");

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
Exemplo n.º 25
0
int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card,
				struct sc_pkcs15_object *obj,
				const u8 ** buf, size_t *buflen)
{
	sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_pin_info info;
	int r;
	size_t flags_len = sizeof(info.flags);
	size_t padchar_len = 1;
	struct sc_asn1_entry asn1_com_ao_attr[2], asn1_pin_attr[10], asn1_type_pin_attr[2];
	struct sc_asn1_entry asn1_pin[2];
	struct sc_asn1_pkcs15_object pin_obj = { obj, asn1_com_ao_attr, NULL, asn1_type_pin_attr };
	
	sc_copy_asn1_entry(c_asn1_pin, asn1_pin);
	sc_copy_asn1_entry(c_asn1_type_pin_attr, asn1_type_pin_attr);
	sc_copy_asn1_entry(c_asn1_pin_attr, asn1_pin_attr);
	sc_copy_asn1_entry(c_asn1_com_ao_attr, asn1_com_ao_attr);

	sc_format_asn1_entry(asn1_pin + 0, &pin_obj, NULL, 0);

	sc_format_asn1_entry(asn1_type_pin_attr + 0, asn1_pin_attr, NULL, 0);

	sc_format_asn1_entry(asn1_pin_attr + 0, &info.flags, &flags_len, 0);
	sc_format_asn1_entry(asn1_pin_attr + 1, &info.type, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 2, &info.min_length, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 3, &info.stored_length, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 4, &info.max_length, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 5, &info.reference, NULL, 0);
	sc_format_asn1_entry(asn1_pin_attr + 6, &info.pad_char, &padchar_len, 0);
	/* We don't support lastPinChange yet. */
	sc_format_asn1_entry(asn1_pin_attr + 8, &info.path, NULL, 0);

	sc_format_asn1_entry(asn1_com_ao_attr + 0, &info.auth_id, NULL, 0);

	/* Fill in defaults */
	memset(&info, 0, sizeof(info));
	info.reference = 0;
	info.tries_left = -1;

	r = sc_asn1_decode(ctx, asn1_pin, *buf, *buflen, buf, buflen);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");
	info.magic = SC_PKCS15_PIN_MAGIC;
	obj->type = SC_PKCS15_TYPE_AUTH_PIN;
	obj->data = malloc(sizeof(info));
	if (obj->data == NULL)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	if (info.max_length == 0) {
		if (p15card->card->max_pin_len != 0)
			info.max_length = p15card->card->max_pin_len;
		else if (info.stored_length != 0)
			info.max_length = info.type != SC_PKCS15_PIN_TYPE_BCD ?
				info.stored_length : 2 * info.stored_length;
		else
			info.max_length = 8; /* shouldn't happen */
	}

	/* OpenSC 0.11.4 and older encoded "pinReference" as a negative
	   value. Fixed in 0.11.5 we need to add a hack, so old cards
	   continue to work. */
	if (p15card->flags & SC_PKCS15_CARD_FLAG_FIX_INTEGERS) {
		if (info.reference < 0) {
			info.reference += 256;
		}
	}

	info.auth_method = SC_AC_CHV;

	memcpy(obj->data, &info, sizeof(info));

	return 0;
}
Exemplo n.º 26
0
/*
 * can be used as an SC_ASN1_CALLBACK while parsing a certificate,
 * or can be called from the sc_pkcs15_pubkey_from_spki_filename
 */
int
sc_pkcs15_pubkey_from_spki(sc_context_t *ctx, sc_pkcs15_pubkey_t ** outpubkey,
		u8 *buf, size_t buflen, int depth)
{

	int r;
	sc_pkcs15_pubkey_t * pubkey = NULL;
	sc_pkcs15_der_t pk = { NULL, 0 };
	struct sc_algorithm_id pk_alg;
	struct sc_asn1_entry asn1_pkinfo[C_ASN1_PKINFO_ATTR_SIZE];
	struct sc_asn1_entry asn1_ec_pointQ[2];

	sc_log(ctx, "sc_pkcs15_pubkey_from_spki %p:%d", buf, buflen);

	memset(&pk_alg, 0, sizeof(pk_alg));
	pubkey = calloc(1, sizeof(sc_pkcs15_pubkey_t));
	if (pubkey == NULL) {
		r = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}

	sc_copy_asn1_entry(c_asn1_pkinfo, asn1_pkinfo);
	sc_format_asn1_entry(asn1_pkinfo + 0, &pk_alg, NULL, 0);
	sc_format_asn1_entry(asn1_pkinfo + 1, &pk.value, &pk.len, 0);

	r = sc_asn1_decode(ctx, asn1_pkinfo, buf, buflen, NULL, NULL);
	if (r < 0)
		goto err;

	pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id));
	if (pubkey->alg_id == NULL) {
		r = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	memcpy(pubkey->alg_id, &pk_alg, sizeof(struct sc_algorithm_id));
	pubkey->algorithm = pk_alg.algorithm;
	pk_alg.params = NULL;

	sc_log(ctx, "DEE pk_alg.algorithm=%d", pk_alg.algorithm);

	/* pk.len is in bits at this point */
	switch (pk_alg.algorithm) {
	case SC_ALGORITHM_EC:
		/*
		 * TODO we really should only have params in one place!
		 * The alg_id may have the sc_ec_params, 
		 * we want to get the curve OID into the 
		 * u.ec.params and get the field length too.  
		 */
		if (pubkey->alg_id->params) {
		    struct sc_ec_params  * ecp = (struct sc_ec_params *)pubkey->alg_id->params;
		    pubkey->u.ec.params.der.value = malloc(ecp->der_len);
		    if (pubkey->u.ec.params.der.value) {
			memcpy(pubkey->u.ec.params.der.value, ecp->der, ecp->der_len);
			pubkey->u.ec.params.der.len = ecp->der_len;
			sc_pkcs15_fix_ec_parameters(ctx,&pubkey->u.ec.params);
		    }
		}
		/*
		 * For most keys, the above ASN.1 parsing of a key works, but for EC keys,
		 * the ec_pointQ in a certificate is stored in the bitstring, in its raw format.
		 * RSA for example is stored in the  bitstring, as a ASN1 DER 
		 * So we encoded the raw ecpointQ  into ASN1 DER as the pubkey->data 
		 * and let the sc_pkcs15_decode_pubkey below get the ecpointQ out later. 
		 */
		pk.len >>= 3;  /* Assume it is multiple of 8 */
		if (pubkey->u.ec.params.field_length == 0) 
		    pubkey->u.ec.params.field_length = (pk.len - 1)/2 * 8;

		sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
		sc_format_asn1_entry(&asn1_ec_pointQ[0], pk.value, &pk.len, 1);
		r = sc_asn1_encode(ctx, asn1_ec_pointQ, &pubkey->data.value, &pubkey->data.len);

		pk.value = NULL;

		sc_log(ctx, "DEE r=%d data=%p:%d", r, pubkey->data.value, pubkey->data.len);
		break;
	default:
		pk.len >>= 3;	/* convert number of bits to bytes */
		pubkey->data = pk; /* save in publey */
		pk.value = NULL;
		break;
	}

	/* Now decode what every is in pk as it depends on the key algorthim */

	r = sc_pkcs15_decode_pubkey(ctx, pubkey, pubkey->data.value, pubkey->data.len);
	if (r < 0)
		goto err;

	*outpubkey = pubkey;
	pubkey = NULL;
	return 0;

err:
	if (pubkey)
		free(pubkey);
	if (pk.value)
		free(pk.value);

	LOG_TEST_RET(ctx, r, "ASN.1 parsing of  subjectPubkeyInfo failed");
	LOG_FUNC_RETURN(ctx, r);
}
Exemplo n.º 27
0
/* Get a specific extension from the cert.
 * The extension is identified by it's oid value.
 * NOTE: extensions can occur in any number or any order, which is why we
 *	can't parse them with a single pass of the asn1 decoder.
 * If is_critical is supplied, then it is set to 1 if the extention is critical
 * and 0 if it is not.
 * The data in the extension is extension specific.
 * The following are common extension values:
 *   Subject Key ID:		struct sc_object_id type = {{2, 5, 29, 14, -1}};
 *   Key Usage:			struct sc_object_id type = {{2, 5, 29, 15, -1}};
 *   Subject Alt Name:		struct sc_object_id type = {{2, 5, 29, 17, -1}};
 *   Basic Constraints:		struct sc_object_id type = {{2, 5, 29, 19, -1}};
 *   CRL Distribution Points:	struct sc_object_id type = {{2, 5, 29, 31, -1}};
 *   Certificate Policies:	struct sc_object_id type = {{2, 5, 29, 32, -1}};
 *   Extended Key Usage:	struct sc_object_id type = {{2, 5, 29, 37, -1}};
 *
 * if *ext_val is NULL, sc_pkcs15_get_extension will allocate space for ext_val.
 */
int
sc_pkcs15_get_extension(struct sc_context *ctx, struct sc_pkcs15_cert *cert,
	const struct sc_object_id *type, u8 **ext_val,
	size_t *ext_val_len, int *is_critical)
{
	const u8 *ext = NULL;
	const u8 *next_ext = NULL;
	size_t ext_len = 0;
	size_t next_ext_len = 0;
	struct sc_object_id oid;
	u8 *val = NULL;
	size_t val_len = 0;
	int critical;
	int r;
	struct sc_asn1_entry asn1_cert_ext[] = {
		{ "x509v3 entry OID", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, &oid, 0 },
		{ "criticalFlag",  SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, SC_ASN1_OPTIONAL, &critical, NULL },
		{ "extensionValue",SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, &val, &val_len },
		{ NULL, 0, 0, 0, NULL, NULL }
	};

	for (next_ext = cert->extensions, next_ext_len = cert->extensions_len; next_ext_len; ) {
		/* unwrap the set and point to the next ava */
		ext = sc_asn1_skip_tag(ctx, &next_ext, &next_ext_len,
			SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &ext_len);
		if (ext == NULL)
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "ASN.1 decoding of AVA");

		/*
		 * use the sc_asn1_decoder for clarity. NOTE it would be more efficient to do this by hand
		 * so we avoid the man malloc/frees here, but one hopes that one day the asn1_decode will allow
		 * a 'static pointer' flag that returns a const pointer to the actual asn1 space so we only need
		 * to make a final copy of the extension value before we return */
		critical = 0;
		r = sc_asn1_decode(ctx, asn1_cert_ext, ext, ext_len, NULL, NULL);
		if (r < 0)
			LOG_FUNC_RETURN(ctx, r);

		/* is it the RN we are looking for */
		if (sc_compare_oid(&oid, type) != 0) {
			if (*ext_val == NULL) {
				*ext_val = val;
				val = NULL;
				*ext_val_len = val_len;
				/* do not free here -- return the allocated value to caller */
			}
			else {
				*ext_val_len = MIN(*ext_val_len, val_len);
				memcpy(*ext_val, val, *ext_val_len);
				free(val);
			}

			if (is_critical)
				*is_critical = critical;

			r = val_len;
			LOG_FUNC_RETURN(ctx, r);
		}
		if (val) {
			free(val);
			val = NULL;
		}
	}
	if (val)
	    free(val);

	LOG_FUNC_RETURN(ctx, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
}
Exemplo n.º 28
0
/* 
 * can be used as an SC_ASN1_CALLBACK while parsing a certificate,
 * or can be called from the sc_pkcs15_pubkey_from_spki_filename
 */
int sc_pkcs15_pubkey_from_spki(sc_context_t *ctx, sc_pkcs15_pubkey_t ** outpubkey, u8 *buf, size_t buflen, int depth)
{

	int r;
	sc_pkcs15_pubkey_t * pubkey = NULL;
	sc_pkcs15_der_t pk = { NULL, 0 };
	struct sc_algorithm_id pk_alg;
	struct sc_asn1_entry asn1_pkinfo[3];
	struct sc_asn1_entry asn1_ec_pointQ[2];

	sc_debug(ctx,SC_LOG_DEBUG_NORMAL,"sc_pkcs15_pubkey_from_spki %p:%d", buf, buflen);

	memset(&pk_alg, 0, sizeof(pk_alg));
	pubkey = calloc(1, sizeof(sc_pkcs15_pubkey_t));
	if (pubkey == NULL) {
		r = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}

	sc_copy_asn1_entry(c_asn1_pkinfo, asn1_pkinfo);
	sc_format_asn1_entry(asn1_pkinfo + 0, &pk_alg, NULL, 0);
	sc_format_asn1_entry(asn1_pkinfo + 1, &pk.value, &pk.len, 0);

	r = sc_asn1_decode(ctx, asn1_pkinfo, buf, buflen, NULL, NULL);
	if (r < 0)  
		goto err;

	pubkey->alg_id = calloc(1, sizeof(struct sc_algorithm_id));
    if (pubkey->alg_id == NULL) {
		r = SC_ERROR_OUT_OF_MEMORY;
		goto err;
	}
	memcpy(pubkey->alg_id, &pk_alg, sizeof(struct sc_algorithm_id));
 	pubkey->algorithm = pk_alg.algorithm;

	sc_debug(ctx,SC_LOG_DEBUG_NORMAL,"DEE pk_alg.algorithm=%d",pk_alg.algorithm);

	/* pk.len is in bits at this point */
	switch (pk_alg.algorithm) {
		case SC_ALGORITHM_EC:
			/* 
			 * For most keys, the above ASN.1 parsing of a key works, but for EC keys,
			 * the ec_pointQ in a certificate is stored in a bitstring, but 
			 * in PKCS#11 it is an octet string and we just decoded its 
			 * contents from the bitstring in the certificate. So we need to encode it 
			 * back to an octet string so we can store it as an octet string. 
			 */
			pk.len >>= 3;  /* Assume it is multiple of 8 */
//			pubkey->u.ec.field_length = (pk.len - 1)/2 * 8;

			sc_copy_asn1_entry(c_asn1_ec_pointQ, asn1_ec_pointQ);
			sc_format_asn1_entry(&asn1_ec_pointQ[0], pk.value, &pk.len, 1);
		 	r = sc_asn1_encode(ctx, asn1_ec_pointQ, 
					&pubkey->data.value, &pubkey->data.len);
		sc_debug(ctx,SC_LOG_DEBUG_NORMAL,"DEE r=%d data=%p:%d",
			r,pubkey->data.value, pubkey->data.len);
			break;
		default:
			pk.len >>= 3;	/* convert number of bits to bytes */
			pubkey->data = pk; /* save in publey */
			pk.value = NULL;
		break;
	}
	
		/* Now decode what every is in pk as it depends on the key algorthim */

		r = sc_pkcs15_decode_pubkey(ctx, pubkey, pubkey->data.value, pubkey->data.len);
		if (r < 0)
			goto err;

	*outpubkey = pubkey;
	pubkey = NULL;
	return 0;

err:
	if (pubkey)
		free(pubkey);
	if (pk.value)
		free(pk.value);

	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 parsing of  subjectPubkeyInfo failed");
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Exemplo n.º 29
0
static int
parse_x509_cert(sc_context_t *ctx, struct sc_pkcs15_der *der, struct sc_pkcs15_cert *cert)
{
    int r;
    struct sc_algorithm_id sig_alg;
    struct sc_pkcs15_pubkey *pubkey = NULL;
    unsigned char *serial = NULL, *issuer = NULL, *subject = NULL, *buf =  der->value;
    size_t serial_len = 0, issuer_len = 0, subject_len = 0, data_len = 0, buflen = der->len;
    struct sc_asn1_entry asn1_version[] = {
        { "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, &cert->version, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_x509v3[] = {
        { "certificatePolicies",	SC_ASN1_OCTET_STRING, SC_ASN1_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
        { "subjectKeyIdentifier",	SC_ASN1_OCTET_STRING, SC_ASN1_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
        { "crlDistributionPoints",	SC_ASN1_OCTET_STRING, SC_ASN1_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, &cert->crl, &cert->crl_len },
        { "authorityKeyIdentifier",	SC_ASN1_OCTET_STRING, SC_ASN1_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
        { "keyUsage",			SC_ASN1_BOOLEAN, SC_ASN1_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_extensions[] = {
        { "x509v3",		SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, asn1_x509v3, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_tbscert[] = {
        { "version",		SC_ASN1_STRUCT,    SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, asn1_version, NULL },
        { "serialNumber",	SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, &serial, &serial_len },
        { "signature",		SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
        { "issuer",		SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, &issuer, &issuer_len },
        { "validity",		SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
        { "subject",		SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, &subject, &subject_len },
        /* Use a callback to get the algorithm, parameters and pubkey into sc_pkcs15_pubkey */
        { "subjectPublicKeyInfo",SC_ASN1_CALLBACK, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, sc_pkcs15_pubkey_from_spki,  &pubkey },
        { "extensions",		SC_ASN1_STRUCT,    SC_ASN1_CTX | 3 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, asn1_extensions, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_cert[] = {
        { "tbsCertificate",	SC_ASN1_STRUCT,    SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, asn1_tbscert, NULL },
        { "signatureAlgorithm",	SC_ASN1_ALGORITHM_ID, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, &sig_alg, NULL },
        { "signatureValue",	SC_ASN1_BIT_STRING, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_serial_number[] = {
        { "serialNumber", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_subject[] = {
        { "subject", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };
    struct sc_asn1_entry asn1_issuer[] = {
        { "issuer", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_ALLOC, NULL, NULL },
        { NULL, 0, 0, 0, NULL, NULL }
    };

    const u8 *obj;
    size_t objlen;

    memset(cert, 0, sizeof(*cert));
    obj = sc_asn1_verify_tag(ctx, buf, buflen, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &objlen);
    if (obj == NULL)
        LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "X.509 certificate not found");

    data_len = objlen + (obj - buf);
    cert->data.value = malloc(data_len);
    if (!cert->data.value)
        LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
    memcpy(cert->data.value, buf, data_len);
    cert->data.len = data_len;

    r = sc_asn1_decode(ctx, asn1_cert, obj, objlen, NULL, NULL);
    LOG_TEST_RET(ctx, r, "ASN.1 parsing of certificate failed");

    cert->version++;

    if (!pubkey)
        LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Unable to decode subjectPublicKeyInfo from cert");
    cert->key = pubkey;

    sc_asn1_clear_algorithm_id(&sig_alg);

    if (serial && serial_len)   {
        sc_format_asn1_entry(asn1_serial_number + 0, serial, &serial_len, 1);
        r = sc_asn1_encode(ctx, asn1_serial_number, &cert->serial, &cert->serial_len);
        free(serial);
        LOG_TEST_RET(ctx, r, "ASN.1 encoding of serial failed");
    }

    if (subject && subject_len)   {
        sc_format_asn1_entry(asn1_subject + 0, subject, &subject_len, 1);
        r = sc_asn1_encode(ctx, asn1_subject, &cert->subject, &cert->subject_len);
        free(subject);
        LOG_TEST_RET(ctx, r, "ASN.1 encoding of subject");
    }

    if (issuer && issuer_len)   {
        sc_format_asn1_entry(asn1_issuer + 0, issuer, &issuer_len, 1);
        r = sc_asn1_encode(ctx, asn1_issuer, &cert->issuer, &cert->issuer_len);
        free(issuer);
        LOG_TEST_RET(ctx, r, "ASN.1 encoding of issuer");
    }

    return SC_SUCCESS;
}
Exemplo n.º 30
0
Arquivo: dir.c Projeto: AktivCo/OpenSC
static int
parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen, int rec_nr)
{
	struct sc_context *ctx = card->ctx;
	struct sc_asn1_entry asn1_dirrecord[5], asn1_dir[2];
	scconf_block *conf_block = NULL;
	sc_app_info_t *app = NULL;
	struct sc_aid aid;
	u8 label[128], path[128], ddo[128];
	size_t label_len = sizeof(label) - 1, path_len = sizeof(path), ddo_len = sizeof(ddo);
	int r;

	LOG_FUNC_CALLED(ctx);
	aid.len = sizeof(aid.value);

	memset(label, 0, sizeof(label));
	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, 0);
	sc_format_asn1_entry(asn1_dirrecord + 0, aid.value, &aid.len, 0);
	sc_format_asn1_entry(asn1_dirrecord + 1, label, &label_len, 0);
	sc_format_asn1_entry(asn1_dirrecord + 2, path, &path_len, 0);
	sc_format_asn1_entry(asn1_dirrecord + 3, ddo, &ddo_len, 0);

	r = sc_asn1_decode(ctx, asn1_dir, *buf, *buflen, (const u8 **) buf, buflen);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		LOG_FUNC_RETURN(ctx, r);
	LOG_TEST_RET(ctx, r, "EF(DIR) parsing failed");

	conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
	if (conf_block)   {
		scconf_block **blocks = NULL;
		char aid_str[SC_MAX_AID_STRING_SIZE];
		int ignore_app = 0;

		sc_bin_to_hex(aid.value, aid.len, aid_str, sizeof(aid_str), 0);
		blocks = scconf_find_blocks(card->ctx->conf, conf_block, "application", aid_str);
		if (blocks)   {
			ignore_app = (blocks[0] && scconf_get_str(blocks[0], "disable", 0));
                        free(blocks);
		 }

		if (ignore_app)   {
			sc_log(ctx, "Application '%s' ignored", aid_str);
			LOG_FUNC_RETURN(ctx, SC_SUCCESS);
		}
	}

	app = calloc(1, sizeof(struct sc_app_info));
	if (app == NULL)
		LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);

	memcpy(&app->aid, &aid, sizeof(struct sc_aid));

	if (asn1_dirrecord[1].flags & SC_ASN1_PRESENT)
		app->label = strdup((char *) label);
	else
		app->label = NULL;

	if (asn1_dirrecord[2].flags & SC_ASN1_PRESENT && path_len > 0) {
		/* application path present: ignore AID */
		if (path_len > SC_MAX_PATH_SIZE) {
			free(app);
			LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Application path is too long.");
		}
		memcpy(app->path.value, path, path_len);
		app->path.len = path_len;
		app->path.type = SC_PATH_TYPE_PATH;
	}
	else {
		/* application path not present: use AID as application path */
		memcpy(app->path.value, aid.value, aid.len);
		app->path.len = aid.len;
		app->path.type = SC_PATH_TYPE_DF_NAME;
	}

	if (asn1_dirrecord[3].flags & SC_ASN1_PRESENT) {
		app->ddo.value = malloc(ddo_len);
		if (app->ddo.value == NULL) {
			free(app);
			LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate DDO value");
		}
		memcpy(app->ddo.value, ddo, ddo_len);
		app->ddo.len = ddo_len;
	} else {
		app->ddo.value = NULL;
		app->ddo.len = 0;
	}

	app->rec_nr = rec_nr;
	card->app[card->app_count] = app;
	card->app_count++;

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}