summaryrefslogtreecommitdiffstats
path: root/src/util/crypto/libcrypto/crypto_base64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto/libcrypto/crypto_base64.c')
-rw-r--r--src/util/crypto/libcrypto/crypto_base64.c103
1 files changed, 99 insertions, 4 deletions
diff --git a/src/util/crypto/libcrypto/crypto_base64.c b/src/util/crypto/libcrypto/crypto_base64.c
index c04914b94..3a119a0e9 100644
--- a/src/util/crypto/libcrypto/crypto_base64.c
+++ b/src/util/crypto/libcrypto/crypto_base64.c
@@ -1,6 +1,7 @@
/*
Authors:
Jan Cholasta <jcholast@redhat.com>
+ George McCollister <george.mccollister@gmail.com>
Copyright (C) 2012 Red Hat
@@ -20,18 +21,112 @@
#include "util/util.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
char *sss_base64_encode(TALLOC_CTX *mem_ctx,
const unsigned char *in,
size_t insize)
{
- DEBUG(SSSDBG_CRIT_FAILURE, ("sss_base64_encode not implemented.\n"));
- return NULL;
+ char *b64encoded = NULL, *outbuf = NULL;
+ int i, j, b64size;
+ BIO *bmem, *b64;
+
+ b64 = BIO_new(BIO_f_base64());
+ if (!b64) return NULL;
+
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+ bmem = BIO_new(BIO_s_mem());
+ if (!bmem) goto done;
+
+ b64 = BIO_push(b64, bmem);
+
+ BIO_write(b64, in, insize);
+
+ (void) BIO_flush(b64);
+
+ b64size = BIO_get_mem_data(bmem, &b64encoded);
+ if (b64encoded) {
+ outbuf = talloc_array(mem_ctx, char, b64size+1);
+ if (outbuf == NULL) goto done;
+
+ for (i=0, j=0; i < b64size; i++) {
+ if (b64encoded[i] == '\n' || b64encoded[i] == '\r') {
+ continue;
+ }
+ outbuf[j++] = b64encoded[i];
+ }
+ outbuf[j++] = '\0';
+ }
+
+done:
+ BIO_free_all(b64);
+ return outbuf;
}
unsigned char *sss_base64_decode(TALLOC_CTX *mem_ctx,
const char *in,
size_t *outsize)
{
- DEBUG(SSSDBG_CRIT_FAILURE, ("sss_base64_decode not implemented.\n"));
- return NULL;
+ unsigned char *outbuf = NULL;
+ unsigned char *b64decoded = NULL;
+ unsigned char inbuf[512];
+ char * in_dup;
+ int size, inlen = strlen(in);
+ BIO *bmem, *b64, *bmem_out;
+ TALLOC_CTX *tmp_ctx = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return NULL;
+ }
+
+ in_dup = talloc_size(tmp_ctx, inlen+1);
+ if (!in_dup) goto done;
+ memcpy(in_dup, in, inlen+1);
+
+ b64 = BIO_new(BIO_f_base64());
+ if (!b64) goto done;
+
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+
+ bmem = BIO_new_mem_buf(in_dup, -1);
+ if (!bmem) {
+ BIO_free(b64);
+ goto done;
+ }
+
+ b64 = BIO_push(b64, bmem);
+
+ bmem_out = BIO_new(BIO_s_mem());
+ if (!bmem_out) {
+ BIO_free_all(b64);
+ goto done;
+ }
+
+ while((inlen = BIO_read(b64, inbuf, 512)) > 0)
+ BIO_write(bmem_out, inbuf, inlen);
+
+ (void) BIO_flush(bmem_out);
+
+ size = BIO_get_mem_data(bmem_out, &b64decoded);
+
+ if (b64decoded) {
+ outbuf = talloc_memdup(mem_ctx, b64decoded, size);
+ if (!outbuf) {
+ BIO_free_all(b64);
+ BIO_free(bmem_out);
+ goto done;
+ }
+
+ *outsize = size;
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot get decoded data\n"));
+ }
+ BIO_free_all(b64);
+ BIO_free(bmem_out);
+
+done:
+ talloc_free(tmp_ctx);
+ return outbuf;
}