00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #include <openssl/opensslconf.h>
00060
00061
00062 #ifdef OPENSSL_NO_DEPRECATED
00063 #undef OPENSSL_NO_DEPRECATED
00064 #endif
00065
00066 #ifndef OPENSSL_NO_RSA
00067 #include <stdio.h>
00068 #include <string.h>
00069 #include <sys/types.h>
00070 #include <sys/stat.h>
00071 #include "apps.h"
00072 #include <openssl/bio.h>
00073 #include <openssl/err.h>
00074 #include <openssl/bn.h>
00075 #include <openssl/rsa.h>
00076 #include <openssl/evp.h>
00077 #include <openssl/x509.h>
00078 #include <openssl/pem.h>
00079 #include <openssl/rand.h>
00080
00081 #define DEFBITS 512
00082 #undef PROG
00083 #define PROG genrsa_main
00084
00085 static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb);
00086
00087 int MAIN(int, char **);
00088
00089 int MAIN(int argc, char **argv)
00090 {
00091 BN_GENCB cb;
00092 #ifndef OPENSSL_NO_ENGINE
00093 ENGINE *e = NULL;
00094 #endif
00095 int ret=1;
00096 int i,num=DEFBITS;
00097 long l;
00098 const EVP_CIPHER *enc=NULL;
00099 unsigned long f4=RSA_F4;
00100 char *outfile=NULL;
00101 char *passargout = NULL, *passout = NULL;
00102 #ifndef OPENSSL_NO_ENGINE
00103 char *engine=NULL;
00104 #endif
00105 char *inrand=NULL;
00106 BIO *out=NULL;
00107 BIGNUM *bn = BN_new();
00108 RSA *rsa = RSA_new();
00109
00110 if(!bn || !rsa) goto err;
00111
00112 apps_startup();
00113 BN_GENCB_set(&cb, genrsa_cb, bio_err);
00114
00115 if (bio_err == NULL)
00116 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
00117 BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
00118
00119 if (!load_config(bio_err, NULL))
00120 goto err;
00121 if ((out=BIO_new(BIO_s_file())) == NULL)
00122 {
00123 BIO_printf(bio_err,"unable to create BIO for output\n");
00124 goto err;
00125 }
00126
00127 argv++;
00128 argc--;
00129 for (;;)
00130 {
00131 if (argc <= 0) break;
00132 if (strcmp(*argv,"-out") == 0)
00133 {
00134 if (--argc < 1) goto bad;
00135 outfile= *(++argv);
00136 }
00137 else if (strcmp(*argv,"-3") == 0)
00138 f4=3;
00139 else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0)
00140 f4=RSA_F4;
00141 #ifndef OPENSSL_NO_ENGINE
00142 else if (strcmp(*argv,"-engine") == 0)
00143 {
00144 if (--argc < 1) goto bad;
00145 engine= *(++argv);
00146 }
00147 #endif
00148 else if (strcmp(*argv,"-rand") == 0)
00149 {
00150 if (--argc < 1) goto bad;
00151 inrand= *(++argv);
00152 }
00153 #ifndef OPENSSL_NO_DES
00154 else if (strcmp(*argv,"-des") == 0)
00155 enc=EVP_des_cbc();
00156 else if (strcmp(*argv,"-des3") == 0)
00157 enc=EVP_des_ede3_cbc();
00158 #endif
00159 #ifndef OPENSSL_NO_IDEA
00160 else if (strcmp(*argv,"-idea") == 0)
00161 enc=EVP_idea_cbc();
00162 #endif
00163 #ifndef OPENSSL_NO_AES
00164 else if (strcmp(*argv,"-aes128") == 0)
00165 enc=EVP_aes_128_cbc();
00166 else if (strcmp(*argv,"-aes192") == 0)
00167 enc=EVP_aes_192_cbc();
00168 else if (strcmp(*argv,"-aes256") == 0)
00169 enc=EVP_aes_256_cbc();
00170 #endif
00171 else if (strcmp(*argv,"-passout") == 0)
00172 {
00173 if (--argc < 1) goto bad;
00174 passargout= *(++argv);
00175 }
00176 else
00177 break;
00178 argv++;
00179 argc--;
00180 }
00181 if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
00182 {
00183 bad:
00184 BIO_printf(bio_err,"usage: genrsa [args] [numbits]\n");
00185 BIO_printf(bio_err," -des encrypt the generated key with DES in cbc mode\n");
00186 BIO_printf(bio_err," -des3 encrypt the generated key with DES in ede cbc mode (168 bit key)\n");
00187 #ifndef OPENSSL_NO_IDEA
00188 BIO_printf(bio_err," -idea encrypt the generated key with IDEA in cbc mode\n");
00189 #endif
00190 #ifndef OPENSSL_NO_AES
00191 BIO_printf(bio_err," -aes128, -aes192, -aes256\n");
00192 BIO_printf(bio_err," encrypt PEM output with cbc aes\n");
00193 #endif
00194 BIO_printf(bio_err," -out file output the key to 'file\n");
00195 BIO_printf(bio_err," -passout arg output file pass phrase source\n");
00196 BIO_printf(bio_err," -f4 use F4 (0x10001) for the E value\n");
00197 BIO_printf(bio_err," -3 use 3 for the E value\n");
00198 #ifndef OPENSSL_NO_ENGINE
00199 BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
00200 #endif
00201 BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
00202 BIO_printf(bio_err," load the file (or the files in the directory) into\n");
00203 BIO_printf(bio_err," the random number generator\n");
00204 goto err;
00205 }
00206
00207 ERR_load_crypto_strings();
00208
00209 if(!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
00210 BIO_printf(bio_err, "Error getting password\n");
00211 goto err;
00212 }
00213
00214 #ifndef OPENSSL_NO_ENGINE
00215 e = setup_engine(bio_err, engine, 0);
00216 #endif
00217
00218 if (outfile == NULL)
00219 {
00220 BIO_set_fp(out,stdout,BIO_NOCLOSE);
00221 #ifdef OPENSSL_SYS_VMS
00222 {
00223 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
00224 out = BIO_push(tmpbio, out);
00225 }
00226 #endif
00227 }
00228 else
00229 {
00230 if (BIO_write_filename(out,outfile) <= 0)
00231 {
00232 perror(outfile);
00233 goto err;
00234 }
00235 }
00236
00237 if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
00238 && !RAND_status())
00239 {
00240 BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
00241 }
00242 if (inrand != NULL)
00243 BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
00244 app_RAND_load_files(inrand));
00245
00246 BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
00247 num);
00248
00249 if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
00250 goto err;
00251
00252 app_RAND_write_file(NULL, bio_err);
00253
00254
00255
00256 l=0L;
00257 for (i=0; i<rsa->e->top; i++)
00258 {
00259 #ifndef SIXTY_FOUR_BIT
00260 l<<=BN_BITS4;
00261 l<<=BN_BITS4;
00262 #endif
00263 l+=rsa->e->d[i];
00264 }
00265 BIO_printf(bio_err,"e is %ld (0x%lX)\n",l,l);
00266 {
00267 PW_CB_DATA cb_data;
00268 cb_data.password = passout;
00269 cb_data.prompt_info = outfile;
00270 if (!PEM_write_bio_RSAPrivateKey(out,rsa,enc,NULL,0,
00271 (pem_password_cb *)password_callback,&cb_data))
00272 goto err;
00273 }
00274
00275 ret=0;
00276 err:
00277 if (bn) BN_free(bn);
00278 if (rsa) RSA_free(rsa);
00279 if (out) BIO_free_all(out);
00280 if(passout) OPENSSL_free(passout);
00281 if (ret != 0)
00282 ERR_print_errors(bio_err);
00283 apps_shutdown();
00284 OPENSSL_EXIT(ret);
00285 }
00286
00287 static int MS_CALLBACK genrsa_cb(int p, int n, BN_GENCB *cb)
00288 {
00289 char c='*';
00290
00291 if (p == 0) c='.';
00292 if (p == 1) c='+';
00293 if (p == 2) c='*';
00294 if (p == 3) c='\n';
00295 BIO_write(cb->arg,&c,1);
00296 (void)BIO_flush(cb->arg);
00297 #ifdef LINT
00298 p=n;
00299 #endif
00300 return 1;
00301 }
00302 #else
00303
00304 # if PEDANTIC
00305 static void *dummy=&dummy;
00306 # endif
00307
00308 #endif