[BACK]Return to rsa.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Diff for /src/usr.bin/openssl/rsa.c between version 1.2 and 1.3

version 1.2, 2014/08/28 14:23:52 version 1.3, 2015/01/24 05:48:39
Line 58 
Line 58 
   
 #include <openssl/opensslconf.h>  #include <openssl/opensslconf.h>
   
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
Line 74 
Line 73 
 #include <openssl/rsa.h>  #include <openssl/rsa.h>
 #include <openssl/x509.h>  #include <openssl/x509.h>
   
 /* -inform arg  - input format - default PEM (one of DER, NET or PEM)  static struct {
  * -outform arg - output format - default PEM          int check;
  * -in arg      - input file - default stdin          const EVP_CIPHER *enc;
  * -out arg     - output file - default stdout  #ifndef OPENSSL_NO_ENGINE
  * -des         - encrypt output if PEM format with DES in cbc mode          char *engine;
  * -des3        - encrypt output if PEM format  #endif
  * -idea        - encrypt output if PEM format          char *infile;
  * -seed        - encrypt output if PEM format          int informat;
  * -aes128      - encrypt output if PEM format          int modulus;
  * -aes192      - encrypt output if PEM format          int noout;
  * -aes256      - encrypt output if PEM format          char *outfile;
  * -camellia128 - encrypt output if PEM format          int outformat;
  * -camellia192 - encrypt output if PEM format          char *passargin;
  * -camellia256 - encrypt output if PEM format          char *passargout;
  * -text        - print a text version          int pubin;
  * -modulus     - print the RSA key modulus          int pubout;
  * -check       - verify key consistency          int pvk_encr;
  * -pubin       - Expect a public key in input file.          int sgckey;
  * -pubout      - Output a public key.          int text;
  */  } rsa_config;
   
 int rsa_main(int, char **);  static int
   rsa_opt_cipher(int argc, char **argv, int *argsused)
   {
           char *name = argv[0];
   
           if (*name++ != '-')
                   return (1);
   
           if ((rsa_config.enc = EVP_get_cipherbyname(name)) == NULL) {
                   fprintf(stderr, "Invalid cipher '%s'\n", name);
                   return (1);
           }
   
           *argsused = 1;
           return (0);
   }
   
   static struct option rsa_options[] = {
           {
                   .name = "check",
                   .desc = "Check consistency of RSA private key",
                   .type = OPTION_FLAG,
                   .opt.flag = &rsa_config.check,
           },
   #ifndef OPENSSL_NO_ENGINE
           {
                   .name = "engine",
                   .argname = "id",
                   .desc = "Use the engine specified by the given identifier",
                   .type = OPTION_ARG,
                   .opt.arg = &rsa_config.engine,
           },
   #endif
           {
                   .name = "in",
                   .argname = "file",
                   .desc = "Input file (default stdin)",
                   .type = OPTION_ARG,
                   .opt.arg = &rsa_config.infile,
           },
           {
                   .name = "inform",
                   .argname = "format",
                   .desc = "Input format (DER, NET or PEM (default))",
                   .type = OPTION_ARG_FORMAT,
                   .opt.value = &rsa_config.informat,
           },
           {
                   .name = "modulus",
                   .desc = "Print the RSA key modulus",
                   .type = OPTION_FLAG,
                   .opt.flag = &rsa_config.modulus,
           },
           {
                   .name = "noout",
                   .desc = "Do not print encoded version of the key",
                   .type = OPTION_FLAG,
                   .opt.flag = &rsa_config.noout,
           },
           {
                   .name = "out",
                   .argname = "file",
                   .desc = "Output file (default stdout)",
                   .type = OPTION_ARG,
                   .opt.arg = &rsa_config.outfile,
           },
           {
                   .name = "outform",
                   .argname = "format",
                   .desc = "Output format (DER, NET or PEM (default PEM))",
                   .type = OPTION_ARG_FORMAT,
                   .opt.value = &rsa_config.outformat,
           },
           {
                   .name = "passin",
                   .argname = "src",
                   .desc = "Input file passphrase source",
                   .type = OPTION_ARG,
                   .opt.arg = &rsa_config.passargin,
           },
           {
                   .name = "passout",
                   .argname = "src",
                   .desc = "Output file passphrase source",
                   .type = OPTION_ARG,
                   .opt.arg = &rsa_config.passargout,
           },
           {
                   .name = "pubin",
                   .desc = "Expect a public key (default private key)",
                   .type = OPTION_VALUE,
                   .value = 1,
                   .opt.value = &rsa_config.pubin,
           },
           {
                   .name = "pubout",
                   .desc = "Output a public key (default private key)",
                   .type = OPTION_VALUE,
                   .value = 1,
                   .opt.value = &rsa_config.pubout,
           },
           {
                   .name = "pvk-none",
                   .type = OPTION_VALUE,
                   .value = 0,
                   .opt.value = &rsa_config.pvk_encr,
           },
           {
                   .name = "pvk-strong",
                   .type = OPTION_VALUE,
                   .value = 2,
                   .opt.value = &rsa_config.pvk_encr,
           },
           {
                   .name = "pvk-weak",
                   .type = OPTION_VALUE,
                   .value = 1,
                   .opt.value = &rsa_config.pvk_encr,
           },
           {
                   .name = "RSAPublicKey_in",
                   .type = OPTION_VALUE,
                   .value = 2,
                   .opt.value = &rsa_config.pubin,
           },
           {
                   .name = "RSAPublicKey_out",
                   .type = OPTION_VALUE,
                   .value = 2,
                   .opt.value = &rsa_config.pubout,
           },
           {
                   .name = "sgckey",
                   .desc = "Use modified NET algorithm for IIS and SGC keys",
                   .type = OPTION_FLAG,
                   .opt.flag = &rsa_config.sgckey,
           },
           {
                   .name = "text",
                   .desc = "Print in plain text in addition to encoded",
                   .type = OPTION_FLAG,
                   .opt.flag = &rsa_config.text,
           },
           {
                   .name = NULL,
                   .type = OPTION_ARGV_FUNC,
                   .opt.argvfunc = rsa_opt_cipher,
           },
           { NULL }
   };
   
   static void
   show_ciphers(const OBJ_NAME *name, void *arg)
   {
           static int n;
   
           fprintf(stderr, " -%-24s%s", name->name, (++n % 3 ? "" : "\n"));
   }
   
   static void
   rsa_usage()
   {
           fprintf(stderr,
               "usage: rsa [-ciphername] [-check] [-engine id] [-in file] "
               "[-inform fmt]\n"
               "    [-modulus] [-noout] [-out file] [-outform fmt] "
               "[-passin src]\n"
               "    [-passout src] [-pubin] [-pubout] [-sgckey] [-text]\n\n");
           options_usage(rsa_options);
           fprintf(stderr, "\n");
   
           fprintf(stderr, "Valid ciphername values:\n\n");
           OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_ciphers, NULL);
           fprintf(stderr, "\n");
   }
   
 int  int
 rsa_main(int argc, char **argv)  rsa_main(int argc, char **argv)
 {  {
         ENGINE *e = NULL;          ENGINE *e = NULL;
         int ret = 1;          int ret = 1;
         RSA *rsa = NULL;          RSA *rsa = NULL;
         int i, badops = 0, sgckey = 0;          int i;
         const EVP_CIPHER *enc = NULL;  
         BIO *out = NULL;          BIO *out = NULL;
         int informat, outformat, text = 0, check = 0, noout = 0;  
         int pubin = 0, pubout = 0;  
         char *infile, *outfile, *prog;  
         char *passargin = NULL, *passargout = NULL;  
         char *passin = NULL, *passout = NULL;          char *passin = NULL, *passout = NULL;
 #ifndef OPENSSL_NO_ENGINE  
         char *engine = NULL;  
 #endif  
         int modulus = 0;  
   
         int pvk_encr = 2;          memset(&rsa_config, 0, sizeof(rsa_config));
           rsa_config.pvk_encr = 2;
           rsa_config.informat = FORMAT_PEM;
           rsa_config.outformat = FORMAT_PEM;
   
         infile = NULL;          if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) {
         outfile = NULL;                  rsa_usage();
         informat = FORMAT_PEM;  
         outformat = FORMAT_PEM;  
   
         prog = argv[0];  
         argc--;  
         argv++;  
         while (argc >= 1) {  
                 if (strcmp(*argv, "-inform") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         informat = str2fmt(*(++argv));  
                 } else if (strcmp(*argv, "-outform") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         outformat = str2fmt(*(++argv));  
                 } else if (strcmp(*argv, "-in") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         infile = *(++argv);  
                 } else if (strcmp(*argv, "-out") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         outfile = *(++argv);  
                 } else if (strcmp(*argv, "-passin") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         passargin = *(++argv);  
                 } else if (strcmp(*argv, "-passout") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         passargout = *(++argv);  
                 }  
 #ifndef OPENSSL_NO_ENGINE  
                 else if (strcmp(*argv, "-engine") == 0) {  
                         if (--argc < 1)  
                                 goto bad;  
                         engine = *(++argv);  
                 }  
 #endif  
                 else if (strcmp(*argv, "-sgckey") == 0)  
                         sgckey = 1;  
                 else if (strcmp(*argv, "-pubin") == 0)  
                         pubin = 1;  
                 else if (strcmp(*argv, "-pubout") == 0)  
                         pubout = 1;  
                 else if (strcmp(*argv, "-RSAPublicKey_in") == 0)  
                         pubin = 2;  
                 else if (strcmp(*argv, "-RSAPublicKey_out") == 0)  
                         pubout = 2;  
                 else if (strcmp(*argv, "-pvk-strong") == 0)  
                         pvk_encr = 2;  
                 else if (strcmp(*argv, "-pvk-weak") == 0)  
                         pvk_encr = 1;  
                 else if (strcmp(*argv, "-pvk-none") == 0)  
                         pvk_encr = 0;  
                 else if (strcmp(*argv, "-noout") == 0)  
                         noout = 1;  
                 else if (strcmp(*argv, "-text") == 0)  
                         text = 1;  
                 else if (strcmp(*argv, "-modulus") == 0)  
                         modulus = 1;  
                 else if (strcmp(*argv, "-check") == 0)  
                         check = 1;  
                 else if ((enc = EVP_get_cipherbyname(&(argv[0][1]))) == NULL) {  
                         BIO_printf(bio_err, "unknown option %s\n", *argv);  
                         badops = 1;  
                         break;  
                 }  
                 argc--;  
                 argv++;  
         }  
   
         if (badops) {  
 bad:  
                 BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);  
                 BIO_printf(bio_err, "where options are\n");  
                 BIO_printf(bio_err, " -inform arg     input format - one of DER NET PEM\n");  
                 BIO_printf(bio_err, " -outform arg    output format - one of DER NET PEM\n");  
                 BIO_printf(bio_err, " -in arg         input file\n");  
                 BIO_printf(bio_err, " -sgckey         Use IIS SGC key format\n");  
                 BIO_printf(bio_err, " -passin arg     input file pass phrase source\n");  
                 BIO_printf(bio_err, " -out arg        output file\n");  
                 BIO_printf(bio_err, " -passout arg    output file pass phrase source\n");  
                 BIO_printf(bio_err, " -des            encrypt PEM output with cbc des\n");  
                 BIO_printf(bio_err, " -des3           encrypt PEM output with ede cbc des using 168 bit key\n");  
 #ifndef OPENSSL_NO_IDEA  
                 BIO_printf(bio_err, " -idea           encrypt PEM output with cbc idea\n");  
 #endif  
 #ifndef OPENSSL_NO_AES  
                 BIO_printf(bio_err, " -aes128, -aes192, -aes256\n");  
                 BIO_printf(bio_err, "                 encrypt PEM output with cbc aes\n");  
 #endif  
 #ifndef OPENSSL_NO_CAMELLIA  
                 BIO_printf(bio_err, " -camellia128, -camellia192, -camellia256\n");  
                 BIO_printf(bio_err, "                 encrypt PEM output with cbc camellia\n");  
 #endif  
                 BIO_printf(bio_err, " -text           print the key in text\n");  
                 BIO_printf(bio_err, " -noout          don't print key out\n");  
                 BIO_printf(bio_err, " -modulus        print the RSA key modulus\n");  
                 BIO_printf(bio_err, " -check          verify key consistency\n");  
                 BIO_printf(bio_err, " -pubin          expect a public key in input file\n");  
                 BIO_printf(bio_err, " -pubout         output a public key\n");  
 #ifndef OPENSSL_NO_ENGINE  
                 BIO_printf(bio_err, " -engine e       use engine e, possibly a hardware device.\n");  
 #endif  
                 goto end;                  goto end;
         }          }
   
 #ifndef OPENSSL_NO_ENGINE  #ifndef OPENSSL_NO_ENGINE
         e = setup_engine(bio_err, engine, 0);          e = setup_engine(bio_err, rsa_config.engine, 0);
 #endif  #endif
   
         if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {          if (!app_passwd(bio_err, rsa_config.passargin, rsa_config.passargout,
               &passin, &passout)) {
                 BIO_printf(bio_err, "Error getting passwords\n");                  BIO_printf(bio_err, "Error getting passwords\n");
                 goto end;                  goto end;
         }          }
         if (check && pubin) {          if (rsa_config.check && rsa_config.pubin) {
                 BIO_printf(bio_err, "Only private keys can be checked\n");                  BIO_printf(bio_err, "Only private keys can be checked\n");
                 goto end;                  goto end;
         }          }
Line 245 
Line 308 
         {          {
                 EVP_PKEY *pkey;                  EVP_PKEY *pkey;
   
                 if (pubin) {                  if (rsa_config.pubin) {
                         int tmpformat = -1;                          int tmpformat = -1;
                         if (pubin == 2) {                          if (rsa_config.pubin == 2) {
                                 if (informat == FORMAT_PEM)                                  if (rsa_config.informat == FORMAT_PEM)
                                         tmpformat = FORMAT_PEMRSA;                                          tmpformat = FORMAT_PEMRSA;
                                 else if (informat == FORMAT_ASN1)                                  else if (rsa_config.informat == FORMAT_ASN1)
                                         tmpformat = FORMAT_ASN1RSA;                                          tmpformat = FORMAT_ASN1RSA;
                         } else if (informat == FORMAT_NETSCAPE && sgckey)                          } else if (rsa_config.informat == FORMAT_NETSCAPE &&
                               rsa_config.sgckey)
                                 tmpformat = FORMAT_IISSGC;                                  tmpformat = FORMAT_IISSGC;
                         else                          else
                                 tmpformat = informat;                                  tmpformat = rsa_config.informat;
   
                         pkey = load_pubkey(bio_err, infile, tmpformat, 1,                          pkey = load_pubkey(bio_err, rsa_config.infile,
                             passin, e, "Public Key");                              tmpformat, 1, passin, e, "Public Key");
                 } else                  } else
                         pkey = load_key(bio_err, infile,                          pkey = load_key(bio_err, rsa_config.infile,
                             (informat == FORMAT_NETSCAPE && sgckey ?                              (rsa_config.informat == FORMAT_NETSCAPE &&
                                 FORMAT_IISSGC : informat), 1,                              rsa_config.sgckey ? FORMAT_IISSGC :
                             passin, e, "Private Key");                              rsa_config.informat), 1, passin, e, "Private Key");
   
                 if (pkey != NULL)                  if (pkey != NULL)
                         rsa = EVP_PKEY_get1_RSA(pkey);                          rsa = EVP_PKEY_get1_RSA(pkey);
Line 274 
Line 338 
                 ERR_print_errors(bio_err);                  ERR_print_errors(bio_err);
                 goto end;                  goto end;
         }          }
         if (outfile == NULL) {          if (rsa_config.outfile == NULL) {
                 BIO_set_fp(out, stdout, BIO_NOCLOSE);                  BIO_set_fp(out, stdout, BIO_NOCLOSE);
         } else {          } else {
                 if (BIO_write_filename(out, outfile) <= 0) {                  if (BIO_write_filename(out, rsa_config.outfile) <= 0) {
                         perror(outfile);                          perror(rsa_config.outfile);
                         goto end;                          goto end;
                 }                  }
         }          }
   
         if (text)          if (rsa_config.text)
                 if (!RSA_print(out, rsa, 0)) {                  if (!RSA_print(out, rsa, 0)) {
                         perror(outfile);                          perror(rsa_config.outfile);
                         ERR_print_errors(bio_err);                          ERR_print_errors(bio_err);
                         goto end;                          goto end;
                 }                  }
         if (modulus) {          if (rsa_config.modulus) {
                 BIO_printf(out, "Modulus=");                  BIO_printf(out, "Modulus=");
                 BN_print(out, rsa->n);                  BN_print(out, rsa->n);
                 BIO_printf(out, "\n");                  BIO_printf(out, "\n");
         }          }
         if (check) {          if (rsa_config.check) {
                 int r = RSA_check_key(rsa);                  int r = RSA_check_key(rsa);
   
                 if (r == 1)                  if (r == 1)
Line 306 
Line 370 
                             ERR_GET_LIB(err) == ERR_LIB_RSA &&                              ERR_GET_LIB(err) == ERR_LIB_RSA &&
                             ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&                              ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
                             ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {                              ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
                                 BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err));                                  BIO_printf(out, "RSA key error: %s\n",
                                       ERR_reason_error_string(err));
                                 ERR_get_error();        /* remove e from error                                  ERR_get_error();        /* remove e from error
                                                          * stack */                                                           * stack */
                         }                          }
Line 317 
Line 382 
                         goto end;                          goto end;
                 }                  }
         }          }
         if (noout) {          if (rsa_config.noout) {
                 ret = 0;                  ret = 0;
                 goto end;                  goto end;
         }          }
         BIO_printf(bio_err, "writing RSA key\n");          BIO_printf(bio_err, "writing RSA key\n");
         if (outformat == FORMAT_ASN1) {          if (rsa_config.outformat == FORMAT_ASN1) {
                 if (pubout || pubin) {                  if (rsa_config.pubout || rsa_config.pubin) {
                         if (pubout == 2)                          if (rsa_config.pubout == 2)
                                 i = i2d_RSAPublicKey_bio(out, rsa);                                  i = i2d_RSAPublicKey_bio(out, rsa);
                         else                          else
                                 i = i2d_RSA_PUBKEY_bio(out, rsa);                                  i = i2d_RSA_PUBKEY_bio(out, rsa);
Line 332 
Line 397 
                         i = i2d_RSAPrivateKey_bio(out, rsa);                          i = i2d_RSAPrivateKey_bio(out, rsa);
         }          }
 #ifndef OPENSSL_NO_RC4  #ifndef OPENSSL_NO_RC4
         else if (outformat == FORMAT_NETSCAPE) {          else if (rsa_config.outformat == FORMAT_NETSCAPE) {
                 unsigned char *p, *pp;                  unsigned char *p, *pp;
                 int size;                  int size;
   
                 i = 1;                  i = 1;
                 size = i2d_RSA_NET(rsa, NULL, NULL, sgckey);                  size = i2d_RSA_NET(rsa, NULL, NULL, rsa_config.sgckey);
                 if ((p = malloc(size)) == NULL) {                  if ((p = malloc(size)) == NULL) {
                         BIO_printf(bio_err, "Memory allocation failure\n");                          BIO_printf(bio_err, "Memory allocation failure\n");
                         goto end;                          goto end;
                 }                  }
                 pp = p;                  pp = p;
                 i2d_RSA_NET(rsa, &p, NULL, sgckey);                  i2d_RSA_NET(rsa, &p, NULL, rsa_config.sgckey);
                 BIO_write(out, (char *) pp, size);                  BIO_write(out, (char *) pp, size);
                 free(pp);                  free(pp);
         }          }
 #endif  #endif
         else if (outformat == FORMAT_PEM) {          else if (rsa_config.outformat == FORMAT_PEM) {
                 if (pubout || pubin) {                  if (rsa_config.pubout || rsa_config.pubin) {
                         if (pubout == 2)                          if (rsa_config.pubout == 2)
                                 i = PEM_write_bio_RSAPublicKey(out, rsa);                                  i = PEM_write_bio_RSAPublicKey(out, rsa);
                         else                          else
                                 i = PEM_write_bio_RSA_PUBKEY(out, rsa);                                  i = PEM_write_bio_RSA_PUBKEY(out, rsa);
                 } else                  } else
                         i = PEM_write_bio_RSAPrivateKey(out, rsa,                          i = PEM_write_bio_RSAPrivateKey(out, rsa,
                             enc, NULL, 0, NULL, passout);                              rsa_config.enc, NULL, 0, NULL, passout);
 #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)  #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
         } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {          } else if (rsa_config.outformat == FORMAT_MSBLOB ||
               rsa_config.outformat == FORMAT_PVK) {
                 EVP_PKEY *pk;                  EVP_PKEY *pk;
                 pk = EVP_PKEY_new();                  pk = EVP_PKEY_new();
                 EVP_PKEY_set1_RSA(pk, rsa);                  EVP_PKEY_set1_RSA(pk, rsa);
                 if (outformat == FORMAT_PVK)                  if (rsa_config.outformat == FORMAT_PVK)
                         i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);                          i = i2b_PVK_bio(out, pk, rsa_config.pvk_encr, 0,
                 else if (pubin || pubout)                              passout);
                   else if (rsa_config.pubin || rsa_config.pubout)
                         i = i2b_PublicKey_bio(out, pk);                          i = i2b_PublicKey_bio(out, pk);
                 else                  else
                         i = i2b_PrivateKey_bio(out, pk);                          i = i2b_PrivateKey_bio(out, pk);
                 EVP_PKEY_free(pk);                  EVP_PKEY_free(pk);
 #endif  #endif
         } else {          } else {
                 BIO_printf(bio_err, "bad output format specified for outfile\n");                  BIO_printf(bio_err,
                       "bad output format specified for outfile\n");
                 goto end;                  goto end;
         }          }
         if (i <= 0) {          if (i <= 0) {
Line 379 
Line 447 
                 ERR_print_errors(bio_err);                  ERR_print_errors(bio_err);
         } else          } else
                 ret = 0;                  ret = 0;
   
 end:  end:
         if (out != NULL)          BIO_free_all(out);
                 BIO_free_all(out);          RSA_free(rsa);
         if (rsa != NULL)  
                 RSA_free(rsa);  
         free(passin);          free(passin);
         free(passout);          free(passout);
   

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3