|
Packit |
aea12f |
/*
|
|
Packit |
aea12f |
* Copyright (C) 2003-2016 Free Software Foundation, Inc.
|
|
Packit |
aea12f |
* Copyright (C) 2015-2016 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 <libtasn1.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
#include <datum.h>
|
|
Packit |
aea12f |
#include <global.h>
|
|
Packit |
aea12f |
#include "errors.h"
|
|
Packit |
aea12f |
#include <common.h>
|
|
Packit |
aea12f |
#include <x509_b64.h>
|
|
Packit |
aea12f |
#include <x509_int.h>
|
|
Packit |
aea12f |
#include <x509.h>
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static int crl_reinit(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl->crl)
|
|
Packit |
aea12f |
asn1_delete_structure(&crl->crl);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = asn1_create_element(_gnutls_get_pkix(),
|
|
Packit |
aea12f |
"PKIX1.CertificateList",
|
|
Packit |
aea12f |
&crl->crl);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
crl->rcache = NULL;
|
|
Packit |
aea12f |
crl->rcache_idx = 0;
|
|
Packit |
aea12f |
crl->raw_issuer_dn.size = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_init:
|
|
Packit |
aea12f |
* @crl: A pointer to the type to be initialized
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will initialize a CRL structure. CRL stands for
|
|
Packit |
aea12f |
* Certificate Revocation List. A revocation list usually contains
|
|
Packit |
aea12f |
* lists of certificate serial numbers that have been revoked by an
|
|
Packit |
aea12f |
* Authority. The revocation lists are always signed with the
|
|
Packit |
aea12f |
* authority's private key.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int gnutls_x509_crl_init(gnutls_x509_crl_t * crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
FAIL_IF_LIB_ERROR;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (*crl) {
|
|
Packit |
aea12f |
int result = crl_reinit(*crl);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
gnutls_free(*crl);
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
return 0; /* success */
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_deinit:
|
|
Packit |
aea12f |
* @crl: The data to be deinitialized
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will deinitialize a CRL structure.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (!crl)
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl->crl)
|
|
Packit |
aea12f |
asn1_delete_structure(&crl->crl);
|
|
Packit |
aea12f |
gnutls_free(crl->der.data);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(crl);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_import:
|
|
Packit |
aea12f |
* @crl: The data to store the parsed CRL.
|
|
Packit |
aea12f |
* @data: The DER or PEM encoded CRL.
|
|
Packit |
aea12f |
* @format: One of DER or PEM
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will convert the given DER or PEM encoded CRL
|
|
Packit |
aea12f |
* to the native #gnutls_x509_crl_t format. The output will be stored in 'crl'.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the CRL is PEM encoded it should have a header of "X509 CRL".
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_import(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
const gnutls_datum_t * data,
|
|
Packit |
aea12f |
gnutls_x509_crt_fmt_t format)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_free_datum(&crl->der);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* If the CRL is in PEM format then decode it
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
if (format == GNUTLS_X509_FMT_PEM) {
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
_gnutls_fbase64_decode(PEM_CRL, data->data, data->size,
|
|
Packit |
aea12f |
&crl->der);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
result = _gnutls_set_datum(&crl->der, data->data, data->size);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl->expanded) {
|
|
Packit |
aea12f |
result = crl_reinit(crl);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
crl->expanded = 1;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
_asn1_strict_der_decode(&crl->crl, crl->der.data, crl->der.size, NULL);
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
result = _gnutls_asn2err(result);
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = _gnutls_x509_get_raw_field2(crl->crl, &crl->der,
|
|
Packit |
aea12f |
"tbsCertList.issuer.rdnSequence",
|
|
Packit |
aea12f |
&crl->raw_issuer_dn);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto cleanup;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
cleanup:
|
|
Packit |
aea12f |
_gnutls_free_datum(&crl->der);
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_issuer_dn:
|
|
Packit |
aea12f |
* @crl: should contain a gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @buf: a pointer to a structure to hold the peer's name (may be null)
|
|
Packit |
aea12f |
* @sizeof_buf: initially holds the size of @buf
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will copy the name of the CRL issuer in the provided
|
|
Packit |
aea12f |
* buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
|
|
Packit |
aea12f |
* described in RFC4514. The output string will be ASCII or UTF-8
|
|
Packit |
aea12f |
* encoded, depending on the certificate data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If buf is %NULL then only the size will be filled.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function does not output a fully RFC4514 compliant string, if
|
|
Packit |
aea12f |
* that is required see gnutls_x509_crl_get_issuer_dn3().
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
|
|
Packit |
aea12f |
* not long enough, and in that case the sizeof_buf will be updated
|
|
Packit |
aea12f |
* with the required size, and 0 on success.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_issuer_dn(gnutls_x509_crl_t crl, char *buf,
|
|
Packit |
aea12f |
size_t * sizeof_buf)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_parse_dn(crl->crl,
|
|
Packit |
aea12f |
"tbsCertList.issuer.rdnSequence",
|
|
Packit |
aea12f |
buf, sizeof_buf, GNUTLS_X509_DN_FLAG_COMPAT);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_issuer_dn_by_oid:
|
|
Packit |
aea12f |
* @crl: should contain a gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @oid: holds an Object Identified in null terminated string
|
|
Packit |
aea12f |
* @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use (0) to get the first one.
|
|
Packit |
aea12f |
* @raw_flag: If non-zero returns the raw DER data of the DN part.
|
|
Packit |
aea12f |
* @buf: a pointer to a structure to hold the peer's name (may be null)
|
|
Packit |
aea12f |
* @sizeof_buf: initially holds the size of @buf
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will extract the part of the name of the CRL issuer
|
|
Packit |
aea12f |
* specified by the given OID. The output will be encoded as described
|
|
Packit |
aea12f |
* in RFC4514. The output string will be ASCII or UTF-8 encoded,
|
|
Packit |
aea12f |
* depending on the certificate data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Some helper macros with popular OIDs can be found in gnutls/x509.h
|
|
Packit |
aea12f |
* If raw flag is (0), this function will only return known OIDs as
|
|
Packit |
aea12f |
* text. Other OIDs will be DER encoded, as described in RFC4514 -- in
|
|
Packit |
aea12f |
* hex format with a '#' prefix. You can check about known OIDs
|
|
Packit |
aea12f |
* using gnutls_x509_dn_oid_known().
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If buf is null then only the size will be filled.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
|
|
Packit |
aea12f |
* not long enough, and in that case the sizeof_buf will be updated
|
|
Packit |
aea12f |
* with the required size, and 0 on success.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
const char *oid, unsigned indx,
|
|
Packit |
aea12f |
unsigned int raw_flag, void *buf,
|
|
Packit |
aea12f |
size_t * sizeof_buf)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
gnutls_datum_t td;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_x509_parse_dn_oid(crl->crl,
|
|
Packit |
aea12f |
"tbsCertList.issuer.rdnSequence",
|
|
Packit |
aea12f |
oid, indx, raw_flag, &td);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_strdatum_to_buf(&td, buf, sizeof_buf);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_dn_oid:
|
|
Packit |
aea12f |
* @crl: should contain a gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @indx: Specifies which DN OID to send. Use (0) to get the first one.
|
|
Packit |
aea12f |
* @oid: a pointer to store the OID (may be null)
|
|
Packit |
aea12f |
* @sizeof_oid: initially holds the size of 'oid'
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will extract the requested OID of the name of the CRL
|
|
Packit |
aea12f |
* issuer, specified by the given index.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If oid is null then only the size will be filled.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
|
|
Packit |
aea12f |
* not long enough, and in that case the sizeof_oid will be updated
|
|
Packit |
aea12f |
* with the required size. On success 0 is returned.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
unsigned indx, void *oid, size_t * sizeof_oid)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_get_dn_oid(crl->crl,
|
|
Packit |
aea12f |
"tbsCertList.issuer.rdnSequence",
|
|
Packit |
aea12f |
indx, oid, sizeof_oid);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_issuer_dn2:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @dn: a pointer to a structure to hold the name
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will allocate buffer and copy the name of the CRL issuer.
|
|
Packit |
aea12f |
* The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
|
|
Packit |
aea12f |
* described in RFC4514. The output string will be ASCII or UTF-8
|
|
Packit |
aea12f |
* encoded, depending on the certificate data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function does not output a fully RFC4514 compliant string, if
|
|
Packit |
aea12f |
* that is required see gnutls_x509_crl_get_issuer_dn3().
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 3.1.10
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_issuer_dn2(gnutls_x509_crl_t crl, gnutls_datum_t * dn)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_get_dn(crl->crl,
|
|
Packit |
aea12f |
"tbsCertList.issuer.rdnSequence",
|
|
Packit |
aea12f |
dn, GNUTLS_X509_DN_FLAG_COMPAT);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_issuer_dn3:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @dn: a pointer to a structure to hold the name
|
|
Packit |
aea12f |
* @flags: zero or %GNUTLS_X509_DN_FLAG_COMPAT
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will allocate buffer and copy the name of the CRL issuer.
|
|
Packit |
aea12f |
* The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
|
|
Packit |
aea12f |
* described in RFC4514. The output string will be ASCII or UTF-8
|
|
Packit |
aea12f |
* encoded, depending on the certificate data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* When the flag %GNUTLS_X509_DN_FLAG_COMPAT is specified, the output
|
|
Packit |
aea12f |
* format will match the format output by previous to 3.5.6 versions of GnuTLS
|
|
Packit |
aea12f |
* which was not not fully RFC4514-compliant.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 3.5.7
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_issuer_dn3(gnutls_x509_crl_t crl, gnutls_datum_t * dn, unsigned flags)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_get_dn(crl->crl,
|
|
Packit |
aea12f |
"tbsCertList.issuer.rdnSequence",
|
|
Packit |
aea12f |
dn, flags);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_signature_algorithm:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return a value of the #gnutls_sign_algorithm_t
|
|
Packit |
aea12f |
* enumeration that is the signature algorithm.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since 3.6.0 this function never returns a negative error code.
|
|
Packit |
aea12f |
* Error cases and unknown/unsupported signature algorithms are
|
|
Packit |
aea12f |
* mapped to %GNUTLS_SIGN_UNKNOWN.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: a #gnutls_sign_algorithm_t value
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
return map_errs_to_zero(_gnutls_x509_get_signature_algorithm(crl->crl,
|
|
Packit |
aea12f |
"signatureAlgorithm"));
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_signature_oid:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @oid: a pointer to a buffer to hold the OID (may be null)
|
|
Packit |
aea12f |
* @oid_size: initially holds the size of @oid
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the OID of the signature algorithm
|
|
Packit |
aea12f |
* that has been used to sign this CRL. This is function
|
|
Packit |
aea12f |
* is useful in the case gnutls_x509_crl_get_signature_algorithm()
|
|
Packit |
aea12f |
* returned %GNUTLS_SIGN_UNKNOWN.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: zero or a negative error code on error.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 3.5.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int gnutls_x509_crl_get_signature_oid(gnutls_x509_crl_t crl, char *oid, size_t *oid_size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
char str[MAX_OID_SIZE];
|
|
Packit |
aea12f |
int len, result, ret;
|
|
Packit |
aea12f |
gnutls_datum_t out;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = sizeof(str);
|
|
Packit |
aea12f |
result = asn1_read_value(crl->crl, "signatureAlgorithm.algorithm", str, &len;;
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
out.data = (void*)str;
|
|
Packit |
aea12f |
out.size = len;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _gnutls_copy_string(&out, (void*)oid, oid_size);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_signature:
|
|
Packit |
aea12f |
* @crl: should contain a gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @sig: a pointer where the signature part will be copied (may be null).
|
|
Packit |
aea12f |
* @sizeof_sig: initially holds the size of @sig
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will extract the signature field of a CRL.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
char *sig, size_t * sizeof_sig)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
unsigned int bits;
|
|
Packit |
aea12f |
int len;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = 0;
|
|
Packit |
aea12f |
result = asn1_read_value(crl->crl, "signature", NULL, &len;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_MEM_ERROR) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
bits = len;
|
|
Packit |
aea12f |
if (bits % 8 != 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_CERTIFICATE_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = bits / 8;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (*sizeof_sig < (unsigned) len) {
|
|
Packit |
aea12f |
*sizeof_sig = bits / 8;
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result = asn1_read_value(crl->crl, "signature", sig, &len;;
|
|
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 |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_version:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the version of the specified CRL.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: The version number, or a negative error code on error.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit Service |
991b93 |
return _gnutls_x509_get_version(crl->crl, "tbsCertList.version");
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_this_update:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the time this CRL was issued.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: when the CRL was issued, or (time_t)-1 on error.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_get_time(crl->crl, "tbsCertList.thisUpdate",
|
|
Packit |
aea12f |
0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_next_update:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the time the next CRL will be issued.
|
|
Packit |
aea12f |
* This field is optional in a CRL so it might be normal to get an
|
|
Packit |
aea12f |
* error instead.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: when the next CRL will be issued, or (time_t)-1 on error.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return (time_t) - 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_get_time(crl->crl, "tbsCertList.nextUpdate",
|
|
Packit |
aea12f |
0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_crt_count:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the number of revoked certificates in the
|
|
Packit |
aea12f |
* given CRL.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: number of certificates, a negative error code on failure.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int count, result;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
asn1_number_of_elements(crl->crl,
|
|
Packit |
aea12f |
"tbsCertList.revokedCertificates",
|
|
Packit |
aea12f |
&count);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return 0; /* no certificates */
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return count;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_crt_serial:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @indx: the index of the certificate to extract (starting from 0)
|
|
Packit |
aea12f |
* @serial: where the serial number will be copied
|
|
Packit |
aea12f |
* @serial_size: initially holds the size of serial
|
|
Packit |
aea12f |
* @t: if non null, will hold the time this certificate was revoked
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will retrieve the serial number of the specified, by
|
|
Packit |
aea12f |
* the index, revoked certificate.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Note that this function will have performance issues in large sequences
|
|
Packit |
aea12f |
* of revoked certificates. In that case use gnutls_x509_crl_iter_crt_serial().
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl, unsigned indx,
|
|
Packit |
aea12f |
unsigned char *serial,
|
|
Packit |
aea12f |
size_t * serial_size, time_t * t)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int result, _serial_size;
|
|
Packit |
aea12f |
char serial_name[MAX_NAME_SIZE];
|
|
Packit |
aea12f |
char date_name[MAX_NAME_SIZE];
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
snprintf(serial_name, sizeof(serial_name),
|
|
Packit |
aea12f |
"tbsCertList.revokedCertificates.?%u.userCertificate",
|
|
Packit |
aea12f |
indx + 1);
|
|
Packit |
aea12f |
snprintf(date_name, sizeof(date_name),
|
|
Packit |
aea12f |
"tbsCertList.revokedCertificates.?%u.revocationDate",
|
|
Packit |
aea12f |
indx + 1);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_serial_size = *serial_size;
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
asn1_read_value(crl->crl, serial_name, serial, &_serial_size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*serial_size = _serial_size;
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
if (result == ASN1_ELEMENT_NOT_FOUND)
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (t) {
|
|
Packit |
aea12f |
*t = _gnutls_x509_get_time(crl->crl, date_name, 0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_iter_deinit:
|
|
Packit |
aea12f |
* @iter: The iterator to be deinitialized
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will deinitialize an iterator type.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
void gnutls_x509_crl_iter_deinit(gnutls_x509_crl_iter_t iter)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (!iter)
|
|
Packit |
aea12f |
return;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(iter);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_iter_crt_serial:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @iter: A pointer to an iterator (initially the iterator should be %NULL)
|
|
Packit |
aea12f |
* @serial: where the serial number will be copied
|
|
Packit |
aea12f |
* @serial_size: initially holds the size of serial
|
|
Packit |
aea12f |
* @t: if non null, will hold the time this certificate was revoked
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function performs the same as gnutls_x509_crl_get_crt_serial(),
|
|
Packit |
aea12f |
* but reads sequentially and keeps state in the iterator
|
|
Packit |
aea12f |
* between calls. That allows it to provide better performance in sequences
|
|
Packit |
aea12f |
* with many elements (50000+).
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* When past the last element is accessed %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
|
|
Packit |
aea12f |
* is returned and the iterator is reset.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* After use, the iterator must be deinitialized using gnutls_x509_crl_iter_deinit().
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_iter_crt_serial(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
gnutls_x509_crl_iter_t *iter,
|
|
Packit |
aea12f |
unsigned char *serial,
|
|
Packit |
aea12f |
size_t * serial_size, time_t * t)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
int result, _serial_size;
|
|
Packit |
aea12f |
char serial_name[MAX_NAME_SIZE];
|
|
Packit |
aea12f |
char date_name[MAX_NAME_SIZE];
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL || iter == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (*iter == NULL) {
|
|
Packit |
aea12f |
*iter = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_iter));
|
|
Packit |
aea12f |
if (*iter == NULL)
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((*iter)->rcache == NULL) {
|
|
Packit |
aea12f |
(*iter)->rcache = asn1_find_node (crl->crl, "tbsCertList.revokedCertificates.?1");
|
|
Packit |
aea12f |
(*iter)->rcache_idx = 1;
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
snprintf(serial_name, sizeof(serial_name),
|
|
Packit |
aea12f |
"?%d", (*iter)->rcache_idx);
|
|
Packit |
aea12f |
(*iter)->rcache = asn1_find_node ((*iter)->rcache, serial_name);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
if ((*iter)->rcache == NULL) {
|
|
Packit |
aea12f |
/* reset */
|
|
Packit |
aea12f |
(*iter)->rcache = NULL;
|
|
Packit |
aea12f |
return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
snprintf(serial_name, sizeof(serial_name),
|
|
Packit |
aea12f |
"?%d.userCertificate", (*iter)->rcache_idx);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_serial_size = *serial_size;
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
asn1_read_value((*iter)->rcache, serial_name, serial, &_serial_size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*serial_size = _serial_size;
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
if (result == ASN1_ELEMENT_NOT_FOUND) {
|
|
Packit |
aea12f |
/* reset */
|
|
Packit |
aea12f |
(*iter)->rcache = NULL;
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (t) {
|
|
Packit |
aea12f |
snprintf(date_name, sizeof(date_name),
|
|
Packit |
aea12f |
"?%d.revocationDate", (*iter)->rcache_idx);
|
|
Packit |
aea12f |
*t = _gnutls_x509_get_time((*iter)->rcache, date_name, 0);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
(*iter)->rcache_idx++;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_raw_issuer_dn:
|
|
Packit |
aea12f |
* @crl: should contain a gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @dn: will hold the starting point of the DN
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return a pointer to the DER encoded DN structure
|
|
Packit |
aea12f |
* and the length.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: a negative error code on error, and (0) on success.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 2.12.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
gnutls_datum_t * dn)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl->raw_issuer_dn.size != 0) {
|
|
Packit |
aea12f |
return _gnutls_set_datum(dn, crl->raw_issuer_dn.data,
|
|
Packit |
aea12f |
crl->raw_issuer_dn.size);
|
|
Packit |
aea12f |
} else {
|
|
Packit |
aea12f |
return _gnutls_x509_get_raw_field(crl->crl, "tbsCertList.issuer.rdnSequence", dn);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_export:
|
|
Packit |
aea12f |
* @crl: Holds the revocation list
|
|
Packit |
aea12f |
* @format: the format of output params. One of PEM or DER.
|
|
Packit |
aea12f |
* @output_data: will contain a private key PEM or DER encoded
|
|
Packit |
aea12f |
* @output_data_size: holds the size of output_data (and will
|
|
Packit |
aea12f |
* be replaced by the actual size of parameters)
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will export the revocation list to DER or PEM format.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the buffer provided is not long enough to hold the output, then
|
|
Packit |
aea12f |
* %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the structure is PEM encoded, it will have a header
|
|
Packit |
aea12f |
* of "BEGIN X509 CRL".
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_export(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
gnutls_x509_crt_fmt_t format, void *output_data,
|
|
Packit |
aea12f |
size_t * output_data_size)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_export_int(crl->crl, format, PEM_CRL,
|
|
Packit |
aea12f |
output_data, output_data_size);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_export2:
|
|
Packit |
aea12f |
* @crl: Holds the revocation list
|
|
Packit |
aea12f |
* @format: the format of output params. One of PEM or DER.
|
|
Packit |
aea12f |
* @out: will contain a private key PEM or DER encoded
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will export the revocation list to DER or PEM format.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* The output buffer is allocated using gnutls_malloc().
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the structure is PEM encoded, it will have a header
|
|
Packit |
aea12f |
* of "BEGIN X509 CRL".
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since 3.1.3
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_export2(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return _gnutls_x509_export_int2(crl->crl, format, PEM_CRL, out);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/*-
|
|
Packit |
aea12f |
* _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @dest: The data where to copy
|
|
Packit |
aea12f |
* @src: The data to be copied
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will copy an X.509 certificate structure.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error value.
|
|
Packit |
aea12f |
-*/
|
|
Packit |
aea12f |
int _gnutls_x509_crl_cpy(gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t tmp;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_export2(src, GNUTLS_X509_FMT_DER, &tmp);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_import(dest, &tmp, GNUTLS_X509_FMT_DER);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
gnutls_free(tmp.data);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
static int
|
|
Packit |
aea12f |
_get_authority_key_id(gnutls_x509_crl_t cert, ASN1_TYPE * c2,
|
|
Packit |
aea12f |
unsigned int *critical)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
gnutls_datum_t id;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*c2 = ASN1_TYPE_EMPTY;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (cert == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((ret =
|
|
Packit |
aea12f |
_gnutls_x509_crl_get_extension(cert, "2.5.29.35", 0, &id,
|
|
Packit |
aea12f |
critical)) < 0) {
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (id.size == 0 || id.data == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = asn1_create_element
|
|
Packit |
aea12f |
(_gnutls_get_pkix(), "PKIX1.AuthorityKeyIdentifier", c2);
|
|
Packit |
aea12f |
if (ret != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
_gnutls_free_datum(&id;;
|
|
Packit |
aea12f |
return _gnutls_asn2err(ret);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _asn1_strict_der_decode(c2, id.data, id.size, NULL);
|
|
Packit |
aea12f |
_gnutls_free_datum(&id;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
asn1_delete_structure(c2);
|
|
Packit |
aea12f |
return _gnutls_asn2err(ret);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_authority_key_gn_serial:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
|
|
Packit |
aea12f |
* @alt: is the place where the alternative name will be copied to
|
|
Packit |
aea12f |
* @alt_size: holds the size of alt.
|
|
Packit |
aea12f |
* @alt_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
|
|
Packit |
aea12f |
* @serial: buffer to store the serial number (may be null)
|
|
Packit |
aea12f |
* @serial_size: Holds the size of the serial field (may be null)
|
|
Packit |
aea12f |
* @critical: will be non-zero if the extension is marked as critical (may be null)
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the X.509 authority key
|
|
Packit |
aea12f |
* identifier when stored as a general name (authorityCertIssuer)
|
|
Packit |
aea12f |
* and serial number.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Because more than one general names might be stored
|
|
Packit |
aea12f |
* @seq can be used as a counter to request them all until
|
|
Packit |
aea12f |
* %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: Returns 0 on success, or an error code.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 3.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_authority_key_gn_serial(gnutls_x509_crl_t crl,
|
|
Packit |
aea12f |
unsigned int seq,
|
|
Packit |
aea12f |
void *alt,
|
|
Packit |
aea12f |
size_t * alt_size,
|
|
Packit |
aea12f |
unsigned int *alt_type,
|
|
Packit |
aea12f |
void *serial,
|
|
Packit |
aea12f |
size_t * serial_size,
|
|
Packit |
aea12f |
unsigned int *critical)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int ret, result, len;
|
|
Packit |
aea12f |
ASN1_TYPE c2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _get_authority_key_id(crl, &c2, critical);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
_gnutls_parse_general_name(c2, "authorityCertIssuer", seq, alt,
|
|
Packit |
aea12f |
alt_size, alt_type, 0);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
ret = gnutls_assert_val(ret);
|
|
Packit |
aea12f |
goto fail;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (serial) {
|
|
Packit |
aea12f |
len = *serial_size;
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
asn1_read_value(c2, "authorityCertSerialNumber",
|
|
Packit |
aea12f |
serial, &len;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*serial_size = len;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
ret = _gnutls_asn2err(result);
|
|
Packit |
aea12f |
goto fail;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
fail:
|
|
Packit |
aea12f |
asn1_delete_structure(&c2;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_authority_key_id:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @id: The place where the identifier will be copied
|
|
Packit |
aea12f |
* @id_size: Holds the size of the result field.
|
|
Packit |
aea12f |
* @critical: will be non-zero if the extension is marked as critical
|
|
Packit |
aea12f |
* (may be null)
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the CRL authority's key identifier. This
|
|
Packit |
aea12f |
* is obtained by the X.509 Authority Key identifier extension field
|
|
Packit |
aea12f |
* (2.5.29.35). Note that this function
|
|
Packit |
aea12f |
* only returns the keyIdentifier field of the extension and
|
|
Packit |
aea12f |
* %GNUTLS_E_X509_UNSUPPORTED_EXTENSION, if the extension contains
|
|
Packit |
aea12f |
* the name and serial number of the certificate. In that case
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_authority_key_gn_serial() may be used.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error code in case of an error.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 2.8.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_authority_key_id(gnutls_x509_crl_t crl, void *id,
|
|
Packit |
aea12f |
size_t * id_size,
|
|
Packit |
aea12f |
unsigned int *critical)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result, len, ret;
|
|
Packit |
aea12f |
ASN1_TYPE c2;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = _get_authority_key_id(crl, &c2, critical);
|
|
Packit |
aea12f |
if (ret < 0)
|
|
Packit |
aea12f |
return gnutls_assert_val(ret);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = *id_size;
|
|
Packit |
aea12f |
result = asn1_read_value(c2, "keyIdentifier", id, &len;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*id_size = len;
|
|
Packit |
aea12f |
asn1_delete_structure(&c2;;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == ASN1_VALUE_NOT_FOUND
|
|
Packit |
aea12f |
|| result == ASN1_ELEMENT_NOT_FOUND)
|
|
Packit |
aea12f |
return
|
|
Packit |
aea12f |
gnutls_assert_val(GNUTLS_E_X509_UNSUPPORTED_EXTENSION);
|
|
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 |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_number:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @ret: The place where the number will be copied
|
|
Packit |
aea12f |
* @ret_size: Holds the size of the result field.
|
|
Packit |
aea12f |
* @critical: will be non-zero if the extension is marked as critical
|
|
Packit |
aea12f |
* (may be null)
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the CRL number extension. This is
|
|
Packit |
aea12f |
* obtained by the CRL Number extension field (2.5.29.20).
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error code in case of an error.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 2.8.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_number(gnutls_x509_crl_t crl, void *ret,
|
|
Packit |
aea12f |
size_t * ret_size, unsigned int *critical)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
gnutls_datum_t id;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret)
|
|
Packit |
aea12f |
memset(ret, 0, *ret_size);
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
*ret_size = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if ((result =
|
|
Packit |
aea12f |
_gnutls_x509_crl_get_extension(crl, "2.5.29.20", 0, &id,
|
|
Packit |
aea12f |
critical)) < 0) {
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (id.size == 0 || id.data == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
_gnutls_x509_ext_extract_number(ret, ret_size, id.data,
|
|
Packit |
aea12f |
id.size);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
_gnutls_free_datum(&id;;
|
|
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 |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_extension_oid:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @indx: Specifies which extension OID to send, use (0) to get the first one.
|
|
Packit |
aea12f |
* @oid: a pointer to store the OID (may be null)
|
|
Packit |
aea12f |
* @sizeof_oid: initially holds the size of @oid
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the requested extension OID in the CRL.
|
|
Packit |
aea12f |
* The extension OID will be stored as a string in the provided
|
|
Packit |
aea12f |
* buffer.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error code in case of an error. If your have reached the
|
|
Packit |
aea12f |
* last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
|
|
Packit |
aea12f |
* will be returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 2.8.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_extension_oid(gnutls_x509_crl_t crl, unsigned indx,
|
|
Packit |
aea12f |
void *oid, size_t * sizeof_oid)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (crl == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
result =
|
|
Packit |
aea12f |
_gnutls_x509_crl_get_extension_oid(crl, indx, oid, sizeof_oid);
|
|
Packit |
aea12f |
if (result < 0) {
|
|
Packit |
aea12f |
return result;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_extension_info:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @indx: Specifies which extension OID to send, use (0) to get the first one.
|
|
Packit |
aea12f |
* @oid: a pointer to store the OID
|
|
Packit |
aea12f |
* @sizeof_oid: initially holds the maximum size of @oid, on return
|
|
Packit |
aea12f |
* holds actual size of @oid.
|
|
Packit |
aea12f |
* @critical: output variable with critical flag, may be NULL.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the requested extension OID in the CRL,
|
|
Packit |
aea12f |
* and the critical flag for it. The extension OID will be stored as
|
|
Packit |
aea12f |
* a string in the provided buffer. Use
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_extension_data() to extract the data.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the buffer provided is not long enough to hold the output, then
|
|
Packit |
aea12f |
* *@sizeof_oid is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will be
|
|
Packit |
aea12f |
* returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error code in case of an error. If your have reached the
|
|
Packit |
aea12f |
* last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
|
|
Packit |
aea12f |
* will be returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 2.8.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_extension_info(gnutls_x509_crl_t crl, unsigned indx,
|
|
Packit |
aea12f |
void *oid, size_t * sizeof_oid,
|
|
Packit |
aea12f |
unsigned int *critical)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result;
|
|
Packit |
aea12f |
char str_critical[10];
|
|
Packit |
aea12f |
char name[MAX_NAME_SIZE];
|
|
Packit |
aea12f |
int len;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!crl) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
snprintf(name, sizeof(name),
|
|
Packit |
aea12f |
"tbsCertList.crlExtensions.?%u.extnID", indx + 1);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = *sizeof_oid;
|
|
Packit |
aea12f |
result = asn1_read_value(crl->crl, name, oid, &len;;
|
|
Packit |
aea12f |
*sizeof_oid = len;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == ASN1_ELEMENT_NOT_FOUND)
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
else if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
snprintf(name, sizeof(name),
|
|
Packit |
aea12f |
"tbsCertList.crlExtensions.?%u.critical", indx + 1);
|
|
Packit |
aea12f |
len = sizeof(str_critical);
|
|
Packit |
aea12f |
result = asn1_read_value(crl->crl, name, str_critical, &len;;
|
|
Packit |
aea12f |
if (result != ASN1_SUCCESS) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (critical) {
|
|
Packit |
aea12f |
if (str_critical[0] == 'T')
|
|
Packit |
aea12f |
*critical = 1;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
*critical = 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_get_extension_data:
|
|
Packit |
aea12f |
* @crl: should contain a #gnutls_x509_crl_t type
|
|
Packit |
aea12f |
* @indx: Specifies which extension OID to send. Use (0) to get the first one.
|
|
Packit |
aea12f |
* @data: a pointer to a structure to hold the data (may be null)
|
|
Packit |
aea12f |
* @sizeof_data: initially holds the size of @oid
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will return the requested extension data in the CRL.
|
|
Packit |
aea12f |
* The extension data will be stored as a string in the provided
|
|
Packit |
aea12f |
* buffer.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Use gnutls_x509_crl_get_extension_info() to extract the OID and
|
|
Packit |
aea12f |
* critical flag. Use gnutls_x509_crl_get_extension_info() instead,
|
|
Packit |
aea12f |
* if you want to get data indexed by the extension OID rather than
|
|
Packit |
aea12f |
* sequence.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
|
|
Packit |
aea12f |
* negative error code in case of an error. If your have reached the
|
|
Packit |
aea12f |
* last extension available %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
|
|
Packit |
aea12f |
* will be returned.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 2.8.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_get_extension_data(gnutls_x509_crl_t crl, unsigned indx,
|
|
Packit |
aea12f |
void *data, size_t * sizeof_data)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int result, len;
|
|
Packit |
aea12f |
char name[MAX_NAME_SIZE];
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!crl) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_INVALID_REQUEST;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
snprintf(name, sizeof(name),
|
|
Packit |
aea12f |
"tbsCertList.crlExtensions.?%u.extnValue", indx + 1);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
len = *sizeof_data;
|
|
Packit |
aea12f |
result = asn1_read_value(crl->crl, name, data, &len;;
|
|
Packit |
aea12f |
*sizeof_data = len;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (result == ASN1_ELEMENT_NOT_FOUND)
|
|
Packit |
aea12f |
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
|
Packit |
aea12f |
else if (result < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return _gnutls_asn2err(result);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_list_import2:
|
|
Packit |
aea12f |
* @crls: Will contain the parsed crl list.
|
|
Packit |
aea12f |
* @size: It will contain the size of the list.
|
|
Packit |
aea12f |
* @data: The PEM encoded CRL.
|
|
Packit |
aea12f |
* @format: One of DER or PEM.
|
|
Packit |
aea12f |
* @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will convert the given PEM encoded CRL list
|
|
Packit |
aea12f |
* to the native gnutls_x509_crl_t format. The output will be stored
|
|
Packit |
aea12f |
* in @crls. They will be automatically initialized.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the Certificate is PEM encoded it should have a header of "X509
|
|
Packit |
aea12f |
* CRL".
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: the number of certificates read or a negative error value.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 3.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_list_import2(gnutls_x509_crl_t ** crls,
|
|
Packit |
aea12f |
unsigned int *size,
|
|
Packit |
aea12f |
const gnutls_datum_t * data,
|
|
Packit |
aea12f |
gnutls_x509_crt_fmt_t format,
|
|
Packit |
aea12f |
unsigned int flags)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
unsigned int init = 1024;
|
|
Packit |
aea12f |
int ret;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crls = gnutls_malloc(sizeof(gnutls_x509_crl_t) * init);
|
|
Packit |
aea12f |
if (*crls == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_crl_list_import(*crls, &init, data, format,
|
|
Packit |
aea12f |
flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
|
|
Packit |
aea12f |
if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
|
|
Packit |
aea12f |
*crls =
|
|
Packit |
aea12f |
gnutls_realloc_fast(*crls,
|
|
Packit |
aea12f |
sizeof(gnutls_x509_crl_t) * init);
|
|
Packit |
aea12f |
if (*crls == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_MEMORY_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_crl_list_import(*crls, &init, data, format,
|
|
Packit |
aea12f |
flags);
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_free(*crls);
|
|
Packit |
aea12f |
*crls = NULL;
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*size = init;
|
|
Packit |
aea12f |
return 0;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/**
|
|
Packit |
aea12f |
* gnutls_x509_crl_list_import:
|
|
Packit |
aea12f |
* @crls: Indicates where the parsed CRLs will be copied to. Must not be initialized.
|
|
Packit |
aea12f |
* @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
|
|
Packit |
aea12f |
* @data: The PEM encoded CRLs
|
|
Packit |
aea12f |
* @format: One of DER or PEM.
|
|
Packit |
aea12f |
* @flags: must be (0) or an OR'd sequence of gnutls_certificate_import_flags.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* This function will convert the given PEM encoded CRL list
|
|
Packit |
aea12f |
* to the native gnutls_x509_crl_t format. The output will be stored
|
|
Packit |
aea12f |
* in @crls. They will be automatically initialized.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* If the Certificate is PEM encoded it should have a header of "X509 CRL".
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Returns: the number of certificates read or a negative error value.
|
|
Packit |
aea12f |
*
|
|
Packit |
aea12f |
* Since: 3.0
|
|
Packit |
aea12f |
**/
|
|
Packit |
aea12f |
int
|
|
Packit |
aea12f |
gnutls_x509_crl_list_import(gnutls_x509_crl_t * crls,
|
|
Packit |
aea12f |
unsigned int *crl_max,
|
|
Packit |
aea12f |
const gnutls_datum_t * data,
|
|
Packit |
aea12f |
gnutls_x509_crt_fmt_t format,
|
|
Packit |
aea12f |
unsigned int flags)
|
|
Packit |
aea12f |
{
|
|
Packit |
aea12f |
int size;
|
|
Packit |
aea12f |
const char *ptr;
|
|
Packit |
aea12f |
gnutls_datum_t tmp;
|
|
Packit |
aea12f |
int ret, nocopy = 0;
|
|
Packit |
aea12f |
unsigned int count = 0, j;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (format == GNUTLS_X509_FMT_DER) {
|
|
Packit |
aea12f |
if (*crl_max < 1) {
|
|
Packit |
aea12f |
*crl_max = 1;
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
count = 1; /* import only the first one */
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_init(&crls[0]);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_import(crls[0], data, format);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crl_max = 1;
|
|
Packit |
aea12f |
return 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* move to the certificate
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
ptr = memmem(data->data, data->size,
|
|
Packit |
aea12f |
PEM_CRL_SEP, sizeof(PEM_CRL_SEP) - 1);
|
|
Packit |
aea12f |
if (ptr == NULL) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
return GNUTLS_E_BASE64_DECODING_ERROR;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
count = 0;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
do {
|
|
Packit |
aea12f |
if (count >= *crl_max) {
|
|
Packit |
aea12f |
if (!
|
|
Packit |
aea12f |
(flags &
|
|
Packit |
aea12f |
GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED)) {
|
|
Packit |
aea12f |
break;
|
|
Packit |
aea12f |
} else if (nocopy == 0) {
|
|
Packit |
aea12f |
for (j = 0; j < count; j++)
|
|
Packit |
aea12f |
gnutls_x509_crl_deinit(crls[j]);
|
|
Packit |
aea12f |
nocopy = 1;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (!nocopy) {
|
|
Packit |
aea12f |
ret = gnutls_x509_crl_init(&crls[count]);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
tmp.data = (void *) ptr;
|
|
Packit |
aea12f |
tmp.size =
|
|
Packit |
aea12f |
data->size - (ptr - (char *) data->data);
|
|
Packit |
aea12f |
ret =
|
|
Packit |
aea12f |
gnutls_x509_crl_import(crls[count], &tmp,
|
|
Packit |
aea12f |
GNUTLS_X509_FMT_PEM);
|
|
Packit |
aea12f |
if (ret < 0) {
|
|
Packit |
aea12f |
gnutls_assert();
|
|
Packit |
aea12f |
count++;
|
|
Packit |
aea12f |
goto error;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
/* now we move ptr after the pem header
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
ptr++;
|
|
Packit |
aea12f |
/* find the next certificate (if any)
|
|
Packit |
aea12f |
*/
|
|
Packit |
aea12f |
size = data->size - (ptr - (char *) data->data);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (size > 0) {
|
|
Packit |
aea12f |
ptr =
|
|
Packit |
aea12f |
memmem(ptr, size, PEM_CRL_SEP,
|
|
Packit |
aea12f |
sizeof(PEM_CRL_SEP) - 1);
|
|
Packit |
aea12f |
} else
|
|
Packit |
aea12f |
ptr = NULL;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
count++;
|
|
Packit |
aea12f |
}
|
|
Packit |
aea12f |
while (ptr != NULL);
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
*crl_max = count;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
if (nocopy == 0)
|
|
Packit |
aea12f |
return count;
|
|
Packit |
aea12f |
else
|
|
Packit |
aea12f |
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
|
Packit |
aea12f |
|
|
Packit |
aea12f |
error:
|
|
Packit |
aea12f |
for (j = 0; j < count; j++)
|
|
Packit |
aea12f |
gnutls_x509_crl_deinit(crls[j]);
|
|
Packit |
aea12f |
return ret;
|
|
Packit |
aea12f |
}
|