Skip to content

Commit

Permalink
Merge pull request Mbed-TLS#5426 from gilles-peskine-arm/ssl-get-vers…
Browse files Browse the repository at this point in the history
…ion-3.1

Add accessors to mbedtls_ssl_context: user data, version
ABI-API-checking fails which was expected as this PR adds a new field in mbedtls_ssl_context and mbedtls_ssl_config.
  • Loading branch information
ronald-cron-arm authored Feb 21, 2022
2 parents e3a2dd7 + 57bf02b commit 4579a97
Show file tree
Hide file tree
Showing 8 changed files with 342 additions and 17 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.d/ssl_context-user_data.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Features
* The structures mbedtls_ssl_config and mbedtls_ssl_context now store
a piece of user data which is reserved for the application. The user
data can be either a pointer or an integer.
* Add an accessor function to get the configuration associated with
an SSL context.
3 changes: 3 additions & 0 deletions ChangeLog.d/ssl_context-version_number.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Features
* Add a function to access the protocol version from an SSL context in a
form that's easy to compare. Fixes #5407.
2 changes: 2 additions & 0 deletions ChangeLog.d/ssl_get_version_1_3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Bugfix
* Fix mbedtls_ssl_get_version() not reporting TLSv1.3. Fixes #5406.
249 changes: 237 additions & 12 deletions include/mbedtls/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,14 @@ struct mbedtls_ssl_session
#endif
};

/** Human-friendly representation of the (D)TLS protocol version. */
typedef enum
{
MBEDTLS_SSL_VERSION_UNKNOWN, /*!< Context not in use or version not yet negotiated. */
MBEDTLS_SSL_VERSION_1_2, /*!< (D)TLS 1.2 */
MBEDTLS_SSL_VERSION_1_3, /*!< (D)TLS 1.3 */
} mbedtls_ssl_protocol_version;

/*
* Identifiers for PRFs used in various versions of TLS.
*/
Expand Down Expand Up @@ -1210,6 +1218,18 @@ typedef void mbedtls_ssl_export_keys_t( void *p_expkey,
const unsigned char server_random[32],
mbedtls_tls_prf_types tls_prf_type );

/* A type for storing user data in a library structure.
*
* The representation of type may change in future versions of the library.
* Only the behaviors guaranteed by documented accessor functions are
* guaranteed to remain stable.
*/
typedef union
{
uintptr_t n; /* typically a handle to an associated object */
void *p; /* typically a pointer to extra data */
} mbedtls_ssl_user_data_t;

/**
* SSL/TLS configuration to be shared between mbedtls_ssl_context structures.
*/
Expand Down Expand Up @@ -1448,6 +1468,13 @@ struct mbedtls_ssl_config
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C)
unsigned int MBEDTLS_PRIVATE(dhm_min_bitlen); /*!< min. bit length of the DHM prime */
#endif

/** User data pointer or handle.
*
* The library sets this to \p 0 when creating a context and does not
* access it afterwards.
*/
mbedtls_ssl_user_data_t MBEDTLS_PRIVATE(user_data);
};

struct mbedtls_ssl_context
Expand Down Expand Up @@ -1669,6 +1696,17 @@ struct mbedtls_ssl_context
/** Callback to export key block and master secret */
mbedtls_ssl_export_keys_t *MBEDTLS_PRIVATE(f_export_keys);
void *MBEDTLS_PRIVATE(p_export_keys); /*!< context for key export callback */

/** User data pointer or handle.
*
* The library sets this to \p 0 when creating a context and does not
* access it afterwards.
*
* \warning Serializing and restoring an SSL context with
* mbedtls_ssl_context_save() and mbedtls_ssl_context_load()
* does not currently restore the user data.
*/
mbedtls_ssl_user_data_t MBEDTLS_PRIVATE(user_data);
};

/**
Expand Down Expand Up @@ -1836,6 +1874,22 @@ void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf,
void (*f_dbg)(void *, int, const char *, int, const char *),
void *p_dbg );

/**
* \brief Return the SSL configuration structure associated
* with the given SSL context.
*
* \note The pointer returned by this function is guaranteed to
* remain valid until the context is freed.
*
* \param ssl The SSL context to query.
* \return Pointer to the SSL configuration associated with \p ssl.
*/
static inline const mbedtls_ssl_config *mbedtls_ssl_context_get_config(
const mbedtls_ssl_context *ssl )
{
return( ssl->MBEDTLS_PRIVATE( conf ) );
}

/**
* \brief Set the underlying BIO callbacks for write, read and
* read-with-timeout.
Expand Down Expand Up @@ -2263,6 +2317,132 @@ void mbedtls_ssl_set_export_keys_cb( mbedtls_ssl_context *ssl,
mbedtls_ssl_export_keys_t *f_export_keys,
void *p_export_keys );

/** \brief Set the user data in an SSL configuration to a pointer.
*
* You can retrieve this value later with mbedtls_ssl_conf_get_user_data_p().
*
* \note The library stores \c p without accessing it. It is the responsibility
* of the caller to ensure that the pointer remains valid.
*
* \param conf The SSL configuration context to modify.
* \param p The new value of the user data.
*/
static inline void mbedtls_ssl_conf_set_user_data_p(
mbedtls_ssl_config *conf,
void *p )
{
conf->MBEDTLS_PRIVATE(user_data).p = p;
}

/** \brief Set the user data in an SSL configuration to an integer.
*
* You can retrieve this value later with mbedtls_ssl_conf_get_user_data_n().
*
* \param conf The SSL configuration context to modify.
* \param n The new value of the user data.
*/
static inline void mbedtls_ssl_conf_set_user_data_n(
mbedtls_ssl_config *conf,
uintptr_t n )
{
conf->MBEDTLS_PRIVATE(user_data).n = n;
}

/** \brief Retrieve the user data in an SSL configuration as a pointer.
*
* This is the value last set with mbedtls_ssl_conf_set_user_data_p(), or
* \c NULL if mbedtls_ssl_conf_set_user_data_p() has not previously been
* called. The value is undefined if mbedtls_ssl_conf_set_user_data_n() has
* been called without a subsequent call to mbedtls_ssl_conf_set_user_data_p().
*
* \param conf The SSL configuration context to modify.
* \return The current value of the user data.
*/
static inline void *mbedtls_ssl_conf_get_user_data_p(
mbedtls_ssl_config *conf )
{
return( conf->MBEDTLS_PRIVATE(user_data).p );
}

/** \brief Retrieve the user data in an SSL configuration as an integer.
*
* This is the value last set with mbedtls_ssl_conf_set_user_data_n(), or
* \c 0 if mbedtls_ssl_conf_set_user_data_n() has not previously been
* called. The value is undefined if mbedtls_ssl_conf_set_user_data_p() has
* been called without a subsequent call to mbedtls_ssl_conf_set_user_data_n().
*
* \param conf The SSL configuration context to modify.
* \return The current value of the user data.
*/
static inline uintptr_t mbedtls_ssl_conf_get_user_data_n(
mbedtls_ssl_config *conf )
{
return( conf->MBEDTLS_PRIVATE(user_data).n );
}

/** \brief Set the user data in an SSL context to a pointer.
*
* You can retrieve this value later with mbedtls_ssl_get_user_data_p().
*
* \note The library stores \c p without accessing it. It is the responsibility
* of the caller to ensure that the pointer remains valid.
*
* \param ssl The SSL context context to modify.
* \param p The new value of the user data.
*/
static inline void mbedtls_ssl_set_user_data_p(
mbedtls_ssl_context *ssl,
void *p )
{
ssl->MBEDTLS_PRIVATE(user_data).p = p;
}

/** \brief Set the user data in an SSL context to an integer.
*
* You can retrieve this value later with mbedtls_ssl_get_user_data_n().
*
* \param ssl The SSL context context to modify.
* \param n The new value of the user data.
*/
static inline void mbedtls_ssl_set_user_data_n(
mbedtls_ssl_context *ssl,
uintptr_t n )
{
ssl->MBEDTLS_PRIVATE(user_data).n = n;
}

/** \brief Retrieve the user data in an SSL context as a pointer.
*
* This is the value last set with mbedtls_ssl_set_user_data_p(), or
* \c NULL if mbedtls_ssl_set_user_data_p() has not previously been
* called. The value is undefined if mbedtls_ssl_set_user_data_n() has
* been called without a subsequent call to mbedtls_ssl_set_user_data_p().
*
* \param ssl The SSL context context to modify.
* \return The current value of the user data.
*/
static inline void *mbedtls_ssl_get_user_data_p(
mbedtls_ssl_context *ssl )
{
return( ssl->MBEDTLS_PRIVATE(user_data).p );
}

/** \brief Retrieve the user data in an SSL context as an integer.
*
* This is the value last set with mbedtls_ssl_set_user_data_n(), or
* \c 0 if mbedtls_ssl_set_user_data_n() has not previously been
* called. The value is undefined if mbedtls_ssl_set_user_data_p() has
* been called without a subsequent call to mbedtls_ssl_set_user_data_n().
*
* \param ssl The SSL context context to modify.
* \return The current value of the user data.
*/
static inline uintptr_t mbedtls_ssl_get_user_data_n(
mbedtls_ssl_context *ssl )
{
return( ssl->MBEDTLS_PRIVATE(user_data).n );
}

#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
/**
* \brief Configure asynchronous private key operation callbacks.
Expand Down Expand Up @@ -3558,31 +3738,50 @@ void mbedtls_ssl_get_dtls_srtp_negotiation_result( const mbedtls_ssl_context *ss

/**
* \brief Set the maximum supported version sent from the client side
* and/or accepted at the server side
* (Default: MBEDTLS_SSL_MAX_MAJOR_VERSION, MBEDTLS_SSL_MAX_MINOR_VERSION)
* and/or accepted at the server side.
*
* \note This ignores ciphersuites from higher versions.
* See also the documentation of mbedtls_ssl_conf_min_version().
*
* \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
* \note This ignores ciphersuites from higher versions.
*
* \param conf SSL configuration
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
* \param minor Minor version number (only MBEDTLS_SSL_MINOR_VERSION_3 supported)
* \param major Major version number (#MBEDTLS_SSL_MAJOR_VERSION_3)
* \param minor Minor version number
* (#MBEDTLS_SSL_MINOR_VERSION_3 for (D)TLS 1.2,
* #MBEDTLS_SSL_MINOR_VERSION_4 for TLS 1.3)
*/
void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor );

/**
* \brief Set the minimum accepted SSL/TLS protocol version
* (Default: TLS 1.2)
*
* \note By default, all supported versions are accepted.
* Future versions of the library may disable older
* protocol versions by default if they become deprecated.
*
* \note The following versions are supported (if enabled at
* compile time):
* - (D)TLS 1.2: \p major = #MBEDTLS_SSL_MAJOR_VERSION_3,
* \p minor = #MBEDTLS_SSL_MINOR_VERSION_3
* - TLS 1.3: \p major = #MBEDTLS_SSL_MAJOR_VERSION_3,
* \p minor = #MBEDTLS_SSL_MINOR_VERSION_4
*
* Note that the numbers in the constant names are the
* TLS internal protocol numbers, and the minor versions
* differ by one from the human-readable versions!
*
* \note Input outside of the SSL_MAX_XXXXX_VERSION and
* SSL_MIN_XXXXX_VERSION range is ignored.
*
* \note With DTLS, use MBEDTLS_SSL_MINOR_VERSION_3 for DTLS 1.2
* \note After the handshake, you can call
* mbedtls_ssl_get_version_number() to see what version was
* negotiated.
*
* \param conf SSL configuration
* \param major Major version number (only MBEDTLS_SSL_MAJOR_VERSION_3 supported)
* \param minor Minor version number (only MBEDTLS_SSL_MINOR_VERSION_3 supported)
* \param major Major version number (#MBEDTLS_SSL_MAJOR_VERSION_3)
* \param minor Minor version number
* (#MBEDTLS_SSL_MINOR_VERSION_3 for (D)TLS 1.2,
* #MBEDTLS_SSL_MINOR_VERSION_4 for TLS 1.3)
*/
void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor );

Expand Down Expand Up @@ -3903,6 +4102,21 @@ int mbedtls_ssl_get_ciphersuite_id_from_ssl( const mbedtls_ssl_context *ssl );
*/
const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl );


/**
* \brief Return the (D)TLS protocol version negotiated in the
* given connection.
*
* \note If you call this function too early during the initial
* handshake, before the two sides have agreed on a version,
* this function returns #MBEDTLS_SSL_VERSION_UNKNOWN.
*
* \param ssl The SSL context to query.
* \return The negotiated protocol version.
*/
mbedtls_ssl_protocol_version mbedtls_ssl_get_version_number(
const mbedtls_ssl_context *ssl );

/**
* \brief Return the current TLS version
*
Expand Down Expand Up @@ -4334,6 +4548,14 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl );
*
* \see mbedtls_ssl_context_load()
*
* \note The serialized data only contains the data that is
* necessary to resume the connection: negotiated protocol
* options, session identifier, keys, etc.
* Loading a saved SSL context does not restore settings and
* state related to how the application accesses the context,
* such as configured callback functions, user data, pending
* incoming or outgoing data, etc.
*
* \note This feature is currently only available under certain
* conditions, see the documentation of the return value
* #MBEDTLS_ERR_SSL_BAD_INPUT_DATA for details.
Expand Down Expand Up @@ -4412,8 +4634,11 @@ int mbedtls_ssl_context_save( mbedtls_ssl_context *ssl,
* (unless they were already set before calling
* mbedtls_ssl_session_reset() and the values are suitable for
* the present connection). Specifically, you want to call
* at least mbedtls_ssl_set_bio() and
* mbedtls_ssl_set_timer_cb(). All other SSL setter functions
* at least mbedtls_ssl_set_bio(),
* mbedtls_ssl_set_timer_cb(), and
* mbedtls_ssl_set_user_data_n() or
* mbedtls_ssl_set_user_data_p() if they were set originally.
* All other SSL setter functions
* are not necessary to call, either because they're only used
* in handshakes, or because the setting is already saved. You
* might choose to call them anyway, for example in order to
Expand Down
2 changes: 2 additions & 0 deletions library/ssl_debug_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@

const char *mbedtls_ssl_states_str( mbedtls_ssl_states in );

const char *mbedtls_ssl_protocol_version_str( mbedtls_ssl_protocol_version in );

const char *mbedtls_tls_prf_types_str( mbedtls_tls_prf_types in );

const char *mbedtls_ssl_key_export_type_str( mbedtls_ssl_key_export_type in );
Expand Down
18 changes: 17 additions & 1 deletion library/ssl_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,21 @@ const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl )
return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite );
}

mbedtls_ssl_protocol_version mbedtls_ssl_get_version_number(
const mbedtls_ssl_context *ssl )
{
/* For major_ver, only 3 is supported, so skip checking it. */
switch( ssl->minor_ver )
{
case MBEDTLS_SSL_MINOR_VERSION_3:
return( MBEDTLS_SSL_VERSION_1_2 );
case MBEDTLS_SSL_MINOR_VERSION_4:
return( MBEDTLS_SSL_VERSION_1_3 );
default:
return( MBEDTLS_SSL_VERSION_UNKNOWN );
}
}

const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
Expand All @@ -2226,7 +2241,8 @@ const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
{
case MBEDTLS_SSL_MINOR_VERSION_3:
return( "TLSv1.2" );

case MBEDTLS_SSL_MINOR_VERSION_4:
return( "TLSv1.3" );
default:
return( "unknown" );
}
Expand Down
Loading

0 comments on commit 4579a97

Please sign in to comment.