2
0

rsautl.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /*
  2. * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <openssl/opensslconf.h>
  10. #include "apps.h"
  11. #include "progs.h"
  12. #include <string.h>
  13. #include <openssl/err.h>
  14. #include <openssl/pem.h>
  15. #include <openssl/rsa.h>
  16. #define RSA_SIGN 1
  17. #define RSA_VERIFY 2
  18. #define RSA_ENCRYPT 3
  19. #define RSA_DECRYPT 4
  20. #define KEY_PRIVKEY 1
  21. #define KEY_PUBKEY 2
  22. #define KEY_CERT 3
  23. typedef enum OPTION_choice {
  24. OPT_COMMON,
  25. OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP,
  26. OPT_RSA_RAW, OPT_OAEP, OPT_PKCS, OPT_X931,
  27. OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
  28. OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM,
  29. OPT_R_ENUM, OPT_PROV_ENUM
  30. } OPTION_CHOICE;
  31. const OPTIONS rsautl_options[] = {
  32. OPT_SECTION("General"),
  33. {"help", OPT_HELP, '-', "Display this summary"},
  34. {"sign", OPT_SIGN, '-', "Sign with private key"},
  35. {"verify", OPT_VERIFY, '-', "Verify with public key"},
  36. {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"},
  37. {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"},
  38. #ifndef OPENSSL_NO_ENGINE
  39. {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
  40. #endif
  41. OPT_SECTION("Input"),
  42. {"in", OPT_IN, '<', "Input file"},
  43. {"inkey", OPT_INKEY, 's', "Input key, by default an RSA private key"},
  44. {"keyform", OPT_KEYFORM, 'E', "Private key format (ENGINE, other values ignored)"},
  45. {"pubin", OPT_PUBIN, '-', "Input key is an RSA public pkey"},
  46. {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"},
  47. {"rev", OPT_REV, '-', "Reverse the order of the input buffer"},
  48. {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
  49. OPT_SECTION("Output"),
  50. {"out", OPT_OUT, '>', "Output file"},
  51. {"raw", OPT_RSA_RAW, '-', "Use no padding"},
  52. {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"},
  53. {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"},
  54. {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"},
  55. {"asn1parse", OPT_ASN1PARSE, '-',
  56. "Run output through asn1parse; useful with -verify"},
  57. {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"},
  58. OPT_R_OPTIONS,
  59. OPT_PROV_OPTIONS,
  60. {NULL}
  61. };
  62. int rsautl_main(int argc, char **argv)
  63. {
  64. BIO *in = NULL, *out = NULL;
  65. ENGINE *e = NULL;
  66. EVP_PKEY *pkey = NULL;
  67. EVP_PKEY_CTX *ctx = NULL;
  68. X509 *x;
  69. char *infile = NULL, *outfile = NULL, *keyfile = NULL;
  70. char *passinarg = NULL, *passin = NULL, *prog;
  71. char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
  72. unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING;
  73. size_t rsa_inlen, rsa_outlen = 0;
  74. int keyformat = FORMAT_UNDEF, keysize, ret = 1, rv;
  75. int hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0;
  76. OPTION_CHOICE o;
  77. prog = opt_init(argc, argv, rsautl_options);
  78. while ((o = opt_next()) != OPT_EOF) {
  79. switch (o) {
  80. case OPT_EOF:
  81. case OPT_ERR:
  82. opthelp:
  83. BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
  84. goto end;
  85. case OPT_HELP:
  86. opt_help(rsautl_options);
  87. ret = 0;
  88. goto end;
  89. case OPT_KEYFORM:
  90. if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
  91. goto opthelp;
  92. break;
  93. case OPT_IN:
  94. infile = opt_arg();
  95. break;
  96. case OPT_OUT:
  97. outfile = opt_arg();
  98. break;
  99. case OPT_ENGINE:
  100. e = setup_engine(opt_arg(), 0);
  101. break;
  102. case OPT_ASN1PARSE:
  103. asn1parse = 1;
  104. break;
  105. case OPT_HEXDUMP:
  106. hexdump = 1;
  107. break;
  108. case OPT_RSA_RAW:
  109. pad = RSA_NO_PADDING;
  110. break;
  111. case OPT_OAEP:
  112. pad = RSA_PKCS1_OAEP_PADDING;
  113. break;
  114. case OPT_PKCS:
  115. pad = RSA_PKCS1_PADDING;
  116. break;
  117. case OPT_X931:
  118. pad = RSA_X931_PADDING;
  119. break;
  120. case OPT_SIGN:
  121. rsa_mode = RSA_SIGN;
  122. need_priv = 1;
  123. break;
  124. case OPT_VERIFY:
  125. rsa_mode = RSA_VERIFY;
  126. break;
  127. case OPT_REV:
  128. rev = 1;
  129. break;
  130. case OPT_ENCRYPT:
  131. rsa_mode = RSA_ENCRYPT;
  132. break;
  133. case OPT_DECRYPT:
  134. rsa_mode = RSA_DECRYPT;
  135. need_priv = 1;
  136. break;
  137. case OPT_PUBIN:
  138. key_type = KEY_PUBKEY;
  139. break;
  140. case OPT_CERTIN:
  141. key_type = KEY_CERT;
  142. break;
  143. case OPT_INKEY:
  144. keyfile = opt_arg();
  145. break;
  146. case OPT_PASSIN:
  147. passinarg = opt_arg();
  148. break;
  149. case OPT_R_CASES:
  150. if (!opt_rand(o))
  151. goto end;
  152. break;
  153. case OPT_PROV_CASES:
  154. if (!opt_provider(o))
  155. goto end;
  156. break;
  157. }
  158. }
  159. /* No extra arguments. */
  160. if (!opt_check_rest_arg(NULL))
  161. goto opthelp;
  162. if (!app_RAND_load())
  163. goto end;
  164. if (need_priv && (key_type != KEY_PRIVKEY)) {
  165. BIO_printf(bio_err, "A private key is needed for this operation\n");
  166. goto end;
  167. }
  168. if (!app_passwd(passinarg, NULL, &passin, NULL)) {
  169. BIO_printf(bio_err, "Error getting password\n");
  170. goto end;
  171. }
  172. switch (key_type) {
  173. case KEY_PRIVKEY:
  174. pkey = load_key(keyfile, keyformat, 0, passin, e, "private key");
  175. break;
  176. case KEY_PUBKEY:
  177. pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "public key");
  178. break;
  179. case KEY_CERT:
  180. x = load_cert(keyfile, FORMAT_UNDEF, "Certificate");
  181. if (x) {
  182. pkey = X509_get_pubkey(x);
  183. X509_free(x);
  184. }
  185. break;
  186. }
  187. if (pkey == NULL)
  188. return 1;
  189. in = bio_open_default(infile, 'r', FORMAT_BINARY);
  190. if (in == NULL)
  191. goto end;
  192. out = bio_open_default(outfile, 'w', FORMAT_BINARY);
  193. if (out == NULL)
  194. goto end;
  195. keysize = EVP_PKEY_get_size(pkey);
  196. rsa_in = app_malloc(keysize * 2, "hold rsa key");
  197. rsa_out = app_malloc(keysize, "output rsa key");
  198. rsa_outlen = keysize;
  199. /* Read the input data */
  200. rv = BIO_read(in, rsa_in, keysize * 2);
  201. if (rv < 0) {
  202. BIO_printf(bio_err, "Error reading input Data\n");
  203. goto end;
  204. }
  205. rsa_inlen = rv;
  206. if (rev) {
  207. size_t i;
  208. unsigned char ctmp;
  209. for (i = 0; i < rsa_inlen / 2; i++) {
  210. ctmp = rsa_in[i];
  211. rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
  212. rsa_in[rsa_inlen - 1 - i] = ctmp;
  213. }
  214. }
  215. if ((ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) == NULL)
  216. goto end;
  217. switch (rsa_mode) {
  218. case RSA_VERIFY:
  219. rv = EVP_PKEY_verify_recover_init(ctx) > 0
  220. && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0
  221. && EVP_PKEY_verify_recover(ctx, rsa_out, &rsa_outlen,
  222. rsa_in, rsa_inlen) > 0;
  223. break;
  224. case RSA_SIGN:
  225. rv = EVP_PKEY_sign_init(ctx) > 0
  226. && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0
  227. && EVP_PKEY_sign(ctx, rsa_out, &rsa_outlen, rsa_in, rsa_inlen) > 0;
  228. break;
  229. case RSA_ENCRYPT:
  230. rv = EVP_PKEY_encrypt_init(ctx) > 0
  231. && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0
  232. && EVP_PKEY_encrypt(ctx, rsa_out, &rsa_outlen, rsa_in, rsa_inlen) > 0;
  233. break;
  234. case RSA_DECRYPT:
  235. rv = EVP_PKEY_decrypt_init(ctx) > 0
  236. && EVP_PKEY_CTX_set_rsa_padding(ctx, pad) > 0
  237. && EVP_PKEY_decrypt(ctx, rsa_out, &rsa_outlen, rsa_in, rsa_inlen) > 0;
  238. break;
  239. }
  240. if (!rv) {
  241. BIO_printf(bio_err, "RSA operation error\n");
  242. ERR_print_errors(bio_err);
  243. goto end;
  244. }
  245. ret = 0;
  246. if (asn1parse) {
  247. if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
  248. ERR_print_errors(bio_err);
  249. }
  250. } else if (hexdump) {
  251. BIO_dump(out, (char *)rsa_out, rsa_outlen);
  252. } else {
  253. BIO_write(out, rsa_out, rsa_outlen);
  254. }
  255. end:
  256. EVP_PKEY_CTX_free(ctx);
  257. EVP_PKEY_free(pkey);
  258. release_engine(e);
  259. BIO_free(in);
  260. BIO_free_all(out);
  261. OPENSSL_free(rsa_in);
  262. OPENSSL_free(rsa_out);
  263. OPENSSL_free(passin);
  264. return ret;
  265. }