|Applies To||RSA BSAFE Crypto-C Micro Edition 2.1|
|Issue||How to Base64 encode and decode in Crypto-C ME|
The documentation of R_BASE64_encode and R_BASE64_decode is missing in the 2.1 release. This will be fixed in 3.0.
Here is the missing documentation:
This sample code shows how to use these methods:
/* Encode data into Base64 format: */
encodedBytes = encodedDataMaxLen;
/*int R_CDECL R_BASE64_encode(unsigned int dlen, unsigned char *dbuf, int eol,
ret = R_BASE64_encode((unsigned int)(dataBytes),
/* Output the Base64 encoded data. */
/* Decode data from Base64 format. */
decodedBytes = decodedDataMaxLen;
/*int R_CDECL R_BASE64_decode(unsigned int dlen, unsigned char *dbuf, int *eol,
ret = R_BASE64_decode((unsigned int)(encodedBytes),
/* Output the decoded data. */
For Base64 encoding the output size should usually look something like this:
(((length + 2)/3) * 4)
plus 1 if we need space for a terminating NULL character. (R_BASE64_encode() requires this extra byte as it always adds a NULL character to the end of the encoded data.)
R_BASE64_encode() uses internal functions which complicate this by allowing up to two carriage-return/line-feed characters for every 48 bytes of input (64 bytes of output) to support PEM format (RFC1113). Using R_BASE64_EOL_NONE as the third parameter to R_BASE64_encode() causes no carriage-return/line-feed characters to be added, but this is not accounted for in the estimated output buffer size.
The value that is actually returned when R_BASE64_encode() is called with NULL as the third parameter looks like this:
(((length + 2)/3) * 4 + (length/48 + 1) * 2) + 80.
The (length/48 + 1) * 2 accounts for the possible carriage-return/line-feed characters for every 48 input bytes, but the + 80 here appears to be overkill.
In summary, as long as you don't need the carriage-return/line-feed characters for PEM, R_BASE64_encode() requires an output buffer that looks like this:
(((length + 2)/3) * 4) + 1.
If you do require a carriage-return and line-feed, you will need a buffer that looks like this:
(((length + 2)/3) * 4) + (length/48 + 1) * 2) + 1.
For only a carriage-return or line-feed use a buffer like this:
(((length + 2)/3) * 4) + (length/48 + 1) + 1.
Similarly, the value that is returned when R_BASE64_decode() is called with NULL as the third parameter looks like this:
Again, this is overkill as Base64 encoded data should be a multiple of 4 bytes and there is no NULL added to the end of binary data. The buffer you need for decoded data should look like this:
R_BASE64_decode() doesn't check to ensure that the input data is valid base64 encoded data. If the length of the data is not a multiple of 4 bytes (as all valid base64 encoded data should be), R_BASE64_decode() will simply decode as much as it can without returning an error code. For example: 3 bytes of input will result in no output and no error code, while 7 bytes of input will result in 3 bytes of output and no error code.
Crypto-C ME 3.0 solves this problem by introducing R_BSASE64_decode_checked() which ensures that the input data is a multiple of 4 bytes. If not, R_ERROR_BAD_LENGTH (10023) is returned and no decoded data will appear in the output buffer.
|Legacy Article ID||a36055|