Click here to Skip to main content
15,897,166 members
Articles / Desktop Programming / Win32
Article

SSL : Convert your Plain Sockets to SSL Sockets in an Easy Way

Rate me:
Please Sign up or sign in to vote.
4.83/5 (21 votes)
14 Mar 2008CPOL3 min read 248.9K   7K   55   82
A simple class that allows you to convert an existing SOCKET handle to SSL under Windows

Includes:

  • SSL class soucre files (SSL.CPP, Z.H, SSL.H)
  • Testing project TEL, telnet client and server with SSL ability.

Introduction

A lot of SSL stuff already exists, but it is in either MFC, NET or some other non-native format. Here is a simple class SSL_SOCKET that allows you to convert an existing SOCKET handle to SSL under Windows. I got much information from the great CSslSocket - SSL/TLS enabled CSocket MFC article, but I need a plain Win32 one

Features

  • x86 / x64 compatible.
  • HTML help.
  • Supports Server and Client.

License

Free, for any kind or freeware, shareware, commercial, or whateverware project, as long as you give me credit for the library in your 'about box' or your application's documentation.

Creating the SSL Client

First, create and connect your socket using the normal socket functions (socket(), and connect()). Then construct an SSL_SOCKET:

C++
// Say that X is a socket
SSL_SOCKET* SX = new SSL_SOCKET(X,0,0);

This creates an SSL_SOCKET object for an SSL_CLIENT. The last parameter to the constructor indicates that the object will create a tempora self-signed certificate to authenticate itself with the SSL server. If you want, you can pass your own PCERT_CONTEXT.

Next step is to call SSL_SOCKET::ClientInit()

C++
// Initialize the Security Session
sX->ClientInit();

This also calls SSL_SOCKET::ClientLoop() to initialize the SSL Session. (If you don't want to initialize the SSL session at this time, call ClientInit(true) and then later call ClientLoop()). Once the loop returns 0 (success), you can then use the following functions:

  • int SSL_SOCKET:: s_send(char* b, int sz); // Sends data, returns 0 or -1 on error (like normal send()).
  • int SSL_SOCKET:: s_ssend(char* b, int sz); // Sends data, returns 0 or -1 on error (like normal send()). Does not return until all the bytes have been sent or an error occurs.
  • int SSL_SOCKET:: s_recv(char* b, int sz); // Receives data, returns 0 or -1 on error (like normal recv()).
  • int SSL_SOCKET:: s_ssend(char* b, int sz); // Receives data, returns 0 or -1 on error (like normal recv()). Does not return until all the bytes have been received or an error occurs.

If you like, you can call also send_p, ssend_p, recv_p, rrecv_p to send/receive raw bytes (without messaging encryption/decryption), if you can encrypt/decrypt the stuff yourself.

Polite shutdown of the client connection is calling SSL_SOCKET :: ClientOff() before calling closesocket().

Creating the SSL Server

First, create and accept your socket using the normal socket functions (socket(), bind(), listen() and accept()). Then construct a SSL_SOCKET:

C++
// Say that X is a socket
SSL_SOCKET* SX = new SSL_SOCKET(X,1,0);

This creates an SSL_SOCKET object for a SSL_CLIENT. The last parameter to the constructor indicates that the object will create a tempora self-signed certificate to authenticate itself with the SSL server. If you want, you can pass your own PCERT_CONTEXT. Note that some clients will test the certificate and reject it or warn it, so you may want to pass a trusted certificate.

Next step is to call SSL_SOCKET::ServerInit()

C++
// Initialize the Security Session
sX->ServerInit();

This also calls SSL_SOCKET::ServerLoop() to initialize the SSL Session. (If you don't want to initialize the SSL session at this time, call ServerInit(true) and then later call ServerLoop()). Once the loop returns 0 (success), you can then use the send/recv functions discussed above.

Shutdown the server by calling SSL_Socket :: ServerOff().

Other Features

These are some features I'd like to implement in the future:

  • Certificate verification (not yet completed)
  • Documentation (SSL.CHM) is pending.

Please leave your questions and comments!

History

  • March 13, 2007 - Original version posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS, Android and Web (HTML/Javascript/CSS).

I 've a PhD in Digital Signal Processing and Artificial Intelligence and I specialize in Pro Audio and AI applications.

My home page: https://www.turbo-play.com

Comments and Discussions

 
GeneralEvent driven sockets? Pin
rix_17-Nov-11 12:25
rix_17-Nov-11 12:25 
GeneralRe: Event driven sockets? Pin
Michael Chourdakis17-Nov-11 20:36
mvaMichael Chourdakis17-Nov-11 20:36 
Questioncan i using this class for https ? Pin
S.Naderi30-Oct-11 5:25
S.Naderi30-Oct-11 5:25 
QuestionThanks and another doubt Pin
dyvim22-Aug-11 3:42
dyvim22-Aug-11 3:42 
AnswerRe: Thanks and another doubt Pin
Michael Chourdakis22-Aug-11 20:26
mvaMichael Chourdakis22-Aug-11 20:26 
GeneralRe: Thanks and another doubt Pin
dyvim22-Aug-11 21:35
dyvim22-Aug-11 21:35 
GeneralRe: Thanks and another doubt Pin
Michael Chourdakis23-Aug-11 0:57
mvaMichael Chourdakis23-Aug-11 0:57 
GeneralRe: Thanks and another doubt Pin
dyvim23-Aug-11 2:49
dyvim23-Aug-11 2:49 
Thank you for your answers!
I managed to make a little application and SSL-connect it with your tel.exe, doing some tests (my application can be server and can be client, I tried with both). I also tried to launch 2 of my applications acting one as server and one as client.
I have some more questions:

1) Sometimes when I try to make a SSL connection between a client and a server the ServerLoop() doesn't end well and in this point:

// Get Some data from the remote site
int rval = recv(X,t + pt,0x10000,0);
if (rval == 0 || rval == -1)
return -1;

it returns -1 here in spite of going to

if (ss == S_OK)
break; // wow!!

This happens often (but not always), expecially when I open client before server or when I have established a connection and than one of the two (client or server) disconnect and reconnect. Sometimes it works and sometimes not, do you have an idea why?

2) When I CloseOff() or ServerOff(), a message is sent from the Server or Client that is stopping to the other end. s_recv() of the application receiving the message doesn't recognize this message as a SSL closing and returns the characters to the application as if it is "normal text" exchange. I think that it should recognize the "ending handshake" here (ss should be SEC_I_CONTEXT_EXPIRED, right?) and not pass it to the application (that doesn't know that string):

if (ss != SEC_E_OK && ss != SEC_I_RENEGOTIATE && ss != SEC_I_CONTEXT_EXPIRED)
return -1;

I made something wrong?

3) How can I load or create a PCCERT_CONTEXT to pass to SSL_SOCKET() different from the tempora self signed one? I read on the article that you can pass it in spite of using the tempora self signed certificate, but I don't know how to create/load a PCCERT_CONTEXT (I also searched a little on the net without success).

4) I tried to setup a Server with tel.exe and connect with my application, than use VerifySessionCertificate(). In this point of the code it breaks:

if(PolicyStatus.dwError) {
Status = PolicyStatus.dwError;
SetLastError(Status);
break;
}

the Status is 2148204809 (via Google I have found that means CertUNTRUSTEDROOT), it is because the certificate is self signed and so it is not trusted, right?
If I try the opposite (my application server and tel.exe client), QueryContextAttributes() fails and exit here:

if (Status != SEC_E_OK)
return Status;

Status has a -2146893042 that seems to have no meaning... I made something wrong?

Many thanks for your help and patience, I'm not sure if it was a good idea to learn SSL Smile | :) !
GeneralRe: Thanks and another doubt Pin
Michael Chourdakis23-Aug-11 3:16
mvaMichael Chourdakis23-Aug-11 3:16 
GeneralRe: Thanks and another doubt Pin
dyvim23-Aug-11 3:35
dyvim23-Aug-11 3:35 
GeneralRe: Thanks and another doubt [modified] Pin
dyvim30-Aug-11 1:21
dyvim30-Aug-11 1:21 
QuestionSome implementation missing Pin
dyvim18-Aug-11 23:05
dyvim18-Aug-11 23:05 
AnswerRe: Some implementation missing Pin
Michael Chourdakis19-Aug-11 9:16
mvaMichael Chourdakis19-Aug-11 9:16 
QuestionLink for Windows 7 version no longer works Pin
dyvim18-Aug-11 4:05
dyvim18-Aug-11 4:05 
AnswerRe: Link for Windows 7 version no longer works Pin
Michael Chourdakis19-Aug-11 9:14
mvaMichael Chourdakis19-Aug-11 9:14 
GeneralCorrection for buggy Microsoft TLS implimentation Pin
Member 371720410-Jun-11 10:57
Member 371720410-Jun-11 10:57 
GeneralRe: Correction for buggy Microsoft TLS implimentation Pin
cin197921-Mar-12 5:05
cin197921-Mar-12 5:05 
GeneralRe: Correction for buggy Microsoft TLS implimentation Pin
Member 371720421-Mar-12 23:11
Member 371720421-Mar-12 23:11 
GeneralCorrection of bug under Windows 7/Windows Server 2008 Pin
IDRASSI Mounir24-Oct-10 13:00
IDRASSI Mounir24-Oct-10 13:00 
GeneralRe: Correction of bug under Windows 7/Windows Server 2008 Pin
Michael Chourdakis25-Oct-10 4:46
mvaMichael Chourdakis25-Oct-10 4:46 
GeneralMessage Closed Pin
28-Jan-22 0:37
Member 1526517628-Jan-22 0:37 
GeneralProblem with Windows 7 Pin
ksutariya14-Oct-10 1:09
ksutariya14-Oct-10 1:09 
QuestionCould i use this on mobile? Pin
latell12-Oct-10 21:10
latell12-Oct-10 21:10 
AnswerRe: Could i use this on mobile? Pin
Michael Chourdakis13-Oct-10 19:11
mvaMichael Chourdakis13-Oct-10 19:11 
GeneralVerifySessionCertificate Pin
Mark Tutt17-Jun-10 4:32
Mark Tutt17-Jun-10 4:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.