~ubuntu-branches/ubuntu/hardy/openssl/hardy-security

« back to all changes in this revision

Viewing changes to apps/rsautl.c

  • Committer: Bazaar Package Importer
  • Author(s): Christoph Martin
  • Date: 2004-05-24 17:02:29 UTC
  • Revision ID: james.westby@ubuntu.com-20040524170229-ixlo08bbbly0xied
Tags: upstream-0.9.7d
ImportĀ upstreamĀ versionĀ 0.9.7d

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
75
static void usage(void);
 
76
 
 
77
#undef PROG
 
78
 
 
79
#define PROG rsautl_main
 
80
 
 
81
int MAIN(int argc, char **);
 
82
 
 
83
int 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
 
 
305
static 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