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:[email protected]] On Behalf Of Maxim 
Dounin
Sent: Monday, September 04, 2017 11:01 AM
To: [email protected]
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 <[email protected]> # 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 <[email protected]>

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 <[email protected]> # 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 <[email protected]>

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 <[email protected]> # 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 <[email protected]>

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 <[email protected]> # 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 <[email protected]>

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
[email protected]
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.
_______________________________________________
nginx-devel mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to