From a5ee80b910089b8ce3b56d29822f4ded576cce8a Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 18 Jun 2012 12:56:59 +0000 Subject: [PATCH] Make it possible to delete all certificates from an SSL structure. --- CHANGES | 5 ++++ ssl/ssl.h | 1 + ssl/ssl_cert.c | 62 +++++++++++++++++++++++++++----------------------- ssl/ssl_lib.c | 5 ++++ ssl/ssl_locl.h | 1 + 5 files changed, 45 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index 801b604a8f..e8b40e7f53 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,11 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] + *) New function SSL_certs_clear() to delete all references to certificates + from an SSL structure. Before this once a certificate had been added + it couldn't be removed. + [Steve Henson] + *) Initial SSL tracing code. This parses out SSL/TLS records using the message callback and prints the results. Needs compile time option "enable-ssl-trace". New options to s_client and s_server to enable diff --git a/ssl/ssl.h b/ssl/ssl.h index 17bdc5a69c..c7828686bf 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -1922,6 +1922,7 @@ char *SSL_get_srp_username(SSL *s); char *SSL_get_srp_userinfo(SSL *s); #endif +void SSL_certs_clear(SSL *s); void SSL_free(SSL *ssl); int SSL_accept(SSL *ssl); int SSL_connect(SSL *ssl); diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index fcf462d41a..64d6f8ae3f 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -379,21 +379,42 @@ err: EC_KEY_free(ret->ecdh_tmp); #endif - for (i = 0; i < SSL_PKEY_NUM; i++) - { - CERT_PKEY *rpk = ret->pkeys + i; - if (rpk->x509 != NULL) - X509_free(rpk->x509); - if (rpk->privatekey != NULL) - EVP_PKEY_free(rpk->privatekey); - if (rpk->chain) - sk_X509_pop_free(rpk->chain, X509_free); - } - + ssl_cert_clear_certs(ret); return NULL; } +/* Free up and clear all certificates and chains */ + +void ssl_cert_clear_certs(CERT *c) + { + int i; + if (c == NULL) + return; + for (i = 0; ipkeys + i; + if (cpk->x509) + { + X509_free(cpk->x509); + cpk->x509 = NULL; + } + if (cpk->privatekey) + { + EVP_PKEY_free(cpk->privatekey); + cpk->privatekey = NULL; + } + if (cpk->chain) + { + sk_X509_pop_free(cpk->chain, X509_free); + cpk->chain = NULL; + } +#ifndef OPENSSL_NO_TLSEXT + if (cpk->authz != NULL) + OPENSSL_free(cpk->authz); +#endif + } + } void ssl_cert_free(CERT *c) { @@ -425,24 +446,7 @@ void ssl_cert_free(CERT *c) if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp); #endif - for (i=0; ipkeys + i; - if (cpk->x509 != NULL) - X509_free(cpk->x509); - if (cpk->privatekey != NULL) - EVP_PKEY_free(cpk->privatekey); - if (cpk->chain) - sk_X509_pop_free(cpk->chain, X509_free); -#if 0 - if (c->pkeys[i].publickey != NULL) - EVP_PKEY_free(c->pkeys[i].publickey); -#endif -#ifndef OPENSSL_NO_TLSEXT - if (c->pkeys[i].authz != NULL) - OPENSSL_free(c->pkeys[i].authz); -#endif - } + ssl_cert_clear_certs(c); if (c->sigalgs) OPENSSL_free(c->sigalgs); OPENSSL_free(c); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index dc9a8665bc..c291ee274c 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -525,6 +525,11 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) return X509_VERIFY_PARAM_set1(ssl->param, vpm); } +void SSL_certs_clear(SSL *s) + { + ssl_cert_clear_certs(s->cert); + } + void SSL_free(SSL *s) { int i; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 872bce6601..622648f72e 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -831,6 +831,7 @@ int ssl_clear_bad_session(SSL *s); CERT *ssl_cert_new(void); CERT *ssl_cert_dup(CERT *cert); int ssl_cert_inst(CERT **o); +void ssl_cert_clear_certs(CERT *c); void ssl_cert_free(CERT *c); SESS_CERT *ssl_sess_cert_new(void); void ssl_sess_cert_free(SESS_CERT *sc); -- 2.25.1