From 09483c58e3b21841d2761ce90b1f12b24f814881 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sat, 22 Jan 2000 13:58:29 +0000 Subject: [PATCH] Add new program dhparam and update docs. --- CHANGES | 17 +- apps/Makefile.ssl | 8 +- apps/dhparam.c | 366 +++++++++++++++++++++++++++++++ apps/progs.h | 4 + apps/progs.pl | 2 +- doc/apps/{dh.pod => dhparam.pod} | 35 ++- doc/apps/gendh.pod | 74 ------- 7 files changed, 418 insertions(+), 88 deletions(-) create mode 100644 apps/dhparam.c rename doc/apps/{dh.pod => dhparam.pod} (61%) delete mode 100644 doc/apps/gendh.pod diff --git a/CHANGES b/CHANGES index 563ee21606..b1bb986994 100644 --- a/CHANGES +++ b/CHANGES @@ -4,14 +4,21 @@ Changes between 0.9.4 and 0.9.5 [xx XXX 1999] - *) Apply Lutz Jaenicke's 56bit cipher patch. This should fix the problems with cipher - ordering and the new EXPORT1024 ciphers. Only two minor changes have been - made, the error reason codes have been altered and the @STRENGTH sorting - behaviour changed so eNULL ciphers are also sorted (if present). + *) Merge the functionality of "dh" and "gendh" programs into a new program + "dhparam". The old programs are retained for now but will handle DH keys + (instead of parameters) in future. + [Steve Henson] + + *) Apply Lutz Jaenicke's 56bit cipher patch. This should fix the problems + with cipher ordering and the new EXPORT1024 ciphers. Only two minor + changes have been made, the error reason codes have been altered and the + @STRENGTH sorting behaviour changed so eNULL ciphers are also sorted + (if present). One other addition: the "ciphers" program didn't check the return code of SSL_CTX_set_cipher_list(). - [Lutz Jaenicke , minor changes by Steve Henson] + [Lutz Jaenicke modified by Steve Henson] + *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1 for the first serial number and places 2 in the serial number file. This avoids problems when the root CA is created with serial number zero and diff --git a/apps/Makefile.ssl b/apps/Makefile.ssl index d93b984196..380e594e01 100644 --- a/apps/Makefile.ssl +++ b/apps/Makefile.ssl @@ -34,8 +34,8 @@ SCRIPTS=CA.sh CA.pl der_chop EXE= $(PROGRAM) -E_EXE= verify asn1pars req dgst dh enc gendh errstr ca crl \ - rsa dsa dsaparam \ +E_EXE= verify asn1pars req dgst dh dhparam enc gendh errstr \ + ca crl rsa dsa dsaparam \ x509 genrsa gendsa s_server s_client speed \ s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \ pkcs8 spkac smime @@ -49,8 +49,8 @@ S_SRC= s_cb.c s_socket.c RAND_OBJ=app_rand.o RAND_SRC=app_rand.c -E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o enc.o gendh.o errstr.o ca.o \ - pkcs7.o crl2p7.o crl.o \ +E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o gendh.o errstr.o \ + ca.o pkcs7.o crl2p7.o crl.o \ rsa.o dsa.o dsaparam.o \ x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \ s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \ diff --git a/apps/dhparam.c b/apps/dhparam.c new file mode 100644 index 0000000000..a7b4213764 --- /dev/null +++ b/apps/dhparam.c @@ -0,0 +1,366 @@ +/* apps/dh.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef NO_DH +#include +#include +#include +#include +#include "apps.h" +#include +#include +#include +#include +#include +#include + +#undef PROG +#define PROG dhparam_main + +#define DEFBITS 512 + +/* -inform arg - input format - default PEM (DER or PEM) + * -outform arg - output format - default PEM + * -in arg - input file - default stdin + * -out arg - output file - default stdout + * -check - check the parameters are ok + * -noout + * -text + * -C + */ + +static void MS_CALLBACK dh_cb(int p, int n, void *arg); + +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; + char *inrand=NULL; + int num = 0, g = 0; + + 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); + + 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); + } + 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 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," -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"); + BIO_printf(bio_err," -rand file:file:...\n"); + 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; + else if(num && !g) g = 2; + + if(num) { + + 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 strong prime, generator of %d\n",num,g); + BIO_printf(bio_err,"This is going to take a long time\n"); + dh=DH_generate_parameters(num,g,dh_cb,bio_err); + + if (dh == NULL) 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) + 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; + } + + } + + 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_STRONG_PRIME) + printf("p value is not a strong 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 *)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; ig,data); + printf("static unsigned char dh%d_g[]={",bits); + for (i=0; ip=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 (!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 paramaters\n"); + ERR_print_errors(bio_err); + goto end; + } + } + ret=0; +end: + if (in != NULL) BIO_free(in); + if (out != NULL) BIO_free(out); + if (dh != NULL) DH_free(dh); + EXIT(ret); + } + +static void MS_CALLBACK dh_cb(int p, int n, void *arg) + { + char c='*'; + + if (p == 0) c='.'; + if (p == 1) c='+'; + if (p == 2) c='*'; + if (p == 3) c='\n'; + BIO_write((BIO *)arg,&c,1); + (void)BIO_flush((BIO *)arg); +#ifdef LINT + p=n; +#endif + } + +#endif diff --git a/apps/progs.h b/apps/progs.h index e60df2a821..2bd335c39d 100644 --- a/apps/progs.h +++ b/apps/progs.h @@ -5,6 +5,7 @@ extern int asn1parse_main(int argc,char *argv[]); extern int req_main(int argc,char *argv[]); extern int dgst_main(int argc,char *argv[]); extern int dh_main(int argc,char *argv[]); +extern int dhparam_main(int argc,char *argv[]); extern int enc_main(int argc,char *argv[]); extern int gendh_main(int argc,char *argv[]); extern int errstr_main(int argc,char *argv[]); @@ -50,6 +51,9 @@ FUNCTION functions[] = { {FUNC_TYPE_GENERAL,"dgst",dgst_main}, #ifndef NO_DH {FUNC_TYPE_GENERAL,"dh",dh_main}, +#endif +#ifndef NO_DH + {FUNC_TYPE_GENERAL,"dhparam",dhparam_main}, #endif {FUNC_TYPE_GENERAL,"enc",enc_main}, #ifndef NO_DH diff --git a/apps/progs.pl b/apps/progs.pl index 46cf8bf629..243a12d59d 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -34,7 +34,7 @@ foreach (@ARGV) { print "#ifndef NO_RSA\n${str}#endif\n"; } elsif ( ($_ =~ /^dsa$/) || ($_ =~ /^gendsa$/) || ($_ =~ /^dsaparam$/)) { print "#ifndef NO_DSA\n${str}#endif\n"; } - elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/)) + elsif ( ($_ =~ /^dh$/) || ($_ =~ /^gendh$/) || ($_ =~ /^dhparam$/)) { print "#ifndef NO_DH\n${str}#endif\n"; } elsif ( ($_ =~ /^pkcs12$/)) { print "#if !defined(NO_DES) && !defined(NO_SHA1)\n${str}#endif\n"; } diff --git a/doc/apps/dh.pod b/doc/apps/dhparam.pod similarity index 61% rename from doc/apps/dh.pod rename to doc/apps/dhparam.pod index 99b307368f..59d1f68300 100644 --- a/doc/apps/dh.pod +++ b/doc/apps/dhparam.pod @@ -2,7 +2,7 @@ =head1 NAME -dh - DH parameter manipulation and generation +dhparam - DH parameter manipulation and generation =head1 SYNOPSIS @@ -14,6 +14,10 @@ B [B<-noout>] [B<-text>] [B<-C>] +[B<-2>] +[B<-5>] +[B<-rand file(s)>] +[numbits] =head1 DESCRIPTION @@ -46,6 +50,25 @@ This specifies the output filename parameters to. Standard output is used if this option is not present. The output filename should B be the same as the input filename. +=item B<-2>, B<-5> + +The generator to use, either 2 or 5. 2 is the default. If present then the +input file is ignored and parameters are generated instead. + +=item B<-rand file(s)> + +a file or files containing random data used to seed the random number +generator. Multiple files can be specified separated by a OS-dependent +character. For MS-Windows, the separator is B<;>. For OpenVMS, it's +B<,>. For all others, it's B<:>. + +=item B + +this option specifies that a parameter set should be generated of size +B. It must be the last option. If not present then a value of 512 +is used. If this option is present then the input file is ignored and +parameters are generated instead. + =item B<-noout> this option inhibits the output of the encoded version of the parameters. @@ -61,6 +84,13 @@ be loaded by calling the B function. =back +=head1 WARNINGS + +The program B combines the functionality of the programs B and +B in previous versions of OpenSSL and SSLeay. The B and B +programs are retained for now but may have different purposes in future +versions of OpenSSL. + =head1 NOTES PEM format DH parameters use the header and footer lines: @@ -75,9 +105,6 @@ This program manipulates DH parameters not keys. =head1 BUGS -This program is badly named: the B and B programs manipulate keys -and not parameters. - There should be a way to generate and manipulate DH keys. =head1 SEE ALSO diff --git a/doc/apps/gendh.pod b/doc/apps/gendh.pod deleted file mode 100644 index 8262622a3d..0000000000 --- a/doc/apps/gendh.pod +++ /dev/null @@ -1,74 +0,0 @@ -=pod - -=head1 NAME - -gendh - DH parameter generation - -=head1 SYNOPSIS - -B -[B<-out filename>] -[B<-2>] -[B<-5>] -[B<-rand file(s)>] -[numbits] - -=head1 DESCRIPTION - -This command is used to generate DH parameter files. - -=head1 OPTIONS - -=over 4 - -=item B<-out filename> - -This specifies the output filename parameters to. Standard output is used -if this option is not present. The output format is a base64 encoded form of -a PKCS#5 DHParameter structure. - -=item B<-2>, B<-5> - -The generator to use, either 2 or 5. 2 is the default. - -=item B<-rand file(s)> - -a file or files containing random data used to seed the random number -generator. Multiple files can be specified separated by a OS-dependent -character. For MS-Windows, the separator is B<;>. For OpenVMS, it's -B<,>. For all others, it's B<:>. - -=item B - -this option specifies that a parameter set should be generated of size -B. It must be the last option. If not present then a value of 512 -is used. - -=back - -=head1 NOTES - -PEM format DH parameters use the header and footer lines: - - -----BEGIN DH PARAMETERS----- - -----END DH PARAMETERS----- - -DH parameter generation is a slow process and as a result the same set of -DH parameters is often reused. - -OpenSSL currently uses PKCS#3 DH not the more recent X9.42 DH. - -This program creates DH parameters only, not DH keys. - -=head1 BUGS - -The program is badly named. The programs B and B generate -actual keys and not parameters. - -There should be a way to generate and manipulate DH keys. - -=head1 SEE ALSO - -dsaparam(1) - -=cut -- GitLab