예제 #1
0
파일: gost_ameth.c 프로젝트: 0culus/openssl
/* ---------- Public key functions * --------------------------------------*/
static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
	{
	X509_ALGOR *palg = NULL;
	const unsigned char *pubkey_buf = NULL;
	unsigned char *databuf;
	ASN1_OBJECT *palgobj = NULL;
	int pub_len,i,j;
	DSA *dsa;
	ASN1_OCTET_STRING *octet= NULL;

	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
			&palg, pub)) return 0;
	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
	if (!decode_gost_algor_params(pk,palg)) return 0;
	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
	if (!octet) 
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST94,ERR_R_MALLOC_FAILURE);
		return 0;
		}	
	databuf = OPENSSL_malloc(octet->length);
	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
		{
		databuf[j]=octet->data[i];
		}	
	dsa = EVP_PKEY_get0(pk);
	dsa->pub_key=BN_bin2bn(databuf,octet->length,NULL);
	ASN1_OCTET_STRING_free(octet);
	OPENSSL_free(databuf);
	return 1;

	}
예제 #2
0
파일: gost_ameth.c 프로젝트: 0culus/openssl
static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
	{
	X509_ALGOR *palg = NULL;
	const unsigned char *pubkey_buf = NULL;
	unsigned char *databuf;
	ASN1_OBJECT *palgobj = NULL;
	int pub_len,i,j;
	EC_POINT *pub_key;
	BIGNUM *X,*Y;
	ASN1_OCTET_STRING *octet= NULL;
	int len;
	const EC_GROUP *group;

	if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len,
			&palg, pub)) return 0;
	EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL);	
	if (!decode_gost_algor_params(pk,palg)) return 0;
	group = EC_KEY_get0_group(EVP_PKEY_get0(pk));
	octet = d2i_ASN1_OCTET_STRING(NULL,&pubkey_buf,pub_len);
	if (!octet) 
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST01,ERR_R_MALLOC_FAILURE);
		return 0;
		}	
	databuf = OPENSSL_malloc(octet->length);
	for (i=0,j=octet->length-1;i<octet->length;i++,j--)
		{
		databuf[j]=octet->data[i];
		}
	len=octet->length/2;
	ASN1_OCTET_STRING_free(octet);	
	
	Y= getbnfrombuf(databuf,len);
	X= getbnfrombuf(databuf+len,len);
	OPENSSL_free(databuf);
	pub_key = EC_POINT_new(group);
	if (!EC_POINT_set_affine_coordinates_GFp(group
			,pub_key,X,Y,NULL))
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST01,
			ERR_R_EC_LIB);
		EC_POINT_free(pub_key);
		BN_free(X);
		BN_free(Y);
		return 0;
		}	
	BN_free(X);
	BN_free(Y);
	if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk),pub_key))
		{
		GOSTerr(GOST_F_PUB_DECODE_GOST01,
			ERR_R_EC_LIB);
		EC_POINT_free(pub_key);
		return 0;
		}	
	EC_POINT_free(pub_key);
	return 1;

	}
예제 #3
0
파일: gost_ameth.c 프로젝트: 0culus/openssl
/* ------------------ private key functions  -----------------------------*/
static int priv_decode_gost( 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;

	if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) 
		return 0;
	p = pkey_buf;
	if (!decode_gost_algor_params(pk,palg)) 
		{
		return 0;
		}
	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||s->length !=32) 
			{
			GOSTerr(GOST_F_PRIV_DECODE_GOST,
				EVP_R_DECODE_ERROR);
			return 0;	
			}
		for (i=0;i<32;i++)
			{
			rev_buf[31-i]=s->data[i];
			}
		ASN1_STRING_free(s);
		pk_num = getbnfrombuf(rev_buf,32);
		} 
	else
		{
		priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
		if (!priv_key) return 0;
		ret= ((pk_num =  ASN1_INTEGER_to_BN(priv_key, NULL))!=NULL) ;
		ASN1_INTEGER_free(priv_key);
		if (!ret)
			{
			GOSTerr(GOST_F_PRIV_DECODE_GOST,
				EVP_R_DECODE_ERROR);
			return 0;	
			}
		}

	ret= gost_set_priv_key(pk,pk_num);
	BN_free(pk_num);
	return ret;
	}
예제 #4
0
static int priv_decode_gost(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;
    int expected_key_len = 32;

    if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf))
        return 0;
    p = pkey_buf;
    if (!decode_gost_algor_params(pk, palg)) {
        return 0;
    }

    expected_key_len = pkey_bits_gost(pk) > 0 ? pkey_bits_gost(pk) / 8 : 0;
    if (expected_key_len == 0) {
        GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
        return 0;
    }

    if (priv_len % expected_key_len == 0) {
        /* Key is not wrapped but masked */
        pk_num = unmask_priv_key(pk, pkey_buf, expected_key_len,
                                 priv_len / expected_key_len - 1);
    } else if (V_ASN1_OCTET_STRING == *p) {
        /* New format - Little endian octet string */
        ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len);
        if (!s || ((s->length != 32) && (s->length != 64))) {
            ASN1_STRING_free(s);
            GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
            return 0;
        }
        pk_num = hashsum2bn(s->data, s->length);
        ASN1_STRING_free(s);
    } else if (V_ASN1_INTEGER == *p) {
        priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len);
        if (!priv_key) {
            GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
            return 0;
        }
        pk_num = ASN1_INTEGER_to_BN(priv_key, NULL);
        ASN1_INTEGER_free(priv_key);
    } else if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == *p) {
        MASKED_GOST_KEY *mgk = NULL;
        mgk = d2i_MASKED_GOST_KEY(NULL, &p, priv_len);

        if (!mgk) {
            GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
            return 0;
        }

        priv_len = mgk->masked_priv_key->length;
        if (priv_len % expected_key_len) {
            MASKED_GOST_KEY_free(mgk);
            GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
            return 0;
        }

        pk_num = unmask_priv_key(pk, mgk->masked_priv_key->data,
                                 expected_key_len,
                                 priv_len / expected_key_len - 1);
        MASKED_GOST_KEY_free(mgk);
    } else {
        GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
        return 0;
    }

    if (pk_num == NULL) {
        GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR);
        return 0;
    }

    ret = gost_set_priv_key(pk, pk_num);
    BN_free(pk_num);
    return ret;
}