Gather printing routines into EVP_PKEY_ASN1_METHOD.
[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  * 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 #include <openssl/evp.h>
70 #ifndef OPENSSL_NO_RSA
71 #include <openssl/rsa.h>
72 #endif
73 #ifndef OPENSSL_NO_DH
74 #include <openssl/dh.h>
75 #endif
76 #ifndef OPENSSL_NO_DSA
77 #include <openssl/dsa.h>
78 #endif
79 #ifndef OPENSSL_NO_EC
80 #include <openssl/ec.h>
81 #endif
82
83 #ifndef OPENSSL_NO_RSA
84 #ifndef OPENSSL_NO_FP_API
85 int RSA_print_fp(FILE *fp, const RSA *x, int off)
86         {
87         BIO *b;
88         int ret;
89
90         if ((b=BIO_new(BIO_s_file())) == NULL)
91                 {
92                 RSAerr(RSA_F_RSA_PRINT_FP,ERR_R_BUF_LIB);
93                 return(0);
94                 }
95         BIO_set_fp(b,fp,BIO_NOCLOSE);
96         ret=RSA_print(b,x,off);
97         BIO_free(b);
98         return(ret);
99         }
100 #endif
101
102 int RSA_print(BIO *bp, const RSA *x, int off)
103         {
104         EVP_PKEY *pk;
105         int ret;
106         pk = EVP_PKEY_new();
107         if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
108                 return 0;
109         ret = EVP_PKEY_print_private(bp, pk, off, NULL);
110         EVP_PKEY_free(pk);
111         return ret;
112         }
113
114 #endif /* OPENSSL_NO_RSA */
115
116 #ifndef OPENSSL_NO_DSA
117 #ifndef OPENSSL_NO_FP_API
118 int DSA_print_fp(FILE *fp, const DSA *x, int off)
119         {
120         BIO *b;
121         int ret;
122
123         if ((b=BIO_new(BIO_s_file())) == NULL)
124                 {
125                 DSAerr(DSA_F_DSA_PRINT_FP,ERR_R_BUF_LIB);
126                 return(0);
127                 }
128         BIO_set_fp(b,fp,BIO_NOCLOSE);
129         ret=DSA_print(b,x,off);
130         BIO_free(b);
131         return(ret);
132         }
133 #endif
134
135 int DSA_print(BIO *bp, const DSA *x, int off)
136         {
137         EVP_PKEY *pk;
138         int ret;
139         pk = EVP_PKEY_new();
140         if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
141                 return 0;
142         ret = EVP_PKEY_print_private(bp, pk, off, NULL);
143         EVP_PKEY_free(pk);
144         return ret;
145         }
146
147 #endif /* !OPENSSL_NO_DSA */
148
149 #ifndef OPENSSL_NO_EC
150 #ifndef OPENSSL_NO_FP_API
151 int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
152         {
153         BIO *b;
154         int ret;
155
156         if ((b=BIO_new(BIO_s_file())) == NULL)
157                 {
158                 ECerr(EC_F_ECPKPARAMETERS_PRINT_FP,ERR_R_BUF_LIB);
159                 return(0);
160                 }
161         BIO_set_fp(b, fp, BIO_NOCLOSE);
162         ret = ECPKParameters_print(b, x, off);
163         BIO_free(b);
164         return(ret);
165         }
166
167 int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
168         {
169         BIO *b;
170         int ret;
171  
172         if ((b=BIO_new(BIO_s_file())) == NULL)
173                 {
174                 ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
175                 return(0);
176                 }
177         BIO_set_fp(b, fp, BIO_NOCLOSE);
178         ret = EC_KEY_print(b, x, off);
179         BIO_free(b);
180         return(ret);
181         }
182 #endif
183
184 int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
185         {
186         EVP_PKEY *pk;
187         int ret;
188         pk = EVP_PKEY_new();
189         if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
190                 return 0;
191         ret = EVP_PKEY_print_private(bp, pk, off, NULL);
192         EVP_PKEY_free(pk);
193         return ret;
194         }
195
196 #endif /* OPENSSL_NO_EC */
197
198 int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
199                         unsigned char *buf, int off)
200         {
201         int n,i;
202         const char *neg;
203
204         if (num == NULL) return(1);
205         neg = (BN_is_negative(num))?"-":"";
206         if(!BIO_indent(bp,off,128))
207                 return 0;
208         if (BN_is_zero(num))
209                 {
210                 if (BIO_printf(bp, "%s 0\n", number) <= 0)
211                         return 0;
212                 return 1;
213                 }
214
215         if (BN_num_bytes(num) <= BN_BYTES)
216                 {
217                 if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
218                         (unsigned long)num->d[0],neg,(unsigned long)num->d[0])
219                         <= 0) return(0);
220                 }
221         else
222                 {
223                 buf[0]=0;
224                 if (BIO_printf(bp,"%s%s",number,
225                         (neg[0] == '-')?" (Negative)":"") <= 0)
226                         return(0);
227                 n=BN_bn2bin(num,&buf[1]);
228         
229                 if (buf[1] & 0x80)
230                         n++;
231                 else    buf++;
232
233                 for (i=0; i<n; i++)
234                         {
235                         if ((i%15) == 0)
236                                 {
237                                 if(BIO_puts(bp,"\n") <= 0
238                                    || !BIO_indent(bp,off+4,128))
239                                     return 0;
240                                 }
241                         if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
242                                 <= 0) return(0);
243                         }
244                 if (BIO_write(bp,"\n",1) <= 0) return(0);
245                 }
246         return(1);
247         }
248
249 #ifndef OPENSSL_NO_DH
250 #ifndef OPENSSL_NO_FP_API
251 int DHparams_print_fp(FILE *fp, const DH *x)
252         {
253         BIO *b;
254         int ret;
255
256         if ((b=BIO_new(BIO_s_file())) == NULL)
257                 {
258                 DHerr(DH_F_DHPARAMS_PRINT_FP,ERR_R_BUF_LIB);
259                 return(0);
260                 }
261         BIO_set_fp(b,fp,BIO_NOCLOSE);
262         ret=DHparams_print(b, x);
263         BIO_free(b);
264         return(ret);
265         }
266 #endif
267
268 int DHparams_print(BIO *bp, const DH *x)
269         {
270         unsigned char *m=NULL;
271         int reason=ERR_R_BUF_LIB,ret=0;
272         size_t buf_len=0, i;
273
274         if (x->p)
275                 buf_len = (size_t)BN_num_bytes(x->p);
276         else
277                 {
278                 reason = ERR_R_PASSED_NULL_PARAMETER;
279                 goto err;
280                 }
281         if (x->g)
282                 if (buf_len < (i = (size_t)BN_num_bytes(x->g)))
283                         buf_len = i;
284         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
285         if (m == NULL)
286                 {
287                 reason=ERR_R_MALLOC_FAILURE;
288                 goto err;
289                 }
290
291         if (BIO_printf(bp,"Diffie-Hellman-Parameters: (%d bit)\n",
292                 BN_num_bits(x->p)) <= 0)
293                 goto err;
294         if (!ASN1_bn_print(bp,"prime:",x->p,m,4)) goto err;
295         if (!ASN1_bn_print(bp,"generator:",x->g,m,4)) goto err;
296         if (x->length != 0)
297                 {
298                 if (BIO_printf(bp,"    recommended-private-length: %d bits\n",
299                         (int)x->length) <= 0) goto err;
300                 }
301         ret=1;
302         if (0)
303                 {
304 err:
305                 DHerr(DH_F_DHPARAMS_PRINT,reason);
306                 }
307         if (m != NULL) OPENSSL_free(m);
308         return(ret);
309         }
310 #endif
311
312 #ifndef OPENSSL_NO_DSA
313 #ifndef OPENSSL_NO_FP_API
314 int DSAparams_print_fp(FILE *fp, const DSA *x)
315         {
316         BIO *b;
317         int ret;
318
319         if ((b=BIO_new(BIO_s_file())) == NULL)
320                 {
321                 DSAerr(DSA_F_DSAPARAMS_PRINT_FP,ERR_R_BUF_LIB);
322                 return(0);
323                 }
324         BIO_set_fp(b,fp,BIO_NOCLOSE);
325         ret=DSAparams_print(b, x);
326         BIO_free(b);
327         return(ret);
328         }
329 #endif
330
331 int DSAparams_print(BIO *bp, const DSA *x)
332         {
333         EVP_PKEY *pk;
334         int ret;
335         pk = EVP_PKEY_new();
336         if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
337                 return 0;
338         ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
339         EVP_PKEY_free(pk);
340         return ret;
341         }
342
343 #endif /* !OPENSSL_NO_DSA */
344
345 #ifndef OPENSSL_NO_EC
346 #ifndef OPENSSL_NO_FP_API
347 int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
348         {
349         BIO *b;
350         int ret;
351  
352         if ((b=BIO_new(BIO_s_file())) == NULL)
353                 {
354                 ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
355                 return(0);
356                 }
357         BIO_set_fp(b, fp, BIO_NOCLOSE);
358         ret = ECParameters_print(b, x);
359         BIO_free(b);
360         return(ret);
361         }
362 #endif
363
364 int ECParameters_print(BIO *bp, const EC_KEY *x)
365         {
366         EVP_PKEY *pk;
367         int ret;
368         pk = EVP_PKEY_new();
369         if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x))
370                 return 0;
371         ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
372         EVP_PKEY_free(pk);
373         return ret;
374         }
375
376 #endif