c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta/*
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta Authors:
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta Jan Cholasta <jcholast@redhat.com>
e07a94a66985b674c5df11ca466792902164c4e2George McCollister George McCollister <george.mccollister@gmail.com>
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta Copyright (C) 2012 Red Hat
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta This program is free software; you can redistribute it and/or modify
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta it under the terms of the GNU General Public License as published by
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta the Free Software Foundation; either version 3 of the License, or
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta (at your option) any later version.
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta This program is distributed in the hope that it will be useful,
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta but WITHOUT ANY WARRANTY; without even the implied warranty of
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta GNU General Public License for more details.
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta You should have received a copy of the GNU General Public License
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta along with this program. If not, see <http://www.gnu.org/licenses/>.
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta*/
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta#include "util/util.h"
5cd4414fce1e0eb4133dfc6fc828bf25c8a959f9Lukas Slebodnik#include "util/crypto/sss_crypto.h"
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
e07a94a66985b674c5df11ca466792902164c4e2George McCollister#include <openssl/bio.h>
e07a94a66985b674c5df11ca466792902164c4e2George McCollister#include <openssl/evp.h>
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholastachar *sss_base64_encode(TALLOC_CTX *mem_ctx,
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta const unsigned char *in,
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta size_t insize)
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta{
e07a94a66985b674c5df11ca466792902164c4e2George McCollister char *b64encoded = NULL, *outbuf = NULL;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister int i, j, b64size;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO *bmem, *b64;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister b64 = BIO_new(BIO_f_base64());
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!b64) return NULL;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister bmem = BIO_new(BIO_s_mem());
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!bmem) goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister b64 = BIO_push(b64, bmem);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_write(b64, in, insize);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister (void) BIO_flush(b64);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister b64size = BIO_get_mem_data(bmem, &b64encoded);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (b64encoded) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister outbuf = talloc_array(mem_ctx, char, b64size+1);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (outbuf == NULL) goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister for (i=0, j=0; i < b64size; i++) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (b64encoded[i] == '\n' || b64encoded[i] == '\r') {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister continue;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister outbuf[j++] = b64encoded[i];
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister outbuf[j++] = '\0';
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollisterdone:
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free_all(b64);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister return outbuf;
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta}
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholastaunsigned char *sss_base64_decode(TALLOC_CTX *mem_ctx,
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta const char *in,
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta size_t *outsize)
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta{
e07a94a66985b674c5df11ca466792902164c4e2George McCollister unsigned char *outbuf = NULL;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister unsigned char *b64decoded = NULL;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister unsigned char inbuf[512];
e07a94a66985b674c5df11ca466792902164c4e2George McCollister char * in_dup;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister int size, inlen = strlen(in);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO *bmem, *b64, *bmem_out;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister TALLOC_CTX *tmp_ctx = NULL;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister tmp_ctx = talloc_new(NULL);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!tmp_ctx) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister return NULL;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister in_dup = talloc_size(tmp_ctx, inlen+1);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!in_dup) goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister memcpy(in_dup, in, inlen+1);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister b64 = BIO_new(BIO_f_base64());
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!b64) goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister bmem = BIO_new_mem_buf(in_dup, -1);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!bmem) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free(b64);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister b64 = BIO_push(b64, bmem);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister bmem_out = BIO_new(BIO_s_mem());
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!bmem_out) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free_all(b64);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister while((inlen = BIO_read(b64, inbuf, 512)) > 0)
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_write(bmem_out, inbuf, inlen);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister (void) BIO_flush(bmem_out);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister size = BIO_get_mem_data(bmem_out, &b64decoded);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (b64decoded) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister outbuf = talloc_memdup(mem_ctx, b64decoded, size);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister if (!outbuf) {
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free_all(b64);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free(bmem_out);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister goto done;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollister *outsize = size;
e07a94a66985b674c5df11ca466792902164c4e2George McCollister } else {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get decoded data\n");
e07a94a66985b674c5df11ca466792902164c4e2George McCollister }
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free_all(b64);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister BIO_free(bmem_out);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister
e07a94a66985b674c5df11ca466792902164c4e2George McCollisterdone:
e07a94a66985b674c5df11ca466792902164c4e2George McCollister talloc_free(tmp_ctx);
e07a94a66985b674c5df11ca466792902164c4e2George McCollister return outbuf;
c7919a4fe41133cc466aa3d9431bfceee5784e7bJan Cholasta}