How to empty a BIO buffer?

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

How to empty a BIO buffer?

Iñaki Baz Castillo
Hi, I'm trying to avoid a BIO_read() call given that it copies the BIO
buffer data into a buffer I must provide to the function. I use a BIO
memory pair.

In my case it would be nice if I can get the pointer and length of the
current BIO buffer and then tell the BIO to empty/clean it.

So I want to replace this code:

----------------------------------
int read = BIO_read(sslBioToNetwork, (void*)myBuffer, MY_BUFFER_SIZE);

// Use the read data
----------------------------------

with something like this:

-----------------------------------
long read;
char** data = (char**)&myBuffer;

read = BIO_get_mem_data(sslBioToNetwork, data);

// Emtpy the BIO buffer data, HOW?

// Use the read data
-----------------------------------


But I do not know how to empty the already read BIO buffer data.
BIO_flush() does nothing.

How may I do this?

Thanks a lot.

--
Iñaki Baz Castillo
<[hidden email]>
______________________________________________________________________
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: How to empty a BIO buffer?

Iñaki Baz Castillo
2014-09-08 14:44 GMT+02:00 Iñaki Baz Castillo <[hidden email]>:

> ----------------------------------
> int read = BIO_read(sslBioToNetwork, (void*)myBuffer, MY_BUFFER_SIZE);
>
> // Use the read data
> ----------------------------------
>
> with something like this:
>
> -----------------------------------
> long read;
> char** data = (char**)&myBuffer;
>
> read = BIO_get_mem_data(sslBioToNetwork, data);
>
> // Emtpy the BIO buffer data, HOW?
>
> // Use the read data
> -----------------------------------
>
>
> But I do not know how to empty the already read BIO buffer data.
> BIO_flush() does nothing.


Sorry, BIO_flush() works. The problem is that calling BIO_eof() after
BIO_flush() does not return 1 so I get a loop. Updated my code not to
check BIO_eof() after BIO_flush().

--
Iñaki Baz Castillo
<[hidden email]>
______________________________________________________________________
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: How to empty a BIO buffer?

Richard Levitte - VMS Whacker
In message <CALiegf=+4vr1GU=[hidden email]> on Mon, 8 Sep 2014 15:10:04 +0200, Iñaki Baz Castillo <[hidden email]> said:

ibc> 2014-09-08 14:44 GMT+02:00 Iñaki Baz Castillo <[hidden email]>:
ibc> > ----------------------------------
ibc> > int read = BIO_read(sslBioToNetwork, (void*)myBuffer, MY_BUFFER_SIZE);
ibc> >
ibc> > // Use the read data
ibc> > ----------------------------------
ibc> >
ibc> > with something like this:
ibc> >
ibc> > -----------------------------------
ibc> > long read;
ibc> > char** data = (char**)&myBuffer;
ibc> >
ibc> > read = BIO_get_mem_data(sslBioToNetwork, data);
ibc> >
ibc> > // Emtpy the BIO buffer data, HOW?
ibc> >
ibc> > // Use the read data
ibc> > -----------------------------------
ibc> >
ibc> >
ibc> > But I do not know how to empty the already read BIO buffer data.
ibc> > BIO_flush() does nothing.
ibc>
ibc>
ibc> Sorry, BIO_flush() works. The problem is that calling BIO_eof() after
ibc> BIO_flush() does not return 1 so I get a loop. Updated my code not to
ibc> check BIO_eof() after BIO_flush().

Sorry, BIO_flush() isn't what you want (it doesn't reset the buffer to
empty), BIO_reset() is.

However, you need to be careful...  if I were you, I would use the
read data before resetting, as BIO_get_mem_data() gives you the
pointer to the internal BIO_s_mem buffer, not to a duplicate of it.

Cheers,
Richard

--
Richard Levitte                         [hidden email]
                                        http://richard.levitte.org/

"Life is a tremendous celebration - and I'm invited!"
-- from a friend's blog, translated from Swedish
______________________________________________________________________
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: How to empty a BIO buffer?

Iñaki Baz Castillo
2014-09-08 16:08 GMT+02:00 Richard Levitte <[hidden email]>:
> Sorry, BIO_flush() isn't what you want (it doesn't reset the buffer to
> empty), BIO_reset() is.
>
> However, you need to be careful...  if I were you, I would use the
> read data before resetting, as BIO_get_mem_data() gives you the
> pointer to the internal BIO_s_mem buffer, not to a duplicate of it.


Thanks, it does work. However... I do not understand how...

This works fine:

-----------------------------------
long read;
// myBuffer is an already allocated buffer.
char** data = (char**)&myBuffer;

read = BIO_get_mem_data(bio, data);

// Use data and read values.

BIO_reset(bio);
-----------------------------------

This crashes:

-----------------------------------
long read;
char** data = NULL;

read = BIO_get_mem_data(bio, data);

// Use data and read values.

BIO_reset(bio);
-----------------------------------


Why do I need to provide BIO_get_mem_data() with an already allocated
buffer? I've checked the function and I do not understand what it
does). The only I want is to get the pointer to the BIO's buffer in
which SSL_write() wrote. Why should I provide an allocated buffer? The
BIO already has a buffer and the data is already in there after
calling SSL_write(). Why do I need to pass an allocated buffer?

Thanks a lot.

--
Iñaki Baz Castillo
<[hidden email]>
______________________________________________________________________
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: How to empty a BIO buffer?

Iñaki Baz Castillo
2014-09-08 18:19 GMT+02:00 Iñaki Baz Castillo <[hidden email]>:

> This works fine:
>
> -----------------------------------
> long read;
> // myBuffer is an already allocated buffer.
> char** data = (char**)&myBuffer;
>
> read = BIO_get_mem_data(bio, data);
>
> // Use data and read values.
>
> BIO_reset(bio);
> -----------------------------------

BTW I've realized that it also works by removing the BIO_reset() call.
I assume that SSL_write() writes into the BIO and overrides the
existing data (and the BIO buffer length gets updated with the most
recent written data).


--
Iñaki Baz Castillo
<[hidden email]>
______________________________________________________________________
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: How to empty a BIO buffer?

Kyle Hamilton
In reply to this post by Iñaki Baz Castillo
The allocated buffer needs to be sizeof(char *). What's happening is the address of the buffer (&buffer[0]) gets written to the pointer-to-pointer-to-char, data. If data == NULL, you're asking to write the address of the buffer to unallocated memory.

It's done this way because the return value of the function is the number of valid bytes you can read from that location, and the address must go somewhere for you to get the data from it.

I'm sorry this is probably difficult to understand, I don't know if I can explain it more easily.

-Kyle H


On September 8, 2014 9:19:09 AM PST, "Iñaki Baz Castillo" <[hidden email]> wrote:
2014-09-08 16:08 GMT+02:00 Richard Levitte <[hidden email]>:
Sorry, BIO_flush() isn't what you want (it doesn't reset the buffer to
empty), BIO_reset() is.

However, you need to be careful... if I were you, I would use the
read data before resetting, as BIO_get_mem_data() gives you the
pointer to the internal BIO_s_mem buffer, not to a duplicate of it.


Thanks, it does work. However... I do not understand how...

This works fine:



long read;
// myBuffer is an already allocated buffer.
char** data = (char**)&myBuffer;

read = BIO_get_mem_data(bio, data);

// Use data and read values.

BIO_reset(bio);



This crashes:



long read;
char** data = NULL;

read = BIO_get_mem_data(bio, data);

// Use data and read values.

BIO_reset(bio);




Why do I need to provide BIO_get_mem_data() with an already allocated
buffer? I've checked the function and I do not understand what it
does). The only I want is to get the pointer to the BIO's buffer in
which SSL_write() wrote. Why should I provide an allocated buffer? The
BIO already has a buffer and the data is already in there after
calling SSL_write(). Why do I need to pass an allocated buffer?

Thanks a lot.

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
Reply | Threaded
Open this post in threaded view
|

Re: How to empty a BIO buffer?

Iñaki Baz Castillo
2014-09-08 18:35 GMT+02:00 Kyle Hamilton <[hidden email]>:

> The allocated buffer needs to be sizeof(char *). What's happening is the
> address of the buffer (&buffer[0]) gets written to the
> pointer-to-pointer-to-char, data. If data == NULL, you're asking to write
> the address of the buffer to unallocated memory.
>
> It's done this way because the return value of the function is the number of
> valid bytes you can read from that location, and the address must go
> somewhere for you to get the data from it.
>
> I'm sorry this is probably difficult to understand, I don't know if I can
> explain it more easily.

It's clear. And my error was terrible, I was creating a char** data
instead of char* data. The following updated code does work:


-------------------------------------
long read;
char* data = NULL;

read = BIO_get_mem_data(bio, &data);

// Use data and read values.
-------------------------------------


Thanks a lot.


--
Iñaki Baz Castillo
<[hidden email]>
______________________________________________________________________
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: How to empty a BIO buffer?

Richard Levitte - VMS Whacker
In reply to this post by Iñaki Baz Castillo
In message <CALiegfmvaG-nc=[hidden email]> on Mon, 8 Sep 2014 18:19:09 +0200, Iñaki Baz Castillo <[hidden email]> said:

ibc> Why do I need to provide BIO_get_mem_data() with an already allocated
ibc> buffer? I've checked the function and I do not understand what it
ibc> does). The only I want is to get the pointer to the BIO's buffer in
ibc> which SSL_write() wrote. Why should I provide an allocated buffer? The
ibc> BIO already has a buffer and the data is already in there after
ibc> calling SSL_write(). Why do I need to pass an allocated buffer?

Actually, you don't, you only need to pass it the address to a char*
(that's what a char** is).  This code snippet (which is your code
snippet that crashes with a small change) is sufficient:

------------------------------
long read;
char* data = NULL;

read = BIO_get_mem_data(bio, &data);

// Use data and read values.

BIO_reset(bio);
------------------------------

Cheers,
Richard

--
Richard Levitte                         [hidden email]
                                        http://richard.levitte.org/

"Life is a tremendous celebration - and I'm invited!"
-- from a friend's blog, translated from Swedish
______________________________________________________________________
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: How to empty a BIO buffer?

Richard Levitte - VMS Whacker
In reply to this post by Iñaki Baz Castillo
And of course, I noticed this email after sending my own...  sorry.

In message <CALiegf=BytJ-1ZDzcCw3=e2=[hidden email]> on Mon, 8 Sep 2014 18:41:40 +0200, Iñaki Baz Castillo <[hidden email]> said:

ibc> 2014-09-08 18:35 GMT+02:00 Kyle Hamilton <[hidden email]>:
ibc> > The allocated buffer needs to be sizeof(char *). What's happening is the
ibc> > address of the buffer (&buffer[0]) gets written to the
ibc> > pointer-to-pointer-to-char, data. If data == NULL, you're asking to write
ibc> > the address of the buffer to unallocated memory.
ibc> >
ibc> > It's done this way because the return value of the function is the number of
ibc> > valid bytes you can read from that location, and the address must go
ibc> > somewhere for you to get the data from it.
ibc> >
ibc> > I'm sorry this is probably difficult to understand, I don't know if I can
ibc> > explain it more easily.
ibc>
ibc> It's clear. And my error was terrible, I was creating a char** data
ibc> instead of char* data. The following updated code does work:
ibc>
ibc>
ibc> -------------------------------------
ibc> long read;
ibc> char* data = NULL;
ibc>
ibc> read = BIO_get_mem_data(bio, &data);
ibc>
ibc> // Use data and read values.
ibc> -------------------------------------
ibc>
ibc>
ibc> Thanks a lot.
ibc>
ibc>
ibc> --
ibc> Iñaki Baz Castillo
ibc> <[hidden email]>
______________________________________________________________________
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: How to empty a BIO buffer?

Iñaki Baz Castillo
2014-09-09 10:46 GMT+02:00 Richard Levitte <[hidden email]>:
> And of course, I noticed this email after sending my own...  sorry.


:)

Thanks a lot.

--
Iñaki Baz Castillo
<[hidden email]>
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [hidden email]
Automated List Manager                           [hidden email]