| 1 |
/*CAsyncSslSocketLayer by Tim Kosse (Tim.Kosse@gmx.de) |
/* CAsyncSslSocketLayer by Tim Kosse |
| 2 |
Version 1.0 (2003-04-05) |
mailto: tim.kosse@filezilla-project.org) |
| 3 |
------------------------------------------------------ |
Version 2.0 (2005-02-27) |
| 4 |
|
------------------------------------------------------------- |
| 5 |
|
|
| 6 |
Introduction |
Introduction |
| 7 |
------------ |
------------ |
| 8 |
|
|
| 9 |
CAsyncSslSocketLayer is a layer class for CAsyncSocketEx which allows you to establish SSL secured |
CAsyncSslSocketLayer is a layer class for CAsyncSocketEx which allows you to establish SSL secured |
| 10 |
connections to servers. |
connections. Support for both client and server side is provided. |
| 11 |
|
|
| 12 |
How to use |
How to use |
| 13 |
---------- |
---------- |
| 15 |
Using this class is really simple. In the easiest case, just add an instance of |
Using this class is really simple. In the easiest case, just add an instance of |
| 16 |
CAsyncSslSocketLayer to your socket and call InitClientSsl after creation of the socket. |
CAsyncSslSocketLayer to your socket and call InitClientSsl after creation of the socket. |
| 17 |
|
|
| 18 |
This class only has three new public functions: |
This class only has a couple of public functions: |
| 19 |
- InitClientSsl(); |
- int InitSSLConnection(bool clientMode); |
| 20 |
This functions establishes an SSL connection to the server. You can call it at any |
This functions establishes an SSL connection. The clientMode parameter specifies wether the SSL connection |
| 21 |
time one the socket has been created. |
is in server or in client mode. |
| 22 |
Most likely you want to call this function right after calling Create for the socket. |
Most likely you want to call this function right after calling Create for the socket. |
| 23 |
But sometimes, you'll need to call this function later. One example is for an FTP connection |
But sometimes, you'll need to call this function later. One example is for an FTP connection |
| 24 |
with explicit SSL: In this case you would have to call InitClientSsl after receiving the reply |
with explicit SSL: In this case you would have to call InitSSLConnection after receiving the reply |
| 25 |
to an 'AUTH SSL' command. |
to an 'AUTH SSL' command. |
| 26 |
|
InitSSLConnection returns 0 on success, else an error code as described below under SSL_FAILURE |
| 27 |
- Is UsingSSL(); |
- Is UsingSSL(); |
| 28 |
Returns true if you've previously called InitClientSsl() |
Returns true if you've previously called InitClientSsl() |
| 29 |
- SetNotifyReply(SetNotifyReply(int nID, int nCode, int result); |
- SetNotifyReply(SetNotifyReply(int nID, int nCode, int result); |
| 30 |
You can call this function only after receiving a layerspecific callback with the SSL_VERIFY_CERT |
You can call this function only after receiving a layerspecific callback with the SSL_VERIFY_CERT |
| 31 |
id. See below for details. |
id. Set result to 1 if you trust the certificate and 0 if you don't trust it. |
| 32 |
|
nID has to be the priv_data element of the t_SslCertData structure and nCode has to be SSL_VERIFY_CERT. |
| 33 |
|
- CreateSslCertificate(LPCTSTR filename, int bits, unsigned char* country, unsigned char* state, |
| 34 |
|
unsigned char* locality, unsigned char* organization, unsigned char* unit, unsigned char* cname, |
| 35 |
|
unsigned char *email, CString& err); |
| 36 |
|
Creates a new self-signed SSL certificate and stores it in the given file |
| 37 |
|
- SendRaw(const void* lpBuf, int nBufLen, int nFlags = 0) |
| 38 |
|
Sends a raw, unencrypted message. This may be useful after successful initialization to tell the other |
| 39 |
|
side that can use SSL. |
| 40 |
|
|
| 41 |
This layer sends some layerspecific notifications to your socket instance, you can handle them in |
This layer sends some layerspecific notifications to your socket instance, you can handle them in |
| 42 |
OnLayerCallback of your socket class. |
OnLayerCallback of your socket class. |
| 49 |
- SSL_FAILURE 1 |
- SSL_FAILURE 1 |
| 50 |
This notification is sent if the SSL connection could not be established or if an existing |
This notification is sent if the SSL connection could not be established or if an existing |
| 51 |
connection failed. Valid values for param2 are: |
connection failed. Valid values for param2 are: |
| 52 |
- SSL_FAILURE_UNKNOWN 0 - Details may have been sent with a SSL_VERBOSE_* notification. |
- SSL_FAILURE_NONE 0 - Everything OK |
| 53 |
- SSL_FAILURE_ESTABLISH 1 - Problem during SSL negotiation |
- SSL_FAILURE_UNKNOWN 1 - Details may have been sent with a SSL_VERBOSE_* notification. |
| 54 |
- SSL_FAILURE_LOADDLLS 2 |
- SSL_FAILURE_ESTABLISH 2 - Problem during SSL negotiation |
| 55 |
- SSL_FAILURE_INITSSL 4 |
- SSL_FAILURE_LOADDLLS 4 |
| 56 |
- SSL_FAILURE_VERIFYCERT 8 - The remote SSL certificate was invalid |
- SSL_FAILURE_INITSSL 8 |
| 57 |
|
- SSL_FAILURE_VERIFYCERT 16 - The remote SSL certificate was invalid |
| 58 |
|
- SSL_FAILURE_CERTREJECTED 32 - The remote SSL certificate was rejected by user |
| 59 |
- SSL_VERBOSE_WARNING 3 |
- SSL_VERBOSE_WARNING 3 |
| 60 |
SSL_VERBOSE_INFO 4 |
SSL_VERBOSE_INFO 4 |
| 61 |
This two notifications contain some additional information. The value given by param2 is a |
This two notifications contain some additional information. The value given by param2 is a |
| 64 |
This notification is sent each time a remote certificate has to be verified. |
This notification is sent each time a remote certificate has to be verified. |
| 65 |
param2 is a pointer to a t_SslCertData structure which contains some information |
param2 is a pointer to a t_SslCertData structure which contains some information |
| 66 |
about the remote certificate. |
about the remote certificate. |
| 67 |
Return 1 if you trust the certificate and 0 if you don't trust it. If you're unsure so that the |
You have to set the reply to this message using the SetNotifyReply function. |
|
user has to choose to trust the certificate return 2. |
|
|
In this case, you have to call SetNotifyReply later to resume the SSL connection. nID has to be |
|
|
the priv_data element of the t_SslCertData structure and nCode has to be SSL_VERIFY_CERT. |
|
|
Set nAction to 1 if you trust the certificate and 0 if you don't trust it. |
|
| 68 |
|
|
| 69 |
Be careful with closing the connection after sending data, not all data may have been sent already. |
Be careful with closing the connection after sending data, not all data may have been sent already. |
| 70 |
Before closing the connection, you should call Shutdown() and wait for the SSL_INFO_SHUTDOWNCOMPLETE |
Before closing the connection, you should call Shutdown() and wait for the SSL_INFO_SHUTDOWNCOMPLETE |
| 75 |
|
|
| 76 |
Feel free to use this class, as long as you don't claim that you wrote it |
Feel free to use this class, as long as you don't claim that you wrote it |
| 77 |
and this copyright notice stays intact in the source files. |
and this copyright notice stays intact in the source files. |
| 78 |
If you use this class in commercial applications, please send a short message |
If you want to use this class in a commercial application, a short message |
| 79 |
to tim.kosse@gmx.de |
to tim.kosse@filezilla-project.org would be appreciated but is not required. |
| 80 |
|
|
| 81 |
This product includes software developed by the OpenSSL Project |
This product includes software developed by the OpenSSL Project |
| 82 |
for use in the OpenSSL Toolkit. (http://www.openssl.org/) |
for use in the OpenSSL Toolkit. (http://www.openssl.org/) |
| 83 |
|
|
| 84 |
|
Version history |
| 85 |
|
--------------- |
| 86 |
|
|
| 87 |
|
Version 2.0: |
| 88 |
|
- Add server support |
| 89 |
|
- a lot of bug fixes |
| 90 |
|
|
| 91 |
*/ |
*/ |
| 92 |
|
|
| 93 |
#ifndef ASYNCSSLSOCKETLEAYER_INCLUDED |
#ifndef ASYNCSSLSOCKETLEAYER_INCLUDED |
| 94 |
#define ASYNCSSLSOCKETLEAYER_INCLUDED |
#define ASYNCSSLSOCKETLEAYER_INCLUDED |
| 95 |
|
|
| 96 |
|
#ifndef _AFX |
| 97 |
|
#define CString CStdString |
| 98 |
|
#endif |
| 99 |
|
|
| 100 |
#include "AsyncSocketExLayer.h" |
#include "AsyncSocketExLayer.h" |
| 101 |
#include "openssl\ssl.h" |
#include <openssl/ssl.h> |
| 102 |
|
|
| 103 |
// Details of SSL certificate, can be used by app to verify if certificate is valid |
// Details of SSL certificate, can be used by app to verify if certificate is valid |
| 104 |
struct t_SslCertData |
struct t_SslCertData |
| 141 |
BOOL GetPeerCertificateData(t_SslCertData &SslCertData); |
BOOL GetPeerCertificateData(t_SslCertData &SslCertData); |
| 142 |
|
|
| 143 |
bool IsUsingSSL(); |
bool IsUsingSSL(); |
| 144 |
bool InitClientSSL(); |
int InitSSLConnection(bool clientMode); |
| 145 |
|
|
| 146 |
|
static bool CreateSslCertificate(LPCTSTR filename, int bits, unsigned char* country, unsigned char* state, |
| 147 |
|
unsigned char* locality, unsigned char* organization, unsigned char* unit, unsigned char* cname, |
| 148 |
|
unsigned char *email, CString& err); |
| 149 |
|
|
| 150 |
|
bool SetCertKeyFile(const char* cert, const char* key); |
| 151 |
|
|
| 152 |
|
// Send raw text, useful to send a confirmation after the ssl connection |
| 153 |
|
// has been initialized |
| 154 |
|
int SendRaw(const void* lpBuf, int nBufLen, int nFlags = 0); |
| 155 |
|
|
| 156 |
private: |
private: |
| 157 |
virtual void Close(); |
virtual void Close(); |
| 168 |
void ResetSslSession(); |
void ResetSslSession(); |
| 169 |
void PrintSessionInfo(); |
void PrintSessionInfo(); |
| 170 |
BOOL ShutDownComplete(); |
BOOL ShutDownComplete(); |
| 171 |
bool InitSSL(); |
int InitSSL(); |
| 172 |
void UnloadSSL(); |
void UnloadSSL(); |
| 173 |
void PrintLastErrorMsg(); |
void PrintLastErrorMsg(); |
| 174 |
|
|
| 175 |
|
void TriggerEvents(); |
| 176 |
|
|
| 177 |
//Will be called from the OpenSSL library |
//Will be called from the OpenSSL library |
| 178 |
static void apps_ssl_info_callback(SSL *s, int where, int ret); |
static void apps_ssl_info_callback(SSL *s, int where, int ret); |
| 179 |
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx); |
static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx); |
| 195 |
CString m_CertStorage; |
CString m_CertStorage; |
| 196 |
int m_nVerificationResult; |
int m_nVerificationResult; |
| 197 |
int m_nVerificationDepth; |
int m_nVerificationDepth; |
|
BOOL m_bClose; |
|
|
BOOL m_bOnCloseCalled; |
|
| 198 |
|
|
| 199 |
static struct t_SslLayerList |
static struct t_SslLayerList |
| 200 |
{ |
{ |
| 219 |
char* m_pNetworkSendBuffer; |
char* m_pNetworkSendBuffer; |
| 220 |
int m_nNetworkSendBufferLen; |
int m_nNetworkSendBufferLen; |
| 221 |
int m_nNetworkSendBufferMaxLen; |
int m_nNetworkSendBufferMaxLen; |
| 222 |
|
|
| 223 |
|
bool m_mayTriggerRead; |
| 224 |
|
bool m_mayTriggerWrite; |
| 225 |
|
bool m_mayTriggerReadUp; |
| 226 |
|
bool m_mayTriggerWriteUp; |
| 227 |
}; |
}; |
| 228 |
|
|
| 229 |
#define SSL_INFO 0 |
#define SSL_INFO 0 |