OpenSSLMfc.cpp
上传用户:dengkfang
上传日期:2008-12-30
资源大小:5233k
文件大小:7k
源码类别:

CA认证

开发平台:

Visual C++

  1. /*
  2. Module : OpenSSLMfc.cpp
  3. Purpose: Implementation for wrapper classes for the OpenSSL C variable types
  4. Created: PJN / 24-05-2002
  5. History: PJN / 29-12-2004 1. Updated to suit new layout of CWSocket methods
  6.          PJN / 19-02-2005 1. Provided a derived implementation of CSSLSocket::IsReadible.
  7. Copyright (c) 2002 - 2005 by PJ Naughter.  (Web: www.naughter.com, Email: pjna@naughter.com)
  8. All rights reserved.
  9. Copyright / Usage Details:
  10. You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
  11. when your product is released in binary form. You are allowed to modify the source code in any way you want 
  12. except you cannot modify the copyright details at the top of each module. If you want to distribute source 
  13. code with your application, then you are only allowed to distribute versions released by the author. This is 
  14. to maintain a single distribution point for the source code. 
  15. */
  16. //////////////// Includes ////////////////////////////////////////////
  17. #include "stdafx.h"
  18. #include "OpenSSLMfc.h"
  19. //////////////// Macros //////////////////////////////////////////////
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. //////////////// Implementation //////////////////////////////////////
  26. CSSLContext::CSSLContext()
  27. {
  28.   //Initialize our member variable to sane defaults
  29.   m_pSSLContext = NULL;
  30. }
  31. CSSLContext::CSSLContext(SSL_CTX* pSSLContext)
  32. {
  33.   m_pSSLContext = pSSLContext;
  34. }
  35. CSSLContext::CSSLContext(const CSSLContext& SSLContext)
  36. {
  37.   *this = SSLContext;
  38. }
  39. CSSLContext::~CSSLContext()
  40. {
  41.   Close();
  42. }
  43. void CSSLContext::Close()
  44. {
  45.   if (m_pSSLContext)
  46.   {
  47.     SSL_CTX_free(m_pSSLContext);
  48.     m_pSSLContext = NULL;
  49.   }
  50. }
  51. CSSLContext::operator SSL_CTX*() const
  52. {
  53.   return m_pSSLContext;
  54. }
  55. void CSSLContext::Attach(SSL_CTX* pSSLContext)
  56. {
  57.   Close();
  58.   m_pSSLContext = pSSLContext;
  59. }
  60. CSSLContext& CSSLContext::operator=(const CSSLContext& SSLContext)
  61. {
  62.   Close();
  63.   m_pSSLContext = SSLContext;
  64.   return *this;
  65. }
  66. SSL_CTX* CSSLContext::Detach()
  67. {
  68.   SSL_CTX* pTemp = m_pSSLContext;
  69.   m_pSSLContext = NULL;
  70.   return pTemp;
  71. }
  72. CSSL::CSSL()
  73. {
  74.   //Initialize our member variable to sane defaults
  75.   m_pSSL = NULL;
  76. }
  77. CSSL::CSSL(SSL* pSSL)
  78. {
  79.   m_pSSL = pSSL;
  80. }
  81. CSSL::CSSL(const CSSL& ssl)
  82. {
  83.   *this = ssl;
  84. }
  85. CSSL::~CSSL()
  86. {
  87.   Close();
  88. }
  89. void CSSL::Close()
  90. {
  91.   if (m_pSSL)
  92.   {
  93.     for (int i=0; i<3 && SSL_shutdown(m_pSSL)== 0; i++) 
  94.       Sleep(0); 
  95.     SSL_free(m_pSSL);
  96.     m_pSSL = NULL;
  97.   }
  98. }
  99. CSSL::operator SSL*() const
  100. {
  101.   return m_pSSL;
  102. }
  103. void CSSL::Attach(SSL* pSSL)
  104. {
  105.   Close();
  106.   m_pSSL = pSSL;
  107. }
  108. CSSL& CSSL::operator=(const CSSL& ssl)
  109. {
  110.   Close();
  111.   m_pSSL = ssl;
  112.   return *this;
  113. }
  114. SSL* CSSL::Detach()
  115. {
  116.   SSL* pTemp = m_pSSL;
  117.   m_pSSL = NULL;
  118.   return pTemp;
  119. }
  120. CSSLSocket::CSSLSocket()
  121. {
  122.   m_pSocket = NULL;
  123. }
  124. CSSLSocket::~CSSLSocket()
  125. {
  126.   Close();
  127. }
  128. BOOL CSSLSocket::Create(CSSLContext& sslContext, CWSocket& socket)
  129. {
  130.   //Create the SSL object
  131.   SSL* pSSL = SSL_new(sslContext);
  132.   if (pSSL == NULL)
  133.     return FALSE;
  134.   else
  135.     m_SSL.Attach(pSSL);
  136.   //Associate the socket with the SSL connection object
  137.   if (SSL_set_fd(m_SSL, socket) != 1)
  138.   {
  139.     Close();
  140.     return FALSE;
  141.   }
  142.   //Hive away the socket pointer
  143.   m_pSocket = &socket;
  144.   return TRUE;
  145. }
  146. BOOL CSSLSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  147. {
  148.   //Validate our parameters
  149.   ASSERT(m_pSocket);
  150.   //Call the low level socket connect
  151.   m_pSocket->Connect(lpszHostAddress, nHostPort);
  152.   //Just call the SSL_accept function
  153.   int nSSLConnect = SSL_connect(m_SSL);
  154.   return (nSSLConnect == 1);
  155. }
  156. BOOL CSSLSocket::ConnectViaSocks4(LPCTSTR lpszHostAddress, UINT nHostPort, LPCTSTR lpszSocksServer, UINT nSocksPort, DWORD dwConnectionTimeout)
  157. {
  158.   //Validate our parameters
  159.   ASSERT(m_pSocket);
  160.   //Call the low level socket connect
  161.   m_pSocket->ConnectViaSocks4(lpszHostAddress, nHostPort, lpszSocksServer, nSocksPort, dwConnectionTimeout);
  162.   //Just call the SSL_accept function
  163.   int nSSLConnect = SSL_connect(m_SSL);
  164.   return (nSSLConnect == 1);
  165. }
  166. BOOL CSSLSocket::ConnectViaSocks5(LPCTSTR lpszHostAddress, UINT nHostPort, LPCTSTR lpszSocksServer, UINT nSocksPort, LPCTSTR lpszUserName, LPCTSTR lpszPassword, DWORD dwConnectionTimeout, BOOL bUDP)
  167. {
  168.   //Validate our parameters
  169.   ASSERT(m_pSocket);
  170.   //Call the low level socket connect
  171.   m_pSocket->ConnectViaSocks5(lpszHostAddress, nHostPort, lpszSocksServer, nSocksPort, lpszUserName, lpszPassword, dwConnectionTimeout, bUDP);
  172.   //Just call the SSL_accept function
  173.   int nSSLConnect = SSL_connect(m_SSL);
  174.   return (nSSLConnect == 1);
  175. }
  176. BOOL CSSLSocket::ConnectViaHTTPProxy(LPCTSTR lpszHostAddress, UINT nHostPort, LPCTSTR lpszHTTPServer, UINT nHTTPProxyPort, CString& sProxyResponse, LPCTSTR lpszUserName, LPCTSTR lpszPassword, DWORD dwConnectionTimeout, LPCTSTR lpszUserAgent)
  177. {
  178.   //Validate our parameters
  179.   ASSERT(m_pSocket);
  180.   //Call the low level socket connect
  181.   m_pSocket->ConnectViaHTTPProxy(lpszHostAddress, nHostPort, lpszHTTPServer, nHTTPProxyPort, sProxyResponse, lpszUserName, lpszPassword, dwConnectionTimeout, lpszUserAgent);
  182.   //Just call the SSL_accept function
  183.   int nSSLConnect = SSL_connect(m_SSL);
  184.   return (nSSLConnect == 1);
  185. }
  186. BOOL CSSLSocket::Accept(DWORD dwSSLNegotiationTimeout)
  187. {
  188.   //Validate our parameters
  189.   ASSERT(m_pSocket);
  190.   //Then do the SSL accept
  191.   BOOL bNegotiationComplete = FALSE;
  192.   while (!bNegotiationComplete)
  193.   {
  194.     int nSSLAccept = SSL_accept(m_SSL);
  195.     if (nSSLAccept != 1)
  196.     {
  197.       BOOL bRetry = FALSE;
  198.       int nSSL_get_error = SSL_get_error(m_SSL, nSSLAccept);
  199.       if (nSSL_get_error == SSL_ERROR_WANT_READ)
  200.       {
  201.         if (m_pSocket->IsReadible(dwSSLNegotiationTimeout))
  202.           bRetry = TRUE;
  203.       }
  204.       if (!bRetry)
  205.         return FALSE;
  206.     }
  207.     else
  208.       bNegotiationComplete = TRUE;
  209.   }
  210.   return TRUE;
  211. }
  212. void CSSLSocket::Close()
  213. {
  214.   //Close down the SSL connection
  215.   if (m_SSL.operator SSL*())
  216.     m_SSL.Close();
  217.   //Close down the socket connection
  218.   if (m_pSocket)
  219.   {
  220.     m_pSocket->Close();
  221.     m_pSocket = NULL;
  222.   }
  223. }
  224. int CSSLSocket::Send(void* pBuffer, int nBuf)
  225. {
  226.   //Validate our parameters
  227.   ASSERT(m_SSL.operator SSL*());
  228.   //Just call the SSL_write function
  229.   return SSL_write(m_SSL, pBuffer, nBuf);
  230. }
  231. int CSSLSocket::Receive(void* pBuffer, int nBuf)
  232. {
  233.   //Validate our parameters
  234.   ASSERT(m_SSL.operator SSL*());
  235.   //Just call the SSL_read function
  236.   return SSL_read(m_SSL, pBuffer, nBuf);
  237. }
  238. CSSLSocket::operator SSL*() const
  239. {
  240.   return m_SSL.operator SSL*();
  241. }
  242. CSSLSocket::operator CWSocket&() const
  243. {
  244.   //validate our parameters
  245.   ASSERT(m_pSocket);
  246.   return *m_pSocket;
  247. }
  248. BOOL CSSLSocket::IsReadible(DWORD dwTimeout)
  249. {
  250.   //Validate our parameters
  251.   ASSERT(m_pSocket);
  252.   //Try SSL_pending before we defer to our socket implementation
  253.   if (m_SSL.m_pSSL)
  254.   {
  255.     if (SSL_pending(m_SSL))
  256.       return TRUE;
  257.   }
  258.   return m_pSocket->IsReadible(dwTimeout);
  259. }