Просмотр исходного кода

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.

Dr. Stephen Henson 13 лет назад
Родитель
Сommit
08557cf22c
14 измененных файлов с 142 добавлено и 35 удалено
  1. 6 0
      CHANGES
  2. 2 0
      apps/apps.h
  3. 1 1
      apps/ciphers.c
  4. 3 3
      apps/s_client.c
  5. 11 11
      apps/s_server.c
  6. 10 8
      apps/sess_id.c
  7. 3 0
      ssl/dtls1.h
  8. 45 12
      ssl/ssl.h
  9. 4 0
      ssl/ssl2.h
  10. 7 0
      ssl/ssl3.h
  11. 5 0
      ssl/ssl_ciph.c
  12. 1 0
      ssl/ssl_err.c
  13. 15 0
      ssl/ssl_lib.c
  14. 29 0
      ssl/ssl_sess.c

+ 6 - 0
CHANGES

@@ -4,6 +4,12 @@
 
  Changes between 1.0.1 and 1.1.0  [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]
+
   *) Minor change to DRBG entropy callback semantics. In some cases
      there is no mutiple of the block length between min_len and
      max_len. Allow the callback to return more than max_len bytes

+ 2 - 0
apps/apps.h

@@ -365,6 +365,8 @@ int raw_write_stdout(const void *,int);
 double app_tminterval (int stop,int usertime);
 #endif
 
+#define OPENSSL_NO_SSL_INTERN
+
 #ifndef OPENSSL_NO_NEXTPROTONEG
 unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
 #endif

+ 1 - 1
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);

+ 3 - 3
apps/s_client.c

@@ -1238,7 +1238,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)
 		{
@@ -1287,7 +1287,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);
 		}
@@ -1972,7 +1972,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),

+ 11 - 11
apps/s_server.c

@@ -2042,7 +2042,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);
 		}
@@ -2380,7 +2380,7 @@ static int init_ssl_connection(SSL *con)
 		BIO_printf(bio_s_out, "\n");
 		}
 #endif
-	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");
@@ -2499,7 +2499,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);
 		}
@@ -2585,7 +2585,7 @@ static int www_body(char *hostname, int s, unsigned char *context)
 				goto err;
 				}
 			/* EVIL HACK! */
-			con->state = SSL_ST_ACCEPT;
+			SSL_set_state(con, SSL_ST_ACCEPT);
 			i=SSL_do_handshake(con);
 			BIO_printf(bio_s_out, "SSL_do_handshake -> %d\n",i);
 			if (i <= 0)
@@ -2651,7 +2651,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);
@@ -2908,7 +2908,7 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
 typedef struct simple_ssl_session_st
 	{
 	unsigned char *id;
-	int idlen;
+	unsigned int idlen;
 	unsigned char *der;
 	int derlen;
 	struct simple_ssl_session_st *next;
@@ -2923,10 +2923,10 @@ static int add_session(SSL *ssl, SSL_SESSION *session)
 
 	sess = OPENSSL_malloc(sizeof(simple_ssl_session));
 
-	sess->idlen = session->session_id_length;
+	sess->idlen = SSL_SESSION_get_id_len(session);
 	sess->derlen = i2d_SSL_SESSION(session, NULL);
 
-	sess->id = BUF_memdup(session->session_id, sess->idlen);
+	sess->id = BUF_memdup(SSL_SESSION_get0_id(session), sess->idlen);
 
 	sess->der = OPENSSL_malloc(sess->derlen);
 	p = sess->der;
@@ -2945,7 +2945,7 @@ static SSL_SESSION *get_session(SSL *ssl, unsigned char *id, int idlen,
 	*do_copy = 0;
 	for (sess = first; sess; sess = sess->next)
 		{
-		if (idlen == sess->idlen && !memcmp(sess->id, id, idlen))
+		if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen))
 			{
 			const unsigned char *p = sess->der;
 			BIO_printf(bio_err, "Lookup session: cache hit\n");
@@ -2959,8 +2959,8 @@ static SSL_SESSION *get_session(SSL *ssl, unsigned char *id, int idlen,
 static void del_session(SSL_CTX *sctx, SSL_SESSION *session)
 	{
 	simple_ssl_session *sess, *prev = NULL;
-	unsigned char *id = session->session_id;
-	int idlen = session->session_id_length;
+	const unsigned char *id = SSL_SESSION_get0_id(session);
+	unsigned int idlen = SSL_SESSION_get_id_len(session);
 	for (sess = first; sess; sess = sess->next)
 		{
 		if (idlen == sess->idlen && !memcmp(sess->id, id, idlen))

+ 10 - 8
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;

+ 3 - 0
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

+ 45 - 12
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? */
@@ -522,8 +529,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
@@ -655,6 +663,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 */
@@ -677,6 +687,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);
@@ -714,7 +726,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;
@@ -723,7 +739,7 @@ typedef struct ssl_comp_st
 #else
 	char *method;
 #endif
-	} SSL_COMP;
+	};
 
 DECLARE_STACK_OF(SSL_COMP)
 DECLARE_LHASH_OF(SSL_SESSION);
@@ -941,6 +957,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
@@ -1057,6 +1075,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
@@ -1301,6 +1321,8 @@ struct ssl_st
 #endif /* OPENSSL_NO_TLSEXT */
 	};
 
+#endif
+
 #ifdef __cplusplus
 }
 #endif
@@ -1611,6 +1633,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);
@@ -1676,6 +1699,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,
@@ -1867,6 +1895,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);
@@ -1977,6 +2006,9 @@ void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx,
 void SSL_set_not_resumable_session_callback(SSL *ssl,
 	int (*cb)(SSL *ssl, int is_forward_secure));
 
+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.
@@ -2154,6 +2186,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

+ 4 - 0
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)

+ 7 - 0
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;
@@ -520,6 +526,7 @@ typedef struct ssl3_state_st
         int send_connection_binding; /* TODOEKR */
 	} SSL3_STATE;
 
+#endif
 
 /* SSLv3 */
 /*client */

+ 5 - 0
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;

+ 1 - 0
ssl/ssl_err.c

@@ -238,6 +238,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"},

+ 15 - 0
ssl/ssl_lib.c

@@ -2934,6 +2934,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;
@@ -3205,6 +3210,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

+ 29 - 0
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;