Commit 4c97a04e authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

PKCS#3 DH PKCS#8 ASN1 support.

parent fb05e1cd
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -216,14 +216,18 @@ void ERR_load_DH_strings(void);
#define DH_F_DH_BUILTIN_GENPARAMS			 106
#define DH_F_DH_NEW_METHOD				 105
#define DH_F_DH_PARAM_DECODE				 107
#define DH_F_DH_PRIV_DECODE				 110
#define DH_F_DH_PRIV_ENCODE				 111
#define DH_F_DH_PUB_DECODE				 108
#define DH_F_DH_PUB_ENCODE				 109
#define DH_F_DSA_PRIV_ENCODE				 112
#define DH_F_GENERATE_KEY				 103
#define DH_F_GENERATE_PARAMETERS			 104

/* Reason codes. */
#define DH_R_BAD_GENERATOR				 101
#define DH_R_BN_DECODE_ERROR				 103
#define DH_R_BN_ERROR					 106
#define DH_R_DECODE_ERROR				 104
#define DH_R_INVALID_PUBKEY				 102
#define DH_R_NO_PRIVATE_VALUE				 100
+113 −2
Original line number Diff line number Diff line
@@ -174,6 +174,117 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
	return 0;
	}


/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
 * that the AlgorithmIdentifier contains the paramaters, the private key
 * is explcitly included and the pubkey must be recalculated.
 */
	
static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
	{
	const unsigned char *p, *pm;
	int pklen, pmlen;
	int ptype;
	void *pval;
	ASN1_STRING *pstr;
	X509_ALGOR *palg;
	ASN1_INTEGER *privkey = NULL;

	DH *dh = NULL;

	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
		return 0;

	X509_ALGOR_get0(NULL, &ptype, &pval, palg);

	if (ptype != V_ASN1_SEQUENCE)
			goto decerr;

	if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
		goto decerr;


	pstr = pval;	
	pm = pstr->data;
	pmlen = pstr->length;
	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
		goto decerr;
	/* We have parameters now set private key */
	if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
		{
		DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
		goto dherr;
		}
	/* Calculate public key */
	if (!DH_generate_key(dh))
		goto dherr;

	EVP_PKEY_assign_DH(pkey, dh);

	ASN1_INTEGER_free(privkey);

	return 1;

	decerr:
	DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
	dherr:
	DH_free(dh);
	return 0;
	}

static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
	ASN1_STRING *params = NULL;
	ASN1_INTEGER *prkey = NULL;
	unsigned char *dp = NULL;
	int dplen;

	params = ASN1_STRING_new();

	if (!params)
		{
		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
	if (params->length <= 0)
		{
		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	params->type = V_ASN1_SEQUENCE;

	/* Get private key into integer */
	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);

	if (!prkey)
		{
		DHerr(DH_F_DSA_PRIV_ENCODE,DH_R_BN_ERROR);
		goto err;
		}

	dplen = i2d_ASN1_INTEGER(prkey, &dp);

	ASN1_INTEGER_free(prkey);

	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
				V_ASN1_SEQUENCE, params, dp, dplen))
		goto err;

	return 1;

err:
	if (dp != NULL)
		OPENSSL_free(dp);
	if (params != NULL)
		ASN1_STRING_free(params);
	if (prkey != NULL)
		ASN1_INTEGER_free(prkey);
	return 0;
}


static void update_buflen(const BIGNUM *b, size_t *pbuflen)
	{
	int i;
@@ -361,8 +472,8 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
	dh_pub_cmp,
	dh_public_print,

	0,
	0,
	dh_priv_decode,
	dh_priv_encode,
	dh_private_print,

	int_dh_size,
+4 −0
Original line number Diff line number Diff line
@@ -76,8 +76,11 @@ static ERR_STRING_DATA DH_str_functs[]=
{ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
{ERR_FUNC(DH_F_DH_NEW_METHOD),	"DH_new_method"},
{ERR_FUNC(DH_F_DH_PARAM_DECODE),	"DH_PARAM_DECODE"},
{ERR_FUNC(DH_F_DH_PRIV_DECODE),	"DH_PRIV_DECODE"},
{ERR_FUNC(DH_F_DH_PRIV_ENCODE),	"DH_PRIV_ENCODE"},
{ERR_FUNC(DH_F_DH_PUB_DECODE),	"DH_PUB_DECODE"},
{ERR_FUNC(DH_F_DH_PUB_ENCODE),	"DH_PUB_ENCODE"},
{ERR_FUNC(DH_F_DSA_PRIV_ENCODE),	"DSA_PRIV_ENCODE"},
{ERR_FUNC(DH_F_GENERATE_KEY),	"GENERATE_KEY"},
{ERR_FUNC(DH_F_GENERATE_PARAMETERS),	"GENERATE_PARAMETERS"},
{0,NULL}
@@ -87,6 +90,7 @@ static ERR_STRING_DATA DH_str_reasons[]=
	{
{ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
{ERR_REASON(DH_R_BN_DECODE_ERROR)        ,"bn decode error"},
{ERR_REASON(DH_R_BN_ERROR)               ,"bn error"},
{ERR_REASON(DH_R_DECODE_ERROR)           ,"decode error"},
{ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
{ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},