/** * gnutls_privkey_generate2: * @pkey: The private key * @algo: is one of the algorithms in #gnutls_pk_algorithm_t. * @bits: the size of the modulus * @flags: Must be zero or flags from #gnutls_privkey_flags_t. * @data: Allow specifying %gnutls_keygen_data_st types such as the seed to be used. * @data_size: The number of @data available. * * This function will generate a random private key. Note that this * function must be called on an empty private key. The flag %GNUTLS_PRIVKEY_FLAG_PROVABLE * instructs the key generation process to use algorithms which generate * provable parameters out of a seed. * * Note that when generating an elliptic curve key, the curve * can be substituted in the place of the bits parameter using the * GNUTLS_CURVE_TO_BITS() macro. * * Do not set the number of bits directly, use gnutls_sec_param_to_pk_bits(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.5.0 **/ int gnutls_privkey_generate2(gnutls_privkey_t pkey, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags, const gnutls_keygen_data_st *data, unsigned data_size) { int ret; ret = gnutls_x509_privkey_init(&pkey->key.x509); if (ret < 0) return gnutls_assert_val(ret); ret = gnutls_x509_privkey_generate2(pkey->key.x509, algo, bits, flags, data, data_size); if (ret < 0) { gnutls_x509_privkey_deinit(pkey->key.x509); pkey->key.x509 = NULL; return gnutls_assert_val(ret); } pkey->type = GNUTLS_PRIVKEY_X509; pkey->pk_algorithm = algo; pkey->flags = flags | GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE; return 0; }
/* If how is zero then the included parameters are used. */ int generate_prime(FILE * outfile, int how, common_info_st * info) { int ret; gnutls_dh_params_t dh_params; gnutls_datum_t p, g; int bits = get_bits(GNUTLS_PK_DH, info->bits, info->sec_param, 1); unsigned int q_bits = 0, key_bits = 0; fix_lbuffer(0); gnutls_dh_params_init(&dh_params); if (how != 0) { fprintf(stderr, "Generating DH parameters (%d bits)...\n", bits); fprintf(stderr, "(might take long time)\n"); } else fprintf(stderr, "Retrieving DH parameters...\n"); if (how != 0) { if (info->provable != 0) { gnutls_x509_privkey_t pkey; unsigned save; ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "Error initializing key: %s\n", gnutls_strerror(ret)); exit(1); } if (info->seed_size > 0) { gnutls_keygen_data_st data; if (info->seed_size < 32) { fprintf(stderr, "For DH parameter generation a 32-byte seed value or larger is expected (have: %d); use -d 2 for more information.\n", (int)info->seed_size); exit(1); } data.type = GNUTLS_KEYGEN_SEED; data.data = (void*)info->seed; data.size = info->seed_size; ret = gnutls_x509_privkey_generate2(pkey, GNUTLS_PK_DSA, bits, GNUTLS_PRIVKEY_FLAG_PROVABLE, &data, 1); } else { ret = gnutls_x509_privkey_generate(pkey, GNUTLS_PK_DSA, bits, GNUTLS_PRIVKEY_FLAG_PROVABLE); } if (ret < 0) { fprintf(stderr, "Error generating DSA parameters: %s\n", gnutls_strerror(ret)); exit(1); } if (info->outcert_format == GNUTLS_X509_FMT_PEM) { save = info->no_compat; info->no_compat = 1; print_private_key(outfile, info, pkey); info->no_compat = save; } ret = gnutls_dh_params_import_dsa(dh_params, pkey); if (ret < 0) { fprintf(stderr, "Error importing DSA parameters: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_privkey_deinit(pkey); } else { ret = gnutls_dh_params_generate2(dh_params, bits); if (ret < 0) { fprintf(stderr, "Error generating parameters: %s\n", gnutls_strerror(ret)); exit(1); } } ret = gnutls_dh_params_export_raw(dh_params, &p, &g, &q_bits); if (ret < 0) { fprintf(stderr, "Error exporting parameters: %s\n", gnutls_strerror(ret)); exit(1); } } else { if (info->provable != 0) { fprintf(stderr, "The DH parameters obtained via this option are not provable\n"); exit(1); } #if defined(ENABLE_DHE) || defined(ENABLE_ANON) if (bits <= 2048) { p = gnutls_ffdhe_2048_group_prime; g = gnutls_ffdhe_2048_group_generator; key_bits = gnutls_ffdhe_2048_key_bits; bits = 2048; } else if (bits <= 3072) { p = gnutls_ffdhe_3072_group_prime; g = gnutls_ffdhe_3072_group_generator; key_bits = gnutls_ffdhe_3072_key_bits; bits = 3072; } else if (bits <= 4096) { p = gnutls_ffdhe_4096_group_prime; g = gnutls_ffdhe_4096_group_generator; key_bits = gnutls_ffdhe_4096_key_bits; bits = 4096; } else { p = gnutls_ffdhe_8192_group_prime; g = gnutls_ffdhe_8192_group_generator; key_bits = gnutls_ffdhe_8192_key_bits; bits = 8192; } ret = gnutls_dh_params_import_raw2(dh_params, &p, &g, key_bits); if (ret < 0) { fprintf(stderr, "Error exporting parameters: %s\n", gnutls_strerror(ret)); exit(1); } #elif defined(ENABLE_SRP) if (bits <= 1024) { p = gnutls_srp_1024_group_prime; g = gnutls_srp_1024_group_generator; bits = 1024; } else if (bits <= 1536) { p = gnutls_srp_1536_group_prime; g = gnutls_srp_1536_group_generator; bits = 1536; } else if (bits <= 2048) { p = gnutls_srp_2048_group_prime; g = gnutls_srp_2048_group_generator; bits = 2048; } else if (bits <= 3072) { p = gnutls_srp_3072_group_prime; g = gnutls_srp_3072_group_generator; bits = 3072; } else { p = gnutls_srp_4096_group_prime; g = gnutls_srp_4096_group_generator; bits = 4096; } ret = gnutls_dh_params_import_raw(dh_params, &p, &g); if (ret < 0) { fprintf(stderr, "Error exporting parameters: %s\n", gnutls_strerror(ret)); exit(1); } #else fprintf(stderr, "Parameters unavailable as SRP is disabled.\n"); exit(1); #endif } if (info->outcert_format == GNUTLS_X509_FMT_PEM) print_dh_info(outfile, &p, &g, q_bits, info->cprint); if (!info->cprint) { /* generate a PKCS#3 structure */ size_t len = lbuffer_size; ret = gnutls_dh_params_export_pkcs3(dh_params, info->outcert_format, lbuffer, &len); if (ret == 0) { if (info->outcert_format == GNUTLS_X509_FMT_PEM) fprintf(outfile, "\n%s", lbuffer); else fwrite(lbuffer, 1, len, outfile); } else { fprintf(stderr, "Error: %s\n", gnutls_strerror(ret)); } } if (how != 0) { gnutls_free(p.data); gnutls_free(g.data); } gnutls_dh_params_deinit(dh_params); return 0; }