|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* Copyright (C) 2003-2012 Free Software Foundation, Inc.
|
|
Packit |
aea12f |
* Copyright (C) 2015-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 |
#include "gnutls_int.h"
|
|
Packit |
aea12f |
#include "errors.h"
|
|
Packit |
aea12f |
#include <global.h>
|
|
Packit |
aea12f |
#include <libtasn1.h>
|
|
Packit |
aea12f |
#include <datum.h>
|
|
Packit |
aea12f |
#include "common.h"
|
|
Packit |
aea12f |
#include "x509_int.h"
|
|
Packit |
aea12f |
#include <num.h>
|
|
Packit |
aea12f |
#include <limits.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Reads an Integer from the DER encoded data
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int _gnutls_x509_read_der_int(uint8_t * der, int dersize, bigint_t * out)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
ASN1_TYPE spk = ASN1_TYPE_EMPTY;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* == INTEGER */
|
|
Packit |
aea12f |
if ((result = asn1_create_element
|
|
Packit |
aea12f |
(_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
|
|
Packit |
aea12f |
&spk)) != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
asn1_delete_structure(&spk;;
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Read Y */
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((result = _gnutls_x509_read_int(spk, "", out)) < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
asn1_delete_structure(&spk;;
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
asn1_delete_structure(&spk;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int _gnutls_x509_read_der_uint(uint8_t * der, int dersize, unsigned int *out)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
ASN1_TYPE spk = ASN1_TYPE_EMPTY;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* == INTEGER */
|
|
Packit |
aea12f |
if ((result = asn1_create_element
|
|
Packit |
aea12f |
(_gnutls_get_gnutls_asn(), "GNUTLS.DSAPublicKey",
|
|
Packit |
aea12f |
&spk)) != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _asn1_strict_der_decode(&spk, der, dersize, NULL);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
asn1_delete_structure(&spk;;
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Read Y */
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((result = _gnutls_x509_read_uint(spk, "", out)) < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
asn1_delete_structure(&spk;;
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
asn1_delete_structure(&spk;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Extracts DSA and RSA parameters from a certificate.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_get_asn_mpis(ASN1_TYPE asn, const char *root,
|
|
Packit |
aea12f |
gnutls_pk_params_st * params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
char name[256];
|
|
Packit |
aea12f |
gnutls_datum_t tmp = { NULL, 0 };
|
|
Packit |
aea12f |
gnutls_pk_algorithm_t pk_algorithm;
|
|
Packit |
aea12f |
gnutls_ecc_curve_t curve;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_pk_params_init(params);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_get_pk_algorithm(asn, root, &curve, NULL);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
pk_algorithm = result;
|
|
Packit |
aea12f |
params->curve = curve;
|
|
Packit |
aea12f |
params->algo = pk_algorithm;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Read the algorithm's parameters
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
_asnstr_append_name(name, sizeof(name), root,
|
|
Packit |
aea12f |
".algorithm.parameters");
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
if (pk_algorithm != GNUTLS_PK_RSA &&
|
|
Packit Service |
991b93 |
pk_algorithm != GNUTLS_PK_EDDSA_ED25519 && pk_algorithm != GNUTLS_PK_ECDH_X25519 &&
|
|
Packit Service |
991b93 |
pk_algorithm != GNUTLS_PK_EDDSA_ED448 && pk_algorithm != GNUTLS_PK_ECDH_X448) {
|
|
Packit |
aea12f |
/* RSA and EdDSA do not use parameters */
|
|
Packit |
aea12f |
result = _gnutls_x509_read_value(asn, name, &tmp);
|
|
Packit |
aea12f |
if (pk_algorithm == GNUTLS_PK_RSA_PSS &&
|
|
Packit |
aea12f |
(result == GNUTLS_E_ASN1_VALUE_NOT_FOUND || result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)) {
|
|
Packit |
aea12f |
goto skip_params;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
_gnutls_x509_read_pubkey_params(pk_algorithm,
|
|
Packit |
aea12f |
tmp.data, tmp.size,
|
|
Packit |
aea12f |
params);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_free_datum(&tmp);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
skip_params:
|
|
Packit |
aea12f |
/* Now read the public key */
|
|
Packit |
aea12f |
_asnstr_append_name(name, sizeof(name), root, ".subjectPublicKey");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_read_value(asn, name, &tmp);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((result =
|
|
Packit |
aea12f |
_gnutls_x509_read_pubkey(pk_algorithm, tmp.data, tmp.size,
|
|
Packit |
aea12f |
params)) < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_check_pubkey_params(params);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
error:
|
|
Packit |
aea12f |
if (result < 0)
|
|
Packit |
aea12f |
gnutls_pk_params_release(params);
|
|
Packit |
aea12f |
_gnutls_free_datum(&tmp);
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Extracts DSA and RSA parameters from a certificate.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_crt_get_mpis(gnutls_x509_crt_t cert,
|
|
Packit |
aea12f |
gnutls_pk_params_st * params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
/* Read the algorithm's OID
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
return _gnutls_get_asn_mpis(cert->cert,
|
|
Packit |
aea12f |
"tbsCertificate.subjectPublicKeyInfo",
|
|
Packit |
aea12f |
params);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Extracts DSA and RSA parameters from a certificate.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_crq_get_mpis(gnutls_x509_crq_t cert,
|
|
Packit |
aea12f |
gnutls_pk_params_st * params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
/* Read the algorithm's OID
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
return _gnutls_get_asn_mpis(cert->crq,
|
|
Packit |
aea12f |
"certificationRequestInfo.subjectPKInfo",
|
|
Packit |
aea12f |
params);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* This function reads and decodes the parameters for DSS or RSA keys.
|
|
Packit |
aea12f |
* This is the "signatureAlgorithm" fields.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_read_pkalgo_params(ASN1_TYPE src, const char *src_name,
|
|
Packit |
aea12f |
gnutls_x509_spki_st *spki, unsigned is_sig)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
char name[128];
|
|
Packit |
aea12f |
char oid[MAX_OID_SIZE];
|
|
Packit |
aea12f |
int oid_size;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
memset(spki, 0, sizeof(*spki));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), src_name);
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".algorithm");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
oid_size = sizeof(oid);
|
|
Packit |
aea12f |
result = asn1_read_value(src, name, oid, &oid_size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (strcmp (oid, PK_PKIX1_RSA_PSS_OID) == 0) {
|
|
Packit |
aea12f |
gnutls_datum_t tmp = { NULL, 0 };
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), src_name);
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".parameters");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_read_value(src, name, &tmp);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
if (!is_sig) {
|
|
Packit |
aea12f |
if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
|
|
Packit |
aea12f |
result != GNUTLS_E_ASN1_VALUE_NOT_FOUND) {
|
|
Packit |
aea12f |
/* it is ok to not have parameters in SPKI, but
|
|
Packit |
aea12f |
* not in signatures */
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return gnutls_assert_val(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_read_rsa_pss_params(tmp.data, tmp.size,
|
|
Packit |
aea12f |
spki);
|
|
Packit |
aea12f |
_gnutls_free_datum(&tmp);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result < 0)
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static int write_oid_and_params(ASN1_TYPE dst, const char *dst_name, const char *oid, gnutls_x509_spki_st *params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
char name[128];
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (params == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), dst_name);
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".algorithm");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* write the OID.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
result = asn1_write_value(dst, name, oid, 1);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_str_cpy(name, sizeof(name), dst_name);
|
|
Packit |
aea12f |
_gnutls_str_cat(name, sizeof(name), ".parameters");
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (params->pk == GNUTLS_PK_RSA)
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
asn1_write_value(dst, name, ASN1_NULL, ASN1_NULL_SIZE);
|
|
Packit |
aea12f |
else if (params->pk == GNUTLS_PK_RSA_PSS) {
|
|
Packit |
aea12f |
gnutls_datum_t tmp = { NULL, 0 };
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_write_rsa_pss_params(params, &tmp);
|
|
Packit |
aea12f |
if (result < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(result);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = asn1_write_value(dst, name, tmp.data, tmp.size);
|
|
Packit |
aea12f |
_gnutls_free_datum(&tmp);
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
result = asn1_write_value(dst, name, NULL, 0);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND) {
|
|
Packit |
aea12f |
/* Here we ignore the element not found error, since this
|
|
Packit |
aea12f |
* may have been disabled before.
|
|
Packit |
aea12f |
*/
|
|
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_spki_params(ASN1_TYPE dst, const char *dst_name,
|
|
Packit |
aea12f |
gnutls_x509_spki_st *params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
const char *oid;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (params->legacy && params->pk == GNUTLS_PK_RSA)
|
|
Packit |
aea12f |
oid = PK_PKIX1_RSA_OID;
|
|
Packit |
aea12f |
else if (params->pk == GNUTLS_PK_RSA_PSS)
|
|
Packit |
aea12f |
oid = PK_PKIX1_RSA_PSS_OID;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
oid = gnutls_pk_get_oid(params->pk);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (oid == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
_gnutls_debug_log
|
|
Packit |
aea12f |
("Cannot find OID for public key algorithm %s\n",
|
|
Packit |
aea12f |
gnutls_pk_get_name(params->pk));
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return write_oid_and_params(dst, dst_name, oid, params);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_write_sign_params(ASN1_TYPE dst, const char *dst_name,
|
|
Packit |
aea12f |
const gnutls_sign_entry_st *se, gnutls_x509_spki_st *params)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
const char *oid;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (params->legacy && params->pk == GNUTLS_PK_RSA)
|
|
Packit |
aea12f |
oid = PK_PKIX1_RSA_OID;
|
|
Packit |
aea12f |
else if (params->pk == GNUTLS_PK_RSA_PSS)
|
|
Packit |
aea12f |
oid = PK_PKIX1_RSA_PSS_OID;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
oid = se->oid;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (oid == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
_gnutls_debug_log
|
|
Packit |
aea12f |
("Cannot find OID for sign algorithm %s\n",
|
|
Packit |
aea12f |
se->name);
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return write_oid_and_params(dst, dst_name, oid, params);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* this function reads a (small) unsigned integer
|
|
Packit |
aea12f |
* from asn1 structs. Combines the read and the conversion
|
|
Packit |
aea12f |
* steps.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_read_uint(ASN1_TYPE node, const char *value,
|
|
Packit |
aea12f |
unsigned int *ret)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int len, result;
|
|
Packit |
aea12f |
uint8_t *tmpstr;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = 0;
|
|
Packit |
aea12f |
result = asn1_read_value(node, value, NULL, &len;;
|
|
Packit |
aea12f |
if (result != ASN1_MEM_ERROR) {
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmpstr = gnutls_malloc(len);
|
|
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, &len;;
|
|
Packit |
aea12f |
|
|
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 (len == 1)
|
|
Packit |
aea12f |
*ret = tmpstr[0];
|
|
Packit |
aea12f |
else if (len == 2)
|
|
Packit |
aea12f |
*ret = _gnutls_read_uint16(tmpstr);
|
|
Packit |
aea12f |
else if (len == 3)
|
|
Packit |
aea12f |
*ret = _gnutls_read_uint24(tmpstr);
|
|
Packit |
aea12f |
else if (len == 4)
|
|
Packit |
aea12f |
*ret = _gnutls_read_uint32(tmpstr);
|
|
Packit |
aea12f |
else {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
gnutls_free(tmpstr);
|
|
Packit |
aea12f |
return GNUTLS_E_INTERNAL_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(tmpstr);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* Writes the specified integer into the specified node.
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
_gnutls_x509_write_uint32(ASN1_TYPE node, const char *value, uint32_t num)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
uint8_t tmpstr[5];
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmpstr[0] = 0;
|
|
Packit |
aea12f |
_gnutls_write_uint32(num, tmpstr+1);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (tmpstr[1] > SCHAR_MAX) {
|
|
Packit |
aea12f |
result = asn1_write_value(node, value, tmpstr, 5);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result = asn1_write_value(node, value, tmpstr+1, 4);
|
|
Packit |
aea12f |
}
|
|
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 |
}
|