1221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * project 2006.
3221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
4221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* ====================================================================
5221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
7221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Redistribution and use in source and binary forms, with or without
8221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * modification, are permitted provided that the following conditions
9221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * are met:
10221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
11221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 1. Redistributions of source code must retain the above copyright
12221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    notice, this list of conditions and the following disclaimer.
13221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
14221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 2. Redistributions in binary form must reproduce the above copyright
15221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    notice, this list of conditions and the following disclaimer in
16221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    the documentation and/or other materials provided with the
17221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    distribution.
18221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
19221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 3. All advertising materials mentioning features or use of this
20221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    software must display the following acknowledgment:
21221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    "This product includes software developed by the OpenSSL Project
22221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
24221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    endorse or promote products derived from this software without
26221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    prior written permission. For written permission, please contact
27221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    licensing@OpenSSL.org.
28221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
29221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 5. Products derived from this software may not be called "OpenSSL"
30221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    nor may "OpenSSL" appear in their names without prior written
31221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    permission of the OpenSSL Project.
32221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
33221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * 6. Redistributions of any form whatsoever must retain the following
34221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    acknowledgment:
35221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    "This product includes software developed by the OpenSSL Project
36221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
38221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * OF THE POSSIBILITY OF SUCH DAMAGE.
50221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ====================================================================
51221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
52221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * This product includes cryptographic software written by Eric Young
53221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * (eay@cryptsoft.com).  This product includes software written by Tim
54221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Hudson (tjh@cryptsoft.com).
55221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
56221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
57221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
58221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <stdio.h>
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "cryptlib.h"
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/x509.h>
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/asn1.h>
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/dh.h>
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <openssl/bn.h>
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "asn1_locl.h"
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void int_dh_free(EVP_PKEY *pkey)
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DH_free(pkey->pkey.dh);
69221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
70221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
72221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
73221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const unsigned char *p, *pm;
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int pklen, pmlen;
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ptype;
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *pval;
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_STRING *pstr;
78221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_ALGOR *palg;
79221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER *public_key = NULL;
80221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DH *dh = NULL;
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ptype != V_ASN1_SEQUENCE)
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
93221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pstr = pval;
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pm = pstr->data;
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pmlen = pstr->length;
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
97221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
98221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
109221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* We have parameters now set public key */
110221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER_free(public_key);
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_assign_DH(pkey, dh);
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err:
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (public_key)
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ASN1_INTEGER_free(public_key);
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (dh)
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DH_free(dh);
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DH *dh;
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *pval = NULL;
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ptype;
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char *penc = NULL;
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int penclen;
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_STRING *str;
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER *pub_key = NULL;
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh=pkey->pkey.dh;
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	str = ASN1_STRING_new();
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	str->length = i2d_DHparams(dh, &str->data);
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (str->length <= 0)
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pval = str;
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ptype = V_ASN1_SEQUENCE;
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!pub_key)
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	penclen = i2d_ASN1_INTEGER(pub_key, &penc);
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER_free(pub_key);
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (penclen <= 0)
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH),
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				ptype, pval, penc, penclen))
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	err:
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (penc)
171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		OPENSSL_free(penc);
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (pval)
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ASN1_STRING_free(pval);
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * that the AlgorithmIdentifier contains the paramaters, the private key
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * is explcitly included and the pubkey must be recalculated.
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const unsigned char *p, *pm;
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int pklen, pmlen;
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int ptype;
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *pval;
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_STRING *pstr;
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_ALGOR *palg;
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER *privkey = NULL;
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DH *dh = NULL;
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	X509_ALGOR_get0(NULL, &ptype, &pval, palg);
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ptype != V_ASN1_SEQUENCE)
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			goto decerr;
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto decerr;
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pstr = pval;
209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pm = pstr->data;
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	pmlen = pstr->length;
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto decerr;
213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* We have parameters now set private key */
214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto dherr;
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Calculate public key */
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!DH_generate_key(dh))
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto dherr;
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_assign_DH(pkey, dh);
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER_free(privkey);
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	decerr:
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dherr:
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DH_free(dh);
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_STRING *params = NULL;
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER *prkey = NULL;
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char *dp = NULL;
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int dplen;
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	params = ASN1_STRING_new();
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!params)
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (params->length <= 0)
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	params->type = V_ASN1_SEQUENCE;
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Get private key into integer */
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!prkey)
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dplen = i2d_ASN1_INTEGER(prkey, &dp);
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ASN1_INTEGER_free(prkey);
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				V_ASN1_SEQUENCE, params, dp, dplen))
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromerr:
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (dp != NULL)
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		OPENSSL_free(dp);
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (params != NULL)
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ASN1_STRING_free(params);
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (prkey != NULL)
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ASN1_INTEGER_free(prkey);
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void update_buflen(const BIGNUM *b, size_t *pbuflen)
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	size_t i;
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!b)
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return;
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			*pbuflen = i;
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_param_decode(EVP_PKEY *pkey,
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					const unsigned char **pder, int derlen)
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	DH *dh;
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!(dh = d2i_DHparams(NULL, pder, derlen)))
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_assign_DH(pkey, dh);
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return i2d_DHparams(pkey->pkey.dh, pder);
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int do_dh_print(BIO *bp, const DH *x, int indent,
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom						ASN1_PCTX *ctx, int ptype)
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char *m=NULL;
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int reason=ERR_R_BUF_LIB,ret=0;
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	size_t buf_len=0;
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const char *ktype = NULL;
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIGNUM *priv_key, *pub_key;
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ptype == 2)
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		priv_key = x->priv_key;
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		priv_key = NULL;
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ptype > 0)
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		pub_key = x->pub_key;
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		pub_key = NULL;
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	update_buflen(x->p, &buf_len);
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (buf_len == 0)
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		reason = ERR_R_PASSED_NULL_PARAMETER;
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	update_buflen(x->g, &buf_len);
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	update_buflen(pub_key, &buf_len);
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	update_buflen(priv_key, &buf_len);
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ptype == 2)
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ktype = "PKCS#3 DH Private-Key";
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else if (ptype == 1)
352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ktype = "PKCS#3 DH Public-Key";
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ktype = "PKCS#3 DH Parameters";
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	m= OPENSSL_malloc(buf_len+10);
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (m == NULL)
358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		reason=ERR_R_MALLOC_FAILURE;
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIO_indent(bp, indent, 128);
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		goto err;
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	indent += 4;
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (x->length != 0)
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BIO_indent(bp, indent, 128);
376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (BIO_printf(bp,"recommended-private-length: %d bits\n",
377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			(int)x->length) <= 0) goto err;
378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ret=1;
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (0)
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromerr:
385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		DHerr(DH_F_DO_DH_PRINT,reason);
386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (m != NULL) OPENSSL_free(m);
388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return(ret);
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int int_dh_size(const EVP_PKEY *pkey)
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return(DH_size(pkey->pkey.dh));
394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_bits(const EVP_PKEY *pkey)
397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return BN_num_bits(pkey->pkey.dh->p);
399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (	BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	BIGNUM *a;
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((a=BN_dup(from->pkey.dh->p)) == NULL)
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (to->pkey.dh->p != NULL)
417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BN_free(to->pkey.dh->p);
418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	to->pkey.dh->p=a;
419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if ((a=BN_dup(from->pkey.dh->g)) == NULL)
421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (to->pkey.dh->g != NULL)
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		BN_free(to->pkey.dh->g);
424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	to->pkey.dh->g=a;
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 1;
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_missing_parameters(const EVP_PKEY *a)
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!a->pkey.dh->p || !a->pkey.dh->g)
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return 0;
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (dh_cmp_parameters(a, b) == 0)
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 1;
444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							ASN1_PCTX *ctx)
448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							ASN1_PCTX *ctx)
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom							ASN1_PCTX *ctx)
460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint DHparams_print(BIO *bp, const DH *x)
465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return do_dh_print(bp, x, 4, NULL, 0);
467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromconst EVP_PKEY_ASN1_METHOD dh_asn1_meth =
470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_DH,
472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY_DH,
473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0,
474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	"DH",
476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	"OpenSSL PKCS#3 DH method",
477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_pub_decode,
479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_pub_encode,
480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_pub_cmp,
481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_public_print,
482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_priv_decode,
484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_priv_encode,
485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_private_print,
486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_dh_size,
488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_bits,
489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_param_decode,
491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_param_encode,
492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_missing_parameters,
493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_copy_parameters,
494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_cmp_parameters,
495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dh_param_print,
496392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	0,
497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int_dh_free,
499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	0
500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	};
501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
502