Change verification API to use a callback.
authorWerner Koch <wk@gnupg.org>
Sun, 19 Feb 2017 09:26:49 +0000 (10:26 +0100)
committerWerner Koch <wk@gnupg.org>
Sun, 19 Feb 2017 09:26:49 +0000 (10:26 +0100)
* src/ntbtls.h.in: Include ksba.h.
(ntbtls_verify_cb_t): New type.
(ntbtls_set_ca_chain): Remove prototype.
(ntbtls_set_verify_cb): New.
(ntbtls_x509_get_peer_cert): New.
* src/visibility.c (ntbtls_set_ca_chain): Remove.
(ntbtls_set_verify_cb): New.
(ntbtls_x509_get_peer_cert): New.
* src/visibility.h (ntbtls_set_ca_chain): Remove
(ntbtls_set_verify_cb): Mark visible.
(ntbtls_x509_get_peer_cert): Ditto.
* src/libntbtls.def (ntbtls_set_ca_chain): Remove.
(ntbtls_set_verify_cb, ntbtls_x509_get_peer_cert): New.
* src/libntbtls.vers (ntbtls_set_ca_chain): Remove.
(ntbtls_set_verify_cb, ntbtls_x509_get_peer_cert): New.

* src/context.h (_ntbtls_context_s: Remove 'ca_chain' and
'crl_chain'.  Add 'verify_cb' and 'verify_cb_value'.
* src/protocol.c (_ntbtls_read_certificate): Call verify callback.
(session_deinit): Remove superfluous conditional.
(_ntbtls_set_ca_chain): Remove.
(_ntbtls_set_verify_cb): New.
* src/x509.c (x)509_cert_s): Remove fields 'fpr', 'is_self_signed',
and 'is_valid'.
(_ntbtls_x509_verify): Remove
(_ntbtls_x509_get_cert): Fix use of IDX.
(_ntbtls_x509_get_peer_cert): New.

Signed-off-by: Werner Koch <wk@gnupg.org>
src/context.h
src/libntbtls.def
src/libntbtls.vers
src/ntbtls-int.h
src/ntbtls.h.in
src/protocol.c
src/visibility.c
src/visibility.h
src/x509.c

index 3a644c7..61616bc 100644 (file)
@@ -370,8 +370,8 @@ struct _ntbtls_context_s
    */
   key_cert_t key_cert;          /*!<  own certificate(s)/key(s) */
 
-  x509_cert_t ca_chain;         /*!<  own trusted CA chain      */
-  x509_crl_t  ca_crl;           /*!<  trusted CA CRLs           */
+  ntbtls_verify_cb_t verify_cb; /*!<  the verify callback              */
+  void *verify_cb_value;;       /*!<  the first arg passed to this cb  */
 
   /*
    * Support for generating and checking session tickets
index 065287c..c0b9eb8 100644 (file)
@@ -32,8 +32,11 @@ EXPORTS
 
     ntbtls_handshake                      @8
 
-    ntbtls_set_ca_chain                   @9
+    ntbtls_set_verify_cb                  @9
+
     ntbtls_x509_cert_new                  @10
     ntbtls_x509_cert_release              @11
     ntbtls_x509_append_cert               @12
+
+    ntbtls_x509_get_peer_cert             @13
 ; END
index 41c7eb5..8909c19 100644 (file)
@@ -32,10 +32,12 @@ NTBTLS_1.0 {
 
     ntbtls_handshake;
 
-    ntbtls_set_ca_chain;
+    ntbtls_set_verify_cb;
+
     ntbtls_x509_cert_new;
     ntbtls_x509_cert_release;
     ntbtls_x509_append_cert;
+    ntbtls_x509_get_peer_cert;
 
   local:
     *;
index cfc5e72..a059115 100644 (file)
@@ -324,8 +324,8 @@ gpg_error_t _ntbtls_get_stream (ntbtls_t tls,
                                 gpgrt_stream_t *r_readfp,
                                 gpgrt_stream_t *r_writefp);
 
-gpg_error_t _ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain,
-                                  x509_crl_t ca_crl);
+gpg_error_t _ntbtls_set_verify_cb (ntbtls_t tls,
+                                   ntbtls_verify_cb_t cb, void *cb_value);
 
 gpg_error_t _ntbtls_set_hostname (ntbtls_t tls, const char *hostname);
 
@@ -375,13 +375,10 @@ gpg_error_t _ntbtls_x509_append_cert (x509_cert_t cert,
 void _ntbtls_x509_log_cert (const char *text, x509_cert_t chain, int full);
 const unsigned char *_ntbtls_x509_get_cert (x509_cert_t cert, int idx,
                                             size_t *r_derlen);
+ksba_cert_t _ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx);
 gpg_error_t _ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk);
 
 
-gpg_error_t _ntbtls_x509_verify (x509_cert_t cert, x509_cert_t trust_ca,
-                                 x509_crl_t ca_crl,
-                                 const char *cn, int *r_flags);
-
 int _ntbtls_x509_can_do (x509_privkey_t privkey, pk_algo_t pkalgo);
 
 
index 864c40f..ce713e4 100644 (file)
@@ -23,6 +23,7 @@
 #define _NTBTLS_H
 
 #include <gpg-error.h>
+#include <ksba.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -54,7 +55,7 @@ struct _ntbtls_context_s;
 typedef struct _ntbtls_context_s *ntbtls_t;
 
 /*
- * Object to hold X.509 certifciates.
+ * Object to hold X.509 certificates.
  */
 struct x509_cert_s;
 typedef struct x509_cert_s *x509_cert_t;
@@ -65,6 +66,17 @@ typedef struct x509_cert_s *x509_cert_t;
 struct x509_crl_s;
 typedef struct x509_crl_s *x509_crl_t;
 
+/*
+ * The type of the verification callback.  This must be registered
+ * prior to the handshake and will be called by ntbltls when a peer's
+ * certificate needs to be verified.  OPAQUE is the vale set when the
+ * callback has been set.  TLS is the respective TLS context.
+ * VERIFY_FLAGS are not yet defined flags.
+ */
+typedef gpg_error_t (*ntbtls_verify_cb_t) (void *opaque,
+                                           ntbtls_t tls,
+                                           unsigned int verify_flags);
+
 
 /* Check that the library fulfills the version requirement.  */
 const char *ntbtls_check_version (const char *req_version);
@@ -96,8 +108,8 @@ gpg_error_t ntbtls_get_stream (ntbtls_t tls,
                                gpgrt_stream_t *r_writefp);
 
 /* Set the data required to verify peer certificate.  */
-gpg_error_t ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain,
-                                 x509_crl_t ca_crl);
+gpg_error_t ntbtls_set_verify_cb (ntbtls_t tls,
+                                  ntbtls_verify_cb_t cb, void *cb_value);
 
 /* Set the hostname to check against the received server certificate.
    It is used for SNI, too.  */
@@ -107,6 +119,8 @@ gpg_error_t ntbtls_set_hostname (ntbtls_t tls, const char *hostname);
    connected before starting this handshake.  */
 gpg_error_t ntbtls_handshake (ntbtls_t tls);
 
+/* Return the peer's certificate.  */
+ksba_cert_t ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx);
 
 
 /*
index d46238d..dbbc259 100644 (file)
@@ -1994,22 +1994,18 @@ _ntbtls_read_certificate (ntbtls_t tls)
 
   if (tls->authmode != TLS_VERIFY_NONE)
     {
-      if (!tls->ca_chain)
-        {
-          debug_msg (1, "got no CA chain");
-          return gpg_error (GPG_ERR_NO_CERT_CHAIN);
-        }
-
       /*
        * Main check: verify certificate
        */
-      err = _ntbtls_x509_verify (tls->session_negotiate->peer_chain,
-                                 tls->ca_chain, tls->ca_crl,
-                                 tls->hostname,
-                                 &tls->session_negotiate->verify_result);
+      if (!tls->verify_cb)
+        {
+          debug_msg (1, "verify callback not set");
+          return gpg_error (GPG_ERR_NOT_INITIALIZED);
+        }
+      err = tls->verify_cb (tls->verify_cb_value, tls, 0);
       if (err)
         {
-          debug_ret (1, "x509_verify", err);
+          debug_ret (1, "error from the verify callback", err);
         }
 
       /*
@@ -2455,8 +2451,7 @@ session_deinit (session_t session)
   if (!session)
     return;
 
-  if (session->peer_chain)
-    _ntbtls_x509_cert_release (session->peer_chain);
+  _ntbtls_x509_cert_release (session->peer_chain);
 
   free (session->ticket);
   wipememory (session, sizeof *session);
@@ -2792,10 +2787,6 @@ _ntbtls_release (ntbtls_t tls)
       tls->psk_identity_len = 0;
     }
 
-  if (tls->ca_chain)
-    {
-      _ntbtls_x509_cert_release (tls->ca_chain);
-    }
 
   //FIXME:
   /* ssl_key_cert_free (tls->key_cert); */
@@ -3038,14 +3029,20 @@ _ntbtls_set_session (ntbtls_t tls, const session_t session)
 /* } */
 
 
+/* Set a certificate verify callback for the session TLS.  */
 gpg_error_t
-_ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain, x509_crl_t ca_crl)
+_ntbtls_set_verify_cb (ntbtls_t tls, ntbtls_verify_cb_t cb, void *cb_value)
 {
   if (!tls)
     return gpg_error (GPG_ERR_INV_ARG);
 
-  tls->ca_chain = ca_chain;
-  tls->ca_crl = ca_crl;
+  tls->verify_cb = cb;
+  tls->verify_cb_value = cb_value;
+
+  /* Make sure we have an authmode set.  Right now, there is no API to
+   * change thye authmode.  */
+  tls->authmode = cb ? TLS_VERIFY_REQUIRED : TLS_VERIFY_NONE;
+
   return 0;
 }
 
index f79ef0c..37a67ae 100644 (file)
@@ -83,9 +83,9 @@ ntbtls_handshake (ntbtls_t tls)
 
 
 gpg_error_t
-ntbtls_set_ca_chain (ntbtls_t tls, x509_cert_t ca_chain, x509_crl_t ca_crl)
+ntbtls_set_verify_cb (ntbtls_t tls,  ntbtls_verify_cb_t cb, void *cb_value)
 {
-  return _ntbtls_set_ca_chain (tls, ca_chain, ca_crl);
+  return _ntbtls_set_verify_cb (tls, cb, cb_value);
 }
 
 
@@ -108,3 +108,9 @@ ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen)
 {
   return _ntbtls_x509_append_cert (cert, der, derlen);
 }
+
+ksba_cert_t
+ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx)
+{
+  return _ntbtls_x509_get_peer_cert (tls, idx);
+}
index 69249d3..b3f973d 100644 (file)
@@ -50,10 +50,12 @@ MARK_VISIBLE (ntbtls_get_stream)
 MARK_VISIBLE (ntbtls_set_hostname)
 MARK_VISIBLE (ntbtls_handshake)
 
-MARK_VISIBLE (ntbtls_set_ca_chain)
+MARK_VISIBLE (ntbtls_set_verify_cb)
+
 MARK_VISIBLE (ntbtls_x509_cert_new)
 MARK_VISIBLE (ntbtls_x509_cert_release)
 MARK_VISIBLE (ntbtls_x509_append_cert)
+MARK_VISIBLE (ntbtls_x509_get_peer_cert)
 
 
 #undef MARK_VISIBLE
@@ -72,10 +74,11 @@ MARK_VISIBLE (ntbtls_x509_append_cert)
 #define ntbtls_set_hostname          _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_handshake             _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 
-#define ntbtls_set_ca_chain          _ntbtls_USE_THE_UNDERSCORED_FUNCTION
+#define ntbtls_set_verify_cb         _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_x509_cert_new         _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_x509_cert_release     _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 #define ntbtls_x509_append_cert      _ntbtls_USE_THE_UNDERSCORED_FUNCTION
+#define ntbtls_x509_get_peer_cert    _ntbtls_USE_THE_UNDERSCORED_FUNCTION
 
 #endif /*!_NTBTLS_INCLUDED_BY_VISIBILITY_C*/
 #endif /*NTBTLS_VISIBILITY_H*/
index 6cf8f57..6ad7655 100644 (file)
@@ -33,9 +33,6 @@ struct x509_cert_s
 {
   x509_cert_t next;
   ksba_cert_t crt;       /* The actual certificate object.  */
-  unsigned char fpr[20]; /* Fingerprint of the certificate.  */
-  int is_self_signed:1;  /* This certificate is self-signed.  */
-  int is_valid:1;        /* The certifiate is valid except for revocations.  */
 };
 
 
@@ -90,7 +87,7 @@ _ntbtls_x509_append_cert (x509_cert_t cert, const void *der, size_t derlen)
   if (!cert)
     return gpg_error (GPG_ERR_INV_ARG);
 
-  /* Walk to the last certifciate of the chain.  */
+  /* Walk to the last certificate of the chain.  */
   while (cert->next)
     cert = cert->next;
 
@@ -227,7 +224,9 @@ _ntbtls_x509_log_cert (const char *text, x509_cert_t chain_arg, int full)
 const unsigned char *
 _ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen)
 {
-  for (; cert && idx >= 0; cert = cert->next, idx--)
+  if (idx < 0)
+    return NULL;
+  for (; cert && idx; cert = cert->next, idx--)
     ;
   if (!cert)
     return NULL;
@@ -236,6 +235,32 @@ _ntbtls_x509_get_cert (x509_cert_t cert, int idx, size_t *r_derlen)
 }
 
 
+/* Return the peer's certificates.  A value of 0 for IDX returns the
+ * host's certificate.  To enumerate all other certificates IDX needs
+ * to be incremented until the function returns NULL.  The caller
+ * must release the returned certificate. */
+ksba_cert_t
+_ntbtls_x509_get_peer_cert (ntbtls_t tls, int idx)
+{
+  x509_cert_t cert;
+
+  debug_crt (1, "peer certs A", tls->session_negotiate->peer_chain);
+
+  if (!tls || !tls->session_negotiate || idx < 0)
+    return NULL;
+  for (cert = tls->session_negotiate->peer_chain;
+       cert && idx;
+       cert = cert->next, idx--)
+    ;
+  if (!cert || !cert->crt)
+    return NULL;
+
+  ksba_cert_ref (cert->crt);
+  debug_crt (1, "peer certs B", tls->session_negotiate->peer_chain);
+  return cert->crt;
+}
+
+
 /* Return the public key from the certificate with index IDX in CERT
    and store it as an S-expression at R_PK.  On error return an error
    code and store NULL at R_PK.  */
@@ -279,17 +304,6 @@ _ntbtls_x509_get_pk (x509_cert_t cert, int idx, gcry_sexp_t *r_pk)
 }
 
 
-
-gpg_error_t
-_ntbtls_x509_verify (x509_cert_t chain, x509_cert_t trust_ca, x509_crl_t ca_crl,
-                     const char *cn, int *r_flags)
-{
-  //FIXME:
-
-  return 0;
-}
-
-
 /* Return true if PRIVKEY can do an operation using the public key
    algorithm PKALGO.  */
 int