V2: Print also curve details, add missing ifdef
V3: Goto err instead of using M_FATAL, format fixes, use
EC_GROUP_get_curve_name + OBJ_nid2sn instead of ECPKParameters_print, add
compat headers for 1.0.2
V4: Formatting changes and change M_ERR to M_WARN
Acked-by: Steffan Karger <steffan@karger.me>
Message-Id: <1500828336-30314-1-git-send-email-arne@rfc2549.org>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg15124.html
Signed-off-by: David Sommerseth <davids@openvpn.net>
(cherry picked from commit bb23eca847c8edac9c3979b7f35468b74db00459)
... | ... |
@@ -914,6 +914,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then |
914 | 914 |
EVP_PKEY_id \ |
915 | 915 |
EVP_PKEY_get0_RSA \ |
916 | 916 |
EVP_PKEY_get0_DSA \ |
917 |
+ EVP_PKEY_get0_EC_KEY \ |
|
917 | 918 |
RSA_set_flags \ |
918 | 919 |
RSA_bits \ |
919 | 920 |
RSA_get0_key \ |
... | ... |
@@ -929,6 +930,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then |
929 | 929 |
RSA_meth_set_init \ |
930 | 930 |
RSA_meth_set_finish \ |
931 | 931 |
RSA_meth_set0_app_data \ |
932 |
+ EC_GROUP_order_bits |
|
932 | 933 |
] |
933 | 934 |
) |
934 | 935 |
|
... | ... |
@@ -244,6 +244,20 @@ EVP_PKEY_get0_RSA(EVP_PKEY *pkey) |
244 | 244 |
} |
245 | 245 |
#endif |
246 | 246 |
|
247 |
+#if !defined(HAVE_EVP_PKEY_GET0_EC_KEY) && !defined(OPENSSL_NO_EC) |
|
248 |
+/** |
|
249 |
+ * Get the EC_KEY object of a public key |
|
250 |
+ * |
|
251 |
+ * @param pkey Public key object |
|
252 |
+ * @return The underlying EC_KEY object |
|
253 |
+ */ |
|
254 |
+static inline EC_KEY * |
|
255 |
+EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) |
|
256 |
+{ |
|
257 |
+ return pkey ? pkey->pkey.ec : NULL; |
|
258 |
+} |
|
259 |
+#endif |
|
260 |
+ |
|
247 | 261 |
#if !defined(HAVE_EVP_PKEY_ID) |
248 | 262 |
/** |
249 | 263 |
* Get the PKEY type |
... | ... |
@@ -610,6 +624,24 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) |
610 | 610 |
} |
611 | 611 |
#endif |
612 | 612 |
|
613 |
+#if !defined(HAVE_EC_GROUP_ORDER_BITS) && !defined(OPENSSL_NO_EC) |
|
614 |
+/** |
|
615 |
+ * Gets the number of bits of the order of an EC_GROUP |
|
616 |
+ * |
|
617 |
+ * @param group EC_GROUP object |
|
618 |
+ * @return number of bits of group order. |
|
619 |
+ */ |
|
620 |
+static inline int |
|
621 |
+EC_GROUP_order_bits(const EC_GROUP *group) |
|
622 |
+{ |
|
623 |
+ BIGNUM* order = BN_new(); |
|
624 |
+ EC_GROUP_get_order(group, order, NULL); |
|
625 |
+ int bits = BN_num_bits(order); |
|
626 |
+ BN_free(order); |
|
627 |
+ return bits; |
|
628 |
+} |
|
629 |
+#endif |
|
630 |
+ |
|
613 | 631 |
/* SSLeay symbols have been renamed in OpenSSL 1.1 */ |
614 | 632 |
#if !defined(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT) |
615 | 633 |
#define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT |
... | ... |
@@ -1080,6 +1080,13 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx, |
1080 | 1080 |
ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ |
1081 | 1081 |
pub_rsa = EVP_PKEY_get0_RSA(pkey); |
1082 | 1082 |
|
1083 |
+ /* Certificate might not be RSA but DSA or EC */ |
|
1084 |
+ if (!pub_rsa) |
|
1085 |
+ { |
|
1086 |
+ crypto_msg(M_WARN, "management-external-key requires a RSA certificate"); |
|
1087 |
+ goto err; |
|
1088 |
+ } |
|
1089 |
+ |
|
1083 | 1090 |
/* initialize RSA object */ |
1084 | 1091 |
const BIGNUM *n = NULL; |
1085 | 1092 |
const BIGNUM *e = NULL; |
... | ... |
@@ -1686,18 +1693,36 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix) |
1686 | 1686 |
EVP_PKEY *pkey = X509_get_pubkey(cert); |
1687 | 1687 |
if (pkey != NULL) |
1688 | 1688 |
{ |
1689 |
- if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL) |
|
1689 |
+ if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) && (EVP_PKEY_get0_RSA(pkey) != NULL)) |
|
1690 | 1690 |
{ |
1691 | 1691 |
RSA *rsa = EVP_PKEY_get0_RSA(pkey); |
1692 | 1692 |
openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", |
1693 | 1693 |
RSA_bits(rsa)); |
1694 | 1694 |
} |
1695 |
- else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL) |
|
1695 |
+ else if ((EVP_PKEY_id(pkey) == EVP_PKEY_DSA) && (EVP_PKEY_get0_DSA(pkey) != NULL)) |
|
1696 | 1696 |
{ |
1697 | 1697 |
DSA *dsa = EVP_PKEY_get0_DSA(pkey); |
1698 | 1698 |
openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", |
1699 | 1699 |
DSA_bits(dsa)); |
1700 | 1700 |
} |
1701 |
+#ifndef OPENSSL_NO_EC |
|
1702 |
+ else if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && (EVP_PKEY_get0_EC_KEY(pkey) != NULL)) |
|
1703 |
+ { |
|
1704 |
+ EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); |
|
1705 |
+ const EC_GROUP *group = EC_KEY_get0_group(ec); |
|
1706 |
+ const char* curve; |
|
1707 |
+ |
|
1708 |
+ int nid = EC_GROUP_get_curve_name(group); |
|
1709 |
+ if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL) |
|
1710 |
+ { |
|
1711 |
+ curve = "Error getting curve name"; |
|
1712 |
+ } |
|
1713 |
+ |
|
1714 |
+ openvpn_snprintf(s2, sizeof(s2), ", %d bit EC, curve: %s", |
|
1715 |
+ EC_GROUP_order_bits(group), curve); |
|
1716 |
+ |
|
1717 |
+ } |
|
1718 |
+#endif |
|
1701 | 1719 |
EVP_PKEY_free(pkey); |
1702 | 1720 |
} |
1703 | 1721 |
X509_free(cert); |