summaryrefslogtreecommitdiffstats
path: root/src/ssl/ssl_cert.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ssl/ssl_cert.c')
-rw-r--r--src/ssl/ssl_cert.c254
1 files changed, 78 insertions, 176 deletions
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 624c41a..770912b 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -112,7 +112,9 @@
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
+#include <errno.h>
#include <stdio.h>
+#include <string.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
@@ -126,7 +128,7 @@
#include "../crypto/dh/internal.h"
#include "../crypto/directory.h"
-#include "ssl_locl.h"
+#include "internal.h"
int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
@@ -178,7 +180,6 @@ CERT *ssl_cert_dup(CERT *cert) {
OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
return NULL;
}
-
memset(ret, 0, sizeof(CERT));
ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
@@ -213,15 +214,8 @@ CERT *ssl_cert_dup(CERT *cert) {
}
ret->dh_tmp_cb = cert->dh_tmp_cb;
- if (cert->ecdh_tmp) {
- ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
- if (ret->ecdh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_EC_LIB);
- goto err;
- }
- }
+ ret->ecdh_nid = cert->ecdh_nid;
ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
- ret->ecdh_tmp_auto = cert->ecdh_tmp_auto;
for (i = 0; i < SSL_PKEY_NUM; i++) {
CERT_PKEY *cpk = cert->pkeys + i;
@@ -231,7 +225,7 @@ CERT *ssl_cert_dup(CERT *cert) {
}
if (cpk->privatekey != NULL) {
- rpk->privatekey = EVP_PKEY_dup(cpk->privatekey);
+ rpk->privatekey = EVP_PKEY_up_ref(cpk->privatekey);
}
if (cpk->chain) {
@@ -243,34 +237,24 @@ CERT *ssl_cert_dup(CERT *cert) {
}
}
- /* Peer sigalgs set to NULL as we get these from handshake too */
- ret->peer_sigalgs = NULL;
- ret->peer_sigalgslen = 0;
- /* Configured sigalgs however we copy across */
-
+ /* Copy over signature algorithm configuration. */
if (cert->conf_sigalgs) {
- ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
+ ret->conf_sigalgs = BUF_memdup(cert->conf_sigalgs, cert->conf_sigalgslen);
if (!ret->conf_sigalgs) {
goto err;
}
- memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen);
ret->conf_sigalgslen = cert->conf_sigalgslen;
- } else {
- ret->conf_sigalgs = NULL;
}
if (cert->client_sigalgs) {
- ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
+ ret->client_sigalgs = BUF_memdup(cert->client_sigalgs,
+ cert->client_sigalgslen);
if (!ret->client_sigalgs) {
goto err;
}
- memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen);
ret->client_sigalgslen = cert->client_sigalgslen;
- } else {
- ret->client_sigalgs = NULL;
}
- /* Shared sigalgs also NULL */
- ret->shared_sigalgs = NULL;
+
/* Copy any custom client certificate types */
if (cert->client_certificate_types) {
ret->client_certificate_types = BUF_memdup(
@@ -281,8 +265,6 @@ CERT *ssl_cert_dup(CERT *cert) {
ret->num_client_certificate_types = cert->num_client_certificate_types;
}
- ret->cert_flags = cert->cert_flags;
-
ret->cert_cb = cert->cert_cb;
ret->cert_cb_arg = cert->cert_cb_arg;
@@ -296,8 +278,6 @@ CERT *ssl_cert_dup(CERT *cert) {
ret->chain_store = cert->chain_store;
}
- ret->ciphers_raw = NULL;
-
return ret;
err:
@@ -334,79 +314,32 @@ void ssl_cert_free(CERT *c) {
return;
}
- if (c->dh_tmp) {
- DH_free(c->dh_tmp);
- }
- if (c->ecdh_tmp) {
- EC_KEY_free(c->ecdh_tmp);
- }
+ DH_free(c->dh_tmp);
ssl_cert_clear_certs(c);
- if (c->peer_sigalgs) {
- OPENSSL_free(c->peer_sigalgs);
- }
- if (c->conf_sigalgs) {
- OPENSSL_free(c->conf_sigalgs);
- }
- if (c->client_sigalgs) {
- OPENSSL_free(c->client_sigalgs);
- }
- if (c->shared_sigalgs) {
- OPENSSL_free(c->shared_sigalgs);
- }
- if (c->client_certificate_types) {
- OPENSSL_free(c->client_certificate_types);
- }
- if (c->verify_store) {
- X509_STORE_free(c->verify_store);
- }
- if (c->chain_store) {
- X509_STORE_free(c->chain_store);
- }
- if (c->ciphers_raw) {
- OPENSSL_free(c->ciphers_raw);
- }
+ OPENSSL_free(c->peer_sigalgs);
+ OPENSSL_free(c->conf_sigalgs);
+ OPENSSL_free(c->client_sigalgs);
+ OPENSSL_free(c->shared_sigalgs);
+ OPENSSL_free(c->client_certificate_types);
+ X509_STORE_free(c->verify_store);
+ X509_STORE_free(c->chain_store);
OPENSSL_free(c);
}
-int ssl_cert_inst(CERT **o) {
- /* Create a CERT if there isn't already one (which cannot really happen, as
- * it is initially created in SSL_CTX_new; but the earlier code usually
- * allows for that one being non-existant, so we follow that behaviour, as it
- * might turn out that there actually is a reason for it -- but I'm not sure
- * that *all* of the existing code could cope with s->cert being NULL,
- * otherwise we could do without the initialization in SSL_CTX_new). */
-
- if (o == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_inst, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
- if (*o == NULL) {
- *o = ssl_cert_new();
- if (*o == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_new, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- }
-
- return 1;
-}
-
-int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) * chain) {
+int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) {
CERT_PKEY *cpk = c->key;
if (!cpk) {
return 0;
}
- if (cpk->chain) {
- sk_X509_pop_free(cpk->chain, X509_free);
- }
+ sk_X509_pop_free(cpk->chain, X509_free);
cpk->chain = chain;
return 1;
}
-int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) * chain) {
- STACK_OF(X509) * dchain;
+int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) {
+ STACK_OF(X509) *dchain;
if (!chain) {
return ssl_cert_set0_chain(c, NULL);
}
@@ -499,22 +432,14 @@ void ssl_sess_cert_free(SESS_CERT *sc) {
return;
}
- if (sc->cert_chain != NULL) {
- sk_X509_pop_free(sc->cert_chain, X509_free);
- }
+ sk_X509_pop_free(sc->cert_chain, X509_free);
for (i = 0; i < SSL_PKEY_NUM; i++) {
- if (sc->peer_pkeys[i].x509 != NULL) {
- X509_free(sc->peer_pkeys[i].x509);
- }
+ X509_free(sc->peer_pkeys[i].x509);
}
- if (sc->peer_dh_tmp != NULL) {
- DH_free(sc->peer_dh_tmp);
- }
- if (sc->peer_ecdh_tmp != NULL) {
- EC_KEY_free(sc->peer_ecdh_tmp);
- }
+ DH_free(sc->peer_dh_tmp);
+ EC_KEY_free(sc->peer_ecdh_tmp);
OPENSSL_free(sc);
}
@@ -524,7 +449,7 @@ int ssl_set_peer_cert_type(SESS_CERT *sc, int type) {
return 1;
}
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) * sk) {
+int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) {
X509 *x;
int i;
X509_STORE *verify_store;
@@ -571,18 +496,15 @@ int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) * sk) {
return i;
}
-static void set_client_CA_list(STACK_OF(X509_NAME) * *ca_list,
- STACK_OF(X509_NAME) * name_list) {
- if (*ca_list != NULL) {
- sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
- }
-
+static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
+ STACK_OF(X509_NAME) *name_list) {
+ sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
*ca_list = name_list;
}
-STACK_OF(X509_NAME) * SSL_dup_CA_list(STACK_OF(X509_NAME) * sk) {
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) {
size_t i;
- STACK_OF(X509_NAME) * ret;
+ STACK_OF(X509_NAME) *ret;
X509_NAME *name;
ret = sk_X509_NAME_new_null();
@@ -597,19 +519,19 @@ STACK_OF(X509_NAME) * SSL_dup_CA_list(STACK_OF(X509_NAME) * sk) {
return ret;
}
-void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) * name_list) {
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) {
set_client_CA_list(&(s->client_CA), name_list);
}
-void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) * name_list) {
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) {
set_client_CA_list(&(ctx->client_CA), name_list);
}
-STACK_OF(X509_NAME) * SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
return ctx->client_CA;
}
-STACK_OF(X509_NAME) * SSL_get_client_CA_list(const SSL *s) {
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) {
if (s->server) {
if (s->client_CA != NULL) {
return s->client_CA;
@@ -625,7 +547,7 @@ STACK_OF(X509_NAME) * SSL_get_client_CA_list(const SSL *s) {
}
}
-static int add_client_CA(STACK_OF(X509_NAME) * *sk, X509 *x) {
+static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
X509_NAME *name;
if (x == NULL) {
@@ -670,7 +592,7 @@ static int xname_cmp(const X509_NAME **a, const X509_NAME **b) {
*
* \param file the file containing one or more certs.
* \return a ::STACK containing the certs. */
-STACK_OF(X509_NAME) * SSL_load_client_CA_file(const char *file) {
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
BIO *in;
X509 *x = NULL;
X509_NAME *xn = NULL;
@@ -719,21 +641,13 @@ STACK_OF(X509_NAME) * SSL_load_client_CA_file(const char *file) {
if (0) {
err:
- if (ret != NULL) {
- sk_X509_NAME_pop_free(ret, X509_NAME_free);
- }
+ sk_X509_NAME_pop_free(ret, X509_NAME_free);
ret = NULL;
}
- if (sk != NULL) {
- sk_X509_NAME_free(sk);
- }
- if (in != NULL) {
- BIO_free(in);
- }
- if (x != NULL) {
- X509_free(x);
- }
+ sk_X509_NAME_free(sk);
+ BIO_free(in);
+ X509_free(x);
if (ret != NULL) {
ERR_clear_error();
}
@@ -747,7 +661,7 @@ STACK_OF(X509_NAME) * SSL_load_client_CA_file(const char *file) {
* already in the stack will be added.
* \return 1 for success, 0 for failure. Note that in the case of failure some
* certs may have been added to \c stack. */
-int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) * stack,
+int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
const char *file) {
BIO *in;
X509 *x = NULL;
@@ -794,12 +708,8 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) * stack,
ret = 0;
}
- if (in != NULL) {
- BIO_free(in);
- }
- if (x != NULL) {
- X509_free(x);
- }
+ BIO_free(in);
+ X509_free(x);
(void) sk_X509_NAME_set_cmp_func(stack, oldcmp);
@@ -815,7 +725,7 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) * stack,
* be included.
* \return 1 for success, 0 for failure. Note that in the case of failure some
* certs may have been added to \c stack. */
-int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) * stack,
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
const char *dir) {
OPENSSL_DIR_CTX *d = NULL;
const char *filename;
@@ -842,7 +752,7 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) * stack,
}
if (errno) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_file_cert_subjects_to_stack, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(SSL, SSL_add_dir_cert_subjects_to_stack, ERR_R_SYS_LIB);
ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
goto err;
}
@@ -881,12 +791,13 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
int no_chain = 0;
size_t i;
- X509 *x = NULL;
- STACK_OF(X509) * extra_certs;
+ X509 *x = cpk->x509;
+ STACK_OF(X509) *extra_certs;
X509_STORE *chain_store;
- if (cpk) {
- x = cpk->x509;
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, SSL_R_NO_CERTIFICATE_SET);
+ return 0;
}
if (s->cert->chain_store) {
@@ -906,44 +817,36 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
no_chain = 1;
}
- /* TLSv1 sends a chain with nothing in it, instead of an alert. */
- if (!BUF_MEM_grow_clean(buf, 10)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_BUF_LIB);
- return 0;
- }
+ if (no_chain) {
+ if (!ssl_add_cert_to_buf(buf, l, x)) {
+ return 0;
+ }
- if (x != NULL) {
- if (no_chain) {
+ for (i = 0; i < sk_X509_num(extra_certs); i++) {
+ x = sk_X509_value(extra_certs, i);
if (!ssl_add_cert_to_buf(buf, l, x)) {
return 0;
}
- } else {
- X509_STORE_CTX xs_ctx;
-
- if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_X509_LIB);
- return 0;
- }
- X509_verify_cert(&xs_ctx);
- /* Don't leave errors in the queue */
- ERR_clear_error();
- for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
- x = sk_X509_value(xs_ctx.chain, i);
-
- if (!ssl_add_cert_to_buf(buf, l, x)) {
- X509_STORE_CTX_cleanup(&xs_ctx);
- return 0;
- }
- }
- X509_STORE_CTX_cleanup(&xs_ctx);
}
- }
+ } else {
+ X509_STORE_CTX xs_ctx;
- for (i = 0; i < sk_X509_num(extra_certs); i++) {
- x = sk_X509_value(extra_certs, i);
- if (!ssl_add_cert_to_buf(buf, l, x)) {
+ if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) {
+ OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_X509_LIB);
return 0;
}
+ X509_verify_cert(&xs_ctx);
+ /* Don't leave errors in the queue */
+ ERR_clear_error();
+ for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
+ x = sk_X509_value(xs_ctx.chain, i);
+
+ if (!ssl_add_cert_to_buf(buf, l, x)) {
+ X509_STORE_CTX_cleanup(&xs_ctx);
+ return 0;
+ }
+ }
+ X509_STORE_CTX_cleanup(&xs_ctx);
}
return 1;
@@ -956,7 +859,7 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) {
STACK_OF(X509) *chain = NULL, *untrusted = NULL;
X509 *x;
int i, rv = 0;
- unsigned long error;
+ uint32_t error;
if (!cpk->x509) {
OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, SSL_R_NO_CERTIFICATE_SET);
@@ -1050,8 +953,9 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) {
}
cpk->chain = chain;
- if (rv == 0)
+ if (rv == 0) {
rv = 1;
+ }
err:
if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
@@ -1069,9 +973,7 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) {
pstore = &c->verify_store;
}
- if (*pstore) {
- X509_STORE_free(*pstore);
- }
+ X509_STORE_free(*pstore);
*pstore = store;
if (ref && store) {