Make it possible to delete all certificates from an SSL structure.
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 14:18:50 +0000 (14:18 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Dec 2012 14:18:50 +0000 (14:18 +0000)
(backport from HEAD)

CHANGES
ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_lib.c
ssl/ssl_locl.h

diff --git a/CHANGES b/CHANGES
index 3097b95..a1c6e46 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  Changes between 1.0.1 and 1.0.2 [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]
+
   *) Integrate hostname, email address and IP address checking with certificate
      verification. New verify options supporting checking in opensl utility.
      [Steve Henson]
index f5a5e7e..7eebdb8 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1913,6 +1913,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);
index 3b05932..9f8b463 100644 (file)
@@ -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; i<SSL_PKEY_NUM; i++)
+               {
+               CERT_PKEY *cpk = c->pkeys + 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; i<SSL_PKEY_NUM; i++)
-               {
-               CERT_PKEY *cpk = c->pkeys + 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);
index 5206fd8..6091ea9 100644 (file)
@@ -524,6 +524,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;
index 90ef7cb..3a8f6f4 100644 (file)
@@ -833,6 +833,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);