Skip to content
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

bearssl_validation example invalid public key #5086

Closed
chegewara opened this issue Aug 28, 2018 · 9 comments
Closed

bearssl_validation example invalid public key #5086

chegewara opened this issue Aug 28, 2018 · 9 comments
Assignees
Labels
component: examples component: TLS type: bug waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Milestone

Comments

@chegewara
Copy link

This public key seems to be invalid:
https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation.ino#L134-L140

This is valid public key:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy+3Up8qBkIn/7S9AfWlH
Od8SdXmnWx+JCIHvnWzjFcLeLvQb2rMqqCDL5XDlvkyC5SZ8ZyLITemej5aJYuBv
zcKPzyZ0QfYZiskU9nzL2qBQj8alzJJ/Cc32AWuuWrPrzVxBmOEW9gRCGFCD3m0z
53y6GjcmBS2wcX7RagqbD7g2frEGko4G7kmW96H6dyh2j9Rou8TwAK6CnbiXPAM/
5Q6dyfdYlHOCgP75F7hhdKB5gpprm9A/OnQsmZjUPzy4u0EKCxE8MfhBerZrZdod
88ZdDG3CvTgm050bc+lGlbsT+s09lp0dgxSZIeI8+syV2Owt4YF/PdjeeymtzQdI
wQIDAQAB
@devyte
Copy link
Collaborator

devyte commented Aug 28, 2018

CC @earlephilhower
@chegewara you opened an issue from a code line, didn't you? And you didn't see the issue template?

@earlephilhower
Copy link
Collaborator

@chegewara BearSSL handles both DER and PEM (base64 and binary) certificates. It's entirely possible the Github cert has changed, they've changed more than once since I started working on BearSSL early this year. That's why it's not a good idea to hardcode certs (unless you control them!), but the code itself is a sample and github seemed like as good a website to show things on as any.

If you've tested the new one extracted in DER format, please put in a PR w/the update and I can merge easily once tested. The certificate SHA1 fingerprint would also be different, if the public key is changed, so please update both.

@chegewara
Copy link
Author

chegewara commented Aug 28, 2018

@earlephilhower I can understand that and im not complaining, just wanted to provide some information (sorry if i dont follow issue template). There is one more question, in this example is also used digicert ca root certificate. This certificate is not changed but fetchCertAuthority is not working too:

A specific certification authority can be passed in and used to validate
a chain of certificates from a given server.  These will be validated
using BearSSL's rules, which do NOT include certificate revocation lists.
A specific server's certificate, or your own self-signed root certificate
can also be used.  ESP8266 time needs to be valid for checks to pass as
BearSSL does verify the notValidBefore/After fields.
Try validating without setting the time (should fail)
Trying: api.github.com:443...*** Can't connect. ***
-------
Try again after setting NTP time (should pass)
Waiting for NTP time sync: .
Current time: Tue Aug 28 05:38:00 2018
Trying: api.github.com:443...*** Can't connect. ***

I may not understand some things yet, but another weird thing with this example is when i move setClock() just few lines above i get this log output (first time with set time i can connect but not second time). Code:

  setClock();
  BearSSL::WiFiClientSecure client;
  BearSSLX509List cert(digicert);
  client.setTrustAnchors(&cert);
  Serial.printf("Try validating without setting the time (should fail)\n");
  fetchURL(&client, host, port, path);

  Serial.printf("Try again after setting NTP time (should pass)\n");
  fetchURL(&client, host, port, path);

and logs:

A specific certification authority can be passed in and used to validate
a chain of certificates from a given server.  These will be validated
using BearSSL's rules, which do NOT include certificate revocation lists.
A specific server's certificate, or your own self-signed root certificate
can also be used.  ESP8266 time needs to be valid for checks to pass as
BearSSL does verify the notValidBefore/After fields.
Waiting for NTP time sync: .
Current time: Tue Aug 28 08:02:17 2018
Try validating without setting the time (should fail)
Trying: api.github.com:443...Connected!
-------
HTTP/1.1 200 OK
-------

Try again after setting NTP time (should pass)
Trying: api.github.com:443...*** Can't connect. ***

EDIT for some reason fingerprint match but public key does not

@chegewara
Copy link
Author

chegewara commented Aug 28, 2018

Another strange behavior, when i try two requests then i get response from both:

  fetchKnownKey();
  fetchCertAuthority();

but when i try only fetchCertAuthority(); then i have no response or empty response.

PS this time with my server, not the one from example

@earlephilhower
Copy link
Collaborator

Interesting observations! I'm still traveling so haven't been able to look at this, but do appreciate the debug. The example was running before, believe it or not. My first guess is that something changed in the core that's interacting weirdly now (but just a guess), because the SSL code hasn't really been tweaked recently AFAIR.

BearSSL also just released an 0.6 "official beta" version so I need to update it anyway, so this is a good time to check the plumbing too.

@chegewara
Copy link
Author

Sorry i cant perform more test and to provide more info, but i have limited access to electricity now.
I can say that for some reason connection is not closed, and client->connect(host, port) is closing old connection without opening new one. Anyway, thanks for all support.

@RexLBrownSr
Copy link

I have tried the example with similar results, however, I did some testing to try to discover what may be causing these results. Here is what I have found:

  1. I retrieved a new public key which worked OK.
  2. I modifed the fetchCertAuthority() function to make two calls to another function with the setClock() between them. The sub function did all the work that was previously done in the fetchCertAuthority() except I passed the digicert to the sub function. This seemed to work. I attributed it to something in the client needing to be deleted and re-initialized.
  3. I modified the fetchSelfSigned() in the same way and it also seemed to work. However, strangely now the fetchCertAuthority() connects before and after the setClock() call. Still looking at this...
    Hope this helps somebody.

@RexLBrownSr
Copy link

RexLBrownSr commented Aug 31, 2018

Update on my previous comment:

  1. I went back and commented out the call to the fetchSelfSigned() function and then the fetchCertAuthority() started working as expected again.
  2. I put the function fetchSelfSigned() back and I added a call to print the date and time before the first call the fetchCertAuthority(). The fetchCertAuthority() then began passing in both cases (before and after the setClock() call). HOWEVER, the time and date were correct in both instances (even before the setClock() call. Evidently something in the fetchSelfSigned() function is causing the time and date to be updated.

earlephilhower added a commit to earlephilhower/Arduino that referenced this issue Sep 11, 2018
As part of the "clear connection configuration for reused objects"
patch, a ::stop would reset the self-signed, trust anchors, etc.
WiFiClient, unfortunately, calls ::stop as part of the connection
process, so all of these settings were lost.

Now only clear the connection settings on ::stop if we've already
been connected.

Also update the github public key which changed yet again.

Fixes esp8266#5086
@earlephilhower
Copy link
Collaborator

The root cause was a regression due to the prior update which effectively cleared connection option flags during the connect sometimes. Simple fix and things are back running again (with updated GH key):

WiFi connected
IP address: 
192.168.1.138

If there are no CAs or insecure options specified, BearSSL will not connect.
Expect the following call to fail as none have been configured.
Trying: api.github.com:443...*** Can't connect. ***
-------

This is absolutely *insecure*, but you can tell BearSSL not to check the
certificate of the server.  In this mode it will accept ANY certificate,
which is subject to man-in-the-middle (MITM) attacks.
Trying: api.github.com:443...Connected!
-------
HTTP/1.1 200 OK
-------


The SHA-1 fingerprint of an X.509 certificate can be used to validate it
instead of the while certificate.  This is not nearly as secure as real
X.509 validation, but is better than nothing.
Trying: api.github.com:443...Connected!
-------
HTTP/1.1 200 OK
-------


It is also possible to accept *any* self-signed certificate.  This is
absolutely insecure as anyone can make a self-signed certificate.
First, try and connect to a badssl.com self-signed website (will fail):
Trying: self-signed.badssl.com:443...*** Can't connect. ***
-------
Now we'll enable self-signed certs (will pass)
Trying: self-signed.badssl.com:443...Connected!
-------
HTTP/1.1 200 OK
-------


The server certificate can be completely ignored and its public key
hardcoded in your application. This should be secure as the public key
needs to be paired with the private key of the site, which is obviously
private and not shared.  A MITM without the private key would not be
able to establish communications.
Trying: api.github.com:443...Connected!
-------
HTTP/1.1 200 OK
-------


A specific certification authority can be passed in and used to validate
a chain of certificates from a given server.  These will be validated
using BearSSL's rules, which do NOT include certificate revocation lists.
A specific server's certificate, or your own self-signed root certificate
can also be used.  ESP8266 time needs to be valid for checks to pass as
BearSSL does verify the notValidBefore/After fields.
Try validating without setting the time (should fail)
Trying: api.github.com:443...*** Can't connect. ***
-------
Try again after setting NTP time (should pass)
Waiting for NTP time sync: .

Current time: Tue Sep 11 12:49:30 2018
Trying: api.github.com:443...Connected!
-------
HTTP/1.1 200 OK
-------

@earlephilhower earlephilhower added the waiting for feedback Waiting on additional info. If it's not received, the issue may be closed. label Sep 11, 2018
devyte pushed a commit that referenced this issue Sep 17, 2018
As part of the "clear connection configuration for reused objects"
patch, a ::stop would reset the self-signed, trust anchors, etc.
WiFiClient, unfortunately, calls ::stop as part of the connection
process, so all of these settings were lost.

Now only clear the connection settings on ::stop if we've already
been connected.

Also update the github public key which changed yet again.

Fixes #5086
@devyte devyte added this to the 2.5.0 milestone Sep 17, 2018
d-a-v pushed a commit to d-a-v/Arduino that referenced this issue Sep 18, 2018
As part of the "clear connection configuration for reused objects"
patch, a ::stop would reset the self-signed, trust anchors, etc.
WiFiClient, unfortunately, calls ::stop as part of the connection
process, so all of these settings were lost.

Now only clear the connection settings on ::stop if we've already
been connected.

Also update the github public key which changed yet again.

Fixes esp8266#5086
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: examples component: TLS type: bug waiting for feedback Waiting on additional info. If it's not received, the issue may be closed.
Projects
None yet
Development

No branches or pull requests

4 participants