At first glance, there's a thing: 1) your code shows a classic mistake in a wicked way: that is OpenSSL works on *data*, not on *C strings*. (C strings are NUL-sentinel terminated, data is just data, no terminator.
Since you extract the amount of *data* written to the BIO mem sink (bptr->length), you must, at least, reserve extra space for the NUL sentinel if you want to transform it into a C string: > buff = malloc(bptr->length); --> buff = malloc(bptr->length + 1); Your code (correctly) assumes you won't be bothered with NUL bytes embedded in the data stored in the BIOmem sink, thanks to the to-base64 transformation filter in your BIO chain. However, and this illustrates the 'data vs. string', you overwrite the last *data* byte with your NUL sentinel: > buff[bptr->length-1]=0; --> buff[bptr->length]=0; which means *all* your input will have been chopped by one character, after base64 encoding. Since base64 'expands' 4:3 plus does minimal padding of the output for input sizes not divisible by 3, this probably explains why you get some numbers 'clipped' and not others: check your example and notice that the input which is clipped has a length divisible by 3 (len=15) so the last 3 input bytes will end up in the last 4 base64 bytes: chop away one and you just lost about 6 bits of your input data. Then consider the 14-byte sample, which came out 'unharmed': well, it _is_ harmed, but you're 'lucky' that the base64 DEcoder is so tolerant on its input (both in the len=15 and len=14 case): at len=14, the last 3-byte input block for the base64 encoding only 'carries' your last two bytes. As these end up in a 6-bits-per-output-byte spread, losing the last output byte, again assuming a VERY tolerant base64 DEcoder, doesn't visibly harm your (de-coded) 2 byte data: the last byte, which you lost on the way, only carried 6 input bits of byte 3 and those 6 input bits are unused, as the block only carries 2 bytes, not 3. Which leaves the 'extremely tolerant' base64 DEcoder: if it had been a little stricter in format-checking, it would have rejected the entire last block, or even the entire line, as the base64 format allows one to detect such damages (losing 1-3 base64 characters from the base64 output). --> did you use the OpenSSL base64 BIO filter to decode base64 back to literal data or do you use another base64 decoder? (I'd expected the OpenSSL one to yak about damaged input, but I might be wrong there.) 2) since you were saying you were encrypting / decrypting your data, I was expecting a BIO_f_cipher() BIO filter in there as well. Or are you just base64-encoding your data? You're doing write+flush so that's fine, al right. On Fri, Feb 13, 2009 at 4:26 AM, Rafel Coyle <rafel.co...@earthlink.net> wrote: > Below is my base64 encoding code. Any ideas? > > char *base64(const unsigned char *input, int length) > { > BIO *bmem, *b64; > BUF_MEM *bptr; > > char *buff ; > b64 = BIO_new(BIO_f_base64()); > bmem = BIO_new(BIO_s_mem()); > b64 = BIO_push(b64, bmem); > BIO_write( b64, input, length); > BIO_flush( b64 ); > BIO_get_mem_ptr( b64, &bptr ); > buff = malloc(bptr->length); > > memcpy(buff, bptr->data, bptr->length); > buff[bptr->length-1]=0; > BIO_free_all(b64); > return buff; -- Met vriendelijke groeten / Best regards, Ger Hobbelt -------------------------------------------------- web: http://www.hobbelt.com/ http://www.hebbut.net/ mail: g...@hobbelt.com mobile: +31-6-11 120 978 -------------------------------------------------- ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org