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

Reply via email to