Alon Bar-Lev wrote:
> This is nice!
>
> Some questions:
>
> 1. Why not enable this automatically if openssl is sufficient version?
> There is no point in not using this if available.
>
some distro's (notably RedHat) disable EC support by default; so it's
not possible to check the OpenSSL version number. There is a '#define
OPENSSL_NO_EC'  that could be used, so the configure.ac script should
check for that. As other SSL implementations might use a different
#define to state that ECs are supported (or are NOT supported), I figure
the decision whether to support ECs should be made by the configure.ac
script, not by the openvpn code itself.
> 2. I would have liked to see this in negotiation as well, so server
> will use EC if supported by the client and fallback if not... This way
> migration path can take place.
>
The client won't even enter the negotiation phase without this patch: if
the client and server are configured to use ECDSA+SHA512 certs and the
'ecdh' parameters are NOT set on the server then the initial TLS
handshake fails.

cheers,

JJK



> On Tue, Feb 7, 2012 at 5:13 PM, Jan Just Keijser <janj...@nikhef.nl
> <mailto:janj...@nikhef.nl>> wrote:
>
>     Added support for Elliptic curves (ECDSA) + SHA2 family signed
>     certificates.
>     ---
>      init.c         |    7 ++++
>      options.c      |   15 ++++++++++
>      options.h      |    6 ++++
>      ssl.c          |    3 ++
>      ssl_backend.h  |   10 ++++++
>      ssl_openssl.c  |   84
>     ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>      ssl_polarssl.c |    9 ++++++
>      7 files changed, 134 insertions(+), 0 deletions(-)
>
>     diff --git a/init.c b/init.c
>     index 525f441..51b0d64 100644
>     --- a/init.c
>     +++ b/init.c
>     @@ -895,6 +895,9 @@ print_openssl_info (const struct options *options)
>       if (options->show_ciphers || options->show_digests ||
>     options->show_engines
>      #ifdef USE_SSL
>           || options->show_tls_ciphers
>     +#ifdef USE_SSL_EC
>     +|| options->show_curves
>     +#endif
>      #endif
>         )
>         {
>     @@ -907,6 +910,10 @@ print_openssl_info (const struct options
>     *options)
>      #ifdef USE_SSL
>           if (options->show_tls_ciphers)
>            show_available_tls_ciphers ();
>     +#ifdef USE_SSL_EC
>     +      if (options->show_curves)
>     +    show_available_curves ();
>     +#endif
>      #endif
>           return true;
>         }
>     diff --git a/options.c b/options.c
>     index 6b8ae22..ce23dbc 100644
>     --- a/options.c
>     +++ b/options.c
>     @@ -836,6 +836,9 @@ init_options (struct options *o, const bool
>     init_gc)
>      #ifdef ENABLE_X509ALTUSERNAME
>       o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;
>      #endif
>     +#ifdef USE_SSL_EC
>     +  o->curve_name = NULL;
>     +#endif
>      #endif /* USE_SSL */
>      #endif /* USE_CRYPTO */
>      #ifdef ENABLE_PKCS11
>     @@ -6368,6 +6371,18 @@ add_option (struct options *options,
>           VERIFY_PERMISSION (OPT_P_GENERAL);
>           options->show_tls_ciphers = true;
>         }
>     +#ifdef USE_SSL_EC
>     +  else if (streq (p[0], "show-curves"))
>     +    {
>     +      VERIFY_PERMISSION (OPT_P_GENERAL);
>     +      options->show_curves = true;
>     +    }
>     +  else if (streq (p[0], "ecdh") && p[1])
>     +    {
>     +      VERIFY_PERMISSION (OPT_P_CRYPTO);
>     +      options->curve_name= p[1];
>     +    }
>     +#endif
>       else if (streq (p[0], "tls-server"))
>         {
>           VERIFY_PERMISSION (OPT_P_GENERAL);
>     diff --git a/options.h b/options.h
>     index 831d4f6..81e0757 100644
>     --- a/options.h
>     +++ b/options.h
>     @@ -200,6 +200,9 @@ struct options
>       bool show_engines;
>      #ifdef USE_SSL
>       bool show_tls_ciphers;
>     +#ifdef USE_SSL_EC
>     +  bool show_curves;
>     +#endif
>      #endif
>       bool genkey;
>      #endif
>     @@ -533,6 +536,9 @@ struct options
>       const char *priv_key_file;
>       const char *pkcs12_file;
>       const char *cipher_list;
>     +#ifdef USE_SSL_EC
>     +  const char *curve_name;
>     +#endif
>       const char *tls_verify;
>       const char *tls_export_cert;
>       const char *tls_remote;
>     diff --git a/ssl.c b/ssl.c
>     index c26756e..54efe2f 100644
>     --- a/ssl.c
>     +++ b/ssl.c
>     @@ -308,6 +308,9 @@ init_ssl (const struct options *options,
>     struct tls_root_ctx *new_ctx)
>         {
>           tls_ctx_server_new(new_ctx);
>           tls_ctx_load_dh_params(new_ctx, options->dh_file,
>     options->dh_file_inline);
>     +#ifdef USE_SSL_EC
>     +      tls_ctx_load_ecdh_params(new_ctx, options->curve_name);
>     +#endif
>         }
>       else                         /* if client */
>         {
>     diff --git a/ssl_backend.h b/ssl_backend.h
>     index 243c9e3..ebf9f36 100644
>     --- a/ssl_backend.h
>     +++ b/ssl_backend.h
>     @@ -145,6 +145,16 @@ void tls_ctx_load_dh_params(struct
>     tls_root_ctx *ctx, const char *dh_file
>         );
>
>      /**
>     + * Load Elliptic Curve Parameters, and load them into the
>     library-specific
>     + * TLS context.
>     + *
>     + * @param ctx                  TLS context to use
>     + * @param curve_name   The name of the elliptic curve to load.
>     + */
>     +void tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const
>     char *curve_name
>     +    );
>     +
>     +/**
>      * Load PKCS #12 file for key, cert and (optionally) CA certs, and
>     add to
>      * library-specific TLS context.
>      *
>     diff --git a/ssl_openssl.c b/ssl_openssl.c
>     index b95944c..912dd8f 100644
>     --- a/ssl_openssl.c
>     +++ b/ssl_openssl.c
>     @@ -50,6 +50,9 @@
>      #include <openssl/pkcs12.h>
>      #include <openssl/x509.h>
>      #include <openssl/crypto.h>
>     +#ifdef USE_SSL_EC
>     +#include <openssl/ec.h>
>     +#endif
>
>      /*
>      * Allocate space in SSL objects in which to store a struct
>     tls_session
>     @@ -238,6 +241,46 @@ tls_ctx_load_dh_params (struct tls_root_ctx
>     *ctx, const char *dh_file
>       DH_free (dh);
>      }
>
>     +void
>     +tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char
>     *curve_name
>     +    )
>     +{
>     +#ifdef USE_SSL_EC
>     +  if (curve_name != NULL)
>     +  {
>     +    int nid;
>     +    EC_KEY   *ecdh  = NULL;
>     +
>     +    nid = OBJ_sn2nid(curve_name);
>     +
>     +    if (nid == 0)
>     +      msg(M_SSLERR, "unknown curve name (%s)", curve_name);
>     +    else
>     +    {
>     +      ecdh = EC_KEY_new_by_curve_name(nid);
>     +      if (ecdh == NULL)
>     +        msg (M_SSLERR, "Unable to create curve (%s)", curve_name);
>     +      else
>     +      {
>     +        const char *sname;
>     +
>     +        if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh))
>     +          msg (M_SSLERR, "SSL_CTX_set_tmp_ecdh: cannot add curve");
>     +
>     +        /* Translate NID back to name , just for kicks */
>     +        sname   = OBJ_nid2sn(nid);
>     +        if (sname == NULL) sname = "(Unknown)";
>     +        msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname);
>     +
>     +        EC_KEY_free(ecdh);
>     +      }
>     +    }
>     +  }
>     +#else
>     +  msg(M_SSLERR, "Elliptic Curves not supported by this version of
>     OpenSSL");
>     +#endif
>     +}
>     +
>      int
>      tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char
>     *pkcs12_file,
>      #if ENABLE_INLINE_FILES
>     @@ -1273,6 +1316,47 @@ show_available_tls_ciphers ()
>       SSL_CTX_free (ctx);
>      }
>
>     +/*
>     + *  * Show the Elliptic curves that are available for us to use
>     + *   * in the OpenSSL library.
>     + *    */
>     +#ifdef USE_SSL_EC
>     +void
>     +show_available_curves()
>     +{
>     +  EC_builtin_curve *curves = NULL;
>     +  size_t crv_len = 0;
>     +  size_t n = 0;
>     +
>     +  crv_len = EC_get_builtin_curves(NULL, 0);
>     +
>     +  curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
>     +
>     +  if (curves == NULL)
>     +    msg (M_SSLERR, "Cannot create EC_builtin_curve object");
>     +  else
>     +  {
>     +    if (EC_get_builtin_curves(curves, crv_len))
>     +    {
>     +      printf ("Available Elliptic curves:\n");
>     +      for (n = 0; n < crv_len; n++)
>     +      {
>     +        const char *sname;
>     +        sname   = OBJ_nid2sn(curves[n].nid);
>     +        if (sname == NULL) sname = "";
>     +
>     +        printf("%s\n", sname);
>     +      }
>     +    }
>     +    else
>     +    {
>     +      msg (M_SSLERR, "Cannot get list of builtin curves");
>     +    }
>     +    OPENSSL_free(curves);
>     +  }
>     +}
>     +#endif
>     +
>      void
>      get_highest_preference_tls_cipher (char *buf, int size)
>      {
>     diff --git a/ssl_polarssl.c b/ssl_polarssl.c
>     index c50cf0a..a7a6d61 100644
>     --- a/ssl_polarssl.c
>     +++ b/ssl_polarssl.c
>     @@ -218,6 +218,15 @@ else
>           (counter_type) 8 * mpi_size(&ctx->dhm_ctx->P));
>      }
>
>     +#ifdef USE_SSL_EC
>     +void
>     +tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char
>     *curve_name
>     +    )
>     +{
>     +    msg(M_WARN, "Elliptic Curves not yet supported by PolarSSL");
>     +}
>     +#endif
>     +
>      int
>      tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char
>     *pkcs12_file,
>      #if ENABLE_INLINE_FILES
>     --
>     1.7.4.4
>


Reply via email to