vendor/nginx/src/event/ngx_event_openssl.c in nginxtra-1.8.1.12 vs vendor/nginx/src/event/ngx_event_openssl.c in nginxtra-1.10.1.12

- old
+ new

@@ -37,10 +37,13 @@ ngx_str_t *sess_ctx); ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data); static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn, ngx_ssl_session_t *sess); static ngx_ssl_session_t *ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, +#if OPENSSL_VERSION_NUMBER >= 0x10100003L + const +#endif u_char *id, int len, int *copy); static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess); static void ngx_ssl_expire_sessions(ngx_ssl_session_cache_t *cache, ngx_slab_pool_t *shpool, ngx_uint_t n); static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp, @@ -50,11 +53,11 @@ static int ngx_ssl_session_ticket_key_callback(ngx_ssl_conn_t *ssl_conn, unsigned char *name, unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); #endif -#if (OPENSSL_VERSION_NUMBER < 0x10002002L || defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10002002L static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *str); #endif static void *ngx_openssl_create_conf(ngx_cycle_t *cycle); static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -106,19 +109,27 @@ ngx_int_t ngx_ssl_init(ngx_log_t *log) { +#if OPENSSL_VERSION_NUMBER >= 0x10100003L + + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); + +#else + #ifndef OPENSSL_IS_BORINGSSL OPENSSL_config(NULL); #endif SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); +#endif + #if OPENSSL_VERSION_NUMBER >= 0x0090800fL #ifndef SSL_OP_NO_COMPRESSION { /* * Disable gzip compression in OpenSSL prior to 1.0.0 version, @@ -745,11 +756,11 @@ if (key_length != 512) { return NULL; } -#ifndef OPENSSL_NO_DEPRECATED +#if (OPENSSL_VERSION_NUMBER < 0x10100003L && !defined OPENSSL_NO_DEPRECATED) if (key == NULL) { key = RSA_generate_key(512, RSA_F4, NULL, NULL); } @@ -1158,18 +1169,20 @@ c->recv = ngx_ssl_recv; c->send = ngx_ssl_write; c->recv_chain = ngx_ssl_recv_chain; c->send_chain = ngx_ssl_send_chain; +#if OPENSSL_VERSION_NUMBER < 0x10100000L #ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS /* initial handshake done, disable renegotiation (CVE-2009-3555) */ if (c->ssl->connection->s3) { c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS; } #endif +#endif return NGX_OK; } sslerr = SSL_get_error(c->ssl->connection, n); @@ -1592,11 +1605,11 @@ if (send + size > limit) { size = (ssize_t) (limit - send); } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, - "SSL buf copy: %d", size); + "SSL buf copy: %z", size); ngx_memcpy(buf->last, in->buf->pos, size); buf->last += size; in->buf->pos += size; @@ -1664,11 +1677,11 @@ int n, sslerr; ngx_err_t err; ngx_ssl_clear_error(c->log); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size); n = SSL_write(c->ssl->connection, data, size); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_write: %d", n); @@ -1763,10 +1776,23 @@ ngx_ssl_shutdown(ngx_connection_t *c) { int n, sslerr, mode; ngx_err_t err; + if (SSL_in_init(c->ssl->connection)) { + /* + * OpenSSL 1.0.2f complains if SSL_shutdown() is called during + * an SSL handshake, while previous versions always return 0. + * Avoid calling SSL_shutdown() if handshake wasn't completed. + */ + + SSL_free(c->ssl->connection); + c->ssl = NULL; + + return NGX_OK; + } + if (c->timedout) { mode = SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN; SSL_set_quiet_shutdown(c->ssl->connection, 1); } else { @@ -1793,11 +1819,11 @@ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n); sslerr = 0; - /* SSL_shutdown() never returns -1, on error it returns 0 */ + /* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */ if (n != 1 && ERR_peek_error()) { sslerr = SSL_get_error(c->ssl->connection, n); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, @@ -1939,10 +1965,11 @@ #endif #ifdef SSL_R_INAPPROPRIATE_FALLBACK || n == SSL_R_INAPPROPRIATE_FALLBACK /* 373 */ #endif || n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */ +#ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE || n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */ || n == SSL_R_SSLV3_ALERT_BAD_RECORD_MAC /* 1020 */ || n == SSL_R_TLSV1_ALERT_DECRYPTION_FAILED /* 1021 */ || n == SSL_R_TLSV1_ALERT_RECORD_OVERFLOW /* 1022 */ || n == SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE /* 1030 */ @@ -1961,11 +1988,13 @@ || n == SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION /* 1060 */ || n == SSL_R_TLSV1_ALERT_PROTOCOL_VERSION /* 1070 */ || n == SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY /* 1071 */ || n == SSL_R_TLSV1_ALERT_INTERNAL_ERROR /* 1080 */ || n == SSL_R_TLSV1_ALERT_USER_CANCELLED /* 1090 */ - || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION) /* 1100 */ + || n == SSL_R_TLSV1_ALERT_NO_RENEGOTIATION /* 1100 */ +#endif + ) { switch (c->log_error) { case NGX_ERROR_IGNORE_ECONNRESET: case NGX_ERROR_INFO: @@ -2043,11 +2072,11 @@ next: (void) ERR_get_error(); } - ngx_log_error(level, log, err, "%s)", errstr); + ngx_log_error(level, log, err, "%*s)", p - errstr, errstr); } ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, @@ -2126,29 +2155,32 @@ ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx) { int n, i; X509 *cert; X509_NAME *name; - EVP_MD_CTX md; + EVP_MD_CTX *md; unsigned int len; STACK_OF(X509_NAME) *list; u_char buf[EVP_MAX_MD_SIZE]; /* * Session ID context is set based on the string provided, * the server certificate, and the client CA list. */ - EVP_MD_CTX_init(&md); + md = EVP_MD_CTX_create(); + if (md == NULL) { + return NGX_ERROR; + } - if (EVP_DigestInit_ex(&md, EVP_sha1(), NULL) == 0) { + if (EVP_DigestInit_ex(md, EVP_sha1(), NULL) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestInit_ex() failed"); goto failed; } - if (EVP_DigestUpdate(&md, sess_ctx->data, sess_ctx->len) == 0) { + if (EVP_DigestUpdate(md, sess_ctx->data, sess_ctx->len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; } @@ -2158,11 +2190,11 @@ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_digest() failed"); goto failed; } - if (EVP_DigestUpdate(&md, buf, len) == 0) { + if (EVP_DigestUpdate(md, buf, len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; } @@ -2178,25 +2210,25 @@ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "X509_NAME_digest() failed"); goto failed; } - if (EVP_DigestUpdate(&md, buf, len) == 0) { + if (EVP_DigestUpdate(md, buf, len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; } } } - if (EVP_DigestFinal_ex(&md, buf, &len) == 0) { + if (EVP_DigestFinal_ex(md, buf, &len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "EVP_DigestUpdate() failed"); goto failed; } - EVP_MD_CTX_cleanup(&md); + EVP_MD_CTX_destroy(md); if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_set_session_id_context() failed"); return NGX_ERROR; @@ -2204,11 +2236,11 @@ return NGX_OK; failed: - EVP_MD_CTX_cleanup(&md); + EVP_MD_CTX_destroy(md); return NGX_ERROR; } @@ -2425,12 +2457,15 @@ return 0; } static ngx_ssl_session_t * -ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, u_char *id, int len, - int *copy) +ngx_ssl_get_cached_session(ngx_ssl_conn_t *ssl_conn, +#if OPENSSL_VERSION_NUMBER >= 0x10100003L + const +#endif + u_char *id, int len, int *copy) { #if OPENSSL_VERSION_NUMBER >= 0x0090707fL const #endif u_char *p; @@ -2443,11 +2478,11 @@ ngx_ssl_sess_id_t *sess_id; ngx_ssl_session_cache_t *cache; u_char buf[NGX_SSL_MAX_SESSION_SIZE]; ngx_connection_t *c; - hash = ngx_crc32_short(id, (size_t) len); + hash = ngx_crc32_short((u_char *) (uintptr_t) id, (size_t) len); *copy = 0; c = ngx_ssl_get_connection(ssl_conn); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, @@ -2481,11 +2516,12 @@ /* hash == node->key */ sess_id = (ngx_ssl_sess_id_t *) node; - rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data); + rc = ngx_memn2cmp((u_char *) (uintptr_t) id, sess_id->id, + (size_t) len, (size_t) node->data); if (rc == 0) { if (sess_id->expire > ngx_time()) { ngx_memcpy(buf, sess_id->session, sess_id->len); @@ -2525,13 +2561,13 @@ void ngx_ssl_remove_cached_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) { - SSL_CTX_remove_session(ssl, sess); + SSL_CTX_remove_session(ssl, sess); - ngx_ssl_remove_session(ssl, sess); + ngx_ssl_remove_session(ssl, sess); } static void ngx_ssl_remove_session(SSL_CTX *ssl, ngx_ssl_session_t *sess) @@ -2854,11 +2890,11 @@ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl session ticket encrypt, key: \"%*s\" (%s session)", ngx_hex_dump(buf, key[0].name, 16) - buf, buf, SSL_session_reused(ssl_conn) ? "reused" : "new"); - RAND_pseudo_bytes(iv, 16); + RAND_bytes(iv, 16); EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key[0].aes_key, iv); HMAC_Init_ex(hctx, key[0].hmac_key, 16, ngx_ssl_session_ticket_md(), NULL); ngx_memcpy(name, key[0].name, 16); @@ -2927,11 +2963,11 @@ cert = SSL_get_peer_certificate(c->ssl->connection); if (cert == NULL) { return NGX_ERROR; } -#if (OPENSSL_VERSION_NUMBER >= 0x10002002L && !defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER >= 0x10002002L /* X509_check_host() is only available in OpenSSL 1.0.2+ */ if (name->len == 0) { goto failed; @@ -3044,11 +3080,11 @@ X509_free(cert); return NGX_OK; } -#if (OPENSSL_VERSION_NUMBER < 0x10002002L || defined LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER < 0x10002002L static ngx_int_t ngx_ssl_check_name(ngx_str_t *name, ASN1_STRING *pattern) { u_char *s, *p, *end; @@ -3521,10 +3557,14 @@ static void ngx_openssl_exit(ngx_cycle_t *cycle) { +#if OPENSSL_VERSION_NUMBER < 0x10100003L + EVP_cleanup(); #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); +#endif + #endif }