summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-08-08 11:35:26 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-08-08 16:10:51 +0200
commitdcc956872958ec62352d422d394d509c43ffdd32 (patch)
tree82b19da44d9ae6e3aa3aef8900d4beb1eb1d18ba
parente1e03f7e1d4258dda65d6258a04db60eb0b77f86 (diff)
downloadgnutls-dcc956872958ec62352d422d394d509c43ffdd32.tar.gz
gnutls_certificate_credentials_t: combine privkey into cert_st structure
This reduces the number of applications and allows for easier use of the structure information, as they are now self-contained for most uses. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/auth/cert.c8
-rw-r--r--lib/auth/cert.h16
-rw-r--r--lib/cert.c14
-rw-r--r--lib/x509.c119
4 files changed, 61 insertions, 96 deletions
diff --git a/lib/auth/cert.c b/lib/auth/cert.c
index c66f4f2950..5fd2286266 100644
--- a/lib/auth/cert.c
+++ b/lib/auth/cert.c
@@ -596,7 +596,7 @@ select_client_cert(gnutls_session_t session,
cert_list[0],
cred->certs[indx].
cert_list_length,
- cred->pkey[indx], 0,
+ cred->certs[indx].pkey, 0,
NULL, NULL);
} else {
_gnutls_selected_certs_set(session, NULL, 0, NULL, 0,
@@ -1567,7 +1567,7 @@ _gnutls_server_select_cert(gnutls_session_t session, const gnutls_cipher_suite_e
ret = select_sign_algorithm(session,
&cred->certs[i].cert_list[0],
- cred->pkey[i],
+ cred->certs[i].pkey,
cs);
if (ret >= 0) {
idx = i;
@@ -1604,7 +1604,7 @@ _gnutls_server_select_cert(gnutls_session_t session, const gnutls_cipher_suite_e
ret = select_sign_algorithm(session,
&cred->certs[i].cert_list[0],
- cred->pkey[i],
+ cred->certs[i].pkey,
cs);
if (ret >= 0) {
idx = i;
@@ -1626,7 +1626,7 @@ _gnutls_server_select_cert(gnutls_session_t session, const gnutls_cipher_suite_e
_gnutls_selected_certs_set(session,
&cred->certs[idx].cert_list[0],
cred->certs[idx].cert_list_length,
- cred->pkey[idx], 0,
+ cred->certs[idx].pkey, 0,
cred->certs[idx].ocsp_func,
cred->certs[idx].ocsp_func_ptr);
} else {
diff --git a/lib/auth/cert.h b/lib/auth/cert.h
index 2d72762722..be6945dd21 100644
--- a/lib/auth/cert.h
+++ b/lib/auth/cert.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2002-2012 Free Software Foundation, Inc.
+ * Copyright (C) 2016-2017 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -37,6 +38,9 @@ typedef struct {
gnutls_status_request_ocsp_func ocsp_func;
void *ocsp_func_ptr; /* corresponding OCSP response function + ptr */
char *ocsp_response_file; /* corresponding OCSP response file */
+
+ /* the private key corresponding to certificate */
+ gnutls_privkey_t pkey;
} certs_st;
/* This structure may be complex, but it's the only way to
@@ -55,12 +59,6 @@ typedef struct gnutls_certificate_credentials_st {
certs_st *certs;
unsigned ncerts; /* the number of certs */
- gnutls_privkey_t *pkey;
- /* private keys. It contains ncerts private
- * keys. pkey[i] corresponds to certificate in
- * cert_list[i][0].
- */
-
/* X509 specific stuff */
gnutls_x509_trust_list_t tlist;
unsigned flags; /* gnutls_certificate_flags */
@@ -133,12 +131,6 @@ int _gnutls_get_auth_info_pcert(gnutls_pcert_st * gcert,
gnutls_certificate_type_t type,
cert_auth_info_t info);
-int certificate_credential_append_crt_list(gnutls_certificate_credentials_t
- res, gnutls_str_array_t names,
- gnutls_pcert_st * crt, int nr);
-int certificate_credentials_append_pkey(gnutls_certificate_credentials_t
- res, gnutls_privkey_t pkey);
-
int _gnutls_selected_cert_supported_kx(struct gnutls_session_int *session,
gnutls_kx_algorithm_t * alg,
int *alg_size);
diff --git a/lib/cert.c b/lib/cert.c
index b53ad21fb1..4defec87e2 100644
--- a/lib/cert.c
+++ b/lib/cert.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2016 Free Software Foundation, Inc.
- * Copyright (C) 2015-2016 Red Hat, Inc.
+ * Copyright (C) 2015-2017 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -62,18 +62,12 @@ void gnutls_certificate_free_keys(gnutls_certificate_credentials_t sc)
gnutls_free(sc->certs[i].cert_list);
gnutls_free(sc->certs[i].ocsp_response_file);
_gnutls_str_array_clear(&sc->certs[i].names);
+ gnutls_privkey_deinit(sc->certs[i].pkey);
}
gnutls_free(sc->certs);
sc->certs = NULL;
- for (i = 0; i < sc->ncerts; i++) {
- gnutls_privkey_deinit(sc->pkey[i]);
- }
-
- gnutls_free(sc->pkey);
- sc->pkey = NULL;
-
sc->ncerts = 0;
}
@@ -684,7 +678,7 @@ int _gnutls_check_key_cert_match(gnutls_certificate_credentials_t res)
gnutls_pubkey_get_pk_algorithm(res->certs[res->ncerts - 1].
cert_list[0].pubkey, NULL);
pk2 =
- gnutls_privkey_get_pk_algorithm(res->pkey[res->ncerts - 1],
+ gnutls_privkey_get_pk_algorithm(res->certs[res->ncerts - 1].pkey,
NULL);
if (GNUTLS_PK_IS_RSA(pk) && GNUTLS_PK_IS_RSA(pk2)) {
@@ -707,7 +701,7 @@ int _gnutls_check_key_cert_match(gnutls_certificate_credentials_t res)
/* now check if keys really match. We use the sign/verify approach
* because we cannot always obtain the parameters from the abstract
* keys (e.g. PKCS #11). */
- ret = gnutls_privkey_sign_data2(res->pkey[res->ncerts - 1],
+ ret = gnutls_privkey_sign_data2(res->certs[res->ncerts - 1].pkey,
sign_algo, 0, &test, &sig);
if (ret < 0) {
/* for some reason we couldn't sign that. That shouldn't have
diff --git a/lib/x509.c b/lib/x509.c
index 3e64fb14a8..d1171dc7c7 100644
--- a/lib/x509.c
+++ b/lib/x509.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2016 Free Software Foundation, Inc.
- * Copyright (C) 2016 Red Hat, Inc.
+ * Copyright (C) 2016-2017 Red Hat, Inc.
*
* Author: Nikos Mavrogiannopoulos
*
@@ -56,6 +56,12 @@
* some x509 certificate parsing functions.
*/
+static int
+certificate_credential_append_crt_list(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
+ gnutls_str_array_t names,
+ gnutls_pcert_st * crt, int nr);
+
#define CRED_RET_SUCCESS(cred) \
if (cred->flags & GNUTLS_CERTIFICATE_API_V2) { \
return cred->ncerts-1; \
@@ -475,6 +481,7 @@ static int get_x509_name(gnutls_x509_crt_t crt, gnutls_str_array_t * names)
*/
static int
parse_der_cert_mem(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
const void *input_cert, int input_cert_size)
{
gnutls_datum_t tmp;
@@ -522,7 +529,7 @@ parse_der_cert_mem(gnutls_certificate_credentials_t res,
goto cleanup;
}
- ret = certificate_credential_append_crt_list(res, names, ccert, 1);
+ ret = certificate_credential_append_crt_list(res, key, names, ccert, 1);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -541,6 +548,7 @@ parse_der_cert_mem(gnutls_certificate_credentials_t res,
*/
static int
parse_pem_cert_mem(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
const char *input_cert, int input_cert_size)
{
int size;
@@ -637,7 +645,7 @@ parse_pem_cert_mem(gnutls_certificate_credentials_t res,
}
ret =
- certificate_credential_append_crt_list(res, names, pcerts,
+ certificate_credential_append_crt_list(res, key, names, pcerts,
ncerts);
if (ret < 0) {
gnutls_assert();
@@ -666,15 +674,17 @@ parse_pem_cert_mem(gnutls_certificate_credentials_t res,
/* Reads a DER or PEM certificate from memory
*/
static int
-read_cert_mem(gnutls_certificate_credentials_t res, const void *cert,
+read_cert_mem(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
+ const void *cert,
int cert_size, gnutls_x509_crt_fmt_t type)
{
int ret;
if (type == GNUTLS_X509_FMT_DER)
- ret = parse_der_cert_mem(res, cert, cert_size);
+ ret = parse_der_cert_mem(res, key, cert, cert_size);
else
- ret = parse_pem_cert_mem(res, cert, cert_size);
+ ret = parse_pem_cert_mem(res, key, cert, cert_size);
if (ret < 0) {
gnutls_assert();
@@ -699,13 +709,15 @@ static int tmp_pin_cb(void *userdata, int attempt, const char *token_url,
}
/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
- * indicates the certificate format. KEY can be NULL, to indicate
- * that GnuTLS doesn't know the private key.
+ * indicates the certificate format.
+ *
+ * It returns the private key read in @rkey.
*/
static int
read_key_mem(gnutls_certificate_credentials_t res,
const void *key, int key_size, gnutls_x509_crt_fmt_t type,
- const char *pass, unsigned int flags)
+ const char *pass, unsigned int flags,
+ gnutls_privkey_t *rkey)
{
int ret;
gnutls_datum_t tmp;
@@ -742,19 +754,12 @@ read_key_mem(gnutls_certificate_credentials_t res,
return ret;
}
- ret = certificate_credentials_append_pkey(res, privkey);
- if (ret < 0) {
- gnutls_assert();
- gnutls_privkey_deinit(privkey);
- return ret;
- }
-
+ *rkey = privkey;
} else {
gnutls_assert();
return GNUTLS_E_INVALID_REQUEST;
}
-
return 0;
}
@@ -762,7 +767,7 @@ read_key_mem(gnutls_certificate_credentials_t res,
/* Reads a private key from a token.
*/
static int
-read_key_url(gnutls_certificate_credentials_t res, const char *url)
+read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey)
{
int ret;
gnutls_privkey_t pkey = NULL;
@@ -785,11 +790,7 @@ read_key_url(gnutls_certificate_credentials_t res, const char *url)
goto cleanup;
}
- ret = certificate_credentials_append_pkey(res, pkey);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
+ *rkey = pkey;
return 0;
@@ -805,7 +806,7 @@ read_key_url(gnutls_certificate_credentials_t res, const char *url)
/* Reads a certificate key from a token.
*/
static int
-read_cert_url(gnutls_certificate_credentials_t res, const char *url)
+read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const char *url)
{
int ret;
gnutls_x509_crt_t crt = NULL;
@@ -885,7 +886,7 @@ read_cert_url(gnutls_certificate_credentials_t res, const char *url)
t.data = NULL;
}
- ret = certificate_credential_append_crt_list(res, names, ccert, count);
+ ret = certificate_credential_append_crt_list(res, key, names, ccert, count);
if (ret < 0) {
gnutls_assert();
goto cleanup;
@@ -908,6 +909,7 @@ cleanup:
*/
static int
read_cert_file(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
const char *certfile, gnutls_x509_crt_fmt_t type)
{
int ret;
@@ -915,7 +917,7 @@ read_cert_file(gnutls_certificate_credentials_t res,
char *data;
if (gnutls_url_is_supported(certfile)) {
- return read_cert_url(res, certfile);
+ return read_cert_url(res, key, certfile);
}
data = read_binary_file(certfile, &size);
@@ -925,7 +927,7 @@ read_cert_file(gnutls_certificate_credentials_t res,
return GNUTLS_E_FILE_ERROR;
}
- ret = read_cert_mem(res, data, size, type);
+ ret = read_cert_mem(res, key, data, size, type);
free(data);
return ret;
@@ -940,7 +942,8 @@ read_cert_file(gnutls_certificate_credentials_t res,
static int
read_key_file(gnutls_certificate_credentials_t res,
const char *keyfile, gnutls_x509_crt_fmt_t type,
- const char *pass, unsigned int flags)
+ const char *pass, unsigned int flags,
+ gnutls_privkey_t *rkey)
{
int ret;
size_t size;
@@ -955,7 +958,7 @@ read_key_file(gnutls_certificate_credentials_t res,
gnutls_certificate_set_pin_function(res, tmp_pin_cb, res->pin_tmp);
}
- return read_key_url(res, keyfile);
+ return read_key_url(res, keyfile, rkey);
} else
return
gnutls_assert_val
@@ -969,7 +972,7 @@ read_key_file(gnutls_certificate_credentials_t res,
return GNUTLS_E_FILE_ERROR;
}
- ret = read_key_mem(res, data, size, type, pass, flags);
+ ret = read_key_mem(res, data, size, type, pass, flags, rkey);
free(data);
return ret;
@@ -1052,16 +1055,17 @@ gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
const char *pass, unsigned int flags)
{
int ret;
+ gnutls_privkey_t rkey;
/* this should be first
*/
if ((ret = read_key_mem(res, key ? key->data : NULL,
key ? key->size : 0, type, pass,
- flags)) < 0)
+ flags, &rkey)) < 0)
return ret;
- if ((ret = read_cert_mem(res, cert->data, cert->size, type)) < 0) {
- gnutls_privkey_deinit(res->pkey[res->ncerts]);
+ if ((ret = read_cert_mem(res, rkey, cert->data, cert->size, type)) < 0) {
+ gnutls_privkey_deinit(rkey);
return ret;
}
@@ -1075,9 +1079,10 @@ gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
CRED_RET_SUCCESS(res);
}
-int
-certificate_credential_append_crt_list(gnutls_certificate_credentials_t
- res, gnutls_str_array_t names,
+static int
+certificate_credential_append_crt_list(gnutls_certificate_credentials_t res,
+ gnutls_privkey_t key,
+ gnutls_str_array_t names,
gnutls_pcert_st * crt, int nr)
{
res->certs = gnutls_realloc_fast(res->certs,
@@ -1093,27 +1098,12 @@ certificate_credential_append_crt_list(gnutls_certificate_credentials_t
res->certs[res->ncerts].cert_list = crt;
res->certs[res->ncerts].cert_list_length = nr;
res->certs[res->ncerts].names = names;
+ res->certs[res->ncerts].pkey = key;
return 0;
}
-int
-certificate_credentials_append_pkey(gnutls_certificate_credentials_t res,
- gnutls_privkey_t pkey)
-{
- res->pkey = gnutls_realloc_fast(res->pkey,
- (1 + res->ncerts) *
- sizeof(gnutls_privkey_t));
- if (res->pkey == NULL) {
- gnutls_assert();
- return GNUTLS_E_MEMORY_ERROR;
- }
- res->pkey[res->ncerts] = pkey;
- return 0;
-
-}
-
/**
* gnutls_certificate_set_x509_key:
* @res: is a #gnutls_certificate_credentials_t type.
@@ -1175,12 +1165,6 @@ gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
return ret;
}
- ret = certificate_credentials_append_pkey(res, pkey);
- if (ret < 0) {
- gnutls_assert();
- return ret;
- }
-
/* load certificates */
pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * cert_list_size);
if (pcerts == NULL) {
@@ -1203,7 +1187,7 @@ gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
}
ret =
- certificate_credential_append_crt_list(res, names, pcerts,
+ certificate_credential_append_crt_list(res, pkey, names, pcerts,
cert_list_size);
if (ret < 0) {
gnutls_assert();
@@ -1263,7 +1247,7 @@ gnutls_certificate_get_x509_key(gnutls_certificate_credentials_t res,
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
}
- return gnutls_privkey_export_x509(res->pkey[index], key);
+ return gnutls_privkey_export_x509(res->certs[index].pkey, key);
}
/**
@@ -1415,12 +1399,6 @@ gnutls_certificate_set_key(gnutls_certificate_credentials_t res,
gnutls_privkey_set_pin_function(key, res->pin.cb,
res->pin.data);
- ret = certificate_credentials_append_pkey(res, key);
- if (ret < 0) {
- gnutls_assert();
- goto cleanup;
- }
-
new_pcert_list = gnutls_malloc(sizeof(gnutls_pcert_st) * pcert_list_size);
if (new_pcert_list == NULL) {
gnutls_assert();
@@ -1429,7 +1407,7 @@ gnutls_certificate_set_key(gnutls_certificate_credentials_t res,
memcpy(new_pcert_list, pcert_list, sizeof(gnutls_pcert_st) * pcert_list_size);
ret =
- certificate_credential_append_crt_list(res, str_names,
+ certificate_credential_append_crt_list(res, key, str_names,
new_pcert_list,
pcert_list_size);
if (ret < 0) {
@@ -1599,15 +1577,16 @@ gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res,
const char *pass, unsigned int flags)
{
int ret;
+ gnutls_privkey_t rkey;
/* this should be first
*/
- if ((ret = read_key_file(res, keyfile, type, pass, flags)) < 0)
+ if ((ret = read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
return ret;
- if ((ret = read_cert_file(res, certfile, type)) < 0) {
- gnutls_privkey_deinit(res->pkey[res->ncerts]);
+ if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) {
+ gnutls_privkey_deinit(rkey);
return ret;
}