RE: Base64 Encoding and Decoding error

2011-03-03 Thread Dave Thompson
   From: owner-openssl-us...@openssl.org On Behalf Of Vinay Kumar L
   Sent: Tuesday, 01 March, 2011 23:42

   Thanks for your reply, but OpenSSL Base64 decoding api returns NULL 
 on passing Base64 encoded data. The code snippet is as follows:

I very much doubt it returns NULL. NULL in C is a null POINTER 
(pedantically, a null pointer CONSTANT). Your code will return 
a string of zero characters, i.e. an empty string.
In general this is sometimes called a null STRING but in C 
that's confusing because a null string is not a null pointer.
(And FWIW in SQL a NULL value is not an empty string either,
although some user tools will DISPLAY it as such.)

Also, the byte that terminates a C (narrow) string is a null 
character or null byte, sometimes called NUL (note 3 letters).
But this character is not IN the string, it is AFTER the string.

   int main(int argc, char **argv)
   {
   char *output = unbase64(dGVzdGVuY29kaW5nCg==,
strlen(dGVzdGVuY29kaW5nCg==));

Your real problem is that the ENCODING should have terminating newline.
See below. (The encoded/decoded DATA can include a newline or not, 
which as you have already seen changes the encoding, but often 
isn't even characters so the concept of newline doesn't apply.)

   printf(Unbase64: %s\n, output);
   free(output);
   }

In C99 or C++ you must have at least a declaration of the function 
before the call. (You can have the definition which is also a 
declaration, by arranging your code 'bottom up'.)

But in C89, the implicit declaration is 'returns int'. You should 
be unable to assign it to a char* without at least a warning.
And even if you add a cast, it still won't work on some systems 
because the calling sequence is actually different. (Pedantically, 
initialization isn't assignment but it's sufficiently like.)

In C (both C89 and C99) you can choose whether to use a prototype 
declaration (with parameter types) or a nonprototype aka KR1
declaration without. Prototypes are Better(tm).

   char *unbase64(unsigned char *input, int length)

With a nonprototype (including implicit) declaration this is wrong.
strlen() returns size_t, not int. On SOME systems size_t and int are 
actually the same size (and passed compatibly) and this 'accidentally' 
works. On some systems it doesn't work at all. (With a prototype 
it will be converted as long as the value is in range. If you have 
data long enough its length fits in size_t but not int, use size_t.)

Technically unsigned-char* is not the same type as plain-char*, 
which is the value of the string literal above -- even on systems 
where plain-char is unsigned. In practice this will always work. 
However, since (valid) b64 data is always in a limited character set 
that is a subset of the 'basic execution' set, it usually makes sense 
to store it in array of plain-char, and pass it as pointer to same.

OTOH the data encoded into and decoded from b64 is often binary 
(although your example isn't) so in general treating it as 
array of and pointer to unsigned-char is usually better.

   {
   BIO *b64, *bmem;
   
   char *buffer = (char *)malloc(length);

Should check for failed allocation (returned null pointer) before using,
but I'll assume this is only test/example code. The cast is not needed 
in C if you have #include'd stdlib.h as required; without that correct 
declaration the cast doesn't actually solve the problem on some systems, 
it just silences the warning because you lied to the compiler.

In C++ the cast is needed if you use malloc but you shouldn't use malloc.

   memset(buffer, 0, length);

Don't need this if you add just one null terminator in the right place.
If you actually do need zero-fill, calloc() may be less inefficient.


   b64 = BIO_new(BIO_f_base64());
   bmem = BIO_new_mem_buf(input, length);
   bmem = BIO_push(b64, bmem);
   BIO_read(bmem, buffer, length);

You should use the return value of BIO_read.
For the data above, the return value is zero, because by default 
b64BIO requires input to have the line terminators specified 
by PEM (always at the end, plus in the middle if 'too long') 
and similarly inserts them on output (which you don't have here).
You can change this with 
  BIO_set_flags (b64,BIO_FLAGS_BASE64_NO_NL)

When successful, the return value is the number of bytes decoded, 
which is convenient for a number of things; in your case you want 
to treat the data as a null-terminated string, so that's the 
right place to insert a single null-character terminator.

   BIO_free_all(bmem);
   return buffer;
   }



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

RE: Base64 Encoding and Decoding error

2011-03-03 Thread Jeremy Farrell
 

 From: Dave Thompson
 Sent: Thursday, March 03, 2011 10:35 PM
 To: openssl-users@openssl.org
 
 Also, the byte that terminates a C (narrow) string is a null 
 character or null byte, sometimes called NUL (note 3 letters).
 But this character is not IN the string, it is AFTER the string.

If we're being pedantic, the null character is part of the string as far as C 
is 
concerned.__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


Re: Base64 Encoding and Decoding error

2011-03-01 Thread Vinay Kumar L

Hi Jan,

Thanks for your reply, but OpenSSL Base64 decoding api returns NULL on 
passing Base64 encoded data. The code snippet is as follows:


int main(int argc, char **argv)
{
   char *output = unbase64(dGVzdGVuY29kaW5nCg==, 
strlen(dGVzdGVuY29kaW5nCg==));

   printf(Unbase64: %s\n, output);
   free(output);
}
char *unbase64(unsigned char *input, int length)
{
   BIO *b64, *bmem;

   char *buffer = (char *)malloc(length);
   memset(buffer, 0, length);
   b64 = BIO_new(BIO_f_base64());
   bmem = BIO_new_mem_buf(input, length);
   bmem = BIO_push(b64, bmem);
   BIO_read(bmem, buffer, length);
   BIO_free_all(bmem);
   return buffer;
}

The string *dGVzdGVuY29kaW5nCg==* on Base64 decoding should return 
*testencoding\n*, but the above code returns *NULL*.  Please let me 
know the cause of Base64 returning NULL.


Thanks  Best Regards,
Vinay

Jan Steffens wrote:

On Tue, Mar 1, 2011 at 7:00 AM, Vinay Kumar L
vinaykuma...@globaledgesoft.com wrote:
  

Encoding of string testencoding using base64 command:

#base64 data.txt  encode.txt
data.txt - It contains only the string testencoding
encode.txt - It contains encoded data
#cat encode.txt
dGVzdGVuY29kaW5nCg==



This is actually the encoding for the string testencoding\n. Note
the trailing newline, and check what your data.txt really contains.
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org

  




Re: Base64 Encoding and Decoding error

2011-02-28 Thread Jan Steffens
On Tue, Mar 1, 2011 at 7:00 AM, Vinay Kumar L
vinaykuma...@globaledgesoft.com wrote:
 Encoding of string testencoding using base64 command:

 #base64 data.txt  encode.txt
     data.txt - It contains only the string testencoding
     encode.txt - It contains encoded data
 #cat encode.txt
 dGVzdGVuY29kaW5nCg==

This is actually the encoding for the string testencoding\n. Note
the trailing newline, and check what your data.txt really contains.
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org