--- openssl-1.0.0b.orig/ssl/ssl.h 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl.h 2010-11-30 00:03:47.000000000 +0000 @@ -1133,6 +1133,9 @@ struct ssl_st /* This can also be in the session once a session is established */ SSL_SESSION *session; + /* This can be disabled to prevent the use of uncached sessions */ + int session_creation_enabled; + /* Default generate session ID callback. */ GEN_SESSION_CB generate_session_id; @@ -1554,6 +1558,7 @@ const char * SSL_get_cipher_list(const char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len); int SSL_get_read_ahead(const SSL * s); int SSL_pending(const SSL *s); +const char * SSL_authentication_method(const SSL *c); #ifndef OPENSSL_NO_SOCK int SSL_set_fd(SSL *s, int fd); int SSL_set_rfd(SSL *s, int fd); @@ -1565,6 +1570,7 @@ BIO * SSL_get_rbio(const SSL *s); BIO * SSL_get_wbio(const SSL *s); #endif int SSL_set_cipher_list(SSL *s, const char *str); +int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk); void SSL_set_read_ahead(SSL *s, int yes); int SSL_get_verify_mode(const SSL *s); int SSL_get_verify_depth(const SSL *s); @@ -1580,6 +1586,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKE int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len); int SSL_use_certificate(SSL *ssl, X509 *x); int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); +int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain); +STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x); #ifndef OPENSSL_NO_STDIO int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); @@ -1615,6 +1623,7 @@ void SSL_copy_session_id(SSL *to,const S SSL_SESSION *SSL_SESSION_new(void); const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len); +const char * SSL_SESSION_get_version(const SSL_SESSION *s); unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); #ifndef OPENSSL_NO_FP_API int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses); @@ -1624,6 +1633,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_ void SSL_SESSION_free(SSL_SESSION *ses); int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); int SSL_set_session(SSL *to, SSL_SESSION *session); +void SSL_set_session_creation_enabled(SSL *, int); int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c); int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); @@ -2066,6 +2076,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 #define SSL_F_SSL_USE_CERTIFICATE 198 #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000 #define SSL_F_SSL_USE_CERTIFICATE_FILE 200 #define SSL_F_SSL_USE_PRIVATEKEY 201 #define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 @@ -2272,6 +2283,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 #define SSL_R_SERVERHELLO_TLSEXT 275 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000 #define SSL_R_SHORT_READ 219 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 --- openssl-1.0.0b.orig/ssl/d1_clnt.c 2010-01-26 19:46:29.000000000 +0000 +++ openssl-1.0.0b/ssl/d1_clnt.c 2010-11-30 00:03:47.000000000 +0000 @@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s) #endif (s->session->not_resumable)) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) goto err; } --- openssl-1.0.0b.orig/ssl/s23_clnt.c 2010-02-16 14:20:40.000000000 +0000 +++ openssl-1.0.0b/ssl/s23_clnt.c 2010-11-30 00:03:47.000000000 +0000 @@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s /* Since, if we are sending a ssl23 client hello, we are not * reusing a session-id */ + if (!s->session_creation_enabled) + { + if (!(s->client_version == SSL2_VERSION)) + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) goto err; --- openssl-1.0.0b.orig/ssl/s3_both.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/s3_both.c 2010-11-30 00:03:47.000000000 +0000 @@ -347,8 +347,11 @@ unsigned long ssl3_output_cert_chain(SSL unsigned long l=7; BUF_MEM *buf; int no_chain; + STACK_OF(X509) *cert_chain; - if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) + cert_chain = SSL_get_certificate_chain(s, x); + + if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain) no_chain = 1; else no_chain = 0; @@ -400,6 +403,10 @@ unsigned long ssl3_output_cert_chain(SSL return(0); } + for (i=0; i<sk_X509_num(cert_chain); i++) + if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i))) + return(0); + l-=7; p=(unsigned char *)&(buf->data[4]); l2n3(l,p); --- openssl-1.0.0b.orig/ssl/s3_clnt.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/s3_clnt.c 2010-11-30 00:03:47.000000000 +0000 @@ -686,6 +686,12 @@ int ssl3_client_hello(SSL *s) #endif (sess->not_resumable)) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) goto err; } @@ -894,6 +900,12 @@ int ssl3_get_server_hello(SSL *s) s->hit=0; if (s->session->session_id_length > 0) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) { al=SSL_AD_INTERNAL_ERROR; --- openssl-1.0.0b.orig/ssl/s3_srvr.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/s3_srvr.c 2010-11-30 00:03:47.000000000 +0000 @@ -902,6 +902,12 @@ int ssl3_get_client_hello(SSL *s) */ if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,1)) goto err; } @@ -916,6 +922,12 @@ int ssl3_get_client_hello(SSL *s) goto err; else /* i == 0 */ { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,1)) goto err; } --- openssl-1.0.0b.orig/ssl/ssl_ciph.c 2010-06-15 17:25:14.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_ciph.c 2010-11-30 00:03:47.000000000 +0000 @@ -1652,6 +1652,52 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER return(ret); } +/* return string version of key exchange algorithm */ +const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher) + { + switch (cipher->algorithm_mkey) + { + case SSL_kRSA: + return SSL_TXT_RSA; + case SSL_kDHr: + return SSL_TXT_DH "_" SSL_TXT_RSA; + case SSL_kDHd: + return SSL_TXT_DH "_" SSL_TXT_DSS; + case SSL_kEDH: + switch (cipher->algorithm_auth) + { + case SSL_aDSS: + return "DHE_" SSL_TXT_DSS; + case SSL_aRSA: + return "DHE_" SSL_TXT_RSA; + case SSL_aNULL: + return SSL_TXT_DH "_anon"; + default: + return "UNKNOWN"; + } + case SSL_kKRB5: + return SSL_TXT_KRB5; + case SSL_kECDHr: + return SSL_TXT_ECDH "_" SSL_TXT_RSA; + case SSL_kECDHe: + return SSL_TXT_ECDH "_" SSL_TXT_ECDSA; + case SSL_kEECDH: + switch (cipher->algorithm_auth) + { + case SSL_aECDSA: + return "ECDHE_" SSL_TXT_ECDSA; + case SSL_aRSA: + return "ECDHE_" SSL_TXT_RSA; + case SSL_aNULL: + return SSL_TXT_ECDH "_anon"; + default: + return "UNKNOWN"; + } + default: + return "UNKNOWN"; + } + } + SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) { SSL_COMP *ctmp; --- openssl-1.0.0b.orig/ssl/ssl_err.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_err.c 2010-11-30 00:03:47.000000000 +0000 @@ -465,6 +465,7 @@ static ERR_STRING_DATA SSL_str_reasons[] {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"}, {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"}, {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, +{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"}, {ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, --- openssl-1.0.0b.orig/ssl/ssl_lib.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_lib.c 2010-11-30 00:03:47.000000000 +0000 @@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx) OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx)); s->verify_callback=ctx->default_verify_callback; + s->session_creation_enabled=1; s->generate_session_id=ctx->generate_session_id; s->param = X509_VERIFY_PARAM_new(); @@ -1311,6 +1312,32 @@ int SSL_set_cipher_list(SSL *s,const cha return 1; } +/** specify the ciphers to be used by the SSL */ +int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk) + { + STACK_OF(SSL_CIPHER) *tmp_cipher_list; + + if (sk == NULL) + return 0; + + /* Based on end of ssl_create_cipher_list */ + tmp_cipher_list = sk_SSL_CIPHER_dup(sk); + if (tmp_cipher_list == NULL) + { + return 0; + } + if (s->cipher_list != NULL) + sk_SSL_CIPHER_free(s->cipher_list); + s->cipher_list = sk; + if (s->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + s->cipher_list_by_id = tmp_cipher_list; + (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp); + + sk_SSL_CIPHER_sort(s->cipher_list_by_id); + return 1; + } + /* works well for SSLv2, not so good for SSLv3 */ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) { @@ -2551,22 +2578,45 @@ SSL_METHOD *ssl_bad_method(int ver) return(NULL); } -const char *SSL_get_version(const SSL *s) +static const char *ssl_get_version(int version) { - if (s->version == TLS1_2_VERSION) + if (version == TLS1_2_VERSION) return("TLSv1.2"); - else if (s->version == TLS1_1_VERSION) + else if (version == TLS1_1_VERSION) return("TLSv1.1"); - else if (s->version == TLS1_VERSION) + else if (version == TLS1_VERSION) return("TLSv1"); - else if (s->version == SSL3_VERSION) + else if (version == SSL3_VERSION) return("SSLv3"); - else if (s->version == SSL2_VERSION) + else if (version == SSL2_VERSION) return("SSLv2"); else return("unknown"); } +const char *SSL_get_version(const SSL *s) + { + return ssl_get_version(s->version); + } + +const char *SSL_SESSION_get_version(const SSL_SESSION *s) + { + return ssl_get_version(s->ssl_version); + } + +const char* SSL_authentication_method(const SSL* ssl) + { + if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL) + return SSL_TXT_RSA "_" SSL_TXT_EXPORT; + switch (ssl->version) + { + case SSL2_VERSION: + return SSL_TXT_RSA; + default: + return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher); + } + } + SSL *SSL_dup(SSL *s) { STACK_OF(X509_NAME) *sk; --- openssl-1.0.0b.orig/ssl/ssl_locl.h 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_locl.h 2010-11-30 00:03:47.000000000 +0000 @@ -456,6 +456,7 @@ typedef struct cert_pkey_st { X509 *x509; + STACK_OF(X509) *cert_chain; EVP_PKEY *privatekey; } CERT_PKEY; --- openssl-1.0.0b.orig/ssl/ssl_rsa.c 2009-09-12 23:09:26.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_rsa.c 2010-11-30 00:03:47.000000000 +0000 @@ -697,6 +697,44 @@ int SSL_CTX_use_PrivateKey_ASN1(int type } +int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain) + { + if (ssl == NULL) + { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + if (ssl->cert == NULL) + { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED); + return(0); + } + if (ssl->cert->key == NULL) + { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED); + return(0); + } + if (ssl->cert->key->cert_chain != NULL) + sk_X509_pop_free(ssl->cert->key->cert_chain, X509_free); + ssl->cert->key->cert_chain = cert_chain; + return(1); + } + +STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x) + { + int i; + if (x == NULL) + return NULL; + if (ssl == NULL) + return NULL; + if (ssl->cert == NULL) + return NULL; + for (i = 0; i < SSL_PKEY_NUM; i++) + if (ssl->cert->pkeys[i].x509 == x) + return ssl->cert->pkeys[i].cert_chain; + return NULL; + } + #ifndef OPENSSL_NO_STDIO /* Read a file that contains our certificate in "PEM" format, * possibly followed by a sequence of CA certificates that should be --- openssl-1.0.0b.orig/ssl/ssl_sess.c 2010-02-01 16:49:42.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_sess.c 2010-11-30 00:03:47.000000000 +0000 @@ -261,6 +261,11 @@ static int def_generate_session_id(const return 0; } +void SSL_set_session_creation_enabled (SSL *s, int creation_enabled) + { + s->session_creation_enabled = creation_enabled; + } + int ssl_get_new_session(SSL *s, int session) { /* This gets used by clients and servers. */ @@ -269,6 +274,8 @@ int ssl_get_new_session(SSL *s, int sess SSL_SESSION *ss=NULL; GEN_SESSION_CB cb = def_generate_session_id; + /* caller should check this if they can do better error handling */ + if (!s->session_creation_enabled) return(0); if ((ss=SSL_SESSION_new()) == NULL) return(0); /* If the context has a default timeout, use it */