1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* rsautl.c */
2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 2000.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/opensslconf.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RSA
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "apps.h"
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <string.h>
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/err.h>
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/pem.h>
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/rsa.h>
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define RSA_SIGN 	1
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define RSA_VERIFY 	2
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define RSA_ENCRYPT 	3
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define RSA_DECRYPT 	4
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define KEY_PRIVKEY	1
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define KEY_PUBKEY	2
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define KEY_CERT	3
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void usage(void);
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#undef PROG
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define PROG rsautl_main
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint MAIN(int argc, char **);
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint MAIN(int argc, char **argv)
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ENGINE *e = NULL;
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO *in = NULL, *out = NULL;
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *infile = NULL, *outfile = NULL;
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *engine = NULL;
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *keyfile = NULL;
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int keyform = FORMAT_PEM;
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char need_priv = 0, badarg = 0, rev = 0;
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char hexdump = 0, asn1parse = 0;
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	X509 *x;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY *pkey = NULL;
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	RSA *rsa = NULL;
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *passargin = NULL, *passin = NULL;
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int rsa_inlen, rsa_outlen = 0;
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int keysize;
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret = 1;
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	argc--;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	argv++;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!load_config(bio_err, NULL))
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ERR_load_crypto_strings();
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OpenSSL_add_all_algorithms();
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	pad = RSA_PKCS1_PADDING;
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(argc >= 1)
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!strcmp(*argv,"-in")) {
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (--argc < 1)
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				badarg = 1;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				infile= *(++argv);
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*argv,"-out")) {
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (--argc < 1)
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				badarg = 1;
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				outfile= *(++argv);
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(!strcmp(*argv, "-inkey")) {
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (--argc < 1)
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				badarg = 1;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				keyfile = *(++argv);
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (!strcmp(*argv,"-passin")) {
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (--argc < 1)
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				badarg = 1;
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				passargin= *(++argv);
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if (strcmp(*argv,"-keyform") == 0) {
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (--argc < 1)
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				badarg = 1;
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				keyform=str2fmt(*(++argv));
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(!strcmp(*argv, "-engine")) {
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (--argc < 1)
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				badarg = 1;
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				engine = *(++argv);
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(!strcmp(*argv, "-pubin")) {
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			key_type = KEY_PUBKEY;
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(!strcmp(*argv, "-certin")) {
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			key_type = KEY_CERT;
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1;
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-hexdump")) hexdump = 1;
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING;
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING;
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING;
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-sign")) {
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_mode = RSA_SIGN;
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			need_priv = 1;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-rev")) rev = 1;
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT;
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if(!strcmp(*argv, "-decrypt")) {
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_mode = RSA_DECRYPT;
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			need_priv = 1;
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else badarg = 1;
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(badarg) {
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			usage();
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto end;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		argc--;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		argv++;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(need_priv && (key_type != KEY_PRIVKEY)) {
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err, "A private key is needed for this operation\n");
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        e = setup_engine(bio_err, engine, 0);
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err, "Error getting password\n");
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* FIXME: seed PRNG only if needed */
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	app_RAND_load_file(NULL, bio_err, 0);
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch(key_type) {
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case KEY_PRIVKEY:
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pkey = load_key(bio_err, keyfile, keyform, 0,
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			passin, e, "Private Key");
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case KEY_PUBKEY:
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			NULL, e, "Public Key");
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case KEY_CERT:
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		x = load_cert(bio_err, keyfile, keyform,
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			NULL, e, "Certificate");
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(x) {
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			pkey = X509_get_pubkey(x);
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			X509_free(x);
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!pkey) {
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return 1;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rsa = EVP_PKEY_get1_RSA(pkey);
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_PKEY_free(pkey);
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!rsa) {
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err, "Error getting RSA key\n");
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_print_errors(bio_err);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(infile) {
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!(in = BIO_new_file(infile, "rb"))) {
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_printf(bio_err, "Error Reading Input File\n");
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_print_errors(bio_err);
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto end;
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else in = BIO_new_fp(stdin, BIO_NOCLOSE);
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(outfile) {
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!(out = BIO_new_file(outfile, "wb"))) {
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			BIO_printf(bio_err, "Error Reading Output File\n");
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_print_errors(bio_err);
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto end;
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else {
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		out = BIO_new_fp(stdout, BIO_NOCLOSE);
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef OPENSSL_SYS_VMS
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		    out = BIO_push(tmpbio, out);
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	keysize = RSA_size(rsa);
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rsa_in = OPENSSL_malloc(keysize * 2);
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rsa_out = OPENSSL_malloc(keysize);
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Read the input data */
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(rsa_inlen <= 0) {
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err, "Error reading input Data\n");
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		exit(1);
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(rev) {
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		int i;
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned char ctmp;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for(i = 0; i < rsa_inlen/2; i++) {
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ctmp = rsa_in[i];
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_in[rsa_inlen - 1 - i] = ctmp;
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch(rsa_mode) {
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case RSA_VERIFY:
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case RSA_SIGN:
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case RSA_ENCRYPT:
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case RSA_DECRYPT:
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(rsa_outlen <= 0) {
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_printf(bio_err, "RSA operation error\n");
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_print_errors(bio_err);
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto end;
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = 0;
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(asn1parse) {
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ERR_print_errors(bio_err);
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else BIO_write(out, rsa_out, rsa_outlen);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	end:
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	RSA_free(rsa);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_free(in);
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_free_all(out);
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(rsa_in) OPENSSL_free(rsa_in);
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(rsa_out) OPENSSL_free(rsa_out);
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(passin) OPENSSL_free(passin);
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ret;
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void usage()
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "Usage: rsautl [options]\n");
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-in file        input file\n");
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-out file       output file\n");
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-inkey file     input key\n");
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-pubin          input is an RSA public\n");
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-certin         input is a certificate carrying an RSA public key\n");
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-ssl            use SSL v2 padding\n");
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-raw            use no padding\n");
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-pkcs           use PKCS#1 v1.5 padding (default)\n");
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-oaep           use PKCS#1 OAEP\n");
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-sign           sign with private key\n");
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-verify         verify with public key\n");
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-hexdump        hex dump output\n");
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	BIO_printf (bio_err, "-passin arg    pass phrase source\n");
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#else /* !OPENSSL_NO_RSA */
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# if PEDANTIC
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void *dummy=&dummy;
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# endif
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
352