Advertisement

OpenSSL tutorials?

Started by October 07, 2014 07:29 AM
14 comments, last by Evil Steve 10 years, 1 month ago
Hi,

I'm trying to add SSL support to my server app, written in C++ and running on Windows. The primary use for SSL is for making HTTPS requests to Facebook and Twitter for social interaction.
Currently I'm proxying HTTPS via my Apache web server, but I'd like to be able to do the HTTPS directly without needing a proxy.

I'm well versed with socket programming, using BSD sockets, WinSock, and IOCP, with the server using IOCP currently. However, I'm very new to SSL.

Firstly, does anyone know of any good tutorials for OpenSSL? I've got a *very* simple connection going by following this tutorial, but it's a bit... lacking: http://www.ibm.com/developerworks/library/l-openssl/ (And x64 OpenSSL 1.0.1i I think)
I'd like to avoid using the BIO interface if possible, and I'd prefer to layer SSL over my existing socket layer, since that will require minimal code changes.

Secondly, I understand that I need to have a store of CAs to verify the certificates used by a server, which I believe is done with the SSL_CTX_load_verify_locations function. However, if I'm just making client connections, is this call and the CA store required, or is this only if I'm writing an SSL server?

Thanks,
Steve

Well, they have a wiki which includes code samples on client usage. I'd start with that.

If that isn't enough, I'd look at the source of curl and see how they did things.

Advertisement
Also, there's a few blog posts from people trying to do this, and swearing at the terrible and inconsistent design of the API.
Reading through it, I would tend to agree.
If you can use a higher-level library like libcurl, that's probably better for you.
enum Bool { True, False, FileNotFound };

Thanks for the replies; libCurl is probably a good option now I think about it. I had a quick look on google, but most of the tutorials I've found are very high level introductions.

I somehow missed the wiki completely too - I'll have a look through that also.

Cheers,

Steve

There is built-in support for it in Windows APIs, for handshakes and encrypt/decrypt. Found this for example, that wraps send/recv on a socket to properly encode the data: http://www.codeproject.com/Articles/24379/SSL-Convert-your-Plain-Sockets-to-SSL-Sockets-in-a

Why aren't you just using HTTP.SYS... It's part of pretty much every windows distribution since XP SP3... it handles this kind of stuff internally, you can use standard windows certificate management, self signed certificates, etc.

OpenSSL is, frankly, a mess. It's a pain in the ass to use, it's a pain in the ass to use CORRECTLY, and all it takes is ONE SINGLE TRIVIAL mistake and you're encryption is trivially breakable. Why do all that work when someone else has done the work to correctly implement it and secure it, and it's part of every modern windows system?

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364510(v=vs.85).aspx

On the client side you can use WinHTTP, OR ANY OTHER Web API that you prefer. http://msdn.microsoft.com/en-us/magazine/cc716528.aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/aa382925(v=vs.85).aspx

I realize you desire to not replace existing socket code, but using raw sockets to execute HTTP requests (or HTTPS requests) for this kind of stuff is silly. There are a lot of web frameworks out there already written that make it so much simpler to just focus on writing the important code.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Advertisement
Interesting, I didn't know WinHTTP existed. I've been looking into libcurl, and it seems to do exactly what I need with the minimum of fuss.
I've got no compunction in stripping out my existing HTTP code, since it's far from perfect, and was just quickly knocked together - I recently added chunked request support to it, since that wasn't supported before, and Facebook sends some responses back as chunked - so there's no doubt loads of other things it doesn't support that will break in the future.

Cheers,
Steve

I haven't used libcurl. It is probably fine, my biggest concern (if you're worried about security, which I almost always am) is if its been evaluated or tested in any way to ensure that it actually "does the right thing."

WinHTTP is not... perfect, it has re-entrance issues and other problems, but it has had a lot of testing and professional software written using it, which means most of the security side bugs have been killed. I cannot say the same thing for libcurl. It might be a lot like OpenSSL, where very few eyes have actually looked at it and said "oh yeah, this is safe."

Here's a simple example of using WinHTTP to issue a secure request to google for its front page. You need to include the HttpRequest.idl into your project, visual studio will automatically build the appropriate header (mine called it httprequest_h.h). Do note that I'm using ATL to avoid manually managing memory. Also you can specify a certificate path and explicitly pick out a certificate to use if you wanted. I selected the client default certificate.


#include <string>
#include <Windows.h>
#include <atlbase.h>
#include "httprequest_h.h"

struct ScopedComInitialize {
	ScopedComInitialize() {
		CoInitialize(0);
	}

	~ScopedComInitialize() {
		CoUninitialize();
	}
};

int main()
{
	ScopedComInitialize s;
	CComPtr<IWinHttpRequest> request;

	HRESULT hr = CoCreateInstance(CLSID_WinHttpRequest, nullptr, CLSCTX_INPROC_SERVER, IID_IWinHttpRequest, reinterpret_cast<void**>(&request.p));

	if (FAILED(hr)) {
		std::cout << "Failed to create HTTP request." << std::endl;
		return -1;
	}

	CComBSTR url("https://www.google.com/");
	CComBSTR method("GET");
	CComVariant isAsync(false);
	
	hr = request->Open(method, url, isAsync);
	if (FAILED(hr)) {
		std::cout << "Failed to open secure connection to google.com" << std::endl;
		return -1;
	}

	hr = request->SetClientCertificate(CComBSTR(""));
	if (FAILED(hr)) {
		std::cout << "Failed to set client certificate." << std::endl;
		return -1;
	}

	CComVariant empty;
	empty.ChangeType(VT_ERROR);

	hr = request->Send(empty);
	if (FAILED(hr)) {
		std::cout << "Failed to send request to google.com" << std::endl;
		return -1;
	}

	CComBSTR responseText;
	hr = request->get_ResponseText(&responseText);

	if (FAILED(hr)) {
		std::cout << "Failed to read response text." << std::endl;
		return -1;
	}

	std::cout << CW2A(responseText) << std::endl;
	return 0;
}

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

my biggest concern (if you're worried about security, which I almost always am) is if its been evaluated or tested in any way to ensure that it actually "does the right thing."


Given that most Linux and even BSD distribution package managers end up relying on that library for their package management, I would be very surprised if it had inherent security flaws!
enum Bool { True, False, FileNotFound };

my biggest concern (if you're worried about security, which I almost always am) is if its been evaluated or tested in any way to ensure that it actually "does the right thing."


Given that most Linux and even BSD distribution package managers end up relying on that library for their package management, I would be very surprised if it had inherent security flaws!

Heh. Heh. HAHAHAHAHAHAHAHAHA. Oh you, such a joker. Man... you're hilarious. The way you said that with such a deadpan expression on your face... if one didn't know better, one might think you were being serious.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

This topic is closed to new replies.

Advertisement