]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/crypto/asn1/t_pkey.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / crypto / asn1 / t_pkey.c
1 /* crypto/asn1/t_pkey.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 /* ====================================================================
59  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60  * Binary polynomial ECC support in OpenSSL originally developed by
61  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62  */
63
64 #include <stdio.h>
65 #include "cryptlib.h"
66 #include <openssl/objects.h>
67 #include <openssl/buffer.h>
68 #include <openssl/bn.h>
69 #ifndef OPENSSL_NO_RSA
70 # include <openssl/rsa.h>
71 #endif
72 #ifndef OPENSSL_NO_DH
73 # include <openssl/dh.h>
74 #endif
75 #ifndef OPENSSL_NO_DSA
76 # include <openssl/dsa.h>
77 #endif
78 #ifndef OPENSSL_NO_EC
79 # include <openssl/ec.h>
80 #endif
81
82 static int print(BIO *fp, const char *str, const BIGNUM *num,
83                  unsigned char *buf, int off);
84 #ifndef OPENSSL_NO_EC
85 static int print_bin(BIO *fp, const char *str, const unsigned char *num,
86                      size_t len, int off);
87 #endif
88 #ifndef OPENSSL_NO_RSA
89 # ifndef OPENSSL_NO_FP_API
90 int RSA_print_fp(FILE *fp, const RSA *x, int off)
91 {
92     BIO *b;
93     int ret;
94
95     if ((b = BIO_new(BIO_s_file())) == NULL) {
96         RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB);
97         return (0);
98     }
99     BIO_set_fp(b, fp, BIO_NOCLOSE);
100     ret = RSA_print(b, x, off);
101     BIO_free(b);
102     return (ret);
103 }
104 # endif
105
106 int RSA_print(BIO *bp, const RSA *x, int off)
107 {
108     char str[128];
109     const char *s;
110     unsigned char *m = NULL;
111     int ret = 0, mod_len = 0;
112     size_t buf_len = 0, i;
113
114     if (x->n)
115         buf_len = (size_t)BN_num_bytes(x->n);
116     if (x->e)
117         if (buf_len < (i = (size_t)BN_num_bytes(x->e)))
118             buf_len = i;
119     if (x->d)
120         if (buf_len < (i = (size_t)BN_num_bytes(x->d)))
121             buf_len = i;
122     if (x->p)
123         if (buf_len < (i = (size_t)BN_num_bytes(x->p)))
124             buf_len = i;
125     if (x->q)
126         if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
127             buf_len = i;
128     if (x->dmp1)
129         if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1)))
130             buf_len = i;
131     if (x->dmq1)
132         if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1)))
133             buf_len = i;
134     if (x->iqmp)
135         if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp)))
136             buf_len = i;
137
138     m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
139     if (m == NULL) {
140         RSAerr(RSA_F_RSA_PRINT, ERR_R_MALLOC_FAILURE);
141         goto err;
142     }
143
144     if (x->n != NULL)
145         mod_len = BN_num_bits(x->n);
146
147     if (x->d != NULL) {
148         if (!BIO_indent(bp, off, 128))
149             goto err;
150         if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len)
151             <= 0)
152             goto err;
153     }
154
155     if (x->d == NULL)
156         BIO_snprintf(str, sizeof str, "Modulus (%d bit):", mod_len);
157     else
158         BUF_strlcpy(str, "modulus:", sizeof str);
159     if (!print(bp, str, x->n, m, off))
160         goto err;
161     s = (x->d == NULL) ? "Exponent:" : "publicExponent:";
162     if ((x->e != NULL) && !print(bp, s, x->e, m, off))
163         goto err;
164     if ((x->d != NULL) && !print(bp, "privateExponent:", x->d, m, off))
165         goto err;
166     if ((x->p != NULL) && !print(bp, "prime1:", x->p, m, off))
167         goto err;
168     if ((x->q != NULL) && !print(bp, "prime2:", x->q, m, off))
169         goto err;
170     if ((x->dmp1 != NULL) && !print(bp, "exponent1:", x->dmp1, m, off))
171         goto err;
172     if ((x->dmq1 != NULL) && !print(bp, "exponent2:", x->dmq1, m, off))
173         goto err;
174     if ((x->iqmp != NULL) && !print(bp, "coefficient:", x->iqmp, m, off))
175         goto err;
176     ret = 1;
177  err:
178     if (m != NULL)
179         OPENSSL_free(m);
180     return (ret);
181 }
182 #endif                          /* OPENSSL_NO_RSA */
183
184 #ifndef OPENSSL_NO_DSA
185 # ifndef OPENSSL_NO_FP_API
186 int DSA_print_fp(FILE *fp, const DSA *x, int off)
187 {
188     BIO *b;
189     int ret;
190
191     if ((b = BIO_new(BIO_s_file())) == NULL) {
192         DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB);
193         return (0);
194     }
195     BIO_set_fp(b, fp, BIO_NOCLOSE);
196     ret = DSA_print(b, x, off);
197     BIO_free(b);
198     return (ret);
199 }
200 # endif
201
202 int DSA_print(BIO *bp, const DSA *x, int off)
203 {
204     unsigned char *m = NULL;
205     int ret = 0;
206     size_t buf_len = 0, i;
207
208     if (x->p)
209         buf_len = (size_t)BN_num_bytes(x->p);
210     if (x->q)
211         if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
212             buf_len = i;
213     if (x->g)
214         if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
215             buf_len = i;
216     if (x->priv_key)
217         if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key)))
218             buf_len = i;
219     if (x->pub_key)
220         if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key)))
221             buf_len = i;
222
223     m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
224     if (m == NULL) {
225         DSAerr(DSA_F_DSA_PRINT, ERR_R_MALLOC_FAILURE);
226         goto err;
227     }
228
229     if (x->priv_key != NULL) {
230         if (!BIO_indent(bp, off, 128))
231             goto err;
232         if (BIO_printf(bp, "Private-Key: (%d bit)\n", BN_num_bits(x->p))
233             <= 0)
234             goto err;
235     }
236
237     if ((x->priv_key != NULL) && !print(bp, "priv:", x->priv_key, m, off))
238         goto err;
239     if ((x->pub_key != NULL) && !print(bp, "pub: ", x->pub_key, m, off))
240         goto err;
241     if ((x->p != NULL) && !print(bp, "P:   ", x->p, m, off))
242         goto err;
243     if ((x->q != NULL) && !print(bp, "Q:   ", x->q, m, off))
244         goto err;
245     if ((x->g != NULL) && !print(bp, "G:   ", x->g, m, off))
246         goto err;
247     ret = 1;
248  err:
249     if (m != NULL)
250         OPENSSL_free(m);
251     return (ret);
252 }
253 #endif                          /* !OPENSSL_NO_DSA */
254
255 #ifndef OPENSSL_NO_EC
256 # ifndef OPENSSL_NO_FP_API
257 int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
258 {
259     BIO *b;
260     int ret;
261
262     if ((b = BIO_new(BIO_s_file())) == NULL) {
263         ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
264         return (0);
265     }
266     BIO_set_fp(b, fp, BIO_NOCLOSE);
267     ret = ECPKParameters_print(b, x, off);
268     BIO_free(b);
269     return (ret);
270 }
271
272 int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
273 {
274     BIO *b;
275     int ret;
276
277     if ((b = BIO_new(BIO_s_file())) == NULL) {
278         ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
279         return (0);
280     }
281     BIO_set_fp(b, fp, BIO_NOCLOSE);
282     ret = EC_KEY_print(b, x, off);
283     BIO_free(b);
284     return (ret);
285 }
286 # endif
287
288 int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
289 {
290     unsigned char *buffer = NULL;
291     size_t buf_len = 0, i;
292     int ret = 0, reason = ERR_R_BIO_LIB;
293     BN_CTX *ctx = NULL;
294     const EC_POINT *point = NULL;
295     BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL,
296         *order = NULL, *cofactor = NULL;
297     const unsigned char *seed;
298     size_t seed_len = 0;
299
300     static const char *gen_compressed = "Generator (compressed):";
301     static const char *gen_uncompressed = "Generator (uncompressed):";
302     static const char *gen_hybrid = "Generator (hybrid):";
303
304     if (!x) {
305         reason = ERR_R_PASSED_NULL_PARAMETER;
306         goto err;
307     }
308
309     if (EC_GROUP_get_asn1_flag(x)) {
310         /* the curve parameter are given by an asn1 OID */
311         int nid;
312
313         if (!BIO_indent(bp, off, 128))
314             goto err;
315
316         nid = EC_GROUP_get_curve_name(x);
317         if (nid == 0)
318             goto err;
319
320         if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
321             goto err;
322         if (BIO_printf(bp, "\n") <= 0)
323             goto err;
324     } else {
325         /* explicit parameters */
326         int is_char_two = 0;
327         point_conversion_form_t form;
328         int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
329
330         if (tmp_nid == NID_X9_62_characteristic_two_field)
331             is_char_two = 1;
332
333         if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
334             (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
335             (cofactor = BN_new()) == NULL) {
336             reason = ERR_R_MALLOC_FAILURE;
337             goto err;
338         }
339
340         if (is_char_two) {
341             if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
342                 reason = ERR_R_EC_LIB;
343                 goto err;
344             }
345         } else {                /* prime field */
346
347             if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
348                 reason = ERR_R_EC_LIB;
349                 goto err;
350             }
351         }
352
353         if ((point = EC_GROUP_get0_generator(x)) == NULL) {
354             reason = ERR_R_EC_LIB;
355             goto err;
356         }
357         if (!EC_GROUP_get_order(x, order, NULL) ||
358             !EC_GROUP_get_cofactor(x, cofactor, NULL)) {
359             reason = ERR_R_EC_LIB;
360             goto err;
361         }
362
363         form = EC_GROUP_get_point_conversion_form(x);
364
365         if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
366             reason = ERR_R_EC_LIB;
367             goto err;
368         }
369
370         buf_len = (size_t)BN_num_bytes(p);
371         if (buf_len < (i = (size_t)BN_num_bytes(a)))
372             buf_len = i;
373         if (buf_len < (i = (size_t)BN_num_bytes(b)))
374             buf_len = i;
375         if (buf_len < (i = (size_t)BN_num_bytes(gen)))
376             buf_len = i;
377         if (buf_len < (i = (size_t)BN_num_bytes(order)))
378             buf_len = i;
379         if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
380             buf_len = i;
381
382         if ((seed = EC_GROUP_get0_seed(x)) != NULL)
383             seed_len = EC_GROUP_get_seed_len(x);
384
385         buf_len += 10;
386         if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
387             reason = ERR_R_MALLOC_FAILURE;
388             goto err;
389         }
390
391         if (!BIO_indent(bp, off, 128))
392             goto err;
393
394         /* print the 'short name' of the field type */
395         if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
396             <= 0)
397             goto err;
398
399         if (is_char_two) {
400             /* print the 'short name' of the base type OID */
401             int basis_type = EC_GROUP_get_basis_type(x);
402             if (basis_type == 0)
403                 goto err;
404
405             if (!BIO_indent(bp, off, 128))
406                 goto err;
407
408             if (BIO_printf(bp, "Basis Type: %s\n",
409                            OBJ_nid2sn(basis_type)) <= 0)
410                 goto err;
411
412             /* print the polynomial */
413             if ((p != NULL) && !print(bp, "Polynomial:", p, buffer, off))
414                 goto err;
415         } else {
416             if ((p != NULL) && !print(bp, "Prime:", p, buffer, off))
417                 goto err;
418         }
419         if ((a != NULL) && !print(bp, "A:   ", a, buffer, off))
420             goto err;
421         if ((b != NULL) && !print(bp, "B:   ", b, buffer, off))
422             goto err;
423         if (form == POINT_CONVERSION_COMPRESSED) {
424             if ((gen != NULL) && !print(bp, gen_compressed, gen, buffer, off))
425                 goto err;
426         } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
427             if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
428                                         buffer, off))
429                 goto err;
430         } else {                /* form == POINT_CONVERSION_HYBRID */
431
432             if ((gen != NULL) && !print(bp, gen_hybrid, gen, buffer, off))
433                 goto err;
434         }
435         if ((order != NULL) && !print(bp, "Order: ", order, buffer, off))
436             goto err;
437         if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor,
438                                          buffer, off))
439             goto err;
440         if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
441             goto err;
442     }
443     ret = 1;
444  err:
445     if (!ret)
446         ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
447     if (p)
448         BN_free(p);
449     if (a)
450         BN_free(a);
451     if (b)
452         BN_free(b);
453     if (gen)
454         BN_free(gen);
455     if (order)
456         BN_free(order);
457     if (cofactor)
458         BN_free(cofactor);
459     if (ctx)
460         BN_CTX_free(ctx);
461     if (buffer != NULL)
462         OPENSSL_free(buffer);
463     return (ret);
464 }
465
466 int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
467 {
468     unsigned char *buffer = NULL;
469     size_t buf_len = 0, i;
470     int ret = 0, reason = ERR_R_BIO_LIB;
471     BIGNUM *pub_key = NULL, *order = NULL;
472     BN_CTX *ctx = NULL;
473     const EC_GROUP *group;
474     const EC_POINT *public_key;
475     const BIGNUM *priv_key;
476
477     if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
478         reason = ERR_R_PASSED_NULL_PARAMETER;
479         goto err;
480     }
481
482     public_key = EC_KEY_get0_public_key(x);
483     if ((pub_key = EC_POINT_point2bn(group, public_key,
484                                      EC_KEY_get_conv_form(x), NULL,
485                                      ctx)) == NULL) {
486         reason = ERR_R_EC_LIB;
487         goto err;
488     }
489
490     buf_len = (size_t)BN_num_bytes(pub_key);
491     priv_key = EC_KEY_get0_private_key(x);
492     if (priv_key != NULL) {
493         if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
494             buf_len = i;
495     }
496
497     buf_len += 10;
498     if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
499         reason = ERR_R_MALLOC_FAILURE;
500         goto err;
501     }
502
503     if (priv_key != NULL) {
504         if (!BIO_indent(bp, off, 128))
505             goto err;
506         if ((order = BN_new()) == NULL)
507             goto err;
508         if (!EC_GROUP_get_order(group, order, NULL))
509             goto err;
510         if (BIO_printf(bp, "Private-Key: (%d bit)\n",
511                        BN_num_bits(order)) <= 0)
512             goto err;
513     }
514
515     if ((priv_key != NULL) && !print(bp, "priv:", priv_key, buffer, off))
516         goto err;
517     if ((pub_key != NULL) && !print(bp, "pub: ", pub_key, buffer, off))
518         goto err;
519     if (!ECPKParameters_print(bp, group, off))
520         goto err;
521     ret = 1;
522  err:
523     if (!ret)
524         ECerr(EC_F_EC_KEY_PRINT, reason);
525     if (pub_key)
526         BN_free(pub_key);
527     if (order)
528         BN_free(order);
529     if (ctx)
530         BN_CTX_free(ctx);
531     if (buffer != NULL)
532         OPENSSL_free(buffer);
533     return (ret);
534 }
535 #endif                          /* OPENSSL_NO_EC */
536
537 static int print(BIO *bp, const char *number, const BIGNUM *num,
538                  unsigned char *buf, int off)
539 {
540     int n, i;
541     const char *neg;
542
543     if (num == NULL)
544         return (1);
545     neg = (BN_is_negative(num)) ? "-" : "";
546     if (!BIO_indent(bp, off, 128))
547         return 0;
548     if (BN_is_zero(num)) {
549         if (BIO_printf(bp, "%s 0\n", number) <= 0)
550             return 0;
551         return 1;
552     }
553
554     if (BN_num_bytes(num) <= BN_BYTES) {
555         if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
556                        (unsigned long)num->d[0], neg,
557                        (unsigned long)num->d[0])
558             <= 0)
559             return (0);
560     } else {
561         buf[0] = 0;
562         if (BIO_printf(bp, "%s%s", number,
563                        (neg[0] == '-') ? " (Negative)" : "") <= 0)
564             return (0);
565         n = BN_bn2bin(num, &buf[1]);
566
567         if (buf[1] & 0x80)
568             n++;
569         else
570             buf++;
571
572         for (i = 0; i < n; i++) {
573             if ((i % 15) == 0) {
574                 if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128))
575                     return 0;
576             }
577             if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":")
578                 <= 0)
579                 return (0);
580         }
581         if (BIO_write(bp, "\n", 1) <= 0)
582             return (0);
583     }
584     return (1);
585 }
586
587 #ifndef OPENSSL_NO_EC
588 static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
589                      size_t len, int off)
590 {
591     size_t i;
592     char str[128];
593
594     if (buf == NULL)
595         return 1;
596     if (off) {
597         if (off > 128)
598             off = 128;
599         memset(str, ' ', off);
600         if (BIO_write(fp, str, off) <= 0)
601             return 0;
602     }
603
604     if (BIO_printf(fp, "%s", name) <= 0)
605         return 0;
606
607     for (i = 0; i < len; i++) {
608         if ((i % 15) == 0) {
609             str[0] = '\n';
610             memset(&(str[1]), ' ', off + 4);
611             if (BIO_write(fp, str, off + 1 + 4) <= 0)
612                 return 0;
613         }
614         if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <=
615             0)
616             return 0;
617     }
618     if (BIO_write(fp, "\n", 1) <= 0)
619         return 0;
620
621     return 1;
622 }
623 #endif
624
625 #ifndef OPENSSL_NO_DH
626 # ifndef OPENSSL_NO_FP_API
627 int DHparams_print_fp(FILE *fp, const DH *x)
628 {
629     BIO *b;
630     int ret;
631
632     if ((b = BIO_new(BIO_s_file())) == NULL) {
633         DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB);
634         return (0);
635     }
636     BIO_set_fp(b, fp, BIO_NOCLOSE);
637     ret = DHparams_print(b, x);
638     BIO_free(b);
639     return (ret);
640 }
641 # endif
642
643 int DHparams_print(BIO *bp, const DH *x)
644 {
645     unsigned char *m = NULL;
646     int reason = ERR_R_BUF_LIB, ret = 0;
647     size_t buf_len = 0, i;
648
649     if (x->p)
650         buf_len = (size_t)BN_num_bytes(x->p);
651     else {
652         reason = ERR_R_PASSED_NULL_PARAMETER;
653         goto err;
654     }
655     if (x->g)
656         if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
657             buf_len = i;
658     m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
659     if (m == NULL) {
660         reason = ERR_R_MALLOC_FAILURE;
661         goto err;
662     }
663
664     if (BIO_printf(bp, "Diffie-Hellman-Parameters: (%d bit)\n",
665                    BN_num_bits(x->p)) <= 0)
666         goto err;
667     if (!print(bp, "prime:", x->p, m, 4))
668         goto err;
669     if (!print(bp, "generator:", x->g, m, 4))
670         goto err;
671     if (x->length != 0) {
672         if (BIO_printf(bp, "    recommended-private-length: %d bits\n",
673                        (int)x->length) <= 0)
674             goto err;
675     }
676     ret = 1;
677     if (0) {
678  err:
679         DHerr(DH_F_DHPARAMS_PRINT, reason);
680     }
681     if (m != NULL)
682         OPENSSL_free(m);
683     return (ret);
684 }
685 #endif
686
687 #ifndef OPENSSL_NO_DSA
688 # ifndef OPENSSL_NO_FP_API
689 int DSAparams_print_fp(FILE *fp, const DSA *x)
690 {
691     BIO *b;
692     int ret;
693
694     if ((b = BIO_new(BIO_s_file())) == NULL) {
695         DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB);
696         return (0);
697     }
698     BIO_set_fp(b, fp, BIO_NOCLOSE);
699     ret = DSAparams_print(b, x);
700     BIO_free(b);
701     return (ret);
702 }
703 # endif
704
705 int DSAparams_print(BIO *bp, const DSA *x)
706 {
707     unsigned char *m = NULL;
708     int ret = 0;
709     size_t buf_len = 0, i;
710
711     if (x->p)
712         buf_len = (size_t)BN_num_bytes(x->p);
713     else {
714         DSAerr(DSA_F_DSAPARAMS_PRINT, DSA_R_MISSING_PARAMETERS);
715         goto err;
716     }
717     if (x->q)
718         if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
719             buf_len = i;
720     if (x->g)
721         if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
722             buf_len = i;
723     m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
724     if (m == NULL) {
725         DSAerr(DSA_F_DSAPARAMS_PRINT, ERR_R_MALLOC_FAILURE);
726         goto err;
727     }
728
729     if (BIO_printf(bp, "DSA-Parameters: (%d bit)\n", BN_num_bits(x->p)) <= 0)
730         goto err;
731     if (!print(bp, "p:", x->p, m, 4))
732         goto err;
733     if ((x->q != NULL) && !print(bp, "q:", x->q, m, 4))
734         goto err;
735     if ((x->g != NULL) && !print(bp, "g:", x->g, m, 4))
736         goto err;
737     ret = 1;
738  err:
739     if (m != NULL)
740         OPENSSL_free(m);
741     return (ret);
742 }
743
744 #endif                          /* !OPENSSL_NO_DSA */
745
746 #ifndef OPENSSL_NO_EC
747 # ifndef OPENSSL_NO_FP_API
748 int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
749 {
750     BIO *b;
751     int ret;
752
753     if ((b = BIO_new(BIO_s_file())) == NULL) {
754         ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
755         return (0);
756     }
757     BIO_set_fp(b, fp, BIO_NOCLOSE);
758     ret = ECParameters_print(b, x);
759     BIO_free(b);
760     return (ret);
761 }
762 # endif
763
764 int ECParameters_print(BIO *bp, const EC_KEY *x)
765 {
766     int reason = ERR_R_EC_LIB, ret = 0;
767     BIGNUM *order = NULL;
768     const EC_GROUP *group;
769
770     if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
771         reason = ERR_R_PASSED_NULL_PARAMETER;;
772         goto err;
773     }
774
775     if ((order = BN_new()) == NULL) {
776         reason = ERR_R_MALLOC_FAILURE;
777         goto err;
778     }
779
780     if (!EC_GROUP_get_order(group, order, NULL)) {
781         reason = ERR_R_EC_LIB;
782         goto err;
783     }
784
785     if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n",
786                    BN_num_bits(order)) <= 0)
787         goto err;
788     if (!ECPKParameters_print(bp, group, 4))
789         goto err;
790     ret = 1;
791  err:
792     if (order)
793         BN_free(order);
794     ECerr(EC_F_ECPARAMETERS_PRINT, reason);
795     return (ret);
796 }
797
798 #endif