-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
extmod/modtls_mbedtls: Fix key_len passed to mbedtls_pk_parse_key. #14385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extmod/modtls_mbedtls: Fix key_len passed to mbedtls_pk_parse_key. #14385
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #14385 +/- ##
=======================================
Coverage 98.43% 98.43%
=======================================
Files 161 161
Lines 21281 21281
=======================================
Hits 20948 20948
Misses 333 333 ☔ View full report in Codecov by Sentry. |
dcdd202
to
bb981c8
Compare
Code size report:
|
Thanks for the patch. This looks OK, except that actually mbedtls is not configured to be able to parse PEM files at all. To enable that requries: #define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_BASE64_C As such, it's not possible to write a test for the code added in this PR. What I suggest is to change all cert/key parsing code in And then add optional support for PEM parsing via the following (essentially what this PR does but with a if guard): #if MBEDTLS_PEM_PARSE_C
// len should include terminating null if the data is PEM encoded
if ((key_len >= 10) && (memcmp(key, "-----BEGIN", 10) == 0)) {
key_len += 1;
}
#endif |
bb981c8
to
9943e43
Compare
Yes, I enabled PEM parsing while testing for this bug/patch. The support for PEM parsing was mostly added to this PR to not break the code of people who use PEM. This Patch is mostly to fix the PKCS8 DER parsing that was broken by the update of mbedtls. I have added the |
9943e43
to
6e79721
Compare
Do the calls to
Is it possible to add a test which fails prior to this PR but passes after this PR? In other words, can we add a test that has a PKCS8 DER certificate? How to generate such a certificate? |
After taking a look at When The documentation states the same thing as
The problem seems to be possible, at the end of the function
After some time searching I could not find a way to create a Certificate that triggers this condition causing the parsing to fail. As for the test, in the next iteration I will add a certificate generated like described in #14371 to the tests which will currently fail but will be fixed with this PR. Should I include the fix for |
Yes, please include the fix in this PR. Even if we can't find a test that fails here (passing DER with an extra null byte counted in the length), the documentation is quite clear:
So, if it's not PEM data, it shouldn't include a terminating null byte. |
2bb03e7
to
7aa3934
Compare
I have addde the fix for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for digging into this, @peterzuger!
As damien noted, I ran into the same problem last week after updating ESP-IDF v5.2.2 and dropped in a separate fix here:
b180f1f
... I should have looked at open PRs first and saved myself some time! 😁
I like the idea of increasing the test coverage to include this, although as per my comment I'm not actually sure about what behaviour we should expect on most ports.
extmod/modtls_mbedtls.c
Outdated
@@ -100,6 +100,12 @@ static void mbedtls_debug(void *ctx, int level, const char *file, int line, cons | |||
} | |||
#endif | |||
|
|||
#if defined(MBEDTLS_PEM_PARSE_C) | |||
static int mbedtls_is_pem(const byte *data, size_t len) { | |||
return (len >= 10) && (memcmp(data, "-----BEGIN", 10) == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all PEM data starts with "-----BEGIN" this is used to check if the data is PEM.
This is frustratingly not quite true, because PEM is an outgrowth of a mail format it can contain preceding plaintext.
Suggest using strstr()
like mbedTLS does here: https://github.com/Mbed-TLS/mbedtls/blob/cfe8c4c57d7e71ea4763252e76b20fe019040eb8/tf-psa-crypto/drivers/builtin/src/pkparse.c#L1337
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was kind of aware of this, but I decided to only accept "clean" PEM data (for no particular reason).
Should I change this?
I am in favor of doing it the right way if at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's relatively minor, but I'd say if there's a PEM certificate file that is accepted by desktop mbedTLS and openSSL then it should be accepted by MicroPython as well. Which means allowing preceding text, even if it's not something commonly used.
What do you think about combining my commit and your test addition for this? My version of the fix already uses strstr and it's a little more factored (less duplicate code), and they both do more or less the same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peterzuger The change b180f1f that @projectgus refers to is a little cleaner than the changes here, because it factors the extraction of cert data into a helper function, and only has one location with a conditional check on MBEDTLS_PEM_PARSE_C
. So I would prefer that simpler commit.
The test from this PR is very good though, we definitely want that.
What do you think, shall we take @projectgus 's commit and your test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated this to use strstr
.
7aa3934
to
d24879a
Compare
`mbedtls_pk_parse_key()` expects `key_len` to include the NULL terminator for PEM data but not for DER encoded data. This also applies to `mbedtls_x509_crt_parse()` and `cert_len`. Since all PEM data contains "-----BEGIN" this is used to check if the data is PEM (as per mbedtls code). This can be done for both v2 and v3 of mbedtls since the fundamental behaviour/expectation did not change. What changed is that in v3 the PKCS#8 DER parser now checks that the passed key buffer is fully utilized and no bytes are remaining (all other DER formats still do not check this). Signed-off-by: Peter Züger <[email protected]>
Signed-off-by: Peter Züger <[email protected]>
d24879a
to
1473ed4
Compare
See issue #14371:
mbedtls_pk_parse_key() expects key_len to include the NULL terminator for PEM data but not for DER encoded data.
Since all PEM data starts with "-----BEGIN" this is used to check if the data is PEM.
This can be done for both v2 and v3 of mbedtls since the fundamental behaviour/expectation did not change.
What changed is that in v3 the
PKCS#8
DER parser now checks that the passed key buffer was fully utilized and no bytes are remaining (all other DER formats still do not check this).