dh.c revision 312826
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/*- 78 * -inform arg - input format - default PEM (DER or PEM) 79 * -outform arg - output format - default PEM 80 * -in arg - input file - default stdin 81 * -out arg - output file - default stdout 82 * -check - check the parameters are ok 83 * -noout 84 * -text 85 * -C 86 */ 87 88int MAIN(int, char **); 89 90int MAIN(int argc, char **argv) 91{ 92 DH *dh = NULL; 93 int i, badops = 0, text = 0; 94 BIO *in = NULL, *out = NULL; 95 int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; 96 char *infile, *outfile, *prog; 97 char *engine; 98 99 apps_startup(); 100 101 if (bio_err == NULL) 102 if ((bio_err = BIO_new(BIO_s_file())) != NULL) 103 BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 104 105 if (!load_config(bio_err, NULL)) 106 goto end; 107 108 engine = NULL; 109 infile = NULL; 110 outfile = NULL; 111 informat = FORMAT_PEM; 112 outformat = FORMAT_PEM; 113 114 prog = argv[0]; 115 argc--; 116 argv++; 117 while (argc >= 1) { 118 if (strcmp(*argv, "-inform") == 0) { 119 if (--argc < 1) 120 goto bad; 121 informat = str2fmt(*(++argv)); 122 } else if (strcmp(*argv, "-outform") == 0) { 123 if (--argc < 1) 124 goto bad; 125 outformat = str2fmt(*(++argv)); 126 } else if (strcmp(*argv, "-in") == 0) { 127 if (--argc < 1) 128 goto bad; 129 infile = *(++argv); 130 } else if (strcmp(*argv, "-out") == 0) { 131 if (--argc < 1) 132 goto bad; 133 outfile = *(++argv); 134 } 135# ifndef OPENSSL_NO_ENGINE 136 else if (strcmp(*argv, "-engine") == 0) { 137 if (--argc < 1) 138 goto bad; 139 engine = *(++argv); 140 } 141# endif 142 else if (strcmp(*argv, "-check") == 0) 143 check = 1; 144 else if (strcmp(*argv, "-text") == 0) 145 text = 1; 146 else if (strcmp(*argv, "-C") == 0) 147 C = 1; 148 else if (strcmp(*argv, "-noout") == 0) 149 noout = 1; 150 else { 151 BIO_printf(bio_err, "unknown option %s\n", *argv); 152 badops = 1; 153 break; 154 } 155 argc--; 156 argv++; 157 } 158 159 if (badops) { 160 bad: 161 BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 162 BIO_printf(bio_err, "where options are\n"); 163 BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); 164 BIO_printf(bio_err, 165 " -outform arg output format - one of DER PEM\n"); 166 BIO_printf(bio_err, " -in arg input file\n"); 167 BIO_printf(bio_err, " -out arg output file\n"); 168 BIO_printf(bio_err, " -check check the DH parameters\n"); 169 BIO_printf(bio_err, 170 " -text print a text form of the DH parameters\n"); 171 BIO_printf(bio_err, " -C Output C code\n"); 172 BIO_printf(bio_err, " -noout no output\n"); 173# ifndef OPENSSL_NO_ENGINE 174 BIO_printf(bio_err, 175 " -engine e use engine e, possibly a hardware device.\n"); 176# endif 177 goto end; 178 } 179 180 ERR_load_crypto_strings(); 181 182 setup_engine(bio_err, engine, 0); 183 184 in = BIO_new(BIO_s_file()); 185 out = BIO_new(BIO_s_file()); 186 if ((in == NULL) || (out == NULL)) { 187 ERR_print_errors(bio_err); 188 goto end; 189 } 190 191 if (infile == NULL) 192 BIO_set_fp(in, stdin, BIO_NOCLOSE); 193 else { 194 if (BIO_read_filename(in, infile) <= 0) { 195 perror(infile); 196 goto end; 197 } 198 } 199 if (outfile == NULL) { 200 BIO_set_fp(out, stdout, BIO_NOCLOSE); 201# ifdef OPENSSL_SYS_VMS 202 { 203 BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 204 out = BIO_push(tmpbio, out); 205 } 206# endif 207 } else { 208 if (BIO_write_filename(out, outfile) <= 0) { 209 perror(outfile); 210 goto end; 211 } 212 } 213 214 if (informat == FORMAT_ASN1) 215 dh = d2i_DHparams_bio(in, NULL); 216 else if (informat == FORMAT_PEM) 217 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 218 else { 219 BIO_printf(bio_err, "bad input format specified\n"); 220 goto end; 221 } 222 if (dh == NULL) { 223 BIO_printf(bio_err, "unable to load DH parameters\n"); 224 ERR_print_errors(bio_err); 225 goto end; 226 } 227 228 if (text) { 229 DHparams_print(out, dh); 230# ifdef undef 231 printf("p="); 232 BN_print(stdout, dh->p); 233 printf("\ng="); 234 BN_print(stdout, dh->g); 235 printf("\n"); 236 if (dh->length != 0) 237 printf("recommended private length=%ld\n", dh->length); 238# endif 239 } 240 241 if (check) { 242 if (!DH_check(dh, &i)) { 243 ERR_print_errors(bio_err); 244 goto end; 245 } 246 if (i & DH_CHECK_P_NOT_PRIME) 247 printf("p value is not prime\n"); 248 if (i & DH_CHECK_P_NOT_SAFE_PRIME) 249 printf("p value is not a safe prime\n"); 250 if (i & DH_UNABLE_TO_CHECK_GENERATOR) 251 printf("unable to check the generator value\n"); 252 if (i & DH_NOT_SUITABLE_GENERATOR) 253 printf("the g value is not a generator\n"); 254 if (i == 0) 255 printf("DH parameters appear to be ok.\n"); 256 } 257 if (C) { 258 unsigned char *data; 259 int len, l, bits; 260 261 len = BN_num_bytes(dh->p); 262 bits = BN_num_bits(dh->p); 263 data = (unsigned char *)OPENSSL_malloc(len); 264 if (data == NULL) { 265 perror("OPENSSL_malloc"); 266 goto end; 267 } 268 l = BN_bn2bin(dh->p, data); 269 printf("static unsigned char dh%d_p[]={", bits); 270 for (i = 0; i < l; i++) { 271 if ((i % 12) == 0) 272 printf("\n\t"); 273 printf("0x%02X,", data[i]); 274 } 275 printf("\n\t};\n"); 276 277 l = BN_bn2bin(dh->g, data); 278 printf("static unsigned char dh%d_g[]={", bits); 279 for (i = 0; i < l; i++) { 280 if ((i % 12) == 0) 281 printf("\n\t"); 282 printf("0x%02X,", data[i]); 283 } 284 printf("\n\t};\n\n"); 285 286 printf("DH *get_dh%d()\n\t{\n", bits); 287 printf("\tDH *dh;\n\n"); 288 printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); 289 printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", 290 bits, bits); 291 printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", 292 bits, bits); 293 printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); 294 printf("\t\treturn(NULL);\n"); 295 printf("\treturn(dh);\n\t}\n"); 296 OPENSSL_free(data); 297 } 298 299 if (!noout) { 300 if (outformat == FORMAT_ASN1) 301 i = i2d_DHparams_bio(out, dh); 302 else if (outformat == FORMAT_PEM) 303 i = PEM_write_bio_DHparams(out, dh); 304 else { 305 BIO_printf(bio_err, "bad output format specified for outfile\n"); 306 goto end; 307 } 308 if (!i) { 309 BIO_printf(bio_err, "unable to write DH parameters\n"); 310 ERR_print_errors(bio_err); 311 goto end; 312 } 313 } 314 ret = 0; 315 end: 316 if (in != NULL) 317 BIO_free(in); 318 if (out != NULL) 319 BIO_free_all(out); 320 if (dh != NULL) 321 DH_free(dh); 322 apps_shutdown(); 323 OPENSSL_EXIT(ret); 324} 325#else /* !OPENSSL_NO_DH */ 326 327# if PEDANTIC 328static void *dummy = &dummy; 329# endif 330 331#endif 332