|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* Copyright (C) 2001-2012 Free Software Foundation, 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 |
#include "gnutls_int.h"
|
|
Packit |
aea12f |
#include "errors.h"
|
|
Packit |
aea12f |
#include <datum.h>
|
|
Packit |
aea12f |
#include <auth/srp_passwd.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#ifdef ENABLE_SRP
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* this is a modified base64 for srp !!!
|
|
Packit |
aea12f |
* It seems that everybody makes their own base64 conversion.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static const uint8_t b64table[] =
|
|
Packit |
aea12f |
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static const uint8_t asciitable[128] = {
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0x3e, 0x3f,
|
|
Packit |
aea12f |
0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
|
Packit |
aea12f |
0x06, 0x07, 0x08, 0x09, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff, 0xff, 0xff, 0xff, 0x0a,
|
|
Packit |
aea12f |
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
|
Packit |
aea12f |
0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
|
Packit |
aea12f |
0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
|
|
Packit |
aea12f |
0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22,
|
|
Packit |
aea12f |
0x23, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0x24, 0x25, 0x26, 0x27, 0x28,
|
|
Packit |
aea12f |
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
|
|
Packit |
aea12f |
0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
|
Packit |
aea12f |
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,
|
|
Packit |
aea12f |
0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff,
|
|
Packit |
aea12f |
0xff, 0xff
|
|
Packit |
aea12f |
};
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
inline static int encode(uint8_t * result, const uint8_t * rdata, unsigned left)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int data_len;
|
|
Packit |
aea12f |
int c, ret = 4;
|
|
Packit |
aea12f |
uint8_t data[3];
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (left > 3)
|
|
Packit |
aea12f |
data_len = 3;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
data_len = left;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
data[0] = data[1] = data[2] = 0;
|
|
Packit |
aea12f |
memcpy(data, rdata, data_len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
switch (data_len) {
|
|
Packit |
aea12f |
case 3:
|
|
Packit |
aea12f |
result[0] = b64table[((data[0] & 0xfc) >> 2)];
|
|
Packit |
aea12f |
result[1] =
|
|
Packit |
aea12f |
b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) |
|
|
Packit |
aea12f |
((data[1] & 0xf0) >> 4))];
|
|
Packit |
aea12f |
result[2] =
|
|
Packit |
aea12f |
b64table[((((data[1] & 0x0f) << 2) & 0xff) |
|
|
Packit |
aea12f |
((data[2] & 0xc0) >> 6))];
|
|
Packit |
aea12f |
result[3] = b64table[(data[2] & 0x3f) & 0xff];
|
|
Packit |
aea12f |
break;
|
|
Packit |
aea12f |
case 2:
|
|
Packit |
aea12f |
if ((c = ((data[0] & 0xf0) >> 4)) != 0) {
|
|
Packit |
aea12f |
result[0] = b64table[c];
|
|
Packit |
aea12f |
result[1] =
|
|
Packit |
aea12f |
b64table[((((data[0] & 0x0f) << 2) & 0xff) |
|
|
Packit |
aea12f |
((data[1] & 0xc0) >> 6))];
|
|
Packit |
aea12f |
result[2] = b64table[(data[1] & 0x3f) & 0xff];
|
|
Packit |
aea12f |
result[3] = '\0';
|
|
Packit |
aea12f |
ret -= 1;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
if ((c =
|
|
Packit |
aea12f |
((data[0] & 0x0f) << 2) | ((data[1] & 0xc0) >>
|
|
Packit |
aea12f |
6)) != 0) {
|
|
Packit |
aea12f |
result[0] = b64table[c];
|
|
Packit |
aea12f |
result[1] = b64table[data[1] & 0x3f];
|
|
Packit |
aea12f |
result[2] = '\0';
|
|
Packit |
aea12f |
result[3] = '\0';
|
|
Packit |
aea12f |
ret -= 2;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result[0] = b64table[data[0] & 0x3f];
|
|
Packit |
aea12f |
result[1] = '\0';
|
|
Packit |
aea12f |
result[2] = '\0';
|
|
Packit |
aea12f |
result[3] = '\0';
|
|
Packit |
aea12f |
ret -= 3;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
break;
|
|
Packit |
aea12f |
case 1:
|
|
Packit |
aea12f |
if ((c = ((data[0] & 0xc0) >> 6)) != 0) {
|
|
Packit |
aea12f |
result[0] = b64table[c];
|
|
Packit |
aea12f |
result[1] = b64table[(data[0] & 0x3f) & 0xff];
|
|
Packit |
aea12f |
result[2] = '\0';
|
|
Packit |
aea12f |
result[3] = '\0';
|
|
Packit |
aea12f |
ret -= 2;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result[0] = b64table[(data[0] & 0x3f) & 0xff];
|
|
Packit |
aea12f |
result[1] = '\0';
|
|
Packit |
aea12f |
result[2] = '\0';
|
|
Packit |
aea12f |
result[3] = '\0';
|
|
Packit |
aea12f |
ret -= 3;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
break;
|
|
Packit |
aea12f |
default:
|
|
Packit |
aea12f |
return GNUTLS_E_BASE64_ENCODING_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* encodes data and puts the result into result (locally allocated)
|
|
Packit |
aea12f |
* The result_size is the return value
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static int
|
|
Packit |
aea12f |
_gnutls_sbase64_encode(uint8_t * data, size_t data_size, char **result)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned i, j;
|
|
Packit |
aea12f |
int ret, tmp;
|
|
Packit |
aea12f |
uint8_t tmpres[4];
|
|
Packit |
aea12f |
unsigned mod = data_size % 3;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = mod;
|
|
Packit |
aea12f |
if (ret != 0)
|
|
Packit |
aea12f |
ret = 4;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
ret = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret += (data_size * 4) / 3;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
(*result) = gnutls_calloc(1, ret + 1);
|
|
Packit |
aea12f |
if ((*result) == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
i = j = 0;
|
|
Packit |
aea12f |
/* encode the bytes that are not a multiple of 3
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (mod > 0) {
|
|
Packit |
aea12f |
tmp = encode(tmpres, &data[0], mod);
|
|
Packit |
aea12f |
if (tmp < 0) {
|
|
Packit |
aea12f |
gnutls_free((*result));
|
|
Packit |
aea12f |
return tmp;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
memcpy(&(*result)[0], tmpres, tmp);
|
|
Packit |
aea12f |
i = mod;
|
|
Packit |
aea12f |
j = tmp;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
/* encode the rest
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
for (; i < data_size; i += 3, j += 4) {
|
|
Packit |
aea12f |
tmp = encode(tmpres, &data[i], data_size - i);
|
|
Packit |
aea12f |
if (tmp < 0) {
|
|
Packit |
aea12f |
gnutls_free((*result));
|
|
Packit |
aea12f |
return tmp;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
memcpy(&(*result)[j], tmpres, tmp);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return strlen(*result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* data must be 4 bytes
|
|
Packit |
aea12f |
* result should be 3 bytes
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
#define TOASCII(c) (c < 127 ? asciitable[c] : 0xff)
|
|
Packit |
aea12f |
inline static int decode(uint8_t * result, const uint8_t * data)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
uint8_t a1, a2;
|
|
Packit |
aea12f |
int ret = 3;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
memset(result, 0, 3);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
a1 = TOASCII(data[3]);
|
|
Packit |
aea12f |
a2 = TOASCII(data[2]);
|
|
Packit |
aea12f |
if (a1 != 0xff)
|
|
Packit |
aea12f |
result[2] = a1 & 0xff;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
return GNUTLS_E_BASE64_DECODING_ERROR;
|
|
Packit |
aea12f |
if (a2 != 0xff)
|
|
Packit |
aea12f |
result[2] |= ((a2 & 0x03) << 6) & 0xff;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
a1 = a2;
|
|
Packit |
aea12f |
a2 = TOASCII(data[1]);
|
|
Packit |
aea12f |
if (a1 != 0xff)
|
|
Packit |
aea12f |
result[1] = ((a1 & 0x3c) >> 2);
|
|
Packit |
aea12f |
if (a2 != 0xff)
|
|
Packit |
aea12f |
result[1] |= ((a2 & 0x0f) << 4);
|
|
Packit |
aea12f |
else if (a1 == 0xff || result[1] == 0)
|
|
Packit |
aea12f |
ret--;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
a1 = a2;
|
|
Packit |
aea12f |
a2 = TOASCII(data[0]);
|
|
Packit |
aea12f |
if (a1 != 0xff)
|
|
Packit |
aea12f |
result[0] = (((a1 & 0x30) >> 4) & 0xff);
|
|
Packit |
aea12f |
if (a2 != 0xff)
|
|
Packit |
aea12f |
result[0] |= ((a2 << 2) & 0xff);
|
|
Packit |
aea12f |
else if (a1 == 0xff || result[0] == 0)
|
|
Packit |
aea12f |
ret--;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* decodes data and puts the result into result (locally allocated)
|
|
Packit |
aea12f |
* The result_size is the return value.
|
|
Packit |
aea12f |
* That function does not ignore newlines tabs etc. You should remove them
|
|
Packit |
aea12f |
* before calling it.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_sbase64_decode(char *data, size_t idata_size, uint8_t ** result)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned i, j;
|
|
Packit |
aea12f |
int ret, left;
|
|
Packit |
aea12f |
int data_size, tmp;
|
|
Packit |
aea12f |
uint8_t datrev[4];
|
|
Packit |
aea12f |
uint8_t tmpres[3];
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
data_size = (idata_size / 4) * 4;
|
|
Packit |
aea12f |
left = idata_size % 4;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = (data_size / 4) * 3;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (left > 0)
|
|
Packit |
aea12f |
ret += 3;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
(*result) = gnutls_malloc(ret + 1);
|
|
Packit |
aea12f |
if ((*result) == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* the first "block" is treated with special care */
|
|
Packit |
aea12f |
tmp = 0;
|
|
Packit |
aea12f |
if (left > 0) {
|
|
Packit |
aea12f |
memset(datrev, 0, 4);
|
|
Packit |
aea12f |
memcpy(&datrev[4 - left], data, left);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmp = decode(tmpres, datrev);
|
|
Packit |
aea12f |
if (tmp < 0) {
|
|
Packit |
aea12f |
gnutls_free((*result));
|
|
Packit |
aea12f |
return tmp;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
memcpy(*result, &tmpres[3 - tmp], tmp);
|
|
Packit |
aea12f |
if (tmp < 3)
|
|
Packit |
aea12f |
ret -= (3 - tmp);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* rest data */
|
|
Packit |
aea12f |
for (i = left, j = tmp; i < idata_size; i += 4) {
|
|
Packit |
aea12f |
tmp = decode(tmpres, (uint8_t *) & data[i]);
|
|
Packit |
aea12f |
if (tmp < 0) {
|
|
Packit |
aea12f |
gnutls_free((*result));
|
|
Packit |
aea12f |
return tmp;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
memcpy(&(*result)[j], tmpres, tmp);
|
|
Packit |
aea12f |
if (tmp < 3)
|
|
Packit |
aea12f |
ret -= (3 - tmp);
|
|
Packit |
aea12f |
j += 3;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_srp_base64_encode:
|
|
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, as used in the libsrp. This is the encoding
|
|
Packit |
aea12f |
* used in SRP password files. If the provided buffer is not long
|
|
Packit |
aea12f |
* enough GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Warning! This base64 encoding is not the "standard" encoding, so
|
|
Packit |
aea12f |
* do not use it for non-SRP purposes.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
|
|
Packit |
aea12f |
* long enough, or 0 on success.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_srp_base64_encode(const gnutls_datum_t * data, char *result,
|
|
Packit |
aea12f |
size_t * result_size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char *res;
|
|
Packit |
aea12f |
int size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = _gnutls_sbase64_encode(data->data, data->size, &res;;
|
|
Packit |
aea12f |
if (size < 0)
|
|
Packit |
aea12f |
return size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == NULL || *result_size < (size_t) size) {
|
|
Packit |
aea12f |
gnutls_free(res);
|
|
Packit |
aea12f |
*result_size = size;
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
memcpy(result, res, size);
|
|
Packit |
aea12f |
gnutls_free(res);
|
|
Packit |
aea12f |
*result_size = size;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_srp_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 is the encoding used in SRP password
|
|
Packit |
aea12f |
* files. This function will allocate the required memory to hold
|
|
Packit |
aea12f |
* the encoded data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* You should use gnutls_free() to free the returned data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Warning! This base64 encoding is not the "standard" encoding, so
|
|
Packit |
aea12f |
* do not use it for non-SRP purposes.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: 0 on success, or an error code.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_srp_base64_encode2(const gnutls_datum_t * data,
|
|
Packit |
aea12f |
gnutls_datum_t * result)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char *res;
|
|
Packit |
aea12f |
int size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = _gnutls_sbase64_encode(data->data, data->size, &res;;
|
|
Packit |
aea12f |
if (size < 0)
|
|
Packit |
aea12f |
return size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == NULL) {
|
|
Packit |
aea12f |
gnutls_free(res);
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result->data = (uint8_t *) res;
|
|
Packit |
aea12f |
result->size = size;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_srp_base64_decode:
|
|
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, using the base64
|
|
Packit |
aea12f |
* encoding found in libsrp.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Note that @b64_data should be null terminated.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Warning! This base64 encoding is not the "standard" encoding, so
|
|
Packit |
aea12f |
* do not use it for non-SRP purposes.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not
|
|
Packit |
aea12f |
* long enough, or 0 on success.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_srp_base64_decode(const gnutls_datum_t * b64_data, char *result,
|
|
Packit |
aea12f |
size_t * result_size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
uint8_t *res;
|
|
Packit |
aea12f |
int size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size =
|
|
Packit |
aea12f |
_gnutls_sbase64_decode((char *) b64_data->data, b64_data->size,
|
|
Packit |
aea12f |
&res;;
|
|
Packit |
aea12f |
if (size < 0)
|
|
Packit |
aea12f |
return size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == NULL || *result_size < (size_t) size) {
|
|
Packit |
aea12f |
gnutls_free(res);
|
|
Packit |
aea12f |
*result_size = size;
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
memcpy(result, res, size);
|
|
Packit |
aea12f |
gnutls_free(res);
|
|
Packit |
aea12f |
*result_size = size;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_srp_base64_decode2:
|
|
Packit |
aea12f |
* @b64_data: contains the encoded data
|
|
Packit |
aea12f |
* @result: the place where decoded data lie
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will decode the given encoded data. The decoded data
|
|
Packit |
aea12f |
* will be allocated, and stored into result. It will decode using
|
|
Packit |
aea12f |
* the base64 algorithm as used in libsrp.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* You should use gnutls_free() to free the returned data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Warning! This base64 encoding is not the "standard" encoding, so
|
|
Packit |
aea12f |
* do not use it for non-SRP purposes.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: 0 on success, or an error code.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_srp_base64_decode2(const gnutls_datum_t * b64_data,
|
|
Packit |
aea12f |
gnutls_datum_t * result)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
uint8_t *ret;
|
|
Packit |
aea12f |
int size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size =
|
|
Packit |
aea12f |
_gnutls_sbase64_decode((char *) b64_data->data, b64_data->size,
|
|
Packit |
aea12f |
&ret;;
|
|
Packit |
aea12f |
if (size < 0)
|
|
Packit |
aea12f |
return size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == NULL) {
|
|
Packit |
aea12f |
gnutls_free(ret);
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result->data = ret;
|
|
Packit |
aea12f |
result->size = size;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#endif /* ENABLE_SRP */
|