Prior to this commit, the security parameter struct `ssl_transform`
contained a `ciphersuite_info` field pointing to the information
structure for the negotiated ciphersuite. However, the only
information extracted from that structure that was used in the core
encryption and decryption functions `ssl_encrypt_buf`/`ssl_decrypt_buf`
was the authentication tag length in case of an AEAD cipher.
The present commit removes the `ciphersuite_info` field from the
`ssl_transform` structure and adds an explicit `taglen` field
for AEAD authentication tag length.
This is in accordance with the principle that the `ssl_transform`
structure should contain the raw parameters needed for the record
encryption and decryption functions to work, but not the higher-level
information that gave rise to them. For example, the `ssl_transform`
structure implicitly contains the encryption/decryption keys within
their cipher contexts, but it doesn't contain the SSL master or
premaster secrets. Likewise, it contains an explicit `maclen`, while
the status of the 'Truncated HMAC' extension -- which determines the
value of `maclen` when the `ssl_transform` structure is created in
`ssl_derive_keys` -- is not contained in `ssl_transform`.
The `ciphersuite_info` pointer was used in other places outside
the encryption/decryption functions during the handshake, and for
these functions to work, this commit adds a `ciphersuite_info` pointer
field to the handshake-local `ssl_handshake_params` structure.
The `ssl_transform` security parameter structure contains opaque
cipher contexts for use by the record encryption/decryption functions
`ssl_decrypt_buf`/`ssl_encrypt_buf`, while the underlying key material
is configured once in `ssl_derive_keys` and is not explicitly dealt with
anymore afterwards. In particular, the key length is not needed
explicitly by the encryption/decryption functions but is nonetheless
stored in an explicit yet superfluous `keylen` field in `ssl_transform`.
This commit removes this field.
Resolve conflicts by performing the following:
- Ensure calls to mbedtls_x509_crt_verify_* are made with callbacks
* origin/pr/2539:
Make CRT callback tests more robust
Rename constant in client2.c
Fix typo
Add test for configuration specific CRT callback
Fix doxygen documentation of mbedtls_ssl_set_verify()
Add test exercising context-specific CRT callback to ssl-opt.sh
Add cmd to use context-specific CRT callback in ssl_client2
Implement context-specific verification callbacks
Add context-specific CRT verification callbacks
Improve documentation of mbedtls_ssl_conf_verify()
* origin/pr/2532: (29 commits)
Document and test flags in x509_verify
Fix style issues and a typo
Fix name to function call
Address comments for x509 tests
Address review comments regarding ssl_client2 and ssl tests
Remove mbedtls_ from the static function name
Change docs according to review comments
Change the verify function naming
Fix ssl_client2 and ssl_server2 if !PLATFORM_C
Correct placement of usage macro in ssl_client2
Update version_features.c
Remove trailing whitespace in test_suite_x509parse.function
Update query_config.c
Add ssl-opt.sh tests for trusted CA callbacks
Only run X.509 CRT verification tests with CA callback tests if !CRL
Minor fixes to CA callback tests
Declare CA callback type even if feature is disabled
Implement X.509 CRT verification using CA callback
Add prototype for CRT verification with static and dynamic CA list
Make use of CA callback if present when verifying peer CRT chain
...
So far, there were the following CRT verification functions:
- `mbedtls_x509_crt_verify()` -- no profile, no restartable ECC
- `mbedtls_x509_crt_verify_with_profile()` -- profile, no restartable ECC
- `mbedtls_x509_crt_verify_restartable()` -- profile, restartable ECC
all publicly declared and offering increasing functionality.
On the implementation-side,
- `mbedtls_x509_crt_verify()` resolves to
a call to `mbedtls_x509_crt_verify_with_profile()` setting
the profile to `NULL`, and
- `mbedtls_x509_crt_verify_with_profile()`
resolves to a call to ``mbedtls_x509_crt_verify_restartable()`
setting the ECC restart context to NULL.
This commit adds two more functions to this zoo:
- `mbedtls_x509_crt_verify_with_cb()`
- `x509_crt_verify_restartable_cb()`
Here, `mbedtls_x509_crt_verify_with_cb()` is similar to
`mbedtls_x509_crt_verify_with_profile()` but uses a CA callback
instead of a static CA list, and no restart context.
`x509_crt_verify_restartable_cb()` is similar to
`mbedtls_x509_crt_verify_restartable()` but allows to either use
a static list of trusted CAs _or_ a trusted CA callback.
On the implementation-side,
- the body of `mbedtls_x509_crt_verify_restartable()` is moved to
`x509_crt_verify_restartable_cb()`, and the new version of
`mbedtls_x509_crt_verify_restartable()` just resolves to
`x509_crt_verify_restartable_cb()` with the trusted CA callback
set to NULL.
- The new function `mbedtls_x509_crt_verify_with_cb()`
forward to `x509_crt_verify_restartable_cb()` with the restart
context set to `NULL`.
There's no change to the implementation yet, and in particular,
`mbedtls_x509_crt_verify_with_cb()` isn't yet usable.
* restricted/pr/551:
ECP: Clarify test descriptions
ECP: remove extra whitespaces
Fix ECDH secret export for Mongomery curves
Improve ECP test names
Make ecp_get_type public
Add more tests for ecp_read_key
ECP: Catch unsupported import/export
Improve documentation of mbedtls_ecp_read_key
Fix typo in ECP module
Remove unnecessary cast from ECP test
Improve mbedtls_ecp_point_read_binary tests
Add Montgomery points to ecp_point_write_binary
ECDH: Add test vectors for Curve25519
Add little endian export to Bignum
Add mbedtls_ecp_read_key
Add Montgomery points to ecp_point_read_binary
Add little endian import to Bignum
Ensure this merge passes tests by auto-generating query_config.c, adding
MBEDTLS_ECDH_LEGACY_CONTEXT to it.
* restricted/pr/552:
Fix mbedtls_ecdh_get_params with new ECDH context
Test undefining MBEDTLS_ECDH_LEGACY_CONTEXT in all.sh
Define MBEDTLS_ECDH_LEGACY_CONTEXT in config.h
Add changelog entry for mbedtls_ecdh_get_params robustness
Fix ecdh_get_params with mismatching group
Add test case for ecdh_get_params with mismatching group
Add test case for ecdh_calc_secret
Fix typo in documentation
Ensure tests pass when the submodule is used by updating the list of
crypto tests to include test_suite_oid in both tests/CMakeLists.txt and
tests/Makefile.
* origin/pr/2531:
Add changeLog entry
Add certificate policy of type any policy id
* origin/pr/2509:
all.sh: Generate seedfile for crypto submodule tests
Update crypto submodule to test with private headers
tests: Use globbing in test suite exclusion list
Update crypto submodule to Mbed Crypto development
tests: Test crypto via the crypto submodule
Update the crypto submodule to the top of the Mbed Crypto development
branch. This brings in a version of Mbed Crypto that enables building
Mbed Crypto tests that depend on private headers, like
'psa_crypto_invasive.h'.
This also requires updating our config.h to include new configuration
options added to Mbed Crypto. MBEDTLS_PSA_ITS_FILE_C replaces
MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C and MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C.
MBEDTLS_PSA_INJECT_ENTROPY replaces MBEDTLS_PSA_HAS_ITS_IO.
* origin/pr/1520:
Use certificates from data_files and refer them
Specify server certificate to use in SHA-1 test
refactor CA and SRV certificates into separate blocks
refactor SHA-1 certificate defintions and assignment
refactor server SHA-1 certificate definition into a new block
define TEST_SRV_CRT_RSA_SOME in similar logic to TEST_CA_CRT_RSA_SOME
server SHA-256 certificate now follows the same logic as CA SHA-256 certificate
add entry to ChangeLog
* public/pr/2421: (68 commits)
Fix unused variable warning in ssl_parse_certificate_coordinate()
Add missing compile time guard in ssl_client2
Update programs/ssl/query_config.c
ssl_client2: Reset peer CRT info string on reconnect
Add further debug statements on assertion failures
Fix typo in documentation of ssl_parse_certificate_chain()
Add debug output in case of assertion failure
Fix typo in SSL ticket documentation
Add config sanity check for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
ssl_client2: Zeroize peer CRT info buffer when reconnecting
Reintroduce numerous ssl-opt.sh tests if !MBEDTLS_SSL_KEEP_PEER_CERT
ssl_client2: Extract peer CRT info from verification callback
Improve documentation of mbedtls_ssl_get_peer_cert()
Improve documentation of MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
Fix indentation of Doxygen comment in ssl_internal.h
Set peer CRT length only after successful allocation
Remove question in comment about verify flags on cli vs. server
Remove misleading and redundant guard around restartable ECC field
Add test for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE to all.sh
Free peer CRT chain immediately after verifying it
...
* restricted/pr/528:
Update query_config.c
Fix failure in SSLv3 per-version suites test
Adjust DES exclude lists in test scripts
Clarify 3DES changes in ChangeLog
Fix documentation for 3DES removal
Exclude 3DES tests in test scripts
Fix wording of ChangeLog and 3DES_REMOVE docs
Reduce priority of 3DES ciphersuites
* public/pr/2028:
Update the crypto submodule to a78c958
Fix ChangeLog entry to correct release version
Fix typo in x509write test data
Add ChangeLog entry for unused bits in bitstrings
Improve docs for named bitstrings and their usage
Add tests for (named) bitstring to suite_asn1write
Add new function mbedtls_asn1_write_named_bitstring()
Add a new function mbedtls_asn1_write_named_bitstring() that removes
trailing 0s at the end of DER encoded bitstrings. The function is
implemented according to Hanno Becker's suggestions.
This commit also changes the functions x509write_crt_set_ns_cert_type
and crt_set_key_usage to call the new function as the use named
bitstrings instead of the regular bitstrings.
The ecp_get_type function comes handy in higher level modules and tests
as well. It is not inline anymore, to enable alternative implementations
to implement it for themselves.
mbedtls_ecp_read_key() module returned without an error even when
importing keys corresponding to the requested group was not
implemented.
We change this and return an error when the requested group is not
supported and make the remaining import/export functions more robust.
If we don't need to store the peer's CRT chain permanently, we may
free it immediately after verifying it. Moreover, since we parse the
CRT chain in-place from the input buffer in this case, pointers from
the CRT structure remain valid after freeing the structure, and we
use that to extract the digest and pubkey from the CRT after freeing
the structure.
It is used in `mbedtls_ssl_session_free()` under
`MBEDTLS_X509_CRT_PARSE_C`, but defined only if
`MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED`.
Issue #2422 tracks the use of
`MBEDTLS_KEY_EXCHANGE__WITH_CERT_ENABLED` instead of
`MBEDTLS_X509_CRT_PARSE_C` for code and fields
related to CRT-based ciphersuites.
The server expects a CertificateVerify message only if it has
previously received a Certificate from the client.
So far, this was detected by looking at the `peer_cert` field
in the current session. Preparing to remove the latter, this
commit changes this to instead determine the presence of a peer
certificate by checking the new `peer_cert_digest` pointer.
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
We must dispatch between the peer's public key stored as part of
the peer's CRT in the current session structure (situation until
now, and future behaviour if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is
enabled), and the sole public key stored in the handshake structure
(new, if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is disabled).
This commit modifies `mbedtls_ssl_parse_certificate()` to store a
copy of the peer's public key after parsing and verifying the peer's
CRT chain.
So far, this leads to heavy memory duplication: We have the CRT chain
in the I/O buffer, then parse (and, thereby, copy) it to a
`mbedtls_x509_crt` structure, and then make another copy of the
peer's public key, plus the overhead from the MPI and ECP structures.
This inefficiency will soon go away to a significant extend, because:
- Another PR adds functionality to parse CRTs without taking
ownership of the input buffers. Applying this here will allow
parsing and verifying the peer's chain without making an additional
raw copy. The overhead reduces to the size of `mbedtls_x509_crt`,
the public key, and the DN structures referenced in the CRT.
- Once copyless parsing is in place and the removal of the peer CRT
is fully implemented, we can extract the public key bounds from
the parsed certificate and then free the entire chain before
parsing the public key again. This means that we never store
the parsed public key twice at the same time.
When removing the (session-local) copy of the peer's CRT chain, we must
keep a handshake-local copy of the peer's public key, as (naturally) every
key exchange will make use of that public key at some point to verify that
the peer actually owns the corresponding private key (e.g., verify signatures
from ServerKeyExchange or CertificateVerify, or encrypt a PMS in a RSA-based
exchange, or extract static (EC)DH parameters).
This commit adds a PK context field `peer_pubkey` to the handshake parameter
structure `mbedtls_handshake_params_init()` and adapts the init and free
functions accordingly. It does not yet make actual use of the new field.
This commit adds an ASN.1 buffer field `pk_raw` to `mbedtls_x509_crt`
which stores the bounds of the raw public key data within an X.509 CRT.
This will be useful in subsequent commits to extract the peer's public
key from its certificate chain.
This commit changes the format of session tickets to include
the digest of the peer's CRT if MBEDTLS_SSL_KEEP_PEER_CERTIFICATE
is disabled.
This commit does not yet remove the peer CRT itself.
`mbedtls_ssl_parse_certificate()` parses the peer's certificate chain
directly into the `peer_cert` field of the `mbedtls_ssl_session`
structure being established. To allow to optionally remove this field
from the session structure, this commit changes this to parse the peer's
chain into a local variable instead first, which can then either be freed
after CRT verification - in case the chain should not be stored - or
mapped to the `peer_cert` if it should be kept. For now, only the latter
is implemented.
mbedtls_ssl_parse_certificate() will fail if a ciphersuite requires
a certificate, but none is provided. While it is sensible to double-
check this, failure should be reported as an internal error and not
as an unexpected message.
A subsequent commit will need this function in the session ticket
and session cache implementations. As the latter are server-side,
this commit also removes the MBEDTLS_SSL_CLI_C guard.
For now, the function is declared in ssl_internal.h and hence not
part of the public API.
This commit modifies the helper `ssl_parse_certificate_chain()` to
accep any target X.509 CRT chain instead of hardcoding it to
`session_negotiate->peer_cert`. This increases modularity and paves
the way towards removing `mbedtls_ssl_session::peer_cert`.
This commit simplifies the client-side code for outgoing CertificateVerify
messages, and server-side code for outgoing CertificateRequest messages and
incoming CertificateVerify messages, through the use of the macro
`MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED`
indicating whether a ciphersuite allowing CertificateRequest messages
is enabled in the configuration, as well as the helper function
`mbedtls_ssl_ciphersuite_cert_req_allowed()`
indicating whether a particular ciphersuite allows CertificateRequest
messages.
These were already used in the client-side code to simplify the
parsing functions for CertificateRequest messages.
This commit adds a helper function `ssl_parse_certificate_coordinate()`
which checks whether a `Certificate` message is expected from the peer.
The logic is the following:
- For ciphersuites which don't use server-side CRTs, no Certificate
message is expected (neither for the server, nor the client).
- On the server, no client certificate is expected in the following cases:
* The server server didn't request a Certificate, which is controlled
by the `authmode` setting.
* A RSA-PSK suite is used; this is the only suite using server CRTs
but not allowing client-side authentication.
This commit introduces a static helper function
`mbedtls_ssl_ciphersuite_uses_srv_cert()`
which determines whether a ciphersuite may make use of server-side CRTs.
This function is in turn uses in `mbedtls_ssl_parse_certificate()` to
skip certificate parsing for ciphersuites which don't involve CRTs.
Note: Ciphersuites not using server-side CRTs don't allow client-side CRTs
either, so it is safe to guard `mbedtls_ssl_{parse/write}_certificate()`
this way.
Note: Previously, the code uses a positive check over the suites
- MBEDTLS_KEY_EXCHANGE_PSK
- MBEDTLS_KEY_EXCHANGE_DHE_PSK
- MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
- MBEDTLS_KEY_EXCHANGE_ECJPAKE,
while now, it uses a negative check over `mbedtls_ssl_ciphersuite_uses_srv_cert()`,
which checks for the suites
- MBEDTLS_KEY_EXCHANGE_RSA
- MBEDTLS_KEY_EXCHANGE_RSA_PSK
- MBEDTLS_KEY_EXCHANGE_DHE_RSA
- MBEDTLS_KEY_EXCHANGE_ECDH_RSA
- MBEDTLS_KEY_EXCHANGE_ECDHE_RSA
- MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA
- MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
This is equivalent since, together, those are all ciphersuites.
Quoting ssl_ciphersuites.h:
```
typedef enum {
MBEDTLS_KEY_EXCHANGE_NONE = 0,
MBEDTLS_KEY_EXCHANGE_RSA,
MBEDTLS_KEY_EXCHANGE_DHE_RSA,
MBEDTLS_KEY_EXCHANGE_ECDHE_RSA,
MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA,
MBEDTLS_KEY_EXCHANGE_PSK,
MBEDTLS_KEY_EXCHANGE_DHE_PSK,
MBEDTLS_KEY_EXCHANGE_RSA_PSK,
MBEDTLS_KEY_EXCHANGE_ECDHE_PSK,
MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
MBEDTLS_KEY_EXCHANGE_ECJPAKE,
} mbedtls_key_exchange_type_t;
```
The handler `mbedtls_ssl_parse_certificate()` for incoming `Certificate`
messages contains many branches updating the handshake state. For easier
reasoning about state evolution, this commit introduces a single code-path
updating the state machine at the end of `mbedtls_ssl_parse_certificate()`.
If an attempt for session resumption fails, the `session_negotiate` structure
might be partially filled, and in particular already contain a peer certificate
structure. This certificate structure needs to be freed before parsing the
certificate sent in the `Certificate` message.
This commit moves the code-path taking care of this from the helper
function `ssl_parse_certificate_chain()`, whose purpose should be parsing
only, to the top-level handler `mbedtls_ssl_parse_certificate()`.
The fact that we don't know the state of `ssl->session_negotiate` after
a failed attempt for session resumption is undesirable, and a separate
issue #2414 has been opened to improve on this.
This commit introduces a server-side static helper function
`ssl_srv_check_client_no_crt_notification()`, which checks if
the message we received during the incoming certificate state
notifies the server of the lack of certificate on the client.
For SSLv3, such a notification comes as a specific alert,
while for all other TLS versions, it comes as a `Certificate`
handshake message with an empty CRT list.