int ssl_get_new_session(SSL *s, int session) { /* This gets used by clients and servers. */ SSL_SESSION *ss = NULL; if ((ss = SSL_SESSION_new()) == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); return 0; } /* If the context has a default timeout, use it */ if (s->session_ctx->session_timeout == 0) ss->timeout = SSL_get_default_timeout(s); else ss->timeout = s->session_ctx->session_timeout; SSL_SESSION_free(s->session); s->session = NULL; if (session) { if (!ssl_generate_session_id(s, ss)) { /* SSLfatal() already called */ SSL_SESSION_free(ss); return 0; } if (s->ext.hostname) { ss->ext.hostname = OPENSSL_strdup(s->ext.hostname); if (ss->ext.hostname == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } } } else { ss->session_id_length = 0; } if (s->sid_ctx_length > sizeof ss->sid_ctx) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); ss->sid_ctx_length = s->sid_ctx_length; s->session = ss; ss->ssl_version = s->version; ss->verify_result = X509_V_OK; /* If client supports extended master secret set it in session */ if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) ss->flags |= SSL_SESS_FLAG_EXTMS; return 1; }
static int openssl_ssl_get(lua_State*L) { SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl"); int i; int top = lua_gettop(L); for (i = 2; i <= top; i++) { const char* what = luaL_checklstring(L, i, NULL); if (strcmp(what, "fd") == 0) { lua_pushinteger(L, SSL_get_fd(s)); } else if (strcmp(what, "rfd") == 0) { lua_pushinteger(L, SSL_get_rfd(s)); } else if (strcmp(what, "wfd") == 0) { lua_pushinteger(L, SSL_get_wfd(s)); } else if (strcmp(what, "client_CA_list") == 0) { STACK_OF(X509_NAME)* sn = SSL_get_client_CA_list(s); PUSH_OBJECT(sn, "openssl.sk_x509_name"); } else if (strcmp(what, "read_ahead") == 0) { lua_pushboolean(L, SSL_get_read_ahead(s)); } else if (strcmp(what, "shared_ciphers") == 0) { char buf[LUAL_BUFFERSIZE] = {0}; lua_pushstring(L, SSL_get_shared_ciphers(s, buf, sizeof(buf))); } else if (strcmp(what, "cipher_list") == 0) { //TODO FIX lua_pushstring(L, SSL_get_cipher_list(s, 0)); } else if (strcmp(what, "verify_mode") == 0) { //FIX lua_pushinteger(L, SSL_get_verify_mode(s)); } else if (strcmp(what, "verify_depth") == 0) { lua_pushinteger(L, SSL_get_verify_depth(s)); } else if (strcmp(what, "state_string") == 0) { lua_pushstring(L, SSL_state_string(s)); } else if (strcmp(what, "state_string_long") == 0) { lua_pushstring(L, SSL_state_string_long(s)); } else if (strcmp(what, "rstate_string") == 0) { lua_pushstring(L, SSL_rstate_string(s)); } else if (strcmp(what, "rstate_string_long") == 0) { lua_pushstring(L, SSL_rstate_string_long(s)); } else if (strcmp(what, "version") == 0) { lua_pushstring(L, SSL_get_version(s)); } else if (strcmp(what, "iversion") == 0) { lua_pushinteger(L, SSL_version(s)); } else if (strcmp(what, "default_timeout") == 0) { lua_pushinteger(L, SSL_get_default_timeout(s)); } else if (strcmp(what, "certificate") == 0) { X509* cert = SSL_get_certificate(s); PUSH_OBJECT(cert, "openssl.x509"); } else if (strcmp(what, "verify_result") == 0) { long l = SSL_get_verify_result(s); lua_pushinteger(L, l); } else if (strcmp(what, "version") == 0) { lua_pushstring(L, SSL_get_version(s)); } else if (strcmp(what, "state") == 0) { lua_pushinteger(L, SSL_state(s)); } else if (strcmp(what, "hostname") == 0) { lua_pushstring(L, SSL_get_servername(s, TLSEXT_NAMETYPE_host_name)); } else luaL_argerror(L, i, "can't understant"); } return top - 1; }
int ssl_get_new_session(SSL *s, int session) { /* This gets used by clients and servers. */ unsigned int tmp; SSL_SESSION *ss = NULL; GEN_SESSION_CB cb = def_generate_session_id; if ((ss = SSL_SESSION_new()) == NULL) return (0); /* If the context has a default timeout, use it */ if (s->session_ctx->session_timeout == 0) ss->timeout = SSL_get_default_timeout(s); else ss->timeout = s->session_ctx->session_timeout; SSL_SESSION_free(s->session); s->session = NULL; if (session) { if (s->version == SSL3_VERSION) { ss->ssl_version = SSL3_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == TLS1_VERSION) { ss->ssl_version = TLS1_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == TLS1_1_VERSION) { ss->ssl_version = TLS1_1_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == TLS1_2_VERSION) { ss->ssl_version = TLS1_2_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == TLS1_3_VERSION) { ss->ssl_version = TLS1_3_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == DTLS1_BAD_VER) { ss->ssl_version = DTLS1_BAD_VER; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == DTLS1_VERSION) { ss->ssl_version = DTLS1_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else if (s->version == DTLS1_2_VERSION) { ss->ssl_version = DTLS1_2_VERSION; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; } else { SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); SSL_SESSION_free(ss); return (0); } /*- * If RFC5077 ticket, use empty session ID (as server). * Note that: * (a) ssl_get_prev_session() does lookahead into the * ClientHello extensions to find the session ticket. * When ssl_get_prev_session() fails, statem_srvr.c calls * ssl_get_new_session() in tls_process_client_hello(). * At that point, it has not yet parsed the extensions, * however, because of the lookahead, it already knows * whether a ticket is expected or not. * * (b) statem_clnt.c calls ssl_get_new_session() before parsing * ServerHello extensions, and before recording the session * ID received from the server, so this block is a noop. */ if (s->ext.ticket_expected) { ss->session_id_length = 0; goto sess_id_done; } /* Choose which callback will set the session ID */ CRYPTO_THREAD_read_lock(s->lock); CRYPTO_THREAD_read_lock(s->session_ctx->lock); if (s->generate_session_id) cb = s->generate_session_id; else if (s->session_ctx->generate_session_id) cb = s->session_ctx->generate_session_id; CRYPTO_THREAD_unlock(s->session_ctx->lock); CRYPTO_THREAD_unlock(s->lock); /* Choose a session ID */ memset(ss->session_id, 0, ss->session_id_length); tmp = (int)ss->session_id_length; if (!cb(s, ss->session_id, &tmp)) { /* The callback failed */ SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); SSL_SESSION_free(ss); return (0); } /* * Don't allow the callback to set the session length to zero. nor * set it higher than it was. */ if (tmp == 0 || tmp > ss->session_id_length) { /* The callback set an illegal length */ SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); SSL_SESSION_free(ss); return (0); } ss->session_id_length = tmp; /* Finally, check for a conflict */ if (SSL_has_matching_session_id(s, ss->session_id, (unsigned int)ss->session_id_length)) { SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); SSL_SESSION_free(ss); return (0); } sess_id_done: if (s->ext.hostname) { ss->ext.hostname = OPENSSL_strdup(s->ext.hostname); if (ss->ext.hostname == NULL) { SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } } } else { ss->session_id_length = 0; } if (s->sid_ctx_length > sizeof ss->sid_ctx) { SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); ss->sid_ctx_length = s->sid_ctx_length; s->session = ss; ss->ssl_version = s->version; ss->verify_result = X509_V_OK; /* If client supports extended master secret set it in session */ if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) ss->flags |= SSL_SESS_FLAG_EXTMS; return (1); }
int ssl_get_new_session(SSL *s, int session) { unsigned int tmp; SSL_SESSION *ss = NULL; GEN_SESSION_CB cb = def_generate_session_id; /* This gets used by clients and servers. */ if ((ss = SSL_SESSION_new()) == NULL) return (0); /* If the context has a default timeout, use it */ if (s->session_ctx->session_timeout == 0) ss->timeout = SSL_get_default_timeout(s); else ss->timeout = s->session_ctx->session_timeout; if (s->session != NULL) { SSL_SESSION_free(s->session); s->session = NULL; } if (session) { switch (s->version) { case TLS1_VERSION: case TLS1_1_VERSION: case TLS1_2_VERSION: case DTLS1_VERSION: ss->ssl_version = s->version; ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; break; default: SSLerror(s, SSL_R_UNSUPPORTED_SSL_VERSION); SSL_SESSION_free(ss); return (0); } /* If RFC4507 ticket use empty session ID. */ if (s->internal->tlsext_ticket_expected) { ss->session_id_length = 0; goto sess_id_done; } /* Choose which callback will set the session ID. */ CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); if (s->internal->generate_session_id) cb = s->internal->generate_session_id; else if (s->session_ctx->internal->generate_session_id) cb = s->session_ctx->internal->generate_session_id; CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); /* Choose a session ID. */ tmp = ss->session_id_length; if (!cb(s, ss->session_id, &tmp)) { /* The callback failed */ SSLerror(s, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); SSL_SESSION_free(ss); return (0); } /* * Don't allow the callback to set the session length to zero. * nor set it higher than it was. */ if (!tmp || (tmp > ss->session_id_length)) { /* The callback set an illegal length */ SSLerror(s, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); SSL_SESSION_free(ss); return (0); } ss->session_id_length = tmp; /* Finally, check for a conflict. */ if (SSL_has_matching_session_id(s, ss->session_id, ss->session_id_length)) { SSLerror(s, SSL_R_SSL_SESSION_ID_CONFLICT); SSL_SESSION_free(ss); return (0); } sess_id_done: if (s->tlsext_hostname) { ss->tlsext_hostname = strdup(s->tlsext_hostname); if (ss->tlsext_hostname == NULL) { SSLerror(s, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } } } else { ss->session_id_length = 0; } if (s->sid_ctx_length > sizeof ss->sid_ctx) { SSLerror(s, ERR_R_INTERNAL_ERROR); SSL_SESSION_free(ss); return 0; } memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); ss->sid_ctx_length = s->sid_ctx_length; s->session = ss; ss->ssl_version = s->version; ss->verify_result = X509_V_OK; return (1); }