/* Certs are not automatically varified during the handshake */ static int tlsg_cert_verify( tlsg_session *ssl ) { unsigned int status = 0; int err; time_t now = time(0); time_t peertime; err = gnutls_certificate_verify_peers2( ssl->session, &status ); if ( err < 0 ) { Debug( LDAP_DEBUG_ANY,"TLS: gnutls_certificate_verify_peers2 failed %d\n", err,0,0 ); return -1; } if ( status ) { Debug( LDAP_DEBUG_TRACE,"TLS: peer cert untrusted or revoked (0x%x)\n", status, 0,0 ); return -1; } peertime = gnutls_certificate_expiration_time_peers( ssl->session ); if ( peertime == (time_t) -1 ) { Debug( LDAP_DEBUG_ANY, "TLS: gnutls_certificate_expiration_time_peers failed\n", 0, 0, 0 ); return -1; } if ( peertime < now ) { Debug( LDAP_DEBUG_ANY, "TLS: peer certificate is expired\n", 0, 0, 0 ); return -1; } peertime = gnutls_certificate_activation_time_peers( ssl->session ); if ( peertime == (time_t) -1 ) { Debug( LDAP_DEBUG_ANY, "TLS: gnutls_certificate_activation_time_peers failed\n", 0, 0, 0 ); return -1; } if ( peertime > now ) { Debug( LDAP_DEBUG_ANY, "TLS: peer certificate not yet active\n", 0, 0, 0 ); return -1; } return 0; }
static gboolean ssl_verify_certificate (LmSSL *ssl, const gchar *server) { LmSSLBase *base; unsigned int status; int rc; base = LM_SSL_BASE (ssl); /* This verification function uses the trusted CAs in the credentials * structure. So you must have installed one or more CA certificates. */ rc = gnutls_certificate_verify_peers2 (ssl->gnutls_session, &status); if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (rc != 0) { if (base->func (ssl, LM_SSL_STATUS_GENERIC_ERROR, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) { if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (status & GNUTLS_CERT_INVALID || status & GNUTLS_CERT_REVOKED) { if (base->func (ssl, LM_SSL_STATUS_UNTRUSTED_CERT, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (gnutls_certificate_expiration_time_peers (ssl->gnutls_session) < time (0)) { if (base->func (ssl, LM_SSL_STATUS_CERT_EXPIRED, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (gnutls_certificate_activation_time_peers (ssl->gnutls_session) > time (0)) { if (base->func (ssl, LM_SSL_STATUS_CERT_NOT_ACTIVATED, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (gnutls_certificate_type_get (ssl->gnutls_session) == GNUTLS_CRT_X509) { const gnutls_datum_t* cert_list; guint cert_list_size; gnutls_digest_algorithm_t digest = GNUTLS_DIG_SHA256; guchar digest_bin[LM_FINGERPRINT_LENGTH]; size_t digest_size; gnutls_x509_crt_t cert; cert_list = gnutls_certificate_get_peers (ssl->gnutls_session, &cert_list_size); if (cert_list == NULL) { if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } gnutls_x509_crt_init (&cert); if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) != 0) { if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (!gnutls_x509_crt_check_hostname (cert, server)) { if (base->func (ssl, LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } gnutls_x509_crt_deinit (cert); digest_size = gnutls_hash_get_len(digest); g_assert(digest_size < sizeof(digest_bin)); if (gnutls_fingerprint (digest, &cert_list[0], digest_bin, &digest_size) >= 0) { _lm_ssl_base_set_fingerprint(base, digest_bin, digest_size); if (_lm_ssl_base_check_fingerprint(base) != 0 && base->func (ssl, LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } else if (base->func (ssl, LM_SSL_STATUS_GENERIC_ERROR, base->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } return TRUE; }
time_t session::get_peers_certificate_expiration_time () const { return gnutls_certificate_expiration_time_peers (s); }
static gboolean ssl_verify_certificate (LmSSL *ssl, const gchar *server) { int status; /* This verification function uses the trusted CAs in the credentials * structure. So you must have installed one or more CA certificates. */ status = gnutls_certificate_verify_peers (ssl->gnutls_session); if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) { if (ssl->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (status & GNUTLS_CERT_INVALID || status & GNUTLS_CERT_REVOKED) { if (ssl->func (ssl, LM_SSL_STATUS_UNTRUSTED_CERT, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (gnutls_certificate_expiration_time_peers (ssl->gnutls_session) < time (0)) { if (ssl->func (ssl, LM_SSL_STATUS_CERT_EXPIRED, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (gnutls_certificate_activation_time_peers (ssl->gnutls_session) > time (0)) { if (ssl->func (ssl, LM_SSL_STATUS_CERT_NOT_ACTIVATED, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (gnutls_certificate_type_get (ssl->gnutls_session) == GNUTLS_CRT_X509) { const gnutls_datum* cert_list; guint cert_list_size; size_t digest_size; gnutls_x509_crt cert; cert_list = gnutls_certificate_get_peers (ssl->gnutls_session, &cert_list_size); if (cert_list == NULL) { if (ssl->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } gnutls_x509_crt_init (&cert); if (!gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER)) { if (ssl->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } if (!gnutls_x509_crt_check_hostname (cert, server)) { if (ssl->func (ssl, LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } gnutls_x509_crt_deinit (cert); if (gnutls_fingerprint (GNUTLS_DIG_MD5, &cert_list[0], ssl->fingerprint, &digest_size) >= 0) { if (ssl->expected_fingerprint && memcmp (ssl->expected_fingerprint, ssl->fingerprint, digest_size) && ssl->func (ssl, LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } else if (ssl->func (ssl, LM_SSL_STATUS_GENERIC_ERROR, ssl->func_data) != LM_SSL_RESPONSE_CONTINUE) { return FALSE; } } return TRUE; }