source: trunk/third/openssl/apps/rsa.c @ 15530

Revision 15530, 10.8 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15529, which included commits to RCS files with non-trunk default branches.
Line 
1/* apps/rsa.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#ifndef NO_RSA
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63#include <time.h>
64#include "apps.h"
65#include <openssl/bio.h>
66#include <openssl/err.h>
67#include <openssl/rsa.h>
68#include <openssl/evp.h>
69#include <openssl/x509.h>
70#include <openssl/pem.h>
71
72#undef PROG
73#define PROG    rsa_main
74
75/* -inform arg  - input format - default PEM (one of DER, NET or PEM)
76 * -outform arg - output format - default PEM
77 * -in arg      - input file - default stdin
78 * -out arg     - output file - default stdout
79 * -des         - encrypt output if PEM format with DES in cbc mode
80 * -des3        - encrypt output if PEM format
81 * -idea        - encrypt output if PEM format
82 * -text        - print a text version
83 * -modulus     - print the RSA key modulus
84 * -check       - verify key consistency
85 * -pubin       - Expect a public key in input file.
86 * -pubout      - Output a public key.
87 */
88
89int MAIN(int, char **);
90
91int MAIN(int argc, char **argv)
92        {
93        int ret=1;
94        RSA *rsa=NULL;
95        int i,badops=0, sgckey=0;
96        const EVP_CIPHER *enc=NULL;
97        BIO *in=NULL,*out=NULL;
98        int informat,outformat,text=0,check=0,noout=0;
99        int pubin = 0, pubout = 0;
100        char *infile,*outfile,*prog;
101        char *passargin = NULL, *passargout = NULL;
102        char *passin = NULL, *passout = NULL;
103        int modulus=0;
104
105        apps_startup();
106
107        if (bio_err == NULL)
108                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
109                        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
110
111        infile=NULL;
112        outfile=NULL;
113        informat=FORMAT_PEM;
114        outformat=FORMAT_PEM;
115
116        prog=argv[0];
117        argc--;
118        argv++;
119        while (argc >= 1)
120                {
121                if      (strcmp(*argv,"-inform") == 0)
122                        {
123                        if (--argc < 1) goto bad;
124                        informat=str2fmt(*(++argv));
125                        }
126                else if (strcmp(*argv,"-outform") == 0)
127                        {
128                        if (--argc < 1) goto bad;
129                        outformat=str2fmt(*(++argv));
130                        }
131                else if (strcmp(*argv,"-in") == 0)
132                        {
133                        if (--argc < 1) goto bad;
134                        infile= *(++argv);
135                        }
136                else if (strcmp(*argv,"-out") == 0)
137                        {
138                        if (--argc < 1) goto bad;
139                        outfile= *(++argv);
140                        }
141                else if (strcmp(*argv,"-passin") == 0)
142                        {
143                        if (--argc < 1) goto bad;
144                        passargin= *(++argv);
145                        }
146                else if (strcmp(*argv,"-passout") == 0)
147                        {
148                        if (--argc < 1) goto bad;
149                        passargout= *(++argv);
150                        }
151                else if (strcmp(*argv,"-sgckey") == 0)
152                        sgckey=1;
153                else if (strcmp(*argv,"-pubin") == 0)
154                        pubin=1;
155                else if (strcmp(*argv,"-pubout") == 0)
156                        pubout=1;
157                else if (strcmp(*argv,"-noout") == 0)
158                        noout=1;
159                else if (strcmp(*argv,"-text") == 0)
160                        text=1;
161                else if (strcmp(*argv,"-modulus") == 0)
162                        modulus=1;
163                else if (strcmp(*argv,"-check") == 0)
164                        check=1;
165                else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
166                        {
167                        BIO_printf(bio_err,"unknown option %s\n",*argv);
168                        badops=1;
169                        break;
170                        }
171                argc--;
172                argv++;
173                }
174
175        if (badops)
176                {
177bad:
178                BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
179                BIO_printf(bio_err,"where options are\n");
180                BIO_printf(bio_err," -inform arg     input format - one of DER NET PEM\n");
181                BIO_printf(bio_err," -outform arg    output format - one of DER NET PEM\n");
182                BIO_printf(bio_err," -in arg         input file\n");
183                BIO_printf(bio_err," -sgckey         Use IIS SGC key format\n");
184                BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
185                BIO_printf(bio_err," -out arg        output file\n");
186                BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
187                BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
188                BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
189#ifndef NO_IDEA
190                BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
191#endif
192                BIO_printf(bio_err," -text           print the key in text\n");
193                BIO_printf(bio_err," -noout          don't print key out\n");
194                BIO_printf(bio_err," -modulus        print the RSA key modulus\n");
195                BIO_printf(bio_err," -check          verify key consistency\n");
196                BIO_printf(bio_err," -pubin          expect a public key in input file\n");
197                BIO_printf(bio_err," -pubout         output a public key\n");
198                goto end;
199                }
200
201        ERR_load_crypto_strings();
202
203        if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
204                BIO_printf(bio_err, "Error getting passwords\n");
205                goto end;
206        }
207
208        if(check && pubin) {
209                BIO_printf(bio_err, "Only private keys can be checked\n");
210                goto end;
211        }
212
213        in=BIO_new(BIO_s_file());
214        out=BIO_new(BIO_s_file());
215        if ((in == NULL) || (out == NULL))
216                {
217                ERR_print_errors(bio_err);
218                goto end;
219                }
220
221        if (infile == NULL)
222                BIO_set_fp(in,stdin,BIO_NOCLOSE);
223        else
224                {
225                if (BIO_read_filename(in,infile) <= 0)
226                        {
227                        perror(infile);
228                        goto end;
229                        }
230                }
231
232        BIO_printf(bio_err,"read RSA key\n");
233        if      (informat == FORMAT_ASN1) {
234                if (pubin) rsa=d2i_RSA_PUBKEY_bio(in,NULL);
235                else rsa=d2i_RSAPrivateKey_bio(in,NULL);
236        }
237#ifndef NO_RC4
238        else if (informat == FORMAT_NETSCAPE)
239                {
240                BUF_MEM *buf=NULL;
241                unsigned char *p;
242                int size=0;
243
244                buf=BUF_MEM_new();
245                for (;;)
246                        {
247                        if ((buf == NULL) || (!BUF_MEM_grow(buf,size+1024*10)))
248                                goto end;
249                        i=BIO_read(in,&(buf->data[size]),1024*10);
250                        size+=i;
251                        if (i == 0) break;
252                        if (i < 0)
253                                {
254                                perror("reading private key");
255                                BUF_MEM_free(buf);
256                                goto end;
257                                }
258                        }
259                p=(unsigned char *)buf->data;
260                rsa=d2i_RSA_NET(NULL,&p,(long)size,NULL, sgckey);
261                BUF_MEM_free(buf);
262                }
263#endif
264        else if (informat == FORMAT_PEM) {
265                if(pubin) rsa=PEM_read_bio_RSA_PUBKEY(in,NULL,NULL,NULL);
266                else rsa=PEM_read_bio_RSAPrivateKey(in,NULL, NULL,passin);
267        }
268        else
269                {
270                BIO_printf(bio_err,"bad input format specified for key\n");
271                goto end;
272                }
273        if (rsa == NULL)
274                {
275                BIO_printf(bio_err,"unable to load key\n");
276                ERR_print_errors(bio_err);
277                goto end;
278                }
279
280        if (outfile == NULL)
281                {
282                BIO_set_fp(out,stdout,BIO_NOCLOSE);
283#ifdef VMS
284                {
285                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
286                out = BIO_push(tmpbio, out);
287                }
288#endif
289                }
290        else
291                {
292                if (BIO_write_filename(out,outfile) <= 0)
293                        {
294                        perror(outfile);
295                        goto end;
296                        }
297                }
298
299        if (text)
300                if (!RSA_print(out,rsa,0))
301                        {
302                        perror(outfile);
303                        ERR_print_errors(bio_err);
304                        goto end;
305                        }
306
307        if (modulus)
308                {
309                BIO_printf(out,"Modulus=");
310                BN_print(out,rsa->n);
311                BIO_printf(out,"\n");
312                }
313
314        if (check)
315                {
316                int r = RSA_check_key(rsa);
317
318                if (r == 1)
319                        BIO_printf(out,"RSA key ok\n");
320                else if (r == 0)
321                        {
322                        long e;
323
324                        while ((e = ERR_peek_error()) != 0 &&
325                                ERR_GET_LIB(e) == ERR_LIB_RSA &&
326                                ERR_GET_FUNC(e) == RSA_F_RSA_CHECK_KEY &&
327                                ERR_GET_REASON(e) != ERR_R_MALLOC_FAILURE)
328                                {
329                                BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(e));
330                                ERR_get_error(); /* remove e from error stack */
331                                }
332                        }
333               
334                if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */
335                        {
336                        ERR_print_errors(bio_err);
337                        goto end;
338                        }
339                }
340               
341        if (noout)
342                {
343                ret = 0;
344                goto end;
345                }
346        BIO_printf(bio_err,"writing RSA key\n");
347        if      (outformat == FORMAT_ASN1) {
348                if(pubout || pubin) i=i2d_RSA_PUBKEY_bio(out,rsa);
349                else i=i2d_RSAPrivateKey_bio(out,rsa);
350        }
351#ifndef NO_RC4
352        else if (outformat == FORMAT_NETSCAPE)
353                {
354                unsigned char *p,*pp;
355                int size;
356
357                i=1;
358                size=i2d_RSA_NET(rsa,NULL,NULL, sgckey);
359                if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL)
360                        {
361                        BIO_printf(bio_err,"Memory allocation failure\n");
362                        goto end;
363                        }
364                pp=p;
365                i2d_RSA_NET(rsa,&p,NULL, sgckey);
366                BIO_write(out,(char *)pp,size);
367                OPENSSL_free(pp);
368                }
369#endif
370        else if (outformat == FORMAT_PEM) {
371                if(pubout || pubin)
372                    i=PEM_write_bio_RSA_PUBKEY(out,rsa);
373                else i=PEM_write_bio_RSAPrivateKey(out,rsa,
374                                                enc,NULL,0,NULL,passout);
375        } else  {
376                BIO_printf(bio_err,"bad output format specified for outfile\n");
377                goto end;
378                }
379        if (!i)
380                {
381                BIO_printf(bio_err,"unable to write key\n");
382                ERR_print_errors(bio_err);
383                }
384        else
385                ret=0;
386end:
387        if(in != NULL) BIO_free(in);
388        if(out != NULL) BIO_free_all(out);
389        if(rsa != NULL) RSA_free(rsa);
390        if(passin) OPENSSL_free(passin);
391        if(passout) OPENSSL_free(passout);
392        EXIT(ret);
393        }
394#else /* !NO_RSA */
395
396# if PEDANTIC
397static void *dummy=&dummy;
398# endif
399
400#endif
Note: See TracBrowser for help on using the repository browser.