Skip to content

Commit ecaf660

Browse files
committed
tlshd: Report peer certificate verification failures
Parse the session's verification error bit mask and report the individual errors to help admins debug certificate verification problems. Signed-off-by: Chuck Lever <[email protected]>
1 parent e9c67f1 commit ecaf660

File tree

4 files changed

+56
-5
lines changed

4 files changed

+56
-5
lines changed

src/tlshd/handshake.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,13 @@ void tlshd_client_handshake(gnutls_session_t session)
103103
ret = gnutls_handshake(session);
104104
} while (ret < 0 && !gnutls_error_is_fatal(ret));
105105
if (ret < 0) {
106-
tlshd_log_gnutls_error(ret);
106+
switch (ret) {
107+
case GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR:
108+
tlshd_log_cert_verification_error(session);
109+
break;
110+
default:
111+
tlshd_log_gnutls_error(ret);
112+
}
107113
return;
108114
}
109115

src/tlshd/log.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,50 @@ void tlshd_log_gai_error(int error)
120120
syslog(LOG_NOTICE, "%s\n", gai_strerror(error));
121121
}
122122

123+
struct tlshd_cert_status_bit {
124+
unsigned int bit;
125+
char *name;
126+
};
127+
128+
static const struct tlshd_cert_status_bit tlshd_cert_status_names[] = {
129+
/* { GNUTLS_CERT_INVALID, "invalid" }, */
130+
{ GNUTLS_CERT_REVOKED, "revoked" },
131+
{ GNUTLS_CERT_SIGNER_NOT_FOUND, "signer not found" },
132+
{ GNUTLS_CERT_SIGNER_NOT_CA, "signer not CA" },
133+
{ GNUTLS_CERT_INSECURE_ALGORITHM, "uses insecure algorithm" },
134+
{ GNUTLS_CERT_NOT_ACTIVATED, "not activated" },
135+
{ GNUTLS_CERT_EXPIRED, "expired" },
136+
{ GNUTLS_CERT_SIGNATURE_FAILURE, "signature failure" },
137+
{ GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED, "revocation data superseded" },
138+
{ GNUTLS_CERT_UNEXPECTED_OWNER, "owner unexpected" },
139+
{ GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE, "revocation data issued in the future" },
140+
{ GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE, "signer constraints failure" },
141+
{ GNUTLS_CERT_MISMATCH, "mismatch" },
142+
{ GNUTLS_CERT_PURPOSE_MISMATCH, "purpose mismatch" },
143+
{ GNUTLS_CERT_MISSING_OCSP_STATUS, "has missing OCSP status" },
144+
{ GNUTLS_CERT_INVALID_OCSP_STATUS, "has invalid OCSP status" },
145+
{ GNUTLS_CERT_UNKNOWN_CRIT_EXTENSIONS, "has unknown crit extensions" },
146+
{ 0, NULL }
147+
};
148+
149+
/**
150+
* tlshd_log_cert_verification_error - Report a failed certificate verification
151+
* @session: Session with a failed handshake
152+
*
153+
*/
154+
void tlshd_log_cert_verification_error(gnutls_session_t session)
155+
{
156+
unsigned int status;
157+
int i;
158+
159+
status = gnutls_session_get_verify_cert_status(session);
160+
161+
for (i = 0; tlshd_cert_status_names[i].name; i++)
162+
if (status & tlshd_cert_status_names[i].bit)
163+
syslog(LOG_ERR, "Certificate %s.\n",
164+
tlshd_cert_status_names[i].name);
165+
}
166+
123167
/**
124168
* tlshd_log_gnutls_error - Emit "library call failed" notification
125169
* @error: GnuTLS error code to log

src/tlshd/tlshd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ void tlshd_log_debug(const char *fmt, ...);
5252
extern void tlshd_log_error(const char *msg);
5353
extern void tlshd_log_perror(const char *prefix);
5454
extern void tlshd_log_gai_error(int error);
55-
extern void tlshd_log_gnutls_error(int error);
5655

56+
extern void tlshd_log_cert_verification_error(gnutls_session_t session);
57+
extern void tlshd_log_gnutls_error(int error);
5758
extern void tlshd_gnutls_log_func(int level, const char *msg);
5859
extern void tlshd_gnutls_audit_func(gnutls_session_t session, const char *msg);
5960

src/tlshd/x509.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,15 @@ static void tlshd_client_anon_x509_handshake(int sock, const char *peername)
8484

8585
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
8686

87-
if (tlshd_verify_server)
88-
gnutls_session_set_verify_cert(session, peername, 0);
89-
9087
ret = gnutls_set_default_priority(session);
9188
if (ret != GNUTLS_E_SUCCESS) {
9289
tlshd_log_gnutls_error(ret);
9390
return;
9491
}
9592

93+
if (tlshd_verify_server)
94+
gnutls_session_set_verify_cert(session, peername, 0);
95+
9696
tlshd_client_handshake(session);
9797

9898
gnutls_deinit(session);

0 commit comments

Comments
 (0)