Blame lib/x509_b64.c

Packit aea12f
/*
Packit aea12f
 * Copyright (C) 2000-2012 Free Software Foundation, Inc.
Packit aea12f
 * Copyright (C) 2017 Red Hat, Inc.
Packit aea12f
 *
Packit aea12f
 * Author: Nikos Mavrogiannopoulos
Packit aea12f
 *
Packit aea12f
 * This file is part of GnuTLS.
Packit aea12f
 *
Packit aea12f
 * The GnuTLS is free software; you can redistribute it and/or
Packit aea12f
 * modify it under the terms of the GNU Lesser General Public License
Packit aea12f
 * as published by the Free Software Foundation; either version 2.1 of
Packit aea12f
 * the License, or (at your option) any later version.
Packit aea12f
 *
Packit aea12f
 * This library is distributed in the hope that it will be useful, but
Packit aea12f
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit aea12f
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit aea12f
 * Lesser General Public License for more details.
Packit aea12f
 *
Packit aea12f
 * You should have received a copy of the GNU Lesser General Public License
Packit aea12f
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
Packit aea12f
 *
Packit aea12f
 */
Packit aea12f
Packit aea12f
/* Functions that relate to base64 encoding and decoding.
Packit aea12f
 */
Packit aea12f
Packit aea12f
#include "gnutls_int.h"
Packit aea12f
#include "errors.h"
Packit aea12f
#include <datum.h>
Packit aea12f
#include <x509_b64.h>
Packit aea12f
#include <nettle/base64.h>
Packit aea12f
Packit aea12f
#define INCR(what, size, max_len) \
Packit aea12f
	do { \
Packit aea12f
	what+=size; \
Packit aea12f
	if (what > max_len) { \
Packit aea12f
		gnutls_assert(); \
Packit aea12f
		gnutls_free( result->data); result->data = NULL; \
Packit aea12f
		return GNUTLS_E_INTERNAL_ERROR; \
Packit aea12f
	} \
Packit aea12f
	} while(0)
Packit aea12f
Packit aea12f
/* encodes data and puts the result into result (locally allocated)
Packit aea12f
 * The result_size (including the null terminator) is the return value.
Packit aea12f
 */
Packit aea12f
int
Packit aea12f
_gnutls_fbase64_encode(const char *msg, const uint8_t * data,
Packit aea12f
		       size_t data_size, gnutls_datum_t * result)
Packit aea12f
{
Packit aea12f
	int tmp;
Packit aea12f
	unsigned int i;
Packit aea12f
	uint8_t tmpres[66];
Packit aea12f
	uint8_t *ptr;
Packit aea12f
	char top[80];
Packit aea12f
	char bottom[80];
Packit aea12f
	size_t size, max, bytes;
Packit aea12f
	int pos, top_len = 0, bottom_len = 0;
Packit aea12f
	unsigned raw_encoding = 0;
Packit aea12f
Packit aea12f
	if (msg == NULL || msg[0] == 0)
Packit aea12f
		raw_encoding = 1;
Packit aea12f
Packit aea12f
	if (!raw_encoding) {
Packit aea12f
		if (strlen(msg) > 50) {
Packit aea12f
			gnutls_assert();
Packit aea12f
			return GNUTLS_E_BASE64_ENCODING_ERROR;
Packit aea12f
		}
Packit aea12f
Packit aea12f
		_gnutls_str_cpy(top, sizeof(top), "-----BEGIN ");
Packit aea12f
		_gnutls_str_cat(top, sizeof(top), msg);
Packit aea12f
		_gnutls_str_cat(top, sizeof(top), "-----\n");
Packit aea12f
Packit aea12f
		_gnutls_str_cpy(bottom, sizeof(bottom), "-----END ");
Packit aea12f
		_gnutls_str_cat(bottom, sizeof(bottom), msg);
Packit aea12f
		_gnutls_str_cat(bottom, sizeof(bottom), "-----\n");
Packit aea12f
Packit aea12f
		top_len = strlen(top);
Packit aea12f
		bottom_len = strlen(bottom);
Packit aea12f
	}
Packit aea12f
Packit aea12f
	max = B64FSIZE(top_len + bottom_len, data_size);
Packit aea12f
Packit aea12f
	result->data = gnutls_malloc(max + 1);
Packit aea12f
	if (result->data == NULL) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return GNUTLS_E_MEMORY_ERROR;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	bytes = pos = 0;
Packit aea12f
	INCR(bytes, top_len, max);
Packit aea12f
	pos = top_len;
Packit aea12f
Packit aea12f
	memcpy(result->data, top, top_len);
Packit aea12f
Packit aea12f
	for (i = 0; i < data_size; i += 48) {
Packit aea12f
		if (data_size - i < 48)
Packit aea12f
			tmp = data_size - i;
Packit aea12f
		else
Packit aea12f
			tmp = 48;
Packit aea12f
Packit aea12f
		size = BASE64_ENCODE_RAW_LENGTH(tmp);
Packit aea12f
		if (sizeof(tmpres) < size)
Packit aea12f
			return gnutls_assert_val(GNUTLS_E_BASE64_ENCODING_ERROR);
Packit aea12f
Packit aea12f
		base64_encode_raw((void*)tmpres, tmp, &data[i]);
Packit aea12f
Packit aea12f
		INCR(bytes, size + 1, max);
Packit aea12f
		ptr = &result->data[pos];
Packit aea12f
Packit aea12f
		memcpy(ptr, tmpres, size);
Packit aea12f
		ptr += size;
Packit aea12f
		pos += size;
Packit aea12f
		if (!raw_encoding) {
Packit aea12f
			*ptr++ = '\n';
Packit aea12f
			pos++;
Packit aea12f
		} else {
Packit aea12f
			bytes--;
Packit aea12f
		}
Packit aea12f
	}
Packit aea12f
Packit aea12f
	INCR(bytes, bottom_len, max);
Packit aea12f
Packit aea12f
	memcpy(&result->data[bytes - bottom_len], bottom, bottom_len);
Packit aea12f
	result->data[bytes] = 0;
Packit aea12f
	result->size = bytes;
Packit aea12f
Packit aea12f
	return max + 1;
Packit aea12f
}
Packit aea12f
Packit aea12f
/**
Packit aea12f
 * gnutls_pem_base64_encode:
Packit aea12f
 * @msg: is a message to be put in the header (may be %NULL)
Packit aea12f
 * @data: contain the raw data
Packit aea12f
 * @result: the place where base64 data will be copied
Packit aea12f
 * @result_size: holds the size of the result
Packit aea12f
 *
Packit aea12f
 * This function will convert the given data to printable data, using
Packit aea12f
 * the base64 encoding. This is the encoding used in PEM messages.
Packit aea12f
 *
Packit aea12f
 * The output string will be null terminated, although the output size will
Packit aea12f
 * not include the terminating null.
Packit aea12f
 *
Packit aea12f
 * Returns: On success %GNUTLS_E_SUCCESS (0) is returned,
Packit aea12f
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER is returned if the buffer given is
Packit aea12f
 *   not long enough, or 0 on success.
Packit aea12f
 **/
Packit aea12f
int
Packit aea12f
gnutls_pem_base64_encode(const char *msg, const gnutls_datum_t * data,
Packit aea12f
			 char *result, size_t * result_size)
Packit aea12f
{
Packit aea12f
	gnutls_datum_t res;
Packit aea12f
	int ret;
Packit aea12f
Packit aea12f
	ret = _gnutls_fbase64_encode(msg, data->data, data->size, &res;;
Packit aea12f
	if (ret < 0)
Packit aea12f
		return ret;
Packit aea12f
Packit aea12f
	if (result == NULL || *result_size < (unsigned) res.size) {
Packit aea12f
		gnutls_free(res.data);
Packit aea12f
		*result_size = res.size + 1;
Packit aea12f
		return GNUTLS_E_SHORT_MEMORY_BUFFER;
Packit aea12f
	} else {
Packit aea12f
		memcpy(result, res.data, res.size);
Packit aea12f
		gnutls_free(res.data);
Packit aea12f
		*result_size = res.size;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	return 0;
Packit aea12f
}
Packit aea12f
Packit aea12f
/**
Packit aea12f
 * gnutls_pem_base64_encode2:
Packit aea12f
 * @header: is a message to be put in the encoded header (may be %NULL)
Packit aea12f
 * @data: contains the raw data
Packit aea12f
 * @result: will hold the newly allocated encoded data
Packit aea12f
 *
Packit aea12f
 * This function will convert the given data to printable data, using
Packit aea12f
 * the base64 encoding.  This is the encoding used in PEM messages.
Packit aea12f
 * This function will allocate the required memory to hold the encoded
Packit aea12f
 * data.
Packit aea12f
 *
Packit aea12f
 * You should use gnutls_free() to free the returned data.
Packit aea12f
 *
Packit aea12f
 * Note, that prior to GnuTLS 3.4.0 this function was available
Packit aea12f
 * under the name gnutls_pem_base64_encode_alloc(). There is
Packit aea12f
 * compatibility macro pointing to this function.
Packit aea12f
 *
Packit aea12f
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
Packit aea12f
 *   an error code is returned.
Packit aea12f
 *
Packit aea12f
 * Since: 3.4.0
Packit aea12f
 **/
Packit aea12f
int
Packit aea12f
gnutls_pem_base64_encode2(const char *header,
Packit aea12f
			       const gnutls_datum_t * data,
Packit aea12f
			       gnutls_datum_t * result)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
Packit aea12f
	if (result == NULL)
Packit aea12f
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit aea12f
Packit aea12f
	ret = _gnutls_fbase64_encode(header, data->data, data->size, result);
Packit aea12f
	if (ret < 0)
Packit aea12f
		return gnutls_assert_val(ret);
Packit aea12f
Packit aea12f
	return 0;
Packit aea12f
}
Packit aea12f
Packit aea12f
/* copies data to result but removes newlines and <CR>
Packit aea12f
 * returns the size of the data copied.
Packit aea12f
 *
Packit aea12f
 * It will fail with GNUTLS_E_BASE64_DECODING_ERROR if the
Packit aea12f
 * end-result is the empty string.
Packit aea12f
 */
Packit aea12f
inline static int
Packit aea12f
cpydata(const uint8_t * data, int data_size, gnutls_datum_t * result)
Packit aea12f
{
Packit aea12f
	int i, j;
Packit aea12f
Packit aea12f
	result->data = gnutls_malloc(data_size + 1);
Packit aea12f
	if (result->data == NULL)
Packit aea12f
		return GNUTLS_E_MEMORY_ERROR;
Packit aea12f
Packit aea12f
	for (j = i = 0; i < data_size; i++) {
Packit aea12f
		if (data[i] == '\n' || data[i] == '\r' || data[i] == ' '
Packit aea12f
		    || data[i] == '\t')
Packit aea12f
			continue;
Packit aea12f
		else if (data[i] == '-')
Packit aea12f
			break;
Packit aea12f
		result->data[j] = data[i];
Packit aea12f
		j++;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	result->size = j;
Packit aea12f
	result->data[j] = 0;
Packit aea12f
Packit aea12f
	if (j==0) {
Packit aea12f
		gnutls_free(result->data);
Packit aea12f
		return gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR);
Packit aea12f
	}
Packit aea12f
Packit aea12f
	return j;
Packit aea12f
}
Packit aea12f
Packit aea12f
/* decodes data and puts the result into result (locally allocated).
Packit aea12f
 * Note that encodings of zero-length strings are being rejected
Packit aea12f
 * with GNUTLS_E_BASE64_DECODING_ERROR.
Packit aea12f
 *
Packit aea12f
 * The result_size is the return value.
Packit aea12f
 */
Packit aea12f
int
Packit aea12f
_gnutls_base64_decode(const uint8_t * data, size_t data_size,
Packit aea12f
		      gnutls_datum_t * result)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
	size_t size;
Packit aea12f
	gnutls_datum_t pdata;
Packit aea12f
	struct base64_decode_ctx ctx;
Packit aea12f
Packit Service 991b93
	if (data_size == 0) {
Packit Service 991b93
		result->data = (unsigned char*)gnutls_strdup("");
Packit Service 991b93
		if (result->data == NULL)
Packit Service 991b93
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
Packit Service 991b93
		result->size = 0;
Packit Service 991b93
		return 0;
Packit Service 991b93
	}
Packit aea12f
Packit aea12f
	ret = cpydata(data, data_size, &pdata);
Packit aea12f
	if (ret < 0) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return ret;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	base64_decode_init(&ctx;;
Packit aea12f
Packit aea12f
	size = BASE64_DECODE_LENGTH(pdata.size);
Packit aea12f
	if (size == 0) {
Packit aea12f
		ret = gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR);
Packit aea12f
		goto cleanup;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	result->data = gnutls_malloc(size);
Packit aea12f
	if (result->data == NULL) {
Packit aea12f
		ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
Packit aea12f
		goto cleanup;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	ret = base64_decode_update(&ctx, &size, result->data,
Packit aea12f
				   pdata.size, (void*)pdata.data);
Packit aea12f
	if (ret == 0 || size == 0) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		ret = GNUTLS_E_BASE64_DECODING_ERROR;
Packit aea12f
		goto fail;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	ret = base64_decode_final(&ctx;;
Packit aea12f
	if (ret != 1) {
Packit aea12f
		ret = gnutls_assert_val(GNUTLS_E_BASE64_DECODING_ERROR);
Packit aea12f
		goto fail;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	result->size = size;
Packit aea12f
Packit aea12f
	ret = size;
Packit aea12f
	goto cleanup;
Packit aea12f
Packit aea12f
 fail:
Packit aea12f
	gnutls_free(result->data);
Packit aea12f
Packit aea12f
 cleanup:
Packit aea12f
	gnutls_free(pdata.data);
Packit aea12f
	return ret;
Packit aea12f
}
Packit aea12f
Packit aea12f
Packit aea12f
/* Searches the given string for ONE PEM encoded certificate, and
Packit aea12f
 * stores it in the result.
Packit aea12f
 *
Packit aea12f
 * The result_size (always non-zero) is the return value,
Packit aea12f
 * or a negative error code.
Packit aea12f
 */
Packit aea12f
#define ENDSTR "-----"
Packit aea12f
int
Packit aea12f
_gnutls_fbase64_decode(const char *header, const uint8_t * data,
Packit aea12f
		       size_t data_size, gnutls_datum_t * result)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
	static const char top[] = "-----BEGIN ";
Packit aea12f
	static const char bottom[] = "-----END ";
Packit aea12f
	uint8_t *rdata, *kdata;
Packit aea12f
	int rdata_size;
Packit aea12f
	char pem_header[128];
Packit aea12f
Packit aea12f
	_gnutls_str_cpy(pem_header, sizeof(pem_header), top);
Packit aea12f
	if (header != NULL)
Packit aea12f
		_gnutls_str_cat(pem_header, sizeof(pem_header), header);
Packit aea12f
Packit aea12f
	rdata = memmem(data, data_size, pem_header, strlen(pem_header));
Packit aea12f
	if (rdata == NULL) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		_gnutls_hard_log("Could not find '%s'\n", pem_header);
Packit aea12f
		return GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	data_size -= MEMSUB(rdata, data);
Packit aea12f
Packit aea12f
	if (data_size < 4 + strlen(bottom)) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return GNUTLS_E_BASE64_DECODING_ERROR;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	kdata =
Packit aea12f
	    memmem(rdata + 1, data_size - 1, ENDSTR, sizeof(ENDSTR) - 1);
Packit aea12f
	/* allow CR as well.
Packit aea12f
	 */
Packit aea12f
	if (kdata == NULL) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		_gnutls_hard_log("Could not find '%s'\n", ENDSTR);
Packit aea12f
		return GNUTLS_E_BASE64_DECODING_ERROR;
Packit aea12f
	}
Packit aea12f
	data_size -= strlen(ENDSTR);
Packit aea12f
	data_size -= MEMSUB(kdata, rdata);
Packit aea12f
Packit aea12f
	rdata = kdata + strlen(ENDSTR);
Packit aea12f
Packit aea12f
	/* position is now after the ---BEGIN--- headers */
Packit aea12f
Packit aea12f
	kdata = memmem(rdata, data_size, bottom, strlen(bottom));
Packit aea12f
	if (kdata == NULL) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return GNUTLS_E_BASE64_DECODING_ERROR;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	/* position of kdata is before the ----END--- footer 
Packit aea12f
	 */
Packit aea12f
	rdata_size = MEMSUB(kdata, rdata);
Packit aea12f
Packit aea12f
	if (rdata_size < 4) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return GNUTLS_E_BASE64_DECODING_ERROR;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	if ((ret = _gnutls_base64_decode(rdata, rdata_size, result)) < 0) {
Packit aea12f
		gnutls_assert();
Packit aea12f
		return GNUTLS_E_BASE64_DECODING_ERROR;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	return ret;
Packit aea12f
}
Packit aea12f
Packit aea12f
/**
Packit aea12f
 * gnutls_pem_base64_decode:
Packit aea12f
 * @header: A null terminated string with the PEM header (eg. CERTIFICATE)
Packit aea12f
 * @b64_data: contain the encoded data
Packit aea12f
 * @result: the place where decoded data will be copied
Packit aea12f
 * @result_size: holds the size of the result
Packit aea12f
 *
Packit aea12f
 * This function will decode the given encoded data.  If the header
Packit aea12f
 * given is non %NULL this function will search for "-----BEGIN header"
Packit aea12f
 * and decode only this part.  Otherwise it will decode the first PEM
Packit aea12f
 * packet found.
Packit aea12f
 *
Packit aea12f
 * Returns: On success %GNUTLS_E_SUCCESS (0) is returned,
Packit aea12f
 *   %GNUTLS_E_SHORT_MEMORY_BUFFER is returned if the buffer given is
Packit aea12f
 *   not long enough, or 0 on success.
Packit aea12f
 **/
Packit aea12f
int
Packit aea12f
gnutls_pem_base64_decode(const char *header,
Packit aea12f
			 const gnutls_datum_t * b64_data,
Packit aea12f
			 unsigned char *result, size_t * result_size)
Packit aea12f
{
Packit aea12f
	gnutls_datum_t res;
Packit aea12f
	int ret;
Packit aea12f
Packit aea12f
	ret =
Packit aea12f
	    _gnutls_fbase64_decode(header, b64_data->data, b64_data->size,
Packit aea12f
				   &res;;
Packit aea12f
	if (ret < 0)
Packit aea12f
		return gnutls_assert_val(ret);
Packit aea12f
Packit aea12f
	if (result == NULL || *result_size < (unsigned) res.size) {
Packit aea12f
		gnutls_free(res.data);
Packit aea12f
		*result_size = res.size;
Packit aea12f
		return GNUTLS_E_SHORT_MEMORY_BUFFER;
Packit aea12f
	} else {
Packit aea12f
		memcpy(result, res.data, res.size);
Packit aea12f
		gnutls_free(res.data);
Packit aea12f
		*result_size = res.size;
Packit aea12f
	}
Packit aea12f
Packit aea12f
	return 0;
Packit aea12f
}
Packit aea12f
Packit aea12f
/**
Packit aea12f
 * gnutls_pem_base64_decode2:
Packit aea12f
 * @header: The PEM header (eg. CERTIFICATE)
Packit aea12f
 * @b64_data: contains the encoded data
Packit aea12f
 * @result: the location of decoded data
Packit aea12f
 *
Packit aea12f
 * This function will decode the given encoded data. The decoded data
Packit aea12f
 * will be allocated, and stored into result.  If the header given is
Packit aea12f
 * non null this function will search for "-----BEGIN header" and
Packit aea12f
 * decode only this part. Otherwise it will decode the first PEM
Packit aea12f
 * packet found.
Packit aea12f
 *
Packit aea12f
 * You should use gnutls_free() to free the returned data.
Packit aea12f
 *
Packit aea12f
 * Note, that prior to GnuTLS 3.4.0 this function was available
Packit aea12f
 * under the name gnutls_pem_base64_decode_alloc(). There is
Packit aea12f
 * compatibility macro pointing to this function.
Packit aea12f
 *
Packit aea12f
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
Packit aea12f
 *   an error code is returned.
Packit aea12f
 *
Packit aea12f
 * Since: 3.4.0
Packit aea12f
 **/
Packit aea12f
int
Packit aea12f
gnutls_pem_base64_decode2(const char *header,
Packit aea12f
			       const gnutls_datum_t * b64_data,
Packit aea12f
			       gnutls_datum_t * result)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
Packit aea12f
	if (result == NULL)
Packit aea12f
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit aea12f
Packit aea12f
	ret =
Packit aea12f
	    _gnutls_fbase64_decode(header, b64_data->data, b64_data->size,
Packit aea12f
				   result);
Packit aea12f
	if (ret < 0)
Packit aea12f
		return gnutls_assert_val(ret);
Packit aea12f
Packit aea12f
	return 0;
Packit aea12f
}
Packit aea12f
Packit aea12f
/**
Packit aea12f
 * gnutls_base64_decode2:
Packit aea12f
 * @base64: contains the encoded data
Packit aea12f
 * @result: the location of decoded data
Packit aea12f
 *
Packit aea12f
 * This function will decode the given base64 encoded data. The decoded data
Packit aea12f
 * will be allocated, and stored into result.
Packit aea12f
 *
Packit aea12f
 * You should use gnutls_free() to free the returned data.
Packit aea12f
 *
Packit aea12f
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
Packit aea12f
 *   an error code is returned.
Packit aea12f
 *
Packit aea12f
 * Since: 3.6.0
Packit aea12f
 **/
Packit aea12f
int
Packit aea12f
gnutls_base64_decode2(const gnutls_datum_t *base64,
Packit aea12f
		      gnutls_datum_t *result)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
Packit aea12f
	ret = _gnutls_base64_decode(base64->data, base64->size, result);
Packit aea12f
	if (ret < 0) {
Packit aea12f
		return gnutls_assert_val(ret);
Packit aea12f
	}
Packit aea12f
Packit aea12f
	return 0;
Packit aea12f
}
Packit aea12f
Packit aea12f
/**
Packit aea12f
 * gnutls_base64_encode2:
Packit aea12f
 * @data: contains the raw data
Packit aea12f
 * @result: will hold the newly allocated encoded data
Packit aea12f
 *
Packit aea12f
 * This function will convert the given data to printable data, using
Packit aea12f
 * the base64 encoding. This function will allocate the required
Packit aea12f
 * memory to hold the encoded data.
Packit aea12f
 *
Packit aea12f
 * You should use gnutls_free() to free the returned data.
Packit aea12f
 *
Packit aea12f
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise
Packit aea12f
 *   an error code is returned.
Packit aea12f
 *
Packit aea12f
 * Since: 3.6.0
Packit aea12f
 **/
Packit aea12f
int
Packit aea12f
gnutls_base64_encode2(const gnutls_datum_t *data,
Packit aea12f
		      gnutls_datum_t *result)
Packit aea12f
{
Packit aea12f
	int ret;
Packit aea12f
Packit aea12f
	if (result == NULL)
Packit aea12f
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
Packit aea12f
Packit aea12f
	ret = _gnutls_fbase64_encode(NULL, data->data, data->size, result);
Packit aea12f
	if (ret < 0)
Packit aea12f
		return gnutls_assert_val(ret);
Packit aea12f
Packit aea12f
	return 0;
Packit aea12f
}