summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2011-01-31 22:19:02 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2011-01-31 22:30:31 +0100
commit115ea68a5986c63dab5524794b8e65c971d8380d (patch)
treeab063a0d2be20cd75184af59c6e4e2de37bdd669
parent441eccc7be861374b9b4ef4aeca15a25655ef5c4 (diff)
downloadgnutls-115ea68a5986c63dab5524794b8e65c971d8380d.tar.gz
The internal subsystem uses the new certificate verification functions.
This has the side effect of deprecating gnutls_certificate_get_x509_crls() and gnutls_certificate_get_x509_cas() that can no longer operation since they relied on internal structures.
-rw-r--r--NEWS7
-rw-r--r--doc/examples/ex-verify.c4
-rw-r--r--lib/auth_cert.h10
-rw-r--r--lib/gnutls_cert.c38
-rw-r--r--lib/gnutls_x509.c462
-rw-r--r--lib/includes/gnutls/compat.h13
-rw-r--r--lib/includes/gnutls/gnutls.h.in8
-rw-r--r--lib/includes/gnutls/x509.h9
-rw-r--r--lib/libgnutls.map2
-rw-r--r--lib/x509/crl.c57
-rw-r--r--lib/x509/x509.c57
-rw-r--r--src/certtool.c20
-rw-r--r--tests/certificate_set_x509_crl.c2
13 files changed, 337 insertions, 352 deletions
diff --git a/NEWS b/NEWS
index 6f55a8c642..f300148451 100644
--- a/NEWS
+++ b/NEWS
@@ -37,11 +37,16 @@ gnutls_pubkey_verify_data() respectively.
** libgnutls: gnutls_*_export_raw() functions now add leading zero in
integers.
+** libgnutls: Added convenience functions gnutls_x509_crl_list_import2()
+and gnutls_x509_crt_list_import2().
+
** crypto.h: Fix use with C++.
Reported by "Brendan Doherty" <brendand@gentrack.com>.
** API and ABI modifications:
gnutls_x509_crl_list_import: ADDED
+gnutls_x509_crl_list_import2: ADDED
+gnutls_x509_crt_list_import2: ADDED
gnutls_x509_trust_list_verify_crt: ADDED
gnutls_x509_trust_list_add_crls: ADDED
gnutls_x509_trust_list_add_cas: ADDED
@@ -63,6 +68,8 @@ gnutls_x509_privkey_verify_data: DEPRECATED (use: gnutls_pubkey_verify_data)
gnutls_psk_netconf_derive_key: DEPRECATED
gnutls_session_set_finished_function: DEPRECATED
gnutls_ext_register: DEPRECATED
+gnutls_certificate_get_x509_crls: DEPRECATED
+gnutls_certificate_get_x509_cas: DEPRECATED
gnutls_x509_crt_verify_hash: DEPRECATED (use: gnutls_pubkey_verify_hash)
gnutls_x509_crt_verify_data: DEPRECATED (use: gnutls_pubkey_verify_data)
gnutls_x509_crt_get_verify_algorithm: DEPRECATED (use: gnutls_pubkey_get_verify_algorithm)
diff --git a/doc/examples/ex-verify.c b/doc/examples/ex-verify.c
index 302892657f..f71039ad41 100644
--- a/doc/examples/ex-verify.c
+++ b/doc/examples/ex-verify.c
@@ -41,8 +41,8 @@ verify_certificate_chain (gnutls_session_t session,
unsigned int output;
/* Initialize the trusted certificate list. This should be done
- * once on initialization. gnutls_x509_crt_list_import() and
- * gnutls_x509_crl_list_import() can be used to load them.
+ * once on initialization. gnutls_x509_crt_list_import2() and
+ * gnutls_x509_crl_list_import2() can be used to load them.
*/
gnutls_x509_trust_list_init(&tlist);
diff --git a/lib/auth_cert.h b/lib/auth_cert.h
index 95ca2e06d0..d447b71e71 100644
--- a/lib/auth_cert.h
+++ b/lib/auth_cert.h
@@ -71,15 +71,7 @@ typedef struct gnutls_certificate_credentials_st
#endif
/* X509 specific stuff */
-
- gnutls_x509_crt_t *x509_ca_list;
- unsigned x509_ncas; /* number of CAs in the ca_list
- */
-
- gnutls_x509_crl_t *x509_crl_list;
- unsigned x509_ncrls; /* number of CRLs in the crl_list
- */
-
+ gnutls_x509_trust_list_t tlist;
unsigned int verify_flags; /* flags to be used at
* certificate verification.
*/
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index ab6831f216..27ba009e91 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -98,18 +98,8 @@ gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc)
void
gnutls_certificate_free_cas (gnutls_certificate_credentials_t sc)
{
- unsigned j;
-
- for (j = 0; j < sc->x509_ncas; j++)
- {
- gnutls_x509_crt_deinit (sc->x509_ca_list[j]);
- }
-
- sc->x509_ncas = 0;
-
- gnutls_free (sc->x509_ca_list);
- sc->x509_ca_list = NULL;
-
+ /* do nothing for now */
+ return;
}
/**
@@ -122,14 +112,15 @@ gnutls_certificate_free_cas (gnutls_certificate_credentials_t sc)
* credentials.
*
* Since: 2.4.0
+ * Deprecated and defunctional since: 2.11.0
**/
void
gnutls_certificate_get_x509_cas (gnutls_certificate_credentials_t sc,
gnutls_x509_crt_t ** x509_ca_list,
unsigned int *ncas)
{
- *x509_ca_list = sc->x509_ca_list;
- *ncas = sc->x509_ncas;
+ *x509_ca_list = NULL;
+ *ncas = 0;
}
/**
@@ -142,14 +133,15 @@ gnutls_certificate_get_x509_cas (gnutls_certificate_credentials_t sc,
* credentials.
*
* Since: 2.4.0
+ * Deprecated and defunctional since: 2.11.0
**/
void
gnutls_certificate_get_x509_crls (gnutls_certificate_credentials_t sc,
gnutls_x509_crl_t ** x509_crl_list,
unsigned int *ncrls)
{
- *x509_crl_list = sc->x509_crl_list;
- *ncrls = sc->x509_ncrls;
+ *x509_crl_list = NULL;
+ *ncrls = 0;
}
#ifdef ENABLE_OPENPGP
@@ -246,12 +238,9 @@ _gnutls_certificate_get_rsa_params (gnutls_rsa_params_t rsa_params,
void
gnutls_certificate_free_credentials (gnutls_certificate_credentials_t sc)
{
+ gnutls_x509_trust_list_deinit(sc->tlist, 1);
gnutls_certificate_free_keys (sc);
- gnutls_certificate_free_cas (sc);
gnutls_certificate_free_ca_names (sc);
-#ifdef ENABLE_PKI
- gnutls_certificate_free_crls (sc);
-#endif
#ifdef ENABLE_OPENPGP
gnutls_openpgp_keyring_deinit (sc->keyring);
@@ -274,11 +263,20 @@ int
gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t *
res)
{
+int ret;
+
*res = gnutls_calloc (1, sizeof (certificate_credentials_st));
if (*res == NULL)
return GNUTLS_E_MEMORY_ERROR;
+ ret = gnutls_x509_trust_list_init( &(*res)->tlist);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ gnutls_free(*res);
+ return GNUTLS_E_MEMORY_ERROR;
+ }
(*res)->verify_bits = DEFAULT_VERIFY_BITS;
(*res)->verify_depth = DEFAULT_VERIFY_DEPTH;
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 36f304a116..3cf9f1dba5 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -46,7 +46,6 @@
#include "x509/x509_int.h"
#include "read-file.h"
-
/*
* some x509 certificate parsing functions.
*/
@@ -173,13 +172,11 @@ _gnutls_x509_cert_verify_peers (gnutls_session_t session,
/* Verify certificate
*/
- ret = gnutls_x509_crt_list_verify (peer_certificate_list,
+ ret = gnutls_x509_trust_list_verify_crt (cred->tlist, peer_certificate_list,
peer_certificate_list_size,
- cred->x509_ca_list, cred->x509_ncas,
- cred->x509_crl_list, cred->x509_ncrls,
cred->verify_flags | session->internals.
priorities.additional_verify_flags,
- status);
+ status, NULL);
CLEAR_CERTS;
@@ -612,12 +609,12 @@ read_cas_url (gnutls_certificate_credentials_t res, const char *url)
goto cleanup;
}
- res->x509_ca_list = xcrt_list;
- res->x509_ncas = pcrt_list_size;
-
- gnutls_free (pcrt_list);
-
- return pcrt_list_size;
+ ret = gnutls_x509_trust_list_add_cas(res->tlist, xcrt_list, pcrt_list_size, 0);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
cleanup:
gnutls_free (xcrt_list);
@@ -996,7 +993,8 @@ gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res,
}
static int
-add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, int new)
+add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, gnutls_x509_crt_t* crts,
+ unsigned int crt_size)
{
gnutls_datum_t tmp;
int ret;
@@ -1017,9 +1015,9 @@ add_new_crt_to_rdn_seq (gnutls_certificate_credentials_t res, int new)
* so optimizing that is less important.
*/
- for (i = res->x509_ncas - new; i < res->x509_ncas; i++)
+ for (i = 0; i < crt_size; i++)
{
- if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
+ if ((ret = gnutls_x509_crt_get_raw_dn (crts[i], &tmp)) < 0)
{
gnutls_assert ();
return ret;
@@ -1107,147 +1105,90 @@ _gnutls_check_key_usage (const gnutls_cert * cert, gnutls_kx_algorithm_t alg)
return 0;
}
-
-
static int
-parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
+parse_pem_ca_mem (gnutls_certificate_credentials_t res,
const opaque * input_cert, int input_cert_size)
{
- int i, size;
- const opaque *ptr;
- gnutls_datum_t tmp;
- int ret, count;
+ gnutls_x509_crt_t *x509_cert_list;
+ unsigned int x509_ncerts;
+ gnutls_datum tmp;
+ int ret;
- /* move to the certificate
- */
- ptr = memmem (input_cert, input_cert_size,
- PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
- if (ptr == NULL)
- ptr = memmem (input_cert, input_cert_size,
- PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
+ tmp.data = (void*)input_cert;
+ tmp.size = input_cert_size;
- if (ptr == NULL)
+ ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
+ GNUTLS_X509_FMT_PEM, 0);
+ if (ret < 0)
{
- gnutls_assert ();
- return GNUTLS_E_BASE64_DECODING_ERROR;
+ gnutls_assert();
+ return ret;
}
- size = input_cert_size - (ptr - input_cert);
-
- i = *ncerts + 1;
- count = 0;
- do
+ if ((ret = add_new_crt_to_rdn_seq (res, x509_cert_list, x509_ncerts)) < 0)
{
-
- *cert_list =
- (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
- i *
- sizeof
- (gnutls_x509_crt_t));
-
- if (*cert_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- tmp.data = (opaque *) ptr;
- tmp.size = size;
-
- ret =
- gnutls_x509_crt_import (cert_list[0][i - 1],
- &tmp, GNUTLS_X509_FMT_PEM);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- /* now we move ptr after the pem header
- */
- ptr++;
- size--;
- /* find the next certificate (if any)
- */
-
- if (size > 0)
- {
- char *ptr3;
-
- ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
- if (ptr3 == NULL)
- ptr3 = memmem (ptr, size,
- PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
-
- ptr = ptr3;
- size = input_cert_size - (ptr - input_cert);
- }
- else
- ptr = NULL;
-
- i++;
- count++;
-
+ gnutls_assert();
+ goto cleanup;
}
- while (ptr != NULL);
- *ncerts = i - 1;
+ ret = gnutls_x509_trust_list_add_cas(res->tlist, x509_cert_list, x509_ncerts, 0);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
- return count;
+cleanup:
+ gnutls_free(x509_cert_list);
+ return ret;
}
/* Reads a DER encoded certificate list from memory and stores it to a
* gnutls_cert structure. Returns the number of certificates parsed.
*/
static int
-parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
+parse_der_ca_mem (gnutls_certificate_credentials_t res,
const void *input_cert, int input_cert_size)
{
- int i;
- gnutls_datum_t tmp;
+ gnutls_x509_crt_t crt;
+ gnutls_datum tmp;
int ret;
- i = *ncerts + 1;
-
- *cert_list =
- (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
- i *
- sizeof (gnutls_x509_crt_t));
+ tmp.data = (void*)input_cert;
+ tmp.size = input_cert_size;
- if (*cert_list == NULL)
+ ret = gnutls_x509_crt_init( &crt);
+ if (ret < 0)
{
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
+ gnutls_assert();
+ return ret;
}
- tmp.data = (opaque *) input_cert;
- tmp.size = input_cert_size;
-
- ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
+ ret = gnutls_x509_crt_import( crt, &tmp, GNUTLS_X509_FMT_DER);
if (ret < 0)
{
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ goto cleanup;
}
- ret =
- gnutls_x509_crt_import (cert_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
+ if ((ret = add_new_crt_to_rdn_seq (res, &crt, 1)) < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_trust_list_add_cas(res->tlist, &crt, 1, 0);
if (ret < 0)
{
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ goto cleanup;
}
- *ncerts = i;
+ return ret;
- return 1; /* one certificate parsed */
+cleanup:
+ gnutls_x509_crt_deinit(crt);
+ return ret;
}
/**
@@ -1274,18 +1215,15 @@ gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res,
const gnutls_datum_t * ca,
gnutls_x509_crt_fmt_t type)
{
- int ret, ret2;
+ int ret;
if (type == GNUTLS_X509_FMT_DER)
- ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas,
+ ret = parse_der_ca_mem (res,
ca->data, ca->size);
else
- ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas,
+ ret = parse_pem_ca_mem (res,
ca->data, ca->size);
- if ((ret2 = add_new_crt_to_rdn_seq (res, ret)) < 0)
- return ret2;
-
return ret;
}
@@ -1314,44 +1252,49 @@ gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
gnutls_x509_crt_t * ca_list,
int ca_list_size)
{
- int ret, i, ret2;
-
- res->x509_ca_list = gnutls_realloc_fast (res->x509_ca_list,
- (ca_list_size +
- res->x509_ncas) *
- sizeof (gnutls_x509_crt_t));
- if (res->x509_ca_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ int ret, i, j;
+ gnutls_x509_crt_t new_list[ca_list_size];
for (i = 0; i < ca_list_size; i++)
{
- ret = gnutls_x509_crt_init (&res->x509_ca_list[res->x509_ncas]);
+ ret = gnutls_x509_crt_init (&new_list[i]);
if (ret < 0)
{
gnutls_assert ();
- return ret;
+ goto cleanup;
}
- ret = _gnutls_x509_crt_cpy (res->x509_ca_list[res->x509_ncas],
- ca_list[i]);
+ ret = _gnutls_x509_crt_cpy (new_list[i], ca_list[i]);
if (ret < 0)
{
gnutls_assert ();
- gnutls_x509_crt_deinit (res->x509_ca_list[res->x509_ncas]);
- return ret;
+ goto cleanup;
}
- res->x509_ncas++;
}
- if ((ret2 = add_new_crt_to_rdn_seq (res, ca_list_size)) < 0)
- return ret2;
+ if ((ret = add_new_crt_to_rdn_seq (res, new_list, ca_list_size)) < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
- return 0;
+ ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, 0);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ return ret;
+
+cleanup:
+ for (j=0;j<i;i++)
+ gnutls_x509_crt_deinit(new_list[j]);
+
+ return ret;
}
+
/**
* gnutls_certificate_set_x509_trust_file:
* @res: is a #gnutls_certificate_credentials_t structure.
@@ -1379,7 +1322,7 @@ gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t res,
const char *cafile,
gnutls_x509_crt_fmt_t type)
{
- int ret, ret2;
+ int ret;
size_t size;
char *data;
@@ -1396,9 +1339,9 @@ gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t res,
}
if (type == GNUTLS_X509_FMT_DER)
- ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
+ ret = parse_der_ca_mem (res, data, size);
else
- ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
+ ret = parse_pem_ca_mem (res, data, size);
free (data);
@@ -1408,140 +1351,84 @@ gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t res,
return ret;
}
- if ((ret2 = add_new_crt_to_rdn_seq (res, ret)) < 0)
- return ret2;
-
return ret;
}
#ifdef ENABLE_PKI
static int
-parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
+parse_pem_crl_mem (gnutls_x509_trust_list_t tlist,
const opaque * input_crl, int input_crl_size)
{
- int size, i;
- const opaque *ptr;
- gnutls_datum_t tmp;
- int ret, count;
+ gnutls_x509_crl_t *x509_crl_list;
+ unsigned int x509_ncrls;
+ gnutls_datum tmp;
+ int ret;
- /* move to the certificate
- */
- ptr = memmem (input_crl, input_crl_size,
- PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
- if (ptr == NULL)
+ tmp.data = (void*)input_crl;
+ tmp.size = input_crl_size;
+
+ ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
+ GNUTLS_X509_FMT_PEM, 0);
+ if (ret < 0)
{
- gnutls_assert ();
- return GNUTLS_E_BASE64_DECODING_ERROR;
+ gnutls_assert();
+ return ret;
}
- size = input_crl_size - (ptr - input_crl);
-
- i = *ncrls + 1;
- count = 0;
-
- do
+ ret = gnutls_x509_trust_list_add_crls(tlist, x509_crl_list, x509_ncrls, 0, 0);
+ if (ret < 0)
{
-
- *crl_list =
- (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
- i *
- sizeof
- (gnutls_x509_crl_t));
-
- if (*crl_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- tmp.data = (char *) ptr;
- tmp.size = size;
-
- ret =
- gnutls_x509_crl_import (crl_list[0][i - 1],
- &tmp, GNUTLS_X509_FMT_PEM);
- if (ret < 0)
- {
- gnutls_assert ();
- return ret;
- }
-
- /* now we move ptr after the pem header
- */
- ptr++;
- /* find the next certificate (if any)
- */
-
- size = input_crl_size - (ptr - input_crl);
-
- if (size > 0)
- ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
- else
- ptr = NULL;
- i++;
- count++;
-
+ gnutls_assert();
+ goto cleanup;
}
- while (ptr != NULL);
-
- *ncrls = i - 1;
- return count;
+cleanup:
+ gnutls_free(x509_crl_list);
+ return ret;
}
/* Reads a DER encoded certificate list from memory and stores it to a
* gnutls_cert structure. Returns the number of certificates parsed.
*/
static int
-parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
+parse_der_crl_mem (gnutls_x509_trust_list_t tlist,
const void *input_crl, int input_crl_size)
{
- int i;
- gnutls_datum_t tmp;
+ gnutls_x509_crl_t crl;
+ gnutls_datum tmp;
int ret;
- i = *ncrls + 1;
-
- *crl_list =
- (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
- i *
- sizeof (gnutls_x509_crl_t));
+ tmp.data = (void*)input_crl;
+ tmp.size = input_crl_size;
- if (*crl_list == NULL)
+ ret = gnutls_x509_crl_init( &crl);
+ if (ret < 0)
{
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
+ gnutls_assert();
+ return ret;
}
- tmp.data = (opaque *) input_crl;
- tmp.size = input_crl_size;
-
- ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
+ ret = gnutls_x509_crl_import( crl, &tmp, GNUTLS_X509_FMT_DER);
if (ret < 0)
{
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ goto cleanup;
}
- ret =
- gnutls_x509_crl_import (crl_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
+ ret = gnutls_x509_trust_list_add_crls(tlist, &crl, 1, 0, 0);
if (ret < 0)
{
- gnutls_assert ();
- return ret;
+ gnutls_assert();
+ goto cleanup;
}
- *ncrls = i;
+ return ret;
+
+cleanup:
+ gnutls_x509_crl_deinit(crl);
+ return ret;
- return 1; /* one certificate parsed */
}
@@ -1553,29 +1440,14 @@ read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
{
int ret;
- /* allocate space for the certificate to add
- */
- res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
- (1 +
- res->x509_ncrls) *
- sizeof (gnutls_x509_crl_t));
- if (res->x509_crl_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
if (type == GNUTLS_X509_FMT_DER)
- ret = parse_der_crl_mem (&res->x509_crl_list,
- &res->x509_ncrls, crl, crl_size);
+ ret = parse_der_crl_mem (res->tlist, crl, crl_size);
else
- ret = parse_pem_crl_mem (&res->x509_crl_list,
- &res->x509_ncrls, crl, crl_size);
+ ret = parse_pem_crl_mem (res->tlist, crl, crl_size);
if (ret < 0)
{
gnutls_assert ();
- return ret;
}
return ret;
@@ -1600,12 +1472,7 @@ gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res,
const gnutls_datum_t * CRL,
gnutls_x509_crt_fmt_t type)
{
- int ret;
-
- if ((ret = read_crl_mem (res, CRL->data, CRL->size, type)) < 0)
- return ret;
-
- return ret;
+ return read_crl_mem (res, CRL->data, CRL->size, type);
}
/**
@@ -1629,38 +1496,40 @@ gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
gnutls_x509_crl_t * crl_list,
int crl_list_size)
{
- int ret, i;
-
- res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
- (crl_list_size +
- res->x509_ncrls) *
- sizeof (gnutls_x509_crl_t));
- if (res->x509_crl_list == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
+ int ret, i, j;
+ gnutls_x509_crl_t new_crl[crl_list_size];
for (i = 0; i < crl_list_size; i++)
{
- ret = gnutls_x509_crl_init (&res->x509_crl_list[res->x509_ncrls]);
+ ret = gnutls_x509_crl_init (&new_crl[i]);
if (ret < 0)
{
gnutls_assert ();
- return ret;
+ goto cleanup;
}
- ret = _gnutls_x509_crl_cpy (res->x509_crl_list[res->x509_ncrls],
- crl_list[i]);
+ ret = _gnutls_x509_crl_cpy (new_crl[i], crl_list[i]);
if (ret < 0)
{
gnutls_assert ();
- return ret;
+ goto cleanup;
}
- res->x509_ncrls++;
}
- return 0;
+ ret = gnutls_x509_trust_list_add_crls(res->tlist, new_crl, crl_list_size, 0, 0);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ return ret;
+
+cleanup:
+ for (j=0;j<i;j++)
+ gnutls_x509_crl_deinit(new_crl[j]);
+
+ return ret;
}
/**
@@ -1693,11 +1562,9 @@ gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t res,
}
if (type == GNUTLS_X509_FMT_DER)
- ret = parse_der_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
- data, size);
+ ret = parse_der_crl_mem (res->tlist, data, size);
else
- ret = parse_pem_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
- data, size);
+ ret = parse_pem_crl_mem (res->tlist, data, size);
free (data);
@@ -2194,17 +2061,8 @@ done:
void
gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
{
- unsigned j;
-
- for (j = 0; j < sc->x509_ncrls; j++)
- {
- gnutls_x509_crl_deinit (sc->x509_crl_list[j]);
- }
-
- sc->x509_ncrls = 0;
-
- gnutls_free (sc->x509_crl_list);
- sc->x509_crl_list = NULL;
+ /* do nothing for now */
+ return;
}
#endif
diff --git a/lib/includes/gnutls/compat.h b/lib/includes/gnutls/compat.h
index f283f8f20e..a047dc89a7 100644
--- a/lib/includes/gnutls/compat.h
+++ b/lib/includes/gnutls/compat.h
@@ -308,5 +308,18 @@ gnutls_sign_callback_get (gnutls_session_t session, void **userdata)
unsigned int flags)
_GNUTLS_GCC_ATTR_DEPRECATED;
+/* These functions cannot be supported. They export internal
+ * structure.
+ */
+ void gnutls_certificate_get_x509_cas (gnutls_certificate_credentials_t sc,
+ gnutls_x509_crt_t ** x509_ca_list,
+ unsigned int *ncas)
+ _GNUTLS_GCC_ATTR_DEPRECATED;
+
+ void gnutls_certificate_get_x509_crls (gnutls_certificate_credentials_t sc,
+ gnutls_x509_crl_t ** x509_crl_list,
+ unsigned int *ncrls)
+ _GNUTLS_GCC_ATTR_DEPRECATED;
+
#endif /* _GNUTLS_COMPAT_H */
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index fe9909ab1d..cd0b96b771 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1107,14 +1107,6 @@ extern "C"
gnutls_x509_crl_t * crl_list,
int crl_list_size);
- void gnutls_certificate_get_x509_cas (gnutls_certificate_credentials_t sc,
- gnutls_x509_crt_t ** x509_ca_list,
- unsigned int *ncas);
-
- void gnutls_certificate_get_x509_crls (gnutls_certificate_credentials_t sc,
- gnutls_x509_crl_t ** x509_crl_list,
- unsigned int *ncrls);
-
void
gnutls_certificate_get_openpgp_keyring (gnutls_certificate_credentials_t
sc,
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index 85ee4cc8f7..7cbc81057b 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -105,6 +105,10 @@ extern "C"
int gnutls_x509_crt_import (gnutls_x509_crt_t cert,
const gnutls_datum_t * data,
gnutls_x509_crt_fmt_t format);
+ int gnutls_x509_crt_list_import2 (gnutls_x509_crt_t ** certs,
+ unsigned int * size,
+ const gnutls_datum_t * data,
+ gnutls_x509_crt_fmt_t format, unsigned int flags);
int gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
unsigned int *cert_max,
const gnutls_datum_t * data,
@@ -426,6 +430,11 @@ extern "C"
int gnutls_x509_crl_check_issuer (gnutls_x509_crl_t crl,
gnutls_x509_crt_t issuer);
+ int gnutls_x509_crl_list_import2 (gnutls_x509_crl_t ** crls,
+ unsigned int * size,
+ const gnutls_datum_t * data,
+ gnutls_x509_crt_fmt_t format, unsigned int flags);
+
int gnutls_x509_crl_list_import (gnutls_x509_crl_t * crls,
unsigned int *crl_max,
const gnutls_datum_t * data,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 85f5db4109..623c0fd39a 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -701,6 +701,8 @@ GNUTLS_2_12
gnutls_x509_trust_list_init;
gnutls_x509_trust_list_deinit;
gnutls_x509_crl_list_import;
+ gnutls_x509_crl_list_import2;
+ gnutls_x509_crt_list_import2;
} GNUTLS_2_10;
GNUTLS_PRIVATE {
diff --git a/lib/x509/crl.c b/lib/x509/crl.c
index 4438db5b21..fca657fde7 100644
--- a/lib/x509/crl.c
+++ b/lib/x509/crl.c
@@ -1026,6 +1026,63 @@ gnutls_x509_crl_get_extension_data (gnutls_x509_crl_t crl, int indx,
}
/**
+ * gnutls_x509_crl_list_import2:
+ * @crls: The structures to store the parsed crl list. Must not be initialized.
+ * @size: It will contain the size of the list.
+ * @data: The PEM encoded CRL.
+ * @format: One of DER or PEM.
+ * @flags: must be zero or an OR'd sequence of gnutls_certificate_import_flags.
+ *
+ * This function will convert the given PEM encoded CRL list
+ * to the native gnutls_x509_crl_t format. The output will be stored
+ * in @crls. They will be automatically initialized.
+ *
+ * If the Certificate is PEM encoded it should have a header of "X509
+ * CRL".
+ *
+ * Returns: the number of certificates read or a negative error value.
+ **/
+int
+gnutls_x509_crl_list_import2 (gnutls_x509_crl_t ** crls,
+ unsigned int * size,
+ const gnutls_datum_t * data,
+ gnutls_x509_crt_fmt_t format, unsigned int flags)
+{
+unsigned int init = 1024;
+int ret;
+
+ *crls = gnutls_malloc(sizeof(gnutls_x509_crl_t*)*init);
+ if (*crls == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crl_list_import(*crls, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
+ if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ *crls = gnutls_realloc_fast(*crls, sizeof(gnutls_x509_crl_t*)*init);
+ if (*crls == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crl_list_import(*crls, &init, data, format, flags);
+ }
+
+ if (ret < 0)
+ {
+ gnutls_free(*crls);
+ *crls = NULL;
+ return ret;
+ }
+
+ *size = init;
+ return 0;
+}
+
+/**
* gnutls_x509_crl_list_import:
* @crls: The structures to store the parsed CRLs. Must not be initialized.
* @crl_max: Initially must hold the maximum number of crls. It will be updated with the number of crls available.
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 2755cc6e71..300ee8e674 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -3078,6 +3078,63 @@ cleanup:
}
#endif
+/**
+ * gnutls_x509_crt_list_import2:
+ * @certs: The structures to store the parsed certificate. Must not be initialized.
+ * @size: It will contain the size of the list.
+ * @data: The PEM encoded certificate.
+ * @format: One of DER or PEM.
+ * @flags: must be zero or an OR'd sequence of gnutls_certificate_import_flags.
+ *
+ * This function will convert the given PEM encoded certificate list
+ * to the native gnutls_x509_crt_t format. The output will be stored
+ * in @certs. They will be automatically initialized.
+ *
+ * If the Certificate is PEM encoded it should have a header of "X509
+ * CERTIFICATE", or "CERTIFICATE".
+ *
+ * Returns: the number of certificates read or a negative error value.
+ **/
+int
+gnutls_x509_crt_list_import2 (gnutls_x509_crt_t ** certs,
+ unsigned int * size,
+ const gnutls_datum_t * data,
+ gnutls_x509_crt_fmt_t format, unsigned int flags)
+{
+unsigned int init = 1024;
+int ret;
+
+ *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t*)*init);
+ if (*certs == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crt_list_import(*certs, &init, data, format, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
+ if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ *certs = gnutls_realloc_fast(*certs, sizeof(gnutls_x509_crt_t*)*init);
+ if (*certs == NULL)
+ {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ ret = gnutls_x509_crt_list_import(*certs, &init, data, format, flags);
+ }
+
+ if (ret < 0)
+ {
+ gnutls_free(*certs);
+ *certs = NULL;
+ return ret;
+ }
+
+ *size = init;
+ return 0;
+}
+
/**
* gnutls_x509_crt_list_import:
diff --git a/src/certtool.c b/src/certtool.c
index cdb8b222b3..ae946b4457 100644
--- a/src/certtool.c
+++ b/src/certtool.c
@@ -1925,8 +1925,6 @@ generate_request (common_info_st * cinfo)
static void print_verification_res (FILE* outfile, unsigned int output);
-#define MAX_LIST 512
-
static int detailed_verification(gnutls_x509_crt_t cert,
gnutls_x509_crt_t issuer, gnutls_x509_crl_t crl,
unsigned int verification_output)
@@ -2005,8 +2003,8 @@ _verify_x509_mem (const void *cert, int cert_size)
{
int ret;
gnutls_datum_t tmp;
- gnutls_x509_crt_t x509_cert_list[MAX_LIST];
- gnutls_x509_crl_t x509_crl_list[MAX_LIST];
+ gnutls_x509_crt_t *x509_cert_list = NULL;
+ gnutls_x509_crl_t *x509_crl_list = NULL;
unsigned int x509_ncerts, x509_ncrls = 0;
gnutls_x509_trust_list_t list;
unsigned int output;
@@ -2014,19 +2012,18 @@ _verify_x509_mem (const void *cert, int cert_size)
tmp.data = (void*)cert;
tmp.size = cert_size;
- x509_ncrls = MAX_LIST;
- ret = gnutls_x509_crl_list_import( x509_crl_list, &x509_ncrls, &tmp,
- GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
+ ret = gnutls_x509_crl_list_import2( &x509_crl_list, &x509_ncrls, &tmp,
+ GNUTLS_X509_FMT_PEM, 0);
if (ret < 0)
{
+ x509_crl_list = NULL;
x509_ncrls = 0;
}
/* ignore errors. CRL might not be given */
- x509_ncerts = MAX_LIST;
- ret = gnutls_x509_crt_list_import( x509_cert_list, &x509_ncerts, &tmp,
- GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
+ ret = gnutls_x509_crt_list_import2( &x509_cert_list, &x509_ncerts, &tmp,
+ GNUTLS_X509_FMT_PEM, 0);
if (ret < 0 || x509_ncerts < 1)
error (EXIT_FAILURE, 0, "error parsing CRTs: %s",
gnutls_strerror (ret));
@@ -2048,6 +2045,8 @@ _verify_x509_mem (const void *cert, int cert_size)
error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_crls: %s",
gnutls_strerror (ret));
+ gnutls_free(x509_crl_list);
+
ret = gnutls_x509_trust_list_verify_crt (list, x509_cert_list, x509_ncerts,
GNUTLS_VERIFY_DO_NOT_ALLOW_SAME|GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, &output,
detailed_verification);
@@ -2083,6 +2082,7 @@ _verify_x509_mem (const void *cert, int cert_size)
}
}
+ gnutls_free(x509_cert_list);
gnutls_x509_trust_list_deinit(list, 1);
if (ret < 0)
diff --git a/tests/certificate_set_x509_crl.c b/tests/certificate_set_x509_crl.c
index 20ebb3085a..8f39898f5a 100644
--- a/tests/certificate_set_x509_crl.c
+++ b/tests/certificate_set_x509_crl.c
@@ -94,7 +94,7 @@ main (void)
}
rc = gnutls_certificate_set_x509_crl (crt, &crl, 1);
- if (rc)
+ if (rc < 0)
{
printf ("gnutls_certificate_set_x509_crl rc %d: %s\n",
rc, gnutls_strerror (rc));