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

Using basic example #1

Closed
GoldeggCoder opened this issue Nov 9, 2024 · 7 comments
Closed

Using basic example #1

GoldeggCoder opened this issue Nov 9, 2024 · 7 comments

Comments

@GoldeggCoder
Copy link

I have an issue testing this code. I used the exact same code provided but changed my WiFi_SSID, WiFi_Password, Server Address and also the Headers in my HTTP packet. Then i also changed the certificate to:

#define PICOHTTPS_CA_ROOT_CERT                          \
"-----BEGIN CERTIFICATE-----"                           \
"MIIDoTCCA0agAwIBAgIRAMCgnk8GqKH3E4EnkupwH14wCgYIKoZIzj0EAwIwOzEL" \
"MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG" \
"A1UEAxMDV0UxMB4XDTI0MTAwNzAxMTU1NloXDTI1MDEwNTAxMTU1NVowFDESMBAG" \
"A1UEAxMJcmVxcmVzLmluMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEA71Vk0fv" \
"Z+zVMBJlqoFe/8r5I/i2o+pCp3akon+eZqeNDmtuNQFxD3NNUefoG7wVJth7TAIQ" \
"bozF02LcjBvZN6OCAlAwggJMMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggr" \
"BgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSVLSlIP1h3myJJwfdbaPGF" \
"RNmqjDAfBgNVHSMEGDAWgBSQd5I1Z8T/qMyp5nvZgHl7zJP5ODBeBggrBgEFBQcB" \
"AQRSMFAwJwYIKwYBBQUHMAGGG2h0dHA6Ly9vLnBraS5nb29nL3Mvd2UxL3dLQTAl" \
"BggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UxLmNydDAhBgNVHREEGjAY" \
"gglyZXFyZXMuaW6CCyoucmVxcmVzLmluMBMGA1UdIAQMMAowCAYGZ4EMAQIBMDYG" \
"A1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jLnBraS5nb29nL3dlMS8yRHFmUzI0a2Nk" \
"SS5jcmwwggEFBgorBgEEAdZ5AgQCBIH2BIHzAPEAdgDPEVbu1S58r/OHW9lpLpvp" \
"GnFnSrAX7KwB0lt3zsw7CAAAAZJkwwpYAAAEAwBHMEUCICISgPJ2iYDLfEh9peT9" \
"zrBvJgtqhV6MNlzACX4D5AUGAiEA1ZPNMGrSUNE/rkJH/JHoIhqJ4D0+gy4QcO7j" \
"kN7u2AgAdwB9WR4S4XgqexxhZ3xe/fjQh1wUoE6VnrkDL9kOjC55uAAAAZJkww2J" \
"AAAEAwBIMEYCIQCza/6IkB8jvOoJZpws8fnBVqOUa00qjTvWuNHx0rZ/3wIhALko" \
"mZfpUC3g92GA4mO3x39ZYB7SP6tvboVx5WDJfWKnMAoGCCqGSM49BAMCA0kAMEYC" \
"IQDlPor5wtr0tcM3D5sc+ZfXM6RxUByuoy5Fh/SPq9Du+QIhAJeVXCwxbnc8+xMP" \
"he7hNXk7wi7GNozspaeHccgj5HZy" \
"-----END CERTIFICATE-----"

Which is equivalent to the certificate from reqres.in. I get the error "Failed to connect to https://104.26.10.213:443". I debugged a little further and found out that it could not generate "config" in the function "connect_to_host".

cyw43_arch_lwip_begin();
struct altcp_tls_config* config = altcp_tls_create_config_client(
    ca_cert,
    LEN(ca_cert)
);
cyw43_arch_lwip_end();

I am using Pico SDK 1.5.0

@marceloalcocer
Copy link
Owner

Hmm, I see a few issues here;

  1. The certificate above is in PEM format. The example Mbed TLS configuration (mbedtls_config.h) does not enable PEM certificate parsing, so only certificates in binary (DER) format are supported. To use PEM certificates, you will need to add #define MBEDTLS_BASE64_C and #define MBEDTLS_PEM_PARSE_C to mbedtls_config.h.
  2. PEM certificates must be wrapped to 64 chars. As such, you will need to add \n before each line continuation of your #define PICOHTTPS_CA_ROOT_CERT
  3. The certificate above seems to be reqres.in's certificate rather than the CA's certificate used to sign it. The first CA certificate in the current chain belongs to WE1. This is what should be used in #define PICOHTTPS_CA_ROOT_CERT

Note though that even addressing these issues, I am still struggling to connect to reqres.in specifically. I suspect this is because its certificate is signed using ECDSA rather than PKCS. I think that Mbed TLS should support ECDSA signatures, but cannot seem to find the correct combination of options to get it working 😞

Will keep digging though and let you know if I get it working.

In the meantime, you should be able to get the example working with a server supplying a PKCS signed certificate, e.g. example.edu, mozilla.org, etc.

@GoldeggCoder
Copy link
Author

GoldeggCoder commented Nov 11, 2024

Thanks for the reply.

I did following steps:

  1. Adding #define MBEDTLS_BASE64_C and #define MBEDTLS_PEM_PARSE_C
  2. Adding \n to the the #define PICOHTTPS_CA_ROOT_CERT
  3. Changed from the certificate from reqres.in's to a self signed certificate described here

Now i can connect to the server. However the error callback function gets called with the LwIP Error Code -15 Connection error [lwip_err_t err == -15], even though afterwards I get the message that the Connection is established.

Log:
Resolving example.edu
Resolved example.edu (93.184.215.14)
Connecting to https://93.184.215.14:443
Connection error [lwip_err_t err == -15]
Connected to https://93.184.215.14:443
Sending request
Failed to send request

This is the Request if that helps:
#define PICOHTTPS_REQUEST \
"GET / HTTP/1.1\r\n" \
"Host: " PICOHTTPS_HOSTNAME "\r\n" \
"\r\n"

@GoldeggCoder
Copy link
Author

Have you found anything new?

@marceloalcocer
Copy link
Owner

Ok, so I think we've got this working now. The debug was a bit trickier than expected! 😅

Turns out the issue was not a lack of client-side ECDSA support, but rather the server aborting the TLS handshake (fatal alert 40) due to a missing Server Name Indication TLS extension from the client (in the ClientHello message). This seems to be a de-facto requirement for many servers nowadays, and they will abort the connection somewhat opaquely if it's missing.

The SNI extension is enabled in Mbed TLS with MBEDTLS_SSL_SERVER_NAME_INDICATION, but is not currently exposed in the ALTCP compatible Mbed TLS port bundled with the lwIP code base. This is a known missing feature of lwIP (see lwip-tcpip/lwip#47, and more specifically lwip-tcpip/lwip@c53c9d0).

The supplied patch is for Mbed TLS v3.6 however, and so cannot be applied cleanly to the Mbed TLS code base supplied in the Pico SDK 1.5.0. The corresponding equivalent would be something like;

diff --git a/usr/local/src/pico-sdk/lib/lwip/src/include/lwip/altcp_tls.h b/usr/local/src/pico-sdk/lib/lwip/src/include/lwip/altcp_tls.h
index fcb784d..4aa9940 100644
--- a/usr/local/src/pico-sdk/lib/lwip/src/include/lwip/altcp_tls.h
+++ b/usr/local/src/pico-sdk/lib/lwip/src/include/lwip/altcp_tls.h
@@ -92,7 +92,7 @@ struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t
 /** @ingroup altcp_tls
  * Create an ALTCP_TLS client configuration handle
  */
-struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
+struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len, char* host);
 
 /** @ingroup altcp_tls
  * Create an ALTCP_TLS client configuration handle with two-way server/client authentication
diff --git a/usr/local/src/pico-sdk/lib/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c b/usr/local/src/pico-sdk/lib/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c
index e787ae2..861b23e 100644
--- a/usr/local/src/pico-sdk/lib/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c
+++ b/usr/local/src/pico-sdk/lib/lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c
@@ -107,6 +107,7 @@ struct altcp_tls_config {
   u8_t pkey_count;
   u8_t pkey_max;
   mbedtls_x509_crt *ca;
+  char host[256];
 #if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
   /** Inter-connection cache for fast connection startup */
   struct mbedtls_ssl_cache_context cache;
@@ -633,6 +634,7 @@ altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_
   /* tell mbedtls about our I/O functions */
   mbedtls_ssl_set_bio(&state->ssl_context, conn, altcp_mbedtls_bio_send, altcp_mbedtls_bio_recv, NULL);
 
+  mbedtls_ssl_set_hostname(&state->ssl_context, config->host);
   altcp_mbedtls_setup_callbacks(conn, inner_conn);
   conn->inner_conn = inner_conn;
   conn->fns = &altcp_mbedtls_functions;
@@ -942,7 +944,7 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
 }
 
 static struct altcp_tls_config *
-altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
+altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth, char* host)
 {
   int ret;
   struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL);
@@ -964,13 +966,14 @@ altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2way
 
     mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
   }
+  memcpy(conf->host, host, sizeof(conf->host));
   return conf;
 }
 
 struct altcp_tls_config *
-altcp_tls_create_config_client(const u8_t *ca, size_t ca_len)
+altcp_tls_create_config_client(const u8_t *ca, size_t ca_len, char* host)
 {
-  return altcp_tls_create_config_client_common(ca, ca_len, 0);
+  return altcp_tls_create_config_client_common(ca, ca_len, 0, host);
 }
 
 struct altcp_tls_config *
@@ -986,7 +989,7 @@ altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_
     return NULL;
   }
 
-  conf = altcp_tls_create_config_client_common(ca, ca_len, 1);
+  conf = altcp_tls_create_config_client_common(ca, ca_len, 1, NULL);
   if (conf == NULL) {
     return NULL;
   }

With lwIP patched, all that remains is to pass the server hostname to the altcp_tls_create_config_client() call in picohttps.c;

diff --git a/picohttps.c b/picohttps.c
index 81bf2bc..135ea93 100644
--- a/picohttps.c
+++ b/picohttps.c
@@ -200,7 +200,8 @@ bool connect_to_host(ip_addr_t* ipaddr, struct altcp_pcb** pcb){
     cyw43_arch_lwip_begin();
     struct altcp_tls_config* config = altcp_tls_create_config_client(
         ca_cert,
-        LEN(ca_cert)
+        LEN(ca_cert),
+        PICOHTTPS_HOSTNAME
     );
     cyw43_arch_lwip_end();
     if(!config) return false;

HTH!

marceloalcocer added a commit to marceloalcocer/lwip that referenced this issue Nov 20, 2024
This is a known missing feature;

* [lwip-tcpip#47][gh-lwip-pr]
* [lwip-tcpip/lwip@c53c9d020][gh-lwip-commit]

Added here again for compatibility with [pico-sdk][gh-pico] v1.5.x.
See discussion in [marceloalcocer/picohttps#1][gh-issue] for more
details.

[gh-lwip-pr]: lwip-tcpip#47
[gh-lwip-commit] lwip-tcpip@c53c9d0
[gh-pico]: https://github.com/raspberrypi/pico-sdk
[gh-issue]: marceloalcocer/picohttps#1 (comment)
@GoldeggCoder
Copy link
Author

Thanks a lot for the help! It worked for me.👍 Nevertheless I completely switched to the MicroPython Pico-SDK due to the complexity.

@marceloalcocer
Copy link
Owner

Glad to hear you got it working!
FYI, I've just pushed a workaround which does not require patching lwIP (see 922ef25). Should hopefully make life easier if you ever decide to return to the C/C++ SDK.

@GoldeggCoder
Copy link
Author

Thank you so much for your help. I really appreciate your time and effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants