aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2012-04-23 21:56:33 +0000
committerDr. Stephen Henson <steve@openssl.org>2012-04-23 21:56:33 +0000
commit579d553464604832911c1eb08d014f487e54e0ff (patch)
tree9a1102bb53ab75fa0f51b81605e103f70c424a89
parent71fa3bc5ece9121d1aa9bb513b5641e9ea605e14 (diff)
downloadopenssl-579d553464604832911c1eb08d014f487e54e0ff.tar.gz
update NEWS
-rw-r--r--NEWS18
-rw-r--r--apps/s_cb.c13
-rw-r--r--ssl/s3_clnt.c7
-rw-r--r--ssl/s3_srvr.c8
-rw-r--r--ssl/ssl.h4
-rw-r--r--ssl/ssl_cert.c62
-rw-r--r--ssl/ssl_err.c1
-rw-r--r--ssl/ssl_lib.c16
-rw-r--r--ssl/ssl_locl.h11
9 files changed, 115 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index a46361198d..e70fcba092 100644
--- 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.
+ 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.
@@ -18,6 +24,10 @@
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
@@ -90,6 +100,14 @@
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
diff --git a/apps/s_cb.c b/apps/s_cb.c
index b21a4283df..0c5c39e4f0 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -285,6 +285,19 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
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;
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index ee8aeb05f8..3e6a9d4d4c 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -3161,6 +3161,13 @@ int ssl3_send_client_certificate(SSL *s)
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
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 87678c181b..68920a72db 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -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;
}
+ /* 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));
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 708dc33d6b..23e79eaaae 100644
--- 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_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
@@ -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);
+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
@@ -1892,6 +1894,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);
@@ -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_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
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 222f703284..784300e26a 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -345,6 +345,9 @@ CERT *ssl_cert_dup(CERT *cert)
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)
@@ -363,21 +366,36 @@ 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;
+ 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)
{
@@ -409,20 +427,8 @@ 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
- }
+ ssl_cert_clear_certs(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;
}
+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;
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index eec42fa54b..7bde072466 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -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_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"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 679894cb3d..12a0448fe2 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -526,6 +526,12 @@ int SSL_set1_param(SSL *ssl, X509_VERIFY_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;
@@ -2037,6 +2043,16 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int 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;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index c340ac3ce7..cc15a5d411 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -512,6 +512,15 @@ typedef struct cert_st
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;
@@ -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);
+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);
@@ -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);
+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);