dh.c revision 109998
1263367Semaste/* apps/dh.c */ 2254721Semaste/* obsoleted by dhparam.c */ 3254721Semaste/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 4254721Semaste * All rights reserved. 5254721Semaste * 6254721Semaste * This package is an SSL implementation written 7254721Semaste * by Eric Young (eay@cryptsoft.com). 8254721Semaste * The implementation was written so as to conform with Netscapes SSL. 9254721Semaste * 10254721Semaste * This library is free for commercial and non-commercial use as long as 11254721Semaste * the following conditions are aheared to. The following conditions 12254721Semaste * apply to all code found in this distribution, be it the RC4, RSA, 13254721Semaste * lhash, DES, etc., code; not just the SSL code. The SSL documentation 14254721Semaste * included with this distribution is covered by the same copyright terms 15254721Semaste * except that the holder is Tim Hudson (tjh@cryptsoft.com). 16269024Semaste * 17254721Semaste * Copyright remains Eric Young's, and as such any Copyright notices in 18254721Semaste * the code are not to be removed. 19263363Semaste * If this package is used in a product, Eric Young should be given attribution 20263363Semaste * as the author of the parts of the library used. 21269024Semaste * This can be in the form of a textual message at program startup or 22269024Semaste * in documentation (online or textual) provided with the package. 23263363Semaste * 24263363Semaste * Redistribution and use in source and binary forms, with or without 25254721Semaste * modification, are permitted provided that the following conditions 26254721Semaste * are met: 27254721Semaste * 1. Redistributions of source code must retain the copyright 28254721Semaste * notice, this list of conditions and the following disclaimer. 29254721Semaste * 2. Redistributions in binary form must reproduce the above copyright 30254721Semaste * notice, this list of conditions and the following disclaimer in the 31254721Semaste * documentation and/or other materials provided with the distribution. 32254721Semaste * 3. All advertising materials mentioning features or use of this software 33254721Semaste * must display the following acknowledgement: 34254721Semaste * "This product includes cryptographic software written by 35254721Semaste * Eric Young (eay@cryptsoft.com)" 36254721Semaste * The word 'cryptographic' can be left out if the rouines from the library 37254721Semaste * being used are not cryptographic related :-). 38254721Semaste * 4. If you include any Windows specific code (or a derivative thereof) from 39254721Semaste * the apps directory (application code) you must include an acknowledgement: 40254721Semaste * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 41254721Semaste * 42254721Semaste * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 43254721Semaste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44254721Semaste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45254721Semaste * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 46254721Semaste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47254721Semaste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48254721Semaste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49254721Semaste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50254721Semaste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51254721Semaste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52254721Semaste * SUCH DAMAGE. 53254721Semaste * 54254721Semaste * The licence and distribution terms for any publically available version or 55254721Semaste * derivative of this code cannot be changed. i.e. this code cannot simply be 56254721Semaste * copied and put under another distribution licence 57254721Semaste * [including the GNU Public Licence.] 58254721Semaste */ 59254721Semaste 60254721Semaste#ifndef OPENSSL_NO_DH 61254721Semaste#include <stdio.h> 62254721Semaste#include <stdlib.h> 63254721Semaste#include <time.h> 64254721Semaste#include <string.h> 65254721Semaste#include "apps.h" 66254721Semaste#include <openssl/bio.h> 67254721Semaste#include <openssl/err.h> 68254721Semaste#include <openssl/bn.h> 69254721Semaste#include <openssl/dh.h> 70254721Semaste#include <openssl/x509.h> 71254721Semaste#include <openssl/pem.h> 72254721Semaste 73254721Semaste#undef PROG 74254721Semaste#define PROG dh_main 75254721Semaste 76254721Semaste/* -inform arg - input format - default PEM (DER or PEM) 77254721Semaste * -outform arg - output format - default PEM 78254721Semaste * -in arg - input file - default stdin 79254721Semaste * -out arg - output file - default stdout 80254721Semaste * -check - check the parameters are ok 81254721Semaste * -noout 82269024Semaste * -text 83269024Semaste * -C 84269024Semaste */ 85269024Semaste 86269024Semasteint MAIN(int, char **); 87254721Semaste 88254721Semasteint MAIN(int argc, char **argv) 89254721Semaste { 90254721Semaste ENGINE *e = NULL; 91263363Semaste DH *dh=NULL; 92263363Semaste int i,badops=0,text=0; 93263363Semaste BIO *in=NULL,*out=NULL; 94263363Semaste int informat,outformat,check=0,noout=0,C=0,ret=1; 95263363Semaste char *infile,*outfile,*prog,*engine; 96263363Semaste 97269024Semaste apps_startup(); 98269024Semaste 99269024Semaste if (bio_err == NULL) 100269024Semaste if ((bio_err=BIO_new(BIO_s_file())) != NULL) 101269024Semaste BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); 102263363Semaste 103263363Semaste if (!load_config(bio_err, NULL)) 104263363Semaste goto end; 105263363Semaste 106263363Semaste engine=NULL; 107263363Semaste infile=NULL; 108263363Semaste outfile=NULL; 109254721Semaste informat=FORMAT_PEM; 110254721Semaste outformat=FORMAT_PEM; 111254721Semaste 112254721Semaste prog=argv[0]; 113269024Semaste argc--; 114269024Semaste argv++; 115269024Semaste while (argc >= 1) 116269024Semaste { 117254721Semaste if (strcmp(*argv,"-inform") == 0) 118254721Semaste { 119254721Semaste if (--argc < 1) goto bad; 120254721Semaste informat=str2fmt(*(++argv)); 121254721Semaste } 122254721Semaste else if (strcmp(*argv,"-outform") == 0) 123254721Semaste { 124254721Semaste if (--argc < 1) goto bad; 125254721Semaste outformat=str2fmt(*(++argv)); 126254721Semaste } 127254721Semaste else if (strcmp(*argv,"-in") == 0) 128254721Semaste { 129254721Semaste if (--argc < 1) goto bad; 130254721Semaste infile= *(++argv); 131254721Semaste } 132254721Semaste else if (strcmp(*argv,"-out") == 0) 133254721Semaste { 134254721Semaste if (--argc < 1) goto bad; 135254721Semaste outfile= *(++argv); 136254721Semaste } 137254721Semaste else if (strcmp(*argv,"-engine") == 0) 138254721Semaste { 139254721Semaste if (--argc < 1) goto bad; 140254721Semaste engine= *(++argv); 141254721Semaste } 142254721Semaste else if (strcmp(*argv,"-check") == 0) 143254721Semaste check=1; 144254721Semaste else if (strcmp(*argv,"-text") == 0) 145254721Semaste text=1; 146254721Semaste else if (strcmp(*argv,"-C") == 0) 147254721Semaste C=1; 148254721Semaste else if (strcmp(*argv,"-noout") == 0) 149254721Semaste noout=1; 150254721Semaste else 151254721Semaste { 152254721Semaste BIO_printf(bio_err,"unknown option %s\n",*argv); 153254721Semaste badops=1; 154254721Semaste break; 155254721Semaste } 156254721Semaste argc--; 157269024Semaste argv++; 158254721Semaste } 159254721Semaste 160254721Semaste if (badops) 161254721Semaste { 162254721Semastebad: 163254721Semaste BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); 164254721Semaste BIO_printf(bio_err,"where options are\n"); 165254721Semaste BIO_printf(bio_err," -inform arg input format - one of DER PEM\n"); 166254721Semaste BIO_printf(bio_err," -outform arg output format - one of DER PEM\n"); 167254721Semaste BIO_printf(bio_err," -in arg input file\n"); 168254721Semaste BIO_printf(bio_err," -out arg output file\n"); 169254721Semaste BIO_printf(bio_err," -check check the DH parameters\n"); 170254721Semaste BIO_printf(bio_err," -text print a text form of the DH parameters\n"); 171269024Semaste BIO_printf(bio_err," -C Output C code\n"); 172269024Semaste BIO_printf(bio_err," -noout no output\n"); 173269024Semaste BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); 174269024Semaste goto end; 175269024Semaste } 176269024Semaste 177269024Semaste ERR_load_crypto_strings(); 178269024Semaste 179269024Semaste e = setup_engine(bio_err, engine, 0); 180269024Semaste 181269024Semaste in=BIO_new(BIO_s_file()); 182269024Semaste out=BIO_new(BIO_s_file()); 183254721Semaste if ((in == NULL) || (out == NULL)) 184254721Semaste { 185254721Semaste ERR_print_errors(bio_err); 186254721Semaste goto end; 187269024Semaste } 188269024Semaste 189269024Semaste if (infile == NULL) 190269024Semaste BIO_set_fp(in,stdin,BIO_NOCLOSE); 191269024Semaste else 192269024Semaste { 193269024Semaste if (BIO_read_filename(in,infile) <= 0) 194269024Semaste { 195269024Semaste perror(infile); 196254721Semaste goto end; 197254721Semaste } 198254721Semaste } 199254721Semaste if (outfile == NULL) 200254721Semaste { 201254721Semaste BIO_set_fp(out,stdout,BIO_NOCLOSE); 202254721Semaste#ifdef OPENSSL_SYS_VMS 203254721Semaste { 204254721Semaste BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 205254721Semaste out = BIO_push(tmpbio, out); 206254721Semaste } 207254721Semaste#endif 208254721Semaste } 209269024Semaste else 210254721Semaste { 211254721Semaste if (BIO_write_filename(out,outfile) <= 0) 212254721Semaste { 213254721Semaste perror(outfile); 214254721Semaste goto end; 215254721Semaste } 216254721Semaste } 217254721Semaste 218254721Semaste if (informat == FORMAT_ASN1) 219254721Semaste dh=d2i_DHparams_bio(in,NULL); 220254721Semaste else if (informat == FORMAT_PEM) 221263363Semaste dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL); 222263363Semaste else 223263363Semaste { 224254721Semaste BIO_printf(bio_err,"bad input format specified\n"); 225263363Semaste goto end; 226254721Semaste } 227254721Semaste if (dh == NULL) 228254721Semaste { 229254721Semaste BIO_printf(bio_err,"unable to load DH parameters\n"); 230254721Semaste ERR_print_errors(bio_err); 231269024Semaste goto end; 232254721Semaste } 233254721Semaste 234254721Semaste 235254721Semaste 236254721Semaste if (text) 237254721Semaste { 238254721Semaste DHparams_print(out,dh); 239254721Semaste#ifdef undef 240254721Semaste printf("p="); 241254721Semaste BN_print(stdout,dh->p); 242254721Semaste printf("\ng="); 243254721Semaste BN_print(stdout,dh->g); 244254721Semaste printf("\n"); 245254721Semaste if (dh->length != 0) 246254721Semaste printf("recommended private length=%ld\n",dh->length); 247254721Semaste#endif 248254721Semaste } 249254721Semaste 250254721Semaste if (check) 251254721Semaste { 252254721Semaste if (!DH_check(dh,&i)) 253254721Semaste { 254254721Semaste ERR_print_errors(bio_err); 255254721Semaste goto end; 256254721Semaste } 257254721Semaste if (i & DH_CHECK_P_NOT_PRIME) 258254721Semaste printf("p value is not prime\n"); 259254721Semaste if (i & DH_CHECK_P_NOT_SAFE_PRIME) 260254721Semaste printf("p value is not a safe prime\n"); 261254721Semaste if (i & DH_UNABLE_TO_CHECK_GENERATOR) 262254721Semaste printf("unable to check the generator value\n"); 263254721Semaste if (i & DH_NOT_SUITABLE_GENERATOR) 264254721Semaste printf("the g value is not a generator\n"); 265254721Semaste if (i == 0) 266254721Semaste printf("DH parameters appear to be ok.\n"); 267254721Semaste } 268254721Semaste if (C) 269254721Semaste { 270254721Semaste unsigned char *data; 271254721Semaste int len,l,bits; 272254721Semaste 273263367Semaste len=BN_num_bytes(dh->p); 274263367Semaste bits=BN_num_bits(dh->p); 275263367Semaste data=(unsigned char *)OPENSSL_malloc(len); 276263367Semaste if (data == NULL) 277263367Semaste { 278254721Semaste perror("OPENSSL_malloc"); 279254721Semaste goto end; 280263363Semaste } 281254721Semaste l=BN_bn2bin(dh->p,data); 282254721Semaste printf("static unsigned char dh%d_p[]={",bits); 283263363Semaste for (i=0; i<l; i++) 284263363Semaste { 285263363Semaste if ((i%12) == 0) printf("\n\t"); 286254721Semaste printf("0x%02X,",data[i]); 287254721Semaste } 288254721Semaste printf("\n\t};\n"); 289254721Semaste 290263367Semaste l=BN_bn2bin(dh->g,data); 291263367Semaste printf("static unsigned char dh%d_g[]={",bits); 292263367Semaste for (i=0; i<l; i++) 293263367Semaste { 294263367Semaste if ((i%12) == 0) printf("\n\t"); 295263367Semaste printf("0x%02X,",data[i]); 296263367Semaste } 297263367Semaste printf("\n\t};\n\n"); 298263367Semaste 299254721Semaste printf("DH *get_dh%d()\n\t{\n",bits); 300254721Semaste printf("\tDH *dh;\n\n"); 301254721Semaste printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); 302254721Semaste printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", 303254721Semaste bits,bits); 304254721Semaste printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", 305254721Semaste bits,bits); 306254721Semaste printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); 307254721Semaste printf("\t\treturn(NULL);\n"); 308254721Semaste printf("\treturn(dh);\n\t}\n"); 309269024Semaste OPENSSL_free(data); 310269024Semaste } 311269024Semaste 312269024Semaste 313254721Semaste if (!noout) 314254721Semaste { 315254721Semaste if (outformat == FORMAT_ASN1) 316254721Semaste i=i2d_DHparams_bio(out,dh); 317263363Semaste else if (outformat == FORMAT_PEM) 318263363Semaste i=PEM_write_bio_DHparams(out,dh); 319263363Semaste else { 320263363Semaste BIO_printf(bio_err,"bad output format specified for outfile\n"); 321263363Semaste goto end; 322263363Semaste } 323263363Semaste if (!i) 324263363Semaste { 325263363Semaste BIO_printf(bio_err,"unable to write DH parameters\n"); 326263363Semaste ERR_print_errors(bio_err); 327263363Semaste goto end; 328263367Semaste } 329263363Semaste } 330263363Semaste ret=0; 331263363Semasteend: 332263363Semaste if (in != NULL) BIO_free(in); 333263363Semaste if (out != NULL) BIO_free_all(out); 334263363Semaste if (dh != NULL) DH_free(dh); 335263363Semaste apps_shutdown(); 336263363Semaste OPENSSL_EXIT(ret); 337263363Semaste } 338263363Semaste#endif 339263363Semaste