-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
SSL certificate verification #8854
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
SSL certificate verification #8854
Conversation
Codecov Report
@@ Coverage Diff @@
## master #8854 +/- ##
==========================================
+ Coverage 98.34% 98.37% +0.02%
==========================================
Files 156 156
Lines 20237 20281 +44
==========================================
+ Hits 19902 19951 +49
+ Misses 335 330 -5
Help us with your feedback. Take ten seconds to tell us how you rate us. |
This is great, thanks for this! One comment though, I think |
Great idea, I'll do that and update the PR! |
Actually, it's not quite that simple, because the different boards each use a different epoch (the RP2 uses 1970-1-1, the ESP8266 uses 2000-1-1). I could easily create a per-board module called something like |
I'm not sure, maybe just define the epoch in time modules ? For example in diff --git a/ports/rp2/modutime.c b/ports/rp2/modutime.c
index ac291c893..312381b14 100644
--- a/ports/rp2/modutime.c
+++ b/ports/rp2/modutime.c
@@ -117,6 +117,11 @@ STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
+ #if MICROPY_EPOCH_IS_1970
+ { MP_ROM_QSTR(MP_QSTR_epoch), MP_ROM_INT(1970) },
+ #else
+ { MP_ROM_QSTR(MP_QSTR_epoch), MP_ROM_INT(2000) },
+ #endif
}; Alternatively, could also just add an arg ntptime.time ? diff --git a/ports/esp8266/modules/ntptime.py b/ports/esp8266/modules/ntptime.py
index dd07e46f1..cddc96a4d 100644
--- a/ports/esp8266/modules/ntptime.py
+++ b/ports/esp8266/modules/ntptime.py
@@ -14,7 +14,7 @@ NTP_DELTA = 3155673600
host = "pool.ntp.org"
-def time():
+def time(epoch = 1970):
NTP_QUERY = bytearray(48)
NTP_QUERY[0] = 0x1B
addr = socket.getaddrinfo(host, 123)[0][-1]
@@ -26,7 +26,7 @@ def time():
finally:
s.close()
val = struct.unpack("!I", msg[40:44])[0]
- return val - NTP_DELTA
+ return val - (NTP_DELTA if epoch = 1970 else NTP_DELTA_2000) |
@daviesian Nice to see that this gets some attention 👍🏼
Yes probably is better to move it out one level, it makes sense, I don't know why I didn't that in the first place... RTC check for expiration date is a nice addition as well as PEM format compatibility. IMO I would convert this to a draft and then split this in 2 or 3 PRs which may be easier to review/discuss/merge , one PR could be just rp2 port and the other esp/stm32/rest... 🤔 |
b952c18
to
8ebd8a8
Compare
Thanks @iabdalkader and @Carglglz for your comments and suggestions. I have now updated the branch to address the issue with the duplicated I tried a bunch of different options for overriding the epoch in some ports, and this seemed the cleanest. I have added a README file in the common Recap This PR is an improved version of #8252, which adds full TLS certificate verification to the RP2 port, and factors out the @dpgeorge, are you happy with this? |
Yes this looks really good! (See other previous attempt #4419.) |
9805565
to
4b4843f
Compare
@dpgeorge Thanks a lot for your very sensible suggestions, I've pushed an updated implementation. Is there anything further you'd like me to address? |
ports/rp2/mbedtls/mbedtls_config.h
Outdated
@@ -94,6 +94,8 @@ | |||
#define MBEDTLS_X509_CRT_PARSE_C | |||
#define MBEDTLS_X509_USE_C | |||
|
|||
#define MBEDTLS_BASE64_C | |||
#define MBEDTLS_PEM_PARSE_C |
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.
please split this change into the rp2 commit (so that there's on commit that just touches extmod/modussl_mbedtls.c
)
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.
Done!
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.
But another point of discussion is whether enabling PEM parsing is a good idea. If it's enabled here then it sets a precedence that other ports should follow, otherwise writing portable code is hard (eg using a PEM in code on rp2 won't then work on an stm32 board).
PEM parsing adds a lot of unnecessary overhead (code size and RAM and time), it's much simpler to use DER format. PEM is essentially base-64 encoded DER with header/footer data. So to parse PEM means allocating a chunk of memory to hold the DER and then base-64 decoding the PEM into that buffer, and then using the DER (eg parsing it).
I think for MicroPython we should standardise on using (and documenting how to use) DER format only. I'd be interested to hear your thoughts on this.
In order not to hold up this PR any longer, would be good not enable PEM here, and instead discuss it more widely.
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.
@daviesian any thoughts on this point? My suggestion is to not add these 2 lines in this PR.
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.
@daviesian ping
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.
Sorry for missing this! You're quite right that this doesn't really belong here, although I do think I would be in favour of including it by default. Removed!
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.
FYI @dpgeorge if cadata is in DER format it can contain only one certificate, so in other words without PEM parsing enabled (and PEM data) this function can't load a cert chain (probably should use mbedtls_x509_crt_parse_der
instead and load one DER at a time).
* For certificates in PEM encoding, this may be a concatenation
* of multiple certificates; for DER encoding, the buffer must
* comprise exactly one certificate.
* int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen );
I'm inclined to merge #8252 which does implement the core This PR could then contribute 1) ntptime generalisation; 2) rp2 improvements. |
That sounds like an excellent plan - I would have based this PR off that one if PRs-on-PRs didn't make my head explode. I'll watch for that one being merged, then rebase this one. Thanks! |
4b4843f
to
46de59e
Compare
@daviesian can you please rebase on master now that |
741c248
to
15021cc
Compare
@dpgeorge Sure thing, this is now rebased on |
Can these changes be propagated to other ports, especially the |
That would be great, but I don't have knowledge of, or access to, any other hardware. Once this is merged, it should be as simple as implementing the time hook in this commit for other ports, so the PR/review process should be pretty minimal for those. |
@dpgeorge Is there anything else needed here before merging? It would be great to get this into master! |
See inline comment above. |
The ntptime module was previously only included in the ESP8266 port. This commit factors that module out into the extmod directory.
54feed2
to
0f6bd96
Compare
Sorry for missing the inline comment - I clearly need to improve my Github Notification settings! Anyway, I've now removed those unnecessary |
* This is a reimplementation of micropython#8854 for the stm32 port.
* This is a reimplementation of micropython#8854 for the stm32 port.
* This is a reimplementation of micropython#8854 for the stm32 port.
* This is a reimplementation of micropython#8854 for the stm32 port.
* This is a reimplementation of micropython#8854 for the stm32 port.
* This is a reimplementation of micropython#8854 for the stm32 port.
…n-main Translations update from Hosted Weblate
This PR is an improved and extended version of #8252, which adds support for the
cert_reqs
andca_certs
arguments tossl.wrap_socket
. PR #8252 only verifies the server certificate when doing mutual TLS, but this version verifies the server certificate whenever one is provided andcert_reqs
is set appropriately. This is implemented in the first commit -6dd27ee91d30da, relying heavily on #8252 (thanks @Carglglz!).This PR also verifies certificate time validity on the RP2 port, making use of the RTC. If
cert_reqs
is set tossl.CERT_REQUIRED
, certificates will only be verified successfully if they are valid at the current time. This is implemented in the second commit -e306e2a1664939.Of course, this requires the RTC to be set correctly, so this PR also includes an implementation of the
ntptime
module, copied and modified from the ESP8266 port. This is implemented in the third commit -b97a3424b4843f. Before making SSL connections, developers should callntptime.settime()
or set the RTC to the correct time by some other means.I'm not expecting this PR to be directly merged as-is, but would welcome feedback on the wisdom (or otherwise) of the various choices I've proposed. Namely:
ca_certs
handling logic out one level, so it happens whenever theca_certs
argument is provided. @Carglglz - does this sound sensible?MBEDTLS_BASE64_C
andMBEDTLS_PEM_PARSE_C
to the RP2 port, making it easy for developers to provideca_certs
.If this is broadly acceptable then I'd be happy to polish this PR into something suitable for merging.