When renegotiating, verify that any certificate received from the client contains the same username.

This commit is contained in:
Nikos Mavrogiannopoulos
2014-06-13 15:08:40 +02:00
parent 18cef50ebe
commit 1d2f36f9bf
3 changed files with 29 additions and 3 deletions

View File

@@ -245,11 +245,35 @@ static int verify_certificate_cb(gnutls_session_t session)
return -1;
}
if (session == ws->dtls_session) /* no certificate is verified in DTLS */
return 0;
if (session == ws->dtls_session) {
oclog(ws, LOG_ERR, "unexpected issue; client shouldn't have offered a certificate in DTLS");
return GNUTLS_E_CERTIFICATE_ERROR;
}
ws->cert_auth_ok = 0;
/* now verify whether the username in the certificate matches the username of the session */
if (ws->cert_username[0] != 0) {
char prev_username[MAX_USERNAME_SIZE];
const gnutls_datum_t *cert;
unsigned cert_size;
cert = gnutls_certificate_get_peers(session, &cert_size);
if (cert != NULL) { /* it's ok for the user not to send any certificate on renegotiation */
memcpy(prev_username, ws->cert_username, MAX_USERNAME_SIZE);
ret = get_cert_names(ws, &cert[0]);
if (ret < 0) {
oclog(ws, LOG_ERR, "cannot parse certificate");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (strcmp(prev_username, ws->cert_username) != 0) {
oclog(ws, LOG_ERR, "user switched during renegotiation!");
return GNUTLS_E_CERTIFICATE_ERROR;
}
}
}
/* This verification function uses the trusted CAs in the credentials
* structure. So you must have installed one or more CA certificates.
*/
@@ -282,6 +306,8 @@ static int verify_certificate_cb(gnutls_session_t session)
/* notify gnutls to continue handshake normally */
return 0;
fail:
/* In cisco client compatibility we don't hangup immediately, we
* simply use the flag (ws->cert_auth_ok). */
if (ws->config->cisco_client_compat == 0)
return GNUTLS_E_CERTIFICATE_ERROR;
else

View File

@@ -378,7 +378,6 @@ int get_auth_handler(worker_st * ws, unsigned http_ver)
return get_auth_handler2(ws, http_ver, NULL);
}
static
int get_cert_names(worker_st * ws, const gnutls_datum_t * raw)
{
gnutls_x509_crt_t crt;

View File

@@ -246,6 +246,7 @@ int get_empty_handler(worker_st *server, unsigned http_ver);
int get_config_handler(worker_st *ws, unsigned http_ver);
int get_string_handler(worker_st *ws, unsigned http_ver);
int get_dl_handler(worker_st *ws, unsigned http_ver);
int get_cert_names(worker_st * ws, const gnutls_datum_t * raw);
void set_resume_db_funcs(gnutls_session_t);