• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
RSA_print_fp(FILE * fp,const RSA * x,int off)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 
RSA_print(BIO * bp,const RSA * x,int off)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, 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;
178 err:
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
DSA_print_fp(FILE * fp,const DSA * x,int off)186 int DSA_print_fp(FILE *fp, const DSA *x, int off)
187 	{
188 	BIO *b;
189 	int ret;
190 
191 	if ((b=BIO_new(BIO_s_file())) == NULL)
192 		{
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 
DSA_print(BIO * bp,const DSA * x,int off)203 int 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;
252 err:
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
ECPKParameters_print_fp(FILE * fp,const EC_GROUP * x,int off)260 int 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 
EC_KEY_print_fp(FILE * fp,const EC_KEY * x,int off)276 int 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 
ECPKParameters_print(BIO * bp,const EC_GROUP * x,int off)293 int 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;
472 err:
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 
EC_KEY_print(BIO * bp,const EC_KEY * x,int off)494 int 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;
555 err:
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 
print(BIO * bp,const char * number,const BIGNUM * num,unsigned char * buf,int off)570 static 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
print_bin(BIO * fp,const char * name,const unsigned char * buf,size_t len,int off)622 static 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
DHparams_print_fp(FILE * fp,const DH * x)663 int 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 
DHparams_print(BIO * bp,const DH * x)680 int 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 		{
716 err:
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
DSAparams_print_fp(FILE * fp,const DSA * x)726 int 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 
DSAparams_print(BIO * bp,const DSA * x)743 int 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;
776 err:
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
ECParameters_print_fp(FILE * fp,const EC_KEY * x)785 int 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 
ECParameters_print(BIO * bp,const EC_KEY * x)802 int 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;
832 err:
833 	if (order)
834 		BN_free(order);
835 	ECerr(EC_F_ECPARAMETERS_PRINT, reason);
836 	return(ret);
837 	}
838 
839 #endif
840