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