diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 010dffc63..18851db41 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,7 +50,7 @@ When backporting to these branches please observe the following rules: 2. All bug fixes that correct a defect that is also present in an LTS branch must be backported to that LTS branch. If a bug fix introduces a change to the API such as a new function, the fix should be reworked to avoid the API change. API changes without very strong justification are unlikely to be accepted. - 3. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be addtional test cases or quality improvements such as changes to build or test scripts. + 3. If a contribution is a new feature or enhancement, no backporting is required. Exceptions to this may be additional test cases or quality improvements such as changes to build or test scripts. It would be highly appreciated if contributions are backported to LTS branches in addition to the [development branch](https://github.com/ARMmbed/mbedtls/tree/development) by contributors. diff --git a/ChangeLog b/ChangeLog index 49c3acf5f..3e85f3f66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,41 @@ mbed TLS ChangeLog (Sorted per branch, date) -= mbed TLS 2.x.x branch released xxxx-xx-xx += mbed TLS x.x.x branch released xxxx-xx-xx + +Features + * Add new configuration option MBEDTLS_SSL_NO_SESSION_CACHE that enables + code size savings in configurations where cache-based session resumption is + not used. + * Add new configuration option MBEDTLS_SSL_NO_SESSION_RESUMPTION that + enables code size savings in configurations where no form of session + resumption is used. + +Bugfix + * Fix to allow building test suites with any warning that detects unused + functions. Fixes #1628. + * Fix typo in net_would_block(). Fixes #528 reported by github-monoculture. + * Remove redundant include file in timing.c. Fixes #2640 reported by irwir. + * Fix Visual Studio Release x64 build configuration by inheriting + PlatformToolset from the project configuration. Fixes #1430 reported by + irwir. + * Enable Suite B with subset of ECP curves. Make sure the code compiles even + if some curves are not defined. Fixes #1591 reported by dbedev. + +Changes + * Make it easier to define MBEDTLS_PARAM_FAILED as assert (which config.h + suggests). #2671 + * Make `make clean` clean all programs always. Fixes #1862. + +API Changes + * Add a new compile-time option `MBEDTLS_X509_ON_DEMAND_PARSING`, + disabled by default, which allows to parse and cache X.509 CRTs + on demand only, at the benefit of lower RAM usage. Enabling + this option breaks the structure API of X.509 in that most + fields of `mbedtls_x509_crt` are removed, but it keeps the + X.509 function API. See the API changes section as well as + the documentation in `config.h` for more information. + += mbed TLS 2.16.2 branch released 2019-06-11 Security * Make mbedtls_ecdh_get_params return an error if the second key @@ -462,7 +497,7 @@ Security 1.2, that allowed a local attacker, able to execute code on the local machine as well as manipulate network packets, to partially recover the plaintext of messages under some conditions by using a cache attack - targetting an internal MD/SHA buffer. With TLS or if + targeting an internal MD/SHA buffer. With TLS or if mbedtls_ssl_conf_dtls_badmac_limit() was used, the attack only worked if the same secret (for example a HTTP Cookie) has been repeatedly sent over connections manipulated by the attacker. Connections using GCM or CCM @@ -1348,7 +1383,7 @@ Bugfix * Fix potential build failures related to the 'apidoc' target, introduced in the previous patch release. Found by Robert Scheck. #390 #391 * Fix issue in Makefile that prevented building using armar. #386 - * Fix memory leak that occured only when ECJPAKE was enabled and ECDHE and + * Fix memory leak that occurred only when ECJPAKE was enabled and ECDHE and ECDSA was disabled in config.h . The leak didn't occur by default. * Fix an issue that caused valid certificates to be rejected whenever an expired or not yet valid certificate was parsed before a valid certificate @@ -1590,7 +1625,7 @@ API Changes You now need to link to all of them if you use TLS for example. * All public identifiers moved to the mbedtls_* or MBEDTLS_* namespace. Some names have been further changed to make them more consistent. - Migration helpers scripts/rename.pl and include/mbedlts/compat-1.3.h are + Migration helpers scripts/rename.pl and include/mbedtls/compat-1.3.h are provided. Full list of renamings in scripts/data_files/rename-1.3-2.0.txt * Renamings of fields inside structures, not covered by the previous list: mbedtls_cipher_info_t.key_length -> key_bitlen @@ -1645,7 +1680,7 @@ API Changes * net_accept() gained new arguments for the size of the client_ip buffer. * In the threading layer, mbedtls_mutex_init() and mbedtls_mutex_free() now return void. - * ecdsa_write_signature() gained an addtional md_alg argument and + * ecdsa_write_signature() gained an additional md_alg argument and ecdsa_write_signature_det() was deprecated. * pk_sign() no longer accepts md_alg == POLARSSL_MD_NONE with ECDSA. * Last argument of x509_crt_check_key_usage() and @@ -3180,7 +3215,7 @@ XySSL ChangeLog not swapped on PadLock; also fixed compilation on older versions of gcc (bug reported by David Barrett) * Correctly handle the case in padlock_xcryptcbc() when input or - ouput data is non-aligned by falling back to the software + output data is non-aligned by falling back to the software implementation, as VIA Nehemiah cannot handle non-aligned buffers * Fixed a memory leak in x509parse_crt() which was reported by Greg Robson-Garth; some x509write.c fixes by Pascal Vizeli, thanks to diff --git a/README.md b/README.md index 94ea84b9d..62dd4e2b2 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ In order to build for a Windows platform, you should use `WINDOWS_BUILD=1` if th Setting the variable `SHARED` in your environment will build shared libraries in addition to the static libraries. Setting `DEBUG` gives you a debug build. You can override `CFLAGS` and `LDFLAGS` by setting them in your environment or on the make command line; compiler warning options may be overridden separately using `WARNING_CFLAGS`. Some directory-specific options (for example, `-I` directives) are still preserved. -Please note that setting `CFLAGS` overrides its default value of `-O2` and setting `WARNING_CFLAGS` overrides its default value (starting with `-Wall -W`), so if you just want to add some warning options to the default ones, you can do so by setting `CFLAGS=-O2 -Werror` for example. Setting `WARNING_CFLAGS` is useful when you want to get rid of its default content (for example because your compiler doesn't accept `-Wall` as an option). Directory-specific options cannot be overriden from the command line. +Please note that setting `CFLAGS` overrides its default value of `-O2` and setting `WARNING_CFLAGS` overrides its default value (starting with `-Wall -W`), so if you just want to add some warning options to the default ones, you can do so by setting `CFLAGS=-O2 -Werror` for example. Setting `WARNING_CFLAGS` is useful when you want to get rid of its default content (for example because your compiler doesn't accept `-Wall` as an option). Directory-specific options cannot be overridden from the command line. Depending on your platform, you might run into some issues. Please check the Makefiles in `library/`, `programs/` and `tests/` for options to manually add or remove for specific platforms. You can also check [the Mbed TLS Knowledge Base](https://tls.mbed.org/kb) for articles on your platform or issue. diff --git a/configs/baremetal.h b/configs/baremetal.h index 330b513fc..7ff7b07c9 100644 --- a/configs/baremetal.h +++ b/configs/baremetal.h @@ -71,6 +71,8 @@ #define MBEDTLS_SSL_TLS_C #define MBEDTLS_SSL_PROTO_TLS1_2 #define MBEDTLS_SSL_EXTENDED_MASTER_SECRET +#define MBEDTLS_SSL_NO_SESSION_CACHE +#define MBEDTLS_SSL_NO_SESSION_RESUMPTION #define MBEDTLS_SSL_COOKIE_C #define MBEDTLS_SSL_PROTO_DTLS #define MBEDTLS_SSL_PROTO_NO_TLS @@ -80,6 +82,17 @@ #define MBEDTLS_SSL_DTLS_CONNECTION_ID /* Compile-time fixed parts of the SSL configuration */ +#define MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED +#define MBEDTLS_SSL_CONF_READ_TIMEOUT 0 +#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN 1000 +#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX 16000 +#define MBEDTLS_SSL_CONF_CID_LEN 2 +#define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE +#define MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION \ + MBEDTLS_SSL_SECURE_RENEGOTIATION +#define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED +#define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0 +#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED #define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET \ MBEDTLS_SSL_EXTENDED_MS_ENABLED #define MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET \ @@ -91,6 +104,8 @@ #define MBEDTLS_X509_CHECK_KEY_USAGE #define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE #define MBEDTLS_X509_REMOVE_INFO +#define MBEDTLS_X509_ON_DEMAND_PARSING +#define MBEDTLS_X509_ALWAYS_FLUSH #define MBEDTLS_ASN1_PARSE_C /* X.509 CSR writing */ diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index 6345ddc0b..3336f0fca 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -24,7 +24,7 @@ */ /** - * @mainpage mbed TLS v2.16.1 source code documentation + * @mainpage mbed TLS v2.16.2 source code documentation * * This documentation describes the internal structure of mbed TLS. It was * automatically generated from specially formatted comment blocks in diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index e5d2ddaae..d19c23182 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -28,7 +28,7 @@ DOXYFILE_ENCODING = UTF-8 # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. -PROJECT_NAME = "mbed TLS v2.16.1" +PROJECT_NAME = "mbed TLS v2.16.2" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or diff --git a/include/mbedtls/asn1.h b/include/mbedtls/asn1.h index 96c1c9a8a..94990fe5e 100644 --- a/include/mbedtls/asn1.h +++ b/include/mbedtls/asn1.h @@ -89,6 +89,18 @@ #define MBEDTLS_ASN1_CONSTRUCTED 0x20 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80 +/* Slightly smaller way to check if tag is a string tag + * compared to canonical implementation. */ +#define MBEDTLS_ASN1_IS_STRING_TAG( tag ) \ + ( ( tag ) < 32u && ( \ + ( ( 1u << ( tag ) ) & ( ( 1u << MBEDTLS_ASN1_BMP_STRING ) | \ + ( 1u << MBEDTLS_ASN1_UTF8_STRING ) | \ + ( 1u << MBEDTLS_ASN1_T61_STRING ) | \ + ( 1u << MBEDTLS_ASN1_IA5_STRING ) | \ + ( 1u << MBEDTLS_ASN1_UNIVERSAL_STRING ) | \ + ( 1u << MBEDTLS_ASN1_PRINTABLE_STRING ) | \ + ( 1u << MBEDTLS_ASN1_BIT_STRING ) ) ) != 0 ) ) + /* * Bit masks for each of the components of an ASN.1 tag as specified in * ITU X.690 (08/2015), section 8.1 "General rules for encoding", @@ -119,6 +131,10 @@ ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \ memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 ) +#define MBEDTLS_OID_CMP_RAW(oid_str, oid_buf, oid_buf_len) \ + ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len) ) || \ + memcmp( (oid_str), (oid_buf), (oid_buf_len) ) != 0 ) + #ifdef __cplusplus extern "C" { #endif @@ -260,20 +276,97 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end size_t *len ); /** - * \brief Parses and splits an ASN.1 "SEQUENCE OF " - * Updated the pointer to immediately behind the full sequence tag. + * \brief Free a heap-allocated linked list presentation of + * an ASN.1 sequence, including the first element. * - * \param p The position in the ASN.1 data - * \param end End of data - * \param cur First variable in the chain to fill - * \param tag Type of sequence + * \param seq The address of the first sequence component. This may + * be \c NULL, in which case this functions returns + * immediately. + */ +void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq ); + +/** + * \brief This function parses and splits an ASN.1 "SEQUENCE OF " + * and updates the source buffer pointer to immediately behind + * the full sequence. + * + * \param p The address of the pointer to the beginning of the + * ASN.1 SEQUENCE OF structure, including ASN.1 tag+length header. + * On success, `*p` is advanced to point to the first byte + * following the parsed ASN.1 sequence. + * \param end The end of the ASN.1 input buffer starting at \p p. This is + * used for bounds checking. + * \param cur The address at which to store the first entry in the parsed + * sequence. Further entries are heap-allocated and referenced + * from \p cur. + * \param tag The common tag of the entries in the ASN.1 sequence. + * + * \note Ownership for the heap-allocated elements \c cur->next, + * \c cur->next->next, ..., is passed to the caller. It + * is hence the caller's responsibility to free them when + * no longer needed, and mbedtls_asn1_sequence_free() can + * be used for that, passing \c cur->next as the \c seq + * argument (or \p cur if \p cur itself was heap-allocated + * by the caller). * * \return 0 if successful or a specific ASN.1 error code. */ int mbedtls_asn1_get_sequence_of( unsigned char **p, const unsigned char *end, mbedtls_asn1_sequence *cur, - int tag); + int tag ); + +/** + * \brief Traverse an ASN.1 SEQUENCE container and + * call a callback for each entry. + * + * \warning This function is still experimental and may change + * at any time. + * + * \param p The address of the pointer to the beginning of + * the ASN.1 SEQUENCE header. This is updated to + * point to the end of the ASN.1 SEQUENCE container + * on a successful invocation. + * \param end The end of the ASN.1 SEQUENCE container. + * \param tag_must_mask A mask to be applied to the ASN.1 tags found within + * the SEQUENCE before comparing to \p tag_must_value. + * \param tag_must_val The required value of each ASN.1 tag found in the + * SEQUENCE, after masking with \p tag_must_mask. + * Mismatching tags lead to an error. + * For example, a value of \c 0 for both \p tag_must_mask + * and \p tag_must_val means that every tag is allowed, + * while a value of \c 0xFF for \p tag_must_mask means + * that \p tag_must_val is the only allowed tag. + * \param tag_may_mask A mask to be applied to the ASN.1 tags found within + * the SEQUENCE before comparing to \p tag_may_value. + * \param tag_may_val The desired value of each ASN.1 tag found in the + * SEQUENCE, after masking with \p tag_may_mask. + * Mismatching tags will be silently ignored. + * For example, a value of \c 0 for \p tag_may_mask and + * \p tag_may_val means that any tag will be considered, + * while a value of \c 0xFF for \p tag_may_mask means + * that all tags with value different from \p tag_may_val + * will be ignored. + * \param cb The callback to trigger for each component + * in the ASN.1 SEQUENCE. If the callback returns + * a non-zero value, the function stops immediately, + * forwarding the callback's return value. + * \param ctx The context to be passed to the callback \p cb. + * + * \return \c 0 if successful the entire ASN.1 SEQUENCE + * was traversed without parsing or callback errors. + * \return A negative ASN.1 error code on a parsing failure. + * \return A non-zero error code forwarded from the callback + * \p cb in case the latter returns a non-zero value. + */ +int mbedtls_asn1_traverse_sequence_of( + unsigned char **p, + const unsigned char *end, + uint8_t tag_must_mask, uint8_t tag_must_val, + uint8_t tag_may_mask, uint8_t tag_may_val, + int (*cb)( void *ctx, int tag, + unsigned char* start, size_t len ), + void *ctx ); #if defined(MBEDTLS_BIGNUM_C) /** diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h index 88f47011b..764fba4b4 100644 --- a/include/mbedtls/check_config.h +++ b/include/mbedtls/check_config.h @@ -631,6 +631,20 @@ #error "MBEDTLS_SSL_CID_OUT_LEN_MAX too large (max 255)" #endif +#if ( defined(MBEDTLS_SSL_CONF_CID_LEN) && \ + !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) ) || \ + ( !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ + defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) ) +#error "MBEDTLS_SSL_CONF_CID_LEN and MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID must be defined simultaneously" +#endif + +#if ( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \ + !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) || \ + ( !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) && \ + defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) ) +#error "MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN and MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX must be defined simultaneously" +#endif + #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ ( !defined(MBEDTLS_SSL_TLS_C) || !defined(MBEDTLS_SSL_PROTO_DTLS) ) #error "MBEDTLS_SSL_DTLS_BADMAC_LIMIT defined, but not all prerequisites" @@ -671,6 +685,16 @@ #error "MBEDTLS_SSL_SERVER_NAME_INDICATION defined, but not all prerequisites" #endif +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && \ + defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) +#error "MBEDTLS_SSL_SESSION_TICKETS cannot be defined with MBEDTLS_SSL_NO_SESSION_RESUMPTION" +#endif + +#if !defined(MBEDTLS_SSL_NO_SESSION_CACHE) && \ + defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) +#error "MBEDTLS_SSL_NO_SESSION_CACHE needs to be defined with MBEDTLS_SSL_NO_SESSION_RESUMPTION" +#endif + #if defined(MBEDTLS_THREADING_PTHREAD) #if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL) #error "MBEDTLS_THREADING_PTHREAD defined, but not all prerequisites" @@ -738,7 +762,7 @@ /* * Avoid warning from -pedantic. This is a convenient place for this * workaround since this is included by every single file before the - * #if defined(MBEDTLS_xxx_C) that results in emtpy translation units. + * #if defined(MBEDTLS_xxx_C) that results in empty translation units. */ typedef int mbedtls_iso_c_forbids_empty_translation_units; diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 2116521dc..95dd4cdbe 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -139,7 +139,7 @@ * * System has time.h, time(), and an implementation for * mbedtls_platform_gmtime_r() (see below). - * The time needs to be correct (not necesarily very accurate, but at least + * The time needs to be correct (not necessarily very accurate, but at least * the date should be correct). This is used to verify the validity period of * X.509 certificates. * @@ -276,28 +276,52 @@ * For example, when a function accepts as input a pointer to a buffer that may * contain untrusted data, and its documentation mentions that this pointer * must not be NULL: - * - the pointer is checked to be non-NULL only if this option is enabled - * - the content of the buffer is always validated + * - The pointer is checked to be non-NULL only if this option is enabled. + * - The content of the buffer is always validated. * * When this flag is defined, if a library function receives a parameter that - * is invalid, it will: - * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a - * call to the function mbedtls_param_failed() - * - immediately return (with a specific error code unless the function - * returns void and can't communicate an error). + * is invalid: + * 1. The function will invoke the macro MBEDTLS_PARAM_FAILED(). + * 2. If MBEDTLS_PARAM_FAILED() did not terminate the program, the function + * will immediately return. If the function returns an Mbed TLS error code, + * the error code in this case is MBEDTLS_ERR_xxx_BAD_INPUT_DATA. * - * When defining this flag, you also need to: - * - either provide a definition of the function mbedtls_param_failed() in - * your application (see platform_util.h for its prototype) as the library - * calls that function, but does not provide a default definition for it, - * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED() - * below if the above mechanism is not flexible enough to suit your needs. - * See the documentation of this macro later in this file. + * When defining this flag, you also need to arrange a definition for + * MBEDTLS_PARAM_FAILED(). You can do this by any of the following methods: + * - By default, the library defines MBEDTLS_PARAM_FAILED() to call a + * function mbedtls_param_failed(), but the library does not define this + * function. If you do not make any other arrangements, you must provide + * the function mbedtls_param_failed() in your application. + * See `platform_util.h` for its prototype. + * - If you enable the macro #MBEDTLS_CHECK_PARAMS_ASSERT, then the + * library defines #MBEDTLS_PARAM_FAILED(\c cond) to be `assert(cond)`. + * You can still supply an alternative definition of + * MBEDTLS_PARAM_FAILED(), which may call `assert`. + * - If you define a macro MBEDTLS_PARAM_FAILED() before including `config.h` + * or you uncomment the definition of MBEDTLS_PARAM_FAILED() in `config.h`, + * the library will call the macro that you defined and will not supply + * its own version. Note that if MBEDTLS_PARAM_FAILED() calls `assert`, + * you need to enable #MBEDTLS_CHECK_PARAMS_ASSERT so that library source + * files include ``. * * Uncomment to enable validation of application-controlled parameters. */ //#define MBEDTLS_CHECK_PARAMS +/** + * \def MBEDTLS_CHECK_PARAMS_ASSERT + * + * Allow MBEDTLS_PARAM_FAILED() to call `assert`, and make it default to + * `assert`. This macro is only used if #MBEDTLS_CHECK_PARAMS is defined. + * + * If this macro is not defined, then MBEDTLS_PARAM_FAILED() defaults to + * calling a function mbedtls_param_failed(). See the documentation of + * #MBEDTLS_CHECK_PARAMS for details. + * + * Uncomment to allow MBEDTLS_PARAM_FAILED() to call `assert`. + */ +//#define MBEDTLS_CHECK_PARAMS_ASSERT + /* \} name SECTION: System support */ /** @@ -401,7 +425,7 @@ * \note Because of a signature change, the core AES encryption and decryption routines are * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, * respectively. When setting up alternative implementations, these functions should - * be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt * must stay untouched. * * \note If you use the AES_xxx_ALT macros, then is is recommended to also set @@ -1278,8 +1302,8 @@ * which allows to identify DTLS connections across changes * in the underlying transport. * - * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, - * `mbedtls_ssl_get_peer_cid()` and `mbedtls_ssl_conf_cid()`. + * Setting this option enables the SSL APIs mbedtls_ssl_set_cid(), + * mbedtls_ssl_get_peer_cid() and mbedtls_ssl_conf_cid(). * See the corresponding documentation for more information. * * \warning The Connection ID extension is still in draft state. @@ -1658,16 +1682,69 @@ * \def MBEDTLS_SSL_SESSION_TICKETS * * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintainance of a + * Client-side, provides full support for session tickets (maintenance of a * session store remains the responsibility of the application, though). * Server-side, you also need to provide callbacks for writing and parsing * tickets, including authenticated encryption and key management. Example * callbacks are provided by MBEDTLS_SSL_TICKET_C. * - * Comment this macro to disable support for SSL session tickets + * Requires: !MBEDTLS_SSL_NO_SESSION_RESUMPTION + * + * Comment this macro to disable support for SSL session tickets. */ #define MBEDTLS_SSL_SESSION_TICKETS +/** + * \def MBEDTLS_SSL_NO_SESSION_CACHE + * + * Disable support for cache based session resumption. This is useful to + * reduce code size in configurations where cache-based session resumption is + * not used. + * + * This option is only about the server-side support of the session caches. + * Client will only need !MBEDTLS_SSL_NO_SESSION_RESUMPTION to support + * cache based session resumption. + * + * Server-side, you also need to provide callbacks for storing and reading + * sessions from cache. Example callbacks are provided by MBEDTLS_SSL_CACHE_C. + * + * If MBEDTLS_SSL_NO_SESSION_RESUMPTION is defined, this needs to be defined + * as well. + * + * Uncomment this macro to disable support for SSL session cache. + */ +//#define MBEDTLS_SSL_NO_SESSION_CACHE + +/** + * \def MBEDTLS_SSL_NO_SESSION_RESUMPTION + * + * Disable support for session resumption. This is useful to reduce code size + * in configurations where no form of session resumption is used. + * + * \note Session resumption is part of the TLS standard, disabling this + * option means that the full implementation of the standard is no longer + * used. This shouldn't cause any interoperability issues as the standard + * mandates that peers who want to resume a session need to be prepared to + * fall back to a full handshake. + * + * When this flag is enabled, following needs to be true: + * MBEDTLS_SSL_NO_SESSION_CACHE enabled + * MBEDTLS_SSL_SESSION_TICKETS disabled + * + * Client-side, this is enough to enable support for cache-based session + * resumption (as defined by the TLS standard); for ticket-based resumption + * you'll also need to enable MBEDTLS_SSL_SESSION_TICKETS. + * + * Server-side, this option is only useful in conjunction with at least + * one of !MBEDTLS_SSL_NO_SESSION_CACHE or MBEDTLS_SSL_SESSION_TICKETS. + * Each one of these additionally requires an implementation of the cache + * or tickets, examples of which are provided by MBEDTLS_SSL_CACHE_C + * and MBEDTLS_SSL_TICKET_C respectively. + * + * Uncomment this macro to disable support for SSL session resumption. + */ +//#define MBEDTLS_SSL_NO_SESSION_RESUMPTION + /** * \def MBEDTLS_SSL_EXPORT_KEYS * @@ -1757,6 +1834,54 @@ */ #define MBEDTLS_VERSION_FEATURES +/** + * \def MBEDTLS_X509_ON_DEMAND_PARSING + * + * Save RAM by reducing mbedtls_x509_crt to a pointer + * to the raw CRT data and parsing CRTs on demand only. + * + * \warning This option changes the API by removing most of + * the structure fields of mbedtls_x509_crt. + * + * \warning This option and its corresponding X.509 API are currently + * under development and may change at any time. + * + * Regardless of whether this option is enabled or not, direct access of + * structure fields of `mbedtls_x509_crt` should be replaced by calls to + * one of the following functions: + * - mbedtls_x509_crt_get_frame(), to obtain a CRT frame giving + * access to several basic CRT fields (such as the CRT version), + * as well as pointers to the raw ASN.1 data of more complex fields + * (such as the issuer). + * - mbedtls_x509_crt_get_pk(), to obtain a public key context + * for the public key contained in the certificate. + * - mbedtls_x509_crt_get_issuer(), to obtain the issuer name. + * - mbedtls_x509_crt_get_subject(), to obtain the subject name. + * - mbedtls_x509_crt_get_subject_alt_names(), to obtain the + * alternative names from the subject alternative names extension. + * - mbedtls_x509_crt_get_ext_key_usage(), to obtain the state of + * the extended key usage extension. + * + * Uncomment this to enable on-demand CRT parsing to save RAM. + */ +//#define MBEDTLS_X509_ON_DEMAND_PARSING + +/** + * \def MBEDTLS_X509_ALWAYS_FLUSH + * + * Save RAM by having Mbed TLS always flush caches for parsed X.509 + * structures after use: This means, firstly, that caches of X.509 + * structures used by an API call are flushed when the call returns, + * but it also encompasses immediate flushing of caches when Mbed TLS uses + * multiple structures in succession, thereby reducing the peak RAM usage. + * Setting this option leads to minimal RAM usage of the X.509 module at + * the cost of performance penalties when using X.509 structures multiple + * times (such as trusted CRTs on systems serving many connections). + * + * Uncomment this to always flush caches for unused X.509 structures. + */ +#define MBEDTLS_X509_ALWAYS_FLUSH + /** * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 * @@ -1835,7 +1960,7 @@ * * \warning TLS-level compression MAY REDUCE SECURITY! See for example the * CRIME attack. Before enabling this option, you should examine with care if - * CRIME or similar exploits may be a applicable to your use case. + * CRIME or similar exploits may be applicable to your use case. * * \note Currently compression can't be used with DTLS. * @@ -3163,7 +3288,7 @@ //#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correclty zero-terminate the buffer! */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ @@ -3180,20 +3305,23 @@ //#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ //#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ -/* Note: your snprintf must correclty zero-terminate the buffer! */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ //#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ //#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ //#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ /** * \brief This macro is invoked by the library when an invalid parameter - * is detected that is only checked with MBEDTLS_CHECK_PARAMS + * is detected that is only checked with #MBEDTLS_CHECK_PARAMS * (see the documentation of that option for context). * - * When you leave this undefined here, a default definition is - * provided that invokes the function mbedtls_param_failed(), - * which is declared in platform_util.h for the benefit of the - * library, but that you need to define in your application. + * When you leave this undefined here, the library provides + * a default definition. If the macro #MBEDTLS_CHECK_PARAMS_ASSERT + * is defined, the default definition is `assert(cond)`, + * otherwise the default definition calls a function + * mbedtls_param_failed(). This function is declared in + * `platform_util.h` for the benefit of the library, but + * you need to define in your application. * * When you define this here, this replaces the default * definition in platform_util.h (which no longer declares the @@ -3202,6 +3330,9 @@ * particular, that all the necessary declarations are visible * from within the library - you can ensure that by providing * them in this file next to the macro definition). + * If you define this macro to call `assert`, also define + * #MBEDTLS_CHECK_PARAMS_ASSERT so that library source files + * include ``. * * Note that you may define this macro to expand to nothing, in * which case you don't have to worry about declarations or @@ -3450,6 +3581,26 @@ * \{ */ +//#define MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION + +//#define MBEDTLS_SSL_CONF_AUTHMODE MBEDTLS_SSL_VERIFY_REQUIRED + +/* Timeout */ +//#define MBEDTLS_SSL_CONF_READ_TIMEOUT 0 + +/* Endpoint (Client/Server) */ +//#define MBEDTLS_SSL_CONF_ENDPOINT MBEDTLS_SSL_IS_CLIENT + +//#define MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED + +/* DTLS-specific settings */ +//#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN +//#define MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX +//#define MBEDTLS_SSL_CONF_ANTI_REPLAY MBEDTLS_SSL_ANTI_REPLAY_ENABLED +//#define MBEDTLS_SSL_CONF_BADMAC_LIMIT 0 +//#define MBEDTLS_SSL_CONF_CID_LEN 0 +//#define MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID MBEDTLS_SSL_UNEXPECTED_CID_IGNORE + /* ExtendedMasterSecret extension * The following two options must be set/unset simultaneously. */ //#define MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET MBEDTLS_SSL_EXTENDED_MS_ENABLED diff --git a/include/mbedtls/hmac_drbg.h b/include/mbedtls/hmac_drbg.h index 7eae32bbd..f1289cb30 100644 --- a/include/mbedtls/hmac_drbg.h +++ b/include/mbedtls/hmac_drbg.h @@ -82,7 +82,7 @@ extern "C" { */ typedef struct mbedtls_hmac_drbg_context { - /* Working state: the key K is not stored explicitely, + /* Working state: the key K is not stored explicitly, * but is implied by the HMAC context */ mbedtls_md_context_t md_ctx; /*!< HMAC context (inc. K) */ unsigned char V[MBEDTLS_MD_MAX_SIZE]; /*!< V in the spec */ diff --git a/include/mbedtls/platform_util.h b/include/mbedtls/platform_util.h index dba6d4598..09d096518 100644 --- a/include/mbedtls/platform_util.h +++ b/include/mbedtls/platform_util.h @@ -43,6 +43,12 @@ extern "C" { #if defined(MBEDTLS_CHECK_PARAMS) +#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) +/* Allow the user to define MBEDTLS_PARAM_FAILED to something like assert + * (which is what our config.h suggests). */ +#include +#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ + #if defined(MBEDTLS_PARAM_FAILED) /** An alternative definition of MBEDTLS_PARAM_FAILED has been set in config.h. * @@ -50,6 +56,11 @@ extern "C" { * MBEDTLS_PARAM_FAILED() will expand to a call to mbedtls_param_failed(). */ #define MBEDTLS_PARAM_FAILED_ALT + +#elif defined(MBEDTLS_CHECK_PARAMS_ASSERT) +#define MBEDTLS_PARAM_FAILED( cond ) assert( cond ) +#define MBEDTLS_PARAM_FAILED_ALT + #else /* MBEDTLS_PARAM_FAILED */ #define MBEDTLS_PARAM_FAILED( cond ) \ mbedtls_param_failed( #cond, __FILE__, __LINE__ ) diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index 906c42733..4ff5bdd83 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -150,13 +150,13 @@ mbedtls_rsa_context; * \note The choice of padding mode is strictly enforced for private key * operations, since there might be security concerns in * mixing padding modes. For public key operations it is - * a default value, which can be overriden by calling specific + * a default value, which can be overridden by calling specific * \c rsa_rsaes_xxx or \c rsa_rsassa_xxx functions. * * \note The hash selected in \p hash_id is always used for OEAP * encryption. For PSS signatures, it is always used for - * making signatures, but can be overriden for verifying them. - * If set to #MBEDTLS_MD_NONE, it is always overriden. + * making signatures, but can be overridden for verifying them. + * If set to #MBEDTLS_MD_NONE, it is always overridden. * * \param ctx The RSA context to initialize. This must not be \c NULL. * \param padding The padding mode to use. This must be either diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b51708970..ead0fa7b4 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -906,11 +906,13 @@ struct mbedtls_ssl_config int (*f_rng)(void *, unsigned char *, size_t); void *p_rng; /*!< context for the RNG function */ +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /** Callback to retrieve a session from the cache */ int (*f_get_cache)(void *, mbedtls_ssl_session *); /** Callback to store a session into the cache */ int (*f_set_cache)(void *, const mbedtls_ssl_session *); void *p_cache; /*!< context for cache callbacks */ +#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) /** Callback for setting cert according to SNI extension */ @@ -957,7 +959,9 @@ struct mbedtls_ssl_config #endif #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#if !defined(MBEDTLS_SSL_CONF_CID_LEN) size_t cid_len; /*!< The length of CIDs for incoming DTLS records. */ +#endif /* !MBEDTLS_SSL_CONF_CID_LEN */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -1013,14 +1017,20 @@ struct mbedtls_ssl_config * Numerical settings (int then char) */ +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) uint32_t read_timeout; /*!< timeout for mbedtls_ssl_read (ms) */ +#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ #if defined(MBEDTLS_SSL_PROTO_DTLS) +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) uint32_t hs_timeout_min; /*!< initial value of the handshake retransmission timeout (ms) */ +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) uint32_t hs_timeout_max; /*!< maximum value of the handshake retransmission timeout (ms) */ -#endif +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ #if defined(MBEDTLS_SSL_RENEGOTIATION) int renego_max_records; /*!< grace period for renegotiation */ @@ -1029,7 +1039,9 @@ struct mbedtls_ssl_config #endif #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) unsigned int badmac_limit; /*!< limit of records with a bad MAC */ +#endif /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ #endif #if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) @@ -1045,11 +1057,17 @@ struct mbedtls_ssl_config * Flags (bitfields) */ +#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) unsigned int endpoint : 1; /*!< 0: client, 1: server */ +#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */ unsigned int transport : 1; /*!< stream (TLS) or datagram (DTLS) */ +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) unsigned int authmode : 2; /*!< MBEDTLS_SSL_VERIFY_XXX */ +#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) /* needed even with renego disabled for LEGACY_BREAK_HANDSHAKE */ unsigned int allow_legacy_renegotiation : 2 ; /*!< MBEDTLS_LEGACY_XXX */ +#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ #if defined(MBEDTLS_ARC4_C) unsigned int arc4_disabled : 1; /*!< blacklist RC4 ciphersuites? */ #endif @@ -1070,8 +1088,10 @@ struct mbedtls_ssl_config #endif /* !MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET */ #endif #if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) unsigned int anti_replay : 1; /*!< detect and prevent replay? */ -#endif +#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ #if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) unsigned int cbc_record_splitting : 1; /*!< do cbc record splitting */ #endif @@ -1088,13 +1108,17 @@ struct mbedtls_ssl_config unsigned int fallback : 1; /*!< is this a fallback? */ #endif #if defined(MBEDTLS_SSL_SRV_C) +#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) unsigned int cert_req_ca_list : 1; /*!< enable sending CA list in Certificate Request messages? */ +#endif /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ #endif #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#if !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) unsigned int ignore_unexpected_cid : 1; /*!< Determines whether DTLS * record with unexpected CID * should lead to failure. */ +#endif /* !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ #endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ }; @@ -1363,13 +1387,18 @@ int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, */ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ); +#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) /** * \brief Set the current endpoint type * + * \note On constrained systems, this can also be configured + * at compile-time via MBEDTLS_SSL_CONF_ENDPOINT. + * * \param conf SSL configuration * \param endpoint must be MBEDTLS_SSL_IS_CLIENT or MBEDTLS_SSL_IS_SERVER */ void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ); +#endif /* !MBEDTLS_SSL_CONF_ENDPOINT */ /** * \brief Set the transport type (TLS or DTLS). @@ -1680,6 +1709,7 @@ int mbedtls_ssl_get_peer_cid( mbedtls_ssl_context *ssl, void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) /** * \brief Set the timeout period for mbedtls_ssl_read() * (Default: no timeout.) @@ -1693,10 +1723,14 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); * With non-blocking I/O, this will only work if timer * callbacks were set with \c mbedtls_ssl_set_timer_cb(). * + * \note On constrained systems, this option can also be configured + * at compile-time via MBEDTLS_SSL_CONF_READ_TIMEOUT. + * * \note With non-blocking I/O, you may also skip this function * altogether and handle timeouts at the application layer. */ void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ); +#endif /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ /** * \brief Set the timer callbacks (Mandatory for DTLS.) @@ -2016,14 +2050,16 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, #endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) /** * \brief Enable or disable anti-replay protection for DTLS. * (DTLS only, no effect on TLS.) * Default: enabled. * * \param conf SSL configuration - * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or MBEDTLS_SSL_ANTI_REPLAY_DISABLED. + * \param mode MBEDTLS_SSL_ANTI_REPLAY_ENABLED or + * MBEDTLS_SSL_ANTI_REPLAY_DISABLED. * * \warning Disabling this is a security risk unless the application * protocol handles duplicated packets in a safe way. You @@ -2031,11 +2067,16 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, * However, if your application already detects duplicated * packets and needs information about them to adjust its * transmission strategy, then you'll want to disable this. + * + * \note On constrained systems, this option can also be + * fixed at compile-time by defining the constant + * MBEDTLS_SSL_CONF_ANTI_REPLAY. */ void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); -#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY && !MBEDTLS_SSL_CONF_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) /** * \brief Set a limit on the number of records with a bad MAC * before terminating the connection. @@ -2058,9 +2099,13 @@ void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ); * connection. On the other hand, a high limit or no limit * might make us waste resources checking authentication on * many bogus packets. + * + * \note On constrained systems, this option can also be + * fixed at compile-time by defining the constant + * MBEDTLS_SSL_CONF_BADMAC_LIMIT. */ void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ); -#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT && !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -2129,7 +2174,7 @@ void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ -#if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /** * \brief Set the session cache callbacks (server-side only) * If not set, no session resuming is done (except if session @@ -2171,9 +2216,9 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, void *p_cache, int (*f_get_cache)(void *, mbedtls_ssl_session *), int (*f_set_cache)(void *, const mbedtls_ssl_session *) ); -#endif /* MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ -#if defined(MBEDTLS_SSL_CLI_C) +#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) /** * \brief Request resumption of session (client-side only) * Session data is copied from presented session structure. @@ -2189,7 +2234,7 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, * \sa mbedtls_ssl_get_session() */ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ); -#endif /* MBEDTLS_SSL_CLI_C */ +#endif /* MBEDTLS_SSL_CLI_C && !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ /** * \brief Load serialized session data into a session structure. @@ -2293,9 +2338,11 @@ const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_co void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, const int *ciphersuites ); -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) #define MBEDTLS_SSL_UNEXPECTED_CID_IGNORE 0 #define MBEDTLS_SSL_UNEXPECTED_CID_FAIL 1 +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ + !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) /** * \brief Specify the length of Connection IDs for incoming * encrypted DTLS records, as well as the behaviour @@ -2324,13 +2371,19 @@ void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, * same SSL configuration; this allows simpler parsing of * record headers. * + * \note On constrained systems, this configuration can also be + * fixed at compile-time via MBEDTLS_SSL_CONF_CID_LEN and + * MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID. + * * \return \c 0 on success. * \return #MBEDTLS_ERR_SSL_BAD_INPUT_DATA if \p own_cid_len * is too large. */ int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, size_t len, int ignore_other_cids ); -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID && + !MBEDTLS_SSL_CONF_CID_LEN && + !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ /** * \brief Set the list of allowed ciphersuites and the @@ -2395,7 +2448,7 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, * provision more than one cert/key pair (eg one ECDSA, one * RSA with SHA-256, one RSA with SHA-1). An adequate * certificate will be selected according to the client's - * advertised capabilities. In case mutliple certificates are + * advertised capabilities. In case multiple certificates are * adequate, preference is given to the one set by the first * call to this function, then second, etc. * @@ -2916,19 +2969,22 @@ void mbedtls_ssl_conf_extended_master_secret_enforce( mbedtls_ssl_config *conf, void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ); #endif /* MBEDTLS_ARC4_C */ -#if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) /** * \brief Whether to send a list of acceptable CAs in * CertificateRequest messages. * (Default: do send) * + * \note On constrained systems, this options can also be configured + * at compile-time via MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST. + * * \param conf SSL configuration * \param cert_req_ca_list MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED or * MBEDTLS_SSL_CERT_REQ_CA_LIST_DISABLED */ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, char cert_req_ca_list ); -#endif /* MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) /** @@ -3030,6 +3086,7 @@ void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ); #endif /* MBEDTLS_SSL_RENEGOTIATION */ +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) /** * \brief Prevent or allow legacy renegotiation. * (Default: MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION) @@ -3056,8 +3113,14 @@ void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation * \param allow_legacy Prevent or allow (SSL_NO_LEGACY_RENEGOTIATION, * SSL_ALLOW_LEGACY_RENEGOTIATION or * MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE) + * + * + * \note On constrained systems, this option can also be + * fixed at compile-time by defining the constant + * MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION. */ void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ); +#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) /** @@ -3733,7 +3796,7 @@ int mbedtls_ssl_context_load( mbedtls_ssl_context *ssl, * mbedtls_ssl_config_defaults() or mbedtls_ssl_config_free(). * * \note You need to call mbedtls_ssl_config_defaults() unless you - * manually set all of the relevent fields yourself. + * manually set all of the relevant fields yourself. * * \param conf SSL configuration context */ diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h index 7009c4f8b..74c9f1a94 100644 --- a/include/mbedtls/ssl_internal.h +++ b/include/mbedtls/ssl_internal.h @@ -509,7 +509,9 @@ struct mbedtls_ssl_handshake_params unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; /*!< premaster secret */ +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) int resume; /*!< session resume indicator*/ +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ int max_major_ver; /*!< max. major version client*/ int max_minor_ver; /*!< max. minor version client*/ int cli_exts; /*!< client extension presence*/ @@ -1080,11 +1082,213 @@ int mbedtls_ssl_decrypt_buf( mbedtls_ssl_context *ssl, mbedtls_record *rec ); +/* + * Accessor functions for optional fields of various structures + */ + +static inline int mbedtls_ssl_handshake_get_resume( + const mbedtls_ssl_handshake_params *handshake ) +{ +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) + return( handshake->resume ); +#else + (void) handshake; + return( 0 ); +#endif +} + +static inline int mbedtls_ssl_get_renego_status( + const mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + return( ssl->renego_status ); +#else + (void) ssl; + return( MBEDTLS_SSL_INITIAL_HANDSHAKE ); +#endif +} + + /* * Getter functions for fields in mbedtls_ssl_config which may * be fixed at compile time via one of MBEDTLS_SSL_SSL_CONF_XXX. */ +#if defined(MBEDTLS_SSL_SRV_C) +#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) +static inline unsigned int mbedtls_ssl_conf_get_cert_req_ca_list( + mbedtls_ssl_config const *conf ) +{ + return( conf->cert_req_ca_list ); +} +#else /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ +static inline unsigned int mbedtls_ssl_conf_get_cert_req_ca_list( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST ); +} +#endif /* MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ +#endif /* MBEDTLS_SSL_SRV_C */ + +#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) +static inline unsigned int mbedtls_ssl_conf_get_endpoint( + mbedtls_ssl_config const *conf ) +{ + return( conf->endpoint ); +} +#else /* !MBEDTLS_SSL_CONF_ENDPOINT */ +static inline unsigned int mbedtls_ssl_conf_get_endpoint( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_ENDPOINT ); +} +#endif /* MBEDTLS_SSL_CONF_ENDPOINT */ + +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) +static inline uint32_t mbedtls_ssl_conf_get_read_timeout( + mbedtls_ssl_config const *conf ) +{ + return( conf->read_timeout ); +} +#else /* !MBEDTLS_SSL_CONF_READ_TIMEOUT */ +static inline uint32_t mbedtls_ssl_conf_get_read_timeout( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_READ_TIMEOUT ); +} +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_min( + mbedtls_ssl_config const *conf ) +{ + return( conf->hs_timeout_min ); +} +#else /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_min( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN ); +} +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ + +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_max( + mbedtls_ssl_config const *conf ) +{ + return( conf->hs_timeout_max ); +} +#else /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +static inline uint32_t mbedtls_ssl_conf_get_hs_timeout_max( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ); +} +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#if !defined(MBEDTLS_SSL_CONF_CID_LEN) +static inline size_t mbedtls_ssl_conf_get_cid_len( + mbedtls_ssl_config const *conf ) +{ + return( conf->cid_len ); +} +#else /* !MBEDTLS_SSL_CONF_CID_LEN */ +static inline size_t mbedtls_ssl_conf_get_cid_len( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_CID_LEN ); +} +#endif /* MBEDTLS_SSL_CONF_CID_LEN */ + +#if !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) +static inline unsigned int mbedtls_ssl_conf_get_ignore_unexpected_cid( + mbedtls_ssl_config const *conf ) +{ + return( conf->ignore_unexpected_cid ); +} +#else /* !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ +static inline unsigned int mbedtls_ssl_conf_get_ignore_unexpected_cid( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID ); +} +#endif /* MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ + +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) +static inline unsigned int mbedtls_ssl_conf_get_allow_legacy_renegotiation( + mbedtls_ssl_config const *conf ) +{ + return( conf->allow_legacy_renegotiation ); +} +#else /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ +static inline unsigned int mbedtls_ssl_conf_get_allow_legacy_renegotiation( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION ); +} +#endif /* MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ + +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) +static inline int mbedtls_ssl_conf_get_authmode( + mbedtls_ssl_config const *conf ) +{ + return( conf->authmode ); +} +#else /* !MBEDTLS_SSL_CONF_AUTHMODE */ +static inline int mbedtls_ssl_conf_get_authmode( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_AUTHMODE ); +} +#endif /* MBEDTLS_SSL_CONF_AUTHMODE */ + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) +static inline unsigned int mbedtls_ssl_conf_get_badmac_limit( + mbedtls_ssl_config const *conf ) +{ + return( conf->badmac_limit ); +} +#else /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ +static inline unsigned int mbedtls_ssl_conf_get_badmac_limit( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_BADMAC_LIMIT ); +} +#endif /* MBEDTLS_SSL_CONF_BADMAC_LIMIT */ +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) +static inline unsigned int mbedtls_ssl_conf_get_anti_replay( + mbedtls_ssl_config const *conf ) +{ + return( conf->anti_replay ); +} +#else /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +static inline unsigned int mbedtls_ssl_conf_get_anti_replay( + mbedtls_ssl_config const *conf ) +{ + ((void) conf); + return( MBEDTLS_SSL_CONF_ANTI_REPLAY ); +} +#endif /* MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ + #if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) static inline unsigned int mbedtls_ssl_conf_get_ems( mbedtls_ssl_config const *conf ) diff --git a/include/mbedtls/ssl_ticket.h b/include/mbedtls/ssl_ticket.h index a84e7816e..774a007a9 100644 --- a/include/mbedtls/ssl_ticket.h +++ b/include/mbedtls/ssl_ticket.h @@ -117,14 +117,14 @@ int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, /** * \brief Implementation of the ticket write callback * - * \note See \c mbedlts_ssl_ticket_write_t for description + * \note See \c mbedtls_ssl_ticket_write_t for description */ mbedtls_ssl_ticket_write_t mbedtls_ssl_ticket_write; /** * \brief Implementation of the ticket parse callback * - * \note See \c mbedlts_ssl_ticket_parse_t for description + * \note See \c mbedtls_ssl_ticket_parse_t for description */ mbedtls_ssl_ticket_parse_t mbedtls_ssl_ticket_parse; diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h index cc736e159..ef8e4c1f4 100644 --- a/include/mbedtls/version.h +++ b/include/mbedtls/version.h @@ -40,16 +40,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 1 +#define MBEDTLS_VERSION_PATCH 2 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02100100 -#define MBEDTLS_VERSION_STRING "2.16.1" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.1" +#define MBEDTLS_VERSION_NUMBER 0x02100200 +#define MBEDTLS_VERSION_STRING "2.16.2" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.2" #if defined(MBEDTLS_VERSION_C) diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h index ff06d13b3..b69dd71ad 100644 --- a/include/mbedtls/x509.h +++ b/include/mbedtls/x509.h @@ -77,7 +77,7 @@ #define MBEDTLS_ERR_X509_ALLOC_FAILED -0x2880 /**< Allocation of memory failed. */ #define MBEDTLS_ERR_X509_FILE_IO_ERROR -0x2900 /**< Read/write of file failed. */ #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL -0x2980 /**< Destination buffer is too small. */ -#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */ +#define MBEDTLS_ERR_X509_FATAL_ERROR -0x3000 /**< A fatal error occurred, eg the chain is too long or the vrfy callback failed. */ /* \} name */ /** @@ -183,6 +183,15 @@ extern "C" { * \{ */ +/** + * Basic length-value buffer structure + */ +typedef struct mbedtls_x509_buf_raw +{ + unsigned char *p; /*!< The address of the first byte in the buffer. */ + size_t len; /*!< The number of Bytes in the buffer. */ +} mbedtls_x509_buf_raw; + /** * Type-length-value structure that allows for ASN1 using DER. */ @@ -250,7 +259,7 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se * * \param to mbedtls_x509_time to check * - * \return 1 if the given time is in the past or an error occured, + * \return 1 if the given time is in the past or an error occurred, * 0 otherwise. */ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); @@ -264,11 +273,34 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); * * \param from mbedtls_x509_time to check * - * \return 1 if the given time is in the future or an error occured, + * \return 1 if the given time is in the future or an error occurred, * 0 otherwise. */ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); +/** + * \brief Free a dynamic linked list presentation of an X.509 name + * as returned e.g. by mbedtls_x509_crt_get_subject(). + * + * \param name The address of the first name component. This may + * be \c NULL, in which case this functions returns + * immediately. + */ +void mbedtls_x509_name_free( mbedtls_x509_name *name ); + +/** + * \brief Free a dynamic linked list presentation of an X.509 sequence + * as returned e.g. by mbedtls_x509_crt_get_subject_alt_name(). + * + * \param seq The address of the first sequence component. This may + * be \c NULL, in which case this functions returns + * immediately. + */ +static inline void mbedtls_x509_sequence_free( mbedtls_x509_sequence *seq ) +{ + mbedtls_asn1_sequence_free( (mbedtls_asn1_sequence*) seq ); +} + #if defined(MBEDTLS_SELF_TEST) /** @@ -280,49 +312,6 @@ int mbedtls_x509_self_test( int verbose ); #endif /* MBEDTLS_SELF_TEST */ -/* - * Internal module functions. You probably do not want to use these unless you - * know you do. - */ -int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur ); -int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg ); -int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); -#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) -int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, - mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, - int *salt_len ); -#endif -int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); -int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, - mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, - void **sig_opts ); -int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, - mbedtls_x509_time *t ); -int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *serial ); -int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ); -#if !defined(MBEDTLS_X509_REMOVE_INFO) -int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ); -#endif -int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); -int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); -int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, - int critical, const unsigned char *val, - size_t val_len ); -int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ); -int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, - mbedtls_asn1_named_data *first ); -int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, - const char *oid, size_t oid_len, - unsigned char *sig, size_t size ); - #define MBEDTLS_X509_SAFE_SNPRINTF \ do { \ if( ret < 0 || (size_t) ret >= n ) \ @@ -332,6 +321,18 @@ int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, p += (size_t) ret; \ } while( 0 ) +#define MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP \ + do { \ + if( ret < 0 || (size_t) ret >= n ) \ + { \ + ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; \ + goto cleanup; \ + } \ + \ + n -= (size_t) ret; \ + p += (size_t) ret; \ + } while( 0 ) + #ifdef __cplusplus } #endif diff --git a/include/mbedtls/x509_crl.h b/include/mbedtls/x509_crl.h index 2bb95de16..bf9e3befa 100644 --- a/include/mbedtls/x509_crl.h +++ b/include/mbedtls/x509_crl.h @@ -75,7 +75,7 @@ typedef struct mbedtls_x509_crl int version; /**< CRL version (1=v1, 2=v2) */ mbedtls_x509_buf sig_oid; /**< CRL signature type identifier */ - mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). */ + mbedtls_x509_buf_raw issuer_raw; /**< The raw issuer data (DER). */ mbedtls_x509_name issuer; /**< The parsed issuer data (named information object). */ @@ -111,7 +111,7 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, /** * \brief Parse one or more CRLs and append them to the chained list * - * \note Mutliple CRLs are accepted only if using PEM format + * \note Multiple CRLs are accepted only if using PEM format * * \param chain points to the start of the chain * \param buf buffer holding the CRL data in PEM or DER format @@ -126,7 +126,7 @@ int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, s /** * \brief Load one or more CRLs and append them to the chained list * - * \note Mutliple CRLs are accepted only if using PEM format + * \note Multiple CRLs are accepted only if using PEM format * * \param chain points to the start of the chain * \param path filename to read the CRLs from (in PEM or DER encoding) diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h index 09ba69f39..3eee460fb 100644 --- a/include/mbedtls/x509_crt.h +++ b/include/mbedtls/x509_crt.h @@ -32,6 +32,7 @@ #include "x509.h" #include "x509_crl.h" +#include "x509_internal.h" /** * \addtogroup x509_module @@ -47,14 +48,69 @@ extern "C" { * \{ */ +typedef struct mbedtls_x509_crt_frame +{ + /* Keep these 8-bit fields at the front of the structure to allow them to + * be fetched in a single instruction on Thumb2; putting them at the back + * requires an intermediate address calculation. */ + + uint8_t version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ + uint8_t ca_istrue; /**< Optional Basic Constraint extension value: + * 1 if this certificate belongs to a CA, 0 otherwise. */ + uint8_t max_pathlen; /**< Optional Basic Constraint extension value: + * The maximum path length to the root certificate. + * Path length is 1 higher than RFC 5280 'meaning', so 1+ */ + uint8_t ns_cert_type; /**< Optional Netscape certificate type extension value: + * See the values in x509.h */ + + mbedtls_md_type_t sig_md; /**< The hash algorithm used to hash CRT before signing. */ + mbedtls_pk_type_t sig_pk; /**< The signature algorithm used to sign the CRT hash. */ + + uint16_t key_usage; /**< Optional key usage extension value: See the values in x509.h */ + uint32_t ext_types; /**< Bitfield indicating which extensions are present. + * See the values in x509.h. */ + + mbedtls_x509_time valid_from; /**< The start time of certificate validity. */ + mbedtls_x509_time valid_to; /**< The end time of certificate validity. */ + + mbedtls_x509_buf_raw raw; /**< The raw certificate data in DER. */ + mbedtls_x509_buf_raw tbs; /**< The part of the CRT that is [T]o [B]e [S]igned. */ + + mbedtls_x509_buf_raw serial; /**< The unique ID for certificate issued by a specific CA. */ + + mbedtls_x509_buf_raw pubkey_raw; /**< The raw public key data (DER). */ + + mbedtls_x509_buf_raw issuer_id; /**< Optional X.509 v2/v3 issuer unique identifier. */ + mbedtls_x509_buf_raw issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */ + + mbedtls_x509_buf_raw subject_id; /**< Optional X.509 v2/v3 subject unique identifier. */ + mbedtls_x509_buf_raw subject_raw; /**< The raw subject data (DER). Used for quick comparison. */ + + mbedtls_x509_buf_raw sig; /**< Signature: hash of the tbs part signed with the private key. */ + mbedtls_x509_buf_raw sig_alg; /**< The signature algorithm used for \p sig. */ + + mbedtls_x509_buf_raw v3_ext; /**< The raw data for the extension list in the certificate. + * Might be useful for manual inspection of extensions that + * Mbed TLS doesn't yet support. */ + mbedtls_x509_buf_raw subject_alt_raw; /**< The raw data for the SubjectAlternativeNames extension. */ + mbedtls_x509_buf_raw ext_key_usage_raw; /**< The raw data for the ExtendedKeyUsage extension. */ + +} mbedtls_x509_crt_frame; + /** * Container for an X.509 certificate. The certificate may be chained. */ 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). */ + * by the structure or not. */ + mbedtls_x509_buf raw; /**< The raw certificate data (DER). */ + mbedtls_x509_crt_cache *cache; /**< Internal parsing cache. */ + + struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ + + /* Legacy fields */ +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) mbedtls_x509_buf tbs; /**< The raw certificate body (DER). The part that is To Be Signed. */ int version; /**< The X.509 version. (1=v1, 2=v2, 3=v3) */ @@ -84,7 +140,7 @@ typedef struct mbedtls_x509_crt unsigned int key_usage; /**< Optional key usage extension value: See the values in x509.h */ - mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ + mbedtls_x509_sequence ext_key_usage; /**< Optional list of extended key usage OIDs. */ unsigned char ns_cert_type; /**< Optional Netscape certificate type extension value: See the values in x509.h */ @@ -92,8 +148,7 @@ typedef struct mbedtls_x509_crt mbedtls_md_type_t sig_md; /**< Internal representation of the MD algorithm of the signature algorithm, e.g. MBEDTLS_MD_SHA256 */ mbedtls_pk_type_t sig_pk; /**< Internal representation of the Public Key algorithm of the signature algorithm, e.g. MBEDTLS_PK_RSA */ void *sig_opts; /**< Signature options to be passed to mbedtls_pk_verify_ext(), e.g. for RSASSA-PSS */ - - struct mbedtls_x509_crt *next; /**< Next certificate in the CA-chain. */ +#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ } mbedtls_x509_crt; @@ -586,6 +641,366 @@ void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx ); */ void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx ); #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ + +/** + * \brief Request CRT frame giving access to basic CRT fields + * and raw ASN.1 data of complex fields. + * + * \param crt The CRT to use. This must be initialized and set up. + * \param dst The address of the destination frame structure. + * This need not be initialized. + * + * \note ::mbedtls_x509_crt_frame does not contain pointers to + * dynamically allocated memory, and hence need not be freed. + * Users may e.g. allocate an instance of + * ::mbedtls_x509_crt_frame on the stack and call this function + * on it, in which case no allocation/freeing has to be done. + * + * \note You may also use mbedtls_x509_crt_frame_acquire() and + * mbedtls_x509_crt_frame_release() for copy-less variants + * of this function. + * + * \return \c 0 on success. In this case, \p dst is updated + * to hold the frame for the given CRT. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt, + mbedtls_x509_crt_frame *dst ); + +/** + * \brief Set up a PK context with the public key in a certificate. + * + * \param crt The certificate to use. This must be initialized and set up. + * \param pk The address of the destination PK context to fill. + * This must be initialized via mbedtls_pk_init(). + * + * \note You may also use mbedtls_x509_crt_pk_acquire() and + * mbedtls_x509_crt_pk_release() for copy-less variants + * of this function. + * + * \return \c 0 on success. In this case, the user takes ownership + * of the destination PK context, and is responsible for + * calling mbedtls_pk_free() on it once it's no longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt, + mbedtls_pk_context *pk ); + +/** + * \brief Request the subject name of a CRT, presented + * as a dynamically allocated linked list. + * + * \param crt The CRT to use. This must be initialized and set up. + * \param subject The address at which to store the address of the + * first entry of the generated linked list holding + * the subject name. + * + * \note Depending on your use case, consider using the raw ASN.1 + * describing the subject name instead of the heap-allocated + * linked list generated by this call. The pointers to the + * raw ASN.1 data are part of the CRT frame that can be queried + * via mbedtls_x509_crt_get_frame(), and they can be traversed + * via mbedtls_asn1_traverse_sequence_of(). + * + * \return \c 0 on success. In this case, the user takes ownership + * of the name context, and is responsible for freeing it + * through a call to mbedtls_x509_name_free() once it's no + * longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt, + mbedtls_x509_name **subject ); + +/** + * \brief Request the subject name of a CRT, presented + * as a dynamically allocated linked list. + * + * \param crt The CRT to use. This must be initialized and set up. + * \param issuer The address at which to store the address of the + * first entry of the generated linked list holding + * the subject name. + * + * \note Depending on your use case, consider using the raw ASN.1 + * describing the issuer name instead of the heap-allocated + * linked list generated by this call. The pointers to the + * raw ASN.1 data are part of the CRT frame that can be queried + * via mbedtls_x509_crt_get_frame(), and they can be traversed + * via mbedtls_asn1_traverse_sequence_of(). + * + * \return \c 0 on success. In this case, the user takes ownership + * of the name context, and is responsible for freeing it + * through a call to mbedtls_x509_name_free() once it's no + * longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt, + mbedtls_x509_name **issuer ); + +/** + * \brief Request the subject alternative name of a CRT, presented + * as a dynamically allocated linked list. + * + * \param crt The CRT to use. This must be initialized and set up. + * \param subj_alt The address at which to store the address of the + * first component of the subject alternative names list. + * + * \note Depending in your use case, consider using the raw ASN.1 + * describing the subject alternative names extension + * instead of the heap-allocated linked list generated by this + * call. The pointers to the raw ASN.1 data are part of the CRT + * frame that can be queried via mbedtls_x509_crt_get_frame(), + * and mbedtls_asn1_traverse_sequence_of() can be used to + * traverse the list of subject alternative names. + * + * \return \c 0 on success. In this case, the user takes ownership + * of the name context, and is responsible for freeing it + * through a call to mbedtls_x509_sequence_free() once it's + * no longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt, + mbedtls_x509_sequence **subj_alt ); + +/** + * \brief Request the ExtendedKeyUsage extension of a CRT, + * presented as a dynamically allocated linked list. + * + * \param crt The CRT to use. This must be initialized and set up. + * \param ext_key_usage The address at which to store the address of the + * first entry of the ExtendedKeyUsage extension. + * + * \note Depending in your use case, consider using the raw ASN.1 + * describing the extended key usage extension instead of + * the heap-allocated linked list generated by this call. + * The pointers to the raw ASN.1 data are part of the CRT + * frame that can be queried via mbedtls_x509_crt_get_frame(), + * and mbedtls_asn1_traverse_sequence_of() can be used to + * traverse the entries in the extended key usage extension. + * + * \return \c 0 on success. In this case, the user takes ownership + * of the name context, and is responsible for freeing it + * through a call to mbedtls_x509_sequence_free() once it's + * no longer needed. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_get_ext_key_usage( mbedtls_x509_crt const *crt, + mbedtls_x509_sequence **ext_key_usage ); + +/** + * \brief Flush internal X.509 CRT parsing cache, if present. + * + * \param crt The CRT structure whose cache to flush. + * + * \note Calling this function frequently reduces RAM usage + * at the cost of performance. + * + * \return \c 0 on success. + * \return A negative error code on failure. + */ +int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt ); + +/** + * \brief Request temporary read-access to a certificate frame + * for a given certificate. + * + * Once no longer needed, the frame must be released + * through a call to mbedtls_x509_crt_frame_release(). + * + * This is a copy-less version of mbedtls_x509_crt_get_frame(). + * See there for more information. + * + * \param crt The certificate to use. This must be initialized and set up. + * \param dst The address at which to store the address of a readable + * certificate frame for the input certificate \p crt which the + * caller can use until calling mbedtls_x509_crt_frame_release(). + * + * \note The certificate frame `**frame_ptr` returned by this function + * is owned by the X.509 module and must not be freed or modified + * by the caller. The X.509 module guarantees its validity as long + * as \p crt is valid and mbedtls_x509_crt_frame_release() hasn't + * been issued. + * + * \note In a single-threaded application using + * MBEDTLS_X509_ALWAYS_FLUSH, nested calls to this function + * are not allowed and will fail gracefully with + * MBEDTLS_ERR_X509_FATAL_ERROR. + * + * \return \c 0 on success. In this case, `*frame_ptr` is updated + * to hold the address of a frame for the given CRT. + * \return A negative error code on failure. + */ +static inline int mbedtls_x509_crt_frame_acquire( mbedtls_x509_crt const *crt, + mbedtls_x509_crt_frame const **dst ) +{ + int ret = 0; +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif /* MBEDTLS_THREADING_C */ + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + if( crt->cache->frame_readers == 0 ) +#endif + ret = mbedtls_x509_crt_cache_provide_frame( crt ); + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + if( crt->cache->frame_readers == MBEDTLS_X509_CACHE_FRAME_READERS_MAX ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + crt->cache->frame_readers++; +#endif + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif /* MBEDTLS_THREADING_C */ + + *dst = crt->cache->frame; + return( ret ); +} + +/** + * \brief Release access to a certificate frame acquired + * through a prior call to mbedtls_x509_crt_frame_acquire(). + * + * \param crt The certificate for which a certificate frame has + * previously been acquired. + */ +static inline int mbedtls_x509_crt_frame_release( mbedtls_x509_crt const *crt ) +{ +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif /* MBEDTLS_THREADING_C */ + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + if( crt->cache->frame_readers == 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + crt->cache->frame_readers--; +#endif + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock( &crt->cache->frame_mutex ); +#endif /* MBEDTLS_THREADING_C */ + +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) + (void) mbedtls_x509_crt_flush_cache_frame( crt ); +#endif /* MBEDTLS_X509_ALWAYS_FLUSH */ + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ + !defined(MBEDTLS_THREADING_C) + ((void) crt); +#endif + + return( 0 ); +} + +/** + * \brief Request temporary access to a public key context + * for a given certificate. + * + * Once no longer needed, the frame must be released + * through a call to mbedtls_x509_crt_pk_release(). + * + * This is a copy-less version of mbedtls_x509_crt_get_pk(). + * See there for more information. + * + * \param crt The certificate to use. This must be initialized and set up. + * \param dst The address at which to store the address of a public key + * context for the public key in the input certificate \p crt. + * + * \warning The public key context `**pk_ptr` returned by this function + * is owned by the X.509 module and must be used by the caller + * in a thread-safe way. In particular, the caller must only + * use the context with functions which are `const` on the input + * context, or those which are known to be thread-safe. The latter + * for example includes mbedtls_pk_verify() for ECC or RSA public + * key contexts. + * + * \note In a single-threaded application using + * MBEDTLS_X509_ALWAYS_FLUSH, nested calls to this function + * are not allowed and will fail gracefully with + * MBEDTLS_ERR_X509_FATAL_ERROR. + * + * \return \c 0 on success. In this case, `*pk_ptr` is updated + * to hold the address of a public key context for the given + * certificate. + * \return A negative error code on failure. + */ +static inline int mbedtls_x509_crt_pk_acquire( mbedtls_x509_crt const *crt, + mbedtls_pk_context **dst ) +{ + int ret = 0; +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif /* MBEDTLS_THREADING_C */ + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + if( crt->cache->pk_readers == 0 ) +#endif + ret = mbedtls_x509_crt_cache_provide_pk( crt ); + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + if( crt->cache->pk_readers == MBEDTLS_X509_CACHE_PK_READERS_MAX ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + crt->cache->pk_readers++; +#endif + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif /* MBEDTLS_THREADING_C */ + + *dst = crt->cache->pk; + return( ret ); +} + +/** + * \brief Release access to a public key context acquired + * through a prior call to mbedtls_x509_crt_frame_acquire(). + * + * \param crt The certificate for which a certificate frame has + * previously been acquired. + */ +static inline int mbedtls_x509_crt_pk_release( mbedtls_x509_crt const *crt ) +{ +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif /* MBEDTLS_THREADING_C */ + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + if( crt->cache->pk_readers == 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + crt->cache->pk_readers--; +#endif + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_unlock( &crt->cache->pk_mutex ); +#endif /* MBEDTLS_THREADING_C */ + +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) + (void) mbedtls_x509_crt_flush_cache_pk( crt ); +#endif /* MBEDTLS_X509_ALWAYS_FLUSH */ + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ + !defined(MBEDTLS_THREADING_C) + ((void) crt); +#endif + + return( 0 ); +} + #endif /* MBEDTLS_X509_CRT_PARSE_C */ /* \} name */ diff --git a/include/mbedtls/x509_internal.h b/include/mbedtls/x509_internal.h new file mode 100644 index 000000000..6ca3db590 --- /dev/null +++ b/include/mbedtls/x509_internal.h @@ -0,0 +1,117 @@ +/** + * \file x509_internal.h + * + * \brief Internal X.509 functions + */ +/* + * Copyright (C) 2006-2019, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of Mbed TLS (https://tls.mbed.org) + * + */ +#ifndef MBEDTLS_X509_INTERNAL_H +#define MBEDTLS_X509_INTERNAL_H + +#include "x509.h" +#include "threading.h" + +/* Internal structure used for caching parsed data from an X.509 CRT. */ + +struct mbedtls_x509_crt; +struct mbedtls_pk_context; +struct mbedtls_x509_crt_frame; +#define MBEDTLS_X509_CACHE_PK_READERS_MAX ((uint32_t) -1) +#define MBEDTLS_X509_CACHE_FRAME_READERS_MAX ((uint32_t) -1) +typedef struct mbedtls_x509_crt_cache +{ +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + uint32_t frame_readers; + uint32_t pk_readers; +#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || MBEDTLS_THREADING_C */ +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t frame_mutex; + mbedtls_threading_mutex_t pk_mutex; +#endif + mbedtls_x509_buf_raw pk_raw; + struct mbedtls_x509_crt_frame *frame; + struct mbedtls_pk_context *pk; +} mbedtls_x509_crt_cache; + +/* Internal X.509 CRT cache handling functions. */ + +int mbedtls_x509_crt_flush_cache_frame( struct mbedtls_x509_crt const *crt ); +int mbedtls_x509_crt_flush_cache_pk( struct mbedtls_x509_crt const *crt ); + +int mbedtls_x509_crt_cache_provide_frame( struct mbedtls_x509_crt const *crt ); +int mbedtls_x509_crt_cache_provide_pk( struct mbedtls_x509_crt const *crt ); + +/* Uncategorized internal X.509 functions */ + +int mbedtls_x509_get_name( unsigned char *p, size_t len, + mbedtls_x509_name *cur ); +int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg ); +int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg, mbedtls_x509_buf *params ); +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) +int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, + mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, + int *salt_len ); +#endif +int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ); +int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end, + mbedtls_md_type_t *md_alg, + mbedtls_pk_type_t *pk_alg, + void **sig_opts ); +int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, + mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, + void **sig_opts ); +int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, + mbedtls_x509_time *t ); +int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *serial ); +int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a, + mbedtls_x509_buf_raw const *b, + int (*check)( void *ctx, + mbedtls_x509_buf *oid, + mbedtls_x509_buf *val, + int next_merged ), + void *check_ctx ); +int mbedtls_x509_memcasecmp( const void *s1, const void *s2, + size_t len1, size_t len2 ); +int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *ext, int tag ); + +#if !defined(MBEDTLS_X509_REMOVE_INFO) +int mbedtls_x509_sig_alg_gets( char *buf, size_t size, + mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, + const void *sig_opts ); +#endif +int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ); +int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ); +int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, + size_t val_len ); +int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ); +int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ); +int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size ); + +#endif /* MBEDTLS_X509_INTERNAL_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index a9a5b7b16..461843b05 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -167,15 +167,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY) add_library(mbedcrypto SHARED ${src_crypto}) - set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.1 SOVERSION 3) + set_target_properties(mbedcrypto PROPERTIES VERSION 2.16.2 SOVERSION 3) target_link_libraries(mbedcrypto ${libs}) add_library(mbedx509 SHARED ${src_x509}) - set_target_properties(mbedx509 PROPERTIES VERSION 2.16.1 SOVERSION 0) + set_target_properties(mbedx509 PROPERTIES VERSION 2.16.2 SOVERSION 0) target_link_libraries(mbedx509 ${libs} mbedcrypto) add_library(mbedtls SHARED ${src_tls}) - set_target_properties(mbedtls PROPERTIES VERSION 2.16.1 SOVERSION 12) + set_target_properties(mbedtls PROPERTIES VERSION 2.16.2 SOVERSION 12) target_link_libraries(mbedtls ${libs} mbedx509) install(TARGETS mbedtls mbedx509 mbedcrypto diff --git a/library/Makefile b/library/Makefile index d653aa0ef..45ed1485a 100644 --- a/library/Makefile +++ b/library/Makefile @@ -39,7 +39,7 @@ SOEXT_TLS=so.12 SOEXT_X509=so.0 SOEXT_CRYPTO=so.3 -# Set AR_DASH= (empty string) to use an ar implentation that does not accept +# Set AR_DASH= (empty string) to use an ar implementation that does not accept # the - prefix for command line options (e.g. llvm-ar) AR_DASH ?= - diff --git a/library/asn1parse.c b/library/asn1parse.c index 171c340b8..aac253b01 100644 --- a/library/asn1parse.c +++ b/library/asn1parse.c @@ -229,6 +229,103 @@ int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end return( 0 ); } +void mbedtls_asn1_sequence_free( mbedtls_asn1_sequence *seq ) +{ + while( seq != NULL ) + { + mbedtls_asn1_sequence *next = seq->next; + mbedtls_platform_zeroize( seq, sizeof( *seq ) ); + mbedtls_free( seq ); + seq = next; + } +} + +/* + * Traverse an ASN.1 "SEQUENCE OF " + * and call a callback for each entry found. + */ +int mbedtls_asn1_traverse_sequence_of( + unsigned char **p, + const unsigned char *end, + uint8_t tag_must_mask, uint8_t tag_must_val, + uint8_t tag_may_mask, uint8_t tag_may_val, + int (*cb)( void *ctx, int tag, + unsigned char *start, size_t len ), + void *ctx ) +{ + int ret; + size_t len; + + /* Get main sequence tag */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( ret ); + } + + if( *p + len != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + unsigned char const tag = *(*p)++; + + if( ( tag & tag_must_mask ) != tag_must_val ) + return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + if( ( ret = mbedtls_asn1_get_len( p, end, &len ) ) != 0 ) + return( ret ); + + if( ( tag & tag_may_mask ) == tag_may_val ) + { + if( cb != NULL ) + { + ret = cb( ctx, tag, *p, len ); + if( ret != 0 ) + return( ret ); + } + } + + *p += len; + } + + return( 0 ); +} + +typedef struct +{ + int tag; + mbedtls_asn1_sequence *cur; +} asn1_get_sequence_of_cb_ctx_t; + +static int asn1_get_sequence_of_cb( void *ctx, + int tag, + unsigned char *start, + size_t len ) +{ + asn1_get_sequence_of_cb_ctx_t *cb_ctx = + (asn1_get_sequence_of_cb_ctx_t *) ctx; + mbedtls_asn1_sequence *cur = + cb_ctx->cur; + + if( cur->buf.p != NULL ) + { + cur->next = + mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + + cur = cur->next; + } + + cur->buf.p = start; + cur->buf.len = len; + cur->buf.tag = tag; + + cb_ctx->cur = cur; + return( 0 ); +} /* @@ -239,49 +336,11 @@ int mbedtls_asn1_get_sequence_of( unsigned char **p, mbedtls_asn1_sequence *cur, int tag) { - int ret; - size_t len; - mbedtls_asn1_buf *buf; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - buf = &(cur->buf); - buf->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) - return( ret ); - - buf->p = *p; - *p += buf->len; - - /* Allocate and assign next pointer */ - if( *p < end ) - { - cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, - sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if( *p != end ) - return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); + asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur }; + memset( cur, 0, sizeof( mbedtls_asn1_sequence ) ); + return( mbedtls_asn1_traverse_sequence_of( + p, end, 0xFF, tag, 0, 0, + asn1_get_sequence_of_cb, &cb_ctx ) ); } int mbedtls_asn1_get_alg( unsigned char **p, @@ -295,15 +354,12 @@ int mbedtls_asn1_get_alg( unsigned char **p, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( ret ); - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - alg->tag = **p; end = *p + len; if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) return( ret ); + alg->tag = MBEDTLS_ASN1_OID; alg->p = *p; *p += alg->len; diff --git a/library/bignum.c b/library/bignum.c index 41946183c..d94754a56 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -127,7 +127,7 @@ int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) if( X->n < nblimbs ) { - if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) + if( ( p = (mbedtls_mpi_uint *)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->p != NULL ) @@ -169,7 +169,7 @@ int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) if( i < nblimbs ) i = nblimbs; - if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) + if( ( p = (mbedtls_mpi_uint *)mbedtls_calloc( i, ciL ) ) == NULL ) return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); if( X->p != NULL ) diff --git a/library/cipher.c b/library/cipher.c index 273997577..58217163c 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -331,13 +331,13 @@ int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, ? MBEDTLS_CHACHAPOLY_ENCRYPT : MBEDTLS_CHACHAPOLY_DECRYPT; - result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + result = mbedtls_chachapoly_starts( (mbedtls_chachapoly_context *) ctx->cipher_ctx, ctx->iv, mode ); if ( result != 0 ) return( result ); - return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + return( mbedtls_chachapoly_update_aad( (mbedtls_chachapoly_context *) ctx->cipher_ctx, ad, ad_len ) ); } #endif @@ -391,7 +391,7 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i if ( ctx->cipher_info->type == MBEDTLS_CIPHER_CHACHA20_POLY1305 ) { *olen = ilen; - return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + return( mbedtls_chachapoly_update( (mbedtls_chachapoly_context *) ctx->cipher_ctx, ilen, input, output ) ); } #endif @@ -924,7 +924,7 @@ int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, if ( tag_len != 16U ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + return( mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx, tag ) ); } #endif @@ -975,7 +975,7 @@ int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, if ( tag_len != sizeof( check_tag ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context*) ctx->cipher_ctx, + ret = mbedtls_chachapoly_finish( (mbedtls_chachapoly_context *) ctx->cipher_ctx, check_tag ); if ( ret != 0 ) { diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index 6dd8c5d3a..54572efb9 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -1987,7 +1987,7 @@ static int chachapoly_setkey_wrap( void *ctx, if( key_bitlen != 256U ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); - if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context*)ctx, key ) ) + if ( 0 != mbedtls_chachapoly_setkey( (mbedtls_chachapoly_context *)ctx, key ) ) return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); return( 0 ); diff --git a/library/debug.c b/library/debug.c index c6788b62b..da4ceac2c 100644 --- a/library/debug.c +++ b/library/debug.c @@ -71,7 +71,7 @@ static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level, */ #if defined(MBEDTLS_THREADING_C) char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ - mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str ); + mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void *)ssl, str ); ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr ); #else ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str ); @@ -382,6 +382,8 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, while( crt != NULL ) { + int ret; + mbedtls_pk_context *pk; char buf[1024]; mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i ); @@ -390,7 +392,17 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt ); debug_print_line_by_line( ssl, level, file, line, buf ); - debug_print_pk( ssl, level, file, line, "crt->", &crt->pk ); + ret = mbedtls_x509_crt_pk_acquire( crt, &pk ); + if( ret != 0 ) + { + mbedtls_snprintf( str, sizeof( str ), + "mbedtls_x509_crt_pk_acquire() failed with -%#04x\n", + -ret ); + debug_send_line( ssl, level, file, line, str ); + return; + } + debug_print_pk( ssl, level, file, line, "crt->", pk ); + mbedtls_x509_crt_pk_release( crt ); crt = crt->next; } diff --git a/library/ecjpake.c b/library/ecjpake.c index be941b14b..b276514e8 100644 --- a/library/ecjpake.c +++ b/library/ecjpake.c @@ -951,7 +951,7 @@ static const unsigned char ecjpake_test_pms[] = { 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 }; -/* Load my private keys and generate the correponding public keys */ +/* Load my private keys and generate the corresponding public keys */ static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, const unsigned char *xm1, size_t len1, const unsigned char *xm2, size_t len2 ) diff --git a/library/error.c b/library/error.c index 546fa49df..f250fe4c9 100644 --- a/library/error.c +++ b/library/error.c @@ -571,7 +571,7 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen ) if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) ) - mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" ); + mbedtls_snprintf( buf, buflen, "X509 - A fatal error occurred, eg the chain is too long or the vrfy callback failed" ); #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ // END generated code diff --git a/library/net_sockets.c b/library/net_sockets.c index 816b1303d..8d6c788dc 100644 --- a/library/net_sockets.c +++ b/library/net_sockets.c @@ -72,8 +72,8 @@ #endif #endif /* _MSC_VER */ -#define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 ) -#define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 ) +#define read(fd,buf,len) recv( fd, (char *)( buf ), (int)( len ), 0 ) +#define write(fd,buf,len) send( fd, (char *)( buf ), (int)( len ), 0 ) #define close(fd) closesocket(fd) static int wsa_init_done = 0; @@ -284,7 +284,7 @@ static int net_would_block( const mbedtls_net_context *ctx ) int err = errno; /* - * Never return 'WOULD BLOCK' on a non-blocking socket + * Never return 'WOULD BLOCK' on a blocking socket */ if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) { diff --git a/library/ssl_cli.c b/library/ssl_cli.c index 17611d6fc..274938979 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -828,9 +828,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_NO_RNG ); } -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif + if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) { ssl->major_ver = ssl->conf->min_major_ver; ssl->minor_ver = ssl->conf->min_minor_ver; @@ -882,36 +880,40 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) * .. . .. extensions length (2 bytes) * .. . .. extensions */ - n = ssl->session_negotiate->id_len; - if( n < 16 || n > 32 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif - ssl->handshake->resume == 0 ) + /* + * We'll write a session of non-zero length if resumption was requested + * by the user, we're not renegotiating, and the session ID is of + * appropriate length. Otherwise make the length 0 (for now, see next code + * block for behaviour with tickets). + */ + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 0 || + mbedtls_ssl_get_renego_status( ssl ) != MBEDTLS_SSL_INITIAL_HANDSHAKE || + ssl->session_negotiate->id_len < 16 || + ssl->session_negotiate->id_len > 32 ) { n = 0; } + else + { + n = ssl->session_negotiate->id_len; + } #if defined(MBEDTLS_SSL_SESSION_TICKETS) /* * RFC 5077 section 3.4: "When presenting a ticket, the client MAY * generate and include a Session ID in the TLS ClientHello." */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif + if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && + ssl->session_negotiate->ticket != NULL && + ssl->session_negotiate->ticket_len != 0 ) { - if( ssl->session_negotiate->ticket != NULL && - ssl->session_negotiate->ticket_len != 0 ) - { - ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); + ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); - if( ret != 0 ) - return( ret ); + if( ret != 0 ) + return( ret ); - ssl->session_negotiate->id_len = n = 32; - } + ssl->session_negotiate->id_len = n = 32; } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ @@ -985,9 +987,7 @@ static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) /* * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif + if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding EMPTY_RENEGOTIATION_INFO_SCSV" ) ); *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); @@ -1797,28 +1797,30 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) /* * Check if the session can be resumed + * + * We're only resuming a session if it was requested (handshake->resume + * already set to 1 by mbedtls_ssl_set_session()), and further conditions + * are satisfied (not renegotiating, ID and ciphersuite match, etc). + * + * Update handshake->resume to the value it will keep for the rest of the + * handshake, and that will be used to determine the relative order + * client/server last flights, as well as in handshake_wrapup(). */ - if( ssl->handshake->resume == 0 || n == 0 || -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || -#endif +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) + if( n == 0 || + mbedtls_ssl_get_renego_status( ssl ) != MBEDTLS_SSL_INITIAL_HANDSHAKE || ssl->session_negotiate->ciphersuite != i || ssl->session_negotiate->compression != comp || ssl->session_negotiate->id_len != n || memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) { - ssl->state++; ssl->handshake->resume = 0; -#if defined(MBEDTLS_HAVE_TIME) - ssl->session_negotiate->start = mbedtls_time( NULL ); -#endif - ssl->session_negotiate->ciphersuite = i; - ssl->session_negotiate->compression = comp; - ssl->session_negotiate->id_len = n; - memcpy( ssl->session_negotiate->id, buf + 35, n ); } - else +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ + + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 1 ) { + /* Resume a session */ ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) @@ -1829,9 +1831,21 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) return( ret ); } } + else + { + /* Start a new session */ + ssl->state++; +#if defined(MBEDTLS_HAVE_TIME) + ssl->session_negotiate->start = mbedtls_time( NULL ); +#endif + ssl->session_negotiate->ciphersuite = i; + ssl->session_negotiate->compression = comp; + ssl->session_negotiate->id_len = n; + memcpy( ssl->session_negotiate->id, buf + 35, n ); + } MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - ssl->handshake->resume ? "a" : "no" ) ); + mbedtls_ssl_handshake_get_resume( ssl->handshake ) ? "a" : "no" ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); @@ -2059,7 +2073,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) * Renegotiation security checks */ if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == + MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); handshake_failure = 1; @@ -2074,7 +2089,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) } else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == + MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); handshake_failure = 1; @@ -2334,7 +2350,15 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, peer_pk = &ssl->handshake->peer_pubkey; #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( ssl->session_negotiate->peer_cert != NULL ) - peer_pk = &ssl->session_negotiate->peer_cert->pk; + { + ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, + &peer_pk ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); + return( ret ); + } + } #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( peer_pk == NULL ) @@ -2350,7 +2374,8 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_RSA ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); + ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; + goto cleanup; } if( ( ret = mbedtls_pk_encrypt( peer_pk, @@ -2360,7 +2385,7 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); - return( ret ); + goto cleanup; } #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ @@ -2373,11 +2398,16 @@ static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, } #endif +cleanup: + #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) /* We don't need the peer's public key anymore. Free it. */ mbedtls_pk_free( peer_pk ); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ - return( 0 ); +#else + mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + + return( ret ); } #endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ @@ -2463,13 +2493,21 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - peer_pk = &ssl->session_negotiate->peer_cert->pk; + + ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, + &peer_pk ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); + return( ret ); + } #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( ! mbedtls_pk_can_do( peer_pk, MBEDTLS_PK_ECKEY ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); - return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); + ret = MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH; + goto cleanup; } peer_key = mbedtls_pk_ec( *peer_pk ); @@ -2478,21 +2516,26 @@ static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) MBEDTLS_ECDH_THEIRS ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); - return( ret ); + goto cleanup; } if( ssl_check_server_ecdh_params( ssl ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + goto cleanup; } +cleanup: + #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) /* We don't need the peer's public key anymore. Free it, * so that more RAM is available for upcoming expensive * operations like ECDHE. */ mbedtls_pk_free( peer_pk ); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#else + mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ return( ret ); } @@ -2799,7 +2842,14 @@ start_processing: MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } - peer_pk = &ssl->session_negotiate->peer_cert->pk; + + ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, + &peer_pk ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); + return( ret ); + } #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ /* @@ -2810,6 +2860,9 @@ start_processing: MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); } @@ -2831,6 +2884,9 @@ start_processing: if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) ret = MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS; #endif +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ return( ret ); } @@ -2839,7 +2895,9 @@ start_processing: * so that more RAM is available for upcoming expensive * operations like ECDHE. */ mbedtls_pk_free( peer_pk ); -#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ +#else + mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ } #endif /* MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED */ diff --git a/library/ssl_srv.c b/library/ssl_srv.c index ecde1b0b5..66f25ead9 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -55,7 +55,7 @@ int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, const unsigned char *info, size_t ilen ) { - if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) != MBEDTLS_SSL_IS_SERVER ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); mbedtls_free( ssl->cli_id ); @@ -791,15 +791,58 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, for( cur = list; cur != NULL; cur = cur->next ) { - MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", - cur->cert ); + int match = 1; + mbedtls_pk_context *pk; - if( ! mbedtls_pk_can_do( &cur->cert->pk, pk_alg ) ) + /* WARNING: With the current X.509 caching architecture, this MUST + * happen outside of the PK acquire/release block, because it moves + * the cached PK context. In a threading-enabled build, this would + * rightfully fail, but lead to a use-after-free otherwise. */ + MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", + cur->cert ); + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + /* ASYNC_PRIVATE may use a NULL entry for the opaque private key, so + * we have to use the public key context to infer the capabilities + * of the key. */ + { + int ret; + ret = mbedtls_x509_crt_pk_acquire( cur->cert, &pk ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); + return( ret ); + } + } +#else + /* Outside of ASYNC_PRIVATE, use private key context directly + * instead of querying for the public key context from the + * certificate, so save a few bytes of code. */ + pk = cur->key; +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + + if( ! mbedtls_pk_can_do( pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); - continue; + match = 0; } +#if defined(MBEDTLS_ECDSA_C) + if( pk_alg == MBEDTLS_PK_ECDSA && + ssl_check_key_curve( pk, ssl->handshake->curves ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); + match = 0; + } +#endif + +#if defined(MBEDTLS_SSL_ASYNC_PRIVATE) + mbedtls_x509_crt_pk_release( cur->cert ); +#endif /* MBEDTLS_SSL_ASYNC_PRIVATE */ + + if( match == 0 ) + continue; + /* * This avoids sending the client a cert it'll reject based on * keyUsage or other extensions. @@ -816,31 +859,42 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl, continue; } -#if defined(MBEDTLS_ECDSA_C) - if( pk_alg == MBEDTLS_PK_ECDSA && - ssl_check_key_curve( &cur->cert->pk, ssl->handshake->curves ) != 0 ) - { - MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); - continue; - } -#endif - +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) /* * Try to select a SHA-1 certificate for pre-1.2 clients, but still * present them a SHA-higher cert rather than failing if it's the only * one we got that satisfies the other conditions. */ - if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 && - cur->cert->sig_md != MBEDTLS_MD_SHA1 ) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) { - if( fallback == NULL ) - fallback = cur; + mbedtls_md_type_t sig_md; { + int ret; + mbedtls_x509_crt_frame const *frame; + ret = mbedtls_x509_crt_frame_acquire( cur->cert, &frame ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_frame_acquire", ret ); + return( ret ); + } + sig_md = frame->sig_md; + mbedtls_x509_crt_frame_release( cur->cert ); + } + + if( sig_md != MBEDTLS_MD_SHA1 ) + { + if( fallback == NULL ) + fallback = cur; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: " - "sha-2 with pre-TLS 1.2 client" ) ); - continue; + "sha-2 with pre-TLS 1.2 client" ) ); + continue; } } +#endif /* MBEDTLS_SSL_PROTO_TLS1 || + MBEDTLS_SSL_PROTO_TLS1_1 || + MBEDTLS_SSL_PROTO_SSL3 */ /* If we get there, we got a winner */ break; @@ -1227,7 +1281,8 @@ have_ciphersuite_v2: * SSLv2 Client Hello relevant renegotiation security checks */ if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == + MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, @@ -1287,16 +1342,12 @@ read_record_header: * otherwise read it ourselves manually in order to support SSLv2 * ClientHello, which doesn't use the same record layer format. */ -#if defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) -#endif + if( mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && + ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) { - if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) - { - /* No alert on a read error. */ - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); - return( ret ); - } + /* No alert on a read error. */ + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); } buf = ssl->in_hdr; @@ -1351,11 +1402,8 @@ read_record_header: /* 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( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) + if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && + mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) { /* Epoch should be 0 for initial handshakes */ if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) @@ -1525,7 +1573,7 @@ read_record_header: */ /* - * Minimal length (with everything empty and extensions ommitted) is + * Minimal length (with everything empty and extensions omitted) is * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can * read at least up to session id length without worrying. */ @@ -1616,11 +1664,8 @@ read_record_header: buf + cookie_offset + 1, cookie_len ); #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) - if( ssl->conf->f_cookie_check != NULL -#if defined(MBEDTLS_SSL_RENEGOTIATION) - && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE -#endif - ) + if( ssl->conf->f_cookie_check != NULL && + mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE ) { if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, buf + cookie_offset + 1, cookie_len, @@ -2004,7 +2049,8 @@ read_record_header: * Renegotiation security checks */ if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == + MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); handshake_failure = 1; @@ -2019,7 +2065,8 @@ read_record_header: } else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) + == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); handshake_failure = 1; @@ -2637,15 +2684,14 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); +#if !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /* * Resume is 0 by default, see ssl_handshake_init(). * It may be already set to 1 by ssl_parse_session_ticket_ext(). * If not, try looking up session ID in our cache. */ - if( ssl->handshake->resume == 0 && -#if defined(MBEDTLS_SSL_RENEGOTIATION) - ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && -#endif + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 0 && + mbedtls_ssl_get_renego_status( ssl ) == MBEDTLS_SSL_INITIAL_HANDSHAKE && ssl->session_negotiate->id_len != 0 && ssl->conf->f_get_cache != NULL && ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) @@ -2653,8 +2699,25 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); ssl->handshake->resume = 1; } +#endif /* !MBEDTLS_SSL_NO_SESSION_CACHE */ - if( ssl->handshake->resume == 0 ) +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) + if( mbedtls_ssl_handshake_get_resume( ssl->handshake ) == 1 ) + { + /* + * Resuming a session + */ + n = ssl->session_negotiate->id_len; + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); + } + } + else +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ { /* * New session, create a new session id, @@ -2681,20 +2744,6 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) return( ret ); } } - else - { - /* - * Resuming a session - */ - n = ssl->session_negotiate->id_len; - ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; - - if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) - { - MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); - return( ret ); - } - } /* * 38 . 38 session id length @@ -2711,7 +2760,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", - ssl->handshake->resume ? "a" : "no" ) ); + mbedtls_ssl_handshake_get_resume( ssl->handshake ) ? "a" : "no" ) ); *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); @@ -2848,7 +2897,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) authmode = ssl->handshake->sni_authmode; else #endif - authmode = ssl->conf->authmode; + authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); if( !mbedtls_ssl_ciphersuite_cert_req_allowed( ciphersuite_info ) || authmode == MBEDTLS_SSL_VERIFY_NONE ) @@ -2944,7 +2993,8 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) total_dn_size = 0; - if( ssl->conf->cert_req_ca_list == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) + if( mbedtls_ssl_conf_get_cert_req_ca_list( ssl->conf ) + == MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED ) { #if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) if( ssl->handshake->sni_ca_chain != NULL ) @@ -2953,26 +3003,38 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) #endif crt = ssl->conf->ca_chain; - while( crt != NULL && crt->version != 0 ) + while( crt != NULL && crt->raw.p != NULL ) { - dn_size = crt->subject_raw.len; + mbedtls_x509_crt_frame const *frame; + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_frame_acquire", ret ); + return( ret ); + } + + dn_size = frame->subject_raw.len; if( end < p || (size_t)( end - p ) < dn_size || (size_t)( end - p ) < 2 + dn_size ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); + mbedtls_x509_crt_frame_release( crt ); break; } *p++ = (unsigned char)( dn_size >> 8 ); *p++ = (unsigned char)( dn_size ); - memcpy( p, crt->subject_raw.p, dn_size ); + memcpy( p, frame->subject_raw.p, dn_size ); p += dn_size; MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); total_dn_size += 2 + dn_size; + + mbedtls_x509_crt_frame_release( crt ); + crt = crt->next; } } @@ -3614,9 +3676,8 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, size_t peer_pmssize ) { int ret; + size_t len = (size_t)( end - p ); /* Cast is safe because p <= end. */ mbedtls_pk_context *private_key = mbedtls_ssl_own_key( ssl ); - mbedtls_pk_context *public_key = &mbedtls_ssl_own_cert( ssl )->pk; - size_t len = mbedtls_pk_get_len( public_key ); #if defined(MBEDTLS_SSL_ASYNC_PRIVATE) /* If we have already started decoding the message and there is an ongoing @@ -3634,12 +3695,17 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, */ #if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SSL_PROTO_SSL3) if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ { - if ( p + 2 > end ) { + if( len < 2 ) + { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); } + len -= 2; + if( *p++ != ( ( len >> 8 ) & 0xFF ) || *p++ != ( ( len ) & 0xFF ) ) { @@ -3649,12 +3715,6 @@ static int ssl_decrypt_encrypted_pms( mbedtls_ssl_context *ssl, } #endif - if( p + len != end ) - { - MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); - } - /* * Decrypt the premaster secret */ @@ -4194,7 +4254,15 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) peer_pk = &ssl->handshake->peer_pubkey; #else /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( ssl->session_negotiate->peer_cert != NULL ) - peer_pk = &ssl->session_negotiate->peer_cert->pk; + { + ret = mbedtls_x509_crt_pk_acquire( ssl->session_negotiate->peer_cert, + &peer_pk ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); + return( ret ); + } + } #endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ if( peer_pk == NULL ) @@ -4209,7 +4277,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( 0 != ret ) { MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record" ), ret ); - return( ret ); + goto exit; } ssl->state++; @@ -4219,7 +4287,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } i = mbedtls_ssl_hs_hdr_len( ssl ); @@ -4254,7 +4323,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( i + 2 > ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } /* @@ -4266,7 +4336,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" " for verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } #if !defined(MBEDTLS_MD_SHA1) @@ -4287,7 +4358,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" " for verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } /* @@ -4296,7 +4368,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( !mbedtls_pk_can_do( peer_pk, pk_alg ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } i++; @@ -4311,7 +4384,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( i + 2 > ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1]; @@ -4320,7 +4394,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) if( i + sig_len != ssl->in_hslen ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); - return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY; + goto exit; } /* Calculate hash and verify signature */ @@ -4334,13 +4409,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) ssl->in_msg + i, sig_len ) ) != 0 ) { MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); - return( ret ); + goto exit; } mbedtls_ssl_update_handshake_status( ssl ); MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); +exit: + +#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) + mbedtls_x509_crt_pk_release( ssl->session_negotiate->peer_cert ); +#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */ + return( ret ); } #endif /* MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED */ diff --git a/library/ssl_tls.c b/library/ssl_tls.c index fff20ff1b..91b944cc4 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -117,6 +117,9 @@ static void ssl_update_in_pointers( mbedtls_ssl_context *ssl ); #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) /* Top-level Connection ID API */ +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ + !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, size_t len, int ignore_other_cid ) @@ -134,6 +137,21 @@ int mbedtls_ssl_conf_cid( mbedtls_ssl_config *conf, conf->cid_len = len; return( 0 ); } +#else /* MBEDTLS_SSL_DTLS_CONNECTION_ID && + !MBEDTLS_SSL_CONF_CID_LEN && + !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ + +#if MBEDTLS_SSL_CONF_CID_LEN > MBEDTLS_SSL_CID_IN_LEN_MAX +#error "Invalid hardcoded value for MBEDTLS_SSL_CONF_CID_LEN" +#endif +#if MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID != MBEDTLS_SSL_UNEXPECTED_CID_IGNORE && \ + MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID != MBEDTLS_SSL_UNEXPECTED_CID_FAIL +#error "Invalid hardcoded value for MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID" +#endif + +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID && + !MBEDTLS_SSL_CONF_CID_LEN && + !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, int enable, @@ -152,11 +170,11 @@ int mbedtls_ssl_set_cid( mbedtls_ssl_context *ssl, MBEDTLS_SSL_DEBUG_MSG( 3, ( "Enable use of CID extension." ) ); MBEDTLS_SSL_DEBUG_BUF( 3, "Own CID", own_cid, own_cid_len ); - if( own_cid_len != ssl->conf->cid_len ) + if( own_cid_len != mbedtls_ssl_conf_get_cid_len( ssl->conf ) ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "CID length %u does not match CID length %u in config", (unsigned) own_cid_len, - (unsigned) ssl->conf->cid_len ) ); + (unsigned) mbedtls_ssl_conf_get_cid_len( ssl->conf ) ) ); return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -300,8 +318,11 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) { uint32_t new_timeout; - if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) + if( ssl->handshake->retransmit_timeout >= + mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) ) + { return( -1 ); + } /* Implement the final paragraph of RFC 6347 section 4.1.1.1 * in the following way: after the initial transmission and a first @@ -309,7 +330,8 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) * This value is guaranteed to be deliverable (if not guaranteed to be * delivered) of any compliant IPv4 (and IPv6) network, and should work * on most non-IP stacks too. */ - if( ssl->handshake->retransmit_timeout != ssl->conf->hs_timeout_min ) + if( ssl->handshake->retransmit_timeout != + mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) ) { ssl->handshake->mtu = 508; MBEDTLS_SSL_DEBUG_MSG( 2, ( "mtu autoreduction to %d bytes", ssl->handshake->mtu ) ); @@ -319,9 +341,9 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) /* Avoid arithmetic overflow and range overflow */ if( new_timeout < ssl->handshake->retransmit_timeout || - new_timeout > ssl->conf->hs_timeout_max ) + new_timeout > mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) ) { - new_timeout = ssl->conf->hs_timeout_max; + new_timeout = mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ); } ssl->handshake->retransmit_timeout = new_timeout; @@ -333,7 +355,7 @@ static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) { - ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; + ssl->handshake->retransmit_timeout = mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", ssl->handshake->retransmit_timeout ) ); } @@ -1263,11 +1285,13 @@ static int ssl_compute_master( mbedtls_ssl_handshake_params *handshake, (void) ssl; #endif +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) if( handshake->resume != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); return( 0 ); } +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, handshake->pmslen ); @@ -1366,7 +1390,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) ssl->handshake->tls_prf, ssl->handshake->randbytes, ssl->minor_ver, - ssl->conf->endpoint, + mbedtls_ssl_conf_get_endpoint( ssl->conf ), ssl ); if( ret != 0 ) { @@ -2993,7 +3017,9 @@ static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) * timeout if we were using the usual handshake doubling scheme */ if( ssl->conf->renego_max_records < 0 ) { - uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; + uint32_t ratio = + mbedtls_ssl_conf_get_hs_timeout_max( ssl->conf ) / + mbedtls_ssl_conf_get_hs_timeout_min( ssl->conf ) + 1; unsigned char doublings = 1; while( ratio != 0 ) @@ -3107,7 +3133,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) } /* - * A record can't be split accross datagrams. If we need to read but + * A record can't be split across datagrams. If we need to read but * are not at the beginning of a new record, the caller did something * wrong. */ @@ -3134,7 +3160,7 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) timeout = ssl->handshake->retransmit_timeout; else - timeout = ssl->conf->read_timeout; + timeout = mbedtls_ssl_conf_get_read_timeout( ssl->conf ); MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); @@ -3172,7 +3198,8 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) return( MBEDTLS_ERR_SSL_WANT_READ ); } #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + else if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) @@ -3209,8 +3236,8 @@ int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) if( ssl->f_recv_timeout != NULL ) { ret = ssl->f_recv_timeout( ssl->p_bio, - ssl->in_hdr + ssl->in_left, len, - ssl->conf->read_timeout ); + ssl->in_hdr + ssl->in_left, len, + mbedtls_ssl_conf_get_read_timeout( ssl->conf ) ); } else { @@ -3698,7 +3725,8 @@ int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) if( ! ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && ssl->out_msgtype == MBEDTLS_SSL_MSG_ALERT && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) ) + mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT ) ) #endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); @@ -4322,8 +4350,11 @@ int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); uint64_t bit; - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + if( mbedtls_ssl_conf_get_anti_replay( ssl->conf ) == + MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + { return( 0 ); + } if( rec_seqnum > ssl->in_window_top ) return( 0 ); @@ -4346,8 +4377,11 @@ void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) { uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); - if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + if( mbedtls_ssl_conf_get_anti_replay( ssl->conf ) == + MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + { return; + } if( rec_seqnum > ssl->in_window_top ) { @@ -4611,7 +4645,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && ssl->in_msgtype == MBEDTLS_SSL_MSG_CID && - ssl->conf->cid_len != 0 ) + mbedtls_ssl_conf_get_cid_len( ssl->conf ) != 0 ) { /* Shift pointers to account for record header including CID * struct { @@ -4628,7 +4662,7 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) /* So far, we only support static CID lengths * fixed in the configuration. */ - ssl->in_len = ssl->in_cid + ssl->conf->cid_len; + ssl->in_len = ssl->in_cid + mbedtls_ssl_conf_get_cid_len( ssl->conf ); ssl->in_iv = ssl->in_msg = ssl->in_len + 2; } else @@ -4724,7 +4758,8 @@ static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) * have an active transform (possibly iv_len != 0), so use the * fact that the record header len is 13 instead. */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER && ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && rec_epoch == 0 && ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && @@ -4857,8 +4892,8 @@ static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_CID && - ssl->conf->ignore_unexpected_cid - == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) + mbedtls_ssl_conf_get_ignore_unexpected_cid( ssl->conf ) + == MBEDTLS_SSL_UNEXPECTED_CID_IGNORE ) { MBEDTLS_SSL_DEBUG_MSG( 3, ( "ignoring unexpected CID" ) ); ret = MBEDTLS_ERR_SSL_CONTINUE_PROCESSING; @@ -5774,8 +5809,8 @@ static int ssl_get_next_record( mbedtls_ssl_context *ssl ) } #if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) - if( ssl->conf->badmac_limit != 0 && - ++ssl->badmac_seen >= ssl->conf->badmac_limit ) + if( mbedtls_ssl_conf_get_badmac_limit( ssl->conf ) != 0 && + ++ssl->badmac_seen >= mbedtls_ssl_conf_get_badmac_limit( ssl->conf ) ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); return( MBEDTLS_ERR_SSL_INVALID_MAC ); @@ -5907,7 +5942,8 @@ int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER && ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) { @@ -6074,7 +6110,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) } #if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT ) { if( ssl->client_auth == 0 ) { @@ -6103,7 +6140,7 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) } #endif /* MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) { if( mbedtls_ssl_own_cert( ssl ) == NULL ) { @@ -6307,7 +6344,8 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl, /* Check if we're handling the first CRT in the chain. */ #if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) if( crt_cnt++ == 0 && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) { /* During client-side renegotiation, check that the server's @@ -6373,7 +6411,7 @@ static int ssl_parse_certificate_chain( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_SSL_SRV_C) static int ssl_srv_check_client_no_crt_notification( mbedtls_ssl_context *ssl ) { - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) return( -1 ); #if defined(MBEDTLS_SSL_PROTO_SSL3) @@ -6431,7 +6469,7 @@ static int ssl_parse_certificate_coordinate( mbedtls_ssl_context *ssl, return( SSL_CERTIFICATE_SKIP ); #if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) { if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) return( SSL_CERTIFICATE_SKIP ); @@ -6455,7 +6493,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, mbedtls_x509_crt *chain, void *rs_ctx ) { - int ret = 0; + int verify_ret; const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info; mbedtls_x509_crt *ca_chain; @@ -6480,7 +6518,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, /* * Main check: verify certificate */ - ret = mbedtls_x509_crt_verify_restartable( + verify_ret = mbedtls_x509_crt_verify_restartable( chain, ca_chain, ca_crl, ssl->conf->cert_profile, @@ -6488,13 +6526,13 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, &ssl->session_negotiate->verify_result, ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx ); - if( ret != 0 ) + if( verify_ret != 0 ) { - MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); + MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", verify_ret ); } #if defined(MBEDTLS_SSL__ECP_RESTARTABLE) - if( ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) + if( verify_ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) return( MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS ); #endif @@ -6504,29 +6542,41 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, #if defined(MBEDTLS_ECP_C) { - const mbedtls_pk_context *pk = &chain->pk; + int ret; + mbedtls_pk_context *pk; + ret = mbedtls_x509_crt_pk_acquire( chain, &pk ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_x509_crt_pk_acquire", ret ); + return( ret ); + } /* If certificate uses an EC key, make sure the curve is OK */ - if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && - mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) + if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) ) + ret = mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ); + + mbedtls_x509_crt_pk_release( chain ); + + if( ret != 0 ) { ssl->session_negotiate->verify_result |= MBEDTLS_X509_BADCERT_BAD_KEY; MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); - if( ret == 0 ) - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + if( verify_ret == 0 ) + verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; } } #endif /* MBEDTLS_ECP_C */ if( mbedtls_ssl_check_cert_usage( chain, ciphersuite_info, - ! ssl->conf->endpoint, + ( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT ), &ssl->session_negotiate->verify_result ) != 0 ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); - if( ret == 0 ) - ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + if( verify_ret == 0 ) + verify_ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; } /* mbedtls_x509_crt_verify_with_profile is supposed to report a @@ -6536,19 +6586,19 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, * functions, are treated as fatal and lead to a failure of * ssl_parse_certificate even if verification was optional. */ if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL && - ( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || - ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) + ( verify_ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED || + verify_ret == MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ) ) { - ret = 0; + verify_ret = 0; } if( ca_chain == NULL && authmode == MBEDTLS_SSL_VERIFY_REQUIRED ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); - ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; + verify_ret = MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED; } - if( ret != 0 ) + if( verify_ret != 0 ) { uint8_t alert; @@ -6593,7 +6643,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_DEBUG_C */ - return( ret ); + return( verify_ret ); } #if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) @@ -6658,9 +6708,9 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ? ssl->handshake->sni_authmode - : ssl->conf->authmode; + : mbedtls_ssl_conf_get_authmode( ssl->conf ); #else - const int authmode = ssl->conf->authmode; + const int authmode = mbedtls_ssl_conf_get_authmode( ssl->conf ); #endif void *rs_ctx = NULL; mbedtls_x509_crt *chain = NULL; @@ -6760,8 +6810,8 @@ crt_verify: crt_len = chain->raw.len; #endif /* MBEDTLS_SSL_RENEGOTIATION */ - pk_start = chain->pk_raw.p; - pk_len = chain->pk_raw.len; + pk_start = chain->cache->pk_raw.p; + pk_len = chain->cache->pk_raw.len; /* Free the CRT structures before computing * digest and copying the peer's public key. */ @@ -7273,8 +7323,6 @@ static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) { - int resume = ssl->handshake->resume; - MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); #if defined(MBEDTLS_SSL_RENEGOTIATION) @@ -7302,16 +7350,18 @@ void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) ssl->session = ssl->session_negotiate; ssl->session_negotiate = NULL; +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) /* * Add cache entry */ if( ssl->conf->f_set_cache != NULL && ssl->session->id_len != 0 && - resume == 0 ) + ssl->handshake->resume == 0 ) { if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); } +#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && @@ -7341,7 +7391,8 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) ssl_update_out_pointers( ssl, ssl->transform_negotiate ); - ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); + ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, + mbedtls_ssl_conf_get_endpoint( ssl->conf ) ); /* * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites @@ -7360,6 +7411,7 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) /* * In case of session resuming, invert the client and server * ChangeCipherSpec messages order. @@ -7367,15 +7419,22 @@ int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) if( ssl->handshake->resume != 0 ) { #if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT ) + { ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + } #endif #if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER ) + { ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; + } #endif } else +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ ssl->state++; /* @@ -7469,7 +7528,8 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); - ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 ); + ssl->handshake->calc_finished( ssl, buf, + mbedtls_ssl_conf_get_endpoint( ssl->conf ) ^ 1 ); if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) { @@ -7516,18 +7576,20 @@ int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) memcpy( ssl->peer_verify_data, buf, hash_len ); #endif +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) if( ssl->handshake->resume != 0 ) { #if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; #endif #if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; #endif } else +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ ssl->state++; #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -7672,7 +7734,7 @@ static int ssl_handshake_init( mbedtls_ssl_context *ssl ) { ssl->handshake->alt_transform_out = ssl->transform_out; - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; else ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; @@ -8044,29 +8106,34 @@ int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) /* * SSL set accessors */ +#if !defined(MBEDTLS_SSL_CONF_ENDPOINT) void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ) { conf->endpoint = endpoint; } +#endif /* MBEDTLS_SSL_CONF_ENDPOINT */ void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) { conf->transport = transport; } -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) { - conf->anti_replay = mode; + conf->anti_replay = mode; } -#endif +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY && !MBEDTLS_SSL_CONF_ANTI_REPLAY */ -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) -void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) +void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, + unsigned limit ) { conf->badmac_limit = limit; } -#endif +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT && !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ #if defined(MBEDTLS_SSL_PROTO_DTLS) @@ -8076,17 +8143,36 @@ void mbedtls_ssl_set_datagram_packing( mbedtls_ssl_context *ssl, ssl->disable_datagram_packing = !allow_packing; } +#if !( defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) && \ + defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) ) void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ) { conf->hs_timeout_min = min; conf->hs_timeout_max = max; } -#endif +#else /* !( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN && + MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ) */ +void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, + uint32_t min, uint32_t max ) +{ + ((void) conf); + ((void) min); + ((void) max); +} +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN && + MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ + +#endif /* MBEDTLS_SSL_PROTO_DTLS */ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) { - conf->authmode = authmode; +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) + conf->authmode = authmode; +#else + ((void) conf); + ((void) authmode); +#endif /* MBEDTLS_SSL_CONF_AUTHMODE */ } #if defined(MBEDTLS_X509_CRT_PARSE_C) @@ -8134,10 +8220,12 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ) } #endif +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) { conf->read_timeout = timeout; } +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, void *p_timer, @@ -8152,7 +8240,7 @@ void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, ssl_set_timer( ssl, 0 ); } -#if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, void *p_cache, int (*f_get_cache)(void *, mbedtls_ssl_session *), @@ -8162,9 +8250,9 @@ void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, conf->f_get_cache = f_get_cache; conf->f_set_cache = f_set_cache; } -#endif /* MBEDTLS_SSL_SRV_C */ +#endif /* MBEDTLS_SSL_SRV_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ -#if defined(MBEDTLS_SSL_CLI_C) +#if defined(MBEDTLS_SSL_CLI_C) && !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ) { int ret; @@ -8172,7 +8260,7 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session if( ssl == NULL || session == NULL || ssl->session_negotiate == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) + mbedtls_ssl_conf_get_endpoint( ssl->conf ) != MBEDTLS_SSL_IS_CLIENT ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -8185,7 +8273,7 @@ int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session return( 0 ); } -#endif /* MBEDTLS_SSL_CLI_C */ +#endif /* MBEDTLS_SSL_CLI_C && !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, const int *ciphersuites ) @@ -8300,7 +8388,7 @@ int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, if( ssl->handshake == NULL || ssl->conf == NULL ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) role = MBEDTLS_ECJPAKE_SERVER; else role = MBEDTLS_ECJPAKE_CLIENT; @@ -8594,7 +8682,7 @@ void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) } #endif -#if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_SRV_C) && !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, char cert_req_ca_list ) { @@ -8661,10 +8749,12 @@ void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split } #endif +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ) { conf->allow_legacy_renegotiation = allow_legacy; } +#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ) @@ -8968,7 +9058,7 @@ size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) static size_t ssl_get_current_mtu( const mbedtls_ssl_context *ssl ) { /* Return unlimited mtu for client hello messages to avoid fragmentation. */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT && ( ssl->state == MBEDTLS_SSL_CLIENT_HELLO || ssl->state == MBEDTLS_SSL_SERVER_HELLO ) ) return ( 0 ); @@ -9050,7 +9140,7 @@ int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, if( ssl == NULL || dst == NULL || ssl->session == NULL || - ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) + mbedtls_ssl_conf_get_endpoint( ssl->conf ) != MBEDTLS_SSL_IS_CLIENT ) { return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); } @@ -9634,11 +9724,11 @@ int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); #if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_CLIENT ) ret = mbedtls_ssl_handshake_client_step( ssl ); #endif #if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) ret = mbedtls_ssl_handshake_server_step( ssl ); #endif @@ -9721,10 +9811,15 @@ static int ssl_start_renegotiation( mbedtls_ssl_context *ssl ) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER ) + { ssl->handshake->out_msg_seq = 1; + } else + { ssl->handshake->in_msg_seq = 1; + } } #endif @@ -9755,7 +9850,7 @@ int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) #if defined(MBEDTLS_SSL_SRV_C) /* On server, just send the request */ - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == MBEDTLS_SSL_IS_SERVER ) { if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); @@ -9898,7 +9993,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) if( ssl->f_get_timer != NULL && ssl->f_get_timer( ssl->p_timer ) == -1 ) { - ssl_set_timer( ssl, ssl->conf->read_timeout ); + ssl_set_timer( ssl, + mbedtls_ssl_conf_get_read_timeout( ssl->conf ) ); } if( ( ret = mbedtls_ssl_read_record( ssl, 1 ) ) != 0 ) @@ -9937,7 +10033,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) */ #if defined(MBEDTLS_SSL_CLI_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT && ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) { @@ -9960,7 +10057,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) #endif /* MBEDTLS_SSL_CLI_C */ #if defined(MBEDTLS_SSL_SRV_C) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER && ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); @@ -9985,7 +10083,7 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* Determine whether renegotiation attempt should be accepted */ if( ! ( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && - ssl->conf->allow_legacy_renegotiation == + mbedtls_ssl_conf_get_allow_legacy_renegotiation( ssl->conf ) == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) ) { /* @@ -9995,7 +10093,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) /* DTLS clients need to know renego is server-initiated */ #if defined(MBEDTLS_SSL_PROTO_DTLS) if( MBEDTLS_SSL_TRANSPORT_IS_DTLS( ssl->conf->transport ) && - ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_CLIENT ) { ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; } @@ -10108,7 +10207,8 @@ int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) * Do it now, after setting in_offt, to avoid taking this branch * again if ssl_write_hello_request() returns WANT_WRITE */ #if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) - if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + if( mbedtls_ssl_conf_get_endpoint( ssl->conf ) == + MBEDTLS_SSL_IS_SERVER && ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) { if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) @@ -10677,8 +10777,12 @@ static int ssl_preset_suiteb_hashes[] = { #if defined(MBEDTLS_ECP_C) static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) MBEDTLS_ECP_DP_SECP256R1, +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) MBEDTLS_ECP_DP_SECP384R1, +#endif MBEDTLS_ECP_DP_NONE }; #endif @@ -10704,7 +10808,9 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_CLI_C) if( endpoint == MBEDTLS_SSL_IS_CLIENT ) { +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; +#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ #if defined(MBEDTLS_SSL_SESSION_TICKETS) conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED; #endif @@ -10738,18 +10844,25 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, conf->f_cookie_check = ssl_cookie_check_dummy; #endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; #endif #if defined(MBEDTLS_SSL_SRV_C) +#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) conf->cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED; -#endif +#endif /* !MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ +#endif /* MBEDTLS_SSL_SRV_C */ #if defined(MBEDTLS_SSL_PROTO_DTLS) +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ +#if !defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; -#endif +#endif /* !MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ +#endif /* MBEDTLS_SSL_PROTO_DTLS */ #if defined(MBEDTLS_SSL_RENEGOTIATION) conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; diff --git a/library/timing.c b/library/timing.c index 413d133fb..009516a6e 100644 --- a/library/timing.c +++ b/library/timing.c @@ -51,7 +51,6 @@ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include -#include #include struct _hr_time diff --git a/library/version_features.c b/library/version_features.c index 5e9d9239b..3753864d0 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -87,6 +87,9 @@ static const char *features[] = { #if defined(MBEDTLS_CHECK_PARAMS) "MBEDTLS_CHECK_PARAMS", #endif /* MBEDTLS_CHECK_PARAMS */ +#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) + "MBEDTLS_CHECK_PARAMS_ASSERT", +#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ #if defined(MBEDTLS_TIMING_ALT) "MBEDTLS_TIMING_ALT", #endif /* MBEDTLS_TIMING_ALT */ @@ -513,6 +516,12 @@ static const char *features[] = { #if defined(MBEDTLS_SSL_SESSION_TICKETS) "MBEDTLS_SSL_SESSION_TICKETS", #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_NO_SESSION_CACHE) + "MBEDTLS_SSL_NO_SESSION_CACHE", +#endif /* MBEDTLS_SSL_NO_SESSION_CACHE */ +#if defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) + "MBEDTLS_SSL_NO_SESSION_RESUMPTION", +#endif /* MBEDTLS_SSL_NO_SESSION_RESUMPTION */ #if defined(MBEDTLS_SSL_EXPORT_KEYS) "MBEDTLS_SSL_EXPORT_KEYS", #endif /* MBEDTLS_SSL_EXPORT_KEYS */ @@ -534,6 +543,12 @@ static const char *features[] = { #if defined(MBEDTLS_VERSION_FEATURES) "MBEDTLS_VERSION_FEATURES", #endif /* MBEDTLS_VERSION_FEATURES */ +#if defined(MBEDTLS_X509_ON_DEMAND_PARSING) + "MBEDTLS_X509_ON_DEMAND_PARSING", +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) + "MBEDTLS_X509_ALWAYS_FLUSH", +#endif /* MBEDTLS_X509_ALWAYS_FLUSH */ #if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", #endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */ diff --git a/library/x509.c b/library/x509.c index 858dd904e..0d2b9efab 100644 --- a/library/x509.c +++ b/library/x509.c @@ -38,6 +38,7 @@ #if defined(MBEDTLS_X509_USE_C) #include "mbedtls/x509.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/asn1.h" #include "mbedtls/oid.h" @@ -123,7 +124,7 @@ int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, } /* - * Parse an algorithm identifier with (optional) paramaters + * Parse an algorithm identifier with (optional) parameters */ int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) @@ -347,64 +348,59 @@ int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, * AttributeType ::= OBJECT IDENTIFIER * * AttributeValue ::= ANY DEFINED BY AttributeType + * + * NOTE: This function returns an ASN.1 low-level error code. */ static int x509_get_attr_type_value( unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur ) + mbedtls_x509_buf *oid, + mbedtls_x509_buf *val ) { int ret; size_t len; - mbedtls_x509_buf *oid; - mbedtls_x509_buf *val; - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ); + if( ret != 0 ) + goto exit; end = *p + len; - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - oid = &cur->oid; - oid->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ); + if( ret != 0 ) + goto exit; + oid->tag = MBEDTLS_ASN1_OID; oid->p = *p; *p += oid->len; - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + if( *p == end ) + { + ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA; + goto exit; + } - if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && - **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && - **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && - **p != MBEDTLS_ASN1_BIT_STRING ) - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + if( !MBEDTLS_ASN1_IS_STRING_TAG( **p ) ) + { + ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; + goto exit; + } - val = &cur->val; val->tag = *(*p)++; - if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + ret = mbedtls_asn1_get_len( p, end, &val->len ); + if( ret != 0 ) + goto exit; val->p = *p; *p += val->len; if( *p != end ) - { - return( MBEDTLS_ERR_X509_INVALID_NAME + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } + ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; - cur->next = NULL; - - return( 0 ); +exit: + return( ret ); } /* @@ -429,58 +425,235 @@ static int x509_get_attr_type_value( unsigned char **p, * For the general case we still use a flat list, but we mark elements of the * same set so that they are "merged" together in the functions that consume * this list, eg mbedtls_x509_dn_gets(). + * + * NOTE: This function returns an ASN.1 low-level error code. */ -int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, - mbedtls_x509_name *cur ) +static int x509_set_sequence_iterate( unsigned char **p, + unsigned char const **end_set, + unsigned char const *end, + mbedtls_x509_buf *oid, + mbedtls_x509_buf *val ) { int ret; size_t set_len; - const unsigned char *end_set; - /* don't use recursion, we'd risk stack overflow if not optimized */ - while( 1 ) + if( *p == *end_set ) { - /* - * parse SET - */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + /* Parse next TLV of ASN.1 SET structure. */ + ret = mbedtls_asn1_get_tag( p, end, &set_len, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SET ); + if( ret != 0 ) + goto exit; - end_set = *p + set_len; + *end_set = *p + set_len; + } - while( 1 ) + /* x509_get_attr_type_value() returns ASN.1 low-level error codes. */ + ret = x509_get_attr_type_value( p, *end_set, oid, val ); + +exit: + return( ret ); +} + +/* + * Like memcmp, but case-insensitive and always returns -1 if different + */ +int mbedtls_x509_memcasecmp( const void *s1, const void *s2, + size_t len1, size_t len2 ) +{ + size_t i; + unsigned char diff; + const unsigned char *n1 = s1, *n2 = s2; + + if( len1 != len2 ) + return( -1 ); + + for( i = 0; i < len1; i++ ) + { + diff = n1[i] ^ n2[i]; + + if( diff == 0 ) + continue; + + if( diff == 32 && + ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || + ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) { - if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) - return( ret ); - - if( *p == end_set ) - break; - - /* Mark this item as being no the only one in a set */ - cur->next_merged = 1; - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); - - cur = cur->next; + continue; } - /* - * continue until end of SEQUENCE is reached - */ - if( *p == end ) - return( 0 ); + return( -1 ); + } + return( 0 ); +} + +/* + * Compare two X.509 strings, case-insensitive, and allowing for some encoding + * variations (but not all). + * + * Return 0 if equal, -1 otherwise. + */ +static int x509_string_cmp( const mbedtls_x509_buf *a, + const mbedtls_x509_buf *b ) +{ + if( a->tag == b->tag && + a->len == b->len && + memcmp( a->p, b->p, b->len ) == 0 ) + { + return( 0 ); + } + + if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && + ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && + mbedtls_x509_memcasecmp( a->p, b->p, + a->len, b->len ) == 0 ) + { + return( 0 ); + } + + return( -1 ); +} + +/* + * Compare two X.509 Names (aka rdnSequence) given as raw ASN.1 data. + * + * See RFC 5280 section 7.1, though we don't implement the whole algorithm: + * We sometimes return unequal when the full algorithm would return equal, + * but never the other way. (In particular, we don't do Unicode normalisation + * or space folding.) + * + * Further, this function allows to pass a callback to be triggered for every + * pair of well-formed and equal entries in the two input name lists. + * + * Returns: + * - 0 if both sequences are well-formed, present the same X.509 name, + * and the callback (if provided) hasn't returned a non-zero value + * on any of the name components. + * - 1 if a difference was detected in the name components. + * - A non-zero error code if the abort callback returns a non-zero value. + * In this case, the returned error code is the error code from the callback. + * - A negative error code if a parsing error occurred in either + * of the two buffers. + * + * This function can be used to verify that a buffer contains a well-formed + * ASN.1 encoded X.509 name by calling it with equal parameters. + */ +int mbedtls_x509_name_cmp_raw( mbedtls_x509_buf_raw const *a, + mbedtls_x509_buf_raw const *b, + int (*abort_check)( void *ctx, + mbedtls_x509_buf *oid, + mbedtls_x509_buf *val, + int next_merged ), + void *abort_check_ctx ) +{ + int ret; + size_t idx; + unsigned char *p[2], *end[2], *set[2]; + + p[0] = a->p; + p[1] = b->p; + end[0] = p[0] + a->len; + end[1] = p[1] + b->len; + + for( idx = 0; idx < 2; idx++ ) + { + size_t len; + ret = mbedtls_asn1_get_tag( &p[idx], end[idx], &len, + MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ); + + if( end[idx] != p[idx] + len ) + { + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + set[idx] = p[idx]; + } + + while( 1 ) + { + int next_merged; + mbedtls_x509_buf oid[2], val[2]; + + ret = x509_set_sequence_iterate( &p[0], (const unsigned char **) &set[0], + end[0], &oid[0], &val[0] ); + if( ret != 0 ) + goto exit; + + ret = x509_set_sequence_iterate( &p[1], (const unsigned char **) &set[1], + end[1], &oid[1], &val[1] ); + if( ret != 0 ) + goto exit; + + if( oid[0].len != oid[1].len || + memcmp( oid[0].p, oid[1].p, oid[1].len ) != 0 ) + { + return( 1 ); + } + + if( x509_string_cmp( &val[0], &val[1] ) != 0 ) + return( 1 ); + + next_merged = ( set[0] != p[0] ); + if( next_merged != ( set[1] != p[1] ) ) + return( 1 ); + + if( abort_check != NULL ) + { + ret = abort_check( abort_check_ctx, &oid[0], &val[0], + next_merged ); + if( ret != 0 ) + return( ret ); + } + + if( p[0] == end[0] && p[1] == end[1] ) + break; + } + +exit: + if( ret < 0 ) + ret += MBEDTLS_ERR_X509_INVALID_NAME; + + return( ret ); +} + +static int x509_get_name_cb( void *ctx, + mbedtls_x509_buf *oid, + mbedtls_x509_buf *val, + int next_merged ) +{ + mbedtls_x509_name **cur_ptr = (mbedtls_x509_name**) ctx; + mbedtls_x509_name *cur = *cur_ptr; + + if( cur->oid.p != NULL ) + { cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); cur = cur->next; } + + cur->oid = *oid; + cur->val = *val; + cur->next_merged = next_merged; + + *cur_ptr = cur; + return( 0 ); +} + +int mbedtls_x509_get_name( unsigned char *p, + size_t len, + mbedtls_x509_name *cur ) +{ + mbedtls_x509_buf_raw name_buf = { p, len }; + memset( cur, 0, sizeof( mbedtls_x509_name ) ); + return( mbedtls_x509_name_cmp_raw( &name_buf, &name_buf, + x509_get_name_cb, + &cur ) ); } static int x509_parse_int( unsigned char **p, size_t n, int *res ) @@ -655,6 +828,21 @@ int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x return( 0 ); } +int mbedtls_x509_get_sig_alg_raw( unsigned char **p, unsigned char const *end, + mbedtls_md_type_t *md_alg, + mbedtls_pk_type_t *pk_alg, + void **sig_opts ) +{ + int ret; + mbedtls_asn1_buf alg, params; + ret = mbedtls_asn1_get_alg( p, end, &alg, ¶ms ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + return( mbedtls_x509_get_sig_alg( &alg, ¶ms, md_alg, + pk_alg, sig_opts ) ); +} + /* * Get signature algorithm from alg OID and optional parameters */ @@ -664,9 +852,6 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50 { int ret; - if( *sig_opts != NULL ) - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); @@ -689,7 +874,10 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50 return( ret ); } - *sig_opts = (void *) pss_opts; + if( sig_opts != NULL ) + *sig_opts = (void *) pss_opts; + else + mbedtls_free( pss_opts ); } else #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ @@ -697,7 +885,10 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50 /* Make sure parameters are absent or NULL */ if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || sig_params->len != 0 ) - return( MBEDTLS_ERR_X509_INVALID_ALG ); + return( MBEDTLS_ERR_X509_INVALID_ALG ); + + if( sig_opts != NULL ) + *sig_opts = NULL; } return( 0 ); @@ -840,20 +1031,34 @@ int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *se /* * Helper for writing signature algorithms */ -int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, - mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, - const void *sig_opts ) +int mbedtls_x509_sig_alg_gets( char *buf, size_t size, mbedtls_pk_type_t pk_alg, + mbedtls_md_type_t md_alg, const void *sig_opts ) { int ret; char *p = buf; size_t n = size; const char *desc = NULL; + mbedtls_x509_buf sig_oid; + mbedtls_md_type_t tmp_md_alg = md_alg; - ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); - if( ret != 0 ) - ret = mbedtls_snprintf( p, n, "???" ); - else +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + /* The hash for RSASSA is determined by the algorithm parameters; + * in the OID list, the hash is set to MBEDTLS_MD_NONE. */ + if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) + tmp_md_alg = MBEDTLS_MD_NONE; +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + + sig_oid.tag = MBEDTLS_ASN1_OID; + ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, tmp_md_alg, + (const char**) &sig_oid.p, + &sig_oid.len ); + if( ret == 0 && + mbedtls_oid_get_sig_alg_desc( &sig_oid, &desc ) == 0 ) + { ret = mbedtls_snprintf( p, n, "%s", desc ); + } + else + ret = mbedtls_snprintf( p, n, "???" ); MBEDTLS_X509_SAFE_SNPRINTF; #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) @@ -1003,6 +1208,17 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) } #endif /* MBEDTLS_HAVE_TIME_DATE */ +void mbedtls_x509_name_free( mbedtls_x509_name *name ) +{ + while( name != NULL ) + { + mbedtls_x509_name *next = name->next; + mbedtls_platform_zeroize( name, sizeof( *name ) ); + mbedtls_free( name ); + name = next; + } +} + #if defined(MBEDTLS_SELF_TEST) #include "mbedtls/x509_crt.h" diff --git a/library/x509_create.c b/library/x509_create.c index 546e8fa1a..1639630a2 100644 --- a/library/x509_create.c +++ b/library/x509_create.c @@ -28,6 +28,7 @@ #if defined(MBEDTLS_X509_CREATE_C) #include "mbedtls/x509.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/asn1write.h" #include "mbedtls/oid.h" diff --git a/library/x509_crl.c b/library/x509_crl.c index 4f5507f0e..3113de42c 100644 --- a/library/x509_crl.c +++ b/library/x509_crl.c @@ -38,6 +38,7 @@ #if defined(MBEDTLS_X509_CRL_PARSE_C) #include "mbedtls/x509_crl.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" @@ -428,15 +429,17 @@ int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, mbedtls_x509_crl_free( crl ); return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } + p += len; + crl->issuer_raw.len = p - crl->issuer_raw.p; - if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 ) + if( ( ret = mbedtls_x509_get_name( crl->issuer_raw.p, + crl->issuer_raw.len, + &crl->issuer ) ) != 0 ) { mbedtls_x509_crl_free( crl ); return( ret ); } - crl->issuer_raw.len = p - crl->issuer_raw.p; - /* * thisUpdate Time * nextUpdate Time OPTIONAL @@ -690,8 +693,8 @@ int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md, - crl->sig_opts ); + ret = mbedtls_x509_sig_alg_gets( p, n, crl->sig_pk, + crl->sig_md, crl->sig_opts ); MBEDTLS_X509_SAFE_SNPRINTF; ret = mbedtls_snprintf( p, n, "\n" ); diff --git a/library/x509_crt.c b/library/x509_crt.c index e4a35f64d..eb3ee990b 100644 --- a/library/x509_crt.c +++ b/library/x509_crt.c @@ -40,6 +40,7 @@ #if defined(MBEDTLS_X509_CRT_PARSE_C) #include "mbedtls/x509_crt.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" @@ -78,6 +79,385 @@ #endif /* !_WIN32 || EFIX64 || EFI32 */ #endif +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) +static void x509_buf_to_buf_raw( mbedtls_x509_buf_raw *dst, + mbedtls_x509_buf const *src ) +{ + dst->p = src->p; + dst->len = src->len; +} + +static void x509_buf_raw_to_buf( mbedtls_x509_buf *dst, + mbedtls_x509_buf_raw const *src ) +{ + dst->p = src->p; + dst->len = src->len; +} +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ + +static int x509_crt_parse_frame( unsigned char *start, + unsigned char *end, + mbedtls_x509_crt_frame *frame ); +static int x509_crt_subject_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_name *subject ); +static int x509_crt_issuer_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_name *issuer ); +static int x509_crt_subject_alt_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_sequence *subject_alt ); +static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_sequence *ext_key_usage ); + +int mbedtls_x509_crt_flush_cache_pk( mbedtls_x509_crt const *crt ) +{ +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &crt->cache->pk_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + /* Can only free the PK context if nobody is using it. + * If MBEDTLS_X509_ALWAYS_FLUSH is set, nested uses + * of xxx_acquire() are prohibited, and no reference + * counting is needed. Also, notice that the code-path + * below is safe if the cache isn't filled. */ + if( crt->cache->pk_readers == 0 ) +#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || + MBEDTLS_THREADING_C */ + { +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) + /* The cache holds a shallow copy of the PK context + * in the legacy struct, so don't free PK context. */ + mbedtls_free( crt->cache->pk ); +#else + mbedtls_pk_free( crt->cache->pk ); + mbedtls_free( crt->cache->pk ); +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ + crt->cache->pk = NULL; + } + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &crt->cache->pk_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + return( 0 ); +} + +int mbedtls_x509_crt_flush_cache_frame( mbedtls_x509_crt const *crt ) +{ +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &crt->cache->frame_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + /* Can only free the PK context if nobody is using it. + * If MBEDTLS_X509_ALWAYS_FLUSH is set, nested uses + * of xxx_acquire() are prohibited, and no reference + * counting is needed. Also, notice that the code-path + * below is safe if the cache isn't filled. */ + if( crt->cache->frame_readers == 0 ) +#endif /* !MBEDTLS_X509_ALWAYS_FLUSH || + MBEDTLS_THREADING_C */ + { + mbedtls_free( crt->cache->frame ); + crt->cache->frame = NULL; + } + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &crt->cache->frame_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + return( 0 ); +} + +int mbedtls_x509_crt_flush_cache( mbedtls_x509_crt const *crt ) +{ + int ret; + ret = mbedtls_x509_crt_flush_cache_frame( crt ); + if( ret != 0 ) + return( ret ); + ret = mbedtls_x509_crt_flush_cache_pk( crt ); + if( ret != 0 ) + return( ret ); + return( 0 ); +} + +static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame ); + +int mbedtls_x509_crt_cache_provide_frame( mbedtls_x509_crt const *crt ) +{ + mbedtls_x509_crt_cache *cache = crt->cache; + mbedtls_x509_crt_frame *frame; + + if( cache->frame != NULL ) + { +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + return( 0 ); +#else + /* If MBEDTLS_X509_ALWAYS_FLUSH is set, we don't + * allow nested uses of acquire. */ + return( MBEDTLS_ERR_X509_FATAL_ERROR ); +#endif + } + + frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) ); + if( frame == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + cache->frame = frame; + +#if defined(MBEDTLS_X509_ON_DEMAND_PARSING) + /* This would work with !MBEDTLS_X509_ON_DEMAND_PARSING, too, + * but is inefficient compared to copying the respective fields + * from the legacy mbedtls_x509_crt. */ + return( x509_crt_parse_frame( crt->raw.p, + crt->raw.p + crt->raw.len, + frame ) ); +#else /* MBEDTLS_X509_ON_DEMAND_PARSING */ + /* Make sure all extension related fields are properly initialized. */ + frame->ca_istrue = 0; + frame->max_pathlen = 0; + frame->ext_types = 0; + frame->version = crt->version; + frame->sig_md = crt->sig_md; + frame->sig_pk = crt->sig_pk; + frame->valid_from = crt->valid_from; + frame->valid_to = crt->valid_to; + x509_buf_to_buf_raw( &frame->raw, &crt->raw ); + x509_buf_to_buf_raw( &frame->tbs, &crt->tbs ); + x509_buf_to_buf_raw( &frame->serial, &crt->serial ); + x509_buf_to_buf_raw( &frame->pubkey_raw, &crt->pk_raw ); + x509_buf_to_buf_raw( &frame->issuer_raw, &crt->issuer_raw ); + x509_buf_to_buf_raw( &frame->subject_raw, &crt->subject_raw ); + x509_buf_to_buf_raw( &frame->subject_id, &crt->subject_id ); + x509_buf_to_buf_raw( &frame->issuer_id, &crt->issuer_id ); + x509_buf_to_buf_raw( &frame->sig, &crt->sig ); + x509_buf_to_buf_raw( &frame->v3_ext, &crt->v3_ext ); + + /* The legacy CRT structure doesn't explicitly contain + * the `AlgorithmIdentifier` bounds; however, those can + * be inferred from the surrounding (mandatory) `SerialNumber` + * and `Issuer` fields. */ + frame->sig_alg.p = crt->serial.p + crt->serial.len; + frame->sig_alg.len = crt->issuer_raw.p - frame->sig_alg.p; + + return( x509_crt_frame_parse_ext( frame ) ); +#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ +} + +int mbedtls_x509_crt_cache_provide_pk( mbedtls_x509_crt const *crt ) +{ + mbedtls_x509_crt_cache *cache = crt->cache; + mbedtls_pk_context *pk; + + if( cache->pk != NULL ) + { +#if !defined(MBEDTLS_X509_ALWAYS_FLUSH) || \ + defined(MBEDTLS_THREADING_C) + return( 0 ); +#else + /* If MBEDTLS_X509_ALWAYS_FLUSH is set, we don't + * allow nested uses of acquire. */ + return( MBEDTLS_ERR_X509_FATAL_ERROR ); +#endif + } + + pk = mbedtls_calloc( 1, sizeof( mbedtls_pk_context ) ); + if( pk == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + cache->pk = pk; + +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) + *pk = crt->pk; + return( 0 ); +#else + { + mbedtls_x509_buf_raw pk_raw = cache->pk_raw; + return( mbedtls_pk_parse_subpubkey( &pk_raw.p, + pk_raw.p + pk_raw.len, + pk ) ); + } +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ +} + +static void x509_crt_cache_init( mbedtls_x509_crt_cache *cache ) +{ + memset( cache, 0, sizeof( *cache ) ); +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &cache->frame_mutex ); + mbedtls_mutex_init( &cache->pk_mutex ); +#endif +} + +static void x509_crt_cache_clear_pk( mbedtls_x509_crt_cache *cache ) +{ +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) + /* The cache holds a shallow copy of the PK context + * in the legacy struct, so don't free PK context. */ + mbedtls_free( cache->pk ); +#else + mbedtls_pk_free( cache->pk ); + mbedtls_free( cache->pk ); +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ + + cache->pk = NULL; +} + +static void x509_crt_cache_clear_frame( mbedtls_x509_crt_cache *cache ) +{ + mbedtls_free( cache->frame ); + cache->frame = NULL; +} + +static void x509_crt_cache_free( mbedtls_x509_crt_cache *cache ) +{ + if( cache == NULL ) + return; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &cache->frame_mutex ); + mbedtls_mutex_free( &cache->pk_mutex ); +#endif + + x509_crt_cache_clear_frame( cache ); + x509_crt_cache_clear_pk( cache ); + + memset( cache, 0, sizeof( *cache ) ); +} + +int mbedtls_x509_crt_get_subject_alt_names( mbedtls_x509_crt const *crt, + mbedtls_x509_sequence **subj_alt ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + mbedtls_x509_sequence *seq; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + seq = mbedtls_calloc( 1, sizeof( mbedtls_x509_sequence ) ); + if( seq == NULL ) + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + else + ret = x509_crt_subject_alt_from_frame( frame, seq ); + + mbedtls_x509_crt_frame_release( crt ); + + *subj_alt = seq; + return( ret ); +} + +int mbedtls_x509_crt_get_ext_key_usage( mbedtls_x509_crt const *crt, + mbedtls_x509_sequence **ext_key_usage ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + mbedtls_x509_sequence *seq; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + seq = mbedtls_calloc( 1, sizeof( mbedtls_x509_sequence ) ); + if( seq == NULL ) + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + else + ret = x509_crt_ext_key_usage_from_frame( frame, seq ); + + mbedtls_x509_crt_frame_release( crt ); + + *ext_key_usage = seq; + return( ret ); +} + +int mbedtls_x509_crt_get_subject( mbedtls_x509_crt const *crt, + mbedtls_x509_name **subject ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + mbedtls_x509_name *name; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + if( name == NULL ) + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + else + ret = x509_crt_subject_from_frame( frame, name ); + + mbedtls_x509_crt_frame_release( crt ); + + *subject = name; + return( ret ); +} + +int mbedtls_x509_crt_get_issuer( mbedtls_x509_crt const *crt, + mbedtls_x509_name **issuer ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + mbedtls_x509_name *name; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + if( name == NULL ) + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + else + ret = x509_crt_issuer_from_frame( frame, name ); + + mbedtls_x509_crt_frame_release( crt ); + + *issuer = name; + return( ret ); +} + +int mbedtls_x509_crt_get_frame( mbedtls_x509_crt const *crt, + mbedtls_x509_crt_frame *dst ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + *dst = *frame; + mbedtls_x509_crt_frame_release( crt ); + return( 0 ); +} + +int mbedtls_x509_crt_get_pk( mbedtls_x509_crt const *crt, + mbedtls_pk_context *dst ) +{ +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) + mbedtls_x509_buf_raw pk_raw = crt->cache->pk_raw; + return( mbedtls_pk_parse_subpubkey( &pk_raw.p, + pk_raw.p + pk_raw.len, + dst ) ); +#else /* !MBEDTLS_X509_ON_DEMAND_PARSING */ + int ret; + mbedtls_pk_context *pk; + ret = mbedtls_x509_crt_pk_acquire( crt, &pk ); + if( ret != 0 ) + return( ret ); + + /* Move PK from CRT cache to destination pointer + * to avoid a copy. */ + *dst = *pk; + mbedtls_free( crt->cache->pk ); + crt->cache->pk = NULL; + + mbedtls_x509_crt_pk_release( crt ); + return( 0 ); +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ +} + /* * Item in a verification chain: cert and flags for it */ @@ -227,45 +607,19 @@ static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, return( -1 ); } -/* - * Like memcmp, but case-insensitive and always returns -1 if different - */ -static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) -{ - size_t i; - unsigned char diff; - const unsigned char *n1 = s1, *n2 = s2; - - for( i = 0; i < len; i++ ) - { - diff = n1[i] ^ n2[i]; - - if( diff == 0 ) - continue; - - if( diff == 32 && - ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || - ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) - { - continue; - } - - return( -1 ); - } - - return( 0 ); -} - /* * Return 0 if name matches wildcard, -1 otherwise */ -static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) +static int x509_check_wildcard( char const *cn, + size_t cn_len, + unsigned char const *buf, + size_t buf_len ) { size_t i; - size_t cn_idx = 0, cn_len = strlen( cn ); + size_t cn_idx = 0; /* We can't have a match if there is no wildcard to match */ - if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) + if( buf_len < 3 || buf[0] != '*' || buf[1] != '.' ) return( -1 ); for( i = 0; i < cn_len; ++i ) @@ -280,8 +634,8 @@ static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) if( cn_idx == 0 ) return( -1 ); - if( cn_len - cn_idx == name->len - 1 && - x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) + if( mbedtls_x509_memcasecmp( buf + 1, cn + cn_idx, + buf_len - 1, cn_len - cn_idx ) == 0 ) { return( 0 ); } @@ -289,74 +643,6 @@ static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) return( -1 ); } -/* - * Compare two X.509 strings, case-insensitive, and allowing for some encoding - * variations (but not all). - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) -{ - if( a->tag == b->tag && - a->len == b->len && - memcmp( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && - a->len == b->len && - x509_memcasecmp( a->p, b->p, b->len ) == 0 ) - { - return( 0 ); - } - - return( -1 ); -} - -/* - * Compare two X.509 Names (aka rdnSequence). - * - * See RFC 5280 section 7.1, though we don't implement the whole algorithm: - * we sometimes return unequal when the full algorithm would return equal, - * but never the other way. (In particular, we don't do Unicode normalisation - * or space folding.) - * - * Return 0 if equal, -1 otherwise. - */ -static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) -{ - /* Avoid recursion, it might not be optimised by the compiler */ - while( a != NULL || b != NULL ) - { - if( a == NULL || b == NULL ) - return( -1 ); - - /* type */ - if( a->oid.tag != b->oid.tag || - a->oid.len != b->oid.len || - memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) - { - return( -1 ); - } - - /* value */ - if( x509_string_cmp( &a->val, &b->val ) != 0 ) - return( -1 ); - - /* structure of the list of sets */ - if( a->next_merged != b->next_merged ) - return( -1 ); - - a = a->next; - b = b->next; - } - - /* a == NULL == b */ - return( 0 ); -} - /* * Reset (init or clear) a verify_chain */ @@ -445,15 +731,13 @@ static int x509_get_dates( unsigned char **p, */ static int x509_get_uid( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *uid, int n ) + mbedtls_x509_buf_raw *uid, int n ) { int ret; if( *p == end ) return( 0 ); - uid->tag = **p; - if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) { @@ -487,7 +771,7 @@ static int x509_get_basic_constraints( unsigned char **p, if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + return( ret ); if( *p == end ) return( 0 ); @@ -498,7 +782,7 @@ static int x509_get_basic_constraints( unsigned char **p, ret = mbedtls_asn1_get_int( p, end, ca_istrue ); if( ret != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + return( ret ); if( *ca_istrue != 0 ) *ca_istrue = 1; @@ -508,11 +792,10 @@ static int x509_get_basic_constraints( unsigned char **p, return( 0 ); if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + return( ret ); if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); (*max_pathlen)++; @@ -527,11 +810,10 @@ static int x509_get_ns_cert_type( unsigned char **p, mbedtls_x509_bitstring bs = { 0, 0, NULL }; if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + return( ret ); if( bs.len != 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); /* Get actual bitstring */ *ns_cert_type = *bs.p; @@ -540,29 +822,53 @@ static int x509_get_ns_cert_type( unsigned char **p, static int x509_get_key_usage( unsigned char **p, const unsigned char *end, - unsigned int *key_usage) + uint16_t *key_usage) { int ret; size_t i; mbedtls_x509_bitstring bs = { 0, 0, NULL }; if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + return( ret ); if( bs.len < 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); /* Get actual bitstring */ *key_usage = 0; - for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) + for( i = 0; i < bs.len && i < sizeof( *key_usage ); i++ ) { - *key_usage |= (unsigned int) bs.p[i] << (8*i); + *key_usage |= (uint16_t) bs.p[i] << ( 8*i ); } return( 0 ); } +static int asn1_build_sequence_cb( void *ctx, + int tag, + unsigned char *data, + size_t data_len ) +{ + mbedtls_asn1_sequence **cur_ptr = (mbedtls_asn1_sequence **) ctx; + mbedtls_asn1_sequence *cur = *cur_ptr; + + /* Allocate and assign next pointer */ + if( cur->buf.p != NULL ) + { + cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); + if( cur->next == NULL ) + return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + cur = cur->next; + } + + cur->buf.tag = tag; + cur->buf.p = data; + cur->buf.len = data_len; + + *cur_ptr = cur; + return( 0 ); +} + /* * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId * @@ -572,17 +878,11 @@ static int x509_get_ext_key_usage( unsigned char **p, const unsigned char *end, mbedtls_x509_sequence *ext_key_usage) { - int ret; - - if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Sequence length must be >= 1 */ - if( ext_key_usage->buf.p == NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - - return( 0 ); + return( mbedtls_asn1_traverse_sequence_of( p, end, + 0xFF, MBEDTLS_ASN1_OID, + 0, 0, + asn1_build_sequence_cb, + (void *) &ext_key_usage ) ); } /* @@ -611,220 +911,551 @@ static int x509_get_ext_key_usage( unsigned char **p, * * NOTE: we only parse and use dNSName at this point. */ -static int x509_get_subject_alt_name( unsigned char **p, +static int x509_get_subject_alt_name( unsigned char *p, const unsigned char *end, mbedtls_x509_sequence *subject_alt_name ) { - int ret; - size_t len, tag_len; - mbedtls_asn1_buf *buf; - unsigned char tag; - mbedtls_asn1_sequence *cur = subject_alt_name; - - /* Get main sequence tag */ - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( *p + len != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - while( *p < end ) - { - if( ( end - *p ) < 1 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_OUT_OF_DATA ); - - tag = **p; - (*p)++; - if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != - MBEDTLS_ASN1_CONTEXT_SPECIFIC ) - { - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } - - /* Skip everything but DNS name */ - if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) - { - *p += tag_len; - continue; - } - - /* Allocate and assign next pointer */ - if( cur->buf.p != NULL ) - { - if( cur->next != NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - - cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); - - if( cur->next == NULL ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_ALLOC_FAILED ); - - cur = cur->next; - } - - buf = &(cur->buf); - buf->tag = tag; - buf->p = *p; - buf->len = tag_len; - *p += buf->len; - } - - /* Set final sequence entry's next pointer to NULL */ - cur->next = NULL; - - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - return( 0 ); + return( mbedtls_asn1_traverse_sequence_of( &p, end, + MBEDTLS_ASN1_TAG_CLASS_MASK, + MBEDTLS_ASN1_CONTEXT_SPECIFIC, + MBEDTLS_ASN1_TAG_VALUE_MASK, + 2 /* SubjectAlt DNS */, + asn1_build_sequence_cb, + (void *) &subject_alt_name ) ); } /* * X.509 v3 extensions * */ -static int x509_get_crt_ext( unsigned char **p, - const unsigned char *end, - mbedtls_x509_crt *crt ) +static int x509_crt_get_ext_cb( void *ctx, + int tag, + unsigned char *p, + size_t ext_len ) { int ret; + mbedtls_x509_crt_frame *frame = (mbedtls_x509_crt_frame *) ctx; size_t len; - unsigned char *end_ext_data, *end_ext_octet; + unsigned char *end, *end_ext_octet; + mbedtls_x509_buf extn_oid = { 0, 0, NULL }; + int is_critical = 0; /* DEFAULT FALSE */ + int ext_type = 0; - if( *p == end ) - return( 0 ); + ((void) tag); - if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) - return( ret ); + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ - end = crt->v3_ext.p + crt->v3_ext.len; - while( *p < end ) + end = p + ext_len; + + /* Get extension ID */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &extn_oid.len, + MBEDTLS_ASN1_OID ) ) != 0 ) + goto err; + + extn_oid.tag = MBEDTLS_ASN1_OID; + extn_oid.p = p; + p += extn_oid.len; + + /* Get optional critical */ + if( ( ret = mbedtls_asn1_get_bool( &p, end, &is_critical ) ) != 0 && + ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) + goto err; + + /* Data should be octet string type */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + goto err; + + end_ext_octet = p + len; + if( end_ext_octet != end ) { - /* - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } - */ - mbedtls_x509_buf extn_oid = {0, 0, NULL}; - int is_critical = 0; /* DEFAULT FALSE */ - int ext_type = 0; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - end_ext_data = *p + len; - - /* Get extension ID */ - if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len, - MBEDTLS_ASN1_OID ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - extn_oid.tag = MBEDTLS_ASN1_OID; - extn_oid.p = *p; - *p += extn_oid.len; - - /* Get optional critical */ - if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && - ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - /* Data should be octet string type */ - if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, - MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - - end_ext_octet = *p + len; - - if( end_ext_octet != end_ext_data ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - - /* - * Detect supported extensions - */ - ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); - - if( ret != 0 ) - { - /* No parser found, skip extension */ - *p = end_ext_octet; + ret = MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + goto err; + } + /* + * Detect supported extensions + */ + ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); + if( ret != 0 ) + { #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) - if( is_critical ) - { - /* Data is marked as critical: fail */ - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + - MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); - } -#endif - continue; - } - - /* Forbid repeated extensions */ - if( ( crt->ext_types & ext_type ) != 0 ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); - - crt->ext_types |= ext_type; - - switch( ext_type ) + if( is_critical ) { + /* Data is marked as critical: fail */ + ret = MBEDTLS_ERR_ASN1_UNEXPECTED_TAG; + goto err; + } +#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ + return( 0 ); + } + + /* Forbid repeated extensions */ + if( ( frame->ext_types & ext_type ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); + + frame->ext_types |= ext_type; + switch( ext_type ) + { case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: + { + int ca_istrue; + int max_pathlen; + /* Parse basic constraints */ - if( ( ret = x509_get_basic_constraints( p, end_ext_octet, - &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) - return( ret ); + ret = x509_get_basic_constraints( &p, end_ext_octet, + &ca_istrue, + &max_pathlen ); + if( ret != 0 ) + goto err; + + frame->ca_istrue = ca_istrue; + frame->max_pathlen = max_pathlen; break; + } case MBEDTLS_X509_EXT_KEY_USAGE: /* Parse key usage */ - if( ( ret = x509_get_key_usage( p, end_ext_octet, - &crt->key_usage ) ) != 0 ) - return( ret ); + ret = x509_get_key_usage( &p, end_ext_octet, + &frame->key_usage ); + if( ret != 0 ) + goto err; + break; + + case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: + /* Copy reference to raw subject alt name data. */ + frame->subject_alt_raw.p = p; + frame->subject_alt_raw.len = end_ext_octet - p; + + ret = mbedtls_asn1_traverse_sequence_of( &p, end_ext_octet, + MBEDTLS_ASN1_TAG_CLASS_MASK, + MBEDTLS_ASN1_CONTEXT_SPECIFIC, + MBEDTLS_ASN1_TAG_VALUE_MASK, + 2 /* SubjectAlt DNS */, + NULL, NULL ); + if( ret != 0 ) + goto err; break; case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: /* Parse extended key usage */ - if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, - &crt->ext_key_usage ) ) != 0 ) - return( ret ); - break; + frame->ext_key_usage_raw.p = p; + frame->ext_key_usage_raw.len = end_ext_octet - p; + if( frame->ext_key_usage_raw.len == 0 ) + { + ret = MBEDTLS_ERR_ASN1_INVALID_LENGTH; + goto err; + } + + /* Check structural sanity of extension. */ + ret = mbedtls_asn1_traverse_sequence_of( &p, end_ext_octet, + 0xFF, MBEDTLS_ASN1_OID, + 0, 0, NULL, NULL ); + if( ret != 0 ) + goto err; - case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: - /* Parse subject alt name */ - if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, - &crt->subject_alt_names ) ) != 0 ) - return( ret ); break; case MBEDTLS_X509_EXT_NS_CERT_TYPE: /* Parse netscape certificate type */ - if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, - &crt->ns_cert_type ) ) != 0 ) - return( ret ); + ret = x509_get_ns_cert_type( &p, end_ext_octet, + &frame->ns_cert_type ); + if( ret != 0 ) + goto err; break; default: - return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); - } + /* + * If this is a non-critical extension, which the oid layer + * supports, but there isn't an X.509 parser for it, + * skip the extension. + */ +#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + if( is_critical ) + return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); +#endif + p = end_ext_octet; } - if( *p != end ) - return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + return( 0 ); + +err: + return( ret ); +} + +static int x509_crt_frame_parse_ext( mbedtls_x509_crt_frame *frame ) +{ + int ret; + unsigned char *p = frame->v3_ext.p; + unsigned char *end = p + frame->v3_ext.len; + + if( p == end ) + return( 0 ); + + ret = mbedtls_asn1_traverse_sequence_of( &p, end, + 0xFF, MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED, + 0, 0, x509_crt_get_ext_cb, frame ); + + if( ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ) + return( ret ); + if( ret == MBEDTLS_ERR_X509_INVALID_EXTENSIONS ) + return( ret ); + + if( ret != 0 ) + ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + + return( ret ); +} + +static int x509_crt_parse_frame( unsigned char *start, + unsigned char *end, + mbedtls_x509_crt_frame *frame ) +{ + int ret; + unsigned char *p; + size_t len; + + mbedtls_x509_buf tmp; + unsigned char *tbs_start; + + mbedtls_x509_buf outer_sig_alg; + size_t inner_sig_alg_len; + unsigned char *inner_sig_alg_start; + + memset( frame, 0, sizeof( *frame ) ); + + /* + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + * } + * + */ + p = start; + + frame->raw.p = p; + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + } + + /* NOTE: We are currently not checking that the `Certificate` + * structure spans the entire buffer. */ + end = p + len; + frame->raw.len = end - frame->raw.p; + + /* + * TBSCertificate ::= SEQUENCE { ... + */ + frame->tbs.p = p; + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT ); + } + tbs_start = p; + + /* Breadth-first parsing: Jump over TBS for now. */ + p += len; + frame->tbs.len = p - frame->tbs.p; + + /* + * AlgorithmIdentifier ::= SEQUENCE { ... + */ + outer_sig_alg.p = p; + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + } + p += len; + outer_sig_alg.len = p - outer_sig_alg.p; + + /* + * signatureValue BIT STRING + */ + ret = mbedtls_x509_get_sig( &p, end, &tmp ); + if( ret != 0 ) + return( ret ); + frame->sig.p = tmp.p; + frame->sig.len = tmp.len; + + /* Check that we consumed the entire `Certificate` structure. */ + if( p != end ) + { + return( MBEDTLS_ERR_X509_INVALID_FORMAT + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + /* Parse TBSCertificate structure + * + * TBSCertificate ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version MUST be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version MUST be v3 + * } + */ + end = frame->tbs.p + frame->tbs.len; + p = tbs_start; + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + { + int version; + ret = x509_get_version( &p, end, &version ); + if( ret != 0 ) + return( ret ); + + if( version < 0 || version > 2 ) + return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); + + frame->version = version + 1; + } + + /* + * CertificateSerialNumber ::= INTEGER + */ + ret = mbedtls_x509_get_serial( &p, end, &tmp ); + if( ret != 0 ) + return( ret ); + + frame->serial.p = tmp.p; + frame->serial.len = tmp.len; + + /* + * signature AlgorithmIdentifier + */ + inner_sig_alg_start = p; + ret = mbedtls_x509_get_sig_alg_raw( &p, end, &frame->sig_md, + &frame->sig_pk, NULL ); + if( ret != 0 ) + return( ret ); + inner_sig_alg_len = p - inner_sig_alg_start; + + frame->sig_alg.p = inner_sig_alg_start; + frame->sig_alg.len = inner_sig_alg_len; + + /* Consistency check: + * Inner and outer AlgorithmIdentifier structures must coincide: + * + * Quoting RFC 5280, Section 4.1.1.2: + * This field MUST contain the same algorithm identifier as the + * signature field in the sequence tbsCertificate (Section 4.1.2.3). + */ + if( outer_sig_alg.len != inner_sig_alg_len || + memcmp( outer_sig_alg.p, inner_sig_alg_start, inner_sig_alg_len ) != 0 ) + { + return( MBEDTLS_ERR_X509_SIG_MISMATCH ); + } + + /* + * issuer Name + * + * Name ::= CHOICE { -- only one possibility for now -- + * rdnSequence RDNSequence } + * + * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + */ + frame->issuer_raw.p = p; + + ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ); + if( ret != 0 ) + return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT ); + p += len; + frame->issuer_raw.len = p - frame->issuer_raw.p; + + /* Comparing the raw buffer to itself amounts to structural validation. */ + ret = mbedtls_x509_name_cmp_raw( &frame->issuer_raw, + &frame->issuer_raw, + NULL, NULL ); + if( ret != 0 ) + return( ret ); + + /* + * Validity ::= SEQUENCE { ... + */ + ret = x509_get_dates( &p, end, &frame->valid_from, &frame->valid_to ); + if( ret != 0 ) + return( ret ); + + /* + * subject Name + * + * Name ::= CHOICE { -- only one possibility for now -- + * rdnSequence RDNSequence } + * + * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + */ + frame->subject_raw.p = p; + + ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ); + if( ret != 0 ) + return( ret + MBEDTLS_ERR_X509_INVALID_FORMAT ); + p += len; + frame->subject_raw.len = p - frame->subject_raw.p; + + /* Comparing the raw buffer to itself amounts to structural validation. */ + ret = mbedtls_x509_name_cmp_raw( &frame->subject_raw, + &frame->subject_raw, + NULL, NULL ); + if( ret != 0 ) + return( ret ); + + /* + * SubjectPublicKeyInfo + */ + frame->pubkey_raw.p = p; + ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ); + if( ret != 0 ) + return( ret + MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + p += len; + frame->pubkey_raw.len = p - frame->pubkey_raw.p; + + if( frame->version != 1 ) + { + /* + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + */ + ret = x509_get_uid( &p, end, &frame->issuer_id, 1 /* implicit tag */ ); + if( ret != 0 ) + return( ret ); + + /* + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + */ + ret = x509_get_uid( &p, end, &frame->subject_id, 2 /* implicit tag */ ); + if( ret != 0 ) + return( ret ); + } + + /* + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version shall be v3 + */ +#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) + if( frame->version == 3 ) +#endif + { + if( p != end ) + { + ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 3 ); + if( len == 0 ) + ret = MBEDTLS_ERR_ASN1_OUT_OF_DATA; + if( ret != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + frame->v3_ext.p = p; + frame->v3_ext.len = len; + + p += len; + } + + ret = x509_crt_frame_parse_ext( frame ); + if( ret != 0 ) + return( ret ); + } + + /* Wrapup: Check that we consumed the entire `TBSCertificate` structure. */ + if( p != end ) + { + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } return( 0 ); } +static int x509_crt_subject_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_name *subject ) +{ + return( mbedtls_x509_get_name( frame->subject_raw.p, + frame->subject_raw.len, + subject ) ); +} + +static int x509_crt_issuer_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_name *issuer ) +{ + return( mbedtls_x509_get_name( frame->issuer_raw.p, + frame->issuer_raw.len, + issuer ) ); +} + +static int x509_crt_subject_alt_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_sequence *subject_alt ) +{ + int ret; + unsigned char *p = frame->subject_alt_raw.p; + unsigned char *end = p + frame->subject_alt_raw.len; + + memset( subject_alt, 0, sizeof( *subject_alt ) ); + + if( ( frame->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) == 0 ) + return( 0 ); + + ret = x509_get_subject_alt_name( p, end, subject_alt ); + if( ret != 0 ) + ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + return( ret ); +} + +static int x509_crt_ext_key_usage_from_frame( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_sequence *ext_key_usage ) +{ + int ret; + unsigned char *p = frame->ext_key_usage_raw.p; + unsigned char *end = p + frame->ext_key_usage_raw.len; + + memset( ext_key_usage, 0, sizeof( *ext_key_usage ) ); + + if( ( frame->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) + return( 0 ); + + ret = x509_get_ext_key_usage( &p, end, ext_key_usage ); + if( ret != 0 ) + { + ret += MBEDTLS_ERR_X509_INVALID_EXTENSIONS; + return( ret ); + } + + return( 0 ); +} + +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) +static int x509_crt_pk_from_frame( mbedtls_x509_crt_frame *frame, + mbedtls_pk_context *pk ) +{ + unsigned char *p = frame->pubkey_raw.p; + unsigned char *end = p + frame->pubkey_raw.len; + return( mbedtls_pk_parse_subpubkey( &p, end, pk ) ); +} +#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ + /* * Parse and fill a single X.509 certificate in DER format */ @@ -834,256 +1465,178 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, int make_copy ) { int ret; - size_t len; - unsigned char *p, *end, *crt_end; - mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; + mbedtls_x509_crt_frame *frame; + mbedtls_x509_crt_cache *cache; - memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); - memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); - - /* - * Check for valid input - */ if( crt == NULL || buf == NULL ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - /* Use the original buffer until we figure out actual length. */ - p = (unsigned char*) buf; - len = buflen; - end = p + len; - - /* - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING } - */ - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + if( make_copy == 0 ) { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT ); - } - - 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; + crt->raw.p = (unsigned char*) buf; + crt->raw.len = buflen; + crt->own_buffer = 0; } else { - crt->raw.p = (unsigned char*) buf; - crt->own_buffer = 0; + /* Call mbedtls_calloc with buflen + 1 in order to avoid potential + * return of NULL in case of length 0 certificates, which we want + * to cleanly fail with MBEDTLS_ERR_X509_INVALID_FORMAT in the + * core parsing routine, but not here. */ + crt->raw.p = mbedtls_calloc( 1, buflen + 1 ); + if( crt->raw.p == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + crt->raw.len = buflen; + memcpy( crt->raw.p, buf, buflen ); + + crt->own_buffer = 1; } + cache = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_cache ) ); + if( cache == NULL ) + { + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + goto exit; + } + crt->cache = cache; + x509_crt_cache_init( cache ); + +#if defined(MBEDTLS_X509_ON_DEMAND_PARSING) + + ret = mbedtls_x509_crt_cache_provide_frame( crt ); + if( ret != 0 ) + goto exit; + + frame = crt->cache->frame; + +#else /* MBEDTLS_X509_ON_DEMAND_PARSING */ + + frame = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt_frame ) ); + if( frame == NULL ) + { + ret = MBEDTLS_ERR_X509_ALLOC_FAILED; + goto exit; + } + cache->frame = frame; + + ret = x509_crt_parse_frame( crt->raw.p, + crt->raw.p + crt->raw.len, + frame ); + if( ret != 0 ) + goto exit; + + /* Copy frame to legacy CRT structure -- that's inefficient, but if + * memory matters, the new CRT structure should be used anyway. */ + x509_buf_raw_to_buf( &crt->tbs, &frame->tbs ); + x509_buf_raw_to_buf( &crt->serial, &frame->serial ); + x509_buf_raw_to_buf( &crt->issuer_raw, &frame->issuer_raw ); + x509_buf_raw_to_buf( &crt->subject_raw, &frame->subject_raw ); + x509_buf_raw_to_buf( &crt->issuer_id, &frame->issuer_id ); + x509_buf_raw_to_buf( &crt->subject_id, &frame->subject_id ); + x509_buf_raw_to_buf( &crt->pk_raw, &frame->pubkey_raw ); + x509_buf_raw_to_buf( &crt->sig, &frame->sig ); + x509_buf_raw_to_buf( &crt->v3_ext, &frame->v3_ext ); + crt->valid_from = frame->valid_from; + crt->valid_to = frame->valid_to; + crt->version = frame->version; + crt->ca_istrue = frame->ca_istrue; + crt->max_pathlen = frame->max_pathlen; + crt->ext_types = frame->ext_types; + crt->key_usage = frame->key_usage; + crt->ns_cert_type = frame->ns_cert_type; + /* - * TBSCertificate ::= SEQUENCE { + * Obtain the remaining fields from the frame. */ - crt->tbs.p = p; - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } + /* sig_oid: Previously, needed for convenience in + * mbedtls_x509_crt_info(), now pure legacy burden. */ + unsigned char *tmp = frame->sig_alg.p; + unsigned char *end = tmp + frame->sig_alg.len; + mbedtls_x509_buf sig_oid, sig_params; - end = p + len; - crt->tbs.len = end - crt->tbs.p; - - /* - * Version ::= INTEGER { v1(0), v2(1), v3(2) } - * - * CertificateSerialNumber ::= INTEGER - * - * signature AlgorithmIdentifier - */ - if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || - ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || - ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, - &sig_params1 ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - if( crt->version < 0 || crt->version > 2 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); - } - - crt->version++; - - if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, - &crt->sig_md, &crt->sig_pk, - &crt->sig_opts ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * issuer Name - */ - crt->issuer_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - crt->issuer_raw.len = p - crt->issuer_raw.p; - - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time } - * - */ - if( ( ret = x509_get_dates( &p, end, &crt->valid_from, - &crt->valid_to ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - /* - * subject Name - */ - crt->subject_raw.p = p; - - if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); - } - - if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - - crt->subject_raw.len = p - crt->subject_raw.p; - - /* - * SubjectPublicKeyInfo - */ - crt->pk_raw.p = p; - if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - crt->pk_raw.len = p - crt->pk_raw.p; - - /* - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - * -- If present, version shall be v2 or v3 - * extensions [3] EXPLICIT Extensions OPTIONAL - * -- If present, version shall be v3 - */ - if( crt->version == 2 || crt->version == 3 ) - { - ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); + ret = mbedtls_x509_get_alg( &tmp, end, + &sig_oid, &sig_params ); if( ret != 0 ) { - mbedtls_x509_crt_free( crt ); - return( ret ); + /* This should never happen, because we check + * the sanity of the AlgorithmIdentifier structure + * during frame parsing. */ + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto exit; + } + crt->sig_oid = sig_oid; + + /* Signature parameters */ + tmp = frame->sig_alg.p; + ret = mbedtls_x509_get_sig_alg_raw( &tmp, end, + &crt->sig_md, &crt->sig_pk, + &crt->sig_opts ); + if( ret != 0 ) + { + /* Again, this should never happen. */ + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto exit; } } - if( crt->version == 2 || crt->version == 3 ) - { - ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } + ret = x509_crt_pk_from_frame( frame, &crt->pk ); + if( ret != 0 ) + goto exit; -#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) - if( crt->version == 3 ) -#endif - { - ret = x509_get_crt_ext( &p, end, crt ); - if( ret != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } - } + ret = x509_crt_subject_from_frame( frame, &crt->subject ); + if( ret != 0 ) + goto exit; - if( p != end ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } + ret = x509_crt_issuer_from_frame( frame, &crt->issuer ); + if( ret != 0 ) + goto exit; - end = crt_end; + ret = x509_crt_subject_alt_from_frame( frame, &crt->subject_alt_names ); + if( ret != 0 ) + goto exit; - /* - * } - * -- end of TBSCertificate + ret = x509_crt_ext_key_usage_from_frame( frame, &crt->ext_key_usage ); + if( ret != 0 ) + goto exit; +#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ + + /* Currently, we accept DER encoded CRTs with trailing garbage + * and promise to not account for the garbage in the `raw` field. * - * signatureAlgorithm AlgorithmIdentifier, - * signatureValue BIT STRING - */ - if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } + * Note that this means that `crt->raw.len` is not necessarily the + * full size of the heap buffer allocated at `crt->raw.p` in case + * of copy-mode, but this is not a problem: freeing the buffer doesn't + * need the size, and the garbage data doesn't need zeroization. */ + crt->raw.len = frame->raw.len; - if( crt->sig_oid.len != sig_oid2.len || - memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || - sig_params1.len != sig_params2.len || - ( sig_params1.len != 0 && - memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_SIG_MISMATCH ); - } + cache->pk_raw = frame->pubkey_raw; - if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) - { - mbedtls_x509_crt_free( crt ); - return( ret ); - } + /* Free the frame before parsing the public key to + * keep peak RAM usage low. This is slightly inefficient + * because the frame will need to be parsed again on the + * first usage of the CRT, but that seems acceptable. + * As soon as the frame gets used multiple times, it + * will be cached by default. */ + x509_crt_cache_clear_frame( crt->cache ); - if( p != end ) - { - mbedtls_x509_crt_free( crt ); - return( MBEDTLS_ERR_X509_INVALID_FORMAT + - MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); - } + /* The cache just references the PK structure from the legacy + * implementation, so set up the latter first before setting up + * the cache. + * + * We're not actually using the parsed PK context here; + * we just parse it to check that it's well-formed. */ + ret = mbedtls_x509_crt_cache_provide_pk( crt ); + if( ret != 0 ) + goto exit; + x509_crt_cache_clear_pk( crt->cache ); - return( 0 ); +exit: + if( ret != 0 ) + mbedtls_x509_crt_free( crt ); + + return( ret ); } /* @@ -1104,7 +1657,7 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, if( crt == NULL || buf == NULL ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); - while( crt->version != 0 && crt->next != NULL ) + while( crt->raw.p != NULL && crt->next != NULL ) { prev = crt; crt = crt->next; @@ -1113,7 +1666,7 @@ static int mbedtls_x509_crt_parse_der_internal( mbedtls_x509_crt *chain, /* * Add new certificate on the end of the chain if needed. */ - if( crt->version != 0 && crt->next == NULL ) + if( crt->raw.p != NULL && crt->next == NULL ) { crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); @@ -1415,6 +1968,71 @@ cleanup: } #endif /* MBEDTLS_FS_IO */ +typedef struct mbedtls_x509_crt_sig_info +{ + mbedtls_md_type_t sig_md; + mbedtls_pk_type_t sig_pk; + void *sig_opts; + uint8_t crt_hash[MBEDTLS_MD_MAX_SIZE]; + size_t crt_hash_len; + mbedtls_x509_buf_raw sig; + mbedtls_x509_buf_raw issuer_raw; +} mbedtls_x509_crt_sig_info; + +static void x509_crt_free_sig_info( mbedtls_x509_crt_sig_info *info ) +{ +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + mbedtls_free( info->sig_opts ); +#else + ((void) info); +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ +} + +static int x509_crt_get_sig_info( mbedtls_x509_crt_frame const *frame, + mbedtls_x509_crt_sig_info *info ) +{ + const mbedtls_md_info_t *md_info; + + md_info = mbedtls_md_info_from_type( frame->sig_md ); + if( mbedtls_md( md_info, frame->tbs.p, frame->tbs.len, + info->crt_hash ) != 0 ) + { + /* Note: this can't happen except after an internal error */ + return( -1 ); + } + + info->crt_hash_len = mbedtls_md_get_size( md_info ); + + /* Make sure that this function leaves the target structure + * ready to be freed, regardless of success of failure. */ + info->sig_opts = NULL; + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + { + int ret; + unsigned char *alg_start = frame->sig_alg.p; + unsigned char *alg_end = alg_start + frame->sig_alg.len; + + /* Get signature options -- currently only + * necessary for RSASSA-PSS. */ + ret = mbedtls_x509_get_sig_alg_raw( &alg_start, alg_end, &info->sig_md, + &info->sig_pk, &info->sig_opts ); + if( ret != 0 ) + { + /* Note: this can't happen except after an internal error */ + return( -1 ); + } + } +#else /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + info->sig_md = frame->sig_md; + info->sig_pk = frame->sig_pk; +#endif /* !MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + + info->issuer_raw = frame->issuer_raw; + info->sig = frame->sig; + return( 0 ); +} + #if !defined(MBEDTLS_X509_REMOVE_INFO) static int x509_info_subject_alt_name( char **buf, size_t *size, const mbedtls_x509_sequence *subject_alt_name ) @@ -1551,135 +2169,209 @@ static int x509_info_ext_key_usage( char **buf, size_t *size, #define BEFORE_COLON 18 #define BC "18" int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, - const mbedtls_x509_crt *crt ) + const mbedtls_x509_crt *crt ) { int ret; size_t n; char *p; char key_size_str[BEFORE_COLON]; + mbedtls_x509_crt_frame frame; + mbedtls_pk_context pk; + + mbedtls_x509_name *issuer = NULL, *subject = NULL; + mbedtls_x509_sequence *ext_key_usage = NULL, *subject_alt_names = NULL; + mbedtls_x509_crt_sig_info sig_info; p = buf; n = size; + memset( &sig_info, 0, sizeof( mbedtls_x509_crt_sig_info ) ); + mbedtls_pk_init( &pk ); + if( NULL == crt ) { ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; return( (int) ( size - n ) ); } - ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", - prefix, crt->version ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_snprintf( p, n, "%sserial number : ", - prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_crt_get_frame( crt, &frame ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } - ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_crt_get_subject( crt, &subject ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = mbedtls_x509_crt_get_issuer( crt, &issuer ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = mbedtls_x509_crt_get_subject_alt_names( crt, &subject_alt_names ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = mbedtls_x509_crt_get_ext_key_usage( crt, &ext_key_usage ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = mbedtls_x509_crt_get_pk( crt, &pk ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = x509_crt_get_sig_info( &frame, &sig_info ); + if( ret != 0 ) + { + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + goto cleanup; + } + + ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", + prefix, frame.version ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + + { + mbedtls_x509_buf serial; + serial.p = frame.serial.p; + serial.len = frame.serial.len; + ret = mbedtls_snprintf( p, n, "%sserial number : ", + prefix ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + ret = mbedtls_x509_serial_gets( p, n, &serial ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + } ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + ret = mbedtls_x509_dn_gets( p, n, issuer ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + ret = mbedtls_x509_dn_gets( p, n, subject ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_from.year, crt->valid_from.mon, - crt->valid_from.day, crt->valid_from.hour, - crt->valid_from.min, crt->valid_from.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; + frame.valid_from.year, frame.valid_from.mon, + frame.valid_from.day, frame.valid_from.hour, + frame.valid_from.min, frame.valid_from.sec ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ "%04d-%02d-%02d %02d:%02d:%02d", prefix, - crt->valid_to.year, crt->valid_to.mon, - crt->valid_to.day, crt->valid_to.hour, - crt->valid_to.min, crt->valid_to.sec ); - MBEDTLS_X509_SAFE_SNPRINTF; + frame.valid_to.year, frame.valid_to.mon, + frame.valid_to.day, frame.valid_to.hour, + frame.valid_to.min, frame.valid_to.sec ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk, - crt->sig_md, crt->sig_opts ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_sig_alg_gets( p, n, sig_info.sig_pk, + sig_info.sig_md, sig_info.sig_opts ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; /* Key size */ if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, - mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) + mbedtls_pk_get_name( &pk ) ) ) != 0 ) { return( ret ); } ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, - (int) mbedtls_pk_get_bitlen( &crt->pk ) ); - MBEDTLS_X509_SAFE_SNPRINTF; + (int) mbedtls_pk_get_bitlen( &pk ) ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; /* * Optional extensions */ - if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) + if( frame.ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) { ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, - crt->ca_istrue ? "true" : "false" ); - MBEDTLS_X509_SAFE_SNPRINTF; + frame.ca_istrue ? "true" : "false" ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - if( crt->max_pathlen > 0 ) + if( frame.max_pathlen > 0 ) { - ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", frame.max_pathlen - 1 ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; } } - if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + if( frame.ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) { ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; if( ( ret = x509_info_subject_alt_name( &p, &n, - &crt->subject_alt_names ) ) != 0 ) + subject_alt_names ) ) != 0 ) return( ret ); } - if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) + if( frame.ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) { ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) + if( ( ret = x509_info_cert_type( &p, &n, frame.ns_cert_type ) ) != 0 ) return( ret ); } - if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) + if( frame.ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) { ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) + if( ( ret = x509_info_key_usage( &p, &n, frame.key_usage ) ) != 0 ) return( ret ); } - if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) + if( frame.ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) { ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; if( ( ret = x509_info_ext_key_usage( &p, &n, - &crt->ext_key_usage ) ) != 0 ) + ext_key_usage ) ) != 0 ) return( ret ); } ret = mbedtls_snprintf( p, n, "\n" ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - return( (int) ( size - n ) ); + ret = (int) ( size - n ); + +cleanup: + + x509_crt_free_sig_info( &sig_info ); + mbedtls_pk_free( &pk ); + mbedtls_x509_name_free( issuer ); + mbedtls_x509_name_free( subject ); + mbedtls_x509_sequence_free( ext_key_usage ); + mbedtls_x509_sequence_free( subject_alt_names ); + + return( ret ); } struct x509_crt_verify_string { @@ -1741,8 +2433,8 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, #endif /* !MBEDTLS_X509_REMOVE_INFO */ #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) -int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, - unsigned int usage ) +static int x509_crt_check_key_usage_frame( const mbedtls_x509_crt_frame *crt, + unsigned int usage ) { unsigned int usage_must, usage_may; unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY @@ -1763,37 +2455,87 @@ int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, return( 0 ); } + +int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, + unsigned int usage ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + ret = x509_crt_check_key_usage_frame( frame, usage ); + mbedtls_x509_crt_frame_release( crt ); + + return( ret ); +} #endif #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) -int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, - const char *usage_oid, - size_t usage_len ) +typedef struct { - const mbedtls_x509_sequence *cur; + const char *oid; + size_t oid_len; +} x509_crt_check_ext_key_usage_cb_ctx_t; - /* Extension is not mandatory, absent means no restriction */ - if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) - return( 0 ); +static int x509_crt_check_ext_key_usage_cb( void *ctx, + int tag, + unsigned char *data, + size_t data_len ) +{ + x509_crt_check_ext_key_usage_cb_ctx_t *cb_ctx = + (x509_crt_check_ext_key_usage_cb_ctx_t *) ctx; + ((void) tag); - /* - * Look for the requested usage (or wildcard ANY) in our list - */ - for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) + if( MBEDTLS_OID_CMP_RAW( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, + data, data_len ) == 0 ) { - const mbedtls_x509_buf *cur_oid = &cur->buf; - - if( cur_oid->len == usage_len && - memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) - { - return( 0 ); - } - - if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) - return( 0 ); + return( 1 ); } - return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + if( data_len == cb_ctx->oid_len && memcmp( data, cb_ctx->oid, + data_len ) == 0 ) + { + return( 1 ); + } + + return( 0 ); +} + +int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, + const char *usage_oid, + size_t usage_len ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + unsigned ext_types; + unsigned char *p, *end; + x509_crt_check_ext_key_usage_cb_ctx_t cb_ctx = { usage_oid, usage_len }; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + /* Extension is not mandatory, absent means no restriction */ + ext_types = frame->ext_types; + if( ( ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) != 0 ) + { + p = frame->ext_key_usage_raw.p; + end = p + frame->ext_key_usage_raw.len; + + ret = mbedtls_asn1_traverse_sequence_of( &p, end, + 0xFF, MBEDTLS_ASN1_OID, 0, 0, + x509_crt_check_ext_key_usage_cb, + &cb_ctx ); + if( ret == 1 ) + ret = 0; + else + ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; + } + + mbedtls_x509_crt_frame_release( crt ); + return( ret ); } #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ @@ -1801,14 +2543,16 @@ int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, /* * Return 1 if the certificate is revoked, or 0 otherwise. */ -int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) +static int x509_serial_is_revoked( unsigned char const *serial, + size_t serial_len, + const mbedtls_x509_crl *crl ) { const mbedtls_x509_crl_entry *cur = &crl->entry; while( cur != NULL && cur->serial.len != 0 ) { - if( crt->serial.len == cur->serial.len && - memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) + if( serial_len == cur->serial.len && + memcmp( serial, cur->serial.p, serial_len ) == 0 ) { if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) return( 1 ); @@ -1820,25 +2564,71 @@ int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509 return( 0 ); } +int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, + const mbedtls_x509_crl *crl ) +{ + int ret; + mbedtls_x509_crt_frame const *frame; + + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + ret = x509_serial_is_revoked( frame->serial.p, + frame->serial.len, + crl ); + mbedtls_x509_crt_frame_release( crt ); + return( ret ); +} + /* * Check that the given certificate is not revoked according to the CRL. * Skip validation if no CRL for the given CA is present. */ -static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, +static int x509_crt_verifycrl( unsigned char *crt_serial, + size_t crt_serial_len, + mbedtls_x509_crt *ca_crt, mbedtls_x509_crl *crl_list, const mbedtls_x509_crt_profile *profile ) { + int ret; int flags = 0; unsigned char hash[MBEDTLS_MD_MAX_SIZE]; const mbedtls_md_info_t *md_info; + mbedtls_x509_buf_raw ca_subject; + mbedtls_pk_context *pk; + int can_sign; - if( ca == NULL ) + if( ca_crt == NULL ) return( flags ); + { + mbedtls_x509_crt_frame const *ca; + ret = mbedtls_x509_crt_frame_acquire( ca_crt, &ca ); + if( ret != 0 ) + return( MBEDTLS_X509_BADCRL_NOT_TRUSTED ); + + ca_subject = ca->subject_raw; + + can_sign = 0; + if( x509_crt_check_key_usage_frame( ca, + MBEDTLS_X509_KU_CRL_SIGN ) == 0 ) + { + can_sign = 1; + } + + mbedtls_x509_crt_frame_release( ca_crt ); + } + + ret = mbedtls_x509_crt_pk_acquire( ca_crt, &pk ); + if( ret != 0 ) + return( MBEDTLS_X509_BADCRL_NOT_TRUSTED ); + while( crl_list != NULL ) { if( crl_list->version == 0 || - x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 ) + mbedtls_x509_name_cmp_raw( &crl_list->issuer_raw, + &ca_subject, NULL, NULL ) != 0 ) { crl_list = crl_list->next; continue; @@ -1848,8 +2638,7 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, * Check if the CA is configured to sign CRLs */ #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) - if( mbedtls_x509_crt_check_key_usage( ca, - MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) + if( !can_sign ) { flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; break; @@ -1873,10 +2662,10 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, break; } - if( x509_profile_check_key( profile, &ca->pk ) != 0 ) + if( x509_profile_check_key( profile, pk ) != 0 ) flags |= MBEDTLS_X509_BADCERT_BAD_KEY; - if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, + if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, pk, crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), crl_list->sig.p, crl_list->sig.len ) != 0 ) { @@ -1896,7 +2685,8 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, /* * Check if certificate is revoked */ - if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) + if( x509_serial_is_revoked( crt_serial, crt_serial_len, + crl_list ) ) { flags |= MBEDTLS_X509_BADCERT_REVOKED; break; @@ -1905,6 +2695,7 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, crl_list = crl_list->next; } + mbedtls_x509_crt_pk_release( ca_crt ); return( flags ); } #endif /* MBEDTLS_X509_CRL_PARSE_C */ @@ -1912,38 +2703,49 @@ static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, /* * Check the signature of a certificate by its parent */ -static int x509_crt_check_signature( const mbedtls_x509_crt *child, +static int x509_crt_check_signature( const mbedtls_x509_crt_sig_info *sig_info, mbedtls_x509_crt *parent, mbedtls_x509_crt_restart_ctx *rs_ctx ) { - const mbedtls_md_info_t *md_info; - unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + int ret; + mbedtls_pk_context *pk; - md_info = mbedtls_md_info_from_type( child->sig_md ); - if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) - { - /* Note: this can't happen except after an internal error */ - return( -1 ); - } + ret = mbedtls_x509_crt_pk_acquire( parent, &pk ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); /* Skip expensive computation on obvious mismatch */ - if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) ) - return( -1 ); - -#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) - if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA ) + if( ! mbedtls_pk_can_do( pk, sig_info->sig_pk ) ) { - return( mbedtls_pk_verify_restartable( &parent->pk, - child->sig_md, hash, mbedtls_md_get_size( md_info ), - child->sig.p, child->sig.len, &rs_ctx->pk ) ); + ret = -1; + goto exit; } -#else - (void) rs_ctx; -#endif - return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, - child->sig_md, hash, mbedtls_md_get_size( md_info ), - child->sig.p, child->sig.len ) ); +#if !( defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) ) + ((void) rs_ctx); +#else + if( rs_ctx != NULL && sig_info->sig_pk == MBEDTLS_PK_ECDSA ) + { + ret = mbedtls_pk_verify_restartable( pk, + sig_info->sig_md, + sig_info->crt_hash, sig_info->crt_hash_len, + sig_info->sig.p, sig_info->sig.len, + &rs_ctx->pk ); + } + else +#endif + { + ret = mbedtls_pk_verify_ext( sig_info->sig_pk, + sig_info->sig_opts, + pk, + sig_info->sig_md, + sig_info->crt_hash, sig_info->crt_hash_len, + sig_info->sig.p, sig_info->sig.len ); + } + +exit: + mbedtls_x509_crt_pk_release( parent ); + return( ret ); } /* @@ -1952,15 +2754,19 @@ static int x509_crt_check_signature( const mbedtls_x509_crt *child, * * top means parent is a locally-trusted certificate */ -static int x509_crt_check_parent( const mbedtls_x509_crt *child, - const mbedtls_x509_crt *parent, +static int x509_crt_check_parent( const mbedtls_x509_crt_sig_info *sig_info, + const mbedtls_x509_crt_frame *parent, int top ) { int need_ca_bit; /* Parent must be the issuer */ - if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) + if( mbedtls_x509_name_cmp_raw( &sig_info->issuer_raw, + &parent->subject_raw, + NULL, NULL ) != 0 ) + { return( -1 ); + } /* Parent must have the basicConstraints CA bit set as a general rule */ need_ca_bit = 1; @@ -1974,7 +2780,8 @@ static int x509_crt_check_parent( const mbedtls_x509_crt *child, #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) if( need_ca_bit && - mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) + x509_crt_check_key_usage_frame( parent, + MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) { return( -1 ); } @@ -2027,7 +2834,7 @@ static int x509_crt_check_parent( const mbedtls_x509_crt *child, * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise */ static int x509_crt_find_parent_in( - mbedtls_x509_crt *child, + mbedtls_x509_crt_sig_info const *child_sig, mbedtls_x509_crt *candidates, mbedtls_x509_crt **r_parent, int *r_signature_is_good, @@ -2037,7 +2844,7 @@ static int x509_crt_find_parent_in( mbedtls_x509_crt_restart_ctx *rs_ctx ) { int ret; - mbedtls_x509_crt *parent, *fallback_parent; + mbedtls_x509_crt *parent_crt, *fallback_parent; int signature_is_good, fallback_signature_is_good; #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) @@ -2045,7 +2852,7 @@ static int x509_crt_find_parent_in( if( rs_ctx != NULL && rs_ctx->parent != NULL ) { /* restore saved state */ - parent = rs_ctx->parent; + parent_crt = rs_ctx->parent; fallback_parent = rs_ctx->fallback_parent; fallback_signature_is_good = rs_ctx->fallback_signature_is_good; @@ -2062,30 +2869,55 @@ static int x509_crt_find_parent_in( fallback_parent = NULL; fallback_signature_is_good = 0; - for( parent = candidates; parent != NULL; parent = parent->next ) + for( parent_crt = candidates; parent_crt != NULL; + parent_crt = parent_crt->next ) { - /* basic parenting skills (name, CA bit, key usage) */ - if( x509_crt_check_parent( child, parent, top ) != 0 ) - continue; + int parent_valid, parent_match, path_len_ok; - /* +1 because stored max_pathlen is 1 higher that the actual value */ - if( parent->max_pathlen > 0 && - (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) - { - continue; - } - - /* Signature */ #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) check_signature: #endif - ret = x509_crt_check_signature( child, parent, rs_ctx ); + + parent_valid = parent_match = path_len_ok = 0; + { + mbedtls_x509_crt_frame const *parent; + + ret = mbedtls_x509_crt_frame_acquire( parent_crt, &parent ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + if( !mbedtls_x509_time_is_past( &parent->valid_to ) && + !mbedtls_x509_time_is_future( &parent->valid_from ) ) + { + parent_valid = 1; + } + + /* basic parenting skills (name, CA bit, key usage) */ + if( x509_crt_check_parent( child_sig, parent, top ) == 0 ) + parent_match = 1; + + /* +1 because the stored max_pathlen is 1 higher + * than the actual value */ + if( !( parent->max_pathlen > 0 && + (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) ) + { + path_len_ok = 1; + } + + mbedtls_x509_crt_frame_release( parent_crt ); + } + + if( parent_match == 0 || path_len_ok == 0 ) + continue; + + /* Signature */ + ret = x509_crt_check_signature( child_sig, parent_crt, rs_ctx ); #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) { /* save state */ - rs_ctx->parent = parent; + rs_ctx->parent = parent_crt; rs_ctx->fallback_parent = fallback_parent; rs_ctx->fallback_signature_is_good = fallback_signature_is_good; @@ -2100,12 +2932,11 @@ check_signature: continue; /* optional time check */ - if( mbedtls_x509_time_is_past( &parent->valid_to ) || - mbedtls_x509_time_is_future( &parent->valid_from ) ) + if( !parent_valid ) { if( fallback_parent == NULL ) { - fallback_parent = parent; + fallback_parent = parent_crt; fallback_signature_is_good = signature_is_good; } @@ -2115,9 +2946,9 @@ check_signature: break; } - if( parent != NULL ) + if( parent_crt != NULL ) { - *r_parent = parent; + *r_parent = parent_crt; *r_signature_is_good = signature_is_good; } else @@ -2152,7 +2983,8 @@ check_signature: * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise */ static int x509_crt_find_parent( - mbedtls_x509_crt *child, + mbedtls_x509_crt_sig_info const *child_sig, + mbedtls_x509_crt *rest, mbedtls_x509_crt *trust_ca, mbedtls_x509_crt **parent, int *parent_is_trusted, @@ -2176,9 +3008,9 @@ static int x509_crt_find_parent( #endif while( 1 ) { - search_list = *parent_is_trusted ? trust_ca : child->next; + search_list = *parent_is_trusted ? trust_ca : rest; - ret = x509_crt_find_parent_in( child, search_list, + ret = x509_crt_find_parent_in( child_sig, search_list, parent, signature_is_good, *parent_is_trusted, path_cnt, self_cnt, rs_ctx ); @@ -2219,14 +3051,10 @@ static int x509_crt_find_parent( * check for self-issued as self-signatures are not checked) */ static int x509_crt_check_ee_locally_trusted( - mbedtls_x509_crt *crt, - mbedtls_x509_crt *trust_ca ) + mbedtls_x509_crt_frame const *crt, + mbedtls_x509_crt const *trust_ca ) { - mbedtls_x509_crt *cur; - - /* must be self-issued */ - if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 ) - return( -1 ); + mbedtls_x509_crt const *cur; /* look for an exact match with trusted cert */ for( cur = trust_ca; cur != NULL; cur = cur->next ) @@ -2261,7 +3089,7 @@ static int x509_crt_check_ee_locally_trusted( * Tests for (aspects of) this function should include at least: * - trusted EE * - EE -> trusted root - * - EE -> intermedate CA -> trusted root + * - EE -> intermediate CA -> trusted root * - if relevant: EE untrusted * - if relevant: EE -> intermediate, untrusted * with the aspect under test checked at each relevant level (EE, int, root). @@ -2295,8 +3123,8 @@ static int x509_crt_verify_chain( int ret; uint32_t *flags; mbedtls_x509_crt_verify_chain_item *cur; - mbedtls_x509_crt *child; - mbedtls_x509_crt *parent; + mbedtls_x509_crt *child_crt; + mbedtls_x509_crt *parent_crt; int parent_is_trusted; int child_is_trusted; int signature_is_good; @@ -2312,58 +3140,100 @@ static int x509_crt_verify_chain( /* restore derived state */ cur = &ver_chain->items[ver_chain->len - 1]; - child = cur->crt; - flags = &cur->flags; + child_crt = cur->crt; + child_is_trusted = 0; goto find_parent; } #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */ - child = crt; + child_crt = crt; self_cnt = 0; parent_is_trusted = 0; child_is_trusted = 0; while( 1 ) { +#if defined(MBEDTLS_X509_CRL_PARSE_C) + mbedtls_x509_buf_raw child_serial; +#endif /* MBEDTLS_X509_CRL_PARSE_C */ + int self_issued; + /* Add certificate to the verification chain */ cur = &ver_chain->items[ver_chain->len]; - cur->crt = child; + cur->crt = child_crt; cur->flags = 0; ver_chain->len++; - flags = &cur->flags; - - /* Check time-validity (all certificates) */ - if( mbedtls_x509_time_is_past( &child->valid_to ) ) - *flags |= MBEDTLS_X509_BADCERT_EXPIRED; - - if( mbedtls_x509_time_is_future( &child->valid_from ) ) - *flags |= MBEDTLS_X509_BADCERT_FUTURE; - - /* Stop here for trusted roots (but not for trusted EE certs) */ - if( child_is_trusted ) - return( 0 ); - - /* Check signature algorithm: MD & PK algs */ - if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_MD; - - if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_PK; - - /* Special case: EE certs that are locally trusted */ - if( ver_chain->len == 1 && - x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) - { - return( 0 ); - } #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) find_parent: #endif - /* Look for a parent in trusted CAs or up the chain */ - ret = x509_crt_find_parent( child, trust_ca, &parent, - &parent_is_trusted, &signature_is_good, - ver_chain->len - 1, self_cnt, rs_ctx ); + + flags = &cur->flags; + + { + mbedtls_x509_crt_sig_info child_sig; + { + mbedtls_x509_crt_frame const *child; + + ret = mbedtls_x509_crt_frame_acquire( child_crt, &child ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + /* Check time-validity (all certificates) */ + if( mbedtls_x509_time_is_past( &child->valid_to ) ) + *flags |= MBEDTLS_X509_BADCERT_EXPIRED; + if( mbedtls_x509_time_is_future( &child->valid_from ) ) + *flags |= MBEDTLS_X509_BADCERT_FUTURE; + + /* Stop here for trusted roots (but not for trusted EE certs) */ + if( child_is_trusted ) + { + mbedtls_x509_crt_frame_release( child_crt ); + return( 0 ); + } + + self_issued = 0; + if( mbedtls_x509_name_cmp_raw( &child->issuer_raw, + &child->subject_raw, + NULL, NULL ) == 0 ) + { + self_issued = 1; + } + + /* Check signature algorithm: MD & PK algs */ + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + /* Special case: EE certs that are locally trusted */ + if( ver_chain->len == 1 && self_issued && + x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) + { + mbedtls_x509_crt_frame_release( child_crt ); + return( 0 ); + } + +#if defined(MBEDTLS_X509_CRL_PARSE_C) + child_serial = child->serial; +#endif /* MBEDTLS_X509_CRL_PARSE_C */ + + ret = x509_crt_get_sig_info( child, &child_sig ); + mbedtls_x509_crt_frame_release( child_crt ); + + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + } + + /* Look for a parent in trusted CAs or up the chain */ + ret = x509_crt_find_parent( &child_sig, child_crt->next, + trust_ca, &parent_crt, + &parent_is_trusted, &signature_is_good, + ver_chain->len - 1, self_cnt, rs_ctx ); + + x509_crt_free_sig_info( &child_sig ); + } #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS ) @@ -2372,7 +3242,6 @@ find_parent: rs_ctx->in_progress = x509_crt_rs_find_parent; rs_ctx->self_cnt = self_cnt; rs_ctx->ver_chain = *ver_chain; /* struct copy */ - return( ret ); } #else @@ -2380,7 +3249,7 @@ find_parent: #endif /* No parent? We're done here */ - if( parent == NULL ) + if( parent_crt == NULL ) { *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; return( 0 ); @@ -2389,11 +3258,8 @@ find_parent: /* Count intermediate self-issued (not necessarily self-signed) certs. * These can occur with some strategies for key rollover, see [SIRO], * and should be excluded from max_pathlen checks. */ - if( ver_chain->len != 1 && - x509_name_cmp( &child->issuer, &child->subject ) == 0 ) - { + if( ver_chain->len != 1 && self_issued ) self_cnt++; - } /* path_cnt is 0 for the first intermediate CA, * and if parent is trusted it's not an intermediate CA */ @@ -2408,20 +3274,31 @@ find_parent: if( ! signature_is_good ) *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; - /* check size of signing key */ - if( x509_profile_check_key( profile, &parent->pk ) != 0 ) - *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + { + mbedtls_pk_context *parent_pk; + ret = mbedtls_x509_crt_pk_acquire( parent_crt, &parent_pk ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + /* check size of signing key */ + if( x509_profile_check_key( profile, parent_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + mbedtls_x509_crt_pk_release( parent_crt ); + } #if defined(MBEDTLS_X509_CRL_PARSE_C) /* Check trusted CA's CRL for the given crt */ - *flags |= x509_crt_verifycrl( child, parent, ca_crl, profile ); + *flags |= x509_crt_verifycrl( child_serial.p, + child_serial.len, + parent_crt, ca_crl, profile ); #else (void) ca_crl; #endif /* prepare for next iteration */ - child = parent; - parent = NULL; + child_crt = parent_crt; + parent_crt = NULL; child_is_trusted = parent_is_trusted; signature_is_good = 0; } @@ -2430,18 +3307,17 @@ find_parent: /* * Check for CN match */ -static int x509_crt_check_cn( const mbedtls_x509_buf *name, - const char *cn, size_t cn_len ) +static int x509_crt_check_cn( unsigned char const *buf, + size_t buflen, + const char *cn, + size_t cn_len ) { - /* try exact match */ - if( name->len == cn_len && - x509_memcasecmp( cn, name->p, cn_len ) == 0 ) - { + /* Try exact match */ + if( mbedtls_x509_memcasecmp( cn, buf, buflen, cn_len ) == 0 ) return( 0 ); - } /* try wildcard match */ - if( x509_check_wildcard( cn, name ) == 0 ) + if( x509_check_wildcard( cn, cn_len, buf, buflen ) == 0 ) { return( 0 ); } @@ -2449,42 +3325,95 @@ static int x509_crt_check_cn( const mbedtls_x509_buf *name, return( -1 ); } +/* Returns 1 on a match and 0 on a mismatch. + * This is because this function is used as a callback for + * mbedtls_x509_name_cmp_raw(), which continues the name + * traversal as long as the callback returns 0. */ +static int x509_crt_check_name( void *ctx, + mbedtls_x509_buf *oid, + mbedtls_x509_buf *val, + int next_merged ) +{ + char const *cn = (char const*) ctx; + size_t cn_len = strlen( cn ); + ((void) next_merged); + + if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, oid ) == 0 && + x509_crt_check_cn( val->p, val->len, cn, cn_len ) == 0 ) + { + return( 1 ); + } + + return( 0 ); +} + +/* Returns 1 on a match and 0 on a mismatch. + * This is because this function is used as a callback for + * mbedtls_asn1_traverse_sequence_of(), which continues the + * traversal as long as the callback returns 0. */ +static int x509_crt_subject_alt_check_name( void *ctx, + int tag, + unsigned char *data, + size_t data_len ) +{ + char const *cn = (char const*) ctx; + size_t cn_len = strlen( cn ); + ((void) tag); + + if( x509_crt_check_cn( data, data_len, cn, cn_len ) == 0 ) + return( 1 ); + + return( 0 ); +} + /* * Verify the requested CN - only call this if cn is not NULL! */ -static void x509_crt_verify_name( const mbedtls_x509_crt *crt, - const char *cn, - uint32_t *flags ) +static int x509_crt_verify_name( const mbedtls_x509_crt *crt, + const char *cn, + uint32_t *flags ) { - const mbedtls_x509_name *name; - const mbedtls_x509_sequence *cur; - size_t cn_len = strlen( cn ); + int ret; + mbedtls_x509_crt_frame const *frame; - if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); + + if( frame->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) { - for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next ) - { - if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 ) - break; - } + unsigned char *p = + frame->subject_alt_raw.p; + const unsigned char *end = + frame->subject_alt_raw.p + frame->subject_alt_raw.len; - if( cur == NULL ) - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + ret = mbedtls_asn1_traverse_sequence_of( &p, end, + MBEDTLS_ASN1_TAG_CLASS_MASK, + MBEDTLS_ASN1_CONTEXT_SPECIFIC, + MBEDTLS_ASN1_TAG_VALUE_MASK, + 2 /* SubjectAlt DNS */, + x509_crt_subject_alt_check_name, + (void *) cn ); } else { - for( name = &crt->subject; name != NULL; name = name->next ) - { - if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 && - x509_crt_check_cn( &name->val, cn, cn_len ) == 0 ) - { - break; - } - } - - if( name == NULL ) - *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + ret = mbedtls_x509_name_cmp_raw( &frame->subject_raw, + &frame->subject_raw, + x509_crt_check_name, (void *) cn ); } + + mbedtls_x509_crt_frame_release( crt ); + + /* x509_crt_check_name() and x509_crt_subject_alt_check_name() + * return 1 when finding a name component matching `cn`. */ + if( ret == 1 ) + return( 0 ); + + if( ret != 0 ) + ret = MBEDTLS_ERR_X509_FATAL_ERROR; + + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + return( ret ); } /* @@ -2566,7 +3495,6 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, mbedtls_x509_crt_restart_ctx *rs_ctx ) { int ret; - mbedtls_pk_type_t pk_type; mbedtls_x509_crt_verify_chain ver_chain; uint32_t ee_flags; @@ -2582,16 +3510,31 @@ int mbedtls_x509_crt_verify_restartable( mbedtls_x509_crt *crt, /* check name if requested */ if( cn != NULL ) - x509_crt_verify_name( crt, cn, &ee_flags ); + { + ret = x509_crt_verify_name( crt, cn, &ee_flags ); + if( ret != 0 ) + return( ret ); + } - /* Check the type and size of the key */ - pk_type = mbedtls_pk_get_type( &crt->pk ); + { + mbedtls_pk_context *pk; + mbedtls_pk_type_t pk_type; - if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; + ret = mbedtls_x509_crt_pk_acquire( crt, &pk ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_FATAL_ERROR ); - if( x509_profile_check_key( profile, &crt->pk ) != 0 ) - ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + /* Check the type and size of the key */ + pk_type = mbedtls_pk_get_type( pk ); + + if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) + ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + if( x509_profile_check_key( profile, pk ) != 0 ) + ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + mbedtls_x509_crt_pk_release( crt ); + } /* Check the chain */ ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile, @@ -2641,63 +3584,32 @@ void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) /* * Unallocate all certificate data */ + void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) { mbedtls_x509_crt *cert_cur = crt; mbedtls_x509_crt *cert_prv; - mbedtls_x509_name *name_cur; - mbedtls_x509_name *name_prv; - mbedtls_x509_sequence *seq_cur; - mbedtls_x509_sequence *seq_prv; if( crt == NULL ) return; do { + x509_crt_cache_free( cert_cur->cache ); + mbedtls_free( cert_cur->cache ); + +#if !defined(MBEDTLS_X509_ON_DEMAND_PARSING) mbedtls_pk_free( &cert_cur->pk ); #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) mbedtls_free( cert_cur->sig_opts ); #endif - name_cur = cert_cur->issuer.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - name_cur = cert_cur->subject.next; - while( name_cur != NULL ) - { - name_prv = name_cur; - name_cur = name_cur->next; - mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); - mbedtls_free( name_prv ); - } - - seq_cur = cert_cur->ext_key_usage.next; - while( seq_cur != NULL ) - { - seq_prv = seq_cur; - seq_cur = seq_cur->next; - mbedtls_platform_zeroize( seq_prv, - sizeof( mbedtls_x509_sequence ) ); - mbedtls_free( seq_prv ); - } - - seq_cur = cert_cur->subject_alt_names.next; - while( seq_cur != NULL ) - { - seq_prv = seq_cur; - seq_cur = seq_cur->next; - mbedtls_platform_zeroize( seq_prv, - sizeof( mbedtls_x509_sequence ) ); - mbedtls_free( seq_prv ); - } + mbedtls_x509_name_free( cert_cur->issuer.next ); + mbedtls_x509_name_free( cert_cur->subject.next ); + mbedtls_x509_sequence_free( cert_cur->ext_key_usage.next ); + mbedtls_x509_sequence_free( cert_cur->subject_alt_names.next ); +#endif /* !MBEDTLS_X509_ON_DEMAND_PARSING */ if( cert_cur->raw.p != NULL && cert_cur->own_buffer ) { diff --git a/library/x509_csr.c b/library/x509_csr.c index aa519fb93..9b58a86fe 100644 --- a/library/x509_csr.c +++ b/library/x509_csr.c @@ -38,6 +38,7 @@ #if defined(MBEDTLS_X509_CSR_PARSE_C) #include "mbedtls/x509_csr.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/oid.h" #include "mbedtls/platform_util.h" @@ -183,15 +184,17 @@ int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, mbedtls_x509_csr_free( csr ); return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } + p += len; + csr->subject_raw.len = p - csr->subject_raw.p; - if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) + if( ( ret = mbedtls_x509_get_name( csr->subject_raw.p, + csr->subject_raw.len, + &csr->subject ) ) != 0 ) { mbedtls_x509_csr_free( csr ); return( ret ); } - csr->subject_raw.len = p - csr->subject_raw.p; - /* * subjectPKInfo SubjectPublicKeyInfo */ @@ -357,8 +360,8 @@ int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); MBEDTLS_X509_SAFE_SNPRINTF; - ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, - csr->sig_opts ); + ret = mbedtls_x509_sig_alg_gets( p, n, csr->sig_pk, + csr->sig_md, csr->sig_opts ); MBEDTLS_X509_SAFE_SNPRINTF; if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, diff --git a/library/x509write_crt.c b/library/x509write_crt.c index 10497e752..93cd82f7a 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -34,6 +34,7 @@ #if defined(MBEDTLS_X509_CRT_WRITE_C) #include "mbedtls/x509_crt.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/oid.h" #include "mbedtls/asn1write.h" #include "mbedtls/sha1.h" diff --git a/library/x509write_csr.c b/library/x509write_csr.c index d70ba0ed9..85331b163 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -33,6 +33,7 @@ #if defined(MBEDTLS_X509_CSR_WRITE_C) #include "mbedtls/x509_csr.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/oid.h" #include "mbedtls/asn1write.h" #include "mbedtls/platform_util.h" diff --git a/programs/Makefile b/programs/Makefile index 28c747b76..d09949bbf 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -296,6 +296,8 @@ x509/req_app$(EXEXT): x509/req_app.c $(DEP) clean: ifndef WINDOWS rm -f $(APPS) + -rm -f ssl/ssl_pthread_server$(EXEXT) + -rm -f test/cpp_dummy_build$(EXEXT) else del /S /Q /F *.o *.exe endif diff --git a/programs/aes/aescrypt2.c b/programs/aes/aescrypt2.c index bdeac3afc..8242ea7c9 100644 --- a/programs/aes/aescrypt2.c +++ b/programs/aes/aescrypt2.c @@ -80,17 +80,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/aes/crypt_and_hash.c b/programs/aes/crypt_and_hash.c index f58e6166d..a5acf5b8b 100644 --- a/programs/aes/crypt_and_hash.c +++ b/programs/aes/crypt_and_hash.c @@ -82,17 +82,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/hash/generic_sum.c b/programs/hash/generic_sum.c index 4b7fe37be..709a149e0 100644 --- a/programs/hash/generic_sum.c +++ b/programs/hash/generic_sum.c @@ -52,17 +52,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static int generic_wrapper( const mbedtls_md_info_t *md_info, char *filename, unsigned char *sum ) { diff --git a/programs/hash/hello.c b/programs/hash/hello.c index 6046f868c..55a0c7e74 100644 --- a/programs/hash/hello.c +++ b/programs/hash/hello.c @@ -48,17 +48,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( void ) { diff --git a/programs/pkey/dh_client.c b/programs/pkey/dh_client.c index 1dce31aa7..86b260ca0 100644 --- a/programs/pkey/dh_client.c +++ b/programs/pkey/dh_client.c @@ -72,17 +72,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( void ) { diff --git a/programs/pkey/dh_genprime.c b/programs/pkey/dh_genprime.c index cca43ca59..bf5482ed0 100644 --- a/programs/pkey/dh_genprime.c +++ b/programs/pkey/dh_genprime.c @@ -69,17 +69,6 @@ int main( void ) */ #define GENERATOR "4" -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char **argv ) { diff --git a/programs/pkey/dh_server.c b/programs/pkey/dh_server.c index a797e6070..c01177485 100644 --- a/programs/pkey/dh_server.c +++ b/programs/pkey/dh_server.c @@ -72,17 +72,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( void ) { diff --git a/programs/pkey/ecdh_curve25519.c b/programs/pkey/ecdh_curve25519.c index 9267c7ef5..9f849dd29 100644 --- a/programs/pkey/ecdh_curve25519.c +++ b/programs/pkey/ecdh_curve25519.c @@ -53,17 +53,6 @@ int main( void ) #include "mbedtls/ctr_drbg.h" #include "mbedtls/ecdh.h" -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/ecdsa.c b/programs/pkey/ecdsa.c index 4471a201e..b851c3173 100644 --- a/programs/pkey/ecdsa.c +++ b/programs/pkey/ecdsa.c @@ -100,17 +100,6 @@ static void dump_pubkey( const char *title, mbedtls_ecdsa_context *key ) #define dump_pubkey( a, b ) #endif -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/gen_key.c b/programs/pkey/gen_key.c index 35fc1498f..23e4e145c 100644 --- a/programs/pkey/gen_key.c +++ b/programs/pkey/gen_key.c @@ -137,17 +137,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/pkey/key_app.c b/programs/pkey/key_app.c index 0bd61e481..793930991 100644 --- a/programs/pkey/key_app.c +++ b/programs/pkey/key_app.c @@ -64,7 +64,6 @@ " password_file=%%s default: \"\"\n" \ "\n" - #if !defined(MBEDTLS_BIGNUM_C) || \ !defined(MBEDTLS_PK_PARSE_C) || !defined(MBEDTLS_FS_IO) int main( void ) @@ -75,17 +74,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/pkey/key_app_writer.c b/programs/pkey/key_app_writer.c index b81530ceb..60964292b 100644 --- a/programs/pkey/key_app_writer.c +++ b/programs/pkey/key_app_writer.c @@ -98,17 +98,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/pkey/mpi_demo.c b/programs/pkey/mpi_demo.c index 80573c0ed..ecdcd329a 100644 --- a/programs/pkey/mpi_demo.c +++ b/programs/pkey/mpi_demo.c @@ -50,17 +50,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( void ) { diff --git a/programs/pkey/pk_decrypt.c b/programs/pkey/pk_decrypt.c index 978f39ef1..bf425079e 100644 --- a/programs/pkey/pk_decrypt.c +++ b/programs/pkey/pk_decrypt.c @@ -48,7 +48,6 @@ #include #endif - #if !defined(MBEDTLS_BIGNUM_C) || !defined(MBEDTLS_PK_PARSE_C) || \ !defined(MBEDTLS_FS_IO) || !defined(MBEDTLS_ENTROPY_C) || \ !defined(MBEDTLS_CTR_DRBG_C) @@ -61,17 +60,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/pk_encrypt.c b/programs/pkey/pk_encrypt.c index 806c59aae..a32b14761 100644 --- a/programs/pkey/pk_encrypt.c +++ b/programs/pkey/pk_encrypt.c @@ -61,17 +61,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/pk_sign.c b/programs/pkey/pk_sign.c index 7354082f1..47a098a1a 100644 --- a/programs/pkey/pk_sign.c +++ b/programs/pkey/pk_sign.c @@ -60,17 +60,6 @@ int main( void ) #include #include -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/pk_verify.c b/programs/pkey/pk_verify.c index 9fcf029b8..a6bfe3f29 100644 --- a/programs/pkey/pk_verify.c +++ b/programs/pkey/pk_verify.c @@ -56,17 +56,6 @@ int main( void ) #include #include -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { @@ -112,7 +101,6 @@ int main( int argc, char *argv[] ) goto exit; } - i = fread( buf, 1, sizeof(buf), f ); fclose( f ); diff --git a/programs/pkey/rsa_decrypt.c b/programs/pkey/rsa_decrypt.c index dc8a9200d..ff71bd055 100644 --- a/programs/pkey/rsa_decrypt.c +++ b/programs/pkey/rsa_decrypt.c @@ -59,17 +59,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/rsa_encrypt.c b/programs/pkey/rsa_encrypt.c index e9effe806..4a71c15dd 100644 --- a/programs/pkey/rsa_encrypt.c +++ b/programs/pkey/rsa_encrypt.c @@ -59,17 +59,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/rsa_genkey.c b/programs/pkey/rsa_genkey.c index 81867ee9e..d556c1902 100644 --- a/programs/pkey/rsa_genkey.c +++ b/programs/pkey/rsa_genkey.c @@ -64,17 +64,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( void ) { diff --git a/programs/pkey/rsa_sign.c b/programs/pkey/rsa_sign.c index f01487202..9bcd7a627 100644 --- a/programs/pkey/rsa_sign.c +++ b/programs/pkey/rsa_sign.c @@ -56,17 +56,6 @@ int main( void ) #include #include -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/rsa_sign_pss.c b/programs/pkey/rsa_sign_pss.c index 51317457b..42209e27c 100644 --- a/programs/pkey/rsa_sign_pss.c +++ b/programs/pkey/rsa_sign_pss.c @@ -60,17 +60,6 @@ int main( void ) #include #include -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/rsa_verify.c b/programs/pkey/rsa_verify.c index 5d1c0851e..94f0ef9ce 100644 --- a/programs/pkey/rsa_verify.c +++ b/programs/pkey/rsa_verify.c @@ -55,17 +55,6 @@ int main( void ) #include #include -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/pkey/rsa_verify_pss.c b/programs/pkey/rsa_verify_pss.c index 34122ca4f..148cd5110 100644 --- a/programs/pkey/rsa_verify_pss.c +++ b/programs/pkey/rsa_verify_pss.c @@ -60,17 +60,6 @@ int main( void ) #include #include -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { @@ -125,7 +114,6 @@ int main( int argc, char *argv[] ) goto exit; } - i = fread( buf, 1, MBEDTLS_MPI_MAX_SIZE, f ); fclose( f ); diff --git a/programs/random/gen_entropy.c b/programs/random/gen_entropy.c index 3b350ede2..6ae63b725 100644 --- a/programs/random/gen_entropy.c +++ b/programs/random/gen_entropy.c @@ -51,17 +51,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/random/gen_random_ctr_drbg.c b/programs/random/gen_random_ctr_drbg.c index a50402f19..59df34b66 100644 --- a/programs/random/gen_random_ctr_drbg.c +++ b/programs/random/gen_random_ctr_drbg.c @@ -54,17 +54,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/random/gen_random_havege.c b/programs/random/gen_random_havege.c index ef888ff61..5ea52aec9 100644 --- a/programs/random/gen_random_havege.c +++ b/programs/random/gen_random_havege.c @@ -52,17 +52,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/ssl/dtls_client.c b/programs/ssl/dtls_client.c index cd2866abb..cb2851b8c 100644 --- a/programs/ssl/dtls_client.c +++ b/programs/ssl/dtls_client.c @@ -82,17 +82,6 @@ int main( void ) #define DEBUG_LEVEL 0 -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static void my_debug( void *ctx, int level, const char *file, int line, diff --git a/programs/ssl/dtls_server.c b/programs/ssl/dtls_server.c index dd21fbf47..7d19d69e5 100644 --- a/programs/ssl/dtls_server.c +++ b/programs/ssl/dtls_server.c @@ -91,17 +91,6 @@ int main( void ) #define READ_TIMEOUT_MS 10000 /* 5 seconds */ #define DEBUG_LEVEL 0 -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static void my_debug( void *ctx, int level, const char *file, int line, @@ -236,11 +225,11 @@ int main( void ) mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); -#if defined(MBEDTLS_SSL_CACHE_C) +#if defined(MBEDTLS_SSL_CACHE_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) mbedtls_ssl_conf_session_cache( &conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set ); -#endif +#endif /* MBEDTLS_SSL_CACHE_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL ); if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 ) diff --git a/programs/ssl/mini_client.c b/programs/ssl/mini_client.c index ff3612885..4b8140e68 100644 --- a/programs/ssl/mini_client.c +++ b/programs/ssl/mini_client.c @@ -166,17 +166,6 @@ enum exit_codes ssl_write_failed, }; -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( void ) { diff --git a/programs/ssl/query_config.c b/programs/ssl/query_config.c index d45a6634f..419be6bdb 100644 --- a/programs/ssl/query_config.c +++ b/programs/ssl/query_config.c @@ -274,6 +274,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_CHECK_PARAMS */ +#if defined(MBEDTLS_CHECK_PARAMS_ASSERT) + if( strcmp( "MBEDTLS_CHECK_PARAMS_ASSERT", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_CHECK_PARAMS_ASSERT ); + return( 0 ); + } +#endif /* MBEDTLS_CHECK_PARAMS_ASSERT */ + #if defined(MBEDTLS_TIMING_ALT) if( strcmp( "MBEDTLS_TIMING_ALT", config ) == 0 ) { @@ -1410,6 +1418,22 @@ int query_config( const char *config ) } #endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_NO_SESSION_CACHE) + if( strcmp( "MBEDTLS_SSL_NO_SESSION_CACHE", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_NO_SESSION_CACHE ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_NO_SESSION_CACHE */ + +#if defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) + if( strcmp( "MBEDTLS_SSL_NO_SESSION_RESUMPTION", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_NO_SESSION_RESUMPTION ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_NO_SESSION_RESUMPTION */ + #if defined(MBEDTLS_SSL_EXPORT_KEYS) if( strcmp( "MBEDTLS_SSL_EXPORT_KEYS", config ) == 0 ) { @@ -1466,6 +1490,22 @@ int query_config( const char *config ) } #endif /* MBEDTLS_VERSION_FEATURES */ +#if defined(MBEDTLS_X509_ON_DEMAND_PARSING) + if( strcmp( "MBEDTLS_X509_ON_DEMAND_PARSING", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_X509_ON_DEMAND_PARSING ); + return( 0 ); + } +#endif /* MBEDTLS_X509_ON_DEMAND_PARSING */ + +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) + if( strcmp( "MBEDTLS_X509_ALWAYS_FLUSH", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_X509_ALWAYS_FLUSH ); + return( 0 ); + } +#endif /* MBEDTLS_X509_ALWAYS_FLUSH */ + #if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) if( strcmp( "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", config ) == 0 ) { @@ -2578,6 +2618,94 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PLATFORM_GMTIME_R_ALT */ +#if defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) + if( strcmp( "MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ + +#if defined(MBEDTLS_SSL_CONF_AUTHMODE) + if( strcmp( "MBEDTLS_SSL_CONF_AUTHMODE", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_AUTHMODE ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_AUTHMODE */ + +#if defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) + if( strcmp( "MBEDTLS_SSL_CONF_READ_TIMEOUT", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_READ_TIMEOUT ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ + +#if defined(MBEDTLS_SSL_CONF_ENDPOINT) + if( strcmp( "MBEDTLS_SSL_CONF_ENDPOINT", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_ENDPOINT ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_ENDPOINT */ + +#if defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) + if( strcmp( "MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST */ + +#if defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN) + if( strcmp( "MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MIN */ + +#if defined(MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX) + if( strcmp( "MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_HS_TIMEOUT_MAX */ + +#if defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) + if( strcmp( "MBEDTLS_SSL_CONF_ANTI_REPLAY", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_ANTI_REPLAY ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_ANTI_REPLAY */ + +#if defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) + if( strcmp( "MBEDTLS_SSL_CONF_BADMAC_LIMIT", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_BADMAC_LIMIT ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_BADMAC_LIMIT */ + +#if defined(MBEDTLS_SSL_CONF_CID_LEN) + if( strcmp( "MBEDTLS_SSL_CONF_CID_LEN", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_CID_LEN ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_CID_LEN */ + +#if defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) + if( strcmp( "MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ + #if defined(MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET) if( strcmp( "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET", config ) == 0 ) { diff --git a/programs/ssl/ssl_client1.c b/programs/ssl/ssl_client1.c index 375e5e385..28ecc21c0 100644 --- a/programs/ssl/ssl_client1.c +++ b/programs/ssl/ssl_client1.c @@ -72,17 +72,6 @@ int main( void ) #define DEBUG_LEVEL 1 -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static void my_debug( void *ctx, int level, const char *file, int line, diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 982857659..8d7ee0a36 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -293,6 +293,27 @@ int main( void ) #define USAGE_SERIALIZATION "" #endif +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) +#define USAGE_AUTH_MODE \ + " auth_mode=%%s default: (library default: none)\n" \ + " options: none, optional, required\n" +#else +#define USAGE_AUTH_MODE "" +#endif + +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) +#define USAGE_ALLOW_LEGACY_RENEGO " allow_legacy=%%d default: (library default: no)\n" +#else +#define USAGE_ALLOW_LEGACY_RENEGO "" +#endif + +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) +#define USAGE_READ_TIMEOUT \ + " read_timeout=%%d default: 0 ms (no timeout)\n" +#else +#define USAGE_READ_TIMEOUT "" +#endif + #define USAGE \ "\n usage: ssl_client2 param=<>...\n" \ "\n acceptable parameters:\n" \ @@ -311,21 +332,20 @@ int main( void ) " options: 1 (non-blocking), 2 (added delays)\n" \ " event=%%d default: 0 (loop)\n" \ " options: 1 (level-triggered, implies nbio=1),\n" \ - " read_timeout=%%d default: 0 ms (no timeout)\n" \ + USAGE_READ_TIMEOUT \ " max_resend=%%d default: 0 (no resend on timeout)\n" \ "\n" \ USAGE_DTLS \ USAGE_CID \ "\n" \ - " auth_mode=%%s default: (library default: none)\n" \ - " options: none, optional, required\n" \ + USAGE_AUTH_MODE \ USAGE_IO \ "\n" \ USAGE_PSK \ USAGE_ECJPAKE \ USAGE_ECRESTART \ "\n" \ - " allow_legacy=%%d default: (library default: no)\n" \ + USAGE_ALLOW_LEGACY_RENEGO \ USAGE_RENEGO \ " exchanges=%%d default: 1\n" \ " reconnect=%%d number of reconnections using session resumption\n" \ @@ -363,17 +383,6 @@ int main( void ) #define ALPN_LIST_SIZE 10 #define CURVE_LIST_SIZE 20 -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options @@ -908,8 +917,10 @@ int main( int argc, char *argv[] ) if( opt.event < 0 || opt.event > 2 ) goto usage; } +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) else if( strcmp( p, "read_timeout" ) == 0 ) opt.read_timeout = atoi( q ); +#endif else if( strcmp( p, "max_resend" ) == 0 ) { opt.max_resend = atoi( q ); @@ -980,6 +991,7 @@ int main( int argc, char *argv[] ) MBEDTLS_SSL_RENEGOTIATION_ENABLED : MBEDTLS_SSL_RENEGOTIATION_DISABLED; } +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) else if( strcmp( p, "allow_legacy" ) == 0 ) { switch( atoi( q ) ) @@ -996,6 +1008,7 @@ int main( int argc, char *argv[] ) default: goto usage; } } +#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ else if( strcmp( p, "renegotiate" ) == 0 ) { opt.renegotiate = atoi( q ); @@ -1175,6 +1188,7 @@ int main( int argc, char *argv[] ) else goto usage; } +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) else if( strcmp( p, "auth_mode" ) == 0 ) { if( strcmp( q, "none" ) == 0 ) @@ -1186,6 +1200,7 @@ int main( int argc, char *argv[] ) else goto usage; } +#endif else if( strcmp( p, "max_frag_len" ) == 0 ) { if( strcmp( q, "512" ) == 0 ) @@ -1655,7 +1670,9 @@ int main( int argc, char *argv[] ) memset( peer_crt_info, 0, sizeof( peer_crt_info ) ); #endif /* MBEDTLS_X509_CRT_PARSE_C */ -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ + !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) if( opt.cid_enabled == 1 || opt.cid_enabled_renego == 1 ) { if( opt.cid_enabled == 1 && @@ -1680,7 +1697,9 @@ int main( int argc, char *argv[] ) goto exit; } } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID && + !MBEDTLS_SSL_CONF_CID_LEN && + !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ if( opt.auth_mode != DFL_AUTH_MODE ) mbedtls_ssl_conf_authmode( &conf, opt.auth_mode ); @@ -1748,7 +1767,9 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); +#endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) mbedtls_ssl_conf_session_tickets( &conf, opt.tickets ); @@ -1762,8 +1783,10 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_arc4_support( &conf, opt.arc4 ); #endif +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) if( opt.allow_legacy != DFL_ALLOW_LEGACY ) mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy ); +#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation ); #endif @@ -2545,12 +2568,14 @@ reconnect: } } +#if !defined(MBEDTLS_SSL_NO_SESSION_RESUMPTION) if( ( ret = mbedtls_ssl_set_session( &ssl, &saved_session ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ssl_set_session returned -0x%x\n\n", -ret ); goto exit; } +#endif /* !MBEDTLS_SSL_NO_SESSION_RESUMPTION */ if( ( ret = mbedtls_net_connect( &server_fd, opt.server_addr, opt.server_port, diff --git a/programs/ssl/ssl_fork_server.c b/programs/ssl/ssl_fork_server.c index bbe61fd2a..b4a541411 100644 --- a/programs/ssl/ssl_fork_server.c +++ b/programs/ssl/ssl_fork_server.c @@ -89,17 +89,6 @@ int main( void ) #define DEBUG_LEVEL 0 -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static void my_debug( void *ctx, int level, const char *file, int line, diff --git a/programs/ssl/ssl_mail_client.c b/programs/ssl/ssl_mail_client.c index e5d965844..58804684e 100644 --- a/programs/ssl/ssl_mail_client.c +++ b/programs/ssl/ssl_mail_client.c @@ -142,17 +142,6 @@ int main( void ) " force_ciphersuite= default: all enabled\n" \ " acceptable ciphersuite names:\n" -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/ssl/ssl_pthread_server.c b/programs/ssl/ssl_pthread_server.c index 17f4584f0..11298a5aa 100644 --- a/programs/ssl/ssl_pthread_server.c +++ b/programs/ssl/ssl_pthread_server.c @@ -82,17 +82,6 @@ int main( void ) #include "mbedtls/memory_buffer_alloc.h" #endif -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif #define HTTP_RESPONSE \ "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n" \ @@ -464,7 +453,6 @@ int main( void ) mbedtls_printf( " ok\n" ); - /* * 2. Setup the listening TCP socket */ diff --git a/programs/ssl/ssl_server.c b/programs/ssl/ssl_server.c index 97918562a..f5fcfda4a 100644 --- a/programs/ssl/ssl_server.c +++ b/programs/ssl/ssl_server.c @@ -84,17 +84,6 @@ int main( void ) #define DEBUG_LEVEL 0 -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static void my_debug( void *ctx, int level, const char *file, int line, @@ -224,11 +213,11 @@ int main( void ) mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg ); mbedtls_ssl_conf_dbg( &conf, my_debug, stdout ); -#if defined(MBEDTLS_SSL_CACHE_C) +#if defined(MBEDTLS_SSL_CACHE_C) && !defined(MBEDTLS_SSL_NO_SESSION_CACHE) mbedtls_ssl_conf_session_cache( &conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set ); -#endif +#endif /* MBEDTLS_SSL_CACHE_C && !MBEDTLS_SSL_NO_SESSION_CACHE */ mbedtls_ssl_conf_ca_chain( &conf, srvcert.next, NULL ); if( ( ret = mbedtls_ssl_conf_own_cert( &conf, &srvcert, &pkey ) ) != 0 ) diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c index 5d751b6a7..5135ad407 100644 --- a/programs/ssl/ssl_server2.c +++ b/programs/ssl/ssl_server2.c @@ -317,14 +317,16 @@ int main( void ) #define USAGE_COOKIES "" #endif -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) #define USAGE_ANTI_REPLAY \ " anti_replay=0/1 default: (library default: enabled)\n" #else #define USAGE_ANTI_REPLAY "" #endif -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) #define USAGE_BADMAC_LIMIT \ " badmac_limit=%%d default: (library default: disabled)\n" #else @@ -398,6 +400,36 @@ int main( void ) #define USAGE_SERIALIZATION "" #endif +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) +#define USAGE_AUTH_MODE \ + " auth_mode=%%s default: (library default: none)\n" \ + " options: none, optional, required\n" +#else +#define USAGE_AUTH_MODE "" +#endif + +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) +#define USAGE_ALLOW_LEGACY_RENEGO \ + " allow_legacy=%%d default: (library default: no)\n" +#else +#define USAGE_ALLOW_LEGACY_RENEGO "" +#endif + +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) +#define USAGE_READ_TIMEOUT \ + " read_timeout=%%d default: 0 ms (no timeout)\n" +#else +#define USAGE_READ_TIMEOUT "" +#endif + +#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) +#define USAGE_CERT_REQ_CA_LIST \ + " cert_req_ca_list=%%d default: 1 (send ca list)\n" \ + " options: 1 (send ca list), 0 (don't send)\n" +#else +#define USAGE_CERT_REQ_CA_LIST "" +#endif + #define USAGE \ "\n usage: ssl_server2 param=<>...\n" \ "\n acceptable parameters:\n" \ @@ -413,17 +445,15 @@ int main( void ) " options: 1 (non-blocking), 2 (added delays)\n" \ " event=%%d default: 0 (loop)\n" \ " options: 1 (level-triggered, implies nbio=1),\n" \ - " read_timeout=%%d default: 0 ms (no timeout)\n" \ + USAGE_READ_TIMEOUT \ "\n" \ USAGE_DTLS \ USAGE_COOKIES \ USAGE_ANTI_REPLAY \ USAGE_BADMAC_LIMIT \ "\n" \ - " auth_mode=%%s default: (library default: none)\n" \ - " options: none, optional, required\n" \ - " cert_req_ca_list=%%d default: 1 (send ca list)\n" \ - " options: 1 (send ca list), 0 (don't send)\n" \ + USAGE_AUTH_MODE \ + USAGE_CERT_REQ_CA_LIST \ USAGE_IO \ USAGE_SSL_ASYNC \ USAGE_SNI \ @@ -431,7 +461,7 @@ int main( void ) USAGE_PSK \ USAGE_ECJPAKE \ "\n" \ - " allow_legacy=%%d default: (library default: no)\n" \ + USAGE_ALLOW_LEGACY_RENEGO \ USAGE_RENEGO \ " exchanges=%%d default: 1\n" \ "\n" \ @@ -462,7 +492,6 @@ int main( void ) USAGE_SERIALIZATION \ " acceptable ciphersuite names:\n" - #define ALPN_LIST_SIZE 10 #define CURVE_LIST_SIZE 20 @@ -478,17 +507,6 @@ int main( void ) (out_be)[(i) + 7] = (unsigned char)( ( (in_le) >> 0 ) & 0xFF ); \ } -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options @@ -617,6 +635,7 @@ static int my_send( void *ctx, const unsigned char *buf, size_t len ) return( ret ); } +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) /* * Return authmode from string, or -1 on error */ @@ -631,6 +650,7 @@ static int get_auth_mode( const char *s ) return( -1 ); } +#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ /* * Used by sni_parse and psk_parse to handle coma-separated lists @@ -1067,6 +1087,7 @@ static int ssl_async_start( mbedtls_ssl_context *ssl, const unsigned char *input, size_t input_len ) { + int ret; ssl_async_key_context_t *config_data = mbedtls_ssl_conf_get_async_config_data( ssl->conf ); unsigned slot; @@ -1075,9 +1096,17 @@ static int ssl_async_start( mbedtls_ssl_context *ssl, { char dn[100]; - if( mbedtls_x509_dn_gets( dn, sizeof( dn ), &cert->subject ) > 0 ) + mbedtls_x509_name *subject; + + ret = mbedtls_x509_crt_get_subject( cert, &subject ); + if( ret != 0 ) + return( ret ); + + if( mbedtls_x509_dn_gets( dn, sizeof( dn ), subject ) > 0 ) mbedtls_printf( "Async %s callback: looking for DN=%s\n", op_name, dn ); + + mbedtls_x509_name_free( subject ); } /* Look for a private key that matches the public key in cert. @@ -1086,8 +1115,14 @@ static int ssl_async_start( mbedtls_ssl_context *ssl, * public key. */ for( slot = 0; slot < config_data->slots_used; slot++ ) { - if( mbedtls_pk_check_pair( &cert->pk, - config_data->slots[slot].pk ) == 0 ) + mbedtls_pk_context *pk; + int match; + ret = mbedtls_x509_crt_pk_acquire( cert, &pk ); + if( ret != 0 ) + return( ret ); + match = mbedtls_pk_check_pair( pk, config_data->slots[slot].pk ); + mbedtls_x509_crt_pk_release( cert ); + if( match == 0 ) break; } if( slot == config_data->slots_used ) @@ -1557,8 +1592,10 @@ int main( int argc, char *argv[] ) if( opt.event < 0 || opt.event > 2 ) goto usage; } +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) else if( strcmp( p, "read_timeout" ) == 0 ) opt.read_timeout = atoi( q ); +#endif else if( strcmp( p, "buffer_size" ) == 0 ) { opt.buffer_size = atoi( q ); @@ -1657,6 +1694,7 @@ int main( int argc, char *argv[] ) MBEDTLS_SSL_RENEGOTIATION_ENABLED : MBEDTLS_SSL_RENEGOTIATION_DISABLED; } +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) else if( strcmp( p, "allow_legacy" ) == 0 ) { switch( atoi( q ) ) @@ -1673,6 +1711,7 @@ int main( int argc, char *argv[] ) default: goto usage; } } +#endif /* !MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION */ else if( strcmp( p, "renegotiate" ) == 0 ) { opt.renegotiate = atoi( q ); @@ -1785,11 +1824,13 @@ int main( int argc, char *argv[] ) else goto usage; } +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) else if( strcmp( p, "auth_mode" ) == 0 ) { if( ( opt.auth_mode = get_auth_mode( q ) ) < 0 ) goto usage; } +#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ else if( strcmp( p, "cert_req_ca_list" ) == 0 ) { opt.cert_req_ca_list = atoi( q ); @@ -1889,18 +1930,22 @@ int main( int argc, char *argv[] ) if( opt.cookies < -1 || opt.cookies > 1) goto usage; } +#if !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) else if( strcmp( p, "anti_replay" ) == 0 ) { opt.anti_replay = atoi( q ); if( opt.anti_replay < 0 || opt.anti_replay > 1) goto usage; } +#endif /* !MBEDTLS_SSL_CONF_ANTI_REPLAY */ +#if !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) else if( strcmp( p, "badmac_limit" ) == 0 ) { opt.badmac_limit = atoi( q ); if( opt.badmac_limit < 0 ) goto usage; } +#endif /* !MBEDTLS_SSL_CONF_BADMAC_LIMIT */ else if( strcmp( p, "hs_timeout" ) == 0 ) { if( ( p = strchr( q, '-' ) ) == NULL ) @@ -2439,11 +2484,15 @@ int main( int argc, char *argv[] ) } #endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if !defined(MBEDTLS_SSL_CONF_AUTHMODE) if( opt.auth_mode != DFL_AUTH_MODE ) mbedtls_ssl_conf_authmode( &conf, opt.auth_mode ); +#endif /* !MBEDTLS_SSL_CONF_AUTHMODE */ +#if !defined(MBEDTLS_SSL_CONF_CERT_REQ_CA_LIST) if( opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST ) mbedtls_ssl_conf_cert_req_ca_list( &conf, opt.cert_req_ca_list ); +#endif #if defined(MBEDTLS_SSL_PROTO_DTLS) if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX ) @@ -2461,7 +2510,9 @@ int main( int argc, char *argv[] ) }; #endif -#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) +#if defined(MBEDTLS_SSL_DTLS_CONNECTION_ID) && \ + !defined(MBEDTLS_SSL_CONF_CID_LEN) && \ + !defined(MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID) if( opt.cid_enabled == 1 || opt.cid_enabled_renego == 1 ) { if( opt.cid_enabled == 1 && @@ -2486,7 +2537,9 @@ int main( int argc, char *argv[] ) goto exit; } } -#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID */ +#endif /* MBEDTLS_SSL_DTLS_CONNECTION_ID && + !MBEDTLS_SSL_CONF_CID_LEN && + !MBEDTLS_SSL_CONF_IGNORE_UNEXPECTED_CID */ #if defined(MBEDTLS_SSL_TRUNCATED_HMAC) if( opt.trunc_hmac != DFL_TRUNC_HMAC ) @@ -2527,9 +2580,11 @@ int main( int argc, char *argv[] ) if( opt.cache_timeout != -1 ) mbedtls_ssl_cache_set_timeout( &cache, opt.cache_timeout ); +#if !defined(MBEDTLS_SSL_NO_SESSION_CACHE) mbedtls_ssl_conf_session_cache( &conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set ); +#endif /* !MBEDTLS_SSL_NO_SESSION_CACHE */ #endif #if defined(MBEDTLS_SSL_SESSION_TICKETS) @@ -2580,12 +2635,14 @@ int main( int argc, char *argv[] ) ; /* Nothing to do */ } -#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) && \ + !defined(MBEDTLS_SSL_CONF_ANTI_REPLAY) if( opt.anti_replay != DFL_ANTI_REPLAY ) mbedtls_ssl_conf_dtls_anti_replay( &conf, opt.anti_replay ); #endif -#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) && \ + !defined(MBEDTLS_SSL_CONF_BADMAC_LIMIT) if( opt.badmac_limit != DFL_BADMAC_LIMIT ) mbedtls_ssl_conf_dtls_badmac_limit( &conf, opt.badmac_limit ); #endif @@ -2616,8 +2673,10 @@ int main( int argc, char *argv[] ) MBEDTLS_SSL_MINOR_VERSION_3 ); } +#if !defined(MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION) if( opt.allow_legacy != DFL_ALLOW_LEGACY ) mbedtls_ssl_conf_legacy_renegotiation( &conf, opt.allow_legacy ); +#endif #if defined(MBEDTLS_SSL_RENEGOTIATION) mbedtls_ssl_conf_renegotiation( &conf, opt.renegotiation ); @@ -2891,7 +2950,9 @@ reset: goto exit; } +#if !defined(MBEDTLS_SSL_CONF_READ_TIMEOUT) mbedtls_ssl_conf_read_timeout( &conf, opt.read_timeout ); +#endif /* MBEDTLS_SSL_CONF_READ_TIMEOUT */ #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c index e31faafeb..2b8656692 100644 --- a/programs/test/benchmark.c +++ b/programs/test/benchmark.c @@ -258,17 +258,6 @@ typedef struct { rsa, dhm, ecdsa, ecdh; } todo_list; -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif int main( int argc, char *argv[] ) { diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 9d3ea7ec0..727054ee6 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -77,17 +77,6 @@ #include "mbedtls/memory_buffer_alloc.h" #endif -#if defined(MBEDTLS_CHECK_PARAMS) -#include "mbedtls/platform_util.h" -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif static int test_snprintf( size_t n, const char ref_buf[10], int ref_ret ) { diff --git a/programs/util/pem2der.c b/programs/util/pem2der.c index 0cc9d0664..f18493926 100644 --- a/programs/util/pem2der.c +++ b/programs/util/pem2der.c @@ -65,17 +65,6 @@ int main( void ) } #else -#if defined(MBEDTLS_CHECK_PARAMS) -#define mbedtls_exit exit -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/x509/cert_app.c b/programs/x509/cert_app.c index fd527199c..3fc093e5d 100644 --- a/programs/x509/cert_app.c +++ b/programs/x509/cert_app.c @@ -100,17 +100,6 @@ int main( void ) " permissive=%%d default: 0 (disabled)\n" \ "\n" -#if defined(MBEDTLS_CHECK_PARAMS) -#define mbedtls_exit exit -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/x509/cert_req.c b/programs/x509/cert_req.c index b2052ecf1..f3d915750 100644 --- a/programs/x509/cert_req.c +++ b/programs/x509/cert_req.c @@ -107,16 +107,6 @@ int main( void ) " SHA384, SHA512\n" \ "\n" -#if defined(MBEDTLS_CHECK_PARAMS) -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c index 497c3376b..ef40447be 100644 --- a/programs/x509/cert_write.c +++ b/programs/x509/cert_write.c @@ -154,17 +154,6 @@ int main( void ) " object_signing_ca\n" \ "\n" -#if defined(MBEDTLS_CHECK_PARAMS) -#define mbedtls_exit exit -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options @@ -524,6 +513,8 @@ int main( int argc, char *argv[] ) // if( !opt.selfsign && strlen( opt.issuer_crt ) ) { + mbedtls_x509_name *subject; + /* * 1.0.a. Load the certificates */ @@ -538,8 +529,17 @@ int main( int argc, char *argv[] ) goto exit; } + ret = mbedtls_x509_crt_get_subject( &issuer_crt, &subject ); + if( ret != 0 ) + { + mbedtls_strerror( ret, buf, 1024 ); + mbedtls_printf( " failed\n ! mbedtls_x509_crt_get_subject " + "returned -0x%04x - %s\n\n", -ret, buf ); + goto exit; + } + ret = mbedtls_x509_dn_gets( issuer_name, sizeof(issuer_name), - &issuer_crt.subject ); + subject ); if( ret < 0 ) { mbedtls_strerror( ret, buf, 1024 ); @@ -550,6 +550,8 @@ int main( int argc, char *argv[] ) opt.issuer_name = issuer_name; + mbedtls_x509_name_free( subject ); + mbedtls_printf( " ok\n" ); } @@ -627,12 +629,24 @@ int main( int argc, char *argv[] ) // if( strlen( opt.issuer_crt ) ) { - if( mbedtls_pk_check_pair( &issuer_crt.pk, issuer_key ) != 0 ) + mbedtls_pk_context pk; + ret = mbedtls_x509_crt_get_pk( &issuer_crt, &pk ); + if( ret != 0 ) + { + mbedtls_strerror( ret, buf, 1024 ); + mbedtls_printf( " failed\n ! mbedtls_x509_crt_get_pk " + "returned -0x%04x - %s\n\n", -ret, buf ); + goto exit; + } + + if( mbedtls_pk_check_pair( &pk, issuer_key ) != 0 ) { mbedtls_printf( " failed\n ! issuer_key does not match " "issuer certificate\n\n" ); goto exit; } + + mbedtls_pk_free( &pk ); } mbedtls_printf( " ok\n" ); diff --git a/programs/x509/crl_app.c b/programs/x509/crl_app.c index 00b742c65..fc2218800 100644 --- a/programs/x509/crl_app.c +++ b/programs/x509/crl_app.c @@ -63,17 +63,6 @@ int main( void ) " filename=%%s default: crl.pem\n" \ "\n" -#if defined(MBEDTLS_CHECK_PARAMS) -#define mbedtls_exit exit -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/programs/x509/req_app.c b/programs/x509/req_app.c index be421755f..ed8015574 100644 --- a/programs/x509/req_app.c +++ b/programs/x509/req_app.c @@ -63,17 +63,6 @@ int main( void ) " filename=%%s default: cert.req\n" \ "\n" -#if defined(MBEDTLS_CHECK_PARAMS) -#define mbedtls_exit exit -void mbedtls_param_failed( const char *failure_condition, - const char *file, - int line ) -{ - mbedtls_printf( "%s:%i: Input param failed - %s\n", - file, line, failure_condition ); - mbedtls_exit( MBEDTLS_EXIT_FAILURE ); -} -#endif /* * global options diff --git a/scripts/baremetal.sh b/scripts/baremetal.sh index be5fd0488..11b84f857 100755 --- a/scripts/baremetal.sh +++ b/scripts/baremetal.sh @@ -155,7 +155,7 @@ baremetal_build_armc6() echo "Create 32-bit library-only baremetal build (ARMC6, Config: $BAREMETAL_CONFIG)" armc6_ver=$($ARMC6_CC --version | sed -n 's/.*ARM Compiler \([^ ]*\)$/\1/p') - CFLAGS_BAREMETAL="-Os --target=arm-arm-none-eabi -mthumb -mcpu=cortex-m0plus -xc --std=c99" + CFLAGS_BAREMETAL="-Oz --target=arm-arm-none-eabi -mthumb -mcpu=cortex-m0plus -xc --std=c99" if [ $check -ne 0 ]; then CFLAGS_BAREMETAL="$CFLAGS_BAREMETAL -Werror" fi @@ -213,7 +213,8 @@ baremetal_ram_heap() { : ${CLI:=./programs/ssl/ssl_client2} : ${CLI_PARAMS:="dtls=1 cid=1 cid_val=beef"} : ${SRV:=./programs/ssl/ssl_server2} - : ${SRV_PARAMS:="dtls=1 renegotiation=1 auth_mode=required cid=1 cid_val=dead"} + : ${SRV_PARAMS:="dtls=1 cid=1 cid_val=dead"} # renegotiation=1 auth_mode=required implicit + # compile-time hardcoding of configuration : ${VALGRIND:=valgrind} : ${VALGRIND_MASSIF_PARAMS="--time-unit=B --threshold=0.01 --detailed-freq=1"} @@ -271,7 +272,8 @@ baremetal_ram_stack() { : ${CLI:=./programs/ssl/ssl_client2} : ${CLI_PARAMS:="dtls=1"} : ${SRV:=./programs/ssl/ssl_server2} - : ${SRV_PARAMS:="dtls=1 renegotiation=1 auth_mode=required"} + : ${SRV_PARAMS:="dtls=1"} # renegotiation=1 auth_mode=required implicit + # compile-time hardcoding of configuration : ${VALGRIND:=valgrind} : ${VALGRIND_CALLGRIND_PARAMS:="--separate-callers=100"} diff --git a/scripts/config.pl b/scripts/config.pl index c10a3b316..1c7c736c6 100755 --- a/scripts/config.pl +++ b/scripts/config.pl @@ -32,6 +32,8 @@ # MBEDTLS_REMOVE_3DES_CIPHERSUITES # MBEDTLS_SSL_HW_RECORD_ACCEL # MBEDTLS_SSL_PROTO_NO_DTLS +# MBEDTLS_SSL_NO_SESSION_CACHE +# MBEDTLS_SSL_NO_SESSION_RESUMPTION # MBEDTLS_RSA_NO_CRT # MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 # MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION @@ -95,6 +97,8 @@ MBEDTLS_REMOVE_ARC4_CIPHERSUITES MBEDTLS_REMOVE_3DES_CIPHERSUITES MBEDTLS_SSL_HW_RECORD_ACCEL MBEDTLS_SSL_PROTO_NO_TLS +MBEDTLS_SSL_NO_SESSION_CACHE +MBEDTLS_SSL_NO_SESSION_RESUMPTION MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION MBEDTLS_X509_REMOVE_INFO diff --git a/scripts/data_files/vs2010-app-template.vcxproj b/scripts/data_files/vs2010-app-template.vcxproj index fac9812e6..1db7ee42a 100644 --- a/scripts/data_files/vs2010-app-template.vcxproj +++ b/scripts/data_files/vs2010-app-template.vcxproj @@ -53,7 +53,6 @@ false true Unicode - Windows7.1SDK diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a8e7523e5..5938a5fc8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,3 +1,5 @@ +option(LINK_WITH_PTHREAD "Explicitly link mbed TLS library to pthread." OFF) + set(libs mbedtls ) @@ -10,6 +12,10 @@ if(ENABLE_ZLIB_SUPPORT) set(libs ${libs} ${ZLIB_LIBRARIES}) endif(ENABLE_ZLIB_SUPPORT) +if(LINK_WITH_PTHREAD) + set(libs ${libs} pthread) +endif(LINK_WITH_PTHREAD) + find_package(Perl) if(NOT PERL_FOUND) message(FATAL_ERROR "Cannot build test suites without Perl") diff --git a/tests/Makefile b/tests/Makefile index 4ef74177b..0db496320 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,7 +3,7 @@ # To compile with PKCS11: add "-lpkcs11-helper" to LDFLAGS CFLAGS ?= -O2 -WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement -Wno-unused-function -Wno-unused-value +WARNING_CFLAGS ?= -Wall -W -Wdeclaration-after-statement -Wunused LDFLAGS ?= LOCAL_CFLAGS = $(WARNING_CFLAGS) -I../include -D_FILE_OFFSET_BITS=64 @@ -53,11 +53,20 @@ ifdef ZLIB LOCAL_LDFLAGS += -lz endif +# Pthread shared library extension +ifdef PTHREAD +LOCAL_LDFLAGS += -lpthread +endif + # A test application is built for each suites/test_suite_*.data file. # Application name is same as .data file's base name and can be # constructed by stripping path 'suites/' and extension .data. APPS = $(basename $(subst suites/,,$(wildcard suites/test_suite_*.data))) +ifndef PTHREAD +APPS := $(filter-out test_suite_x509parse_pthread, $(APPS)) +endif + # Construct executable name by adding OS specific suffix $(EXEXT). BINARIES := $(addsuffix $(EXEXT),$(APPS)) @@ -136,4 +145,3 @@ $(EMBEDDED_TESTS): embedded_%: suites/$$(firstword $$(subst ., ,$$*)).function s -o ./TESTS/mbedtls/$* generate-target-tests: $(EMBEDDED_TESTS) - diff --git a/tests/compat.sh b/tests/compat.sh index 35983cd7e..0eae1eab3 100755 --- a/tests/compat.sh +++ b/tests/compat.sh @@ -21,7 +21,7 @@ FAILED=0 SKIPPED=0 SRVMEM=0 -# default commands, can be overriden by the environment +# default commands, can be overridden by the environment : ${M_SRV:=../programs/ssl/ssl_server2} : ${M_CLI:=../programs/ssl/ssl_client2} : ${OPENSSL_CMD:=openssl} # OPENSSL would conflict with the build system diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 2f1a1b54e..f626b55c3 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -120,7 +120,7 @@ pre_initialize_variables () { FORCE=0 KEEP_GOING=0 - # Default commands, can be overriden by the environment + # Default commands, can be overridden by the environment : ${OPENSSL:="openssl"} : ${OPENSSL_LEGACY:="$OPENSSL"} : ${OPENSSL_NEXT:="$OPENSSL"} @@ -682,6 +682,21 @@ component_test_rsa_no_crt () { if_build_succeeded tests/compat.sh -t RSA } +component_test_no_resumption () { + msg "build: Default + MBEDTLS_SSL_NO_SESSION_RESUMPTION (ASan build)" # ~ 6 min + scripts/config.pl unset MBEDTLS_SSL_SESSION_TICKETS + scripts/config.pl set MBEDTLS_SSL_NO_SESSION_CACHE + scripts/config.pl set MBEDTLS_SSL_NO_SESSION_RESUMPTION + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + + msg "test: MBEDTLS_SSL_NO_SESSION_RESUMPTION - main suites (inc. selftests) (ASan build)" # ~ 50s + make test + + msg "test: MBEDTLS_SSL_NO_SESSION_RESUMPTION - ssl-opt.sh (ASan build)" # ~ 6 min + if_build_succeeded tests/ssl-opt.sh +} + component_test_small_ssl_out_content_len () { msg "build: small SSL_OUT_CONTENT_LEN (ASan build)" scripts/config.pl set MBEDTLS_SSL_IN_CONTENT_LEN 16384 @@ -728,7 +743,7 @@ component_test_full_cmake_clang () { msg "build: cmake, full config, clang" # ~ 50s scripts/config.pl full scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests - CC=clang cmake -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On . + CC=clang cmake -D LINK_WITH_PTHREAD=1 -D CMAKE_BUILD_TYPE:String=Check -D ENABLE_TESTING=On . make msg "test: main suites (full config)" # ~ 5s @@ -750,7 +765,7 @@ component_build_deprecated () { scripts/config.pl set MBEDTLS_DEPRECATED_WARNING # Build with -O -Wextra to catch a maximum of issues. make CC=gcc CFLAGS='-O -Werror -Wall -Wextra' lib programs - make CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests + make PTHREAD=1 CC=gcc CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests msg "build: make, full config + DEPRECATED_REMOVED, clang -O" # ~ 30s # No cleanup, just tweak the configuration and rebuild @@ -759,7 +774,7 @@ component_build_deprecated () { scripts/config.pl set MBEDTLS_DEPRECATED_REMOVED # Build with -O -Wextra to catch a maximum of issues. make CC=clang CFLAGS='-O -Werror -Wall -Wextra' lib programs - make CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests + make PTHREAD=1 CC=clang CFLAGS='-O -Werror -Wall -Wextra -Wno-unused-function' tests } @@ -794,9 +809,21 @@ component_build_default_make_gcc_and_cxx () { make TEST_CPP=1 } +component_test_check_params_functionality () { + msg "build+test: MBEDTLS_CHECK_PARAMS functionality" + scripts/config.pl full # includes CHECK_PARAMS + # Make MBEDTLS_PARAM_FAILED call mbedtls_param_failed(). + scripts/config.pl unset MBEDTLS_CHECK_PARAMS_ASSERT + scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C + # Only build and run tests. Do not build sample programs, because + # they don't have a mbedtls_param_failed() function. + make CC=gcc CFLAGS='-Werror -O1' lib test +} + component_test_check_params_without_platform () { msg "build+test: MBEDTLS_CHECK_PARAMS without MBEDTLS_PLATFORM_C" scripts/config.pl full # includes CHECK_PARAMS + # Keep MBEDTLS_PARAM_FAILED as assert. scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C scripts/config.pl unset MBEDTLS_PLATFORM_EXIT_ALT @@ -807,15 +834,16 @@ component_test_check_params_without_platform () { scripts/config.pl unset MBEDTLS_PLATFORM_SNPRINTF_ALT scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED scripts/config.pl unset MBEDTLS_PLATFORM_C - make CC=gcc CFLAGS='-Werror -O1' all test + make CC=gcc PTHREAD=1 CFLAGS='-Werror -O1' all test } component_test_check_params_silent () { msg "build+test: MBEDTLS_CHECK_PARAMS with alternative MBEDTLS_PARAM_FAILED()" scripts/config.pl full # includes CHECK_PARAMS scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests + # Set MBEDTLS_PARAM_FAILED to nothing. sed -i 's/.*\(#define MBEDTLS_PARAM_FAILED( cond )\).*/\1/' "$CONFIG_H" - make CC=gcc CFLAGS='-Werror -O1' all test + make CC=gcc PTHREAD=1 CFLAGS='-Werror -O1' all test } component_test_no_platform () { @@ -837,8 +865,8 @@ component_test_no_platform () { scripts/config.pl unset MBEDTLS_FS_IO # Note, _DEFAULT_SOURCE needs to be defined for platforms using glibc version >2.19, # to re-enable platform integration features otherwise disabled in C99 builds - make CC=gcc CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' test + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -std=c99 -pedantic -O0 -D_DEFAULT_SOURCE' lib programs + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' test } component_build_no_std_function () { @@ -847,21 +875,21 @@ component_build_no_std_function () { scripts/config.pl full scripts/config.pl set MBEDTLS_PLATFORM_NO_STD_FUNCTIONS scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' } component_build_no_ssl_srv () { msg "build: full config except ssl_srv.c, make, gcc" # ~ 30s scripts/config.pl full scripts/config.pl unset MBEDTLS_SSL_SRV_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' } component_build_no_ssl_cli () { msg "build: full config except ssl_cli.c, make, gcc" # ~ 30s scripts/config.pl full scripts/config.pl unset MBEDTLS_SSL_CLI_C - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0' + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0' } component_build_no_sockets () { @@ -871,7 +899,7 @@ component_build_no_sockets () { scripts/config.pl full scripts/config.pl unset MBEDTLS_NET_C # getaddrinfo() undeclared, etc. scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY # uses syscall() on GNU/Linux - make CC=gcc CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -O0 -std=c99 -pedantic' lib } component_test_no_max_fragment_length () { @@ -918,6 +946,22 @@ component_test_asan_remove_peer_certificate_no_renego () { if_build_succeeded tests/compat.sh } +component_test_asan_on_demand_parsing_remove_peer_cert () { + msg "build: default config, no peer CRT, on-demand CRT parsing (ASan build)" + scripts/config.pl unset MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + scripts/config.pl set MBEDTLS_X509_ON_DEMAND_PARSING + scripts/config.pl set MBEDTLS_THREADING_C + scripts/config.pl set MBEDTLS_THREADING_PTHREAD + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan -D LINK_WITH_PTHREAD=1 . + make + + msg "test: !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, MBEDTLS_X509_ON_DEMAND_PARSING" + make test + + msg "test: ssl-opt.sh, !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE, MBEDTLS_X509_ON_DEMAND_PARSING" + if_build_succeeded tests/ssl-opt.sh +} + component_test_no_max_fragment_length_small_ssl_out_content_len () { msg "build: no MFL extension, small SSL_OUT_CONTENT_LEN (ASan build)" scripts/config.pl unset MBEDTLS_SSL_MAX_FRAGMENT_LENGTH @@ -1008,7 +1052,10 @@ component_test_m32_o0 () { # Build once with -O0, to compile out the i386 specific inline assembly msg "build: i386, make, gcc -O0 (ASan build)" # ~ 30s scripts/config.pl full - make CC=gcc CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' + scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE + scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C + scripts/config.pl unset MBEDTLS_MEMORY_DEBUG + make CC=gcc PTHREAD=1 CFLAGS='-O0 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32' msg "test: i386, make, gcc -O0 (ASan build)" make test @@ -1027,7 +1074,7 @@ component_test_m32_o1 () { scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C scripts/config.pl unset MBEDTLS_MEMORY_DEBUG - make CC=gcc CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' + make CC=gcc PTHREAD=1 CFLAGS='-O1 -Werror -Wall -Wextra -m32 -fsanitize=address' LDFLAGS='-m32' msg "test: i386, make, gcc -O1 (ASan build)" make test @@ -1042,7 +1089,7 @@ support_test_m32_o1 () { component_test_mx32 () { msg "build: 64-bit ILP32, make, gcc" # ~ 30s scripts/config.pl full - make CC=gcc CFLAGS='-Werror -Wall -Wextra -mx32' + make CC=gcc PTHREAD=1 CFLAGS='-Werror -Wall -Wextra -mx32' LDFLAGS='-mx32' msg "test: 64-bit ILP32, make, gcc" make test @@ -1137,35 +1184,13 @@ component_test_no_x509_info () { component_build_arm_none_eabi_gcc () { msg "build: arm-none-eabi-gcc, make" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_NET_C - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit + scripts/config.pl baremetal make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib } component_build_arm_none_eabi_gcc_no_udbl_division () { msg "build: arm-none-eabi-gcc -DMBEDTLS_NO_UDBL_DIVISION, make" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_NET_C - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit + scripts/config.pl baremetal scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib echo "Checking that software 64-bit division is not required" @@ -1174,18 +1199,7 @@ component_build_arm_none_eabi_gcc_no_udbl_division () { component_build_arm_none_eabi_gcc_no_64bit_multiplication () { msg "build: arm-none-eabi-gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s - scripts/config.pl full - scripts/config.pl unset MBEDTLS_NET_C - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit + scripts/config.pl baremetal scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -O1 -march=armv6-m -mthumb' lib echo "Checking that software 64-bit multiplication is not required" @@ -1194,22 +1208,7 @@ component_build_arm_none_eabi_gcc_no_64bit_multiplication () { component_build_armcc () { msg "build: ARM Compiler 5, make" - scripts/config.pl full - scripts/config.pl unset MBEDTLS_NET_C - scripts/config.pl unset MBEDTLS_TIMING_C - scripts/config.pl unset MBEDTLS_FS_IO - scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED - scripts/config.pl unset MBEDTLS_HAVE_TIME - scripts/config.pl unset MBEDTLS_HAVE_TIME_DATE - scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY - # following things are not in the default config - scripts/config.pl unset MBEDTLS_DEPRECATED_WARNING - scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c - scripts/config.pl unset MBEDTLS_THREADING_PTHREAD - scripts/config.pl unset MBEDTLS_THREADING_C - scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h - scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit - scripts/config.pl unset MBEDTLS_PLATFORM_TIME_ALT # depends on MBEDTLS_HAVE_TIME + scripts/config.pl baremetal make CC="$ARMC5_CC" AR="$ARMC5_AR" WARNING_CFLAGS='--strict --c99' lib make clean diff --git a/tests/scripts/test_zeroize.gdb b/tests/scripts/test_zeroize.gdb index 2f995d2a3..c929c88a0 100644 --- a/tests/scripts/test_zeroize.gdb +++ b/tests/scripts/test_zeroize.gdb @@ -17,7 +17,7 @@ # seem to be a mechanism to reliably check whether the zeroize calls are being # eliminated by compiler optimizations from within the compiled program. The # problem is that a compiler would typically remove what it considers to be -# "unecessary" assignments as part of redundant code elimination. To identify +# "unnecessary" assignments as part of redundant code elimination. To identify # such code, the compilar will create some form dependency graph between # reads and writes to variables (among other situations). It will then use this # data structure to remove redundant code that does not have an impact on the diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 7bcba2438..5f9e2ecdd 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -26,7 +26,7 @@ if cd $( dirname $0 ); then :; else exit 1 fi -# default values, can be overriden by the environment +# default values, can be overridden by the environment : ${P_SRV:=../programs/ssl/ssl_server2} : ${P_CLI:=../programs/ssl/ssl_client2} : ${P_PXY:=../programs/test/udp_proxy} @@ -529,6 +529,34 @@ check_cmdline_param_compat() { fi } +check_cmdline_authmode_compat() { + __VAL="$( get_config_value_or_default "MBEDTLS_SSL_CONF_AUTHMODE" )" + if [ ! -z "$__VAL" ]; then + extract_cmdline_argument "auth_mode" + if [ "$__ARG" = "none" ] && [ "$__VAL" != "0" ]; then + SKIP_NEXT="YES"; + elif [ "$__ARG" = "optional" ] && [ "$__VAL" != "1" ]; then + SKIP_NEXT="YES" + elif [ "$__ARG" = "required" ] && [ "$__VAL" != "2" ]; then + SKIP_NEXT="YES" + fi + fi +} + +check_cmdline_legacy_renego_compat() { + __VAL="$( get_config_value_or_default "MBEDTLS_SSL_CONF_ALLOW_LEGACY_RENEGOTIATION" )" + if [ ! -z "$__VAL" ]; then + extract_cmdline_argument "allow_legacy" + if [ "$__ARG" = "-1" ] && [ "$__VAL" != "2" ]; then + SKIP_NEXT="YES"; + elif [ "$__ARG" = "0" ] && [ "$__VAL" != "0" ]; then + SKIP_NEXT="YES" + elif [ "$__ARG" = "1" ] && [ "$__VAL" != "1" ]; then + SKIP_NEXT="YES" + fi + fi +} + # Go through all options that can be hardcoded at compile-time and # detect whether the command line configures them in a conflicting # way. If so, skip the test. Otherwise, remove the corresponding @@ -544,6 +572,20 @@ check_cmdline_compat() { "MBEDTLS_SSL_CONF_EXTENDED_MASTER_SECRET" check_cmdline_param_compat "enforce_extended_master_secret" \ "MBEDTLS_SSL_CONF_ENFORCE_EXTENDED_MASTER_SECRET" + + # DTLS anti replay protection configuration + check_cmdline_param_compat "anti_replay" \ + "MBEDTLS_SSL_CONF_ANTI_REPLAY" + + # DTLS bad MAC limit + check_cmdline_param_compat "badmac_limit" \ + "MBEDTLS_SSL_CONF_BADMAC_LIMIT" + + # Authentication mode + check_cmdline_authmode_compat + + # Legacy renegotiation + check_cmdline_legacy_renego_compat } # Usage: run_test name [-p proxy_cmd] srv_cmd cli_cmd cli_exit [option [...]] @@ -738,7 +780,7 @@ run_test() { # The filtering in the following two options (-u and -U) do the following # - ignore valgrind output - # - filter out everything but lines right after the pattern occurances + # - filter out everything but lines right after the pattern occurrences # - keep one of each non-unique line # - count how many lines remain # A line with '--' will remain in the result from previous outputs, so the number of lines in the result will be 1 @@ -2130,6 +2172,9 @@ run_test "Fallback SCSV: end of list" \ -s "inapropriate fallback" ## Here the expected response is a valid ServerHello prefix, up to the random. +## Due to the way the clienthello was generated, this currently needs the +## server to have support for session tickets. +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS requires_openssl_with_fallback_scsv run_test "Fallback SCSV: not in list" \ "$P_SRV debug_level=2" \ @@ -2206,6 +2251,8 @@ run_test "CBC Record splitting: TLS 1.0, splitting, nbio" \ # Tests for Session Tickets +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets: basic" \ "$P_SRV debug_level=3 tickets=1" \ "$P_CLI debug_level=3 tickets=1 reconnect=1" \ @@ -2220,6 +2267,8 @@ run_test "Session resume using tickets: basic" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets: cache disabled" \ "$P_SRV debug_level=3 tickets=1 cache_max=0" \ "$P_CLI debug_level=3 tickets=1 reconnect=1" \ @@ -2234,6 +2283,8 @@ run_test "Session resume using tickets: cache disabled" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets: timeout" \ "$P_SRV debug_level=3 tickets=1 cache_max=0 ticket_timeout=1" \ "$P_CLI debug_level=3 tickets=1 reconnect=1 reco_delay=2" \ @@ -2248,6 +2299,8 @@ run_test "Session resume using tickets: timeout" \ -S "a session has been resumed" \ -C "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets: session copy" \ "$P_SRV debug_level=3 tickets=1 cache_max=0" \ "$P_CLI debug_level=3 tickets=1 reconnect=1 reco_mode=0" \ @@ -2262,6 +2315,8 @@ run_test "Session resume using tickets: session copy" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets: openssl server" \ "$O_SRV" \ "$P_CLI debug_level=3 tickets=1 reconnect=1" \ @@ -2271,6 +2326,8 @@ run_test "Session resume using tickets: openssl server" \ -c "parse new session ticket" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets: openssl client" \ "$P_SRV debug_level=3 tickets=1" \ "( $O_CLI -sess_out $SESSION; \ @@ -2285,6 +2342,8 @@ run_test "Session resume using tickets: openssl client" \ # Tests for Session Tickets with DTLS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets, DTLS: basic" \ "$P_SRV debug_level=3 dtls=1 tickets=1" \ "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \ @@ -2299,6 +2358,8 @@ run_test "Session resume using tickets, DTLS: basic" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets, DTLS: cache disabled" \ "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \ "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1" \ @@ -2313,6 +2374,8 @@ run_test "Session resume using tickets, DTLS: cache disabled" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets, DTLS: timeout" \ "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0 ticket_timeout=1" \ "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 reco_delay=2" \ @@ -2327,6 +2390,8 @@ run_test "Session resume using tickets, DTLS: timeout" \ -S "a session has been resumed" \ -C "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets, DTLS: session copy" \ "$P_SRV debug_level=3 dtls=1 tickets=1 cache_max=0" \ "$P_CLI debug_level=3 dtls=1 tickets=1 reconnect=1 reco_mode=0" \ @@ -2341,6 +2406,8 @@ run_test "Session resume using tickets, DTLS: session copy" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets, DTLS: openssl server" \ "$O_SRV -dtls1" \ "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \ @@ -2350,6 +2417,8 @@ run_test "Session resume using tickets, DTLS: openssl server" \ -c "parse new session ticket" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "Session resume using tickets, DTLS: openssl client" \ "$P_SRV dtls=1 debug_level=3 tickets=1" \ "( $O_CLI -dtls1 -sess_out $SESSION; \ @@ -2364,6 +2433,9 @@ run_test "Session resume using tickets, DTLS: openssl client" \ # Tests for Session Resume based on session-ID and cache +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: tickets enabled on client" \ "$P_SRV debug_level=3 tickets=0" \ "$P_CLI debug_level=3 tickets=1 reconnect=1" \ @@ -2378,6 +2450,9 @@ run_test "Session resume using cache: tickets enabled on client" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: tickets enabled on server" \ "$P_SRV debug_level=3 tickets=1" \ "$P_CLI debug_level=3 tickets=0 reconnect=1" \ @@ -2392,6 +2467,8 @@ run_test "Session resume using cache: tickets enabled on server" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: cache_max=0" \ "$P_SRV debug_level=3 tickets=0 cache_max=0" \ "$P_CLI debug_level=3 tickets=0 reconnect=1" \ @@ -2401,6 +2478,8 @@ run_test "Session resume using cache: cache_max=0" \ -S "a session has been resumed" \ -C "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: cache_max=1" \ "$P_SRV debug_level=3 tickets=0 cache_max=1" \ "$P_CLI debug_level=3 tickets=0 reconnect=1" \ @@ -2410,6 +2489,8 @@ run_test "Session resume using cache: cache_max=1" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: timeout > delay" \ "$P_SRV debug_level=3 tickets=0" \ "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=0" \ @@ -2419,6 +2500,8 @@ run_test "Session resume using cache: timeout > delay" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: timeout < delay" \ "$P_SRV debug_level=3 tickets=0 cache_timeout=1" \ "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2" \ @@ -2428,6 +2511,8 @@ run_test "Session resume using cache: timeout < delay" \ -S "a session has been resumed" \ -C "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: no timeout" \ "$P_SRV debug_level=3 tickets=0 cache_timeout=0" \ "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_delay=2" \ @@ -2437,6 +2522,8 @@ run_test "Session resume using cache: no timeout" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: session copy" \ "$P_SRV debug_level=3 tickets=0" \ "$P_CLI debug_level=3 tickets=0 reconnect=1 reco_mode=0" \ @@ -2446,6 +2533,8 @@ run_test "Session resume using cache: session copy" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: openssl client" \ "$P_SRV debug_level=3 tickets=0" \ "( $O_CLI -sess_out $SESSION; \ @@ -2458,6 +2547,8 @@ run_test "Session resume using cache: openssl client" \ -S "session successfully restored from ticket" \ -s "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache: openssl server" \ "$O_SRV" \ "$P_CLI debug_level=3 tickets=0 reconnect=1" \ @@ -2468,6 +2559,9 @@ run_test "Session resume using cache: openssl server" \ # Tests for Session Resume based on session-ID and cache, DTLS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: tickets enabled on client" \ "$P_SRV dtls=1 debug_level=3 tickets=0" \ "$P_CLI dtls=1 debug_level=3 tickets=1 reconnect=1" \ @@ -2482,6 +2576,9 @@ run_test "Session resume using cache, DTLS: tickets enabled on client" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: tickets enabled on server" \ "$P_SRV dtls=1 debug_level=3 tickets=1" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \ @@ -2496,6 +2593,8 @@ run_test "Session resume using cache, DTLS: tickets enabled on server" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: cache_max=0" \ "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=0" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \ @@ -2505,6 +2604,8 @@ run_test "Session resume using cache, DTLS: cache_max=0" \ -S "a session has been resumed" \ -C "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: cache_max=1" \ "$P_SRV dtls=1 debug_level=3 tickets=0 cache_max=1" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \ @@ -2514,6 +2615,8 @@ run_test "Session resume using cache, DTLS: cache_max=1" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: timeout > delay" \ "$P_SRV dtls=1 debug_level=3 tickets=0" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=0" \ @@ -2523,6 +2626,8 @@ run_test "Session resume using cache, DTLS: timeout > delay" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: timeout < delay" \ "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=1" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=2" \ @@ -2532,6 +2637,8 @@ run_test "Session resume using cache, DTLS: timeout < delay" \ -S "a session has been resumed" \ -C "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: no timeout" \ "$P_SRV dtls=1 debug_level=3 tickets=0 cache_timeout=0" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_delay=2" \ @@ -2541,6 +2648,8 @@ run_test "Session resume using cache, DTLS: no timeout" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: session copy" \ "$P_SRV dtls=1 debug_level=3 tickets=0" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1 reco_mode=0" \ @@ -2550,6 +2659,8 @@ run_test "Session resume using cache, DTLS: session copy" \ -s "a session has been resumed" \ -c "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: openssl client" \ "$P_SRV dtls=1 debug_level=3 tickets=0" \ "( $O_CLI -dtls1 -sess_out $SESSION; \ @@ -2562,6 +2673,8 @@ run_test "Session resume using cache, DTLS: openssl client" \ -S "session successfully restored from ticket" \ -s "a session has been resumed" +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "Session resume using cache, DTLS: openssl server" \ "$O_SRV -dtls1" \ "$P_CLI dtls=1 debug_level=3 tickets=0 reconnect=1" \ @@ -3546,7 +3659,7 @@ run_test "Authentication: server max_int chain, client default" \ key_file=data_files/dir-maxpath/09.key" \ "$P_CLI server_name=CA09 ca_file=data_files/dir-maxpath/00.crt" \ 0 \ - -C "X509 - A fatal error occured" + -C "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: server max_int+1 chain, client default" \ @@ -3554,7 +3667,7 @@ run_test "Authentication: server max_int+1 chain, client default" \ key_file=data_files/dir-maxpath/10.key" \ "$P_CLI server_name=CA10 ca_file=data_files/dir-maxpath/00.crt" \ 1 \ - -c "X509 - A fatal error occured" + -c "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: server max_int+1 chain, client optional" \ @@ -3563,7 +3676,7 @@ run_test "Authentication: server max_int+1 chain, client optional" \ "$P_CLI server_name=CA10 ca_file=data_files/dir-maxpath/00.crt \ auth_mode=optional" \ 1 \ - -c "X509 - A fatal error occured" + -c "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: server max_int+1 chain, client none" \ @@ -3572,7 +3685,7 @@ run_test "Authentication: server max_int+1 chain, client none" \ "$P_CLI server_name=CA10 ca_file=data_files/dir-maxpath/00.crt \ auth_mode=none" \ 0 \ - -C "X509 - A fatal error occured" + -C "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: client max_int+1 chain, server default" \ @@ -3580,7 +3693,7 @@ run_test "Authentication: client max_int+1 chain, server default" \ "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \ key_file=data_files/dir-maxpath/10.key" \ 0 \ - -S "X509 - A fatal error occured" + -S "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: client max_int+1 chain, server optional" \ @@ -3588,7 +3701,7 @@ run_test "Authentication: client max_int+1 chain, server optional" \ "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \ key_file=data_files/dir-maxpath/10.key" \ 1 \ - -s "X509 - A fatal error occured" + -s "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: client max_int+1 chain, server required" \ @@ -3596,7 +3709,7 @@ run_test "Authentication: client max_int+1 chain, server required" \ "$P_CLI crt_file=data_files/dir-maxpath/c10.pem \ key_file=data_files/dir-maxpath/10.key" \ 1 \ - -s "X509 - A fatal error occured" + -s "X509 - A fatal error occurred" requires_full_size_output_buffer run_test "Authentication: client max_int chain, server required" \ @@ -3604,7 +3717,7 @@ run_test "Authentication: client max_int chain, server required" \ "$P_CLI crt_file=data_files/dir-maxpath/c09.pem \ key_file=data_files/dir-maxpath/09.key" \ 0 \ - -S "X509 - A fatal error occured" + -S "X509 - A fatal error occurred" # Tests for CA list in CertificateRequest messages @@ -7669,7 +7782,7 @@ run_test "DTLS proxy: reference" \ not_with_valgrind # spurious resend due to timeout run_test "DTLS proxy: duplicate every packet" \ -p "$P_PXY duplicate=1" \ - "$P_SRV dtls=1 dgram_packing=0 debug_level=2" \ + "$P_SRV dtls=1 dgram_packing=0 debug_level=2 anti_replay=1" \ "$P_CLI dtls=1 dgram_packing=0 debug_level=2" \ 0 \ -c "replayed record" \ @@ -7864,6 +7977,8 @@ run_test "DTLS reordering: Buffer out-of-order handshake message on server" \ -S "Injecting buffered CCS message" \ -S "Remember CCS message" +# This needs session tickets; otherwise CCS is the first message in its flight +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS run_test "DTLS reordering: Buffer out-of-order CCS message on client"\ -p "$P_PXY delay_srv=NewSessionTicket" \ "$P_SRV dgram_packing=0 cookies=0 dtls=1 debug_level=2 \ @@ -8006,6 +8121,9 @@ run_test "DTLS proxy: 3d, max handshake, nbio" \ -c "HTTP/1.0 200 OK" client_needs_more_time 4 +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "DTLS proxy: 3d, min handshake, resumption" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \ @@ -8020,6 +8138,9 @@ run_test "DTLS proxy: 3d, min handshake, resumption" \ -c "HTTP/1.0 200 OK" client_needs_more_time 4 +requires_config_disabled MBEDTLS_SSL_NO_SESSION_RESUMPTION +requires_config_enabled MBEDTLS_SSL_SESSION_TICKETS +requires_config_disabled MBEDTLS_SSL_NO_SESSION_CACHE run_test "DTLS proxy: 3d, min handshake, resumption, nbio" \ -p "$P_PXY drop=5 delay=5 duplicate=5" \ "$P_SRV dtls=1 dgram_packing=0 hs_timeout=500-10000 tickets=0 auth_mode=none \ diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function index 1255ff4be..a33cc0345 100644 --- a/tests/suites/helpers.function +++ b/tests/suites/helpers.function @@ -207,7 +207,7 @@ typedef enum #define TEST_VALID_PARAM( TEST ) \ TEST_ASSERT( ( TEST, 1 ) ); -#define assert(a) if( !( a ) ) \ +#define TEST_HELPER_ASSERT(a) if( !( a ) ) \ { \ mbedtls_fprintf( stderr, "Assertion Failed at %s:%d - %s\n", \ __FILE__, __LINE__, #a ); \ @@ -278,7 +278,7 @@ jmp_buf jmp_tmp; /*----------------------------------------------------------------------------*/ /* Helper Functions */ -static void test_fail( const char *test, int line_no, const char* filename ) +void test_fail( const char *test, int line_no, const char* filename ) { test_info.failed = 1; test_info.test = test; @@ -369,11 +369,11 @@ static void close_output( FILE* out_stream ) } #endif /* __unix__ || __APPLE__ __MACH__ */ -static int unhexify( unsigned char *obuf, const char *ibuf ) +int unhexify( unsigned char *obuf, const char *ibuf ) { unsigned char c, c2; int len = strlen( ibuf ) / 2; - assert( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */ + TEST_HELPER_ASSERT( strlen( ibuf ) % 2 == 0 ); /* must be even number of bytes */ while( *ibuf != 0 ) { @@ -385,7 +385,7 @@ static int unhexify( unsigned char *obuf, const char *ibuf ) else if( c >= 'A' && c <= 'F' ) c -= 'A' - 10; else - assert( 0 ); + TEST_HELPER_ASSERT( 0 ); c2 = *ibuf++; if( c2 >= '0' && c2 <= '9' ) @@ -395,7 +395,7 @@ static int unhexify( unsigned char *obuf, const char *ibuf ) else if( c2 >= 'A' && c2 <= 'F' ) c2 -= 'A' - 10; else - assert( 0 ); + TEST_HELPER_ASSERT( 0 ); *obuf++ = ( c << 4 ) | c2; } @@ -403,7 +403,7 @@ static int unhexify( unsigned char *obuf, const char *ibuf ) return len; } -static void hexify( unsigned char *obuf, const unsigned char *ibuf, int len ) +void hexify( unsigned char *obuf, const unsigned char *ibuf, int len ) { unsigned char l, h; @@ -440,7 +440,7 @@ static unsigned char *zero_alloc( size_t len ) size_t actual_len = ( len != 0 ) ? len : 1; p = mbedtls_calloc( 1, actual_len ); - assert( p != NULL ); + TEST_HELPER_ASSERT( p != NULL ); memset( p, 0x00, actual_len ); @@ -457,7 +457,7 @@ static unsigned char *zero_alloc( size_t len ) * * For convenience, dies if allocation fails. */ -static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen ) +unsigned char *unhexify_alloc( const char *ibuf, size_t *olen ) { unsigned char *obuf; @@ -467,7 +467,7 @@ static unsigned char *unhexify_alloc( const char *ibuf, size_t *olen ) return( zero_alloc( *olen ) ); obuf = mbedtls_calloc( 1, *olen ); - assert( obuf != NULL ); + TEST_HELPER_ASSERT( obuf != NULL ); (void) unhexify( obuf, ibuf ); @@ -508,7 +508,7 @@ static int rnd_std_rand( void *rng_state, unsigned char *output, size_t len ) * * rng_state shall be NULL. */ -static int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len ) +int rnd_zero_rand( void *rng_state, unsigned char *output, size_t len ) { if( rng_state != NULL ) rng_state = NULL; @@ -535,7 +535,7 @@ typedef struct * * After the buffer is empty it will return rand(); */ -static int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len ) +int rnd_buffer_rand( void *rng_state, unsigned char *output, size_t len ) { rnd_buf_info *info = (rnd_buf_info *) rng_state; size_t use_len; @@ -581,7 +581,7 @@ typedef struct * * rng_state shall be a pointer to a rnd_pseudo_info structure. */ -static int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len ) +int rnd_pseudo_rand( void *rng_state, unsigned char *output, size_t len ) { rnd_pseudo_info *info = (rnd_pseudo_info *) rng_state; uint32_t i, *k, sum, delta=0x9E3779B9; diff --git a/tests/suites/host_test.function b/tests/suites/host_test.function index 3c4303208..fe6a2bc07 100644 --- a/tests/suites/host_test.function +++ b/tests/suites/host_test.function @@ -179,7 +179,7 @@ static int parse_arguments( char *buf, size_t len, char **params, if( p + 1 < buf + len ) { cur = p + 1; - assert( cnt < params_len ); + TEST_HELPER_ASSERT( cnt < params_len ); params[cnt++] = cur; } *p = '\0'; diff --git a/tests/suites/target_test.function b/tests/suites/target_test.function index 56abf2948..e4c3e30de 100644 --- a/tests/suites/target_test.function +++ b/tests/suites/target_test.function @@ -13,11 +13,11 @@ */ #define INCR_ASSERT(p, start, len, step) do \ { \ - assert( ( p ) >= ( start ) ); \ - assert( sizeof( *( p ) ) == sizeof( *( start ) ) ); \ + TEST_HELPER_ASSERT( ( p ) >= ( start ) ); \ + TEST_HELPER_ASSERT( sizeof( *( p ) ) == sizeof( *( start ) ) ); \ /* <= is checked to support use inside a loop where \ pointer is incremented after reading data. */ \ - assert( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\ + TEST_HELPER_ASSERT( (uint32_t)( ( ( p ) - ( start ) ) + ( step ) ) <= ( len ) );\ ( p ) += ( step ); \ } \ while( 0 ) @@ -127,7 +127,7 @@ uint8_t * receive_data( uint32_t * data_len ) /* Read data length */ *data_len = receive_uint32(); data = (uint8_t *)malloc( *data_len ); - assert( data != NULL ); + TEST_HELPER_ASSERT( data != NULL ); greentea_getc(); // read ';' received after key i.e. *data_len @@ -221,7 +221,7 @@ void ** parse_parameters( uint8_t count, uint8_t * data, uint32_t data_len, hex_count = find_hex_count(count, data, data_len); params = (void **)malloc( sizeof( void *) * ( count + hex_count ) ); - assert( params != NULL ); + TEST_HELPER_ASSERT( params != NULL ); cur = params; p = data; @@ -360,7 +360,7 @@ int execute_tests( int args, const char ** argv ) { /* Read dependency count */ count = *p; - assert( count < data_len ); + TEST_HELPER_ASSERT( count < data_len ); INCR_ASSERT( p, data, data_len, sizeof( uint8_t ) ); ret = verify_dependencies( count, p ); if ( ret != DEPENDENCY_SUPPORTED ) diff --git a/tests/suites/test_suite_ccm.data b/tests/suites/test_suite_ccm.data index ac9c565da..46c172bbb 100644 --- a/tests/suites/test_suite_ccm.data +++ b/tests/suites/test_suite_ccm.data @@ -41,7 +41,7 @@ ccm_lengths:5:10:5:18:MBEDTLS_ERR_CCM_BAD_INPUT CCM lengths #6 tag length not even ccm_lengths:5:10:5:7:MBEDTLS_ERR_CCM_BAD_INPUT -CCM lenghts #7 AD too long (2^16 - 2^8 + 1) +CCM lengths #7 AD too long (2^16 - 2^8 + 1) depends_on:!MBEDTLS_CCM_ALT ccm_lengths:5:10:65281:8:MBEDTLS_ERR_CCM_BAD_INPUT diff --git a/tests/suites/test_suite_ecdh.function b/tests/suites/test_suite_ecdh.function index 9a9cf5f7f..1a33d8175 100644 --- a/tests/suites/test_suite_ecdh.function +++ b/tests/suites/test_suite_ecdh.function @@ -387,7 +387,7 @@ void ecdh_restart( int id, char *dA_str, char *dB_str, char *z_str, mbedtls_ecdh_enable_restart( &cli ); } - /* server writes its paramaters */ + /* server writes its parameters */ memset( buf, 0x00, sizeof( buf ) ); len = 0; diff --git a/tests/suites/test_suite_entropy.function b/tests/suites/test_suite_entropy.function index 0b1cfe80d..5a41b9a52 100644 --- a/tests/suites/test_suite_entropy.function +++ b/tests/suites/test_suite_entropy.function @@ -48,7 +48,7 @@ static int entropy_dummy_source( void *data, unsigned char *output, * This might break memory checks in the future if sources need 'free-ing' then * as well. */ -static void entropy_clear_sources( mbedtls_entropy_context *ctx ) +void entropy_clear_sources( mbedtls_entropy_context *ctx ) { ctx->source_count = 0; } @@ -58,7 +58,7 @@ static void entropy_clear_sources( mbedtls_entropy_context *ctx ) */ static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE]; -static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len ) +int buffer_nv_seed_read( unsigned char *buf, size_t buf_len ) { if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE ) return( -1 ); @@ -67,7 +67,7 @@ static int buffer_nv_seed_read( unsigned char *buf, size_t buf_len ) return( 0 ); } -static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len ) +int buffer_nv_seed_write( unsigned char *buf, size_t buf_len ) { if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE ) return( -1 ); @@ -79,7 +79,7 @@ static int buffer_nv_seed_write( unsigned char *buf, size_t buf_len ) /* * NV seed read/write helpers that fill the base seedfile */ -static int write_nv_seed( unsigned char *buf, size_t buf_len ) +int write_nv_seed( unsigned char *buf, size_t buf_len ) { FILE *f; @@ -98,7 +98,7 @@ static int write_nv_seed( unsigned char *buf, size_t buf_len ) return( 0 ); } -static int read_nv_seed( unsigned char *buf, size_t buf_len ) +int read_nv_seed( unsigned char *buf, size_t buf_len ) { FILE *f; diff --git a/tests/suites/test_suite_nist_kw.function b/tests/suites/test_suite_nist_kw.function index ae3ef8062..f1acde91a 100644 --- a/tests/suites/test_suite_nist_kw.function +++ b/tests/suites/test_suite_nist_kw.function @@ -30,7 +30,7 @@ void mbedtls_nist_kw_mix_contexts( ) memset( key, 0, sizeof( key ) ); /* - * 1. Check wrap and unwrap with two seperate contexts + * 1. Check wrap and unwrap with two separate contexts */ mbedtls_nist_kw_init( &ctx1 ); mbedtls_nist_kw_init( &ctx2 ); diff --git a/tests/suites/test_suite_rsa.data b/tests/suites/test_suite_rsa.data index 5f49ad671..953b1ff92 100644 --- a/tests/suites/test_suite_rsa.data +++ b/tests/suites/test_suite_rsa.data @@ -478,7 +478,7 @@ mbedtls_rsa_import:16:"":16:"e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bb RSA Import (N,-,-,D,E) mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":0:1:0:0 -RSA Import (N,-,-,D,E), succesive +RSA Import (N,-,-,D,E), successive mbedtls_rsa_import:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1:0:0 RSA Import (N,P,Q,-,E) @@ -565,7 +565,7 @@ mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7 RSA Export (N,-,-,D,E) mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:0 -RSA Export (N,-,-,D,E), succesive +RSA Export (N,-,-,D,E), successive mbedtls_rsa_export:16:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":16:"":16:"":16:"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":16:"3":1:1 RSA Export (N,P,Q,-,E) @@ -586,7 +586,7 @@ mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f RSA Export Raw (N,-,-,D,E) mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:0 -RSA Export Raw (N,-,-,D,E), succesive +RSA Export Raw (N,-,-,D,E), successive mbedtls_rsa_export_raw:"b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f":"":"":"77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB":"03":1:1 RSA Export Raw (N,P,Q,-,E) diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index 40fc9237b..cd1cee461 100644 --- a/tests/suites/test_suite_version.data +++ b/tests/suites/test_suite_version.data @@ -1,8 +1,8 @@ Check compiletime library version -check_compiletime_version:"2.16.1" +check_compiletime_version:"2.16.2" Check runtime library version -check_runtime_version:"2.16.1" +check_runtime_version:"2.16.2" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data index f8d787533..6536cc9c7 100644 --- a/tests/suites/test_suite_x509parse.data +++ b/tests/suites/test_suite_x509parse.data @@ -935,6 +935,10 @@ X509 Parse Selftest depends_on:MBEDTLS_SHA1_C:MBEDTLS_PEM_PARSE_C:MBEDTLS_CERTS_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15 x509_selftest: +X509 nested acquire +depends_on:MBEDTLS_RSA_C:MBEDTLS_SHA256_C +x509_nested_acquire:"308196308180a0030201008204deadbeef300d06092a864886f70d01010b0500300c310a30080600130454657374301c170c303930313031303030303030170c303931323331323335393539300c310a30080600130454657374302a300d06092a864886f70d010101050003190030160210ffffffffffffffffffffffffffffffff0202ffff300d06092a864886f70d01010b0500030200ff" + X509 CRT ASN1 (Empty Certificate) x509parse_crt:"":"":MBEDTLS_ERR_X509_INVALID_FORMAT diff --git a/tests/suites/test_suite_x509parse.function b/tests/suites/test_suite_x509parse.function index c9fe63f09..25b0d7f8f 100644 --- a/tests/suites/test_suite_x509parse.function +++ b/tests/suites/test_suite_x509parse.function @@ -4,6 +4,7 @@ #include "mbedtls/x509_crt.h" #include "mbedtls/x509_crl.h" #include "mbedtls/x509_csr.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/pem.h" #include "mbedtls/oid.h" #include "mbedtls/base64.h" @@ -142,25 +143,48 @@ int verify_print( void *data, mbedtls_x509_crt *crt, int certificate_depth, uint verify_print_context *ctx = (verify_print_context *) data; char *p = ctx->p; size_t n = ctx->buf + sizeof( ctx->buf ) - ctx->p; + mbedtls_x509_crt_frame const *frame; + mbedtls_x509_name *subject; ((void) flags); - ret = mbedtls_snprintf( p, n, "depth %d - serial ", certificate_depth ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_crt_get_subject( crt, &subject ); + if( ret != 0 ) + return( ret ); - ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_crt_frame_acquire( crt, &frame ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_snprintf( p, n, "depth %d - serial ", certificate_depth ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + + { + mbedtls_x509_buf serial; + serial.p = frame->serial.p; + serial.len = frame->serial.len; + ret = mbedtls_x509_serial_gets( p, n, &serial ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; + } ret = mbedtls_snprintf( p, n, " - subject " ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; - ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); - MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, subject ); + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; ret = mbedtls_snprintf( p, n, " - flags 0x%08x\n", *flags ); - MBEDTLS_X509_SAFE_SNPRINTF; + MBEDTLS_X509_SAFE_SNPRINTF_WITH_CLEANUP; ctx->p = p; +cleanup: + + mbedtls_x509_name_free( subject ); + mbedtls_x509_crt_frame_release( crt ); + + if( ret < 0 ) + return( ret ); + return( 0 ); } #endif /* MBEDTLS_X509_CRT_PARSE_C */ @@ -428,15 +452,19 @@ void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str ) mbedtls_x509_crt crt; char buf[2000]; int res = 0; + mbedtls_x509_name *subject = NULL, *issuer = NULL; mbedtls_x509_crt_init( &crt ); memset( buf, 0, 2000 ); TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_get_subject( &crt, &subject ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_get_issuer( &crt, &issuer ) == 0 ); + if( strcmp( entity, "subject" ) == 0 ) - res = mbedtls_x509_dn_gets( buf, 2000, &crt.subject ); + res = mbedtls_x509_dn_gets( buf, 2000, subject ); else if( strcmp( entity, "issuer" ) == 0 ) - res = mbedtls_x509_dn_gets( buf, 2000, &crt.issuer ); + res = mbedtls_x509_dn_gets( buf, 2000, issuer ); else TEST_ASSERT( "Unknown entity" == 0 ); @@ -446,6 +474,8 @@ void mbedtls_x509_dn_gets( char * crt_file, char * entity, char * result_str ) TEST_ASSERT( strcmp( buf, result_str ) == 0 ); exit: + mbedtls_x509_name_free( issuer ); + mbedtls_x509_name_free( subject ); mbedtls_x509_crt_free( &crt ); } /* END_CASE */ @@ -453,16 +483,18 @@ exit: /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */ void mbedtls_x509_time_is_past( char * crt_file, char * entity, int result ) { - mbedtls_x509_crt crt; + mbedtls_x509_crt crt; + mbedtls_x509_crt_frame frame; mbedtls_x509_crt_init( &crt ); TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_get_frame( &crt, &frame ) == 0 ); if( strcmp( entity, "valid_from" ) == 0 ) - TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_from ) == result ); + TEST_ASSERT( mbedtls_x509_time_is_past( &frame.valid_from ) == result ); else if( strcmp( entity, "valid_to" ) == 0 ) - TEST_ASSERT( mbedtls_x509_time_is_past( &crt.valid_to ) == result ); + TEST_ASSERT( mbedtls_x509_time_is_past( &frame.valid_to ) == result ); else TEST_ASSERT( "Unknown entity" == 0 ); @@ -474,16 +506,18 @@ exit: /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_X509_CRT_PARSE_C */ void mbedtls_x509_time_is_future( char * crt_file, char * entity, int result ) { - mbedtls_x509_crt crt; + mbedtls_x509_crt crt; + mbedtls_x509_crt_frame frame; mbedtls_x509_crt_init( &crt ); TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_get_frame( &crt, &frame ) == 0 ); if( strcmp( entity, "valid_from" ) == 0 ) - TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_from ) == result ); + TEST_ASSERT( mbedtls_x509_time_is_future( &frame.valid_from ) == result ); else if( strcmp( entity, "valid_to" ) == 0 ) - TEST_ASSERT( mbedtls_x509_time_is_future( &crt.valid_to ) == result ); + TEST_ASSERT( mbedtls_x509_time_is_future( &frame.valid_to ) == result ); else TEST_ASSERT( "Unknown entity" == 0 ); @@ -563,6 +597,99 @@ exit: } /* END_CASE */ +/* BEGIN_CASE depends_on:MBEDTLS_X509_CRT_PARSE_C */ +void x509_nested_acquire( data_t * buf ) +{ + /* This tests exercises the behavior of the library when + * facing nested calls to mbedtls_x509_crt_xxx_acquire(). + * This is allowed if !MBEDTLS_X509_ALWAYS_FLUSH or + * MBEDTLS_THREADING_C, but forbidden otherwise. */ + + mbedtls_x509_crt crt; + mbedtls_x509_crt_init( &crt ); + TEST_ASSERT( mbedtls_x509_crt_parse_der( &crt, buf->x, buf->len ) == 0 ); + + /* Nested aquire for CRT frames */ + { + int ret; + mbedtls_x509_crt_frame const *frame1; + mbedtls_x509_crt_frame const *frame2; + + /* Perform a (hopefully) innocent acquire-release pair first. */ + + TEST_ASSERT( mbedtls_x509_crt_frame_acquire( &crt, &frame1 ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_frame_release( &crt ) == 0 ); + + /* Perform two nested acquire calls. */ + + TEST_ASSERT( mbedtls_x509_crt_frame_acquire( &crt, &frame1 ) == 0 ); + + ret = mbedtls_x509_crt_frame_acquire( &crt, &frame2 ); +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ + !defined(MBEDTLS_THREADING_C) + TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR ); +#else + TEST_ASSERT( ret == 0 ); + TEST_ASSERT( mbedtls_x509_crt_frame_release( &crt ) == 0 ); +#endif + + TEST_ASSERT( mbedtls_x509_crt_frame_release( &crt ) == 0 ); + + ret = mbedtls_x509_crt_frame_release( &crt ); + + /* In contexts which use resource counting, we expect an + * error on an attempted release() without prior acquire(). */ +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ + !defined(MBEDTLS_THREADING_C) + TEST_ASSERT( ret == 0 ); +#else + TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR ); +#endif + } + + /* Nested aquire for PK contexts */ + { + int ret; + mbedtls_pk_context *pk1; + mbedtls_pk_context *pk2; + + /* Perform a (hopefully) innocent acquire-release pair first. */ + + TEST_ASSERT( mbedtls_x509_crt_pk_acquire( &crt, &pk1 ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_pk_release( &crt ) == 0 ); + + /* Perform two nested acquire calls. */ + + TEST_ASSERT( mbedtls_x509_crt_pk_acquire( &crt, &pk1 ) == 0 ); + + ret = mbedtls_x509_crt_pk_acquire( &crt, &pk2 ); +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ + !defined(MBEDTLS_THREADING_C) + TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR ); +#else + TEST_ASSERT( ret == 0 ); + TEST_ASSERT( mbedtls_x509_crt_pk_release( &crt ) == 0 ); +#endif + + TEST_ASSERT( mbedtls_x509_crt_pk_release( &crt ) == 0 ); + + ret = mbedtls_x509_crt_pk_release( &crt ); + + /* In contexts which use resource counting, we expect an + * error on an attempted release() without prior acquire(). */ +#if defined(MBEDTLS_X509_ALWAYS_FLUSH) && \ + !defined(MBEDTLS_THREADING_C) + TEST_ASSERT( ret == 0 ); +#else + TEST_ASSERT( ret == MBEDTLS_ERR_X509_FATAL_ERROR ); +#endif + } + +exit: + mbedtls_x509_crt_free( &crt ); +} +/* END_CASE */ + /* BEGIN_CASE depends_on:MBEDTLS_X509_CRL_PARSE_C:!MBEDTLS_X509_REMOVE_INFO */ void x509parse_crl( data_t * buf, char * result_str, int result ) { diff --git a/tests/suites/test_suite_x509parse_pthread.data b/tests/suites/test_suite_x509parse_pthread.data new file mode 100644 index 000000000..7940b7f57 --- /dev/null +++ b/tests/suites/test_suite_x509parse_pthread.data @@ -0,0 +1,19 @@ +X509 CRT concurrent verification #1 (RSA cert, RSA CA) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C +x509_verify_thread:"data_files/server1.crt":"data_files/test-ca.crt":0:0:25:50 + +X509 CRT concurrent verification #2 (EC cert, RSA CA) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP192R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_SHA1_C +x509_verify_thread:"data_files/server3.crt":"data_files/test-ca.crt":0:0:25:50 + +X509 CRT concurrent verification #3 (RSA cert, EC CA) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_ECP_DP_SECP384R1_ENABLED +x509_verify_thread:"data_files/server4.crt":"data_files/test-ca2.crt":0:0:25:50 + +X509 CRT concurrent verification #4 (EC cert, EC CA) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_SHA256_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECP_DP_SECP384R1_ENABLED +x509_verify_thread:"data_files/server5.crt":"data_files/test-ca2.crt":0:0:25:50 + +X509 CRT concurrent verification #5 (RSA cert, RSA CA, RSASSA-PSS) +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_X509_RSASSA_PSS_SUPPORT:MBEDTLS_SHA1_C +x509_verify_thread:"data_files/server9-with-ca.crt":"data_files/test-ca.crt":0:0:25:50 diff --git a/tests/suites/test_suite_x509parse_pthread.function b/tests/suites/test_suite_x509parse_pthread.function new file mode 100644 index 000000000..2728e9617 --- /dev/null +++ b/tests/suites/test_suite_x509parse_pthread.function @@ -0,0 +1,125 @@ +/* BEGIN_HEADER */ +#include "mbedtls/bignum.h" +#include "mbedtls/x509.h" +#include "mbedtls/x509_crt.h" +#include "mbedtls/x509_crl.h" +#include "mbedtls/x509_csr.h" +#include "mbedtls/x509_internal.h" +#include "mbedtls/pem.h" +#include "mbedtls/oid.h" +#include "mbedtls/base64.h" +#include "string.h" + +/* Profile for backward compatibility. Allows SHA-1, unlike the default + profile. */ +const mbedtls_x509_crt_profile compat_profile = +{ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 1024, +}; + +typedef struct +{ + mbedtls_x509_crt *crt; + mbedtls_x509_crt *ca; + uint32_t expected_flags; + unsigned id; + int expected_result; + int iter_total; + int result; +} x509_verify_thread_ctx; + +void* x509_verify_thread_worker( void *p ) +{ + unsigned iter_cnt; + x509_verify_thread_ctx *ctx = (x509_verify_thread_ctx *) p; + + for( iter_cnt=0; iter_cnt < (unsigned) ctx->iter_total; iter_cnt++ ) + { + uint32_t flags; + int res; + + res = mbedtls_x509_crt_verify_with_profile( ctx->crt, ctx->ca, + NULL, &compat_profile, + NULL, &flags, NULL, NULL ); + if( res != ctx->expected_result || + flags != ctx->expected_flags ) + { + ctx->result = 1; + pthread_exit( NULL ); + } + } + + ctx->result = 0; + pthread_exit( NULL ); + return( NULL ); +} +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_THREADING_PTHREAD:MBEDTLS_X509_CRT_PARSE_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ +void x509_verify_thread( char *crt_file, char *ca_file, + int result, int flags_result, + int thread_total, + int iterations_per_thread ) +{ + x509_verify_thread_ctx *thread_ctx; + pthread_t *threads; + int cur_thread; + + mbedtls_x509_crt crt; + mbedtls_x509_crt ca; + +#if defined(MBEDTLS_USE_PSA_CRYPTO) + TEST_ASSERT( psa_crypto_init() == 0 ); +#endif + + mbedtls_x509_crt_init( &crt ); + mbedtls_x509_crt_init( &ca ); + threads = mbedtls_calloc( thread_total, sizeof( pthread_t ) ); + thread_ctx = mbedtls_calloc( thread_total, sizeof( x509_verify_thread_ctx ) ); + + TEST_ASSERT( mbedtls_x509_crt_parse_file( &crt, crt_file ) == 0 ); + TEST_ASSERT( mbedtls_x509_crt_parse_file( &ca, ca_file ) == 0 ); + TEST_ASSERT( threads != NULL ); + + /* Start all verify threads */ + for( cur_thread = 0; cur_thread < thread_total; cur_thread++ ) + { + thread_ctx[ cur_thread ].id = (unsigned) cur_thread; + thread_ctx[ cur_thread ].ca = &ca; + thread_ctx[ cur_thread ].crt = &crt; + thread_ctx[ cur_thread ].expected_result = result; + thread_ctx[ cur_thread ].expected_flags = flags_result; + thread_ctx[ cur_thread ].iter_total = iterations_per_thread; + TEST_ASSERT( pthread_create( &threads[ cur_thread ], NULL, + &x509_verify_thread_worker, + &thread_ctx[ cur_thread ] ) == 0 ); + } + + /* Wait for all threads to complete */ + for( cur_thread = 0; cur_thread < thread_total; cur_thread++ ) + TEST_ASSERT( pthread_join( threads[ cur_thread ], NULL ) == 0 ); + + /* Check their results */ + for( cur_thread = 0; cur_thread < thread_total; cur_thread++ ) + TEST_ASSERT( thread_ctx[ cur_thread ].result == 0 ); + +exit: + mbedtls_free( threads ); + mbedtls_free( thread_ctx ); + mbedtls_x509_crt_free( &crt ); + mbedtls_x509_crt_free( &ca ); +} +/* END_CASE */ diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function index 535807e3a..923716594 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -2,6 +2,7 @@ #include "mbedtls/bignum.h" #include "mbedtls/x509_crt.h" #include "mbedtls/x509_csr.h" +#include "mbedtls/x509_internal.h" #include "mbedtls/pem.h" #include "mbedtls/oid.h" #include "mbedtls/rsa.h" @@ -216,7 +217,7 @@ void mbedtls_x509_string_to_names( char * name, char * parsed_name, int result ) { int ret; - size_t len = 0; + size_t len; mbedtls_asn1_named_data *names = NULL; mbedtls_x509_name parsed, *parsed_cur, *parsed_prv; unsigned char buf[1024], out[1024], *c; @@ -234,10 +235,9 @@ void mbedtls_x509_string_to_names( char * name, char * parsed_name, int result ret = mbedtls_x509_write_names( &c, buf, names ); TEST_ASSERT( ret > 0 ); + len = (size_t) ret; - TEST_ASSERT( mbedtls_asn1_get_tag( &c, buf + sizeof( buf ), &len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) == 0 ); - TEST_ASSERT( mbedtls_x509_get_name( &c, buf + sizeof( buf ), &parsed ) == 0 ); + TEST_ASSERT( mbedtls_x509_get_name( c, len, &parsed ) == 0 ); ret = mbedtls_x509_dn_gets( (char *) out, sizeof( out ), &parsed ); TEST_ASSERT( ret > 0 ); diff --git a/visualc/VS2010/aescrypt2.vcxproj b/visualc/VS2010/aescrypt2.vcxproj index db387f979..63a124aee 100644 --- a/visualc/VS2010/aescrypt2.vcxproj +++ b/visualc/VS2010/aescrypt2.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/benchmark.vcxproj b/visualc/VS2010/benchmark.vcxproj index 934c84438..ffbd1ad4d 100644 --- a/visualc/VS2010/benchmark.vcxproj +++ b/visualc/VS2010/benchmark.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/cert_app.vcxproj b/visualc/VS2010/cert_app.vcxproj index fef0efe6d..6f1c46eeb 100644 --- a/visualc/VS2010/cert_app.vcxproj +++ b/visualc/VS2010/cert_app.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/cert_req.vcxproj b/visualc/VS2010/cert_req.vcxproj index 7d8694bfe..1e7edd025 100644 --- a/visualc/VS2010/cert_req.vcxproj +++ b/visualc/VS2010/cert_req.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/cert_write.vcxproj b/visualc/VS2010/cert_write.vcxproj index 8891d8aef..bed8728e4 100644 --- a/visualc/VS2010/cert_write.vcxproj +++ b/visualc/VS2010/cert_write.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/crl_app.vcxproj b/visualc/VS2010/crl_app.vcxproj index c51caef54..9fbd408a9 100644 --- a/visualc/VS2010/crl_app.vcxproj +++ b/visualc/VS2010/crl_app.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/crypt_and_hash.vcxproj b/visualc/VS2010/crypt_and_hash.vcxproj index 99199d965..fb7ef77d1 100644 --- a/visualc/VS2010/crypt_and_hash.vcxproj +++ b/visualc/VS2010/crypt_and_hash.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/dh_client.vcxproj b/visualc/VS2010/dh_client.vcxproj index b2fae8093..a0990e1d5 100644 --- a/visualc/VS2010/dh_client.vcxproj +++ b/visualc/VS2010/dh_client.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/dh_genprime.vcxproj b/visualc/VS2010/dh_genprime.vcxproj index d9c19009a..fdd6c6fdf 100644 --- a/visualc/VS2010/dh_genprime.vcxproj +++ b/visualc/VS2010/dh_genprime.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/dh_server.vcxproj b/visualc/VS2010/dh_server.vcxproj index 6f87cb8b0..d1a73453b 100644 --- a/visualc/VS2010/dh_server.vcxproj +++ b/visualc/VS2010/dh_server.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/dtls_client.vcxproj b/visualc/VS2010/dtls_client.vcxproj index 60715fe29..72b2d4b9e 100644 --- a/visualc/VS2010/dtls_client.vcxproj +++ b/visualc/VS2010/dtls_client.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/dtls_server.vcxproj b/visualc/VS2010/dtls_server.vcxproj index 8789d7fea..b975369f3 100644 --- a/visualc/VS2010/dtls_server.vcxproj +++ b/visualc/VS2010/dtls_server.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ecdh_curve25519.vcxproj b/visualc/VS2010/ecdh_curve25519.vcxproj index 1120111f1..748b6d121 100644 --- a/visualc/VS2010/ecdh_curve25519.vcxproj +++ b/visualc/VS2010/ecdh_curve25519.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ecdsa.vcxproj b/visualc/VS2010/ecdsa.vcxproj index 3718c9f27..03418d082 100644 --- a/visualc/VS2010/ecdsa.vcxproj +++ b/visualc/VS2010/ecdsa.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/gen_entropy.vcxproj b/visualc/VS2010/gen_entropy.vcxproj index 4c57655b2..89b41c081 100644 --- a/visualc/VS2010/gen_entropy.vcxproj +++ b/visualc/VS2010/gen_entropy.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/gen_key.vcxproj b/visualc/VS2010/gen_key.vcxproj index a07e1aacc..c8ea11f42 100644 --- a/visualc/VS2010/gen_key.vcxproj +++ b/visualc/VS2010/gen_key.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/gen_random_ctr_drbg.vcxproj b/visualc/VS2010/gen_random_ctr_drbg.vcxproj index 11740c448..64200afbe 100644 --- a/visualc/VS2010/gen_random_ctr_drbg.vcxproj +++ b/visualc/VS2010/gen_random_ctr_drbg.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/gen_random_havege.vcxproj b/visualc/VS2010/gen_random_havege.vcxproj index 01253ceef..70c8138a0 100644 --- a/visualc/VS2010/gen_random_havege.vcxproj +++ b/visualc/VS2010/gen_random_havege.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/generic_sum.vcxproj b/visualc/VS2010/generic_sum.vcxproj index 0f2ecb43c..21bd90f62 100644 --- a/visualc/VS2010/generic_sum.vcxproj +++ b/visualc/VS2010/generic_sum.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/hello.vcxproj b/visualc/VS2010/hello.vcxproj index c986b07be..b5f6eb005 100644 --- a/visualc/VS2010/hello.vcxproj +++ b/visualc/VS2010/hello.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/key_app.vcxproj b/visualc/VS2010/key_app.vcxproj index f96a0b052..0fc246a8f 100644 --- a/visualc/VS2010/key_app.vcxproj +++ b/visualc/VS2010/key_app.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/key_app_writer.vcxproj b/visualc/VS2010/key_app_writer.vcxproj index 0e4af3a58..e4ef62b04 100644 --- a/visualc/VS2010/key_app_writer.vcxproj +++ b/visualc/VS2010/key_app_writer.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 73c92bda5..2ec9178af 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -223,6 +223,7 @@ + diff --git a/visualc/VS2010/mini_client.vcxproj b/visualc/VS2010/mini_client.vcxproj index b5567bdfe..3756404dd 100644 --- a/visualc/VS2010/mini_client.vcxproj +++ b/visualc/VS2010/mini_client.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/mpi_demo.vcxproj b/visualc/VS2010/mpi_demo.vcxproj index d68bc75b3..d770d35af 100644 --- a/visualc/VS2010/mpi_demo.vcxproj +++ b/visualc/VS2010/mpi_demo.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/pem2der.vcxproj b/visualc/VS2010/pem2der.vcxproj index 507c79a4d..2f1248c5d 100644 --- a/visualc/VS2010/pem2der.vcxproj +++ b/visualc/VS2010/pem2der.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/pk_decrypt.vcxproj b/visualc/VS2010/pk_decrypt.vcxproj index 5ccaf4f1e..168adf34b 100644 --- a/visualc/VS2010/pk_decrypt.vcxproj +++ b/visualc/VS2010/pk_decrypt.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/pk_encrypt.vcxproj b/visualc/VS2010/pk_encrypt.vcxproj index d5ef208d8..bb09f06aa 100644 --- a/visualc/VS2010/pk_encrypt.vcxproj +++ b/visualc/VS2010/pk_encrypt.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/pk_sign.vcxproj b/visualc/VS2010/pk_sign.vcxproj index d21f17a41..98941f4be 100644 --- a/visualc/VS2010/pk_sign.vcxproj +++ b/visualc/VS2010/pk_sign.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/pk_verify.vcxproj b/visualc/VS2010/pk_verify.vcxproj index 637ddd6f5..6d3006e61 100644 --- a/visualc/VS2010/pk_verify.vcxproj +++ b/visualc/VS2010/pk_verify.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/query_compile_time_config.vcxproj b/visualc/VS2010/query_compile_time_config.vcxproj index 83a29f067..e14764722 100644 --- a/visualc/VS2010/query_compile_time_config.vcxproj +++ b/visualc/VS2010/query_compile_time_config.vcxproj @@ -55,7 +55,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/req_app.vcxproj b/visualc/VS2010/req_app.vcxproj index 3ffcea594..992efcfb4 100644 --- a/visualc/VS2010/req_app.vcxproj +++ b/visualc/VS2010/req_app.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_decrypt.vcxproj b/visualc/VS2010/rsa_decrypt.vcxproj index 9e1d0a20e..ffba32a6a 100644 --- a/visualc/VS2010/rsa_decrypt.vcxproj +++ b/visualc/VS2010/rsa_decrypt.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_encrypt.vcxproj b/visualc/VS2010/rsa_encrypt.vcxproj index c3b03716c..9f5f32784 100644 --- a/visualc/VS2010/rsa_encrypt.vcxproj +++ b/visualc/VS2010/rsa_encrypt.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_genkey.vcxproj b/visualc/VS2010/rsa_genkey.vcxproj index e6b506000..824e3043c 100644 --- a/visualc/VS2010/rsa_genkey.vcxproj +++ b/visualc/VS2010/rsa_genkey.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_sign.vcxproj b/visualc/VS2010/rsa_sign.vcxproj index c1147c3c2..dda4756cd 100644 --- a/visualc/VS2010/rsa_sign.vcxproj +++ b/visualc/VS2010/rsa_sign.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_sign_pss.vcxproj b/visualc/VS2010/rsa_sign_pss.vcxproj index adfee6d9c..31da8cade 100644 --- a/visualc/VS2010/rsa_sign_pss.vcxproj +++ b/visualc/VS2010/rsa_sign_pss.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_verify.vcxproj b/visualc/VS2010/rsa_verify.vcxproj index bb44b4f9d..b78dfc338 100644 --- a/visualc/VS2010/rsa_verify.vcxproj +++ b/visualc/VS2010/rsa_verify.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/rsa_verify_pss.vcxproj b/visualc/VS2010/rsa_verify_pss.vcxproj index 7781aa51a..220ad2d42 100644 --- a/visualc/VS2010/rsa_verify_pss.vcxproj +++ b/visualc/VS2010/rsa_verify_pss.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/selftest.vcxproj b/visualc/VS2010/selftest.vcxproj index 12ff76d70..1f5e10918 100644 --- a/visualc/VS2010/selftest.vcxproj +++ b/visualc/VS2010/selftest.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ssl_client1.vcxproj b/visualc/VS2010/ssl_client1.vcxproj index 4ac158224..c36a8ed11 100644 --- a/visualc/VS2010/ssl_client1.vcxproj +++ b/visualc/VS2010/ssl_client1.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ssl_client2.vcxproj b/visualc/VS2010/ssl_client2.vcxproj index a960facf0..aa9a0c3af 100644 --- a/visualc/VS2010/ssl_client2.vcxproj +++ b/visualc/VS2010/ssl_client2.vcxproj @@ -55,7 +55,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ssl_fork_server.vcxproj b/visualc/VS2010/ssl_fork_server.vcxproj index 922a9953e..84c917d83 100644 --- a/visualc/VS2010/ssl_fork_server.vcxproj +++ b/visualc/VS2010/ssl_fork_server.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ssl_mail_client.vcxproj b/visualc/VS2010/ssl_mail_client.vcxproj index a9b01d0d5..a89e3322d 100644 --- a/visualc/VS2010/ssl_mail_client.vcxproj +++ b/visualc/VS2010/ssl_mail_client.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ssl_server.vcxproj b/visualc/VS2010/ssl_server.vcxproj index ae28e1839..7fb841e55 100644 --- a/visualc/VS2010/ssl_server.vcxproj +++ b/visualc/VS2010/ssl_server.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/ssl_server2.vcxproj b/visualc/VS2010/ssl_server2.vcxproj index 06a91cb49..b74bd6543 100644 --- a/visualc/VS2010/ssl_server2.vcxproj +++ b/visualc/VS2010/ssl_server2.vcxproj @@ -55,7 +55,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/strerror.vcxproj b/visualc/VS2010/strerror.vcxproj index d7ec570d6..c3ec8fa74 100644 --- a/visualc/VS2010/strerror.vcxproj +++ b/visualc/VS2010/strerror.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/udp_proxy.vcxproj b/visualc/VS2010/udp_proxy.vcxproj index 30ae55e99..e75dd9a29 100644 --- a/visualc/VS2010/udp_proxy.vcxproj +++ b/visualc/VS2010/udp_proxy.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK diff --git a/visualc/VS2010/zeroize.vcxproj b/visualc/VS2010/zeroize.vcxproj index 9d311c721..dff71d30e 100644 --- a/visualc/VS2010/zeroize.vcxproj +++ b/visualc/VS2010/zeroize.vcxproj @@ -54,7 +54,6 @@ false true Unicode - Windows7.1SDK