Klaus Demo nginx / 6ec0f4d
SSL: session id context now includes certificate hash. This prevents inappropriate session reuse in unrelated server{} blocks, while preserving ability to restore sessions on other servers when using TLS Session Tickets. Additionally, session context is now set even if there is no session cache configured. This is needed as it's also used for TLS Session Tickets. Thanks to Antoine Delignat-Lavaud and Piotr Sikora. Maxim Dounin 7 years ago
1 changed file(s) with 96 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
3232 ngx_err_t err, char *text);
3333 static void ngx_ssl_clear_error(ngx_log_t *log);
3434
35 static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl,
36 ngx_str_t *sess_ctx);
3537 ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
3638 static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
3739 ngx_ssl_session_t *sess);
19721974
19731975 SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
19741976
1977 if (ngx_ssl_session_id_context(ssl, sess_ctx) != NGX_OK) {
1978 return NGX_ERROR;
1979 }
1980
19751981 if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
19761982 SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
19771983 return NGX_OK;
19781984 }
1979
1980 SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
19811985
19821986 if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
19831987
20322036 }
20332037
20342038 return NGX_OK;
2039 }
2040
2041
2042 static ngx_int_t
2043 ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
2044 {
2045 int n, i;
2046 X509 *cert;
2047 X509_NAME *name;
2048 EVP_MD_CTX md;
2049 unsigned int len;
2050 STACK_OF(X509_NAME) *list;
2051 u_char buf[EVP_MAX_MD_SIZE];
2052
2053 /*
2054 * Session ID context is set based on the string provided,
2055 * the server certificate, and the client CA list.
2056 */
2057
2058 EVP_MD_CTX_init(&md);
2059
2060 if (EVP_DigestInit_ex(&md, EVP_sha1(), NULL) == 0) {
2061 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2062 "EVP_DigestInit_ex() failed");
2063 goto failed;
2064 }
2065
2066 if (EVP_DigestUpdate(&md, sess_ctx->data, sess_ctx->len) == 0) {
2067 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2068 "EVP_DigestUpdate() failed");
2069 goto failed;
2070 }
2071
2072 cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
2073
2074 if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
2075 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2076 "X509_digest() failed");
2077 goto failed;
2078 }
2079
2080 if (EVP_DigestUpdate(&md, buf, len) == 0) {
2081 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2082 "EVP_DigestUpdate() failed");
2083 goto failed;
2084 }
2085
2086 list = SSL_CTX_get_client_CA_list(ssl->ctx);
2087
2088 if (list != NULL) {
2089 n = sk_X509_NAME_num(list);
2090
2091 for (i = 0; i < n; i++) {
2092 name = sk_X509_NAME_value(list, i);
2093
2094 if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
2095 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2096 "X509_NAME_digest() failed");
2097 goto failed;
2098 }
2099
2100 if (EVP_DigestUpdate(&md, buf, len) == 0) {
2101 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2102 "EVP_DigestUpdate() failed");
2103 goto failed;
2104 }
2105 }
2106 }
2107
2108 if (EVP_DigestFinal_ex(&md, buf, &len) == 0) {
2109 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2110 "EVP_DigestUpdate() failed");
2111 goto failed;
2112 }
2113
2114 EVP_MD_CTX_cleanup(&md);
2115
2116 if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
2117 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
2118 "SSL_CTX_set_session_id_context() failed");
2119 return NGX_ERROR;
2120 }
2121
2122 return NGX_OK;
2123
2124 failed:
2125
2126 EVP_MD_CTX_cleanup(&md);
2127
2128 return NGX_ERROR;
20352129 }
20362130
20372131