I am building an HTTP(S) server on Intel SGX, using mbedtls as my TLS library.
I can serve content as expected using HTTP, but when switching over to TLS/SSL using mbedtls I am getting some more complex issues and the error messages are difficult to understand.
Concretely, when I access my site using the “https://” prefix, I can tell that mongoose/mbedtls goes out and reads cert.pem and key.pem, and then makes a recv call on “/”. During that recv call it coughs up the following error:
mg_ssl_if_mbed_err 0x7f9e8c023060 mbedTLS error: -0x7780
From mbedtls src I can read this slightly not so useful explanation:
#define MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE -0x7780 /**< A fatal alert message was received from our peer. */
My starting point is the simplest_web_server_ssl.
Questions:
How do I enable mg and mbedtls debug logging?
How do I interpret these errors (or even; what can be some reasons for this error)?
Sincerely grateful for any hints!
See https://github.com/cesanta/mongoose/blob/6.16/mongoose.c#L5161
and https://github.com/cesanta/mongoose/blob/6.16/mongoose.c#L5075
Thus you can increase debug log level by calling cs_log_set_level(LL_VERBOSE_DEBUG)
The error you see is most probably due to the invalid cert your client does not accept.
Try to access your server by curl -k https://IPADDR
-k option disables cert verification. If that curl command works, then just fix your cert - your C code works fine.
Related
Using the grpc version 1.38.0, compiled on CentOS 7 from sources with gcc version 9.4.0 and cmake version 3.19.6 (with all the cmake dependencies set to "module"), the following code taken from the grpc documentation site:
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
auto channel = grpc::CreateChannel(server_name, channel_creds);
compiles, links, runs, does not coredump but the respective grpc calls executed against that channel all fail with the following error message:
E0816 17:49:03.236686130 14443 ssl_transport_security.cc:1468] Handshake failed with fatal error SSL_ERROR_SSL: error:100000f7:SSL routines:OPENSSL_internal:WRONG_VERSION_NUMBER.
Since the referenced above google's documentation sample that implements
the simplest authentication scenario, where a client just wants to authenticate the server and encrypt all data
is taken to be complete, the respective grpc c++ server was bound to a needed port via the grpc::InsecureServerCredentials() option.
Clearly, either the sample code is not complete or some other instructions on how to implement "the simplest authentication scenario, where a client just wants to authenticate the server and encrypt all data" are missing.
Question: could someone please provide a complete c++ code that must be written on both the grpc c++ client side and the grpc c++ server side so that the much advertised "simplest authentication scenario, where a client just wants to authenticate the server and encrypt all data" actually works and the encrypted bytes do flow over the wire from a grpc c++ client to its grpc c++ server and the said grpc c++ server decrypts these bytes and passes them onto the underlying application? Along with any other non code instructions if those are needed.
Changing the code on the grpc c++ server side to use the grpc::SslServerCredentials( grpc::SslServerCredentialsOptions() ) leads to a code that compiles, links, runs but quickly dumps core with the following error message:
E0816 19:24:26.270527688 15081 ssl_security_connector.cc:268] Handshaker factory creation failed with TSI_INVALID_ARGUMENT.
E0816 19:24:26.270775700 15081 server_secure_chttp2.cc:124] {"created":"#1629141866.270756657","description":"Unable to create secure server with credentials of type Ssl","file":"/opt/grpc_source/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc","file_line":104}
Segmentation fault
Running both the grpc c++ client and the grpc c++ server (on two different CentOS 7 boxes) in the "clear text" or "non secure" mode works perfectly fine - the said client happily packages its data into the protobuf message, executes the grpc call, the grpc c++ server receives the message and all is good.
Does anyone have any idea about what has to be done on the grpc c++ server side, I suspect, so that the functionality advertised on the grpc documentation site actually works - I am not looking to mess about with the custom certificate files, if it can be helped at all.
Using the default and built-in Ssl/Tls mechanism of the native grpc libraries is perfectly fine. In other words, some minimal viable grpc security is sufficient.
Thank you for any constructive insight.
I'm trying to send a client certificate to a webserver that requires it.
If I make the request from the command line curl command, it works.
I pass --key filename and --cert filename and everything works fine.
When I do it from the libcurl library, I do this:
curl_easy_setopt(curl, CURLOPT_SSLCERT, client_cert_file.c_str());
curl_easy_setopt(curl, CURLOPT_SSLKEY, client_key_file.c_str());
Same exact thing, the server says the client certificate is missing.
I tried doing things like giving it a nonexistent filename in hopes of provoking some other error messages that might give me a clue what's wrong, but libcurl (and command line curl for that matter) with verbose on don't yield any error messages when something goes wrong. Surely there's a failure case, but nothing is yielding me any kind of error to follow up on.
Is there any way to get more diagnostics out of libcurl?
Pulling what's left of my hair out here.
This is on windows 10 by the way, we built libcurl ourselves. SSL is built in, https connections work, I just can't get it to send the client cert and there's no indication what's going wrong.
UPDATE:
I think I found my problem...
https://curl.haxx.se/docs/todo.html#Add_support_for_client_certifica
Does anybody know how to make this work?
Okay so I worked something out.
It turns out you can build libcurl on windows with openssh or schannel.
If you use schannel, then the CURLOPT_SSLCERT and CURLOPT_SSLKEY do nothing. (no warning or error mind you.)
Maybe they do do something, in relation to schannel, but I couldn't find any docs on that.
So in short if you build libcurl with openssl you can supply a client cert to send in the TLS handshake.
The tipoff was here:
https://curl.haxx.se/docs/todo.html#Add_support_for_client_certifica
Support for CURLOPT_SSLCERT in conjunction with WinSSL/SChannel was added in curl 7.60.0 (changelog).
As the documentation for CURLOPT_SSLCERT states:
Client certificates must be specified by a path expression to a certificate store. [...] You can use "<store location>\<store name>\<thumbprint>" to refer to a certificate in the system certificates store, for example, "CurrentUser\MY\934a7ac6f8a5d579285a74fa61e19f23ddfe8d7a". [...] Following store locations are supported: CurrentUser, LocalMachine, CurrentService, Services, CurrentUserGroupPolicy, LocalMachineGroupPolicy, LocalMachineEnterprise.
I came to you today because I've got a problem with my Client+Server app. I built a server and client app which were working fine with QTcpSocket but I thought about adding some security and going for QSslSocket with delayed handshake. The problem is that my client is acting really weirdly. Here is the situation :
If I use connectToHostEncrypted() in my Client and call startServerEncryption() just after geting the socket in my incomingConnection slot it works fine.
But if I delay the handshake (by doing some read/write in the socket) and call later startServerEncryption(), I got the error : Error during SSL handshake: error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number on server side. I've also tried to use startClientEncryption() on client side but I get the same error.
The certificate is self-signed and loaded and applied to the socket correctly on server (I checked by testing the first situation with openssl s_client and the server accept all the protocol that I can test with (SSLv3, TLSv1, TLSv1.1, TLSv1.2).I cannot test with SSLv2 : on the Client, using this protocol with QSslSocket::setProtocol(QSsl::SslV2) show the error unsupported protocol and openssl s_client won't connect with the -ssl2 argument, it just show the available arguments.
I'm using Qt 5.9.1 and I've installed OpenSSL-Win32 v1.0.2L to get the dlls. I'm also compiling with msvc2015 32bit on Windows 7 64bit.
I hope that you can help me (and sorry for my bad english), Nicolas.
I've just found my error : I was using a readyRead slot which was using socket->readAll() and that prevented the SSL handshake ! I've also discovered that you need to call both startClientEncryption and startServerEncryption to make a SSL handshake.
I'm developing a client and a Threaded server in C++ but I'm facing problems with OpenSSL/TLS integration.
So far, I've followed the ThriftServer.cpp and ThriftClient.cpp but I'm getting random errors which cause the crash of my application.
Specifically, the crash happens when a client tries to call the defined thrift interface on the server (already live)
/* server init with PEM public/private certificates
* and trusted certificates, socketFactory->accept(true),
* transport->open() */
myServer->start(); //running on separated thread, calling thriftserver->serve();
/* client init with PEM public/private certificates
* and trusted certificates, socketFactory->accept(true),
* transport->open() */
myClient->beginSession(); //Thrift API call - crash
The crashes are really generic: sometimes it gives me
TConnectedClient died: SSL_accept: error 0
and sometimes
TConnectedClient died: SSL_accept: parse tlsext
and both ending with SIGSEV.
I am running a Debian 8.1 x64 with latest OpenSSL 1.0.2d compiled from sources and flag enable-tlsext, thrift from github/trunk and libevent from github/trunk.
I've tried my custom self-signed certificates and the testing certificates shipped with Thrift: in both cases it doesn't work, but they are working with openssl s_client and openssl s_server
Any idea about the cause of these errors?
EDIT
I've compiled OpenSSL with Thread support (threads flag on ./configure) and now my application triggers always the error
SSL_shutdown: broken pipe
when the client tries to contact the server. Digging more in details, the openssl s_client triggers a
sslv3 alert handshake failure
using TLSv1.2 as protocol. I've checked this other Stackoverflow question but it didn't help, as long as I'm using the latest OpenSSL snapshot already
Regarding the SSL_shutdown problem, according to this document, you are supposed ignore the SIGPIPE signal to avoid server crashes:
SIGPIPE signal
Applications running OpenSSL over network connections may crash if SIGPIPE is not ignored. This happens when they receive a connection reset by remote peer exception, which somehow triggers a SIGPIPE signal. If not handled, this signal would kill the application.
This can be done with:
#include <csignal>
// ...
signal(SIGPIPE, SIG_IGN);
I am searching for a client TLS connection example in C++. Best for Visual Studio, but honestly it can be any compiler. I found several C samples. But no one worked. I started with this sample in C:
https://wiki.openssl.org/index.php/SSL/TLS_Client
But it failes on
res = BIO_do_connect(web);
with "system library" if I want to connect to my own node.js server (using the direct ip address) or with "bad hostname lookup" using encrypted.google.com as url.
Both with libressl and Visual Studio 2013.
Next stop: http://fm4dd.com/openssl/sslconnect.htm
Here the program runs successful. But any attempt to write to the SSL connection at the end with:
std::string json = "{'test':'huhu'}";
char buff[1024];
sprintf(buff, "POST /test.de HTTP/1.1 \nHost: test.de\nContent-Type: application/json\nContent-Length: %d\n\n", json.length());
std::string post = buff;
int snd = SSL_write(ssl, post.data(), post.length());
snd = SSL_write(ssl, json.data(), json.length());
forces the server to close the connection (I do not see exactly what happend as I do not now how I can tell node.js to tell me more).
So I search for a working sample or how to get a TLS connection with own certificate running in C++
I am searching for a client TLS connection example in C++.
I think there are a couple of ports of OpenSSL to C++. They try to do the full class wrapper thing. See openssl++ class on Google.
When I use it in C++, I use unique pointers for cleanup. See, for example, How to properly print RSA* as string in C++?. I use it primarily to ensure cleanup. I think its similar to Resource Acquisition Is Initialization pattern.
OpenSSL also provides a page for similar libraries and frameworks. See the Related Links page on the OpenSSL wiki.
But it fails on
res = BIO_do_connect(web);
with "system library" if I want to connect to my own node.js server (using the > direct ip address) or with "bad hostname lookup"
My guess here would be the name in the certificate does not match the name used in the URL to connect.
You can make the names work by adding an entry in your host file. Effectively, this is your local DNS override. See Microsoft TCP/IP Host Name Resolution Order.
Or, you can generate a certificate with all the required names. For that, see How to create a self-signed certificate with openssl?
forces the server to close the connection (I do not see exactly what happend as I do not now how I can tell node.js to tell me more).
"POST /test.de HTTP/1.1 \nHost: test.de\nContent-Type:
application/json\nContent-Length: %d\n\n"
Since you lack the Connection: close request header, the server is probably following RFC 7230, HTTP/1.1 Message Syntax and Routing, Section 6.1:
A server that does not support persistent connections MUST send the
"close" connection option in every response message that does not
have a 1xx (Informational) status code.
Also, that should probably be:
"POST /test.de HTTP/1.1\r\nHost: test.de\r\nContent-Type:
application/json\r\nContent-Length:%d\r\n\r\n"
\r\n is used as new line, not \r and not \n. A double \r\n is used to terminate the header. You can quickly verify be searching for "CRLF" in the standard. You will land in a discussion of the ABNF grammar.
So I search for a working sample or how to get a TLS connection with own certificate running in C++
The trick here is creating a well-formed certificate. For that, see How to create a self-signed certificate with openssl?
Here's an updated example for LibreSSL using pinned cert bundle: C++ libtls example on github