Branch data Line data Source code
1 : : /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2 : : * project 2006.
3 : : */
4 : : /* ====================================================================
5 : : * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions
9 : : * are met:
10 : : *
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer.
13 : : *
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in
16 : : * the documentation and/or other materials provided with the
17 : : * distribution.
18 : : *
19 : : * 3. All advertising materials mentioning features or use of this
20 : : * software must display the following acknowledgment:
21 : : * "This product includes software developed by the OpenSSL Project
22 : : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23 : : *
24 : : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25 : : * endorse or promote products derived from this software without
26 : : * prior written permission. For written permission, please contact
27 : : * licensing@OpenSSL.org.
28 : : *
29 : : * 5. Products derived from this software may not be called "OpenSSL"
30 : : * nor may "OpenSSL" appear in their names without prior written
31 : : * permission of the OpenSSL Project.
32 : : *
33 : : * 6. Redistributions of any form whatsoever must retain the following
34 : : * acknowledgment:
35 : : * "This product includes software developed by the OpenSSL Project
36 : : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37 : : *
38 : : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39 : : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41 : : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42 : : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 : : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 : : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47 : : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49 : : * OF THE POSSIBILITY OF SUCH DAMAGE.
50 : : * ====================================================================
51 : : *
52 : : * This product includes cryptographic software written by Eric Young
53 : : * (eay@cryptsoft.com). This product includes software written by Tim
54 : : * Hudson (tjh@cryptsoft.com).
55 : : *
56 : : */
57 : :
58 : : #include <stdio.h>
59 : : #include "cryptlib.h"
60 : : #include <openssl/x509.h>
61 : : #include <openssl/asn1.h>
62 : : #include <openssl/dh.h>
63 : : #include <openssl/bn.h>
64 : : #include "asn1_locl.h"
65 : : #ifndef OPENSSL_NO_CMS
66 : : #include <openssl/cms.h>
67 : : #endif
68 : :
69 : : extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
70 : :
71 : : /* i2d/d2i like DH parameter functions which use the appropriate routine
72 : : * for PKCS#3 DH or X9.42 DH.
73 : : */
74 : :
75 : 4 : static DH * d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, long length)
76 : : {
77 [ + - ]: 2 : if (pkey->ameth == &dhx_asn1_meth)
78 : 2 : return d2i_DHxparams(NULL, pp, length);
79 : 0 : return d2i_DHparams(NULL, pp, length);
80 : : }
81 : :
82 : 0 : static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
83 : : {
84 [ # # ]: 0 : if (pkey->ameth == &dhx_asn1_meth)
85 : 0 : return i2d_DHxparams(a, pp);
86 : 0 : return i2d_DHparams(a, pp);
87 : : }
88 : :
89 : 4 : static void int_dh_free(EVP_PKEY *pkey)
90 : : {
91 : 4 : DH_free(pkey->pkey.dh);
92 : 4 : }
93 : :
94 : 1 : static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
95 : : {
96 : : const unsigned char *p, *pm;
97 : : int pklen, pmlen;
98 : : int ptype;
99 : : void *pval;
100 : : ASN1_STRING *pstr;
101 : : X509_ALGOR *palg;
102 : 1 : ASN1_INTEGER *public_key = NULL;
103 : :
104 : 1 : DH *dh = NULL;
105 : :
106 [ + - ]: 1 : if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
107 : : return 0;
108 : 1 : X509_ALGOR_get0(NULL, &ptype, &pval, palg);
109 : :
110 [ - + ]: 1 : if (ptype != V_ASN1_SEQUENCE)
111 : : {
112 : 0 : DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
113 : 0 : goto err;
114 : : }
115 : :
116 : 1 : pstr = pval;
117 : 1 : pm = pstr->data;
118 : 1 : pmlen = pstr->length;
119 : :
120 [ - + ]: 1 : if (!(dh = d2i_dhp(pkey, &pm, pmlen)))
121 : : {
122 : 0 : DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
123 : 0 : goto err;
124 : : }
125 : :
126 [ - + ]: 1 : if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
127 : : {
128 : 0 : DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
129 : 0 : goto err;
130 : : }
131 : :
132 : : /* We have parameters now set public key */
133 [ - + ]: 1 : if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
134 : : {
135 : 0 : DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
136 : 0 : goto err;
137 : : }
138 : :
139 : 1 : ASN1_INTEGER_free(public_key);
140 : 1 : EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
141 : 1 : return 1;
142 : :
143 : : err:
144 [ # # ]: 0 : if (public_key)
145 : 0 : ASN1_INTEGER_free(public_key);
146 [ # # ]: 0 : if (dh)
147 : 0 : DH_free(dh);
148 : : return 0;
149 : :
150 : : }
151 : :
152 : 0 : static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
153 : : {
154 : : DH *dh;
155 : 0 : void *pval = NULL;
156 : : int ptype;
157 : 0 : unsigned char *penc = NULL;
158 : : int penclen;
159 : : ASN1_STRING *str;
160 : 0 : ASN1_INTEGER *pub_key = NULL;
161 : :
162 : 0 : dh=pkey->pkey.dh;
163 : :
164 : 0 : str = ASN1_STRING_new();
165 : 0 : str->length = i2d_dhp(pkey, dh, &str->data);
166 [ # # ]: 0 : if (str->length <= 0)
167 : : {
168 : 0 : DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
169 : 0 : goto err;
170 : : }
171 : 0 : pval = str;
172 : 0 : ptype = V_ASN1_SEQUENCE;
173 : :
174 : 0 : pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
175 [ # # ]: 0 : if (!pub_key)
176 : : goto err;
177 : :
178 : 0 : penclen = i2d_ASN1_INTEGER(pub_key, &penc);
179 : :
180 : 0 : ASN1_INTEGER_free(pub_key);
181 : :
182 [ # # ]: 0 : if (penclen <= 0)
183 : : {
184 : 0 : DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
185 : 0 : goto err;
186 : : }
187 : :
188 [ # # ]: 0 : if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
189 : : ptype, pval, penc, penclen))
190 : : return 1;
191 : :
192 : : err:
193 [ # # ]: 0 : if (penc)
194 : 0 : OPENSSL_free(penc);
195 [ # # ]: 0 : if (pval)
196 : 0 : ASN1_STRING_free(pval);
197 : :
198 : : return 0;
199 : : }
200 : :
201 : :
202 : : /* PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in
203 : : * that the AlgorithmIdentifier contains the parameters, the private key
204 : : * is explcitly included and the pubkey must be recalculated.
205 : : */
206 : :
207 : 1 : static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
208 : : {
209 : : const unsigned char *p, *pm;
210 : : int pklen, pmlen;
211 : : int ptype;
212 : : void *pval;
213 : : ASN1_STRING *pstr;
214 : : X509_ALGOR *palg;
215 : 1 : ASN1_INTEGER *privkey = NULL;
216 : :
217 : 1 : DH *dh = NULL;
218 : :
219 [ + - ]: 1 : if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
220 : : return 0;
221 : :
222 : 1 : X509_ALGOR_get0(NULL, &ptype, &pval, palg);
223 : :
224 [ + - ]: 1 : if (ptype != V_ASN1_SEQUENCE)
225 : : goto decerr;
226 : :
227 [ + - ]: 1 : if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
228 : : goto decerr;
229 : :
230 : :
231 : 1 : pstr = pval;
232 : 1 : pm = pstr->data;
233 : 1 : pmlen = pstr->length;
234 [ + - ]: 1 : if (!(dh = d2i_dhp(pkey, &pm, pmlen)))
235 : : goto decerr;
236 : : /* We have parameters now set private key */
237 [ - + ]: 1 : if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
238 : : {
239 : 0 : DHerr(DH_F_DH_PRIV_DECODE,DH_R_BN_ERROR);
240 : 0 : goto dherr;
241 : : }
242 : : /* Calculate public key */
243 [ + - ]: 1 : if (!DH_generate_key(dh))
244 : : goto dherr;
245 : :
246 : 1 : EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
247 : :
248 : 1 : ASN1_INTEGER_free(privkey);
249 : :
250 : 1 : return 1;
251 : :
252 : : decerr:
253 : 0 : DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
254 : : dherr:
255 : 0 : DH_free(dh);
256 : 0 : return 0;
257 : : }
258 : :
259 : 0 : static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
260 : : {
261 : 0 : ASN1_STRING *params = NULL;
262 : 0 : ASN1_INTEGER *prkey = NULL;
263 : 0 : unsigned char *dp = NULL;
264 : : int dplen;
265 : :
266 : 0 : params = ASN1_STRING_new();
267 : :
268 [ # # ]: 0 : if (!params)
269 : : {
270 : 0 : DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
271 : 0 : goto err;
272 : : }
273 : :
274 : 0 : params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data);
275 [ # # ]: 0 : if (params->length <= 0)
276 : : {
277 : 0 : DHerr(DH_F_DH_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
278 : 0 : goto err;
279 : : }
280 : 0 : params->type = V_ASN1_SEQUENCE;
281 : :
282 : : /* Get private key into integer */
283 : 0 : prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
284 : :
285 [ # # ]: 0 : if (!prkey)
286 : : {
287 : 0 : DHerr(DH_F_DH_PRIV_ENCODE,DH_R_BN_ERROR);
288 : 0 : goto err;
289 : : }
290 : :
291 : 0 : dplen = i2d_ASN1_INTEGER(prkey, &dp);
292 : :
293 : 0 : ASN1_INTEGER_free(prkey);
294 : :
295 [ # # ]: 0 : if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
296 : : V_ASN1_SEQUENCE, params, dp, dplen))
297 : : goto err;
298 : :
299 : : return 1;
300 : :
301 : : err:
302 [ # # ]: 0 : if (dp != NULL)
303 : 0 : OPENSSL_free(dp);
304 [ # # ]: 0 : if (params != NULL)
305 : 0 : ASN1_STRING_free(params);
306 [ # # ]: 0 : if (prkey != NULL)
307 : 0 : ASN1_INTEGER_free(prkey);
308 : : return 0;
309 : : }
310 : :
311 : :
312 : 0 : static void update_buflen(const BIGNUM *b, size_t *pbuflen)
313 : : {
314 : : size_t i;
315 [ # # ]: 0 : if (!b)
316 : 0 : return;
317 [ # # ]: 0 : if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
318 : 0 : *pbuflen = i;
319 : : }
320 : :
321 : 0 : static int dh_param_decode(EVP_PKEY *pkey,
322 : : const unsigned char **pder, int derlen)
323 : : {
324 : : DH *dh;
325 [ # # ]: 0 : if (!(dh = d2i_dhp(pkey, pder, derlen)))
326 : : {
327 : 0 : DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
328 : 0 : return 0;
329 : : }
330 : 0 : EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
331 : 0 : return 1;
332 : : }
333 : :
334 : 0 : static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
335 : : {
336 : 0 : return i2d_dhp(pkey, pkey->pkey.dh, pder);
337 : : }
338 : :
339 : 0 : static int do_dh_print(BIO *bp, const DH *x, int indent,
340 : : ASN1_PCTX *ctx, int ptype)
341 : : {
342 : 0 : unsigned char *m=NULL;
343 : 0 : int reason=ERR_R_BUF_LIB,ret=0;
344 : 0 : size_t buf_len=0;
345 : :
346 : 0 : const char *ktype = NULL;
347 : :
348 : : BIGNUM *priv_key, *pub_key;
349 : :
350 [ # # ]: 0 : if (ptype == 2)
351 : 0 : priv_key = x->priv_key;
352 : : else
353 : : priv_key = NULL;
354 : :
355 [ # # ]: 0 : if (ptype > 0)
356 : 0 : pub_key = x->pub_key;
357 : : else
358 : : pub_key = NULL;
359 : :
360 : 0 : update_buflen(x->p, &buf_len);
361 : :
362 [ # # ]: 0 : if (buf_len == 0)
363 : : {
364 : : reason = ERR_R_PASSED_NULL_PARAMETER;
365 : : goto err;
366 : : }
367 : :
368 : 0 : update_buflen(x->g, &buf_len);
369 : 0 : update_buflen(x->q, &buf_len);
370 : 0 : update_buflen(x->j, &buf_len);
371 : 0 : update_buflen(x->counter, &buf_len);
372 : 0 : update_buflen(pub_key, &buf_len);
373 : 0 : update_buflen(priv_key, &buf_len);
374 : :
375 [ # # ]: 0 : if (ptype == 2)
376 : : ktype = "DH Private-Key";
377 [ # # ]: 0 : else if (ptype == 1)
378 : : ktype = "DH Public-Key";
379 : : else
380 : 0 : ktype = "DH Parameters";
381 : :
382 : 0 : m= OPENSSL_malloc(buf_len+10);
383 [ # # ]: 0 : if (m == NULL)
384 : : {
385 : : reason=ERR_R_MALLOC_FAILURE;
386 : : goto err;
387 : : }
388 : :
389 : 0 : BIO_indent(bp, indent, 128);
390 [ # # ]: 0 : if (BIO_printf(bp,"%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
391 : : goto err;
392 : 0 : indent += 4;
393 : :
394 [ # # ]: 0 : if (!ASN1_bn_print(bp,"private-key:",priv_key,m,indent)) goto err;
395 [ # # ]: 0 : if (!ASN1_bn_print(bp,"public-key:",pub_key,m,indent)) goto err;
396 : :
397 [ # # ]: 0 : if (!ASN1_bn_print(bp,"prime:",x->p,m,indent)) goto err;
398 [ # # ]: 0 : if (!ASN1_bn_print(bp,"generator:",x->g,m,indent)) goto err;
399 [ # # ][ # # ]: 0 : if (x->q && !ASN1_bn_print(bp,"subgroup order:",x->q,m,indent)) goto err;
400 [ # # ][ # # ]: 0 : if (x->j && !ASN1_bn_print(bp,"subgroup factor:",x->j,m,indent))
401 : : goto err;
402 [ # # ]: 0 : if (x->seed)
403 : : {
404 : : int i;
405 : 0 : BIO_indent(bp, indent, 128);
406 : 0 : BIO_puts(bp, "seed:");
407 [ # # ]: 0 : for (i=0; i < x->seedlen; i++)
408 : : {
409 [ # # ]: 0 : if ((i%15) == 0)
410 : : {
411 [ # # ]: 0 : if(BIO_puts(bp,"\n") <= 0
412 [ # # ]: 0 : || !BIO_indent(bp,indent+4,128))
413 : : goto err;
414 : : }
415 [ # # ][ # # ]: 0 : if (BIO_printf(bp,"%02x%s", x->seed[i],
416 : 0 : ((i+1) == x->seedlen)?"":":") <= 0)
417 : : goto err;
418 : : }
419 [ # # ]: 0 : if (BIO_write(bp,"\n",1) <= 0) return(0);
420 : : }
421 [ # # ][ # # ]: 0 : if (x->counter && !ASN1_bn_print(bp,"counter:",x->counter,m,indent))
422 : : goto err;
423 [ # # ]: 0 : if (x->length != 0)
424 : : {
425 : 0 : BIO_indent(bp, indent, 128);
426 [ # # ]: 0 : if (BIO_printf(bp,"recommended-private-length: %d bits\n",
427 : 0 : (int)x->length) <= 0) goto err;
428 : : }
429 : :
430 : :
431 : : ret=1;
432 : : if (0)
433 : : {
434 : : err:
435 : 0 : DHerr(DH_F_DO_DH_PRINT,reason);
436 : : }
437 [ # # ]: 0 : if (m != NULL) OPENSSL_free(m);
438 : : return(ret);
439 : : }
440 : :
441 : 0 : static int int_dh_size(const EVP_PKEY *pkey)
442 : : {
443 : 0 : return(DH_size(pkey->pkey.dh));
444 : : }
445 : :
446 : 0 : static int dh_bits(const EVP_PKEY *pkey)
447 : : {
448 : 0 : return BN_num_bits(pkey->pkey.dh->p);
449 : : }
450 : :
451 : 0 : static int dh_security_bits(const EVP_PKEY *pkey)
452 : : {
453 : 0 : return DH_security_bits(pkey->pkey.dh);
454 : : }
455 : :
456 : 2 : static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
457 : : {
458 [ + - + - ]: 4 : if ( BN_cmp(a->pkey.dh->p,b->pkey.dh->p) ||
459 : 2 : BN_cmp(a->pkey.dh->g,b->pkey.dh->g))
460 : : return 0;
461 [ + - ]: 2 : else if (a->ameth == &dhx_asn1_meth)
462 : : {
463 [ + - ]: 2 : if (BN_cmp(a->pkey.dh->q,b->pkey.dh->q))
464 : : return 0;
465 : : }
466 : : return 1;
467 : : }
468 : :
469 : 3756 : static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
470 : : {
471 : : BIGNUM *a;
472 [ + + ]: 3756 : if (src)
473 : : {
474 : 3754 : a = BN_dup(src);
475 [ + - ]: 3754 : if (!a)
476 : : return 0;
477 : : }
478 : : else
479 : : a = NULL;
480 [ - + ]: 3756 : if (*dst)
481 : 0 : BN_free(*dst);
482 : 3756 : *dst = a;
483 : 3756 : return 1;
484 : : }
485 : :
486 : 1876 : static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
487 : : {
488 [ + + ]: 1876 : if (is_x942 == -1)
489 : 1875 : is_x942 = !!from->q;
490 [ + - ]: 1876 : if (!int_dh_bn_cpy(&to->p, from->p))
491 : : return 0;
492 [ + - ]: 1876 : if (!int_dh_bn_cpy(&to->g, from->g))
493 : : return 0;
494 [ + + ]: 1876 : if (is_x942)
495 : : {
496 [ + - ]: 2 : if (!int_dh_bn_cpy(&to->q, from->q))
497 : : return 0;
498 [ + - ]: 2 : if (!int_dh_bn_cpy(&to->j, from->j))
499 : : return 0;
500 [ - + ]: 2 : if(to->seed)
501 : : {
502 : 0 : OPENSSL_free(to->seed);
503 : 0 : to->seed = NULL;
504 : 0 : to->seedlen = 0;
505 : : }
506 [ - + ]: 2 : if (from->seed)
507 : : {
508 : 0 : to->seed = BUF_memdup(from->seed, from->seedlen);
509 [ # # ]: 0 : if (!to->seed)
510 : : return 0;
511 : 0 : to->seedlen = from->seedlen;
512 : : }
513 : : }
514 : : else
515 : 1874 : to->length = from->length;
516 : : return 1;
517 : : }
518 : :
519 : :
520 : 1875 : DH *DHparams_dup(DH *dh)
521 : : {
522 : : DH *ret;
523 : 1875 : ret = DH_new();
524 [ + - ]: 1875 : if (!ret)
525 : : return NULL;
526 [ - + ]: 1875 : if (!int_dh_param_copy(ret, dh, -1))
527 : : {
528 : 0 : DH_free(ret);
529 : 0 : return NULL;
530 : : }
531 : : return ret;
532 : : }
533 : :
534 : 1 : static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
535 : : {
536 : 1 : return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
537 : 1 : from->ameth == &dhx_asn1_meth);
538 : : }
539 : :
540 : 3 : static int dh_missing_parameters(const EVP_PKEY *a)
541 : : {
542 [ + - ][ + - ]: 3 : if (!a->pkey.dh->p || !a->pkey.dh->g)
543 : : return 1;
544 : 3 : return 0;
545 : : }
546 : :
547 : 0 : static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
548 : : {
549 [ # # ]: 0 : if (dh_cmp_parameters(a, b) == 0)
550 : : return 0;
551 [ # # ]: 0 : if (BN_cmp(b->pkey.dh->pub_key,a->pkey.dh->pub_key) != 0)
552 : : return 0;
553 : : else
554 : 0 : return 1;
555 : : }
556 : :
557 : 0 : static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
558 : : ASN1_PCTX *ctx)
559 : : {
560 : 0 : return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0);
561 : : }
562 : :
563 : 0 : static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
564 : : ASN1_PCTX *ctx)
565 : : {
566 : 0 : return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1);
567 : : }
568 : :
569 : 0 : static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
570 : : ASN1_PCTX *ctx)
571 : : {
572 : 0 : return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2);
573 : : }
574 : :
575 : 0 : int DHparams_print(BIO *bp, const DH *x)
576 : : {
577 : 0 : return do_dh_print(bp, x, 4, NULL, 0);
578 : : }
579 : :
580 : : #ifndef OPENSSL_NO_CMS
581 : : static int dh_cms_decrypt(CMS_RecipientInfo *ri);
582 : : static int dh_cms_encrypt(CMS_RecipientInfo *ri);
583 : : #endif
584 : :
585 : 4 : static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
586 : : {
587 [ + + - ]: 4 : switch (op)
588 : : {
589 : : #ifndef OPENSSL_NO_CMS
590 : :
591 : : case ASN1_PKEY_CTRL_CMS_ENVELOPE:
592 [ + + ]: 2 : if (arg1 == 1)
593 : 1 : return dh_cms_decrypt(arg2);
594 [ + - ]: 1 : else if (arg1 == 0)
595 : 1 : return dh_cms_encrypt(arg2);
596 : : return -2;
597 : :
598 : : case ASN1_PKEY_CTRL_CMS_RI_TYPE:
599 : 2 : *(int *)arg2 = CMS_RECIPINFO_AGREE;
600 : 2 : return 1;
601 : : #endif
602 : : default:
603 : : return -2;
604 : : }
605 : :
606 : : }
607 : :
608 : : const EVP_PKEY_ASN1_METHOD dh_asn1_meth =
609 : : {
610 : : EVP_PKEY_DH,
611 : : EVP_PKEY_DH,
612 : : 0,
613 : :
614 : : "DH",
615 : : "OpenSSL PKCS#3 DH method",
616 : :
617 : : dh_pub_decode,
618 : : dh_pub_encode,
619 : : dh_pub_cmp,
620 : : dh_public_print,
621 : :
622 : : dh_priv_decode,
623 : : dh_priv_encode,
624 : : dh_private_print,
625 : :
626 : : int_dh_size,
627 : : dh_bits,
628 : : dh_security_bits,
629 : :
630 : : dh_param_decode,
631 : : dh_param_encode,
632 : : dh_missing_parameters,
633 : : dh_copy_parameters,
634 : : dh_cmp_parameters,
635 : : dh_param_print,
636 : : 0,
637 : :
638 : : int_dh_free,
639 : : 0
640 : : };
641 : :
642 : : const EVP_PKEY_ASN1_METHOD dhx_asn1_meth =
643 : : {
644 : : EVP_PKEY_DHX,
645 : : EVP_PKEY_DHX,
646 : : 0,
647 : :
648 : : "X9.42 DH",
649 : : "OpenSSL X9.42 DH method",
650 : :
651 : : dh_pub_decode,
652 : : dh_pub_encode,
653 : : dh_pub_cmp,
654 : : dh_public_print,
655 : :
656 : : dh_priv_decode,
657 : : dh_priv_encode,
658 : : dh_private_print,
659 : :
660 : : int_dh_size,
661 : : dh_bits,
662 : : dh_security_bits,
663 : :
664 : : dh_param_decode,
665 : : dh_param_encode,
666 : : dh_missing_parameters,
667 : : dh_copy_parameters,
668 : : dh_cmp_parameters,
669 : : dh_param_print,
670 : : 0,
671 : :
672 : : int_dh_free,
673 : : dh_pkey_ctrl
674 : : };
675 : : #ifndef OPENSSL_NO_CMS
676 : :
677 : 1 : static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
678 : : X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
679 : : {
680 : : ASN1_OBJECT *aoid;
681 : : int atype;
682 : : void *aval;
683 : 1 : ASN1_INTEGER *public_key = NULL;
684 : 1 : int rv = 0;
685 : 1 : EVP_PKEY *pkpeer = NULL, *pk = NULL;
686 : 1 : DH *dhpeer = NULL;
687 : : const unsigned char *p;
688 : : int plen;
689 : :
690 : 1 : X509_ALGOR_get0(&aoid, &atype, &aval, alg);
691 [ + - ]: 1 : if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
692 : : goto err;
693 : : /* Only absent parameters allowed in RFC XXXX */
694 [ + - ]: 1 : if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
695 : : goto err;
696 : :
697 : 1 : pk = EVP_PKEY_CTX_get0_pkey(pctx);
698 [ + - ]: 1 : if (!pk)
699 : : goto err;
700 [ + - ]: 1 : if (pk->type != EVP_PKEY_DHX)
701 : : goto err;
702 : : /* Get parameters from parent key */
703 : 1 : dhpeer = DHparams_dup(pk->pkey.dh);
704 : : /* We have parameters now set public key */
705 : 1 : plen = ASN1_STRING_length(pubkey);
706 : 1 : p = ASN1_STRING_data(pubkey);
707 [ + - ]: 1 : if (!p || !plen)
708 : : goto err;
709 : :
710 [ - + ]: 1 : if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, plen)))
711 : : {
712 : 0 : DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
713 : 0 : goto err;
714 : : }
715 : :
716 : : /* We have parameters now set public key */
717 [ - + ]: 1 : if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
718 : : {
719 : 0 : DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
720 : 0 : goto err;
721 : : }
722 : :
723 : 1 : pkpeer = EVP_PKEY_new();
724 [ + - ]: 1 : if (!pkpeer)
725 : : goto err;
726 : 1 : EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
727 : 1 : dhpeer = NULL;
728 [ + - ]: 1 : if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
729 : 1 : rv = 1;
730 : : err:
731 [ + - ]: 1 : if (public_key)
732 : 1 : ASN1_INTEGER_free(public_key);
733 [ + - ]: 1 : if (pkpeer)
734 : 1 : EVP_PKEY_free(pkpeer);
735 [ - + ]: 1 : if (dhpeer)
736 : 0 : DH_free(dhpeer);
737 : 1 : return rv;
738 : : }
739 : :
740 : 1 : static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
741 : : {
742 : 1 : int rv = 0;
743 : :
744 : 1 : X509_ALGOR *alg, *kekalg = NULL;
745 : : ASN1_OCTET_STRING *ukm;
746 : : const unsigned char *p;
747 : 1 : unsigned char *dukm = NULL;
748 : 1 : size_t dukmlen = 0;
749 : : int keylen, plen;
750 : : const EVP_CIPHER *kekcipher;
751 : : EVP_CIPHER_CTX *kekctx;
752 : :
753 [ + - ]: 1 : if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
754 : : goto err;
755 : :
756 : : /* For DH we only have one OID permissible. If ever any more get
757 : : * defined we will need something cleverer.
758 : : */
759 [ - + ]: 1 : if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH)
760 : : {
761 : 0 : DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
762 : 0 : goto err;
763 : : }
764 : :
765 [ + - ]: 1 : if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
766 : : goto err;
767 : :
768 [ + - ]: 1 : if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
769 : : goto err;
770 : :
771 [ + - ]: 1 : if (alg->parameter->type != V_ASN1_SEQUENCE)
772 : : goto err;
773 : :
774 : 1 : p = alg->parameter->value.sequence->data;
775 : 1 : plen = alg->parameter->value.sequence->length;
776 : 1 : kekalg = d2i_X509_ALGOR(NULL, &p, plen);
777 [ + - ]: 1 : if (!kekalg)
778 : : goto err;
779 : 1 : kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
780 [ + - ]: 1 : if (!kekctx)
781 : : goto err;
782 : 1 : kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
783 [ + - ][ + - ]: 1 : if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
784 : : goto err;
785 [ + - ]: 1 : if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
786 : : goto err;
787 [ + - ]: 1 : if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
788 : : goto err;
789 : :
790 : 1 : keylen = EVP_CIPHER_CTX_key_length(kekctx);
791 [ + - ]: 1 : if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
792 : : goto err;
793 : : /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
794 [ + - ]: 1 : if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
795 : : OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) <= 0)
796 : : goto err;
797 : :
798 [ - + ]: 1 : if (ukm)
799 : : {
800 : 0 : dukmlen = ASN1_STRING_length(ukm);
801 : 0 : dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
802 [ # # ]: 0 : if (!dukm)
803 : : goto err;
804 : : }
805 : :
806 [ + - ]: 1 : if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
807 : : goto err;
808 : 1 : dukm = NULL;
809 : :
810 : 1 : rv = 1;
811 : : err:
812 [ + - ]: 1 : if (kekalg)
813 : 1 : X509_ALGOR_free(kekalg);
814 [ - + ]: 1 : if (dukm)
815 : 0 : OPENSSL_free(dukm);
816 : 1 : return rv;
817 : : }
818 : :
819 : 1 : static int dh_cms_decrypt(CMS_RecipientInfo *ri)
820 : : {
821 : : EVP_PKEY_CTX *pctx;
822 : 1 : pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
823 [ + - ]: 1 : if (!pctx)
824 : : return 0;
825 : : /* See if we need to set peer key */
826 [ + - ]: 1 : if (!EVP_PKEY_CTX_get0_peerkey(pctx))
827 : : {
828 : : X509_ALGOR *alg;
829 : : ASN1_BIT_STRING *pubkey;
830 [ + - ]: 1 : if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
831 : : NULL, NULL, NULL))
832 : 0 : return 0;
833 [ + - ][ + - ]: 1 : if (!alg || !pubkey)
834 : : return 0;
835 [ - + ]: 1 : if (!dh_cms_set_peerkey(pctx, alg, pubkey))
836 : : {
837 : 1 : DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
838 : 0 : return 0;
839 : : }
840 : : }
841 : : /* Set DH derivation parameters and initialise unwrap context */
842 [ - + ]: 1 : if (!dh_cms_set_shared_info(pctx, ri))
843 : : {
844 : 0 : DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
845 : 0 : return 0;
846 : : }
847 : : return 1;
848 : : }
849 : :
850 : 1 : static int dh_cms_encrypt(CMS_RecipientInfo *ri)
851 : : {
852 : : EVP_PKEY_CTX *pctx;
853 : : EVP_PKEY *pkey;
854 : : EVP_CIPHER_CTX *ctx;
855 : : int keylen;
856 : 1 : X509_ALGOR *talg, *wrap_alg = NULL;
857 : : ASN1_OBJECT *aoid;
858 : : ASN1_BIT_STRING *pubkey;
859 : : ASN1_STRING *wrap_str;
860 : : ASN1_OCTET_STRING *ukm;
861 : 1 : unsigned char *penc = NULL, *dukm = NULL;
862 : : int penclen;
863 : 1 : size_t dukmlen = 0;
864 : 1 : int rv = 0;
865 : : int kdf_type, wrap_nid;
866 : : const EVP_MD *kdf_md;
867 : 1 : pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
868 [ + - ]: 1 : if (!pctx)
869 : : return 0;
870 : : /* Get ephemeral key */
871 : 1 : pkey = EVP_PKEY_CTX_get0_pkey(pctx);
872 [ + - ]: 1 : if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
873 : : NULL, NULL, NULL))
874 : : goto err;
875 : 1 : X509_ALGOR_get0(&aoid, NULL, NULL, talg);
876 : : /* Is everything uninitialised? */
877 [ + - ]: 1 : if (aoid == OBJ_nid2obj(NID_undef))
878 : : {
879 : : ASN1_INTEGER *pubk;
880 : 1 : pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
881 [ + - ]: 1 : if (!pubk)
882 : : goto err;
883 : : /* Set the key */
884 : :
885 : 1 : penclen = i2d_ASN1_INTEGER(pubk, &penc);
886 : 1 : ASN1_INTEGER_free(pubk);
887 [ + - ]: 1 : if (penclen <= 0)
888 : : goto err;
889 : 1 : ASN1_STRING_set0(pubkey, penc, penclen);
890 : 1 : pubkey->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
891 : 1 : pubkey->flags|=ASN1_STRING_FLAG_BITS_LEFT;
892 : :
893 : 1 : penc = NULL;
894 : 1 : X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
895 : : V_ASN1_UNDEF, NULL);
896 : : }
897 : :
898 : : /* See if custom paraneters set */
899 : 1 : kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
900 [ + - ]: 1 : if (kdf_type <= 0)
901 : : goto err;
902 [ + - ]: 1 : if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
903 : : goto err;
904 : :
905 [ + - ]: 1 : if (kdf_type == EVP_PKEY_DH_KDF_NONE)
906 : : {
907 : 1 : kdf_type = EVP_PKEY_DH_KDF_X9_42;
908 [ + - ]: 1 : if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
909 : : goto err;
910 : : }
911 [ # # ]: 0 : else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
912 : : /* Unknown KDF */
913 : : goto err;
914 [ + - ]: 1 : if (kdf_md == NULL)
915 : : {
916 : : /* Only SHA1 supported */
917 : 1 : kdf_md = EVP_sha1();
918 [ + - ]: 1 : if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
919 : : goto err;
920 : : }
921 [ # # ]: 0 : else if (EVP_MD_type(kdf_md) != NID_sha1)
922 : : /* Unsupported digest */
923 : : goto err;
924 : :
925 [ + - ]: 1 : if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
926 : : goto err;
927 : :
928 : : /* Get wrap NID */
929 : 1 : ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
930 : 1 : wrap_nid = EVP_CIPHER_CTX_type(ctx);
931 [ + - ]: 1 : if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
932 : : goto err;
933 : 1 : keylen = EVP_CIPHER_CTX_key_length(ctx);
934 : :
935 : : /* Package wrap algorithm in an AlgorithmIdentifier */
936 : :
937 : 1 : wrap_alg = X509_ALGOR_new();
938 [ + - ]: 1 : if (!wrap_alg)
939 : : goto err;
940 : 1 : wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
941 : 1 : wrap_alg->parameter = ASN1_TYPE_new();
942 [ + - ]: 1 : if (!wrap_alg->parameter)
943 : : goto err;
944 [ + - ]: 1 : if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
945 : : goto err;
946 [ - + ]: 1 : if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef)
947 : : {
948 : 0 : ASN1_TYPE_free(wrap_alg->parameter);
949 : 0 : wrap_alg->parameter = NULL;
950 : : }
951 : :
952 [ + - ]: 1 : if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
953 : : goto err;
954 : :
955 [ - + ]: 1 : if (ukm)
956 : : {
957 : 0 : dukmlen = ASN1_STRING_length(ukm);
958 : 0 : dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
959 [ # # ]: 0 : if (!dukm)
960 : : goto err;
961 : : }
962 : :
963 [ + - ]: 1 : if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
964 : : goto err;
965 : 1 : dukm = NULL;
966 : :
967 : : /* Now need to wrap encoding of wrap AlgorithmIdentifier into
968 : : * parameter of another AlgorithmIdentifier.
969 : : */
970 : 1 : penc = NULL;
971 : 1 : penclen = i2d_X509_ALGOR(wrap_alg, &penc);
972 [ + - ][ + - ]: 1 : if (!penc || !penclen)
973 : : goto err;
974 : 1 : wrap_str = ASN1_STRING_new();
975 [ + - ]: 1 : if (!wrap_str)
976 : : goto err;
977 : 1 : ASN1_STRING_set0(wrap_str, penc, penclen);
978 : 1 : penc = NULL;
979 : 1 : X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
980 : : V_ASN1_SEQUENCE, wrap_str);
981 : :
982 : 1 : rv = 1;
983 : :
984 : : err:
985 [ - + ]: 1 : if (penc)
986 : 0 : OPENSSL_free(penc);
987 [ + - ]: 1 : if (wrap_alg)
988 : 1 : X509_ALGOR_free(wrap_alg);
989 : 1 : return rv;
990 : : }
991 : :
992 : : #endif
993 : :
|