Functions to encode an array of bytes to Base64, and decode a Base64 string to an array of bytes.
Last active
December 16, 2015 20:38
-
-
Save kvelakur/a3ac17ebf5614547ded9 to your computer and use it in GitHub Desktop.
Base 64 encoding and decoding using OpenSSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <openssl/bio.h> | |
#include <openssl/evp.h> | |
#include <openssl/buffer.h> | |
/** | |
* @brief Use the openssl library to decode a base64 string to a C string. | |
* | |
* @param[in] The Base64 encoded string. Has to null terminated. | |
* @param[out] The length of the decoded string. | |
* | |
* @retval Pointer to decoded array of bytes. Note that array is not null-terminated. | |
* NULL if decoding failed. | |
* Caller has to free the memory after using the decoded string. | |
*/ | |
unsigned char *base64_decode(char* b64message, size_t *decode_len) | |
{ | |
BIO *bio = NULL, *b64 = NULL; | |
unsigned char *buffer = NULL; | |
size_t msglen = strlen(b64message); | |
if(msglen == 0) goto cleanup; | |
bio = BIO_new_mem_buf(b64message, -1); | |
if(bio == NULL) goto cleanup; | |
b64 = BIO_new(BIO_f_base64()); | |
if(b64 == NULL) goto cleanup; | |
// New lines should't matter | |
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); | |
bio = BIO_push(b64, bio); | |
// The maximum possible length, after accounting for padding and CR+LF is msglen*3/4 | |
buffer = (unsigned char*) malloc(sizeof(char)*(msglen*3)/4); | |
if (buffer == NULL) goto cleanup; | |
*decode_len = (size_t) BIO_read(bio, buffer, (int) msglen); | |
cleanup: | |
BIO_free_all(bio); | |
return buffer; | |
} | |
/** | |
* @brief Use the openssl library to encode a byte array to a Base64 string. | |
* | |
* @param[in] The byte array to be encoded. | |
* @param[in] The length of the byte array buffer. | |
* | |
* @retval Pointer to encoded null-terminated string, or NULL if encoding failed. | |
* Caller has to free the memory after using the encoded string. | |
*/ | |
char *base64_encode(unsigned char *buffer, size_t length) | |
{ | |
BIO *bio = NULL, *b64 = NULL; | |
BUF_MEM *bufferPtr = NULL; | |
char *b64text = NULL; | |
if(length <= 0) goto cleanup; | |
b64 = BIO_new(BIO_f_base64()); | |
if(b64 == NULL) goto cleanup; | |
bio = BIO_new(BIO_s_mem()); | |
if(bio == NULL) goto cleanup; | |
bio = BIO_push(b64, bio); | |
if(BIO_write(bio, buffer, (int)length) <= 0) goto cleanup; | |
if(BIO_flush(bio) != 1) goto cleanup; | |
BIO_get_mem_ptr(bio, &bufferPtr); | |
b64text = (char*) malloc((bufferPtr->length + 1) * sizeof(char)); | |
if(b64text == NULL) goto cleanup; | |
memcpy(b64text, bufferPtr->data, bufferPtr->length); | |
b64text[bufferPtr->length] = '\0'; | |
BIO_set_close(bio, BIO_NOCLOSE); | |
cleanup: | |
BIO_free_all(bio); | |
return b64text; | |
} | |
int main() { | |
char to_encode[] = "Test data !@#$%^&*()"; | |
char to_decode[] = "VGVzdCBkYXR\n\n\n\n\n\n\n\n" | |
"hICFAIyQlXiYqKCk="; | |
char *encoded = NULL; | |
unsigned char *decoded = NULL; | |
size_t i; | |
encoded = base64_encode((unsigned char *) to_encode, strlen(to_encode)); | |
if(encoded == NULL) goto exit; | |
printf("%s\n", encoded); | |
size_t len; | |
decoded = base64_decode(to_decode, &len); | |
if(decoded == NULL) goto exit; | |
for(i = 0; i < len; i++) putchar(decoded[i]); | |
printf("\n"); | |
exit: | |
free(decoded); | |
free(encoded); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
gcc -g -o base64.out base64.c -lcrypto -lm -Werror |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment