[git] NTBTLS - branch, master, updated. 06bb9a836981e48c2e6939fb21480d97253a4588

by Werner Koch cvs at cvs.gnupg.org
Thu Mar 16 11:34:33 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Not Too Bad TLS".

The branch, master has been updated
       via  06bb9a836981e48c2e6939fb21480d97253a4588 (commit)
       via  5de470fbeb7b6d92070206414d130dfb53d96e69 (commit)
       via  17efdd6202ed0901b51bfd1045e7e48e3a8a3ead (commit)
       via  1fc1669e037cfcc1cef1c1af58141d5aace2e9d2 (commit)
      from  e582e91e47a164816ac074b9078dbed8537601dc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 06bb9a836981e48c2e6939fb21480d97253a4588
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Mar 16 11:31:36 2017 +0100

    Post release updates.
    
    --

diff --git a/NEWS b/NEWS
index d55531f..2a773c3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Noteworthy changes in version 0.1.2 (unreleased) [C0/A0/R_]
+------------------------------------------------
+
+
 Noteworthy changes in version 0.1.1 (2017-03-16) [C0/A0/R1]
 ------------------------------------------------
 
diff --git a/configure.ac b/configure.ac
index c76ccb1..71ee5ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,7 +27,7 @@ min_automake_version="1.14"
 m4_define([mym4_package],[ntbtls])
 m4_define([mym4_major], [0])
 m4_define([mym4_minor], [1])
-m4_define([mym4_micro], [1])
+m4_define([mym4_micro], [2])
 
 # To start a new development series, i.e a new major or minor number
 # you need to mark an arbitrary commit before the first beta release

commit 5de470fbeb7b6d92070206414d130dfb53d96e69
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Mar 16 11:24:55 2017 +0100

    Release 0.1.1
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index 4786e9a..d55531f 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
-Noteworthy changes in version 0.1.1 (unreleased) [C0/A0/R_]
+Noteworthy changes in version 0.1.1 (2017-03-16) [C0/A0/R1]
 ------------------------------------------------
 
+ * Now supports ECDHE-RSA key exchange.
+
 
 Noteworthy changes in version 0.1.0 (2017-02-21) [C0/A0/R0]
 ------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 80b958e..c76ccb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,7 +54,7 @@ AC_INIT([mym4_package],[mym4_version], [http://bugs.gnupg.org])
 #   (No interfaces changed:                   REVISION++)
 LIBNTBTLS_LT_CURRENT=0
 LIBNTBTLS_LT_AGE=0
-LIBNTBTLS_LT_REVISION=0
+LIBNTBTLS_LT_REVISION=1
 
 # If the API is changed in an incompatible way: increment the next counter.
 NTBTLS_CONFIG_API_VERSION=1

commit 17efdd6202ed0901b51bfd1045e7e48e3a8a3ead
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Mar 16 10:40:19 2017 +0100

    Implement ECDHE-RSA key exchange.
    
    * src/ecdh.c: New file.
    * src/Makefile.am (libntbtls_la_SOURCES): Add new file.
    * src/context.h (ecdh_context_t): New type.
    (_ntbtls_handshake_params_s): Use new type for 'ecdh_ctx'.
    * src/protocol.c (handshake_params_init): Init ECDH_CTX.
    (handshake_params_deinit): Deinit ECDH_CTX.
    (ssl_write_hello_request): Rename to write_hello_request.  Change
    caller.
    * src/protocol-cli.c (write_supported_elliptic_curves_ext): Implement.
    (write_cli_supported_point_formats_ext): Implement.
    (write_client_hello): Call them.
    (parse_supported_point_formats_ext): Implement.
    (parse_server_ecdh_params): Implement.
    (parse_signature_algorithm): Fix debug output.
    (read_server_key_exchange): Improve debug output.
    (write_client_key_exchange): Implement ECDHE key exchange.
    * src/ciphersuites.c (_ntbtls_ciphersuite_list): Advertise ECDHE_RSA
    key exchange.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/doc/HACKING b/doc/HACKING
index e034df3..5a56533 100644
--- a/doc/HACKING
+++ b/doc/HACKING
@@ -19,12 +19,29 @@
     --port 8443
 #+end_example
 
+   To test only a single ECDHDE cipher suite, this can be useful:
+
+#+begin_example
+   --priority SECURE128:+ECDHE-RSA:-RSA:-DHE-RSA:-PSK:-CAMELLIA-128-CBC:\
+   -CAMELLIA-256-CBC:-CAMELLIA-256-GCM:-CAMELLIA-128-GCM:-SHA1:\
+   -AES-128-GCM:-AES-256-GCM:-SHA384
+#+end_example
+
+
 ** How to start an OpenSSL test server
 
 
 * Specs
 ** RFC Notes
 
+*** 4492 - Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer
+    Security (TLS). S. Blake-Wilson, N. Bolyard, V. Gupta, C. Hawk, B.
+    Moeller. May 2006. (Format: TXT=72231 bytes) (Updated by RFC5246,
+    RFC7027) (Status: INFORMATIONAL) (DOI: 10.17487/RFC4492)
+
+    - 5246 :: See A.7 for the changes.
+    - 7027 :: Brainpool curves
+
 *** 5246 - The Transport Layer Security (TLS) Protocol Version 1.2.
     T. Dierks, E. Rescorla. August 2008. (Format: TXT=222395 bytes)
     (Obsoletes RFC3268, RFC4346, RFC4366) (Updates RFC4492) (Updated
diff --git a/src/Makefile.am b/src/Makefile.am
index d0fa8a2..23100d0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,7 +86,7 @@ libntbtls_la_SOURCES = \
 	protocol.c \
 	protocol-cli.c \
 	ciphersuites.c ciphersuites.h \
-	pkglue.c x509.c dhm.c \
+	pkglue.c x509.c dhm.c ecdh.c \
 	debug.c
 
 # protocol-srv.c
diff --git a/src/ciphersuites.c b/src/ciphersuites.c
index 68c4108..bce0521 100644
--- a/src/ciphersuites.c
+++ b/src/ciphersuites.c
@@ -1305,7 +1305,6 @@ _ntbtls_ciphersuite_list (void)
               /*FIXME: GCM and CCM are not yet ready for us - disable.  */
               if (suite->ciphermode != GCRY_CIPHER_MODE_GCM
                   && suite->ciphermode != GCRY_CIPHER_MODE_CCM
-                  && suite->key_exchange != KEY_EXCHANGE_ECDHE_RSA
                   && suite->key_exchange != KEY_EXCHANGE_ECDH_RSA
                   && suite->key_exchange != KEY_EXCHANGE_ECDHE_ECDSA
                   && suite->key_exchange != KEY_EXCHANGE_ECDH_ECDSA)
diff --git a/src/context.h b/src/context.h
index aac3017..93652b6 100644
--- a/src/context.h
+++ b/src/context.h
@@ -122,6 +122,13 @@ typedef struct dhm_context_s *dhm_context_t;
 
 
 /*
+ * Object to hold an ECDH context.
+ */
+struct ecdh_context_s;
+typedef struct ecdh_context_s *ecdh_context_t;
+
+
+/*
  * This structure is used for storing current session data.
  */
 struct _ntbtls_session_s
@@ -217,7 +224,7 @@ struct _ntbtls_handshake_params_s
   int cert_type;                /*!<  Requested cert type            */
   int verify_sig_alg;           /*!<  Signature algorithm for verify */
   dhm_context_t dhm_ctx;        /* DHM key exchange info.   */
-  /*ecdh_context*/void* ecdh_ctx;        /*!<  ECDH key exchange       */
+  ecdh_context_t ecdh_ctx;      /* ECDH key exchange info.  */
   const /*ecp_curve_info*/void **curves;/*!<  Supported elliptic curves */
   /**
    * //FIXME: Better explain this
diff --git a/src/ecdh.c b/src/ecdh.c
new file mode 100644
index 0000000..da7e5a2
--- /dev/null
+++ b/src/ecdh.c
@@ -0,0 +1,316 @@
+/* ecdh.c - EC Diffie-Hellman key exchange
+ * Copyright (C) 2014, 2017 g10 Code GmbH
+ *
+ * This file is part of NTBTLS
+ *
+ * NTBTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * NTBTLS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ksba.h>
+
+#include "ntbtls-int.h"
+
+
+/* While running the validation function we need to keep track of the
+ * certificates and the validation outcome of each.  We use this type
+ * for it.  */
+struct ecdh_context_s
+{
+  const char *curve_name;  /* Only for display purposes.  */
+  gcry_ctx_t ecctx;        /* The initialized context for the curve.
+                            * This also holds the secre D and our
+                            * public key Q.  */
+  gcry_mpi_point_t Qpeer;  /* The peer's public value  */
+};
+
+
+
+/* Create a new ECDH context.  */
+gpg_error_t
+_ntbtls_ecdh_new (ecdh_context_t *r_ecdh)
+{
+  ecdh_context_t ecdh;
+
+  *r_ecdh = NULL;
+
+  ecdh = calloc (1, sizeof *ecdh);
+  if (!ecdh)
+    return gpg_error_from_syserror ();
+
+  *r_ecdh = ecdh;
+
+  return 0;
+}
+
+
+/* Release an ECDH context.  */
+void
+_ntbtls_ecdh_release (ecdh_context_t ecdh)
+{
+  if (!ecdh)
+    return;
+  gcry_ctx_release (ecdh->ecctx);
+  gcry_mpi_point_release (ecdh->Qpeer);
+  free (ecdh);
+}
+
+
+/* Parse the TLS ECDHE parameters and store them in ECDH.  DER is the
+ * buffer with the params of length DERLEN.  The number of actual
+ * parsed bytes is stored at R_NPARSED.  */
+gpg_error_t
+_ntbtls_ecdh_read_params (ecdh_context_t ecdh,
+                          const void *_der, size_t derlen,
+                          size_t *r_nparsed)
+{
+  gpg_error_t err;
+  const unsigned char *derstart = _der;
+  const unsigned char *der = _der;
+  size_t n;
+  gcry_mpi_t tmpmpi;
+
+  if (r_nparsed)
+    *r_nparsed = 0;
+
+  if (!ecdh || !der)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  ecdh->curve_name = NULL;
+  gcry_ctx_release (ecdh->ecctx); ecdh->ecctx = NULL;
+  gcry_mpi_point_release (ecdh->Qpeer); ecdh->Qpeer = NULL;
+
+  /* struct {
+   *     ECParameters curve_params;
+   *     ECPoint      public;
+   * } ServerECDHParams;
+   */
+
+  /* Parse ECParameters.  */
+  if (derlen < 3)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+  /* We only support named curves (3).  */
+  if (*der != 3)
+    return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+  der++;
+  derlen--;
+  /* And only the secp256r1 curve (23).  */
+  if (buf16_to_uint (der) != 23)
+    return gpg_error (GPG_ERR_UNKNOWN_CURVE);
+  der += 2;
+  derlen -= 2;
+
+  ecdh->curve_name = "secp256r1";
+  err = gcry_mpi_ec_new (&ecdh->ecctx, NULL, ecdh->curve_name);
+  if (err)
+    return err;
+
+  /* Parse ECPoint.  */
+  if (derlen < 2)
+    return gpg_error (GPG_ERR_TOO_SHORT);
+  n = *der++; derlen--;
+  if (!n)
+    return gpg_error (GPG_ERR_INV_OBJ);
+  if (n > derlen)
+    return gpg_error (GPG_ERR_TOO_LARGE);
+
+  tmpmpi = gcry_mpi_set_opaque_copy (NULL, der, 8*n);
+  if (!tmpmpi)
+    return gpg_error_from_syserror ();
+  der += n;
+  derlen -= n;
+
+  ecdh->Qpeer = gcry_mpi_point_new (0);
+  err = gcry_mpi_ec_decode_point (ecdh->Qpeer, tmpmpi, ecdh->ecctx);
+  gcry_mpi_release (tmpmpi);
+  if (err)
+    {
+      gcry_mpi_point_release (ecdh->Qpeer);
+      ecdh->Qpeer = NULL;
+      return err;
+    }
+
+  if (r_nparsed)
+    *r_nparsed = (der - derstart);
+
+  debug_msg (3, "ECDH curve: %s", ecdh->curve_name);
+  debug_pnt (3, "ECDH Qpeer", ecdh->Qpeer, ecdh->ecctx);
+
+  return 0;
+}
+
+
+/* Generate the secret D with 0 < D < N.  */
+static gcry_mpi_t
+gen_d (ecdh_context_t ecdh)
+{
+  unsigned int nbits;
+  gcry_mpi_t n, d;
+
+  n = gcry_mpi_ec_get_mpi ("n", ecdh->ecctx, 0);
+  if (!n)
+    return NULL;
+  nbits  = gcry_mpi_get_nbits (n);
+  d = gcry_mpi_snew (nbits);
+
+  for (;;)
+    {
+      /* FIXME: For the second and further iterations we use too much
+       * random.  It would be better to get just a few bits and use
+       * set/clear_bit to insert that into the D.  Or implement a
+       * suitable gen_d function in libgcrypt. */
+      gcry_mpi_randomize (d, nbits, GCRY_STRONG_RANDOM);
+
+      /* Make sure we have the requested number of bits.  The code
+       * looks a bit weird but it is easy to understand if you
+       * consider that mpi_set_highbit clears all higher bits. */
+      if (mpi_test_bit (d, nbits-1))
+        mpi_set_highbit (d, nbits-1);
+      else
+        mpi_clear_highbit (d, nbits-1);
+
+      if (mpi_cmp (d, n) < 0        /* check: D < N */
+          && mpi_cmp_ui (d, 0) > 0) /* check: D > 0 */
+        break;	/* okay */
+    }
+
+  gcry_mpi_release (n);
+  return d;
+}
+
+
+/* Create our own private value D and a public key.  Store the public
+   key in OUTBUF.  OUTBUFSIZE is the available length of OUTBUF.  On
+   success the actual length of OUTBUF is stored at R_OUTBUFLEN.  */
+gpg_error_t
+_ntbtls_ecdh_make_public (ecdh_context_t ecdh,
+                          unsigned char *outbuf, size_t outbufsize,
+                          size_t *r_outbuflen)
+{
+  gpg_error_t err;
+  size_t n;
+
+  if (!ecdh || !outbuf || !r_outbuflen || outbufsize < 2)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  *r_outbuflen = 0;
+
+  if (!ecdh->curve_name || !ecdh->ecctx || !ecdh->Qpeer)
+    return gpg_error (GPG_ERR_NOT_INITIALIZED);
+
+  /* Create a secret and store it in the context.  */
+  {
+    gcry_mpi_t d;
+
+    d = gen_d (ecdh);
+    if (!d)
+      return gpg_error (GPG_ERR_INV_OBJ);
+
+    gcry_mpi_ec_set_mpi ("d", d, ecdh->ecctx);
+    debug_mpi (3, "ECDH d    ", d);
+    gcry_mpi_release (d);
+  }
+
+  {
+    gcry_mpi_t Q;
+
+    /* Note that "q" is computed by the get function and returned in
+     * uncompressed form.  */
+    Q = gcry_mpi_ec_get_mpi ("q", ecdh->ecctx, 0);
+    if (!Q)
+      {
+        return gpg_error (GPG_ERR_INTERNAL);
+      }
+    debug_mpi (3, "ECDH Qour ", Q);
+
+    /* Write as an ECPoint, that is prefix it with a one octet length.  */
+    err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf+1, outbufsize-1, &n, Q);
+    gcry_mpi_release (Q);
+    if (err)
+      return err;
+    if (n > 255)
+      return gpg_error (GPG_ERR_INV_DATA);
+    outbuf[0] = n;
+    n++;
+  }
+
+  *r_outbuflen = n;
+
+  return 0;
+}
+
+
+/* Derive the shared secret Z and store it in OUTBUF.  OUTBUFSIZE is
+ * the available length of OUTBUF.  On success the actual length of
+ * OUTBUF is stored at R_OUTBUFLEN.  */
+gpg_error_t
+_ntbtls_ecdh_calc_secret (ecdh_context_t ecdh,
+                          unsigned char *outbuf, size_t outbufsize,
+                          size_t *r_outbuflen)
+{
+  gpg_error_t err;
+  gcry_mpi_point_t P = NULL;
+  gcry_mpi_t d = NULL;
+  gcry_mpi_t x = NULL;
+  size_t n;
+
+  if (!ecdh || !outbuf || !r_outbuflen)
+    return gpg_error (GPG_ERR_INV_ARG);
+
+  *r_outbuflen = 0;
+
+  if (!ecdh->curve_name || !ecdh->ecctx || !ecdh->Qpeer)
+    return gpg_error (GPG_ERR_NOT_INITIALIZED);
+
+  /* 1. Check that Q_peer is on the curve
+   * 2. Compute:  P = d * Q_peer
+   * 2. Check that P is not the point at infinity.
+   * 3. Copy the x-coordinate of P to the output.
+   */
+
+  if (!gcry_mpi_ec_curve_point (ecdh->Qpeer, ecdh->ecctx))
+    {
+      err = gpg_error (GPG_ERR_INV_DATA);
+      goto leave;
+    }
+
+  d = gcry_mpi_ec_get_mpi ("d", ecdh->ecctx, 0);
+  if (!d)
+    return gpg_error (GPG_ERR_NOT_INITIALIZED);
+
+  P = gcry_mpi_point_new (0);
+  gcry_mpi_ec_mul (P, d, ecdh->Qpeer, ecdh->ecctx);
+
+  x = gcry_mpi_new (0);
+  if (gcry_mpi_ec_get_affine (x, NULL, P, ecdh->ecctx))
+    {
+      err = gpg_error (GPG_ERR_INV_DATA);
+      goto leave;
+    }
+
+  err = gcry_mpi_print (GCRYMPI_FMT_USG, outbuf, outbufsize, &n, x);
+  if (err)
+    goto leave;
+
+  *r_outbuflen = n;
+
+ leave:
+  gcry_mpi_release (d);
+  gcry_mpi_release (x);
+  gcry_mpi_point_release (P);
+  return err;
+}
diff --git a/src/ntbtls-int.h b/src/ntbtls-int.h
index e12f592..cb20ccc 100644
--- a/src/ntbtls-int.h
+++ b/src/ntbtls-int.h
@@ -402,6 +402,18 @@ gpg_error_t _ntbtls_dhm_calc_secret (dhm_context_t dhm,
                                      unsigned char *outbuf, size_t outbufsize,
                                      size_t *r_outbuflen);
 
+/*-- ecdh.c --*/
+gpg_error_t _ntbtls_ecdh_new (ecdh_context_t *r_ecdh);
+void _ntbtls_ecdh_release (ecdh_context_t ecdh);
+gpg_error_t _ntbtls_ecdh_read_params (ecdh_context_t ecdh,
+                                      const void *der, size_t derlen,
+                                      size_t *r_nparsed);
+gpg_error_t _ntbtls_ecdh_make_public (ecdh_context_t ecdh,
+                                      unsigned char *outbuf, size_t outbufsize,
+                                      size_t *r_outbuflen);
+gpg_error_t _ntbtls_ecdh_calc_secret (ecdh_context_t ecdh,
+                                      unsigned char *outbuf, size_t outbufsize,
+                                      size_t *r_outbuflen);
 
 
 
diff --git a/src/protocol-cli.c b/src/protocol-cli.c
index d341833..54e8244 100644
--- a/src/protocol-cli.c
+++ b/src/protocol-cli.c
@@ -183,67 +183,56 @@ write_signature_algorithms_ext (ntbtls_t ssl,
 }
 
 
-/* static void */
-/* write_supported_elliptic_curves_ext (ntbtls_t ssl, */
-/*                                      unsigned char *buf, size_t * olen) */
-/* { */
-  //FIXME:
-  /* unsigned char *p = buf; */
-  /* unsigned char *elliptic_curve_list = p + 6; */
-  /* size_t elliptic_curve_len = 0; */
-  /* const ecp_curve_info *info; */
-  /* const ecp_group_id *grp_id; */
-
-  /* *olen = 0; */
+static void
+write_supported_elliptic_curves_ext (ntbtls_t tls,
+                                     unsigned char *buf, size_t * olen)
+{
+  unsigned char *p = buf;
+  unsigned char *elliptic_curve_list = p + 6;
+  size_t elliptic_curve_len = 0;
 
-  /* debug_msg (3, "client hello, adding supported_elliptic_curves extension"); */
+  (void)tls;
 
-  /* for (grp_id = ssl->curve_list; *grp_id != POLARSSL_ECP_DP_NONE; grp_id++) */
-  /*   { */
-  /*     info = ecp_curve_info_from_grp_id (*grp_id); */
-  /*     elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; */
-  /*     elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; */
-  /*   } */
+  debug_msg (3, "client hello, adding supported_elliptic_curves extension");
 
-  /* if (elliptic_curve_len == 0) */
-  /*   return; */
+  /* We only support curve secp256r1 (23).  */
+  elliptic_curve_list[elliptic_curve_len++] = 0;
+  elliptic_curve_list[elliptic_curve_len++] = 23;
 
-  /* *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8) & 0xFF); */
-  /* *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_ELLIPTIC_CURVES) & 0xFF); */
+  *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8) & 0xFF);
+  *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_ELLIPTIC_CURVES) & 0xFF);
 
-  /* *p++ = (unsigned char) (((elliptic_curve_len + 2) >> 8) & 0xFF); */
-  /* *p++ = (unsigned char) (((elliptic_curve_len + 2)) & 0xFF); */
+  *p++ = (unsigned char) (((elliptic_curve_len + 2) >> 8) & 0xFF);
+  *p++ = (unsigned char) (((elliptic_curve_len + 2)) & 0xFF);
 
-  /* *p++ = (unsigned char) (((elliptic_curve_len) >> 8) & 0xFF); */
-  /* *p++ = (unsigned char) (((elliptic_curve_len)) & 0xFF); */
+  *p++ = (unsigned char) (((elliptic_curve_len) >> 8) & 0xFF);
+  *p++ = (unsigned char) (((elliptic_curve_len)) & 0xFF);
 
-  /* *olen = 6 + elliptic_curve_len; */
-/* } */
+  *olen = 6 + elliptic_curve_len;
+}
 
 
-/* static void */
-/* write_cli_supported_point_formats_ext (ntbtls_t ssl, */
-/*                                        unsigned char *buf, size_t * olen) */
-/* { */
-  //FIXME:
-  /* unsigned char *p = buf; */
-  /* ((void) ssl); */
+static void
+write_cli_supported_point_formats_ext (ntbtls_t tls,
+                                       unsigned char *buf, size_t *olen)
+{
+  unsigned char *p = buf;
 
-  /* *olen = 0; */
+  (void)tls;
 
-  /* debug_msg (3, "client hello, adding supported_point_formats extension"); */
+  debug_msg (3, "client hello, adding supported_point_formats extension");
 
-  /* *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_POINT_FORMATS >> 8) & 0xFF); */
-  /* *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_POINT_FORMATS) & 0xFF); */
+  *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_POINT_FORMATS >> 8) & 0xFF);
+  *p++ = (unsigned char) ((TLS_EXT_SUPPORTED_POINT_FORMATS) & 0xFF);
 
-  /* *p++ = 0x00; */
-  /* *p++ = 2; */
+  *p++ = 0;
+  *p++ = 2;
 
-  /* *p++ = 1; */
-  /* *p++ = POLARSSL_ECP_PF_UNCOMPRESSED; */
+  *p++ = 1; /* One item.  */
+  *p++ = 0; /* Uncompressed.  */
 
-  /* *olen = 6; */
-/* } */
+  *olen = 6;
+}
 
 
 static void
@@ -506,7 +495,7 @@ write_client_hello (ntbtls_t tls)
                                            tls->max_minor_ver))
         continue;
 
-      debug_msg (3, "client_hello, add ciphersuite: %5d %s",
+      debug_msg (5, "client_hello, add ciphersuite: %5d %s",
                  ciphersuites[i],
                  _ntbtls_ciphersuite_get_name (ciphersuites[i]));
 
@@ -539,11 +528,11 @@ write_client_hello (ntbtls_t tls)
   write_signature_algorithms_ext (tls, p + 2 + ext_len, &olen);
   ext_len += olen;
 
-  /* ssl_write_supported_elliptic_curves_ext (tls, p + 2 + ext_len, &olen); */
-  /* ext_len += olen; */
+  write_supported_elliptic_curves_ext (tls, p + 2 + ext_len, &olen);
+  ext_len += olen;
 
-  /* write_cli_supported_point_formats_ext (tls, p + 2 + ext_len, &olen); */
-  /* ext_len += olen; */
+  write_cli_supported_point_formats_ext (tls, p + 2 + ext_len, &olen);
+  ext_len += olen;
 
   write_cli_max_fragment_length_ext (tls, p + 2 + ext_len, &olen);
   ext_len += olen;
@@ -680,33 +669,34 @@ static gpg_error_t
 parse_supported_point_formats_ext (ntbtls_t ssl,
                                    const unsigned char *buf, size_t len)
 {
-  //FIXME:
-  /* size_t list_size; */
-  /* const unsigned char *p; */
+  size_t list_size;
+  const unsigned char *p;
 
-  /* list_size = buf[0]; */
-  /* if (list_size + 1 != len) */
-  /*   { */
-  /*     debug_msg (1, "bad server hello message"); */
-  /*     return gpg_error (GPG_ERR_BAD_HS_SERVER_HELLO); */
-  /*   } */
+  list_size = buf[0];
+  if (list_size + 1 != len)
+    {
+      debug_msg (1, "bad server hello message");
+      return gpg_error (GPG_ERR_BAD_HS_SERVER_HELLO);
+    }
 
-  /* p = buf + 1; */
-  /* while (list_size > 0) */
-  /*   { */
-  /*     if (p[0] == POLARSSL_ECP_PF_UNCOMPRESSED || */
-  /*         p[0] == POLARSSL_ECP_PF_COMPRESSED) */
-  /*       { */
-  /*         ssl->handshake->ecdh_ctx.point_format = p[0]; */
-  /*         debug_msg (4, "point format selected: %d", p[0]); */
-  /*         return (0); */
-  /*       } */
-
-  /*     list_size--; */
-  /*     p++; */
-  /*   } */
+  p = buf + 1;
+  while (list_size > 0)
+    {
+      if (p[0] == 0)
+        {
+          /* Fixme: Store the format - right now not required because
+           * we support only one format.  */
+          /* ssl->handshake->ecdh_ctx.point_format = p[0]; */
+          (void)ssl;
+          debug_msg (4, "point format selected: %d", p[0]);
+          return 0;
+        }
 
-  /* debug_msg (1, "no point format in common"); */
+      list_size--;
+      p++;
+    }
+
+  debug_msg (1, "no point format in common");
   return gpg_error (GPG_ERR_BAD_HS_SERVER_HELLO);
 }
 
@@ -1089,58 +1079,21 @@ parse_server_dh_params (ntbtls_t tls, unsigned char **p, unsigned char *end)
 }
 
 
-/* static int */
-/* ssl_check_server_ecdh_params (const ntbtls_t ssl) */
-/* { */
-  //FIXME:
-  /* const ecp_curve_info *curve_info; */
-
-  /* curve_info = ecp_curve_info_from_grp_id (ssl->handshake->ecdh_ctx.grp.id); */
-  /* if (curve_info == NULL) */
-  /*   { */
-  /*     debug_bug (); */
-  /*     return gpg_error (GPG_ERR_INTERNAL); */
-  /*   } */
-
-  /* debug_msg (2, "ECDH curve: %s", curve_info->name); */
-
-  /* if (!ssl_curve_is_acceptable (ssl, ssl->handshake->ecdh_ctx.grp.id)) */
-  /*   return (-1); */
-
-  /* SSL_DEBUG_ECP (3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp); */
-
-/*   return (0); */
-/* } */
-
-
 static int
-parse_server_ecdh_params (ntbtls_t ssl, unsigned char **p, unsigned char *end)
+parse_server_ecdh_params (ntbtls_t tls, unsigned char **p, unsigned char *end)
 {
-  int ret = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-
-  /*
-   * Ephemeral ECDH parameters:
-   *
-   * struct {
-   *     ECParameters curve_params;
-   *     ECPoint      public;
-   * } ServerECDHParams;
-   */
-  //FIXME:
-  /* if ((ret = ecdh_read_params (&ssl->handshake->ecdh_ctx, */
-  /*                              (const unsigned char **) p, end)) != 0) */
-  /*   { */
-  /*     debug_ret (1, ("ecdh_read_params"), ret); */
-  /*     return (ret); */
-  /*   } */
+  gpg_error_t err;
+  size_t n;
 
-  /* if (ssl_check_server_ecdh_params (ssl) != 0) */
-  /*   { */
-  /*     debug_msg (1, "bad server key exchange message (ECDHE curve)"); */
-  /*     return gpg_error (GPG_ERR_BAD_HS_SERVER_KEX); */
-  /*   } */
+  if ((err = _ntbtls_ecdh_read_params (tls->handshake->ecdh_ctx,
+                                       *p, end - *p, &n)))
+    {
+      debug_ret (1, "ecdh_read_params", err);
+      return err;
+    }
+  *p += n;
 
-  return (ret);
+  return 0;
 }
 
 
@@ -1273,10 +1226,10 @@ parse_signature_algorithm (ntbtls_t tls, unsigned char **p, unsigned char *end,
       return gpg_error (GPG_ERR_BAD_HS_SERVER_KEX);
     }
 
-  debug_msg (2, "Server used SignatureAlgorithm %s",
-             gcry_pk_algo_name ((*p)[1]));
-  debug_msg (2, "Server used HashAlgorithm %s",
-             gcry_md_algo_name ((*p)[0]));
+  debug_msg (2, "Server used HashAlgo %s",
+             gcry_md_algo_name (*md_alg));
+  debug_msg (2, "Server used SignAlgo %s",
+             gcry_pk_algo_name (*pk_alg));
   *p += 2;
 
   return 0;
@@ -1445,13 +1398,15 @@ read_server_key_exchange (ntbtls_t tls)
           err = parse_signature_algorithm (tls, &p, end, &md_alg, &pk_alg);
           if (err)
             {
-              debug_msg (1, "bad server_key_exchange message (%d)", __LINE__);
+              debug_msg (1, "bad server_key_exchange message (%d): %s",
+                         __LINE__, gpg_strerror (err));
               return err;
             }
 
           if (pk_alg != _ntbtls_ciphersuite_get_sig_pk_alg (suite))
             {
-              debug_msg (1, "bad server_key_exchange message (%d)", __LINE__);
+              debug_msg (1, "bad server_key_exchange message (%d): %s",
+                         __LINE__, gpg_strerror (err));
               return gpg_error (GPG_ERR_BAD_HS_SERVER_KEX);
             }
           //FIXME: Check that the ECC subtype matches.  */
@@ -1754,29 +1709,24 @@ write_client_key_exchange (ntbtls_t tls)
        */
       i = 4;
 
-      /* ret = ecdh_make_public (&tls->handshake->ecdh_ctx, */
-      /*                         &n, &tls->out_msg[i], 1000); */
-      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      err = _ntbtls_ecdh_make_public (tls->handshake->ecdh_ctx,
+                                      tls->out_msg + i, 1000, &n);
       if (err)
         {
           debug_ret (1, "ecdh_make_public", err);
           return err;
         }
 
-      /* SSL_DEBUG_ECP (3, "ECDH: Q", &tls->handshake->ecdh_ctx.Q); */
 
-      /* err = ecdh_calc_secret (&tls->handshake->ecdh_ctx, */
-      /*                         &tls->handshake->pmslen, */
-      /*                         tls->handshake->premaster, */
-      /*                         POLARSSL_MPI_MAX_SIZE); */
-      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+      err = _ntbtls_ecdh_calc_secret (tls->handshake->ecdh_ctx,
+                                      tls->handshake->premaster,
+                                      TLS_PREMASTER_SIZE,
+                                      &tls->handshake->pmslen);
       if (err)
         {
           debug_ret (1, "ecdh_calc_secret", err);
           return err;
         }
-
-      /* SSL_DEBUG_MPI (3, "ECDH: z", &tls->handshake->ecdh_ctx.z); */
     }
   else if (kex == KEY_EXCHANGE_PSK
            || kex == KEY_EXCHANGE_RSA_PSK
diff --git a/src/protocol.c b/src/protocol.c
index f736894..658cdbd 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -2482,12 +2482,21 @@ handshake_params_init (handshake_params_t handshake)
       return err;
     }
 
-  handshake->update_checksum = update_checksum_start;
-  handshake->sig_alg = TLS_HASH_SHA1;
+  err = _ntbtls_ecdh_new (&handshake->ecdh_ctx);
+  if (err)
+    {
+      _ntbtls_dhm_release (handshake->dhm_ctx);
+      handshake->dhm_ctx = NULL;
+      gcry_md_close (handshake->fin_sha256);
+      handshake->fin_sha256 = NULL;
+      gcry_md_close (handshake->fin_sha512);
+      handshake->fin_sha512 = NULL;
+      return err;
+    }
 
+  handshake->update_checksum = update_checksum_start;
+  handshake->sig_alg = TLS_HASH_SHA256;
 
-  //*FIXME:
-  /* ecdh_init (&handshake->ecdh_ctx); */
   return 0;
 }
 
@@ -2500,9 +2509,8 @@ handshake_params_deinit (handshake_params_t handshake)
 
   _ntbtls_dhm_release (handshake->dhm_ctx);
   handshake->dhm_ctx = NULL;
-
-  //FIXME:
-  /* ecdh_free (&handshake->ecdh_ctx); */
+  _ntbtls_ecdh_release (handshake->ecdh_ctx);
+  handshake->ecdh_ctx = NULL;
 
   free (handshake->curves);
 
@@ -2800,7 +2808,7 @@ _ntbtls_release (ntbtls_t tls)
 
 /* Set the transport stream for the context TLS.  This needs to be
    called right after init and may not be changed later.  INBOUND and
-   OUTBOIUND are usually connected to the same socket.  The caller
+   OUTBOUND are usually connected to the same socket.  The caller
    must ensure that the streams are not closed as long as the context
    TLS is valid.  However, after destroying the context the streams
    may be closed.  This behavior allows to setup a TLS connection on
@@ -3496,7 +3504,7 @@ _ntbtls_handshake (ntbtls_t tls)
  * Write HelloRequest to request renegotiation on server
  */
 static int
-ssl_write_hello_request (ntbtls_t ssl)
+write_hello_request (ntbtls_t ssl)
 {
   int ret;
 
@@ -3568,7 +3576,7 @@ ssl_renegotiate (ntbtls_t ssl)
       if (ssl->state != TLS_HANDSHAKE_OVER)
         return gpg_error (GPG_ERR_INV_ARG);
 
-      return (ssl_write_hello_request (ssl));
+      return write_hello_request (ssl);
     }
 
   /*

commit 1fc1669e037cfcc1cef1c1af58141d5aace2e9d2
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Mar 16 10:30:05 2017 +0100

    New debug macro for print a point value.
    
    * src/debug.c (_ntbtls_debug_pnt): New.
    * src/util.h (debug_pnt): New macro.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/debug.c b/src/debug.c
index 385953b..901b797 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -152,6 +152,17 @@ _ntbtls_debug_mpi (int level, const char *text, gcry_mpi_t a)
 
 
 void
+_ntbtls_debug_pnt (int level, const char *text,
+                   gcry_mpi_point_t a, gcry_ctx_t ctx)
+{
+  if (!debug_level || level > debug_level)
+    return;
+
+  gcry_log_debugpnt (text, a, ctx);
+}
+
+
+void
 _ntbtls_debug_sxp (int level, const char *text, gcry_sexp_t a)
 {
   if (!debug_level || level > debug_level)
diff --git a/src/util.h b/src/util.h
index 4f37f3b..d9a0ebe 100644
--- a/src/util.h
+++ b/src/util.h
@@ -129,6 +129,8 @@ void _ntbtls_debug_buf (int level, const char *text,
 void _ntbtls_debug_bug (const char *file, int line);
 void _ntbtls_debug_ret (int level, const char *name, gpg_error_t err);
 void _ntbtls_debug_mpi (int level, const char *text, gcry_mpi_t a);
+void _ntbtls_debug_pnt (int level, const char *text,
+                        gcry_mpi_point_t a, gcry_ctx_t ctx);
 void _ntbtls_debug_sxp (int level, const char *text, gcry_sexp_t a);
 void _ntbtls_debug_crt (int level, const char *text, x509_cert_t chain);
 
@@ -137,6 +139,7 @@ void _ntbtls_debug_crt (int level, const char *text, x509_cert_t chain);
 #define debug_bug()        _ntbtls_debug_bug (__FILE__, __LINE__)
 #define debug_ret(l,n,e)   _ntbtls_debug_ret ((l),(n),(e))
 #define debug_mpi(l,t,a)   _ntbtls_debug_mpi ((l),(t),(a))
+#define debug_pnt(l,t,a,c) _ntbtls_debug_pnt ((l),(t),(a),(c))
 #define debug_sxp(l,t,a)   _ntbtls_debug_sxp ((l),(t),(a))
 #define debug_crt(l,t,a)   _ntbtls_debug_crt ((l),(t),(a))
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS               |   8 +-
 configure.ac       |   4 +-
 doc/HACKING        |  17 +++
 src/Makefile.am    |   2 +-
 src/ciphersuites.c |   1 -
 src/context.h      |   9 +-
 src/debug.c        |  11 ++
 src/ecdh.c         | 316 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ntbtls-int.h   |  12 ++
 src/protocol-cli.c | 230 +++++++++++++++-----------------------
 src/protocol.c     |  28 +++--
 src/util.h         |   3 +
 12 files changed, 485 insertions(+), 156 deletions(-)
 create mode 100644 src/ecdh.c


hooks/post-receive
-- 
Not Too Bad TLS
http://git.gnupg.org




More information about the Gnupg-commits mailing list