dsaparam.c revision 59191
1139823Simp/* apps/dsaparam.c */ 21541Srgrimes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 31541Srgrimes * All rights reserved. 41541Srgrimes * 51541Srgrimes * This package is an SSL implementation written 61541Srgrimes * by Eric Young (eay@cryptsoft.com). 71541Srgrimes * The implementation was written so as to conform with Netscapes SSL. 81541Srgrimes * 91541Srgrimes * This library is free for commercial and non-commercial use as long as 101541Srgrimes * the following conditions are aheared to. The following conditions 111541Srgrimes * apply to all code found in this distribution, be it the RC4, RSA, 121541Srgrimes * lhash, DES, etc., code; not just the SSL code. The SSL documentation 131541Srgrimes * included with this distribution is covered by the same copyright terms 141541Srgrimes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 151541Srgrimes * 161541Srgrimes * Copyright remains Eric Young's, and as such any Copyright notices in 171541Srgrimes * the code are not to be removed. 181541Srgrimes * If this package is used in a product, Eric Young should be given attribution 191541Srgrimes * as the author of the parts of the library used. 201541Srgrimes * This can be in the form of a textual message at program startup or 211541Srgrimes * in documentation (online or textual) provided with the package. 221541Srgrimes * 231541Srgrimes * Redistribution and use in source and binary forms, with or without 241541Srgrimes * modification, are permitted provided that the following conditions 251541Srgrimes * are met: 261541Srgrimes * 1. Redistributions of source code must retain the copyright 271541Srgrimes * notice, this list of conditions and the following disclaimer. 281541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 291541Srgrimes * notice, this list of conditions and the following disclaimer in the 301541Srgrimes * documentation and/or other materials provided with the distribution. 311541Srgrimes * 3. All advertising materials mentioning features or use of this software 321541Srgrimes * must display the following acknowledgement: 331541Srgrimes * "This product includes cryptographic software written by 341541Srgrimes * Eric Young (eay@cryptsoft.com)" 3517679Spst * The word 'cryptographic' can be left out if the rouines from the library 361541Srgrimes * being used are not cryptographic related :-). 3750477Speter * 4. If you include any Windows specific code (or a derivative thereof) from 381541Srgrimes * the apps directory (application code) you must include an acknowledgement: 391541Srgrimes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 402168Spaul * 412168Spaul * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 422168Spaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4317679Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4417679Spst * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4517679Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4617679Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4717679Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4817679Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 491541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 508876Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 518876Srgrimes * SUCH DAMAGE. 521541Srgrimes * 5339963Salex * The licence and distribution terms for any publically available version or 541541Srgrimes * derivative of this code cannot be changed. i.e. this code cannot simply be 551541Srgrimes * copied and put under another distribution licence 561541Srgrimes * [including the GNU Public Licence.] 5756057Sphk */ 581541Srgrimes 591541Srgrimes#ifndef NO_DSA 601541Srgrimes#include <assert.h> 611541Srgrimes#include <stdio.h> 621541Srgrimes#include <stdlib.h> 631541Srgrimes#include <time.h> 641541Srgrimes#include <string.h> 651541Srgrimes#include "apps.h" 661541Srgrimes#include <openssl/bio.h> 678876Srgrimes#include <openssl/err.h> 681541Srgrimes#include <openssl/bn.h> 691541Srgrimes#include <openssl/dsa.h> 701541Srgrimes#include <openssl/x509.h> 711541Srgrimes#include <openssl/pem.h> 721541Srgrimes 731541Srgrimes#undef PROG 741541Srgrimes#define PROG dsaparam_main 751541Srgrimes 761541Srgrimes/* -inform arg - input format - default PEM (DER or PEM) 778876Srgrimes * -outform arg - output format - default PEM 781541Srgrimes * -in arg - input file - default stdin 791541Srgrimes * -out arg - output file - default stdout 801541Srgrimes * -noout 811541Srgrimes * -text 821541Srgrimes * -C 831541Srgrimes * -noout 841541Srgrimes * -genkey 851541Srgrimes */ 861541Srgrimes 871541Srgrimesstatic void MS_CALLBACK dsa_cb(int p, int n, void *arg); 881541Srgrimes 891541Srgrimesint MAIN(int, char **); 901541Srgrimes 9117679Spstint MAIN(int argc, char **argv) 921541Srgrimes { 931541Srgrimes DSA *dsa=NULL; 941541Srgrimes int i,badops=0,text=0; 951541Srgrimes BIO *in=NULL,*out=NULL; 961541Srgrimes int informat,outformat,noout=0,C=0,ret=1; 971541Srgrimes char *infile,*outfile,*prog,*inrand=NULL; 981541Srgrimes int numbits= -1,num,genkey=0; 991541Srgrimes int need_rand=0; 1001541Srgrimes 1011541Srgrimes apps_startup(); 1021541Srgrimes 1031541Srgrimes if (bio_err == NULL) 1041541Srgrimes if ((bio_err=BIO_new(BIO_s_file())) != NULL) 1051541Srgrimes BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); 1061541Srgrimes 1071541Srgrimes infile=NULL; 1089235Spst outfile=NULL; 1099235Spst informat=FORMAT_PEM; 11052248Smsmith outformat=FORMAT_PEM; 11152248Smsmith 11258192Srwatson prog=argv[0]; 11358192Srwatson argc--; 114109580Ssam argv++; 115109580Ssam while (argc >= 1) 1161541Srgrimes { 1171541Srgrimes if (strcmp(*argv,"-inform") == 0) 1181541Srgrimes { 1191541Srgrimes if (--argc < 1) goto bad; 1201541Srgrimes informat=str2fmt(*(++argv)); 1211541Srgrimes } 12217679Spst else if (strcmp(*argv,"-outform") == 0) 12317679Spst { 1241541Srgrimes if (--argc < 1) goto bad; 1251541Srgrimes outformat=str2fmt(*(++argv)); 1261541Srgrimes } 1271541Srgrimes else if (strcmp(*argv,"-in") == 0) 1281541Srgrimes { 1291541Srgrimes if (--argc < 1) goto bad; 1301541Srgrimes infile= *(++argv); 1311541Srgrimes } 13255205Speter else if (strcmp(*argv,"-out") == 0) 13337619Sbde { 13437619Sbde if (--argc < 1) goto bad; 1351541Srgrimes outfile= *(++argv); 1361541Srgrimes } 1371541Srgrimes else if (strcmp(*argv,"-text") == 0) 1381541Srgrimes text=1; 1391541Srgrimes else if (strcmp(*argv,"-C") == 0) 140129874Sdwmalone C=1; 1411541Srgrimes else if (strcmp(*argv,"-genkey") == 0) 1421541Srgrimes { 1431541Srgrimes genkey=1; 1441541Srgrimes need_rand=1; 1451541Srgrimes } 1461541Srgrimes else if (strcmp(*argv,"-rand") == 0) 1471541Srgrimes { 1481541Srgrimes if (--argc < 1) goto bad; 1491541Srgrimes inrand= *(++argv); 1501541Srgrimes need_rand=1; 15117679Spst } 15238423Sache else if (strcmp(*argv,"-noout") == 0) 1531541Srgrimes noout=1; 1541541Srgrimes else if (sscanf(*argv,"%d",&num) == 1) 15580767Sfenner { 15680767Sfenner /* generate a key */ 15780767Sfenner numbits=num; 15880767Sfenner need_rand=1; 15980767Sfenner } 16080767Sfenner else 16180767Sfenner { 16280767Sfenner BIO_printf(bio_err,"unknown option %s\n",*argv); 16380767Sfenner badops=1; 16480767Sfenner break; 16580767Sfenner } 16680767Sfenner argc--; 16780767Sfenner argv++; 16880767Sfenner } 16980767Sfenner 17080767Sfenner if (badops) 17180767Sfenner { 17280767Sfennerbad: 17398540Sfenner BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog); 17498540Sfenner BIO_printf(bio_err,"where options are\n"); 17598540Sfenner BIO_printf(bio_err," -inform arg input format - DER or PEM\n"); 17680767Sfenner BIO_printf(bio_err," -outform arg output format - DER or PEM\n"); 17780767Sfenner BIO_printf(bio_err," -in arg input file\n"); 17898540Sfenner BIO_printf(bio_err," -out arg output file\n"); 17980767Sfenner BIO_printf(bio_err," -text print the key in text\n"); 18080767Sfenner BIO_printf(bio_err," -C Output C code\n"); 181127674Sbms BIO_printf(bio_err," -noout no output\n"); 182127674Sbms BIO_printf(bio_err," -rand files to use for random number input\n"); 183127674Sbms BIO_printf(bio_err," number number of bits to use for generating private key\n"); 184127674Sbms goto end; 185127674Sbms } 186127674Sbms 18780767Sfenner ERR_load_crypto_strings(); 18880767Sfenner 18980767Sfenner in=BIO_new(BIO_s_file()); 19080767Sfenner out=BIO_new(BIO_s_file()); 19180767Sfenner if ((in == NULL) || (out == NULL)) 19280767Sfenner { 19380767Sfenner ERR_print_errors(bio_err); 19480767Sfenner goto end; 19580767Sfenner } 19680767Sfenner 19780767Sfenner if (infile == NULL) 19880767Sfenner BIO_set_fp(in,stdin,BIO_NOCLOSE); 19980767Sfenner else 20080767Sfenner { 20180767Sfenner if (BIO_read_filename(in,infile) <= 0) 20280767Sfenner { 20380767Sfenner perror(infile); 20480767Sfenner goto end; 20580767Sfenner } 20680767Sfenner } 20780767Sfenner if (outfile == NULL) 20880767Sfenner BIO_set_fp(out,stdout,BIO_NOCLOSE); 20980767Sfenner else 21080767Sfenner { 21180767Sfenner if (BIO_write_filename(out,outfile) <= 0) 212127673Sbms { 213127673Sbms perror(outfile); 214127673Sbms goto end; 215127673Sbms } 216127673Sbms } 217127673Sbms 218127673Sbms if (need_rand) 219127673Sbms { 22080767Sfenner app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 22180767Sfenner if (inrand != NULL) 22280767Sfenner BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 22380767Sfenner app_RAND_load_files(inrand)); 22480767Sfenner } 22580767Sfenner 22698540Sfenner if (numbits > 0) 22780767Sfenner { 22880767Sfenner assert(need_rand); 22980767Sfenner BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num); 23080767Sfenner BIO_printf(bio_err,"This could take some time\n"); 23180767Sfenner dsa=DSA_generate_parameters(num,NULL,0,NULL,NULL, dsa_cb,bio_err); 23280767Sfenner } 23380767Sfenner else if (informat == FORMAT_ASN1) 23480767Sfenner dsa=d2i_DSAparams_bio(in,NULL); 23580767Sfenner else if (informat == FORMAT_PEM) 23680767Sfenner dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL); 237127673Sbms else 238127673Sbms { 239127673Sbms BIO_printf(bio_err,"bad input format specified\n"); 240127673Sbms goto end; 241127673Sbms } 242127673Sbms if (dsa == NULL) 243127673Sbms { 24480767Sfenner BIO_printf(bio_err,"unable to load DSA parameters\n"); 24580767Sfenner ERR_print_errors(bio_err); 24680767Sfenner goto end; 24780767Sfenner } 24880767Sfenner 24998540Sfenner if (text) 25098540Sfenner { 25198540Sfenner DSAparams_print(out,dsa); 25298540Sfenner } 25398540Sfenner 25498540Sfenner if (C) 25598540Sfenner { 25698540Sfenner unsigned char *data; 25798540Sfenner int l,len,bits_p,bits_q,bits_g; 25898540Sfenner 25998540Sfenner len=BN_num_bytes(dsa->p); 26098540Sfenner bits_p=BN_num_bits(dsa->p); 26198540Sfenner bits_q=BN_num_bits(dsa->q); 26298540Sfenner bits_g=BN_num_bits(dsa->g); 26398540Sfenner data=(unsigned char *)Malloc(len+20); 26498540Sfenner if (data == NULL) 26598540Sfenner { 26698540Sfenner perror("Malloc"); 26798540Sfenner goto end; 26898540Sfenner } 26998540Sfenner l=BN_bn2bin(dsa->p,data); 27098540Sfenner printf("static unsigned char dsa%d_p[]={",bits_p); 27198540Sfenner for (i=0; i<l; i++) 27298540Sfenner { 27398540Sfenner if ((i%12) == 0) printf("\n\t"); 27498540Sfenner printf("0x%02X,",data[i]); 27598540Sfenner } 27698540Sfenner printf("\n\t};\n"); 27798540Sfenner 27898540Sfenner l=BN_bn2bin(dsa->q,data); 27998540Sfenner printf("static unsigned char dsa%d_q[]={",bits_p); 28098540Sfenner for (i=0; i<l; i++) 28198540Sfenner { 28298540Sfenner if ((i%12) == 0) printf("\n\t"); 28398540Sfenner printf("0x%02X,",data[i]); 28498540Sfenner } 28598540Sfenner printf("\n\t};\n"); 28698540Sfenner 28798540Sfenner l=BN_bn2bin(dsa->g,data); 28898540Sfenner printf("static unsigned char dsa%d_g[]={",bits_p); 28998540Sfenner for (i=0; i<l; i++) 290127673Sbms { 291127673Sbms if ((i%12) == 0) printf("\n\t"); 292127673Sbms printf("0x%02X,",data[i]); 293127673Sbms } 294127673Sbms printf("\n\t};\n\n"); 295127674Sbms 296127674Sbms printf("DSA *get_dsa%d()\n\t{\n",bits_p); 297127674Sbms printf("\tDSA *dsa;\n\n"); 298127674Sbms printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n"); 299127674Sbms printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n", 300127673Sbms bits_p,bits_p); 301127673Sbms printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n", 302127673Sbms bits_p,bits_p); 303127673Sbms printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n", 304127673Sbms bits_p,bits_p); 305127673Sbms printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n"); 306127673Sbms printf("\t\treturn(NULL);\n"); 307127673Sbms printf("\treturn(dsa);\n\t}\n"); 308127673Sbms } 309127673Sbms 310127674Sbms 311127674Sbms if (!noout) 312127674Sbms { 313127674Sbms if (outformat == FORMAT_ASN1) 314127674Sbms i=i2d_DSAparams_bio(out,dsa); 315127674Sbms else if (outformat == FORMAT_PEM) 316127674Sbms i=PEM_write_bio_DSAparams(out,dsa); 317127674Sbms else { 318127673Sbms BIO_printf(bio_err,"bad output format specified for outfile\n"); 319127673Sbms goto end; 320127673Sbms } 321127673Sbms if (!i) 322127673Sbms { 323127673Sbms BIO_printf(bio_err,"unable to write DSA parameters\n"); 324127673Sbms ERR_print_errors(bio_err); 325127673Sbms goto end; 326127674Sbms } 327127674Sbms } 328127674Sbms if (genkey) 329127674Sbms { 330127674Sbms DSA *dsakey; 331127673Sbms 332127673Sbms assert(need_rand); 333127673Sbms if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end; 334127673Sbms if (!DSA_generate_key(dsakey)) goto end; 335127673Sbms if (outformat == FORMAT_ASN1) 336127674Sbms i=i2d_DSAPrivateKey_bio(out,dsakey); 337127674Sbms else if (outformat == FORMAT_PEM) 338127674Sbms i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL); 339127674Sbms else { 340127674Sbms BIO_printf(bio_err,"bad output format specified for outfile\n"); 341127674Sbms goto end; 342127674Sbms } 343127674Sbms DSA_free(dsakey); 344127674Sbms } 345127674Sbms if (need_rand) 346127674Sbms app_RAND_write_file(NULL, bio_err); 347127674Sbms ret=0; 348146729Ssamend: 349146729Ssam if (in != NULL) BIO_free(in); 350146729Ssam if (out != NULL) BIO_free(out); 351146729Ssam if (dsa != NULL) DSA_free(dsa); 352146729Ssam EXIT(ret); 353146729Ssam } 354146729Ssam 355146729Ssamstatic void MS_CALLBACK dsa_cb(int p, int n, void *arg) 356146729Ssam { 357146729Ssam char c='*'; 358146729Ssam 359146729Ssam if (p == 0) c='.'; 360146729Ssam if (p == 1) c='+'; 361127673Sbms if (p == 2) c='*'; 362127673Sbms if (p == 3) c='\n'; 363127673Sbms BIO_write(arg,&c,1); 364127673Sbms (void)BIO_flush(arg); 365147893Ssam#ifdef LINT 366147893Ssam p=n; 367146729Ssam#endif 368147893Ssam } 369147893Ssam#endif 370147893Ssam