Browse code

Print ec bit details, refuse management-external-key if key is not RSA

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>

Arne Schwabe authored on 2017/07/24 01:45:36
Showing 3 changed files
... ...
@@ -934,6 +934,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
934 934
 			EVP_PKEY_id \
935 935
 			EVP_PKEY_get0_RSA \
936 936
 			EVP_PKEY_get0_DSA \
937
+			EVP_PKEY_get0_EC_KEY \
937 938
 			RSA_set_flags \
938 939
 			RSA_bits \
939 940
 			RSA_get0_key \
... ...
@@ -949,6 +950,7 @@ if test "${enable_crypto}" = "yes" -a "${with_crypto_library}" = "openssl"; then
949 949
 			RSA_meth_set_init \
950 950
 			RSA_meth_set_finish \
951 951
 			RSA_meth_set0_app_data \
952
+			EC_GROUP_order_bits
952 953
 		]
953 954
 	)
954 955
 
... ...
@@ -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
... ...
@@ -1077,6 +1077,13 @@ tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
1077 1077
     ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */
1078 1078
     pub_rsa = EVP_PKEY_get0_RSA(pkey);
1079 1079
 
1080
+    /* Certificate might not be RSA but DSA or EC */
1081
+    if (!pub_rsa)
1082
+    {
1083
+        crypto_msg(M_WARN, "management-external-key requires a RSA certificate");
1084
+        goto err;
1085
+    }
1086
+
1080 1087
     /* initialize RSA object */
1081 1088
     const BIGNUM *n = NULL;
1082 1089
     const BIGNUM *e = NULL;
... ...
@@ -1683,18 +1690,36 @@ print_details(struct key_state_ssl *ks_ssl, const char *prefix)
1683 1683
         EVP_PKEY *pkey = X509_get_pubkey(cert);
1684 1684
         if (pkey != NULL)
1685 1685
         {
1686
-            if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) != NULL)
1686
+            if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) && (EVP_PKEY_get0_RSA(pkey) != NULL))
1687 1687
             {
1688 1688
                 RSA *rsa = EVP_PKEY_get0_RSA(pkey);
1689 1689
                 openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA",
1690 1690
                                  RSA_bits(rsa));
1691 1691
             }
1692
-            else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && EVP_PKEY_get0_DSA(pkey) != NULL)
1692
+            else if ((EVP_PKEY_id(pkey) == EVP_PKEY_DSA) && (EVP_PKEY_get0_DSA(pkey) != NULL))
1693 1693
             {
1694 1694
                 DSA *dsa = EVP_PKEY_get0_DSA(pkey);
1695 1695
                 openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA",
1696 1696
                                  DSA_bits(dsa));
1697 1697
             }
1698
+#ifndef OPENSSL_NO_EC
1699
+            else if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && (EVP_PKEY_get0_EC_KEY(pkey) != NULL))
1700
+            {
1701
+                EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey);
1702
+                const EC_GROUP *group = EC_KEY_get0_group(ec);
1703
+                const char* curve;
1704
+
1705
+                int nid = EC_GROUP_get_curve_name(group);
1706
+                if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL)
1707
+                {
1708
+                    curve = "Error getting curve name";
1709
+                }
1710
+
1711
+                openvpn_snprintf(s2, sizeof(s2), ", %d bit EC, curve: %s",
1712
+                                 EC_GROUP_order_bits(group), curve);
1713
+
1714
+            }
1715
+#endif
1698 1716
             EVP_PKEY_free(pkey);
1699 1717
         }
1700 1718
         X509_free(cert);