dsaparam.c revision 109998
11553Srgrimes/* apps/dsaparam.c */ 21553Srgrimes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 31553Srgrimes * All rights reserved. 41553Srgrimes * 51553Srgrimes * This package is an SSL implementation written 61553Srgrimes * by Eric Young (eay@cryptsoft.com). 71553Srgrimes * The implementation was written so as to conform with Netscapes SSL. 81553Srgrimes * 91553Srgrimes * This library is free for commercial and non-commercial use as long as 101553Srgrimes * the following conditions are aheared to. The following conditions 111553Srgrimes * apply to all code found in this distribution, be it the RC4, RSA, 121553Srgrimes * lhash, DES, etc., code; not just the SSL code. The SSL documentation 131553Srgrimes * included with this distribution is covered by the same copyright terms 141553Srgrimes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 151553Srgrimes * 161553Srgrimes * Copyright remains Eric Young's, and as such any Copyright notices in 171553Srgrimes * the code are not to be removed. 181553Srgrimes * If this package is used in a product, Eric Young should be given attribution 191553Srgrimes * as the author of the parts of the library used. 201553Srgrimes * This can be in the form of a textual message at program startup or 211553Srgrimes * in documentation (online or textual) provided with the package. 221553Srgrimes * 231553Srgrimes * Redistribution and use in source and binary forms, with or without 241553Srgrimes * modification, are permitted provided that the following conditions 251553Srgrimes * are met: 261553Srgrimes * 1. Redistributions of source code must retain the copyright 271553Srgrimes * notice, this list of conditions and the following disclaimer. 281553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 291553Srgrimes * notice, this list of conditions and the following disclaimer in the 301553Srgrimes * documentation and/or other materials provided with the distribution. 311553Srgrimes * 3. All advertising materials mentioning features or use of this software 321553Srgrimes * must display the following acknowledgement: 331553Srgrimes * "This product includes cryptographic software written by 341553Srgrimes * Eric Young (eay@cryptsoft.com)" 351553Srgrimes * The word 'cryptographic' can be left out if the rouines from the library 3631492Swollman * being used are not cryptographic related :-). 371553Srgrimes * 4. If you include any Windows specific code (or a derivative thereof) from 381553Srgrimes * the apps directory (application code) you must include an acknowledgement: 391553Srgrimes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 401553Srgrimes * 411553Srgrimes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4231492Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4315648Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4431492Swollman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4531492Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4650479Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 471553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 481553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 491553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 501553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 511553Srgrimes * SUCH DAMAGE. 521553Srgrimes * 531553Srgrimes * The licence and distribution terms for any publically available version or 541553Srgrimes * derivative of this code cannot be changed. i.e. this code cannot simply be 551553Srgrimes * copied and put under another distribution licence 561553Srgrimes * [including the GNU Public Licence.] 571553Srgrimes */ 581553Srgrimes 591553Srgrimes#ifndef OPENSSL_NO_DSA 601553Srgrimes#include <assert.h> 611553Srgrimes#include <stdio.h> 621553Srgrimes#include <stdlib.h> 631553Srgrimes#include <time.h> 641553Srgrimes#include <string.h> 651553Srgrimes#include "apps.h" 661553Srgrimes#include <openssl/bio.h> 671553Srgrimes#include <openssl/err.h> 681553Srgrimes#include <openssl/bn.h> 691553Srgrimes#include <openssl/dsa.h> 701553Srgrimes#include <openssl/x509.h> 711553Srgrimes#include <openssl/pem.h> 7215032Ssef 7315032Ssef#undef PROG 7415703Sjoerg#define PROG dsaparam_main 751553Srgrimes 761553Srgrimes/* -inform arg - input format - default PEM (DER or PEM) 771553Srgrimes * -outform arg - output format - default PEM 781553Srgrimes * -in arg - input file - default stdin 791553Srgrimes * -out arg - output file - default stdout 801553Srgrimes * -noout 811553Srgrimes * -text 821553Srgrimes * -C 831553Srgrimes * -noout 841553Srgrimes * -genkey 851553Srgrimes */ 861553Srgrimes 871553Srgrimesstatic void MS_CALLBACK dsa_cb(int p, int n, void *arg); 881553Srgrimes 891553Srgrimesint MAIN(int, char **); 901553Srgrimes 911553Srgrimesint MAIN(int argc, char **argv) 921553Srgrimes { 931553Srgrimes ENGINE *e = NULL; 941553Srgrimes DSA *dsa=NULL; 951553Srgrimes int i,badops=0,text=0; 961553Srgrimes BIO *in=NULL,*out=NULL; 971553Srgrimes int informat,outformat,noout=0,C=0,ret=1; 9868253Sgad char *infile,*outfile,*prog,*inrand=NULL; 991553Srgrimes int numbits= -1,num,genkey=0; 1001553Srgrimes int need_rand=0; 1011553Srgrimes char *engine=NULL; 10224831Sbrian 1031553Srgrimes apps_startup(); 1041553Srgrimes 1051553Srgrimes if (bio_err == NULL) 1061553Srgrimes if ((bio_err=BIO_new(BIO_s_file())) != NULL) 10753956Sache BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); 1081553Srgrimes 1091553Srgrimes if (!load_config(bio_err, NULL)) 11078300Sgad goto end; 1111553Srgrimes 1128857Srgrimes infile=NULL; 1131553Srgrimes outfile=NULL; 1141553Srgrimes informat=FORMAT_PEM; 1151553Srgrimes outformat=FORMAT_PEM; 1161553Srgrimes 1171553Srgrimes prog=argv[0]; 11868664Sgad argc--; 11968664Sgad argv++; 1201553Srgrimes while (argc >= 1) 12124831Sbrian { 12224831Sbrian if (strcmp(*argv,"-inform") == 0) 1231553Srgrimes { 12478146Sgad if (--argc < 1) goto bad; 12578146Sgad informat=str2fmt(*(++argv)); 12678146Sgad } 12778146Sgad else if (strcmp(*argv,"-outform") == 0) 12878146Sgad { 12978146Sgad if (--argc < 1) goto bad; 13078146Sgad outformat=str2fmt(*(++argv)); 13178146Sgad } 13278146Sgad else if (strcmp(*argv,"-in") == 0) 13378146Sgad { 13478146Sgad if (--argc < 1) goto bad; 13578146Sgad infile= *(++argv); 13678146Sgad } 13778146Sgad else if (strcmp(*argv,"-out") == 0) 13878146Sgad { 13978146Sgad if (--argc < 1) goto bad; 14078146Sgad outfile= *(++argv); 14178146Sgad } 14278146Sgad else if(strcmp(*argv, "-engine") == 0) 14378146Sgad { 14478146Sgad if (--argc < 1) goto bad; 14578146Sgad engine = *(++argv); 1461553Srgrimes } 1471553Srgrimes else if (strcmp(*argv,"-text") == 0) 14878146Sgad text=1; 1491553Srgrimes else if (strcmp(*argv,"-C") == 0) 1501553Srgrimes C=1; 15168401Sgad else if (strcmp(*argv,"-genkey") == 0) 15268401Sgad { 1531553Srgrimes genkey=1; 15468733Sgad need_rand=1; 15568733Sgad } 1561553Srgrimes else if (strcmp(*argv,"-rand") == 0) 15768733Sgad { 15831492Swollman if (--argc < 1) goto bad; 15931492Swollman inrand= *(++argv); 1601553Srgrimes need_rand=1; 16131492Swollman } 16231492Swollman else if (strcmp(*argv,"-noout") == 0) 1631553Srgrimes noout=1; 1641553Srgrimes else if (sscanf(*argv,"%d",&num) == 1) 1651553Srgrimes { 1661553Srgrimes /* generate a key */ 1671553Srgrimes numbits=num; 16879735Sgad need_rand=1; 16979735Sgad } 17079735Sgad else 17179735Sgad { 17279735Sgad BIO_printf(bio_err,"unknown option %s\n",*argv); 17379735Sgad badops=1; 17479735Sgad break; 17579735Sgad } 1761553Srgrimes argc--; 1771553Srgrimes argv++; 1781553Srgrimes } 1791553Srgrimes 1801553Srgrimes if (badops) 1811553Srgrimes { 1821553Srgrimesbad: 1831553Srgrimes BIO_printf(bio_err,"%s [options] [bits] <infile >outfile\n",prog); 18431492Swollman BIO_printf(bio_err,"where options are\n"); 18531492Swollman BIO_printf(bio_err," -inform arg input format - DER or PEM\n"); 1861553Srgrimes BIO_printf(bio_err," -outform arg output format - DER or PEM\n"); 1871553Srgrimes BIO_printf(bio_err," -in arg input file\n"); 18831492Swollman BIO_printf(bio_err," -out arg output file\n"); 1891553Srgrimes BIO_printf(bio_err," -text print as text\n"); 19031492Swollman BIO_printf(bio_err," -C Output C code\n"); 19131492Swollman BIO_printf(bio_err," -noout no output\n"); 1921553Srgrimes BIO_printf(bio_err," -genkey generate a DSA key\n"); 19331492Swollman BIO_printf(bio_err," -rand files to use for random number input\n"); 19431492Swollman BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); 19531492Swollman BIO_printf(bio_err," number number of bits to use for generating private key\n"); 1961553Srgrimes goto end; 1971553Srgrimes } 19831492Swollman 19931492Swollman ERR_load_crypto_strings(); 20031492Swollman 2011553Srgrimes in=BIO_new(BIO_s_file()); 2021553Srgrimes out=BIO_new(BIO_s_file()); 2031553Srgrimes if ((in == NULL) || (out == NULL)) 2041553Srgrimes { 2051553Srgrimes ERR_print_errors(bio_err); 2061553Srgrimes goto end; 2071553Srgrimes } 2081553Srgrimes 2091553Srgrimes if (infile == NULL) 21031492Swollman BIO_set_fp(in,stdin,BIO_NOCLOSE); 2111553Srgrimes else 2121553Srgrimes { 2131553Srgrimes if (BIO_read_filename(in,infile) <= 0) 2141553Srgrimes { 2151553Srgrimes perror(infile); 21631492Swollman goto end; 21731492Swollman } 21831492Swollman } 2191553Srgrimes if (outfile == NULL) 2201553Srgrimes { 2211553Srgrimes BIO_set_fp(out,stdout,BIO_NOCLOSE); 2221553Srgrimes#ifdef OPENSSL_SYS_VMS 22331492Swollman { 22431492Swollman BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 22531492Swollman out = BIO_push(tmpbio, out); 22631492Swollman } 2271553Srgrimes#endif 22868664Sgad } 22968664Sgad else 23068664Sgad { 23168664Sgad if (BIO_write_filename(out,outfile) <= 0) 23268664Sgad { 23368732Sgad perror(outfile); 23468664Sgad goto end; 23568664Sgad } 23668664Sgad } 23768664Sgad 23868732Sgad e = setup_engine(bio_err, engine, 0); 23968664Sgad 24068664Sgad if (need_rand) 24168664Sgad { 24268664Sgad app_RAND_load_file(NULL, bio_err, (inrand != NULL)); 24331492Swollman if (inrand != NULL) 2441553Srgrimes BIO_printf(bio_err,"%ld semi-random bytes loaded\n", 2451553Srgrimes app_RAND_load_files(inrand)); 2461553Srgrimes } 2471553Srgrimes 2481553Srgrimes if (numbits > 0) 2491553Srgrimes { 2501553Srgrimes assert(need_rand); 2511553Srgrimes BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num); 25268401Sgad BIO_printf(bio_err,"This could take some time\n"); 2531553Srgrimes dsa=DSA_generate_parameters(num,NULL,0,NULL,NULL, dsa_cb,bio_err); 25415648Sjoerg } 2551553Srgrimes else if (informat == FORMAT_ASN1) 25615648Sjoerg dsa=d2i_DSAparams_bio(in,NULL); 25768401Sgad else if (informat == FORMAT_PEM) 2581553Srgrimes dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL); 2591553Srgrimes else 26031492Swollman { 26131492Swollman BIO_printf(bio_err,"bad input format specified\n"); 26231492Swollman goto end; 26368401Sgad } 2641553Srgrimes if (dsa == NULL) 26568401Sgad { 2661553Srgrimes BIO_printf(bio_err,"unable to load DSA parameters\n"); 2671553Srgrimes ERR_print_errors(bio_err); 2681553Srgrimes goto end; 2691553Srgrimes } 2701553Srgrimes 2711553Srgrimes if (text) 27231492Swollman { 2731553Srgrimes DSAparams_print(out,dsa); 2741553Srgrimes } 27531492Swollman 27631492Swollman if (C) 2771553Srgrimes { 27831492Swollman unsigned char *data; 27931492Swollman int l,len,bits_p,bits_q,bits_g; 2801553Srgrimes 28131492Swollman len=BN_num_bytes(dsa->p); 2821553Srgrimes bits_p=BN_num_bits(dsa->p); 2831553Srgrimes bits_q=BN_num_bits(dsa->q); 2841553Srgrimes bits_g=BN_num_bits(dsa->g); 28568733Sgad data=(unsigned char *)OPENSSL_malloc(len+20); 28668733Sgad if (data == NULL) 28715648Sjoerg { 28815648Sjoerg perror("OPENSSL_malloc"); 28931492Swollman goto end; 2901553Srgrimes } 2911553Srgrimes l=BN_bn2bin(dsa->p,data); 2921553Srgrimes printf("static unsigned char dsa%d_p[]={",bits_p); 29315648Sjoerg for (i=0; i<l; i++) 2941553Srgrimes { 29579735Sgad if ((i%12) == 0) printf("\n\t"); 29679735Sgad printf("0x%02X,",data[i]); 29779735Sgad } 2981553Srgrimes printf("\n\t};\n"); 2991553Srgrimes 3001553Srgrimes l=BN_bn2bin(dsa->q,data); 3011553Srgrimes printf("static unsigned char dsa%d_q[]={",bits_p); 30231492Swollman for (i=0; i<l; i++) 30331492Swollman { 30431492Swollman if ((i%12) == 0) printf("\n\t"); 3051553Srgrimes printf("0x%02X,",data[i]); 30615648Sjoerg } 30731492Swollman printf("\n\t};\n"); 30831492Swollman 30931492Swollman l=BN_bn2bin(dsa->g,data); 31068401Sgad printf("static unsigned char dsa%d_g[]={",bits_p); 31115648Sjoerg for (i=0; i<l; i++) 31227748Simp { 31368401Sgad if ((i%12) == 0) printf("\n\t"); 31468401Sgad printf("0x%02X,",data[i]); 31568401Sgad } 31615648Sjoerg printf("\n\t};\n\n"); 31731492Swollman 31815648Sjoerg printf("DSA *get_dsa%d()\n\t{\n",bits_p); 3191553Srgrimes printf("\tDSA *dsa;\n\n"); 3201553Srgrimes printf("\tif ((dsa=DSA_new()) == NULL) return(NULL);\n"); 32131492Swollman printf("\tdsa->p=BN_bin2bn(dsa%d_p,sizeof(dsa%d_p),NULL);\n", 3221553Srgrimes bits_p,bits_p); 3231553Srgrimes printf("\tdsa->q=BN_bin2bn(dsa%d_q,sizeof(dsa%d_q),NULL);\n", 3241553Srgrimes bits_p,bits_p); 32531492Swollman printf("\tdsa->g=BN_bin2bn(dsa%d_g,sizeof(dsa%d_g),NULL);\n", 32631492Swollman bits_p,bits_p); 32731492Swollman printf("\tif ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))\n"); 3281553Srgrimes printf("\t\t{ DSA_free(dsa); return(NULL); }\n"); 3291553Srgrimes printf("\treturn(dsa);\n\t}\n"); 3301553Srgrimes } 3311553Srgrimes 33268733Sgad 33331492Swollman if (!noout) 33431492Swollman { 33531492Swollman if (outformat == FORMAT_ASN1) 33631492Swollman i=i2d_DSAparams_bio(out,dsa); 33731492Swollman else if (outformat == FORMAT_PEM) 33831492Swollman i=PEM_write_bio_DSAparams(out,dsa); 3391553Srgrimes else { 34019202Simp BIO_printf(bio_err,"bad output format specified for outfile\n"); 34119202Simp goto end; 34268664Sgad } 3431553Srgrimes if (!i) 3441553Srgrimes { 3451553Srgrimes BIO_printf(bio_err,"unable to write DSA parameters\n"); 3461553Srgrimes ERR_print_errors(bio_err); 3471553Srgrimes goto end; 3481553Srgrimes } 3491553Srgrimes } 3501553Srgrimes if (genkey) 3511553Srgrimes { 3521553Srgrimes DSA *dsakey; 3531553Srgrimes 3541553Srgrimes assert(need_rand); 3551553Srgrimes if ((dsakey=DSAparams_dup(dsa)) == NULL) goto end; 3561553Srgrimes if (!DSA_generate_key(dsakey)) goto end; 3571553Srgrimes if (outformat == FORMAT_ASN1) 3581553Srgrimes i=i2d_DSAPrivateKey_bio(out,dsakey); 3591553Srgrimes else if (outformat == FORMAT_PEM) 3601553Srgrimes i=PEM_write_bio_DSAPrivateKey(out,dsakey,NULL,NULL,0,NULL,NULL); 3611553Srgrimes else { 36278146Sgad BIO_printf(bio_err,"bad output format specified for outfile\n"); 3631553Srgrimes goto end; 3641553Srgrimes } 36568734Sgad DSA_free(dsakey); 36668734Sgad } 3671553Srgrimes if (need_rand) 36868734Sgad app_RAND_write_file(NULL, bio_err); 36968734Sgad ret=0; 3701553Srgrimesend: 3711553Srgrimes if (in != NULL) BIO_free(in); 3721553Srgrimes if (out != NULL) BIO_free_all(out); 3731553Srgrimes if (dsa != NULL) DSA_free(dsa); 37431492Swollman apps_shutdown(); 3751553Srgrimes OPENSSL_EXIT(ret); 3761553Srgrimes } 3771553Srgrimes 3781553Srgrimesstatic void MS_CALLBACK dsa_cb(int p, int n, void *arg) 3791553Srgrimes { 3801553Srgrimes char c='*'; 3811553Srgrimes 38231492Swollman if (p == 0) c='.'; 3831553Srgrimes if (p == 1) c='+'; 3841553Srgrimes if (p == 2) c='*'; 38568253Sgad if (p == 3) c='\n'; 38668253Sgad BIO_write(arg,&c,1); 38768253Sgad (void)BIO_flush(arg); 3881553Srgrimes#ifdef LINT 3891553Srgrimes p=n; 3901553Srgrimes#endif 3911553Srgrimes } 3921553Srgrimes#endif 3931553Srgrimes