I am trying to solve a problem for which the "SSL On-Disk Session Caching" seems to be an appropriate solution. I need confirmation and pointers to HOW-TO on this subject.
I have a CLI application that connects over SSL to a gSOAP server. I'm currently experiencing around 7 seconds for the session (or communication) or be established. I can affort this latency for one-time, call it a "login" phase. I need to find a way to lower this to zero or 1 second for subsequent usage.
The end result should be something like cvs login; cvs logout, that is
cli login cli cmd cli cmd ... cli logout // or some time expires
O'Reilly OpenSSL, "Advanced Programming with SSL" chapter talks about "An On-Disk, session caching framework". This seems like an appropriate solution. But first I wanted to check...
So I ask you gurus. Is this the way ....
Also I'd appreciate some help from people with gSOAP experience to dig into the 7 seconds latency. It has been posted to gSOAP group but with no avail.
Thanks
__________________________________________________________________
Introducing the New Netscape Internet Service. Only $9.95 a month -- Sign up today at http://isp.netscape.com/register
Netscape. Just the Net You Need.
New! Netscape Toolbar for Internet Explorer Search from anywhere on the Web and block those annoying pop-ups. Download now at http://channels.netscape.com/ns/search/install.jsp ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]
The O'Reilly book does not give any code on how to implement session caching. It just points to some stub functions.
So here is some code:
you will need to setup your CTX's with theses callback like the O'Reilly book talks about.
int new_session_cb(SSL *ctx, SSL_SESSION *session) { char *local, *lname, *lpath; unsigned char *sess_id, c[2]; char *cachepass = NULL; /* Session encryption passwd */ int i; BIO *bio; const EVP_CIPHER *enc;
/* convert SESSION_ID to human readable hex string */
sess_id = malloc(session->session_id_length + 1);
for(i=0; i < session->session_id_length; i++)
{
sprintf(c,"%x", session->session_id[i]);
sess_id[i] = c[0]; }
sess_id[session->session_id_length] = '\0';
#ifdef DEBUG fprintf(stderr, "SESSION_ID is: %s", sess_id); #endif /* sets up a location to write session cache files. */ lpath = strdup("/opt/app/sessions/"); local = malloc(strlen(lpath) + strlen(sess_id) + 1); sprintf(local, "%s%s", lpath, sess_id);
lname = malloc(strlen(lpath)+strlen(local)+3); sprintf(lname, "%s.l%s", lpath, sess_id);
bio = BIO_new_file(local, "w"); /* create the lock file */ if(link(local, lname) == -1) int_error("Error: Creating session lock file!"); enc = EVP_des_ede3_cbc(); /* gets p12 password from shared memory */
/* passphrase to encrypt the session keys with. */ cachepass = strdup( "password" ); PEM_ASN1_write_bio((int (*)())i2d_SSL_SESSION, PEM_STRING_SSL_SESSION, \ bio,(char *)session, enc, NULL, 0, NULL, cachepass); if( cachepass != NULL); free(cachepass);
BIO_flush(bio); BIO_free(bio);
free(sess_id); free(local); free(lpath); unlink(lname); free(lname);
return 1; }
void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *session) { char *local, *lpath, *lname; unsigned char *sess_id, c[2]; int i;
/* convert SESSION_ID to human readable hex string */
sess_id = malloc(session->session_id_length + 1);
for(i=0; i < session->session_id_length; i++)
{
sprintf(c,"%x", session->session_id[i]);
sess_id[i] = c[0]; }
sess_id[session->session_id_length] = '\0';
/* sets up a location to delete session cache file from. */ lpath = strdup("/opt/app/sessions/"); local = malloc(strlen(lpath) + strlen(sess_id) + 1); sprintf(local, "%s%s", lpath, sess_id);
lname = malloc(strlen(lpath)+strlen(local)+3); sprintf(lname, "%s.l%s", lpath, sess_id);
if(access(lname, F_OK) == 0) { unlink(lname); } if(access(local, F_OK) == 0) { unlink(local); }
free(sess_id); free(local); free(lname); free(lpath); }
SSL_SESSION *get_session_cb(SSL *ctx, unsigned char *id, int len, int *ref) { char *local, *lname, *lpath; unsigned char *sess_id, c[2]; char *cachepass = NULL; /* session password from shared memory */ int i, j; BIO *bio; const EVP_CIPHER *enc; SSL_SESSION *sess;
/* convert SESSION_ID to human readable hex string */
sess_id = malloc(len + 1);
for(i=0; i < len; i++)
{
sprintf(c,"%x", id[i]);
sess_id[i] = c[0]; }
sess_id[len] = '\0';
#ifdef DEBUG fprintf( stderr, "SESSION_ID is: %s", sessid ); #endif /* sets up a location to read session cache file from. */ lpath = strdup("/opt/app/sessions/"); local = malloc(strlen(lpath) + strlen(sess_id) + 1); sprintf(local, "%s%s", lpath, sess_id);
lname = malloc(strlen(lpath)+strlen(local)+3); sprintf(lname, "%s.l%s", lpath, sess_id);
/* checks for lock file and waits if there is one. */ for(j=0; (access(lname, F_OK) == 0) || (j > 10); j++) { /* sleep for 10th of a second */ usleep(100000); } /* create the lock file */ if(link(local, lname) == -1) int_error("Error: Createing session lock file!"); enc = EVP_des_ede3_cbc(); bio = BIO_new_file(local, "r");
/* this password will need to be the same as the passphrase * used to write the session to disk */
cachepass = strdup( "password" );
sess = PEM_read_bio_SSL_SESSION(bio, NULL, NULL, cachepass);
if(cachepass != NULL)
free(cachepass);
BIO_flush(bio); BIO_free(bio);
free(sess_id); free(local); free(lpath); unlink(lname); free(lname);
/* not sure if this is *ref = 0 or ref = 0 */ ref = 0;
return sess; }
______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List [EMAIL PROTECTED] Automated List Manager [EMAIL PROTECTED]