I am encrypting prior to encoding. The encryption coding is below.
Also, I tried the coding changes below that were recommended and got the
same results. Any other ideas?
buff = malloc(bptr->length + 1);
buff[bptr->length]=0;
void encrypt(char *inbuf, char *outbuf, int blklen, char *key)
{
int counter = 0;
char iv[8];
BF_KEY keyStruct;
memset(iv, 0, 8);
BF_set_key(&keyStruct, strlen(key), key);
BF_cfb64_encrypt(inbuf, outbuf, blklen, &keyStruct,
iv, &counter, BF_ENCRYPT);
}
Ger Hobbelt wrote:
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;
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openssl-users@openssl.org
Automated List Manager majord...@openssl.org