155714Skris/* apps/dh.c */ 259191Skris/* obsoleted by dhparam.c */ 355714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 455714Skris * All rights reserved. 555714Skris * 655714Skris * This package is an SSL implementation written 755714Skris * by Eric Young (eay@cryptsoft.com). 855714Skris * The implementation was written so as to conform with Netscapes SSL. 9296341Sdelphij * 1055714Skris * This library is free for commercial and non-commercial use as long as 1155714Skris * the following conditions are aheared to. The following conditions 1255714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1355714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1455714Skris * included with this distribution is covered by the same copyright terms 1555714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 16296341Sdelphij * 1755714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1855714Skris * the code are not to be removed. 1955714Skris * If this package is used in a product, Eric Young should be given attribution 2055714Skris * as the author of the parts of the library used. 2155714Skris * This can be in the form of a textual message at program startup or 2255714Skris * in documentation (online or textual) provided with the package. 23296341Sdelphij * 2455714Skris * Redistribution and use in source and binary forms, with or without 2555714Skris * modification, are permitted provided that the following conditions 2655714Skris * are met: 2755714Skris * 1. Redistributions of source code must retain the copyright 2855714Skris * notice, this list of conditions and the following disclaimer. 2955714Skris * 2. Redistributions in binary form must reproduce the above copyright 3055714Skris * notice, this list of conditions and the following disclaimer in the 3155714Skris * documentation and/or other materials provided with the distribution. 3255714Skris * 3. All advertising materials mentioning features or use of this software 3355714Skris * must display the following acknowledgement: 3455714Skris * "This product includes cryptographic software written by 3555714Skris * Eric Young (eay@cryptsoft.com)" 3655714Skris * The word 'cryptographic' can be left out if the rouines from the library 3755714Skris * being used are not cryptographic related :-). 38296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3955714Skris * the apps directory (application code) you must include an acknowledgement: 4055714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 41296341Sdelphij * 4255714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4355714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4455714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4555714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4655714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4755714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4855714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4955714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5055714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5155714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5255714Skris * SUCH DAMAGE. 53296341Sdelphij * 5455714Skris * The licence and distribution terms for any publically available version or 5555714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5655714Skris * copied and put under another distribution licence 5755714Skris * [including the GNU Public Licence.] 5855714Skris */ 5955714Skris 60296341Sdelphij#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */ 61109998Smarkm#ifndef OPENSSL_NO_DH 62296341Sdelphij# include <stdio.h> 63296341Sdelphij# include <stdlib.h> 64296341Sdelphij# include <time.h> 65296341Sdelphij# include <string.h> 66296341Sdelphij# include "apps.h" 67296341Sdelphij# include <openssl/bio.h> 68296341Sdelphij# include <openssl/err.h> 69296341Sdelphij# include <openssl/bn.h> 70296341Sdelphij# include <openssl/dh.h> 71296341Sdelphij# include <openssl/x509.h> 72296341Sdelphij# include <openssl/pem.h> 7355714Skris 74296341Sdelphij# undef PROG 75296341Sdelphij# define PROG dh_main 7655714Skris 77296341Sdelphij/*- 78296341Sdelphij * -inform arg - input format - default PEM (DER or PEM) 7955714Skris * -outform arg - output format - default PEM 80296341Sdelphij * -in arg - input file - default stdin 81296341Sdelphij * -out arg - output file - default stdout 82296341Sdelphij * -check - check the parameters are ok 8355714Skris * -noout 8455714Skris * -text 8555714Skris * -C 8655714Skris */ 8755714Skris 8859191Skrisint MAIN(int, char **); 8959191Skris 9055714Skrisint MAIN(int argc, char **argv) 91296341Sdelphij{ 92296341Sdelphij DH *dh = NULL; 93296341Sdelphij int i, badops = 0, text = 0; 94296341Sdelphij BIO *in = NULL, *out = NULL; 95296341Sdelphij int informat, outformat, check = 0, noout = 0, C = 0, ret = 1; 96296341Sdelphij char *infile, *outfile, *prog; 97296341Sdelphij# ifndef OPENSSL_NO_ENGINE 98296341Sdelphij char *engine; 99296341Sdelphij# endif 10055714Skris 101296341Sdelphij apps_startup(); 10255714Skris 103296341Sdelphij if (bio_err == NULL) 104296341Sdelphij if ((bio_err = BIO_new(BIO_s_file())) != NULL) 105296341Sdelphij BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 10655714Skris 107296341Sdelphij if (!load_config(bio_err, NULL)) 108296341Sdelphij goto end; 109109998Smarkm 110296341Sdelphij# ifndef OPENSSL_NO_ENGINE 111296341Sdelphij engine = NULL; 112296341Sdelphij# endif 113296341Sdelphij infile = NULL; 114296341Sdelphij outfile = NULL; 115296341Sdelphij informat = FORMAT_PEM; 116296341Sdelphij outformat = FORMAT_PEM; 11755714Skris 118296341Sdelphij prog = argv[0]; 119296341Sdelphij argc--; 120296341Sdelphij argv++; 121296341Sdelphij while (argc >= 1) { 122296341Sdelphij if (strcmp(*argv, "-inform") == 0) { 123296341Sdelphij if (--argc < 1) 124296341Sdelphij goto bad; 125296341Sdelphij informat = str2fmt(*(++argv)); 126296341Sdelphij } else if (strcmp(*argv, "-outform") == 0) { 127296341Sdelphij if (--argc < 1) 128296341Sdelphij goto bad; 129296341Sdelphij outformat = str2fmt(*(++argv)); 130296341Sdelphij } else if (strcmp(*argv, "-in") == 0) { 131296341Sdelphij if (--argc < 1) 132296341Sdelphij goto bad; 133296341Sdelphij infile = *(++argv); 134296341Sdelphij } else if (strcmp(*argv, "-out") == 0) { 135296341Sdelphij if (--argc < 1) 136296341Sdelphij goto bad; 137296341Sdelphij outfile = *(++argv); 138296341Sdelphij } 139296341Sdelphij# ifndef OPENSSL_NO_ENGINE 140296341Sdelphij else if (strcmp(*argv, "-engine") == 0) { 141296341Sdelphij if (--argc < 1) 142296341Sdelphij goto bad; 143296341Sdelphij engine = *(++argv); 144296341Sdelphij } 145296341Sdelphij# endif 146296341Sdelphij else if (strcmp(*argv, "-check") == 0) 147296341Sdelphij check = 1; 148296341Sdelphij else if (strcmp(*argv, "-text") == 0) 149296341Sdelphij text = 1; 150296341Sdelphij else if (strcmp(*argv, "-C") == 0) 151296341Sdelphij C = 1; 152296341Sdelphij else if (strcmp(*argv, "-noout") == 0) 153296341Sdelphij noout = 1; 154296341Sdelphij else { 155296341Sdelphij BIO_printf(bio_err, "unknown option %s\n", *argv); 156296341Sdelphij badops = 1; 157296341Sdelphij break; 158296341Sdelphij } 159296341Sdelphij argc--; 160296341Sdelphij argv++; 161296341Sdelphij } 16255714Skris 163296341Sdelphij if (badops) { 164296341Sdelphij bad: 165296341Sdelphij BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 166296341Sdelphij BIO_printf(bio_err, "where options are\n"); 167296341Sdelphij BIO_printf(bio_err, " -inform arg input format - one of DER PEM\n"); 168296341Sdelphij BIO_printf(bio_err, 169296341Sdelphij " -outform arg output format - one of DER PEM\n"); 170296341Sdelphij BIO_printf(bio_err, " -in arg input file\n"); 171296341Sdelphij BIO_printf(bio_err, " -out arg output file\n"); 172296341Sdelphij BIO_printf(bio_err, " -check check the DH parameters\n"); 173296341Sdelphij BIO_printf(bio_err, 174296341Sdelphij " -text print a text form of the DH parameters\n"); 175296341Sdelphij BIO_printf(bio_err, " -C Output C code\n"); 176296341Sdelphij BIO_printf(bio_err, " -noout no output\n"); 177296341Sdelphij# ifndef OPENSSL_NO_ENGINE 178296341Sdelphij BIO_printf(bio_err, 179296341Sdelphij " -engine e use engine e, possibly a hardware device.\n"); 180296341Sdelphij# endif 181296341Sdelphij goto end; 182296341Sdelphij } 18355714Skris 184296341Sdelphij ERR_load_crypto_strings(); 18555714Skris 186296341Sdelphij# ifndef OPENSSL_NO_ENGINE 187296341Sdelphij setup_engine(bio_err, engine, 0); 188296341Sdelphij# endif 189109998Smarkm 190296341Sdelphij in = BIO_new(BIO_s_file()); 191296341Sdelphij out = BIO_new(BIO_s_file()); 192296341Sdelphij if ((in == NULL) || (out == NULL)) { 193296341Sdelphij ERR_print_errors(bio_err); 194296341Sdelphij goto end; 195296341Sdelphij } 19655714Skris 197296341Sdelphij if (infile == NULL) 198296341Sdelphij BIO_set_fp(in, stdin, BIO_NOCLOSE); 199296341Sdelphij else { 200296341Sdelphij if (BIO_read_filename(in, infile) <= 0) { 201296341Sdelphij perror(infile); 202296341Sdelphij goto end; 203296341Sdelphij } 204296341Sdelphij } 205296341Sdelphij if (outfile == NULL) { 206296341Sdelphij BIO_set_fp(out, stdout, BIO_NOCLOSE); 207296341Sdelphij# ifdef OPENSSL_SYS_VMS 208296341Sdelphij { 209296341Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 210296341Sdelphij out = BIO_push(tmpbio, out); 211296341Sdelphij } 212296341Sdelphij# endif 213296341Sdelphij } else { 214296341Sdelphij if (BIO_write_filename(out, outfile) <= 0) { 215296341Sdelphij perror(outfile); 216296341Sdelphij goto end; 217296341Sdelphij } 218296341Sdelphij } 21955714Skris 220296341Sdelphij if (informat == FORMAT_ASN1) 221296341Sdelphij dh = d2i_DHparams_bio(in, NULL); 222296341Sdelphij else if (informat == FORMAT_PEM) 223296341Sdelphij dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 224296341Sdelphij else { 225296341Sdelphij BIO_printf(bio_err, "bad input format specified\n"); 226296341Sdelphij goto end; 227296341Sdelphij } 228296341Sdelphij if (dh == NULL) { 229296341Sdelphij BIO_printf(bio_err, "unable to load DH parameters\n"); 230296341Sdelphij ERR_print_errors(bio_err); 231296341Sdelphij goto end; 232296341Sdelphij } 23355714Skris 234296341Sdelphij if (text) { 235296341Sdelphij DHparams_print(out, dh); 236296341Sdelphij# ifdef undef 237296341Sdelphij printf("p="); 238296341Sdelphij BN_print(stdout, dh->p); 239296341Sdelphij printf("\ng="); 240296341Sdelphij BN_print(stdout, dh->g); 241296341Sdelphij printf("\n"); 242296341Sdelphij if (dh->length != 0) 243296341Sdelphij printf("recommended private length=%ld\n", dh->length); 244296341Sdelphij# endif 245296341Sdelphij } 24655714Skris 247296341Sdelphij if (check) { 248296341Sdelphij if (!DH_check(dh, &i)) { 249296341Sdelphij ERR_print_errors(bio_err); 250296341Sdelphij goto end; 251296341Sdelphij } 252296341Sdelphij if (i & DH_CHECK_P_NOT_PRIME) 253296341Sdelphij printf("p value is not prime\n"); 254296341Sdelphij if (i & DH_CHECK_P_NOT_SAFE_PRIME) 255296341Sdelphij printf("p value is not a safe prime\n"); 256296341Sdelphij if (i & DH_UNABLE_TO_CHECK_GENERATOR) 257296341Sdelphij printf("unable to check the generator value\n"); 258296341Sdelphij if (i & DH_NOT_SUITABLE_GENERATOR) 259296341Sdelphij printf("the g value is not a generator\n"); 260296341Sdelphij if (i == 0) 261296341Sdelphij printf("DH parameters appear to be ok.\n"); 262296341Sdelphij } 263296341Sdelphij if (C) { 264296341Sdelphij unsigned char *data; 265296341Sdelphij int len, l, bits; 26655714Skris 267296341Sdelphij len = BN_num_bytes(dh->p); 268296341Sdelphij bits = BN_num_bits(dh->p); 269296341Sdelphij data = (unsigned char *)OPENSSL_malloc(len); 270296341Sdelphij if (data == NULL) { 271296341Sdelphij perror("OPENSSL_malloc"); 272296341Sdelphij goto end; 273296341Sdelphij } 274296341Sdelphij l = BN_bn2bin(dh->p, data); 275296341Sdelphij printf("static unsigned char dh%d_p[]={", bits); 276296341Sdelphij for (i = 0; i < l; i++) { 277296341Sdelphij if ((i % 12) == 0) 278296341Sdelphij printf("\n\t"); 279296341Sdelphij printf("0x%02X,", data[i]); 280296341Sdelphij } 281296341Sdelphij printf("\n\t};\n"); 28255714Skris 283296341Sdelphij l = BN_bn2bin(dh->g, data); 284296341Sdelphij printf("static unsigned char dh%d_g[]={", bits); 285296341Sdelphij for (i = 0; i < l; i++) { 286296341Sdelphij if ((i % 12) == 0) 287296341Sdelphij printf("\n\t"); 288296341Sdelphij printf("0x%02X,", data[i]); 289296341Sdelphij } 290296341Sdelphij printf("\n\t};\n\n"); 29155714Skris 292296341Sdelphij printf("DH *get_dh%d()\n\t{\n", bits); 293296341Sdelphij printf("\tDH *dh;\n\n"); 294296341Sdelphij printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); 295296341Sdelphij printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", 296296341Sdelphij bits, bits); 297296341Sdelphij printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", 298296341Sdelphij bits, bits); 299296341Sdelphij printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); 300296341Sdelphij printf("\t\treturn(NULL);\n"); 301296341Sdelphij printf("\treturn(dh);\n\t}\n"); 302296341Sdelphij OPENSSL_free(data); 303296341Sdelphij } 30455714Skris 305296341Sdelphij if (!noout) { 306296341Sdelphij if (outformat == FORMAT_ASN1) 307296341Sdelphij i = i2d_DHparams_bio(out, dh); 308296341Sdelphij else if (outformat == FORMAT_PEM) 309296341Sdelphij i = PEM_write_bio_DHparams(out, dh); 310296341Sdelphij else { 311296341Sdelphij BIO_printf(bio_err, "bad output format specified for outfile\n"); 312296341Sdelphij goto end; 313296341Sdelphij } 314296341Sdelphij if (!i) { 315296341Sdelphij BIO_printf(bio_err, "unable to write DH parameters\n"); 316296341Sdelphij ERR_print_errors(bio_err); 317296341Sdelphij goto end; 318296341Sdelphij } 319296341Sdelphij } 320296341Sdelphij ret = 0; 321296341Sdelphij end: 322296341Sdelphij if (in != NULL) 323296341Sdelphij BIO_free(in); 324296341Sdelphij if (out != NULL) 325296341Sdelphij BIO_free_all(out); 326296341Sdelphij if (dh != NULL) 327296341Sdelphij DH_free(dh); 328296341Sdelphij apps_shutdown(); 329296341Sdelphij OPENSSL_EXIT(ret); 330296341Sdelphij} 331296341Sdelphij#else /* !OPENSSL_NO_DH */ 33255714Skris 333238405Sjkim# if PEDANTIC 334296341Sdelphijstatic void *dummy = &dummy; 335238405Sjkim# endif 336238405Sjkim 33755714Skris#endif 338