Commit Graph

2722 Commits

Author SHA1 Message Date
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
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
21f5567571 Introduce X.509 CRT frame structure
This commit restructures the parsing of X.509 CRTs in the following way:

First, it introduces a 'frame' structure `mbedtls_x509_crt_frame`, which
contains pointers to some structured fields of a CRT as well as copies of
primitive fields. For example, there's a pointer-length pair delimiting the raw
public key data in the CRT, but there's a C-uint8 to store the CRT version
(not a pointer-length pair delimiting the ASN.1 structure holding the version).

Setting up a frame from a raw CRT buffer does not require any memory outside
of the frame structure itself; it's just attaches a 'template' to the buffer
that allows to inspect the structured parts of the CRT afterwards.

Note that the frame structure does not correspond to a particular ASN.1
structure; for example, it contains pointers to delimit the three parts
of a CRT (TBS, SignatureAlgorithm, Signature), but also pointers to the
fields of the TBS, and pointers into the Extensions substructure of the TBS.

Further, the commit introduces an internal function `x509_crt_parse_frame()`
which sets up a frame from a raw CRT buffer, as well as several small helper
functions which help setting up the more complex structures (Subject, Issuer, PK)
from the frame.

These functions are then put to use to rewrite the existing parsing function
`mbedtls_x509_crt_parse_der_core()` by setting up a CRT frame from the input
buffer, residing on the stack, and afterwards copying the respective fields
to the actual `mbedtls_x509_crt` structure and performing the deeper parsing
through the various helper functions.
2019-06-25 09:06:26 +01:00
Hanno Becker
6b37812a45 Add next_merged field to X.509 name comparison abort callback 2019-06-25 09:06:26 +01:00
Hanno Becker
b59d3f1692 Add single function to parse ASN.1 AlgorithmIdentifier to x509.c 2019-06-25 09:06:26 +01:00
Hanno Becker
b3def1d341 Move length check into mbedtls_x509_memcasecmp()
At every occasion where we're using `mbedtls_x509_memcasecmp()` we're
checking that the two buffer lengths coincide before making the call.

This commit saves a few bytes of code by moving this length check
to `mbedtls_x509_memcasecmp()`.
2019-06-25 09:06:26 +01:00
Hanno Becker
8730610ae0 Introduce ASN.1 API for traversing ASN.1 SEQUENCEs
This commit adds a new function `mbedtls_asn1_traverse_sequence_of()`
which traverses an ASN.1 SEQUENCE and calls a user-provided callback
for each entry.

It allows to put the following constraints on the tags allowed
in the SEQUENCE:
- A tag mask and mandatory tag value w.r.t. that mask.
  A non-matching tag leads to an MBEDTLS_ERR_ASN1_UNEXPECTED_TAG error.
  For example, it the mask if 0xFF, this means that only
  a single tag will be allowed in the SEQUENCE.
- A tag mask and optional tag value w.r.t. that mask.
  A non-matching tag is silently ignored.

The main use for this flexibility is the traversal of the
`SubjectAlternativeNames` extension, where some parts of the
tag are fixed but some are flexible to indicate which type
of name the entry describes.
2019-06-25 09:06:26 +01:00
Hanno Becker
ded167e18c Add raw buffer holding SubjectAlternativeName ext to CRT structure
This is analogous to a previous commit for the `ExtendedKeyUsage`
extension: We aim at not using dynamically allocated linked lists
to represent the components of the `SubjectAlternativeName` extension,
but to traverse the raw ASN.1 data when needed.

This commit adds a field to `mbedtls_x509_crt` containing the raw
ASN.1 buffer bounds of the `SubjectAlternativeNames` extension.
2019-06-25 09:06:26 +01:00
Hanno Becker
e1956af057 Check for extended key usage by traversing raw extension data
This commit re-implements `mbedtls_x509_crt_check_extended_key_usage()`
to not use the dynamically allocated linked list presentation of the
`ExtendedKeyUsage` but to search for the required usage by traversing
the raw ASN.1 data.
2019-06-25 09:06:26 +01:00
Hanno Becker
7ec9c368f1 Add buffer holding raw ExtKeyUsage extension data to CRT struct
The previous commits replace the use of dynamically allocated linked lists
for X.509 name inspection. This commit is the first in a series which attempts
the same for the `ExtendedKeyUsage` extension. So far, when a CRT is parsed,
the extension is traversed and converted into a dynamically allocated linked
list, which is then search through whenever the usage of a CRT needs to be
checked through `mbedtls_x509_check_extended_key_usage()`.

As a first step, this commit introduces a raw buffer holding the bounds
of the `ExtendedKeyUsage` extension to the `mbedtls_x509_crt` structure.
2019-06-25 09:06:26 +01:00
Hanno Becker
67284cce00 Add abort condition callback to mbedtls_x509_name_cmp_raw()
There are three operations that need to be performed on an X.509 name:
1 Initial traversal to check well-formedness of the ASN.1 structure.
2 Comparison between two X.509 name sequences.
3 Checking whether an X.509 name matches a client's ServerName request.

Each of these tasks involves traversing the nested ASN.1 structure,
In the interest of saving code, we aim to provide a single function
which can perform all of the above tasks.

The existing comparison function is already suitable not only for task 2,
but also for 1: One can simply pass two equal ASN.1 name buffers, in which
case the function will succeed if and only if that buffer is a well-formed
ASN.1 name.

This commit further adds a callback to `mbedtls_x509_name_cmp_raw()` which
is called after each successful step in the simultaneous name traversal and
comparison; it may perform any operation on the current name and potentially
signal that the comparison should be aborted.

With that, task 3 can be implemented by passing equal names and a callback
which aborts as soon as it finds the desired name component.
2019-06-25 09:06:26 +01:00
Hanno Becker
7dee12a38c Make use of raw comparison function in CRT verification
This commit replaces the previous calls to `mbedtls_x509_name_cmp()`
during CRT verification (to match child and parent, to check whether
a CRT is self-issued, and to match CRLs and CAs) by calls to the new
`mbedtls_x509_name_cmp_raw()` using the raw ASN.1 data; it passes the
raw buffers introduced in the last commits.

The previous name comparison function mbedtls_x509_name_cmp() is now
both unused and unneeded, and is removed.
2019-06-25 09:06:26 +01:00
Hanno Becker
f8a42862b7 Add buffers with raw issuer/subject data to CRT structure 2019-06-25 09:06:26 +01:00
Hanno Becker
a632e3638c Add buffer with raw issuer data to CRL structure
To make use of the X.509 name comparison function based on raw
ASN.1 data that was introduced in the previous commit, this commit
adds an ASN.1 buffer field `issuer_raw_no_hdr` to `mbedtls_x509_crl`
which delimits the raw contents of the CRLs `Issuer` field.

The previous field `issuer_raw` isn't suitable for that because
it includes the ASN.1 header.
2019-06-25 09:06:26 +01:00
Hanno Becker
a3a2ca1333 Provide X.509 name comparison based on raw ASN.1 data
This commit provides a new function `mbedtls_x509_name_cmp_raw()`
to x509.c for comparing to X.509 names by traversing the raw ASN.1
data (as opposed to using the dynamically allocated linked list
of `mbedtls_x509_name` structures). It has external linkage because
it will be needed in `x509_crt` and `x509_crl`, but is marked
internal and hence not part of the public API.
2019-06-25 09:06:26 +01:00
Hanno Becker
88de342c95 Move x509_name_cmp() from x509_crt.c to x509.c
This is to prepare a subsequent rewrite of `x509_name_cmp()` in terms
of the X.509 name traversal helper `x509_set_sequence_iterate()`
from `x509.c`.
2019-06-25 09:06:26 +01:00
Hanno Becker
83cd8676fa Remove sig_oid parameter from mbedtls_x509_sig_alg_gets()
The function `mbedtls_x509_sig_alg_gets()` previously needed the
raw ASN.1 OID string even though it is implicit in the PK and MD
parameters.

This commit modifies `mbedtls_x509_sig_alg_gets()` to infer the OID
and remove it from the parameters.

This will be needed for the new X.509 CRT structure which will
likely not store the signature OID.

Care has to be taken to handle the case of RSASSA-PSS correctly,
where the hash algorithm in the OID list is set to MBEDTLS_MD_NONE
because it's only determined by the algorithm parameters.
2019-06-25 09:06:26 +01:00
Hanno Becker
b40dc58a83 Introduce a helper macro to check for ASN.1 string tags
This commit introduces a macro `MBEDTLS_ASN1_IS_STRING_TAG`
that can be used to check if an ASN.1 tag is among the list
of string tags:
- MBEDTLS_ASN1_BMP_STRING
- MBEDTLS_ASN1_UTF8_STRING
- MBEDTLS_ASN1_T61_STRING
- MBEDTLS_ASN1_IA5_STRING
- MBEDTLS_ASN1_UNIVERSAL_STRING
- MBEDTLS_ASN1_PRINTABLE_STRING
- MBEDTLS_ASN1_BIT_STRING
2019-06-25 09:00:25 +01:00
Hanno Becker
5882dd0856 Remove CRT digest from SSL session if !RENEGO + !KEEP_PEER_CERT
If `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` is not set, `mbedtls_ssl_session`
contains the digest of the peer's certificate for the sole purpose of
detecting a CRT change on renegotiation. Hence, it is not needed if
renegotiation is disabled.

This commit removes the `peer_cert_digest` fields (and friends) from
`mbedtls_ssl_session` if
   `!MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + !MBEDTLS_SSL_RENEGOTIATION`,
which is a sensible configuration for constrained devices.

Apart from straightforward replacements of
   `if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)`
by
   `if !defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) && \
        defined(MBEDTLS_SSL_RENEGOTIATION)`,
there's one notable change: On the server-side, the CertificateVerify
parsing function is a no-op if the client hasn't sent a certificate.
So far, this was determined by either looking at the peer CRT or the
peer CRT digest in the SSL session structure (depending on the setting
of `MBEDTLS_SSL_KEEP_PEER_CERTIFICATE`), which now no longer works if
`MBEDTLS_SSL_KEEP_PEER_CERTIFICATE` is unset. Instead, this function
now checks whether the temporary copy of the peer's public key within
the handshake structure is initialized or not (which is also a
beneficial simplification in its own right, because the pubkey is
all the function needs anyway).
2019-06-19 16:56:51 +01:00
Hanno Becker
d972f005bf Use consistent error messages in check_config.h 2019-06-19 14:59:42 +01:00
Hanno Becker
2984bd2543 Add config sanity check for !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE 2019-06-19 14:59:41 +01:00
Hanno Becker
24bc570814 Improve documentation of mbedtls_ssl_get_peer_cert() 2019-06-19 10:26:50 +01:00
Hanno Becker
3ed64578d2 Improve documentation of MBEDTLS_SSL_KEEP_PEER_CERTIFICATE 2019-06-19 10:26:50 +01:00
Hanno Becker
dd689316d1 Fix indentation of Doxygen comment in ssl_internal.h 2019-06-19 10:26:50 +01:00
Hanno Becker
e669770b52 Remove misleading and redundant guard around restartable ECC field
`MBEDTLS_SSL__ECP_RESTARTABLE` is only defined if
`MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED` is set, which
requires `MBEDTLS_X509_PARSE_C` to be set (this is checked
in `check_config.`). The additional `MBEDTLS_X509_PARSE_C`
guard around the `ecrs_peer_cert` field is therefore not
necessary; moreover, it's misleading, because it hasn't
been used consistently throughout the code.
2019-06-19 10:26:50 +01:00
Hanno Becker
3bf8cdf2f8 Add field for peer's raw public key to TLS handshake param structure
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.
2019-06-19 10:25:01 +01:00
Hanno Becker
32c530ece2 Add raw public key buffer bounds to mbedtls_x509_crt struct
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.
2019-06-19 10:25:01 +01:00
Hanno Becker
2e6d34761f Remove peer CRT from mbedtls_ssl_session if !KEEP_PEER_CERT 2019-06-19 10:25:01 +01:00
Hanno Becker
e4aeb76a2c Parse and verify peer CRT chain in local variable
`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.
2019-06-19 10:25:01 +01:00
Hanno Becker
9fb6e2e203 Extend mbedtls_ssl_session by buffer holding peer CRT digest 2019-06-19 10:25:01 +01:00
Hanno Becker
b90f655a78 Add configuration option to remove peer CRT after handshake 2019-06-19 10:25:01 +01:00
Hanno Becker
869144b3e9 Improve documentation of mbedtls_ssl_get_peer_cert() 2019-06-19 10:25:01 +01:00
Hanno Becker
58fccf2f62 Give ssl_session_copy() external linkage
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.
2019-06-19 10:25:01 +01:00
Hanno Becker
5097cba93c Introduce helper function to determine whether suite uses server CRT
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;
```
2019-06-19 10:25:01 +01:00
Simon Butcher
7400e8fb36 Merge remote-tracking branch 'origin/pr/591' into baremetal 2019-06-18 17:36:45 +01:00
Simon Butcher
f2ef573f2b Merge remote-tracking branch 'origin/pr/598' into baremetal 2019-06-18 15:00:02 +01:00
Simon Butcher
f1ff74574d Merge remote-tracking branch 'origin/pr/597' into baremetal 2019-06-18 14:58:37 +01:00
Hanno Becker
c6043f2b75 Address review comments 2019-06-18 11:05:44 +01:00
Hanno Becker
02a2193f60 Rename MBEDTLS_X509_INFO to !MBEDTLS_X509_REMOVE_INFO 2019-06-18 11:05:44 +01:00
Peter Kolbus
dc470ae8af Reduce code size when mbedtls_x509_*_info() unused
Introduce MBEDTLS_X509_INFO to indicate the availability of the
mbedtls_x509_*_info() function and closely related APIs. When this is
not defined, also omit name and description from
mbedtls_oid_descriptor_t, and omit OID arrays, macros, and types that
are entirely unused. This saves several KB of code space.

Change-Id: I056312613379890e0d70e1d08c34171287c0aa17
2019-06-18 11:05:37 +01:00
Manuel Pégourié-Gonnard
889bbc70b6 Fix unreachable code warnings with armc5
Some TLS-only code paths were not protected by an #ifdef and while some
compiler are happy to just silently remove them, armc5 complains:

Warning:  #111-D: statement is unreachable

Let's make armc5 happy.
2019-06-18 10:56:09 +02:00
Manuel Pégourié-Gonnard
c84511fb1f Add check for undocumented positive option 2019-06-18 10:32:25 +02:00
Manuel Pégourié-Gonnard
41efa2109e Improve documentation of PROTO_NO_TLS 2019-06-18 10:28:52 +02:00
Manuel Pégourié-Gonnard
7667afd4fc Clarify documentation of mbedtls_ssl_context_load() 2019-06-18 10:09:27 +02:00
Manuel Pégourié-Gonnard
cc71c77b5d Fix typos, grammar and wording in documentation 2019-06-18 10:09:27 +02:00
Manuel Pégourié-Gonnard
d87601e3ef Declare and document ssl_context_save()/load()
Also introduce stub definitions so that things compile and link.
2019-06-18 10:09:27 +02:00
Manuel Pégourié-Gonnard
91fa5bade3 Add new config MBEDTLS_SSL_CONTEXT_SERIALIZATION
This is enabled by default as we generally enable things by default unless
there's a reason not to (experimental, deprecated, security risk).

We need a compile-time option because, even though the functions themselves
can be easily garbage-collected by the linker, implementing them will require
saving 64 bytes of Client/ServerHello.random values after the handshake, that
would otherwise not be needed, and people who don't need this feature
shouldn't have to pay the price of increased RAM usage.
2019-06-18 10:09:27 +02:00
Hanno Becker
1abb159e90 Merge branch 'mbedtls-2.16' into baremetal 2019-06-18 09:00:37 +01:00
Simon Butcher
c725e4b34e Merge remote-tracking branch 'origin/pr/590' into baremetal 2019-06-17 17:57:26 +01:00
Simon Butcher
01a8eb21d3 Merge remote-tracking branch 'origin/pr/585' into baremetal 2019-06-17 17:53:41 +01:00