[PATCH] [PATCH 4 of 4] SSL: add identity hint config directive

Karstens, Nate Nate.Karstens at garmin.com
Wed Sep 6 13:46:06 UTC 2017


Yes, I see what you were saying now, sorry for the confusion. Your updates look good.

How do you plan to get additional feedback? Maybe at nginx.conf? Our particular use case is more of an embedded environment, so our security constraints are different from a high traffic web server. Perhaps we can extrapolate the best approach for that environment given what we know?

As I see it, we have a few alternatives:

1) Read the file from the PSK worker process (as is being done in the current patch)
2) Read the file when the configuration is loaded and cache results in memory (file only needs to be read by master process)
3) Allow the user to choose between 1 and 2 (using a config file setting)
4) Adding encryption to PSK file (encryption key is loaded when configuration is loaded and PSK file is decrypted by worker process)

Can you think of any others?

The main disadvantage of the second option is that you have to reload the configuration file whenever a PSK is added/removed/changed, right? Can you help me understand the performance implications of reloading the configuration file? If severe, maybe those performance implications could be mitigated by functionality specific to the environment the server is operating in? For example, in an environment with thousands of users maybe the administrators could institute a policy of updating the PSK file and reloading the configuration only once every 5 minutes? Other, less complicated environments could operate without any additional functionality.

Nate

-----Original Message-----
From: nginx-devel [mailto:nginx-devel-bounces at nginx.org] On Behalf Of Maxim Dounin
Sent: Monday, September 04, 2017 11:01 AM
To: nginx-devel at nginx.org
Subject: Re: [PATCH] [PATCH 4 of 4] SSL: add identity hint config directive

Hello!

On Fri, Sep 01, 2017 at 01:18:56PM +0000, Karstens, Nate wrote:

> Maxim,
>
> Your changes look good and test well -- works for me!
>
> Thanks for your work on this, and for your patience!

Thank you for your work, too.  Some additionall problems I'v found looking into this:

1. In the previous review,
http://mailman.nginx.org/pipermail/nginx-devel/2017-August/010419.html,
I've asked to not set callback if file is not empty:

: Always configuring a callback is probably not a good idea.
: Instead, there should be a check if file is not empty.
:
: In particular, this will result in cryptic messages like:
:
: ... [error] ... open() "" failed (SSL:) (2: No such file or directory) while SSL handshaking
:
: on servers without PSK file configured if a client tries to
: use PSK.

I think you've probably get me wrong, and instead tried to check the file contents.  This is not what I mean, I've asked to check the "file" string to see if it is empty, and do nothing if it is - that is, if there is no PSK file specified in the configuration.

There should be something like this in the code, similar to
ngx_ssl_dhparam():

@@ -1181,6 +1181,10 @@ ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl  {  #ifdef PSK_MAX_IDENTITY_LEN

+    if (file->len == 0) {
+        return NGX_OK;
+    }
+
     if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
         return NGX_ERROR;
     }

This should prevent configurations without ssl_psk_file configured from trying to use PSK callback and reading the configuration directory in an attempt to find a secret as the code without the check does.

2. Error logging in the ngx_ssl_psk_callback() function is not correct.  It uses ngx_ssl_error() function, which is intended to log OpenSSL-specific errors with error details extracted from the OpenSSL error stack.  This function uses normal file operations though, and the OpenSSL error stack is always empty.  As such, all messages will contain meaningless "(SSL:)" part.  To avoid this, errors should be logged using normal ngx_log_error().

Updated patches below.

Note well that I'm still not sure if it is good idea to read ssl_psk_file from worker processes instead of reading it once on startup as we do with SSL certificate keys (or, for example, ticket keys).  This and the fact that PSK keys are not protected anyhow, neither with additional password nor hashing, implies that PSK keys can be easily compromissed if an attacker is able to read files accessible to nginx user.

I'm going to postpone further work on this till at least some feedback from people using it in the real world.

# HG changeset patch
# User Nate Karstens <nate.karstens at garmin.com> # Date 1503540018 18000
#      Wed Aug 23 21:00:18 2017 -0500
# Node ID a87e224e8d6b2993dfcd8903bfb0e7eb7fd934fa
# Parent  c7d4017c8876af6d8570e400320537d7d39e9578
Core: add function to decode hexadecimal strings.

Adds functionality to convert a hexadecimal string into binary data.
This will be used to decode PSKs stored in hexadecimal representation.

Signed-off-by: Nate Karstens <nate.karstens at garmin.com>

diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1118,6 +1118,56 @@ ngx_hex_dump(u_char *dst, u_char *src, s  }


+ngx_int_t
+ngx_hex_decode(u_char *dst, u_char *src, size_t len) {
+    u_char  ch, decoded;
+
+    if (len & 1) {
+        return NGX_ERROR;
+    }
+
+    while (len) {
+        ch = *src++;
+        len -= 2;
+
+        if (ch >= '0' && ch <= '9') {
+            decoded = ch - '0';
+            goto second;
+        }
+
+        ch |= 0x20;
+
+        if (ch >= 'a' && ch <= 'f') {
+            decoded = ch - 'a' + 10;
+            goto second;
+        }
+
+        return NGX_ERROR;
+
+    second:
+
+        ch = *src++;
+
+        if (ch >= '0' && ch <= '9') {
+            *dst++ = (u_char) ((decoded << 4) + ch - '0');
+            continue;
+        }
+
+        ch |= 0x20;
+
+        if (ch >= 'a' && ch <= 'f') {
+            *dst++ = (u_char) ((decoded << 4) + ch - 'a' + 10);
+            continue;
+        }
+
+        return NGX_ERROR;
+    }
+
+    return NGX_OK;
+}
+
+
 void
 ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)  { diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -177,6 +177,7 @@ time_t ngx_atotm(u_char *line, size_t n)  ngx_int_t ngx_hextoi(u_char *line, size_t n);

 u_char *ngx_hex_dump(u_char *dst, u_char *src, size_t len);
+ngx_int_t ngx_hex_decode(u_char *dst, u_char *src, size_t len);


 #define ngx_base64_encoded_length(len)  (((len + 2) / 3) * 4) # HG changeset patch # User Nate Karstens <nate.karstens at garmin.com> # Date 1503540059 18000
#      Wed Aug 23 21:00:59 2017 -0500
# Node ID 0cc14a10c863f3d9ba6cb8b6d3769592d619d654
# Parent  a87e224e8d6b2993dfcd8903bfb0e7eb7fd934fa
SSL: add support for PSK cipher suites.

Adds support for TLS connections using PSK cipher suites. A new configuration directive, ssl_psk_file, specifies the file that contains a list of identities and associated PSKs. Each line of the file begins with the identity, followed by a colon character (':'), and ending with the PSK. As required by RFC 4279 section 5.4, PSKs may be entered either as plain text or using hexadecimal encoding. Hexadecimal PSKs must begin with "{HEX}". PSKs without this prefix are assumed to be plain text, but they may optionally begin with "{PLAIN}" to denote this. Some examples:

gary:plain_text_password
min:{PLAIN}another_text_password
cliff:{HEX}ab0123CD

PSK functionality can be easily tested with the OpenSSL s_client using the "-psk" and "-psk_identity" options.

Signed-off-by: Nate Karstens <nate.karstens at garmin.com>

diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim
+++ b/contrib/vim/syntax/nginx.vim
@@ -550,6 +550,7 @@ syn keyword ngxDirective contained ssl_p  syn keyword ngxDirective contained ssl_prefer_server_ciphers  syn keyword ngxDirective contained ssl_preread  syn keyword ngxDirective contained ssl_protocols
+syn keyword ngxDirective contained ssl_psk_file
 syn keyword ngxDirective contained ssl_session_cache  syn keyword ngxDirective contained ssl_session_ticket_key  syn keyword ngxDirective contained ssl_session_tickets diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -11,6 +11,7 @@


 #define NGX_SSL_PASSWORD_BUFFER_SIZE  4096
+#define NGX_SSL_PSK_BUFFER_SIZE       4096


 typedef struct {
@@ -24,6 +25,10 @@ static int ngx_ssl_verify_callback(int o  static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
     int ret);
 static void ngx_ssl_passwords_cleanup(void *data);
+#ifdef PSK_MAX_IDENTITY_LEN
+static unsigned int ngx_ssl_psk_callback(ngx_ssl_conn_t *ssl_conn,
+    const char *identity, unsigned char *psk, unsigned int
+max_psk_len); #endif
 static void ngx_ssl_handshake_handler(ngx_event_t *ev);  static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);  static void ngx_ssl_write_handler(ngx_event_t *wev); @@ -110,6 +115,7 @@ int  ngx_ssl_connection_index;  int  ngx_ssl_server_conf_index;  int  ngx_ssl_session_cache_index;  int  ngx_ssl_session_ticket_keys_index;
+int  ngx_ssl_psk_index;
 int  ngx_ssl_certificate_index;
 int  ngx_ssl_next_certificate_index;
 int  ngx_ssl_certificate_name_index;
@@ -195,6 +201,14 @@ ngx_ssl_init(ngx_log_t *log)
         return NGX_ERROR;
     }

+    ngx_ssl_psk_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
+ NULL);
+
+    if (ngx_ssl_psk_index == -1) {
+        ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+                      "SSL_CTX_get_ex_new_index() failed");
+        return NGX_ERROR;
+    }
+
     ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
                                                          NULL);
     if (ngx_ssl_certificate_index == -1) { @@ -1163,6 +1177,176 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_s


 ngx_int_t
+ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file) {
+#ifdef PSK_MAX_IDENTITY_LEN
+
+    if (file->len == 0) {
+        return NGX_OK;
+    }
+
+    if (ngx_conf_full_name(cf->cycle, file, 1) != NGX_OK) {
+        return NGX_ERROR;
+    }
+
+    if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_psk_index, file) == 0) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_set_ex_data() failed");
+        return NGX_ERROR;
+    }
+
+    SSL_CTX_set_psk_server_callback(ssl->ctx, ngx_ssl_psk_callback);
+
+#endif
+
+    return NGX_OK;
+}
+
+
+#ifdef PSK_MAX_IDENTITY_LEN
+
+static unsigned int
+ngx_ssl_psk_callback(ngx_ssl_conn_t *ssl_conn, const char *identity,
+    unsigned char *psk, unsigned int max_psk_len) {
+    u_char            *p, *last, *end, *colon;
+    size_t             len;
+    ssize_t            n;
+    SSL_CTX           *ssl_ctx;
+    ngx_fd_t           fd;
+    ngx_str_t         *file;
+    unsigned int       psk_len;
+    ngx_connection_t  *c;
+    u_char             buf[NGX_SSL_PSK_BUFFER_SIZE];
+
+    c = ngx_ssl_get_connection(ssl_conn);
+
+    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "ssl psk callback");
+
+    ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
+    file = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_psk_index);
+
+    fd = ngx_open_file(file->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+    if (fd == NGX_INVALID_FILE) {
+        ngx_log_error(NGX_LOG_ERR, c->log, ngx_errno,
+                      ngx_open_file_n " \"%V\" failed", file);
+        return 0;
+    }
+
+    psk_len = 0;
+
+    len = 0;
+    last = buf;
+
+    do {
+        n = ngx_read_fd(fd, last, NGX_SSL_PSK_BUFFER_SIZE - len);
+
+        if (n == -1) {
+            ngx_log_error(NGX_LOG_ERR, c->log, ngx_errno,
+                          ngx_read_fd_n " \"%V\" failed", file);
+            goto cleanup;
+        }
+
+        end = last + n;
+
+        if (len && n == 0) {
+            *end++ = LF;
+        }
+
+        for (p = buf; /* void */; p = last) {
+            last = ngx_strlchr(last, end, LF);
+
+            if (last == NULL) {
+                break;
+            }
+
+            len = last++ - p;
+
+            if (len && p[len - 1] == CR) {
+                len--;
+            }
+
+            if (len == 0) {
+                continue;
+            }
+
+            colon = ngx_strlchr(p, p + len, ':');
+
+            if (colon == NULL) {
+                continue;
+            }
+
+            *colon = '\0';
+
+            if (ngx_strcmp(p, identity) != 0) {
+                continue;
+            }
+
+            len -= colon + 1 - p;
+            p = colon + 1;
+
+            if (ngx_strncmp(p, "{HEX}", sizeof("{HEX}") - 1) == 0) {
+
+                p += sizeof("{HEX}") - 1;
+                len -= sizeof("{HEX}") - 1;
+
+                if (len / 2 > max_psk_len) {
+                    goto cleanup;
+                }
+
+                if (ngx_hex_decode(psk, p, len) != NGX_OK) {
+                    ngx_memzero(psk, len / 2);
+                    goto cleanup;
+                }
+
+                psk_len = len / 2;
+
+                goto cleanup;
+
+            } else if (ngx_strncmp(p, "{PLAIN}", sizeof("{PLAIN}") - 1) == 0) {
+                p += sizeof("{PLAIN}") - 1;
+                len -= sizeof("{PLAIN}") - 1;
+            }
+
+            if (len > max_psk_len) {
+                goto cleanup;
+            }
+
+            ngx_memcpy(psk, p, len);
+            psk_len = len;
+
+            goto cleanup;
+        }
+
+        len = end - p;
+
+        if (len == NGX_SSL_PSK_BUFFER_SIZE) {
+            ngx_log_error(NGX_LOG_ERR, c->log, 0,
+                          "too long line in \"%V\"", file);
+            goto cleanup;
+        }
+
+        ngx_memmove(buf, p, len);
+        last = buf + len;
+
+    } while (n != 0);
+
+cleanup:
+
+    if (ngx_close_file(fd) == NGX_FILE_ERROR) {
+        ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
+                      ngx_close_file_n " %V failed", file);
+    }
+
+    ngx_memzero(buf, NGX_SSL_PSK_BUFFER_SIZE);
+
+    return psk_len;
+}
+
+#endif
+
+
+ngx_int_t
 ngx_ssl_create_connection(ngx_ssl_t *ssl, ngx_connection_t *c, ngx_uint_t flags)  {
     ngx_ssl_connection_t  *sc;
@@ -2071,6 +2255,9 @@ ngx_ssl_connection_error(ngx_connection_
             || n == SSL_R_NO_COMPRESSION_SPECIFIED                   /*  187 */
             || n == SSL_R_NO_SHARED_CIPHER                           /*  193 */
             || n == SSL_R_RECORD_LENGTH_MISMATCH                     /*  213 */
+#ifdef SSL_R_PSK_IDENTITY_NOT_FOUND
+            || n == SSL_R_PSK_IDENTITY_NOT_FOUND                     /*  223 */
+#endif
 #ifdef SSL_R_PARSE_TLSEXT
             || n == SSL_R_PARSE_TLSEXT                               /*  227 */
 #endif
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -167,6 +167,7 @@ RSA *ngx_ssl_rsa512_key_callback(ngx_ssl
 ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);  ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);  ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
+ngx_int_t ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t
+*file);
 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
     ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout);  ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, @@ -253,6 +254,7 @@ extern int  ngx_ssl_connection_index;  extern int  ngx_ssl_server_conf_index;  extern int  ngx_ssl_session_cache_index;  extern int  ngx_ssl_session_ticket_keys_index;
+extern int  ngx_ssl_psk_index;
 extern int  ngx_ssl_certificate_index;
 extern int  ngx_ssl_next_certificate_index;  extern int  ngx_ssl_certificate_name_index; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -234,6 +234,13 @@ static ngx_command_t  ngx_http_ssl_comma
       offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
       NULL },

+    { ngx_string("ssl_psk_file"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, psk_file),
+      NULL },
+
       ngx_null_command
 };

@@ -543,6 +550,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t
      *     sscf->shm_zone = NULL;
      *     sscf->stapling_file = { 0, NULL };
      *     sscf->stapling_responder = { 0, NULL };
+     *     sscf->psk_file = { 0, NULL };
      */

     sscf->enable = NGX_CONF_UNSET;
@@ -624,6 +632,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
     ngx_conf_merge_str_value(conf->stapling_responder,
                          prev->stapling_responder, "");

+    ngx_conf_merge_str_value(conf->psk_file, prev->psk_file, "");
+
     conf->ssl.log = cf->log;

     if (conf->enable) {
@@ -804,6 +814,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *

     }

+    if (ngx_ssl_psk_file(cf, &conf->ssl, &conf->psk_file) != NGX_OK) {
+        return NGX_CONF_ERROR;
+    }
+
     return NGX_CONF_OK;
 }

diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -55,6 +55,8 @@ typedef struct {
     ngx_str_t                       stapling_file;
     ngx_str_t                       stapling_responder;

+    ngx_str_t                       psk_file;
+
     u_char                         *file;
     ngx_uint_t                      line;
 } ngx_http_ssl_srv_conf_t;
# HG changeset patch
# User Nate Karstens <nate.karstens at garmin.com> # Date 1503540211 18000
#      Wed Aug 23 21:03:31 2017 -0500
# Node ID 396eff1bc17996ae8f4fd9e56f5dd9b72f8ce923
# Parent  0cc14a10c863f3d9ba6cb8b6d3769592d619d654
SSL: add PSK identity variable.

Adds the variable $ssl_psk_identity to get the PSK identity used in a connnection secured with a PSK cipher suite.

Signed-off-by: Nate Karstens <nate.karstens at garmin.com>

diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -4356,6 +4356,37 @@ ngx_ssl_parse_time(  }


+ngx_int_t
+ngx_ssl_get_psk_identity(ngx_connection_t *c, ngx_pool_t *pool,
+ngx_str_t *s) { #ifdef PSK_MAX_IDENTITY_LEN
+
+    size_t       len;
+    const char  *identity;
+
+    identity = SSL_get_psk_identity(c->ssl->connection);
+
+    if (identity) {
+        len = ngx_strlen(identity);
+
+        s->len = len;
+        s->data = ngx_pnalloc(pool, len);
+        if (s->data == NULL) {
+            return NGX_ERROR;
+        }
+
+        ngx_memcpy(s->data, identity, len);
+
+        return NGX_OK;
+    }
+
+#endif
+
+    s->len = 0;
+    return NGX_OK;
+}
+
+
 static void *
 ngx_openssl_create_conf(ngx_cycle_t *cycle)  { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -235,6 +235,8 @@ ngx_int_t ngx_ssl_get_client_v_end(ngx_c
     ngx_str_t *s);
 ngx_int_t ngx_ssl_get_client_v_remain(ngx_connection_t *c, ngx_pool_t *pool,
     ngx_str_t *s);
+ngx_int_t ngx_ssl_get_psk_identity(ngx_connection_t *c, ngx_pool_t *pool,
+    ngx_str_t *s);


 ngx_int_t ngx_ssl_handshake(ngx_connection_t *c); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -340,6 +340,9 @@ static ngx_http_variable_t  ngx_http_ssl
     { ngx_string("ssl_client_v_remain"), NULL, ngx_http_ssl_variable,
       (uintptr_t) ngx_ssl_get_client_v_remain, NGX_HTTP_VAR_CHANGEABLE, 0 },

+    { ngx_string("ssl_psk_identity"), NULL, ngx_http_ssl_variable,
+      (uintptr_t) ngx_ssl_get_psk_identity, NGX_HTTP_VAR_CHANGEABLE, 0
+ },
+
       ngx_http_null_variable
 };

# HG changeset patch
# User Nate Karstens <nate.karstens at garmin.com> # Date 1503540237 18000
#      Wed Aug 23 21:03:57 2017 -0500
# Node ID b9689aaec94bcddbf17c16eb55794782f3badd4e
# Parent  396eff1bc17996ae8f4fd9e56f5dd9b72f8ce923
SSL: add identity hint config directive.

Adds the directive "ssl_psk_identity_hint" to the ngx_http_ssl_module.
This allows the user to specify the PSK identity hint given to the connecting client.

Signed-off-by: Nate Karstens <nate.karstens at garmin.com>

diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim
+++ b/contrib/vim/syntax/nginx.vim
@@ -551,6 +551,7 @@ syn keyword ngxDirective contained ssl_p  syn keyword ngxDirective contained ssl_preread  syn keyword ngxDirective contained ssl_protocols  syn keyword ngxDirective contained ssl_psk_file
+syn keyword ngxDirective contained ssl_psk_identity_hint
 syn keyword ngxDirective contained ssl_session_cache  syn keyword ngxDirective contained ssl_session_ticket_key  syn keyword ngxDirective contained ssl_session_tickets diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -1177,7 +1177,8 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_s


 ngx_int_t
-ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
+ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
+    ngx_str_t *identity_hint)
 {
 #ifdef PSK_MAX_IDENTITY_LEN

@@ -1195,6 +1196,14 @@ ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl
         return NGX_ERROR;
     }

+    if (SSL_CTX_use_psk_identity_hint(ssl->ctx, (char *) identity_hint->data)
+        == 0)
+    {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_CTX_use_psk_identity_hint() failed");
+        return NGX_ERROR;
+    }
+
     SSL_CTX_set_psk_server_callback(ssl->ctx, ngx_ssl_psk_callback);

 #endif
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -167,7 +167,8 @@ RSA *ngx_ssl_rsa512_key_callback(ngx_ssl
 ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);  ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);  ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name); -ngx_int_t ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
+ngx_int_t ngx_ssl_psk_file(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file,
+    ngx_str_t *identity_hint);
 ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
     ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout);  ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -241,6 +241,13 @@ static ngx_command_t  ngx_http_ssl_comma
       offsetof(ngx_http_ssl_srv_conf_t, psk_file),
       NULL },

+    { ngx_string("ssl_psk_identity_hint"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, psk_identity_hint),
+      NULL },
+
       ngx_null_command
 };

@@ -554,6 +561,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t
      *     sscf->stapling_file = { 0, NULL };
      *     sscf->stapling_responder = { 0, NULL };
      *     sscf->psk_file = { 0, NULL };
+     *     sscf->psk_identity_hint = { 0, NULL };
      */

     sscf->enable = NGX_CONF_UNSET;
@@ -636,6 +644,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *
                          prev->stapling_responder, "");

     ngx_conf_merge_str_value(conf->psk_file, prev->psk_file, "");
+    ngx_conf_merge_str_value(conf->psk_identity_hint,
+                         prev->psk_identity_hint, "");

     conf->ssl.log = cf->log;

@@ -817,7 +827,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *

     }

-    if (ngx_ssl_psk_file(cf, &conf->ssl, &conf->psk_file) != NGX_OK) {
+    if (ngx_ssl_psk_file(cf, &conf->ssl, &conf->psk_file,
+                         &conf->psk_identity_hint)
+        != NGX_OK)
+    {
         return NGX_CONF_ERROR;
     }

diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -56,6 +56,7 @@ typedef struct {
     ngx_str_t                       stapling_responder;

     ngx_str_t                       psk_file;
+    ngx_str_t                       psk_identity_hint;

     u_char                         *file;
     ngx_uint_t                      line;

--
Maxim Dounin
http://nginx.org/
_______________________________________________
nginx-devel mailing list
nginx-devel at nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

________________________________

CONFIDENTIALITY NOTICE: This email and any attachments are for the sole use of the intended recipient(s) and contain information that may be Garmin confidential and/or Garmin legally privileged. If you have received this email in error, please notify the sender by reply email and delete the message. Any disclosure, copying, distribution or use of this communication (including attachments) by someone other than the intended recipient is prohibited. Thank you.


More information about the nginx-devel mailing list