I am developing a C++ HTTP/HTTPS client application inside environment of CentOS/Redhat 7.7, which the OS comes with OpenSSL 1.0.2k-fips. But I need at least OpenSSL 1.1.1 for my application. So I compiled OpenSSL 1.1.1f from source.
My compilation configuration.
./Configure linux-x86_64 enable-ec_nistp_64_gcc_128 -Wl,-rpath=/usr/local/lib64 --prefix=/usr/local --openssldir=/usr/local
The problem starts here.
Any requests I make with the new OpenSSL results with Verify return code: 20 (unable to get local issuer certificate). I spent some time switching HTTP clients for C++, which was a very tiring process, only to find out that the issue is with OpenSSL itself.
After a long research, the HTTP client I currently use, shared a ca-bundle inside it's repo. Including it into my project resolved the issue.
https://github.com/yhirose/cpp-httplib/blob/master/example/ca-bundle.crt
cli.set_ca_cert_path(./ca-bundle.crt);
Or with command line,
openssl s_client -connect example.com:443 -CAfile ./ca-bundle.crt
This all seems absurd, I never had to do anything like this before in my experience with developing HTTP clients. Therefore my questions:
Is this a problem with CentOS 7 ?
Did I make a mistake while compiling OpenSSL ? (Followed)
Note: Using cli.set_ca_cert_path("/etc/ssl/certs/ca-bundle.crt"); also works (took me a long time to realize), but I never had to do this manually before, hence forgive my ignorance.
Thanks for your time.
Edit: With the help of some code,
const char* dir = getenv(X509_get_default_cert_dir_env());
if (!dir)
dir = X509_get_default_cert_dir();
cout << dir << endl;
It would seem dir is /usr/local/certs which does not exist. But I also tried this with the default installed OpenSSL inside the OS. Which I would guess should point to the real certificates ?
Edit2: Using /etc/pki/tls/cert.pem also works.
Related
I'm trying to run a simple client/server to implement a communication using QSslSocket. I work on Windows (unfortunately) and I use QtCreator for more convenience.
When I try, from the client side, to connect to the server using MyQSslSocket->connectToHostEncrypted(ip, port), I get the following message:
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
When I print the raised error, I get the following one:
QAbstractSocket::SocketError(20)
In the documentation we can find that this error code corresponds to QAbstractSocket::SslInternalError whose the description is:
"The SSL library being used reported an internal error. This is probably the result of a bad installation or misconfiguration of the library."
After some investigations I found that Qt does not provide OpenSSL by itself so I installed it (the binaries, for both 32 and 64 bits versions to be sure) from here https://slproweb.com/products/Win32OpenSSL.html.
During the installation, the dll was copied to C:\Windows\System32 (for the 64 bits). Then I checked that the PATH environment variable does well contain this folder.
At this point I tried again, but I still had the same problem, as if the OpenSSL installation was still not found.
When I print the output of the following calls (in the main function of my client):
qDebug() << QSslSocket::supportsSsl();
qDebug() << QSslSocket::sslLibraryVersionString();
I get the following outputs:
false""
My question is, how to make QSslSocket::supportsSsl() return true ?
If anyone could teach me what I missed, what I am doing wrong and tell me what I should do to be able to make this SSL connection run properly, I would be very grateful.
Fareanor.
PS: Sorry for the long question but I think it is important to clearly expose the problem and the context to help you to easily understand the problem and give me more relevant answers.
Ok,
Thanks to #AlienPenguin and #Macias advices, it was that my version of OpenSSL was too recent.
Finally I have installed the closest available version of the one used for the Qt build (which does make sense, I should have thought of it) which can be found by running the following call:
qDebug() << QSslSocket::sslLibraryBuildVersionString();
Problem solved.
Thanks again.
I have a very simple MongoDB application that connects to a MongoDB database and works fine.
I've then added the connectivity calls to a large, complex, legacy application and when I call:
mongocxx::instance (i.e. the first MongoDB library call)
I get the following response:
2018/08/16 10:20:59.0499: [16856]: ERROR: mongoc: Failed to initialize OpenSSL.
It appears that the low-level call to SSL_CTX_new within the MongoDB C library is returning a null pointer.
I'm not too sure why this is happening. I've even gone so far as recompiling and linking my simple MongoDB app against all of the libraries that the large legacy app uses (calls to ldd are now identical) but the simple app is still working fine.
This is using the following MongoDB drivers:
mongo-c-driver-1.11.0
mongo-cxx-driver-r3.3.0
Compiled and run on RHEL7 box (7.4) using OpenSSL 1.1.0.
Any suggestions?
I was just in trouble with the same error.
It solved it by changing the option of cmake.
In this way, setting an option, it will work.
cmake -DENABLE_SSL=OFF ..
In the following method, OpenSSL initialization error occurs.
cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP = NO
I'd like to know how to prevent initialization errors with "ENABLE_AUTOMATIC_INIT_AND_CLEANUP".
https://github.com/mongodb/mongo-c-driver/blob/r1.10/NEWS#L935
https://github.com/mongodb/mongo-c-driver/blob/2edd3b2a91171a5da88e9282ffb6a3efbbc2bd91/src/libmongoc/CMakeLists.txt#L225
This problem was solved by make of OpenSSL.
Why 'apt-get install openssl' did not install last version of OpenSSL?
I used the following.
openssl-1.1.0f
mongo-c-driver-1.10.1
mongo-cxx-driver-r3.3.0
How can I use SSL_CTX_set_split_send_fragment?
I include and use ssl and crypto linker in my project but when I build my C++ project I face with this error:
error: ‘SSL_CTX_set_split_send_fragment’ was not declared in this scope
My OpenSSL version is 1.0.1e-fips 11 Feb 2013 and gcc version 4.8.5 20150623.
error: ‘SSL_CTX_set_split_send_fragment’ was not declared in this scope
My OpenSSL version is 1.0.1e-fips 11 Feb 2013 and gcc version 4.8.5 20150623.
If you visit OpenSSL's online man pages at OpenSSL Manpages and navigate into the 1.0.1 branch, and then into The SSL library, you will see its not part of OpenSSL 1.0.1. Its not part of OpenSSL 1.0.2, either.
You should try OpenSSL 1.1.0. That will get you past the compile error. Also see the SSL_CTX_set_split_send_fragment man page :).
Also note that some APIs are missing man pages, so the man pages are not a definitive test for availability. A case where an public API is available but undocumented used to be PKCS12_newpass, if I recall correctly. Its also possible a man page is missing because OpenSSL considers the API private. However, in the case of SSL_CTX_set_split_send_fragment, the API is not present:
$ cd openssl-1.0.2h
$ grep -IR SSL_CTX_set_split_send_fragment *
$
I don't usually see questions about the underlying transport PDU size, the record layer size or fragmentation size. In fact, most of the mobile platforms I work on ignore the TCP SO_* options related to them. Carriers effectively hard code their values and that's it. There's no sense in trying to work around it or improve upon it.
With that said, you can usually find good tuning and performance discussions when researching "time to first byte". One I am familiar with is Optimizing NGINX TLS Time To First Byte (TTTFB). It starts by increasing the write buffer size:
(void) BIO_set_write_buffer_size(wbio, 16384);
But I'm not sure how useful BIO_set_write_buffer_size (or anything else) will be given you don't have access to the clients or the MS SQL server.
I'm using cURL 7.42.1 and MinGW. I'm having problems compiling libcurl with ssl support (for HTTPS). Ive tried defining USE_OPENSSL on lib\curl_setup.h but it still didn't work.
Ive been trying to find a solution to this for hours but i couldn't find one.
You must build libcurl with SSL support enabled, adding a define to curl_setup.h won't have the desired effect.
i.e.:
./configure --with-winssl
Then init curl the following way in your application:
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
/* handle error */
I have a C++ client that connects to servers using libcurl on FreeBSD. The system administrators recently update the FreeBSD image and install ports. The system went from cURL version 7.24.0_2 to cURL version 7.31.0. (File name went from libcurl.so.6 to lib curl.so.7 for what that's worth.)
I recompiled my program to link against the new library.
Now I am getting return value 3 (CURLE_URL_MALFORMAT) from my call to curl_easy_perform(3), and the error message string returned is " malformed".
However, nothing else has changed. The URL is unchanged, and has been verified as correct.
Stranger still, the command line "curl" program works fine; isn't it using the same library?!
I've spent a couple hours reading the release notes for libcurl but couldn't spot anything that suggested a reason as to why this should now fail.
Any suggestions?
Turns out the sysadmins built cURL wrong. A new install and it works.