xref: /onnv-gate/usr/src/common/openssl/crypto/asn1/t_pkey.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/asn1/t_pkey.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
58*2139Sjp161948 /* ====================================================================
59*2139Sjp161948  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
60*2139Sjp161948  * Binary polynomial ECC support in OpenSSL originally developed by
61*2139Sjp161948  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
62*2139Sjp161948  */
630Sstevel@tonic-gate 
640Sstevel@tonic-gate #include <stdio.h>
650Sstevel@tonic-gate #include "cryptlib.h"
66*2139Sjp161948 #include <openssl/objects.h>
670Sstevel@tonic-gate #include <openssl/buffer.h>
680Sstevel@tonic-gate #include <openssl/bn.h>
690Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
700Sstevel@tonic-gate #include <openssl/rsa.h>
710Sstevel@tonic-gate #endif
720Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
730Sstevel@tonic-gate #include <openssl/dh.h>
740Sstevel@tonic-gate #endif
750Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
760Sstevel@tonic-gate #include <openssl/dsa.h>
770Sstevel@tonic-gate #endif
78*2139Sjp161948 #ifndef OPENSSL_NO_EC
79*2139Sjp161948 #include <openssl/ec.h>
80*2139Sjp161948 #endif
810Sstevel@tonic-gate 
82*2139Sjp161948 static int print(BIO *fp,const char *str, const BIGNUM *num,
830Sstevel@tonic-gate 		unsigned char *buf,int off);
84*2139Sjp161948 #ifndef OPENSSL_NO_EC
85*2139Sjp161948 static int print_bin(BIO *fp, const char *str, const unsigned char *num,
86*2139Sjp161948 		size_t len, int off);
87*2139Sjp161948 #endif
880Sstevel@tonic-gate #ifndef OPENSSL_NO_RSA
890Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API
RSA_print_fp(FILE * fp,const RSA * x,int off)900Sstevel@tonic-gate int RSA_print_fp(FILE *fp, const RSA *x, int off)
91*2139Sjp161948 	{
92*2139Sjp161948 	BIO *b;
93*2139Sjp161948 	int ret;
940Sstevel@tonic-gate 
95*2139Sjp161948 	if ((b=BIO_new(BIO_s_file())) == NULL)
960Sstevel@tonic-gate 		{
970Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
98*2139Sjp161948 		return(0);
990Sstevel@tonic-gate 		}
100*2139Sjp161948 	BIO_set_fp(b,fp,BIO_NOCLOSE);
101*2139Sjp161948 	ret=RSA_print(b,x,off);
102*2139Sjp161948 	BIO_free(b);
103*2139Sjp161948 	return(ret);
104*2139Sjp161948 	}
1050Sstevel@tonic-gate #endif
1060Sstevel@tonic-gate 
RSA_print(BIO * bp,const RSA * x,int off)1070Sstevel@tonic-gate int RSA_print(BIO *bp, const RSA *x, int off)
1080Sstevel@tonic-gate 	{
1090Sstevel@tonic-gate 	char str[128];
1100Sstevel@tonic-gate 	const char *s;
1110Sstevel@tonic-gate 	unsigned char *m=NULL;
1120Sstevel@tonic-gate 	int ret=0;
1130Sstevel@tonic-gate 	size_t buf_len=0, i;
1140Sstevel@tonic-gate 
1150Sstevel@tonic-gate 	if (x->n)
1160Sstevel@tonic-gate 		buf_len = (size_t)BN_num_bytes(x->n);
1170Sstevel@tonic-gate 	if (x->e)
1180Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->e)))
1190Sstevel@tonic-gate 			buf_len = i;
1200Sstevel@tonic-gate 	if (x->d)
1210Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->d)))
1220Sstevel@tonic-gate 			buf_len = i;
1230Sstevel@tonic-gate 	if (x->p)
1240Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->p)))
1250Sstevel@tonic-gate 			buf_len = i;
1260Sstevel@tonic-gate 	if (x->q)
1270Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
1280Sstevel@tonic-gate 			buf_len = i;
1290Sstevel@tonic-gate 	if (x->dmp1)
1300Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->dmp1)))
1310Sstevel@tonic-gate 			buf_len = i;
1320Sstevel@tonic-gate 	if (x->dmq1)
1330Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->dmq1)))
1340Sstevel@tonic-gate 			buf_len = i;
1350Sstevel@tonic-gate 	if (x->iqmp)
1360Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->iqmp)))
1370Sstevel@tonic-gate 			buf_len = i;
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
1400Sstevel@tonic-gate 	if (m == NULL)
1410Sstevel@tonic-gate 		{
1420Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_PRINT,ERR_R_MALLOC_FAILURE);
1430Sstevel@tonic-gate 		goto err;
1440Sstevel@tonic-gate 		}
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 	if (x->d != NULL)
1470Sstevel@tonic-gate 		{
1480Sstevel@tonic-gate 		if(!BIO_indent(bp,off,128))
1490Sstevel@tonic-gate 		   goto err;
1500Sstevel@tonic-gate 		if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->n))
1510Sstevel@tonic-gate 			<= 0) goto err;
1520Sstevel@tonic-gate 		}
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	if (x->d == NULL)
1550Sstevel@tonic-gate 		BIO_snprintf(str,sizeof str,"Modulus (%d bit):",BN_num_bits(x->n));
1560Sstevel@tonic-gate 	else
1570Sstevel@tonic-gate 		BUF_strlcpy(str,"modulus:",sizeof str);
1580Sstevel@tonic-gate 	if (!print(bp,str,x->n,m,off)) goto err;
1590Sstevel@tonic-gate 	s=(x->d == NULL)?"Exponent:":"publicExponent:";
1600Sstevel@tonic-gate 	if (!print(bp,s,x->e,m,off)) goto err;
1610Sstevel@tonic-gate 	if (!print(bp,"privateExponent:",x->d,m,off)) goto err;
1620Sstevel@tonic-gate 	if (!print(bp,"prime1:",x->p,m,off)) goto err;
1630Sstevel@tonic-gate 	if (!print(bp,"prime2:",x->q,m,off)) goto err;
1640Sstevel@tonic-gate 	if (!print(bp,"exponent1:",x->dmp1,m,off)) goto err;
1650Sstevel@tonic-gate 	if (!print(bp,"exponent2:",x->dmq1,m,off)) goto err;
1660Sstevel@tonic-gate 	if (!print(bp,"coefficient:",x->iqmp,m,off)) goto err;
1670Sstevel@tonic-gate 	ret=1;
1680Sstevel@tonic-gate err:
1690Sstevel@tonic-gate 	if (m != NULL) OPENSSL_free(m);
1700Sstevel@tonic-gate 	return(ret);
1710Sstevel@tonic-gate 	}
1720Sstevel@tonic-gate #endif /* OPENSSL_NO_RSA */
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
1750Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API
DSA_print_fp(FILE * fp,const DSA * x,int off)1760Sstevel@tonic-gate int DSA_print_fp(FILE *fp, const DSA *x, int off)
1770Sstevel@tonic-gate 	{
1780Sstevel@tonic-gate 	BIO *b;
1790Sstevel@tonic-gate 	int ret;
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate 	if ((b=BIO_new(BIO_s_file())) == NULL)
1820Sstevel@tonic-gate 		{
1830Sstevel@tonic-gate 		DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
1840Sstevel@tonic-gate 		return(0);
1850Sstevel@tonic-gate 		}
1860Sstevel@tonic-gate 	BIO_set_fp(b,fp,BIO_NOCLOSE);
1870Sstevel@tonic-gate 	ret=DSA_print(b,x,off);
1880Sstevel@tonic-gate 	BIO_free(b);
1890Sstevel@tonic-gate 	return(ret);
1900Sstevel@tonic-gate 	}
1910Sstevel@tonic-gate #endif
1920Sstevel@tonic-gate 
DSA_print(BIO * bp,const DSA * x,int off)1930Sstevel@tonic-gate int DSA_print(BIO *bp, const DSA *x, int off)
1940Sstevel@tonic-gate 	{
1950Sstevel@tonic-gate 	unsigned char *m=NULL;
1960Sstevel@tonic-gate 	int ret=0;
1970Sstevel@tonic-gate 	size_t buf_len=0,i;
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate 	if (x->p)
2000Sstevel@tonic-gate 		buf_len = (size_t)BN_num_bytes(x->p);
201*2139Sjp161948 	else
202*2139Sjp161948 		{
203*2139Sjp161948 		DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS);
204*2139Sjp161948 		goto err;
205*2139Sjp161948 		}
2060Sstevel@tonic-gate 	if (x->q)
2070Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
2080Sstevel@tonic-gate 			buf_len = i;
2090Sstevel@tonic-gate 	if (x->g)
2100Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
2110Sstevel@tonic-gate 			buf_len = i;
2120Sstevel@tonic-gate 	if (x->priv_key)
2130Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->priv_key)))
2140Sstevel@tonic-gate 			buf_len = i;
2150Sstevel@tonic-gate 	if (x->pub_key)
2160Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->pub_key)))
2170Sstevel@tonic-gate 			buf_len = i;
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
2200Sstevel@tonic-gate 	if (m == NULL)
2210Sstevel@tonic-gate 		{
2220Sstevel@tonic-gate 		DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE);
2230Sstevel@tonic-gate 		goto err;
2240Sstevel@tonic-gate 		}
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	if (x->priv_key != NULL)
2270Sstevel@tonic-gate 		{
2280Sstevel@tonic-gate 		if(!BIO_indent(bp,off,128))
2290Sstevel@tonic-gate 		   goto err;
2300Sstevel@tonic-gate 		if (BIO_printf(bp,"Private-Key: (%d bit)\n",BN_num_bits(x->p))
2310Sstevel@tonic-gate 			<= 0) goto err;
2320Sstevel@tonic-gate 		}
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate 	if ((x->priv_key != NULL) && !print(bp,"priv:",x->priv_key,m,off))
2350Sstevel@tonic-gate 		goto err;
2360Sstevel@tonic-gate 	if ((x->pub_key  != NULL) && !print(bp,"pub: ",x->pub_key,m,off))
2370Sstevel@tonic-gate 		goto err;
2380Sstevel@tonic-gate 	if ((x->p != NULL) && !print(bp,"P:   ",x->p,m,off)) goto err;
2390Sstevel@tonic-gate 	if ((x->q != NULL) && !print(bp,"Q:   ",x->q,m,off)) goto err;
2400Sstevel@tonic-gate 	if ((x->g != NULL) && !print(bp,"G:   ",x->g,m,off)) goto err;
2410Sstevel@tonic-gate 	ret=1;
2420Sstevel@tonic-gate err:
2430Sstevel@tonic-gate 	if (m != NULL) OPENSSL_free(m);
2440Sstevel@tonic-gate 	return(ret);
2450Sstevel@tonic-gate 	}
2460Sstevel@tonic-gate #endif /* !OPENSSL_NO_DSA */
2470Sstevel@tonic-gate 
248*2139Sjp161948 #ifndef OPENSSL_NO_EC
249*2139Sjp161948 #ifndef OPENSSL_NO_FP_API
ECPKParameters_print_fp(FILE * fp,const EC_GROUP * x,int off)250*2139Sjp161948 int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
251*2139Sjp161948 	{
252*2139Sjp161948 	BIO *b;
253*2139Sjp161948 	int ret;
254*2139Sjp161948 
255*2139Sjp161948 	if ((b=BIO_new(BIO_s_file())) == NULL)
256*2139Sjp161948 		{
257*2139Sjp161948 		ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
258*2139Sjp161948 		return(0);
259*2139Sjp161948 		}
260*2139Sjp161948 	BIO_set_fp(b, fp, BIO_NOCLOSE);
261*2139Sjp161948 	ret = ECPKParameters_print(b, x, off);
262*2139Sjp161948 	BIO_free(b);
263*2139Sjp161948 	return(ret);
264*2139Sjp161948 	}
265*2139Sjp161948 
EC_KEY_print_fp(FILE * fp,const EC_KEY * x,int off)266*2139Sjp161948 int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
267*2139Sjp161948 	{
268*2139Sjp161948 	BIO *b;
269*2139Sjp161948 	int ret;
270*2139Sjp161948 
271*2139Sjp161948 	if ((b=BIO_new(BIO_s_file())) == NULL)
272*2139Sjp161948 		{
273*2139Sjp161948 		ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
274*2139Sjp161948 		return(0);
275*2139Sjp161948 		}
276*2139Sjp161948 	BIO_set_fp(b, fp, BIO_NOCLOSE);
277*2139Sjp161948 	ret = EC_KEY_print(b, x, off);
278*2139Sjp161948 	BIO_free(b);
279*2139Sjp161948 	return(ret);
280*2139Sjp161948 	}
281*2139Sjp161948 #endif
282*2139Sjp161948 
ECPKParameters_print(BIO * bp,const EC_GROUP * x,int off)283*2139Sjp161948 int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
284*2139Sjp161948 	{
285*2139Sjp161948 	unsigned char *buffer=NULL;
286*2139Sjp161948 	size_t	buf_len=0, i;
287*2139Sjp161948 	int     ret=0, reason=ERR_R_BIO_LIB;
288*2139Sjp161948 	BN_CTX  *ctx=NULL;
289*2139Sjp161948 	const EC_POINT *point=NULL;
290*2139Sjp161948 	BIGNUM	*p=NULL, *a=NULL, *b=NULL, *gen=NULL,
291*2139Sjp161948 		*order=NULL, *cofactor=NULL;
292*2139Sjp161948 	const unsigned char *seed;
293*2139Sjp161948 	size_t	seed_len=0;
294*2139Sjp161948 
295*2139Sjp161948 	static const char *gen_compressed = "Generator (compressed):";
296*2139Sjp161948 	static const char *gen_uncompressed = "Generator (uncompressed):";
297*2139Sjp161948 	static const char *gen_hybrid = "Generator (hybrid):";
298*2139Sjp161948 
299*2139Sjp161948 	if (!x)
300*2139Sjp161948 		{
301*2139Sjp161948 		reason = ERR_R_PASSED_NULL_PARAMETER;
302*2139Sjp161948 		goto err;
303*2139Sjp161948 		}
304*2139Sjp161948 
305*2139Sjp161948 	if (EC_GROUP_get_asn1_flag(x))
306*2139Sjp161948 		{
307*2139Sjp161948 		/* the curve parameter are given by an asn1 OID */
308*2139Sjp161948 		int nid;
309*2139Sjp161948 
310*2139Sjp161948 		if (!BIO_indent(bp, off, 128))
311*2139Sjp161948 			goto err;
312*2139Sjp161948 
313*2139Sjp161948 		nid = EC_GROUP_get_curve_name(x);
314*2139Sjp161948 		if (nid == 0)
315*2139Sjp161948 			goto err;
316*2139Sjp161948 
317*2139Sjp161948 		if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
318*2139Sjp161948 			goto err;
319*2139Sjp161948 		if (BIO_printf(bp, "\n") <= 0)
320*2139Sjp161948 			goto err;
321*2139Sjp161948 		}
322*2139Sjp161948 	else
323*2139Sjp161948 		{
324*2139Sjp161948 		/* explicit parameters */
325*2139Sjp161948 		int is_char_two = 0;
326*2139Sjp161948 		point_conversion_form_t form;
327*2139Sjp161948 		int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
328*2139Sjp161948 
329*2139Sjp161948 		if (tmp_nid == NID_X9_62_characteristic_two_field)
330*2139Sjp161948 			is_char_two = 1;
331*2139Sjp161948 
332*2139Sjp161948 		if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
333*2139Sjp161948 			(b = BN_new()) == NULL || (order = BN_new()) == NULL ||
334*2139Sjp161948 			(cofactor = BN_new()) == NULL)
335*2139Sjp161948 			{
336*2139Sjp161948 			reason = ERR_R_MALLOC_FAILURE;
337*2139Sjp161948 			goto err;
338*2139Sjp161948 			}
339*2139Sjp161948 
340*2139Sjp161948 		if (is_char_two)
341*2139Sjp161948 			{
342*2139Sjp161948 			if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx))
343*2139Sjp161948 				{
344*2139Sjp161948 				reason = ERR_R_EC_LIB;
345*2139Sjp161948 				goto err;
346*2139Sjp161948 				}
347*2139Sjp161948 			}
348*2139Sjp161948 		else /* prime field */
349*2139Sjp161948 			{
350*2139Sjp161948 			if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx))
351*2139Sjp161948 				{
352*2139Sjp161948 				reason = ERR_R_EC_LIB;
353*2139Sjp161948 				goto err;
354*2139Sjp161948 				}
355*2139Sjp161948 			}
356*2139Sjp161948 
357*2139Sjp161948 		if ((point = EC_GROUP_get0_generator(x)) == NULL)
358*2139Sjp161948 			{
359*2139Sjp161948 			reason = ERR_R_EC_LIB;
360*2139Sjp161948 			goto err;
361*2139Sjp161948 			}
362*2139Sjp161948 		if (!EC_GROUP_get_order(x, order, NULL) ||
363*2139Sjp161948             		!EC_GROUP_get_cofactor(x, cofactor, NULL))
364*2139Sjp161948 			{
365*2139Sjp161948 			reason = ERR_R_EC_LIB;
366*2139Sjp161948 			goto err;
367*2139Sjp161948 			}
368*2139Sjp161948 
369*2139Sjp161948 		form = EC_GROUP_get_point_conversion_form(x);
370*2139Sjp161948 
371*2139Sjp161948 		if ((gen = EC_POINT_point2bn(x, point,
372*2139Sjp161948 				form, NULL, ctx)) == NULL)
373*2139Sjp161948 			{
374*2139Sjp161948 			reason = ERR_R_EC_LIB;
375*2139Sjp161948 			goto err;
376*2139Sjp161948 			}
377*2139Sjp161948 
378*2139Sjp161948 		buf_len = (size_t)BN_num_bytes(p);
379*2139Sjp161948 		if (buf_len < (i = (size_t)BN_num_bytes(a)))
380*2139Sjp161948 			buf_len = i;
381*2139Sjp161948 		if (buf_len < (i = (size_t)BN_num_bytes(b)))
382*2139Sjp161948 			buf_len = i;
383*2139Sjp161948 		if (buf_len < (i = (size_t)BN_num_bytes(gen)))
384*2139Sjp161948 			buf_len = i;
385*2139Sjp161948 		if (buf_len < (i = (size_t)BN_num_bytes(order)))
386*2139Sjp161948 			buf_len = i;
387*2139Sjp161948 		if (buf_len < (i = (size_t)BN_num_bytes(cofactor)))
388*2139Sjp161948 			buf_len = i;
389*2139Sjp161948 
390*2139Sjp161948 		if ((seed = EC_GROUP_get0_seed(x)) != NULL)
391*2139Sjp161948 			seed_len = EC_GROUP_get_seed_len(x);
392*2139Sjp161948 
393*2139Sjp161948 		buf_len += 10;
394*2139Sjp161948 		if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
395*2139Sjp161948 			{
396*2139Sjp161948 			reason = ERR_R_MALLOC_FAILURE;
397*2139Sjp161948 			goto err;
398*2139Sjp161948 			}
399*2139Sjp161948 
400*2139Sjp161948 		if (!BIO_indent(bp, off, 128))
401*2139Sjp161948 			goto err;
402*2139Sjp161948 
403*2139Sjp161948 		/* print the 'short name' of the field type */
404*2139Sjp161948 		if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
405*2139Sjp161948 			<= 0)
406*2139Sjp161948 			goto err;
407*2139Sjp161948 
408*2139Sjp161948 		if (is_char_two)
409*2139Sjp161948 			{
410*2139Sjp161948 			/* print the 'short name' of the base type OID */
411*2139Sjp161948 			int basis_type = EC_GROUP_get_basis_type(x);
412*2139Sjp161948 			if (basis_type == 0)
413*2139Sjp161948 				goto err;
414*2139Sjp161948 
415*2139Sjp161948 			if (!BIO_indent(bp, off, 128))
416*2139Sjp161948 				goto err;
417*2139Sjp161948 
418*2139Sjp161948 			if (BIO_printf(bp, "Basis Type: %s\n",
419*2139Sjp161948 				OBJ_nid2sn(basis_type)) <= 0)
420*2139Sjp161948 				goto err;
421*2139Sjp161948 
422*2139Sjp161948 			/* print the polynomial */
423*2139Sjp161948 			if ((p != NULL) && !print(bp, "Polynomial:", p, buffer,
424*2139Sjp161948 				off))
425*2139Sjp161948 				goto err;
426*2139Sjp161948 			}
427*2139Sjp161948 		else
428*2139Sjp161948 			{
429*2139Sjp161948 			if ((p != NULL) && !print(bp, "Prime:", p, buffer,off))
430*2139Sjp161948 				goto err;
431*2139Sjp161948 			}
432*2139Sjp161948 		if ((a != NULL) && !print(bp, "A:   ", a, buffer, off))
433*2139Sjp161948 			goto err;
434*2139Sjp161948 		if ((b != NULL) && !print(bp, "B:   ", b, buffer, off))
435*2139Sjp161948 			goto err;
436*2139Sjp161948 		if (form == POINT_CONVERSION_COMPRESSED)
437*2139Sjp161948 			{
438*2139Sjp161948 			if ((gen != NULL) && !print(bp, gen_compressed, gen,
439*2139Sjp161948 				buffer, off))
440*2139Sjp161948 				goto err;
441*2139Sjp161948 			}
442*2139Sjp161948 		else if (form == POINT_CONVERSION_UNCOMPRESSED)
443*2139Sjp161948 			{
444*2139Sjp161948 			if ((gen != NULL) && !print(bp, gen_uncompressed, gen,
445*2139Sjp161948 				buffer, off))
446*2139Sjp161948 				goto err;
447*2139Sjp161948 			}
448*2139Sjp161948 		else /* form == POINT_CONVERSION_HYBRID */
449*2139Sjp161948 			{
450*2139Sjp161948 			if ((gen != NULL) && !print(bp, gen_hybrid, gen,
451*2139Sjp161948 				buffer, off))
452*2139Sjp161948 				goto err;
453*2139Sjp161948 			}
454*2139Sjp161948 		if ((order != NULL) && !print(bp, "Order: ", order,
455*2139Sjp161948 			buffer, off)) goto err;
456*2139Sjp161948 		if ((cofactor != NULL) && !print(bp, "Cofactor: ", cofactor,
457*2139Sjp161948 			buffer, off)) goto err;
458*2139Sjp161948 		if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
459*2139Sjp161948 			goto err;
460*2139Sjp161948 		}
461*2139Sjp161948 	ret=1;
462*2139Sjp161948 err:
463*2139Sjp161948 	if (!ret)
464*2139Sjp161948  		ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
465*2139Sjp161948 	if (p)
466*2139Sjp161948 		BN_free(p);
467*2139Sjp161948 	if (a)
468*2139Sjp161948 		BN_free(a);
469*2139Sjp161948 	if (b)
470*2139Sjp161948 		BN_free(b);
471*2139Sjp161948 	if (gen)
472*2139Sjp161948 		BN_free(gen);
473*2139Sjp161948 	if (order)
474*2139Sjp161948 		BN_free(order);
475*2139Sjp161948 	if (cofactor)
476*2139Sjp161948 		BN_free(cofactor);
477*2139Sjp161948 	if (ctx)
478*2139Sjp161948 		BN_CTX_free(ctx);
479*2139Sjp161948 	if (buffer != NULL)
480*2139Sjp161948 		OPENSSL_free(buffer);
481*2139Sjp161948 	return(ret);
482*2139Sjp161948 	}
483*2139Sjp161948 
EC_KEY_print(BIO * bp,const EC_KEY * x,int off)484*2139Sjp161948 int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
485*2139Sjp161948 	{
486*2139Sjp161948 	unsigned char *buffer=NULL;
487*2139Sjp161948 	size_t	buf_len=0, i;
488*2139Sjp161948 	int     ret=0, reason=ERR_R_BIO_LIB;
489*2139Sjp161948 	BIGNUM  *pub_key=NULL, *order=NULL;
490*2139Sjp161948 	BN_CTX  *ctx=NULL;
491*2139Sjp161948 	const EC_GROUP *group;
492*2139Sjp161948 	const EC_POINT *public_key;
493*2139Sjp161948 	const BIGNUM *priv_key;
494*2139Sjp161948 
495*2139Sjp161948 	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
496*2139Sjp161948 		{
497*2139Sjp161948 		reason = ERR_R_PASSED_NULL_PARAMETER;
498*2139Sjp161948 		goto err;
499*2139Sjp161948 		}
500*2139Sjp161948 
501*2139Sjp161948 	public_key = EC_KEY_get0_public_key(x);
502*2139Sjp161948 	if ((pub_key = EC_POINT_point2bn(group, public_key,
503*2139Sjp161948 		EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
504*2139Sjp161948 		{
505*2139Sjp161948 		reason = ERR_R_EC_LIB;
506*2139Sjp161948 		goto err;
507*2139Sjp161948 		}
508*2139Sjp161948 
509*2139Sjp161948 	buf_len = (size_t)BN_num_bytes(pub_key);
510*2139Sjp161948 	priv_key = EC_KEY_get0_private_key(x);
511*2139Sjp161948 	if (priv_key != NULL)
512*2139Sjp161948 		{
513*2139Sjp161948 		if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
514*2139Sjp161948 			buf_len = i;
515*2139Sjp161948 		}
516*2139Sjp161948 
517*2139Sjp161948 	buf_len += 10;
518*2139Sjp161948 	if ((buffer = OPENSSL_malloc(buf_len)) == NULL)
519*2139Sjp161948 		{
520*2139Sjp161948 		reason = ERR_R_MALLOC_FAILURE;
521*2139Sjp161948 		goto err;
522*2139Sjp161948 		}
523*2139Sjp161948 
524*2139Sjp161948 	if (priv_key != NULL)
525*2139Sjp161948 		{
526*2139Sjp161948 		if (!BIO_indent(bp, off, 128))
527*2139Sjp161948 			goto err;
528*2139Sjp161948 		if ((order = BN_new()) == NULL)
529*2139Sjp161948 			goto err;
530*2139Sjp161948 		if (!EC_GROUP_get_order(group, order, NULL))
531*2139Sjp161948 			goto err;
532*2139Sjp161948 		if (BIO_printf(bp, "Private-Key: (%d bit)\n",
533*2139Sjp161948 			BN_num_bits(order)) <= 0) goto err;
534*2139Sjp161948 		}
535*2139Sjp161948 
536*2139Sjp161948 	if ((priv_key != NULL) && !print(bp, "priv:", priv_key,
537*2139Sjp161948 		buffer, off))
538*2139Sjp161948 		goto err;
539*2139Sjp161948 	if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
540*2139Sjp161948 		buffer, off))
541*2139Sjp161948 		goto err;
542*2139Sjp161948 	if (!ECPKParameters_print(bp, group, off))
543*2139Sjp161948 		goto err;
544*2139Sjp161948 	ret=1;
545*2139Sjp161948 err:
546*2139Sjp161948 	if (!ret)
547*2139Sjp161948  		ECerr(EC_F_EC_KEY_PRINT, reason);
548*2139Sjp161948 	if (pub_key)
549*2139Sjp161948 		BN_free(pub_key);
550*2139Sjp161948 	if (order)
551*2139Sjp161948 		BN_free(order);
552*2139Sjp161948 	if (ctx)
553*2139Sjp161948 		BN_CTX_free(ctx);
554*2139Sjp161948 	if (buffer != NULL)
555*2139Sjp161948 		OPENSSL_free(buffer);
556*2139Sjp161948 	return(ret);
557*2139Sjp161948 	}
558*2139Sjp161948 #endif /* OPENSSL_NO_EC */
559*2139Sjp161948 
print(BIO * bp,const char * number,const BIGNUM * num,unsigned char * buf,int off)560*2139Sjp161948 static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf,
5610Sstevel@tonic-gate 	     int off)
5620Sstevel@tonic-gate 	{
5630Sstevel@tonic-gate 	int n,i;
5640Sstevel@tonic-gate 	const char *neg;
5650Sstevel@tonic-gate 
5660Sstevel@tonic-gate 	if (num == NULL) return(1);
567*2139Sjp161948 	neg = (BN_is_negative(num))?"-":"";
5680Sstevel@tonic-gate 	if(!BIO_indent(bp,off,128))
5690Sstevel@tonic-gate 		return 0;
570*2139Sjp161948 	if (BN_is_zero(num))
571*2139Sjp161948 		{
572*2139Sjp161948 		if (BIO_printf(bp, "%s 0\n", number) <= 0)
573*2139Sjp161948 			return 0;
574*2139Sjp161948 		return 1;
575*2139Sjp161948 		}
5760Sstevel@tonic-gate 
5770Sstevel@tonic-gate 	if (BN_num_bytes(num) <= BN_BYTES)
5780Sstevel@tonic-gate 		{
5790Sstevel@tonic-gate 		if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
5800Sstevel@tonic-gate 			(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
5810Sstevel@tonic-gate 			<= 0) return(0);
5820Sstevel@tonic-gate 		}
5830Sstevel@tonic-gate 	else
5840Sstevel@tonic-gate 		{
5850Sstevel@tonic-gate 		buf[0]=0;
5860Sstevel@tonic-gate 		if (BIO_printf(bp,"%s%s",number,
5870Sstevel@tonic-gate 			(neg[0] == '-')?" (Negative)":"") <= 0)
5880Sstevel@tonic-gate 			return(0);
5890Sstevel@tonic-gate 		n=BN_bn2bin(num,&buf[1]);
5900Sstevel@tonic-gate 
5910Sstevel@tonic-gate 		if (buf[1] & 0x80)
5920Sstevel@tonic-gate 			n++;
5930Sstevel@tonic-gate 		else	buf++;
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate 		for (i=0; i<n; i++)
5960Sstevel@tonic-gate 			{
5970Sstevel@tonic-gate 			if ((i%15) == 0)
5980Sstevel@tonic-gate 				{
5990Sstevel@tonic-gate 				if(BIO_puts(bp,"\n") <= 0
6000Sstevel@tonic-gate 				   || !BIO_indent(bp,off+4,128))
6010Sstevel@tonic-gate 				    return 0;
6020Sstevel@tonic-gate 				}
6030Sstevel@tonic-gate 			if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
6040Sstevel@tonic-gate 				<= 0) return(0);
6050Sstevel@tonic-gate 			}
6060Sstevel@tonic-gate 		if (BIO_write(bp,"\n",1) <= 0) return(0);
6070Sstevel@tonic-gate 		}
6080Sstevel@tonic-gate 	return(1);
6090Sstevel@tonic-gate 	}
6100Sstevel@tonic-gate 
611*2139Sjp161948 #ifndef OPENSSL_NO_EC
print_bin(BIO * fp,const char * name,const unsigned char * buf,size_t len,int off)612*2139Sjp161948 static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
613*2139Sjp161948 		size_t len, int off)
614*2139Sjp161948 	{
615*2139Sjp161948 	size_t i;
616*2139Sjp161948 	char str[128];
617*2139Sjp161948 
618*2139Sjp161948 	if (buf == NULL)
619*2139Sjp161948 		return 1;
620*2139Sjp161948 	if (off)
621*2139Sjp161948 		{
622*2139Sjp161948 		if (off > 128)
623*2139Sjp161948 			off=128;
624*2139Sjp161948 		memset(str,' ',off);
625*2139Sjp161948 		if (BIO_write(fp, str, off) <= 0)
626*2139Sjp161948 			return 0;
627*2139Sjp161948 		}
628*2139Sjp161948 
629*2139Sjp161948 	if (BIO_printf(fp,"%s", name) <= 0)
630*2139Sjp161948 		return 0;
631*2139Sjp161948 
632*2139Sjp161948 	for (i=0; i<len; i++)
633*2139Sjp161948 		{
634*2139Sjp161948 		if ((i%15) == 0)
635*2139Sjp161948 			{
636*2139Sjp161948 			str[0]='\n';
637*2139Sjp161948 			memset(&(str[1]),' ',off+4);
638*2139Sjp161948 			if (BIO_write(fp, str, off+1+4) <= 0)
639*2139Sjp161948 				return 0;
640*2139Sjp161948 			}
641*2139Sjp161948 		if (BIO_printf(fp,"%02x%s",buf[i],((i+1) == len)?"":":") <= 0)
642*2139Sjp161948 			return 0;
643*2139Sjp161948 		}
644*2139Sjp161948 	if (BIO_write(fp,"\n",1) <= 0)
645*2139Sjp161948 		return 0;
646*2139Sjp161948 
647*2139Sjp161948 	return 1;
648*2139Sjp161948 	}
649*2139Sjp161948 #endif
650*2139Sjp161948 
6510Sstevel@tonic-gate #ifndef OPENSSL_NO_DH
6520Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API
DHparams_print_fp(FILE * fp,const DH * x)6530Sstevel@tonic-gate int DHparams_print_fp(FILE *fp, const DH *x)
654*2139Sjp161948 	{
655*2139Sjp161948 	BIO *b;
656*2139Sjp161948 	int ret;
6570Sstevel@tonic-gate 
658*2139Sjp161948 	if ((b=BIO_new(BIO_s_file())) == NULL)
6590Sstevel@tonic-gate 		{
6600Sstevel@tonic-gate 		DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
661*2139Sjp161948 		return(0);
6620Sstevel@tonic-gate 		}
663*2139Sjp161948 	BIO_set_fp(b,fp,BIO_NOCLOSE);
664*2139Sjp161948 	ret=DHparams_print(b, x);
665*2139Sjp161948 	BIO_free(b);
666*2139Sjp161948 	return(ret);
667*2139Sjp161948 	}
6680Sstevel@tonic-gate #endif
6690Sstevel@tonic-gate 
DHparams_print(BIO * bp,const DH * x)6700Sstevel@tonic-gate int DHparams_print(BIO *bp, const DH *x)
6710Sstevel@tonic-gate 	{
6720Sstevel@tonic-gate 	unsigned char *m=NULL;
6730Sstevel@tonic-gate 	int reason=ERR_R_BUF_LIB,ret=0;
6740Sstevel@tonic-gate 	size_t buf_len=0, i;
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate 	if (x->p)
6770Sstevel@tonic-gate 		buf_len = (size_t)BN_num_bytes(x->p);
678*2139Sjp161948 	else
679*2139Sjp161948 		{
680*2139Sjp161948 		reason = ERR_R_PASSED_NULL_PARAMETER;
681*2139Sjp161948 		goto err;
682*2139Sjp161948 		}
6830Sstevel@tonic-gate 	if (x->g)
6840Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
6850Sstevel@tonic-gate 			buf_len = i;
6860Sstevel@tonic-gate 	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
6870Sstevel@tonic-gate 	if (m == NULL)
6880Sstevel@tonic-gate 		{
6890Sstevel@tonic-gate 		reason=ERR_R_MALLOC_FAILURE;
6900Sstevel@tonic-gate 		goto err;
6910Sstevel@tonic-gate 		}
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate 	if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
6940Sstevel@tonic-gate 		BN_num_bits(x->p)) <= 0)
6950Sstevel@tonic-gate 		goto err;
6960Sstevel@tonic-gate 	if (!print(bp,"prime:",x->p,m,4)) goto err;
6970Sstevel@tonic-gate 	if (!print(bp,"generator:",x->g,m,4)) goto err;
6980Sstevel@tonic-gate 	if (x->length != 0)
6990Sstevel@tonic-gate 		{
7000Sstevel@tonic-gate 		if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
7010Sstevel@tonic-gate 			(int)x->length) <= 0) goto err;
7020Sstevel@tonic-gate 		}
7030Sstevel@tonic-gate 	ret=1;
7040Sstevel@tonic-gate 	if (0)
7050Sstevel@tonic-gate 		{
7060Sstevel@tonic-gate err:
7070Sstevel@tonic-gate 		DHerr(DH_F_DHPARAMS_PRINT,reason);
7080Sstevel@tonic-gate 		}
7090Sstevel@tonic-gate 	if (m != NULL) OPENSSL_free(m);
7100Sstevel@tonic-gate 	return(ret);
7110Sstevel@tonic-gate 	}
7120Sstevel@tonic-gate #endif
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate #ifndef OPENSSL_NO_DSA
7150Sstevel@tonic-gate #ifndef OPENSSL_NO_FP_API
DSAparams_print_fp(FILE * fp,const DSA * x)7160Sstevel@tonic-gate int DSAparams_print_fp(FILE *fp, const DSA *x)
717*2139Sjp161948 	{
718*2139Sjp161948 	BIO *b;
719*2139Sjp161948 	int ret;
7200Sstevel@tonic-gate 
721*2139Sjp161948 	if ((b=BIO_new(BIO_s_file())) == NULL)
7220Sstevel@tonic-gate 		{
7230Sstevel@tonic-gate 		DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
724*2139Sjp161948 		return(0);
7250Sstevel@tonic-gate 		}
726*2139Sjp161948 	BIO_set_fp(b,fp,BIO_NOCLOSE);
727*2139Sjp161948 	ret=DSAparams_print(b, x);
728*2139Sjp161948 	BIO_free(b);
729*2139Sjp161948 	return(ret);
730*2139Sjp161948 	}
7310Sstevel@tonic-gate #endif
7320Sstevel@tonic-gate 
DSAparams_print(BIO * bp,const DSA * x)7330Sstevel@tonic-gate int DSAparams_print(BIO *bp, const DSA *x)
7340Sstevel@tonic-gate 	{
7350Sstevel@tonic-gate 	unsigned char *m=NULL;
736*2139Sjp161948 	int ret=0;
7370Sstevel@tonic-gate 	size_t buf_len=0,i;
7380Sstevel@tonic-gate 
7390Sstevel@tonic-gate 	if (x->p)
7400Sstevel@tonic-gate 		buf_len = (size_t)BN_num_bytes(x->p);
741*2139Sjp161948 	else
742*2139Sjp161948 		{
743*2139Sjp161948 		DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS);
744*2139Sjp161948 		goto err;
745*2139Sjp161948 		}
7460Sstevel@tonic-gate 	if (x->q)
7470Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->q)))
7480Sstevel@tonic-gate 			buf_len = i;
7490Sstevel@tonic-gate 	if (x->g)
7500Sstevel@tonic-gate 		if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
7510Sstevel@tonic-gate 			buf_len = i;
7520Sstevel@tonic-gate 	m=(unsigned char *)OPENSSL_malloc(buf_len+10);
7530Sstevel@tonic-gate 	if (m == NULL)
7540Sstevel@tonic-gate 		{
755*2139Sjp161948 		DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE);
7560Sstevel@tonic-gate 		goto err;
7570Sstevel@tonic-gate 		}
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 	if (BIO_printf(bp,"DSA-Parameters: (%d bit)\n",
7600Sstevel@tonic-gate 		BN_num_bits(x->p)) <= 0)
7610Sstevel@tonic-gate 		goto err;
7620Sstevel@tonic-gate 	if (!print(bp,"p:",x->p,m,4)) goto err;
7630Sstevel@tonic-gate 	if (!print(bp,"q:",x->q,m,4)) goto err;
7640Sstevel@tonic-gate 	if (!print(bp,"g:",x->g,m,4)) goto err;
7650Sstevel@tonic-gate 	ret=1;
7660Sstevel@tonic-gate err:
7670Sstevel@tonic-gate 	if (m != NULL) OPENSSL_free(m);
7680Sstevel@tonic-gate 	return(ret);
7690Sstevel@tonic-gate 	}
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate #endif /* !OPENSSL_NO_DSA */
7720Sstevel@tonic-gate 
773*2139Sjp161948 #ifndef OPENSSL_NO_EC
774*2139Sjp161948 #ifndef OPENSSL_NO_FP_API
ECParameters_print_fp(FILE * fp,const EC_KEY * x)775*2139Sjp161948 int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
776*2139Sjp161948 	{
777*2139Sjp161948 	BIO *b;
778*2139Sjp161948 	int ret;
779*2139Sjp161948 
780*2139Sjp161948 	if ((b=BIO_new(BIO_s_file())) == NULL)
781*2139Sjp161948 		{
782*2139Sjp161948 		ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
783*2139Sjp161948 		return(0);
784*2139Sjp161948 		}
785*2139Sjp161948 	BIO_set_fp(b, fp, BIO_NOCLOSE);
786*2139Sjp161948 	ret = ECParameters_print(b, x);
787*2139Sjp161948 	BIO_free(b);
788*2139Sjp161948 	return(ret);
789*2139Sjp161948 	}
790*2139Sjp161948 #endif
791*2139Sjp161948 
ECParameters_print(BIO * bp,const EC_KEY * x)792*2139Sjp161948 int ECParameters_print(BIO *bp, const EC_KEY *x)
793*2139Sjp161948 	{
794*2139Sjp161948 	int     reason=ERR_R_EC_LIB, ret=0;
795*2139Sjp161948 	BIGNUM	*order=NULL;
796*2139Sjp161948 	const EC_GROUP *group;
797*2139Sjp161948 
798*2139Sjp161948 	if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
799*2139Sjp161948 		{
800*2139Sjp161948 		reason = ERR_R_PASSED_NULL_PARAMETER;;
801*2139Sjp161948 		goto err;
802*2139Sjp161948 		}
803*2139Sjp161948 
804*2139Sjp161948 	if ((order = BN_new()) == NULL)
805*2139Sjp161948 		{
806*2139Sjp161948 		reason = ERR_R_MALLOC_FAILURE;
807*2139Sjp161948 		goto err;
808*2139Sjp161948 		}
809*2139Sjp161948 
810*2139Sjp161948 	if (!EC_GROUP_get_order(group, order, NULL))
811*2139Sjp161948 		{
812*2139Sjp161948 		reason = ERR_R_EC_LIB;
813*2139Sjp161948 		goto err;
814*2139Sjp161948 		}
815*2139Sjp161948 
816*2139Sjp161948 	if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n",
817*2139Sjp161948 		BN_num_bits(order)) <= 0)
818*2139Sjp161948 		goto err;
819*2139Sjp161948 	if (!ECPKParameters_print(bp, group, 4))
820*2139Sjp161948 		goto err;
821*2139Sjp161948 	ret=1;
822*2139Sjp161948 err:
823*2139Sjp161948 	if (order)
824*2139Sjp161948 		BN_free(order);
825*2139Sjp161948 	ECerr(EC_F_ECPARAMETERS_PRINT, reason);
826*2139Sjp161948 	return(ret);
827*2139Sjp161948 	}
828*2139Sjp161948 
829*2139Sjp161948 #endif
830