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.
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.
Fix an issue that caused valid certificates being rejected whenever an
expired or not yet valid version of the trusted certificate was before the
valid version in the trusted certificate list.
- basicContraints checks are done during verification
- there is no need to set extensions that are not present to default values,
as the code using the extension will check if it was present using
ext_types. (And default values would not make sense anyway.)
Remove check on the pathLenConstraint value when looking for a parent to the
EE cert, as the constraint is on the number of intermediate certs below the
parent, and that number is always 0 at that point, so the constraint is always
satisfied.
The check was actually off-by-one, which caused valid chains to be rejected
under the following conditions:
- the parent certificate is not a trusted root, and
- it has pathLenConstraint == 0 (max_pathlen == 1 in our representation)
fixes#280
* iotssl-515-max-pathlen:
Add Changelog entries for this branch
Fix a style issue
Fix whitespace at EOL issues
Use symbolic constants in test data
Fixed pathlen contraint enforcement.
Additional corner cases for testing pathlen constrains. Just in case.
Added test case for pathlen constrains in intermediate certificates
This helps in the case where an intermediate certificate is directly trusted.
In that case we want to ignore what comes after it in the chain, not only for
performance but also to avoid false negatives (eg an old root being no longer
trusted while the newer intermediate is directly trusted).
closes#220
Assume we have two trusted CAs with the same name, the first uses ECDSA 256
bits, the second RSA 2048; cert is signed by the second. If we do the keysize
check before we checked the key types match, we'll raise the badkey flags when
checking the EC-256 CA and it will remain up even when we finally find the
correct CA. So, move the check for the key size after signature verification,
which implicitly checks the key type.
Just applying rename.pl with this file:
mbedtls_cipher_get_key_size mbedtls_cipher_get_key_bitlen
mbedtls_pk_get_size mbedtls_pk_get_bitlen
MBEDTLS_BLOWFISH_MIN_KEY MBEDTLS_BLOWFISH_MIN_KEY_BITS
MBEDTLS_BLOWFISH_MAX_KEY MBEDTLS_BLOWFISH_MAX_KEY_BITS
- allows to express 'none' or 'all' more easily than lists
- more compact and easier to declare statically
- easier to check too
Only drawback: if we ever have more than 32 curves, we'll need an ABI change to
make that field a uint64_t.
* mbedtls-1.3:
Mark unused constant as such
Update ChangeLog for recent external bugfix
Serious bug fix in entropy.c
Fix memleak with repeated [gc]cm_setkey()
fix minor bug in path_cnt checks
Conflicts:
include/mbedtls/cipher.h
library/ccm.c
library/entropy.c
library/gcm.c
library/x509_crt.c
If the top certificate occurs twice in trust_ca (for example) it would
not be good for the second instance to be checked with check_path_cnt
reduced twice!
- more freedom for us to change it in the future
- enforces hygiene
- performance impact of making accessors no longer inline should really be
negligible
Still todo:
- handle MGF-hash != sign-hash
- check effective salt len == announced salt len
- add support in the PK layer so that we don't have to bypass it here