# CSocket and SSL server side

## vergun

Hello,

I am trying to write SSL socket class with use of CSocket. Class behaves as normal CSocket when no encryption is requestet or is using SSL library when  encryption is needed. Client side works fine but problem is with server side. Function SSL_accept fails. It is either SSL_ERROR_SYSCALL or with small modification of code SSL_ERROR_WANT_READ. 

Here is small part of code:

#define CIPHER_LIST		_T("ALL:!aNULL:!eNULL")

BOOL CSSLSocket::Listen(int nConnectionBacklog /*= 5*/)

{

	if (m_bUseSSL)

	{

		if (!InitSSL())

		return FALSE;

		// Load cipher list

		if (SSL_CTX_set_cipher_list(m_pctx, CIPHER_LIST) <= 0)

			return FALSE;

		// Load server certificate

		int iErr = SSL_CTX_use_certificate_file(m_pctx, SERVER_CERT,                      SSL_FILETYPE_PEM);

		if (iErr <= 0)	

			return FALSE;	

		/*Load the password for the Private Key*/

		SSL_CTX_set_default_passwd_cb_userdata(m_pctx, KEY_PASSWD);

		// Load the server private-key into the SSL context 

		iErr = SSL_CTX_use_PrivateKey_file(m_pctx, SERVER_KEY, SSL_FILETYPE_PEM);

		if (iErr <= 0)

			return FALSE;

		// Make sure the key and certificate file match

		if (SSL_CTX_check_private_key(m_pctx) == 0)

			return FALSE;

		// Set no client verification 

		SSL_CTX_set_verify(m_pctx, SSL_VERIFY_NONE, NULL);

		m_pssl = SSL_new (m_pctx);

	}

	return CSocket::Listen(nConnectionBacklog);

}

Until now everything looks Ok.

Accept is problematic (No clinet certificate verification)

BOOL CSSLSocket::Accept(CAsyncSocket& rConnectedSocket,

					SOCKADDR* lpSockAddr, int* lpSockAddrLen)

{

	BOOL bRet = TRUE;

	//LPCTSTR errBuff[250];

	if (!m_bUseSSL)

	{

		return CSocket::Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);

	}

	else // SSL

	{	

		ASSERT(m_pssl != NULL);

		DWORD dwBlock = 0;

		IOCtl(FIONBIO, &dwBlock);

		bRet = CSocket::Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);

		int status = SSL_set_fd (m_pssl, (int)rConnectedSocket.m_hSocket); 

		if (bRet)

                               {

			do

			{

				status = SSL_accept (m_pssl);

				int iErr = SSL_get_error (m_pssl, status);

				switch (iErr)

				{

				case SSL_ERROR_NONE:	

					break;

				case SSL_ERROR_WANT_WRITE:

					break;

				case SSL_ERROR_WANT_READ:

					break;

				case SSL_ERROR_ZERO_RETURN: 					                               bRet = FALSE; 

					break;

				case SSL_ERROR_SYSCALL:		

					bRet = FALSE;

					break;

				default:

		                                                bRet = FALSE;

					break;

				}

			}

			while (SSL_pending (m_pssl));	

		}

		return bRet;

	}

}

I guess problem causes next call :bRet = CSocket::Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen); prior to SSL_accept. But how to get correct socket handle ?

IniSSL makes simple job:

 m_pctx = SSL_CTX_new (SSLv3_method());

I am not familiar with SSL so probably there is some basic mistake. 

Thanks for help

Alexander

----------

## Hu

 *vergun wrote:*   

> #define CIPHER_LIST		_T("ALL:!aNULL:!eNULL")
> 
> BOOL CSSLSocket::Listen(int nConnectionBacklog /*= 5*/)
> 
> {
> ...

 These quoted bits look like Windows code, not Linux code.  While it is certainly possible to make the code compile on Linux with the right wrappers, I wonder if you are really in the best place to get help with this code.  I am not familiar with CSocket, though the name sounds like it might be part of Microsoft's MFC.  You also use Hungarian notation, Windows datatypes, and an assert that is frequently found on Windows, but not on Linux.

As a more general issue, may I ask why you are trying to do this?  There are portable and free libraries that can already do this for you, on both Windows and Linux.  The socket and SSL socket code in boost::asio comes to mind, though I am sure other posters can offer other libraries as well.

----------

