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

Revision 18442, 10.7 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18441, 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 OPENSSL_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 * -aes128      - encrypt output if PEM format
83 * -aes192      - encrypt output if PEM format
84 * -aes256      - encrypt output if PEM format
85 * -text        - print a text version
86 * -modulus     - print the RSA key modulus
87 * -check       - verify key consistency
88 * -pubin       - Expect a public key in input file.
89 * -pubout      - Output a public key.
90 */
91
92int MAIN(int, char **);
93
94int MAIN(int argc, char **argv)
95        {
96        ENGINE *e = NULL;
97        int ret=1;
98        RSA *rsa=NULL;
99        int i,badops=0, sgckey=0;
100        const EVP_CIPHER *enc=NULL;
101        BIO *out=NULL;
102        int informat,outformat,text=0,check=0,noout=0;
103        int pubin = 0, pubout = 0;
104        char *infile,*outfile,*prog;
105        char *passargin = NULL, *passargout = NULL;
106        char *passin = NULL, *passout = NULL;
107        char *engine=NULL;
108        int modulus=0;
109
110        apps_startup();
111
112        if (bio_err == NULL)
113                if ((bio_err=BIO_new(BIO_s_file())) != NULL)
114                        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
115
116        if (!load_config(bio_err, NULL))
117                goto end;
118
119        infile=NULL;
120        outfile=NULL;
121        informat=FORMAT_PEM;
122        outformat=FORMAT_PEM;
123
124        prog=argv[0];
125        argc--;
126        argv++;
127        while (argc >= 1)
128                {
129                if      (strcmp(*argv,"-inform") == 0)
130                        {
131                        if (--argc < 1) goto bad;
132                        informat=str2fmt(*(++argv));
133                        }
134                else if (strcmp(*argv,"-outform") == 0)
135                        {
136                        if (--argc < 1) goto bad;
137                        outformat=str2fmt(*(++argv));
138                        }
139                else if (strcmp(*argv,"-in") == 0)
140                        {
141                        if (--argc < 1) goto bad;
142                        infile= *(++argv);
143                        }
144                else if (strcmp(*argv,"-out") == 0)
145                        {
146                        if (--argc < 1) goto bad;
147                        outfile= *(++argv);
148                        }
149                else if (strcmp(*argv,"-passin") == 0)
150                        {
151                        if (--argc < 1) goto bad;
152                        passargin= *(++argv);
153                        }
154                else if (strcmp(*argv,"-passout") == 0)
155                        {
156                        if (--argc < 1) goto bad;
157                        passargout= *(++argv);
158                        }
159                else if (strcmp(*argv,"-engine") == 0)
160                        {
161                        if (--argc < 1) goto bad;
162                        engine= *(++argv);
163                        }
164                else if (strcmp(*argv,"-sgckey") == 0)
165                        sgckey=1;
166                else if (strcmp(*argv,"-pubin") == 0)
167                        pubin=1;
168                else if (strcmp(*argv,"-pubout") == 0)
169                        pubout=1;
170                else if (strcmp(*argv,"-noout") == 0)
171                        noout=1;
172                else if (strcmp(*argv,"-text") == 0)
173                        text=1;
174                else if (strcmp(*argv,"-modulus") == 0)
175                        modulus=1;
176                else if (strcmp(*argv,"-check") == 0)
177                        check=1;
178                else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL)
179                        {
180                        BIO_printf(bio_err,"unknown option %s\n",*argv);
181                        badops=1;
182                        break;
183                        }
184                argc--;
185                argv++;
186                }
187
188        if (badops)
189                {
190bad:
191                BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
192                BIO_printf(bio_err,"where options are\n");
193                BIO_printf(bio_err," -inform arg     input format - one of DER NET PEM\n");
194                BIO_printf(bio_err," -outform arg    output format - one of DER NET PEM\n");
195                BIO_printf(bio_err," -in arg         input file\n");
196                BIO_printf(bio_err," -sgckey         Use IIS SGC key format\n");
197                BIO_printf(bio_err," -passin arg     input file pass phrase source\n");
198                BIO_printf(bio_err," -out arg        output file\n");
199                BIO_printf(bio_err," -passout arg    output file pass phrase source\n");
200                BIO_printf(bio_err," -des            encrypt PEM output with cbc des\n");
201                BIO_printf(bio_err," -des3           encrypt PEM output with ede cbc des using 168 bit key\n");
202#ifndef OPENSSL_NO_IDEA
203                BIO_printf(bio_err," -idea           encrypt PEM output with cbc idea\n");
204#endif
205#ifndef OPENSSL_NO_AES
206                BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
207                BIO_printf(bio_err,"                 encrypt PEM output with cbc aes\n");
208#endif
209                BIO_printf(bio_err," -text           print the key in text\n");
210                BIO_printf(bio_err," -noout          don't print key out\n");
211                BIO_printf(bio_err," -modulus        print the RSA key modulus\n");
212                BIO_printf(bio_err," -check          verify key consistency\n");
213                BIO_printf(bio_err," -pubin          expect a public key in input file\n");
214                BIO_printf(bio_err," -pubout         output a public key\n");
215                BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
216                goto end;
217                }
218
219        ERR_load_crypto_strings();
220
221        e = setup_engine(bio_err, engine, 0);
222
223        if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
224                BIO_printf(bio_err, "Error getting passwords\n");
225                goto end;
226        }
227
228        if(check && pubin) {
229                BIO_printf(bio_err, "Only private keys can be checked\n");
230                goto end;
231        }
232
233        out=BIO_new(BIO_s_file());
234
235        {
236                EVP_PKEY        *pkey;
237
238                if (pubin)
239                        pkey = load_pubkey(bio_err, infile,
240                                (informat == FORMAT_NETSCAPE && sgckey ?
241                                        FORMAT_IISSGC : informat), 1,
242                                passin, e, "Public Key");
243                else
244                        pkey = load_key(bio_err, infile,
245                                (informat == FORMAT_NETSCAPE && sgckey ?
246                                        FORMAT_IISSGC : informat), 1,
247                                passin, e, "Private Key");
248
249                if (pkey != NULL)
250                rsa = pkey == NULL ? NULL : EVP_PKEY_get1_RSA(pkey);
251                EVP_PKEY_free(pkey);
252        }
253
254        if (rsa == NULL)
255                {
256                ERR_print_errors(bio_err);
257                goto end;
258                }
259
260        if (outfile == NULL)
261                {
262                BIO_set_fp(out,stdout,BIO_NOCLOSE);
263#ifdef OPENSSL_SYS_VMS
264                {
265                BIO *tmpbio = BIO_new(BIO_f_linebuffer());
266                out = BIO_push(tmpbio, out);
267                }
268#endif
269                }
270        else
271                {
272                if (BIO_write_filename(out,outfile) <= 0)
273                        {
274                        perror(outfile);
275                        goto end;
276                        }
277                }
278
279        if (text)
280                if (!RSA_print(out,rsa,0))
281                        {
282                        perror(outfile);
283                        ERR_print_errors(bio_err);
284                        goto end;
285                        }
286
287        if (modulus)
288                {
289                BIO_printf(out,"Modulus=");
290                BN_print(out,rsa->n);
291                BIO_printf(out,"\n");
292                }
293
294        if (check)
295                {
296                int r = RSA_check_key(rsa);
297
298                if (r == 1)
299                        BIO_printf(out,"RSA key ok\n");
300                else if (r == 0)
301                        {
302                        long err;
303
304                        while ((err = ERR_peek_error()) != 0 &&
305                                ERR_GET_LIB(err) == ERR_LIB_RSA &&
306                                ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
307                                ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE)
308                                {
309                                BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err));
310                                ERR_get_error(); /* remove e from error stack */
311                                }
312                        }
313               
314                if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */
315                        {
316                        ERR_print_errors(bio_err);
317                        goto end;
318                        }
319                }
320               
321        if (noout)
322                {
323                ret = 0;
324                goto end;
325                }
326        BIO_printf(bio_err,"writing RSA key\n");
327        if      (outformat == FORMAT_ASN1) {
328                if(pubout || pubin) i=i2d_RSA_PUBKEY_bio(out,rsa);
329                else i=i2d_RSAPrivateKey_bio(out,rsa);
330        }
331#ifndef OPENSSL_NO_RC4
332        else if (outformat == FORMAT_NETSCAPE)
333                {
334                unsigned char *p,*pp;
335                int size;
336
337                i=1;
338                size=i2d_RSA_NET(rsa,NULL,NULL, sgckey);
339                if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL)
340                        {
341                        BIO_printf(bio_err,"Memory allocation failure\n");
342                        goto end;
343                        }
344                pp=p;
345                i2d_RSA_NET(rsa,&p,NULL, sgckey);
346                BIO_write(out,(char *)pp,size);
347                OPENSSL_free(pp);
348                }
349#endif
350        else if (outformat == FORMAT_PEM) {
351                if(pubout || pubin)
352                    i=PEM_write_bio_RSA_PUBKEY(out,rsa);
353                else i=PEM_write_bio_RSAPrivateKey(out,rsa,
354                                                enc,NULL,0,NULL,passout);
355        } else  {
356                BIO_printf(bio_err,"bad output format specified for outfile\n");
357                goto end;
358                }
359        if (!i)
360                {
361                BIO_printf(bio_err,"unable to write key\n");
362                ERR_print_errors(bio_err);
363                }
364        else
365                ret=0;
366end:
367        if(out != NULL) BIO_free_all(out);
368        if(rsa != NULL) RSA_free(rsa);
369        if(passin) OPENSSL_free(passin);
370        if(passout) OPENSSL_free(passout);
371        apps_shutdown();
372        OPENSSL_EXIT(ret);
373        }
374#else /* !OPENSSL_NO_RSA */
375
376# if PEDANTIC
377static void *dummy=&dummy;
378# endif
379
380#endif
Note: See TracBrowser for help on using the repository browser.