Hi, On 23-07-17 18:45, Arne Schwabe wrote: > 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 > --- > configure.ac | 2 ++ > src/openvpn/openssl_compat.h | 32 ++++++++++++++++++++++++++++++++ > src/openvpn/ssl_openssl.c | 29 +++++++++++++++++++++++++++-- > 3 files changed, 61 insertions(+), 2 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 39d992c0..f6eeb40d 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -934,6 +934,7 @@ if test "${enable_crypto}" = "yes" -a > "${with_crypto_library}" = "openssl"; then > EVP_PKEY_id \ > EVP_PKEY_get0_RSA \ > EVP_PKEY_get0_DSA \ > + EVP_PKEY_get0_EC_KEY \ > RSA_set_flags \ > RSA_bits \ > RSA_get0_key \ > @@ -949,6 +950,7 @@ if test "${enable_crypto}" = "yes" -a > "${with_crypto_library}" = "openssl"; then > RSA_meth_set_init \ > RSA_meth_set_finish \ > RSA_meth_set0_app_data \ > + EC_GROUP_order_bits > ] > ) > > diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h > index 36f68b01..70b19aea 100644 > --- a/src/openvpn/openssl_compat.h > +++ b/src/openvpn/openssl_compat.h > @@ -244,6 +244,20 @@ EVP_PKEY_get0_RSA(EVP_PKEY *pkey) > } > #endif > > +#if !defined(HAVE_EVP_PKEY_GET0_EC_KEY) && !defined(OPENSSL_NO_EC) > +/** > + * Get the EC_KEY object of a public key > + * > + * @param pkey Public key object > + * @return The underlying EC_KEY object > + */ > +static inline EC_KEY * > +EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) > +{ > + return pkey ? pkey->pkey.ec : NULL; > +} > +#endif > + > #if !defined(HAVE_EVP_PKEY_ID) > /** > * Get the PKEY type > @@ -610,6 +624,24 @@ RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data) > } > #endif > > +#if !defined(HAVE_EC_GROUP_ORDER_BITS) && !defined(OPENSSL_NO_EC) > +/** > + * Gets the number of bits of the order of an EC_GROUP > + * > + * @param group EC_GROUP object > + * @return number of bits of group order. > + */ > +static inline int > +EC_GROUP_order_bits(const EC_GROUP *group) > +{ > + BIGNUM* order = BN_new(); > + EC_GROUP_get_order(group, order, NULL); > + int bits = BN_num_bits(order); > + BN_free(order); > + return bits; > +} > +#endif > + > /* SSLeay symbols have been renamed in OpenSSL 1.1 */ > #if !defined(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT) > #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT RSA_F_RSA_EAY_PRIVATE_ENCRYPT > diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c > index 11f4a567..459fe371 100644 > --- a/src/openvpn/ssl_openssl.c > +++ b/src/openvpn/ssl_openssl.c > @@ -1077,6 +1077,13 @@ tls_ctx_use_external_private_key(struct tls_root_ctx > *ctx, > ASSERT(pkey); /* NULL before SSL_CTX_use_certificate() is called */ > pub_rsa = EVP_PKEY_get0_RSA(pkey); > > + /* Certificate might not be RSA but DSA or EC */ > + if (!pub_rsa) > + { > + crypto_msg(M_WARN, "management-external-key requires a RSA > certificate"); > + goto err; > + } > + > /* initialize RSA object */ > const BIGNUM *n = NULL; > const BIGNUM *e = NULL; > @@ -1683,18 +1690,36 @@ print_details(struct key_state_ssl *ks_ssl, const > char *prefix) > EVP_PKEY *pkey = X509_get_pubkey(cert); > if (pkey != NULL) > { > - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA && EVP_PKEY_get0_RSA(pkey) > != NULL) > + if ((EVP_PKEY_id(pkey) == EVP_PKEY_RSA) && > (EVP_PKEY_get0_RSA(pkey) != NULL)) > { > RSA *rsa = EVP_PKEY_get0_RSA(pkey); > openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA", > RSA_bits(rsa)); > } > - else if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA && > EVP_PKEY_get0_DSA(pkey) != NULL) > + else if ((EVP_PKEY_id(pkey) == EVP_PKEY_DSA) && > (EVP_PKEY_get0_DSA(pkey) != NULL)) > { > DSA *dsa = EVP_PKEY_get0_DSA(pkey); > openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA", > DSA_bits(dsa)); > } > +#ifndef OPENSSL_NO_EC > + else if ((EVP_PKEY_id(pkey) == EVP_PKEY_EC) && > (EVP_PKEY_get0_EC_KEY(pkey) != NULL)) > + { > + EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); > + const EC_GROUP *group = EC_KEY_get0_group(ec); > + const char* curve; > + > + int nid = EC_GROUP_get_curve_name(group); > + if (nid == 0 || (curve = OBJ_nid2sn(nid)) == NULL) > + { > + curve = "Error getting curve name"; > + } > + > + openvpn_snprintf(s2, sizeof(s2), ", %d bit EC, curve: %s", > + EC_GROUP_order_bits(group), curve); > + > + } > +#endif > EVP_PKEY_free(pkey); > } > X509_free(cert); >
Patch looks good now, thanks. ACK. (Some trailing whitespace in the patch, but I guess that's easy enough to fix when applying.) -Steffan ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel