Пример #1
0
int
sc_pkcs15_decode_pubkey_with_param(sc_context_t *ctx, struct sc_pkcs15_pubkey *key,
		const u8 *buf, size_t len)
{
	/* We assume all algrothims allow SPKI  which starts with a sequence*/

	if (*buf == 0x30)
		/* Decode  Public Key from SPKI */
		return sc_pkcs15_copy_pubkey_from_spki_object(ctx, buf, len, key);

	key->data.value = (u8 *)buf;
	key->data.len = len;
	return sc_pkcs15_decode_pubkey(ctx, key, buf, len);
}
Пример #2
0
/*
 * Generate key
 */
static int westcos_pkcs15init_generate_key(sc_profile_t *profile,
						sc_pkcs15_card_t *p15card,
						sc_pkcs15_object_t *obj,
						sc_pkcs15_pubkey_t *pubkey)
{
#ifndef ENABLE_OPENSSL
	return SC_ERROR_NOT_SUPPORTED;
#else
	int r = SC_ERROR_UNKNOWN;
	long lg;
	u8 *p;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	RSA *rsa = NULL;
	BIGNUM *bn = NULL;
	BIO *mem = NULL;

	sc_file_t *prkf = NULL;

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

#if OPENSSL_VERSION_NUMBER>=0x00908000L
	rsa = RSA_new();
	bn = BN_new();
	mem = BIO_new(BIO_s_mem());

	if(rsa == NULL || bn == NULL || mem == NULL)
	{
		r = SC_ERROR_OUT_OF_MEMORY;
		goto out;
	}

	if(!BN_set_word(bn, RSA_F4) ||
		!RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL))
#else
	mem = BIO_new(BIO_s_mem());

	if(mem == NULL)
	{
		r = SC_ERROR_OUT_OF_MEMORY;
		goto out;
	}

	rsa = RSA_generate_key(key_info->modulus_length, RSA_F4, NULL, NULL);
	if (!rsa)
#endif
	{
		r = SC_ERROR_UNKNOWN;
		goto out;
	}

	rsa->meth = RSA_PKCS1_SSLeay();

	if(pubkey != NULL)
	{
		if(!i2d_RSAPublicKey_bio(mem, rsa))
		{
			r = SC_ERROR_UNKNOWN;
			goto out;
		}

		lg = BIO_get_mem_data(mem, &p);

		pubkey->algorithm = SC_ALGORITHM_RSA;

		r = sc_pkcs15_decode_pubkey(p15card->card->ctx, pubkey, p, lg);
	}

	(void) BIO_reset(mem);

	if(!i2d_RSAPrivateKey_bio(mem, rsa))
	{
		r = SC_ERROR_UNKNOWN;
		goto out;
	}

	lg = BIO_get_mem_data(mem, &p);

	/* Get the private key file */
	r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf);
	if (r < 0)
	{
		char pbuf[SC_MAX_PATH_STRING_SIZE];

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

		goto out;
	}

	prkf->size = lg;

	r = sc_pkcs15init_create_file(profile, p15card, prkf);
	if(r) goto out;

	r = sc_pkcs15init_update_file(profile, p15card, prkf, p, lg);
	if(r) goto out;

out:
	if(mem)
		BIO_free(mem);
	if(bn)
		BN_free(bn);
	if(rsa)
		RSA_free(rsa);
	if(prkf)
		sc_file_free(prkf);

	return r;
#endif
}
Пример #3
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);
}
Пример #4
0
/*
 * Read public key.
 */
int
sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
		struct sc_pkcs15_pubkey **out)
{
	struct sc_context *ctx = p15card->card->ctx;
	const struct sc_pkcs15_pubkey_info *info = NULL;
	struct sc_pkcs15_pubkey *pubkey = NULL;
	unsigned char *data = NULL;
	size_t	len;
	int	algorithm, r;

	assert(p15card != NULL && obj != NULL && out != NULL);
	LOG_FUNC_CALLED(ctx);

	switch (obj->type) {
	case SC_PKCS15_TYPE_PUBKEY_RSA:
		algorithm = SC_ALGORITHM_RSA;
		break;
	case SC_PKCS15_TYPE_PUBKEY_DSA:
		algorithm = SC_ALGORITHM_DSA;
		break;
	case SC_PKCS15_TYPE_PUBKEY_GOSTR3410:
		algorithm = SC_ALGORITHM_GOSTR3410;
		break;
	case SC_PKCS15_TYPE_PUBKEY_EC:
		algorithm = SC_ALGORITHM_EC;
		break;
	default:
		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported public key type.");
	}
	info = (const struct sc_pkcs15_pubkey_info *) obj->data;

	sc_log(ctx, "Content (%p, %i)", obj->content.value, obj->content.len);
	if (obj->content.value && obj->content.len)   {
		/* public key data is present as 'direct' value of pkcs#15 object */
		data = calloc(1, obj->content.len);
		if (!data)
			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
		memcpy(data, obj->content.value, obj->content.len);
		len = obj->content.len;
	}
	else if (p15card->card->ops->read_public_key)   {
		r = p15card->card->ops->read_public_key(p15card->card, algorithm,
				&info->path, info->key_reference, info->modulus_length,
				&data, &len);
		LOG_TEST_RET(ctx, r, "Card specific 'read-public' procedure failed.");
	}
	else if (info->path.len)   {
		r = sc_pkcs15_read_file(p15card, &info->path, &data, &len);
		LOG_TEST_RET(ctx, r, "Failed to read public key file.");
	}
	else    {
		LOG_TEST_RET(ctx, SC_ERROR_NOT_IMPLEMENTED, "No way to get public key");
	}

	if (!data || !len)
		LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_VALID);

	pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey));
	if (pubkey == NULL) {
		free(data);
		LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
	}
	pubkey->algorithm = algorithm;
	pubkey->data.value = data;
	pubkey->data.len = len;
	if (sc_pkcs15_decode_pubkey(ctx, pubkey, data, len)) {
		free(data);
		free(pubkey);
		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ASN1_OBJECT);
	}

	*out = pubkey;
	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
Пример #5
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);
}
Пример #6
0
/*
 * Read public key.
 */
int
sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card,
			const struct sc_pkcs15_object *obj,
			struct sc_pkcs15_pubkey **out)
{
	struct sc_context *ctx = p15card->card->ctx;
	const struct sc_pkcs15_pubkey_info *info;
	struct sc_pkcs15_pubkey *pubkey;
	u8	*data;
	size_t	len;
	int	algorithm, r;

	assert(p15card != NULL && obj != NULL && out != NULL);
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);

	switch (obj->type) {
	case SC_PKCS15_TYPE_PUBKEY_RSA:
		algorithm = SC_ALGORITHM_RSA;
		break;
	case SC_PKCS15_TYPE_PUBKEY_DSA:
		algorithm = SC_ALGORITHM_DSA;
		break;
	case SC_PKCS15_TYPE_PUBKEY_GOSTR3410:
		algorithm = SC_ALGORITHM_GOSTR3410;
		break;
	case SC_PKCS15_TYPE_PUBKEY_EC:
		algorithm = SC_ALGORITHM_EC;
		break;
	default:
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Unsupported public key type.");
	}
	info = (const struct sc_pkcs15_pubkey_info *) obj->data;

	if (obj->content.value && obj->content.len)   {
		/* public key data is present as 'direct' value of pkcs#15 object */
		data = calloc(1, obj->content.len);
		if (!data)
			SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
		memcpy(data, obj->content.value, obj->content.len);
		len = obj->content.len;
	}
        else   {
		r = sc_pkcs15_read_file(p15card, &info->path, &data, &len);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to read public key file.");
	}

	pubkey = calloc(1, sizeof(struct sc_pkcs15_pubkey));
	if (pubkey == NULL) {
		free(data);
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	}
	pubkey->algorithm = algorithm;
	pubkey->data.value = data;
	pubkey->data.len = len;
	if (sc_pkcs15_decode_pubkey(ctx, pubkey, data, len)) {
		free(data);
		free(pubkey);
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ASN1_OBJECT);
	}

	*out = pubkey;
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}