146988a0eSchristos /*
246988a0eSchristos * Copyright (C) 2018 Yubico AB - See COPYING
346988a0eSchristos */
446988a0eSchristos
546988a0eSchristos #include <openssl/bio.h>
646988a0eSchristos #include <openssl/evp.h>
7*510cde34Schristos #include <limits.h>
846988a0eSchristos #include <stdint.h>
946988a0eSchristos #include <string.h>
1046988a0eSchristos
1146988a0eSchristos #include "b64.h"
1246988a0eSchristos
b64_encode(const void * ptr,size_t len,char ** out)1346988a0eSchristos int b64_encode(const void *ptr, size_t len, char **out) {
1446988a0eSchristos BIO *bio_b64 = NULL;
1546988a0eSchristos BIO *bio_mem = NULL;
1646988a0eSchristos char *b64_ptr = NULL;
1746988a0eSchristos long b64_len;
1846988a0eSchristos int n;
1946988a0eSchristos int ok = 0;
2046988a0eSchristos
2146988a0eSchristos if (ptr == NULL || out == NULL || len > INT_MAX)
2246988a0eSchristos return (0);
2346988a0eSchristos
2446988a0eSchristos *out = NULL;
2546988a0eSchristos
2646988a0eSchristos bio_b64 = BIO_new(BIO_f_base64());
2746988a0eSchristos if (bio_b64 == NULL)
2846988a0eSchristos goto fail;
2946988a0eSchristos
3046988a0eSchristos bio_mem = BIO_new(BIO_s_mem());
3146988a0eSchristos if (bio_mem == NULL)
3246988a0eSchristos goto fail;
3346988a0eSchristos
3446988a0eSchristos BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
3546988a0eSchristos BIO_push(bio_b64, bio_mem);
3646988a0eSchristos
3746988a0eSchristos n = BIO_write(bio_b64, ptr, (int) len);
3846988a0eSchristos if (n < 0 || (size_t) n != len)
3946988a0eSchristos goto fail;
4046988a0eSchristos
4146988a0eSchristos if (BIO_flush(bio_b64) < 0)
4246988a0eSchristos goto fail;
4346988a0eSchristos
4446988a0eSchristos b64_len = BIO_get_mem_data(bio_b64, &b64_ptr);
4546988a0eSchristos if (b64_len < 0 || (size_t) b64_len == SIZE_MAX || b64_ptr == NULL)
4646988a0eSchristos goto fail;
4746988a0eSchristos
4846988a0eSchristos *out = calloc(1, (size_t) b64_len + 1);
4946988a0eSchristos if (*out == NULL)
5046988a0eSchristos goto fail;
5146988a0eSchristos
5246988a0eSchristos memcpy(*out, b64_ptr, (size_t) b64_len);
5346988a0eSchristos ok = 1;
5446988a0eSchristos
5546988a0eSchristos fail:
5646988a0eSchristos BIO_free(bio_b64);
5746988a0eSchristos BIO_free(bio_mem);
5846988a0eSchristos
5946988a0eSchristos return (ok);
6046988a0eSchristos }
6146988a0eSchristos
b64_decode(const char * in,void ** ptr,size_t * len)6246988a0eSchristos int b64_decode(const char *in, void **ptr, size_t *len) {
6346988a0eSchristos BIO *bio_mem = NULL;
6446988a0eSchristos BIO *bio_b64 = NULL;
6546988a0eSchristos size_t alloc_len;
6646988a0eSchristos int n;
6746988a0eSchristos int ok = 0;
6846988a0eSchristos
6946988a0eSchristos if (in == NULL || ptr == NULL || len == NULL || strlen(in) > INT_MAX)
7046988a0eSchristos return (0);
7146988a0eSchristos
7246988a0eSchristos *ptr = NULL;
7346988a0eSchristos *len = 0;
7446988a0eSchristos
7546988a0eSchristos bio_b64 = BIO_new(BIO_f_base64());
7646988a0eSchristos if (bio_b64 == NULL)
7746988a0eSchristos goto fail;
7846988a0eSchristos
79eaea677cSchristos bio_mem = BIO_new_mem_buf((const void *) in, -1);
8046988a0eSchristos if (bio_mem == NULL)
8146988a0eSchristos goto fail;
8246988a0eSchristos
8346988a0eSchristos BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
8446988a0eSchristos BIO_push(bio_b64, bio_mem);
8546988a0eSchristos
8646988a0eSchristos alloc_len = strlen(in);
8746988a0eSchristos *ptr = calloc(1, alloc_len);
8846988a0eSchristos if (*ptr == NULL)
8946988a0eSchristos goto fail;
9046988a0eSchristos
9146988a0eSchristos n = BIO_read(bio_b64, *ptr, (int) alloc_len);
9246988a0eSchristos if (n < 0 || BIO_eof(bio_b64) == 0)
9346988a0eSchristos goto fail;
9446988a0eSchristos
9546988a0eSchristos *len = (size_t) n;
9646988a0eSchristos ok = 1;
9746988a0eSchristos
9846988a0eSchristos fail:
9946988a0eSchristos BIO_free(bio_b64);
10046988a0eSchristos BIO_free(bio_mem);
10146988a0eSchristos
10246988a0eSchristos if (!ok) {
10346988a0eSchristos free(*ptr);
10446988a0eSchristos *ptr = NULL;
10546988a0eSchristos *len = 0;
10646988a0eSchristos }
10746988a0eSchristos
10846988a0eSchristos return (ok);
10946988a0eSchristos }
110