From 74096890ba076de838c858f6beeda778480ef824 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 11 May 2011 12:56:38 +0000 Subject: [PATCH] Initial "opaque SSL" framework. If an application defines OPENSSL_NO_SSL_INTERN all ssl related structures are opaque and internals cannot be directly accessed. Many applications will need some modification to support this and most likely some additional functions added to OpenSSL. The advantage of this option is that any application supporting it will still be binary compatible if SSL structures change. (backport from HEAD). --- CHANGES | 6 ++++++ apps/apps.h | 3 +++ apps/ciphers.c | 2 +- apps/s_client.c | 6 +++--- apps/s_server.c | 8 +++---- apps/sess_id.c | 18 +++++++++------- ssl/dtls1.h | 3 +++ ssl/ssl.h | 57 ++++++++++++++++++++++++++++++++++++++----------- ssl/ssl2.h | 4 ++++ ssl/ssl3.h | 7 ++++++ ssl/ssl_ciph.c | 5 +++++ ssl/ssl_err.c | 1 + ssl/ssl_lib.c | 15 +++++++++++++ ssl/ssl_sess.c | 29 +++++++++++++++++++++++++ 14 files changed, 136 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index 42b4c89c36..deda5ac41c 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,12 @@ _______________ Changes between 1.0.0d and 1.0.1 [xx XXX xxxx] + + *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled + with this defined it will not be affected by any changes to ssl internal + structures. Add several utility functions to allow openssl application + to work with OPENSSL_NO_SSL_INTERN defined. + [Steve Henson] *) Add SRP support. [Tom Wu and Ben Laurie] diff --git a/apps/apps.h b/apps/apps.h index 596a39aceb..f92744b42c 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -357,4 +357,7 @@ int raw_write_stdout(const void *,int); #define TM_START 0 #define TM_STOP 1 double app_tminterval (int stop,int usertime); + +#define OPENSSL_NO_SSL_INTERN + #endif diff --git a/apps/ciphers.c b/apps/ciphers.c index 3d4c60db9e..5f2b739700 100644 --- a/apps/ciphers.c +++ b/apps/ciphers.c @@ -196,7 +196,7 @@ int MAIN(int argc, char **argv) if (Verbose) { - unsigned long id = c->id; + unsigned long id = SSL_CIPHER_get_id(c); int id0 = (int)(id >> 24); int id1 = (int)((id >> 16) & 0xffL); int id2 = (int)((id >> 8) & 0xffL); diff --git a/apps/s_client.c b/apps/s_client.c index 81c7e85fdb..d108534cc2 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -1171,7 +1171,7 @@ re_start: } } #endif - if (c_Pause & 0x01) con->debug=1; + if (c_Pause & 0x01) SSL_set_debug(con, 1); if ( SSL_version(con) == DTLS1_VERSION) { @@ -1220,7 +1220,7 @@ re_start: if (c_debug) { - con->debug=1; + SSL_set_debug(con, 1); BIO_set_callback(sbio,bio_dump_callback); BIO_set_callback_arg(sbio,(char *)bio_c_out); } @@ -1905,7 +1905,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_number_read(SSL_get_rbio(s)), BIO_number_written(SSL_get_wbio(s))); } - BIO_printf(bio,((s->hit)?"---\nReused, ":"---\nNew, ")); + BIO_printf(bio,(SSL_cache_hit(s)?"---\nReused, ":"---\nNew, ")); c=SSL_get_current_cipher(s); BIO_printf(bio,"%s, Cipher is %s\n", SSL_CIPHER_get_version(c), diff --git a/apps/s_server.c b/apps/s_server.c index a1934e893d..16a84ff0ad 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1960,7 +1960,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) if (s_debug) { - con->debug=1; + SSL_set_debug(con, 1); BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); } @@ -2285,7 +2285,7 @@ static int init_ssl_connection(SSL *con) BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf); str=SSL_CIPHER_get_name(SSL_get_current_cipher(con)); BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)"); - if (con->hit) BIO_printf(bio_s_out,"Reused session-id\n"); + if (SSL_cache_hit(con)) BIO_printf(bio_s_out,"Reused session-id\n"); if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) & TLS1_FLAGS_TLS_PADDING_BUG) BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n"); @@ -2405,7 +2405,7 @@ static int www_body(char *hostname, int s, unsigned char *context) if (s_debug) { - con->debug=1; + SSL_set_debug(con, 1); BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); } @@ -2526,7 +2526,7 @@ static int www_body(char *hostname, int s, unsigned char *context) } BIO_puts(io,"\n"); } - BIO_printf(io,((con->hit) + BIO_printf(io,(SSL_cache_hit(con) ?"---\nReused, " :"---\nNew, ")); c=SSL_get_current_cipher(con); diff --git a/apps/sess_id.c b/apps/sess_id.c index b99179f276..b16686c26d 100644 --- a/apps/sess_id.c +++ b/apps/sess_id.c @@ -90,6 +90,7 @@ int MAIN(int, char **); int MAIN(int argc, char **argv) { SSL_SESSION *x=NULL; + X509 *peer = NULL; int ret=1,i,num,badops=0; BIO *out=NULL; int informat,outformat; @@ -163,16 +164,17 @@ bad: ERR_load_crypto_strings(); x=load_sess_id(infile,informat); if (x == NULL) { goto end; } + peer = SSL_SESSION_get0_peer(x); if(context) { - x->sid_ctx_length=strlen(context); - if(x->sid_ctx_length > SSL_MAX_SID_CTX_LENGTH) + size_t ctx_len = strlen(context); + if(ctx_len > SSL_MAX_SID_CTX_LENGTH) { BIO_printf(bio_err,"Context too long\n"); goto end; } - memcpy(x->sid_ctx,context,x->sid_ctx_length); + SSL_SESSION_set1_id_context(x, (unsigned char *)context, ctx_len); } #ifdef undef @@ -231,10 +233,10 @@ bad: if (cert) { - if (x->peer == NULL) + if (peer == NULL) BIO_puts(out,"No certificate present\n"); else - X509_print(out,x->peer); + X509_print(out,peer); } } @@ -253,12 +255,12 @@ bad: goto end; } } - else if (!noout && (x->peer != NULL)) /* just print the certificate */ + else if (!noout && (peer != NULL)) /* just print the certificate */ { if (outformat == FORMAT_ASN1) - i=(int)i2d_X509_bio(out,x->peer); + i=(int)i2d_X509_bio(out,peer); else if (outformat == FORMAT_PEM) - i=PEM_write_bio_X509(out,x->peer); + i=PEM_write_bio_X509(out,peer); else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; diff --git a/ssl/dtls1.h b/ssl/dtls1.h index 2900d1d8ae..e9e4e5f226 100644 --- a/ssl/dtls1.h +++ b/ssl/dtls1.h @@ -105,6 +105,8 @@ extern "C" { #define DTLS1_AL_HEADER_LENGTH 2 #endif +#ifndef OPENSSL_NO_SSL_INTERN + typedef struct dtls1_bitmap_st { @@ -253,6 +255,7 @@ typedef struct dtls1_record_data_st SSL3_RECORD rrec; } DTLS1_RECORD_DATA; +#endif /* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ #define DTLS1_TMO_READ_COUNT 2 diff --git a/ssl/ssl.h b/ssl/ssl.h index 5c71a790e1..104e2ad4e3 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -359,9 +359,20 @@ extern "C" { * in SSL_CTX. */ typedef struct ssl_st *ssl_crock_st; typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; + +DECLARE_STACK_OF(SSL_CIPHER) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); + + +#ifndef OPENSSL_NO_SSL_INTERN /* used to hold info on the particular ciphers used */ -typedef struct ssl_cipher_st +struct ssl_cipher_st { int valid; const char *name; /* text name */ @@ -378,15 +389,11 @@ typedef struct ssl_cipher_st unsigned long algorithm2; /* Extra flags */ int strength_bits; /* Number of bits really used */ int alg_bits; /* Number of bits for algorithm */ - } SSL_CIPHER; - -DECLARE_STACK_OF(SSL_CIPHER) + }; -typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg); -typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ -typedef struct ssl_method_st +struct ssl_method_st { int version; int (*ssl_new)(SSL *s); @@ -419,7 +426,7 @@ typedef struct ssl_method_st int (*ssl_version)(void); long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void)); long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void)); - } SSL_METHOD; + }; /* Lets make this into an ASN.1 type structure as follows * SSL_SESSION_ID ::= SEQUENCE { @@ -444,7 +451,7 @@ typedef struct ssl_method_st * Look in ssl/ssl_asn1.c for more details * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). */ -typedef struct ssl_session_st +struct ssl_session_st { int ssl_version; /* what ssl version session info is * being kept in here? */ @@ -519,8 +526,9 @@ typedef struct ssl_session_st #ifndef OPENSSL_NO_SRP char *srp_username; #endif - } SSL_SESSION; + }; +#endif #define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L #define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L @@ -652,6 +660,8 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con #ifndef OPENSSL_NO_SRP +#ifndef OPENSSL_NO_SSL_INTERN + typedef struct srp_ctx_st { /* param for all the callbacks */ @@ -674,6 +684,8 @@ typedef struct srp_ctx_st unsigned long srp_Mask; } SRP_CTX; +#endif + /* see tls_srp.c */ int SSL_SRP_CTX_init(SSL *s); int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); @@ -711,7 +723,11 @@ int SRP_have_to_put_srp_username(SSL *s); typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id, unsigned int *id_len); -typedef struct ssl_comp_st +typedef struct ssl_comp_st SSL_COMP; + +#ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_comp_st { int id; const char *name; @@ -720,7 +736,7 @@ typedef struct ssl_comp_st #else char *method; #endif - } SSL_COMP; + }; DECLARE_STACK_OF(SSL_COMP) DECLARE_LHASH_OF(SSL_SESSION); @@ -915,6 +931,8 @@ struct ssl_ctx_st #endif }; +#endif + #define SSL_SESS_CACHE_OFF 0x0000 #define SSL_SESS_CACHE_CLIENT 0x0001 #define SSL_SESS_CACHE_SERVER 0x0002 @@ -1007,6 +1025,8 @@ const char *SSL_get_psk_identity(const SSL *s); #define SSL_MAC_FLAG_READ_MAC_STREAM 1 #define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 +#ifndef OPENSSL_NO_SSL_INTERN + struct ssl_st { /* protocol version @@ -1235,6 +1255,8 @@ struct ssl_st #endif /* OPENSSL_NO_TLSEXT */ }; +#endif + #ifdef __cplusplus } #endif @@ -1544,6 +1566,7 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits); char * SSL_CIPHER_get_version(const SSL_CIPHER *c); const char * SSL_CIPHER_get_name(const SSL_CIPHER *c); +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); int SSL_get_fd(const SSL *s); int SSL_get_rfd(const SSL *s); @@ -1609,6 +1632,11 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t); long SSL_SESSION_get_timeout(const SSL_SESSION *s); long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); void SSL_copy_session_id(SSL *to,const SSL *from); +unsigned int SSL_SESSION_get_id_len(SSL_SESSION *s); +const unsigned char *SSL_SESSION_get0_id(SSL_SESSION *s); +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx, + unsigned int sid_ctx_len); SSL_SESSION *SSL_SESSION_new(void); const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, @@ -1800,6 +1828,7 @@ void SSL_set_info_callback(SSL *ssl, void (*cb)(const SSL *ssl,int type,int val)); void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val); int SSL_state(const SSL *ssl); +void SSL_set_state(SSL *ssl, int state); void SSL_set_verify_result(SSL *ssl,long v); long SSL_get_verify_result(const SSL *ssl); @@ -1904,6 +1933,9 @@ int SSL_tls1_key_exporter(SSL *s, unsigned char *label, int label_len, unsigned char *context, int context_len, unsigned char *out, int olen); +void SSL_set_debug(SSL *s, int debug); +int SSL_cache_hit(SSL *s); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. @@ -2080,6 +2112,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 #define SSL_F_SSL_SESSION_NEW 189 #define SSL_F_SSL_SESSION_PRINT_FP 190 +#define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 306 #define SSL_F_SSL_SESS_CERT_NEW 225 #define SSL_F_SSL_SET_CERT 191 #define SSL_F_SSL_SET_CIPHER_LIST 271 diff --git a/ssl/ssl2.h b/ssl/ssl2.h index 99a52ea0dd..eb25dcb0bf 100644 --- a/ssl/ssl2.h +++ b/ssl/ssl2.h @@ -155,6 +155,8 @@ extern "C" { #define CERT char #endif +#ifndef OPENSSL_NO_SSL_INTERN + typedef struct ssl2_state_st { int three_byte_header; @@ -219,6 +221,8 @@ typedef struct ssl2_state_st } tmp; } SSL2_STATE; +#endif + /* SSLv2 */ /* client */ #define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT) diff --git a/ssl/ssl3.h b/ssl/ssl3.h index 8bfa58806e..ae299cf1a8 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -339,6 +339,8 @@ extern "C" { #define SSL3_AD_CERTIFICATE_UNKNOWN 46 #define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */ +#ifndef OPENSSL_NO_SSL_INTERN + typedef struct ssl3_record_st { /*r */ int type; /* type of record */ @@ -360,6 +362,8 @@ typedef struct ssl3_buffer_st int left; /* how many bytes left */ } SSL3_BUFFER; +#endif + #define SSL3_CT_RSA_SIGN 1 #define SSL3_CT_DSS_SIGN 2 #define SSL3_CT_RSA_FIXED_DH 3 @@ -380,6 +384,8 @@ typedef struct ssl3_buffer_st #define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 #define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 +#ifndef OPENSSL_NO_SSL_INTERN + typedef struct ssl3_state_st { long flags; @@ -514,6 +520,7 @@ typedef struct ssl3_state_st int send_connection_binding; /* TODOEKR */ } SSL3_STATE; +#endif /* SSLv3 */ /*client */ diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index bbab6a9ec7..84829e5e9a 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -1660,6 +1660,11 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) return(ret); } +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c) + { + return c->id; + } + SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) { SSL_COMP *ctmp; diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 781fde1448..41b7d1d752 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -237,6 +237,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, +{ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), "SSL_SESSION_set1_id_context"}, {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"}, {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index fb82f7366b..b63beed403 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2802,6 +2802,11 @@ int SSL_state(const SSL *ssl) return(ssl->state); } +void SSL_set_state(SSL *ssl, int state) + { + ssl->state = state; + } + void SSL_set_verify_result(SSL *ssl,long arg) { ssl->verify_result=arg; @@ -3060,6 +3065,16 @@ void ssl_clear_hash_ctx(EVP_MD_CTX **hash) *hash=NULL; } +void SSL_set_debug(SSL *s, int debug) + { + s->debug = debug; + } + +int SSL_cache_hit(SSL *s) + { + return s->hit; + } + #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) #include "../crypto/bio/bss_file.c" #endif diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index a3ce6525ee..3f0b19558d 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -836,6 +836,35 @@ long SSL_SESSION_set_time(SSL_SESSION *s, long t) return(t); } +unsigned int SSL_SESSION_get_id_len(SSL_SESSION *s) + { + return s->session_id_length; + } + +const unsigned char *SSL_SESSION_get0_id(SSL_SESSION *s) + { + return s->session_id; + } + +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) + { + return s->peer; + } + +int SSL_SESSION_set1_id_context(SSL_SESSION *s,const unsigned char *sid_ctx, + unsigned int sid_ctx_len) + { + if(sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) + { + SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + s->sid_ctx_length=sid_ctx_len; + memcpy(s->sid_ctx,sid_ctx,sid_ctx_len); + + return 1; + } + long SSL_CTX_set_timeout(SSL_CTX *s, long t) { long l; -- 2.34.1