diff options
Diffstat (limited to 'lib/ext/client_cert_type.c')
-rw-r--r-- | lib/ext/client_cert_type.c | 176 |
1 files changed, 96 insertions, 80 deletions
diff --git a/lib/ext/client_cert_type.c b/lib/ext/client_cert_type.c index 261b56c800..772f9da640 100644 --- a/lib/ext/client_cert_type.c +++ b/lib/ext/client_cert_type.c @@ -36,13 +36,11 @@ #include "state.h" #include "datum.h" - static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, - const uint8_t* data, + const uint8_t * data, size_t data_size); static int _gnutls_client_cert_type_send_params(gnutls_session_t session, - gnutls_buffer_st* data); - + gnutls_buffer_st * data); const hello_ext_entry_st ext_mod_client_cert_type = { .name = "Client Certificate Type", @@ -51,10 +49,9 @@ const hello_ext_entry_st ext_mod_client_cert_type = { .client_parse_point = GNUTLS_EXT_TLS, .server_parse_point = GNUTLS_EXT_TLS, .validity = GNUTLS_EXT_FLAG_TLS | - GNUTLS_EXT_FLAG_DTLS | - GNUTLS_EXT_FLAG_CLIENT_HELLO | - GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO | - GNUTLS_EXT_FLAG_EE, + GNUTLS_EXT_FLAG_DTLS | + GNUTLS_EXT_FLAG_CLIENT_HELLO | + GNUTLS_EXT_FLAG_TLS12_SERVER_HELLO | GNUTLS_EXT_FLAG_EE, .recv_func = _gnutls_client_cert_type_recv_params, .send_func = _gnutls_client_cert_type_send_params, .pack_func = _gnutls_hello_ext_default_pack, @@ -63,31 +60,31 @@ const hello_ext_entry_st ext_mod_client_cert_type = { .cannot_be_overriden = 1 }; - static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, - const uint8_t* data, + const uint8_t * data, size_t data_size) { int ret; gnutls_certificate_type_t cert_type; size_t i; bool found = false; - const uint8_t* pdata = data; + const uint8_t *pdata = data; /* Only activate this extension if we have cert credentials set * and alternative cert types are allowed */ if (!are_alternative_cert_types_allowed(session) || - (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)) + (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)) return 0; if (!IS_SERVER(session)) { // client mode - gnutls_datum_t sent_cert_types; // Holds the previously sent cert types + gnutls_datum_t sent_cert_types; // Holds the previously sent cert types /* Compare packet length with expected packet length. For the * client this is a single byte. */ if (data_size != 1) { return - gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + gnutls_assert_val + (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); } /* The server picked one of the offered cert types if he supports @@ -98,36 +95,40 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, * to check it nevertheless. */ cert_type = IANA2cert_type(pdata[0]); - _gnutls_handshake_log("EXT[%p]: Received a %s client certificate type confirmation from the server.\n", - session, gnutls_certificate_type_get_name(cert_type)); + _gnutls_handshake_log + ("EXT[%p]: Received a %s client certificate type confirmation from the server.\n", + session, gnutls_certificate_type_get_name(cert_type)); // Check validity of cert type if (cert_type == GNUTLS_CRT_UNKNOWN) { - return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE); + return + gnutls_assert_val + (GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE); } /* Get the cert types that we sent to the server (they were stored * in IANA representation. */ ret = _gnutls_hello_ext_get_datum(session, - GNUTLS_EXTENSION_CLIENT_CERT_TYPE, - &sent_cert_types); + GNUTLS_EXTENSION_CLIENT_CERT_TYPE, + &sent_cert_types); if (ret < 0) { /* This should not happen and indicate a memory corruption! * Assertion are always on in production code so execution * will halt here. */ assert(false); } - // Check whether what we got back is actually offered by us for (i = 0; i < sent_cert_types.size; i++) { - if (IANA2cert_type(sent_cert_types.data[i]) == cert_type) + if (IANA2cert_type(sent_cert_types.data[i]) == + cert_type) found = true; } if (found) { // Everything OK, now set the client certificate type - _gnutls_session_client_cert_type_set(session, cert_type); + _gnutls_session_client_cert_type_set(session, + cert_type); ret = GNUTLS_E_SUCCESS; } else { // No valid cert type found @@ -136,25 +137,26 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, return ret; - } else { // server mode - gnutls_datum_t cert_types; // Holds the received cert types + } else { // server mode + gnutls_datum_t cert_types; // Holds the received cert types // Compare packet length with expected packet length. DECR_LEN(data_size, 1); if (data[0] != data_size) { return - gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); + gnutls_assert_val + (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); } pdata += 1; // Assign the contents of our data buffer to a gnutls_datum_t - cert_types.data = (uint8_t*)pdata; // Need casting to get rid of 'discards const qualifier' warning + cert_types.data = (uint8_t *) pdata; // Need casting to get rid of 'discards const qualifier' warning cert_types.size = data_size; // Store the client certificate types in our session _gnutls_hello_ext_set_datum(session, - GNUTLS_EXTENSION_CLIENT_CERT_TYPE, - &cert_types); + GNUTLS_EXTENSION_CLIENT_CERT_TYPE, + &cert_types); /* We receive a list of supported certificate types that the client * is able to provide when requested via a client certificate @@ -170,11 +172,15 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, if (cert_type == GNUTLS_CRT_UNKNOWN) continue; - _gnutls_handshake_log("EXT[%p]: Checking compatibility of a %s client certificate type that was received from the client.\n", - session, gnutls_certificate_type_get_name(cert_type)); + _gnutls_handshake_log + ("EXT[%p]: Checking compatibility of a %s client certificate type that was received from the client.\n", + session, + gnutls_certificate_type_get_name(cert_type)); // Check for support of this cert type - if (_gnutls_session_is_cert_type_supported(session, cert_type, false, GNUTLS_CTYPE_CLIENT) == 0) { + if (_gnutls_session_is_cert_type_supported + (session, cert_type, false, + GNUTLS_CTYPE_CLIENT) == 0) { found = true; break; } @@ -182,7 +188,8 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, // We found a matching ctype, we pick this one if (found) { - _gnutls_session_client_cert_type_set(session, cert_type); + _gnutls_session_client_cert_type_set(session, + cert_type); ret = GNUTLS_E_SUCCESS; } else { /* If no supported certificate type can be found we terminate @@ -190,8 +197,8 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, * (according to specification rfc7250). */ _gnutls_handshake_log - ("EXT[%p]: No supported client certificate type was found. " - "Aborting connection.\n", session); + ("EXT[%p]: No supported client certificate type was found. " + "Aborting connection.\n", session); ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } @@ -200,27 +207,26 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, } static int _gnutls_client_cert_type_send_params(gnutls_session_t session, - gnutls_buffer_st* data) + gnutls_buffer_st * data) { int ret; - uint8_t cert_type_IANA; // Holds an IANA cert type ID + uint8_t cert_type_IANA; // Holds an IANA cert type ID gnutls_certificate_type_t cert_type; /* Only activate this extension if we have cert credentials set * and alternative cert types are allowed */ if (!are_alternative_cert_types_allowed(session) || - (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)) + (_gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL)) return 0; if (!IS_SERVER(session)) { // Client mode - uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported (IANA) cert types. Inv: 0 <= cert type Id < 256 + uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported (IANA) cert types. Inv: 0 <= cert type Id < 256 size_t i, num_cert_types = 0; - priority_st* cert_priorities; - gnutls_datum_t tmp_cert_types; // For type conversion + priority_st *cert_priorities; + gnutls_datum_t tmp_cert_types; // For type conversion // For brevity - cert_priorities = - &session->internals.priorities->client_ctype; + cert_priorities = &session->internals.priorities->client_ctype; /* Retrieve client certificate type priorities if any. If no * priorities are set then the default client certificate type @@ -235,12 +241,14 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, * types. */ if (cert_priorities->num_priorities == 1 && - cert_priorities->priorities[0] == DEFAULT_CERT_TYPE) { + cert_priorities->priorities[0] == + DEFAULT_CERT_TYPE) { _gnutls_handshake_log - ("EXT[%p]: Client certificate type was set to default cert type (%s). " - "We therefore do not send this extension.\n", - session, - gnutls_certificate_type_get_name(DEFAULT_CERT_TYPE)); + ("EXT[%p]: Client certificate type was set to default cert type (%s). " + "We therefore do not send this extension.\n", + session, + gnutls_certificate_type_get_name + (DEFAULT_CERT_TYPE)); // Explicitly set but default ctype, so don't send anything return 0; @@ -253,14 +261,17 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, for (i = 0; i < cert_priorities->num_priorities; i++) { cert_type = cert_priorities->priorities[i]; - if (_gnutls_session_is_cert_type_supported(session, cert_type, - true, GNUTLS_CTYPE_CLIENT) == 0) { + if (_gnutls_session_is_cert_type_supported + (session, cert_type, true, + GNUTLS_CTYPE_CLIENT) == 0) { /* Check whether we are allowed to store another cert type * in our buffer. In other words, prevent a possible buffer * overflow. This situation can occur when a user sets * duplicate cert types in the priority strings. */ if (num_cert_types >= GNUTLS_CRT_MAX) - return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + return + gnutls_assert_val + (GNUTLS_E_SHORT_MEMORY_BUFFER); // Convert to IANA representation ret = cert_type2IANA(cert_type); @@ -268,17 +279,18 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, if (ret < 0) return gnutls_assert_val(ret); - cert_type_IANA = ret; // For readability + cert_type_IANA = ret; // For readability // Add this cert type to our list with supported types - cert_types[num_cert_types] = cert_type_IANA; + cert_types[num_cert_types] = + cert_type_IANA; num_cert_types++; _gnutls_handshake_log - ("EXT[%p]: Client certificate type %s (%d) was queued.\n", - session, - gnutls_certificate_type_get_name(cert_type), - cert_type_IANA); + ("EXT[%p]: Client certificate type %s (%d) was queued.\n", + session, + gnutls_certificate_type_get_name + (cert_type), cert_type_IANA); } } @@ -289,19 +301,21 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, */ if (num_cert_types == 0) { _gnutls_handshake_log - ("EXT[%p]: Client certificate types were set but none of them is supported. " - "You might want to check your credentials or your priorities. " - "We do not send this extension.\n", - session); + ("EXT[%p]: Client certificate types were set but none of them is supported. " + "You might want to check your credentials or your priorities. " + "We do not send this extension.\n", + session); return 0; } else if (num_cert_types == 1 && - IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) { + IANA2cert_type(cert_types[0]) == + DEFAULT_CERT_TYPE) { _gnutls_handshake_log - ("EXT[%p]: The only supported client certificate type is (%s) which is the default. " - "We therefore do not send this extension.\n", - session, - gnutls_certificate_type_get_name(DEFAULT_CERT_TYPE)); + ("EXT[%p]: The only supported client certificate type is (%s) which is the default. " + "We therefore do not send this extension.\n", + session, + gnutls_certificate_type_get_name + (DEFAULT_CERT_TYPE)); return 0; } @@ -314,16 +328,16 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, tmp_cert_types.size = num_cert_types; _gnutls_hello_ext_set_datum(session, - GNUTLS_EXTENSION_CLIENT_CERT_TYPE, - &tmp_cert_types); + GNUTLS_EXTENSION_CLIENT_CERT_TYPE, + &tmp_cert_types); /* Serialize the certificate types into a sequence of octets * uint8: length of sequence of cert types (1 octet) * uint8: cert types (0 <= #octets <= 255) */ ret = _gnutls_buffer_append_data_prefix(data, 8, - cert_types, - num_cert_types); + cert_types, + num_cert_types); // Check for errors if (ret < 0) { @@ -333,8 +347,8 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, return num_cert_types + 1; } } - } else { // Server mode - const version_entry_st* vers = get_version(session); + } else { // Server mode + const version_entry_st *vers = get_version(session); /* TLS 1.2: * Check whether we are going to send a certificate request, * otherwise omit the response. This is conform spec. @@ -347,8 +361,7 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, * complete the certificate type negotiation and therefore respond * with a cert type message. */ - if (session->internals.send_cert_req != 0 || - vers->tls13_sem) { + if (session->internals.send_cert_req != 0 || vers->tls13_sem) { /* Retrieve negotiated client certificate type and send it to * the client. * The scenario where we want to send a certificate request but @@ -357,23 +370,27 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, * when we cannot find a matching client certificate. This is conform * spec (RFC7250, 4.2 case 2.). */ - cert_type = get_certificate_type(session, GNUTLS_CTYPE_CLIENT); + cert_type = + get_certificate_type(session, GNUTLS_CTYPE_CLIENT); ret = cert_type2IANA(cert_type); if (ret < 0) return gnutls_assert_val(ret); - cert_type_IANA = ret; // For readability + cert_type_IANA = ret; // For readability - _gnutls_handshake_log("EXT[%p]: Confirming to use a %s client certificate type.\n", - session, gnutls_certificate_type_get_name(cert_type)); + _gnutls_handshake_log + ("EXT[%p]: Confirming to use a %s client certificate type.\n", + session, + gnutls_certificate_type_get_name(cert_type)); - ret = gnutls_buffer_append_data(data, &cert_type_IANA, 1); + ret = + gnutls_buffer_append_data(data, &cert_type_IANA, 1); if (ret < 0) return gnutls_assert_val(ret); - return 1; // sent one byte + return 1; // sent one byte } } @@ -381,7 +398,6 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, return 0; } - /** Extension interface **/ /* The interface is defined in state.c: |