SecureServer::SecureServer(boost::asio::io_service& ioService, boost::asio::ssl::context& context, const boost::asio::ip::tcp::endpoint& endpoint, const std::string& chain, const std::string& key, const std::string& keyPassword, const std::string& dhFile) throw (boost::system::system_error) : ioService_(ioService), acceptor_(ioService, endpoint), context_(context), keyPassword_(keyPassword) { context_.set_options(context_ops); context_.set_password_callback(boost::bind(&SecureServer::getPassword, this)); context_.use_certificate_chain_file(chain); context_.use_private_key_file(key, boost::asio::ssl::context::pem); if(!boost::filesystem::exists(dhFile)){ std::cerr << "Generating tmp dh file " << dhFile << std::endl; std::unique_ptr<BIO,void(*)(BIO*)> dhBIO(BIO_new_file(dhFile.c_str(),"w"),&BIO_free_all); if(!dhBIO){ throw_system_error_ssl("Could not open "+dhFile+" for writing"); } std::unique_ptr<DH,void(*)(DH*)> dh(DH_generate_parameters(2048, RSA_F4, nullptr, nullptr),&DH_free); if(!dh){ throw_system_error_ssl("Could not DH_generate_parameters"); } if(PEM_write_bio_DHparams(dhBIO.get(),dh.get()) != 1){ throw_system_error_ssl("Could not write DHparams"); } std::cerr << "done" << std::endl; } context_.use_tmp_dh_file(dhFile); }
static void save_dh_params(DH *p, const char *filename) { int fd; BIO *bio; if(p == NULL || filename == NULL) return; fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0600); if(fd < 0) return; bio = BIO_new_fd(fd, 0); if(bio == NULL) { close(fd); return; } mtevL(mtev_notice, "Saving DH parameters to %s.\n", filename); PEM_write_bio_DHparams(bio,p); BIO_free(bio); fchmod(fd, 0400); close(fd); return; }
/* * call-seq: * dh.export -> aString * dh.to_pem -> aString * dh.to_s -> aString * * Encodes this DH to its PEM encoding. Note that any existing per-session * public/private keys will *not* get encoded, just the Diffie-Hellman * parameters will be encoded. */ static VALUE ossl_dh_export(VALUE self) { DH *dh; BIO *out; VALUE str; GetDH(self, dh); if (!(out = BIO_new(BIO_s_mem()))) { ossl_raise(eDHError, NULL); } if (!PEM_write_bio_DHparams(out, dh)) { BIO_free(out); ossl_raise(eDHError, NULL); } str = ossl_membio2str(out); return str; }
/* * call-seq: * dh.export -> aString * dh.to_pem -> aString * dh.to_s -> aString * * Encodes this DH to its PEM encoding. Note that any existing per-session * public/private keys will *not* get encoded, just the Diffie-Hellman * parameters will be encoded. */ static VALUE ossl_dh_export(VALUE self) { EVP_PKEY *pkey; BIO *out; VALUE str; GetPKeyDH(self, pkey); if (!(out = BIO_new(BIO_s_mem()))) { ossl_raise(eDHError, NULL); } if (!PEM_write_bio_DHparams(out, pkey->pkey.dh)) { BIO_free(out); ossl_raise(eDHError, NULL); } str = ossl_membio2str(out); return str; }
std::string SL::Remote_Access_Library::Crypto::Createdhparams(std::string savelocation, std::string filename, int bits) { assert(INTERNAL::Started);//you must ensure proper startup of the encryption library! std::string saveloc = savelocation; if (saveloc.back() != '/' && saveloc.back() != '\\') saveloc += '/'; assert(!saveloc.empty()); DhParamRAII cry; auto keyloc = saveloc + filename + "_dhparams.pem"; if (!DH_generate_parameters_ex(cry.dh, bits, 2, NULL)) return std::string(""); cry.outfile = BIO_new(BIO_s_file()); if (BIO_write_filename(cry.outfile, (void*)keyloc.c_str()) <= 0) return std::string(""); int i = 0; if (cry.dh->q) i = PEM_write_bio_DHxparams(cry.outfile, cry.dh); else i = PEM_write_bio_DHparams(cry.outfile, cry.dh); if (!i) return std::string(""); return keyloc; }
int MAIN(int argc, char **argv) { BIO *in = NULL, *out = NULL; char *infile, *outfile, *prog; char *inrand = NULL; char *id = NULL; apps_startup(); if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; outfile = NULL; 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, "-check") == 0) check = 1; else if (strcmp(*argv, "-text") == 0) text = 1; else if (strcmp(*argv, "-dsaparam") == 0) dsaparam = 1; else if (strcmp(*argv, "-C") == 0) C = 1; else if (strcmp(*argv, "-noout") == 0) noout = 1; else if (strcmp(*argv, "-2") == 0) g = 2; else if (strcmp(*argv, "-5") == 0) g = 5; else if (strcmp(*argv, "-rand") == 0) { if (--argc < 1) goto bad; inrand = *(++argv); } else if (((sscanf(*argv, "%d", &num) == 0) || (num <= 0))) goto bad; argv++; argc--; } if (badops) { bad: BIO_printf(bio_err, "%s [options] [numbits]\n", prog); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); BIO_printf(bio_err, " -outform arg output format - one of DER PEM\n"); BIO_printf(bio_err, " -in arg input file\n"); BIO_printf(bio_err, " -out arg output file\n"); BIO_printf(bio_err, " -dsaparam read or generate DSA parameters, convert to DH\n"); BIO_printf(bio_err, " -check check the DH parameters\n"); BIO_printf(bio_err, " -text print a text form of the DH parameters\n"); BIO_printf(bio_err, " -C Output C code\n"); BIO_printf(bio_err, " -2 generate parameters using 2 as the generator value\n"); BIO_printf(bio_err, " -5 generate parameters using 5 as the generator value\n"); BIO_printf(bio_err, " numbits number of bits in to generate (default 2048)\n"); BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " - load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf(bio_err, " -noout no output\n"); goto end; } ERR_load_crypto_strings(); if (g && !num) num = DEFBITS; if (dsaparam) { if (g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } } else { /* DH parameters */ if (num && !g) g = 2; } if (num) { BN_GENCB cb; BN_GENCB_set(&cb, dh_cb, bio_err); if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa = DSA_new(); BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); if (!dsa || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) { if (dsa) DSA_free(dsa); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else # endif { dh = DH_new(); BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, g); BIO_printf(bio_err, "This is going to take a long time\n"); if (!dh || !DH_generate_parameters_ex(dh, num, g, &cb)) { ERR_print_errors(bio_err); goto end; } } app_RAND_write_file(NULL, bio_err); } else { in = BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } if (informat != FORMAT_ASN1 && informat != FORMAT_PEM) { BIO_printf(bio_err, "bad input format specified\n"); goto end; } # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa; if (informat == FORMAT_ASN1) dsa = d2i_DSAparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); if (dsa == NULL) { BIO_printf(bio_err, "unable to load DSA parameters\n"); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else # endif { if (informat == FORMAT_ASN1) dh = d2i_DHparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } } /* dh != NULL */ } out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } if (text) { DHparams_print(out, dh); } if (check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (C) { unsigned char *data; int len, l, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); data = (unsigned char *)OPENSSL_malloc(len); if (data == NULL) { perror("OPENSSL_malloc"); goto end; } printf("#ifndef HEADER_DH_H\n" "#include <openssl/dh.h>\n" "#endif\n"); printf("DH *get_dh%d()\n\t{\n", bits); l = BN_bn2bin(dh->p, data); printf("\tstatic unsigned char dh%d_p[]={", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t\t"); printf("0x%02X,", data[i]); } printf("\n\t\t};\n"); l = BN_bn2bin(dh->g, data); printf("\tstatic unsigned char dh%d_g[]={", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t\t"); printf("0x%02X,", data[i]); } printf("\n\t\t};\n"); printf("\tDH *dh;\n\n"); printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", bits, bits); printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", bits, bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\t{ DH_free(dh); return(NULL); }\n"); if (dh->length) printf("\tdh->length = %ld;\n", dh->length); printf("\treturn(dh);\n\t}\n"); OPENSSL_free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); else if (outformat == FORMAT_PEM) { if (dh->q) i = PEM_write_bio_DHxparams(out, dh); else i = PEM_write_bio_DHparams(out, dh); } else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); apps_shutdown(); OPENSSL_EXIT(ret); }
int dh_main(int argc, char **argv) { DH *dh = NULL; int i; BIO *in = NULL, *out = NULL; int ret = 1; memset(&dh_config, 0, sizeof(dh_config)); dh_config.informat = FORMAT_PEM; dh_config.outformat = FORMAT_PEM; if (options_parse(argc, argv, dh_options, NULL, NULL) != 0) { dh_usage(); goto end; } in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if (in == NULL || out == NULL) { ERR_print_errors(bio_err); goto end; } if (dh_config.infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, dh_config.infile) <= 0) { perror(dh_config.infile); goto end; } } if (dh_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, dh_config.outfile) <= 0) { perror(dh_config.outfile); goto end; } } if (dh_config.informat == FORMAT_ASN1) dh = d2i_DHparams_bio(in, NULL); else if (dh_config.informat == FORMAT_PEM) dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); else { BIO_printf(bio_err, "bad input format specified\n"); goto end; } if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } if (dh_config.text) { DHparams_print(out, dh); } if (dh_config.check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (dh_config.C) { unsigned char *data; int len, l, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); data = malloc(len); if (data == NULL) { perror("malloc"); goto end; } l = BN_bn2bin(dh->p, data); printf("static unsigned char dh%d_p[] = {", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t"); printf("0x%02X, ", data[i]); } printf("\n\t};\n"); l = BN_bn2bin(dh->g, data); printf("static unsigned char dh%d_g[] = {", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t"); printf("0x%02X, ", data[i]); } printf("\n\t};\n\n"); printf("DH *get_dh%d()\n\t{\n", bits); printf("\tDH *dh;\n\n"); printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n", bits, bits); printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n", bits, bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\treturn(NULL);\n"); printf("\treturn(dh);\n\t}\n"); free(data); } if (!dh_config.noout) { if (dh_config.outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); else if (dh_config.outformat == FORMAT_PEM) i = PEM_write_bio_DHparams(out, dh); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); return (ret); }
int MAIN(int argc, char **argv) { BN_GENCB cb; DH *dh=NULL; int ret=1,num=DEFBITS; int g=2; char *outfile=NULL; char *inrand=NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif BIO *out=NULL; apps_startup(); BN_GENCB_set(&cb, dh_cb, bio_err); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; argv++; argc--; for (;;) { if (argc <= 0) break; if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-2") == 0) g=2; /* else if (strcmp(*argv,"-3") == 0) g=3; */ else if (strcmp(*argv,"-5") == 0) g=5; #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) goto bad; inrand= *(++argv); } else break; argv++; argc--; } if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0))) { bad: BIO_printf(bio_err,"usage: gendh [args] [numbits]\n"); BIO_printf(bio_err," -out file - output the key to 'file\n"); BIO_printf(bio_err," -2 - use 2 as the generator value\n"); /* BIO_printf(bio_err," -3 - use 3 as the generator value\n"); */ BIO_printf(bio_err," -5 - use 5 as the generator value\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err," - load the file (or the files in the directory) into\n"); BIO_printf(bio_err," the random number generator\n"); goto end; } #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif out=BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) { BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g); BIO_printf(bio_err,"This is going to take a long time\n"); if(((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb)) goto end; app_RAND_write_file(NULL, bio_err); if (!PEM_write_bio_DHparams(out,dh)) goto end; ret=0; end: if (ret != 0) ERR_print_errors(bio_err); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); apps_shutdown(); OPENSSL_EXIT(ret); }
int MAIN(int argc, char **argv) { DH *dh = NULL; int i, badops = 0, text = 0; BIO *in = NULL, *out = NULL; int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; char *infile, *outfile, *prog; # ifndef OPENSSL_NO_ENGINE char *engine; # endif apps_startup(); if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; # ifndef OPENSSL_NO_ENGINE engine = NULL; # endif infile = NULL; outfile = NULL; 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); } # ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } # endif else if (strcmp(*argv, "-check") == 0) check = 1; else if (strcmp(*argv, "-text") == 0) text = 1; else if (strcmp(*argv, "-C") == 0) C = 1; else if (strcmp(*argv, "-noout") == 0) noout = 1; else { 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 PEM\n"); BIO_printf(bio_err, " -outform arg output format - one of DER PEM\n"); BIO_printf(bio_err, " -in arg input file\n"); BIO_printf(bio_err, " -out arg output file\n"); BIO_printf(bio_err, " -check check the DH parameters\n"); BIO_printf(bio_err, " -text print a text form of the DH parameters\n"); BIO_printf(bio_err, " -C Output C code\n"); BIO_printf(bio_err, " -noout no output\n"); # ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n"); # endif goto end; } ERR_load_crypto_strings(); # ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); # endif in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); # ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } # endif } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } if (informat == FORMAT_ASN1) dh = d2i_DHparams_bio(in, NULL); else if (informat == FORMAT_PEM) dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); else { BIO_printf(bio_err, "bad input format specified\n"); goto end; } if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } if (text) { DHparams_print(out, dh); # ifdef undef printf("p="); BN_print(stdout, dh->p); printf("\ng="); BN_print(stdout, dh->g); printf("\n"); if (dh->length != 0) printf("recommended private length=%ld\n", dh->length); # endif } if (check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (C) { unsigned char *data; int len, l, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); data = (unsigned char *)OPENSSL_malloc(len); if (data == NULL) { perror("OPENSSL_malloc"); goto end; } l = BN_bn2bin(dh->p, data); printf("static unsigned char dh%d_p[]={", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t"); printf("0x%02X,", data[i]); } printf("\n\t};\n"); l = BN_bn2bin(dh->g, data); printf("static unsigned char dh%d_g[]={", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t"); printf("0x%02X,", data[i]); } printf("\n\t};\n\n"); printf("DH *get_dh%d()\n\t{\n", bits); printf("\tDH *dh;\n\n"); printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", bits, bits); printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", bits, bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\treturn(NULL);\n"); printf("\treturn(dh);\n\t}\n"); OPENSSL_free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); else if (outformat == FORMAT_PEM) i = PEM_write_bio_DHparams(out, dh); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); apps_shutdown(); OPENSSL_EXIT(ret); }
void Server::initializeCert() { QByteArray crt, key, pass, dhparams; crt = getConf("certificate", QString()).toByteArray(); key = getConf("key", QString()).toByteArray(); pass = getConf("passphrase", QByteArray()).toByteArray(); dhparams = getConf("sslDHParams", Meta::mp.qbaDHParams).toByteArray(); QList<QSslCertificate> ql; // Attempt to load key as an RSA key or a DSA key if (! key.isEmpty()) { qskKey = QSslKey(key, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); if (qskKey.isNull()) qskKey = QSslKey(key, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); } // If we still can't load the key, try loading any keys from the certificate if (qskKey.isNull() && ! crt.isEmpty()) { qskKey = QSslKey(crt, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); if (qskKey.isNull()) qskKey = QSslKey(crt, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); } // If have a key, walk the list of certs, find the one for our key, // remove any certs for our key from the list, what's left is part of // the CA certificate chain. if (! qskKey.isNull()) { ql << QSslCertificate::fromData(crt); ql << QSslCertificate::fromData(key); for (int i=0;i<ql.size();++i) { const QSslCertificate &c = ql.at(i); if (isKeyForCert(qskKey, c)) { qscCert = c; ql.removeAt(i); } } qlCA = ql; } #if defined(USE_QSSLDIFFIEHELLMANPARAMETERS) if (! dhparams.isEmpty()) { QSslDiffieHellmanParameters qdhp = QSslDiffieHellmanParameters(dhparams); if (qdhp.isValid()) { qsdhpDHParams = qdhp; } else { log(QString::fromLatin1("Unable to use specified Diffie-Hellman parameters (sslDHParams): %1").arg(qdhp.errorString())); } } #else if (! dhparams.isEmpty()) { log("Diffie-Hellman parameters (sslDHParams) were specified, but will not be used. This version of Murmur does not support Diffie-Hellman parameters."); } #endif QString issuer; #if QT_VERSION >= 0x050000 QStringList issuerNames = qscCert.issuerInfo(QSslCertificate::CommonName); if (! issuerNames.isEmpty()) { issuer = issuerNames.first(); } #else issuer = qscCert.issuerInfo(QSslCertificate::CommonName); #endif // Really old certs/keys are no good, throw them away so we can // generate a new one below. if (issuer == QString::fromUtf8("Murmur Autogenerated Certificate")) { log("Old autogenerated certificate is unusable for registration, invalidating it"); qscCert = QSslCertificate(); qskKey = QSslKey(); } // If we have a cert, and it's a self-signed one, but we're binding to // all the same addresses as the Meta server is, use it's cert instead. // This allows a self-signed certificate generated by Murmur to be // replaced by a CA-signed certificate in the .ini file. if (!qscCert.isNull() && issuer == QString::fromUtf8("Murmur Autogenerated Certificate v2") && ! Meta::mp.qscCert.isNull() && ! Meta::mp.qskKey.isNull() && (Meta::mp.qlBind == qlBind)) { qscCert = Meta::mp.qscCert; qskKey = Meta::mp.qskKey; } // If we still don't have a certificate by now, try to load the one from Meta if (qscCert.isNull() || qskKey.isNull()) { if (! key.isEmpty() || ! crt.isEmpty()) { log("Certificate specified, but failed to load."); } qskKey = Meta::mp.qskKey; qscCert = Meta::mp.qscCert; // If loading from Meta doesn't work, build+sign a new one if (qscCert.isNull() || qskKey.isNull()) { log("Generating new server certificate."); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); X509 *x509 = X509_new(); EVP_PKEY *pkey = EVP_PKEY_new(); RSA *rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL); EVP_PKEY_assign_RSA(pkey, rsa); X509_set_version(x509, 2); ASN1_INTEGER_set(X509_get_serialNumber(x509),1); X509_gmtime_adj(X509_get_notBefore(x509),0); X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365*20); X509_set_pubkey(x509, pkey); X509_NAME *name=X509_get_subject_name(x509); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char *>(const_cast<char *>("Murmur Autogenerated Certificate v2")), -1, -1, 0); X509_set_issuer_name(x509, name); add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")); add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")); add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")); add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")); X509_sign(x509, pkey, EVP_sha1()); crt.resize(i2d_X509(x509, NULL)); unsigned char *dptr=reinterpret_cast<unsigned char *>(crt.data()); i2d_X509(x509, &dptr); qscCert = QSslCertificate(crt, QSsl::Der); if (qscCert.isNull()) log("Certificate generation failed"); key.resize(i2d_PrivateKey(pkey, NULL)); dptr=reinterpret_cast<unsigned char *>(key.data()); i2d_PrivateKey(pkey, &dptr); qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der); if (qskKey.isNull()) log("Key generation failed"); setConf("certificate", qscCert.toPem()); setConf("key", qskKey.toPem()); } } #if defined(USE_QSSLDIFFIEHELLMANPARAMETERS) if (qsdhpDHParams.isEmpty()) { log("Generating new server 2048-bit Diffie-Hellman parameters. This could take a while..."); DH *dh = DH_new(); if (dh == NULL) { qFatal("DH_new failed: unable to generate Diffie-Hellman parameters for virtual server"); } // Generate DH params. // We register a status callback in order to update the UI // for Murmur on Windows. We don't show the actual status, // but we do it to keep Murmur on Windows responsive while // generating the parameters. BN_GENCB cb; memset(&cb, 0, sizeof(BN_GENCB)); BN_GENCB_set(&cb, dh_progress, NULL); if (DH_generate_parameters_ex(dh, 2048, 2, &cb) == 0) { qFatal("DH_generate_parameters_ex failed: unable to generate Diffie-Hellman parameters for virtual server"); } BIO *mem = BIO_new(BIO_s_mem()); if (PEM_write_bio_DHparams(mem, dh) == 0) { qFatal("PEM_write_bio_DHparams failed: unable to write generated Diffie-Hellman parameters to memory"); } char *pem = NULL; long len = BIO_get_mem_data(mem, &pem); if (len <= 0) { qFatal("BIO_get_mem_data returned an empty or invalid buffer"); } QByteArray pemdh(pem, len); QSslDiffieHellmanParameters qdhp(pemdh); if (!qdhp.isValid()) { qFatal("QSslDiffieHellmanParameters: unable to import generated Diffie-HellmanParameters: %s", qdhp.errorString().toStdString().c_str()); } qsdhpDHParams = qdhp; setConf("sslDHParams", pemdh); BIO_free(mem); DH_free(dh); } #endif // Drain OpenSSL's per-thread error queue // to ensure that errors from the operations // we've done in here do not leak out into // Qt's SSL module. // // If an error leaks, it can break all connections // to the server because each invocation of Qt's SSL // read callback checks OpenSSL's per-thread error // queue (albeit indirectly, via SSL_get_error()). // Qt expects any errors returned from SSL_get_error() // to be related to the QSslSocket it is currently // processing -- which is the obvious thing to expect: // SSL_get_error() takes a pointer to an SSL object // and the return code of the failed operation. // However, it is also documented as: // // "In addition to ssl and ret, SSL_get_error() // inspects the current thread's OpenSSL error // queue." // // So, if any OpenSSL operation on the main thread // forgets to clear the error queue, those errors // *will* leak into other things that *do* error // checking. In our case, into Qt's SSL read callback, // resulting in all clients being disconnected. ERR_clear_error(); }
static LUA_FUNCTION(openssl_pkey_export) { EVP_PKEY * key; int ispriv = 0; int exraw = 0; int expem = 1; size_t passphrase_len = 0; BIO * bio_out = NULL; int ret = 0; const EVP_CIPHER * cipher; const char * passphrase = NULL; key = CHECK_OBJECT(1, EVP_PKEY, "openssl.evp_pkey"); ispriv = openssl_pkey_is_private(key); if (!lua_isnoneornil(L, 2)) expem = lua_toboolean(L, 2); if (expem) { if (!lua_isnoneornil(L, 3)) exraw = lua_toboolean(L, 3); passphrase = luaL_optlstring(L, 4, NULL, &passphrase_len); } else { passphrase = luaL_optlstring(L, 3, NULL, &passphrase_len); } if (passphrase) { cipher = (EVP_CIPHER *) EVP_des_ede3_cbc(); } else { cipher = NULL; } bio_out = BIO_new(BIO_s_mem()); if (expem) { if (exraw==0) { ret = ispriv ? PEM_write_bio_PrivateKey(bio_out, key, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_PUBKEY(bio_out, key); } else { /* export raw key format */ switch (EVP_PKEY_type(key->type)) { case EVP_PKEY_RSA: case EVP_PKEY_RSA2: ret = ispriv ? PEM_write_bio_RSAPrivateKey(bio_out, key->pkey.rsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_RSAPublicKey(bio_out, key->pkey.rsa); break; case EVP_PKEY_DSA: case EVP_PKEY_DSA2: case EVP_PKEY_DSA3: case EVP_PKEY_DSA4: { ret = ispriv ? PEM_write_bio_DSAPrivateKey(bio_out, key->pkey.dsa, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_DSA_PUBKEY(bio_out, key->pkey.dsa); } break; case EVP_PKEY_DH: ret = PEM_write_bio_DHparams(bio_out, key->pkey.dh); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ret = ispriv ? PEM_write_bio_ECPrivateKey(bio_out, key->pkey.ec, cipher, (unsigned char *)passphrase, passphrase_len, NULL, NULL) : PEM_write_bio_EC_PUBKEY(bio_out, key->pkey.ec); break; #endif default: ret = 0; break; } } } else { if (ispriv) { if (passphrase == NULL) { ret = i2d_PrivateKey_bio(bio_out, key); } else { ret = i2d_PKCS8PrivateKey_bio(bio_out, key, cipher, (char *)passphrase, passphrase_len, NULL, NULL); } } else { int l; l = i2d_PublicKey(key, NULL); if (l > 0) { unsigned char* p = malloc(l); unsigned char* pp = p; l = i2d_PublicKey(key, &pp); if (l > 0) { BIO_write(bio_out, p, l); ret = 1; } else ret = 0; free(p); } else ret = 0; } } if (ret) { char * bio_mem_ptr; long bio_mem_len; bio_mem_len = BIO_get_mem_data(bio_out, &bio_mem_ptr); lua_pushlstring(L, bio_mem_ptr, bio_mem_len); ret = 1; } if (bio_out) { BIO_free(bio_out); } return ret; }
void Server::initializeCert() { QByteArray crt, key, pass, dhparams; crt = getConf("certificate", QString()).toByteArray(); key = getConf("key", QString()).toByteArray(); pass = getConf("passphrase", QByteArray()).toByteArray(); dhparams = getConf("sslDHParams", Meta::mp.qbaDHParams).toByteArray(); QList<QSslCertificate> ql; if (! key.isEmpty()) { qskKey = QSslKey(key, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); if (qskKey.isNull()) qskKey = QSslKey(key, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); } if (qskKey.isNull() && ! crt.isEmpty()) { qskKey = QSslKey(crt, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); if (qskKey.isNull()) qskKey = QSslKey(crt, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); } if (! qskKey.isNull()) { ql << QSslCertificate::fromData(crt); ql << QSslCertificate::fromData(key); for (int i=0;i<ql.size();++i) { const QSslCertificate &c = ql.at(i); if (isKeyForCert(qskKey, c)) { qscCert = c; ql.removeAt(i); } } qlCA = ql; } #if defined(USE_QSSLDIFFIEHELLMANPARAMETERS) if (! dhparams.isEmpty()) { QSslDiffieHellmanParameters qdhp = QSslDiffieHellmanParameters(dhparams); if (qdhp.isValid()) { qsdhpDHParams = qdhp; } else { log(QString::fromLatin1("Unable to use specified Diffie-Hellman parameters (sslDHParams): %1").arg(qdhp.errorString())); } } #else if (! dhparams.isEmpty()) { log("Diffie-Hellman parameters (sslDHParams) were specified, but will not be used. This version of Murmur does not support Diffie-Hellman parameters."); } #endif QString issuer; #if QT_VERSION >= 0x050000 QStringList issuerNames = qscCert.issuerInfo(QSslCertificate::CommonName); if (! issuerNames.isEmpty()) { issuer = issuerNames.first(); } #else issuer = qscCert.issuerInfo(QSslCertificate::CommonName); #endif if (issuer == QString::fromUtf8("Murmur Autogenerated Certificate")) { log("Old autogenerated certificate is unusable for registration, invalidating it"); qscCert = QSslCertificate(); qskKey = QSslKey(); } if (!qscCert.isNull() && issuer == QString::fromUtf8("Murmur Autogenerated Certificate v2") && ! Meta::mp.qscCert.isNull() && ! Meta::mp.qskKey.isNull() && (Meta::mp.qlBind == qlBind)) { qscCert = Meta::mp.qscCert; qskKey = Meta::mp.qskKey; } if (qscCert.isNull() || qskKey.isNull()) { if (! key.isEmpty() || ! crt.isEmpty()) { log("Certificate specified, but failed to load."); } qskKey = Meta::mp.qskKey; qscCert = Meta::mp.qscCert; if (qscCert.isNull() || qskKey.isNull()) { log("Generating new server certificate."); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); X509 *x509 = X509_new(); EVP_PKEY *pkey = EVP_PKEY_new(); RSA *rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL); EVP_PKEY_assign_RSA(pkey, rsa); X509_set_version(x509, 2); ASN1_INTEGER_set(X509_get_serialNumber(x509),1); X509_gmtime_adj(X509_get_notBefore(x509),0); X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365*20); X509_set_pubkey(x509, pkey); X509_NAME *name=X509_get_subject_name(x509); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char *>(const_cast<char *>("Murmur Autogenerated Certificate v2")), -1, -1, 0); X509_set_issuer_name(x509, name); add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE")); add_ext(x509, NID_ext_key_usage, SSL_STRING("serverAuth,clientAuth")); add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash")); add_ext(x509, NID_netscape_comment, SSL_STRING("Generated from murmur")); X509_sign(x509, pkey, EVP_sha1()); crt.resize(i2d_X509(x509, NULL)); unsigned char *dptr=reinterpret_cast<unsigned char *>(crt.data()); i2d_X509(x509, &dptr); qscCert = QSslCertificate(crt, QSsl::Der); if (qscCert.isNull()) log("Certificate generation failed"); key.resize(i2d_PrivateKey(pkey, NULL)); dptr=reinterpret_cast<unsigned char *>(key.data()); i2d_PrivateKey(pkey, &dptr); qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der); if (qskKey.isNull()) log("Key generation failed"); setConf("certificate", qscCert.toPem()); setConf("key", qskKey.toPem()); } } #if defined(USE_QSSLDIFFIEHELLMANPARAMETERS) if (qsdhpDHParams.isEmpty()) { log("Generating new server 2048-bit Diffie-Hellman parameters. This could take a while..."); DH *dh = DH_new(); if (dh == NULL) { qFatal("DH_new failed: unable to generate Diffie-Hellman parameters for virtual server"); } // Generate DH params. // We register a status callback in order to update the UI // for Murmur on Windows. We don't show the actual status, // but we do it to keep Murmur on Windows responsive while // generating the parameters. BN_GENCB cb; memset(&cb, 0, sizeof(BN_GENCB)); BN_GENCB_set(&cb, dh_progress, NULL); if (DH_generate_parameters_ex(dh, 2048, 2, &cb) == 0) { qFatal("DH_generate_parameters_ex failed: unable to generate Diffie-Hellman parameters for virtual server"); } BIO *mem = BIO_new(BIO_s_mem()); if (PEM_write_bio_DHparams(mem, dh) == 0) { qFatal("PEM_write_bio_DHparams failed: unable to write generated Diffie-Hellman parameters to memory"); } char *pem = NULL; long len = BIO_get_mem_data(mem, &pem); if (len <= 0) { qFatal("BIO_get_mem_data returned an empty or invalid buffer"); } QByteArray pemdh(pem, len); QSslDiffieHellmanParameters qdhp(pemdh); if (!qdhp.isValid()) { qFatal("QSslDiffieHellmanParameters: unable to import generated Diffie-HellmanParameters: %s", qdhp.errorString().toStdString().c_str()); } qsdhpDHParams = qdhp; setConf("sslDHParams", pemdh); BIO_free(mem); DH_free(dh); } #endif }
inline void dh_key::write_parameters(bio::bio_ptr bio) const { throw_error_if_not(PEM_write_bio_DHparams(bio.raw(), ptr().get()) != 0); }
int dhparam_main(int argc, char **argv) { DH *dh = NULL; int i, badops = 0, text = 0; int dsaparam = 0; BIO *in = NULL, *out = NULL; int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; char *infile, *outfile, *prog; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif int num = 0, g = 0; infile = NULL; outfile = NULL; 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); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } #endif else if (strcmp(*argv, "-check") == 0) check = 1; else if (strcmp(*argv, "-text") == 0) text = 1; else if (strcmp(*argv, "-dsaparam") == 0) dsaparam = 1; else if (strcmp(*argv, "-C") == 0) C = 1; else if (strcmp(*argv, "-noout") == 0) noout = 1; else if (strcmp(*argv, "-2") == 0) g = 2; else if (strcmp(*argv, "-5") == 0) g = 5; else if (((sscanf(*argv, "%d", &num) == 0) || (num <= 0))) goto bad; argv++; argc--; } if (badops) { bad: BIO_printf(bio_err, "%s [options] [numbits]\n", prog); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); BIO_printf(bio_err, " -outform arg output format - one of DER PEM\n"); BIO_printf(bio_err, " -in arg input file\n"); BIO_printf(bio_err, " -out arg output file\n"); BIO_printf(bio_err, " -dsaparam read or generate DSA parameters, convert to DH\n"); BIO_printf(bio_err, " -check check the DH parameters\n"); BIO_printf(bio_err, " -text print a text form of the DH parameters\n"); BIO_printf(bio_err, " -C Output C code\n"); BIO_printf(bio_err, " -2 generate parameters using 2 as the generator value\n"); BIO_printf(bio_err, " -5 generate parameters using 5 as the generator value\n"); BIO_printf(bio_err, " numbits number of bits in to generate (default 512)\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err, " -noout no output\n"); goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif if (g && !num) num = DEFBITS; if (dsaparam) { if (g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } } else { /* DH parameters */ if (num && !g) g = 2; } if (num) { BN_GENCB cb; BN_GENCB_set(&cb, dh_cb, bio_err); if (dsaparam) { DSA *dsa = DSA_new(); BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); if (!dsa || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) { if (dsa) DSA_free(dsa); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else { dh = DH_new(); BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, g); BIO_printf(bio_err, "This is going to take a long time\n"); if (!dh || !DH_generate_parameters_ex(dh, num, g, &cb)) { ERR_print_errors(bio_err); goto end; } } } else { in = BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } if (informat != FORMAT_ASN1 && informat != FORMAT_PEM) { BIO_printf(bio_err, "bad input format specified\n"); goto end; } if (dsaparam) { DSA *dsa; if (informat == FORMAT_ASN1) dsa = d2i_DSAparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); if (dsa == NULL) { BIO_printf(bio_err, "unable to load DSA parameters\n"); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else { if (informat == FORMAT_ASN1) dh = d2i_DHparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } } /* dh != NULL */ } out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } if (text) { DHparams_print(out, dh); } if (check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (C) { unsigned char *data; int len, l, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); data = malloc(len); if (data == NULL) { perror("malloc"); goto end; } printf("#ifndef HEADER_DH_H\n" "#include <openssl/dh.h>\n" "#endif\n"); printf("DH *get_dh%d()\n\t{\n", bits); l = BN_bn2bin(dh->p, data); printf("\tstatic unsigned char dh%d_p[] = {", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t\t"); printf("0x%02X, ", data[i]); } printf("\n\t\t};\n"); l = BN_bn2bin(dh->g, data); printf("\tstatic unsigned char dh%d_g[] = {", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t\t"); printf("0x%02X, ", data[i]); } printf("\n\t\t};\n"); printf("\tDH *dh;\n\n"); printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n", bits, bits); printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n", bits, bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\t{ DH_free(dh); return(NULL); }\n"); if (dh->length) printf("\tdh->length = %ld;\n", dh->length); printf("\treturn(dh);\n\t}\n"); free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); else if (outformat == FORMAT_PEM) i = PEM_write_bio_DHparams(out, dh); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); return (ret); }
int dhparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; char *num_bits = NULL; DH *dh = NULL; int num = 0; int ret = 1; int i; memset(&dhparam_config, 0, sizeof(dhparam_config)); dhparam_config.informat = FORMAT_PEM; dhparam_config.outformat = FORMAT_PEM; if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) { dhparam_usage(); return (1); } if (num_bits != NULL) { if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) { BIO_printf(bio_err, "invalid number of bits: %s\n", num_bits); return (1); } } if (dhparam_config.g && !num) num = DEFBITS; if (dhparam_config.dsaparam) { if (dhparam_config.g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } } else { /* DH parameters */ if (num && !dhparam_config.g) dhparam_config.g = 2; } if (num) { BN_GENCB cb; BN_GENCB_set(&cb, dh_cb, bio_err); if (dhparam_config.dsaparam) { DSA *dsa = DSA_new(); BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); if (!dsa || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) { if (dsa) DSA_free(dsa); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else { dh = DH_new(); BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, dhparam_config.g); BIO_printf(bio_err, "This is going to take a long time\n"); if (!dh || !DH_generate_parameters_ex(dh, num, dhparam_config.g, &cb)) { ERR_print_errors(bio_err); goto end; } } } else { in = BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (dhparam_config.infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, dhparam_config.infile) <= 0) { perror(dhparam_config.infile); goto end; } } if (dhparam_config.informat != FORMAT_ASN1 && dhparam_config.informat != FORMAT_PEM) { BIO_printf(bio_err, "bad input format specified\n"); goto end; } if (dhparam_config.dsaparam) { DSA *dsa; if (dhparam_config.informat == FORMAT_ASN1) dsa = d2i_DSAparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); if (dsa == NULL) { BIO_printf(bio_err, "unable to load DSA parameters\n"); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else { if (dhparam_config.informat == FORMAT_ASN1) dh = d2i_DHparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } } /* dh != NULL */ } out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (dhparam_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, dhparam_config.outfile) <= 0) { perror(dhparam_config.outfile); goto end; } } if (dhparam_config.text) { DHparams_print(out, dh); } if (dhparam_config.check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (dhparam_config.C) { unsigned char *data; int len, l, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); data = malloc(len); if (data == NULL) { perror("malloc"); goto end; } printf("#ifndef HEADER_DH_H\n" "#include <openssl/dh.h>\n" "#endif\n"); printf("DH *get_dh%d()\n\t{\n", bits); l = BN_bn2bin(dh->p, data); printf("\tstatic unsigned char dh%d_p[] = {", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t\t"); printf("0x%02X, ", data[i]); } printf("\n\t\t};\n"); l = BN_bn2bin(dh->g, data); printf("\tstatic unsigned char dh%d_g[] = {", bits); for (i = 0; i < l; i++) { if ((i % 12) == 0) printf("\n\t\t"); printf("0x%02X, ", data[i]); } printf("\n\t\t};\n"); printf("\tDH *dh;\n\n"); printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n", bits, bits); printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n", bits, bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\t{ DH_free(dh); return(NULL); }\n"); if (dh->length) printf("\tdh->length = %ld;\n", dh->length); printf("\treturn(dh);\n\t}\n"); free(data); } if (!dhparam_config.noout) { if (dhparam_config.outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); else if (dhparam_config.outformat == FORMAT_PEM) i = PEM_write_bio_DHparams(out, dh); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); return (ret); }
int dhparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; DH *dh = NULL; char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL; #ifndef OPENSSL_NO_DSA int dsaparam = 0; #endif int i, text = 0, C = 0, ret = 1, num = 0, g = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, dhparam_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(dhparam_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENGINE: (void)setup_engine(opt_arg(), 0); break; case OPT_CHECK: check = 1; break; case OPT_TEXT: text = 1; break; case OPT_DSAPARAM: #ifndef OPENSSL_NO_DSA dsaparam = 1; #endif break; case OPT_C: C = 1; break; case OPT_2: g = 2; break; case OPT_5: g = 5; break; case OPT_NOOUT: noout = 1; break; case OPT_RAND: inrand = opt_arg(); break; } } argc = opt_num_rest(); argv = opt_rest(); if (argv[0] && (!opt_int(argv[0], &num) || num <= 0)) goto end; if (g && !num) num = DEFBITS; # ifndef OPENSSL_NO_DSA if (dsaparam && g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } # endif /* DH parameters */ if (num && !g) g = 2; if (num) { BN_GENCB *cb; cb = BN_GENCB_new(); if (cb == NULL) { ERR_print_errors(bio_err); goto end; } BN_GENCB_set(cb, dh_cb, bio_err); if (!app_RAND_load_file(NULL, 1) && inrand == NULL) { BIO_printf(bio_err, "warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa = DSA_new(); BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); if (dsa == NULL || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) { DSA_free(dsa); BN_GENCB_free(cb); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { BN_GENCB_free(cb); ERR_print_errors(bio_err); goto end; } } else # endif { dh = DH_new(); BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, g); BIO_printf(bio_err, "This is going to take a long time\n"); if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) { BN_GENCB_free(cb); ERR_print_errors(bio_err); goto end; } } BN_GENCB_free(cb); app_RAND_write_file(NULL); } else { in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa; if (informat == FORMAT_ASN1) dsa = d2i_DSAparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); if (dsa == NULL) { BIO_printf(bio_err, "unable to load DSA parameters\n"); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else # endif { if (informat == FORMAT_ASN1) dh = d2i_DHparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } } /* dh != NULL */ } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (text) { DHparams_print(out, dh); } if (check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (C) { unsigned char *data; int len, bits; len = BN_num_bytes(dh->p); bits = BN_num_bits(dh->p); data = app_malloc(len, "print a BN"); BIO_printf(out, "#ifndef HEADER_DH_H\n" "# include <openssl/dh.h>\n" "#endif\n" "\n"); BIO_printf(out, "DH *get_dh%d()\n{\n", bits); print_bignum_var(out, dh->p, "dhp", bits, data); print_bignum_var(out, dh->g, "dhg", bits, data); BIO_printf(out, " DH *dh = DN_new();\n" "\n" " if (dh == NULL)\n" " return NULL;\n"); BIO_printf(out, " dh->p = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n", bits, bits); BIO_printf(out, " dh->g = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n", bits, bits); BIO_printf(out, " if (!dh->p || !dh->g) {\n" " DH_free(dh);\n" " return NULL;\n" " }\n"); if (dh->length) BIO_printf(out, " dh->length = %ld;\n", dh->length); BIO_printf(out, " return dh;\n}\n"); OPENSSL_free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_DHparams_bio(out, dh); else if (dh->q) i = PEM_write_bio_DHxparams(out, dh); else i = PEM_write_bio_DHparams(out, dh); if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: BIO_free(in); BIO_free_all(out); DH_free(dh); return (ret); }
int gendh_main(int argc, char **argv) { BN_GENCB cb; DH *dh = NULL; int ret = 1, num = DEFBITS; int g = 2; char *outfile = NULL; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif BIO *out = NULL; BN_GENCB_set(&cb, dh_cb, bio_err); argv++; argc--; for (;;) { if (argc <= 0) break; if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (strcmp(*argv, "-2") == 0) g = 2; /* * else if (strcmp(*argv,"-3") == 0) g=3; */ else if (strcmp(*argv, "-5") == 0) g = 5; #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv, "-engine") == 0) { if (--argc < 1) goto bad; engine = *(++argv); } #endif else break; argv++; argc--; } if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) { bad: BIO_printf(bio_err, "usage: gendh [args] [numbits]\n"); BIO_printf(bio_err, " -out file - output the key to 'file\n"); BIO_printf(bio_err, " -2 - use 2 as the generator value\n"); /* * BIO_printf(bio_err," -3 - use 3 as the generator * value\n"); */ BIO_printf(bio_err, " -5 - use 5 as the generator value\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, " -engine e - use engine e, possibly a hardware device.\n"); #endif goto end; } #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, g); BIO_printf(bio_err, "This is going to take a long time\n"); if (((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb)) goto end; if (!PEM_write_bio_DHparams(out, dh)) goto end; ret = 0; end: if (ret != 0) ERR_print_errors(bio_err); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); return (ret); }
int dhparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; DH *dh = NULL; char *infile = NULL, *outfile = NULL, *prog; ENGINE *e = NULL; #ifndef OPENSSL_NO_DSA int dsaparam = 0; #endif int i, text = 0, C = 0, ret = 1, num = 0, g = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, dhparam_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(dhparam_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_CHECK: check = 1; break; case OPT_TEXT: text = 1; break; case OPT_DSAPARAM: #ifndef OPENSSL_NO_DSA dsaparam = 1; #endif break; case OPT_C: C = 1; break; case OPT_2: g = 2; break; case OPT_5: g = 5; break; case OPT_NOOUT: noout = 1; break; case OPT_R_CASES: if (!opt_rand(o)) goto end; break; } } argc = opt_num_rest(); argv = opt_rest(); if (argv[0] != NULL && (!opt_int(argv[0], &num) || num <= 0)) goto end; if (g && !num) num = DEFBITS; # ifndef OPENSSL_NO_DSA if (dsaparam && g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } # endif out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; /* DH parameters */ if (num && !g) g = 2; if (num) { BN_GENCB *cb; cb = BN_GENCB_new(); if (cb == NULL) { ERR_print_errors(bio_err); goto end; } BN_GENCB_set(cb, dh_cb, bio_err); # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa = DSA_new(); BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); if (dsa == NULL || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) { DSA_free(dsa); BN_GENCB_free(cb); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { BN_GENCB_free(cb); ERR_print_errors(bio_err); goto end; } } else # endif { dh = DH_new(); BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, g); BIO_printf(bio_err, "This is going to take a long time\n"); if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) { BN_GENCB_free(cb); ERR_print_errors(bio_err); goto end; } } BN_GENCB_free(cb); } else { in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; # ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa; if (informat == FORMAT_ASN1) dsa = d2i_DSAparams_bio(in, NULL); else /* informat == FORMAT_PEM */ dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); if (dsa == NULL) { BIO_printf(bio_err, "unable to load DSA parameters\n"); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else # endif { if (informat == FORMAT_ASN1) { /* * We have no PEM header to determine what type of DH params it * is. We'll just try both. */ dh = d2i_DHparams_bio(in, NULL); /* BIO_reset() returns 0 for success for file BIOs only!!! */ if (dh == NULL && BIO_reset(in) == 0) dh = d2i_DHxparams_bio(in, NULL); } else { /* informat == FORMAT_PEM */ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); } if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } } /* dh != NULL */ } if (text) { DHparams_print(out, dh); } if (check) { if (!DH_check(dh, &i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) BIO_printf(bio_err, "WARNING: p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) BIO_printf(bio_err, "WARNING: p value is not a safe prime\n"); if (i & DH_CHECK_Q_NOT_PRIME) BIO_printf(bio_err, "WARNING: q value is not a prime\n"); if (i & DH_CHECK_INVALID_Q_VALUE) BIO_printf(bio_err, "WARNING: q value is invalid\n"); if (i & DH_CHECK_INVALID_J_VALUE) BIO_printf(bio_err, "WARNING: j value is invalid\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) BIO_printf(bio_err, "WARNING: unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) BIO_printf(bio_err, "WARNING: the g value is not a generator\n"); if (i == 0) BIO_printf(bio_err, "DH parameters appear to be ok.\n"); if (num != 0 && i != 0) { /* * We have generated parameters but DH_check() indicates they are * invalid! This should never happen! */ BIO_printf(bio_err, "ERROR: Invalid parameters generated\n"); goto end; } } if (C) { unsigned char *data; int len, bits; const BIGNUM *pbn, *gbn; len = DH_size(dh); bits = DH_bits(dh); DH_get0_pqg(dh, &pbn, NULL, &gbn); data = app_malloc(len, "print a BN"); BIO_printf(out, "static DH *get_dh%d(void)\n{\n", bits); print_bignum_var(out, pbn, "dhp", bits, data); print_bignum_var(out, gbn, "dhg", bits, data); BIO_printf(out, " DH *dh = DH_new();\n" " BIGNUM *p, *g;\n" "\n" " if (dh == NULL)\n" " return NULL;\n"); BIO_printf(out, " p = BN_bin2bn(dhp_%d, sizeof(dhp_%d), NULL);\n", bits, bits); BIO_printf(out, " g = BN_bin2bn(dhg_%d, sizeof(dhg_%d), NULL);\n", bits, bits); BIO_printf(out, " if (p == NULL || g == NULL\n" " || !DH_set0_pqg(dh, p, NULL, g)) {\n" " DH_free(dh);\n" " BN_free(p);\n" " BN_free(g);\n" " return NULL;\n" " }\n"); if (DH_get_length(dh) > 0) BIO_printf(out, " if (!DH_set_length(dh, %ld)) {\n" " DH_free(dh);\n" " return NULL;\n" " }\n", DH_get_length(dh)); BIO_printf(out, " return dh;\n}\n"); OPENSSL_free(data); } if (!noout) { const BIGNUM *q; DH_get0_pqg(dh, NULL, &q, NULL); if (outformat == FORMAT_ASN1) { if (q != NULL) i = i2d_DHxparams_bio(out, dh); else i = i2d_DHparams_bio(out, dh); } else if (q != NULL) { i = PEM_write_bio_DHxparams(out, dh); } else { i = PEM_write_bio_DHparams(out, dh); } if (!i) { BIO_printf(bio_err, "unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: BIO_free(in); BIO_free_all(out); DH_free(dh); release_engine(e); return ret; }
int gendh_main(int argc, char **argv) { BN_GENCB cb; DH *dh = NULL; int ret = 1, numbits = DEFBITS; BIO *out = NULL; char *strbits = NULL; if (single_execution) { if (pledge("stdio cpath wpath rpath", NULL) == -1) { perror("pledge"); exit(1); } } BN_GENCB_set(&cb, dh_cb, bio_err); memset(&gendh_config, 0, sizeof(gendh_config)); gendh_config.g = 2; if (options_parse(argc, argv, gendh_options, &strbits, NULL) != 0) { gendh_usage(); goto end; } if (strbits != NULL) { const char *errstr; numbits = strtonum(strbits, 0, INT_MAX, &errstr); if (errstr) { fprintf(stderr, "Invalid number of bits: %s\n", errstr); goto end; } } out = BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (gendh_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, gendh_config.outfile) <= 0) { perror(gendh_config.outfile); goto end; } } BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime," " generator %d\n", numbits, gendh_config.g); BIO_printf(bio_err, "This is going to take a long time\n"); if (((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, numbits, gendh_config.g, &cb)) goto end; if (!PEM_write_bio_DHparams(out, dh)) goto end; ret = 0; end: if (ret != 0) ERR_print_errors(bio_err); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); return (ret); }