Exemplo n.º 1
0
int
sc_pkcs15_convert_pubkey(struct sc_pkcs15_pubkey *pkcs15_key, void *evp_key)
{
#ifdef ENABLE_OPENSSL
	EVP_PKEY *pk = (EVP_PKEY *)evp_key;

	switch (pk->type) {
	case EVP_PKEY_RSA: {
		struct sc_pkcs15_pubkey_rsa *dst = &pkcs15_key->u.rsa;
		RSA *src = EVP_PKEY_get1_RSA(pk);

		pkcs15_key->algorithm = SC_ALGORITHM_RSA;
		if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n) || !sc_pkcs15_convert_bignum(&dst->exponent, src->e))
			return SC_ERROR_INVALID_DATA;
		RSA_free(src);
		break;
		}
	case EVP_PKEY_DSA: {
		struct sc_pkcs15_pubkey_dsa *dst = &pkcs15_key->u.dsa;
		DSA *src = EVP_PKEY_get1_DSA(pk);

		pkcs15_key->algorithm = SC_ALGORITHM_DSA;
		sc_pkcs15_convert_bignum(&dst->pub, src->pub_key);
		sc_pkcs15_convert_bignum(&dst->p, src->p);
		sc_pkcs15_convert_bignum(&dst->q, src->q);
		sc_pkcs15_convert_bignum(&dst->g, src->g);
		DSA_free(src);
		break;
		}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
	case NID_id_GostR3410_2001: {
		struct sc_pkcs15_pubkey_gostr3410 *dst = &pkcs15_key->u.gostr3410;
		EC_KEY *eckey = EVP_PKEY_get0(pk);
		const EC_POINT *point;
		BIGNUM *X, *Y;
		int r = 0;

		assert(eckey);
		point = EC_KEY_get0_public_key(eckey);
		if (!point)
			return SC_ERROR_INTERNAL;
		X = BN_new();
		Y = BN_new();
		if (X && Y && EC_KEY_get0_group(eckey))
			r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey),
					point, X, Y, NULL);
		if (r == 1) {
			dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y);
			dst->xy.data = malloc(dst->xy.len);
			if (dst->xy.data) {
				BN_bn2bin(Y, dst->xy.data);
				BN_bn2bin(X, dst->xy.data + BN_num_bytes(Y));
				r = sc_mem_reverse(dst->xy.data, dst->xy.len);
				if (!r)
					r = 1;
				pkcs15_key->algorithm = SC_ALGORITHM_GOSTR3410;
			}
			else
				r = -1;
		}
		BN_free(X);
		BN_free(Y);
		if (r != 1)
			return SC_ERROR_INTERNAL;
		break;
		}
	case EVP_PKEY_EC: {
		struct sc_pkcs15_pubkey_ec *dst = &pkcs15_key->u.ec;
		EC_KEY *src = NULL;
		const EC_GROUP *grp = NULL;
		unsigned char buf[255];
		size_t buflen = 255;
		int nid;

		src = EVP_PKEY_get0(pk);
		assert(src);
		assert(EC_KEY_get0_public_key(src));

		pkcs15_key->algorithm = SC_ALGORITHM_EC;
		grp = EC_KEY_get0_group(src);
		if(grp == 0)
			return SC_ERROR_INCOMPATIBLE_KEY;

		/* Decode EC_POINT from a octet string */
		buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src),
				POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL);

		/* get curve name */
		nid = EC_GROUP_get_curve_name(grp);
		if(nid != 0) {
			const char *name = OBJ_nid2sn(nid);
			if(sizeof(name) > 0)
				dst->params.named_curve = strdup(name);
		}

		/* copy the public key */
		if (buflen > 0) {
			dst->ecpointQ.value = malloc(buflen);
			memcpy(dst->ecpointQ.value, buf, buflen);
			dst->ecpointQ.len = buflen;
			/* calculate the field length */
			dst->params.field_length = (buflen - 1) / 2 * 8;
		}
		else
			return SC_ERROR_INCOMPATIBLE_KEY;

		break;
	}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
	default:
		return SC_ERROR_NOT_SUPPORTED;
	}

	return SC_SUCCESS;
#else
	return SC_ERROR_NOT_IMPLEMENTED;
#endif
}
Exemplo n.º 2
0
int
sc_pkcs15_convert_prkey(struct sc_pkcs15_prkey *pkcs15_key, void *evp_key)
{
#ifdef ENABLE_OPENSSL
	EVP_PKEY *pk = (EVP_PKEY *)evp_key;

	switch (pk->type) {
	case EVP_PKEY_RSA: {
		struct sc_pkcs15_prkey_rsa *dst = &pkcs15_key->u.rsa;
		RSA *src = EVP_PKEY_get1_RSA(pk);

		pkcs15_key->algorithm = SC_ALGORITHM_RSA;
		if (!sc_pkcs15_convert_bignum(&dst->modulus, src->n)
		 || !sc_pkcs15_convert_bignum(&dst->exponent, src->e)
		 || !sc_pkcs15_convert_bignum(&dst->d, src->d)
		 || !sc_pkcs15_convert_bignum(&dst->p, src->p)
		 || !sc_pkcs15_convert_bignum(&dst->q, src->q))
			return SC_ERROR_NOT_SUPPORTED;
		if (src->iqmp && src->dmp1 && src->dmq1) {
			sc_pkcs15_convert_bignum(&dst->iqmp, src->iqmp);
			sc_pkcs15_convert_bignum(&dst->dmp1, src->dmp1);
			sc_pkcs15_convert_bignum(&dst->dmq1, src->dmq1);
		}
		RSA_free(src);
		break;
		}
	case EVP_PKEY_DSA: {
		struct sc_pkcs15_prkey_dsa *dst = &pkcs15_key->u.dsa;
		DSA *src = EVP_PKEY_get1_DSA(pk);

		pkcs15_key->algorithm = SC_ALGORITHM_DSA;
		sc_pkcs15_convert_bignum(&dst->pub, src->pub_key);
		sc_pkcs15_convert_bignum(&dst->p, src->p);
		sc_pkcs15_convert_bignum(&dst->q, src->q);
		sc_pkcs15_convert_bignum(&dst->g, src->g);
		sc_pkcs15_convert_bignum(&dst->priv, src->priv_key);
		DSA_free(src);
		break;
		}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
	case NID_id_GostR3410_2001: {
		struct sc_pkcs15_prkey_gostr3410 *dst = &pkcs15_key->u.gostr3410;
		EC_KEY *src = EVP_PKEY_get0(pk);

		assert(src);
		pkcs15_key->algorithm = SC_ALGORITHM_GOSTR3410;
		assert(EC_KEY_get0_private_key(src));
		sc_pkcs15_convert_bignum(&dst->d, EC_KEY_get0_private_key(src));
		break;
		}
	case EVP_PKEY_EC: {
		struct sc_pkcs15_prkey_ec *dst = &pkcs15_key->u.ec;
		EC_KEY *src = NULL;
		const EC_GROUP *grp = NULL;
		unsigned char buf[255];
		size_t buflen = 255;
		int nid;

		src = EVP_PKEY_get0(pk);
		assert(src);
		assert(EC_KEY_get0_private_key(src));
		assert(EC_KEY_get0_public_key(src));

		pkcs15_key->algorithm = SC_ALGORITHM_EC;

		if (!sc_pkcs15_convert_bignum(&dst->privateD, EC_KEY_get0_private_key(src)))
			return SC_ERROR_INCOMPATIBLE_KEY;

		grp = EC_KEY_get0_group(src);
		if(grp == 0)
			return SC_ERROR_INCOMPATIBLE_KEY;

		/* get curve name */
		nid = EC_GROUP_get_curve_name(grp);
		if(nid != 0)
			dst->params.named_curve = strdup(OBJ_nid2sn(nid));

		/* Decode EC_POINT from a octet string */
		buflen = EC_POINT_point2oct(grp, (const EC_POINT *) EC_KEY_get0_public_key(src),
				POINT_CONVERSION_UNCOMPRESSED, buf, buflen, NULL);
		if (!buflen)
			return SC_ERROR_INCOMPATIBLE_KEY;

		/* copy the public key */
		dst->ecpointQ.value = malloc(buflen);
		memcpy(dst->ecpointQ.value, buf, buflen);
		dst->ecpointQ.len = buflen;

		/* calculate the field length */
		dst->params.field_length = (buflen - 1) / 2 * 8;

		/* Octetstring may need leading zeros if BN is to short */
		if (dst->privateD.len < dst->params.field_length/8)   {
			size_t d = dst->params.field_length/8 - dst->privateD.len;

			dst->privateD.data = realloc(dst->privateD.data, dst->privateD.len + d);
			if (!dst->privateD.data)
				return SC_ERROR_OUT_OF_MEMORY;

			memmove(dst->privateD.data + d, dst->privateD.data, dst->privateD.len);
			memset(dst->privateD.data, 0, d);

			dst->privateD.len += d;
		}

		break;
	}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
	default:
		return SC_ERROR_NOT_SUPPORTED;
	}

	return SC_SUCCESS;
#else
	return SC_ERROR_NOT_IMPLEMENTED;
#endif
}