Exemple #1
0
static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) 
	{
	switch (EVP_PKEY_base_id(pkey)) 
		{
		case NID_id_GostR3410_94:
		{
		DSA *dsa = EVP_PKEY_get0(pkey);
		if (!dsa) 
			{
			dsa = DSA_new();
			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
			}	
		dsa->priv_key = BN_dup(priv);
		if (!EVP_PKEY_missing_parameters(pkey)) 
			gost94_compute_public(dsa);
		break;
		}	
		case NID_id_GostR3410_2001:
		{
		EC_KEY *ec = EVP_PKEY_get0(pkey);
		if (!ec) 
			{
			ec = EC_KEY_new();
			EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
			}	
		if (!EC_KEY_set_private_key(ec,priv)) return 0;
		if (!EVP_PKEY_missing_parameters(pkey)) 
			gost2001_compute_public(ec);
		break;
		}
		}
	return 1;		
	}
Exemple #2
0
static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) 
	{
	EC_KEY *eto = EVP_PKEY_get0(to);
	const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) 
		{
		GOSTerr(GOST_F_PARAM_COPY_GOST01,
			GOST_R_INCOMPATIBLE_ALGORITHMS);
		return 0;
		}	
	if (!efrom) 
		{
		GOSTerr(GOST_F_PARAM_COPY_GOST01,
			GOST_R_KEY_PARAMETERS_MISSING);
		return 0;
		}	
	if (!eto) 
		{
		eto = EC_KEY_new();
		EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
		}	
	EC_KEY_set_group(eto,EC_KEY_get0_group(efrom));
	if (EC_KEY_get0_private_key(eto)) 
		{
		gost2001_compute_public(eto);
		}
	return 1;
	}
// Setters for the GOST private key components
void OSSLGOSTPrivateKey::setD(const ByteString& d)
{
	GOSTPrivateKey::setD(d);

	EC_KEY* ec = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
	if (ec == NULL)
	{
		ByteString der = dummyKey;
		const unsigned char *p = &der[0];
		if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) der.size()) == NULL)
		{
			ERROR_MSG("d2i_PrivateKey failed");

			return;
		}
		ec = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
	}

	const BIGNUM* priv = OSSL::byteString2bn(d);
	if (EC_KEY_set_private_key(ec, priv) <= 0)
	{
		ERROR_MSG("EC_KEY_set_private_key failed");
		return;
	}

#ifdef notyet
	if (gost2001_compute_public(ec) <= 0)
		ERROR_MSG("gost2001_compute_public failed");
#endif		
}
// Setters for the GOST private key components
void OSSLGOSTPrivateKey::setD(const ByteString& inD)
{
	GOSTPrivateKey::setD(inD);

	EC_KEY* inEC = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
	if (inEC == NULL)
	{
		const unsigned char* p = dummyKey;
		if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(dummyKey)) == NULL)
		{
			ERROR_MSG("d2i_PrivateKey failed");

			return;
		}
		inEC = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
	}

	const BIGNUM* priv = OSSL::byteString2bn(inD);
	if (EC_KEY_set_private_key(inEC, priv) <= 0)
	{
		ERROR_MSG("EC_KEY_set_private_key failed");
		return;
	}
	BN_clear_free((BIGNUM*)priv);

#ifdef notyet
	if (gost2001_compute_public(inEC) <= 0)
		ERROR_MSG("gost2001_compute_public failed");
#endif
}
Exemple #5
0
/*
 *
 * Generates GOST R 34.10-2001 keypair
 *
 *
 */
int gost2001_keygen(EC_KEY *ec)
{
    BIGNUM *order = BN_new(), *d = BN_new();
    const EC_GROUP *group = EC_KEY_get0_group(ec);

    if (!group || !EC_GROUP_get_order(group, order, NULL)) {
        GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
        BN_free(d);
        BN_free(order);
        return 0;
    }

    do {
        if (!BN_rand_range(d, order)) {
            GOSTerr(GOST_F_GOST2001_KEYGEN,
                    GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
            BN_free(d);
            BN_free(order);
            return 0;
        }
    }
    while (BN_is_zero(d));

    if (!EC_KEY_set_private_key(ec, d)) {
        GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
        BN_free(d);
        BN_free(order);
        return 0;
    }
    BN_free(d);
    BN_free(order);
    return gost2001_compute_public(ec);
}
int
gost2001_keygen(GOST_KEY *ec)
{
	BIGNUM *order = BN_new(), *d = BN_new();
	const EC_GROUP *group = GOST_KEY_get0_group(ec);
	int rc = 0;

	if (order == NULL || d == NULL)
		goto err;
	if (EC_GROUP_get_order(group, order, NULL) == 0)
		goto err;

	do {
		if (BN_rand_range(d, order) == 0) {
			GOSTerr(GOST_F_GOST2001_KEYGEN,
				GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
			goto err;
		}
	} while (BN_is_zero(d));

	if (GOST_KEY_set_private_key(ec, d) == 0)
		goto err;
	rc = gost2001_compute_public(ec);

err:
	BN_free(d);
	BN_free(order);
	return rc;
}
static int
param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from)
{
	GOST_KEY *eto = to->pkey.gost;
	const GOST_KEY *efrom = from->pkey.gost;
	int ret = 1;

	if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) {
		GOSTerr(GOST_F_PARAM_COPY_GOST01,
		    GOST_R_INCOMPATIBLE_ALGORITHMS);
		return 0;
	}
	if (efrom == NULL) {
		GOSTerr(GOST_F_PARAM_COPY_GOST01,
		    GOST_R_KEY_PARAMETERS_MISSING);
		return 0;
	}
	if (eto == NULL) {
		eto = GOST_KEY_new();
		if (eto == NULL) {
			GOSTerr(GOST_F_PARAM_COPY_GOST01,
			    ERR_R_MALLOC_FAILURE);
			return 0;
		}
		if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) {
			GOST_KEY_free(eto);
			return 0;
		}
	}
	GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom));
	GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom));
	if (GOST_KEY_get0_private_key(eto) != NULL)
		ret = gost2001_compute_public(eto);

	return ret;
}
static int
priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
{
	const unsigned char *pkey_buf = NULL, *p = NULL;
	int priv_len = 0;
	BIGNUM *pk_num = NULL;
	int ret = 0;
	X509_ALGOR *palg = NULL;
	ASN1_OBJECT *palg_obj = NULL;
	ASN1_INTEGER *priv_key = NULL;
	GOST_KEY *ec;
	int ptype = V_ASN1_UNDEF;
	ASN1_STRING *pval = NULL;

	if (PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf) == 0)
		return 0;
	(void)EVP_PKEY_assign_GOST(pk, NULL);
	X509_ALGOR_get0(NULL, &ptype, (void **)&pval, palg);
	if (ptype != V_ASN1_SEQUENCE) {
		GOSTerr(GOST_F_PUB_DECODE_GOST01,
		    GOST_R_BAD_KEY_PARAMETERS_FORMAT);
		return 0;
	}
	p = pval->data;
	if (decode_gost01_algor_params(pk, &p, pval->length) == 0)
		return 0;
	p = pkey_buf;
	if (V_ASN1_OCTET_STRING == *p) {
		/* New format - Little endian octet string */
		unsigned char rev_buf[32];
		int i;
		ASN1_OCTET_STRING *s =
		    d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);

		if (s == NULL || s->length != 32) {
			GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR);
			ASN1_STRING_free(s);
			return 0;
		}
		for (i = 0; i < 32; i++) {
			rev_buf[31 - i] = s->data[i];
		}
		ASN1_STRING_free(s);
		pk_num = BN_bin2bn(rev_buf, 32, NULL);
	} else {
		priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
		if (priv_key == NULL)
			return 0;
		ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL);
		ASN1_INTEGER_free(priv_key);
		if (ret == 0) {
			GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR);
			return 0;
		}
	}

	ec = pk->pkey.gost;
	if (ec == NULL) {
		ec = GOST_KEY_new();
		if (ec == NULL) {
			BN_free(pk_num);
			return 0;
		}
		if (EVP_PKEY_assign_GOST(pk, ec) == 0) {
			BN_free(pk_num);
			GOST_KEY_free(ec);
			return 0;
		}
	}
	if (GOST_KEY_set_private_key(ec, pk_num) == 0) {
		BN_free(pk_num);
		return 0;
	}
	ret = 0;
	if (EVP_PKEY_missing_parameters(pk) == 0)
		ret = gost2001_compute_public(ec) != 0;
	BN_free(pk_num);

	return ret;
}
static isc_result_t
opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
	dst_private_t priv;
	isc_result_t ret;
	isc_mem_t *mctx = key->mctx;
	EVP_PKEY *pkey = NULL;
	EC_KEY *eckey;
	const EC_POINT *pubkey = NULL;
	BIGNUM *privkey = NULL;
	const unsigned char *p;

	/* read private key file */
	ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv);
	if (ret != ISC_R_SUCCESS)
		return (ret);

	if (key->external) {
		if (priv.nelements != 0)
			DST_RET(DST_R_INVALIDPRIVATEKEY);
		if (pub == NULL)
			DST_RET(DST_R_INVALIDPRIVATEKEY);
		key->keydata.pkey = pub->keydata.pkey;
		pub->keydata.pkey = NULL;
		key->key_size = pub->key_size;
		dst__privstruct_free(&priv, mctx);
		memset(&priv, 0, sizeof(priv));
		return (ISC_R_SUCCESS);
	}

	INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) ||
	       (priv.elements[0].tag == TAG_GOST_PRIVRAW));

	if (priv.elements[0].tag == TAG_GOST_PRIVASN1) {
		p = priv.elements[0].data;
		if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
				   (long) priv.elements[0].length) == NULL)
			DST_RET(dst__openssl_toresult2(
					    "d2i_PrivateKey",
					    DST_R_INVALIDPRIVATEKEY));
	} else {
		if ((pub != NULL) && (pub->keydata.pkey != NULL)) {
			eckey = EVP_PKEY_get0(pub->keydata.pkey);
			pubkey = EC_KEY_get0_public_key(eckey);
		}

		privkey = BN_bin2bn(priv.elements[0].data,
				    priv.elements[0].length, NULL);
		if (privkey == NULL)
			DST_RET(ISC_R_NOMEMORY);

		/* can't create directly the whole key */
		p = gost_dummy_key;
		if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
				   (long) sizeof(gost_dummy_key)) == NULL)
			DST_RET(dst__openssl_toresult2(
					    "d2i_PrivateKey",
					    DST_R_INVALIDPRIVATEKEY));

		eckey = EVP_PKEY_get0(pkey);
		if (eckey == NULL)
			return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
		if (!EC_KEY_set_private_key(eckey, privkey))
			DST_RET(ISC_R_NOMEMORY);

		/* have to (re)set the public key */
#ifdef notyet
		(void) gost2001_compute_public(eckey);
#else
		if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey))
			DST_RET(ISC_R_NOMEMORY);
#endif
		BN_clear_free(privkey);
		privkey = NULL;
	}
	key->keydata.pkey = pkey;
	key->key_size = EVP_PKEY_bits(pkey);
	dst__privstruct_free(&priv, mctx);
	memset(&priv, 0, sizeof(priv));
	return (ISC_R_SUCCESS);

 err:
	if (privkey != NULL)
		BN_clear_free(privkey);
	if (pkey != NULL)
		EVP_PKEY_free(pkey);
	opensslgost_destroy(key);
	dst__privstruct_free(&priv, mctx);
	memset(&priv, 0, sizeof(priv));
	return (ret);
}