|
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 |
}
|