fb01e38d79db701016a5b5263e93a19c12a241f5
[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_EC
74 #include <openssl/ec.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
261 int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
262         {
263         BIO *b;
264         int ret;
265  
266         if ((b=BIO_new(BIO_s_file())) == NULL)
267                 {
268                 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
269                 return(0);
270                 }
271         BIO_set_fp(b, fp, BIO_NOCLOSE);
272         ret = EC_KEY_print(b, x, off);
273         BIO_free(b);
274         return(ret);
275         }
276 #endif
277
278 int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
279         {
280         char str[128];
281         unsigned char *buffer=NULL;
282         size_t  buf_len=0, i;
283         int     ret=0, reason=ERR_R_BIO_LIB;
284         BN_CTX  *ctx=NULL;
285         EC_POINT *point=NULL;
286         BIGNUM  *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
287                 *order=NULL, *cofactor=NULL, *seed=NULL;
288         
289         static const char *gen_compressed = "Generator (compressed):";
290         static const char *gen_uncompressed = "Generator (uncompressed):";
291         static const char *gen_hybrid = "Generator (hybrid):";
292  
293         if (!x)
294                 {
295                 reason = ERR_R_PASSED_NULL_PARAMETER;
296                 goto err;
297                 }
298
299         if (EC_GROUP_get_asn1_flag(x))
300                 {
301                 /* the curve parameter are given by an asn1 OID */
302                 int nid;
303
304                 if (off)
305                         {
306                         if (off > 128)
307                                 off=128;
308                         memset(str, ' ', off);
309                         if (BIO_write(bp, str, off) <= 0)
310                                 goto err;
311                         }
312
313                 nid = EC_GROUP_get_nid(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                 /* TODO */
326                 point_conversion_form_t form;
327
328                 if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
329                         (b = BN_new()) == NULL || (order = BN_new()) == NULL ||
330                         (cofactor = BN_new()) == NULL)
331                         {
332                         reason = ERR_R_MALLOC_FAILURE;
333                         goto err;
334                         }
335
336                 if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
337                         {
338                         reason = ERR_R_EC_LIB;
339                         goto err;
340                         }
341
342                 if ((point = EC_GROUP_get0_generator(x)) == NULL)
343                         {
344                         reason = ERR_R_EC_LIB;
345                         goto err;
346                         }
347                 if (!EC_GROUP_get_order(x, order, NULL) || 
348                         !EC_GROUP_get_cofactor(x, cofactor, NULL))
349                         {
350                         reason = ERR_R_EC_LIB;
351                         goto err;
352                         }
353                 
354                 form = EC_GROUP_get_point_conversion_form(x);
355
356                 if ((gen = EC_POINT_point2bn(x, point, 
357                                 form, NULL, ctx)) == NULL)
358                         {
359                         reason = ERR_R_EC_LIB;
360                         goto err;
361                         }
362
363                 buf_len = (size_t)BN_num_bytes(p);
364                 if (buf_len < (i = (size_t)BN_num_bytes(a)))
365                         buf_len = i;
366                 if (buf_len < (i = (size_t)BN_num_bytes(b)))
367                         buf_len = i;
368                 if (buf_len < (i = (size_t)BN_num_bytes(gen)))
369                         buf_len = i;
370                 if (buf_len < (i = (size_t)BN_num_bytes(order)))
371                         buf_len = i;
372                 if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) 
373                         buf_len = i;
374
375                 if (EC_GROUP_get0_seed(x))
376                         {
377                         seed = BN_bin2bn(EC_GROUP_get0_seed(x),
378                                 EC_GROUP_get_seed_len(x), NULL);
379                         if (seed == NULL)
380                                 {
381                                 reason = ERR_R_BN_LIB;
382                                 goto err;
383                                 }
384                         if (buf_len < (i = (size_t)BN_num_bytes(seed))) 
385                                 buf_len = i;
386                         }
387
388                 buf_len += 10;
389                 if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
390                         {
391                         reason = ERR_R_MALLOC_FAILURE;
392                         goto err;
393                         }
394                 if (off)
395                         {
396                         if (off > 128) off=128;
397                         memset(str,' ',off);
398                         }
399   
400                 if ((p != NULL) && !print(bp, "P:   ", p, buffer, off)) 
401                         goto err;
402                 if ((a != NULL) && !print(bp, "A:   ", a, buffer, off)) 
403                         goto err;
404                 if ((b != NULL) && !print(bp, "B:   ", b, buffer, off))
405                         goto err;
406                 if (form == POINT_CONVERSION_COMPRESSED)
407                         {
408                         if ((gen != NULL) && !print(bp, gen_compressed, gen,
409                                 buffer, off))
410                                 goto err;
411                         }
412                 else if (form == POINT_CONVERSION_UNCOMPRESSED)
413                         {
414                         if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
415                                 buffer, off))
416                                 goto err;
417                         }
418                 else /* form == POINT_CONVERSION_HYBRID */
419                         {
420                         if ((gen != NULL) && !print(bp, gen_hybrid, gen,
421                                 buffer, off))
422                                 goto err;
423                         }
424                 if ((order != NULL) && !print(bp, "Order: ", order, 
425                         buffer, off)) goto err;
426                 if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor, 
427                         buffer, off)) goto err;
428                 if ((seed != NULL) && !print(bp, "Seed:", seed, 
429                         buffer, off)) goto err;
430                 }
431         ret=1;
432 err:
433         if (!ret)
434                 ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
435         if (p) 
436                 BN_free(p);
437         if (a) 
438                 BN_free(a);
439         if (b)
440                 BN_free(b);
441         if (gen)
442                 BN_free(gen);
443         if (order)
444                 BN_free(order);
445         if (cofactor)
446                 BN_free(cofactor);
447         if (seed) 
448                 BN_free(seed);
449         if (ctx)
450                 BN_CTX_free(ctx);
451         if (buffer != NULL) 
452                 OPENSSL_free(buffer);
453         return(ret);    
454         }
455
456 int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
457         {
458         char str[128];
459         unsigned char *buffer=NULL;
460         size_t  buf_len=0, i;
461         int     ret=0, reason=ERR_R_BIO_LIB;
462         BIGNUM  *pub_key=NULL;
463         BN_CTX  *ctx=NULL;
464  
465         if (!x || !x->group)
466                 {
467                 reason = ERR_R_PASSED_NULL_PARAMETER;
468                 goto err;
469                 }
470
471         if ((pub_key = EC_POINT_point2bn(x->group, x->pub_key,
472                 x->conv_form, NULL, ctx)) == NULL)
473                 {
474                 reason = ERR_R_EC_LIB;
475                 goto err;
476                 }
477
478         buf_len = (size_t)BN_num_bytes(pub_key);
479         if (x->priv_key)
480                 {
481                 if ((i = (size_t)BN_num_bytes(x->priv_key)) > buf_len)
482                         buf_len = i;
483                 }
484
485         buf_len += 10;
486         if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
487                 {
488                 reason = ERR_R_MALLOC_FAILURE;
489                 goto err;
490                 }
491         if (off)
492                 {
493                 if (off > 128) off=128;
494                 memset(str,' ',off);
495                 }
496         if (x->priv_key != NULL)
497                 {
498                 if (off && (BIO_write(bp, str, off) <= 0)) goto err;
499                 if (BIO_printf(bp, "Private-Key: (%d bit)\n", 
500                         BN_num_bits(x->priv_key)) <= 0) goto err;
501                 }
502   
503         if ((x->priv_key != NULL) && !print(bp, "priv:", x->priv_key, 
504                 buffer, off))
505                 goto err;
506         if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
507                 buffer, off))
508                 goto err;
509         if (!ECPKParameters_print(bp, x->group, off))
510                 goto err;
511         ret=1;
512 err:
513         if (!ret)
514                 ECerr(EC_F_EC_KEY_PRINT, reason);
515         if (pub_key) 
516                 BN_free(pub_key);
517         if (ctx)
518                 BN_CTX_free(ctx);
519         if (buffer != NULL)
520                 OPENSSL_free(buffer);
521         return(ret);
522         }
523 #endif /* OPENSSL_NO_EC */
524
525 static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf,
526              int off)
527         {
528         int n,i;
529         char str[128];
530         const char *neg;
531
532         if (num == NULL) return(1);
533         neg=(num->neg)?"-":"";
534         if (off)
535                 {
536                 if (off > 128) off=128;
537                 memset(str,' ',off);
538                 if (BIO_write(bp,str,off) <= 0) return(0);
539                 }
540
541         if (BN_num_bytes(num) <= BN_BYTES)
542                 {
543                 if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
544                         (unsigned long)num->d[0],neg,(unsigned long)num->d[0])
545                         <= 0) return(0);
546                 }
547         else
548                 {
549                 buf[0]=0;
550                 if (BIO_printf(bp,"%s%s",number,
551                         (neg[0] == '-')?" (Negative)":"") <= 0)
552                         return(0);
553                 n=BN_bn2bin(num,&buf[1]);
554         
555                 if (buf[1] & 0x80)
556                         n++;
557                 else    buf++;
558
559                 for (i=0; i<n; i++)
560                         {
561                         if ((i%15) == 0)
562                                 {
563                                 str[0]='\n';
564                                 memset(&(str[1]),' ',off+4);
565                                 if (BIO_write(bp,str,off+1+4) <= 0) return(0);
566                                 }
567                         if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
568                                 <= 0) return(0);
569                         }
570                 if (BIO_write(bp,"\n",1) <= 0) return(0);
571                 }
572         return(1);
573         }
574
575 #ifndef OPENSSL_NO_DH
576 #ifndef OPENSSL_NO_FP_API
577 int DHparams_print_fp(FILE *fp, const DH *x)
578         {
579         BIO *b;
580         int ret;
581
582         if ((b=BIO_new(BIO_s_file())) == NULL)
583                 {
584                 DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
585                 return(0);
586                 }
587         BIO_set_fp(b,fp,BIO_NOCLOSE);
588         ret=DHparams_print(b, x);
589         BIO_free(b);
590         return(ret);
591         }
592 #endif
593
594 int DHparams_print(BIO *bp, const DH *x)
595         {
596         unsigned char *m=NULL;
597         int reason=ERR_R_BUF_LIB,ret=0;
598         size_t buf_len=0, i;
599
600         if (x->p)
601                 buf_len = (size_t)BN_num_bytes(x->p);
602         if (x->g)
603                 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
604                         buf_len = i;
605         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
606         if (m == NULL)
607                 {
608                 reason=ERR_R_MALLOC_FAILURE;
609                 goto err;
610                 }
611
612         if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
613                 BN_num_bits(x->p)) <= 0)
614                 goto err;
615         if (!print(bp,"prime:",x->p,m,4)) goto err;
616         if (!print(bp,"generator:",x->g,m,4)) goto err;
617         if (x->length != 0)
618                 {
619                 if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
620                         (int)x->length) <= 0) goto err;
621                 }
622         ret=1;
623         if (0)
624                 {
625 err:
626                 DHerr(DH_F_DHPARAMS_PRINT,reason);
627                 }
628         if (m != NULL) OPENSSL_free(m);
629         return(ret);
630         }
631 #endif
632
633 #ifndef OPENSSL_NO_DSA
634 #ifndef OPENSSL_NO_FP_API
635 int DSAparams_print_fp(FILE *fp, const DSA *x)
636         {
637         BIO *b;
638         int ret;
639
640         if ((b=BIO_new(BIO_s_file())) == NULL)
641                 {
642                 DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
643                 return(0);
644                 }
645         BIO_set_fp(b,fp,BIO_NOCLOSE);
646         ret=DSAparams_print(b, x);
647         BIO_free(b);
648         return(ret);
649         }
650 #endif
651
652 int DSAparams_print(BIO *bp, const DSA *x)
653         {
654         unsigned char *m=NULL;
655         int reason=ERR_R_BUF_LIB,ret=0;
656         size_t buf_len=0,i;
657
658         if (x->p)
659                 buf_len = (size_t)BN_num_bytes(x->p);
660         if (x->q)
661                 if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
662                         buf_len = i;
663         if (x->g)
664                 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
665                         buf_len = i;
666         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
667         if (m == NULL)
668                 {
669                 reason=ERR_R_MALLOC_FAILURE;
670                 goto err;
671                 }
672
673         if (BIO_printf(bp,"DSA-Parameters: (%d bit)\n",
674                 BN_num_bits(x->p)) <= 0)
675                 goto err;
676         if (!print(bp,"p:",x->p,m,4)) goto err;
677         if (!print(bp,"q:",x->q,m,4)) goto err;
678         if (!print(bp,"g:",x->g,m,4)) goto err;
679         ret=1;
680 err:
681         if (m != NULL) OPENSSL_free(m);
682         DSAerr(DSA_F_DSAPARAMS_PRINT,reason);
683         return(ret);
684         }
685
686 #endif /* !OPENSSL_NO_DSA */
687
688 #ifndef OPENSSL_NO_EC
689 #ifndef OPENSSL_NO_FP_API
690 int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
691         {
692         BIO *b;
693         int ret;
694  
695         if ((b=BIO_new(BIO_s_file())) == NULL)
696                 {
697                 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
698                 return(0);
699                 }
700         BIO_set_fp(b, fp, BIO_NOCLOSE);
701         ret = ECParameters_print(b, x);
702         BIO_free(b);
703         return(ret);
704         }
705 #endif
706
707 int ECParameters_print(BIO *bp, const EC_KEY *x)
708         {
709         int     reason=ERR_R_EC_LIB, ret=0;
710         BIGNUM  *order=NULL;
711  
712         if (!x || !x->group)
713                 {
714                 reason = ERR_R_PASSED_NULL_PARAMETER;;
715                 goto err;
716                 }
717
718         if ((order = BN_new()) == NULL)
719                 {
720                 reason = ERR_R_MALLOC_FAILURE;
721                 goto err;
722                 }
723
724         if (!EC_GROUP_get_order(x->group, order, NULL))
725                 {
726                 reason = ERR_R_EC_LIB;
727                 goto err;
728                 }
729  
730         if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n", 
731                 BN_num_bits(order)) <= 0)
732                 goto err;
733         if (!ECPKParameters_print(bp, x->group, 4))
734                 goto err;
735         ret=1;
736 err:
737         if (order)
738                 BN_free(order);
739         ECerr(EC_F_ECPARAMETERS_PRINT, reason);
740         return(ret);
741         }
742   
743 #endif