source: trunk/third/openssl/apps/rsautl.c @ 20293

Revision 20293, 9.4 KB checked in by zacheiss, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20292, which included commits to RCS files with non-trunk default branches.
Line 
1/* rsautl.c */
2/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in
17 *    the documentation and/or other materials provided with the
18 *    distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 *    software must display the following acknowledgment:
22 *    "This product includes software developed by the OpenSSL Project
23 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 *    endorse or promote products derived from this software without
27 *    prior written permission. For written permission, please contact
28 *    licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 *    nor may "OpenSSL" appear in their names without prior written
32 *    permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 *    acknowledgment:
36 *    "This product includes software developed by the OpenSSL Project
37 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com).  This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#ifndef OPENSSL_NO_RSA
60
61#include "apps.h"
62#include <string.h>
63#include <openssl/err.h>
64#include <openssl/pem.h>
65
66#define RSA_SIGN        1
67#define RSA_VERIFY      2
68#define RSA_ENCRYPT     3
69#define RSA_DECRYPT     4
70
71#define KEY_PRIVKEY     1
72#define KEY_PUBKEY      2
73#define KEY_CERT        3
74
75static void usage(void);
76
77#undef PROG
78
79#define PROG rsautl_main
80
81int MAIN(int argc, char **);
82
83int MAIN(int argc, char **argv)
84{
85        ENGINE *e = NULL;
86        BIO *in = NULL, *out = NULL;
87        char *infile = NULL, *outfile = NULL;
88#ifndef OPENSSL_NO_ENGINE
89        char *engine = NULL;
90#endif
91        char *keyfile = NULL;
92        char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
93        int keyform = FORMAT_PEM;
94        char need_priv = 0, badarg = 0, rev = 0;
95        char hexdump = 0, asn1parse = 0;
96        X509 *x;
97        EVP_PKEY *pkey = NULL;
98        RSA *rsa = NULL;
99        unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
100        char *passargin = NULL, *passin = NULL;
101        int rsa_inlen, rsa_outlen = 0;
102        int keysize;
103
104        int ret = 1;
105
106        argc--;
107        argv++;
108
109        if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
110
111        if (!load_config(bio_err, NULL))
112                goto end;
113        ERR_load_crypto_strings();
114        OpenSSL_add_all_algorithms();
115        pad = RSA_PKCS1_PADDING;
116       
117        while(argc >= 1)
118        {
119                if (!strcmp(*argv,"-in")) {
120                        if (--argc < 1) badarg = 1;
121                        infile= *(++argv);
122                } else if (!strcmp(*argv,"-out")) {
123                        if (--argc < 1) badarg = 1;
124                        outfile= *(++argv);
125                } else if(!strcmp(*argv, "-inkey")) {
126                        if (--argc < 1) badarg = 1;
127                        keyfile = *(++argv);
128                } else if (!strcmp(*argv,"-passin")) {
129                        if (--argc < 1) badarg = 1;
130                        passargin= *(++argv);
131                } else if (strcmp(*argv,"-keyform") == 0) {
132                        if (--argc < 1) badarg = 1;
133                        keyform=str2fmt(*(++argv));
134#ifndef OPENSSL_NO_ENGINE
135                } else if(!strcmp(*argv, "-engine")) {
136                        if (--argc < 1) badarg = 1;
137                        engine = *(++argv);
138#endif
139                } else if(!strcmp(*argv, "-pubin")) {
140                        key_type = KEY_PUBKEY;
141                } else if(!strcmp(*argv, "-certin")) {
142                        key_type = KEY_CERT;
143                }
144                else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
145                else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
146                else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
147                else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
148                else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
149                else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
150                else if(!strcmp(*argv, "-sign")) {
151                        rsa_mode = RSA_SIGN;
152                        need_priv = 1;
153                } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
154                else if(!strcmp(*argv, "-rev")) rev = 1;
155                else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
156                else if(!strcmp(*argv, "-decrypt")) {
157                        rsa_mode = RSA_DECRYPT;
158                        need_priv = 1;
159                } else badarg = 1;
160                if(badarg) {
161                        usage();
162                        goto end;
163                }
164                argc--;
165                argv++;
166        }
167
168        if(need_priv && (key_type != KEY_PRIVKEY)) {
169                BIO_printf(bio_err, "A private key is needed for this operation\n");
170                goto end;
171        }
172
173#ifndef OPENSSL_NO_ENGINE
174        e = setup_engine(bio_err, engine, 0);
175#endif
176        if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
177                BIO_printf(bio_err, "Error getting password\n");
178                goto end;
179        }
180
181/* FIXME: seed PRNG only if needed */
182        app_RAND_load_file(NULL, bio_err, 0);
183       
184        switch(key_type) {
185                case KEY_PRIVKEY:
186                pkey = load_key(bio_err, keyfile, keyform, 0,
187                        passin, e, "Private Key");
188                break;
189
190                case KEY_PUBKEY:
191                pkey = load_pubkey(bio_err, keyfile, keyform, 0,
192                        NULL, e, "Public Key");
193                break;
194
195                case KEY_CERT:
196                x = load_cert(bio_err, keyfile, keyform,
197                        NULL, e, "Certificate");
198                if(x) {
199                        pkey = X509_get_pubkey(x);
200                        X509_free(x);
201                }
202                break;
203        }
204
205        if(!pkey) {
206                return 1;
207        }
208
209        rsa = EVP_PKEY_get1_RSA(pkey);
210        EVP_PKEY_free(pkey);
211
212        if(!rsa) {
213                BIO_printf(bio_err, "Error getting RSA key\n");
214                ERR_print_errors(bio_err);
215                goto end;
216        }
217
218
219        if(infile) {
220                if(!(in = BIO_new_file(infile, "rb"))) {
221                        BIO_printf(bio_err, "Error Reading Input File\n");
222                        ERR_print_errors(bio_err);     
223                        goto end;
224                }
225        } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
226
227        if(outfile) {
228                if(!(out = BIO_new_file(outfile, "wb"))) {
229                        BIO_printf(bio_err, "Error Reading Output File\n");
230                        ERR_print_errors(bio_err);     
231                        goto end;
232                }
233        } else {
234                out = BIO_new_fp(stdout, BIO_NOCLOSE);
235#ifdef OPENSSL_SYS_VMS
236                {
237                    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
238                    out = BIO_push(tmpbio, out);
239                }
240#endif
241        }
242
243        keysize = RSA_size(rsa);
244
245        rsa_in = OPENSSL_malloc(keysize * 2);
246        rsa_out = OPENSSL_malloc(keysize);
247
248        /* Read the input data */
249        rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
250        if(rsa_inlen <= 0) {
251                BIO_printf(bio_err, "Error reading input Data\n");
252                exit(1);
253        }
254        if(rev) {
255                int i;
256                unsigned char ctmp;
257                for(i = 0; i < rsa_inlen/2; i++) {
258                        ctmp = rsa_in[i];
259                        rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
260                        rsa_in[rsa_inlen - 1 - i] = ctmp;
261                }
262        }
263        switch(rsa_mode) {
264
265                case RSA_VERIFY:
266                        rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
267                break;
268
269                case RSA_SIGN:
270                        rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
271                break;
272
273                case RSA_ENCRYPT:
274                        rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
275                break;
276
277                case RSA_DECRYPT:
278                        rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
279                break;
280
281        }
282
283        if(rsa_outlen <= 0) {
284                BIO_printf(bio_err, "RSA operation error\n");
285                ERR_print_errors(bio_err);
286                goto end;
287        }
288        ret = 0;
289        if(asn1parse) {
290                if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
291                        ERR_print_errors(bio_err);
292                }
293        } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
294        else BIO_write(out, rsa_out, rsa_outlen);
295        end:
296        RSA_free(rsa);
297        BIO_free(in);
298        BIO_free_all(out);
299        if(rsa_in) OPENSSL_free(rsa_in);
300        if(rsa_out) OPENSSL_free(rsa_out);
301        if(passin) OPENSSL_free(passin);
302        return ret;
303}
304
305static void usage()
306{
307        BIO_printf(bio_err, "Usage: rsautl [options]\n");
308        BIO_printf(bio_err, "-in file        input file\n");
309        BIO_printf(bio_err, "-out file       output file\n");
310        BIO_printf(bio_err, "-inkey file     input key\n");
311        BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
312        BIO_printf(bio_err, "-pubin          input is an RSA public\n");
313        BIO_printf(bio_err, "-certin         input is a certificate carrying an RSA public key\n");
314        BIO_printf(bio_err, "-ssl            use SSL v2 padding\n");
315        BIO_printf(bio_err, "-raw            use no padding\n");
316        BIO_printf(bio_err, "-pkcs           use PKCS#1 v1.5 padding (default)\n");
317        BIO_printf(bio_err, "-oaep           use PKCS#1 OAEP\n");
318        BIO_printf(bio_err, "-sign           sign with private key\n");
319        BIO_printf(bio_err, "-verify         verify with public key\n");
320        BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
321        BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
322        BIO_printf(bio_err, "-hexdump        hex dump output\n");
323#ifndef OPENSSL_NO_ENGINE
324        BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
325        BIO_printf (bio_err, "-passin arg    pass phrase source\n");
326#endif
327
328}
329
330#endif
Note: See TracBrowser for help on using the repository browser.