1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60: #include <openssl/opensslconf.h>
61:
62:
63: #ifdef OPENSSL_NO_DEPRECATED
64: #undef OPENSSL_NO_DEPRECATED
65: #endif
66:
67: #ifndef OPENSSL_NO_DH
68: #include <stdio.h>
69: #include <string.h>
70: #include <sys/types.h>
71: #include <sys/stat.h>
72: #include "apps.h"
73: #include <openssl/bio.h>
74: #include <openssl/rand.h>
75: #include <openssl/err.h>
76: #include <openssl/bn.h>
77: #include <openssl/dh.h>
78: #include <openssl/x509.h>
79: #include <openssl/pem.h>
80:
81: #define DEFBITS 512
82: #undef PROG
83: #define PROG gendh_main
84:
85: static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb);
86:
87: int MAIN(int, char **);
88:
89: int MAIN(int argc, char **argv)
90: {
91: BN_GENCB cb;
92: #ifndef OPENSSL_NO_ENGINE
93: ENGINE *e = NULL;
94: #endif
95: DH *dh=NULL;
96: int ret=1,num=DEFBITS;
97: int g=2;
98: char *outfile=NULL;
99: char *inrand=NULL;
100: #ifndef OPENSSL_NO_ENGINE
101: char *engine=NULL;
102: #endif
103: BIO *out=NULL;
104:
105: apps_startup();
106:
107: BN_GENCB_set(&cb, dh_cb, bio_err);
108: if (bio_err == NULL)
109: if ((bio_err=BIO_new(BIO_s_file())) != NULL)
110: BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
111:
112: if (!load_config(bio_err, NULL))
113: goto end;
114:
115: argv++;
116: argc--;
117: for (;;)
118: {
119: if (argc <= 0) break;
120: if (strcmp(*argv,"-out") == 0)
121: {
122: if (--argc < 1) goto bad;
123: outfile= *(++argv);
124: }
125: else if (strcmp(*argv,"-2") == 0)
126: g=2;
127:
128:
129: else if (strcmp(*argv,"-5") == 0)
130: g=5;
131: #ifndef OPENSSL_NO_ENGINE
132: else if (strcmp(*argv,"-engine") == 0)
133: {
134: if (--argc < 1) goto bad;
135: engine= *(++argv);
136: }
137: #endif
138: else if (strcmp(*argv,"-rand") == 0)
139: {
140: if (--argc < 1) goto bad;
141: inrand= *(++argv);
142: }
143: else
144: break;
145: argv++;
146: argc--;
147: }
148: if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
149: {
150: bad:
151: BIO_printf(bio_err,"usage: gendh [args] [numbits]\n");
152: BIO_printf(bio_err," -out file - output the key to 'file\n");
153: BIO_printf(bio_err," -2 - use 2 as the generator value\n");
154:
155: BIO_printf(bio_err," -5 - use 5 as the generator value\n");
156: #ifndef OPENSSL_NO_ENGINE
157: BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
158: #endif
159: BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
160: BIO_printf(bio_err," - load the file (or the files in the directory) into\n");
161: BIO_printf(bio_err," the random number generator\n");
162: goto end;
163: }
164:
165: #ifndef OPENSSL_NO_ENGINE
166: e = setup_engine(bio_err, engine, 0);
167: #endif
168:
169: out=BIO_new(BIO_s_file());
170: if (out == NULL)
171: {
172: ERR_print_errors(bio_err);
173: goto end;
174: }
175:
176: if (outfile == NULL)
177: {
178: BIO_set_fp(out,stdout,BIO_NOCLOSE);
179: #ifdef OPENSSL_SYS_VMS
180: {
181: BIO *tmpbio = BIO_new(BIO_f_linebuffer());
182: out = BIO_push(tmpbio, out);
183: }
184: #endif
185: }
186: else
187: {
188: if (BIO_write_filename(out,outfile) <= 0)
189: {
190: perror(outfile);
191: goto end;
192: }
193: }
194:
195: if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL)
196: {
197: BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
198: }
199: if (inrand != NULL)
200: BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
201: app_RAND_load_files(inrand));
202:
203: BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g);
204: BIO_printf(bio_err,"This is going to take a long time\n");
205:
206: if(((dh = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb))
207: goto end;
208:
209: app_RAND_write_file(NULL, bio_err);
210:
211: if (!PEM_write_bio_DHparams(out,dh))
212: goto end;
213: ret=0;
214: end:
215: if (ret != 0)
216: ERR_print_errors(bio_err);
217: if (out != NULL) BIO_free_all(out);
218: if (dh != NULL) DH_free(dh);
219: apps_shutdown();
220: OPENSSL_EXIT(ret);
221: }
222:
223: static int MS_CALLBACK dh_cb(int p, int n, BN_GENCB *cb)
224: {
225: char c='*';
226:
227: if (p == 0) c='.';
228: if (p == 1) c='+';
229: if (p == 2) c='*';
230: if (p == 3) c='\n';
231: BIO_write(cb->arg,&c,1);
232: (void)BIO_flush(cb->arg);
233: #ifdef LINT
234: p=n;
235: #endif
236: return 1;
237: }
238: #endif