This is the first step towards making verify_chain() iterative. While from a
readability point of view the current recursive version is fine, one of the
goals of this refactoring is to prepare for restartable ECC integration, which
will need the explicit stack anyway.
Besides avoiding near-duplication, this avoids having three generations of
certificate (child, parent, grandparent) in one function, with all the
off-by-one opportunities that come with it.
This also allows to simplify the signature of verify_child(), which will be
done in next commit.
This is from the morally 5th (and soon obsolete) invocation of this function
in verify_top().
Doing this badtime-skipping when we search for a parent in the provided chain
is a change of behaviour, but it's backwards-compatible: it can only cause us
to accept valid chains that we used to reject before. Eg if the peer has a
chain with two version of an intermediate certificate with different validity
periods, the first non valid and the second valid - such cases are probably
rare or users would have complained already, but it doesn't hurt to handle it
properly as it allows for more uniform code.
This may look like a behaviour change because one check has been added to the
function that was previously done in only one of the 3 call sites. However it
is not, because:
- for the 2 call sites in verify(), the test always succeeds as path_cnt is 0.
- for the call site in verify_child(), the same test was done later anyway in
verify_top()
There are 3 instance that were replaced, but 2 instances of variants of this
function exist and will be handled next (the extra parameter that isn't used
so far is in preparation for that):
- one in verify_child() where path_cnt constraint is handled too
- one in verify_top() where there is extra logic to skip parents that are
expired or future, but only if there are better parents to be found
This is a slight change of behaviour in that the previous condition was:
- same subject
- signature matches
while the new condition is:
- exact same certificate
However the documentation for mbedtls_x509_crt_verify() (note on trust_ca)
mentions the new condition, so code that respected the documentation will keep
working.
In addition, this is a bit faster as it doesn't check the self-signature
(which never needs to be checked for certs in the trusted list).
When we're looking for a parent, in trusted CAs, 'top' should be 1.
This only impacted which call site for verify_top() was chosen, and the error
was then fixed inside verify_top() by iterating over CAs again, this time
correctly setting 'top' to 1.
This is the beginning of a series of commits refactoring the chain
building/verification functions in order to:
- make it simpler to understand and work with
- prepare integration of restartable ECC
md() already checks for md_info == NULL. Also, in the future it might also
return other errors (eg hardware errors if acceleration is used), so it make
more sense to check its return value than to check for NULL ourselves and then
assume no other error can occur.
Also, currently, md_info == NULL can never happen except if the MD and OID modules
get out of sync, or if the user messes with members of the x509_crt structure
directly.
This commit does not change the current behaviour, which is to treat MD errors
the same way as a bad signature or no trusted root.
Fix a resource leak on windows platform, in mbedtls_x509_crt_parse_path,
in case a failure. when an error occurs, goto cleanup, and free the
resource, instead of returning error code immediately.
If we didn't walk the whole chain, then there may be any kind of errors in the
part of the chain we didn't check, so setting all flags looks like the safe
thing to do.
By default, keep allowing SHA-1 in key exchange signatures. Disabling
it causes compatibility issues, especially with clients that use
TLS1.2 but don't send the signature_algorithms extension.
SHA-1 is forbidden in certificates by default, since it's vulnerable
to offline collision-based attacks.
Default to forbidding the use of SHA-1 in TLS where it is unsafe: for
certificate signing, and as the signature hash algorithm for the TLS
1.2 handshake signature. SHA-1 remains allowed in HMAC-SHA-1 in the
XXX_SHA ciphersuites and in the PRF for TLS <= 1.1.
For easy backward compatibility for use in controlled environments,
turn on the MBEDTLS_TLS_DEFAULT_ALLOW_SHA1 compiled-time option.
Fixes a regression introduced by an earlier commit that modified
x509_crt_verify_top() to ensure that valid certificates that are after past or
future valid in the chain are processed. However the change introduced a change
in behaviour that caused the verification flags MBEDTLS_X509_BADCERT_EXPIRED and
MBEDTLS_BADCERT_FUTURE to always be set whenever there is a failure in the
verification regardless of the cause.
The fix maintains both behaviours:
* Ensure that valid certificates after future and past are verified
* Ensure that the correct verification flags are set.
This PR fixes a number of unused variable/function compilation warnings
that arise when using a config.h that does not define the macro
MBEDTLS_PEM_PARSE_C.
This change fixes a regression introduced by an earlier commit that
modified x509_crt_verify_top() to ensure that valid certificates
that are after past or future valid in the chain are processed. However
the change introduced a change in behaviour that caused the
verification flags MBEDTLS_X509_BADCERT_EXPIRED and
MBEDTLS_BADCERT_FUTURE to always be set whenever there is a failure in
the verification regardless of the cause.
The fix maintains both behaviours:
* Ensure that valid certificates after future and past are verified
* Ensure that the correct verification flags are set.
To do so, a temporary pointer to the first future or past valid
certificate is maintained while traversing the chain. If a truly valid
certificate is found then that one is used, otherwise if no valid
certificate is found and the end of the chain is reached, the program
reverts back to using the future or past valid certificate.
Allow the size of the entry_name character array in x509_crt.c to be
configurable through a macro in config.h. entry_name holds a
path/filename string. The macro introduced in
MBEDTLS_X509_MAX_FILE_PATH_LEN.