| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 | 
							- /*           CAsyncSslSocketLayer by Tim Kosse
 
-           mailto: [email protected])
 
-                  Version 2.0 (2005-02-27)
 
- -------------------------------------------------------------
 
- Introduction
 
- ------------
 
- CAsyncSslSocketLayer is a layer class for CAsyncSocketEx which allows you to establish SSL secured
 
- connections. Support for both client and server side is provided.
 
- How to use
 
- ----------
 
- Using this class is really simple. In the easiest case, just add an instance of
 
- CAsyncSslSocketLayer to your socket and call InitClientSsl after creation of the socket.
 
- This class only has a couple of public functions:
 
- - int InitSSLConnection(bool clientMode);
 
-   This functions establishes an SSL connection. The clientMode parameter specifies whether the SSL connection
 
-   is in server or in client mode.
 
-   Most likely you want to call this function right after calling Create for the socket.
 
-   But sometimes, you'll need to call this function later. One example is for an FTP connection
 
-   with explicit SSL: In this case you would have to call InitSSLConnection after receiving the reply
 
-   to an 'AUTH SSL' command.
 
-   InitSSLConnection returns 0 on success, else an error code as described below under SSL_FAILURE
 
- - Is UsingSSL();
 
-   Returns true if you've previously called InitClientSsl()
 
- - SetNotifyReply(SetNotifyReply(int nID, int nCode, int result);
 
-   You can call this function only after receiving a layerspecific callback with the SSL_VERIFY_CERT
 
-   id. Set result to 1 if you trust the certificate and 0 if you don't trust it.
 
-   nID has to be the priv_data element of the t_SslCertData structure and nCode has to be SSL_VERIFY_CERT.
 
- This layer sends some layerspecific notifications to your socket instance, you can handle them in
 
- OnLayerCallback of your socket class.
 
- Valid notification IDs are:
 
- - SSL_INFO 0
 
-   There are two possible values for param2:
 
-   SSL_INFO_ESTABLISHED 0 - You'll get this notification if the SSL negotiation was successful
 
-   SSL_INFO_SHUTDOWNCOMPLETE 1 - You'll get this notification if the SSL connection has been shut
 
-                                   down successfully. See below for details.
 
- - SSL_FAILURE 1
 
-   This notification is sent if the SSL connection could not be established or if an existing
 
-   connection failed. Valid values for param2 are:
 
-   - SSL_FAILURE_UNKNOWN 0 - Details may have been sent with a SSL_VERBOSE_* notification.
 
-   - SSL_FAILURE_ESTABLISH 1 - Problem during SSL negotiation
 
-   - SSL_FAILURE_INITSSL 4
 
-   - SSL_FAILURE_VERIFYCERT 8 - The remote SSL certificate was invalid
 
-   - SSL_FAILURE_CERTREJECTED 16 - The remote SSL certificate was rejected by user
 
- - SSL_VERIFY_CERT 2
 
-   This notification is sent each time a remote certificate has to be verified.
 
-   param2 is a pointer to a t_SslCertData structure which contains some information
 
-   about the remote certificate.
 
-   You have to set the reply to this message using the SetNotifyReply function.
 
- Be careful with closing the connection after sending data, not all data may have been sent already.
 
- Before closing the connection, you should call Shutdown() and wait for the SSL_INFO_SHUTDOWNCOMPLETE
 
- notification. This assures that all encrypted data really has been sent.
 
- License
 
- -------
 
- Feel free to use this class, as long as you don't claim that you wrote it
 
- and this copyright notice stays intact in the source files.
 
- If you want to use this class in a commercial application, a short message
 
- to [email protected] would be appreciated but is not required.
 
- This product includes software developed by the OpenSSL Project
 
- for use in the OpenSSL Toolkit. (https://www.openssl.org/)
 
- */
 
- //---------------------------------------------------------------------------
 
- #ifndef AsyncSslSocketLayerH
 
- #define AsyncSslSocketLayerH
 
- //---------------------------------------------------------------------------
 
- #include "AsyncSocketExLayer.h"
 
- #include <openssl/ssl.h>
 
- //---------------------------------------------------------------------------
 
- // Details of SSL certificate, can be used by app to verify if certificate is valid
 
- struct t_SslCertData
 
- {
 
-   ~t_SslCertData()
 
-   {
 
-     delete [] certificate;
 
-   }
 
-   struct t_Contact
 
-   {
 
-     TCHAR Organization[256];
 
-     TCHAR Unit[256];
 
-     TCHAR CommonName[256];
 
-     TCHAR Mail[256];
 
-     TCHAR Country[256];
 
-     TCHAR StateProvince[256];
 
-     TCHAR Town[256];
 
-     TCHAR Other[1024];
 
-   } subject, issuer;
 
-   struct t_validTime
 
-   {
 
-     // Year, Month, day, hour, minute, second
 
-     int y, M, d, h, m, s;
 
-   } validFrom, validUntil;
 
-   TCHAR subjectAltName[10240];
 
-   unsigned char hashSha1[20];
 
-   unsigned char hashSha256[32];
 
-   unsigned char * certificate;
 
-   size_t certificateLen;
 
-   int verificationResult;
 
-   int verificationDepth;
 
-   int priv_data; //Internal data, do not modify
 
- };
 
- //---------------------------------------------------------------------------
 
- class CCriticalSectionWrapper;
 
- class CFileZillaTools;
 
- //---------------------------------------------------------------------------
 
- class CAsyncSslSocketLayer : public CAsyncSocketExLayer
 
- {
 
- public:
 
-   BOOL SetCertStorage(CString file);
 
-   CAsyncSslSocketLayer();
 
-   virtual ~CAsyncSslSocketLayer();
 
-   void SetNotifyReply(int nID, int nCode, int result);
 
-   BOOL GetPeerCertificateData(t_SslCertData & SslCertData, LPCTSTR & Error);
 
-   std::string GetTlsVersionStr();
 
-   std::string GetCipherName();
 
-   void SetClientCertificate(X509 * Certificate, EVP_PKEY * PrivateKey);
 
-   bool IsUsingSSL();
 
-   int InitSSLConnection(bool clientMode,
 
-     CAsyncSslSocketLayer * main,
 
-     bool sessionreuse, const CString & host, CFileZillaTools * tools,
 
-     void* pContext = 0);
 
-   // Send raw text, useful to send a confirmation after the ssl connection
 
-   // has been initialized
 
-   int SendRaw(const void * lpBuf, int nBufLen, int nFlags = 0);
 
-   void* GetContext() { return m_ssl_ctx; }
 
- private:
 
-   virtual void Close();
 
-   virtual BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
 
-   virtual BOOL Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen);
 
-   virtual void OnConnect(int nErrorCode);
 
-   virtual void OnReceive(int nErrorCode);
 
-   virtual void OnSend(int nErrorCode);
 
-   virtual void OnClose(int nErrorCode);
 
-   virtual int Receive(void * lpBuf, int nBufLen, int nFlags = 0);
 
-   virtual int Send(const void * lpBuf, int nBufLen, int nFlags = 0);
 
-   virtual BOOL ShutDown( int nHow = sends );
 
-   void ResetSslSession();
 
-   void PrintSessionInfo();
 
-   BOOL ShutDownComplete();
 
-   int InitSSL();
 
-   void UnloadSSL();
 
-   void PrintLastErrorMsg();
 
-   bool HandleSession(SSL_SESSION * Session);
 
-   void TriggerEvents();
 
-   // Will be called from the OpenSSL library
 
-   static void apps_ssl_info_callback(const SSL * s, int where, int ret);
 
-   static int verify_callback(int preverify_ok, X509_STORE_CTX * ctx);
 
-   static int ProvideClientCert(
 
-     SSL * Ssl, X509 ** Certificate, EVP_PKEY ** PrivateKey);
 
-   static int NewSessionCallback(struct ssl_st * Ssl, SSL_SESSION * Session);
 
-   static CAsyncSslSocketLayer * LookupLayer(SSL * Ssl);
 
-   bool m_bUseSSL;
 
-   BOOL m_bFailureSent;
 
-   // Critical section for thread synchronization
 
-   static CCriticalSectionWrapper m_sCriticalSection;
 
-   // Status variables
 
-   static int m_nSslRefCount;
 
-   BOOL m_bSslInitialized;
 
-   int m_nShutDown;
 
-   int m_nNetworkError;
 
-   int m_nSslAsyncNotifyId;
 
-   BOOL m_bBlocking;
 
-   BOOL m_bSslEstablished;
 
-   CString m_CertStorage;
 
-   int m_nVerificationResult;
 
-   int m_nVerificationDepth;
 
-   static struct t_SslLayerList
 
-   {
 
-     CAsyncSslSocketLayer * pLayer;
 
-     t_SslLayerList * pNext;
 
-   } * m_pSslLayerList;
 
-   // SSL data
 
-   SSL_CTX* m_ssl_ctx;  // SSL context
 
-   static std::map<SSL_CTX *, int> m_contextRefCount;
 
-   SSL* m_ssl;      // current session handle
 
-   SSL_SESSION * m_sessionid;
 
-   bool m_sessionreuse;
 
-   bool m_sessionreuse_failed;
 
-   CAsyncSslSocketLayer * m_Main;
 
-   // Data channels for encrypted/unencrypted data
 
-   BIO* m_nbio; // Network side, sends/receives encrypted data
 
-   BIO* m_ibio; // Internal side, won't be used directly
 
-   BIO* m_sslbio; // The data to encrypt / the decrypted data has to go though this bio
 
-   // Send buffer
 
-   char* m_pNetworkSendBuffer;
 
-   int m_nNetworkSendBufferLen;
 
-   int m_nNetworkSendBufferMaxLen;
 
-   char* m_pRetrySendBuffer;
 
-   int m_nRetrySendBufferLen;
 
-   bool m_mayTriggerRead;
 
-   bool m_mayTriggerWrite;
 
-   bool m_mayTriggerReadUp;
 
-   bool m_mayTriggerWriteUp;
 
-   bool m_onCloseCalled;
 
-   std::string m_TlsVersionStr;
 
-   std::string m_CipherName;
 
-   X509 * FCertificate;
 
-   EVP_PKEY * FPrivateKey;
 
- };
 
- //---------------------------------------------------------------------------
 
- #define SSL_INFO 0
 
- #define SSL_FAILURE 1
 
- #define SSL_VERIFY_CERT 2
 
- //---------------------------------------------------------------------------
 
- #define SSL_INFO_ESTABLISHED 0
 
- #define SSL_INFO_SHUTDOWNCOMPLETE 1
 
- //---------------------------------------------------------------------------
 
- #define SSL_FAILURE_UNKNOWN 0
 
- #define SSL_FAILURE_ESTABLISH 1
 
- #define SSL_FAILURE_INITSSL 4
 
- #define SSL_FAILURE_VERIFYCERT 8
 
- #define SSL_FAILURE_CERTREJECTED 16
 
- //---------------------------------------------------------------------------
 
- #endif // AsyncSslSocketLayerH
 
 
  |