## SSLWrappers v1.19

Welcome to SSLWrappers, a set of C++ classes to provide a complete C++ encapsulation of the TLS/SSL functionality exposed on Windows via the Schannel Security Service Provider Interface (SSPI). Some references which you should read if you want to understand more about TLS/SSL, SSPI and Schannel are as follows:

- Grab a copy of the classic Win32 book "Programming Server-Side Applications for Microsoft Windows 2000" by Jeffrey Richter and Jason D. Clark.
- The Windows/Platform SDK samples of WebClient and WebServer. I believe these articles and source code have been retired from the MSDN Online (at least I could not find them!) so you will need to dig up your old MSDN ISO CD images for this source code.
- The source code and background information at http://www.coastrd.com/c-schannel-smtp and http://www.coastrd.com/tls-with-schannel.

- For details on SSPI and Schannel please check out the official MS documentation starting at https://docs.microsoft.com/en-gb/windows/win32/secauthn/creating-a-secure-connection-using-schannel for creating a Secure connection Using Schannel, https://docs.microsoft.com/windows/win32/api/sspi/nf-sspi-initializesecuritycontextw for InitializeSecurityContext (Schannel), https://docs.microsoft.com/en-us/windows/win32/api/sspi/nf-sspi-acceptsecuritycontext for AcceptSecurityContext (Schannel) & https://docs.microsoft.com/windows/win32/api/sspi/nf-sspi-acquirecredentialshandleW for AcquireCredentialsHandle (Schannel). I would have to say the MS documentation is sorely lacking for this part of the Win32 API and online samples in general are very rare and not easy to follow. It took me the best part of two months to put together SSLWrappers to encapsulate all of the APIs and implement a complete tutorial sample and full documentation on how to use the code from your client applications.

The classes provided are: SSLWrappers::CCredentials, SSLWrappers::CCachedCredentials, SSLWrappers::CContext, SSLWrappers::CSSL & SSLWrappers::CSocket.

CCredentials provides a class based encapsulation of a SSL/TLS Credentials handle as represented by a CredHandle.

CCachedCredentials is a derived version of CCredentials which is used by the CSSL class to keep a copy of the SChannel credentials to use for the SSL connection.

CContext provides a class based encapsulation of a SSL/TLS Security context as represented by a CtxtHandle.

CSSL is the most complex class provided by the class framework and implements all the required logic to do client and server SSL handshakes, reading and writing SSL/TLS messages, requesting SSL/TLS renegotiations, handling SSL/TLS renegotiations and sending SSL/TLS close notify messages. This class is transport mechanism agnostic meaning that you can implement SSL/TLS over any transport by overriding specific virtual methods of this class.

CSocket is derived from CSSL and provides a concrete SSL/TLS implementation over Windows sockets.

Features
Usage
Copyright
Output from Demo Application
History
Class Framework reference
Contacting the Author

## Features

- Provides one C++ Header only module to encapsulate all of the Schannel SSL/TLS functionality on Windows.
- Should make it easier to use all the Windows SSL/TLS support from C++ going forward with automatic Resource Acquisition Is Initialization (RAII) resource management and encapsulation of the truly complicated logic required to be coded to support SSL/TLS via Schannel.
- A complete demo implementation of a HTTPS client and server using SSLWrappers is provided. This demonstrates all the features in a easy to follow manner which you should be able to incorporate into your applications.

## Usage

- To use the various SSLWrappers classes in your project simply #include "SSLWrappers.h" in which ever of the modules in your application requires the SSL/TLS functionality. The header file will look after pulling in any dependent header files and linking to the relevant Windows DLLs.
- As of v1.11 the classes are only supported on VC 2017 or later.
- Included in the download is a VC 2017 console based application which exercises all of the various classes functionality by implemented a demo HTTPS client and server with full demonstration of all features in SSLWrappers including requesting client and server renegotiations, handling client and server renegotiations, sample certificate handling and custom certificate verification on the client and server side of the demo.
- To make the SSLWrappers easier to code, the classes make use of the author's CryptoWrappers class framework for the various certificate and certificate store functionality which it needs. You will need to download this from http://www.naughter.com/cryptowrappers.html and copy in all the CryptoWrappers*.h files into the same directory as where you have SSLWrappers.h located.
- To compile the demo application you will also need to download the author's CWSocket wrapper classes from http://www.naughter.com/w3mfc.html and copy SocMFC.cpp and SocMFC.h into the same demo application directory.

- The steps to implementing a SSL/TLS client using the SSLWrappers classes are as follows:
  - Create an instance of SSLWrappers::CCachedCredentials and call the CCachedCredentials::AcquireClient method. If you use the default parameters to this method, then by default you will not supply any credentials to the server. You can pass non-default parameters to this method or implement your own version of this method if you want to customize this behavior. The demo client in SSLWrappersDemo.cpp has commented out support for providing a client certificate with a common name of "localhost" if you want to develop a SSL/TLS client which provides real client credentials. For details on generating a self-signed client certificate please checkout https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff650751(v=pandp.10) which I found useful while developing the SSL/TLS client code.
  - Create your socket connection to the server as you would do with a standard unencrypted socket application. If you are using the author's CWSocket wrapper (which the sample app provided with SSLWrapper does) then you would create a CWSocket instance and then call CreateAndConnect to create the socket and connect to the server in one step.
  - You then should create a SSLWrappers::CSocket instance or a derived version of the same. You might also then want to customize some of the behavior of this class. For example you might want to call CSSL::SetVerifyServerCertificate if you wanted to do manual verification of the server certificate or CSocket::SetReadTimeout or CSocket::SetWriteTimeout to customize the timeouts. Please see the code in SSLWrappersDemo.cpp for concrete examples of this.
  - Connect the cached credentials to the CSocket instance by calling CSocket::SetCachedCredentials.
  - You can then attach the raw Windows socket to the CSocket instance using CSocket::Attach.
  - You should then call CSSL::SSLConnect to perform the SSL/TLS client handshake. If this method returns SEC_E_OK then you now have a SSL/TLS connection with the remote end.
  - You can then call CSSL::SendEncryptedMessage or CSSL::SendEncrypted to deliver data to the server and CSSL::GetEncryptedMessage to read data from the server. In what order you do this will be dictated by the details of the protocol you are implementing over SSL/TLS. The example client provided in SSLWrappersDemo.cpp implements a very simple HTTPS client. Please note that if too much data has been read from the socket for one SSL/TLS message that this extra data will be buffered internally in the CSSL class and make available when you next call GetEncryptedMessage. To determine how much of this data is buffered in the class you can call CSSL::PendingReadSize. You might want to call this function in conjunction with checking your socket for readability before you make calls to CSSL::GetEncryptedMessage.
  - If you would like to support renegotiation from the server, then you should handle the SEC_I_RENEGOTIATE error code from the CSSL::GetEncryptedMessage method and immediately call CSSL::SSLHandleRenegotiationClient to perform the SSL/TLS handshake again. If you as the client would like to request a renegotiation yourself, then you should call CSSL::SSLRequestRenegotiationClient.
  - When you decide to close down the SSL/TLS connection either on the client's own volition or because the server requested it, you should then call CSSL::SendCloseNotify(true) to send the close notify SSL/TLS message to the other end. Please note that you can detect if the other end has sent you a close notify SSL/TLS message by checking the return value from CSSL::GetEncryptedMessage for the special error code of SEC_I_CONTEXT_EXPIRED.
  - That should be pretty much all that is required to implement a basic SSL/TLS client to get you going. Again please review the source in SSLWrappersDemo.cpp for further additional coding details and error handling.
- The steps to implementing a SSL/TLS server using the SSLWrappers classes are as follows:
  - Create an instance of SSLWrappers::CCachedCredentials and call the CCachedCredentials::AcquireServer method. For a server this would normally be created with application scope / lifetime.
  - You need to create a SSLWrappers::CSocket instance and call CSSL::SetCachedCredentials to setup the credentials which you will be providing as the server. As part of SSL/TLS you must always as a server provide a server certificate. The demo app in SSLWrappersDemo.cpp looks for a certificate with a common name of localhost in the current user certificate store. For details on generating a self-signed server certificate please checkout http://www.lombard.me/2008/01/testing-ssl-and-certificate.html and http://www.yangsoft.com/blog/?p=105 which I found useful while developing the SSL/TLS server code. For performance reasons you should call CreateServerCredentials once and not for each client which connects to you as the SSL/TLS server.
  - Create your server application as you would do with a standard unencrypted socket application. If you are using the author's CWSocket wrapper (which the sample app provided with SSLWrapper does) then you would create a CWSocket instance and then call SetBindAddress, CreateAndBind and then Listen.
  - You would then sit in an loop waiting for client connections as per any sockets server. If you were using the author's CWSocket wrappers a client connection would be created when the CWSocket::Accept method returns. You might then want to customize some of the behavior of this CSocket class at this time. For example you might want to call CSSL::SetVerifyClientCertificate if you wanted to do custom checking of any client certificate presented or CSocket::SetReadTimeout or CSocket::SetWriteTimeout to customize the timeouts. Please see the code in SSLWrappersDemo.cpp for concrete examples of this.
  - You can then attach the raw Windows client socket to the CSocket instance using CSocket::Attach.
  - You should then call CSSL::SSLAccept to perform the SSL/TLS server handshake. If this method returns SEC_E_OK then you now have a SSL/TLS connection with the remote end.
  - You can then call CSSL::SendEncryptedMessage or CSSL::SendEncrypted to deliver data to the client and CSSL::GetEncryptedMessage to read data from the client. In what order you do this will be dictated by the details of the protocol you are implementing over SSL/TLS. The example server provided in SSLWrappersDemo.cpp implements a very simple HTTPS server which serves up a hard coded HTML response page without really doing any parsing of the HTTPS request received from the client. Please note that if too much data has been read from the socket for one SSL/TLS message that this extra data will be buffered internally in the CSSL class and make available when you next call GetEncryptedMessage. To determine how much of this data is buffered in the class you can call CSSL::PendingReadSize. You might want to call this function in conjunction with checking your socket for readability before you make calls to CSSL::GetEncryptedMessage.
  - If you would like to support renegotiation from the server, then you should handle the SEC_I_RENEGOTIATE error code from the CSSL::GetEncryptedMessage method and immediately call CSSL::SSLHandleRenegotiationServer to perform the SSL/TLS handshake again. If you as the server would like to request a renegotiation yourself, then you should call CSSL::SSLRequestRenegotiationServer.
  - When you decide to close down the SSL/TLS connection either on the server's own volition or because the client requested it, you should then call CSSL::SendCloseNotify(false) to send the close notify SSL/TLS message to the other end. Please note that you can detect if the other end has sent you a close notify SSL/TLS message by checking the return value from CSSL::GetEncryptedMessage for the special error code of SEC_I_CONTEXT_EXPIRED.
  - That should be pretty much all that is required to implement a basic SSL/TLS server to get you going. Again please review the source in SSLWrappersDemo.cpp for further additional coding details and error handling.

## Copyright

- You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) when your product is released in binary form.
- You are allowed to modify the source code in any way you want except you cannot modify the copyright details at the top of each module.
- If you want to distribute source code with your application, then you are only allowed to distribute versions released by the author. This is to maintain a single distribution point for the source code.

## Output from Demo application

- Here is a screen capture from the test app when it is run with a command line to make it act as a server (with both the server and client performing handling renegotiation in midstream) and the test client has connected to it. You can see from the auditing from the server code that an IIS Express server certificate with a common name of "localhost" is being used:

> D:\Dev\My Code\SSLWrappers\Release>sslwrappersdemo.exe 1 localhost 443
> Server certificate properties
> Subject string: CN=localhost
> Version: 2
> Serial number: Length:16,
> 5b eb 9a 44 f7 af d4 4e a3 71 3c a6 af 84 0e 1d [..D...N.q<.....
> Crypt algorithm Identifier: 1.3.14.3.2.29
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:29,
> 30 1b 31 19 30 17 06 03 55 04 03 13 10 52 6f 6f 0.1.0...U....Roo
> 74 43 61 43 6c 69 65 6e 74 54 65 73 74 tCaClientTest
> Not valid before: 2016-08-17 17:43:34
> Not valid after: 2039-12-31 23:59:59
> Subject data: Length:22,
> 30 14 31 12 30 10 06 03 55 04 03 13 09 6c 6f 63 0.1.0...U....loc
> 61 6c 68 6f 73 74 alhost
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 e7 88 c4 fb db b0 7d 0..............}
> b8 5a 55 04 88 11 ff 1e 9e c4 f1 89 94 c5 75 b9 .ZU...........u.
> 54 04 56 d6 01 50 0f d4 be 94 fa 36 9f 03 45 64 T.V..P.....6..Ed
> 5b dc 4c dd e8 dc 5a a4 fa 34 4d 13 c2 c8 2d 3e [.L...Z..4M...->
> 8e 13 77 28 ae 80 8a a5 93 d7 44 0c 85 8b da 1e ..w(......D.....
> 2e 2f 41 db 05 89 b1 aa e3 93 c2 f7 14 47 b4 66 ./A..........G.f
> 9d e6 51 b0 19 a2 f5 23 ab 60 e9 52 84 00 df 2c ..Q....#.`.R...,
> 98 d5 54 99 18 a1 ef 53 f4 a5 dd 49 98 51 83 3d ..T....S...I.Q.=
> 31 5f bc 8f 70 a6 fd 1b a2 4a 6c 5f 35 22 16 1a 1_..p....Jl_5"..
> 07 c5 fd c3 b5 8c d0 e0 3c a5 94 26 0c 5d 7c aa ........<..&.]|.
> 40 86 9a f8 6d 1d 96 ee c4 a1 b8 9c 82 a9 de 04 @...m...........
> c8 e7 26 0e 3f ae 6f 5d 90 2a c7 aa c3 6a 78 0d ..&.?.o].*...jx.
> 80 84 ef 1e 32 27 a4 e4 71 ad a3 0c e7 56 2f e9 ....2'..q....V/.
> be f3 80 26 5d 3c c8 cf 52 f3 49 d4 a0 17 76 2c ...&]<..R.I...v,
> 12 30 4e a4 72 bf 88 4a 31 9a 45 b7 c5 90 43 a6 .0N.r..J1.E...C.
> fa 0d 49 af 32 7e c3 4a 2b ed 85 b0 cc 9f cf 49 ..I.2~.J+......I
> 19 7e 4e a5 8c 2e d4 b4 ef 02 03 01 00 01 .~N...........
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.1, Critical:0, Value:: Length:69,
> 30 43 80 10 95 da 51 2f ce a0 10 14 e0 c6 cf 85 0C....Q/........
> 75 94 07 1b a1 1d 30 1b 31 19 30 17 06 03 55 04 u.....0.1.0...U.
> 03 13 10 52 6f 6f 74 43 61 43 6c 69 65 6e 74 54 ...RootCaClientT
> 65 73 74 82 10 b8 44 52 0d 02 c4 1e 87 4e e5 c4 est...DR.....N..
> 04 c7 d5 d7 af .....
> Issuer Public Key MD5 hash
> Length:16,
> 7c 42 8e 1a 88 70 8d a0 6b 2d 96 f4 04 6c 24 5f |B...p..k-...l$_
> MD5 hash
> Length:16,
> 4f 50 9c 20 2c fd 89 cf a9 45 94 13 5f 42 57 ac OP. ,....E.._BW.
> Key Provider Info
> Length:128,
> cc df 15 01 e0 df 15 01 01 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 02 00 00 00 4d 00 79 00 ............M.y.
> 4b 00 65 00 79 00 4e 00 61 00 6d 00 65 00 00 00 K.e.y.N.a.m.e...
> 4d 00 69 00 63 00 72 00 6f 00 73 00 6f 00 66 00 M.i.c.r.o.s.o.f.
> 74 00 20 00 53 00 74 00 72 00 6f 00 6e 00 67 00 t. .S.t.r.o.n.g.
> 20 00 43 00 72 00 79 00 70 00 74 00 6f 00 67 00 .C.r.y.p.t.o.g.
> 72 00 61 00 70 00 68 00 69 00 63 00 20 00 50 00 r.a.p.h.i.c. .P.
> 72 00 6f 00 76 00 69 00 64 00 65 00 72 00 00 00 r.o.v.i.d.e.r...
> SHA1 hash
> Length:20,
> 7e 1e ec a5 0d d4 42 e7 6c 3e 5c f6 86 91 e6 af ~.....B.l>\.....
> 28 fd bf c2 (...
> Key Identifier
> Length:20,
> 55 ee 88 9e 67 9c 62 5e 18 58 09 eb f1 da 13 83 U...g.b^.X......
> 75 b7 80 0d u...
> Signature hash
> Length:20,
> 39 da 7e 90 ac 61 01 93 14 7f 23 0b dd 6b 7d 21 9.~..a....#..k}!
> d2 14 bd 4c ...L
> Subject Public Key Bit length
> Length:4,
> 00 08 00 00 ....
> Subject Public Key MD5 hash
> Length:16,
> 28 92 c7 fd a3 ab 1b 11 c9 b0 a0 e9 9f e4 b6 dd (...............
> Binding to localhost:443
> Listening
> Waiting for client connection
> Accepted client connection
> Performing SSL server handshake
> Protocol: TLS v1.2
> Cipher: AES
> Cipher strength: 256
> Hash: SHA-384
> Hash strength: 0
> Key exchange: Eliptic curve Diffie Hellman Ephemeral
> Key exchange strength: 256
> Getting client request
> Received request data:: Length:6,
> 47 45 54 20 2f 20 GET /
> Client requested renegotiation
> Received request data:: Length:12,
> 48 54 54 50 2f 31 2e 30 0d 0a 0d 0a HTTP/1.0....
> Sending client first part of response
> Requesting client renegotiation
> Sending client second part of response
> Sending close notify
> Closing client connection
> Waiting for client connection

- Here is a screen capture from the test app when it is run with a command line to make it act as a client (with both the server and client performing handling renegotiation in midstream):

> D:\Dev\My Code\SSLWrappers\Release>SSLWrappersDemo.exe 0 localhost 443
> Connecting to localhost:443
> Performing SSL client handshake
> Protocol: TLS v1.2
> Cipher: AES
> Cipher strength: 256
> Hash: SHA-384
> Hash strength: 0
> Key exchange: Eliptic curve Diffie Hellman Ephemeral
> Key exchange strength: 256
> Remote server certificate properties
> Subject string: CN=localhost
> Version: 2
> Serial number: Length:16,
> 5b eb 9a 44 f7 af d4 4e a3 71 3c a6 af 84 0e 1d [..D...N.q<.....
> Crypt algorithm Identifier: 1.3.14.3.2.29
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:29,
> 30 1b 31 19 30 17 06 03 55 04 03 13 10 52 6f 6f 0.1.0...U....Roo
> 74 43 61 43 6c 69 65 6e 74 54 65 73 74 tCaClientTest
> Not valid before: 2016-08-17 17:43:34
> Not valid after: 2039-12-31 23:59:59
> Subject data: Length:22,
> 30 14 31 12 30 10 06 03 55 04 03 13 09 6c 6f 63 0.1.0...U....loc
> 61 6c 68 6f 73 74 alhost
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 e7 88 c4 fb db b0 7d 0..............}
> b8 5a 55 04 88 11 ff 1e 9e c4 f1 89 94 c5 75 b9 .ZU...........u.
> 54 04 56 d6 01 50 0f d4 be 94 fa 36 9f 03 45 64 T.V..P.....6..Ed
> 5b dc 4c dd e8 dc 5a a4 fa 34 4d 13 c2 c8 2d 3e [.L...Z..4M...->
> 8e 13 77 28 ae 80 8a a5 93 d7 44 0c 85 8b da 1e ..w(......D.....
> 2e 2f 41 db 05 89 b1 aa e3 93 c2 f7 14 47 b4 66 ./A..........G.f
> 9d e6 51 b0 19 a2 f5 23 ab 60 e9 52 84 00 df 2c ..Q....#.`.R...,
> 98 d5 54 99 18 a1 ef 53 f4 a5 dd 49 98 51 83 3d ..T....S...I.Q.=
> 31 5f bc 8f 70 a6 fd 1b a2 4a 6c 5f 35 22 16 1a 1_..p....Jl_5"..
> 07 c5 fd c3 b5 8c d0 e0 3c a5 94 26 0c 5d 7c aa ........<..&.]|.
> 40 86 9a f8 6d 1d 96 ee c4 a1 b8 9c 82 a9 de 04 @...m...........
> c8 e7 26 0e 3f ae 6f 5d 90 2a c7 aa c3 6a 78 0d ..&.?.o].*...jx.
> 80 84 ef 1e 32 27 a4 e4 71 ad a3 0c e7 56 2f e9 ....2'..q....V/.
> be f3 80 26 5d 3c c8 cf 52 f3 49 d4 a0 17 76 2c ...&]<..R.I...v,
> 12 30 4e a4 72 bf 88 4a 31 9a 45 b7 c5 90 43 a6 .0N.r..J1.E...C.
> fa 0d 49 af 32 7e c3 4a 2b ed 85 b0 cc 9f cf 49 ..I.2~.J+......I
> 19 7e 4e a5 8c 2e d4 b4 ef 02 03 01 00 01 .~N...........
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.1, Critical:0, Value:: Length:69,
> 30 43 80 10 95 da 51 2f ce a0 10 14 e0 c6 cf 85 0C....Q/........
> 75 94 07 1b a1 1d 30 1b 31 19 30 17 06 03 55 04 u.....0.1.0...U.
> 03 13 10 52 6f 6f 74 43 61 43 6c 69 65 6e 74 54 ...RootCaClientT
> 65 73 74 82 10 b8 44 52 0d 02 c4 1e 87 4e e5 c4 est...DR.....N..
> 04 c7 d5 d7 af .....
> Sending server first part of request
> Requesting server renegotiation
> Sending server second part of request
> Getting response
> Received response data:: Length:16,
> 48 54 54 50 2f 31 2e 30 20 32 30 30 0d 0a 0d 0a HTTP/1.0 200....
> Server requested renegotiation
> Received response data:: Length:106,
> 3c 68 74 6d 6c 3e 3c 68 65 61 64 3e 3c 74 69 74 <html><head><tit
> 6c 65 3e 53 53 4c 20 44 61 74 61 3c 2f 74 69 74 le>SSL Data</tit
> 6c 65 3e 3c 2f 68 65 61 64 3e 3c 62 6f 64 79 3e le></head><body>
> 54 68 69 73 20 69 73 20 74 68 65 20 62 6f 64 79 This is the body
> 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 20 72 65 6e following a ren
> 65 67 6f 74 69 61 74 69 6f 6e 3c 2f 62 6f 64 79 egotiation</body
> 3e 3c 2f 68 74 6d 6c 3e 0d 0a ></html>..
> Stopping receive of response because of SEC_I_CONTEXT_EXPIRED status value from CSSL::GetEncryptedMessage
> Sending close_notify message

- Here is screen capture from the test app when connecting to https://www.microsoft.com (with the client performing handling renegotiation in midstream):

> D:\Dev\My Code\SSLWrappers\Release>SSLWrappersDemo.exe 0 www.microsoft.com 443
> Connecting to www.microsoft.com:443
> Performing SSL client handshake
> Protocol: TLS v1.2
> Cipher: AES
> Cipher strength: 256
> Hash: SHA-384
> Hash strength: 0
> Key exchange: Eliptic curve Diffie Hellman Ephemeral
> Key exchange strength: 256
> Remote server certificate properties
> Subject string: C=US, S=Washington, L=Redmond, O=Microsoft Corporation, CN=www.microsoft.com
> Version: 2
> Serial number: Length:16,
> a5 1e f4 ff a0 90 a3 53 97 90 4a d9 2b 62 8f 2b .......S..J.+b.+
> Crypt algorithm Identifier: 1.2.840.113549.1.1.11
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:128,
> 30 7e 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0~1.0...U....US1
> 1d 30 1b 06 03 55 04 0a 13 14 53 79 6d 61 6e 74 .0...U....Symant
> 65 63 20 43 6f 72 70 6f 72 61 74 69 6f 6e 31 1f ec Corporation1.
> 30 1d 06 03 55 04 0b 13 16 53 79 6d 61 6e 74 65 0...U....Symante
> 63 20 54 72 75 73 74 20 4e 65 74 77 6f 72 6b 31 c Trust Network1
> 2f 30 2d 06 03 55 04 03 13 26 53 79 6d 61 6e 74 /0-..U...&Symant
> 65 63 20 43 6c 61 73 73 20 33 20 53 65 63 75 72 ec Class 3 Secur
> 65 20 53 65 72 76 65 72 20 43 41 20 2d 20 47 34 e Server CA - G4
> Not valid before: 2016-05-23 00:00:00
> Not valid after: 2017-05-23 23:59:59
> Subject data: Length:114,
> 30 70 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0p1.0...U....US1
> 13 30 11 06 03 55 04 08 0c 0a 57 61 73 68 69 6e .0...U....Washin
> 67 74 6f 6e 31 10 30 0e 06 03 55 04 07 0c 07 52 gton1.0...U....R
> 65 64 6d 6f 6e 64 31 1e 30 1c 06 03 55 04 0a 0c edmond1.0...U...
> 15 4d 69 63 72 6f 73 6f 66 74 20 43 6f 72 70 6f .Microsoft Corpo
> 72 61 74 69 6f 6e 31 1a 30 18 06 03 55 04 03 0c ration1.0...U...
> 11 77 77 77 2e 6d 69 63 72 6f 73 6f 66 74 2e 63 .www.microsoft.c
> 6f 6d om
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 9a e2 28 63 37 8b e5 0..........(c7..
> 83 ee 04 24 b2 6e bc dd 6a ef 4e fe a7 ed 91 9e ...$.n..j.N.....
> 03 84 5b d5 31 0f 9e a8 c2 22 97 91 11 64 12 13 ..[.1...."...d..
> d3 a6 a6 3b 01 f7 bf e9 8d d8 04 d4 29 b0 93 85 ...;........)...
> 20 41 6d 24 1b 0e 04 c9 42 c7 2f c0 73 f8 af 2d Am$....B./.s..-
> 7e a9 00 5d 4c bd 2d ac 12 77 e4 3f 23 6e ea 59 ~..]L.-..w.?#n.Y
> c9 7f c9 e0 d6 8f 73 d2 67 00 3c 68 37 5d b1 ff ......s.g.<h7]..
> 2a c4 eb c7 cd 38 36 67 77 be 44 7b 05 29 de 41 *....86gw.D{.).A
> 64 4d 9e aa 6b 4f 78 d9 09 ea a3 58 2e 2e 8d 22 dM..kOx....X..."
> 08 2a b1 cc ea f0 59 30 d0 03 2d 53 1e 0b a8 9a .*....Y0..-S....
> 25 53 29 1e a9 15 b2 b9 c3 10 90 f6 bb c6 40 97 %S)...........@.
> 79 67 5e d1 74 63 fa 09 78 e8 d5 3c 40 8f 41 10 yg^.tc..x..<@.A.
> 0b 4c 8f 54 f1 b6 7e 3f b4 e6 9d 3c fe 03 3a a7 .L.T..~?...<..:.
> c9 a2 7f 47 09 6a 9a e5 9b db aa 0c c7 b0 74 40 ...G.j........t@
> 48 46 de 58 fe fb 39 12 c6 d4 9d 51 d3 ae bd 68 HF.X..9....Q...h
> 29 46 3b 99 71 31 a0 eb b8 8e ac 5f 94 52 20 4a )F;.q1....._.R J
> 4c be a7 e9 5f b1 ce 92 9b 02 03 01 00 01 L..._.........
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.17, Critical:0, Value:: Length:80,
> 30 4e 82 15 70 72 69 76 61 63 79 2e 6d 69 63 72 0N..privacy.micr
> 6f 73 6f 66 74 2e 63 6f 6d 82 13 77 77 77 71 61 osoft.com..wwwqa
> 2e 6d 69 63 72 6f 73 6f 66 74 2e 63 6f 6d 82 11 .microsoft.com..
> 77 77 77 2e 6d 69 63 72 6f 73 6f 66 74 2e 63 6f www.microsoft.co
> 6d 82 0d 6d 69 63 72 6f 73 6f 66 74 2e 63 6f 6d m..microsoft.com
> Extension: OID:2.5.29.19, Critical:0, Value:: Length:2,
> 30 00 0.
> Extension: OID:2.5.29.15, Critical:1, Value:: Length:4,
> 03 02 05 a0 ....
> Extension: OID:2.5.29.32, Critical:0, Value:: Length:90,
> 30 58 30 56 06 06 67 81 0c 01 02 02 30 4c 30 23 0X0V..g.....0L0#
> 06 08 2b 06 01 05 05 07 02 01 16 17 68 74 74 70 ..+.........http
> 73 3a 2f 2f 64 2e 73 79 6d 63 62 2e 63 6f 6d 2f s://d.symcb.com/
> 63 70 73 30 25 06 08 2b 06 01 05 05 07 02 02 30 cps0%..+.......0
> 19 0c 17 68 74 74 70 73 3a 2f 2f 64 2e 73 79 6d ...https://d.sym
> 63 62 2e 63 6f 6d 2f 72 70 61 cb.com/rpa
> Extension: OID:2.5.29.31, Critical:0, Value:: Length:36,
> 30 22 30 20 a0 1e a0 1c 86 1a 68 74 74 70 3a 2f 0"0 ......http:/
> 2f 73 73 2e 73 79 6d 63 62 2e 63 6f 6d 2f 73 73 /ss.symcb.com/ss
> 2e 63 72 6c .crl
> Extension: OID:2.5.29.37, Critical:0, Value:: Length:22,
> 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 0...+.........+.
> 01 05 05 07 03 02 ......
> Extension: OID:2.5.29.35, Critical:0, Value:: Length:24,
> 30 16 80 14 5f 60 cf 61 90 55 df 84 43 14 8a 60 0..._`.a.U..C..`
> 2a b2 f5 7a f4 43 18 ef *..z.C..
> Extension: OID:1.3.6.1.5.5.7.1.1, Critical:0, Value:: Length:75,
> 30 49 30 1f 06 08 2b 06 01 05 05 07 30 01 86 13 0I0...+.....0...
> 68 74 74 70 3a 2f 2f 73 73 2e 73 79 6d 63 64 2e http://ss.symcd.
> 63 6f 6d 30 26 06 08 2b 06 01 05 05 07 30 02 86 com0&..+.....0..
> 1a 68 74 74 70 3a 2f 2f 73 73 2e 73 79 6d 63 62 .http://ss.symcb
> 2e 63 6f 6d 2f 73 73 2e 63 72 74 .com/ss.crt
> Extension: OID:1.3.6.1.4.1.11129.2.4.2, Critical:0, Value:: Length:245,
> 04 81 f2 00 f0 00 75 00 dd eb 1d 2b 7a 0d 4f a6 ......u....+z.O.
> 20 8b 81 ad 81 68 70 7e 2e 8e 9d 01 d5 5c 88 8d ....hp~.....\..
> 3d 11 c4 cd b6 ec be cc 00 00 01 54 df 0f 49 68 =..........T..Ih
> 00 00 04 03 00 46 30 44 02 20 28 0f 62 d7 13 bb .....F0D. (.b...
> 3b 10 c4 e4 f6 bf c6 f5 47 ab 6f 96 7a f8 13 c0 ;.......G.o.z...
> 28 74 eb cf 03 32 a5 42 54 f3 02 20 03 96 7d 09 (t...2.BT.. ..}.
> 17 7a 78 cd 21 fb 0f 24 af 6f 67 29 5f fc 3c 09 .zx.!..$.og)_.<.
> 6a 98 da 87 f6 ee c5 4f 88 72 7b 94 00 77 00 a4 j......O.r{..w..
> b9 09 90 b4 18 58 14 87 bb 13 a2 cc 67 70 0a 3c .....X......gp.<
> 35 98 04 f9 1b df b8 e3 77 cd 0e c8 0d dc 10 00 5.......w.......
> 00 01 54 df 0f 49 9d 00 00 04 03 00 48 30 46 02 ..T..I......H0F.
> 21 00 c1 fc 00 d9 de ca 11 43 29 11 86 9c 84 e4 !........C).....
> 81 86 a1 f1 08 58 fc 0b 01 b7 24 05 c7 e9 1f 2d .....X....$....-
> 27 90 02 21 00 f1 fb 42 30 0b 9c da 3a c7 76 6c '..!...B0...:.vl
> bf e6 83 69 c1 8f a1 e7 89 21 be e7 e7 f4 8a 4a ...i.....!.....J
> f5 67 41 54 01 .gAT.
> Property Identifier: 119
> Length:489,
> 43 53 43 43 e9 01 00 00 a0 00 00 00 38 00 00 00 CSCC........8...
> 03 00 00 00 07 00 00 00 64 01 00 00 85 00 00 00 ........d.......
> 00 00 00 00 00 01 00 00 00 80 92 0c 86 b4 d1 01 ................
> 80 69 2a af 20 d4 d2 01 92 00 00 00 00 00 00 00 .i*. ...........
> 01 00 00 00 06 00 00 00 73 b1 e5 33 00 00 00 00 ........s..3....
> d9 b1 2a 63 be 2c d2 01 9b db b2 01 b6 2c d2 01 ..*c.,.......,..
> 9b ab 3b c5 c6 2c d2 01 00 00 00 00 00 00 00 00 ..;..,..........
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 80 0c ce 7b de 6a 3e 8a ce bc 80 8c e8 d4 a5 a2 ...{.j>.........
> e8 a1 6e 1d e0 3d 31 a8 c9 c9 da b3 3a 34 f5 10 ..n..=1.....:4..
> 38 00 00 00 00 00 00 00 00 00 00 00 02 01 00 00 8...............
> 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 ................
> 5f 0b 37 e6 33 84 0c a0 24 68 55 2e a3 b1 19 7e _.7.3...$hU....~
> 5e 11 8f 7b 00 00 00 00 38 00 00 00 00 00 00 00 ^..{....8.......
> 00 00 00 00 02 01 00 00 01 00 00 00 02 00 00 00 ................
> ff ff ff ff 00 00 00 00 ff 67 36 7c 5c d4 de 4a .........g6|\..J
> e1 8b cc e1 d7 0f da bd 7c 86 61 35 00 00 00 00 ........|.a5....
> 38 00 00 00 00 00 00 00 00 00 00 00 0c 01 00 00 8...............
> ff ff ff ff 00 00 00 00 04 00 00 00 03 00 00 00 ................
> 4e b6 d5 78 49 9b 1c cf 5f 58 1e ad 56 be 3d 9b N..xI..._X..V.=.
> 67 44 a5 e5 00 00 00 00 00 00 00 00 12 00 00 00 gD..............
> 24 00 00 00 3d 00 00 00 4f 00 00 00 61 00 00 00 $...=...O...a...
> 73 00 00 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e s...1.3.6.1.5.5.
> 37 2e 33 2e 31 00 31 2e 33 2e 36 2e 31 2e 35 2e 7.3.1.1.3.6.1.5.
> 35 2e 37 2e 33 2e 32 00 32 2e 31 36 2e 38 34 30 5.7.3.2.2.16.840
> 2e 31 2e 31 31 33 37 33 33 2e 31 2e 37 2e 35 34 .1.113733.1.7.54
> 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e 37 2e 33 .1.3.6.1.5.5.7.3
> 2e 31 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e 37 .1.1.3.6.1.5.5.7
> 2e 33 2e 32 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 .3.2.1.3.6.1.5.5
> 2e 37 2e 33 2e 34 00 31 2e 33 2e 36 2e 31 2e 35 .7.3.4.1.3.6.1.5
> 2e 35 2e 37 2e 33 2e 33 00 .5.7.3.3.
> SHA1 hash
> Length:20,
> 5f 0b 37 e6 33 84 0c a0 24 68 55 2e a3 b1 19 7e _.7.3...$hU....~
> 5e 11 8f 7b ^..{
> Next certificate in chain
> Subject string: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server CA - G4
> Version: 2
> Serial number: Length:16,
> ff 99 06 93 30 8d 41 40 34 b7 70 38 74 b9 3f 51 ....0.A@4.p8t.?Q
> Crypt algorithm Identifier: 1.2.840.113549.1.1.11
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:205,
> 30 81 ca 31 0b 30 09 06 03 55 04 06 13 02 55 53 0..1.0...U....US
> 31 17 30 15 06 03 55 04 0a 13 0e 56 65 72 69 53 1.0...U....VeriS
> 69 67 6e 2c 20 49 6e 63 2e 31 1f 30 1d 06 03 55 ign, Inc.1.0...U
> 04 0b 13 16 56 65 72 69 53 69 67 6e 20 54 72 75 ....VeriSign Tru
> 73 74 20 4e 65 74 77 6f 72 6b 31 3a 30 38 06 03 st Network1:08..
> 55 04 0b 13 31 28 63 29 20 32 30 30 36 20 56 65 U...1(c) 2006 Ve
> 72 69 53 69 67 6e 2c 20 49 6e 63 2e 20 2d 20 46 riSign, Inc. - F
> 6f 72 20 61 75 74 68 6f 72 69 7a 65 64 20 75 73 or authorized us
> 65 20 6f 6e 6c 79 31 45 30 43 06 03 55 04 03 13 e only1E0C..U...
> 3c 56 65 72 69 53 69 67 6e 20 43 6c 61 73 73 20 <VeriSign Class
> 33 20 50 75 62 6c 69 63 20 50 72 69 6d 61 72 79 3 Public Primary
> 20 43 65 72 74 69 66 69 63 61 74 69 6f 6e 20 41 Certification A
> 75 74 68 6f 72 69 74 79 20 2d 20 47 35 uthority - G5
> Not valid before: 2013-10-31 00:00:00
> Not valid after: 2023-10-30 23:59:59
> Subject data: Length:128,
> 30 7e 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0~1.0...U....US1
> 1d 30 1b 06 03 55 04 0a 13 14 53 79 6d 61 6e 74 .0...U....Symant
> 65 63 20 43 6f 72 70 6f 72 61 74 69 6f 6e 31 1f ec Corporation1.
> 30 1d 06 03 55 04 0b 13 16 53 79 6d 61 6e 74 65 0...U....Symante
> 63 20 54 72 75 73 74 20 4e 65 74 77 6f 72 6b 31 c Trust Network1
> 2f 30 2d 06 03 55 04 03 13 26 53 79 6d 61 6e 74 /0-..U...&Symant
> 65 63 20 43 6c 61 73 73 20 33 20 53 65 63 75 72 ec Class 3 Secur
> 65 20 53 65 72 76 65 72 20 43 41 20 2d 20 47 34 e Server CA - G4
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 b2 d8 05 ca 1c 74 2d 0.............t-
> b5 17 56 39 c5 4a 52 09 96 e8 4b d8 0c f1 68 9f ..V9.JR...K...h.
> 9a 42 28 62 c3 a5 30 53 7e 55 11 82 5b 03 7a 0d .B(b..0S~U..[.z.
> 2f e1 79 04 c9 b4 96 77 19 81 01 94 59 f9 bc f7 /.y....w....Y...
> 7a 99 27 82 2d b7 83 dd 5a 27 7f b2 03 7a 9c 53 z.'.-...Z'...z.S
> 25 e9 48 1f 46 4f c8 9d 29 f8 be 79 56 f6 f7 fd %.H.FO..)..yV...
> d9 3a 68 da 8b 4b 82 33 41 12 c3 c8 3c cc d6 96 .:h..K.3A...<...
> 7a 84 21 1a 22 04 03 27 17 8b 1c 68 61 93 0f 0e z.!."..'...ha...
> 51 80 33 1d b4 b5 ce eb 7e d0 62 ac ee b3 7b 01 Q.3.....~.b...{.
> 74 ef 69 35 eb ca d5 3d a9 ee 97 98 ca 8d aa 44 t.i5...=.......D
> 0e 25 99 4a 15 96 a4 ce 6d 02 54 1f 2a 6a 26 e2 .%.J....m.T.*j&.
> 06 3a 63 48 ac b4 4c d1 75 93 50 ff 13 2f d6 da .:cH..L.u.P../..
> e1 c6 18 f5 9f c9 25 5d f3 00 3a de 26 4d b4 29 ......%]..:.&M.)
> 09 cd 0f 3d 23 6f 16 4a 81 16 fb f2 83 10 c3 b8 ...=#o.J........
> d6 d8 55 32 3d f1 bd 0f bd 8c 52 95 4a 16 97 7a ..U2=.....R.J..z
> 52 21 63 75 2f 16 f9 c4 66 be f5 b5 09 d8 ff 27 R!cu/...f......'
> 00 cd 44 7c 6f 4b 3f b0 f7 02 03 01 00 01 ..D|oK?.......
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.19, Critical:1, Value:: Length:8,
> 30 06 01 01 ff 02 01 00 0.......
> Extension: OID:2.5.29.31, Critical:0, Value:: Length:41,
> 30 27 30 25 a0 23 a0 21 86 1f 68 74 74 70 3a 2f 0'0%.#.!..http:/
> 2f 73 31 2e 73 79 6d 63 62 2e 63 6f 6d 2f 70 63 /s1.symcb.com/pc
> 61 33 2d 67 35 2e 63 72 6c a3-g5.crl
> Extension: OID:2.5.29.15, Critical:1, Value:: Length:4,
> 03 02 01 06 ....
> Extension: OID:1.3.6.1.5.5.7.1.1, Critical:0, Value:: Length:35,
> 30 21 30 1f 06 08 2b 06 01 05 05 07 30 01 86 13 0!0...+.....0...
> 68 74 74 70 3a 2f 2f 73 32 2e 73 79 6d 63 62 2e http://s2.symcb.
> 63 6f 6d com
> Extension: OID:2.5.29.32, Critical:0, Value:: Length:100,
> 30 62 30 60 06 0a 60 86 48 01 86 f8 45 01 07 36 0b0`..`.H...E..6
> 30 52 30 26 06 08 2b 06 01 05 05 07 02 01 16 1a 0R0&..+.........
> 68 74 74 70 3a 2f 2f 77 77 77 2e 73 79 6d 61 75 http://www.symau
> 74 68 2e 63 6f 6d 2f 63 70 73 30 28 06 08 2b 06 th.com/cps0(..+.
> 01 05 05 07 02 02 30 1c 1a 1a 68 74 74 70 3a 2f ......0...http:/
> 2f 77 77 77 2e 73 79 6d 61 75 74 68 2e 63 6f 6d /www.symauth.com
> 2f 72 70 61 /rpa
> Extension: OID:2.5.29.17, Critical:0, Value:: Length:34,
> 30 20 a4 1e 30 1c 31 1a 30 18 06 03 55 04 03 13 0 ..0.1.0...U...
> 11 53 79 6d 61 6e 74 65 63 50 4b 49 2d 31 2d 35 .SymantecPKI-1-5
> 33 34 34
> Extension: OID:2.5.29.14, Critical:0, Value:: Length:22,
> 04 14 5f 60 cf 61 90 55 df 84 43 14 8a 60 2a b2 .._`.a.U..C..`*.
> f5 7a f4 43 18 ef .z.C..
> Extension: OID:2.5.29.35, Critical:0, Value:: Length:24,
> 30 16 80 14 7f d3 65 a7 c2 dd ec bb f0 30 09 f3 0.....e......0..
> 43 39 fa 02 af 33 31 33 C9...313
> SHA1 hash
> Length:20,
> ff 67 36 7c 5c d4 de 4a e1 8b cc e1 d7 0f da bd .g6|\..J........
> 7c 86 61 35 |.a5
> Sending server first part of request
> Requesting server renegotiation
> Sending server second part of request
> Getting response
> Received response data:: Length:419,
> 48 54 54 50 2f 31 2e 30 20 34 30 30 20 42 61 64 HTTP/1.0 400 Bad
> 20 52 65 71 75 65 73 74 0d 0a 53 65 72 76 65 72 Request..Server
> 3a 20 41 6b 61 6d 61 69 47 48 6f 73 74 0d 0a 4d : AkamaiGHost..M
> 69 6d 65 2d 56 65 72 73 69 6f 6e 3a 20 31 2e 30 ime-Version: 1.0
> 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 ..Content-Type:
> 74 65 78 74 2f 68 74 6d 6c 0d 0a 43 6f 6e 74 65 text/html..Conte
> 6e 74 2d 4c 65 6e 67 74 68 3a 20 32 30 39 0d 0a nt-Length: 209..
> 45 78 70 69 72 65 73 3a 20 53 61 74 2c 20 32 32 Expires: Sat, 22
> 20 4f 63 74 20 32 30 31 36 20 32 33 3a 34 35 3a Oct 2016 23:45:
> 33 37 20 47 4d 54 0d 0a 44 61 74 65 3a 20 53 61 37 GMT..Date: Sa
> 74 2c 20 32 32 20 4f 63 74 20 32 30 31 36 20 32 t, 22 Oct 2016 2
> 33 3a 34 35 3a 33 37 20 47 4d 54 0d 0a 43 6f 6e 3:45:37 GMT..Con
> 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 0d 0a nection: close..
> 0d 0a 3c 48 54 4d 4c 3e 3c 48 45 41 44 3e 0a 3c ..<HTML><HEAD>.<
> 54 49 54 4c 45 3e 49 6e 76 61 6c 69 64 20 55 52 TITLE>Invalid UR
> 4c 3c 2f 54 49 54 4c 45 3e 0a 3c 2f 48 45 41 44 L</TITLE>.</HEAD
> 3e 3c 42 4f 44 59 3e 0a 3c 48 31 3e 49 6e 76 61 ><BODY>.<H1>Inva
> 6c 69 64 20 55 52 4c 3c 2f 48 31 3e 0a 54 68 65 lid URL</H1>.The
> 20 72 65 71 75 65 73 74 65 64 20 55 52 4c 20 22 requested URL "
> 26 23 39 31 3b 6e 6f 26 23 33 32 3b 55 52 4c 26 &#91;no&#32;URL&
> 23 39 33 3b 22 2c 20 69 73 20 69 6e 76 61 6c 69 #93;", is invali
> 64 2e 3c 70 3e 0a 52 65 66 65 72 65 6e 63 65 26 d.<p>.Reference&
> 23 33 32 3b 26 23 33 35 3b 39 26 23 34 36 3b 34 #32;&#35;9&#46;4
> 64 64 36 31 32 30 32 26 23 34 36 3b 31 34 37 37 dd61202&#46;1477
> 31 37 39 39 33 37 26 23 34 36 3b 31 37 37 31 31 179937&#46;17711
> 36 32 31 0a 3c 2f 42 4f 44 59 3e 3c 2f 48 54 4d 621.</BODY></HTM
> 4c 3e 0a L>.
> Stopping receive of response because of SEC_I_CONTEXT_EXPIRED status value from CSSL::GetEncryptedMessage
> Sending close_notify message

- And finally here is the screen capture from the test app when connecting to https://www.google.com (with the client not performing any client renegotiation in midstream as Google seem to reject that):

> D:\Dev\My Code\SSLWrappers\Release>SSLWrappersDemo.exe 0 www.google.com 443
> Connecting to www.google.com:443
> Performing SSL client handshake
> Protocol: TLS v1.2
> Cipher: AES
> Cipher strength: 128
> Hash: SHA-256
> Hash strength: 0
> Key exchange: Eliptic curve Diffie Hellman Ephemeral
> Key exchange strength: 256
> Remote server certificate properties
> Subject string: C=US, S=California, L=Mountain View, O=Google Inc, CN=www.google.com
> Version: 2
> Serial number: Length:8,
> 5e 30 9a 49 f1 28 f9 29 ^0.I.(.)
> Crypt algorithm Identifier: 1.2.840.113549.1.1.11
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:75,
> 30 49 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0I1.0...U....US1
> 13 30 11 06 03 55 04 0a 13 0a 47 6f 6f 67 6c 65 .0...U....Google
> 20 49 6e 63 31 25 30 23 06 03 55 04 03 13 1c 47 Inc1%0#..U....G
> 6f 6f 67 6c 65 20 49 6e 74 65 72 6e 65 74 20 41 oogle Internet A
> 75 74 68 6f 72 69 74 79 20 47 32 uthority G2
> Not valid before: 2016-10-06 13:02:45
> Not valid after: 2016-12-29 12:28:00
> Subject data: Length:106,
> 30 68 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0h1.0...U....US1
> 13 30 11 06 03 55 04 08 0c 0a 43 61 6c 69 66 6f .0...U....Califo
> 72 6e 69 61 31 16 30 14 06 03 55 04 07 0c 0d 4d rnia1.0...U....M
> 6f 75 6e 74 61 69 6e 20 56 69 65 77 31 13 30 11 ountain View1.0.
> 06 03 55 04 0a 0c 0a 47 6f 6f 67 6c 65 20 49 6e ..U....Google In
> 63 31 17 30 15 06 03 55 04 03 0c 0e 77 77 77 2e c1.0...U....www.
> 67 6f 6f 67 6c 65 2e 63 6f 6d google.com
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 ca 53 57 9a 4f 36 8c 0.........SW.O6.
> 89 d1 d5 61 3a 37 2b 65 0a 3a 72 31 79 78 a7 3c ...a:7+e.:r1yx.<
> 00 4b 49 b0 bf 6d e8 27 03 c6 e8 7e 29 ab a2 9d .KI..m.'...~)...
> 88 1e 81 0b dc 23 19 29 a3 a1 1a a3 be 01 0a 4f .....#.).......O
> 62 d6 ee 0f 5a 15 51 c9 08 d6 a9 50 8c c6 a6 c2 b...Z.Q....P....
> f1 e1 fe 22 45 80 36 8d 73 ca 5c 4d 30 c7 36 0a ..."E.6.s.\M0.6.
> 9b b3 26 77 87 7e 1b 5c 18 91 61 41 b4 d6 51 07 ..&w.~.\..aA..Q.
> 50 69 f6 19 84 b2 b1 a3 b5 62 3b c3 a8 ac f0 05 Pi.......b;.....
> b9 dd c3 c0 c4 28 de eb 92 20 1b 9f 8a 88 b4 0a .....(... ......
> b6 b6 76 da df cf 5f 90 6b 85 81 48 5b 4b 1e 7f ..v..._.k..H[K..
> cc bd 1e 7a ba e3 be ff 39 e7 90 c9 cc 01 2a ca ...z....9.....*.
> 13 c7 95 3e 46 0d ad e6 ea 0b e6 2a 5e 63 3d 20 ...>F......*^c=
> 93 d7 6a 2e d8 3e 9c 41 a1 f8 8c b3 ce 07 39 02 ..j..>.A......9.
> 71 48 68 a7 83 d6 47 24 60 31 ea b6 6d 51 cb 3f qHh...G$`1..mQ.?
> 75 80 e4 d7 f6 d2 c9 99 bd 18 5f 82 6f fe ea 52 u........._.o..R
> 3f 30 64 4a 5c f6 8d 6c 7b 7d 65 20 d5 1d 2a 7f ?0dJ\..l{}e ..*.
> 97 8a 3d bf 25 49 11 6a 65 02 03 01 00 01 ..=.%I.je.....
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.37, Critical:0, Value:: Length:22,
> 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 0...+.........+.
> 01 05 05 07 03 02 ......
> Extension: OID:2.5.29.17, Critical:0, Value:: Length:18,
> 30 10 82 0e 77 77 77 2e 67 6f 6f 67 6c 65 2e 63 0...www.google.c
> 6f 6d om
> Extension: OID:1.3.6.1.5.5.7.1.1, Critical:0, Value:: Length:92,
> 30 5a 30 2b 06 08 2b 06 01 05 05 07 30 02 86 1f 0Z0+..+.....0...
> 68 74 74 70 3a 2f 2f 70 6b 69 2e 67 6f 6f 67 6c http://pki.googl
> 65 2e 63 6f 6d 2f 47 49 41 47 32 2e 63 72 74 30 e.com/GIAG2.crt0
> 2b 06 08 2b 06 01 05 05 07 30 01 86 1f 68 74 74 +..+.....0...htt
> 70 3a 2f 2f 63 6c 69 65 6e 74 73 31 2e 67 6f 6f p://clients1.goo
> 67 6c 65 2e 63 6f 6d 2f 6f 63 73 70 gle.com/ocsp
> Extension: OID:2.5.29.14, Critical:0, Value:: Length:22,
> 04 14 5b 5c 5d 7c e5 50 4a 84 99 8f 4d 8e 5e 6a ..[\]|.PJ...M.^j
> cb fd 17 4c 44 a2 ...LD.
> Extension: OID:2.5.29.19, Critical:1, Value:: Length:2,
> 30 00 0.
> Extension: OID:2.5.29.35, Critical:0, Value:: Length:24,
> 30 16 80 14 4a dd 06 16 1b bc f6 68 b5 76 f5 81 0...J......h.v..
> b6 bb 62 1a ba 5a 81 2f ..b..Z./
> Extension: OID:2.5.29.32, Critical:0, Value:: Length:26,
> 30 18 30 0c 06 0a 2b 06 01 04 01 d6 79 02 05 01 0.0...+.....y...
> 30 08 06 06 67 81 0c 01 02 02 0...g.....
> Extension: OID:2.5.29.31, Critical:0, Value:: Length:41,
> 30 27 30 25 a0 23 a0 21 86 1f 68 74 74 70 3a 2f 0'0%.#.!..http:/
> 2f 70 6b 69 2e 67 6f 6f 67 6c 65 2e 63 6f 6d 2f /pki.google.com/
> 47 49 41 47 32 2e 63 72 6c GIAG2.crl
> Property Identifier: 119
> Length:538,
> 43 53 43 43 1a 02 00 00 a0 00 00 00 38 00 00 00 CSCC........8...
> 03 00 00 00 09 00 00 00 6c 01 00 00 ae 00 00 00 ........l.......
> 00 00 00 00 00 01 00 00 80 c8 12 ee d1 1f d2 01 ................
> 00 08 04 fe ce 61 d2 01 61 00 00 00 00 00 00 00 .....a..a.......
> 01 00 00 00 02 00 00 00 45 6e da 33 00 00 00 00 ........En.3....
> 48 5d 3a ab bc 2c d2 01 ac 82 82 49 b4 2c d2 01 H]:..,.....I.,..
> ac 52 0b 0d c5 2c d2 01 00 00 00 00 00 00 00 00 .R...,..........
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 89 91 31 a1 ee 5e f8 d8 15 46 49 bb a1 1c c7 6e ..1..^...FI....n
> 27 b7 1b 0f 8d f0 5d 8e 74 30 de 89 7c 60 b9 58 '.....].t0..|`.X
> 38 00 00 00 00 00 00 00 00 00 00 00 02 01 00 00 8...............
> 01 00 00 00 00 00 00 00 02 00 00 00 01 00 00 00 ................
> 15 e6 b9 9d 87 ce 30 ac 89 b0 2d 68 bb 9b ab dd ......0...-h....
> 9b d1 e4 85 00 00 00 00 38 00 00 00 00 00 00 00 ........8.......
> 00 00 00 00 02 01 00 00 01 00 00 00 03 00 00 00 ................
> ff ff ff ff 00 00 00 00 d6 ad 07 c6 67 56 30 f5 ............gV0.
> 7b 92 7f 66 be 8c e1 f7 68 f8 79 48 00 00 00 00 {..f....h.yH....
> 38 00 00 00 00 00 00 00 00 00 00 00 0a 01 00 00 8...............
> ff ff ff ff 00 00 00 00 05 00 00 00 04 00 00 00 ................
> de 28 f4 a4 ff e5 b9 2f a3 c5 03 d1 a3 49 a7 f9 .(...../.....I..
> 96 2a 82 12 00 00 00 00 00 00 00 00 18 00 00 00 .*..............
> 2a 00 00 00 3c 00 00 00 54 00 00 00 66 00 00 00 *...<...T...f...
> 78 00 00 00 8a 00 00 00 9c 00 00 00 31 2e 33 2e x...........1.3.
> 36 2e 31 2e 34 2e 31 2e 31 31 31 32 39 2e 32 2e 6.1.4.1.11129.2.
> 35 2e 31 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e 5.1.1.3.6.1.5.5.
> 37 2e 33 2e 31 00 31 2e 33 2e 36 2e 31 2e 35 2e 7.3.1.1.3.6.1.5.
> 35 2e 37 2e 33 2e 32 00 31 2e 33 2e 36 2e 31 2e 5.7.3.2.1.3.6.1.
> 34 2e 31 2e 31 31 31 32 39 2e 32 2e 35 2e 31 00 4.1.11129.2.5.1.
> 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e 37 2e 33 2e 1.3.6.1.5.5.7.3.
> 31 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e 37 2e 1.1.3.6.1.5.5.7.
> 33 2e 32 00 31 2e 33 2e 36 2e 31 2e 35 2e 35 2e 3.2.1.3.6.1.5.5.
> 37 2e 33 2e 34 00 31 2e 33 2e 36 2e 31 2e 35 2e 7.3.4.1.3.6.1.5.
> 35 2e 37 2e 33 2e 33 00 31 2e 33 2e 36 2e 31 2e 5.7.3.3.1.3.6.1.
> 35 2e 35 2e 37 2e 33 2e 38 00 5.5.7.3.8.
> SHA1 hash
> Length:20,
> 15 e6 b9 9d 87 ce 30 ac 89 b0 2d 68 bb 9b ab dd ......0...-h....
> 9b d1 e4 85 ....
> Next certificate in chain
> Subject string: C=US, O=Google Inc, CN=Google Internet Authority G2
> Version: 2
> Serial number: Length:3,
> 92 3a 02 .:.
> Crypt algorithm Identifier: 1.2.840.113549.1.1.11
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:68,
> 30 42 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0B1.0...U....US1
> 16 30 14 06 03 55 04 0a 13 0d 47 65 6f 54 72 75 .0...U....GeoTru
> 73 74 20 49 6e 63 2e 31 1b 30 19 06 03 55 04 03 st Inc.1.0...U..
> 13 12 47 65 6f 54 72 75 73 74 20 47 6c 6f 62 61 ..GeoTrust Globa
> 6c 20 43 41 l CA
> Not valid before: 2015-04-01 00:00:00
> Not valid after: 2017-12-31 23:59:59
> Subject data: Length:75,
> 30 49 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0I1.0...U....US1
> 13 30 11 06 03 55 04 0a 13 0a 47 6f 6f 67 6c 65 .0...U....Google
> 20 49 6e 63 31 25 30 23 06 03 55 04 03 13 1c 47 Inc1%0#..U....G
> 6f 6f 67 6c 65 20 49 6e 74 65 72 6e 65 74 20 41 oogle Internet A
> 75 74 68 6f 72 69 74 79 20 47 32 uthority G2
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 9c 2a 04 77 5c d8 50 0.........*.w\.P
> 91 3a 06 a3 82 e0 d8 50 48 bc 89 3f f1 19 70 1a .:.....PH..?..p.
> 88 46 7e e0 8f c5 f1 89 ce 21 ee 5a fe 61 0d b7 .F~......!.Z.a..
> 32 44 89 a0 74 0b 53 4f 55 a4 ce 82 62 95 ee eb 2D..t.SOU...b...
> 59 5f c6 e1 05 80 12 c4 5e 94 3f bc 5b 48 38 f4 Y_......^.?.[H8.
> 53 f7 24 e6 fb 91 e9 15 c4 cf f4 53 0d f4 4a fc S.$........S..J.
> 9f 54 de 7d be a0 6b 6f 87 c0 d0 50 1f 28 30 03 .T.}..ko...P.(0.
> 40 da 08 73 51 6c 7f ff 3a 3c a7 37 06 8e bd 4b @..sQl..:<.7...K
> 11 04 eb 7d 24 de e6 f9 fc 31 71 fb 94 d5 60 f3 ...}$....1q...`.
> 2e 4a af 42 d2 cb ea c4 6a 1a b2 cc 53 dd 15 4b .J.B....j...S..K
> 8b 1f c8 19 61 1f cd 9d a8 3e 63 2b 84 35 69 65 ....a....>c+.5ie
> 84 c8 19 c5 46 22 f8 53 95 be e3 80 4a 10 c6 2a ....F".S....J..*
> ec ba 97 20 11 c7 39 99 10 04 a0 f0 61 7a 95 25 ... ..9.....az.%
> 8c 4e 52 75 e2 b6 ed 08 ca 14 fc ce 22 6a b3 4e .NRu........"j.N
> cf 46 03 97 97 03 7e c0 b1 de 7b af 45 33 cf ba .F....~...{.E3..
> 3e 71 b7 de f4 25 25 c2 0d 35 89 9d 9d fb 0e 11 >q...%%..5......
> 79 89 1e 37 c5 af 8e 72 69 02 03 01 00 01 y..7...ri.....
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.35, Critical:0, Value:: Length:24,
> 30 16 80 14 c0 7a 98 68 8d 89 fb ab 05 64 0c 11 0....z.h.....d..
> 7d aa 7d 65 b8 ca cc 4e }.}e...N
> Extension: OID:2.5.29.14, Critical:0, Value:: Length:22,
> 04 14 4a dd 06 16 1b bc f6 68 b5 76 f5 81 b6 bb ..J......h.v....
> 62 1a ba 5a 81 2f b..Z./
> Extension: OID:2.5.29.15, Critical:1, Value:: Length:4,
> 03 02 01 06 ....
> Extension: OID:1.3.6.1.5.5.7.1.1, Critical:0, Value:: Length:34,
> 30 20 30 1e 06 08 2b 06 01 05 05 07 30 01 86 12 0 0...+.....0...
> 68 74 74 70 3a 2f 2f 67 2e 73 79 6d 63 64 2e 63 http://g.symcd.c
> 6f 6d om
> Extension: OID:2.5.29.19, Critical:1, Value:: Length:8,
> 30 06 01 01 ff 02 01 00 0.......
> Extension: OID:2.5.29.31, Critical:0, Value:: Length:46,
> 30 2c 30 2a a0 28 a0 26 86 24 68 74 74 70 3a 2f 0,0*.(.&.$http:/
> 2f 67 2e 73 79 6d 63 62 2e 63 6f 6d 2f 63 72 6c /g.symcb.com/crl
> 73 2f 67 74 67 6c 6f 62 61 6c 2e 63 72 6c s/gtglobal.crl
> Extension: OID:2.5.29.32, Critical:0, Value:: Length:16,
> 30 0e 30 0c 06 0a 2b 06 01 04 01 d6 79 02 05 01 0.0...+.....y...
> SHA1 hash
> Length:20,
> d6 ad 07 c6 67 56 30 f5 7b 92 7f 66 be 8c e1 f7 ....gV0.{..f....
> 68 f8 79 48 h.yH
> Next certificate in chain
> Subject string: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
> Version: 2
> Serial number: Length:3,
> e6 bb 12 ...
> Crypt algorithm Identifier: 1.2.840.113549.1.1.5
> Crypt algorithm identifier parameters: Length:2,
> 05 00 ..
> Issuer: Length:80,
> 30 4e 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0N1.0...U....US1
> 10 30 0e 06 03 55 04 0a 13 07 45 71 75 69 66 61 .0...U....Equifa
> 78 31 2d 30 2b 06 03 55 04 0b 13 24 45 71 75 69 x1-0+..U...$Equi
> 66 61 78 20 53 65 63 75 72 65 20 43 65 72 74 69 fax Secure Certi
> 66 69 63 61 74 65 20 41 75 74 68 6f 72 69 74 79 ficate Authority
> Not valid before: 2002-05-21 04:00:00
> Not valid after: 2018-08-21 04:00:00
> Subject data: Length:68,
> 30 42 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 0B1.0...U....US1
> 16 30 14 06 03 55 04 0a 13 0d 47 65 6f 54 72 75 .0...U....GeoTru
> 73 74 20 49 6e 63 2e 31 1b 30 19 06 03 55 04 03 st Inc.1.0...U..
> 13 12 47 65 6f 54 72 75 73 74 20 47 6c 6f 62 61 ..GeoTrust Globa
> 6c 20 43 41 l CA
> Subject public key algorithm Identifier: 1.2.840.113549.1.1.1
> Subject public key: Length:270,
> 30 82 01 0a 02 82 01 01 00 da cc 18 63 30 fd f4 0...........c0..
> 17 23 1a 56 7e 5b df 3c 6c 38 e4 71 b7 78 91 d4 .#.V~[.<l8.q.x..
> bc a1 d8 4c f8 a8 43 b6 03 e9 4d 21 07 08 88 da ...L..C...M!....
> 58 2f 66 39 29 bd 05 78 8b 9d 38 e8 05 b7 6a 7e X/f9)..x..8...j~
> 71 a4 e6 c4 60 a6 b0 ef 80 e4 89 28 0f 9e 25 d6 q...`......(..%.
> ed 83 f3 ad a6 91 c7 98 c9 42 18 35 14 9d ad 98 .........B.5....
> 46 92 2e 4f ca f1 87 43 c1 16 95 57 2d 50 ef 89 F..O...C...W-P..
> 2d 80 7a 57 ad f2 ee 5f 6b d2 00 8d b9 14 f8 14 -.zW..._k.......
> 15 35 d9 c0 46 a3 7b 72 c8 91 bf c9 55 2b cd d0 .5..F.{r....U+..
> 97 3e 9c 26 64 cc df ce 83 19 71 ca 4e e6 d4 d5 .>.&d.....q.N...
> 7b a9 19 cd 55 de c8 ec d2 5e 38 53 e5 5c 4f 8c {...U....^8S.\O.
> 2d fe 50 23 36 fc 66 e6 cb 8e a4 39 19 00 b7 95 -.P#6.f....9....
> 02 39 91 0b 0e fe 38 2e d1 1d 05 9a f6 4d 3e 6f .9....8......M>o
> 0f 07 1d af 2c 1e 8f 60 39 e2 fa 36 53 13 39 d4 ....,..`9..6S.9.
> 5e 26 2b db 3d a8 14 bd 32 eb 18 03 28 52 04 71 ^&+.=...2...(R.q
> e5 ab 33 3d e1 38 bb 07 36 84 62 9c 79 ea 16 30 ..3=.8..6.b.y..0
> f4 5f c0 2b e8 71 6b e4 f9 02 03 01 00 01 ._.+.qk.......
> Issuer unique id: Length:0,
> <NULL>
> Subject unique id: Length:0,
> <NULL>
> Extension: OID:2.5.29.35, Critical:0, Value:: Length:24,
> 30 16 80 14 48 e6 68 f9 2b d2 b2 95 d7 47 d8 23 0...H.h.+....G.#
> 20 10 4f 33 98 90 9f d4 .O3....
> Extension: OID:2.5.29.14, Critical:0, Value:: Length:22,
> 04 14 c0 7a 98 68 8d 89 fb ab 05 64 0c 11 7d aa ...z.h.....d..}.
> 7d 65 b8 ca cc 4e }e...N
> Extension: OID:2.5.29.19, Critical:1, Value:: Length:5,
> 30 03 01 01 ff 0....
> Extension: OID:2.5.29.15, Critical:1, Value:: Length:4,
> 03 02 01 06 ....
> Extension: OID:2.5.29.31, Critical:0, Value:: Length:51,
> 30 31 30 2f a0 2d a0 2b 86 29 68 74 74 70 3a 2f 010/.-.+.)http:/
> 2f 63 72 6c 2e 67 65 6f 74 72 75 73 74 2e 63 6f /crl.geotrust.co
> 6d 2f 63 72 6c 73 2f 73 65 63 75 72 65 63 61 2e m/crls/secureca.
> 63 72 6c crl
> Extension: OID:2.5.29.32, Critical:0, Value:: Length:71,
> 30 45 30 43 06 04 55 1d 20 00 30 3b 30 39 06 08 0E0C..U. .0;09..
> 2b 06 01 05 05 07 02 01 16 2d 68 74 74 70 73 3a +........-https:
> 2f 2f 77 77 77 2e 67 65 6f 74 72 75 73 74 2e 63 //www.geotrust.c
> 6f 6d 2f 72 65 73 6f 75 72 63 65 73 2f 72 65 70 om/resources/rep
> 6f 73 69 74 6f 72 79 ository
> SHA1 hash
> Length:20,
> 73 59 75 5c 6d f9 a0 ab c3 06 0b ce 36 95 64 c8 sYu\m.......6.d.
> ec 45 42 a3 .EB.
> Sending request
> Getting response
> Received response data:: Length:944,
> 48 54 54 50 2f 31 2e 30 20 33 30 32 20 46 6f 75 HTTP/1.0 302 Fou
> 6e 64 0d 0a 4c 6f 63 61 74 69 6f 6e 3a 20 68 74 nd..Location: ht
> 74 70 73 3a 2f 2f 77 77 77 2e 67 6f 6f 67 6c 65 tps://www.google
> 2e 69 65 2f 3f 67 77 73 5f 72 64 3d 63 72 26 65 .ie/?gws_rd=cr&e
> 69 3d 50 5f 63 4c 57 4c 58 47 49 71 7a 55 67 41 i=P_cLWLXGIqzUgA
> 61 34 31 49 47 41 42 51 0d 0a 43 61 63 68 65 2d a41IGABQ..Cache-
> 43 6f 6e 74 72 6f 6c 3a 20 70 72 69 76 61 74 65 Control: private
> 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 ..Content-Type:
> 74 65 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 text/html; chars
> 65 74 3d 55 54 46 2d 38 0d 0a 50 33 50 3a 20 43 et=UTF-8..P3P: C
> 50 3d 22 54 68 69 73 20 69 73 20 6e 6f 74 20 61 P="This is not a
> 20 50 33 50 20 70 6f 6c 69 63 79 21 20 53 65 65 P3P policy! See
> 20 68 74 74 70 73 3a 2f 2f 77 77 77 2e 67 6f 6f https://www.goo
> 67 6c 65 2e 63 6f 6d 2f 73 75 70 70 6f 72 74 2f gle.com/support/
> 61 63 63 6f 75 6e 74 73 2f 61 6e 73 77 65 72 2f accounts/answer/
> 31 35 31 36 35 37 3f 68 6c 3d 65 6e 20 66 6f 72 151657?hl=en for
> 20 6d 6f 72 65 20 69 6e 66 6f 2e 22 0d 0a 44 61 more info."..Da
> 74 65 3a 20 53 61 74 2c 20 32 32 20 4f 63 74 20 te: Sat, 22 Oct
> 32 30 31 36 20 32 33 3a 33 33 3a 31 39 20 47 4d 2016 23:33:19 GM
> 54 0d 0a 53 65 72 76 65 72 3a 20 67 77 73 0d 0a T..Server: gws..
> 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 Content-Length:
> 32 35 39 0d 0a 58 2d 58 53 53 2d 50 72 6f 74 65 259..X-XSS-Prote
> 63 74 69 6f 6e 3a 20 31 3b 20 6d 6f 64 65 3d 62 ction: 1; mode=b
> 6c 6f 63 6b 0d 0a 58 2d 46 72 61 6d 65 2d 4f 70 lock..X-Frame-Op
> 74 69 6f 6e 73 3a 20 53 41 4d 45 4f 52 49 47 49 tions: SAMEORIGI
> 4e 0d 0a 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 4e N..Set-Cookie: N
> 49 44 3d 38 39 3d 74 72 37 62 4a 37 6b 43 61 74 ID=89=tr7bJ7kCat
> 32 54 69 4b 4c 4d 55 65 41 64 4e 43 58 58 58 67 2TiKLMUeAdNCXXXg
> 53 51 31 62 53 6d 54 42 58 38 4f 62 74 79 70 74 SQ1bSmTBX8Obtypt
> 39 54 73 6e 65 4f 57 51 79 32 47 79 37 44 48 51 9TsneOWQy2Gy7DHQ
> 64 74 61 5f 79 50 66 76 65 42 65 55 72 6c 64 44 dta_yPfveBeUrldD
> 4b 56 30 5a 75 6e 6d 36 33 63 36 43 33 61 66 62 KV0Zunm63c6C3afb
> 70 5f 41 42 39 4e 39 77 37 50 62 32 30 31 45 57 p_AB9N9w7Pb201EW
> 56 64 71 39 79 72 68 78 62 76 6d 76 75 7a 79 39 Vdq9yrhxbvmvuzy9
> 55 41 34 68 6c 53 3b 20 65 78 70 69 72 65 73 3d UA4hlS; expires=
> 53 75 6e 2c 20 32 33 2d 41 70 72 2d 32 30 31 37 Sun, 23-Apr-2017
> 20 32 33 3a 33 33 3a 31 39 20 47 4d 54 3b 20 70 23:33:19 GMT; p
> 61 74 68 3d 2f 3b 20 64 6f 6d 61 69 6e 3d 2e 67 ath=/; domain=.g
> 6f 6f 67 6c 65 2e 63 6f 6d 3b 20 48 74 74 70 4f oogle.com; HttpO
> 6e 6c 79 0d 0a 41 6c 74 2d 53 76 63 3a 20 71 75 nly..Alt-Svc: qu
> 69 63 3d 22 3a 34 34 33 22 3b 20 6d 61 3d 32 35 ic=":443"; ma=25
> 39 32 30 30 30 3b 20 76 3d 22 33 36 2c 33 35 2c 92000; v="36,35,
> 33 34 2c 33 33 2c 33 32 22 0d 0a 0d 0a 3c 48 54 34,33,32"....<HT
> 4d 4c 3e 3c 48 45 41 44 3e 3c 6d 65 74 61 20 68 ML><HEAD><meta h
> 74 74 70 2d 65 71 75 69 76 3d 22 63 6f 6e 74 65 ttp-equiv="conte
> 6e 74 2d 74 79 70 65 22 20 63 6f 6e 74 65 6e 74 nt-type" content
> 3d 22 74 65 78 74 2f 68 74 6d 6c 3b 63 68 61 72 ="text/html;char
> 73 65 74 3d 75 74 66 2d 38 22 3e 0a 3c 54 49 54 set=utf-8">.<TIT
> 4c 45 3e 33 30 32 20 4d 6f 76 65 64 3c 2f 54 49 LE>302 Moved</TI
> 54 4c 45 3e 3c 2f 48 45 41 44 3e 3c 42 4f 44 59 TLE></HEAD><BODY
> 3e 0a 3c 48 31 3e 33 30 32 20 4d 6f 76 65 64 3c >.<H1>302 Moved<
> 2f 48 31 3e 0a 54 68 65 20 64 6f 63 75 6d 65 6e /H1>.The documen
> 74 20 68 61 73 20 6d 6f 76 65 64 0a 3c 41 20 48 t has moved.<A H
> 52 45 46 3d 22 68 74 74 70 73 3a 2f 2f 77 77 77 REF="https://www
> 2e 67 6f 6f 67 6c 65 2e 69 65 2f 3f 67 77 73 5f .google.ie/?gws_
> 72 64 3d 63 72 26 61 6d 70 3b 65 69 3d 50 5f 63 rd=cr&amp;ei=P_c
> 4c 57 4c 58 47 49 71 7a 55 67 41 61 34 31 49 47 LWLXGIqzUgAa41IG
> 41 42 51 22 3e 68 65 72 65 3c 2f 41 3e 2e 0d 0a ABQ">here</A>...
> 3c 2f 42 4f 44 59 3e 3c 2f 48 54 4d 4c 3e 0d 0a </BODY></HTML>..
> Stopping receive of response because of graceful disconnect status value from CSSL::GetEncryptedMessage

## History

v1.19 (6 November 2020)

- Fixed an issue where the m_lExtraReadData member variable is not reset in the SSLConnect and SSLAccept methods. This can lead to problems where a CSSL instance is reused to connect to another server or a TLS server connects to a new client. This issue was occurring in the SMTP code of the author when connecting to some SMTP servers which were using a pure SSL/TLS connection as opposed to STARTTLS. Thanks to Koen De Wolf for reporting this issue and helping fix it.

v1.18 (12 April 2020)

- Fixed more Clang-Tidy static code analysis warnings in the code.

v1.17 (4 January 2020)

- Fixed more Clang-Tidy static code analysis warnings in the code.

v1.16 (18 December 2019)

- Fixed various Clang-Tidy static code analysis warnings in the code.

v1.15 (10 November 2019)

- Updated initialization of various structs to use C++ 11 list initialization
- Replaced BOOL with bool in a number of places throughout the codebase

v1.14 (12 September 2019)

- Fixed a number of compiler warnings when the code is compiled with VS 2019 Preview

v1.13 (9 April 2019)

- Updated copyright details.
- Fixed a number of compiler warnings when using VS 2019.

v1.12 (22 August 2018)

- Fixed a number of compiler warnings when using VS 2017 15.8.1

v1.11 (7 June 2018)

- Updated copyright details.
- Fixed a number of C++ core guidelines compiler warnings. These changes mean that the code will now only compile on VC 2017 or later.
- Replaced CMessage class with std::vector<BYTE>

v1.10 (27 April 2017)

- Updated the code to compile cleanly using /permissive-.

v1.09 (15 April 2017)

- Updated the sample app to log more information about the connection in the DisplayConnectionInfo function. New details logged include SECPKGCONTEXT_CONNECTION_INFO_EX_V1, SECPKG_ATTR_CIPHER_INFO, SECPKG_ATTR_CIPHER_STRENGTHS, SECPKG_ATTR_SUPPORTED_ALGS, SECPKG_ATTR_SUPPORTED_PROTOCOLS, SECPKG_ATTR_APP_DATA, SECPKG_ATTR_AUTHORITY, SECPKG_ATTR_EAP_KEY_BLOCK, SECPKG_ATTR_FLAGS, SECPKG_ATTR_LIFESPAN, SECPKG_ATTR_NAMES, SECPKG_ATTR_SESSION_INFO, SECPKG_ATTR_SESSION_KEY, SECPKG_ATTR_SIZES, SECPKG_ATTR_STREAM_SIZES, SECPKG_ATTR_SUPPORTED_SIGNATURES, SECPKG_ATTR_TARGET_INFORMATION, SECPKG_ATTR_KEYING_MATERIAL, SECPKG_ATTR_SRTP_PARAMETERS, SECPKG_ATTR_TOKEN_BINDING & SECPKG_ATTR_KEYING_MATERIAL_TOKEN_BINDING attributes. This also includes provisional logging of TLS v1.3 details. At the moment Windows 10 v1703 does not support TLS v1.3 but I would expect Windows 10 to include support for this protocol sometime in 2017.
- Reviewed schannel.h header file from Windows 10 v15063 SDK for any changes to SChannel in Windows 10 v1703.

v1.08 (3 February 2017)

- Updated copyright details.
- Removed unnecessary demo code from the demo app included in the download. As reported by Geoff Stevens, this demo code which calls the ExportSecurityContext and FreeContextBuffer APIs seems to cause heap corruption inside the FreeContextBuffer call. The issue only seems to occur if the FreeContextBuffer call occurs very quickly after the ExportSecurityContext call. If the call to FreeContextBuffer occurs more than 100 ms later than ExportSecurityContext then the heap corruption does not occur. I was not able to reproduce the issue and as the code was just demo code, I have simply removed it from the demo app.
- Fixed a number of typos in the text when calling the Audit methods.

v1.07 (23 October 2016)

- Updated the sample app to do better logging of the certificate & connection details. The sample app now logs details if the cipher used is CALG_ECDH_EPHEM.
- Fixed up the audit text in some of the code when allocating heap memory.
- Updated the captures of the data which the client app produces in this html documentation when run as client for localhost, www.microsoft.com, www.google.com and as server for localhost.

v1.06 (16 October 2016)

- Updated copyright details.
- Updated the sample app to compile using the latest version of the author's CWSocket class.
- Binaries of the demo app are now included in the SSLWrappers zip file download.

v1.05 (4 November 2015)

- Updated the code to compile cleanly in VC 2015.
- Fixed a bug in CSSL::VerifyServerCertificate where the code was using wrong math to calculate the size of the pCerts local variable.
- Fixed a bug in the demo app's DisplayCertChain method when calculating the size of the buffer to pass to CertNameToStr API.
- Reworked various places which allocates heap memory to use ATL::CHeapPtr instead of raw calls to HeapAlloc.

v1.04 (8 February 2015)

- Updated copyright details
- Fixed a bug in the CSSL constructor where the "m_lExtraReadData" was not being initialized to 0. This causes a bug later when GetEncryptedMessage is called and you have compiled your application without the VC 2013 /sdl compiler flag which resulted in the bug being hidden as /sdl auto initializes member variables. Thanks to Bostjan Erzen for reporting this bug

v1.03 (16 December 2014)

- Removed the unused variable CCachedCredentials::m_Credentials.
- Removed the memset call and the setting of the dwVersion member variable of the m_sslCredentials member variable in the AcquireClient and AcquireServer methods of CCachedCredentials. This allows client code to set specific values into this structure prior to it being used in these methods.
- The default value for CSSL::m_dwAuditFlags is now 0 for debug builds in addition to release builds.
- Addition of a CSSL::GetSecPkgStreamSizes method to allow access to the internal m_SecPkgSizes member variable.
- Addition of a CSSL::SendEncrypted method which handles making multiple calls to SendEncryptedMessage if the data to send exceeds the maximum SSL message size.

v1.02 (26 November 2014)

- Changed the CSSL class to contain a credentials reference rather than an actual instance. A new class called CCachedCredentials is what the CSSL maintains a reference to.

v1.01 (24 October 2014)

- Full review and update of the documentation for incorrect links etc

v1.0 (22 October 2014)

- Initial Public release

## Class Framework Reference

The framework consists of the following classes:

CCredentials
CCachedCredentials
CContext
CSSL
CSocket

CCredentials

CCredentials provides a class based encapsulation of a SSL Credentials handle as represented by a CredHandle.

Functions this class provides include:

CCredentials

~CCredentials

Acquire

Attach

Detach

Free

Handle

QueryAttibute

ValidHandle

CCredentials::CCredentials

CCredentials();

CCredentials(_In_ CCredentials&& credentials);

CCredentials(_In_ const CredHandle& handle);

Remarks

This is the constructor which initializes all the internal variables to a safe state. There are also overridden versions which initialize from an existing instance or from an SDK handle.

See Also

~CCredentials

CCredentials::~CCredentials

~CCredentials();

Remarks

This is the standard destructor for the class. Internally if calls Free to ensure that any handle that is opened is closed.

See Also

CCredentials

CCredentials::Acquire

SECURITY_STATUS Acquire(_In_ unsigned long fCredentialUse, _In_opt_ SCHANNEL_CRED* pAuthData, _Out_opt_ PTimeStamp ptsExpiry = nullptr);

Remarks

This is the wrapper for the SDK function "AcquireCredentialsHandle".

Return Value

A standard SECURITY_STATUS value.

CCredentials::Attach

void Attach(_In_ const CredHandle& handle);

Remarks

This function allows a CCredentials instance to take ownership of an SDK CredHandle value. The handle will be automatically closed in the destructor.

See Also

Detach

CCredentials::Detach

CredHandle Detach();

Remarks

This function allows a CCredentials instance to release ownership of an SDK CredHandle value.

See Also

Attach

CCredentials::Free

SECURITY_STATUS Free();

Remarks

This is the wrapper for the SDK function "FreeCredentialsHandle".

Return Value

A standard SECURITY_STATUS value.

CCredentials::Handle

CredHandle Handle() const;

Remarks

Provides access to the underlying handle which this CCrendentials instance is currently managing.

Return Value

The CredHandle instance this class is managing.

CCredentials::QueryAtrribute

SECURITY_STATUS QueryAttribute(_In_ unsigned long ulAttribute, _Inout_ void* pBuffer);

Remarks

This is the wrapper for the SDK function "QueryCredentialsAttribute".

Return Value

A standard SECURITY_STATUS value.

CCredentials::ValidHandle

bool ValidHandle() const

Remarks

This method is used to indicate if this CCredentials currently is encapsulating a valid handle or not.

Return Value

Returns true if the current instance is encapsulating a valid handle otherwise false.

CCachedCredentials

CCachedCredentials is a derived version of CCredentials which is used by the CSSL class to keep a copy of the SChannel credentials to use for the SSL connection. It is a separate object because at least for a SSL server, the lifetime of the credentials will be different than the ssl socket instance used to service SSL clients. The class internally supports setting up credentials for a client with or without a windows certificate and for a server with a windows certificate via a Cryptowrappers::CCertificate instance. The class also internally keeps a copy of a SDK SCHANNEL_CRED SDK structure.

Functions this class provides include:

CCachedCredentials

AcquireClient

AcquireServer

CCachedCredentials::CCachedCredentials

CCachedCredentials();

Remarks

This is the constructor which initializes all the internal variables to a safe state.

CCachedCredentials::AcquireClient

SECURITY_STATUS AcquireClient(_In_opt_ LPTSTR pszClientCertificateName = nullptr, _In_ LPCSTR lpszStoreProvider = CERT_STORE_PROV_SYSTEM, _In_ DWORD dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, _In_opt_ const void* pvCertOpenStorePara = L"MY")

Remarks

This is the helper function which optionally sets up a client certificate and then calls CCredentials::Acquire appropriate for a client connection.

Return Value

A standard SECURITY_STATUS value.

CCachedCredentials::AcquireServer

SECURITY_STATUS AcquireClient(_In_opt_ LPTSTR pszClientCertificateName = nullptr, _In_ LPCSTR lpszStoreProvider = CERT_STORE_PROV_SYSTEM, _In_ DWORD dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, _In_opt_ const void* pvCertOpenStorePara = L"MY")

Remarks

This is the helper function which optionally sets up a client certificate and then calls CCredentials::Acquire appropriate for a server connection.

Return Value

A standard SECURITY_STATUS value.

CContext

CContext provides a class based encapsulation of a SSL Security context as represented by a CtxtHandle.

Functions this class provides include:

CContext

~CContext

Accept

ApplyControlToken

Attach

DecryptMessage

Delete

Detach

EncryptMessage

Export

Handle

Impersonate

Import

Initialize

QueryAttribute

QueryToken

Revert

SetAttribute

ValidHandle

CContext::CContext

CContext();

CContext(_In_ CContext&& context);

CContext(_In_ const CtxtHandle& handle);

Remarks

This is the constructor which initializes all the internal variables to a safe state. There are also overridden versions which initialize from an existing instance or from an SDK handle.

See Also ~CContext

CContext::~CContext

~CContext();

Remarks

This is the standard destructor for the class. Internally if calls Delete to ensure that any handle that is opened is closed.

See Also

CContext

CContext::Accept

SECURITY_STATUS Accept(_In_ CCredentials& credentials, _In_opt_ PSecBufferDesc pInput, _In_ unsigned long fContextReq, _Inout_opt_ PSecBufferDesc pOutput, _Out_ unsigned long* pfContextAttr, _Out_opt_ PTimeStamp ptsExpiry = nullptr);

Remarks

This is the wrapper for the SDK function "AcceptSecurityContext". This is the main method used by SSL servers to perform handshakes.

Return Value

A standard SECURITY_STATUS value.

See Also

Initialize

CContext::ApplyControlToken

SECURITY_STATUS ApplyControlToken(_In_ PSecBufferDesc pInput);

Remarks

This is the wrapper for the SDK function "AcceptControlToken".

Return Value

A standard SECURITY_STATUS value.

CContext::Attach

void Attach(_In_ const CtxtHandle& handle);

Remarks

This function allows a CContext instance to take ownership of an SDK CtxtHandle value. The handle will be automatically closed in the destructor.

See Also

Detach

CContext::DecryptMessage

SECURITY_STATUS DecryptMessage(_In_ PSecBufferDesc pMessage);

Remarks

This is the wrapper for the SDK function "DecryptMessage".

Return Value

A standard SECURITY_STATUS value.

See Also

EncryptMessage

CContext::Delete

SECURITY_STATUS Delete();

Remarks

This is the wrapper for the SDK function "DeleteSecurityContext".

Return Value

A standard SECURITY_STATUS value.

CContext::Detach

CtxtHandle Detach();

Remarks

This function allows a CContext instance to release ownership of an SDK CtxtHandle value.

See Also

Attach

CContext::EncryptMessage

SECURITY_STATUS EncryptMessage(_In_ PSecBufferDesc pMessage, _In_ unsigned long fQOP = 0);

Remarks

This is the wrapper for the SDK function "EncryptMessage".

Return Value

A standard SECURITY_STATUS value.

See Also

DecryptMessage

CContext::Export

SECURITY_STATUS Export(_In_ ULONG fFlags, _Out_ PSecBuffer pPackedContext, _Out_ void** pToken);

Remarks

This is the wrapper for the SDK function "ExportSecurityContext".

Return Value

A standard SECURITY_STATUS value.

See Also

Import

CContext::Handle

CtxtHandle Handle() const;

Remarks

Provides access to the underlying handle which this CContext instance is currently managing.

Return Value

The CtxtHandle instance this class is managing.

CContext::Impersonate

SECURITY_STATUS Impersonate();

Remarks

This is the wrapper for the SDK function "ImpersonateSecurityContext". This is the corollary method to Revert.

Return Value

A standard SECURITY_STATUS value.

See Also

Revert

CContext::Import

SECURITY_STATUS Import(_In_ PSecBuffer pPackedContext, _In_ VOID* Token);

Remarks

This is the wrapper for the SDK function "ImportSecurityContext".

Return Value

A standard SECURITY_STATUS value.

See Also

Export

CContext::Initialize

SECURITY_STATUS Initialize(_In_ CCredentials& credentials,
#ifdef _UNICODE
_In_opt_ SEC_WCHAR* pszTargetName,
#else
_In_opt_ SEC_CHAR* pszTargetName,
#endif
_In_ unsigned long fContextReq, _In_opt_ PSecBufferDesc pInput, _Inout_opt_ PSecBufferDesc pOutput, _Out_ unsigned long* pfContextAttr, _Out_opt_ PTimeStamp ptsExpiry = nullptr);

Remarks

This is the wrapper for the SDK function "InitializeSecurityContext". This is the main method used by SSL clients to perform handshakes.

Return Value

A standard SECURITY_STATUS value.

See Also

Accept

CContext::QueryAttribute

SECURITY_STATUS QueryAttribute(_In_ unsigned long ulAttribute, _Out_ void* pBuffer);

Remarks

This is the wrapper for the SDK function "QueryContextAttributes". This is the corollary method to SetAttribute.

Return Value

A standard SECURITY_STATUS value.

See Also

SetAttribute

CContext::QueryToken

SECURITY_STATUS QueryToken(_Out_ void** phToken);

Remarks

This is the wrapper for the SDK function "QuerySecurityContextToken".

Return Value

A standard SECURITY_STATUS value.

See Also

SetAttribute

CContext::Revert

SECURITY_STATUS Revert();

Remarks

This is the wrapper for the SDK function "RevertSecurityContext". This is the corollary method to Impersonate.

Return Value

A standard SECURITY_STATUS value.

See Also

Impersonate

CContext::SetAttribute

SECURITY_STATUS SetAttribute(_In_ unsigned long ulAttribute, _In_reads_bytes_(cbBuffer) void* pBuffer, _In_ unsigned long cbBuffer);

Remarks

This is the wrapper for the SDK function "SetContextAttributes". This is the corollary method to QueryAttribute.

Return Value

A standard SECURITY_STATUS value.

See Also

QueryAttribute

CContext::ValidHandle

bool ValidHandle() const

Remarks

This method is used to indicate if this CContext currently is encapsulating a valid handle or not.

Return Value

Returns true if the current instance is encapsulating a valid handle otherwise false.

CSSL

CSSL is the most complex class provided by the class framework and implements all the required logic to do client and server SSL handshakes, reading and writing SSL messages, requesting SSL renegotiations, handling SSL renegotiations and sending SSL close notify messages. This class is transport mechanism agnostic meaning that you can implement SSL over any transport by overriding specific virtual methods of this class.

Functions this class provides include:

CSSL

~CSSL

Audit

AuditData

GetAuditFlags

GetCachedCredentials

GetCertGetCertificateChainFlags

GetCertVerifyCertificateChainPolicyFlags

GetCheckServerCertificateRevocation

GetClientContextRequest

GetEncryptedMessage

GetServerContextRequest

GetVerifyClientCertificate

GetVerifyServerCertificate

PendingReadSize

ReceiveData

SendCloseNotify

SendData

SendEncrypted

SendEncryptedMessage

SetAuditFlags

SetCachedCredentials

SetCertGetCertificateChainFlags

SetCertVerifyCertificateChainPolicyFlags

SetCheckServerCertificateRevocation

SetVerifyClientCertificate

SetVerifyServerCertificate

SSLAccept

SSLConnect

SSLHandleRenegotiationClient

SSLHandleRenegotiationServer

SSLRequestRenegotiationClient

SSLRequestRenegotiationServer

VerifyClientCertificate

VerifyServerCertificate

CSSL::CSSL

CSSL();

Remarks

This is the constructor which initializes all the internal variables to a safe state.

See Also

~CSSL

CSSL::~CSSL

~CSSL();

Remarks

This is the standard destructor for the class. Internally if looks after freeing up the read and write buffers which the class manages.

See Also

CSSL

CSSL::Audit

virtual bool Audit(_In_z_ _Printf_format_string_ LPCTSTR pszFormat, ...);

Remarks

This method is called at various times throughout the lifetime of an CSSL instance to perform auditing of the flow of code. Because the code to handle the various SSL handshakes, sending and receiving of encrypted messages and logic to handle renegotiation is quite involved, the CSSL class includes an extensible auditing mechanism to help diagnose issues when they occur. The default implementation is to call the Win32 API function "OutputDebugString". Derived classes are free to customize this behaviour.

Return Value

A boolean value to indicate if auditing was successful.

CSSL::AuditData

virtual bool AuditData(_In_ LPCTSTR pszTitle, _In_reads_bytes_(lSize) const BYTE* pbyData, _In_ ULONG lSize);

Remarks

This method is similar to the Audit method except that it is called for logging / auditing actual data as opposed to generic events. This is useful to analyze the data as the various SSL handshakes are performed and encrypted messages are sent and received. The default implementation uses the Win32 API function "CryptBinaryToString" to convert the data to printable data before it is displayed using the Win32 API function "OutputDebugString". Derived classes are free to customize this behaviour.

Return Value

A boolean value to indicate if auditing was successful.

CSSL::GetAuditFlags

DWORD GetAuditFlags() const;

Remarks

This method returns a bitmask which indicates what auditing events are logged by the code. The events values are defined as follows:

> enum
> {
> AUDIT_DATA = 0x1,
> AUDIT_EVENTS = 0x02,
> AUDIT_ERRORS = 0x04
> };

Return Value

A DWORD value which specifies the current audit flags in operation

See Also

SetAuditFlags

CSSL::GetCachedCredentials

CCachedCredentials* GetCachedCredentials() const;

Remarks

This method returns the CCachedCredentials value used by the class

Return Value

A pointer which specifies the current value in operation

See Also

SetCachedCredentials

CSSL::GetCertGetCertificateChainFlags

DWORD GetCertGetCertificateChainFlags() const;

Remarks

This method returns the DWORD value passed to the VerifyServerCertificate method as the dwCertGetCertificateChainFlags parameter

Return Value

A DWORD value which specifies the current value in operation

See Also

SetCertGetCertificateChainFlags

CSSL::GetCertVerifyCertificateChainPolicyFlags

DWORD GetCertVerifyCertificateChainPolicyFlags() const;

Remarks

This method returns the DWORD value passed to the VerifyServerCertificate method as the dwCertVerifyCertificateChainPolicyFlags parameter

Return Value

A DWORD value which specifies the current value in operation

See Also

SetCertVerifyCertificateChainPolicyFlags

CSSL::GetCheckServerCertificateRevocation

bool GetCheckServerCertificateRevocation() const;

Remarks

This method returns a boolean value which indicates if a server certificate is checked for revocation when the VerifyServerCertificate method is called.

Return Value

A bool value which specifies the current value in operation

See Also

SetCheckServerCertificateRevocation

CSSL::GetClientContextRequest

virtual unsigned long GetClientContextRequest();

Remarks

This method returns the context request value passed to the CContext::Initialize call during calls to the SSLConnect, SSLRequestRenegotiationClient, SSLHandleRenegotiationClient and SendCloseNotify methods. This value is used by the SSPI infrastructure to specify low level details on the connection such as detecting replay attempts etc.

Return Value

An unsigned long value which specifies the value to use.

CSSL::GetEncryptedMessage

virtual SECURITY_STATUS GetEncryptedMessage(_Inout_ std::vector<BYTE>& message);

Remarks

This method is called to read one SSL message from the other side of the SSL connection. If successful the message read will be returned in the "message" parameter. Internally this function will call the ReceiveData method if it needs more data to read an SSL message. This need to read additional data is handled internally by this method by checking the return value from the SDK DecryptMessage function for the return value SEC_E_INCOMPLETE_MESSAGE. This function will also handle the case where more data is read from the other side of the SSL connection to provide one SSL message. Subsequent calls to GetEncryptedMessage will examine this pending read buffer to produce further SSL messages. If this method returns the standard SEC_I_RENEGOTIATE error code then your code can decide to handle renegotiation by calling either SSLHandleRenegotiationClient or SSLHandleRenegotiationServer.

Return Value

A standard SECURITY_STATUS value.

See Also

PendingReadSize

CSSL::GetServerContextRequest

virtual unsigned long GetServerContextRequest();

Remarks

This method returns the context request value passed to the CContext::Accept call during calls to the SSLAccept, SSLRequestRenegotiationServer, SSLHandleRenegotiationServer and SendCloseNotify methods. This value is used by the SSPI infrastructure to specify low level details on the connection such as detecting replay attempts etc.

Return Value

An unsigned long value which specifies the value to use.

CSSL::GetVerifyClientCertificate

bool GetVerifyClientCertificate() const;

Remarks

This method returns a boolean value which indicates if a client certificate is verified by calling the method VerifyClientCertificate as the server SSL handshake is being performed.

Return Value

A bool value which specifies the current value in operation

See Also

SetVerifyServerCertificate

CSSL::GetVerifyServerCertificate

bool GetVerifyServerCertificate() const;

Remarks

This method returns a boolean value which indicates if a server certificate is verified by calling the method VerifyServerCertificate as the client SSL handshake is being performed.

Return Value

A bool value which specifies the current value in operation

See Also

SetVerifyClientCertificate

CSSL::PendingReadSize

unsigned long PendingReadSize() const;

Remarks

This method returns the current pending number of bytes which the class is maintaining in its read buffers. The CSSL class maintains this buffer as it is possible that the amount of data read is not enough for exactly one SSL message. The GetEncryptedMessage method is designed to only return one message at a time and as such the CSSL class maintains any pending data which has already been read from the other side of the SSL conversation but has not been used yet by GetEncryptedMessage for returning one full SSL message.

Return Value

A unsigned long which specifies the current pending number of bytes

CSSL::ReceiveData

virtual SECURITY_STATUS ReceiveData(_Out_writes_bytes_to_(lSize, lReceived) BYTE* pbyData, _In_ ULONG lSize, _Out_ ULONG& lReceived) ;

Remarks

This method is called during the SSL client and server handshake processes and during calls to GetEncryptedMessage when more data is required to be read to produce one full SSL message. This method is not implemented in CSSL and is implemented by derived classes such as CSocket.

Return Value

The implementation of this method should return a standard HRESULT to indicate success or failure.

CSSL::SendCloseNotify

virtual SECURITY_STATUS SendCloseNotify(_In_ bool bOperatingAsClient) ;

Remarks

This method can be called to send a standard SSL close notify message to the other end. This message is recommended to be send to the other side of the SSL conversation when the SSL connection is being closed. The bOperatingAsClient value indicates what part of the connection the calling code of this method is acting as. For example if the current code is acting as the SSL client then bOperatingAsClient should be set to true when this function is being called. After calling this function no further sending of data should be performed.

Return Value

A standard SECURITY_STATUS value.

CSSL::SendData

virtual SECURITY_STATUS SendData(_In_reads_bytes_(lSize) const BYTE* pbyData, _In_ ULONG lSize) ;

Remarks

This method is called during the SSL client and server handshakes process and during calls to SendEncryptedMessage when data is to be transmitted to the other end of the SSL connection. This method is not implemented in CSSL and is implemented by derived classes such as CSocket.

Return Value

The implementation of this method should return a standard SECURITY_STATUS value to indicate success or failure.

CSSL::SendEncrypted

virtual SECURITY_STATUS SendEncrypted(_In_reads_bytes_(lSize) const BYTE* pbyData, _In_ ULONG lSize) ;

Remarks

This method is a convenience wrapper over SendEncryptedMessage where if the total amount of data to send is greater than the maximum size of an SSL message then more than one call will be made to SendEncryptedMessage internally in this method to send all the data.

Return Value

A standard SECURITY_STATUS value.

See Also

SendEncryptedMessage

CSSL::SendEncryptedMessage

virtual SECURITY_STATUS SendEncryptedMessage(_In_reads_bytes_(lSize) const BYTE* pbyData, _In_ ULONG lSize) ;

Remarks

This method is called to write one SSL message to the other side of the SSL connection. Internally this function will call the SendData method with the actual encrypted data of the SSL message.

Return Value

A standard SECURITY_STATUS value.

See Also

SendEncrypted

CSSL::SetAuditFlags

void SetAuditFlags(_In_ DWORD dwAuditFlags);

Remarks

This method sets the bitmask which indicates what auditing events are logged by the code.

See Also

GetAuditFlags

CSSL::SetCachedCredentials

void SetCachedCredentials(_In_ DCCachedCredentials* pCachedCredentials);

Remarks

This method sets the cached credentials which this class will use.

See Also

GetCachedCredentials

CSSL::SetCertGetCertificateChainFlags

void SetCertGetCertificateChainFlags(_In_ DWORD dwFlags);

Remarks

This method sets the DWORD value passed to the VerifyServerCertificate method as the dwCertGetCertificateChainFlags parameter

See Also

GetCertGetCertificateChainFlags

CSSL::SetCertVerifyCertificateChainPolicyFlags

void SetCertVerifyCertificateChainPolicyFlags(_In_ DWORD dwFlags);

Remarks

This method sets the DWORD value passed to the VerifyServerCertificate method as the dwCertVerifyCertificateChainPolicyFlags parameter

See Also

GetCertVerifyCertificateChainPolicyFlags

CSSL::SetCheckServerCertificateRevocation

void SetCheckServerCertificateRevocation(_In_ bool bCheckServerCertificateRevocation);

Remarks

This method sets the boolean value used to decide if a server certificate is checked for revocation when the VerifyServerCertificate method is called.

See Also

GetCheckServerCertificateRevocation

CSSL::SetVerifyClientCertificate

void SetVerifyClientCertificate(_In_ bool bVerifyClientCertificate);

Remarks

This method sets whether a client certificate is verified by calling the method VerifyClientCertificate as the server SSL handshake is being performed.

See Also

GetVerifyClientCertificate

CSSL::SetVerifyServerCertificate

void SetVerifyServerCertificate(_In_ bool bVerifyServerCertificate);

Remarks

This method sets whether a server certificate is verified by calling the method VerifyServerCertificate as the client SSL handshake is being performed.

See Also

GetVerifyServerCertificate

CSSL::SSLAccept

virtual SECURITY_STATUS SSLAccept(_In_ bool bClientAuth);

Remarks

This is the main method which an SSL server calls to perform the initial SSL handshake. Internally this method will call the ReceiveData method if it needs to read more SSL handshake data. This need to read additional data is handled internally by this method by checking the return value from the CContext::Accept method for SEC_E_INCOMPLETE_MESSAGE. Internally this method will also call the SendData method when it needs to send a SSL handshake message data to the other side. The bClientAuth value indicates if the ASC_REQ_MUTUAL_AUTH is passed to the CContext::Accept method. This method will also handle the case where more data is read from the other side of the SSL connection for the last received SSL handshake message. This is application level data which will be made available to subsequent calls to GetEncryptedMessage.

Return Value

A standard SECURITY_STATUS value.

See Also

SSLConnect

CSSL::SSLConnect

virtual SECURITY_STATUS SSLConnect(_In_ LPCTSTR pszServerName);

Remarks

This is the main method which an SSL client calls to perform the initial SSL handshake. Internally this method will call the ReceiveData method if it needs to read more SSL handshake data. This need to read additional data is handled internally by this method by checking the return value from the CContext::Initialize method for SEC_E_INCOMPLETE_MESSAGE. Internally this method will also call the SendData method when it needs to send a SSL handshake message data to the other side. The pszServerName value should be the domain name of the server being connected to. This will be used for SSL host name validation either automatically via Schannel or manually via the VerifyServerCertificate method. This method will also handle the case where more data is read from the other side of the SSL connection for the last received SSL handshake message. This is application level data which will be made available to subsequent calls to GetEncryptedMessage.

Return Value

A standard SECURITY_STATUS value.

See Also

SSLAccept

CSSL::SSLHandleRenegotiationClient

virtual SECURITY_STATUS SSLHandleRenegotiationClient(_In_ LPCTSTR pszServerName);

Remarks

This is the method which SSL clients should call to handle a renegotiation when GetEncryptedMessage returns the standard SEC_I_RENEGOTIATE error code. If your client does not want to handle the renegotiation then you can treat the SEC_I_RENEGOTIATE error like any other error code returned. Internally this method runs much the same code which SSLConnect uses. Internally this method will call the ReceiveData method if it needs to read more SSL handshake data. This need to read additional data is handled internally by this method by checking the return value from the CContext::Initialize method for SEC_E_INCOMPLETE_MESSAGE. Internally this method will also call the SendData method when it needs to a send SSL handshake message data to the other side. The pszServerName value should be the domain name of the server being connected to. This will be used for SSL host name validation either automatically via Schannel or manually via the VerifyServerCertificate method. This method will also handle the case where more data is read from the other side of the SSL connection for the last received SSL handshake message. This is application level data which will be made available to subsequent calls to GetEncryptedMessage.

Return Value

A standard SECURITY_STATUS value.

See Also

SSLRequestRenegotiationClient, SSLHandleRenegotiationServer, SSLRequestRenegotiationServer

CSSL::SSLHandleRenegotiationServer

virtual SECURITY_STATUS SSLHandleRenegotiationServer(_In_ bool bClientAuth);

Remarks

This is the method which SSL servers should call to handle a renegotiation when GetEncryptedMessage returns the standard SEC_I_RENEGOTIATE error code. If your server does not want to handle the renegotiation then you can treat the SEC_I_RENEGOTIATE error like any other error code returned. Internally this method runs much the same code which SSLAccept uses. Internally this method will call the ReceiveData method if it needs to read more SSL handshake data. This need to read additional data is handled internally by this method by checking the return value from the CContext::Accept method for SEC_E_INCOMPLETE_MESSAGE. Internally this method will also call the SendData method when it needs to send a SSL handshake message data to the other side. The bClientAuth value indicates if the ASC_REQ_MUTUAL_AUTH is passed to the CContext::Accept method. This method will also handle the case where more data is read from the other side of the SSL connection for the last received SSL handshake message. This is application level data which will be made available to subsequent calls to GetEncryptedMessage.

Return Value

A standard SECURITY_STATUS value.

See Also

SSLRequestRenegotiationServer, SSLHandleRenegotiationClient, SSLRequestRenegotiationClient

CSSL::SSLRequestRenegotiationClient

virtual SECURITY_STATUS SSLRequestRenegotiationClient(_In_ LPCTSTR pszServerName);

Remarks

This is the method which an SSL clients should call to request a renegotiation. The other end of the connection will then receive a SEC_I_RENEGOTIATE error when it next calls GetEncryptedMessage. After sending the renegotiation request, this method will then execute much the same code which SSLConnect uses. Internally this method will call the ReceiveData method if it needs to read more SSL handshake data. This need to read additional data is handled internally by this method by checking the return value from the CContext::Initialize method which this method for SEC_E_INCOMPLETE_MESSAGE. Internally this method will also call the SendData method when it needs to send a SSL handshake message data to the other side. The pszServerName value should be the domain name of the server being connected to. This will be used for SSL host name validation either automatically via Schannel or manually via the VerifyServerCertificate method. This method will also handle the case where more data is read from the other side of the SSL connection for the last received SSL handshake message. This is application level data which will be made available to subsequent calls to GetEncryptedMessage.

Return Value

A standard SECURITY_STATUS value.

See Also

SSLHandleRenegotiationClient, SSLHandleRenegotiationServer, SSLRequestRenegotiationServer

CSSL::SSLRequestRenegotiationServer

virtual SECURITY_STATUS SSLRequestRenegotiationServer(_In_ bool bClientAuth);

Remarks

This is the method which an SSL servers should call to request a renegotiation. The other end of the connection will then receive a SEC_I_RENEGOTIATE error when it next calls GetEncryptedMessage. After sending the renegotiation request, this method will then execute much the same code which SSLAccept uses. Internally this method will call the ReceiveData method if it needs to read more SSL handshake data. This need to read additional data is handled internally by this method by checking the return value from the CContext::Accept method for SEC_E_INCOMPLETE_MESSAGE. Internally this method will also call the SendData method when it needs to send a SSL handshake message data to the other side. The bClientAuth value indicates if the ASC_REQ_MUTUAL_AUTH is passed to the CContext::Accept method. This method will also handle the case where more data is read from the other side of the SSL connection for the last received SSL handshake message. This is application level data which will be made available to subsequent calls to GetEncryptedMessage.

Return Value

A standard SECURITY_STATUS value.

See Also

SSLHandleRenegotiationServer, SSLHandleRenegotiationClient, SSLRequestRenegotiationClient

CSSL::VerifyClientCertificate

virtual SECURITY_STATUS VerifyClientCertificate(_In_ CryptoWrappers::CCertificate& clientCertificate);

Remarks

This method is called during processing a SSL Server handshake via SSLAccept or SSLHandleRenegotiationServer if the SetVerifyClientCertificate method was called with a true parameter. The default implementation of this method in this method does not do anything. Derived classes are free to customize this behaviour. The clientCertificate parameter is a C++ class encapsulation of the client certificate which was provided.

Return Value

The implementation of this method should return a standard HRESULT to indicate success or failure.

See Also

VerifyServerCertificate

CSSL::VerifyServerCertificate

virtual SECURITY_STATUS VerifyServerCertificate(_In_ CryptoWrappers::CCertificate& serverCertificate, _In_opt_ LPCWSTR pszServerName, _In_ DWORD dwCertGetCertificateChainFlags, _In_ DWORD dwCertVerifyCertificateChainPolicyFlags);

Remarks

This method is called during processing a SSL client handshake via the SSLConnect or SSLHandleRenegotiationClient methods if the SetVerifyServerCertificate method was called with a true parameter. The default implementation of this method does a comprehensive check of the server certificate. Derived classes are free to do their own custom validation. Note that if you do want to do custom validation then you should probably turn of auto validation of the server certificate by Schannel by using the SCH_CRED_MANUAL_CRED_VALIDATION flag in the call to the CreateClientCredentials method and then to enable VerifyServerCertificate to be called at runtime, you should use SetVerifyServerCertificate(true). For an example of this validation please review the SSLWrappersDemo.cpp module included in the download. Derived classes are free to customize this behaviour. The serverCertificate parameter is a C++ class encapsulation of the server certificate which was provided. The pszServerName parameter is the value which was passed to SSLConnect or SSLHandleRenegotiationClient. The dwCertGetCertificateChainFlags parameter is set via SetCertGetCertificateChainFlags method and the default value is CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT. The dwCertVerifyCertificateChainPolicyFlags parameter is set via SetCertVerifyCertificateChainPolicyFlags method and the default value is 0.

Return Value

A standard SECURITY_STATUS value. Derived class implementations of this method should return a standard HRESULT to indicate success or failure.

See Also

VerifyClientCertificate

CSocket

CSocket is derived from CSSL and provides a concrete SSL implementation over Windows sockets.

Functions this class provides include:

CSocket

Attach

Detach

GetReadTimeout

GetWriteTimeout

ReceiveData

SendData

SetReadTimeout

SetWriteTimeout

CSocket::CSocket

CSocket();

Remarks

This is the constructor which initializes all the internal variables to a safe state.

CSocket::Attach

void Attach(_In_ SOCKET hSocket)

Remarks

This method allows you to associate a Windows socket handle of "hSocket" with the current CSocket instance.

See Also

Detach

CSocket::Detach

SOCKET Detach()

Remarks

This method breaks the connection which a CSocket instance has with a Windows socket handle. The return value from this method is the socket handle which has just been detached.

See Also

Attach

CSocket::GetReadTimeout

DWORD GetReadTimeout() const;

Remarks

This method returns the timeout which the ReceiveData method will wait for data from the socket before it will fail with an error code of MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_TIMEOUT).

Return Value

A DWORD value which specifies the current timeout in operation in milliseconds.

See Also

SetReadTimeout

CSocket::GetWriteTimeout

DWORD GetWriteTimeout() const;

Remarks

This method returns the timeout which the SendData method will wait for the socket to become writable before it will fail with an error code of MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_TIMEOUT).

Return Value

A DWORD value which specifies the current timeout in operation in milliseconds.

See Also

SetWriteTimeout

CSocket::ReceiveData

virtual SECURITY_STATUS ReceiveData(_Out_writes_bytes_to_(lSize, lReceived) BYTE* pbyData, _In_ ULONG lSize, _Out_ ULONG& lReceived) ;

Remarks

This method is a concrete implementation of CSSL::ReceiveData specifically to receive SSL data over a Windows socket. Internally the method will handle checking the socket for readability using the timeout specified by SetReadTimeout and fail the method if the socket is not readable with a standard error value of MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_TIMEOUT). Also any socket receive error will also be reported by the return value from this method. This method will be called during the SSL client and server handshake processes and during calls to CSSL::GetEncryptedMessage when more data is required to be read to produce one full SSL message.

Return Value

Returns SEC_E_OK if data was received correctly otherwise a standard HRESULT is returned to indicate failure.

CSocket::SendData

virtual SECURITY_STATUS SendData(_In_reads_bytes_(lSize) const BYTE* pbyData, _In_ ULONG lSize) ;

Remarks

This method is a concrete implementation of CSSL::SendData specifically to send SSL data over a Windows socket. Internally the method will handle checking the socket for writability using the timeout specified by SetWriteTimeout. This check is necessary if the socket is in non-blocking mode. If the socket is not writable then the method will fail with a standard error value of MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_TIMEOUT). Also any socket send error will also be reported by the return value from this method. This method will be called during the SSL client and server handshake processes and during calls to CSSL::SendEncryptedMessage.

Return Value

Returns SEC_E_OK if data was sent correctly otherwise a standard HRESULT is returned to indicate failure.

CSocket::SetReadTimeout

void SetReadTimeout(_In_ DWORD dwReadTimeout);

Remarks

This method sets the timeout which the ReceiveData method will wait for data from the socket before it will fail. The dwReadTimeout parameter is specified in milliseconds.

See Also

GetReadTimeout

CSocket::SetWriteTimeout

void SetReadTimeout(_In_ DWORD dwWriteTimeout);

Remarks

This method sets the timeout which the SendData method will wait for the socket to become writable before it will fail. The dwWriteTimeout parameter is specified in milliseconds.

See Also

GetWriteTimeout

## Contacting the Author

PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
6 November 2020