Skip to content

Commit

Permalink
Refactor: libcrmcommon: Use gnutls_session_set_verify_cert()
Browse files Browse the repository at this point in the history
Instead of calling gnutls_certificate_set_verify_function() with the
custom callback verify_peer_cert().

gnutls_session_set_verify_cert() is available since GnuTLS 3.4.6. It
sets a verify function for the entire session, overriding any verify
function set for a particular certificate (for example, using
gnutls_certificate_set_verify_function()). For our purposes, each
session has a unique certificate anyway, so the effect is the same
either way.

gnutls_session_set_verify_cert() sets up a verify callback function
automatically, using hostname and flags parameters. At the time of this
commit, it's called auto_verify_cb(); it calls
gnutls_certificate_verify_peers() or a related function and returns 0 on
success or GNUTLS_E_CERTIFICATE_ERROR or
GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR on error.
* Our verify_peer_cert() function passes NULL to
  gnutls_certificate_verify_peers3() to disable hostname verification.
  Accordingly, we pass NULL to gnutls_session_set_verify_cert().
* We don't currently override the default verify flags (which would have
  required a call to gnutls_certificate_set_verify_flags()). So we pass
  0 for the flags argument here, which says to use the defaults.

There will be changes in the output upon error, as we lose our custom
error processing from verify_peer_cert(), but that seems acceptable.

Closes T967

Signed-off-by: Reid Wahl <[email protected]>
  • Loading branch information
nrwahl2 committed Jan 8, 2025
1 parent 73526d8 commit 939fd11
Showing 1 changed file with 2 additions and 44 deletions.
46 changes: 2 additions & 44 deletions lib/common/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,44 +99,6 @@ tls_load_x509_data(pcmk__tls_t *tls)
return pcmk_rc_ok;
}

/*!
* \internal
* \brief Verify a peer's certificate
*
* \return 0 if the certificate is trusted and the gnutls handshake should
* continue, -1 otherwise
*/
static int
verify_peer_cert(gnutls_session_t session)
{
int rc;
int type;
unsigned int status;
gnutls_datum_t out;

/* NULL = no hostname comparison will be performed */
rc = gnutls_certificate_verify_peers3(session, NULL, &status);

/* Success means it was able to perform the verification. We still have
* to check status to see whether the cert is valid or not.
*/
if (rc != GNUTLS_E_SUCCESS) {
crm_err("Failed to verify peer certificate: %s", gnutls_strerror(rc));
return -1;
}

if (status == 0) {
/* The certificate is trusted. */
return 0;
}

type = gnutls_certificate_type_get(session);
gnutls_certificate_verification_status_print(status, type, &out, 0);
crm_err("Peer certificate invalid: %s", out.data);
gnutls_free(out.data);
return GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR;
}

static void
_gnutls_log_func(int level, const char *msg)
{
Expand Down Expand Up @@ -368,12 +330,8 @@ pcmk__new_tls_session(pcmk__tls_t *tls, int csock)
gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUIRE);
}

/* Register a function to verify the peer's certificate.
*
* FIXME: When we can require gnutls >= 3.4.6, remove verify_peer_cert
* and use gnutls_session_set_verify_cert instead.
*/
gnutls_certificate_set_verify_function(tls->credentials.cert, verify_peer_cert);
// Register a function to verify the peer's certificate
gnutls_session_set_verify_cert(session, NULL, 0);
}

return session;
Expand Down

0 comments on commit 939fd11

Please sign in to comment.