diff options
Diffstat (limited to 'lib/ext')
-rw-r--r-- | lib/ext/cert_types.h | 37 | ||||
-rw-r--r-- | lib/ext/client_cert_type.c | 48 | ||||
-rw-r--r-- | lib/ext/server_cert_type.c | 48 |
3 files changed, 93 insertions, 40 deletions
diff --git a/lib/ext/cert_types.h b/lib/ext/cert_types.h index c54e0f2bfe..04e024d5db 100644 --- a/lib/ext/cert_types.h +++ b/lib/ext/cert_types.h @@ -26,11 +26,13 @@ /* Maps IANA TLS Certificate Types identifiers to internal * certificate type representation. */ -static inline gnutls_certificate_type_t _gnutls_IANA2cert_type(int num) +static inline gnutls_certificate_type_t IANA2cert_type(int num) { switch (num) { case 0: return GNUTLS_CRT_X509; + case 2: + return GNUTLS_CRT_RAWPK; default: return GNUTLS_CRT_UNKNOWN; } @@ -39,12 +41,43 @@ static inline gnutls_certificate_type_t _gnutls_IANA2cert_type(int num) /* Maps internal certificate type representation to * IANA TLS Certificate Types identifiers. */ -static inline int _gnutls_cert_type2IANA(gnutls_certificate_type_t cert_type) +static inline int cert_type2IANA(gnutls_certificate_type_t cert_type) { switch (cert_type) { case GNUTLS_CRT_X509: return 0; + case GNUTLS_CRT_RAWPK: + return 2; default: return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } } + +/* Checks whether the given cert type is enabled in the application + */ +static inline bool is_cert_type_enabled(gnutls_session_t session, gnutls_certificate_type_t cert_type) +{ + switch(cert_type) { + case GNUTLS_CRT_X509: + // Default cert type, always enabled + return true; + case GNUTLS_CRT_RAWPK: + return session->internals.flags & GNUTLS_ENABLE_RAWPK; + default: + // When not explicitly supported here disable it + return false; + } +} + +/* Checks whether alternative cert types (i.e. other than X.509) + * are enabled in the application + */ +static inline bool are_alternative_cert_types_allowed(gnutls_session_t session) +{ + // OR-ed list of defined cert type init flags + #define CERT_TYPES_FLAGS GNUTLS_ENABLE_RAWPK + + return session->internals.flags & CERT_TYPES_FLAGS; + + #undef CERT_TYPES_FLAGS +} diff --git a/lib/ext/client_cert_type.c b/lib/ext/client_cert_type.c index 5449eae678..534c407b3a 100644 --- a/lib/ext/client_cert_type.c +++ b/lib/ext/client_cert_type.c @@ -33,8 +33,8 @@ #include "hello_ext.h" #include "hello_ext_lib.h" #include "errors.h" -#include <state.h> -#include <datum.h> +#include "state.h" +#include "datum.h" static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, @@ -76,10 +76,10 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, ssize_t len = data_size; const uint8_t* pdata = data; - /* Only activate this extension if cert type negotiation is enabled - * and we have cert credentials set */ - if (!_gnutls_has_negotiate_ctypes(session) || - _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL) + /* 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)) return 0; if (!IS_SERVER(session)) { // client mode @@ -97,7 +97,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, * receive a cert type that we offered, i.e. one that we support. * Because the world isn't as beautiful as it may seem, we're going * to check it nevertheless. */ - cert_type = _gnutls_IANA2cert_type(pdata[0]); + cert_type = IANA2cert_type(pdata[0]); // Check validity of cert type if (cert_type == GNUTLS_CRT_UNKNOWN) { @@ -119,7 +119,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, // Check whether what we got back is actually offered by us for (i = 0; i < sent_cert_types.size; i++) { - if (_gnutls_IANA2cert_type(sent_cert_types.data[i]) == cert_type) + if (IANA2cert_type(sent_cert_types.data[i]) == cert_type) found = 1; } @@ -160,7 +160,7 @@ static int _gnutls_client_cert_type_recv_params(gnutls_session_t session, */ for (i = 0; i < cert_types.size; i++) { // Convert to internal representation - cert_type = _gnutls_IANA2cert_type(cert_types.data[i]); + cert_type = IANA2cert_type(cert_types.data[i]); // If we have an invalid cert id then continue to the next if (cert_type == GNUTLS_CRT_UNKNOWN) @@ -201,13 +201,13 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, uint8_t i = 0, num_cert_types = 0; priority_st* cert_priorities; gnutls_datum_t tmp_cert_types; // For type conversion - uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types + uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types. Inv: 0 <= cert type Id < 256 const version_entry_st* vers = get_version(session); - /* Only activate this extension if cert type negotiation is enabled - * and we have cert credentials set */ - if (!_gnutls_has_negotiate_ctypes(session) || - _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL) + /* 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)) return 0; if (!IS_SERVER(session)) { // Client mode @@ -255,7 +255,13 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); // Convert to IANA representation - cert_type = _gnutls_cert_type2IANA(cert_priorities->priorities[i]); + ret = cert_type2IANA(cert_priorities->priorities[i]); + + if (ret < 0) + return gnutls_assert_val(ret); + + cert_type = ret; // For readability + // Add this cert type to our list with supported types cert_types[num_cert_types] = cert_type; num_cert_types++; @@ -282,7 +288,7 @@ static int _gnutls_client_cert_type_send_params(gnutls_session_t session, return 0; } else if (num_cert_types == 1 && - _gnutls_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", @@ -342,9 +348,13 @@ 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 = - _gnutls_cert_type2IANA(session-> - security_parameters.client_ctype); + ret = cert_type2IANA(get_certificate_type( + session, GNUTLS_CTYPE_CLIENT)); + + if (ret < 0) + return gnutls_assert_val(ret); + + cert_type = ret; // For readability ret = gnutls_buffer_append_data(data, &cert_type, 1); diff --git a/lib/ext/server_cert_type.c b/lib/ext/server_cert_type.c index a00a0376c9..35c6d751db 100644 --- a/lib/ext/server_cert_type.c +++ b/lib/ext/server_cert_type.c @@ -33,8 +33,8 @@ #include "hello_ext.h" #include "hello_ext_lib.h" #include "errors.h" -#include <state.h> -#include <datum.h> +#include "state.h" +#include "datum.h" static int _gnutls_server_cert_type_recv_params(gnutls_session_t session, @@ -76,10 +76,10 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session, ssize_t len = data_size; const uint8_t* pdata = data; - /* Only activate this extension if cert type negotiation is enabled - * and we have cert credentials set */ - if (!_gnutls_has_negotiate_ctypes(session) || - _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL) + /* 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)) return 0; if (!IS_SERVER(session)) { // client mode @@ -96,7 +96,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session, * may only receive a cert type that we offered, i.e. one that we * support. Because the world isn't as beautiful as it may seem, * we're going to check it nevertheless. */ - cert_type = _gnutls_IANA2cert_type(pdata[0]); + cert_type = IANA2cert_type(pdata[0]); // Check validity of cert type if (cert_type == GNUTLS_CRT_UNKNOWN) { @@ -118,7 +118,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session, // Check whether what we got back is actually offered by us for (i = 0; i < sent_cert_types.size; i++) { - if (_gnutls_IANA2cert_type(sent_cert_types.data[i]) == cert_type) + if (IANA2cert_type(sent_cert_types.data[i]) == cert_type) found = 1; } @@ -159,7 +159,7 @@ static int _gnutls_server_cert_type_recv_params(gnutls_session_t session, */ for (i = 0; i < cert_types.size; i++) { // Convert to internal representation - cert_type = _gnutls_IANA2cert_type(cert_types.data[i]); + cert_type = IANA2cert_type(cert_types.data[i]); // If we have an invalid cert id then continue to the next if (cert_type == GNUTLS_CRT_UNKNOWN) @@ -197,12 +197,12 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session, uint8_t i = 0, num_cert_types = 0; priority_st* cert_priorities; gnutls_datum_t tmp_cert_types; // For type conversion - uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types + uint8_t cert_types[GNUTLS_CRT_MAX]; // The list with supported cert types. Inv: 0 <= cert type Id < 256 - /* Only activate this extension if cert type negotiation is enabled - * and we have cert credentials set */ - if (!_gnutls_has_negotiate_ctypes(session) || - _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE) == NULL) + /* 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)) return 0; if (!IS_SERVER(session)) { // Client mode @@ -255,7 +255,13 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session, return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); // Convert to IANA representation - cert_type = _gnutls_cert_type2IANA(cert_priorities->priorities[i]); + ret = cert_type2IANA(cert_priorities->priorities[i]); + + if (ret < 0) + return gnutls_assert_val(ret); + + cert_type = ret; // For readability + // Add this cert type to our list with supported types cert_types[num_cert_types] = cert_type; num_cert_types++; @@ -281,7 +287,7 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session, return 0; } else if (num_cert_types == 1 && - _gnutls_IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) { + IANA2cert_type(cert_types[0]) == DEFAULT_CERT_TYPE) { _gnutls_handshake_log ("EXT[%p]: The only supported server certificate type is (%s) which is the default. " "We therefore do not send this extension.\n", @@ -320,9 +326,13 @@ static int _gnutls_server_cert_type_send_params(gnutls_session_t session, } } else { // Server mode // Retrieve negotiated server certificate type and send it - cert_type = - _gnutls_cert_type2IANA(session->security_parameters. - server_ctype); + ret = cert_type2IANA(get_certificate_type( + session, GNUTLS_CTYPE_SERVER)); + + if (ret < 0) + return gnutls_assert_val(ret); + + cert_type = ret; // For readability ret = gnutls_buffer_append_data(data, &cert_type, 1); |