Merge remote-tracking branch 'public/pr/2421' into development

* public/pr/2421: (68 commits)
  Fix unused variable warning in ssl_parse_certificate_coordinate()
  Add missing compile time guard in ssl_client2
  Update programs/ssl/query_config.c
  ssl_client2: Reset peer CRT info string on reconnect
  Add further debug statements on assertion failures
  Fix typo in documentation of ssl_parse_certificate_chain()
  Add debug output in case of assertion failure
  Fix typo in SSL ticket documentation
  Add config sanity check for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
  ssl_client2: Zeroize peer CRT info buffer when reconnecting
  Reintroduce numerous ssl-opt.sh tests if !MBEDTLS_SSL_KEEP_PEER_CERT
  ssl_client2: Extract peer CRT info from verification callback
  Improve documentation of mbedtls_ssl_get_peer_cert()
  Improve documentation of MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
  Fix indentation of Doxygen comment in ssl_internal.h
  Set peer CRT length only after successful allocation
  Remove question in comment about verify flags on cli vs. server
  Remove misleading and redundant guard around restartable ECC field
  Add test for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE to all.sh
  Free peer CRT chain immediately after verifying it
  ...
This commit is contained in:
Simon Butcher 2019-03-01 12:46:07 +00:00
commit 535ee4a35b
19 changed files with 901 additions and 452 deletions

View file

@ -16,6 +16,13 @@ Features
API Changes
* Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`.
See the Features section for more information.
* Allow to opt in to the removal the API mbedtls_ssl_get_peer_cert()
for the benefit of saving RAM, by disabling the new compile-time
option MBEDTLS_SSL_KEEP_PEER_CERTIFICATE (enabled by default for
API stability). Disabling this option makes mbedtls_ssl_get_peer_cert()
always return NULL, and removes the peer_cert field from the
mbedtls_ssl_session structure which otherwise stores the peer's
certificate.
Bugfix
* Fix a compilation issue with mbedtls_ecp_restart_ctx not being defined

View file

@ -280,6 +280,14 @@
#error "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
( !defined(MBEDTLS_SHA256_C) && \
!defined(MBEDTLS_SHA512_C) && \
!defined(MBEDTLS_SHA1_C) )
#error "!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE requires MBEDTLS_SHA512_C, MBEDTLS_SHA256_C or MBEDTLS_SHA1_C"
#endif
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) && \
( !defined(MBEDTLS_PLATFORM_C) || !defined(MBEDTLS_PLATFORM_MEMORY) )
#error "MBEDTLS_MEMORY_BUFFER_ALLOC_C defined, but not all prerequisites"

View file

@ -1374,6 +1374,28 @@
*/
#define MBEDTLS_SSL_FALLBACK_SCSV
/**
* \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
*
* This option controls the availability of the API mbedtls_ssl_get_peer_cert()
* giving access to the peer's certificate after completion of the handshake.
*
* Unless you need mbedtls_ssl_peer_cert() in your application, it is
* recommended to disable this option for reduced RAM usage.
*
* \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still
* defined, but always returns \c NULL.
*
* \note This option has no influence on the protection against the
* triple handshake attack. Even if it is disabled, Mbed TLS will
* still ensure that certificates do not change during renegotiation,
* for exaple by keeping a hash of the peer's certificate.
*
* Comment this macro to disable storing the peer's certificate
* after the handshake.
*/
#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
/**
* \def MBEDTLS_SSL_HW_RECORD_ACCEL
*

View file

@ -787,6 +787,25 @@ typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) && \
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
#define MBEDTLS_SSL_PEER_CERT_DIGEST_MAX_LEN 48
#if defined(MBEDTLS_SHA256_C)
#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA256
#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 32
#elif defined(MBEDTLS_SHA512_C)
#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA384
#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 48
#elif defined(MBEDTLS_SHA1_C)
#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_TYPE MBEDTLS_MD_SHA1
#define MBEDTLS_SSL_PEER_CERT_DIGEST_DFL_LEN 20
#else
/* This is already checked in check_config.h, but be sure. */
#error "Bad configuration - need SHA-1, SHA-256 or SHA-512 enabled to compute digest of peer CRT."
#endif
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED &&
!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* This structure is used for storing current session data.
*/
@ -802,7 +821,15 @@ struct mbedtls_ssl_session
unsigned char master[48]; /*!< the master secret */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_x509_crt *peer_cert; /*!< peer X.509 cert chain */
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*! The digest of the peer's end-CRT. This must be kept to detect CRT
* changes during renegotiation, mitigating the triple handshake attack. */
unsigned char *peer_cert_digest;
size_t peer_cert_digest_len;
mbedtls_md_type_t peer_cert_digest_type;
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
uint32_t verify_result; /*!< verification result */
@ -2972,18 +2999,34 @@ int mbedtls_ssl_get_max_out_record_payload( const mbedtls_ssl_context *ssl );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
/**
* \brief Return the peer certificate from the current connection
* \brief Return the peer certificate from the current connection.
*
* Note: Can be NULL in case no certificate was sent during
* the handshake. Different calls for the same connection can
* return the same or different pointers for the same
* certificate and even a different certificate altogether.
* The peer cert CAN change in a single connection if
* renegotiation is performed.
* \param ssl The SSL context to use. This must be initialized and setup.
*
* \param ssl SSL context
* \return The current peer certificate, if available.
* The returned certificate is owned by the SSL context and
* is valid only until the next call to the SSL API.
* \return \c NULL if no peer certificate is available. This might
* be because the chosen ciphersuite doesn't use CRTs
* (PSK-based ciphersuites, for example), or because
* #MBEDTLS_SSL_KEEP_PEER_CERTIFICATE has been disabled,
* allowing the stack to free the peer's CRT to save memory.
*
* \return the current peer certificate
* \note For one-time inspection of the peer's certificate during
* the handshake, consider registering an X.509 CRT verification
* callback through mbedtls_ssl_conf_verify() instead of calling
* this function. Using mbedtls_ssl_conf_verify() also comes at
* the benefit of allowing you to influence the verification
* process, for example by masking expected and tolerated
* verification failures.
*
* \warning You must not use the pointer returned by this function
* after any further call to the SSL API, including
* mbedtls_ssl_read() and mbedtls_ssl_write(); this is
* because the pointer might change during renegotiation,
* which happens transparently to the user.
* If you want to use the certificate across API calls,
* you must make a copy.
*/
const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl );
#endif /* MBEDTLS_X509_CRT_PARSE_C */

View file

@ -70,7 +70,8 @@ struct mbedtls_ssl_cache_entry
mbedtls_time_t timestamp; /*!< entry timestamp */
#endif
mbedtls_ssl_session session; /*!< entry session */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_x509_buf peer_cert; /*!< entry peer_cert */
#endif
mbedtls_ssl_cache_entry *next; /*!< chain pointer */

View file

@ -486,6 +486,24 @@ static inline int mbedtls_ssl_ciphersuite_cert_req_allowed( const mbedtls_ssl_ci
}
}
static inline int mbedtls_ssl_ciphersuite_uses_srv_cert( const mbedtls_ssl_ciphersuite_t *info )
{
switch( info->key_exchange )
{
case MBEDTLS_KEY_EXCHANGE_RSA:
case MBEDTLS_KEY_EXCHANGE_RSA_PSK:
case MBEDTLS_KEY_EXCHANGE_DHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA:
case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA:
return( 1 );
default:
return( 0 );
}
}
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
static inline int mbedtls_ssl_ciphersuite_uses_dhe( const mbedtls_ssl_ciphersuite_t *info )
{

View file

@ -331,8 +331,13 @@ struct mbedtls_ssl_handshake_params
ssl_ecrs_cke_ecdh_calc_secret, /*!< ClientKeyExchange: ECDH step 2 */
ssl_ecrs_crt_vrfy_sign, /*!< CertificateVerify: pk_sign() */
} ecrs_state; /*!< current (or last) operation */
mbedtls_x509_crt *ecrs_peer_cert; /*!< The peer's CRT chain. */
size_t ecrs_n; /*!< place for saving a length */
#endif
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
!defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_pk_context peer_pubkey; /*!< The public key from the peer. */
#endif /* MBEDTLS_X509_CRT_PARSE_C && !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
unsigned int in_msg_seq; /*!< Incoming handshake sequence number */
@ -766,6 +771,9 @@ int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl );
void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl );
#endif
int mbedtls_ssl_session_copy( mbedtls_ssl_session *dst,
const mbedtls_ssl_session *src );
/* constant-time buffer comparison */
static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n )
{

View file

@ -70,6 +70,7 @@ typedef struct mbedtls_x509_crt
mbedtls_x509_time valid_from; /**< Start time of certificate validity. */
mbedtls_x509_time valid_to; /**< End time of certificate validity. */
mbedtls_x509_buf pk_raw;
mbedtls_pk_context pk; /**< Container for the public key context. */
mbedtls_x509_buf issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */

View file

@ -40,6 +40,7 @@
#endif
#include "mbedtls/ssl_cache.h"
#include "mbedtls/ssl_internal.h"
#include <string.h>
@ -92,16 +93,24 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
entry->session.id_len ) != 0 )
continue;
memcpy( session->master, entry->session.master, 48 );
ret = mbedtls_ssl_session_copy( session, &entry->session );
if( ret != 0 )
{
ret = 1;
goto exit;
}
session->verify_result = entry->session.verify_result;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/*
* Restore peer certificate (without rest of the original chain)
*/
if( entry->peer_cert.p != NULL )
{
/* `session->peer_cert` is NULL after the call to
* mbedtls_ssl_session_copy(), because cache entries
* have the `peer_cert` field set to NULL. */
if( ( session->peer_cert = mbedtls_calloc( 1,
sizeof(mbedtls_x509_crt) ) ) == NULL )
{
@ -119,7 +128,7 @@ int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
goto exit;
}
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ret = 0;
goto exit;
@ -239,9 +248,8 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
#endif
}
memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/*
* If we're reusing an entry, free its certificate first
*/
@ -250,26 +258,43 @@ int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
mbedtls_free( cur->peer_cert.p );
memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
}
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Store peer certificate
*/
if( session->peer_cert != NULL )
/* Copy the entire session; this temporarily makes a copy of the
* X.509 CRT structure even though we only want to store the raw CRT.
* This inefficiency will go away as soon as we implement on-demand
* parsing of CRTs, in which case there's no need for the `peer_cert`
* field anymore in the first place, and we're done after this call. */
ret = mbedtls_ssl_session_copy( &cur->session, session );
if( ret != 0 )
{
cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
ret = 1;
goto exit;
}
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* If present, free the X.509 structure and only store the raw CRT data. */
if( cur->session.peer_cert != NULL )
{
cur->peer_cert.p =
mbedtls_calloc( 1, cur->session.peer_cert->raw.len );
if( cur->peer_cert.p == NULL )
{
ret = 1;
goto exit;
}
memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
session->peer_cert->raw.len );
memcpy( cur->peer_cert.p,
cur->session.peer_cert->raw.p,
cur->session.peer_cert->raw.len );
cur->peer_cert.len = session->peer_cert->raw.len;
mbedtls_x509_crt_free( cur->session.peer_cert );
mbedtls_free( cur->session.peer_cert );
cur->session.peer_cert = NULL;
}
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
ret = 0;
@ -311,9 +336,10 @@ void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
mbedtls_ssl_session_free( &prv->session );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_X509_CRT_PARSE_C) && \
defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_free( prv->peer_cert.p );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_free( prv );
}

View file

@ -2265,6 +2265,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
int ret;
size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2;
unsigned char *p = ssl->handshake->premaster + pms_offset;
mbedtls_pk_context * peer_pk;
if( offset + len_bytes > MBEDTLS_SSL_OUT_CONTENT_LEN )
{
@ -2290,23 +2291,28 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
ssl->handshake->pmslen = 48;
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
peer_pk = &ssl->handshake->peer_pubkey;
#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
/* Should never happen */
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
peer_pk = &ssl->session_negotiate->peer_cert->pk;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Now write it out, encrypted
*/
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
MBEDTLS_PK_RSA ) )
if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk,
if( ( ret = mbedtls_pk_encrypt( peer_pk,
p, ssl->handshake->pmslen,
ssl->out_msg + offset + len_bytes, olen,
MBEDTLS_SSL_OUT_CONTENT_LEN - offset - len_bytes,
@ -2326,6 +2332,10 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl,
}
#endif
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* We don't need the peer's public key anymore. Free it. */
mbedtls_pk_free( peer_pk );
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
return( 0 );
}
#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED ||
@ -2401,21 +2411,27 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
{
int ret;
const mbedtls_ecp_keypair *peer_key;
mbedtls_pk_context * peer_pk;
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
peer_pk = &ssl->handshake->peer_pubkey;
#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
/* Should never happen */
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
peer_pk = &ssl->session_negotiate->peer_cert->pk;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
MBEDTLS_PK_ECKEY ) )
if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) );
return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH );
}
peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk );
peer_key = mbedtls_pk_ec( *peer_pk );
if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key,
MBEDTLS_ECDH_THEIRS ) ) != 0 )
@ -2430,6 +2446,13 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* We don't need the peer's public key anymore. Free it,
* so that more RAM is available for upcoming expensive
* operations like ECDHE. */
mbedtls_pk_free( peer_pk );
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
return( ret );
}
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
@ -2640,6 +2663,8 @@ start_processing:
size_t params_len = p - params;
void *rs_ctx = NULL;
mbedtls_pk_context * peer_pk;
/*
* Handle the digitally-signed structure
*/
@ -2742,18 +2767,22 @@ start_processing:
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
peer_pk = &ssl->handshake->peer_pubkey;
#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE );
return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE );
/* Should never happen */
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
peer_pk = &ssl->session_negotiate->peer_cert->pk;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* Verify signature
*/
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@ -2766,8 +2795,7 @@ start_processing:
rs_ctx = &ssl->handshake->ecrs_ctx.pk;
#endif
if( ( ret = mbedtls_pk_verify_restartable(
&ssl->session_negotiate->peer_cert->pk,
if( ( ret = mbedtls_pk_verify_restartable( peer_pk,
md_alg, hash, hashlen, p, sig_len, rs_ctx ) ) != 0 )
{
#if defined(MBEDTLS_SSL__ECP_RESTARTABLE)
@ -2782,6 +2810,13 @@ start_processing:
#endif
return( ret );
}
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* We don't need the peer's public key anymore. Free it,
* so that more RAM is available for upcoming expensive
* operations like ECDHE. */
mbedtls_pk_free( peer_pk );
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
}
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
@ -3456,12 +3491,7 @@ ecdh_calc_secret:
return( 0 );
}
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@ -3476,11 +3506,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@ -3490,7 +3516,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else
#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@ -3519,11 +3545,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++;
@ -3666,12 +3688,7 @@ sign:
return( ret );
}
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl )

View file

@ -2680,12 +2680,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
return( ret );
}
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@ -2693,11 +2688,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
ssl->state++;
@ -2707,7 +2698,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else
#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@ -2731,11 +2722,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
#endif
authmode = ssl->conf->authmode;
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) ||
authmode == MBEDTLS_SSL_VERIFY_NONE )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
@ -2874,12 +2861,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
return( ret );
}
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
@ -4048,12 +4030,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
return( 0 );
}
#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \
!defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \
!defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
#if !defined(MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED)
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
@ -4061,11 +4038,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
@ -4075,7 +4048,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
#else
#else /* !MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
@ -4089,21 +4062,33 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
mbedtls_md_type_t md_alg;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
mbedtls_pk_context * peer_pk;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
ssl->session_negotiate->peer_cert == NULL )
if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
return( 0 );
}
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( ssl->session_negotiate->peer_cert == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
return( 0 );
}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert_digest == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
ssl->state++;
return( 0 );
}
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/* Read the message without adding it to the checksum */
ret = mbedtls_ssl_read_record( ssl, 0 /* no checksum update */ );
if( 0 != ret )
@ -4124,6 +4109,17 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
i = mbedtls_ssl_hs_hdr_len( ssl );
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
peer_pk = &ssl->handshake->peer_pubkey;
#else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( ssl->session_negotiate->peer_cert == NULL )
{
/* Should never happen */
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
peer_pk = &ssl->session_negotiate->peer_cert->pk;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/*
* struct {
* SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only
@ -4138,8 +4134,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
hashlen = 36;
/* For ECDSA, use SHA-1, not MD-5 + SHA-1 */
if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk,
MBEDTLS_PK_ECDSA ) )
if( mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECDSA ) )
{
hash_start += 16;
hashlen -= 16;
@ -4194,7 +4189,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
/*
* Check the certificate's key type matches the signature alg
*/
if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
if( !mbedtls_pk_can_do( peer_pk, pk_alg ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
@ -4227,7 +4222,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
/* Calculate hash and verify signature */
ssl->handshake->calc_verify( ssl, hash );
if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk,
if( ( ret = mbedtls_pk_verify( peer_pk,
md_alg, hash_start, hashlen,
ssl->in_msg + i, sig_len ) ) != 0 )
{
@ -4241,12 +4236,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
return( ret );
}
#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED &&
!MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
#endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */
#if defined(MBEDTLS_SSL_SESSION_TICKETS)
static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl )

View file

@ -187,9 +187,16 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx,
/*
* Serialize a session in the following format:
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
* n . n+2 peer_cert length = m (0 if no certificate)
* n+3 . n+2+m peer cert ASN.1
*
* - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is enabled:
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
* n . n+2 peer_cert length = m (0 if no certificate)
* n+3 . n+2+m peer cert ASN.1
*
* - If MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled:
* 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session)
* n . n length of peer certificate digest = k (0 if no digest)
* n+1 . n+k peer certificate digest (digest type encoded in session)
*/
static int ssl_save_session( const mbedtls_ssl_session *session,
unsigned char *buf, size_t buf_len,
@ -198,17 +205,25 @@ static int ssl_save_session( const mbedtls_ssl_session *session,
unsigned char *p = buf;
size_t left = buf_len;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
size_t cert_len;
#else
size_t cert_digest_len;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( left < sizeof( mbedtls_ssl_session ) )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
/* This also copies the values of pointer fields in the
* session to be serialized, but they'll be ignored when
* loading the session through ssl_load_session(). */
memcpy( p, session, sizeof( mbedtls_ssl_session ) );
p += sizeof( mbedtls_ssl_session );
left -= sizeof( mbedtls_ssl_session );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( session->peer_cert == NULL )
cert_len = 0;
else
@ -220,11 +235,31 @@ static int ssl_save_session( const mbedtls_ssl_session *session,
*p++ = (unsigned char)( ( cert_len >> 16 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( cert_len ) & 0xFF );
left -= 3;
if( session->peer_cert != NULL )
memcpy( p, session->peer_cert->raw.p, cert_len );
p += cert_len;
left -= cert_len;
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
if( session->peer_cert_digest != NULL )
cert_digest_len = 0;
else
cert_digest_len = session->peer_cert_digest_len;
if( left < 1 + cert_digest_len )
return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL );
*p++ = (unsigned char) cert_digest_len;
left--;
if( session->peer_cert_digest != NULL )
memcpy( p, session->peer_cert_digest, cert_digest_len );
p += cert_digest_len;
left -= cert_digest_len;
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
*olen = p - buf;
@ -241,7 +276,11 @@ static int ssl_load_session( mbedtls_ssl_session *session,
const unsigned char *p = buf;
const unsigned char * const end = buf + len;
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
size_t cert_len;
#else
size_t cert_digest_len;
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
@ -250,18 +289,29 @@ static int ssl_load_session( mbedtls_ssl_session *session,
memcpy( session, p, sizeof( mbedtls_ssl_session ) );
p += sizeof( mbedtls_ssl_session );
/* Non-NULL pointer fields of `session` are meaningless
* and potentially harmful. Zeroize them for safety. */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
session->peer_cert = NULL;
#else
session->peer_cert_digest = NULL;
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
session->ticket = NULL;
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
/* Deserialize CRT from the end of the ticket. */
if( 3 > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2];
p += 3;
if( cert_len == 0 )
{
session->peer_cert = NULL;
}
else
if( cert_len != 0 )
{
int ret;
@ -286,6 +336,30 @@ static int ssl_load_session( mbedtls_ssl_session *session,
p += cert_len;
}
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
/* Deserialize CRT digest from the end of the ticket. */
if( 1 > (size_t)( end - p ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
cert_digest_len = (size_t) p[0];
p++;
if( cert_digest_len != 0 )
{
if( cert_digest_len > (size_t)( end - p ) ||
cert_digest_len != session->peer_cert_digest_len )
{
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
session->peer_cert_digest = mbedtls_calloc( 1, cert_digest_len );
if( session->peer_cert_digest == NULL )
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
memcpy( session->peer_cert_digest, p, cert_digest_len );
p += cert_digest_len;
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( p != end )

File diff suppressed because it is too large Load diff

View file

@ -459,6 +459,9 @@ static const char *features[] = {
#if defined(MBEDTLS_SSL_FALLBACK_SCSV)
"MBEDTLS_SSL_FALLBACK_SCSV",
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
"MBEDTLS_SSL_KEEP_PEER_CERTIFICATE",
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
"MBEDTLS_SSL_HW_RECORD_ACCEL",
#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */

View file

@ -996,11 +996,13 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
/*
* SubjectPublicKeyInfo
*/
crt->pk_raw.p = p;
if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
{
mbedtls_x509_crt_free( crt );
return( ret );
}
crt->pk_raw.len = p - crt->pk_raw.p;
/*
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,

View file

@ -1266,6 +1266,14 @@ int query_config( const char *config )
}
#endif /* MBEDTLS_SSL_FALLBACK_SCSV */
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
if( strcmp( "MBEDTLS_SSL_KEEP_PEER_CERTIFICATE", config ) == 0 )
{
MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_KEEP_PEER_CERTIFICATE );
return( 0 );
}
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( strcmp( "MBEDTLS_SSL_HW_RECORD_ACCEL", config ) == 0 )
{

View file

@ -478,6 +478,8 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len )
}
#if defined(MBEDTLS_X509_CRT_PARSE_C)
static unsigned char peer_crt_info[1024];
/*
* Enabled if debug_level > 1 in code below
*/
@ -487,8 +489,14 @@ static int my_verify( void *data, mbedtls_x509_crt *crt,
char buf[1024];
((void) data);
mbedtls_printf( "\nVerify requested for (Depth %d):\n", depth );
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
if( depth == 0 )
memcpy( peer_crt_info, buf, sizeof( buf ) );
if( opt.debug_level == 0 )
return( 0 );
mbedtls_printf( "\nVerify requested for (Depth %d):\n", depth );
mbedtls_printf( "%s", buf );
if ( ( *flags ) == 0 )
@ -1503,8 +1511,8 @@ int main( int argc, char *argv[] )
mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );
}
if( opt.debug_level > 0 )
mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
memset( peer_crt_info, 0, sizeof( peer_crt_info ) );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( opt.auth_mode != DFL_AUTH_MODE )
@ -1833,13 +1841,8 @@ int main( int argc, char *argv[] )
else
mbedtls_printf( " ok\n" );
if( mbedtls_ssl_get_peer_cert( &ssl ) != NULL )
{
mbedtls_printf( " . Peer certificate information ...\n" );
mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ",
mbedtls_ssl_get_peer_cert( &ssl ) );
mbedtls_printf( "%s\n", buf );
}
mbedtls_printf( " . Peer certificate information ...\n" );
mbedtls_printf( "%s\n", peer_crt_info );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
#if defined(MBEDTLS_SSL_RENEGOTIATION)
@ -2144,6 +2147,10 @@ send_request:
mbedtls_printf( " . Restarting connection from same port..." );
fflush( stdout );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
memset( peer_crt_info, 0, sizeof( peer_crt_info ) );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_session_reset returned -0x%x\n\n",
@ -2215,6 +2222,10 @@ reconnect:
mbedtls_printf( " . Reconnecting with saved session..." );
#if defined(MBEDTLS_X509_CRT_PARSE_C)
memset( peer_crt_info, 0, sizeof( peer_crt_info ) );
#endif /* MBEDTLS_X509_CRT_PARSE_C */
if( ( ret = mbedtls_ssl_session_reset( &ssl ) ) != 0 )
{
mbedtls_printf( " failed\n ! mbedtls_ssl_session_reset returned -0x%x\n\n",

View file

@ -467,9 +467,12 @@ int main( int argc, char *argv[] )
/*
* 5. Print the certificate
*/
#if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
mbedtls_printf( " . Peer certificate information ... skipped\n" );
#else
mbedtls_printf( " . Peer certificate information ...\n" );
ret = mbedtls_x509_crt_info( (char *) buf, sizeof( buf ) - 1, " ",
ssl.session->peer_cert );
mbedtls_ssl_get_peer_cert( &ssl ) );
if( ret == -1 )
{
mbedtls_printf( " failed\n ! mbedtls_x509_crt_info returned %d\n\n", ret );
@ -477,6 +480,7 @@ int main( int argc, char *argv[] )
}
mbedtls_printf( "%s\n", buf );
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
mbedtls_ssl_close_notify( &ssl );

View file

@ -968,6 +968,22 @@ component_test_no_max_fragment_length () {
if_build_succeeded tests/ssl-opt.sh -f "Max fragment length"
}
component_test_asan_remove_peer_certificate () {
msg "build: default config with MBEDTLS_SSL_KEEP_PEER_CERTIFICATE disabled (ASan build)"
scripts/config.pl unset MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
make test
msg "test: ssl-opt.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
if_build_succeeded tests/ssl-opt.sh
msg "test: compat.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE"
if_build_succeeded tests/compat.sh
}
component_test_no_max_fragment_length_small_ssl_out_content_len () {
msg "build: no MFL extension, small SSL_OUT_CONTENT_LEN (ASan build)"
scripts/config.pl unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH