title: Secure Socket Connections using c++
body: <p>I am trying to get SSL/TLS connections to work in windows. Right now I am using Schannel, but I am not sure this is the correct way to go about it. Here is my code. An exception is thrown at the InitializeSecurityContextA() function</p>
  
  <pre><code>#include "windows.h"
  #pragma comment(lib, "ws2_32.lib")
  #define SECURITY_WIN32
  #include &lt;SChannel.h&gt;
  #include &lt;security.h&gt;
  
  int CALLBACK WinMain(HINSTANCE currentinstance, HINSTANCE previousinstance, LPSTR BS1, int BS2) {
  
      // Initialize Winsock 2.0
          WSADATA versioninfo;
          WSAStartup (0x0202, &amp;versioninfo);
  
      // Load Security DLL
          HMODULE securitydllmodule = LoadLibrary("Secur32.dll");
  
      // Initialize Schannel
          INIT_SECURITY_INTERFACE initsecurtyinterfacefunction = (INIT_SECURITY_INTERFACE)GetProcAddress(securitydllmodule, "InitSecurityInterfaceA");
          PSecurityFunctionTable schannel = initsecurtyinterfacefunction();
          if (!schannel)
              MessageBox(0, "Failed to initialize schannel", "Message", MB_TASKMODAL | MB_OK);
          else
              MessageBox(0, "initialized schannel", "Message", MB_TASKMODAL | MB_OK);
  
      // Setup Schannel Credentials
          DWORD protocol = SP_PROT_TLS1;
          SCHANNEL_CRED schannelcredentials;
          ZeroMemory(&amp;schannelcredentials, sizeof(schannelcredentials));
          schannelcredentials.dwVersion = SCHANNEL_CRED_VERSION;
          schannelcredentials.grbitEnabledProtocols = protocol;
          schannelcredentials.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
          schannelcredentials.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
  
      // Get Client Credentials handle
          CredHandle clientcredentials;
          SECURITY_STATUS securitystatus = schannel-&gt;AcquireCredentialsHandleA(
              0, 
              UNISP_NAME_A,
              SECPKG_CRED_OUTBOUND,
              0,
              &amp;schannelcredentials,
              0,
              0,
              &amp;clientcredentials,
              0
          );          
          if (securitystatus != SEC_E_OK)
              MessageBox(0, "Failed to get credenetials", "Message", MB_TASKMODAL | MB_OK);
          else
              MessageBox(0, "Got client credenetials", "Message", MB_TASKMODAL | MB_OK);
  
      // Connect to Google
          SOCKET mysocket = socket(PF_INET, SOCK_STREAM, 0);
          sockaddr_in sin;
          sin.sin_family = AF_INET;
          sin.sin_port = htons(443);
          hostent *hp = gethostbyname("www.google.com");
          memcpy(&amp;sin.sin_addr, hp-&gt;h_addr, 4);
          if (connect(mysocket, (struct sockaddr *)&amp;sin, sizeof(sin)) == SOCKET_ERROR)
              MessageBox(0, "Error connecting", "Message", MB_TASKMODAL | MB_OK);
          else
              MessageBox(0, "Connected", "Message", MB_TASKMODAL | MB_OK);
  
      // Perform Handshake:
          DWORD sspiflags = (
              ISC_REQ_SEQUENCE_DETECT
              | ISC_REQ_REPLAY_DETECT
              | ISC_REQ_CONFIDENTIALITY
              | ISC_RET_EXTENDED_ERROR
              | ISC_REQ_ALLOCATE_MEMORY
              | ISC_REQ_STREAM
          );
  
          SecBuffer OutBuffers[1];
          OutBuffers[0].pvBuffer = 0;
          OutBuffers[0].BufferType = SECBUFFER_TOKEN;
          OutBuffers[0].cbBuffer = 0;
  
          SecBufferDesc OutBuffer;
          OutBuffer.cBuffers = 1;
          OutBuffer.pBuffers = OutBuffers;
          OutBuffer.ulVersion = SECBUFFER_VERSION;
  
          DWORD sspioutflags;
          CtxtHandle* contexthandle;
          SECURITY_STATUS scRet = schannel-&gt;InitializeSecurityContextA(
              &amp;clientcredentials,
              0,
              "www.google.com",
              sspiflags,
              0,
              SECURITY_NATIVE_DREP,
              0,
              0,
              contexthandle,
              &amp;OutBuffer,
              &amp;sspioutflags,
              0
          );
          if (scRet != SEC_I_CONTINUE_NEEDED)
              MessageBox(0, "Error Initializing Security Context", "Message", MB_TASKMODAL | MB_OK);
          else
              MessageBox(0, "Security Context Initialized", "Message", MB_TASKMODAL | MB_OK);
  
      // Done
          MessageBox(0, "Done", "Message", MB_TASKMODAL | MB_OK);
          return 0;
  }
  </code></pre>