1251875Speter/* apps/dh.c */ 2251875Speter/* obsoleted by dhparam.c */ 3251875Speter/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 4251875Speter * All rights reserved. 5251875Speter * 6251875Speter * This package is an SSL implementation written 7251875Speter * by Eric Young (eay@cryptsoft.com). 8251875Speter * The implementation was written so as to conform with Netscapes SSL. 9251875Speter * 10251875Speter * This library is free for commercial and non-commercial use as long as 11251875Speter * the following conditions are aheared to. The following conditions 12251875Speter * apply to all code found in this distribution, be it the RC4, RSA, 13251875Speter * lhash, DES, etc., code; not just the SSL code. The SSL documentation 14251875Speter * included with this distribution is covered by the same copyright terms 15251875Speter * except that the holder is Tim Hudson (tjh@cryptsoft.com). 16251875Speter * 17251875Speter * Copyright remains Eric Young's, and as such any Copyright notices in 18251875Speter * the code are not to be removed. 19251875Speter * If this package is used in a product, Eric Young should be given attribution 20251875Speter * as the author of the parts of the library used. 21251875Speter * This can be in the form of a textual message at program startup or 22251875Speter * in documentation (online or textual) provided with the package. 23251875Speter * 24251875Speter * Redistribution and use in source and binary forms, with or without 25251875Speter * modification, are permitted provided that the following conditions 26251875Speter * are met: 27251875Speter * 1. Redistributions of source code must retain the copyright 28251875Speter * notice, this list of conditions and the following disclaimer. 29251875Speter * 2. Redistributions in binary form must reproduce the above copyright 30251875Speter * notice, this list of conditions and the following disclaimer in the 31251875Speter * documentation and/or other materials provided with the distribution. 32251875Speter * 3. All advertising materials mentioning features or use of this software 33251875Speter * must display the following acknowledgement: 34251875Speter * "This product includes cryptographic software written by 35251875Speter * Eric Young (eay@cryptsoft.com)" 36251875Speter * The word 'cryptographic' can be left out if the rouines from the library 37251875Speter * being used are not cryptographic related :-). 38251875Speter * 4. If you include any Windows specific code (or a derivative thereof) from 39251875Speter * the apps directory (application code) you must include an acknowledgement: 40251875Speter * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 41251875Speter * 42251875Speter * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 43251875Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44251875Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45251875Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 46251875Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47251875Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48251875Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49251875Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50251875Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51251875Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52251875Speter * SUCH DAMAGE. 53251875Speter * 54251875Speter * The licence and distribution terms for any publically available version or 55251875Speter * derivative of this code cannot be changed. i.e. this code cannot simply be 56251875Speter * copied and put under another distribution licence 57251875Speter * [including the GNU Public Licence.] 58251875Speter */ 59251875Speter 60251875Speter#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */ 61251875Speter#ifndef OPENSSL_NO_DH 62251875Speter# include <stdio.h> 63251875Speter# include <stdlib.h> 64251875Speter# include <time.h> 65251875Speter# include <string.h> 66251875Speter# include "apps.h" 67251875Speter# include <openssl/bio.h> 68251875Speter# include <openssl/err.h> 69251875Speter# include <openssl/bn.h> 70251875Speter# include <openssl/dh.h> 71251875Speter# include <openssl/x509.h> 72251875Speter# include <openssl/pem.h> 73251875Speter 74251875Speter# undef PROG 75251875Speter# define PROG dh_main 76251875Speter 77251875Speter/*- 78251875Speter * -inform arg - input format - default PEM (DER or PEM) 79251875Speter * -outform arg - output format - default PEM 80251875Speter * -in arg - input file - default stdin 81251875Speter * -out arg - output file - default stdout 82251875Speter * -check - check the parameters are ok 83251875Speter * -noout 84251875Speter * -text 85251875Speter * -C 86251875Speter */ 87251875Speter 88251875Speterint MAIN(int, char **); 89251875Speter 90251875Speterint MAIN(int argc, char **argv) 91251875Speter{ 92251875Speter DH *dh = NULL; 93251875Speter int i, badops = 0, text = 0; 94251875Speter BIO *in = NULL, *out = NULL; 95251875Speter int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; 96251875Speter char *infile, *outfile, *prog; 97251875Speter# ifndef OPENSSL_NO_ENGINE 98251875Speter char *engine; 99251875Speter# endif 100251875Speter 101251875Speter apps_startup(); 102251875Speter 103251875Speter if (bio_err == NULL) 104251875Speter if ((bio_err = BIO_new(BIO_s_file())) != NULL) 105362181Sdim BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 106362181Sdim 107251875Speter if (!load_config(bio_err, NULL)) 108251875Speter goto end; 109251875Speter 110251875Speter# ifndef OPENSSL_NO_ENGINE 111251875Speter engine = NULL; 112251875Speter# endif 113251875Speter infile = NULL; 114251875Speter outfile = NULL; 115251875Speter informat = FORMAT_PEM; 116251875Speter outformat = FORMAT_PEM; 117251875Speter 118251875Speter prog = argv[0]; 119251875Speter argc--; 120251875Speter argv++; 121251875Speter while (argc >= 1) { 122251875Speter if (strcmp(*argv, "-inform") == 0) { 123251875Speter if (--argc < 1) 124251875Speter goto bad; 125251875Speter informat = str2fmt(*(++argv)); 126251875Speter } else if (strcmp(*argv, "-outform") == 0) { 127251875Speter if (--argc < 1) 128251875Speter goto bad; 129251875Speter outformat = str2fmt(*(++argv)); 130251875Speter } else if (strcmp(*argv, "-in") == 0) { 131251875Speter if (--argc < 1) 132251875Speter goto bad; 133251875Speter infile = *(++argv); 134251875Speter } else if (strcmp(*argv, "-out") == 0) { 135251875Speter if (--argc < 1) 136251875Speter goto bad; 137251875Speter outfile = *(++argv); 138251875Speter } 139251875Speter# ifndef OPENSSL_NO_ENGINE 140251875Speter else if (strcmp(*argv, "-engine") == 0) { 141251875Speter if (--argc < 1) 142251875Speter goto bad; 143251875Speter engine = *(++argv); 144251875Speter } 145251875Speter# endif 146251875Speter else if (strcmp(*argv, "-check") == 0) 147251875Speter check = 1; 148251875Speter else if (strcmp(*argv, "-text") == 0) 149251875Speter text = 1; 150251875Speter else if (strcmp(*argv, "-C") == 0) 151251875Speter C = 1; 152251875Speter else if (strcmp(*argv, "-noout") == 0) 153251875Speter noout = 1; 154251875Speter else { 155251875Speter BIO_printf(bio_err, "unknown option %s\n", *argv); 156251875Speter badops = 1; 157251875Speter break; 158251875Speter } 159251875Speter argc--; 160251875Speter argv++; 161251875Speter } 162251875Speter 163251875Speter if (badops) { 164251875Speter bad: 165251875Speter BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 166251875Speter BIO_printf(bio_err, "where options are\n"); 167251875Speter BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); 168251875Speter BIO_printf(bio_err, 169251875Speter " -outform arg output format - one of DER PEM\n"); 170251875Speter BIO_printf(bio_err, " -in arg input file\n"); 171266735Speter BIO_printf(bio_err, " -out arg output file\n"); 172266735Speter BIO_printf(bio_err, " -check check the DH parameters\n"); 173266735Speter BIO_printf(bio_err, 174266735Speter " -text print a text form of the DH parameters\n"); 175266735Speter BIO_printf(bio_err, " -C Output C code\n"); 176266735Speter BIO_printf(bio_err, " -noout no output\n"); 177266735Speter# ifndef OPENSSL_NO_ENGINE 178266735Speter BIO_printf(bio_err, 179266735Speter " -engine e use engine e, possibly a hardware device.\n"); 180266735Speter# endif 181266735Speter goto end; 182266735Speter } 183266735Speter 184266735Speter ERR_load_crypto_strings(); 185266735Speter 186266735Speter# ifndef OPENSSL_NO_ENGINE 187266735Speter setup_engine(bio_err, engine, 0); 188266735Speter# endif 189266735Speter 190266735Speter in = BIO_new(BIO_s_file()); 191266735Speter out = BIO_new(BIO_s_file()); 192251875Speter if ((in == NULL) || (out == NULL)) { 193251875Speter ERR_print_errors(bio_err); 194251875Speter goto end; 195251875Speter } 196251875Speter 197251875Speter if (infile == NULL) 198251875Speter BIO_set_fp(in, stdin, BIO_NOCLOSE); 199251875Speter else { 200251875Speter if (BIO_read_filename(in, infile) <= 0) { 201251875Speter perror(infile); 202251875Speter goto end; 203251875Speter } 204251875Speter } 205251875Speter if (outfile == NULL) { 206251875Speter BIO_set_fp(out, stdout, BIO_NOCLOSE); 207251875Speter# ifdef OPENSSL_SYS_VMS 208251875Speter { 209251875Speter BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 210251875Speter out = BIO_push(tmpbio, out); 211251875Speter } 212251875Speter# endif 213251875Speter } else { 214251875Speter if (BIO_write_filename(out, outfile) <= 0) { 215251875Speter perror(outfile); 216251875Speter goto end; 217251875Speter } 218251875Speter } 219251875Speter 220251875Speter if (informat == FORMAT_ASN1) 221251875Speter dh = d2i_DHparams_bio(in, NULL); 222251875Speter else if (informat == FORMAT_PEM) 223251875Speter dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 224251875Speter else { 225251875Speter BIO_printf(bio_err, "bad input format specified\n"); 226251875Speter goto end; 227251875Speter } 228251875Speter if (dh == NULL) { 229251875Speter BIO_printf(bio_err, "unable to load DH parameters\n"); 230251875Speter ERR_print_errors(bio_err); 231251875Speter goto end; 232251875Speter } 233251875Speter 234251875Speter if (text) { 235251875Speter DHparams_print(out, dh); 236251875Speter# ifdef undef 237251875Speter printf("p="); 238251875Speter BN_print(stdout, dh->p); 239251875Speter printf("\ng="); 240251875Speter BN_print(stdout, dh->g); 241251875Speter printf("\n"); 242251875Speter if (dh->length != 0) 243251875Speter printf("recommended private length=%ld\n", dh->length); 244251875Speter# endif 245251875Speter } 246251875Speter 247251875Speter if (check) { 248251875Speter if (!DH_check(dh, &i)) { 249251875Speter ERR_print_errors(bio_err); 250251875Speter goto end; 251251875Speter } 252251875Speter if (i & DH_CHECK_P_NOT_PRIME) 253251875Speter printf("p value is not prime\n"); 254251875Speter if (i & DH_CHECK_P_NOT_SAFE_PRIME) 255251875Speter printf("p value is not a safe prime\n"); 256251875Speter if (i & DH_UNABLE_TO_CHECK_GENERATOR) 257251875Speter printf("unable to check the generator value\n"); 258251875Speter if (i & DH_NOT_SUITABLE_GENERATOR) 259251875Speter printf("the g value is not a generator\n"); 260251875Speter if (i == 0) 261251875Speter printf("DH parameters appear to be ok.\n"); 262251875Speter } 263251875Speter if (C) { 264251875Speter unsigned char *data; 265251875Speter int len, l, bits; 266251875Speter 267251875Speter len = BN_num_bytes(dh->p); 268251875Speter bits = BN_num_bits(dh->p); 269251875Speter data = (unsigned char *)OPENSSL_malloc(len); 270251875Speter if (data == NULL) { 271251875Speter perror("OPENSSL_malloc"); 272251875Speter goto end; 273251875Speter } 274251875Speter l = BN_bn2bin(dh->p, data); 275251875Speter printf("static unsigned char dh%d_p[]={", bits); 276251875Speter for (i = 0; i < l; i++) { 277251875Speter if ((i % 12) == 0) 278251875Speter printf("\n\t"); 279251875Speter printf("0x%02X,", data[i]); 280251875Speter } 281251875Speter printf("\n\t};\n"); 282251875Speter 283251875Speter l = BN_bn2bin(dh->g, data); 284 printf("static unsigned char dh%d_g[]={", bits); 285 for (i = 0; i < l; i++) { 286 if ((i % 12) == 0) 287 printf("\n\t"); 288 printf("0x%02X,", data[i]); 289 } 290 printf("\n\t};\n\n"); 291 292 printf("DH *get_dh%d()\n\t{\n", bits); 293 printf("\tDH *dh;\n\n"); 294 printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); 295 printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", 296 bits, bits); 297 printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", 298 bits, bits); 299 printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); 300 printf("\t\treturn(NULL);\n"); 301 printf("\treturn(dh);\n\t}\n"); 302 OPENSSL_free(data); 303 } 304 305 if (!noout) { 306 if (outformat == FORMAT_ASN1) 307 i = i2d_DHparams_bio(out, dh); 308 else if (outformat == FORMAT_PEM) 309 i = PEM_write_bio_DHparams(out, dh); 310 else { 311 BIO_printf(bio_err, "bad output format specified for outfile\n"); 312 goto end; 313 } 314 if (!i) { 315 BIO_printf(bio_err, "unable to write DH parameters\n"); 316 ERR_print_errors(bio_err); 317 goto end; 318 } 319 } 320 ret = 0; 321 end: 322 if (in != NULL) 323 BIO_free(in); 324 if (out != NULL) 325 BIO_free_all(out); 326 if (dh != NULL) 327 DH_free(dh); 328 apps_shutdown(); 329 OPENSSL_EXIT(ret); 330} 331#else /* !OPENSSL_NO_DH */ 332 333# if PEDANTIC 334static void *dummy = &dummy; 335# endif 336 337#endif 338