Skip to main content
GameDev.net gamedev.net
🔒 Locked

OpenSSL tutorials?

Started by Evil Steve Oct 7, 2014 at 7:29 AM 14 replies 10.2k views
Original Post
Evil Steve
Evil Steve
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
frob
frob

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.

hplus0603
hplus0603
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 };
Evil Steve
Evil Steve

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

Washu
Washu
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.
Evil Steve
Evil Steve
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
Washu
Washu

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.
hplus0603
hplus0603

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 };
Washu
Washu


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.
hplus0603
hplus0603

if one didn't know better, one might think you were being serious


If it was Gentoo emerge and Arch pacman, I'd be with you :-) When it's some of the more mature projects, I give them a little more credence.

Also, every script-based web framework under the sun includes libcurl, which means that Facebook, Twitter, and a number of other large sites that are known to actually contribute patches back, have been using it. Thus, I'd trust libcurl over my own implementation on top of first principles.

I would be very surprised if it had inherent security flaws!


And here, the context was assumed as "...that are any worse than the Windows libraries" -- the fact that it's connected to the internet is, in itself, an inherent security flaw :-)
enum Bool { True, False, FileNotFound };
Washu
Washu

If it was Gentoo emerge and Arch pacman, I'd be with you :-) When it's some of the more mature projects, I give them a little more credence.

Also, every script-based web framework under the sun includes libcurl, which means that Facebook, Twitter, and a number of other large sites that are known to actually contribute patches back, have been using it. Thus, I'd trust libcurl over my own implementation on top of first principles.


So... you think that somehow it might have more eyes on it? I have no doubt that people contribute patches, but looking at the github I can see that there are 4 main developers who make up 99% of all commits. This is the SAME problem OpenSSL had, and you can recall how secure that "widely used" library turned out.

More eyes doesn't mean people are actually looking at it. and while it is nice in theory to claim that more eyes means more chances to spot the issues... most of these appear to be just feature additions, not necessarily security reviews and enhancements.

I am not saying one should implement their own SSL, in fact I have stated otherwise above. But, you already HAVE an implementation in place on windows, which gets all the benefits of windows security updates, and more. You do not need to use yet another one, where you will likely just drop in the DLL and never update it (or worse, static link it). That and I happen to know that WinHTTP HAS BEEN security audited. I cannot say the same about libcurl (and the same cannot be said about OpenSSL, which is in the process of but has not been completely, security reviewed).

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.
hplus0603
hplus0603

This is the SAME problem OpenSSL had, and you can recall how secure that "widely used" library turned out.


Yes. As I said: no worse than other libraries. It's not like Windows (or AIX, or Solaris, or any other alternative implementation) has been any better.

If you're targeting Windows only, and like the Windows API, the suggestion to stick with the Windows system libraries is fine -- I'm not against that at all.
enum Bool { True, False, FileNotFound };
Evil Steve
Evil Steve

So I set up libCurl, and wow - it's awesome. I don't know why I've not been using it already. I don't mind not being able to use my existing socket code; libcurl is amazingly simple to use and a lot more configurable than I thought it was.

Security isn't really a concern for me, since I'm only using it as an HTTP[S] client, and I'm not sending or receiving particularly sensitive data. I know ot should be a concern, but... meh smile.png

EDIT: Share and enjoy:

Cheers,

Steve

hplus0603
hplus0603
Evil Steve, Thanks for sharing!

An even better way to share code is to use a github gist, or just create a free github repository and check the code in.
To create a public gist, go to gist.github.com
enum Bool { True, False, FileNotFound };
Evil Steve
Evil Steve

That requires more effort than just pasting a Dropbox link though ;)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.