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