1 1.1.1.2 christos /* 2 1.1.1.2 christos * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1.1.2 christos * Licensed under the OpenSSL license (the "License"). You may not use 5 1.1.1.2 christos * this file except in compliance with the License. You can obtain a copy 6 1.1.1.2 christos * in the file LICENSE in the source distribution or at 7 1.1.1.2 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1.1.2 christos #include <openssl/opensslconf.h> 11 1.1.1.2 christos #include <stdio.h> 12 1.1.1.2 christos #include <stdlib.h> 13 1.1.1.2 christos #include <time.h> 14 1.1.1.2 christos #include <string.h> 15 1.1.1.2 christos #include "apps.h" 16 1.1.1.2 christos #include "progs.h" 17 1.1.1.2 christos #include <openssl/bio.h> 18 1.1.1.2 christos #include <openssl/err.h> 19 1.1.1.2 christos #include <openssl/bn.h> 20 1.1.1.2 christos #include <openssl/dh.h> 21 1.1.1.2 christos #include <openssl/x509.h> 22 1.1.1.2 christos #include <openssl/pem.h> 23 1.1 christos 24 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 25 1.1.1.2 christos # include <openssl/dsa.h> 26 1.1.1.2 christos #endif 27 1.1.1.2 christos 28 1.1.1.2 christos #define DEFBITS 2048 29 1.1 christos 30 1.1.1.2 christos static int dh_cb(int p, int n, BN_GENCB *cb); 31 1.1 christos 32 1.1.1.2 christos typedef enum OPTION_choice { 33 1.1.1.2 christos OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 34 1.1.1.2 christos OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, 35 1.1.1.2 christos OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT, 36 1.1.1.2 christos OPT_DSAPARAM, OPT_C, OPT_2, OPT_5, 37 1.1.1.2 christos OPT_R_ENUM 38 1.1.1.2 christos } OPTION_CHOICE; 39 1.1.1.2 christos 40 1.1.1.2 christos const OPTIONS dhparam_options[] = { 41 1.1.1.2 christos {OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"}, 42 1.1.1.2 christos {OPT_HELP_STR, 1, '-', "Valid options are:\n"}, 43 1.1.1.2 christos {"help", OPT_HELP, '-', "Display this summary"}, 44 1.1.1.2 christos {"in", OPT_IN, '<', "Input file"}, 45 1.1.1.2 christos {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"}, 46 1.1.1.2 christos {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"}, 47 1.1.1.2 christos {"out", OPT_OUT, '>', "Output file"}, 48 1.1.1.2 christos {"check", OPT_CHECK, '-', "Check the DH parameters"}, 49 1.1.1.2 christos {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"}, 50 1.1.1.2 christos {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"}, 51 1.1.1.2 christos OPT_R_OPTIONS, 52 1.1.1.2 christos {"C", OPT_C, '-', "Print C code"}, 53 1.1.1.2 christos {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"}, 54 1.1.1.2 christos {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"}, 55 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 56 1.1.1.2 christos {"dsaparam", OPT_DSAPARAM, '-', 57 1.1.1.2 christos "Read or generate DSA parameters, convert to DH"}, 58 1.1.1.2 christos #endif 59 1.1.1.2 christos #ifndef OPENSSL_NO_ENGINE 60 1.1.1.2 christos {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"}, 61 1.1.1.2 christos #endif 62 1.1.1.2 christos {NULL} 63 1.1.1.2 christos }; 64 1.1.1.2 christos 65 1.1.1.2 christos int dhparam_main(int argc, char **argv) 66 1.1 christos { 67 1.1 christos BIO *in = NULL, *out = NULL; 68 1.1.1.2 christos DH *dh = NULL; 69 1.1.1.2 christos char *infile = NULL, *outfile = NULL, *prog; 70 1.1 christos ENGINE *e = NULL; 71 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 72 1.1.1.2 christos int dsaparam = 0; 73 1.1.1.2 christos #endif 74 1.1.1.2 christos int i, text = 0, C = 0, ret = 1, num = 0, g = 0; 75 1.1.1.2 christos int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0; 76 1.1.1.2 christos OPTION_CHOICE o; 77 1.1.1.2 christos 78 1.1.1.2 christos prog = opt_init(argc, argv, dhparam_options); 79 1.1.1.2 christos while ((o = opt_next()) != OPT_EOF) { 80 1.1.1.2 christos switch (o) { 81 1.1.1.2 christos case OPT_EOF: 82 1.1.1.2 christos case OPT_ERR: 83 1.1.1.2 christos opthelp: 84 1.1.1.2 christos BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); 85 1.1.1.2 christos goto end; 86 1.1.1.2 christos case OPT_HELP: 87 1.1.1.2 christos opt_help(dhparam_options); 88 1.1.1.2 christos ret = 0; 89 1.1.1.2 christos goto end; 90 1.1.1.2 christos case OPT_INFORM: 91 1.1.1.2 christos if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) 92 1.1.1.2 christos goto opthelp; 93 1.1.1.2 christos break; 94 1.1.1.2 christos case OPT_OUTFORM: 95 1.1.1.2 christos if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) 96 1.1.1.2 christos goto opthelp; 97 1.1.1.2 christos break; 98 1.1.1.2 christos case OPT_IN: 99 1.1.1.2 christos infile = opt_arg(); 100 1.1.1.2 christos break; 101 1.1.1.2 christos case OPT_OUT: 102 1.1.1.2 christos outfile = opt_arg(); 103 1.1.1.2 christos break; 104 1.1.1.2 christos case OPT_ENGINE: 105 1.1.1.2 christos e = setup_engine(opt_arg(), 0); 106 1.1.1.2 christos break; 107 1.1.1.2 christos case OPT_CHECK: 108 1.1 christos check = 1; 109 1.1.1.2 christos break; 110 1.1.1.2 christos case OPT_TEXT: 111 1.1 christos text = 1; 112 1.1.1.2 christos break; 113 1.1.1.2 christos case OPT_DSAPARAM: 114 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 115 1.1 christos dsaparam = 1; 116 1.1.1.2 christos #endif 117 1.1.1.2 christos break; 118 1.1.1.2 christos case OPT_C: 119 1.1 christos C = 1; 120 1.1.1.2 christos break; 121 1.1.1.2 christos case OPT_2: 122 1.1 christos g = 2; 123 1.1.1.2 christos break; 124 1.1.1.2 christos case OPT_5: 125 1.1 christos g = 5; 126 1.1.1.2 christos break; 127 1.1.1.2 christos case OPT_NOOUT: 128 1.1.1.2 christos noout = 1; 129 1.1.1.2 christos break; 130 1.1.1.2 christos case OPT_R_CASES: 131 1.1.1.2 christos if (!opt_rand(o)) 132 1.1.1.2 christos goto end; 133 1.1.1.2 christos break; 134 1.1.1.2 christos } 135 1.1 christos } 136 1.1.1.2 christos argc = opt_num_rest(); 137 1.1.1.2 christos argv = opt_rest(); 138 1.1 christos 139 1.1.1.2 christos if (argv[0] != NULL && (!opt_int(argv[0], &num) || num <= 0)) 140 1.1 christos goto end; 141 1.1 christos 142 1.1 christos if (g && !num) 143 1.1 christos num = DEFBITS; 144 1.1 christos 145 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 146 1.1.1.2 christos if (dsaparam && g) { 147 1.1.1.2 christos BIO_printf(bio_err, 148 1.1.1.2 christos "generator may not be chosen for DSA parameters\n"); 149 1.1.1.2 christos goto end; 150 1.1 christos } 151 1.1.1.2 christos #endif 152 1.1.1.2 christos 153 1.1.1.2 christos out = bio_open_default(outfile, 'w', outformat); 154 1.1.1.2 christos if (out == NULL) 155 1.1.1.2 christos goto end; 156 1.1.1.2 christos 157 1.1.1.2 christos /* DH parameters */ 158 1.1.1.2 christos if (num && !g) 159 1.1.1.2 christos g = 2; 160 1.1 christos 161 1.1 christos if (num) { 162 1.1 christos 163 1.1.1.2 christos BN_GENCB *cb; 164 1.1.1.2 christos cb = BN_GENCB_new(); 165 1.1.1.2 christos if (cb == NULL) { 166 1.1.1.2 christos ERR_print_errors(bio_err); 167 1.1.1.2 christos goto end; 168 1.1 christos } 169 1.1 christos 170 1.1.1.2 christos BN_GENCB_set(cb, dh_cb, bio_err); 171 1.1.1.2 christos 172 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 173 1.1 christos if (dsaparam) { 174 1.1 christos DSA *dsa = DSA_new(); 175 1.1 christos 176 1.1 christos BIO_printf(bio_err, 177 1.1 christos "Generating DSA parameters, %d bit long prime\n", num); 178 1.1.1.2 christos if (dsa == NULL 179 1.1 christos || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, 180 1.1.1.2 christos cb)) { 181 1.1.1.2 christos DSA_free(dsa); 182 1.1.1.2 christos BN_GENCB_free(cb); 183 1.1 christos ERR_print_errors(bio_err); 184 1.1 christos goto end; 185 1.1 christos } 186 1.1 christos 187 1.1 christos dh = DSA_dup_DH(dsa); 188 1.1 christos DSA_free(dsa); 189 1.1 christos if (dh == NULL) { 190 1.1.1.2 christos BN_GENCB_free(cb); 191 1.1 christos ERR_print_errors(bio_err); 192 1.1 christos goto end; 193 1.1 christos } 194 1.1 christos } else 195 1.1.1.2 christos #endif 196 1.1 christos { 197 1.1 christos dh = DH_new(); 198 1.1 christos BIO_printf(bio_err, 199 1.1 christos "Generating DH parameters, %d bit long safe prime, generator %d\n", 200 1.1 christos num, g); 201 1.1 christos BIO_printf(bio_err, "This is going to take a long time\n"); 202 1.1.1.2 christos if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) { 203 1.1.1.2 christos BN_GENCB_free(cb); 204 1.1 christos ERR_print_errors(bio_err); 205 1.1 christos goto end; 206 1.1 christos } 207 1.1 christos } 208 1.1 christos 209 1.1.1.2 christos BN_GENCB_free(cb); 210 1.1 christos } else { 211 1.1 christos 212 1.1.1.2 christos in = bio_open_default(infile, 'r', informat); 213 1.1.1.2 christos if (in == NULL) 214 1.1 christos goto end; 215 1.1 christos 216 1.1.1.2 christos #ifndef OPENSSL_NO_DSA 217 1.1 christos if (dsaparam) { 218 1.1 christos DSA *dsa; 219 1.1 christos 220 1.1 christos if (informat == FORMAT_ASN1) 221 1.1 christos dsa = d2i_DSAparams_bio(in, NULL); 222 1.1 christos else /* informat == FORMAT_PEM */ 223 1.1 christos dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); 224 1.1 christos 225 1.1 christos if (dsa == NULL) { 226 1.1 christos BIO_printf(bio_err, "unable to load DSA parameters\n"); 227 1.1 christos ERR_print_errors(bio_err); 228 1.1 christos goto end; 229 1.1 christos } 230 1.1 christos 231 1.1 christos dh = DSA_dup_DH(dsa); 232 1.1 christos DSA_free(dsa); 233 1.1 christos if (dh == NULL) { 234 1.1 christos ERR_print_errors(bio_err); 235 1.1 christos goto end; 236 1.1 christos } 237 1.1 christos } else 238 1.1.1.2 christos #endif 239 1.1 christos { 240 1.1.1.2 christos if (informat == FORMAT_ASN1) { 241 1.1.1.2 christos /* 242 1.1.1.2 christos * We have no PEM header to determine what type of DH params it 243 1.1.1.2 christos * is. We'll just try both. 244 1.1.1.2 christos */ 245 1.1 christos dh = d2i_DHparams_bio(in, NULL); 246 1.1.1.2 christos /* BIO_reset() returns 0 for success for file BIOs only!!! */ 247 1.1.1.2 christos if (dh == NULL && BIO_reset(in) == 0) 248 1.1.1.2 christos dh = d2i_DHxparams_bio(in, NULL); 249 1.1.1.2 christos } else { 250 1.1.1.2 christos /* informat == FORMAT_PEM */ 251 1.1 christos dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); 252 1.1.1.2 christos } 253 1.1 christos 254 1.1 christos if (dh == NULL) { 255 1.1 christos BIO_printf(bio_err, "unable to load DH parameters\n"); 256 1.1 christos ERR_print_errors(bio_err); 257 1.1 christos goto end; 258 1.1 christos } 259 1.1 christos } 260 1.1 christos 261 1.1 christos /* dh != NULL */ 262 1.1 christos } 263 1.1 christos 264 1.1 christos if (text) { 265 1.1 christos DHparams_print(out, dh); 266 1.1 christos } 267 1.1 christos 268 1.1 christos if (check) { 269 1.1 christos if (!DH_check(dh, &i)) { 270 1.1 christos ERR_print_errors(bio_err); 271 1.1 christos goto end; 272 1.1 christos } 273 1.1 christos if (i & DH_CHECK_P_NOT_PRIME) 274 1.1.1.2 christos BIO_printf(bio_err, "WARNING: p value is not prime\n"); 275 1.1 christos if (i & DH_CHECK_P_NOT_SAFE_PRIME) 276 1.1.1.2 christos BIO_printf(bio_err, "WARNING: p value is not a safe prime\n"); 277 1.1.1.2 christos if (i & DH_CHECK_Q_NOT_PRIME) 278 1.1.1.2 christos BIO_printf(bio_err, "WARNING: q value is not a prime\n"); 279 1.1.1.2 christos if (i & DH_CHECK_INVALID_Q_VALUE) 280 1.1.1.2 christos BIO_printf(bio_err, "WARNING: q value is invalid\n"); 281 1.1.1.2 christos if (i & DH_CHECK_INVALID_J_VALUE) 282 1.1.1.2 christos BIO_printf(bio_err, "WARNING: j value is invalid\n"); 283 1.1 christos if (i & DH_UNABLE_TO_CHECK_GENERATOR) 284 1.1.1.2 christos BIO_printf(bio_err, 285 1.1.1.2 christos "WARNING: unable to check the generator value\n"); 286 1.1 christos if (i & DH_NOT_SUITABLE_GENERATOR) 287 1.1.1.2 christos BIO_printf(bio_err, "WARNING: the g value is not a generator\n"); 288 1.1 christos if (i == 0) 289 1.1.1.2 christos BIO_printf(bio_err, "DH parameters appear to be ok.\n"); 290 1.1.1.2 christos if (num != 0 && i != 0) { 291 1.1.1.2 christos /* 292 1.1.1.2 christos * We have generated parameters but DH_check() indicates they are 293 1.1.1.2 christos * invalid! This should never happen! 294 1.1.1.2 christos */ 295 1.1.1.2 christos BIO_printf(bio_err, "ERROR: Invalid parameters generated\n"); 296 1.1.1.2 christos goto end; 297 1.1.1.2 christos } 298 1.1 christos } 299 1.1 christos if (C) { 300 1.1 christos unsigned char *data; 301 1.1.1.2 christos int len, bits; 302 1.1.1.2 christos const BIGNUM *pbn, *gbn; 303 1.1 christos 304 1.1.1.2 christos len = DH_size(dh); 305 1.1.1.2 christos bits = DH_bits(dh); 306 1.1.1.2 christos DH_get0_pqg(dh, &pbn, NULL, &gbn); 307 1.1.1.2 christos data = app_malloc(len, "print a BN"); 308 1.1.1.2 christos 309 1.1.1.2 christos BIO_printf(out, "static DH *get_dh%d(void)\n{\n", bits); 310 1.1.1.2 christos print_bignum_var(out, pbn, "dhp", bits, data); 311 1.1.1.2 christos print_bignum_var(out, gbn, "dhg", bits, data); 312 1.1.1.2 christos BIO_printf(out, " DH *dh = DH_new();\n" 313 1.1.1.2 christos " BIGNUM *p, *g;\n" 314 1.1.1.2 christos "\n" 315 1.1.1.2 christos " if (dh == NULL)\n" 316 1.1.1.2 christos " return NULL;\n"); 317 1.1.1.2 christos BIO_printf(out, " p = BN_bin2bn(dhp_%d, sizeof(dhp_%d), NULL);\n", 318 1.1.1.2 christos bits, bits); 319 1.1.1.2 christos BIO_printf(out, " g = BN_bin2bn(dhg_%d, sizeof(dhg_%d), NULL);\n", 320 1.1.1.2 christos bits, bits); 321 1.1.1.2 christos BIO_printf(out, " if (p == NULL || g == NULL\n" 322 1.1.1.2 christos " || !DH_set0_pqg(dh, p, NULL, g)) {\n" 323 1.1.1.2 christos " DH_free(dh);\n" 324 1.1.1.2 christos " BN_free(p);\n" 325 1.1.1.2 christos " BN_free(g);\n" 326 1.1.1.2 christos " return NULL;\n" 327 1.1.1.2 christos " }\n"); 328 1.1.1.2 christos if (DH_get_length(dh) > 0) 329 1.1.1.2 christos BIO_printf(out, 330 1.1.1.2 christos " if (!DH_set_length(dh, %ld)) {\n" 331 1.1.1.2 christos " DH_free(dh);\n" 332 1.1.1.2 christos " return NULL;\n" 333 1.1.1.2 christos " }\n", DH_get_length(dh)); 334 1.1.1.2 christos BIO_printf(out, " return dh;\n}\n"); 335 1.1 christos OPENSSL_free(data); 336 1.1 christos } 337 1.1 christos 338 1.1 christos if (!noout) { 339 1.1.1.2 christos const BIGNUM *q; 340 1.1.1.2 christos DH_get0_pqg(dh, NULL, &q, NULL); 341 1.1.1.2 christos if (outformat == FORMAT_ASN1) { 342 1.1.1.2 christos if (q != NULL) 343 1.1.1.2 christos i = i2d_DHxparams_bio(out, dh); 344 1.1 christos else 345 1.1.1.2 christos i = i2d_DHparams_bio(out, dh); 346 1.1.1.2 christos } else if (q != NULL) { 347 1.1.1.2 christos i = PEM_write_bio_DHxparams(out, dh); 348 1.1 christos } else { 349 1.1.1.2 christos i = PEM_write_bio_DHparams(out, dh); 350 1.1 christos } 351 1.1 christos if (!i) { 352 1.1 christos BIO_printf(bio_err, "unable to write DH parameters\n"); 353 1.1 christos ERR_print_errors(bio_err); 354 1.1 christos goto end; 355 1.1 christos } 356 1.1 christos } 357 1.1 christos ret = 0; 358 1.1 christos end: 359 1.1.1.2 christos BIO_free(in); 360 1.1.1.2 christos BIO_free_all(out); 361 1.1.1.2 christos DH_free(dh); 362 1.1 christos release_engine(e); 363 1.1.1.2 christos return ret; 364 1.1 christos } 365 1.1 christos 366 1.1.1.2 christos static int dh_cb(int p, int n, BN_GENCB *cb) 367 1.1 christos { 368 1.1.1.2 christos static const char symbols[] = ".+*\n"; 369 1.1.1.2 christos char c = (p >= 0 && (size_t)p < sizeof(symbols) - 1) ? symbols[p] : '?'; 370 1.1 christos 371 1.1.1.2 christos BIO_write(BN_GENCB_get_arg(cb), &c, 1); 372 1.1.1.2 christos (void)BIO_flush(BN_GENCB_get_arg(cb)); 373 1.1 christos return 1; 374 1.1 christos } 375