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

Revision 18442, 8.9 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/* 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        char *engine = NULL;
89        char *keyfile = NULL;
90        char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
91        int keyform = FORMAT_PEM;
92        char need_priv = 0, badarg = 0, rev = 0;
93        char hexdump = 0, asn1parse = 0;
94        X509 *x;
95        EVP_PKEY *pkey = NULL;
96        RSA *rsa = NULL;
97        unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
98        int rsa_inlen, rsa_outlen = 0;
99        int keysize;
100
101        int ret = 1;
102
103        argc--;
104        argv++;
105
106        if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
107
108        if (!load_config(bio_err, NULL))
109                goto end;
110        ERR_load_crypto_strings();
111        OpenSSL_add_all_algorithms();
112        pad = RSA_PKCS1_PADDING;
113       
114        while(argc >= 1)
115        {
116                if (!strcmp(*argv,"-in")) {
117                        if (--argc < 1) badarg = 1;
118                        infile= *(++argv);
119                } else if (!strcmp(*argv,"-out")) {
120                        if (--argc < 1) badarg = 1;
121                        outfile= *(++argv);
122                } else if(!strcmp(*argv, "-inkey")) {
123                        if (--argc < 1) badarg = 1;
124                        keyfile = *(++argv);
125                } else if (strcmp(*argv,"-keyform") == 0) {
126                        if (--argc < 1) badarg = 1;
127                        keyform=str2fmt(*(++argv));
128                } else if(!strcmp(*argv, "-engine")) {
129                        if (--argc < 1) badarg = 1;
130                        engine = *(++argv);
131                } else if(!strcmp(*argv, "-pubin")) {
132                        key_type = KEY_PUBKEY;
133                } else if(!strcmp(*argv, "-certin")) {
134                        key_type = KEY_CERT;
135                }
136                else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
137                else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
138                else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
139                else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
140                else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
141                else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
142                else if(!strcmp(*argv, "-sign")) {
143                        rsa_mode = RSA_SIGN;
144                        need_priv = 1;
145                } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
146                else if(!strcmp(*argv, "-rev")) rev = 1;
147                else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
148                else if(!strcmp(*argv, "-decrypt")) {
149                        rsa_mode = RSA_DECRYPT;
150                        need_priv = 1;
151                } else badarg = 1;
152                if(badarg) {
153                        usage();
154                        goto end;
155                }
156                argc--;
157                argv++;
158        }
159
160        if(need_priv && (key_type != KEY_PRIVKEY)) {
161                BIO_printf(bio_err, "A private key is needed for this operation\n");
162                goto end;
163        }
164
165        e = setup_engine(bio_err, engine, 0);
166
167/* FIXME: seed PRNG only if needed */
168        app_RAND_load_file(NULL, bio_err, 0);
169       
170        switch(key_type) {
171                case KEY_PRIVKEY:
172                pkey = load_key(bio_err, keyfile, keyform, 0,
173                        NULL, e, "Private Key");
174                break;
175
176                case KEY_PUBKEY:
177                pkey = load_pubkey(bio_err, keyfile, keyform, 0,
178                        NULL, e, "Public Key");
179                break;
180
181                case KEY_CERT:
182                x = load_cert(bio_err, keyfile, keyform,
183                        NULL, e, "Certificate");
184                if(x) {
185                        pkey = X509_get_pubkey(x);
186                        X509_free(x);
187                }
188                break;
189        }
190
191        if(!pkey) {
192                return 1;
193        }
194
195        rsa = EVP_PKEY_get1_RSA(pkey);
196        EVP_PKEY_free(pkey);
197
198        if(!rsa) {
199                BIO_printf(bio_err, "Error getting RSA key\n");
200                ERR_print_errors(bio_err);
201                goto end;
202        }
203
204
205        if(infile) {
206                if(!(in = BIO_new_file(infile, "rb"))) {
207                        BIO_printf(bio_err, "Error Reading Input File\n");
208                        ERR_print_errors(bio_err);     
209                        goto end;
210                }
211        } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
212
213        if(outfile) {
214                if(!(out = BIO_new_file(outfile, "wb"))) {
215                        BIO_printf(bio_err, "Error Reading Output File\n");
216                        ERR_print_errors(bio_err);     
217                        goto end;
218                }
219        } else {
220                out = BIO_new_fp(stdout, BIO_NOCLOSE);
221#ifdef OPENSSL_SYS_VMS
222                {
223                    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
224                    out = BIO_push(tmpbio, out);
225                }
226#endif
227        }
228
229        keysize = RSA_size(rsa);
230
231        rsa_in = OPENSSL_malloc(keysize * 2);
232        rsa_out = OPENSSL_malloc(keysize);
233
234        /* Read the input data */
235        rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
236        if(rsa_inlen <= 0) {
237                BIO_printf(bio_err, "Error reading input Data\n");
238                exit(1);
239        }
240        if(rev) {
241                int i;
242                unsigned char ctmp;
243                for(i = 0; i < rsa_inlen/2; i++) {
244                        ctmp = rsa_in[i];
245                        rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
246                        rsa_in[rsa_inlen - 1 - i] = ctmp;
247                }
248        }
249        switch(rsa_mode) {
250
251                case RSA_VERIFY:
252                        rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
253                break;
254
255                case RSA_SIGN:
256                        rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
257                break;
258
259                case RSA_ENCRYPT:
260                        rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
261                break;
262
263                case RSA_DECRYPT:
264                        rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
265                break;
266
267        }
268
269        if(rsa_outlen <= 0) {
270                BIO_printf(bio_err, "RSA operation error\n");
271                ERR_print_errors(bio_err);
272                goto end;
273        }
274        ret = 0;
275        if(asn1parse) {
276                if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
277                        ERR_print_errors(bio_err);
278                }
279        } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
280        else BIO_write(out, rsa_out, rsa_outlen);
281        end:
282        RSA_free(rsa);
283        BIO_free(in);
284        BIO_free_all(out);
285        if(rsa_in) OPENSSL_free(rsa_in);
286        if(rsa_out) OPENSSL_free(rsa_out);
287        return ret;
288}
289
290static void usage()
291{
292        BIO_printf(bio_err, "Usage: rsautl [options]\n");
293        BIO_printf(bio_err, "-in file        input file\n");
294        BIO_printf(bio_err, "-out file       output file\n");
295        BIO_printf(bio_err, "-inkey file     input key\n");
296        BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
297        BIO_printf(bio_err, "-pubin          input is an RSA public\n");
298        BIO_printf(bio_err, "-certin         input is a certificate carrying an RSA public key\n");
299        BIO_printf(bio_err, "-ssl            use SSL v2 padding\n");
300        BIO_printf(bio_err, "-raw            use no padding\n");
301        BIO_printf(bio_err, "-pkcs           use PKCS#1 v1.5 padding (default)\n");
302        BIO_printf(bio_err, "-oaep           use PKCS#1 OAEP\n");
303        BIO_printf(bio_err, "-sign           sign with private key\n");
304        BIO_printf(bio_err, "-verify         verify with public key\n");
305        BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
306        BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
307        BIO_printf(bio_err, "-hexdump        hex dump output\n");
308        BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
309
310}
311
312#endif
Note: See TracBrowser for help on using the repository browser.