SSL_SESSION_free(ss);
return(0);
}
+#ifndef OPENSSL_NO_TLSEXT
+ /* If RFC4507 ticket use empty session ID */
+ if (s->tlsext_ticket_expected)
+ {
+ ss->session_id_length = 0;
+ goto sess_id_done;
+ }
+#endif
/* Choose which callback will set the session ID */
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
if(s->generate_session_id)
return(0);
}
#ifndef OPENSSL_NO_TLSEXT
+ sess_id_done:
if (s->tlsext_hostname) {
ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
if (ss->tlsext_hostname == NULL) {
return(1);
}
-int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len)
+int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
+ const unsigned char *limit)
{
/* This is used only by servers. */
- SSL_SESSION *ret=NULL,data;
+ SSL_SESSION *ret=NULL;
int fatal = 0;
+#ifndef OPENSSL_NO_TLSEXT
+ int r;
+#endif
- data.ssl_version=s->version;
- data.session_id_length=len;
if (len > SSL_MAX_SSL_SESSION_ID_LENGTH)
goto err;
- memcpy(data.session_id,session_id,len);
-
+#ifndef OPENSSL_NO_TLSEXT
+ r = tls1_process_ticket(s, session_id, len, limit, &ret);
+ if (r == -1)
+ {
+ fatal = 1;
+ goto err;
+ }
+ else if (r == 0)
+ goto err;
+ else if (!ret && !(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+#else
if (!(s->session_ctx->session_cache_mode & SSL_SESS_CACHE_NO_INTERNAL_LOOKUP))
+#endif
{
+ SSL_SESSION data;
+ data.ssl_version=s->version;
+ data.session_id_length=len;
+ if (len == 0)
+ return 0;
+ memcpy(data.session_id,session_id,len);
CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
ret=(SSL_SESSION *)lh_retrieve(s->session_ctx->sessions,&data);
if (ret != NULL)
/* Now ret is non-NULL, and we own one of its reference counts. */
- if((s->verify_mode&SSL_VERIFY_PEER)
- && (!s->sid_ctx_length || ret->sid_ctx_length != s->sid_ctx_length
- || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length)))
- {
+ if (ret->sid_ctx_length != s->sid_ctx_length
+ || memcmp(ret->sid_ctx,s->sid_ctx,ret->sid_ctx_length))
+ {
/* We've found the session named by the client, but we don't
* want to use it in this context. */
-
- if (s->sid_ctx_length == 0)
- {
- /* application should have used SSL[_CTX]_set_session_id_context
- * -- we could tolerate this and just pretend we never heard
- * of this session, but then applications could effectively
- * disable the session cache by accident without anyone noticing */
- SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
- fatal = 1;
- goto err;
- }
- else
- {
#if 0 /* The client cannot always know when a session is not appropriate,
- * so we shouldn't generate an error message. */
+ * so we shouldn't generate an error message. */
- SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+ SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
#endif
- goto err; /* treat like cache miss */
- }
+ goto err; /* treat like cache miss */
+ }
+
+ if((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0)
+ {
+ /* We can't be sure if this session is being used out of
+ * context, which is especially important for SSL_VERIFY_PEER.
+ * The application should have used SSL[_CTX]_set_session_id_context.
+ *
+ * For this error case, we generate an error instead of treating
+ * the event like a cache miss (otherwise it would be easy for
+ * applications to effectively disable the session cache by
+ * accident without anyone noticing).
+ */
+
+ SSLerr(SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
+ fatal = 1;
+ goto err;
}
if (ret->cipher == NULL)
if (ss->ciphers != NULL) sk_SSL_CIPHER_free(ss->ciphers);
#ifndef OPENSSL_NO_TLSEXT
if (ss->tlsext_hostname != NULL) OPENSSL_free(ss->tlsext_hostname);
+ if (ss->tlsext_tick != NULL) OPENSSL_free(ss->tlsext_tick);
#ifndef OPENSSL_NO_EC
ss->tlsext_ecpointformatlist_length = 0;
if (ss->tlsext_ecpointformatlist != NULL) OPENSSL_free(ss->tlsext_ecpointformatlist);
if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
session->krb5_client_princ_len > 0)
{
- s->kssl_ctx->client_princ = (char *)malloc(session->krb5_client_princ_len + 1);
+ s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
memcpy(s->kssl_ctx->client_princ,session->krb5_client_princ,
session->krb5_client_princ_len);
s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
}
}
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+ int (*cb)(struct ssl_st *ssl,SSL_SESSION *sess))
+ {
+ ctx->new_session_cb=cb;
+ }
+
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess)
+ {
+ return ctx->new_session_cb;
+ }
+
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
+ void (*cb)(SSL_CTX *ctx,SSL_SESSION *sess))
+ {
+ ctx->remove_session_cb=cb;
+ }
+
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX * ctx,SSL_SESSION *sess)
+ {
+ return ctx->remove_session_cb;
+ }
+
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+ SSL_SESSION *(*cb)(struct ssl_st *ssl,
+ unsigned char *data,int len,int *copy))
+ {
+ ctx->get_session_cb=cb;
+ }
+
+SSL_SESSION * (*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl,
+ unsigned char *data,int len,int *copy)
+ {
+ return ctx->get_session_cb;
+ }
+
+void SSL_CTX_set_info_callback(SSL_CTX *ctx,
+ void (*cb)(const SSL *ssl,int type,int val))
+ {
+ ctx->info_callback=cb;
+ }
+
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val)
+ {
+ return ctx->info_callback;
+ }
+
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey))
+ {
+ ctx->client_cert_cb=cb;
+ }
+
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL * ssl, X509 ** x509 , EVP_PKEY **pkey)
+ {
+ return ctx->client_cert_cb;
+ }
+
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
+ {
+ ctx->app_gen_cookie_cb=cb;
+ }
+
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len))
+ {
+ ctx->app_verify_cookie_cb=cb;
+ }
+
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)