A bio pairs question...

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

A bio pairs question...

Usman Riaz
Hi*!
    I am implementing IOCP server (for Windows OS) supporting SSL. For SSL
part i am trying to use OpenSSL's bio pairs. I have looked at the example in
ssltest.c. As i understand (please correct me if i am wrong) of the three
bios (s_ssl_bio, server, server_io) that get created in "doit_biopair"
function, the "server_io" bio is used to read/write "Encrypted" data & the
"s_ssl_bio" is used to read/write "UNEncrypted" data. I have setup my code
according to this principle. Now when the client connects, it sends some
"ssl-handshake" (Encrypted) data & I have to write it "server_io". Here is
how my function looks for writing to "server_io" BIO.

bool CSSLSession::OnRecv(const std::string& RecvData)
{
        bool bRet = false;
        char *pData = NULL;
        int nRet = -1;
        int nLen = -1;

        nLen = BIO_ctrl_get_read_request(m_SessionInfo.ioBio);

        if( !nLen )
        {
                bRet = true;
                return bRet;
        }

        nRet = BIO_nwrite0(m_SessionInfo.ioBio, &pData);

        if( 0 >= nRet || nLen > nRet || !pData )
        {
                return bRet;
        }

        nRet = nLen;

#pragma warning (disable : 4018)
        if( nRet > RecvData.size() )
        {
                nRet = RecvData.size();
        }
#pragma warning (default: 4018)

        memcpy(pData, RecvData.data(), nRet);

        nRet = BIO_nwrite(m_SessionInfo.ioBio, &pData, nRet);
        BIO_flush(m_SessionInfo.ioBio);

        bRet = true;

        return bRet;
}

I am for the time being not handling the retry options (will implement
later). Now the problem is this call "nLen =
BIO_ctrl_get_read_request(m_SessionInfo.ioBio);" always return 0 & the
function returns after that. Shouldn't the SSL engine be wating for some
data on start of server side session?? since its the client who always sends
the handshake data first. Can anyone help me solve this problem??? I check
the return values while setting up ssl context and SSL objects and they all
are retuning success.
Thanks in Advance,
Regards,
Usman.

_________________________________________________________________
Don't just search. Find. Check out the new MSN Search!
http://search.msn.com/

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: A bio pairs question...

Alain Damiral
Hi there,

You might have missed one thing in ssltest.c... there is a first call to
BIO_read on the server side before any data is available. Before that
call, the read request on server_io is actaully 0. After the call to
BIO_read, then some data is requested. So if you're using read request,
the trick would be to first attempt a read before any data is available.

You can also try using write_guarantee. This basically would allow more
data than requested to be available on the network BIO. In either case,
be careful not to drop data that you have received from the network but
that couldn't be fed into the network BIO right away. Since SSL uses a
reliable transport layer, the other end can rightfully assume that this
data has been received and it has no obligation to resend it. In your
code it seems that this would be what is contained at the end in pData,
beyond offset nRet - I think you should buffer this for future use...

I hope this makes sense and helps :)


Usman Riaz wrote:

> Hi*!
>    I am implementing IOCP server (for Windows OS) supporting SSL. For
> SSL part i am trying to use OpenSSL's bio pairs. I have looked at the
> example in ssltest.c. As i understand (please correct me if i am
> wrong) of the three bios (s_ssl_bio, server, server_io) that get
> created in "doit_biopair" function, the "server_io" bio is used to
> read/write "Encrypted" data & the "s_ssl_bio" is used to read/write
> "UNEncrypted" data. I have setup my code according to this principle.
> Now when the client connects, it sends some "ssl-handshake"
> (Encrypted) data & I have to write it "server_io". Here is how my
> function looks for writing to "server_io" BIO.
>
> bool CSSLSession::OnRecv(const std::string& RecvData)
> {
>     bool bRet = false;
>     char *pData = NULL;
>     int nRet = -1;
>     int nLen = -1;
>
>     nLen = BIO_ctrl_get_read_request(m_SessionInfo.ioBio);
>
>     if( !nLen )
>     {
>         bRet = true;
>         return bRet;
>     }
>
>     nRet = BIO_nwrite0(m_SessionInfo.ioBio, &pData);
>
>     if( 0 >= nRet || nLen > nRet || !pData )
>     {
>         return bRet;
>     }
>
>     nRet = nLen;
>
> #pragma warning (disable : 4018)
>     if( nRet > RecvData.size() )
>     {
>         nRet = RecvData.size();
>     }
> #pragma warning (default: 4018)
>
>     memcpy(pData, RecvData.data(), nRet);
>
>     nRet = BIO_nwrite(m_SessionInfo.ioBio, &pData, nRet);
>     BIO_flush(m_SessionInfo.ioBio);
>
>     bRet = true;
>
>     return bRet;
> }
>
> I am for the time being not handling the retry options (will implement
> later). Now the problem is this call "nLen =
> BIO_ctrl_get_read_request(m_SessionInfo.ioBio);" always return 0 & the
> function returns after that. Shouldn't the SSL engine be wating for
> some data on start of server side session?? since its the client who
> always sends the handshake data first. Can anyone help me solve this
> problem??? I check the return values while setting up ssl context and
> SSL objects and they all are retuning success.
> Thanks in Advance,
> Regards,
> Usman.



--
Alain Damiral,

Université Catholique de Louvain - student
alain.damiral'at'student.info.ucl.ac.be

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: A bio pairs question...

Usman Riaz
In reply to this post by Usman Riaz

Thanks for the reply Alain, I have changed as you mentioned by placing a
call to do a read on s_ssl_bio (for reading/writing UNEncrypted Data). Here
is how that function looks like...

bool CSSLSession::GetData(std::string& RecvData)
{
        /*The RecvData WILL contain ****UN-ENCRYPTED-DATA**** that was received
earlier*/
        bool bRet = false;
        int nRet = -1;
        char RecvBuffer[BUF_LEN * 2] = {0, };

        memset(RecvBuffer, 0, sizeof(char) * (BUF_LEN * 2));

        nRet = BIO_read(m_SessionInfo.SSLBio, RecvBuffer, sizeof(char) * (BUF_LEN *
2));
        if( 0 > nRet )
        {
                if( !BIO_should_retry(m_SessionInfo.SSLBio) )
                {
                        return bRet;
                }
                /* Ignore "BIO_should_retry" for the time being */
                nRet = 1;
        }
        else
        {
            if( nRet )
            {
                RecvData.assign(RecvBuffer, nRet);
            }
        }

        if( nRet )
        {
                bRet = true;
        }

        return bRet;
}

Now, in the above function, "BIO_should_retry" returns true or 1 so
afterwards i call the function (the one mentioned in my first post) to write
data to "server_io" BIO (that was received from the client socket). This
time "BIO_ctrl_get_read_request(m_SessionInfo.ioBio);" returns 5, and i
write 5 bytes to the BIO and return (even though i always get something like
105 bytes in the beginning from the client). Now what should be done next
with those remaining bytes??? Should try to write on the "server_io" BIO
again (i tried that but the second time "BIO_ctrl_get_read_request" returns
0. Can you please help me sort this out.
Thanks in Advance,
Regards,
Usman.



My mail server crashed just before I could send this reply to the list so
I'm using another email to send it directly to you. You can reply to the
list if there are further questions...


Hi there,

You might have missed one thing in ssltest.c... there is a first call to
BIO_read on the server side before any data is available. Before that call,
the read request on server_io is actaully 0. After the call to BIO_read,
then some data is requested. So if you're using read request, the trick
would be to first attempt a read before any data is available.

You can also try using write_guarantee. This basically would allow more data
than requested to be available on the network BIO. In either case, be
careful not to drop data that you have received from the network but that
couldn't be fed into the network BIO right away. Since SSL uses a reliable
transport layer, the other end can rightfully assume that this data has been
received and it has no obligation to resend it. In your code it seems that
this would be what is contained at the end in pData, beyond offset nRet - I
think you should buffer this for future use...

I hope this makes sense and helps :)

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE!
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]