rsautl.c 11 KB

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