Merge remote-tracking branch 'public/pr/1270' into development
This commit is contained in:
commit
5f57f1e3cc
@ -10,6 +10,9 @@ Features
|
||||
* Add support for the CCM* block cipher mode as defined in IEEE Std. 802.15.4.
|
||||
* Add support for the XTS block cipher mode with AES (AES-XTS).
|
||||
Contributed by Aorimn in pull request #414.
|
||||
* In TLS servers, support offloading private key operations to an external
|
||||
cryptoprocessor. Private key operations can be asynchronous to allow
|
||||
non-blocking operation of the TLS server stack.
|
||||
|
||||
Bugfix
|
||||
* Fix the cert_write example to handle certificates signed with elliptic
|
||||
|
@ -1148,6 +1148,17 @@
|
||||
*/
|
||||
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
*
|
||||
* Enable asynchronous external private key operations in SSL. This allows
|
||||
* you to configure an SSL connection to call an external cryptographic
|
||||
* module to perform private key operations instead of performing the
|
||||
* operation inside the library.
|
||||
*
|
||||
*/
|
||||
#define MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SSL_DEBUG_ALL
|
||||
*
|
||||
|
@ -91,7 +91,7 @@
|
||||
* MD 5 5
|
||||
* HKDF 5 1 (Started from top)
|
||||
* CIPHER 6 8
|
||||
* SSL 6 17 (Started from top)
|
||||
* SSL 6 22 (Started from top)
|
||||
* SSL 7 31
|
||||
*
|
||||
* Module dependent error code (5 bits 0x.00.-0x.F8.)
|
||||
|
@ -120,6 +120,7 @@
|
||||
#define MBEDTLS_ERR_SSL_NON_FATAL -0x6680 /**< The alert message received indicates a non-fatal error. */
|
||||
#define MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH -0x6600 /**< Couldn't set the hash for verifying CertificateVerify */
|
||||
#define MBEDTLS_ERR_SSL_CONTINUE_PROCESSING -0x6580 /**< Internal-only message signaling that further message-processing should be done */
|
||||
#define MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS -0x6500 /**< The asynchronous operation is not completed yet. */
|
||||
|
||||
/*
|
||||
* Various constants
|
||||
@ -536,7 +537,6 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx,
|
||||
*/
|
||||
typedef int mbedtls_ssl_get_timer_t( void * ctx );
|
||||
|
||||
|
||||
/* Defined below */
|
||||
typedef struct mbedtls_ssl_session mbedtls_ssl_session;
|
||||
typedef struct mbedtls_ssl_context mbedtls_ssl_context;
|
||||
@ -553,6 +553,218 @@ typedef struct mbedtls_ssl_key_cert mbedtls_ssl_key_cert;
|
||||
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
/**
|
||||
* \brief Callback type: start external signature operation.
|
||||
*
|
||||
* This callback is called during an SSL handshake to start
|
||||
* a signature decryption operation using an
|
||||
* external processor. The parameter \p cert contains
|
||||
* the public key; it is up to the callback function to
|
||||
* determine how to access the associated private key.
|
||||
*
|
||||
* This function typically sends or enqueues a request, and
|
||||
* does not wait for the operation to complete. This allows
|
||||
* the handshake step to be non-blocking.
|
||||
*
|
||||
* The parameters \p ssl and \p cert are guaranteed to remain
|
||||
* valid throughout the handshake. On the other hand, this
|
||||
* function must save the contents of \p hash if the value
|
||||
* is needed for later processing, because the \p hash buffer
|
||||
* is no longer valid after this function returns.
|
||||
*
|
||||
* This function may call mbedtls_ssl_set_async_operation_data()
|
||||
* to store an operation context for later retrieval
|
||||
* by the resume or cancel callback.
|
||||
*
|
||||
* \note For RSA signatures, this function must produce output
|
||||
* that is consistent with PKCS#1 v1.5 in the same way as
|
||||
* mbedtls_rsa_pkcs1_sign(). Before the private key operation,
|
||||
* apply the padding steps described in RFC 8017, section 9.2
|
||||
* "EMSA-PKCS1-v1_5" as follows.
|
||||
* - If \p md_alg is #MBEDTLS_MD_NONE, apply the PKCS#1 v1.5
|
||||
* encoding, treating \p hash as the DigestInfo to be
|
||||
* padded. In other words, apply EMSA-PKCS1-v1_5 starting
|
||||
* from step 3, with `T = hash` and `tLen = hash_len`.
|
||||
* - If `md_alg != MBEDTLS_MD_NONE`, apply the PKCS#1 v1.5
|
||||
* encoding, treating \p hash as the hash to be encoded and
|
||||
* padded. In other words, apply EMSA-PKCS1-v1_5 starting
|
||||
* from step 2, with `digestAlgorithm` obtained by calling
|
||||
* mbedtls_oid_get_oid_by_md() on \p md_alg.
|
||||
*
|
||||
* \note For ECDSA signatures, the output format is the DER encoding
|
||||
* `Ecdsa-Sig-Value` defined in
|
||||
* [RFC 4492 section 5.4](https://tools.ietf.org/html/rfc4492#section-5.4).
|
||||
*
|
||||
* \param ssl The SSL connection instance. It should not be
|
||||
* modified other than via
|
||||
* mbedtls_ssl_set_async_operation_data().
|
||||
* \param cert Certificate containing the public key.
|
||||
* In simple cases, this is one of the pointers passed to
|
||||
* mbedtls_ssl_conf_own_cert() when configuring the SSL
|
||||
* connection. However, if other callbacks are used, this
|
||||
* property may not hold. For example, if an SNI callback
|
||||
* is registered with mbedtls_ssl_conf_sni(), then
|
||||
* this callback determines what certificate is used.
|
||||
* \param md_alg Hash algorithm.
|
||||
* \param hash Buffer containing the hash. This buffer is
|
||||
* no longer valid when the function returns.
|
||||
* \param hash_len Size of the \c hash buffer in bytes.
|
||||
*
|
||||
* \return 0 if the operation was started successfully and the SSL
|
||||
* stack should call the resume callback immediately.
|
||||
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
|
||||
* was started successfully and the SSL stack should return
|
||||
* immediately without calling the resume callback yet.
|
||||
* \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
|
||||
* processor does not support this key. The SSL stack will
|
||||
* use the private key object instead.
|
||||
* \return Any other error indicates a fatal failure and is
|
||||
* propagated up the call chain. The callback should
|
||||
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
|
||||
* use \c MBEDTLS_ERR_SSL_xxx error codes except as
|
||||
* directed in the documentation of this callback.
|
||||
*/
|
||||
typedef int mbedtls_ssl_async_sign_t( mbedtls_ssl_context *ssl,
|
||||
mbedtls_x509_crt *cert,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash,
|
||||
size_t hash_len );
|
||||
|
||||
/**
|
||||
* \brief Callback type: start external decryption operation.
|
||||
*
|
||||
* This callback is called during an SSL handshake to start
|
||||
* an RSA decryption operation using an
|
||||
* external processor. The parameter \p cert contains
|
||||
* the public key; it is up to the callback function to
|
||||
* determine how to access the associated private key.
|
||||
*
|
||||
* This function typically sends or enqueues a request, and
|
||||
* does not wait for the operation to complete. This allows
|
||||
* the handshake step to be non-blocking.
|
||||
*
|
||||
* The parameters \p ssl and \p cert are guaranteed to remain
|
||||
* valid throughout the handshake. On the other hand, this
|
||||
* function must save the contents of \p input if the value
|
||||
* is needed for later processing, because the \p input buffer
|
||||
* is no longer valid after this function returns.
|
||||
*
|
||||
* This function may call mbedtls_ssl_set_async_operation_data()
|
||||
* to store an operation context for later retrieval
|
||||
* by the resume or cancel callback.
|
||||
*
|
||||
* \warning RSA decryption as used in TLS is subject to a potential
|
||||
* timing side channel attack first discovered by Bleichenbacher
|
||||
* in 1998. This attack can be remotely exploitable
|
||||
* in practice. To avoid this attack, you must ensure that
|
||||
* if the callback performs an RSA decryption, the time it
|
||||
* takes to execute and return the result does not depend
|
||||
* on whether the RSA decryption succeeded or reported
|
||||
* invalid padding.
|
||||
*
|
||||
* \param ssl The SSL connection instance. It should not be
|
||||
* modified other than via
|
||||
* mbedtls_ssl_set_async_operation_data().
|
||||
* \param cert Certificate containing the public key.
|
||||
* In simple cases, this is one of the pointers passed to
|
||||
* mbedtls_ssl_conf_own_cert() when configuring the SSL
|
||||
* connection. However, if other callbacks are used, this
|
||||
* property may not hold. For example, if an SNI callback
|
||||
* is registered with mbedtls_ssl_conf_sni(), then
|
||||
* this callback determines what certificate is used.
|
||||
* \param input Buffer containing the input ciphertext. This buffer
|
||||
* is no longer valid when the function returns.
|
||||
* \param input_len Size of the \p input buffer in bytes.
|
||||
*
|
||||
* \return 0 if the operation was started successfully and the SSL
|
||||
* stack should call the resume callback immediately.
|
||||
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
|
||||
* was started successfully and the SSL stack should return
|
||||
* immediately without calling the resume callback yet.
|
||||
* \return #MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH if the external
|
||||
* processor does not support this key. The SSL stack will
|
||||
* use the private key object instead.
|
||||
* \return Any other error indicates a fatal failure and is
|
||||
* propagated up the call chain. The callback should
|
||||
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
|
||||
* use \c MBEDTLS_ERR_SSL_xxx error codes except as
|
||||
* directed in the documentation of this callback.
|
||||
*/
|
||||
typedef int mbedtls_ssl_async_decrypt_t( mbedtls_ssl_context *ssl,
|
||||
mbedtls_x509_crt *cert,
|
||||
const unsigned char *input,
|
||||
size_t input_len );
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
/**
|
||||
* \brief Callback type: resume external operation.
|
||||
*
|
||||
* This callback is called during an SSL handshake to resume
|
||||
* an external operation started by the
|
||||
* ::mbedtls_ssl_async_sign_t or
|
||||
* ::mbedtls_ssl_async_decrypt_t callback.
|
||||
*
|
||||
* This function typically checks the status of a pending
|
||||
* request or causes the request queue to make progress, and
|
||||
* does not wait for the operation to complete. This allows
|
||||
* the handshake step to be non-blocking.
|
||||
*
|
||||
* This function may call mbedtls_ssl_get_async_operation_data()
|
||||
* to retrieve an operation context set by the start callback.
|
||||
* It may call mbedtls_ssl_set_async_operation_data() to modify
|
||||
* this context.
|
||||
*
|
||||
* Note that when this function returns a status other than
|
||||
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, it must free any
|
||||
* resources associated with the operation.
|
||||
*
|
||||
* \param ssl The SSL connection instance. It should not be
|
||||
* modified other than via
|
||||
* mbedtls_ssl_set_async_operation_data().
|
||||
* \param output Buffer containing the output (signature or decrypted
|
||||
* data) on success.
|
||||
* \param output_len On success, number of bytes written to \p output.
|
||||
* \param output_size Size of the \p output buffer in bytes.
|
||||
*
|
||||
* \return 0 if output of the operation is available in the
|
||||
* \p output buffer.
|
||||
* \return #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS if the operation
|
||||
* is still in progress. Subsequent requests for progress
|
||||
* on the SSL connection will call the resume callback
|
||||
* again.
|
||||
* \return Any other error means that the operation is aborted.
|
||||
* The SSL handshake is aborted. The callback should
|
||||
* use \c MBEDTLS_ERR_PK_xxx error codes, and <b>must not</b>
|
||||
* use \c MBEDTLS_ERR_SSL_xxx error codes except as
|
||||
* directed in the documentation of this callback.
|
||||
*/
|
||||
typedef int mbedtls_ssl_async_resume_t( mbedtls_ssl_context *ssl,
|
||||
unsigned char *output,
|
||||
size_t *output_len,
|
||||
size_t output_size );
|
||||
|
||||
/**
|
||||
* \brief Callback type: cancel external operation.
|
||||
*
|
||||
* This callback is called if an SSL connection is closed
|
||||
* while an asynchronous operation is in progress. Note that
|
||||
* this callback is not called if the
|
||||
* ::mbedtls_ssl_async_resume_t callback has run and has
|
||||
* returned a value other than
|
||||
* #MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS, since in that case
|
||||
* the asynchronous operation has already completed.
|
||||
*
|
||||
* This function may call mbedtls_ssl_get_async_operation_data()
|
||||
* to retrieve an operation context set by the start callback.
|
||||
*
|
||||
* \param ssl The SSL connection instance. It should not be
|
||||
* modified.
|
||||
*/
|
||||
typedef void mbedtls_ssl_async_cancel_t( mbedtls_ssl_context *ssl );
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
/*
|
||||
* This structure is used for storing current session data.
|
||||
*/
|
||||
@ -669,6 +881,16 @@ struct mbedtls_ssl_config
|
||||
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||
mbedtls_ssl_async_sign_t *f_async_sign_start; /*!< start asynchronous signature operation */
|
||||
mbedtls_ssl_async_decrypt_t *f_async_decrypt_start; /*!< start asynchronous decryption operation */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
mbedtls_ssl_async_resume_t *f_async_resume; /*!< resume asynchronous operation */
|
||||
mbedtls_ssl_async_cancel_t *f_async_cancel; /*!< cancel asynchronous operation */
|
||||
void *p_async_config_data; /*!< Configuration data set by mbedtls_ssl_conf_async_private_cb(). */
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||
const int *sig_hashes; /*!< allowed signature hashes */
|
||||
#endif
|
||||
@ -1307,6 +1529,85 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
|
||||
void *p_export_keys );
|
||||
#endif /* MBEDTLS_SSL_EXPORT_KEYS */
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
/**
|
||||
* \brief Configure asynchronous private key operation callbacks.
|
||||
*
|
||||
* \param conf SSL configuration context
|
||||
* \param f_async_sign Callback to start a signature operation. See
|
||||
* the description of ::mbedtls_ssl_async_sign_t
|
||||
* for more information. This may be \c NULL if the
|
||||
* external processor does not support any signature
|
||||
* operation; in this case the private key object
|
||||
* associated with the certificate will be used.
|
||||
* \param f_async_decrypt Callback to start a decryption operation. See
|
||||
* the description of ::mbedtls_ssl_async_decrypt_t
|
||||
* for more information. This may be \c NULL if the
|
||||
* external processor does not support any decryption
|
||||
* operation; in this case the private key object
|
||||
* associated with the certificate will be used.
|
||||
* \param f_async_resume Callback to resume an asynchronous operation. See
|
||||
* the description of ::mbedtls_ssl_async_resume_t
|
||||
* for more information. This may not be \c NULL unless
|
||||
* \p f_async_sign and \p f_async_decrypt are both
|
||||
* \c NULL.
|
||||
* \param f_async_cancel Callback to cancel an asynchronous operation. See
|
||||
* the description of ::mbedtls_ssl_async_cancel_t
|
||||
* for more information. This may be \c NULL if
|
||||
* no cleanup is needed.
|
||||
* \param config_data A pointer to configuration data which can be
|
||||
* retrieved with
|
||||
* mbedtls_ssl_conf_get_async_config_data(). The
|
||||
* library stores this value without dereferencing it.
|
||||
*/
|
||||
void mbedtls_ssl_conf_async_private_cb( mbedtls_ssl_config *conf,
|
||||
mbedtls_ssl_async_sign_t *f_async_sign,
|
||||
mbedtls_ssl_async_decrypt_t *f_async_decrypt,
|
||||
mbedtls_ssl_async_resume_t *f_async_resume,
|
||||
mbedtls_ssl_async_cancel_t *f_async_cancel,
|
||||
void *config_data );
|
||||
|
||||
/**
|
||||
* \brief Retrieve the configuration data set by
|
||||
* mbedtls_ssl_conf_async_private_cb().
|
||||
*
|
||||
* \param conf SSL configuration context
|
||||
* \return The configuration data set by
|
||||
* mbedtls_ssl_conf_async_private_cb().
|
||||
*/
|
||||
void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf );
|
||||
|
||||
/**
|
||||
* \brief Retrieve the asynchronous operation user context.
|
||||
*
|
||||
* \note This function may only be called while a handshake
|
||||
* is in progress.
|
||||
*
|
||||
* \param ssl The SSL context to access.
|
||||
*
|
||||
* \return The asynchronous operation user context that was last
|
||||
* set during the current handshake. If
|
||||
* mbedtls_ssl_set_async_operation_data() has not yet been
|
||||
* called during the current handshake, this function returns
|
||||
* \c NULL.
|
||||
*/
|
||||
void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl );
|
||||
|
||||
/**
|
||||
* \brief Retrieve the asynchronous operation user context.
|
||||
*
|
||||
* \note This function may only be called while a handshake
|
||||
* is in progress.
|
||||
*
|
||||
* \param ssl The SSL context to access.
|
||||
* \param ctx The new value of the asynchronous operation user context.
|
||||
* Call mbedtls_ssl_get_async_operation_data() later during the
|
||||
* same handshake to retrieve this value.
|
||||
*/
|
||||
void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
|
||||
void *ctx );
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
/**
|
||||
* \brief Callback type: generate a cookie
|
||||
*
|
||||
|
@ -243,6 +243,7 @@ struct mbedtls_ssl_handshake_params
|
||||
mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
|
||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
|
||||
unsigned int in_msg_seq; /*!< Incoming handshake sequence number */
|
||||
@ -307,6 +308,19 @@ struct mbedtls_ssl_handshake_params
|
||||
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
|
||||
int extended_ms; /*!< use Extended Master Secret? */
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
unsigned int async_in_progress : 1; /*!< an asynchronous operation is in progress */
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
/** Asynchronous operation context. This field is meant for use by the
|
||||
* asynchronous operation callbacks (mbedtls_ssl_config::f_async_sign_start,
|
||||
* mbedtls_ssl_config::f_async_decrypt_start,
|
||||
* mbedtls_ssl_config::f_async_resume, mbedtls_ssl_config::f_async_cancel).
|
||||
* The library does not use it internally. */
|
||||
void *user_async_ctx;
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -410,9 +424,9 @@ void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform );
|
||||
* \brief Free referenced items in an SSL handshake context and clear
|
||||
* memory
|
||||
*
|
||||
* \param handshake SSL handshake context
|
||||
* \param ssl SSL context
|
||||
*/
|
||||
void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake );
|
||||
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl );
|
||||
|
||||
int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl );
|
||||
int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl );
|
||||
@ -652,9 +666,9 @@ int mbedtls_ssl_get_key_exchange_md_ssl_tls( mbedtls_ssl_context *ssl,
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
||||
unsigned char *output,
|
||||
unsigned char *data, size_t data_len,
|
||||
mbedtls_md_type_t md_alg );
|
||||
unsigned char *hash, size_t *hashlen,
|
||||
unsigned char *data, size_t data_len,
|
||||
mbedtls_md_type_t md_alg );
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
||||
MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
|
@ -501,6 +501,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
|
||||
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
|
||||
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
|
||||
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
|
||||
if( use_ret == -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) )
|
||||
mbedtls_snprintf( buf, buflen, "SSL - The asynchronous operation is not completed yet" );
|
||||
#endif /* MBEDTLS_SSL_TLS_C */
|
||||
|
||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
|
||||
|
@ -2544,10 +2544,9 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( md_alg != MBEDTLS_MD_NONE )
|
||||
{
|
||||
/* Info from md_alg will be used instead */
|
||||
hashlen = 0;
|
||||
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params,
|
||||
params_len, md_alg );
|
||||
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
|
||||
params, params_len,
|
||||
md_alg );
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
}
|
||||
@ -2559,8 +2558,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
|
||||
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
|
||||
|
||||
if( ssl->session_negotiate->peer_cert == NULL )
|
||||
{
|
||||
|
@ -709,7 +709,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
|
||||
cur->cert );
|
||||
|
||||
if( ! mbedtls_pk_can_do( cur->key, pk_alg ) )
|
||||
if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
|
||||
continue;
|
||||
@ -733,7 +733,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
||||
|
||||
#if defined(MBEDTLS_ECDSA_C)
|
||||
if( pk_alg == MBEDTLS_PK_ECDSA &&
|
||||
ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 )
|
||||
ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
|
||||
continue;
|
||||
@ -2828,54 +2828,56 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
|
||||
|
||||
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
|
||||
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
static int ssl_resume_server_key_exchange( mbedtls_ssl_context *ssl,
|
||||
size_t *signature_len )
|
||||
{
|
||||
/* Append the signature to ssl->out_msg, leaving 2 bytes for the
|
||||
* signature length which will be added in ssl_write_server_key_exchange
|
||||
* after the call to ssl_prepare_server_key_exchange.
|
||||
* ssl_write_server_key_exchange also takes care of incrementing
|
||||
* ssl->out_msglen. */
|
||||
unsigned char *sig_start = ssl->out_msg + ssl->out_msglen + 2;
|
||||
size_t sig_max_len = ( ssl->out_buf + MBEDTLS_SSL_MAX_CONTENT_LEN
|
||||
- sig_start );
|
||||
int ret = ssl->conf->f_async_resume( ssl,
|
||||
sig_start, signature_len, sig_max_len );
|
||||
if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
|
||||
{
|
||||
ssl->handshake->async_in_progress = 0;
|
||||
mbedtls_ssl_set_async_operation_data( ssl, NULL );
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_resume_server_key_exchange", ret );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
|
||||
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
|
||||
|
||||
/* Prepare the ServerKeyExchange message, up to and including
|
||||
* calculating the signature if any, but excluding formatting the
|
||||
* signature and sending the message. */
|
||||
static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
|
||||
size_t *signature_len )
|
||||
{
|
||||
int ret;
|
||||
size_t n = 0;
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
ssl->transform_negotiate->ciphersuite_info;
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
|
||||
unsigned char *p = ssl->out_msg + 4;
|
||||
size_t len;
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||
unsigned char *dig_signed = p;
|
||||
size_t dig_signed_len = 0;
|
||||
unsigned char *dig_signed = NULL;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED */
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
|
||||
(void) ciphersuite_info; /* unused in some configurations */
|
||||
#if !defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||
(void) signature_len;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
||||
|
||||
ssl->out_msglen = 4; /* header (type:1, length:3) to be written later */
|
||||
|
||||
/*
|
||||
*
|
||||
* Part 1: Extract static ECDH parameters and abort
|
||||
* if ServerKeyExchange not needed.
|
||||
*
|
||||
*/
|
||||
|
||||
/* For suites involving ECDH, extract DH parameters
|
||||
* from certificate at this point. */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
|
||||
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
|
||||
{
|
||||
ssl_get_ecdh_params_from_cert( ssl );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
|
||||
|
||||
/* Key exchanges not involving ephemeral keys don't use
|
||||
* ServerKeyExchange, so end here. */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
|
||||
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
|
||||
ssl->state++;
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__NON_PFS__ENABLED */
|
||||
|
||||
/*
|
||||
*
|
||||
* Part 2: Provide key exchange parameters for chosen ciphersuite.
|
||||
* Part 1: Provide key exchange parameters for chosen ciphersuite.
|
||||
*
|
||||
*/
|
||||
|
||||
@ -2885,18 +2887,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
|
||||
{
|
||||
const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN;
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx,
|
||||
p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng );
|
||||
ret = mbedtls_ecjpake_write_round_two(
|
||||
&ssl->handshake->ecjpake_ctx,
|
||||
ssl->out_msg + ssl->out_msglen,
|
||||
MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen, &len,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng );
|
||||
if( ret != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
p += len;
|
||||
n += len;
|
||||
ssl->out_msglen += len;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
|
||||
|
||||
@ -2910,10 +2915,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
|
||||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
|
||||
{
|
||||
*(p++) = 0x00;
|
||||
*(p++) = 0x00;
|
||||
|
||||
n += 2;
|
||||
ssl->out_msg[ssl->out_msglen++] = 0x00;
|
||||
ssl->out_msg[ssl->out_msglen++] = 0x00;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
|
||||
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
|
||||
@ -2924,6 +2927,9 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
|
||||
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
|
||||
@ -2947,21 +2953,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx,
|
||||
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
|
||||
p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
if( ( ret = mbedtls_dhm_make_params(
|
||||
&ssl->handshake->dhm_ctx,
|
||||
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
|
||||
ssl->out_msg + ssl->out_msglen, &len,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||
dig_signed = p;
|
||||
dig_signed_len = len;
|
||||
dig_signed = ssl->out_msg + ssl->out_msglen;
|
||||
#endif
|
||||
|
||||
p += len;
|
||||
n += len;
|
||||
ssl->out_msglen += len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
|
||||
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
|
||||
@ -2986,6 +2992,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
*/
|
||||
const mbedtls_ecp_curve_info **curve = NULL;
|
||||
const mbedtls_ecp_group_id *gid;
|
||||
int ret;
|
||||
size_t len;
|
||||
|
||||
/* Match our preference list against the offered curves */
|
||||
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
|
||||
@ -3009,21 +3017,21 @@ curve_matching_done:
|
||||
return( ret );
|
||||
}
|
||||
|
||||
if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
|
||||
p, MBEDTLS_SSL_MAX_CONTENT_LEN - n,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
if( ( ret = mbedtls_ecdh_make_params(
|
||||
&ssl->handshake->ecdh_ctx, &len,
|
||||
ssl->out_msg + ssl->out_msglen,
|
||||
MBEDTLS_SSL_MAX_CONTENT_LEN - ssl->out_msglen,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||
dig_signed = p;
|
||||
dig_signed_len = len;
|
||||
dig_signed = ssl->out_msg + ssl->out_msglen;
|
||||
#endif
|
||||
|
||||
p += len;
|
||||
n += len;
|
||||
ssl->out_msglen += len;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
|
||||
}
|
||||
@ -3031,19 +3039,20 @@ curve_matching_done:
|
||||
|
||||
/*
|
||||
*
|
||||
* Part 3: For key exchanges involving the server signing the
|
||||
* Part 2: For key exchanges involving the server signing the
|
||||
* exchange parameters, compute and add the signature here.
|
||||
*
|
||||
*/
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
|
||||
{
|
||||
size_t signature_len = 0;
|
||||
unsigned int hashlen = 0;
|
||||
unsigned char hash[64];
|
||||
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
|
||||
size_t hashlen = 0;
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* 3.1: Choose hash algorithm:
|
||||
* 2.1: Choose hash algorithm:
|
||||
* A: For TLS 1.2, obey signature-hash-algorithm extension
|
||||
* to choose appropriate hash.
|
||||
* B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1
|
||||
@ -3090,7 +3099,7 @@ curve_matching_done:
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "pick hash algorithm %d for signing", md_alg ) );
|
||||
|
||||
/*
|
||||
* 3.2: Compute the hash to be signed
|
||||
* 2.2: Compute the hash to be signed
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||
@ -3110,9 +3119,7 @@ curve_matching_done:
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( md_alg != MBEDTLS_MD_NONE )
|
||||
{
|
||||
/* Info from md_alg will be used instead */
|
||||
hashlen = 0;
|
||||
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash,
|
||||
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
|
||||
dig_signed,
|
||||
dig_signed_len,
|
||||
md_alg );
|
||||
@ -3127,18 +3134,11 @@ curve_matching_done:
|
||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
|
||||
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
|
||||
|
||||
/*
|
||||
* 3.3: Compute and add the signature
|
||||
* 2.3: Compute and add the signature
|
||||
*/
|
||||
if( mbedtls_ssl_own_key( ssl ) == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
|
||||
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
|
||||
{
|
||||
@ -3158,33 +3158,150 @@ curve_matching_done:
|
||||
*
|
||||
*/
|
||||
|
||||
*(p++) = mbedtls_ssl_hash_from_md_alg( md_alg );
|
||||
*(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg );
|
||||
|
||||
n += 2;
|
||||
ssl->out_msg[ssl->out_msglen++] =
|
||||
mbedtls_ssl_hash_from_md_alg( md_alg );
|
||||
ssl->out_msg[ssl->out_msglen++] =
|
||||
mbedtls_ssl_sig_from_pk_alg( sig_alg );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||
|
||||
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen,
|
||||
p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( ssl->conf->f_async_sign_start != NULL )
|
||||
{
|
||||
ret = ssl->conf->f_async_sign_start( ssl,
|
||||
mbedtls_ssl_own_cert( ssl ),
|
||||
md_alg, hash, hashlen );
|
||||
switch( ret )
|
||||
{
|
||||
case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
|
||||
/* act as if f_async_sign was null */
|
||||
break;
|
||||
case 0:
|
||||
ssl->handshake->async_in_progress = 1;
|
||||
return( ssl_resume_server_key_exchange( ssl, signature_len ) );
|
||||
case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
|
||||
ssl->handshake->async_in_progress = 1;
|
||||
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
|
||||
default:
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "f_async_sign_start", ret );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
if( mbedtls_ssl_own_key( ssl ) == NULL )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) );
|
||||
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
|
||||
}
|
||||
|
||||
/* Append the signature to ssl->out_msg, leaving 2 bytes for the
|
||||
* signature length which will be added in ssl_write_server_key_exchange
|
||||
* after the call to ssl_prepare_server_key_exchange.
|
||||
* ssl_write_server_key_exchange also takes care of incrementing
|
||||
* ssl->out_msglen. */
|
||||
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ),
|
||||
md_alg, hash, hashlen,
|
||||
ssl->out_msg + ssl->out_msglen + 2,
|
||||
signature_len,
|
||||
ssl->conf->f_rng,
|
||||
ssl->conf->p_rng ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
*(p++) = (unsigned char)( signature_len >> 8 );
|
||||
*(p++) = (unsigned char)( signature_len );
|
||||
n += 2;
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len );
|
||||
|
||||
n += signature_len;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
||||
|
||||
/* Done with actual work; add header and send. */
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
ssl->out_msglen = 4 + n;
|
||||
/* Prepare the ServerKeyExchange message and send it. For ciphersuites
|
||||
* that do not include a ServerKeyExchange message, do nothing. Either
|
||||
* way, if successful, move on to the next step in the SSL state
|
||||
* machine. */
|
||||
static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
int ret;
|
||||
size_t signature_len = 0;
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
|
||||
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||
ssl->transform_negotiate->ciphersuite_info;
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
|
||||
/* Extract static ECDH parameters and abort if ServerKeyExchange
|
||||
* is not needed. */
|
||||
if( mbedtls_ssl_ciphersuite_no_pfs( ciphersuite_info ) )
|
||||
{
|
||||
/* For suites involving ECDH, extract DH parameters
|
||||
* from certificate at this point. */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED)
|
||||
if( mbedtls_ssl_ciphersuite_uses_ecdh( ciphersuite_info ) )
|
||||
{
|
||||
ssl_get_ecdh_params_from_cert( ssl );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDH_ENABLED */
|
||||
|
||||
/* Key exchanges not involving ephemeral keys don't use
|
||||
* ServerKeyExchange, so end here. */
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
|
||||
ssl->state++;
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) && \
|
||||
defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
/* If we have already prepared the message and there is an ongoing
|
||||
* signature operation, resume signing. */
|
||||
if( ssl->handshake->async_in_progress != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming signature operation" ) );
|
||||
ret = ssl_resume_server_key_exchange( ssl, &signature_len );
|
||||
}
|
||||
else
|
||||
#endif /* defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) &&
|
||||
defined(MBEDTLS_SSL_ASYNC_PRIVATE) */
|
||||
{
|
||||
/* ServerKeyExchange is needed. Prepare the message. */
|
||||
ret = ssl_prepare_server_key_exchange( ssl, &signature_len );
|
||||
}
|
||||
|
||||
if( ret != 0 )
|
||||
{
|
||||
/* If we're starting to write a new message, set ssl->out_msglen
|
||||
* to 0. But if we're resuming after an asynchronous message,
|
||||
* out_msglen is the amount of data written so far and mst be
|
||||
* preserved. */
|
||||
if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange (pending)" ) );
|
||||
else
|
||||
ssl->out_msglen = 0;
|
||||
return( ret );
|
||||
}
|
||||
|
||||
/* If there is a signature, write its length.
|
||||
* ssl_prepare_server_key_exchange already wrote the signature
|
||||
* itself at its proper place in the output buffer. */
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||
if( signature_len != 0 )
|
||||
{
|
||||
ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len >> 8 );
|
||||
ssl->out_msg[ssl->out_msglen++] = (unsigned char)( signature_len );
|
||||
|
||||
MBEDTLS_SSL_DEBUG_BUF( 3, "my signature",
|
||||
ssl->out_msg + ssl->out_msglen,
|
||||
signature_len );
|
||||
|
||||
/* Skip over the already-written signature */
|
||||
ssl->out_msglen += signature_len;
|
||||
}
|
||||
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
||||
|
||||
/* Add header and send. */
|
||||
ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
|
||||
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
|
||||
|
||||
@ -3197,7 +3314,6 @@ curve_matching_done:
|
||||
}
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
@ -3272,28 +3388,50 @@ static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char *
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
|
||||
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *p,
|
||||
const unsigned char *end,
|
||||
size_t pms_offset )
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
|
||||
unsigned char *peer_pms,
|
||||
size_t *peer_pmslen,
|
||||
size_t peer_pmssize )
|
||||
{
|
||||
int ret = ssl->conf->f_async_resume( ssl,
|
||||
peer_pms, peer_pmslen, peer_pmssize );
|
||||
if( ret != MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
|
||||
{
|
||||
ssl->handshake->async_in_progress = 0;
|
||||
mbedtls_ssl_set_async_operation_data( ssl, NULL );
|
||||
}
|
||||
MBEDTLS_SSL_DEBUG_RET( 2, "ssl_decrypt_encrypted_pms", ret );
|
||||
return( ret );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *p,
|
||||
const unsigned char *end,
|
||||
unsigned char *peer_pms,
|
||||
size_t *peer_pmslen,
|
||||
size_t peer_pmssize )
|
||||
{
|
||||
int ret;
|
||||
size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) );
|
||||
unsigned char *pms = ssl->handshake->premaster + pms_offset;
|
||||
unsigned char ver[2];
|
||||
unsigned char fake_pms[48], peer_pms[48];
|
||||
unsigned char mask;
|
||||
size_t i, peer_pmslen;
|
||||
unsigned int diff;
|
||||
mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
|
||||
mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
|
||||
size_t len = mbedtls_pk_get_len( public_key );
|
||||
|
||||
if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) )
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
/* If we have already started decoding the message and there is an ongoing
|
||||
* decryption operation, resume signing. */
|
||||
if( ssl->handshake->async_in_progress != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
|
||||
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) );
|
||||
return( ssl_resume_decrypt_pms( ssl,
|
||||
peer_pms, peer_pmslen, peer_pmssize ) );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
/*
|
||||
* Decrypt the premaster using own private RSA key
|
||||
* Prepare to decrypt the premaster using own private RSA key
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
@ -3314,30 +3452,120 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
|
||||
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
|
||||
}
|
||||
|
||||
/*
|
||||
* Decrypt the premaster secret
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( ssl->conf->f_async_decrypt_start != NULL )
|
||||
{
|
||||
ret = ssl->conf->f_async_decrypt_start( ssl,
|
||||
mbedtls_ssl_own_cert( ssl ),
|
||||
p, len );
|
||||
switch( ret )
|
||||
{
|
||||
case MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH:
|
||||
/* act as if f_async_decrypt_start was null */
|
||||
break;
|
||||
case 0:
|
||||
ssl->handshake->async_in_progress = 1;
|
||||
return( ssl_resume_decrypt_pms( ssl,
|
||||
peer_pms,
|
||||
peer_pmslen,
|
||||
peer_pmssize ) );
|
||||
case MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS:
|
||||
ssl->handshake->async_in_progress = 1;
|
||||
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
|
||||
default:
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "f_async_decrypt_start", ret );
|
||||
return( ret );
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
if( ! mbedtls_pk_can_do( private_key, MBEDTLS_PK_RSA ) )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) );
|
||||
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
|
||||
}
|
||||
|
||||
ret = mbedtls_pk_decrypt( private_key, p, len,
|
||||
peer_pms, peer_pmslen, peer_pmssize,
|
||||
ssl->conf->f_rng, ssl->conf->p_rng );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
|
||||
const unsigned char *p,
|
||||
const unsigned char *end,
|
||||
size_t pms_offset )
|
||||
{
|
||||
int ret;
|
||||
unsigned char *pms = ssl->handshake->premaster + pms_offset;
|
||||
unsigned char ver[2];
|
||||
unsigned char fake_pms[48], peer_pms[48];
|
||||
unsigned char mask;
|
||||
size_t i, peer_pmslen;
|
||||
unsigned int diff;
|
||||
|
||||
/* In case of a failure in decryption, the decryption may write less than
|
||||
* 2 bytes of output, but we always read the first two bytes. It doesn't
|
||||
* matter in the end because diff will be nonzero in that case due to
|
||||
* peer_pmslen being less than 48, and we only care whether diff is 0.
|
||||
* But do initialize peer_pms for robustness anyway. This also makes
|
||||
* memory analyzers happy (don't access uninitialized memory, even
|
||||
* if it's an unsigned char). */
|
||||
peer_pms[0] = peer_pms[1] = ~0;
|
||||
|
||||
ret = ssl_decrypt_encrypted_pms( ssl, p, end,
|
||||
peer_pms,
|
||||
&peer_pmslen,
|
||||
sizeof( peer_pms ) );
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if ( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS )
|
||||
return( ret );
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
|
||||
ssl->handshake->max_minor_ver,
|
||||
ssl->conf->transport, ver );
|
||||
ssl->handshake->max_minor_ver,
|
||||
ssl->conf->transport, ver );
|
||||
|
||||
/* Avoid data-dependent branches while checking for invalid
|
||||
* padding, to protect against timing-based Bleichenbacher-type
|
||||
* attacks. */
|
||||
diff = (unsigned int) ret;
|
||||
diff |= peer_pmslen ^ 48;
|
||||
diff |= peer_pms[0] ^ ver[0];
|
||||
diff |= peer_pms[1] ^ ver[1];
|
||||
|
||||
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
|
||||
/* MSVC has a warning about unary minus on unsigned, but this is
|
||||
* well-defined and precisely what we want to do here */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
|
||||
* must not cause the connection to end immediately; instead, send a
|
||||
* bad_record_mac later in the handshake.
|
||||
* Also, avoid data-dependant branches here to protect against
|
||||
* timing-based variants.
|
||||
* To protect against timing-based variants of the attack, we must
|
||||
* not have any branch that depends on whether the decryption was
|
||||
* successful. In particular, always generate the fake premaster secret,
|
||||
* regardless of whether it will ultimately influence the output or not.
|
||||
*/
|
||||
ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
|
||||
if( ret != 0 )
|
||||
{
|
||||
/* It's ok to abort on an RNG failure, since this does not reveal
|
||||
* anything about the RSA decryption. */
|
||||
return( ret );
|
||||
|
||||
ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len,
|
||||
peer_pms, &peer_pmslen,
|
||||
sizeof( peer_pms ),
|
||||
ssl->conf->f_rng, ssl->conf->p_rng );
|
||||
|
||||
diff = (unsigned int) ret;
|
||||
diff |= peer_pmslen ^ 48;
|
||||
diff |= peer_pms[0] ^ ver[0];
|
||||
diff |= peer_pms[1] ^ ver[1];
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_DEBUG_ALL)
|
||||
if( diff != 0 )
|
||||
@ -3352,18 +3580,8 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
|
||||
}
|
||||
ssl->handshake->pmslen = 48;
|
||||
|
||||
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
|
||||
/* MSVC has a warning about unary minus on unsigned, but this is
|
||||
* well-defined and precisely what we want to do here */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4146 )
|
||||
#endif
|
||||
mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) );
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
/* Set pms to either the true or the fake PMS, without
|
||||
* data-dependent branches. */
|
||||
for( i = 0; i < ssl->handshake->pmslen; i++ )
|
||||
pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] );
|
||||
|
||||
@ -3445,6 +3663,20 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
|
||||
|
||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) && \
|
||||
( defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
|
||||
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) )
|
||||
if( ( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
|
||||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) &&
|
||||
( ssl->handshake->async_in_progress != 0 ) )
|
||||
{
|
||||
/* We've already read a record and there is an asynchronous
|
||||
* operation in progress to decrypt it. So skip reading the
|
||||
* record. */
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "will resume decryption of previously-read record" ) );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
|
||||
@ -3557,6 +3789,19 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
|
||||
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
|
||||
{
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if ( ssl->handshake->async_in_progress != 0 )
|
||||
{
|
||||
/* There is an asynchronous operation in progress to
|
||||
* decrypt the encrypted premaster secret, so skip
|
||||
* directly to resuming this operation. */
|
||||
MBEDTLS_SSL_DEBUG_MSG( 3, ( "PSK identity already parsed" ) );
|
||||
/* Update p to skip the PSK identity. ssl_parse_encrypted_pms
|
||||
* won't actually use it, but maintain p anyway for robustness. */
|
||||
p += ssl->conf->psk_identity_len + 2;
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
|
||||
|
@ -5202,7 +5202,7 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl )
|
||||
/*
|
||||
* Free our handshake params
|
||||
*/
|
||||
mbedtls_ssl_handshake_free( ssl->handshake );
|
||||
mbedtls_ssl_handshake_free( ssl );
|
||||
mbedtls_free( ssl->handshake );
|
||||
ssl->handshake = NULL;
|
||||
|
||||
@ -5557,7 +5557,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
|
||||
if( ssl->session_negotiate )
|
||||
mbedtls_ssl_session_free( ssl->session_negotiate );
|
||||
if( ssl->handshake )
|
||||
mbedtls_ssl_handshake_free( ssl->handshake );
|
||||
mbedtls_ssl_handshake_free( ssl );
|
||||
|
||||
/*
|
||||
* Either the pointers are now NULL or cleared properly and can be freed.
|
||||
@ -6480,6 +6480,43 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
void mbedtls_ssl_conf_async_private_cb(
|
||||
mbedtls_ssl_config *conf,
|
||||
mbedtls_ssl_async_sign_t *f_async_sign,
|
||||
mbedtls_ssl_async_decrypt_t *f_async_decrypt,
|
||||
mbedtls_ssl_async_resume_t *f_async_resume,
|
||||
mbedtls_ssl_async_cancel_t *f_async_cancel,
|
||||
void *async_config_data )
|
||||
{
|
||||
conf->f_async_sign_start = f_async_sign;
|
||||
conf->f_async_decrypt_start = f_async_decrypt;
|
||||
conf->f_async_resume = f_async_resume;
|
||||
conf->f_async_cancel = f_async_cancel;
|
||||
conf->p_async_config_data = async_config_data;
|
||||
}
|
||||
|
||||
void *mbedtls_ssl_conf_get_async_config_data( const mbedtls_ssl_config *conf )
|
||||
{
|
||||
return( conf->p_async_config_data );
|
||||
}
|
||||
|
||||
void *mbedtls_ssl_get_async_operation_data( const mbedtls_ssl_context *ssl )
|
||||
{
|
||||
if( ssl->handshake == NULL )
|
||||
return( NULL );
|
||||
else
|
||||
return( ssl->handshake->user_async_ctx );
|
||||
}
|
||||
|
||||
void mbedtls_ssl_set_async_operation_data( mbedtls_ssl_context *ssl,
|
||||
void *ctx )
|
||||
{
|
||||
if( ssl->handshake != NULL )
|
||||
ssl->handshake->user_async_ctx = ctx;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
/*
|
||||
* SSL get accessors
|
||||
*/
|
||||
@ -7387,11 +7424,21 @@ static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert )
|
||||
}
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake )
|
||||
void mbedtls_ssl_handshake_free( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
mbedtls_ssl_handshake_params *handshake = ssl->handshake;
|
||||
|
||||
if( handshake == NULL )
|
||||
return;
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( ssl->conf->f_async_cancel != NULL && handshake->async_in_progress != 0 )
|
||||
{
|
||||
ssl->conf->f_async_cancel( ssl );
|
||||
handshake->async_in_progress = 0;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||
mbedtls_md5_free( &handshake->fin_md5 );
|
||||
@ -7522,7 +7569,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
|
||||
|
||||
if( ssl->handshake )
|
||||
{
|
||||
mbedtls_ssl_handshake_free( ssl->handshake );
|
||||
mbedtls_ssl_handshake_free( ssl );
|
||||
mbedtls_ssl_transform_free( ssl->transform_negotiate );
|
||||
mbedtls_ssl_session_free( ssl->session_negotiate );
|
||||
|
||||
@ -8289,13 +8336,14 @@ exit:
|
||||
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
||||
unsigned char *output,
|
||||
unsigned char *data, size_t data_len,
|
||||
mbedtls_md_type_t md_alg )
|
||||
unsigned char *hash, size_t *hashlen,
|
||||
unsigned char *data, size_t data_len,
|
||||
mbedtls_md_type_t md_alg )
|
||||
{
|
||||
int ret = 0;
|
||||
mbedtls_md_context_t ctx;
|
||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
|
||||
*hashlen = mbedtls_md_get_size( md_info );
|
||||
|
||||
mbedtls_md_init( &ctx );
|
||||
|
||||
@ -8326,7 +8374,7 @@ int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
|
||||
goto exit;
|
||||
}
|
||||
if( ( ret = mbedtls_md_finish( &ctx, output ) ) != 0 )
|
||||
if( ( ret = mbedtls_md_finish( &ctx, hash ) ) != 0 )
|
||||
{
|
||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
|
||||
goto exit;
|
||||
|
@ -411,6 +411,9 @@ static const char *features[] = {
|
||||
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
|
||||
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
|
||||
#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
"MBEDTLS_SSL_ASYNC_PRIVATE",
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
#if defined(MBEDTLS_SSL_DEBUG_ALL)
|
||||
"MBEDTLS_SSL_DEBUG_ALL",
|
||||
#endif /* MBEDTLS_SSL_DEBUG_ALL */
|
||||
|
@ -109,6 +109,10 @@ int main( void )
|
||||
#define DFL_KEY_FILE ""
|
||||
#define DFL_CRT_FILE2 ""
|
||||
#define DFL_KEY_FILE2 ""
|
||||
#define DFL_ASYNC_OPERATIONS "-"
|
||||
#define DFL_ASYNC_PRIVATE_DELAY1 ( -1 )
|
||||
#define DFL_ASYNC_PRIVATE_DELAY2 ( -1 )
|
||||
#define DFL_ASYNC_PRIVATE_ERROR ( 0 )
|
||||
#define DFL_PSK ""
|
||||
#define DFL_PSK_IDENTITY "Client_identity"
|
||||
#define DFL_ECJPAKE_PW NULL
|
||||
@ -196,6 +200,18 @@ int main( void )
|
||||
#define USAGE_IO ""
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
#define USAGE_SSL_ASYNC \
|
||||
" async_operations=%%c... d=decrypt, s=sign (default: -=off)\n" \
|
||||
" async_private_delay1=%%d Asynchronous delay for key_file or preloaded key\n" \
|
||||
" async_private_delay2=%%d Asynchronous delay for key_file2 and sni\n" \
|
||||
" default: -1 (not asynchronous)\n" \
|
||||
" async_private_error=%%d Async callback error injection (default=0=none,\n" \
|
||||
" 1=start, 2=cancel, 3=resume, negative=first time only)"
|
||||
#else
|
||||
#define USAGE_SSL_ASYNC ""
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
||||
#define USAGE_PSK \
|
||||
" psk=%%s default: \"\" (in hex, without 0x)\n" \
|
||||
@ -346,6 +362,7 @@ int main( void )
|
||||
" cert_req_ca_list=%%d default: 1 (send ca list)\n" \
|
||||
" options: 1 (send ca list), 0 (don't send)\n" \
|
||||
USAGE_IO \
|
||||
USAGE_SSL_ASYNC \
|
||||
USAGE_SNI \
|
||||
"\n" \
|
||||
USAGE_PSK \
|
||||
@ -410,6 +427,10 @@ struct options
|
||||
const char *key_file; /* the file with the server key */
|
||||
const char *crt_file2; /* the file with the 2nd server certificate */
|
||||
const char *key_file2; /* the file with the 2nd server key */
|
||||
const char *async_operations; /* supported SSL asynchronous operations */
|
||||
int async_private_delay1; /* number of times f_async_resume needs to be called for key 1, or -1 for no async */
|
||||
int async_private_delay2; /* number of times f_async_resume needs to be called for key 2, or -1 for no async */
|
||||
int async_private_error; /* inject error in async private callback */
|
||||
const char *psk; /* the pre-shared key */
|
||||
const char *psk_identity; /* the pre-shared key identity */
|
||||
char *psk_list; /* list of PSK id/key pairs for callback */
|
||||
@ -841,6 +862,243 @@ static int ssl_sig_hashes_for_test[] = {
|
||||
};
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
/** Return true if \p ret is a status code indicating that there is an
|
||||
* operation in progress on an SSL connection, and false if it indicates
|
||||
* success or a fatal error.
|
||||
*
|
||||
* The possible operations in progress are:
|
||||
*
|
||||
* - A read, when the SSL input buffer does not contain a full message.
|
||||
* - A write, when the SSL output buffer contains some data that has not
|
||||
* been sent over the network yet.
|
||||
* - An asynchronous callback that has not completed yet. */
|
||||
static int mbedtls_status_is_ssl_in_progress( int ret )
|
||||
{
|
||||
return( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
|
||||
ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
typedef struct
|
||||
{
|
||||
mbedtls_x509_crt *cert; /*!< Certificate corresponding to the key */
|
||||
mbedtls_pk_context *pk; /*!< Private key */
|
||||
unsigned delay; /*!< Number of resume steps to go through */
|
||||
unsigned pk_owned : 1; /*!< Whether to free the pk object on exit */
|
||||
} ssl_async_key_slot_t;
|
||||
|
||||
typedef enum {
|
||||
SSL_ASYNC_INJECT_ERROR_NONE = 0, /*!< Let the callbacks succeed */
|
||||
SSL_ASYNC_INJECT_ERROR_START, /*!< Inject error during start */
|
||||
SSL_ASYNC_INJECT_ERROR_CANCEL, /*!< Close the connection after async start */
|
||||
SSL_ASYNC_INJECT_ERROR_RESUME, /*!< Inject error during resume */
|
||||
#define SSL_ASYNC_INJECT_ERROR_MAX SSL_ASYNC_INJECT_ERROR_RESUME
|
||||
} ssl_async_inject_error_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ssl_async_key_slot_t slots[4]; /* key, key2, sni1, sni2 */
|
||||
size_t slots_used;
|
||||
ssl_async_inject_error_t inject_error;
|
||||
int (*f_rng)(void *, unsigned char *, size_t);
|
||||
void *p_rng;
|
||||
} ssl_async_key_context_t;
|
||||
|
||||
int ssl_async_set_key( ssl_async_key_context_t *ctx,
|
||||
mbedtls_x509_crt *cert,
|
||||
mbedtls_pk_context *pk,
|
||||
int pk_take_ownership,
|
||||
unsigned delay )
|
||||
{
|
||||
if( ctx->slots_used >= sizeof( ctx->slots ) / sizeof( *ctx->slots ) )
|
||||
return( -1 );
|
||||
ctx->slots[ctx->slots_used].cert = cert;
|
||||
ctx->slots[ctx->slots_used].pk = pk;
|
||||
ctx->slots[ctx->slots_used].delay = delay;
|
||||
ctx->slots[ctx->slots_used].pk_owned = pk_take_ownership;
|
||||
++ctx->slots_used;
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define SSL_ASYNC_INPUT_MAX_SIZE 512
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ASYNC_OP_SIGN,
|
||||
ASYNC_OP_DECRYPT,
|
||||
} ssl_async_operation_type_t;
|
||||
/* Note that the enum above and the array below need to be kept in sync!
|
||||
* `ssl_async_operation_names[op]` is the name of op for each value `op`
|
||||
* of type `ssl_async_operation_type_t`. */
|
||||
static const char *const ssl_async_operation_names[] =
|
||||
{
|
||||
"sign",
|
||||
"decrypt",
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned slot;
|
||||
ssl_async_operation_type_t operation_type;
|
||||
mbedtls_md_type_t md_alg;
|
||||
unsigned char input[SSL_ASYNC_INPUT_MAX_SIZE];
|
||||
size_t input_len;
|
||||
unsigned remaining_delay;
|
||||
} ssl_async_operation_context_t;
|
||||
|
||||
static int ssl_async_start( mbedtls_ssl_context *ssl,
|
||||
mbedtls_x509_crt *cert,
|
||||
ssl_async_operation_type_t op_type,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *input,
|
||||
size_t input_len )
|
||||
{
|
||||
ssl_async_key_context_t *config_data =
|
||||
mbedtls_ssl_conf_get_async_config_data( ssl->conf );
|
||||
unsigned slot;
|
||||
ssl_async_operation_context_t *ctx = NULL;
|
||||
const char *op_name = ssl_async_operation_names[op_type];
|
||||
|
||||
{
|
||||
char dn[100];
|
||||
mbedtls_x509_dn_gets( dn, sizeof( dn ), &cert->subject );
|
||||
mbedtls_printf( "Async %s callback: looking for DN=%s\n", op_name, dn );
|
||||
}
|
||||
|
||||
/* Look for a private key that matches the public key in cert.
|
||||
* Since this test code has the private key inside Mbed TLS,
|
||||
* we call mbedtls_pk_check_pair to match a private key with the
|
||||
* public key. */
|
||||
for( slot = 0; slot < config_data->slots_used; slot++ )
|
||||
{
|
||||
if( mbedtls_pk_check_pair( &cert->pk,
|
||||
config_data->slots[slot].pk ) == 0 )
|
||||
break;
|
||||
}
|
||||
if( slot == config_data->slots_used )
|
||||
{
|
||||
mbedtls_printf( "Async %s callback: no key matches this certificate.\n",
|
||||
op_name );
|
||||
return( MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH );
|
||||
}
|
||||
mbedtls_printf( "Async %s callback: using key slot %u, delay=%u.\n",
|
||||
op_name, slot, config_data->slots[slot].delay );
|
||||
|
||||
if( config_data->inject_error == SSL_ASYNC_INJECT_ERROR_START )
|
||||
{
|
||||
mbedtls_printf( "Async %s callback: injected error\n", op_name );
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
if( input_len > SSL_ASYNC_INPUT_MAX_SIZE )
|
||||
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
|
||||
|
||||
ctx = mbedtls_calloc( 1, sizeof( *ctx ) );
|
||||
if( ctx == NULL )
|
||||
return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
|
||||
ctx->slot = slot;
|
||||
ctx->operation_type = op_type;
|
||||
ctx->md_alg = md_alg;
|
||||
memcpy( ctx->input, input, input_len );
|
||||
ctx->input_len = input_len;
|
||||
ctx->remaining_delay = config_data->slots[slot].delay;
|
||||
mbedtls_ssl_set_async_operation_data( ssl, ctx );
|
||||
|
||||
if( ctx->remaining_delay == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
|
||||
}
|
||||
|
||||
static int ssl_async_sign( mbedtls_ssl_context *ssl,
|
||||
mbedtls_x509_crt *cert,
|
||||
mbedtls_md_type_t md_alg,
|
||||
const unsigned char *hash,
|
||||
size_t hash_len )
|
||||
{
|
||||
return( ssl_async_start( ssl, cert,
|
||||
ASYNC_OP_SIGN, md_alg,
|
||||
hash, hash_len ) );
|
||||
}
|
||||
|
||||
static int ssl_async_decrypt( mbedtls_ssl_context *ssl,
|
||||
mbedtls_x509_crt *cert,
|
||||
const unsigned char *input,
|
||||
size_t input_len )
|
||||
{
|
||||
return( ssl_async_start( ssl, cert,
|
||||
ASYNC_OP_DECRYPT, MBEDTLS_MD_NONE,
|
||||
input, input_len ) );
|
||||
}
|
||||
|
||||
static int ssl_async_resume( mbedtls_ssl_context *ssl,
|
||||
unsigned char *output,
|
||||
size_t *output_len,
|
||||
size_t output_size )
|
||||
{
|
||||
ssl_async_operation_context_t *ctx = mbedtls_ssl_get_async_operation_data( ssl );
|
||||
ssl_async_key_context_t *config_data =
|
||||
mbedtls_ssl_conf_get_async_config_data( ssl->conf );
|
||||
ssl_async_key_slot_t *key_slot = &config_data->slots[ctx->slot];
|
||||
int ret;
|
||||
const char *op_name;
|
||||
|
||||
if( ctx->remaining_delay > 0 )
|
||||
{
|
||||
--ctx->remaining_delay;
|
||||
mbedtls_printf( "Async resume (slot %u): call %u more times.\n",
|
||||
ctx->slot, ctx->remaining_delay );
|
||||
return( MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS );
|
||||
}
|
||||
|
||||
switch( ctx->operation_type )
|
||||
{
|
||||
case ASYNC_OP_DECRYPT:
|
||||
ret = mbedtls_pk_decrypt( key_slot->pk,
|
||||
ctx->input, ctx->input_len,
|
||||
output, output_len, output_size,
|
||||
config_data->f_rng, config_data->p_rng );
|
||||
break;
|
||||
case ASYNC_OP_SIGN:
|
||||
ret = mbedtls_pk_sign( key_slot->pk,
|
||||
ctx->md_alg,
|
||||
ctx->input, ctx->input_len,
|
||||
output, output_len,
|
||||
config_data->f_rng, config_data->p_rng );
|
||||
break;
|
||||
default:
|
||||
mbedtls_printf( "Async resume (slot %u): unknown operation type %ld. This shouldn't happen.\n",
|
||||
ctx->slot, (long) ctx->operation_type );
|
||||
mbedtls_free( ctx );
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||
break;
|
||||
}
|
||||
|
||||
op_name = ssl_async_operation_names[ctx->operation_type];
|
||||
|
||||
if( config_data->inject_error == SSL_ASYNC_INJECT_ERROR_RESUME )
|
||||
{
|
||||
mbedtls_printf( "Async resume callback: %s done but injected error\n",
|
||||
op_name );
|
||||
mbedtls_free( ctx );
|
||||
return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
mbedtls_printf( "Async resume (slot %u): %s done, status=%d.\n",
|
||||
ctx->slot, op_name, ret );
|
||||
mbedtls_free( ctx );
|
||||
return( ret );
|
||||
}
|
||||
|
||||
static void ssl_async_cancel( mbedtls_ssl_context *ssl )
|
||||
{
|
||||
ssl_async_operation_context_t *ctx = mbedtls_ssl_get_async_operation_data( ssl );
|
||||
mbedtls_printf( "Async cancel callback.\n" );
|
||||
mbedtls_free( ctx );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
/*
|
||||
* Wait for an event from the underlying transport or the timer
|
||||
* (Used in event-driven IO mode).
|
||||
@ -929,7 +1187,10 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_x509_crt srvcert2;
|
||||
mbedtls_pk_context pkey2;
|
||||
int key_cert_init = 0, key_cert_init2 = 0;
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
ssl_async_key_context_t ssl_async_keys;
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
|
||||
mbedtls_dhm_context dhm;
|
||||
#endif
|
||||
@ -975,6 +1236,9 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_pk_init( &pkey );
|
||||
mbedtls_x509_crt_init( &srvcert2 );
|
||||
mbedtls_pk_init( &pkey2 );
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
memset( &ssl_async_keys, 0, sizeof( ssl_async_keys ) );
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
|
||||
mbedtls_dhm_init( &dhm );
|
||||
@ -1032,6 +1296,10 @@ int main( int argc, char *argv[] )
|
||||
opt.key_file = DFL_KEY_FILE;
|
||||
opt.crt_file2 = DFL_CRT_FILE2;
|
||||
opt.key_file2 = DFL_KEY_FILE2;
|
||||
opt.async_operations = DFL_ASYNC_OPERATIONS;
|
||||
opt.async_private_delay1 = DFL_ASYNC_PRIVATE_DELAY1;
|
||||
opt.async_private_delay2 = DFL_ASYNC_PRIVATE_DELAY2;
|
||||
opt.async_private_error = DFL_ASYNC_PRIVATE_ERROR;
|
||||
opt.psk = DFL_PSK;
|
||||
opt.psk_identity = DFL_PSK_IDENTITY;
|
||||
opt.psk_list = DFL_PSK_LIST;
|
||||
@ -1124,6 +1392,25 @@ int main( int argc, char *argv[] )
|
||||
opt.key_file2 = q;
|
||||
else if( strcmp( p, "dhm_file" ) == 0 )
|
||||
opt.dhm_file = q;
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
else if( strcmp( p, "async_operations" ) == 0 )
|
||||
opt.async_operations = q;
|
||||
else if( strcmp( p, "async_private_delay1" ) == 0 )
|
||||
opt.async_private_delay1 = atoi( q );
|
||||
else if( strcmp( p, "async_private_delay2" ) == 0 )
|
||||
opt.async_private_delay2 = atoi( q );
|
||||
else if( strcmp( p, "async_private_error" ) == 0 )
|
||||
{
|
||||
int n = atoi( q );
|
||||
if( n < -SSL_ASYNC_INJECT_ERROR_MAX ||
|
||||
n > SSL_ASYNC_INJECT_ERROR_MAX )
|
||||
{
|
||||
ret = 2;
|
||||
goto usage;
|
||||
}
|
||||
opt.async_private_error = n;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
else if( strcmp( p, "psk" ) == 0 )
|
||||
opt.psk = q;
|
||||
else if( strcmp( p, "psk_identity" ) == 0 )
|
||||
@ -2018,22 +2305,109 @@ int main( int argc, char *argv[] )
|
||||
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
|
||||
}
|
||||
if( key_cert_init )
|
||||
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 )
|
||||
{
|
||||
mbedtls_pk_context *pk = &pkey;
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( opt.async_private_delay1 >= 0 )
|
||||
{
|
||||
ret = ssl_async_set_key( &ssl_async_keys, &srvcert, pk, 0,
|
||||
opt.async_private_delay1 );
|
||||
if( ret < 0 )
|
||||
{
|
||||
mbedtls_printf( " Test error: ssl_async_set_key failed (%d)\n",
|
||||
ret );
|
||||
goto exit;
|
||||
}
|
||||
pk = NULL;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, pk ) ) != 0 )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if( key_cert_init2 )
|
||||
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert2, &pkey2 ) ) != 0 )
|
||||
{
|
||||
mbedtls_pk_context *pk = &pkey2;
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( opt.async_private_delay2 >= 0 )
|
||||
{
|
||||
ret = ssl_async_set_key( &ssl_async_keys, &srvcert2, pk, 0,
|
||||
opt.async_private_delay2 );
|
||||
if( ret < 0 )
|
||||
{
|
||||
mbedtls_printf( " Test error: ssl_async_set_key failed (%d)\n",
|
||||
ret );
|
||||
goto exit;
|
||||
}
|
||||
pk = NULL;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert2, pk ) ) != 0 )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( opt.async_operations[0] != '-' )
|
||||
{
|
||||
mbedtls_ssl_async_sign_t *sign = NULL;
|
||||
mbedtls_ssl_async_decrypt_t *decrypt = NULL;
|
||||
const char *r;
|
||||
for( r = opt.async_operations; *r; r++ )
|
||||
{
|
||||
switch( *r )
|
||||
{
|
||||
case 'd':
|
||||
decrypt = ssl_async_decrypt;
|
||||
break;
|
||||
case 's':
|
||||
sign = ssl_async_sign;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ssl_async_keys.inject_error = ( opt.async_private_error < 0 ?
|
||||
- opt.async_private_error :
|
||||
opt.async_private_error );
|
||||
ssl_async_keys.f_rng = mbedtls_ctr_drbg_random;
|
||||
ssl_async_keys.p_rng = &ctr_drbg;
|
||||
mbedtls_ssl_conf_async_private_cb( &conf,
|
||||
sign,
|
||||
decrypt,
|
||||
ssl_async_resume,
|
||||
ssl_async_cancel,
|
||||
&ssl_async_keys );
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||
|
||||
#if defined(SNI_OPTION)
|
||||
if( opt.sni != NULL )
|
||||
{
|
||||
mbedtls_ssl_conf_sni( &conf, sni_callback, sni_info );
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( opt.async_private_delay2 >= 0 )
|
||||
{
|
||||
sni_entry *cur;
|
||||
for( cur = sni_info; cur != NULL; cur = cur->next )
|
||||
{
|
||||
ret = ssl_async_set_key( &ssl_async_keys,
|
||||
cur->cert, cur->key, 1,
|
||||
opt.async_private_delay2 );
|
||||
if( ret < 0 )
|
||||
{
|
||||
mbedtls_printf( " Test error: ssl_async_set_key failed (%d)\n",
|
||||
ret );
|
||||
goto exit;
|
||||
}
|
||||
cur->key = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_ECP_C)
|
||||
@ -2205,8 +2579,16 @@ handshake:
|
||||
|
||||
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
|
||||
{
|
||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS &&
|
||||
ssl_async_keys.inject_error == SSL_ASYNC_INJECT_ERROR_CANCEL )
|
||||
{
|
||||
mbedtls_printf( " cancelling on injected error\n" );
|
||||
break;
|
||||
}
|
||||
#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */
|
||||
|
||||
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||
break;
|
||||
|
||||
/* For event-driven IO, wait for socket to become available */
|
||||
@ -2244,6 +2626,11 @@ handshake:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
if( opt.async_private_error < 0 )
|
||||
/* Injected error only the first time round, to test reset */
|
||||
ssl_async_keys.inject_error = SSL_ASYNC_INJECT_ERROR_NONE;
|
||||
#endif
|
||||
goto reset;
|
||||
}
|
||||
else /* ret == 0 */
|
||||
@ -2324,8 +2711,7 @@ data_exchange:
|
||||
memset( buf, 0, sizeof( buf ) );
|
||||
ret = mbedtls_ssl_read( &ssl, buf, len );
|
||||
|
||||
if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
||||
ret == MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
if( mbedtls_status_is_ssl_in_progress( ret ) )
|
||||
{
|
||||
if( opt.event == 1 /* level triggered IO */ )
|
||||
{
|
||||
@ -2425,7 +2811,7 @@ data_exchange:
|
||||
len = sizeof( buf ) - 1;
|
||||
memset( buf, 0, sizeof( buf ) );
|
||||
|
||||
while( 1 )
|
||||
do
|
||||
{
|
||||
/* Without the call to `mbedtls_ssl_check_pending`, it might
|
||||
* happen that the client sends application data in the same
|
||||
@ -2455,10 +2841,8 @@ data_exchange:
|
||||
* it can happen that the subsequent call to `mbedtls_ssl_read`
|
||||
* returns `MBEDTLS_ERR_SSL_WANT_READ`, because the pending messages
|
||||
* might be discarded (e.g. because they are retransmissions). */
|
||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
break;
|
||||
}
|
||||
while( mbedtls_status_is_ssl_in_progress( ret ) );
|
||||
|
||||
if( ret <= 0 )
|
||||
{
|
||||
@ -2493,8 +2877,7 @@ data_exchange:
|
||||
|
||||
while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
|
||||
{
|
||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
|
||||
goto reset;
|
||||
@ -2537,8 +2920,7 @@ data_exchange:
|
||||
goto reset;
|
||||
}
|
||||
|
||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||
{
|
||||
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
|
||||
goto reset;
|
||||
@ -2562,8 +2944,7 @@ data_exchange:
|
||||
{
|
||||
ret = mbedtls_ssl_write( &ssl, buf, len );
|
||||
|
||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
||||
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||
break;
|
||||
|
||||
/* For event-driven IO, wait for socket to become available */
|
||||
@ -2641,6 +3022,17 @@ exit:
|
||||
mbedtls_x509_crt_free( &srvcert2 );
|
||||
mbedtls_pk_free( &pkey2 );
|
||||
#endif
|
||||
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||
for( i = 0; (size_t) i < ssl_async_keys.slots_used; i++ )
|
||||
{
|
||||
if( ssl_async_keys.slots[i].pk_owned )
|
||||
{
|
||||
mbedtls_pk_free( ssl_async_keys.slots[i].pk );
|
||||
mbedtls_free( ssl_async_keys.slots[i].pk );
|
||||
ssl_async_keys.slots[i].pk = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(SNI_OPTION)
|
||||
sni_free( sni_info );
|
||||
#endif
|
||||
|
@ -531,8 +531,8 @@ make
|
||||
msg "test: main suites (full config)" # ~ 5s
|
||||
make test
|
||||
|
||||
msg "test: ssl-opt.sh default (full config)" # ~ 1s
|
||||
if_build_succeeded tests/ssl-opt.sh -f Default
|
||||
msg "test: ssl-opt.sh default, ECJPAKE (full config)" # ~ 1s
|
||||
if_build_succeeded tests/ssl-opt.sh -f 'Default\|ECJPAKE'
|
||||
|
||||
msg "test: compat.sh RC4, DES & NULL (full config)" # ~ 2 min
|
||||
if_build_succeeded env OPENSSL_CMD="$OPENSSL_LEGACY" GNUTLS_CLI="$GNUTLS_LEGACY_CLI" GNUTLS_SERV="$GNUTLS_LEGACY_SERV" tests/compat.sh -e '3DES\|DES-CBC3' -f 'NULL\|DES\|RC4\|ARCFOUR'
|
||||
|
348
tests/ssl-opt.sh
348
tests/ssl-opt.sh
@ -4067,6 +4067,354 @@ run_test "Large packet TLS 1.2 AEAD shorter tag" \
|
||||
-c "16384 bytes written in 1 fragments" \
|
||||
-s "Read from client: 16384 bytes read"
|
||||
|
||||
# Tests of asynchronous private key support in SSL
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, delay=0" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=0 async_private_delay2=0" \
|
||||
"$P_CLI" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, delay=1" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1" \
|
||||
"$P_CLI" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): call 0 more times." \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, delay=2" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=2 async_private_delay2=2" \
|
||||
"$P_CLI" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-U "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): call 1 more times." \
|
||||
-s "Async resume (slot [0-9]): call 0 more times." \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0"
|
||||
|
||||
# Test that the async callback correctly signs the 36-byte hash of TLS 1.0/1.1
|
||||
# with RSA PKCS#1v1.5 as used in TLS 1.0/1.1.
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_1
|
||||
run_test "SSL async private: sign, RSA, TLS 1.1" \
|
||||
"$P_SRV key_file=data_files/server2.key crt_file=data_files/server2.crt \
|
||||
async_operations=s async_private_delay1=0 async_private_delay2=0" \
|
||||
"$P_CLI force_version=tls1_1" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, SNI" \
|
||||
"$P_SRV debug_level=3 \
|
||||
async_operations=s async_private_delay1=0 async_private_delay2=0 \
|
||||
crt_file=data_files/server5.crt key_file=data_files/server5.key \
|
||||
sni=localhost,data_files/server2.crt,data_files/server2.key,-,-,-,polarssl.example,data_files/server1-nospace.crt,data_files/server1.key,-,-,-" \
|
||||
"$P_CLI server_name=polarssl.example" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0" \
|
||||
-s "parse ServerName extension" \
|
||||
-c "issuer name *: C=NL, O=PolarSSL, CN=PolarSSL Test CA" \
|
||||
-c "subject name *: C=NL, O=PolarSSL, CN=polarssl.example"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt, delay=0" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=0 async_private_delay2=0" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
0 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt, delay=1" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
0 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): call 0 more times." \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt RSA-PSK, delay=0" \
|
||||
"$P_SRV psk=abc123 \
|
||||
async_operations=d async_private_delay1=0 async_private_delay2=0" \
|
||||
"$P_CLI psk=abc123 \
|
||||
force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt RSA-PSK, delay=1" \
|
||||
"$P_SRV psk=abc123 \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1" \
|
||||
"$P_CLI psk=abc123 \
|
||||
force_ciphersuite=TLS-RSA-PSK-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): call 0 more times." \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign callback not present" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1" \
|
||||
"$P_CLI; [ \$? -eq 1 ] &&
|
||||
$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
0 \
|
||||
-S "Async sign callback" \
|
||||
-s "! mbedtls_ssl_handshake returned" \
|
||||
-s "The own private key or pre-shared key is not set, but needed" \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0" \
|
||||
-s "Successful connection"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt callback not present" \
|
||||
"$P_SRV debug_level=1 \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA;
|
||||
[ \$? -eq 1 ] && $P_CLI" \
|
||||
0 \
|
||||
-S "Async decrypt callback" \
|
||||
-s "! mbedtls_ssl_handshake returned" \
|
||||
-s "got no RSA private key" \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0" \
|
||||
-s "Successful connection"
|
||||
|
||||
# key1: ECDSA, key2: RSA; use key1 from slot 0
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: slot 0 used with key1" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 \
|
||||
key_file=data_files/server5.key crt_file=data_files/server5.crt \
|
||||
key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
|
||||
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot 0," \
|
||||
-s "Async resume (slot 0): call 0 more times." \
|
||||
-s "Async resume (slot 0): sign done, status=0"
|
||||
|
||||
# key1: ECDSA, key2: RSA; use key2 from slot 0
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: slot 0 used with key2" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay2=1 \
|
||||
key_file=data_files/server5.key crt_file=data_files/server5.crt \
|
||||
key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
|
||||
"$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot 0," \
|
||||
-s "Async resume (slot 0): call 0 more times." \
|
||||
-s "Async resume (slot 0): sign done, status=0"
|
||||
|
||||
# key1: ECDSA, key2: RSA; use key2 from slot 1
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: slot 1 used with key2" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
key_file=data_files/server5.key crt_file=data_files/server5.crt \
|
||||
key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
|
||||
"$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot 1," \
|
||||
-s "Async resume (slot 1): call 0 more times." \
|
||||
-s "Async resume (slot 1): sign done, status=0"
|
||||
|
||||
# key1: ECDSA, key2: RSA; use key2 directly
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: fall back to transparent key" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 \
|
||||
key_file=data_files/server5.key crt_file=data_files/server5.crt \
|
||||
key_file2=data_files/server2.key crt_file2=data_files/server2.crt " \
|
||||
"$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async sign callback: no key matches this certificate."
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, error in start" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=1" \
|
||||
"$P_CLI" \
|
||||
1 \
|
||||
-s "Async sign callback: injected error" \
|
||||
-S "Async resume" \
|
||||
-S "Async cancel" \
|
||||
-s "! mbedtls_ssl_handshake returned"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, cancel after start" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=2" \
|
||||
"$P_CLI" \
|
||||
1 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-S "Async resume" \
|
||||
-s "Async cancel"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, error in resume" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=3" \
|
||||
"$P_CLI" \
|
||||
1 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume callback: sign done but injected error" \
|
||||
-S "Async cancel" \
|
||||
-s "! mbedtls_ssl_handshake returned"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt, error in start" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=1" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
1 \
|
||||
-s "Async decrypt callback: injected error" \
|
||||
-S "Async resume" \
|
||||
-S "Async cancel" \
|
||||
-s "! mbedtls_ssl_handshake returned"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt, cancel after start" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=2" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
1 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-S "Async resume" \
|
||||
-s "Async cancel"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: decrypt, error in resume" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=3" \
|
||||
"$P_CLI force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
1 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume callback: decrypt done but injected error" \
|
||||
-S "Async cancel" \
|
||||
-s "! mbedtls_ssl_handshake returned"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: cancel after start then operate correctly" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=-2" \
|
||||
"$P_CLI; [ \$? -eq 1 ] && $P_CLI" \
|
||||
0 \
|
||||
-s "Async cancel" \
|
||||
-s "! mbedtls_ssl_handshake returned" \
|
||||
-s "Async resume" \
|
||||
-s "Successful connection"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: error in resume then operate correctly" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
async_private_error=-3" \
|
||||
"$P_CLI; [ \$? -eq 1 ] && $P_CLI" \
|
||||
0 \
|
||||
-s "! mbedtls_ssl_handshake returned" \
|
||||
-s "Async resume" \
|
||||
-s "Successful connection"
|
||||
|
||||
# key1: ECDSA, key2: RSA; use key1 through async, then key2 directly
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: cancel after start then fall back to transparent key" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_error=-2 \
|
||||
key_file=data_files/server5.key crt_file=data_files/server5.crt \
|
||||
key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
|
||||
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256;
|
||||
[ \$? -eq 1 ] &&
|
||||
$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot 0" \
|
||||
-S "Async resume" \
|
||||
-s "Async cancel" \
|
||||
-s "! mbedtls_ssl_handshake returned" \
|
||||
-s "Async sign callback: no key matches this certificate." \
|
||||
-s "Successful connection"
|
||||
|
||||
# key1: ECDSA, key2: RSA; use key1 through async, then key2 directly
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
run_test "SSL async private: sign, error in resume then fall back to transparent key" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_error=-3 \
|
||||
key_file=data_files/server5.key crt_file=data_files/server5.crt \
|
||||
key_file2=data_files/server2.key crt_file2=data_files/server2.crt" \
|
||||
"$P_CLI force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256;
|
||||
[ \$? -eq 1 ] &&
|
||||
$P_CLI force_ciphersuite=TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256" \
|
||||
0 \
|
||||
-s "Async resume" \
|
||||
-s "! mbedtls_ssl_handshake returned" \
|
||||
-s "Async sign callback: no key matches this certificate." \
|
||||
-s "Successful connection"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
|
||||
run_test "SSL async private: renegotiation: client-initiated; sign" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
exchanges=2 renegotiation=1" \
|
||||
"$P_CLI exchanges=2 renegotiation=1 renegotiate=1" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
|
||||
run_test "SSL async private: renegotiation: server-initiated; sign" \
|
||||
"$P_SRV \
|
||||
async_operations=s async_private_delay1=1 async_private_delay2=1 \
|
||||
exchanges=2 renegotiation=1 renegotiate=1" \
|
||||
"$P_CLI exchanges=2 renegotiation=1" \
|
||||
0 \
|
||||
-s "Async sign callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): sign done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
|
||||
run_test "SSL async private: renegotiation: client-initiated; decrypt" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1 \
|
||||
exchanges=2 renegotiation=1" \
|
||||
"$P_CLI exchanges=2 renegotiation=1 renegotiate=1 \
|
||||
force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
0 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0"
|
||||
|
||||
requires_config_enabled MBEDTLS_SSL_ASYNC_PRIVATE
|
||||
requires_config_enabled MBEDTLS_SSL_RENEGOTIATION
|
||||
run_test "SSL async private: renegotiation: server-initiated; decrypt" \
|
||||
"$P_SRV \
|
||||
async_operations=d async_private_delay1=1 async_private_delay2=1 \
|
||||
exchanges=2 renegotiation=1 renegotiate=1" \
|
||||
"$P_CLI exchanges=2 renegotiation=1 \
|
||||
force_ciphersuite=TLS-RSA-WITH-AES-128-CBC-SHA" \
|
||||
0 \
|
||||
-s "Async decrypt callback: using key slot " \
|
||||
-s "Async resume (slot [0-9]): decrypt done, status=0"
|
||||
|
||||
# Tests for DTLS HelloVerifyRequest
|
||||
|
||||
run_test "DTLS cookie: enabled" \
|
||||
|
Loading…
Reference in New Issue
Block a user