Commit graph

9235 commits

Author SHA1 Message Date
Hanno Becker 76428359b3 Move existence check for pk/frame to mbedtls_x509_crt_provide_xxx() 2019-06-25 09:07:16 +01:00
Hanno Becker bc685199d9 Implement MBEDTLS_X509_ALWAYS_FLUSH 2019-06-25 09:07:16 +01:00
Hanno Becker ffcd8c39a4 Introduce compile-time option to always flush X.509 CRT caches
This commit introduces a compile-time option MBEDTLS_X509_ALWAYS_FLUSH
which controls whether releasing of CRT frames or public key contexts
associated to X.509 CRTs (or, in the future, other cached parsed X.509
structures) should lead to freeing those structures immediately.

Enabling this alongside of the MBEDTLS_X509_ON_DEMAND_PARSING leads
to significant reduction of the average RAM consumption of Mbed TLS.

The option is enabled by default to reduce the permanent RAM overhead of
MBEDTLS_X509_ON_DEMAND_PARSING in case the latter is *disabled* (default).
(Note that there is very little performance penalty enabling
MBEDTLS_X509_ALWAYS_FLUSH in case MBEDTLS_X509_ON_DEMAND_PARSING is disabled,
because hardly any parsing needs to be done to setup a CRT frame / PK context
from the legacy `mbedtls_x509_crt` structure.)
2019-06-25 09:07:16 +01:00
Hanno Becker c6d1c3ed1c Remove frame/pk parameter from mbedtls_x509_crt_xxx_release() 2019-06-25 09:07:16 +01:00
Hanno Becker 7dbf49a518 Enable threading in all.sh test for X.509 on demand parsing 2019-06-25 09:07:16 +01:00
Hanno Becker 38f0cb487c Introduce helpers for conversion between X.509 buffer structs
This commit introduces two static helpers
- `x509_buf_to_buf_raw()`
- `x509_buf_raw_to_buf()`
which convert to/from the old `mbedtls_x509_buf` and
the new `mbedtls_x509_buf_raw` (the latter omitting the
ASN.1 tag field).
2019-06-25 09:07:16 +01:00
Hanno Becker 1e11f217d4 Solely use raw X.509 name data references including SEQUENCE header
So far, the CRT frame structure `mbedtls_x509_crt_frame` used
as `issuer_raw` and `subject_raw` the _content_ of the ASN.1
name structure for issuer resp. subject. This was in contrast
to the fields `issuer_raw` and `subject_raw` from the legacy
`mbedtls_x509_crt` structure, and caused some information
duplication by having both variants `xxx_no_hdr` and `xxx_with_hdr`
in `mbedtls_x509_crt` and `mbedtls_x509_crt_frame`.

This commit removes this mismatch by solely using the legacy
form of `issuer_raw` and `subject_raw`, i.e. those _including_
the ASN.1 name header.
2019-06-25 09:07:16 +01:00
Hanno Becker 4e021c8f50 Remove raw SubjectAltNames and ExtKeyUsage from legacy CRT struct 2019-06-25 09:07:16 +01:00
Hanno Becker ea32d8ba2a Provide direct way of setting up a CRT frame from legacy CRT struct
Previously, `mbedtls_x509_crt_cache_provide_frame()` provided the requested
CRT frame by always parsing the raw data underlying the CRT. That's inefficient
in legacy mode, where the CRTs fields are permanently accessible through the
legacy `mbedtls_x509_crt` structure.

This commit modifies `mbedtls_x509_crt_cache_provide_frame()` in legacy mode
(that is, !MBEDTLS_X509_ON_DEMAND_PARSING) to setup the CRT frame by copying
fields from the legacy CRT structure.
2019-06-25 09:07:16 +01:00
Hanno Becker bfabd1dfae Add test to all.sh
This commit adds a `make test` and `ssl-opt.sh` run to `all.sh`
exercising the default configuration, plus the following changes:
- MBEDTLS_SSL_KEEP_PEER_CERTIFICATE disabled
- MBEDTLS_X509_ON_DEMAND_PARSING enabled.
2019-06-25 09:07:16 +01:00
Hanno Becker 008d304d1b Adapt ChangeLog 2019-06-25 09:07:16 +01:00
Hanno Becker 5d9021e7f2 Make use of new API in ssl_server2 example application 2019-06-25 09:06:26 +01:00
Hanno Becker 4588dc4754 Update query_config.c 2019-06-25 09:06:26 +01:00
Hanno Becker 3f8f0dc3fd Use mbedtls_x509_crt_get_subject() in test_suite_x509parse test 2019-06-25 09:06:26 +01:00
Hanno Becker 5226c53e13 Modify mbedtls_x509_crt_info() to use getter API 2019-06-25 09:06:26 +01:00
Hanno Becker 7a4de9cdab Flush CRT cache after parsing
This commit modifies the CRT parsing routine to flush
the CRT cache after parsing. More specifically, the
frame cache is flushed before the PK is parsed, to
avoid storing the PK and frame in RAM at the same time.
2019-06-25 09:06:26 +01:00
Hanno Becker 828a8c08b6 Add compile-guard for < TLS1.2 path in server-side ssl_pick_cert()
Minor code-size optimization along the way.
2019-06-25 09:06:26 +01:00
Hanno Becker c69c4465b6 Adapt test_suite_x509parse to new CRT structure 2019-06-25 09:06:26 +01:00
Hanno Becker d8eab343d2 Adapt cert_write example program to work with new CRT structure 2019-06-25 09:06:26 +01:00
Hanno Becker 2bcc7640f8 Give x509_{sequence|name}_free() external linkage
With the introduction of `mbedtls_x509_crt_get_{issuer|name}()`,
users need an easy way of freeing the dynamic name structures these
functions return.

To that end, this commit renames `x509_{sequence|name}_free()`
to `mbedtls_x509_{sequence|name}_free()` and gives them external linkage.
2019-06-25 09:06:26 +01:00
Hanno Becker ab6c8ea8bc Add public API to query SubjectAltNames and ExtKeyUsage extensions 2019-06-25 09:06:26 +01:00
Hanno Becker 63e6998dd7 Add public API to query subject and issuer from CRT
The legacy `mbedtls_x509_crt` contains fields `issuer/subject`
which are dynamically allocated linked list presentations of the
CRTs issuer and subject names, respectively.

The new CRT frame structure `mbedtls_x509_crt_frame`, however,
only provides pointers to the raw ASN.1 buffers for the issuer
and subject, for reasons of memory usage.

For convenience to users that previously used the `issuer`/`subject`
fields of `mbedtls_x509_crt`, this commit adds two public API functions
`mbedtls_x509_crt_get_subject()` and `mbedtls_x509_crt_get_issuer()`
which allow to request the legacy linked list presentation of the
CRTs subject / issuer names.

Similar to `mbedtls_x509_crt_get_pk()`, the returned names are owned
by the user, and must be freed through a call to `mbedtls_x509_name_free()`.
2019-06-25 09:06:26 +01:00
Hanno Becker 823efad6e8 Add public API to query for CRT frame and PK
This commit unconditionally adds two convenience API functions:
- mbedtls_x509_crt_get_frame()
- mbedtls_x509_crt_get_pk()
which allow users to extract a CRT frame or PK context
from a certificate.

The difference with the existing acquire/release API for frame and PK
contexts is that in contrast to the latter, the structures returned by
the new API are owned by the user (and, in case of the PK context, need
to be freed by him). This makes the API easier to use, but comes at the
cost of additional memory overhead.
2019-06-25 09:06:26 +01:00
Hanno Becker 180f7bf60b Add compile-time option to remove legacy CRT fields 2019-06-25 09:06:26 +01:00
Hanno Becker b6c39fca5c Add parsing cache to mbedtls_x509_crt
This commit replaces the dummy implementation of the CRT acquire/release
framework by a cache-based implementation which remembers frame and PK
associated to a CRT across multiple `acquire/release` pairs.
2019-06-25 09:06:26 +01:00
Hanno Becker 73cd8d8adc Make use of acquire/release in ssl_parse_certificate_verify() 2019-06-25 09:06:26 +01:00
Hanno Becker 2fefa4845d Make use of acquire/release in ssl_parse_server_key_exchange() 2019-06-25 09:06:26 +01:00
Hanno Becker 39ae65cf73 Make use of acquire/release in ssl_get_ecdh_params_from_cert() 2019-06-25 09:06:26 +01:00
Hanno Becker 0c1681685c Make use of acquire/release in client-side ssl_write_encrypted_pms() 2019-06-25 09:06:26 +01:00
Hanno Becker 232f8faf00 Make use of CRT acquire/release in ssl_write_certificate_request() 2019-06-25 09:06:26 +01:00
Hanno Becker 30649f7a17 Make use of CRT acquire/release in server-side ssl_pick_cert() 2019-06-25 09:06:26 +01:00
Hanno Becker 8c13ee615f Make use of CRT acquire/release in ssl_parse_certificate_verify()
Access the peer's PK through the PK acquire/release API only.

Care has to be taken not to accidentally overwrite the return
value `ret` from the CRT chain verification.
2019-06-25 09:06:26 +01:00
Hanno Becker 6cb5f86dac Make use of CRT acquire/release in mbedtls_debug_print_crt() 2019-06-25 09:06:26 +01:00
Hanno Becker 5c03058bbc Make use of CRT acquire/release in test_suite_x509parse suite 2019-06-25 09:06:26 +01:00
Hanno Becker 8723336831 Make use of CRT acquire/release in x509_crt_verify_restartable 2019-06-25 09:06:26 +01:00
Hanno Becker 082435c011 Make use of CRT acquire/release in x509_crt_verify_name()
This commit modifies the static function `x509_crt_verify_name()` to
use the acquire/release API to access the given CRTs `subject` field.

This function is solely called from the beginning of the CRT chain
verification routine, which also needs to access the child's CRT frame.
It should therefore be considered - for a later commit - to collapse
the two acquire/release pairs to one, thereby saving some code.
2019-06-25 09:06:26 +01:00
Hanno Becker 58c35646df Make use of CRT acquire/release in CRT chain verification #2 2019-06-25 09:06:26 +01:00
Hanno Becker bb26613d32 Make use of CRT acquire/release in x509_crt_verifycrl() 2019-06-25 09:06:26 +01:00
Hanno Becker 79ae5b68e7 Make use of CRT acquire/release in x509_serial_is_revoked() 2019-06-25 09:06:26 +01:00
Hanno Becker e9718b451a Make use of CRT acquire/release in ExtKeyUsage checking 2019-06-25 09:06:26 +01:00
Hanno Becker 371e0e4573 Determine whether CRT is initialized or not through raw data pointer
Previously, `mbedtls_x509_crt_der_internal()` used the `version` field
(which is `0` after initialization but strictly greater than 0 once a
CRT has successfully been parsed) to determine whether an
`mbedtls_x509_crt` instance had already been setup.

Preparating for the removal of `version` from the structure, this
commit modifies the code to instead peek at the raw data pointer,
which is NULL as long as the CRT structure hasn't been setup with a CRT,
and will be kept in the new CRT structure.
2019-06-25 09:06:26 +01:00
Hanno Becker 4f869eda64 Make use of CRT acquire/release in mbedtls_x509_crt_info()
This commit adapts `mbedtls_x509_crt_info()` to no longer access
structure fields from `mbedtls_x509_crt` directly, but to instead
query for a `mbedtls_x509_crt_frame` and `mbedtls_pk_context` and
use these to extract the required CRT information.
2019-06-25 09:06:26 +01:00
Hanno Becker 343fec08ad Add version of MBEDTLS_X509_SAFE_SNPRINTF supporting cleanup section
This will be needed in debugging functions that maintain heap
allocated state, and which hence needs to be freed in case an
`snprintf()` call fails.
2019-06-25 09:06:26 +01:00
Hanno Becker 45eedf1ace Make use of CRT acquire/release in mbedtls_x509_crt_check_key_usage 2019-06-25 09:06:26 +01:00
Hanno Becker 43bf900018 Make use of CRT acquire/release searching for issuer in CRT verif.
This commit continues rewriting the CRT chain verification to use
the new acquire/release framework for CRTs. Specifically, it replaces
all member accesses of the current _parent_ CRT by accesses to the
respective frame.
2019-06-25 09:06:26 +01:00
Hanno Becker e449e2d846 Make use of CRT acquire/release for X.509 CRT signature checking 2019-06-25 09:06:26 +01:00
Hanno Becker 5299cf87d4 Add structure holding X.509 CRT signature information
This commit introduces an internal structure `mbedtls_x509_crt_sig_info`
containing all information that has to be kept from a child CRT when searching
for a potential parent:
- The issuer name
- The signature type
- The signature
- The hash of the CRT

The structure can be obtained from a CRT frame via `x509_crt_get_sig_info()`
and freed via `x509_crt_free_sig_info()`.

The purpose of this is to reduce the amount of RAM used during CRT
chain verification; once we've extracted the signature info structure
from the current child CRT, we can free all cached data for that CRT
(frame and PK) before searching for a suitable parent. This way, there
will ultimately not be more than one frame needed at a single point
during the verification.
2019-06-25 09:06:26 +01:00
Hanno Becker a788cab46d Check validity of potential parent before checking signature
The function `x509_crt_find_parent_in()` traverses a list of CRTs
to find a potential parent to a given CRT. So far, the logic was
the following: For each candidate,
- check basic parenting skills (mostly name match)
- verify signature
- verify validity
This order is insuitable for the new acquire/release layer of
indirection when dealing with CRTs, because we either have to
query the candidate's CRT frame twice, or query frame and PK
simultaneously.

This commit moves the validity check to the beginning of the
routine to allow querying for the frame and then for the PK.

The entry point for restartable ECC needs to be moved for that
to not forget the validity-flag while pausing ECC computations.
2019-06-25 09:06:26 +01:00
Hanno Becker 1e0677acc1 Make use of CRT acquire/release for child in CRT chain verification
During CRT verification, `x509_crt_check_signature()` checks whether a
candidate parent CRT correctly signs the current child CRT.

This commit rewrites this function to use the new acquire/release
framework for using CRTs.
2019-06-25 09:06:26 +01:00
Hanno Becker 337088aa2d Add internal API for acquire/release of CRT frames and PKs
The goal of the subsequent commits is to remove all direct uses
of the existing `mbedtls_x509_crt` apart from the `raw` buffer
and the linked list `next` pointer.

The approach is the following: Whenever a code-path needs to inspect
a CRT, it can request a frame for the CRT through the API
`x509_crt_frame_acquire()`. On success, this function returns a pointer
to a frame structure for the CRT (the origin of which is flexible and
need not concern the caller) that can be used to inspect the desired
fields. Once done, the caller hands back the frame through an explicit
call to `x509_crt_frame_release()`.

This commit also adds an inefficient dummy implementation for
`x509_crt_frame_acquire()` which always allocates a new
`mbedtls_x509_crt_frame` structure on the heap and parses it
from the raw data underlying the CRT. This will change in subsequent
commits, but it constitutes a valid implementation to test against.

Ultimately, `x509_crt_frame_acquire()` is to compute a frame for the
given CRT only once, and cache it for subsequent calls.

The need for `x509_crt_frame_release()` is the following: When
implementing `x509_crt_frame_acquire()` through a flushable cache
as indicated above, it must be ensured that no thread destroys
a cached frame structure for the time it is needed by another
thread. The `acquire/release` pair allows to explicitly delimit
the lifetime requirements for the returned frame structure.
The frame pointer must not be used after the `release` call anymore;
and in fact, the dummy implementation shows that it would
immediately lead to a memory failure.

Analogously to `x509_crt_frame_{acquire|release}()`, there's also
`x509_crt_pk_{acquire|release}()` which allows to acquire/release
a PK context setup from the public key contained within the CRT.
2019-06-25 09:06:26 +01:00