| 852 | } |
| 853 | |
| 854 | static apr_status_t gen_ec(md_pkey_t **ppkey, apr_pool_t *p, const char *curve) |
| 855 | { |
| 856 | EVP_PKEY_CTX *ctx = NULL; |
| 857 | apr_status_t rv; |
| 858 | int curve_nid = NID_undef; |
| 859 | |
| 860 | /* 1. Convert the cure into its registered identifier. Curves can be known under |
| 861 | * different names. |
| 862 | * 2. Determine, if the curve is supported by OpenSSL (or whatever is linked). |
| 863 | * 3. Generate the key, respecting the specific quirks some curves require. |
| 864 | */ |
| 865 | curve_nid = EC_curve_nist2nid(curve); |
| 866 | /* In case this fails, try some names from other standards, like SECG */ |
| 867 | #ifdef NID_secp384r1 |
| 868 | if (NID_undef == curve_nid && !apr_cstr_casecmp("secp384r1", curve)) { |
| 869 | curve_nid = NID_secp384r1; |
| 870 | curve = EC_curve_nid2nist(curve_nid); |
| 871 | } |
| 872 | #endif |
| 873 | #ifdef NID_X9_62_prime256v1 |
| 874 | if (NID_undef == curve_nid && !apr_cstr_casecmp("secp256r1", curve)) { |
| 875 | curve_nid = NID_X9_62_prime256v1; |
| 876 | curve = EC_curve_nid2nist(curve_nid); |
| 877 | } |
| 878 | #endif |
| 879 | #ifdef NID_X9_62_prime192v1 |
| 880 | if (NID_undef == curve_nid && !apr_cstr_casecmp("secp192r1", curve)) { |
| 881 | curve_nid = NID_X9_62_prime192v1; |
| 882 | curve = EC_curve_nid2nist(curve_nid); |
| 883 | } |
| 884 | #endif |
| 885 | #if defined(NID_X25519) && (!defined(LIBRESSL_VERSION_NUMBER) || \ |
| 886 | LIBRESSL_VERSION_NUMBER >= 0x3070000fL) |
| 887 | if (NID_undef == curve_nid && !apr_cstr_casecmp("X25519", curve)) { |
| 888 | curve_nid = NID_X25519; |
| 889 | curve = EC_curve_nid2nist(curve_nid); |
| 890 | } |
| 891 | #endif |
| 892 | if (NID_undef == curve_nid) { |
| 893 | /* OpenSSL object/curve names */ |
| 894 | curve_nid = OBJ_sn2nid(curve); |
| 895 | } |
| 896 | if (NID_undef == curve_nid) { |
| 897 | md_log_perror(MD_LOG_MARK, MD_LOG_ERR, 0, p, "ec curve unknown: %s", curve); |
| 898 | rv = APR_ENOTIMPL; goto leave; |
| 899 | } |
| 900 | |
| 901 | *ppkey = make_pkey(p); |
| 902 | switch (curve_nid) { |
| 903 | |
| 904 | #if defined(NID_X25519) && (!defined(LIBRESSL_VERSION_NUMBER) || \ |
| 905 | LIBRESSL_VERSION_NUMBER >= 0x3070000fL) |
| 906 | case NID_X25519: |
| 907 | /* no parameters */ |
| 908 | if (NULL == (ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL)) |
| 909 | || EVP_PKEY_keygen_init(ctx) <= 0 |
| 910 | || EVP_PKEY_keygen(ctx, &(*ppkey)->pkey) <= 0) { |
| 911 | md_log_perror(MD_LOG_MARK, MD_LOG_WARNING, 0, p, |
no test coverage detected