hi all
 i'm a newbie to the openssl and plan to integrate SSL to my server. my
server is developed based on IO completion port. so i want
to separate the  SSL engine from the socket object totally. after googled in
mail list, i found it is possible by using BIO pair mechanism .
 after almost two weeks paining, i decide to turn to you.(i know this topic
was discussed many times in the mail list,but i still cannot figure out)
 please help me out of it.
 i think i was trapped by some wrong things.


 to make you better understand, i wrote a simple server and past below. My
idea is:
1.make the bio pair.bioInternal,bioNetwork
2.got client accept.
3.receive data from client (eg.client hello)
4.feed the data(eg.client hello) to bioNetwork
5. waiting data(eg.server hello) in bioNetwork and send back to client.
6.(repeat the step 3,4,5 until the handshake process finish)

----code.(writed by VS2008)-----------------------
#include "openssl/ssl.h"
#include <winsock2.h>
#include <stdlib.h>
#include <stdio.h>


int _tmain(int argc, _TCHAR* argv[])
{
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
 SSL_CTX* pCTX=SSL_CTX_new(TLSv1_server_method());

/*INIT*/
{
char cCurDir[255];
::GetCurrentDirectory( 255,cCurDir );

char cTmp[1024];

sprintf( cTmp,"%s\\pem\\ca.cer",cCurDir );
if(!SSL_CTX_load_verify_locations(pCTX, cTmp, NULL) )
goto bad_ssl;

sprintf( cTmp,"%s\\pem\\ns.cer",cCurDir );
if(!SSL_CTX_use_certificate_file(pCTX, cTmp, SSL_FILETYPE_PEM))
goto bad_ssl;

sprintf( cTmp,"%s\\pem\\ns.key",cCurDir );
if(!SSL_CTX_use_PrivateKey_file(pCTX, cTmp, SSL_FILETYPE_PEM))
goto bad_ssl;

if (!SSL_CTX_check_private_key(pCTX))
goto bad_ssl;
}

SOCKET sktAccepted = INVALID_SOCKET;
 /*windows network*/
{
WSADATA neto;
if (WSAStartup(MAKEWORD(2,2), &neto)!=0)
goto bad_ssl;

SOCKET sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sk == SOCKET_ERROR)
goto bad_ssl;

SOCKADDR_IN sa;
sa.sin_addr.S_un.S_addr =  INADDR_ANY;
sa.sin_family = AF_INET;
sa.sin_port = htons(8001);

if(bind(sk, (SOCKADDR*)&sa, sizeof(sa))== SOCKET_ERROR)
goto bad_ssl;

if(listen(sk,5)== SOCKET_ERROR)
goto bad_ssl;

sktAccepted = accept(sk, (struct sockaddr *)&sa, NULL);
if(sktAccepted == INVALID_SOCKET)
goto bad_ssl;
}

//after got client accept,prepare for handshake
SSL* pSSL = SSL_new( pCTX );
if( pSSL == NULL )
goto bad_ssl;

BIO* pBIOnet = BIO_new( BIO_s_mem() );
BIO* pBIOint = BIO_new( BIO_s_mem() );
//BIO* pBIO_SSL = BIO_new(BIO_f_ssl());

BIO_make_bio_pair( pBIOint,pBIOnet );

//long lOptions = SSL_ctrl( pSSL, SSL_CTRL_OPTIONS, 0, 0) | SSL_OP_ALL;
//SSL_ctrl(pSSL, SSL_CTRL_OPTIONS, lOptions, 0);

SSL_set_accept_state( pSSL );
SSL_set_bio( pSSL,pBIOint,pBIOint );
//BIO_set_ssl( pBIO_SSL, pSSL, BIO_NOCLOSE);

SSL_set_mode(pSSL, SSL_MODE_AUTO_RETRY);
 char cTmp[4*1024];
//waitting data from client
while( true )
{
//(here.always got 124 len data from client.i use client tool 'openssl
s_client -connect 127.0.0.1:8001' )
int iRe = recv( sktAccepted,cTmp,4*1024,0);
if( iRe == 0 || iRe == SOCKET_ERROR  )
break;
//data got from network. send to SSL
int iWritedLen = BIO_write( pBIOnet,cTmp,iRe );
BIO_flush( pBIOnet );

if( SSL_in_init( pSSL ) )
{
int iRe = SSL_accept( pSSL );// SSL_do_handshake( pSSL );
if( iRe <= 0 )
{
int iErrCode = SSL_get_error( pSSL,iRe );
printf("Error happen during BIO_do_handshake(..).err:%d\n",iErrCode );
switch( iErrCode )
{
case SSL_ERROR_WANT_READ:
{//where can i got data to feed SSL?
}
break;
case SSL_ERROR_WANT_WRITE:
break;
}
}
 //if( 0 )
{
//in handshake process, after data got from network,there should be data
needed sending back to client.for example."Server Hello"
int iPendingLen = BIO_pending( pBIOnet );
if( iPendingLen > 0 )
{
int iReadedDataLen = BIO_read( pBIOnet,cTmp,iPendingLen );//(the data is
exactly the same with the data recived from client.??!)
//send to client
send( sktAccepted,cTmp,iReadedDataLen,0 );
}
}
}
else
{//handshake is done.then the data is application logic data.
//got plain application data.
if( BIO_pending( pBIOint ) > 0 )
{
//read and dealing...
//(...)
}
}
}

 bad_ssl:
  //destroy all resource...
  //(...)

  return 0;

}

many thanks.
anakin.jin

Reply via email to