I am building realy simple IoT project, and I am stuck on nodeMCU TLS problem. I have MQTT broker on my Raspberry pi, all certificates are correctly inserted (everything working fine with Paho Client on same raspberry or with Mqtt.fx client on remote PC), but when I try to connect from my ESP8266 with nodeMCU I am getting SSL handshake error (yes, I am using same cert file for all mentioned clients). My ESP8266 code looks like this:
tls.cert.verify([[
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
]])
m:connect(config.HOST, 8883, 1, function(con)
print("Connected to MQTT broker")
register_myself()
-- And then pings each 1000 milliseconds
tmr.stop(6)
tmr.alarm(6, 1000, 1, send_ping)
end, handle_mqtt_error)
I am getting error code -5 (mqtt.CONN_FAIL_SERVER_NOT_FOUND) from m:connect, but when I analyze packets using Wireshark it TLS handshake looks like this:
Client Hello
Server Hello
Certificate, Server Hello Done
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Unknown CA)
Also in ESPlorer console there is this line: E:M 544, I dont realy know what that means.
In case someone encountres same thing, my problem was actualy caused by high memory usage in other parts of my project, I used AES for encryption on application layer, without it everything works great.
The ESP8266 is too slow to use certificates reliably. You should upgrade to the ESP32 or something with a little more support for it.
See section 3.2 of this below PDF, referencing SSL handshake failure for ESP8266. This looks similar to your issue. You really have to get creative and lean to make it work reliably, which lowers the value of whatever you are making. So, it might not be worth the hassle.
https://www.espressif.com/sites/default/files/documentation/5a-esp8266_sdk_ssl_user_manual_en.pdf
Also, try TLS 1.1 to see what it does. It might not support TLS 1.2.
Related
I'm trying to understand how to implement client certificate authentication with Kestrel/ASP.Net Core 6.0 on Windows.
So far I was able to successfully authenticate Firefox and Edge with a client certificate to my server prototype.
Now I want to test failures of client certificate authentication due to invalid certificates and decided to begin with a certificate which has expired.
The first issue I faced was that the browsers I am using are not willing to offer the expired certificate for authentication after I imported them into the MS certificate store, so I was hoping that a more versatile client like curl would allow me to do that.
So I set up WSL and figured out how to successfully authenticate curl with a (valid) client certificate to the server.
Then I switched to an expired certificate and happily noticed that I could not connect.
But after looking more closely at the scenario I'm getting the impression that this is because already curl seems to check the certificate and does note seem to even try to use it -- the reason for me to believe this is that my breakpoint in the certificate validation handler of the server are not hit, while they are hit when I'm testing with a valid certificate. In addition, when I disabled the ValidateValidityPeriod in the server CertificateAuthenticationDefaults options this did not have any effect.
(On the other hand, the pertinent message in the curl output
* TLSv1.2 (IN), TLS alert, certificate expired (557):
* OpenSSL SSL_read: error:14094415:SSL routines:ssl3_read_bytes:sslv3 alert certificate expired, errno 0
starts with TLSv1.2 (IN) - this seems to indicate that the certificate validation failure is on server side, doesn't it? I have to admit that I'm confused.)
Has anyone experience with testing the server side of client certificate validation and could hint me
either to convince curl to use the expired (or otherwise invalid) client certificate or
explain to me why the validation handler in Kestrel are not hit in the debugger or
suggest a different tool for that purpose?
(I alread tried the --insecure switch of curl, but that did not seem to help. I was also considering to write my own client, but I don't like testing self-written software with self-written tools).
I'm trying to hit an https endpoint to pull back some data using common-lisp(sbcl). For a while this worked without issue. Then one day I started receiving the following error
SSL error queue:
error:0A000152:SSL routines::unsafe legacy renegotiation disabled
[Condition of type CL+SSL::SSL-ERROR-SSL]
I've tried using both drakma and dexador, but see the same error from both. I've confirmed through openssl that the server I'm trying to connect to does not support renegotiation.
From openssl s_client -connect
New, TLSv1/SSLv3, Cipher is AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
I'm on OSX and my open ssl version is LibreSSL 2.8.3.
So to my understanding my client is trying to initiate renegotiation, but the server is rejecting it. I don't really know where to go from here and at this point I'm not even sure what level the problem is truly at, openSSL, CL+SSL, or the http client libraries built on top of CL+SSL. Is there some way to disable renegotiation, or force a new connection? Is there some setting I'm missing?
In Openssl 1.1.1, the SSL_OP_LEGACY_SERVER_CONNECT flag was turned on by default, but
It is turned off by default as of Openssl 3.0.0.
check the article below
SSL_CTX_set_options(ssl_ctx, SSL_OP_LEGACY_SERVER_CONNECT);
https://www.openssl.org/docs/man3.0/man3/SSL_clear_options.html
I am in a big issue regarding TLSv1.2 and unable to resolve this.
Scenario:
Hostapd should act as an integrated EAP server.I have an openwrt device on which hostapdv2.6-devel is running.
2.Wpa_Supplicant is acting as a client and should talk to hostapd for successful authentication.wpa_supplicantv2.6-devel is running on a different openwrt device.
3.Two way SSL handshake(EAP-TLS) should happen successfully and hostapd should authenticate the client device without any issue.
4.Requirement is that this communication should take place on TLSv1.2 i.e. server (hostapd)is bound to send TLSv1.2.
Configuration:
EAP server(hostapd configuration):
1.Since by default server is sending TLSv1.0 to the client so I made it to send TLSv1.2 forcefully by recompiling the package for TLSv12 and install again on the router.
2.Created a configuration file, which has all the server certificate, ca certificate chain eap_server=1 etc.
3.Started the hostapd process on the device successfully.
client configuration(wpa_supplicant):
1.Created a configuration file, which has all client certificate, CA chain, identity, SSID etc.
2.Started the wpa_supplicant on the device successfully.
SSL transactions:
1.client send client hello message and TLSv1.2 in it.
2.Server responds with server hello message and TLSv1.2
3.Server sends its certificate, serverkeyexchange, certificate request message.
4.Afterward a fatal alert occurs "decode_error" and no more transaction are seen and authentication gets failed.
Please see the wireshark capture below.
ClientHello
ServerHello
Alert Message
Kindly help me to resolve this issue as its making my life difficult.
Please let me know if any other information is required.
Thanks.
I have 100 HTTPS services running on a single server using SNI. (Actually, I don't have access to them. It's an assignment. All I know are their domain names N.xxx.yy where N is in range from 00 to 99.) The goal of the assignment is to evaluate security of every single connection to each of these servers. So some of the servers contain expired certificates, certificates with wrong CN, etc.
My problem is that I cannot get past the handshake on some of the servers. I have written my own application in C++ using OpenSSL, but I've also tried it with openssl s_client. This is how I connect to the server:
openssl s_client -host N.xxx.yy -port 443 -verify 1 -servername N.xxx.yy -CAfile assignment-ca.pem
And this is what I get:
139625941858168:error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:s3_pkt.c:1493:SSL alert number 80
139625941858168:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
In Wireshark, I see that client sent ClientHello, server responded with ServerHello (choosing TLSv1.2 and ECDHE-RSA-AES256-GCM-SHA384) followed by Certificate and then it sent me Alert message containing Internal Error (80).
After trying different thing I have found out that if I run s_client with -tls1 or -tls1_1 I can successfully get past the handshake. -tls1_2 does not work. What is even stranger is that connection through Chrome/Firefox/any other browser succeeds even if TLSv1.2 is negotiated. From what I see, Chrome is sending a different cipher list than me or s_client but even after modifying the cipher list to match the one in Chrome (and making sure that server chooses ECDHE-RSA-AES128-GCM-SHA256), it does not work either. Chrome is sending these TLS extensions, which I don't but most of them seem empty:
Unknown 47802
renegotiation_info
Extended Master Secret
signed_certificate_timestamp
status_request
Application Layer Protocol Negotiation
channel_id
Unknown 6682
Can anybody explain me what is happening here? Unfortunately, I have no way to debug it on the server side so this is all I know.
UPDATE:
After playing around with forged ClientHello messages I managed to track it down to signature_algorithms extension. My app and s_client provide SHA384 + {RSA,DSA,ECDSA} but if I remove these and keep just SHA256 + {RSA,DSA,ECDSA}, as Chrome does, it works and I receive Server Key Exchange message successfully. Could it be that server somehow does not support it, but instead of providing meaningful error message, it just ends unexpectedly and gives me this internal error?
UPDATE 2:
I found answer to why it works with TLS versions prior to 1.2 in RFC5246. Question from the previous UPDATE still holds.
Note: this extension is not meaningful for TLS versions prior to 1.2.
Clients MUST NOT offer it if they are offering prior versions.
However, even if clients do offer it, the rules specified in [TLSEXT]
require servers to ignore extensions they do not understand.
Since you wrote that -tls1_2 does not work I assume either you and/or the server uses an older openssl library. The current version while writing this is 1.1.0e
There were quite some fixes since 0.9.8, which could often be seen on older systems.
For Version 1.0.1 there was this fix, which sounds like your problem:
`Some servers which support TLS 1.0 can choke if we initially indicate
support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
encrypted premaster secret. As a workaround use the maximum permitted
client version in client hello, this should keep such servers happy
and still work with previous versions of OpenSSL.`
Maybe also notable:
Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
So I would suggest to update your openssl-Version and in case of the servers out of your control I would stick to the settings you already found.
I am using AWS ELB as entry point (in Proxy mode) to load balance among 2 HAProxy-es behind it from where traffic goes further to MQTT broker.
Those 2 HAProxies are responsible for client TLS termination (2 way TLS).
Certificates kind of work. I've tested on local setup between 2 servers. I've been able to publish with 2-way TLS, properly terminate it, and publish message to mqtt. Problem arise when moving everything to AWS.
I am using self signed root CA, intermediate CA, server certificate and client certificates. Using Elliptic Curve...
Problem might be due to a servers CN. I think it has to be the same as hostname connecting to with tools like mosquitto_pub.
Error that I get is TLS error, whith debug -> ssl handshake failure. Somehow I am not able to produce more verbose errors. Using openssl with s_client and debug for max debug output. Which produce me ssl handshake failure.
I would really appreciate any hint/suggestion.
Thanks in advance.
Tomaz
I solved this by using subjectAltName feature. I edited openssl.cnf and add new section [alt_names] and reference it later on in configuration. Under alt_names I added 1 DNS key, and 2 IPs. Found with man x509v3_config.
Best,
Tomaz