Merge remote-tracking branch 'origin/pr/590' into baremetal
diff --git a/ChangeLog b/ChangeLog
index a48baf4..75f6220 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,10 @@
mbedtls_ssl_session_load() to allow serializing a session, for example to
store it in non-volatile storage, and later using it for TLS session
resumption.
+ * Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`
+ which allows copy-less parsing of DER encoded X.509 CRTs,
+ at the cost of additional lifetime constraints on the input
+ buffer, but at the benefit of reduced RAM consumption.
* Add new API function mbedtls_ssl_conf_extended_master_secret_enforce() to
allow enforcing the usage of ExtendedMasterSecret extension. If the
extension is used and this option is enabled, handshakes not leading to
@@ -33,6 +37,10 @@
consent to the use of the ExtendedMasterSecret extension in its
ServerHello.
+API Changes
+ * Add a new X.509 API call `mbedtls_x509_parse_der_nocopy()`.
+ See the Features section for more information.
+
Bugfix
* Server's RSA certificate in certs.c was SHA-1 signed. In the default
mbedTLS configuration only SHA-2 signed certificates are accepted.
@@ -111,6 +119,8 @@
leading content octet. Fixes #1610.
Changes
+ * Reduce RAM consumption during session renegotiation by not storing
+ the peer CRT chain and session ticket twice.
* Include configuration file in all header files that use configuration,
instead of relying on other header files that they include.
Inserted as an enhancement for #1371
diff --git a/configs/baremetal.h b/configs/baremetal.h
index 2fbc359..24cce6b 100644
--- a/configs/baremetal.h
+++ b/configs/baremetal.h
@@ -34,9 +34,6 @@
#ifndef MBEDTLS_BAREMETAL_CONFIG_H
#define MBEDTLS_BAREMETAL_CONFIG_H
-#define MBEDTLS_HAVE_TIME
-#define MBEDTLS_HAVE_TIME_DATE
-
/* Symmetric crypto: AES-CCM only */
#define MBEDTLS_CIPHER_C
#define MBEDTLS_AES_C
diff --git a/configs/config-ccm-psk-tls1_2.h b/configs/config-ccm-psk-tls1_2.h
index c9b58dd..bd2c1a3 100644
--- a/configs/config-ccm-psk-tls1_2.h
+++ b/configs/config-ccm-psk-tls1_2.h
@@ -41,6 +41,7 @@
/* mbed TLS feature support */
#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2
+#define MBEDTLS_SSL_PROTO_TLS
/* mbed TLS modules */
#define MBEDTLS_AES_C
diff --git a/configs/config-mini-tls1_1.h b/configs/config-mini-tls1_1.h
index 013bc03..349ea8e 100644
--- a/configs/config-mini-tls1_1.h
+++ b/configs/config-mini-tls1_1.h
@@ -40,6 +40,7 @@
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_1
+#define MBEDTLS_SSL_PROTO_TLS
/* mbed TLS modules */
#define MBEDTLS_AES_C
diff --git a/configs/config-suite-b.h b/configs/config-suite-b.h
index 18e2c40..e6fad1c 100644
--- a/configs/config-suite-b.h
+++ b/configs/config-suite-b.h
@@ -47,6 +47,7 @@
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#define MBEDTLS_SSL_PROTO_TLS1_2
+#define MBEDTLS_SSL_PROTO_TLS
/* mbed TLS modules */
#define MBEDTLS_AES_C
diff --git a/configs/config-thread.h b/configs/config-thread.h
index 25db16b..3166aa9 100644
--- a/configs/config-thread.h
+++ b/configs/config-thread.h
@@ -29,6 +29,7 @@
* Distinguishing features:
* - no RSA or classic DH, fully based on ECC
* - no X.509
+ * - no TLS, only DTLS
* - support for experimental EC J-PAKE key exchange
*
* See README.txt for usage instructions.
diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
index 48555f6..b3677b5 100644
--- a/include/mbedtls/check_config.h
+++ b/include/mbedtls/check_config.h
@@ -562,7 +562,12 @@
#if defined(MBEDTLS_SSL_TLS_C) && (!defined(MBEDTLS_SSL_PROTO_SSL3) && \
!defined(MBEDTLS_SSL_PROTO_TLS1) && !defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2))
-#error "MBEDTLS_SSL_TLS_C defined, but no protocols are active"
+#error "MBEDTLS_SSL_TLS_C defined, but no protocol version is active"
+#endif
+
+#if defined(MBEDTLS_SSL_TLS_C) && \
+ ( !defined(MBEDTLS_SSL_PROTO_TLS) && !defined(MBEDTLS_SSL_PROTO_DTLS) )
+#error "MBEDTLS_SSL_TLS_C defined, but neither TLS or DTLS is active"
#endif
#if defined(MBEDTLS_SSL_TLS_C) && (defined(MBEDTLS_SSL_PROTO_SSL3) && \
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index f5b2de9..e0b5ba4 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -1453,7 +1453,7 @@
/**
* \def MBEDTLS_SSL_PROTO_SSL3
*
- * Enable support for SSL 3.0.
+ * Enable support for SSL 3.0 (if TLS is enabled).
*
* Requires: MBEDTLS_MD5_C
* MBEDTLS_SHA1_C
@@ -1465,7 +1465,7 @@
/**
* \def MBEDTLS_SSL_PROTO_TLS1
*
- * Enable support for TLS 1.0.
+ * Enable support for TLS 1.0 (if TLS is enabled).
*
* Requires: MBEDTLS_MD5_C
* MBEDTLS_SHA1_C
@@ -1477,7 +1477,8 @@
/**
* \def MBEDTLS_SSL_PROTO_TLS1_1
*
- * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ * Enable support for TLS 1.1 (if TLS is enabled) and DTLS 1.0 (if DTLS is
+ * enabled).
*
* Requires: MBEDTLS_MD5_C
* MBEDTLS_SHA1_C
@@ -1489,7 +1490,8 @@
/**
* \def MBEDTLS_SSL_PROTO_TLS1_2
*
- * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ * Enable support for TLS 1.2 (if TLS is enabled) and DTLS 1.2 (if DTLS is
+ * enabled).
*
* Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
* (Depends on ciphersuites)
@@ -1503,8 +1505,10 @@
*
* Enable support for DTLS (all available versions).
*
- * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
- * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0.
+ *
+ * \see MBEDTLS_SSL_PROTO_TLS
*
* Requires: MBEDTLS_SSL_PROTO_TLS1_1
* or MBEDTLS_SSL_PROTO_TLS1_2
@@ -1514,6 +1518,27 @@
#define MBEDTLS_SSL_PROTO_DTLS
/**
+ * \def MBEDTLS_SSL_PROTO_TLS
+ *
+ * Enable support for SSL/TLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable TLS 1.2;
+ * enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable TLS 1.1;
+ * enable this and MBEDTLS_SSL_PROTO_TLS1 to enable TLS 1.0;
+ * and/or this and MBEDTLS_SSL_PROTO_SSL3 to enable SSL 3.0 (deprecated).
+ *
+ * \see MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_2
+ * or MBEDTLS_SSL_PROTO_TLS1_1
+ * or MBEDTLS_SSL_PROTO_TLS1
+ * or MBEDTLS_SSL_PROTO_SSL3 (deprecated)
+ *
+ * Comment this macro to disable support for TLS
+ */
+#define MBEDTLS_SSL_PROTO_TLS
+
+/**
* \def MBEDTLS_SSL_ALPN
*
* Enable support for RFC 7301 Application Layer Protocol Negotiation.
diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
index d219322..5066807 100644
--- a/include/mbedtls/ssl.h
+++ b/include/mbedtls/ssl.h
@@ -1343,7 +1343,8 @@
/**
* \brief Set the transport type (TLS or DTLS).
- * Default: TLS
+ * Default: TLS if #MBEDTLS_SSL_PROTO_TLS is defined, else
+ * DTLS.
*
* \note For DTLS, you must either provide a recv callback that
* doesn't block, or one that handles timeouts, see
diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
index 45ea26a..1c8709f 100644
--- a/include/mbedtls/ssl_internal.h
+++ b/include/mbedtls/ssl_internal.h
@@ -264,6 +264,57 @@
#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0)
#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1)
+/*
+ * Helpers for code specific to TLS or DTLS.
+ *
+ * Goals for these helpers:
+ * - generate minimal code, eg don't test if mode is DTLS in a DTLS-only build
+ * - make the flow clear to the compiler, so that in TLS and DTLS combined
+ * builds, when there are two branches, it knows exactly one of them is taken
+ * - preserve readability
+ *
+ * There are three macros:
+ * - MBEDTLS_SSL_TRANSPORT_IS_TLS( transport )
+ * - MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport )
+ * - MBEDTLS_SSL_TRANSPORT_ELSE
+ *
+ * The first two are macros rather than static inline functions because some
+ * compilers (eg arm-none-eabi-gcc 5.4.1 20160919) don't propagate constants
+ * well enough for us with static inline functions.
+ *
+ * Usage 1 (can replace DTLS with TLS):
+ * #if defined(MBEDTLS_SSL_PROTO_DTLS)
+ * if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) )
+ * // DTLS-specific code
+ * #endif
+ *
+ * Usage 2 (can swap DTLS and TLS);
+ * #if defined(MBEDTLS_SSL_PROTO_DTLS)
+ * if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) )
+ * // DTLS-specific code
+ * MBEDTLS_SSL_TRANSPORT_ELSE
+ * #endif
+ * #if defined(MBEDTLS_SSL_PROTO_TLS)
+ * // TLS-specific code
+ * #endif
+ */
+#if defined(MBEDTLS_SSL_PROTO_DTLS) && defined(MBEDTLS_SSL_PROTO_TLS) /* both */
+#define MBEDTLS_SSL_TRANSPORT__BOTH /* shortcut for future tests */
+#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) \
+ ( (transport) == MBEDTLS_SSL_TRANSPORT_STREAM )
+#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) \
+ ( (transport) == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+#define MBEDTLS_SSL_TRANSPORT_ELSE else
+#elif defined(MBEDTLS_SSL_PROTO_DTLS) /* DTLS only */
+#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) 0
+#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) 1
+#define MBEDTLS_SSL_TRANSPORT_ELSE /* empty: no other branch */
+#else /* TLS only */
+#define MBEDTLS_SSL_TRANSPORT_IS_TLS( transport ) 1
+#define MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) 0
+#define MBEDTLS_SSL_TRANSPORT_ELSE /* empty: no other branch */
+#endif /* TLS and/or DTLS */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -905,12 +956,14 @@
static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl )
{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 12 );
-#else
+#if !defined(MBEDTLS_SSL_PROTO__BOTH)
((void) ssl);
#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
+ return( 12 );
+#endif
return( 4 );
}
diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
index 670bd10..62c3c2e 100644
--- a/include/mbedtls/x509_crt.h
+++ b/include/mbedtls/x509_crt.h
@@ -52,6 +52,8 @@
*/
typedef struct mbedtls_x509_crt
{
+ int own_buffer; /**< Indicates if \c raw is owned
+ * by the structure or not. */
mbedtls_x509_buf raw; /**< The raw certificate data (DER). */
mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */
@@ -220,16 +222,58 @@
/**
* \brief Parse a single DER formatted certificate and add it
- * to the chained list.
+ * to the end of the provided chained list.
*
- * \param chain points to the start of the chain
- * \param buf buffer holding the certificate DER data
- * \param buflen size of the buffer
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The buffer holding the DER encoded certificate.
+ * \param buflen The size in Bytes of \p buf.
*
- * \return 0 if successful, or a specific X509 or PEM error code
+ * \note This function makes an internal copy of the CRT buffer
+ * \p buf. In particular, \p buf may be destroyed or reused
+ * after this call returns. To avoid duplicating the CRT
+ * buffer (at the cost of stricter lifetime constraints),
+ * use mbedtls_x509_crt_parse_der_nocopy() instead.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
*/
-int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
- size_t buflen );
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen );
+
+/**
+ * \brief Parse a single DER formatted certificate and add it
+ * to the end of the provided chained list. This is a
+ * variant of mbedtls_x509_crt_parse_der() which takes
+ * temporary ownership of the CRT buffer until the CRT
+ * is destroyed.
+ *
+ * \param chain The pointer to the start of the CRT chain to attach to.
+ * When parsing the first CRT in a chain, this should point
+ * to an instance of ::mbedtls_x509_crt initialized through
+ * mbedtls_x509_crt_init().
+ * \param buf The address of the readable buffer holding the DER encoded
+ * certificate to use. On success, this buffer must be
+ * retained and not be changed for the liftetime of the
+ * CRT chain \p chain, that is, until \p chain is destroyed
+ * through a call to mbedtls_x509_crt_free().
+ * \param buflen The size in Bytes of \p buf.
+ *
+ * \note This call is functionally equivalent to
+ * mbedtls_x509_crt_parse_der(), but it avoids creating a
+ * copy of the input buffer at the cost of stronger lifetime
+ * constraints. This is useful in constrained environments
+ * where duplication of the CRT cannot be tolerated.
+ *
+ * \return \c 0 if successful.
+ * \return A negative error code on failure.
+ */
+int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen );
/**
* \brief Parse one DER-encoded or one or more concatenated PEM-encoded
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 2cf9c79..cd9793e 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -452,7 +452,7 @@
*/
*olen = 0;
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ||
ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
{
return;
@@ -734,7 +734,7 @@
* When responding to a verify request, MUST reuse random (RFC 6347 4.2.1)
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake->verify_cookie != NULL )
{
return( 0 );
@@ -785,7 +785,7 @@
return( 1 );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
return( 1 );
#endif
@@ -926,7 +926,7 @@
* DTLS cookie
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
if( ssl->handshake->verify_cookie == NULL )
{
@@ -1021,7 +1021,7 @@
* an actual need for it.
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
offer_compress = 0;
#endif
@@ -1137,7 +1137,7 @@
ssl->state++;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
mbedtls_ssl_send_flight_completed( ssl );
#endif
@@ -1148,7 +1148,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
@@ -1252,7 +1252,7 @@
size_t peer_cid_len;
if( /* CID extension only makes sense in DTLS */
- ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ||
/* The server must only send the CID extension if we have offered it. */
ssl->negotiate_cid == MBEDTLS_SSL_CID_DISABLED )
{
@@ -1645,7 +1645,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST )
{
@@ -1762,12 +1762,7 @@
#if defined(MBEDTLS_ZLIB_SUPPORT)
/* See comments in ssl_write_client_hello() */
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- accept_comp = 0;
- else
-#endif
- accept_comp = 1;
+ accept_comp = MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport );
if( comp != MBEDTLS_SSL_COMPRESS_NULL &&
( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) )
@@ -3016,7 +3011,7 @@
ssl->state++;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
mbedtls_ssl_recv_flight_completed( ssl );
#endif
@@ -3598,6 +3593,15 @@
if( ticket_len == 0 )
return( 0 );
+ if( ssl->session != NULL && ssl->session->ticket != NULL )
+ {
+ mbedtls_platform_zeroize( ssl->session->ticket,
+ ssl->session->ticket_len );
+ mbedtls_free( ssl->session->ticket );
+ ssl->session->ticket = NULL;
+ ssl->session->ticket_len = 0;
+ }
+
mbedtls_platform_zeroize( ssl->session_negotiate->ticket,
ssl->session_negotiate->ticket_len );
mbedtls_free( ssl->session_negotiate->ticket );
@@ -3648,7 +3652,7 @@
return( ret );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{
if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index 14202d8..d40a21f 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -441,7 +441,7 @@
size_t peer_cid_len;
/* CID extension only makes sense in DTLS */
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@@ -899,7 +899,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) )
return( 0 );
#endif
@@ -1304,12 +1304,13 @@
buf = ssl->in_hdr;
-#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM )
-#endif
- if( ( buf[0] & 0x80 ) != 0 )
- return( ssl_parse_client_hello_v2( ssl ) );
+#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) && \
+ defined(MBEDTLS_SSL_PROTO_TLS)
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) &&
+ ( buf[0] & 0x80 ) != 0 )
+ {
+ return( ssl_parse_client_hello_v2( ssl ) );
+ }
#endif
MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_in_hdr_len( ssl ) );
@@ -1353,7 +1354,7 @@
/* For DTLS if this is the initial handshake, remember the client sequence
* number to use it in our next message (RFC 6347 4.2.1) */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport )
#if defined(MBEDTLS_SSL_RENEGOTIATION)
&& ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE
#endif
@@ -1407,13 +1408,19 @@
return( ret );
}
- /* Done reading this record, get ready for the next one */
+ /* Done reading this record, get ready for the next one */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
+ {
ssl->next_record_offset = msg_len + mbedtls_ssl_in_hdr_len( ssl );
- else
+ }
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ {
ssl->in_left = 0;
+ }
+#endif
}
buf = ssl->in_msg;
@@ -1456,7 +1463,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
/*
* Copy the client's handshake message_seq on initial handshakes,
@@ -1595,7 +1602,7 @@
* Check the cookie length and content
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
cookie_offset = 35 + sess_len;
cookie_len = buf[cookie_offset];
@@ -1650,9 +1657,13 @@
*/
ciph_offset = cookie_offset + 1 + cookie_len;
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ {
ciph_offset = 35 + sess_len;
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS */
ciph_len = ( buf[ciph_offset + 0] << 8 )
| ( buf[ciph_offset + 1] );
@@ -1704,7 +1715,7 @@
/* See comments in ssl_write_client_hello() */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL;
#endif
@@ -2101,7 +2112,7 @@
ssl->state++;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
mbedtls_ssl_recv_flight_completed( ssl );
#endif
@@ -2536,7 +2547,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
@@ -2562,7 +2573,7 @@
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) );
#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake->verify_cookie_len != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) );
@@ -3520,7 +3531,7 @@
ssl->state++;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
mbedtls_ssl_send_flight_completed( ssl );
#endif
@@ -3531,7 +3542,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
@@ -4416,7 +4427,7 @@
return( ret );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{
if( ( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 1f8690a..ca4ab36 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -61,12 +61,14 @@
/* Length of the "epoch" field in the record header */
static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl )
{
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- return( 2 );
-#else
+#if !defined(MBEDTLS_SSL_TRANSPORT__BOTH)
((void) ssl);
#endif
+
+#if defined(MBEDTLS_SSL_PROTO_DTLS)
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
+ return( 2 );
+#endif
return( 0 );
}
@@ -135,7 +137,7 @@
unsigned char const *own_cid,
size_t own_cid_len )
{
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
ssl->negotiate_cid = enable;
@@ -170,7 +172,7 @@
{
*enabled = MBEDTLS_SSL_CID_DISABLED;
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM ||
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) ||
ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER )
{
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
@@ -3023,7 +3025,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
uint32_t timeout;
@@ -3164,8 +3166,9 @@
ssl->in_left = ret;
}
- else
-#endif
+ MBEDTLS_SSL_TRANSPORT_ELSE
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d",
ssl->in_left, nb_want ) );
@@ -3212,6 +3215,7 @@
ssl->in_left += ret;
}
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) );
@@ -3267,15 +3271,17 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
ssl->out_hdr = ssl->out_buf;
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
ssl->out_hdr = ssl->out_buf + 8;
}
+#endif
ssl_update_out_pointers( ssl, ssl->transform_out );
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) );
@@ -3686,7 +3692,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake != NULL &&
ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING )
{
@@ -3729,7 +3735,7 @@
* uint24 fragment_length;
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
/* Make room for the additional DTLS fields */
if( MBEDTLS_SSL_OUT_CONTENT_LEN - ssl->out_msglen < 8 )
@@ -3771,7 +3777,7 @@
/* Either send now, or just save to be sent (and resent) later */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
! ( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE &&
hs_type == MBEDTLS_SSL_HS_HELLO_REQUEST ) )
{
@@ -3909,7 +3915,7 @@
#if defined(MBEDTLS_SSL_PROTO_DTLS)
/* In case of DTLS, double-check that we don't exceed
* the remaining space in the datagram. */
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
ret = ssl_get_remaining_space_in_datagram( ssl );
if( ret < 0 )
@@ -3951,7 +3957,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
flush == SSL_DONT_FORCE_FLUSH )
{
size_t remaining;
@@ -4135,7 +4141,7 @@
ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
int ret;
unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5];
@@ -4199,14 +4205,18 @@
return( MBEDTLS_ERR_SSL_EARLY_MESSAGE );
}
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif /* MBEDTLS_SSL_PROTO_DTLS */
- /* With TLS we don't handle fragmentation (for now) */
- if( ssl->in_msglen < ssl->in_hslen )
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
- return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ /* With TLS we don't handle fragmentation (for now) */
+ if( ssl->in_msglen < ssl->in_hslen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) );
+ return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
return( 0 );
}
@@ -4222,7 +4232,7 @@
/* Handshake message is complete, increment counter */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake != NULL )
{
unsigned offset;
@@ -4574,7 +4584,7 @@
/* Check record type */
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->in_msgtype == MBEDTLS_SSL_MSG_CID &&
ssl->conf->cid_len != 0 )
{
@@ -4602,13 +4612,15 @@
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) );
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
+#if defined(MBEDTLS_SSL_PROTO_TLS)
/* Silently ignore invalid DTLS records as recommended by RFC 6347
- * Section 4.1.2.7 */
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
-#endif /* MBEDTLS_SSL_PROTO_DTLS */
+ * Section 4.1.2.7, that is, send alert only with TLS */
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
+ {
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE );
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS */
return( MBEDTLS_ERR_SSL_INVALID_RECORD );
}
@@ -4669,7 +4681,7 @@
* record leads to the entire datagram being dropped.
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1];
@@ -4904,26 +4916,23 @@
else
ssl->nb_zero = 0;
-#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
- {
- ; /* in_ctr read from peer, not maintained internally */
- }
- else
-#endif
+ /* Only needed for TLS, as with DTLS in_ctr is read from the header */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
{
unsigned i;
- for( i = 8; i > ssl_ep_len( ssl ); i-- )
+ for( i = 8; i > 0; i-- )
if( ++ssl->in_ctr[i - 1] != 0 )
break;
- /* The loop goes to its end iff the counter is wrapping */
- if( i == ssl_ep_len( ssl ) )
+ /* The loop goes to its end only if the counter is wrapping around */
+ if( i == 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) );
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
}
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
}
@@ -4940,7 +4949,7 @@
#endif /* MBEDTLS_ZLIB_SUPPORT */
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
mbedtls_ssl_dtls_replay_update( ssl );
}
@@ -4986,7 +4995,7 @@
/* We only check for buffered messages if the
* current datagram is fully consumed. */
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl_next_record_is_in_datagram( ssl ) == 0 )
{
if( ssl_load_buffered_message( ssl ) == 0 )
@@ -5509,7 +5518,7 @@
size_t rec_len;
unsigned rec_epoch;
- if( ssl->conf->transport != MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_TLS( ssl->conf->transport ) )
return( 0 );
if( hs == NULL )
@@ -5647,7 +5656,7 @@
if( ( ret = ssl_parse_record_header( ssl ) ) != 0 )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT )
{
if( ret == MBEDTLS_ERR_SSL_EARLY_MESSAGE )
@@ -5698,7 +5707,7 @@
/* Done reading this record, get ready for the next one */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_in_hdr_len( ssl );
if( ssl->next_record_offset < ssl->in_left )
@@ -5706,14 +5715,18 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "more than one record within datagram" ) );
}
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ {
ssl->in_left = 0;
+ }
+#endif
if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
/* Silently discard invalid records */
if( ret == MBEDTLS_ERR_SSL_INVALID_MAC )
@@ -5756,8 +5769,9 @@
return( ret );
}
- else
-#endif
+ MBEDTLS_SSL_TRANSPORT_ELSE
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
/* Error out (and send alert) on invalid records */
#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES)
@@ -5770,6 +5784,7 @@
#endif
return( ret );
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
}
return( 0 );
@@ -5807,7 +5822,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC &&
ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC )
{
@@ -5882,7 +5897,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
/* Drop unexpected ApplicationData records,
* except at the beginning of renegotiations */
@@ -6120,6 +6135,23 @@
return( ret );
}
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+static int ssl_check_peer_crt_unchanged( mbedtls_ssl_context *ssl,
+ unsigned char *crt_buf,
+ size_t crt_buf_len )
+{
+ mbedtls_x509_crt const * const peer_crt = ssl->session->peer_cert;
+
+ if( peer_crt == NULL )
+ return( -1 );
+
+ if( peer_crt->raw.len != crt_buf_len )
+ return( -1 );
+
+ return( memcmp( peer_crt->raw.p, crt_buf, crt_buf_len ) );
+}
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
/*
* Once the certificate message is read, parse it into a cert chain and
* perform basic checks, but leave actual verification to the caller
@@ -6210,43 +6242,40 @@
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* Make &ssl->in_msg[i] point to the beginning of the CRT chain. */
+ i += 3;
+
/* In case we tried to reuse a session but it failed */
if( ssl->session_negotiate->peer_cert != NULL )
{
mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert );
mbedtls_free( ssl->session_negotiate->peer_cert );
+ ssl->session_negotiate->peer_cert = NULL;
}
- if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1,
- sizeof( mbedtls_x509_crt ) ) ) == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
- sizeof( mbedtls_x509_crt ) ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
- return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
- }
-
- mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
-
- i += 3;
-
+ /* Iterate through and parse the CRTs in the provided chain. */
while( i < ssl->in_hslen )
{
+ /* Check that there's room for the next CRT's length fields. */
if ( i + 3 > ssl->in_hslen ) {
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* In theory, the CRT can be up to 2**24 Bytes, but we don't support
+ * anything beyond 2**16 ~ 64K. */
if( ssl->in_msg[i] != 0 )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* Read length of the next CRT in the chain. */
n = ( (unsigned int) ssl->in_msg[i + 1] << 8 )
| (unsigned int) ssl->in_msg[i + 2];
i += 3;
@@ -6254,72 +6283,101 @@
if( n < 128 || i + n > ssl->in_hslen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
}
+ /* Check if we're handling the first CRT in the chain. */
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ /* During client-side renegotiation, check that the server's
+ * end-CRTs hasn't changed compared to the initial handshake,
+ * mitigating the triple handshake attack. On success, reuse
+ * the original end-CRT instead of parsing it again. */
+#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
+ if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
+ ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 3, ( "Check that peer CRT hasn't changed during renegotiation" ) );
+ if( ssl_check_peer_crt_unchanged( ssl,
+ &ssl->in_msg[i],
+ n ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
+ return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
+ }
+
+ /* Move CRT chain structure to new session instance. */
+ ssl->session_negotiate->peer_cert = ssl->session->peer_cert;
+ ssl->session->peer_cert = NULL;
+
+ /* Delete all remaining CRTs from the original CRT chain. */
+ mbedtls_x509_crt_free(
+ ssl->session_negotiate->peer_cert->next );
+ mbedtls_free( ssl->session_negotiate->peer_cert->next );
+ ssl->session_negotiate->peer_cert->next = NULL;
+
+ i += n;
+ continue;
+ }
+#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
+
+ /* Outside of client-side renegotiation, create a fresh X.509 CRT
+ * instance to parse the end-CRT into. */
+
+ ssl->session_negotiate->peer_cert =
+ mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
+ if( ssl->session_negotiate->peer_cert == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed",
+ sizeof( mbedtls_x509_crt ) ) );
+ mbedtls_ssl_send_alert_message( ssl,
+ MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR );
+ return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
+ }
+
+ mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert );
+
+ /* Intentional fall through */
+ }
+
+ /* Parse the next certificate in the chain. */
ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert,
- ssl->in_msg + i, n );
+ ssl->in_msg + i, n );
switch( ret )
{
- case 0: /*ok*/
- case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
- /* Ignore certificate with an unknown algorithm: maybe a
- prior certificate was already trusted. */
- break;
+ case 0: /*ok*/
+ case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND:
+ /* Ignore certificate with an unknown algorithm: maybe a
+ prior certificate was already trusted. */
+ break;
- case MBEDTLS_ERR_X509_ALLOC_FAILED:
- alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
- goto crt_parse_der_failed;
+ case MBEDTLS_ERR_X509_ALLOC_FAILED:
+ alert = MBEDTLS_SSL_ALERT_MSG_INTERNAL_ERROR;
+ goto crt_parse_der_failed;
- case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
- alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
- goto crt_parse_der_failed;
+ case MBEDTLS_ERR_X509_UNKNOWN_VERSION:
+ alert = MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT;
+ goto crt_parse_der_failed;
- default:
- alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
- crt_parse_der_failed:
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
- MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
- return( ret );
+ default:
+ alert = MBEDTLS_SSL_ALERT_MSG_BAD_CERT;
+ crt_parse_der_failed:
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, alert );
+ MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret );
+ return( ret );
}
i += n;
}
MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert );
-
- /*
- * On client, make sure the server cert doesn't change during renego to
- * avoid "triple handshake" attack: https://secure-resumption.com/
- */
-#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C)
- if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT &&
- ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS )
- {
- if( ssl->session->peer_cert == NULL )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
-
- if( ssl->session->peer_cert->raw.len !=
- ssl->session_negotiate->peer_cert->raw.len ||
- memcmp( ssl->session->peer_cert->raw.p,
- ssl->session_negotiate->peer_cert->raw.p,
- ssl->session->peer_cert->raw.len ) != 0 )
- {
- MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) );
- mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
- MBEDTLS_SSL_ALERT_MSG_ACCESS_DENIED );
- return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE );
- }
- }
-#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */
-
return( 0 );
}
@@ -6612,7 +6670,7 @@
ssl->session_in = ssl->session_negotiate;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY)
ssl_dtls_replay_reset( ssl );
@@ -6627,9 +6685,13 @@
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
}
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->in_ctr, 0, 8 );
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ {
+ memset( ssl->in_ctr, 0, 8 );
+ }
+#endif
ssl_update_in_pointers( ssl );
@@ -7057,7 +7119,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->handshake->flight != NULL )
{
/* Cancel handshake timer */
@@ -7128,7 +7190,7 @@
MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
unsigned char i;
@@ -7151,9 +7213,13 @@
return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING );
}
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif /* MBEDTLS_SSL_PROTO_DTLS */
- memset( ssl->cur_out_ctr, 0, 8 );
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ {
+ memset( ssl->cur_out_ctr, 0, 8 );
+ }
+#endif
ssl->transform_out = ssl->transform_negotiate;
ssl->session_out = ssl->session_negotiate;
@@ -7170,7 +7236,7 @@
#endif
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
mbedtls_ssl_send_flight_completed( ssl );
#endif
@@ -7181,7 +7247,7 @@
}
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
( ret = mbedtls_ssl_flight_transmit( ssl ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flight_transmit", ret );
@@ -7270,7 +7336,7 @@
ssl->state++;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
mbedtls_ssl_recv_flight_completed( ssl );
#endif
@@ -7402,7 +7468,7 @@
ssl_handshake_params_init( ssl->handshake );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
ssl->handshake->alt_transform_out = ssl->transform_out;
@@ -7459,7 +7525,7 @@
mbedtls_ssl_transform *transform )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
ssl->out_ctr = ssl->out_hdr + 3;
#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID)
@@ -7472,8 +7538,9 @@
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
ssl->out_iv = ssl->out_len + 2;
}
- else
-#endif
+ MBEDTLS_SSL_TRANSPORT_ELSE
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
ssl->out_ctr = ssl->out_hdr - 8;
ssl->out_len = ssl->out_hdr + 3;
@@ -7482,6 +7549,7 @@
#endif
ssl->out_iv = ssl->out_hdr + 5;
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
/* Adjust out_msg to make space for explicit IV, if used. */
if( transform != NULL &&
@@ -7514,7 +7582,7 @@
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
/* This sets the header pointers to match records
* without CID. When we receive a record containing
@@ -7529,8 +7597,9 @@
#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */
ssl->in_iv = ssl->in_len + 2;
}
- else
-#endif
+ MBEDTLS_SSL_TRANSPORT_ELSE
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
ssl->in_ctr = ssl->in_hdr - 8;
ssl->in_len = ssl->in_hdr + 3;
@@ -7539,6 +7608,7 @@
#endif
ssl->in_iv = ssl->in_hdr + 5;
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
/* This will be adjusted at record decryption time. */
ssl->in_msg = ssl->in_iv;
@@ -7560,17 +7630,19 @@
{
/* Set the incoming and outgoing record pointers. */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
ssl->out_hdr = ssl->out_buf;
ssl->in_hdr = ssl->in_buf;
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
ssl->out_hdr = ssl->out_buf + 8;
ssl->in_hdr = ssl->in_buf + 8;
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
/* Derive other internal pointers. */
ssl_update_out_pointers( ssl, NULL /* no transform enabled */ );
@@ -8502,7 +8574,7 @@
*/
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->in_left > ssl->next_record_offset )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "ssl_check_pending: more records within current datagram" ) );
@@ -8561,7 +8633,7 @@
const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
switch( ssl->minor_ver )
{
@@ -9356,7 +9428,7 @@
/* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and
* the ServerHello will have message_seq = 1" */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING )
{
if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER )
@@ -9482,7 +9554,7 @@
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) );
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
return( ret );
@@ -9583,7 +9655,7 @@
/* With DTLS, drop the packet (probably from last handshake) */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
continue;
}
@@ -9600,7 +9672,7 @@
/* With DTLS, drop the packet (probably from last handshake) */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
continue;
}
@@ -9622,7 +9694,7 @@
/* DTLS clients need to know renego is server-initiated */
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) &&
ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT )
{
ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING;
@@ -9799,16 +9871,20 @@
if( len > max_len )
{
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) "
"maximum fragment length: %d > %d",
len, max_len ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
- else
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ {
len = max_len;
+ }
+#endif
}
if( ssl->out_left != 0 )
@@ -10222,6 +10298,10 @@
void mbedtls_ssl_config_init( mbedtls_ssl_config *conf )
{
memset( conf, 0, sizeof( mbedtls_ssl_config ) );
+
+#if !defined(MBEDTLS_SSL_PROTO_TLS)
+ conf->transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
+#endif
}
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
@@ -10399,7 +10479,7 @@
conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION;
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) )
conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2;
#endif
@@ -10772,8 +10852,12 @@
void mbedtls_ssl_write_version( int major, int minor, int transport,
unsigned char ver[2] )
{
+#if !defined(MBEDTLS_SSL_TRANSPORT__BOTH)
+ ((void) transport);
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) )
{
if( minor == MBEDTLS_SSL_MINOR_VERSION_2 )
--minor; /* DTLS 1.0 stored as TLS 1.1 internally */
@@ -10781,21 +10865,25 @@
ver[0] = (unsigned char)( 255 - ( major - 2 ) );
ver[1] = (unsigned char)( 255 - ( minor - 1 ) );
}
- else
-#else
- ((void) transport);
+ MBEDTLS_SSL_TRANSPORT_ELSE
#endif
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
ver[0] = (unsigned char) major;
ver[1] = (unsigned char) minor;
}
+#endif
}
void mbedtls_ssl_read_version( int *major, int *minor, int transport,
const unsigned char ver[2] )
{
+#if !defined(MBEDTLS_SSL_TRANSPORT__BOTH)
+ ((void) transport);
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS)
- if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+ if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( transport ) )
{
*major = 255 - ver[0] + 2;
*minor = 255 - ver[1] + 1;
@@ -10803,14 +10891,14 @@
if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 )
++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */
}
- else
-#else
- ((void) transport);
-#endif
+ MBEDTLS_SSL_TRANSPORT_ELSE
+#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
{
*major = ver[0];
*minor = ver[1];
}
+#endif /* MBEDTLS_SSL_PROTO_TLS */
}
int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md )
diff --git a/library/version_features.c b/library/version_features.c
index 7494b42..fc0b1f8 100644
--- a/library/version_features.c
+++ b/library/version_features.c
@@ -486,6 +486,9 @@
#if defined(MBEDTLS_SSL_PROTO_DTLS)
"MBEDTLS_SSL_PROTO_DTLS",
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ "MBEDTLS_SSL_PROTO_TLS",
+#endif /* MBEDTLS_SSL_PROTO_TLS */
#if defined(MBEDTLS_SSL_ALPN)
"MBEDTLS_SSL_ALPN",
#endif /* MBEDTLS_SSL_ALPN */
diff --git a/library/x509_crt.c b/library/x509_crt.c
index ebd118d..2c93311 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -829,8 +829,10 @@
/*
* Parse and fill a single X.509 certificate in DER format
*/
-static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
- size_t buflen )
+static int x509_crt_parse_der_core( mbedtls_x509_crt *crt,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy )
{
int ret;
size_t len;
@@ -847,7 +849,7 @@
if( crt == NULL || buf == NULL )
return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
- // Use the original buffer until we figure out actual length
+ /* Use the original buffer until we figure out actual length. */
p = (unsigned char*) buf;
len = buflen;
end = p + len;
@@ -865,25 +867,26 @@
return( MBEDTLS_ERR_X509_INVALID_FORMAT );
}
- if( len > (size_t) ( end - p ) )
- {
- mbedtls_x509_crt_free( crt );
- return( MBEDTLS_ERR_X509_INVALID_FORMAT +
- MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
- }
- crt_end = p + len;
-
- // Create and populate a new buffer for the raw field
- crt->raw.len = crt_end - buf;
- crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
- if( p == NULL )
- return( MBEDTLS_ERR_X509_ALLOC_FAILED );
-
- memcpy( p, buf, crt->raw.len );
-
- // Direct pointers to the new buffer
- p += crt->raw.len - len;
end = crt_end = p + len;
+ crt->raw.len = crt_end - buf;
+ if( make_copy != 0 )
+ {
+ /* Create and populate a new buffer for the raw field. */
+ crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
+ if( crt->raw.p == NULL )
+ return( MBEDTLS_ERR_X509_ALLOC_FAILED );
+
+ memcpy( crt->raw.p, buf, crt->raw.len );
+ crt->own_buffer = 1;
+
+ p += crt->raw.len - len;
+ end = crt_end = p + len;
+ }
+ else
+ {
+ crt->raw.p = (unsigned char*) buf;
+ crt->own_buffer = 0;
+ }
/*
* TBSCertificate ::= SEQUENCE {
@@ -1086,8 +1089,10 @@
* Parse one X.509 certificate in DER format from a buffer and add them to a
* chained list
*/
-int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
- size_t buflen )
+static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen,
+ int make_copy )
{
int ret;
mbedtls_x509_crt *crt = chain, *prev = NULL;
@@ -1119,7 +1124,7 @@
crt = crt->next;
}
- if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
+ if( ( ret = x509_crt_parse_der_core( crt, buf, buflen, make_copy ) ) != 0 )
{
if( prev )
prev->next = NULL;
@@ -1133,11 +1138,27 @@
return( 0 );
}
+int mbedtls_x509_crt_parse_der_nocopy( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 0 ) );
+}
+
+int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
+{
+ return( mbedtls_x509_crt_parse_der_internal( chain, buf, buflen, 1 ) );
+}
+
/*
* Parse one or more PEM certificates from a buffer and add them to the chained
* list
*/
-int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
+int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain,
+ const unsigned char *buf,
+ size_t buflen )
{
#if defined(MBEDTLS_PEM_PARSE_C)
int success = 0, first_error = 0, total_failed = 0;
@@ -2675,7 +2696,7 @@
mbedtls_free( seq_prv );
}
- if( cert_cur->raw.p != NULL )
+ if( cert_cur->raw.p != NULL && cert_cur->own_buffer )
{
mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
mbedtls_free( cert_cur->raw.p );
diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c
index e1d1332..be35a76 100644
--- a/programs/ssl/query_config.c
+++ b/programs/ssl/query_config.c
@@ -1338,6 +1338,14 @@
}
#endif /* MBEDTLS_SSL_PROTO_DTLS */
+#if defined(MBEDTLS_SSL_PROTO_TLS)
+ if( strcmp( "MBEDTLS_SSL_PROTO_TLS", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_PROTO_TLS );
+ return( 0 );
+ }
+#endif /* MBEDTLS_SSL_PROTO_TLS */
+
#if defined(MBEDTLS_SSL_ALPN)
if( strcmp( "MBEDTLS_SSL_ALPN", config ) == 0 )
{
diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c
index 646909f..fc601ec 100644
--- a/programs/ssl/ssl_client1.c
+++ b/programs/ssl/ssl_client1.c
@@ -43,14 +43,15 @@
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_CERTS_C) || !defined(MBEDTLS_PEM_PARSE_C) || \
- !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C)
+ !defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
+ !defined(MBEDTLS_SSL_PROTO_TLS)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
- "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
- "not defined.\n");
+ "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or"
+ "MBEDTLS_SSL_PROTO_TLS not defined.\n");
return( 0 );
}
#else
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 9220d5d..bbd4d25 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -224,7 +224,7 @@
#if defined(MBEDTLS_SSL_PROTO_DTLS)
#define USAGE_DTLS \
- " dtls=%%d default: 0 (TLS)\n" \
+ " dtls=%%d default: 0 (TLS) (if both enabled)\n" \
" hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
" range of DTLS handshake timeouts in millisecs\n" \
" mtu=%%d default: (library default: unlimited)\n" \
diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c
index b6f1cc4..62b4c40 100644
--- a/programs/ssl/ssl_fork_server.c
+++ b/programs/ssl/ssl_fork_server.c
@@ -43,7 +43,8 @@
!defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_TIMING_C) || \
- !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_PEM_PARSE_C)
+ !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_PEM_PARSE_C) || \
+ !defined(MBEDTLS_SSL_PROTO_TLS)
int main( int argc, char *argv[] )
{
((void) argc);
@@ -53,7 +54,8 @@
"and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
- "MBEDTLS_TIMING_C and/or MBEDTLS_PEM_PARSE_C not defined.\n");
+ "MBEDTLS_TIMING_C and/or MBEDTLS_PEM_PARSE_C and/or "
+ "MBEDTLS_SSL_PROTO_TLS not defined.\n");
return( 0 );
}
#elif defined(_WIN32)
diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c
index c73297c..55c90c6 100644
--- a/programs/ssl/ssl_mail_client.c
+++ b/programs/ssl/ssl_mail_client.c
@@ -48,14 +48,14 @@
!defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_CLI_C) || \
!defined(MBEDTLS_NET_C) || !defined(MBEDTLS_RSA_C) || \
!defined(MBEDTLS_CTR_DRBG_C) || !defined(MBEDTLS_X509_CRT_PARSE_C) || \
- !defined(MBEDTLS_FS_IO)
+ !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_SSL_PROTO_TLS)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_ENTROPY_C and/or "
"MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_CLI_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
- "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
- "not defined.\n");
+ "MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
+ "MBEDTLS_SSL_PROTO_TLS not defined.\n");
return( 0 );
}
#else
diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c
index b502695..b00f476 100644
--- a/programs/ssl/ssl_pthread_server.c
+++ b/programs/ssl/ssl_pthread_server.c
@@ -45,7 +45,7 @@
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
!defined(MBEDTLS_THREADING_C) || !defined(MBEDTLS_THREADING_PTHREAD) || \
- !defined(MBEDTLS_PEM_PARSE_C)
+ !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_SSL_PROTO_TLS)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or MBEDTLS_ENTROPY_C "
@@ -53,7 +53,8 @@
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C and/or "
"MBEDTLS_THREADING_C and/or MBEDTLS_THREADING_PTHREAD "
- "and/or MBEDTLS_PEM_PARSE_C not defined.\n");
+ "and/or MBEDTLS_PEM_PARSE_C and/or "
+ "MBEDTLS_SSL_PROTO_TLS not defined.\n");
return( 0 );
}
#else
diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c
index 1852b2b..05d58fa 100644
--- a/programs/ssl/ssl_server.c
+++ b/programs/ssl/ssl_server.c
@@ -44,14 +44,15 @@
!defined(MBEDTLS_SSL_SRV_C) || !defined(MBEDTLS_NET_C) || \
!defined(MBEDTLS_RSA_C) || !defined(MBEDTLS_CTR_DRBG_C) || \
!defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_FS_IO) || \
- !defined(MBEDTLS_PEM_PARSE_C)
+ !defined(MBEDTLS_PEM_PARSE_C) || !defined(MBEDTLS_SSL_PROTO_TLS)
int main( void )
{
mbedtls_printf("MBEDTLS_BIGNUM_C and/or MBEDTLS_CERTS_C and/or MBEDTLS_ENTROPY_C "
"and/or MBEDTLS_SSL_TLS_C and/or MBEDTLS_SSL_SRV_C and/or "
"MBEDTLS_NET_C and/or MBEDTLS_RSA_C and/or "
"MBEDTLS_CTR_DRBG_C and/or MBEDTLS_X509_CRT_PARSE_C "
- "and/or MBEDTLS_PEM_PARSE_C not defined.\n");
+ "and/or MBEDTLS_PEM_PARSE_C and/or "
+ "MBEDTLS_SSL_PROTO_TLS not defined.\n");
return( 0 );
}
#else
diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
index 4dcbb16..b048bc7 100644
--- a/programs/ssl/ssl_server2.c
+++ b/programs/ssl/ssl_server2.c
@@ -330,7 +330,7 @@
#if defined(MBEDTLS_SSL_PROTO_DTLS)
#define USAGE_DTLS \
- " dtls=%%d default: 0 (TLS)\n" \
+ " dtls=%%d default: 0 (TLS) (if both enabled)\n" \
" hs_timeout=%%d-%%d default: (library default: 1000-60000)\n" \
" range of DTLS handshake timeouts in millisecs\n" \
" mtu=%%d default: (library default: unlimited)\n" \
diff --git a/programs/test/udp_proxy.c b/programs/test/udp_proxy.c
index 999c87e..979910e 100644
--- a/programs/test/udp_proxy.c
+++ b/programs/test/udp_proxy.c
@@ -637,32 +637,17 @@
static unsigned char dropped[2048] = { 0 };
#define DROP_MAX 2
-/*
- * OpenSSL groups packets in a datagram the first time it sends them, but not
- * when it resends them. Count every record as seen the first time.
- */
+/* We only drop packets at the level of entire datagrams, not at the level
+ * of records. In particular, if the peer changes the way it packs multiple
+ * records into a single datagram, we don't necessarily count the number of
+ * times a record has been dropped correctly. However, the only known reason
+ * why a peer would change datagram packing is disabling the latter on
+ * retransmission, in which case we'd drop involved records at most
+ * DROP_MAX + 1 times. */
void update_dropped( const packet *p )
{
size_t id = p->len % sizeof( dropped );
- const unsigned char *end = p->buf + p->len;
- const unsigned char *cur = p->buf;
- size_t len = ( ( cur[11] << 8 ) | cur[12] ) + 13;
-
++dropped[id];
-
- /* Avoid counting single record twice */
- if( len == p->len )
- return;
-
- while( cur < end )
- {
- len = ( ( cur[11] << 8 ) | cur[12] ) + 13;
-
- id = len % sizeof( dropped );
- ++dropped[id];
-
- cur += len;
- }
}
int handle_message( const char *way,
diff --git a/scripts/baremetal.sh b/scripts/baremetal.sh
index 86fac56..4b798b9 100755
--- a/scripts/baremetal.sh
+++ b/scripts/baremetal.sh
@@ -94,6 +94,11 @@
echo "ROM statistics written to:"
echo "* $ROM_OUT_FILE"
echo "* $ROM_OUT_SYMS"
+
+ # Print summary
+ cat $ROM_OUT_FILE | grep "libmbedtls.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
+ cat $ROM_OUT_FILE | grep "libmbedcrypto.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
+ cat $ROM_OUT_FILE | grep "libmbedx509.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
}
baremetal_build_armc5()
@@ -122,6 +127,11 @@
echo "ROM statistics written to:"
echo "* $ROM_OUT_FILE"
echo "* $ROM_OUT_SYMS"
+
+ # Print summary
+ cat $ROM_OUT_FILE | grep "libmbedtls.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
+ cat $ROM_OUT_FILE | grep "libmbedcrypto.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
+ cat $ROM_OUT_FILE | grep "libmbedx509.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
}
baremetal_build_armc6()
@@ -150,6 +160,11 @@
echo "ROM statistics written to:"
echo "* $ROM_OUT_FILE"
echo "* $ROM_OUT_SYMS"
+
+ # Print summary
+ cat $ROM_OUT_FILE | grep "libmbedtls.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
+ cat $ROM_OUT_FILE | grep "libmbedcrypto.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
+ cat $ROM_OUT_FILE | grep "libmbedx509.a" | awk '{printf( "%15s: %s Bytes\n", $4, $5)}'
}
# 32-bit host-build of library, tests and example programs,
diff --git a/tests/data_files/Makefile b/tests/data_files/Makefile
index d023c8d..acf8e9b 100644
--- a/tests/data_files/Makefile
+++ b/tests/data_files/Makefile
@@ -44,7 +44,9 @@
test-ca.crt: $(test_ca_key_file_rsa) test-ca.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=3 request_file=test-ca.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=PolarSSL Test CA" issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144400 not_after=20210212144400 md=SHA1 version=3 output_file=$@
-all_final += test-ca.crt
+test-ca.der: test-ca.crt
+ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
+all_final += test-ca.crt test-ca.der
test-ca-sha1.crt: $(test_ca_key_file_rsa) test-ca.req.sha256
$(MBEDTLS_CERT_WRITE) is_ca=1 serial=3 request_file=test-ca.req.sha256 selfsign=1 issuer_name="C=NL,O=PolarSSL,CN=PolarSSL Test CA" issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144400 not_after=20210212144400 md=SHA1 version=3 output_file=$@
@@ -903,7 +905,9 @@
server2.crt: server2.req.sha256
$(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA1 version=3 output_file=$@
-all_final += server2.crt
+server2.der: server2.crt
+ $(OPENSSL) x509 -inform PEM -in $< -outform DER -out $@
+all_final += server2.crt server2.der
server2-sha256.crt: server2.req.sha256
$(MBEDTLS_CERT_WRITE) request_file=server2.req.sha256 serial=2 issuer_crt=$(test_ca_crt) issuer_key=$(test_ca_key_file_rsa) issuer_pwd=$(test_ca_pwd_rsa) not_before=20110212144406 not_after=20210212144406 md=SHA256 version=3 output_file=$@
diff --git a/tests/data_files/server1.der b/tests/data_files/server1.der
new file mode 100644
index 0000000..fcf45cd
--- /dev/null
+++ b/tests/data_files/server1.der
Binary files differ
diff --git a/tests/data_files/server2.der b/tests/data_files/server2.der
new file mode 100644
index 0000000..ec03190
--- /dev/null
+++ b/tests/data_files/server2.der
Binary files differ
diff --git a/tests/data_files/test-ca.der b/tests/data_files/test-ca.der
new file mode 100644
index 0000000..039fb9e
--- /dev/null
+++ b/tests/data_files/test-ca.der
Binary files differ
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 6786c36..042d653 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -2,14 +2,26 @@
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/server1.crt":"cert. version \: 3\nserial number \: 01\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
+X509 Certificate information #1 (DER)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+x509_cert_info:"data_files/server1.der":"cert. version \: 3\nserial number \: 01\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
+
X509 Certificate information #2
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/server2.crt":"cert. version \: 3\nserial number \: 02\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
+X509 Certificate information #2 (DER)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+x509_cert_info:"data_files/server2.der":"cert. version \: 3\nserial number \: 02\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=localhost\nissued on \: 2011-02-12 14\:44\:06\nexpires on \: 2021-02-12 14\:44\:06\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
+
X509 Certificate information #3
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
x509_cert_info:"data_files/test-ca.crt":"cert. version \: 3\nserial number \: 03\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nissued on \: 2011-02-12 14\:44\:00\nexpires on \: 2021-02-12 14\:44\:00\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\n"
+X509 Certificate information #3 (DER)
+depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA1_C
+x509_cert_info:"data_files/test-ca.der":"cert. version \: 3\nserial number \: 03\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nissued on \: 2011-02-12 14\:44\:00\nexpires on \: 2021-02-12 14\:44\:00\nsigned using \: RSA with SHA1\nRSA key size \: 2048 bits\nbasic constraints \: CA=true\n"
+
X509 Certificate information MD2 Digest
depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_MD2_C
x509_cert_info:"data_files/cert_md2.crt":"cert. version \: 3\nserial number \: 09\nissuer name \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name \: C=NL, O=PolarSSL, CN=PolarSSL Cert MD2\nissued on \: 2009-07-12 10\:56\:59\nexpires on \: 2011-07-12 10\:56\:59\nsigned using \: RSA with MD2\nRSA key size \: 2048 bits\nbasic constraints \: CA=false\n"
diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function
index 552c494..a921310 100644
--- a/tests/suites/test_suite_x509parse.function
+++ b/tests/suites/test_suite_x509parse.function
@@ -505,8 +505,22 @@
mbedtls_x509_crt_init( &crt );
memset( output, 0, 2000 );
+ TEST_ASSERT( mbedtls_x509_crt_parse_der( &crt, buf->x, buf->len ) == ( result ) );
+ if( ( result ) == 0 )
+ {
+ res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );
- TEST_ASSERT( mbedtls_x509_crt_parse( &crt, buf->x, buf->len ) == ( result ) );
+ TEST_ASSERT( res != -1 );
+ TEST_ASSERT( res != -2 );
+
+ TEST_ASSERT( strcmp( (char *) output, result_str ) == 0 );
+ }
+
+ mbedtls_x509_crt_free( &crt );
+ mbedtls_x509_crt_init( &crt );
+ memset( output, 0, 2000 );
+
+ TEST_ASSERT( mbedtls_x509_crt_parse_der_nocopy( &crt, buf->x, buf->len ) == ( result ) );
if( ( result ) == 0 )
{
res = mbedtls_x509_crt_info( (char *) output, 2000, "", &crt );