|
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 |
/* Here lie everything that has to do with large numbers, libgcrypt and
|
|
Packit |
aea12f |
* other stuff that didn't fit anywhere else.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include "gnutls_int.h"
|
|
Packit |
aea12f |
#include <libtasn1.h>
|
|
Packit |
aea12f |
#include "errors.h"
|
|
Packit |
aea12f |
#include <num.h>
|
|
Packit |
aea12f |
#include <mpi.h>
|
|
Packit |
aea12f |
#include <random.h>
|
|
Packit |
aea12f |
#include <x509/x509_int.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Functions that refer to the mpi library.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Returns a random number r, 0 < r < p */
|
|
Packit |
aea12f |
bigint_t
|
|
Packit |
aea12f |
_gnutls_mpi_random_modp(bigint_t r, bigint_t p,
|
|
Packit |
aea12f |
gnutls_rnd_level_t level)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
size_t size;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
bigint_t tmp;
|
|
Packit |
aea12f |
uint8_t tmpbuf[512];
|
|
Packit |
aea12f |
uint8_t *buf;
|
|
Packit |
aea12f |
int buf_release = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
size = ((_gnutls_mpi_get_nbits(p)+64)/8) + 1;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (size < sizeof(tmpbuf)) {
|
|
Packit |
aea12f |
buf = tmpbuf;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
buf = gnutls_malloc(size);
|
|
Packit |
aea12f |
if (buf == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
buf_release = 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_rnd(level, buf, size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_init_scan(&tmp, buf, size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_modm(tmp, tmp, p);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (_gnutls_mpi_cmp_ui(tmp, 0) == 0) {
|
|
Packit |
aea12f |
ret = _gnutls_mpi_add_ui(tmp, tmp, 1);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (buf_release != 0) {
|
|
Packit |
aea12f |
gnutls_free(buf);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (r != NULL) {
|
|
Packit |
aea12f |
ret = _gnutls_mpi_set(r, tmp);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_mpi_release(&tmp);
|
|
Packit |
aea12f |
return r;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return tmp;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
cleanup:
|
|
Packit |
aea12f |
if (buf_release != 0)
|
|
Packit |
aea12f |
gnutls_free(buf);
|
|
Packit |
aea12f |
return NULL;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* returns %GNUTLS_E_SUCCESS (0) on success
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int _gnutls_mpi_init_scan(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
bigint_t r;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_init(&r);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
_gnutls_mpi_scan(r, buffer, nbytes);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
_gnutls_mpi_release(&r);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*ret_mpi = r;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* returns %GNUTLS_E_SUCCESS (0) on success. Fails if the number is zero.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_init_scan(ret_mpi, buffer, nbytes);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* MPIs with 0 bits are illegal
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (_gnutls_mpi_cmp_ui(*ret_mpi, 0) == 0) {
|
|
Packit |
aea12f |
_gnutls_mpi_release(ret_mpi);
|
|
Packit |
aea12f |
return GNUTLS_E_MPI_SCAN_FAILED;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_mpi_init_scan_le(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
bigint_t r;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_init(&r);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_scan_le(r, buffer, nbytes);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
_gnutls_mpi_release(&r);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*ret_mpi = r;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int _gnutls_mpi_dprint_le(const bigint_t a, gnutls_datum_t * dest)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
uint8_t *buf = NULL;
|
|
Packit |
aea12f |
size_t bytes = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (dest == NULL || a == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_mpi_print_le(a, NULL, &bytes);
|
|
Packit |
aea12f |
if (bytes != 0)
|
|
Packit |
aea12f |
buf = gnutls_malloc(bytes);
|
|
Packit |
aea12f |
if (buf == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_print_le(a, buf, &bytes);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_free(buf);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
dest->data = buf;
|
|
Packit |
aea12f |
dest->size = bytes;
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Always has the first bit zero */
|
|
Packit |
aea12f |
int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
uint8_t *buf = NULL;
|
|
Packit |
aea12f |
size_t bytes = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (dest == NULL || a == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_mpi_print_lz(a, NULL, &bytes);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (bytes != 0)
|
|
Packit |
aea12f |
buf = gnutls_malloc(bytes);
|
|
Packit |
aea12f |
if (buf == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_print_lz(a, buf, &bytes);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_free(buf);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
dest->data = buf;
|
|
Packit |
aea12f |
dest->size = bytes;
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int _gnutls_mpi_dprint(const bigint_t a, gnutls_datum_t * dest)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
uint8_t *buf = NULL;
|
|
Packit |
aea12f |
size_t bytes = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (dest == NULL || a == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_mpi_print(a, NULL, &bytes);
|
|
Packit |
aea12f |
if (bytes != 0)
|
|
Packit |
aea12f |
buf = gnutls_malloc(bytes);
|
|
Packit |
aea12f |
if (buf == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_mpi_print(a, buf, &bytes);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_free(buf);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
dest->data = buf;
|
|
Packit |
aea12f |
dest->size = bytes;
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* This function will copy the mpi data into a datum,
|
|
Packit |
aea12f |
* but will set minimum size to 'size'. That means that
|
|
Packit |
aea12f |
* the output value is left padded with zeros.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest,
|
|
Packit |
aea12f |
size_t size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
uint8_t *buf = NULL;
|
|
Packit |
aea12f |
size_t bytes = 0;
|
|
Packit |
aea12f |
unsigned int i;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (dest == NULL || a == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_mpi_print(a, NULL, &bytes);
|
|
Packit |
aea12f |
if (bytes != 0)
|
|
Packit |
aea12f |
buf = gnutls_malloc(MAX(size, bytes));
|
|
Packit |
aea12f |
if (buf == NULL)
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (bytes <= size) {
|
|
Packit |
aea12f |
size_t diff = size - bytes;
|
|
Packit |
aea12f |
for (i = 0; i < diff; i++)
|
|
Packit |
aea12f |
buf[i] = 0;
|
|
Packit |
aea12f |
ret = _gnutls_mpi_print(a, &buf[diff], &bytes);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
ret = _gnutls_mpi_print(a, buf, &bytes);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_free(buf);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
dest->data = buf;
|
|
Packit |
aea12f |
dest->size = MAX(size, bytes);
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* like _gnutls_mpi_dprint_size, but prints into preallocated byte buffer */
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_mpi_bprint_size(const bigint_t a, uint8_t *buf, size_t size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
size_t bytes = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_mpi_print(a, NULL, &bytes);
|
|
Packit |
aea12f |
if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
|
|
Packit |
aea12f |
return gnutls_assert_val(result);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (bytes <= size) {
|
|
Packit |
aea12f |
unsigned i;
|
|
Packit |
aea12f |
size_t diff = size - bytes;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
for (i = 0; i < diff; i++)
|
|
Packit |
aea12f |
buf[i] = 0;
|
|
Packit |
aea12f |
result = _gnutls_mpi_print(a, &buf[diff], &bytes);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result = _gnutls_mpi_print(a, buf, &bytes);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Flags for __gnutls_x509_read_int() and __gnutls_x509_write_int */
|
|
Packit |
aea12f |
#define GNUTLS_X509_INT_OVERWRITE (1 << 0)
|
|
Packit |
aea12f |
#define GNUTLS_X509_INT_LE (1 << 1)
|
|
Packit |
aea12f |
#define GNUTLS_X509_INT_LZ (1 << 2) /* write only */
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* this function reads an integer
|
|
Packit |
aea12f |
* from asn1 structs. Combines the read and mpi_scan
|
|
Packit |
aea12f |
* steps.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static int
|
|
Packit |
aea12f |
__gnutls_x509_read_int(ASN1_TYPE node, const char *value,
|
|
Packit |
aea12f |
bigint_t * ret_mpi, unsigned int flags)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
uint8_t *tmpstr = NULL;
|
|
Packit |
aea12f |
int tmpstr_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmpstr_size = 0;
|
|
Packit |
aea12f |
result = asn1_read_value(node, value, NULL, &tmpstr_size);
|
|
Packit |
aea12f |
if (result != ASN1_MEM_ERROR) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmpstr = gnutls_malloc(tmpstr_size);
|
|
Packit |
aea12f |
if (tmpstr == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = asn1_read_value(node, value, tmpstr, &tmpstr_size);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
gnutls_free(tmpstr);
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (flags & GNUTLS_X509_INT_LE)
|
|
Packit |
aea12f |
result = _gnutls_mpi_init_scan_le(ret_mpi, tmpstr,
|
|
Packit |
aea12f |
tmpstr_size);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
result = _gnutls_mpi_init_scan(ret_mpi, tmpstr,
|
|
Packit |
aea12f |
tmpstr_size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (flags & GNUTLS_X509_INT_OVERWRITE)
|
|
Packit |
aea12f |
zeroize_key(tmpstr, tmpstr_size);
|
|
Packit |
aea12f |
gnutls_free(tmpstr);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_read_int(ASN1_TYPE node, const char *value,
|
|
Packit |
aea12f |
bigint_t * ret_mpi)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return __gnutls_x509_read_int(node, value, ret_mpi,
|
|
Packit |
aea12f |
0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_read_key_int(ASN1_TYPE node, const char *value,
|
|
Packit |
aea12f |
bigint_t * ret_mpi)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return __gnutls_x509_read_int(node, value, ret_mpi,
|
|
Packit |
aea12f |
GNUTLS_X509_INT_OVERWRITE);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_read_key_int_le(ASN1_TYPE node, const char *value,
|
|
Packit |
aea12f |
bigint_t * ret_mpi)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return __gnutls_x509_read_int(node, value, ret_mpi,
|
|
Packit |
aea12f |
GNUTLS_X509_INT_OVERWRITE |
|
|
Packit |
aea12f |
GNUTLS_X509_INT_LE);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Writes the specified integer into the specified node.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
static int
|
|
Packit |
aea12f |
__gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi,
|
|
Packit |
aea12f |
unsigned int flags)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
uint8_t *tmpstr;
|
|
Packit |
aea12f |
size_t s_len;
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
s_len = 0;
|
|
Packit |
aea12f |
if (flags & GNUTLS_X509_INT_LZ)
|
|
Packit |
aea12f |
result = _gnutls_mpi_print_lz(mpi, NULL, &s_len);
|
|
Packit |
aea12f |
else if (GNUTLS_X509_INT_LE)
|
|
Packit |
aea12f |
result = _gnutls_mpi_print_le(mpi, NULL, &s_len);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
result = _gnutls_mpi_print(mpi, NULL, &s_len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmpstr = gnutls_malloc(s_len);
|
|
Packit |
aea12f |
if (tmpstr == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (flags & GNUTLS_X509_INT_LZ)
|
|
Packit |
aea12f |
result = _gnutls_mpi_print_lz(mpi, tmpstr, &s_len);
|
|
Packit |
aea12f |
else if (GNUTLS_X509_INT_LE)
|
|
Packit |
aea12f |
result = _gnutls_mpi_print_le(mpi, tmpstr, &s_len);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
result = _gnutls_mpi_print(mpi, tmpstr, &s_len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
gnutls_free(tmpstr);
|
|
Packit |
aea12f |
return GNUTLS_E_MPI_PRINT_FAILED;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = asn1_write_value(node, value, tmpstr, s_len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (flags & GNUTLS_X509_INT_OVERWRITE)
|
|
Packit |
aea12f |
zeroize_key(tmpstr, s_len);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(tmpstr);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_write_int(ASN1_TYPE node, const char *value, bigint_t mpi,
|
|
Packit |
aea12f |
int lz)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return __gnutls_x509_write_int(node, value, mpi,
|
|
Packit |
aea12f |
lz ? GNUTLS_X509_INT_LZ : 0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_write_key_int(ASN1_TYPE node, const char *value, bigint_t mpi,
|
|
Packit |
aea12f |
int lz)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return __gnutls_x509_write_int(node, value, mpi,
|
|
Packit |
aea12f |
(lz ? GNUTLS_X509_INT_LZ : 0) |
|
|
Packit |
aea12f |
GNUTLS_X509_INT_OVERWRITE);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_write_key_int_le(ASN1_TYPE node, const char *value, bigint_t mpi)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return __gnutls_x509_write_int(node, value, mpi,
|
|
Packit |
aea12f |
GNUTLS_X509_INT_OVERWRITE |
|
|
Packit |
aea12f |
GNUTLS_X509_INT_LE);
|
|
Packit |
aea12f |
}
|