1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: dhparam.c,v 1.14 2022/01/14 09:22:50 tb Exp $ */ 2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3f5b1c8a1SJohn Marino * All rights reserved. 4f5b1c8a1SJohn Marino * 5f5b1c8a1SJohn Marino * This package is an SSL implementation written 6f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com). 7f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL. 8f5b1c8a1SJohn Marino * 9f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as 10f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions 11f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA, 12f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms 14f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15f5b1c8a1SJohn Marino * 16f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in 17f5b1c8a1SJohn Marino * the code are not to be removed. 18f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution 19f5b1c8a1SJohn Marino * as the author of the parts of the library used. 20f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or 21f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package. 22f5b1c8a1SJohn Marino * 23f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 24f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 25f5b1c8a1SJohn Marino * are met: 26f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright 27f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 28f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 29f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the 30f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution. 31f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software 32f5b1c8a1SJohn Marino * must display the following acknowledgement: 33f5b1c8a1SJohn Marino * "This product includes cryptographic software written by 34f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)" 35f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library 36f5b1c8a1SJohn Marino * being used are not cryptographic related :-). 37f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from 38f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement: 39f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40f5b1c8a1SJohn Marino * 41f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51f5b1c8a1SJohn Marino * SUCH DAMAGE. 52f5b1c8a1SJohn Marino * 53f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or 54f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be 55f5b1c8a1SJohn Marino * copied and put under another distribution licence 56f5b1c8a1SJohn Marino * [including the GNU Public Licence.] 57f5b1c8a1SJohn Marino */ 58f5b1c8a1SJohn Marino /* ==================================================================== 59f5b1c8a1SJohn Marino * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 60f5b1c8a1SJohn Marino * 61f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 62f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 63f5b1c8a1SJohn Marino * are met: 64f5b1c8a1SJohn Marino * 65f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the above copyright 66f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 67f5b1c8a1SJohn Marino * 68f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 69f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in 70f5b1c8a1SJohn Marino * the documentation and/or other materials provided with the 71f5b1c8a1SJohn Marino * distribution. 72f5b1c8a1SJohn Marino * 73f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this 74f5b1c8a1SJohn Marino * software must display the following acknowledgment: 75f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 76f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77f5b1c8a1SJohn Marino * 78f5b1c8a1SJohn Marino * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79f5b1c8a1SJohn Marino * endorse or promote products derived from this software without 80f5b1c8a1SJohn Marino * prior written permission. For written permission, please contact 81f5b1c8a1SJohn Marino * openssl-core@openssl.org. 82f5b1c8a1SJohn Marino * 83f5b1c8a1SJohn Marino * 5. Products derived from this software may not be called "OpenSSL" 84f5b1c8a1SJohn Marino * nor may "OpenSSL" appear in their names without prior written 85f5b1c8a1SJohn Marino * permission of the OpenSSL Project. 86f5b1c8a1SJohn Marino * 87f5b1c8a1SJohn Marino * 6. Redistributions of any form whatsoever must retain the following 88f5b1c8a1SJohn Marino * acknowledgment: 89f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 90f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91f5b1c8a1SJohn Marino * 92f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93f5b1c8a1SJohn Marino * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95f5b1c8a1SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96f5b1c8a1SJohn Marino * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97f5b1c8a1SJohn Marino * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98f5b1c8a1SJohn Marino * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99f5b1c8a1SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101f5b1c8a1SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102f5b1c8a1SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103f5b1c8a1SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE. 104f5b1c8a1SJohn Marino * ==================================================================== 105f5b1c8a1SJohn Marino * 106f5b1c8a1SJohn Marino * This product includes cryptographic software written by Eric Young 107f5b1c8a1SJohn Marino * (eay@cryptsoft.com). This product includes software written by Tim 108f5b1c8a1SJohn Marino * Hudson (tjh@cryptsoft.com). 109f5b1c8a1SJohn Marino * 110f5b1c8a1SJohn Marino */ 111f5b1c8a1SJohn Marino 112f5b1c8a1SJohn Marino #include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */ 113f5b1c8a1SJohn Marino 114f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_DH 115f5b1c8a1SJohn Marino 116f5b1c8a1SJohn Marino #include <stdio.h> 117f5b1c8a1SJohn Marino #include <stdlib.h> 118f5b1c8a1SJohn Marino #include <string.h> 119f5b1c8a1SJohn Marino #include <time.h> 120f5b1c8a1SJohn Marino 121f5b1c8a1SJohn Marino #include "apps.h" 122f5b1c8a1SJohn Marino 123f5b1c8a1SJohn Marino #include <openssl/bio.h> 124f5b1c8a1SJohn Marino #include <openssl/bn.h> 125f5b1c8a1SJohn Marino #include <openssl/err.h> 126f5b1c8a1SJohn Marino #include <openssl/dh.h> 127f5b1c8a1SJohn Marino #include <openssl/pem.h> 128f5b1c8a1SJohn Marino #include <openssl/x509.h> 129f5b1c8a1SJohn Marino 130f5b1c8a1SJohn Marino #include <openssl/dsa.h> 131f5b1c8a1SJohn Marino 132f5b1c8a1SJohn Marino #define DEFBITS 2048 133f5b1c8a1SJohn Marino 134f5b1c8a1SJohn Marino struct { 135f5b1c8a1SJohn Marino int C; 136f5b1c8a1SJohn Marino int check; 137f5b1c8a1SJohn Marino int dsaparam; 138f5b1c8a1SJohn Marino int g; 139f5b1c8a1SJohn Marino char *infile; 140f5b1c8a1SJohn Marino int informat; 141f5b1c8a1SJohn Marino int noout; 142f5b1c8a1SJohn Marino char *outfile; 143f5b1c8a1SJohn Marino int outformat; 144f5b1c8a1SJohn Marino int text; 145f5b1c8a1SJohn Marino } dhparam_config; 146f5b1c8a1SJohn Marino 147cca6fc52SDaniel Fojt static const struct option dhparam_options[] = { 148f5b1c8a1SJohn Marino { 149f5b1c8a1SJohn Marino .name = "2", 150f5b1c8a1SJohn Marino .desc = "Generate DH parameters with a generator value of 2 " 151f5b1c8a1SJohn Marino "(default)", 152f5b1c8a1SJohn Marino .type = OPTION_VALUE, 153f5b1c8a1SJohn Marino .opt.value = &dhparam_config.g, 154f5b1c8a1SJohn Marino .value = 2, 155f5b1c8a1SJohn Marino }, 156f5b1c8a1SJohn Marino { 157f5b1c8a1SJohn Marino .name = "5", 158f5b1c8a1SJohn Marino .desc = "Generate DH parameters with a generator value of 5", 159f5b1c8a1SJohn Marino .type = OPTION_VALUE, 160f5b1c8a1SJohn Marino .opt.value = &dhparam_config.g, 161f5b1c8a1SJohn Marino .value = 5, 162f5b1c8a1SJohn Marino }, 163f5b1c8a1SJohn Marino { 164f5b1c8a1SJohn Marino .name = "C", 165f5b1c8a1SJohn Marino .desc = "Convert DH parameters into C code", 166f5b1c8a1SJohn Marino .type = OPTION_FLAG, 167f5b1c8a1SJohn Marino .opt.flag = &dhparam_config.C, 168f5b1c8a1SJohn Marino }, 169f5b1c8a1SJohn Marino { 170f5b1c8a1SJohn Marino .name = "check", 171f5b1c8a1SJohn Marino .desc = "Check the DH parameters", 172f5b1c8a1SJohn Marino .type = OPTION_FLAG, 173f5b1c8a1SJohn Marino .opt.flag = &dhparam_config.check, 174f5b1c8a1SJohn Marino }, 175f5b1c8a1SJohn Marino { 176f5b1c8a1SJohn Marino .name = "dsaparam", 177f5b1c8a1SJohn Marino .desc = "Read or generate DSA parameters and convert to DH", 178f5b1c8a1SJohn Marino .type = OPTION_FLAG, 179f5b1c8a1SJohn Marino .opt.flag = &dhparam_config.dsaparam, 180f5b1c8a1SJohn Marino }, 181f5b1c8a1SJohn Marino { 182f5b1c8a1SJohn Marino .name = "in", 183f5b1c8a1SJohn Marino .argname = "file", 184f5b1c8a1SJohn Marino .desc = "Input file (default stdin)", 185f5b1c8a1SJohn Marino .type = OPTION_ARG, 186f5b1c8a1SJohn Marino .opt.arg = &dhparam_config.infile, 187f5b1c8a1SJohn Marino }, 188f5b1c8a1SJohn Marino { 189f5b1c8a1SJohn Marino .name = "inform", 190f5b1c8a1SJohn Marino .argname = "format", 191f5b1c8a1SJohn Marino .desc = "Input format (DER or PEM (default))", 192f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 193f5b1c8a1SJohn Marino .opt.value = &dhparam_config.informat, 194f5b1c8a1SJohn Marino }, 195f5b1c8a1SJohn Marino { 196f5b1c8a1SJohn Marino .name = "noout", 197f5b1c8a1SJohn Marino .desc = "Do not output encoded version of DH parameters", 198f5b1c8a1SJohn Marino .type = OPTION_FLAG, 199f5b1c8a1SJohn Marino .opt.flag = &dhparam_config.noout, 200f5b1c8a1SJohn Marino }, 201f5b1c8a1SJohn Marino { 202f5b1c8a1SJohn Marino .name = "out", 203f5b1c8a1SJohn Marino .argname = "file", 204f5b1c8a1SJohn Marino .desc = "Output file (default stdout)", 205f5b1c8a1SJohn Marino .type = OPTION_ARG, 206f5b1c8a1SJohn Marino .opt.arg = &dhparam_config.outfile, 207f5b1c8a1SJohn Marino }, 208f5b1c8a1SJohn Marino { 209f5b1c8a1SJohn Marino .name = "outform", 210f5b1c8a1SJohn Marino .argname = "format", 211f5b1c8a1SJohn Marino .desc = "Output format (DER or PEM (default))", 212f5b1c8a1SJohn Marino .type = OPTION_ARG_FORMAT, 213f5b1c8a1SJohn Marino .opt.value = &dhparam_config.outformat, 214f5b1c8a1SJohn Marino }, 215f5b1c8a1SJohn Marino { 216f5b1c8a1SJohn Marino .name = "text", 217f5b1c8a1SJohn Marino .desc = "Print DH parameters in plain text", 218f5b1c8a1SJohn Marino .type = OPTION_FLAG, 219f5b1c8a1SJohn Marino .opt.flag = &dhparam_config.text, 220f5b1c8a1SJohn Marino }, 221f5b1c8a1SJohn Marino { NULL }, 222f5b1c8a1SJohn Marino }; 223f5b1c8a1SJohn Marino 224f5b1c8a1SJohn Marino static void 225f5b1c8a1SJohn Marino dhparam_usage() 226f5b1c8a1SJohn Marino { 227f5b1c8a1SJohn Marino fprintf(stderr, 228f5b1c8a1SJohn Marino "usage: dhparam [-2 | -5] [-C] [-check] [-dsaparam]\n" 229f5b1c8a1SJohn Marino " [-in file] [-inform DER | PEM] [-noout] [-out file]\n" 230f5b1c8a1SJohn Marino " [-outform DER | PEM] [-text] [numbits]\n\n"); 231f5b1c8a1SJohn Marino options_usage(dhparam_options); 232f5b1c8a1SJohn Marino } 233f5b1c8a1SJohn Marino 234f5b1c8a1SJohn Marino static int dh_cb(int p, int n, BN_GENCB *cb); 235f5b1c8a1SJohn Marino 236f5b1c8a1SJohn Marino int 237f5b1c8a1SJohn Marino dhparam_main(int argc, char **argv) 238f5b1c8a1SJohn Marino { 239f5b1c8a1SJohn Marino BIO *in = NULL, *out = NULL; 240*de0e0e4dSAntonio Huete Jimenez BN_GENCB *cb = NULL; 241f5b1c8a1SJohn Marino char *num_bits = NULL; 242f5b1c8a1SJohn Marino DH *dh = NULL; 243f5b1c8a1SJohn Marino int num = 0; 244f5b1c8a1SJohn Marino int ret = 1; 245f5b1c8a1SJohn Marino int i; 246f5b1c8a1SJohn Marino 247f5b1c8a1SJohn Marino if (single_execution) { 24872c33676SMaxim Ag if (pledge("stdio cpath wpath rpath", NULL) == -1) { 249f5b1c8a1SJohn Marino perror("pledge"); 250f5b1c8a1SJohn Marino exit(1); 251f5b1c8a1SJohn Marino } 252f5b1c8a1SJohn Marino } 253f5b1c8a1SJohn Marino 254f5b1c8a1SJohn Marino memset(&dhparam_config, 0, sizeof(dhparam_config)); 255f5b1c8a1SJohn Marino 256f5b1c8a1SJohn Marino dhparam_config.informat = FORMAT_PEM; 257f5b1c8a1SJohn Marino dhparam_config.outformat = FORMAT_PEM; 258f5b1c8a1SJohn Marino 259f5b1c8a1SJohn Marino if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) { 260f5b1c8a1SJohn Marino dhparam_usage(); 261f5b1c8a1SJohn Marino return (1); 262f5b1c8a1SJohn Marino } 263f5b1c8a1SJohn Marino 264f5b1c8a1SJohn Marino if (num_bits != NULL) { 265f5b1c8a1SJohn Marino if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) { 266f5b1c8a1SJohn Marino BIO_printf(bio_err, "invalid number of bits: %s\n", 267f5b1c8a1SJohn Marino num_bits); 268f5b1c8a1SJohn Marino return (1); 269f5b1c8a1SJohn Marino } 270f5b1c8a1SJohn Marino } 271f5b1c8a1SJohn Marino 272f5b1c8a1SJohn Marino if (dhparam_config.g && !num) 273f5b1c8a1SJohn Marino num = DEFBITS; 274f5b1c8a1SJohn Marino 275f5b1c8a1SJohn Marino if (dhparam_config.dsaparam) { 276f5b1c8a1SJohn Marino if (dhparam_config.g) { 277f5b1c8a1SJohn Marino BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); 278f5b1c8a1SJohn Marino goto end; 279f5b1c8a1SJohn Marino } 280f5b1c8a1SJohn Marino } else { 281f5b1c8a1SJohn Marino /* DH parameters */ 282f5b1c8a1SJohn Marino if (num && !dhparam_config.g) 283f5b1c8a1SJohn Marino dhparam_config.g = 2; 284f5b1c8a1SJohn Marino } 285f5b1c8a1SJohn Marino 286f5b1c8a1SJohn Marino if (num) { 287*de0e0e4dSAntonio Huete Jimenez if ((cb = BN_GENCB_new()) == NULL) { 288*de0e0e4dSAntonio Huete Jimenez BIO_printf(bio_err, 289*de0e0e4dSAntonio Huete Jimenez "Error allocating BN_GENCB object\n"); 290*de0e0e4dSAntonio Huete Jimenez goto end; 291*de0e0e4dSAntonio Huete Jimenez } 292f5b1c8a1SJohn Marino 293*de0e0e4dSAntonio Huete Jimenez BN_GENCB_set(cb, dh_cb, bio_err); 294f5b1c8a1SJohn Marino if (dhparam_config.dsaparam) { 295f5b1c8a1SJohn Marino DSA *dsa = DSA_new(); 296f5b1c8a1SJohn Marino 297f5b1c8a1SJohn Marino BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num); 298f5b1c8a1SJohn Marino if (!dsa || !DSA_generate_parameters_ex(dsa, num, 299*de0e0e4dSAntonio Huete Jimenez NULL, 0, NULL, NULL, cb)) { 300f5b1c8a1SJohn Marino DSA_free(dsa); 301f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 302f5b1c8a1SJohn Marino goto end; 303f5b1c8a1SJohn Marino } 304f5b1c8a1SJohn Marino dh = DSA_dup_DH(dsa); 305f5b1c8a1SJohn Marino DSA_free(dsa); 306f5b1c8a1SJohn Marino if (dh == NULL) { 307f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 308f5b1c8a1SJohn Marino goto end; 309f5b1c8a1SJohn Marino } 310f5b1c8a1SJohn Marino } else { 311f5b1c8a1SJohn Marino dh = DH_new(); 312f5b1c8a1SJohn Marino BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, dhparam_config.g); 313f5b1c8a1SJohn Marino BIO_printf(bio_err, "This is going to take a long time\n"); 314*de0e0e4dSAntonio Huete Jimenez if (!dh || !DH_generate_parameters_ex(dh, num, dhparam_config.g, cb)) { 315f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 316f5b1c8a1SJohn Marino goto end; 317f5b1c8a1SJohn Marino } 318f5b1c8a1SJohn Marino } 319f5b1c8a1SJohn Marino } else { 320f5b1c8a1SJohn Marino 321f5b1c8a1SJohn Marino in = BIO_new(BIO_s_file()); 322f5b1c8a1SJohn Marino if (in == NULL) { 323f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 324f5b1c8a1SJohn Marino goto end; 325f5b1c8a1SJohn Marino } 326f5b1c8a1SJohn Marino if (dhparam_config.infile == NULL) 327f5b1c8a1SJohn Marino BIO_set_fp(in, stdin, BIO_NOCLOSE); 328f5b1c8a1SJohn Marino else { 329f5b1c8a1SJohn Marino if (BIO_read_filename(in, dhparam_config.infile) <= 0) { 330f5b1c8a1SJohn Marino perror(dhparam_config.infile); 331f5b1c8a1SJohn Marino goto end; 332f5b1c8a1SJohn Marino } 333f5b1c8a1SJohn Marino } 334f5b1c8a1SJohn Marino 335f5b1c8a1SJohn Marino if (dhparam_config.informat != FORMAT_ASN1 && 336f5b1c8a1SJohn Marino dhparam_config.informat != FORMAT_PEM) { 337f5b1c8a1SJohn Marino BIO_printf(bio_err, "bad input format specified\n"); 338f5b1c8a1SJohn Marino goto end; 339f5b1c8a1SJohn Marino } 340f5b1c8a1SJohn Marino if (dhparam_config.dsaparam) { 341f5b1c8a1SJohn Marino DSA *dsa; 342f5b1c8a1SJohn Marino 343f5b1c8a1SJohn Marino if (dhparam_config.informat == FORMAT_ASN1) 344f5b1c8a1SJohn Marino dsa = d2i_DSAparams_bio(in, NULL); 345f5b1c8a1SJohn Marino else /* informat == FORMAT_PEM */ 346f5b1c8a1SJohn Marino dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); 347f5b1c8a1SJohn Marino 348f5b1c8a1SJohn Marino if (dsa == NULL) { 349f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to load DSA parameters\n"); 350f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 351f5b1c8a1SJohn Marino goto end; 352f5b1c8a1SJohn Marino } 353f5b1c8a1SJohn Marino dh = DSA_dup_DH(dsa); 354f5b1c8a1SJohn Marino DSA_free(dsa); 355f5b1c8a1SJohn Marino if (dh == NULL) { 356f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 357f5b1c8a1SJohn Marino goto end; 358f5b1c8a1SJohn Marino } 359f5b1c8a1SJohn Marino } else 360f5b1c8a1SJohn Marino { 361f5b1c8a1SJohn Marino if (dhparam_config.informat == FORMAT_ASN1) 362f5b1c8a1SJohn Marino dh = d2i_DHparams_bio(in, NULL); 363f5b1c8a1SJohn Marino else /* informat == FORMAT_PEM */ 364f5b1c8a1SJohn Marino dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 365f5b1c8a1SJohn Marino 366f5b1c8a1SJohn Marino if (dh == NULL) { 367f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to load DH parameters\n"); 368f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 369f5b1c8a1SJohn Marino goto end; 370f5b1c8a1SJohn Marino } 371f5b1c8a1SJohn Marino } 372f5b1c8a1SJohn Marino 373f5b1c8a1SJohn Marino /* dh != NULL */ 374f5b1c8a1SJohn Marino } 375f5b1c8a1SJohn Marino 376f5b1c8a1SJohn Marino out = BIO_new(BIO_s_file()); 377f5b1c8a1SJohn Marino if (out == NULL) { 378f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 379f5b1c8a1SJohn Marino goto end; 380f5b1c8a1SJohn Marino } 381f5b1c8a1SJohn Marino if (dhparam_config.outfile == NULL) { 382f5b1c8a1SJohn Marino BIO_set_fp(out, stdout, BIO_NOCLOSE); 383f5b1c8a1SJohn Marino } else { 384f5b1c8a1SJohn Marino if (BIO_write_filename(out, dhparam_config.outfile) <= 0) { 385f5b1c8a1SJohn Marino perror(dhparam_config.outfile); 386f5b1c8a1SJohn Marino goto end; 387f5b1c8a1SJohn Marino } 388f5b1c8a1SJohn Marino } 389f5b1c8a1SJohn Marino 390f5b1c8a1SJohn Marino 391f5b1c8a1SJohn Marino if (dhparam_config.text) { 392f5b1c8a1SJohn Marino DHparams_print(out, dh); 393f5b1c8a1SJohn Marino } 394f5b1c8a1SJohn Marino if (dhparam_config.check) { 395f5b1c8a1SJohn Marino if (!DH_check(dh, &i)) { 396f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 397f5b1c8a1SJohn Marino goto end; 398f5b1c8a1SJohn Marino } 399f5b1c8a1SJohn Marino if (i & DH_CHECK_P_NOT_PRIME) 400f5b1c8a1SJohn Marino printf("p value is not prime\n"); 401f5b1c8a1SJohn Marino if (i & DH_CHECK_P_NOT_SAFE_PRIME) 402f5b1c8a1SJohn Marino printf("p value is not a safe prime\n"); 403f5b1c8a1SJohn Marino if (i & DH_UNABLE_TO_CHECK_GENERATOR) 404f5b1c8a1SJohn Marino printf("unable to check the generator value\n"); 405f5b1c8a1SJohn Marino if (i & DH_NOT_SUITABLE_GENERATOR) 406f5b1c8a1SJohn Marino printf("the g value is not a generator\n"); 407f5b1c8a1SJohn Marino if (i == 0) 408f5b1c8a1SJohn Marino printf("DH parameters appear to be ok.\n"); 409f5b1c8a1SJohn Marino } 410f5b1c8a1SJohn Marino if (dhparam_config.C) { 411f5b1c8a1SJohn Marino unsigned char *data; 412f5b1c8a1SJohn Marino int len, l, bits; 413f5b1c8a1SJohn Marino 414*de0e0e4dSAntonio Huete Jimenez len = BN_num_bytes(DH_get0_p(dh)); 415*de0e0e4dSAntonio Huete Jimenez bits = BN_num_bits(DH_get0_p(dh)); 416f5b1c8a1SJohn Marino data = malloc(len); 417f5b1c8a1SJohn Marino if (data == NULL) { 418f5b1c8a1SJohn Marino perror("malloc"); 419f5b1c8a1SJohn Marino goto end; 420f5b1c8a1SJohn Marino } 421f5b1c8a1SJohn Marino printf("#ifndef HEADER_DH_H\n" 422f5b1c8a1SJohn Marino "#include <openssl/dh.h>\n" 423f5b1c8a1SJohn Marino "#endif\n"); 424f5b1c8a1SJohn Marino printf("DH *get_dh%d()\n\t{\n", bits); 425f5b1c8a1SJohn Marino 426*de0e0e4dSAntonio Huete Jimenez l = BN_bn2bin(DH_get0_p(dh), data); 427f5b1c8a1SJohn Marino printf("\tstatic unsigned char dh%d_p[] = {", bits); 428f5b1c8a1SJohn Marino for (i = 0; i < l; i++) { 429f5b1c8a1SJohn Marino if ((i % 12) == 0) 430f5b1c8a1SJohn Marino printf("\n\t\t"); 431f5b1c8a1SJohn Marino printf("0x%02X, ", data[i]); 432f5b1c8a1SJohn Marino } 433f5b1c8a1SJohn Marino printf("\n\t\t};\n"); 434f5b1c8a1SJohn Marino 435*de0e0e4dSAntonio Huete Jimenez l = BN_bn2bin(DH_get0_g(dh), data); 436f5b1c8a1SJohn Marino printf("\tstatic unsigned char dh%d_g[] = {", bits); 437f5b1c8a1SJohn Marino for (i = 0; i < l; i++) { 438f5b1c8a1SJohn Marino if ((i % 12) == 0) 439f5b1c8a1SJohn Marino printf("\n\t\t"); 440f5b1c8a1SJohn Marino printf("0x%02X, ", data[i]); 441f5b1c8a1SJohn Marino } 442f5b1c8a1SJohn Marino printf("\n\t\t};\n"); 443f5b1c8a1SJohn Marino 444*de0e0e4dSAntonio Huete Jimenez printf("\tDH *dh;\n"); 445*de0e0e4dSAntonio Huete Jimenez printf("\tBIGNUM *p = NULL, *g = NULL;\n\n"); 446f5b1c8a1SJohn Marino printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n"); 447*de0e0e4dSAntonio Huete Jimenez printf("\tp = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n", 448f5b1c8a1SJohn Marino bits, bits); 449*de0e0e4dSAntonio Huete Jimenez printf("\tg = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n", 450f5b1c8a1SJohn Marino bits, bits); 451*de0e0e4dSAntonio Huete Jimenez printf("\tif (p == NULL || g == NULL)\n"); 452*de0e0e4dSAntonio Huete Jimenez printf("\t\t{ BN_free(p); BN_free(g); DH_free(dh); return(NULL); }\n"); 453*de0e0e4dSAntonio Huete Jimenez printf("\tDH_set0_pqg(dh, p, NULL, g);\n"); 454*de0e0e4dSAntonio Huete Jimenez if (DH_get_length(dh) > 0) 455*de0e0e4dSAntonio Huete Jimenez printf("\tDH_set_length(dh, %ld);\n", DH_get_length(dh)); 456f5b1c8a1SJohn Marino printf("\treturn(dh);\n\t}\n"); 457f5b1c8a1SJohn Marino free(data); 458f5b1c8a1SJohn Marino } 459f5b1c8a1SJohn Marino if (!dhparam_config.noout) { 460f5b1c8a1SJohn Marino if (dhparam_config.outformat == FORMAT_ASN1) 461f5b1c8a1SJohn Marino i = i2d_DHparams_bio(out, dh); 462f5b1c8a1SJohn Marino else if (dhparam_config.outformat == FORMAT_PEM) 463f5b1c8a1SJohn Marino i = PEM_write_bio_DHparams(out, dh); 464f5b1c8a1SJohn Marino else { 465f5b1c8a1SJohn Marino BIO_printf(bio_err, "bad output format specified for outfile\n"); 466f5b1c8a1SJohn Marino goto end; 467f5b1c8a1SJohn Marino } 468f5b1c8a1SJohn Marino if (!i) { 469f5b1c8a1SJohn Marino BIO_printf(bio_err, "unable to write DH parameters\n"); 470f5b1c8a1SJohn Marino ERR_print_errors(bio_err); 471f5b1c8a1SJohn Marino goto end; 472f5b1c8a1SJohn Marino } 473f5b1c8a1SJohn Marino } 474f5b1c8a1SJohn Marino ret = 0; 475f5b1c8a1SJohn Marino 476f5b1c8a1SJohn Marino end: 477f5b1c8a1SJohn Marino BIO_free(in); 478f5b1c8a1SJohn Marino BIO_free_all(out); 479*de0e0e4dSAntonio Huete Jimenez BN_GENCB_free(cb); 480f5b1c8a1SJohn Marino DH_free(dh); 481f5b1c8a1SJohn Marino 482f5b1c8a1SJohn Marino return (ret); 483f5b1c8a1SJohn Marino } 484f5b1c8a1SJohn Marino 485f5b1c8a1SJohn Marino /* dh_cb is identical to dsa_cb in apps/dsaparam.c */ 486f5b1c8a1SJohn Marino static int 487f5b1c8a1SJohn Marino dh_cb(int p, int n, BN_GENCB *cb) 488f5b1c8a1SJohn Marino { 489f5b1c8a1SJohn Marino char c = '*'; 490f5b1c8a1SJohn Marino 491f5b1c8a1SJohn Marino if (p == 0) 492f5b1c8a1SJohn Marino c = '.'; 493f5b1c8a1SJohn Marino if (p == 1) 494f5b1c8a1SJohn Marino c = '+'; 495f5b1c8a1SJohn Marino if (p == 2) 496f5b1c8a1SJohn Marino c = '*'; 497f5b1c8a1SJohn Marino if (p == 3) 498f5b1c8a1SJohn Marino c = '\n'; 499*de0e0e4dSAntonio Huete Jimenez BIO_write(BN_GENCB_get_arg(cb), &c, 1); 500*de0e0e4dSAntonio Huete Jimenez (void) BIO_flush(BN_GENCB_get_arg(cb)); 501f5b1c8a1SJohn Marino return 1; 502f5b1c8a1SJohn Marino } 503f5b1c8a1SJohn Marino 504f5b1c8a1SJohn Marino #endif 505