Merge remote-tracking branch 'public/pr/1270' into development
This commit is contained in:
commit
5f57f1e3cc
13 changed files with 1544 additions and 179 deletions
|
@ -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 CCM* block cipher mode as defined in IEEE Std. 802.15.4.
|
||||||
* Add support for the XTS block cipher mode with AES (AES-XTS).
|
* Add support for the XTS block cipher mode with AES (AES-XTS).
|
||||||
Contributed by Aorimn in pull request #414.
|
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
|
Bugfix
|
||||||
* Fix the cert_write example to handle certificates signed with elliptic
|
* Fix the cert_write example to handle certificates signed with elliptic
|
||||||
|
|
|
@ -1148,6 +1148,17 @@
|
||||||
*/
|
*/
|
||||||
#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
|
#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
|
* \def MBEDTLS_SSL_DEBUG_ALL
|
||||||
*
|
*
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
* MD 5 5
|
* MD 5 5
|
||||||
* HKDF 5 1 (Started from top)
|
* HKDF 5 1 (Started from top)
|
||||||
* CIPHER 6 8
|
* CIPHER 6 8
|
||||||
* SSL 6 17 (Started from top)
|
* SSL 6 22 (Started from top)
|
||||||
* SSL 7 31
|
* SSL 7 31
|
||||||
*
|
*
|
||||||
* Module dependent error code (5 bits 0x.00.-0x.F8.)
|
* 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_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_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_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
|
* Various constants
|
||||||
|
@ -536,7 +537,6 @@ typedef void mbedtls_ssl_set_timer_t( void * ctx,
|
||||||
*/
|
*/
|
||||||
typedef int mbedtls_ssl_get_timer_t( void * ctx );
|
typedef int mbedtls_ssl_get_timer_t( void * ctx );
|
||||||
|
|
||||||
|
|
||||||
/* Defined below */
|
/* Defined below */
|
||||||
typedef struct mbedtls_ssl_session mbedtls_ssl_session;
|
typedef struct mbedtls_ssl_session mbedtls_ssl_session;
|
||||||
typedef struct mbedtls_ssl_context mbedtls_ssl_context;
|
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;
|
typedef struct mbedtls_ssl_flight_item mbedtls_ssl_flight_item;
|
||||||
#endif
|
#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.
|
* 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 */
|
mbedtls_x509_crl *ca_crl; /*!< trusted CAs CRLs */
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
#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)
|
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
|
||||||
const int *sig_hashes; /*!< allowed signature hashes */
|
const int *sig_hashes; /*!< allowed signature hashes */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1307,6 +1529,85 @@ void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf,
|
||||||
void *p_export_keys );
|
void *p_export_keys );
|
||||||
#endif /* MBEDTLS_SSL_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
|
* \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 */
|
mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */
|
||||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||||
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
|
unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */
|
||||||
unsigned int in_msg_seq; /*!< Incoming 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)
|
#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET)
|
||||||
int extended_ms; /*!< use Extended Master Secret? */
|
int extended_ms; /*!< use Extended Master Secret? */
|
||||||
#endif
|
#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
|
* \brief Free referenced items in an SSL handshake context and clear
|
||||||
* memory
|
* 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_client_step( mbedtls_ssl_context *ssl );
|
||||||
int mbedtls_ssl_handshake_server_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) || \
|
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
||||||
unsigned char *output,
|
unsigned char *hash, size_t *hashlen,
|
||||||
unsigned char *data, size_t data_len,
|
unsigned char *data, size_t data_len,
|
||||||
mbedtls_md_type_t md_alg );
|
mbedtls_md_type_t md_alg );
|
||||||
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \
|
||||||
MBEDTLS_SSL_PROTO_TLS1_2 */
|
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" );
|
mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" );
|
||||||
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
|
if( use_ret == -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING) )
|
||||||
mbedtls_snprintf( buf, buflen, "SSL - Internal-only message signaling that further message-processing should be done" );
|
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 */
|
#endif /* MBEDTLS_SSL_TLS_C */
|
||||||
|
|
||||||
#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_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)
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
if( md_alg != MBEDTLS_MD_NONE )
|
if( md_alg != MBEDTLS_MD_NONE )
|
||||||
{
|
{
|
||||||
/* Info from md_alg will be used instead */
|
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
|
||||||
hashlen = 0;
|
params, params_len,
|
||||||
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, params,
|
md_alg );
|
||||||
params_len, md_alg );
|
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
@ -2559,8 +2558,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
|
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
|
||||||
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
|
|
||||||
|
|
||||||
if( ssl->session_negotiate->peer_cert == NULL )
|
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",
|
MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate",
|
||||||
cur->cert );
|
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" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) );
|
||||||
continue;
|
continue;
|
||||||
|
@ -733,7 +733,7 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECDSA_C)
|
#if defined(MBEDTLS_ECDSA_C)
|
||||||
if( pk_alg == MBEDTLS_PK_ECDSA &&
|
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" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) );
|
||||||
continue;
|
continue;
|
||||||
|
@ -2828,54 +2828,56 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl )
|
||||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
|
#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||
|
||||||
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_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 =
|
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
|
||||||
ssl->transform_negotiate->ciphersuite_info;
|
ssl->transform_negotiate->ciphersuite_info;
|
||||||
|
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
|
#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)
|
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||||
unsigned char *dig_signed = p;
|
unsigned char *dig_signed = NULL;
|
||||||
size_t dig_signed_len = 0;
|
|
||||||
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
#endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */
|
||||||
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_PFS__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
|
* Part 1: Provide key exchange parameters for chosen ciphersuite.
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -2885,18 +2887,21 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
|
||||||
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
|
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,
|
ret = mbedtls_ecjpake_write_round_two(
|
||||||
p, end - p, &len, ssl->conf->f_rng, ssl->conf->p_rng );
|
&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 )
|
if( ret != 0 )
|
||||||
{
|
{
|
||||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
p += len;
|
ssl->out_msglen += len;
|
||||||
n += len;
|
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */
|
#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 ||
|
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
|
||||||
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
|
ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
|
||||||
{
|
{
|
||||||
*(p++) = 0x00;
|
ssl->out_msg[ssl->out_msglen++] = 0x00;
|
||||||
*(p++) = 0x00;
|
ssl->out_msg[ssl->out_msglen++] = 0x00;
|
||||||
|
|
||||||
n += 2;
|
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
|
#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
|
||||||
MBEDTLS_KEY_EXCHANGE_ECDHE_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 defined(MBEDTLS_KEY_EXCHANGE__SOME__DHE_ENABLED)
|
||||||
if( mbedtls_ssl_ciphersuite_uses_dhe( ciphersuite_info ) )
|
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 )
|
if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL )
|
||||||
{
|
{
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) );
|
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 );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx,
|
if( ( ret = mbedtls_dhm_make_params(
|
||||||
(int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ),
|
&ssl->handshake->dhm_ctx,
|
||||||
p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
(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 );
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||||
dig_signed = p;
|
dig_signed = ssl->out_msg + ssl->out_msglen;
|
||||||
dig_signed_len = len;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p += len;
|
ssl->out_msglen += len;
|
||||||
n += len;
|
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
|
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
|
||||||
MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
|
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_curve_info **curve = NULL;
|
||||||
const mbedtls_ecp_group_id *gid;
|
const mbedtls_ecp_group_id *gid;
|
||||||
|
int ret;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
/* Match our preference list against the offered curves */
|
/* Match our preference list against the offered curves */
|
||||||
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
|
for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ )
|
||||||
|
@ -3009,21 +3017,21 @@ curve_matching_done:
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len,
|
if( ( ret = mbedtls_ecdh_make_params(
|
||||||
p, MBEDTLS_SSL_MAX_CONTENT_LEN - n,
|
&ssl->handshake->ecdh_ctx, &len,
|
||||||
ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
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 );
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||||
dig_signed = p;
|
dig_signed = ssl->out_msg + ssl->out_msglen;
|
||||||
dig_signed_len = len;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p += len;
|
ssl->out_msglen += len;
|
||||||
n += len;
|
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
|
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.
|
* exchange parameters, compute and add the signature here.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
|
||||||
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
|
if( mbedtls_ssl_ciphersuite_uses_server_signature( ciphersuite_info ) )
|
||||||
{
|
{
|
||||||
size_t signature_len = 0;
|
size_t dig_signed_len = ssl->out_msg + ssl->out_msglen - dig_signed;
|
||||||
unsigned int hashlen = 0;
|
size_t hashlen = 0;
|
||||||
unsigned char hash[64];
|
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
|
* A: For TLS 1.2, obey signature-hash-algorithm extension
|
||||||
* to choose appropriate hash.
|
* to choose appropriate hash.
|
||||||
* B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1
|
* 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 ) );
|
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) || \
|
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||||
|
@ -3110,9 +3119,7 @@ curve_matching_done:
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
if( md_alg != MBEDTLS_MD_NONE )
|
if( md_alg != MBEDTLS_MD_NONE )
|
||||||
{
|
{
|
||||||
/* Info from md_alg will be used instead */
|
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash, &hashlen,
|
||||||
hashlen = 0;
|
|
||||||
ret = mbedtls_ssl_get_key_exchange_md_tls1_2( ssl, hash,
|
|
||||||
dig_signed,
|
dig_signed,
|
||||||
dig_signed_len,
|
dig_signed_len,
|
||||||
md_alg );
|
md_alg );
|
||||||
|
@ -3127,18 +3134,11 @@ curve_matching_done:
|
||||||
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
|
||||||
}
|
}
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen :
|
MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
|
||||||
(unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) );
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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 defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
|
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 );
|
ssl->out_msg[ssl->out_msglen++] =
|
||||||
*(p++) = mbedtls_ssl_sig_from_pk_alg( sig_alg );
|
mbedtls_ssl_hash_from_md_alg( md_alg );
|
||||||
|
ssl->out_msg[ssl->out_msglen++] =
|
||||||
n += 2;
|
mbedtls_ssl_sig_from_pk_alg( sig_alg );
|
||||||
}
|
}
|
||||||
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */
|
||||||
|
|
||||||
if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen,
|
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||||
p + 2 , &signature_len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 )
|
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 );
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret );
|
||||||
return( 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 */
|
#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_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE;
|
||||||
ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE;
|
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" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
|
||||||
|
|
||||||
return( 0 );
|
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) || \
|
#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
|
||||||
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
|
defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
|
||||||
static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
|
|
||||||
const unsigned char *p,
|
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||||
const unsigned char *end,
|
static int ssl_resume_decrypt_pms( mbedtls_ssl_context *ssl,
|
||||||
size_t pms_offset )
|
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;
|
int ret;
|
||||||
size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) );
|
mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl );
|
||||||
unsigned char *pms = ssl->handshake->premaster + pms_offset;
|
mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk;
|
||||||
unsigned char ver[2];
|
size_t len = mbedtls_pk_get_len( public_key );
|
||||||
unsigned char fake_pms[48], peer_pms[48];
|
|
||||||
unsigned char mask;
|
|
||||||
size_t i, peer_pmslen;
|
|
||||||
unsigned int diff;
|
|
||||||
|
|
||||||
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" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "resuming decryption operation" ) );
|
||||||
return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
|
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) || \
|
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
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 );
|
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,
|
mbedtls_ssl_write_version( ssl->handshake->max_major_ver,
|
||||||
ssl->handshake->max_minor_ver,
|
ssl->handshake->max_minor_ver,
|
||||||
ssl->conf->transport, 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
|
* Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding
|
||||||
* must not cause the connection to end immediately; instead, send a
|
* must not cause the connection to end immediately; instead, send a
|
||||||
* bad_record_mac later in the handshake.
|
* bad_record_mac later in the handshake.
|
||||||
* Also, avoid data-dependant branches here to protect against
|
* To protect against timing-based variants of the attack, we must
|
||||||
* timing-based variants.
|
* 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 ) );
|
ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) );
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
/* It's ok to abort on an RNG failure, since this does not reveal
|
||||||
|
* anything about the RSA decryption. */
|
||||||
return( ret );
|
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 defined(MBEDTLS_SSL_DEBUG_ALL)
|
||||||
if( diff != 0 )
|
if( diff != 0 )
|
||||||
|
@ -3352,18 +3580,8 @@ static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl,
|
||||||
}
|
}
|
||||||
ssl->handshake->pmslen = 48;
|
ssl->handshake->pmslen = 48;
|
||||||
|
|
||||||
/* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */
|
/* Set pms to either the true or the fake PMS, without
|
||||||
/* MSVC has a warning about unary minus on unsigned, but this is
|
* data-dependent branches. */
|
||||||
* 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
|
|
||||||
|
|
||||||
for( i = 0; i < ssl->handshake->pmslen; i++ )
|
for( i = 0; i < ssl->handshake->pmslen; i++ )
|
||||||
pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[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" ) );
|
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 )
|
if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 )
|
||||||
{
|
{
|
||||||
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret );
|
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 defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED)
|
||||||
if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK )
|
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 )
|
if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 )
|
||||||
{
|
{
|
||||||
MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret );
|
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
|
* Free our handshake params
|
||||||
*/
|
*/
|
||||||
mbedtls_ssl_handshake_free( ssl->handshake );
|
mbedtls_ssl_handshake_free( ssl );
|
||||||
mbedtls_free( ssl->handshake );
|
mbedtls_free( ssl->handshake );
|
||||||
ssl->handshake = NULL;
|
ssl->handshake = NULL;
|
||||||
|
|
||||||
|
@ -5557,7 +5557,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl )
|
||||||
if( ssl->session_negotiate )
|
if( ssl->session_negotiate )
|
||||||
mbedtls_ssl_session_free( ssl->session_negotiate );
|
mbedtls_ssl_session_free( ssl->session_negotiate );
|
||||||
if( ssl->handshake )
|
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.
|
* 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
|
#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
|
* 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 */
|
#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 )
|
if( handshake == NULL )
|
||||||
return;
|
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) || \
|
#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
defined(MBEDTLS_SSL_PROTO_TLS1_1)
|
||||||
mbedtls_md5_free( &handshake->fin_md5 );
|
mbedtls_md5_free( &handshake->fin_md5 );
|
||||||
|
@ -7522,7 +7569,7 @@ void mbedtls_ssl_free( mbedtls_ssl_context *ssl )
|
||||||
|
|
||||||
if( ssl->handshake )
|
if( ssl->handshake )
|
||||||
{
|
{
|
||||||
mbedtls_ssl_handshake_free( ssl->handshake );
|
mbedtls_ssl_handshake_free( ssl );
|
||||||
mbedtls_ssl_transform_free( ssl->transform_negotiate );
|
mbedtls_ssl_transform_free( ssl->transform_negotiate );
|
||||||
mbedtls_ssl_session_free( ssl->session_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) || \
|
#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \
|
||||||
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
defined(MBEDTLS_SSL_PROTO_TLS1_2)
|
||||||
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
int mbedtls_ssl_get_key_exchange_md_tls1_2( mbedtls_ssl_context *ssl,
|
||||||
unsigned char *output,
|
unsigned char *hash, size_t *hashlen,
|
||||||
unsigned char *data, size_t data_len,
|
unsigned char *data, size_t data_len,
|
||||||
mbedtls_md_type_t md_alg )
|
mbedtls_md_type_t md_alg )
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
mbedtls_md_context_t ctx;
|
mbedtls_md_context_t ctx;
|
||||||
const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
|
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 );
|
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 );
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_update", ret );
|
||||||
goto exit;
|
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 );
|
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_finish", ret );
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
|
@ -411,6 +411,9 @@ static const char *features[] = {
|
||||||
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
|
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
|
||||||
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
|
"MBEDTLS_SSL_ALL_ALERT_MESSAGES",
|
||||||
#endif /* 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)
|
#if defined(MBEDTLS_SSL_DEBUG_ALL)
|
||||||
"MBEDTLS_SSL_DEBUG_ALL",
|
"MBEDTLS_SSL_DEBUG_ALL",
|
||||||
#endif /* MBEDTLS_SSL_DEBUG_ALL */
|
#endif /* MBEDTLS_SSL_DEBUG_ALL */
|
||||||
|
|
|
@ -109,6 +109,10 @@ int main( void )
|
||||||
#define DFL_KEY_FILE ""
|
#define DFL_KEY_FILE ""
|
||||||
#define DFL_CRT_FILE2 ""
|
#define DFL_CRT_FILE2 ""
|
||||||
#define DFL_KEY_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 ""
|
||||||
#define DFL_PSK_IDENTITY "Client_identity"
|
#define DFL_PSK_IDENTITY "Client_identity"
|
||||||
#define DFL_ECJPAKE_PW NULL
|
#define DFL_ECJPAKE_PW NULL
|
||||||
|
@ -196,6 +200,18 @@ int main( void )
|
||||||
#define USAGE_IO ""
|
#define USAGE_IO ""
|
||||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
|
#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)
|
#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
|
||||||
#define USAGE_PSK \
|
#define USAGE_PSK \
|
||||||
" psk=%%s default: \"\" (in hex, without 0x)\n" \
|
" 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" \
|
" cert_req_ca_list=%%d default: 1 (send ca list)\n" \
|
||||||
" options: 1 (send ca list), 0 (don't send)\n" \
|
" options: 1 (send ca list), 0 (don't send)\n" \
|
||||||
USAGE_IO \
|
USAGE_IO \
|
||||||
|
USAGE_SSL_ASYNC \
|
||||||
USAGE_SNI \
|
USAGE_SNI \
|
||||||
"\n" \
|
"\n" \
|
||||||
USAGE_PSK \
|
USAGE_PSK \
|
||||||
|
@ -410,6 +427,10 @@ struct options
|
||||||
const char *key_file; /* the file with the server key */
|
const char *key_file; /* the file with the server key */
|
||||||
const char *crt_file2; /* the file with the 2nd server certificate */
|
const char *crt_file2; /* the file with the 2nd server certificate */
|
||||||
const char *key_file2; /* the file with the 2nd server key */
|
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; /* the pre-shared key */
|
||||||
const char *psk_identity; /* the pre-shared key identity */
|
const char *psk_identity; /* the pre-shared key identity */
|
||||||
char *psk_list; /* list of PSK id/key pairs for callback */
|
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 */
|
#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
|
* Wait for an event from the underlying transport or the timer
|
||||||
* (Used in event-driven IO mode).
|
* (Used in event-driven IO mode).
|
||||||
|
@ -929,7 +1187,10 @@ int main( int argc, char *argv[] )
|
||||||
mbedtls_x509_crt srvcert2;
|
mbedtls_x509_crt srvcert2;
|
||||||
mbedtls_pk_context pkey2;
|
mbedtls_pk_context pkey2;
|
||||||
int key_cert_init = 0, key_cert_init2 = 0;
|
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)
|
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
|
||||||
mbedtls_dhm_context dhm;
|
mbedtls_dhm_context dhm;
|
||||||
#endif
|
#endif
|
||||||
|
@ -975,6 +1236,9 @@ int main( int argc, char *argv[] )
|
||||||
mbedtls_pk_init( &pkey );
|
mbedtls_pk_init( &pkey );
|
||||||
mbedtls_x509_crt_init( &srvcert2 );
|
mbedtls_x509_crt_init( &srvcert2 );
|
||||||
mbedtls_pk_init( &pkey2 );
|
mbedtls_pk_init( &pkey2 );
|
||||||
|
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||||
|
memset( &ssl_async_keys, 0, sizeof( ssl_async_keys ) );
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
|
#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_FS_IO)
|
||||||
mbedtls_dhm_init( &dhm );
|
mbedtls_dhm_init( &dhm );
|
||||||
|
@ -1032,6 +1296,10 @@ int main( int argc, char *argv[] )
|
||||||
opt.key_file = DFL_KEY_FILE;
|
opt.key_file = DFL_KEY_FILE;
|
||||||
opt.crt_file2 = DFL_CRT_FILE2;
|
opt.crt_file2 = DFL_CRT_FILE2;
|
||||||
opt.key_file2 = DFL_KEY_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 = DFL_PSK;
|
||||||
opt.psk_identity = DFL_PSK_IDENTITY;
|
opt.psk_identity = DFL_PSK_IDENTITY;
|
||||||
opt.psk_list = DFL_PSK_LIST;
|
opt.psk_list = DFL_PSK_LIST;
|
||||||
|
@ -1124,6 +1392,25 @@ int main( int argc, char *argv[] )
|
||||||
opt.key_file2 = q;
|
opt.key_file2 = q;
|
||||||
else if( strcmp( p, "dhm_file" ) == 0 )
|
else if( strcmp( p, "dhm_file" ) == 0 )
|
||||||
opt.dhm_file = q;
|
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 )
|
else if( strcmp( p, "psk" ) == 0 )
|
||||||
opt.psk = q;
|
opt.psk = q;
|
||||||
else if( strcmp( p, "psk_identity" ) == 0 )
|
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 );
|
mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL );
|
||||||
}
|
}
|
||||||
if( key_cert_init )
|
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 );
|
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if( key_cert_init2 )
|
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 );
|
mbedtls_printf( " failed\n ! mbedtls_ssl_conf_own_cert returned %d\n\n", ret );
|
||||||
goto exit;
|
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 defined(SNI_OPTION)
|
||||||
if( opt.sni != NULL )
|
if( opt.sni != NULL )
|
||||||
|
{
|
||||||
mbedtls_ssl_conf_sni( &conf, sni_callback, sni_info );
|
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
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_ECP_C)
|
#if defined(MBEDTLS_ECP_C)
|
||||||
|
@ -2205,8 +2579,16 @@ handshake:
|
||||||
|
|
||||||
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
|
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
|
||||||
{
|
{
|
||||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
#if defined(MBEDTLS_SSL_ASYNC_PRIVATE)
|
||||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
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;
|
break;
|
||||||
|
|
||||||
/* For event-driven IO, wait for socket to become available */
|
/* For event-driven IO, wait for socket to become available */
|
||||||
|
@ -2244,6 +2626,11 @@ handshake:
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
goto reset;
|
||||||
}
|
}
|
||||||
else /* ret == 0 */
|
else /* ret == 0 */
|
||||||
|
@ -2324,8 +2711,7 @@ data_exchange:
|
||||||
memset( buf, 0, sizeof( buf ) );
|
memset( buf, 0, sizeof( buf ) );
|
||||||
ret = mbedtls_ssl_read( &ssl, buf, len );
|
ret = mbedtls_ssl_read( &ssl, buf, len );
|
||||||
|
|
||||||
if( ret == MBEDTLS_ERR_SSL_WANT_READ ||
|
if( mbedtls_status_is_ssl_in_progress( ret ) )
|
||||||
ret == MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
||||||
{
|
{
|
||||||
if( opt.event == 1 /* level triggered IO */ )
|
if( opt.event == 1 /* level triggered IO */ )
|
||||||
{
|
{
|
||||||
|
@ -2425,7 +2811,7 @@ data_exchange:
|
||||||
len = sizeof( buf ) - 1;
|
len = sizeof( buf ) - 1;
|
||||||
memset( buf, 0, sizeof( buf ) );
|
memset( buf, 0, sizeof( buf ) );
|
||||||
|
|
||||||
while( 1 )
|
do
|
||||||
{
|
{
|
||||||
/* Without the call to `mbedtls_ssl_check_pending`, it might
|
/* Without the call to `mbedtls_ssl_check_pending`, it might
|
||||||
* happen that the client sends application data in the same
|
* 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`
|
* it can happen that the subsequent call to `mbedtls_ssl_read`
|
||||||
* returns `MBEDTLS_ERR_SSL_WANT_READ`, because the pending messages
|
* returns `MBEDTLS_ERR_SSL_WANT_READ`, because the pending messages
|
||||||
* might be discarded (e.g. because they are retransmissions). */
|
* 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 )
|
if( ret <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -2493,8 +2877,7 @@ data_exchange:
|
||||||
|
|
||||||
while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
|
while( ( ret = mbedtls_ssl_renegotiate( &ssl ) ) != 0 )
|
||||||
{
|
{
|
||||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
||||||
{
|
{
|
||||||
mbedtls_printf( " failed\n ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
|
mbedtls_printf( " failed\n ! mbedtls_ssl_renegotiate returned %d\n\n", ret );
|
||||||
goto reset;
|
goto reset;
|
||||||
|
@ -2537,8 +2920,7 @@ data_exchange:
|
||||||
goto reset;
|
goto reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
||||||
{
|
{
|
||||||
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
|
mbedtls_printf( " failed\n ! mbedtls_ssl_write returned %d\n\n", ret );
|
||||||
goto reset;
|
goto reset;
|
||||||
|
@ -2562,8 +2944,7 @@ data_exchange:
|
||||||
{
|
{
|
||||||
ret = mbedtls_ssl_write( &ssl, buf, len );
|
ret = mbedtls_ssl_write( &ssl, buf, len );
|
||||||
|
|
||||||
if( ret != MBEDTLS_ERR_SSL_WANT_READ &&
|
if( ! mbedtls_status_is_ssl_in_progress( ret ) )
|
||||||
ret != MBEDTLS_ERR_SSL_WANT_WRITE )
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* For event-driven IO, wait for socket to become available */
|
/* For event-driven IO, wait for socket to become available */
|
||||||
|
@ -2641,6 +3022,17 @@ exit:
|
||||||
mbedtls_x509_crt_free( &srvcert2 );
|
mbedtls_x509_crt_free( &srvcert2 );
|
||||||
mbedtls_pk_free( &pkey2 );
|
mbedtls_pk_free( &pkey2 );
|
||||||
#endif
|
#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)
|
#if defined(SNI_OPTION)
|
||||||
sni_free( sni_info );
|
sni_free( sni_info );
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -531,8 +531,8 @@ make
|
||||||
msg "test: main suites (full config)" # ~ 5s
|
msg "test: main suites (full config)" # ~ 5s
|
||||||
make test
|
make test
|
||||||
|
|
||||||
msg "test: ssl-opt.sh default (full config)" # ~ 1s
|
msg "test: ssl-opt.sh default, ECJPAKE (full config)" # ~ 1s
|
||||||
if_build_succeeded tests/ssl-opt.sh -f Default
|
if_build_succeeded tests/ssl-opt.sh -f 'Default\|ECJPAKE'
|
||||||
|
|
||||||
msg "test: compat.sh RC4, DES & NULL (full config)" # ~ 2 min
|
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'
|
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" \
|
-c "16384 bytes written in 1 fragments" \
|
||||||
-s "Read from client: 16384 bytes read"
|
-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
|
# Tests for DTLS HelloVerifyRequest
|
||||||
|
|
||||||
run_test "DTLS cookie: enabled" \
|
run_test "DTLS cookie: enabled" \
|
||||||
|
|
Loading…
Reference in a new issue