Some error code cleanups (SSL lib. used SSL_R_... codes reserved for alerts)
[openssl.git] / 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                 {
97                 RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
98                 return(0);
99                 }
100         BIO_set_fp(b,fp,BIO_NOCLOSE);
101         ret=RSA_print(b,x,off);
102         BIO_free(b);
103         return(ret);
104         }
105 #endif
106
107 int RSA_print(BIO *bp, const RSA *x, int off)
108         {
109         char str[128];
110         const char *s;
111         unsigned char *m=NULL;
112         int ret=0;
113         size_t buf_len=0, i;
114
115         if (x->n)
116                 buf_len = (size_t)BN_num_bytes(x->n);
117         if (x->e)
118                 if (buf_len < (i = (size_t)BN_num_bytes(x->e)))
119                         buf_len = i;
120         if (x->d)
121                 if (buf_len < (i = (size_t)BN_num_bytes(x->d)))
122                         buf_len = i;
123         if (x->p)
124                 if (buf_len < (i = (size_t)BN_num_bytes(x->p)))
125                         buf_len = i;
126         if (x->q)
127                 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
128                         buf_len = i;
129         if (x->dmp1)
130                 if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1)))
131                         buf_len = i;
132         if (x->dmq1)
133                 if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1)))
134                         buf_len = i;
135         if (x->iqmp)
136                 if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp)))
137                         buf_len = i;
138
139         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
140         if (m == NULL)
141                 {
142                 RSAerr(RSA_F_RSA_PRINT,ERR_R_MALLOC_FAILURE);
143                 goto err;
144                 }
145
146         if (x->d != NULL)
147                 {
148                 if(!BIO_indent(bp,off,128))
149                    goto err;
150                 if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->n))
151                         <= 0) goto err;
152                 }
153
154         if (x->d == NULL)
155                 BIO_snprintf(str,sizeof str,"Modulus (%d bit):",BN_num_bits(x->n));
156         else
157                 BUF_strlcpy(str,"modulus:",sizeof str);
158         if (!print(bp,str,x->n,m,off)) goto err;
159         s=(x->d == NULL)?"Exponent:":"publicExponent:";
160         if (!print(bp,s,x->e,m,off)) goto err;
161         if (!print(bp,"privateExponent:",x->d,m,off)) goto err;
162         if (!print(bp,"prime1:",x->p,m,off)) goto err;
163         if (!print(bp,"prime2:",x->q,m,off)) goto err;
164         if (!print(bp,"exponent1:",x->dmp1,m,off)) goto err;
165         if (!print(bp,"exponent2:",x->dmq1,m,off)) goto err;
166         if (!print(bp,"coefficient:",x->iqmp,m,off)) goto err;
167         ret=1;
168 err:
169         if (m != NULL) OPENSSL_free(m);
170         return(ret);
171         }
172 #endif /* OPENSSL_NO_RSA */
173
174 #ifndef OPENSSL_NO_DSA
175 #ifndef OPENSSL_NO_FP_API
176 int DSA_print_fp(FILE *fp, const DSA *x, int off)
177         {
178         BIO *b;
179         int ret;
180
181         if ((b=BIO_new(BIO_s_file())) == NULL)
182                 {
183                 DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
184                 return(0);
185                 }
186         BIO_set_fp(b,fp,BIO_NOCLOSE);
187         ret=DSA_print(b,x,off);
188         BIO_free(b);
189         return(ret);
190         }
191 #endif
192
193 int DSA_print(BIO *bp, const DSA *x, int off)
194         {
195         unsigned char *m=NULL;
196         int ret=0;
197         size_t buf_len=0,i;
198
199         if (x->p)
200                 buf_len = (size_t)BN_num_bytes(x->p);
201         else
202                 {
203                 DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS);
204                 goto err;
205                 }
206         if (x->q)
207                 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
208                         buf_len = i;
209         if (x->g)
210                 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
211                         buf_len = i;
212         if (x->priv_key)
213                 if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key)))
214                         buf_len = i;
215         if (x->pub_key)
216                 if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key)))
217                         buf_len = i;
218
219         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
220         if (m == NULL)
221                 {
222                 DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE);
223                 goto err;
224                 }
225
226         if (x->priv_key != NULL)
227                 {
228                 if(!BIO_indent(bp,off,128))
229                    goto err;
230                 if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->p))
231                         <= 0) goto err;
232                 }
233
234         if ((x->priv_key != NULL) && !print(bp,"priv:",x->priv_key,m,off))
235                 goto err;
236         if ((x->pub_key  != NULL) && !print(bp,"pub: ",x->pub_key,m,off))
237                 goto err;
238         if ((x->p != NULL) && !print(bp,"P:   ",x->p,m,off)) goto err;
239         if ((x->q != NULL) && !print(bp,"Q:   ",x->q,m,off)) goto err;
240         if ((x->g != NULL) && !print(bp,"G:   ",x->g,m,off)) goto err;
241         ret=1;
242 err:
243         if (m != NULL) OPENSSL_free(m);
244         return(ret);
245         }
246 #endif /* !OPENSSL_NO_DSA */
247
248 #ifndef OPENSSL_NO_EC
249 #ifndef OPENSSL_NO_FP_API
250 int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
251         {
252         BIO *b;
253         int ret;
254
255         if ((b=BIO_new(BIO_s_file())) == NULL)
256                 {
257                 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
258                 return(0);
259                 }
260         BIO_set_fp(b, fp, BIO_NOCLOSE);
261         ret = ECPKParameters_print(b, x, off);
262         BIO_free(b);
263         return(ret);
264         }
265
266 int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
267         {
268         BIO *b;
269         int ret;
270  
271         if ((b=BIO_new(BIO_s_file())) == NULL)
272                 {
273                 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
274                 return(0);
275                 }
276         BIO_set_fp(b, fp, BIO_NOCLOSE);
277         ret = EC_KEY_print(b, x, off);
278         BIO_free(b);
279         return(ret);
280         }
281 #endif
282
283 int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
284         {
285         unsigned char *buffer=NULL;
286         size_t  buf_len=0, i;
287         int     ret=0, reason=ERR_R_BIO_LIB;
288         BN_CTX  *ctx=NULL;
289         const EC_POINT *point=NULL;
290         BIGNUM  *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
291                 *order=NULL, *cofactor=NULL;
292         const unsigned char *seed;
293         size_t  seed_len=0;
294         
295         static const char *gen_compressed = "Generator (compressed):";
296         static const char *gen_uncompressed = "Generator (uncompressed):";
297         static const char *gen_hybrid = "Generator (hybrid):";
298  
299         if (!x)
300                 {
301                 reason = ERR_R_PASSED_NULL_PARAMETER;
302                 goto err;
303                 }
304
305         if (EC_GROUP_get_asn1_flag(x))
306                 {
307                 /* the curve parameter are given by an asn1 OID */
308                 int nid;
309
310                 if (!BIO_indent(bp, off, 128))
311                         goto err;
312
313                 nid = EC_GROUP_get_curve_name(x);
314                 if (nid == 0)
315                         goto err;
316
317                 if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
318                         goto err;
319                 if (BIO_printf(bp, "\n") <= 0)
320                         goto err;
321                 }
322         else
323                 {
324                 /* explicit parameters */
325                 int is_char_two = 0;
326                 point_conversion_form_t form;
327                 int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
328
329                 if (tmp_nid == NID_X9_62_characteristic_two_field)
330                         is_char_two = 1;
331
332                 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
333                         (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
334                         (cofactor = BN_new()) == NULL)
335                         {
336                         reason = ERR_R_MALLOC_FAILURE;
337                         goto err;
338                         }
339
340                 if (is_char_two)
341                         {
342                         if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
343                                 {
344                                 reason = ERR_R_EC_LIB;
345                                 goto err;
346                                 }
347                         }
348                 else /* prime field */
349                         {
350                         if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
351                                 {
352                                 reason = ERR_R_EC_LIB;
353                                 goto err;
354                                 }
355                         }
356
357                 if ((point = EC_GROUP_get0_generator(x)) == NULL)
358                         {
359                         reason = ERR_R_EC_LIB;
360                         goto err;
361                         }
362                 if (!EC_GROUP_get_order(x, order, NULL) || 
363                         !EC_GROUP_get_cofactor(x, cofactor, NULL))
364                         {
365                         reason = ERR_R_EC_LIB;
366                         goto err;
367                         }
368                 
369                 form = EC_GROUP_get_point_conversion_form(x);
370
371                 if ((gen = EC_POINT_point2bn(x, point, 
372                                 form, NULL, ctx)) == NULL)
373                         {
374                         reason = ERR_R_EC_LIB;
375                         goto err;
376                         }
377
378                 buf_len = (size_t)BN_num_bytes(p);
379                 if (buf_len < (i = (size_t)BN_num_bytes(a)))
380                         buf_len = i;
381                 if (buf_len < (i = (size_t)BN_num_bytes(b)))
382                         buf_len = i;
383                 if (buf_len < (i = (size_t)BN_num_bytes(gen)))
384                         buf_len = i;
385                 if (buf_len < (i = (size_t)BN_num_bytes(order)))
386                         buf_len = i;
387                 if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 
388                         buf_len = i;
389
390                 if ((seed = EC_GROUP_get0_seed(x)) != NULL)
391                         seed_len = EC_GROUP_get_seed_len(x);
392
393                 buf_len += 10;
394                 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
395                         {
396                         reason = ERR_R_MALLOC_FAILURE;
397                         goto err;
398                         }
399
400                 if (!BIO_indent(bp, off, 128))
401                         goto err;
402
403                 /* print the 'short name' of the field type */
404                 if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
405                         <= 0)
406                         goto err;  
407
408                 if (is_char_two)
409                         {
410                         /* print the 'short name' of the base type OID */
411                         int basis_type = EC_GROUP_get_basis_type(x);
412                         if (basis_type == 0)
413                                 goto err;
414
415                         if (!BIO_indent(bp, off, 128))
416                                 goto err;
417
418                         if (BIO_printf(bp, "Basis Type: %s\n", 
419                                 OBJ_nid2sn(basis_type)) <= 0)
420                                 goto err;
421
422                         /* print the polynomial */
423                         if ((p != NULL) && !print(bp, "Polynomial:", p, buffer,
424                                 off))
425                                 goto err;
426                         }
427                 else
428                         {
429                         if ((p != NULL) && !print(bp, "Prime:", p, buffer,off))
430                                 goto err;
431                         }
432                 if ((a != NULL) && !print(bp, "A:   ", a, buffer, off)) 
433                         goto err;
434                 if ((b != NULL) && !print(bp, "B:   ", b, buffer, off))
435                         goto err;
436                 if (form == POINT_CONVERSION_COMPRESSED)
437                         {
438                         if ((gen != NULL) && !print(bp, gen_compressed, gen,
439                                 buffer, off))
440                                 goto err;
441                         }
442                 else if (form == POINT_CONVERSION_UNCOMPRESSED)
443                         {
444                         if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
445                                 buffer, off))
446                                 goto err;
447                         }
448                 else /* form == POINT_CONVERSION_HYBRID */
449                         {
450                         if ((gen != NULL) && !print(bp, gen_hybrid, gen,
451                                 buffer, off))
452                                 goto err;
453                         }
454                 if ((order != NULL) && !print(bp, "Order: ", order, 
455                         buffer, off)) goto err;
456                 if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor, 
457                         buffer, off)) goto err;
458                 if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
459                         goto err;
460                 }
461         ret=1;
462 err:
463         if (!ret)
464                 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
465         if (p) 
466                 BN_free(p);
467         if (a) 
468                 BN_free(a);
469         if (b)
470                 BN_free(b);
471         if (gen)
472                 BN_free(gen);
473         if (order)
474                 BN_free(order);
475         if (cofactor)
476                 BN_free(cofactor);
477         if (ctx)
478                 BN_CTX_free(ctx);
479         if (buffer != NULL) 
480                 OPENSSL_free(buffer);
481         return(ret);    
482         }
483
484 int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
485         {
486         unsigned char *buffer=NULL;
487         size_t  buf_len=0, i;
488         int     ret=0, reason=ERR_R_BIO_LIB;
489         BIGNUM  *pub_key=NULL, *order=NULL;
490         BN_CTX  *ctx=NULL;
491         const EC_GROUP *group;
492         const EC_POINT *public_key;
493         const BIGNUM *priv_key;
494  
495         if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
496                 {
497                 reason = ERR_R_PASSED_NULL_PARAMETER;
498                 goto err;
499                 }
500
501         public_key = EC_KEY_get0_public_key(x);
502         if ((pub_key = EC_POINT_point2bn(group, public_key,
503                 EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
504                 {
505                 reason = ERR_R_EC_LIB;
506                 goto err;
507                 }
508
509         buf_len = (size_t)BN_num_bytes(pub_key);
510         priv_key = EC_KEY_get0_private_key(x);
511         if (priv_key != NULL)
512                 {
513                 if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
514                         buf_len = i;
515                 }
516
517         buf_len += 10;
518         if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
519                 {
520                 reason = ERR_R_MALLOC_FAILURE;
521                 goto err;
522                 }
523
524         if (priv_key != NULL)
525                 {
526                 if (!BIO_indent(bp, off, 128))
527                         goto err;
528                 if ((order = BN_new()) == NULL)
529                         goto err;
530                 if (!EC_GROUP_get_order(group, order, NULL))
531                         goto err;
532                 if (BIO_printf(bp, "Private-Key: (%d bit)\n", 
533                         BN_num_bits(order)) <= 0) goto err;
534                 }
535   
536         if ((priv_key != NULL) && !print(bp, "priv:", priv_key, 
537                 buffer, off))
538                 goto err;
539         if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
540                 buffer, off))
541                 goto err;
542         if (!ECPKParameters_print(bp, group, off))
543                 goto err;
544         ret=1;
545 err:
546         if (!ret)
547                 ECerr(EC_F_EC_KEY_PRINT, reason);
548         if (pub_key) 
549                 BN_free(pub_key);
550         if (order)
551                 BN_free(order);
552         if (ctx)
553                 BN_CTX_free(ctx);
554         if (buffer != NULL)
555                 OPENSSL_free(buffer);
556         return(ret);
557         }
558 #endif /* OPENSSL_NO_EC */
559
560 static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf,
561              int off)
562         {
563         int n,i;
564         const char *neg;
565
566         if (num == NULL) return(1);
567         neg = (BN_is_negative(num))?"-":"";
568         if(!BIO_indent(bp,off,128))
569                 return 0;
570         if (BN_is_zero(num))
571                 {
572                 if (BIO_printf(bp, "%s 0\n", number) <= 0)
573                         return 0;
574                 return 1;
575                 }
576
577         if (BN_num_bytes(num) <= BN_BYTES)
578                 {
579                 if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
580                         (unsigned long)num->d[0],neg,(unsigned long)num->d[0])
581                         <= 0) return(0);
582                 }
583         else
584                 {
585                 buf[0]=0;
586                 if (BIO_printf(bp,"%s%s",number,
587                         (neg[0] == '-')?" (Negative)":"") <= 0)
588                         return(0);
589                 n=BN_bn2bin(num,&buf[1]);
590         
591                 if (buf[1] & 0x80)
592                         n++;
593                 else    buf++;
594
595                 for (i=0; i<n; i++)
596                         {
597                         if ((i%15) == 0)
598                                 {
599                                 if(BIO_puts(bp,"\n") <= 0
600                                    || !BIO_indent(bp,off+4,128))
601                                     return 0;
602                                 }
603                         if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
604                                 <= 0) return(0);
605                         }
606                 if (BIO_write(bp,"\n",1) <= 0) return(0);
607                 }
608         return(1);
609         }
610
611 #ifndef OPENSSL_NO_EC
612 static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
613                 size_t len, int off)
614         {
615         size_t i;
616         char str[128];
617
618         if (buf == NULL)
619                 return 1;
620         if (off)
621                 {
622                 if (off > 128)
623                         off=128;
624                 memset(str,' ',off);
625                 if (BIO_write(fp, str, off) <= 0)
626                         return 0;
627                 }
628
629         if (BIO_printf(fp,"%s", name) <= 0)
630                 return 0;
631
632         for (i=0; i<len; i++)
633                 {
634                 if ((i%15) == 0)
635                         {
636                         str[0]='\n';
637                         memset(&(str[1]),' ',off+4);
638                         if (BIO_write(fp, str, off+1+4) <= 0)
639                                 return 0;
640                         }
641                 if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
642                         return 0;
643                 }
644         if (BIO_write(fp,"\n",1) <= 0)
645                 return 0;
646
647         return 1;
648         }
649 #endif
650
651 #ifndef OPENSSL_NO_DH
652 #ifndef OPENSSL_NO_FP_API
653 int DHparams_print_fp(FILE *fp, const DH *x)
654         {
655         BIO *b;
656         int ret;
657
658         if ((b=BIO_new(BIO_s_file())) == NULL)
659                 {
660                 DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
661                 return(0);
662                 }
663         BIO_set_fp(b,fp,BIO_NOCLOSE);
664         ret=DHparams_print(b, x);
665         BIO_free(b);
666         return(ret);
667         }
668 #endif
669
670 int DHparams_print(BIO *bp, const DH *x)
671         {
672         unsigned char *m=NULL;
673         int reason=ERR_R_BUF_LIB,ret=0;
674         size_t buf_len=0, i;
675
676         if (x->p)
677                 buf_len = (size_t)BN_num_bytes(x->p);
678         else
679                 {
680                 reason = ERR_R_PASSED_NULL_PARAMETER;
681                 goto err;
682                 }
683         if (x->g)
684                 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
685                         buf_len = i;
686         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
687         if (m == NULL)
688                 {
689                 reason=ERR_R_MALLOC_FAILURE;
690                 goto err;
691                 }
692
693         if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
694                 BN_num_bits(x->p)) <= 0)
695                 goto err;
696         if (!print(bp,"prime:",x->p,m,4)) goto err;
697         if (!print(bp,"generator:",x->g,m,4)) goto err;
698         if (x->length != 0)
699                 {
700                 if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
701                         (int)x->length) <= 0) goto err;
702                 }
703         ret=1;
704         if (0)
705                 {
706 err:
707                 DHerr(DH_F_DHPARAMS_PRINT,reason);
708                 }
709         if (m != NULL) OPENSSL_free(m);
710         return(ret);
711         }
712 #endif
713
714 #ifndef OPENSSL_NO_DSA
715 #ifndef OPENSSL_NO_FP_API
716 int DSAparams_print_fp(FILE *fp, const DSA *x)
717         {
718         BIO *b;
719         int ret;
720
721         if ((b=BIO_new(BIO_s_file())) == NULL)
722                 {
723                 DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
724                 return(0);
725                 }
726         BIO_set_fp(b,fp,BIO_NOCLOSE);
727         ret=DSAparams_print(b, x);
728         BIO_free(b);
729         return(ret);
730         }
731 #endif
732
733 int DSAparams_print(BIO *bp, const DSA *x)
734         {
735         unsigned char *m=NULL;
736         int ret=0;
737         size_t buf_len=0,i;
738
739         if (x->p)
740                 buf_len = (size_t)BN_num_bytes(x->p);
741         else
742                 {
743                 DSAerr(DSA_F_DSAPARAMS_PRINT,DSA_R_MISSING_PARAMETERS);
744                 goto err;
745                 }
746         if (x->q)
747                 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
748                         buf_len = i;
749         if (x->g)
750                 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
751                         buf_len = i;
752         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
753         if (m == NULL)
754                 {
755                 DSAerr(DSA_F_DSAPARAMS_PRINT,ERR_R_MALLOC_FAILURE);
756                 goto err;
757                 }
758
759         if (BIO_printf(bp,"DSA-Parameters: (%d bit)\n",
760                 BN_num_bits(x->p)) <= 0)
761                 goto err;
762         if (!print(bp,"p:",x->p,m,4)) goto err;
763         if (!print(bp,"q:",x->q,m,4)) goto err;
764         if (!print(bp,"g:",x->g,m,4)) goto err;
765         ret=1;
766 err:
767         if (m != NULL) OPENSSL_free(m);
768         return(ret);
769         }
770
771 #endif /* !OPENSSL_NO_DSA */
772
773 #ifndef OPENSSL_NO_EC
774 #ifndef OPENSSL_NO_FP_API
775 int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
776         {
777         BIO *b;
778         int ret;
779  
780         if ((b=BIO_new(BIO_s_file())) == NULL)
781                 {
782                 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
783                 return(0);
784                 }
785         BIO_set_fp(b, fp, BIO_NOCLOSE);
786         ret = ECParameters_print(b, x);
787         BIO_free(b);
788         return(ret);
789         }
790 #endif
791
792 int ECParameters_print(BIO *bp, const EC_KEY *x)
793         {
794         int     reason=ERR_R_EC_LIB, ret=0;
795         BIGNUM  *order=NULL;
796         const EC_GROUP *group;
797  
798         if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
799                 {
800                 reason = ERR_R_PASSED_NULL_PARAMETER;;
801                 goto err;
802                 }
803
804         if ((order = BN_new()) == NULL)
805                 {
806                 reason = ERR_R_MALLOC_FAILURE;
807                 goto err;
808                 }
809
810         if (!EC_GROUP_get_order(group, order, NULL))
811                 {
812                 reason = ERR_R_EC_LIB;
813                 goto err;
814                 }
815  
816         if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n", 
817                 BN_num_bits(order)) <= 0)
818                 goto err;
819         if (!ECPKParameters_print(bp, group, 4))
820                 goto err;
821         ret=1;
822 err:
823         if (order)
824                 BN_free(order);
825         ECerr(EC_F_ECPARAMETERS_PRINT, reason);
826         return(ret);
827         }
828   
829 #endif