]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_session_set_verify_function
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 24 Aug 2015 09:03:09 +0000 (11:03 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 24 Aug 2015 09:10:00 +0000 (11:10 +0200)
That allows to set a verification callback per session rather
than only globally on the credentials structure.

lib/gnutls_int.h
lib/handshake.c
lib/includes/gnutls/gnutls.h.in
lib/libgnutls.map
lib/state.c

index 2846fa96104b87a94426b4a246a623e2b333d07d..6e28296737665142298db3ebb50e52ac297388c3 100644 (file)
@@ -998,6 +998,10 @@ typedef struct {
        bool no_replay_protection;      /* DTLS replay protection */
        bool try_ext_master_secret;     /* whether to try negotiating the ext master secret */
 
+       /* a verify callback to override the verify callback from the credentials
+        * structure */
+       gnutls_certificate_verify_function *verify_callback;
+
        /* whether this session uses non-blocking sockets */
        bool blocking;
 
index 3ea25bc81fe4ba765c33573771c23b0823226791..f31161c8bfc4bf6d66de16fad061228f9d471b69 100644 (file)
@@ -2684,14 +2684,18 @@ static int run_verify_callback(gnutls_session_t session, unsigned int side)
        if (type != GNUTLS_CRD_CERTIFICATE)
                return 0;
 
-       if (cred != NULL && cred->verify_callback != NULL &&
+       if (cred != NULL &&
+           (cred->verify_callback != NULL || session->internals.verify_callback != NULL) &&
            (session->security_parameters.entity == GNUTLS_CLIENT ||
             session->internals.send_cert_req != GNUTLS_CERT_IGNORE)) {
-               ret = cred->verify_callback(session);
+               if (session->internals.verify_callback)
+                       ret = session->internals.verify_callback(session);
+               else
+                       ret = cred->verify_callback(session);
                if (ret < -1)
-                       return ret;
+                       return gnutls_assert_val(ret);
                else if (ret != 0)
-                       return GNUTLS_E_CERTIFICATE_ERROR;
+                       return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
        }
 
        return 0;
index a81087b72a45bdc915ecf1fdbbbf7d1e3576f2d7..bfd4ba5e751d60de0f3182d84e3830148ee11c31 100644 (file)
@@ -1268,6 +1268,9 @@ void gnutls_session_get_random(gnutls_session_t session,
                               gnutls_datum_t * server);
 char *gnutls_session_get_desc(gnutls_session_t session);
 
+typedef int gnutls_certificate_verify_function(gnutls_session_t);
+void gnutls_session_set_verify_function(gnutls_session_t session, gnutls_certificate_verify_function * func);
+
 int gnutls_session_set_premaster(gnutls_session_t session,
                                 unsigned int entity,
                                 gnutls_protocol_t version,
@@ -2065,7 +2068,6 @@ gnutls_certificate_set_retrieve_function(gnutls_certificate_credentials_t
                                         gnutls_certificate_retrieve_function
                                         * func);
 
-typedef int gnutls_certificate_verify_function(gnutls_session_t);
 void
 gnutls_certificate_set_verify_function(gnutls_certificate_credentials_t
                                       cred,
index 3c77ddc1564fec11e8484e18440400fbcb2845ba..dcb303f85c7d8b5c28c488e64f688ce3c5275b45 100644 (file)
@@ -1052,6 +1052,7 @@ GNUTLS_3_4
        gnutls_prf_rfc5705;
        gnutls_hex_decode2;
        gnutls_hex_encode2;
+       gnutls_session_set_verify_function;
  local:
        *;
 };
index 738706a4d3ef938197bb4cc835611032bc20834b..ab5b07f596e6ce03fffa11cdc369bb9b4f69dc5a 100644 (file)
@@ -895,6 +895,37 @@ void gnutls_session_set_ptr(gnutls_session_t session, void *ptr)
        session->internals.user_ptr = ptr;
 }
 
+/**
+ * gnutls_session_set_verify_function:
+ * @session: is a #gnutls_session_t type.
+ * @func: is the callback function
+ *
+ * This function sets a callback to be called when peer's certificate
+ * has been received in order to verify it on receipt rather than
+ * doing after the handshake is completed. This overrides any callback
+ * set using gnutls_certificate_set_verify_function().
+ *
+ * The callback's function prototype is:
+ * int (*callback)(gnutls_session_t);
+ *
+ * If the callback function is provided then gnutls will call it, in the
+ * handshake, just after the certificate message has been received.
+ * To verify or obtain the certificate the gnutls_certificate_verify_peers2(),
+ * gnutls_certificate_type_get(), gnutls_certificate_get_peers() functions
+ * can be used.
+ *
+ * The callback function should return 0 for the handshake to continue
+ * or non-zero to terminate.
+ *
+ * Since: 3.5.0
+ **/
+void
+ gnutls_session_set_verify_function
+    (gnutls_session_t session,
+     gnutls_certificate_verify_function * func)
+{
+       session->internals.verify_callback = func;
+}
 
 /**
  * gnutls_record_get_direction: