update NEWS
authorDr. Stephen Henson <steve@openssl.org>
Mon, 23 Apr 2012 21:56:33 +0000 (21:56 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Mon, 23 Apr 2012 21:56:33 +0000 (21:56 +0000)
NEWS
apps/s_cb.c
ssl/s3_clnt.c
ssl/s3_srvr.c
ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_err.c
ssl/ssl_lib.c
ssl/ssl_locl.h

diff --git a/NEWS b/NEWS
index a46361198d5441d81a6b56d26720b2d2428c3274..e70fcba0928b9555f4d07dd393b868d02a7fa612 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,12 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a:
+
+      o Fix for ASN1 overflow bug CVE-2012-2110
+      o Workarounds for some servers that hang on long client hellos.
+      o Fix SEGV in AES code.
+
   Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1:
 
       o TLS/DTLS heartbeat support.
   Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1:
 
       o TLS/DTLS heartbeat support.
       o Preliminary FIPS capability for unvalidated 2.0 FIPS module.
       o SRP support.
 
       o Preliminary FIPS capability for unvalidated 2.0 FIPS module.
       o SRP support.
 
+  Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.0i:
+
+      o Fix for ASN1 overflow bug CVE-2012-2110
+
   Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h:
 
       o Fix for CMS/PKCS#7 MMA CVE-2012-0884
   Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h:
 
       o Fix for CMS/PKCS#7 MMA CVE-2012-0884
       o Opaque PRF Input TLS extension support.
       o Updated time routines to avoid OS limitations.
 
       o Opaque PRF Input TLS extension support.
       o Updated time routines to avoid OS limitations.
 
+  Major changes between OpenSSL 0.9.8v and OpenSSL 0.9.8w:
+
+      o Fix for CVE-2012-2131 (corrected fix for 0.9.8 and CVE-2012-2110)
+
+  Major changes between OpenSSL 0.9.8u and OpenSSL 0.9.8v:
+
+      o Fix for ASN1 overflow bug CVE-2012-2110
+
   Major changes between OpenSSL 0.9.8t and OpenSSL 0.9.8u:
 
       o Fix for CMS/PKCS#7 MMA CVE-2012-0884
   Major changes between OpenSSL 0.9.8t and OpenSSL 0.9.8u:
 
       o Fix for CMS/PKCS#7 MMA CVE-2012-0884
index b21a4283dfb478499fd9adc88810d296e5730edb..0c5c39e4f0aa2aa21d86e1e7440446b57c6e4dd2 100644 (file)
@@ -285,6 +285,19 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
        return 1;
        }
 
        return 1;
        }
 
+typedef struct 
+       {
+       X509 *cert;
+       EVP_PKEY *key;
+       STACK_OF(X509) *chain;
+       struct ssl_excert_st *next;
+       } SSL_EXCERT;
+
+static int set_cert_cb(SSL *ssl, void *arg)
+       {
+       return 1;
+       }
+
 int ssl_print_sigalgs(BIO *out, SSL *s)
        {
        int i, nsig;
 int ssl_print_sigalgs(BIO *out, SSL *s)
        {
        int i, nsig;
index ee8aeb05f8cc15d5d84e513a7ae2b55cdbe9f81a..3e6a9d4d4c1e7813c79ed26d5359dd603cfdbb4b 100644 (file)
@@ -3161,6 +3161,13 @@ int ssl3_send_client_certificate(SSL *s)
 
        if (s->state == SSL3_ST_CW_CERT_A)
                {
 
        if (s->state == SSL3_ST_CW_CERT_A)
                {
+               /* Let cert callback update client certificates if required */
+               if (s->cert->cert_cb
+                       && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0)
+                       {
+                       ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR);
+                       return 0;
+                       }
                if (ssl3_check_client_certificate(s))
                        s->state=SSL3_ST_CW_CERT_C;
                else
                if (ssl3_check_client_certificate(s))
                        s->state=SSL3_ST_CW_CERT_C;
                else
index 87678c181b0a9926d5cd7ac9503f20b3224cd206..68920a72db603cab90408b5d61bc04849d631194 100644 (file)
@@ -1341,6 +1341,14 @@ int ssl3_get_client_hello(SSL *s)
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);
                        goto f_err;
                        }
                        SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_PASSED);
                        goto f_err;
                        }
+               /* Let cert callback update server certificates if required */
+               if (s->cert->cert_cb
+                       && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0)
+                       {
+                       al=SSL_AD_INTERNAL_ERROR;
+                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR);
+                       goto f_err;
+                       }
                ciphers=NULL;
                c=ssl3_choose_cipher(s,s->session->ciphers,
                                     SSL_get_ciphers(s));
                ciphers=NULL;
                c=ssl3_choose_cipher(s,s->session->ciphers,
                                     SSL_get_ciphers(s));
index 708dc33d6bd02851dab51599ddd08e6ddab1a166..23e79eaaaee16898f936d379123e1c464a05cf3e 100644 (file)
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -1759,6 +1759,7 @@ int       (*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
 void   SSL_set_verify(SSL *s, int mode,
                       int (*callback)(int ok,X509_STORE_CTX *ctx));
 void   SSL_set_verify_depth(SSL *s, int depth);
 void   SSL_set_verify(SSL *s, int mode,
                       int (*callback)(int ok,X509_STORE_CTX *ctx));
 void   SSL_set_verify_depth(SSL *s, int depth);
+void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg);
 #ifndef OPENSSL_NO_RSA
 int    SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
 #endif
 #ifndef OPENSSL_NO_RSA
 int    SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
 #endif
@@ -1837,6 +1838,7 @@ void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
                        int (*callback)(int, X509_STORE_CTX *));
 void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
 void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
                        int (*callback)(int, X509_STORE_CTX *));
 void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
 void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
+void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg), void *arg);
 #ifndef OPENSSL_NO_RSA
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
 #endif
 #ifndef OPENSSL_NO_RSA
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
 #endif
@@ -1892,6 +1894,7 @@ char *SSL_get_srp_username(SSL *s);
 char *SSL_get_srp_userinfo(SSL *s);
 #endif
 
 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);
 void   SSL_free(SSL *ssl);
 int    SSL_accept(SSL *ssl);
 int    SSL_connect(SSL *ssl);
@@ -2387,6 +2390,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_R_CA_DN_TOO_LONG                            132
 #define SSL_R_CCS_RECEIVED_EARLY                        133
 #define SSL_R_CERTIFICATE_VERIFY_FAILED                         134
 #define SSL_R_CA_DN_TOO_LONG                            132
 #define SSL_R_CCS_RECEIVED_EARLY                        133
 #define SSL_R_CERTIFICATE_VERIFY_FAILED                         134
+#define SSL_R_CERT_CB_ERROR                             371
 #define SSL_R_CERT_LENGTH_MISMATCH                      135
 #define SSL_R_CHALLENGE_IS_DIFFERENT                    136
 #define SSL_R_CIPHER_CODE_WRONG_LENGTH                  137
 #define SSL_R_CERT_LENGTH_MISMATCH                      135
 #define SSL_R_CHALLENGE_IS_DIFFERENT                    136
 #define SSL_R_CIPHER_CODE_WRONG_LENGTH                  137
index 222f703284355ba821c09a32f2bd07d960e239c2..784300e26a6401e1976a7c953acfeb90599529c5 100644 (file)
@@ -345,6 +345,9 @@ CERT *ssl_cert_dup(CERT *cert)
        ret->sigalgs = NULL;
        ret->sigalgslen = 0;
 
        ret->sigalgs = NULL;
        ret->sigalgslen = 0;
 
+       ret->cert_cb = cert->cert_cb;
+       ret->cert_cb_arg = cert->cert_cb_arg;
+
        return(ret);
        
 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
        return(ret);
        
 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
@@ -363,21 +366,36 @@ err:
                EC_KEY_free(ret->ecdh_tmp);
 #endif
 
                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;
        }
 
 
        return NULL;
        }
 
+/* Free up and clear all certificates and chains */
+
+void ssl_cert_clear_certs(CERT *c)
+       {
+       int i;
+       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;
+                       }
+               }
+       }
 
 void ssl_cert_free(CERT *c)
        {
 
 void ssl_cert_free(CERT *c)
        {
@@ -409,20 +427,8 @@ void ssl_cert_free(CERT *c)
        if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
 #endif
 
        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
-               }
+       ssl_cert_clear_certs(c);
+
        if (c->sigalgs)
                OPENSSL_free(c->sigalgs);
        OPENSSL_free(c);
        if (c->sigalgs)
                OPENSSL_free(c->sigalgs);
        OPENSSL_free(c);
@@ -510,6 +516,12 @@ int ssl_cert_add1_chain_cert(CERT *c, X509 *x)
        return 1;
        }
 
        return 1;
        }
 
+void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg)
+       {
+       c->cert_cb = cb;
+       c->cert_cb_arg = arg;
+       }
+
 SESS_CERT *ssl_sess_cert_new(void)
        {
        SESS_CERT *ret;
 SESS_CERT *ssl_sess_cert_new(void)
        {
        SESS_CERT *ret;
index eec42fa54ba59e390574bd50207a7f470f19d375..7bde072466b9a6f0424b8baf013907893326bb7a 100644 (file)
@@ -345,6 +345,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_CA_DN_TOO_LONG)        ,"ca dn too long"},
 {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY)    ,"ccs received early"},
 {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
 {ERR_REASON(SSL_R_CA_DN_TOO_LONG)        ,"ca dn too long"},
 {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY)    ,"ccs received early"},
 {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),"certificate verify failed"},
+{ERR_REASON(SSL_R_CERT_CB_ERROR)         ,"cert cb error"},
 {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH)  ,"cert length mismatch"},
 {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
 {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
 {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH)  ,"cert length mismatch"},
 {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT),"challenge is different"},
 {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH),"cipher code wrong length"},
index 679894cb3db15328c03b0d89a2cae9bbc652b32a..12a0448fe26c55920e4369619888748d9e6ba3a5 100644 (file)
@@ -526,6 +526,12 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
        return X509_VERIFY_PARAM_set1(ssl->param, vpm);
        }
 
        return X509_VERIFY_PARAM_set1(ssl->param, vpm);
        }
 
+void SSL_certs_clear(SSL *s)
+       {
+       if (s->cert)
+               ssl_cert_clear_certs(s->cert);
+       }
+
 void SSL_free(SSL *s)
        {
        int i;
 void SSL_free(SSL *s)
        {
        int i;
@@ -2037,6 +2043,16 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth)
        X509_VERIFY_PARAM_set_depth(ctx->param, depth);
        }
 
        X509_VERIFY_PARAM_set_depth(ctx->param, depth);
        }
 
+void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg), void *arg)
+       {
+       ssl_cert_set_cert_cb(c->cert, cb, arg);
+       }
+
+void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg)
+       {
+       ssl_cert_set_cert_cb(s->cert, cb, arg);
+       }
+
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
        {
        CERT_PKEY *cpk;
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
        {
        CERT_PKEY *cpk;
index c340ac3ce70360d342656647e11489659bec1a6c..cc15a5d411e9c675e88624d18cabbf52792e1782 100644 (file)
@@ -512,6 +512,15 @@ typedef struct cert_st
        TLS_SIGALGS *sigalgs;
        /* Size of above array */
        size_t sigalgslen;
        TLS_SIGALGS *sigalgs;
        /* Size of above array */
        size_t sigalgslen;
+       /* Certificate setup callback: if set is called whenever a
+        * certificate may be required (client or server). the callback
+        * can then examine any appropriate parameters and setup any
+        * certificates required. This allows advanced applications
+        * to select certificates on the fly: for example based on
+        * supported signature algorithms or curves.
+        */
+       int (*cert_cb)(SSL *ssl, void *arg);
+       void *cert_cb_arg;
 
        int references; /* >1 only if SSL_copy_session_id is used */
        } CERT;
 
        int references; /* >1 only if SSL_copy_session_id is used */
        } CERT;
@@ -822,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);
 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);
 void ssl_cert_free(CERT *c);
 SESS_CERT *ssl_sess_cert_new(void);
 void ssl_sess_cert_free(SESS_CERT *sc);
@@ -849,6 +859,7 @@ int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
 int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
 int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
 int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
 int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
 int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
 int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
+void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg);
 
 int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
 int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
 
 int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
 int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);