Branch data Line data Source code
1 : : /* apps/dh.c */
2 : : /* obsoleted by dhparam.c */
3 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
4 : : * All rights reserved.
5 : : *
6 : : * This package is an SSL implementation written
7 : : * by Eric Young (eay@cryptsoft.com).
8 : : * The implementation was written so as to conform with Netscapes SSL.
9 : : *
10 : : * This library is free for commercial and non-commercial use as long as
11 : : * the following conditions are aheared to. The following conditions
12 : : * apply to all code found in this distribution, be it the RC4, RSA,
13 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
14 : : * included with this distribution is covered by the same copyright terms
15 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
16 : : *
17 : : * Copyright remains Eric Young's, and as such any Copyright notices in
18 : : * the code are not to be removed.
19 : : * If this package is used in a product, Eric Young should be given attribution
20 : : * as the author of the parts of the library used.
21 : : * This can be in the form of a textual message at program startup or
22 : : * in documentation (online or textual) provided with the package.
23 : : *
24 : : * Redistribution and use in source and binary forms, with or without
25 : : * modification, are permitted provided that the following conditions
26 : : * are met:
27 : : * 1. Redistributions of source code must retain the copyright
28 : : * notice, this list of conditions and the following disclaimer.
29 : : * 2. Redistributions in binary form must reproduce the above copyright
30 : : * notice, this list of conditions and the following disclaimer in the
31 : : * documentation and/or other materials provided with the distribution.
32 : : * 3. All advertising materials mentioning features or use of this software
33 : : * must display the following acknowledgement:
34 : : * "This product includes cryptographic software written by
35 : : * Eric Young (eay@cryptsoft.com)"
36 : : * The word 'cryptographic' can be left out if the rouines from the library
37 : : * being used are not cryptographic related :-).
38 : : * 4. If you include any Windows specific code (or a derivative thereof) from
39 : : * the apps directory (application code) you must include an acknowledgement:
40 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41 : : *
42 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
43 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
46 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 : : * SUCH DAMAGE.
53 : : *
54 : : * The licence and distribution terms for any publically available version or
55 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
56 : : * copied and put under another distribution licence
57 : : * [including the GNU Public Licence.]
58 : : */
59 : :
60 : : #include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
61 : : #ifndef OPENSSL_NO_DH
62 : : #include <stdio.h>
63 : : #include <stdlib.h>
64 : : #include <time.h>
65 : : #include <string.h>
66 : : #include "apps.h"
67 : : #include <openssl/bio.h>
68 : : #include <openssl/err.h>
69 : : #include <openssl/bn.h>
70 : : #include <openssl/dh.h>
71 : : #include <openssl/x509.h>
72 : : #include <openssl/pem.h>
73 : :
74 : : #undef PROG
75 : : #define PROG dh_main
76 : :
77 : : /* -inform arg - input format - default PEM (DER or PEM)
78 : : * -outform arg - output format - default PEM
79 : : * -in arg - input file - default stdin
80 : : * -out arg - output file - default stdout
81 : : * -check - check the parameters are ok
82 : : * -noout
83 : : * -text
84 : : * -C
85 : : */
86 : :
87 : : int MAIN(int, char **);
88 : :
89 : 0 : int MAIN(int argc, char **argv)
90 : : {
91 : 0 : DH *dh=NULL;
92 : 0 : int i,badops=0,text=0;
93 : 0 : BIO *in=NULL,*out=NULL;
94 : 0 : int informat,outformat,check=0,noout=0,C=0,ret=1;
95 : : char *infile,*outfile,*prog;
96 : : #ifndef OPENSSL_NO_ENGINE
97 : : char *engine;
98 : : #endif
99 : :
100 : 0 : apps_startup();
101 : :
102 [ # # ]: 0 : if (bio_err == NULL)
103 [ # # ]: 0 : if ((bio_err=BIO_new(BIO_s_file())) != NULL)
104 : 0 : BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
105 : :
106 [ # # ]: 0 : if (!load_config(bio_err, NULL))
107 : : goto end;
108 : :
109 : : #ifndef OPENSSL_NO_ENGINE
110 : 0 : engine=NULL;
111 : : #endif
112 : 0 : infile=NULL;
113 : 0 : outfile=NULL;
114 : 0 : informat=FORMAT_PEM;
115 : 0 : outformat=FORMAT_PEM;
116 : :
117 : 0 : prog=argv[0];
118 : 0 : argc--;
119 : 0 : argv++;
120 [ # # ]: 0 : while (argc >= 1)
121 : : {
122 [ # # ]: 0 : if (strcmp(*argv,"-inform") == 0)
123 : : {
124 [ # # ]: 0 : if (--argc < 1) goto bad;
125 : 0 : informat=str2fmt(*(++argv));
126 : : }
127 [ # # ]: 0 : else if (strcmp(*argv,"-outform") == 0)
128 : : {
129 [ # # ]: 0 : if (--argc < 1) goto bad;
130 : 0 : outformat=str2fmt(*(++argv));
131 : : }
132 [ # # ]: 0 : else if (strcmp(*argv,"-in") == 0)
133 : : {
134 [ # # ]: 0 : if (--argc < 1) goto bad;
135 : 0 : infile= *(++argv);
136 : : }
137 [ # # ]: 0 : else if (strcmp(*argv,"-out") == 0)
138 : : {
139 [ # # ]: 0 : if (--argc < 1) goto bad;
140 : 0 : outfile= *(++argv);
141 : : }
142 : : #ifndef OPENSSL_NO_ENGINE
143 [ # # ]: 0 : else if (strcmp(*argv,"-engine") == 0)
144 : : {
145 [ # # ]: 0 : if (--argc < 1) goto bad;
146 : 0 : engine= *(++argv);
147 : : }
148 : : #endif
149 [ # # ]: 0 : else if (strcmp(*argv,"-check") == 0)
150 : : check=1;
151 [ # # ]: 0 : else if (strcmp(*argv,"-text") == 0)
152 : : text=1;
153 [ # # ]: 0 : else if (strcmp(*argv,"-C") == 0)
154 : : C=1;
155 [ # # ]: 0 : else if (strcmp(*argv,"-noout") == 0)
156 : : noout=1;
157 : : else
158 : : {
159 : 0 : BIO_printf(bio_err,"unknown option %s\n",*argv);
160 : 0 : badops=1;
161 : 0 : break;
162 : : }
163 : 0 : argc--;
164 : 0 : argv++;
165 : : }
166 : :
167 [ # # ]: 0 : if (badops)
168 : : {
169 : : bad:
170 : 0 : BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
171 : 0 : BIO_printf(bio_err,"where options are\n");
172 : 0 : BIO_printf(bio_err," -inform arg input format - one of DER PEM\n");
173 : 0 : BIO_printf(bio_err," -outform arg output format - one of DER PEM\n");
174 : 0 : BIO_printf(bio_err," -in arg input file\n");
175 : 0 : BIO_printf(bio_err," -out arg output file\n");
176 : 0 : BIO_printf(bio_err," -check check the DH parameters\n");
177 : 0 : BIO_printf(bio_err," -text print a text form of the DH parameters\n");
178 : 0 : BIO_printf(bio_err," -C Output C code\n");
179 : 0 : BIO_printf(bio_err," -noout no output\n");
180 : : #ifndef OPENSSL_NO_ENGINE
181 : 0 : BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n");
182 : : #endif
183 : 0 : goto end;
184 : : }
185 : :
186 : 0 : ERR_load_crypto_strings();
187 : :
188 : : #ifndef OPENSSL_NO_ENGINE
189 : 0 : setup_engine(bio_err, engine, 0);
190 : : #endif
191 : :
192 : 0 : in=BIO_new(BIO_s_file());
193 : 0 : out=BIO_new(BIO_s_file());
194 [ # # ]: 0 : if ((in == NULL) || (out == NULL))
195 : : {
196 : 0 : ERR_print_errors(bio_err);
197 : 0 : goto end;
198 : : }
199 : :
200 [ # # ]: 0 : if (infile == NULL)
201 : 0 : BIO_set_fp(in,stdin,BIO_NOCLOSE);
202 : : else
203 : : {
204 [ # # ]: 0 : if (BIO_read_filename(in,infile) <= 0)
205 : : {
206 : 0 : perror(infile);
207 : 0 : goto end;
208 : : }
209 : : }
210 [ # # ]: 0 : if (outfile == NULL)
211 : : {
212 : 0 : BIO_set_fp(out,stdout,BIO_NOCLOSE);
213 : : #ifdef OPENSSL_SYS_VMS
214 : : {
215 : : BIO *tmpbio = BIO_new(BIO_f_linebuffer());
216 : : out = BIO_push(tmpbio, out);
217 : : }
218 : : #endif
219 : : }
220 : : else
221 : : {
222 [ # # ]: 0 : if (BIO_write_filename(out,outfile) <= 0)
223 : : {
224 : 0 : perror(outfile);
225 : 0 : goto end;
226 : : }
227 : : }
228 : :
229 [ # # ]: 0 : if (informat == FORMAT_ASN1)
230 : 0 : dh=d2i_DHparams_bio(in,NULL);
231 [ # # ]: 0 : else if (informat == FORMAT_PEM)
232 : 0 : dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
233 : : else
234 : : {
235 : 0 : BIO_printf(bio_err,"bad input format specified\n");
236 : 0 : goto end;
237 : : }
238 [ # # ]: 0 : if (dh == NULL)
239 : : {
240 : 0 : BIO_printf(bio_err,"unable to load DH parameters\n");
241 : 0 : ERR_print_errors(bio_err);
242 : 0 : goto end;
243 : : }
244 : :
245 : :
246 : :
247 [ # # ]: 0 : if (text)
248 : : {
249 : 0 : DHparams_print(out,dh);
250 : : #ifdef undef
251 : : printf("p=");
252 : : BN_print(stdout,dh->p);
253 : : printf("\ng=");
254 : : BN_print(stdout,dh->g);
255 : : printf("\n");
256 : : if (dh->length != 0)
257 : : printf("recommended private length=%ld\n",dh->length);
258 : : #endif
259 : : }
260 : :
261 [ # # ]: 0 : if (check)
262 : : {
263 [ # # ]: 0 : if (!DH_check(dh,&i))
264 : : {
265 : 0 : ERR_print_errors(bio_err);
266 : 0 : goto end;
267 : : }
268 [ # # ]: 0 : if (i & DH_CHECK_P_NOT_PRIME)
269 : : printf("p value is not prime\n");
270 [ # # ]: 0 : if (i & DH_CHECK_P_NOT_SAFE_PRIME)
271 : : printf("p value is not a safe prime\n");
272 [ # # ]: 0 : if (i & DH_UNABLE_TO_CHECK_GENERATOR)
273 : : printf("unable to check the generator value\n");
274 [ # # ]: 0 : if (i & DH_NOT_SUITABLE_GENERATOR)
275 : : printf("the g value is not a generator\n");
276 [ # # ]: 0 : if (i == 0)
277 : : printf("DH parameters appear to be ok.\n");
278 : : }
279 [ # # ]: 0 : if (C)
280 : : {
281 : : unsigned char *data;
282 : : int len,l,bits;
283 : :
284 : 0 : len=BN_num_bytes(dh->p);
285 : 0 : bits=BN_num_bits(dh->p);
286 : 0 : data=(unsigned char *)OPENSSL_malloc(len);
287 [ # # ]: 0 : if (data == NULL)
288 : : {
289 : 0 : perror("OPENSSL_malloc");
290 : 0 : goto end;
291 : : }
292 : 0 : l=BN_bn2bin(dh->p,data);
293 : : printf("static unsigned char dh%d_p[]={",bits);
294 [ # # ]: 0 : for (i=0; i<l; i++)
295 : : {
296 [ # # ]: 0 : if ((i%12) == 0) printf("\n\t");
297 : 0 : printf("0x%02X,",data[i]);
298 : : }
299 : : printf("\n\t};\n");
300 : :
301 : 0 : l=BN_bn2bin(dh->g,data);
302 : : printf("static unsigned char dh%d_g[]={",bits);
303 [ # # ]: 0 : for (i=0; i<l; i++)
304 : : {
305 [ # # ]: 0 : if ((i%12) == 0) printf("\n\t");
306 : 0 : printf("0x%02X,",data[i]);
307 : : }
308 : : printf("\n\t};\n\n");
309 : :
310 : : printf("DH *get_dh%d()\n\t{\n",bits);
311 : : printf("\tDH *dh;\n\n");
312 : : printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
313 : : printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
314 : : bits,bits);
315 : : printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
316 : : bits,bits);
317 : : printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
318 : : printf("\t\treturn(NULL);\n");
319 : : printf("\treturn(dh);\n\t}\n");
320 : 0 : OPENSSL_free(data);
321 : : }
322 : :
323 : :
324 [ # # ]: 0 : if (!noout)
325 : : {
326 [ # # ]: 0 : if (outformat == FORMAT_ASN1)
327 : 0 : i=i2d_DHparams_bio(out,dh);
328 [ # # ]: 0 : else if (outformat == FORMAT_PEM)
329 : 0 : i=PEM_write_bio_DHparams(out,dh);
330 : : else {
331 : 0 : BIO_printf(bio_err,"bad output format specified for outfile\n");
332 : 0 : goto end;
333 : : }
334 [ # # ]: 0 : if (!i)
335 : : {
336 : 0 : BIO_printf(bio_err,"unable to write DH parameters\n");
337 : 0 : ERR_print_errors(bio_err);
338 : 0 : goto end;
339 : : }
340 : : }
341 : : ret=0;
342 : : end:
343 [ # # ]: 0 : if (in != NULL) BIO_free(in);
344 [ # # ]: 0 : if (out != NULL) BIO_free_all(out);
345 [ # # ]: 0 : if (dh != NULL) DH_free(dh);
346 : : apps_shutdown();
347 : 0 : OPENSSL_EXIT(ret);
348 : : }
349 : : #else /* !OPENSSL_NO_DH */
350 : :
351 : : # if PEDANTIC
352 : : static void *dummy=&dummy;
353 : : # endif
354 : :
355 : : #endif
|