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