On Tue December 30 2008, Frank B. Brokken wrote:
> Hi List-members,
> 
> The following problem has (in some form) popped up on this list repeatedly,
> but after having browsed the archives until the beginning of this century I
> didn't encounter (or simply missed?) a solution for my current problem, hence
> the posting.
> 

For implementing a solution using the openSSL libraries, I leave to the experts.

In general - consider reading any fixed length record -
Your input is sets of 4 octets, you can't have a split set -
Your output is sets of 3 octets, (a 4*6bit -> 3*8bit function) -

So your read function must either guarantee that a full records (4*x)
have been read or somehow handle the excess 1 - 3 octets as the
first part of the next read.

For a general purpose function, it is probably a poor idea to expect
the input to have line breaks (although some uses of base64 do have
line breaks - just not in general).

Same coding situation you would have if you where reading text lines,
any partial line read must be treated as the first part of the next
read operation.

Here is a page with a link to a public domain, base64 encode/decode
routine:
http://www.fourmilab.ch/webtools/base64/
(scroll down the page to the tar ball link)

Read it (I haven't) - see how they handled the situation.
Since those can be used in a pipeline, it must have an example of
the code you need in it.

Mike
> For some time now I'm trying to decode a base64 encoded file which is filtered
> through a BIO_s_mem method. My intention is to write a function in which the
> actual decoding is decoupled from the source of the encoded information as
> well as from the destination of the decoded info, and so I thought of using a
> BIO_s_mem method as an intermediate storage medium chained to a BIO_f_base64
> method: obtain info the the source, put it into s_mem, base64 decode it, write
> the decoded info to the destination.
> 
> As an initial attempt the following program does the trick, but a problem
> occurs when I uncomment the section marked `Doesn't work'. In that case only
> the first block of bytes that's read is decoded after which BIO_read
> consistently returns 0.
> 
> The program as-is properly decodes base64 encoded information but requires me
> to read all the encoded information into the s_mem buffer first, which is
> unacceptable as it would require me to have all information available in
> memory before base64 can start decoding.
> 
> So my questions are: What's the flaw in my reasoning (c.q. program)? And: what
> must be done to decode information in a series of read-decode cycles rather
> than using a `read-all, decode-all' procedure?
> 
> Here's the little program I used:
> 
> --------------------------------------------------------------------------
> #include <openssl/bio.h> 
> #include <openssl/evp.h> 
> #include <stdio.h>
> 
> int main()
> {
>     BIO *bio, *b64;
>     char inbuf[500];
>     int inlen;
> 
>     b64 = BIO_new(BIO_f_base64());      // define BIOs
>     BIO *mem = BIO_new(BIO_s_mem());
> 
>     bio = BIO_push(b64, mem);           // set up the chain
> 
>     BIO_set_mem_eof_return(mem, 0);     // define s_mem eof
> 
>                                         // read info from some source
>     while ((inlen = fread(inbuf, 1, 500, stdin)) != 0)
>     {
>         BIO_write(mem, inbuf, inlen);   // put it in the s_mem buffer
>         BIO_flush(mem);
> 
> // Doesn't work:
> //        while (1)
> //        {                               // read what's already available
> //            inlen = BIO_read(bio, inbuf, inlen);
> //            if (inlen <= 0)             // no more, then done
> //                break;                  
> //                                        // write decoded info to a dest.
> //            fwrite(inbuf, 1, inlen, stdout);
> //        }
>     }
> 
>         // same procedure, but now write to the destination after first 
>         // reading all info into s_mem  
>     while (1)                  
>     {                          
>         inlen = BIO_read(bio, inbuf, 200);
>         if (inlen <= 0)
>             break;
>         fwrite(inbuf, 1, inlen, stdout);
>     }
> 
>     BIO_free_all(bio);
> }
> --------------------------------------------------------------------------
> 
> 
> Any suggestion I receive will of course greatly be appreciated.
> 
> Cheers,
> 


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to