From: Nikos Mavrogiannopoulos Date: Mon, 24 Aug 2015 09:03:09 +0000 (+0200) Subject: Added gnutls_session_set_verify_function X-Git-Tag: gnutls_3_5_0~717 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=05ddde02ff6f121a615cb472ed63039af419da04;p=thirdparty%2Fgnutls.git Added gnutls_session_set_verify_function That allows to set a verification callback per session rather than only globally on the credentials structure. --- diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 2846fa9610..6e28296737 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -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; diff --git a/lib/handshake.c b/lib/handshake.c index 3ea25bc81f..f31161c8bf 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -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; diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index a81087b72a..bfd4ba5e75 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -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, diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 3c77ddc156..dcb303f85c 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1052,6 +1052,7 @@ GNUTLS_3_4 gnutls_prf_rfc5705; gnutls_hex_decode2; gnutls_hex_encode2; + gnutls_session_set_verify_function; local: *; }; diff --git a/lib/state.c b/lib/state.c index 738706a4d3..ab5b07f596 100644 --- a/lib/state.c +++ b/lib/state.c @@ -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: