Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-12-23 Thread Valentin V. Bartenev
On Tuesday 24 December 2013 00:05:31 kyprizel wrote:
> I mean, if something goes wrong while ticket file copying - nginx still
> should function, no b/c it's not essential thing?
> 

And it will function. Just a quote from: http://nginx.org/en/docs/control.html

"The master process first checks the syntax validity, then tries to apply new 
configuration, that is, to open log files and new listen sockets. If this 
fails, it rolls back changes and continues to work with old configuration."

  wbr, Valentin V. Bartenev


> On Mon, Dec 23, 2013 at 9:14 PM, Maxim Dounin  wrote:
> > Hello!
> > 
> > On Mon, Dec 23, 2013 at 07:54:01PM +0400, kyprizel wrote:
> > > Do we really should fail configuration check if we were not able to read
> > > ticket key file?
> > 
> > That's what configuration check is for, no?
> > 
> > --
> > Maxim Dounin
> > http://nginx.org/
> > 
> > ___
> > nginx-devel mailing list
> > nginx-devel@nginx.org
> > http://mailman.nginx.org/mailman/listinfo/nginx-devel

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-12-23 Thread kyprizel
I mean, if something goes wrong while ticket file copying - nginx still
should function, no b/c it's not essential thing?


On Mon, Dec 23, 2013 at 9:14 PM, Maxim Dounin  wrote:

> Hello!
>
> On Mon, Dec 23, 2013 at 07:54:01PM +0400, kyprizel wrote:
>
> > Do we really should fail configuration check if we were not able to read
> > ticket key file?
>
> That's what configuration check is for, no?
>
> --
> Maxim Dounin
> http://nginx.org/
>
> ___
> nginx-devel mailing list
> nginx-devel@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-12-23 Thread Maxim Dounin
Hello!

On Mon, Dec 23, 2013 at 07:54:01PM +0400, kyprizel wrote:

> Do we really should fail configuration check if we were not able to read
> ticket key file?

That's what configuration check is for, no?

-- 
Maxim Dounin
http://nginx.org/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-12-23 Thread kyprizel
Do we really should fail configuration check if we were not able to read
ticket key file?


On Mon, Oct 14, 2013 at 5:29 PM, Maxim Dounin  wrote:

> Hello!
>
> On Fri, Oct 11, 2013 at 04:22:07PM -0700, Piotr Sikora wrote:
>
> > Hey Maxim,
> >
> > > Wouldn't it better to move ngx_ssl_session_ticket_md defines
> > > to ngx_ssl_session_ticket_key_callback() implementation?
> >
> > You mean inside the function or just above it? I moved them just above
> it.
>
> I'm fine with either variant.
>
> > > Do we really need these #ifdef's?  I don't think saving several
> > > bytes in ancient OpenSSL versions worth it (and the
> > > ngx_ssl_stapling_index doesn't have #ifdef's).
> >
> > Probably not, removed.
> >
> > While there, I moved the definitions and initialization right after
> > ngx_ssl_session_cache_index, so that the two session resumption
> > indexes are together, hopefully that's alright.
>
> Looks good.
>
> > > Wouldn't ngx_ssl_ticket_key_t be better?  Up to you, but
> > > "ngx_ssl_session_ticket_key_t" looks a bit too long.
> >
> > It's a bit too long, yes, but I prefer to keep everything with the
> > same prefix, so either rename everything to "ngx_ssl_ticket_" (which I
> > don't like that much) or keep long names.
>
> I think it would be fine to name functions ngx_ssl_session_ticket_keys()
> and ngx_ssl_session_ticket_key_callback(), but use shorter names for
> the rest of the identifiers.  Especially keeping in mind OpenSSL
> calls relevant call SSL_CTX_set_tlsext_ticket_key_cb() anyway.
> But I don't insist, up to you.
>
> > > What about something like this:
> > >
> > > ngx_log_debug3(NGX_LOG_DEBUG_HTTP, 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");
> > >
> > > ?
> > >
> > > (Well, actually I'm not sure we need key name logged, but it
> > > probably doesn't matter much.)
> >
> > That's much better, thanks.
> >
> > It's used only for the debugging, so I think it's fine to print it.
>
> Sometimes too much debugging is bad, too.  But let's keep it as is
> for now.
>
> > > Just in case, using a shorter name "ngx_ssl_ticket_md()" would
> > > save us from wrapping here and in decrypt case.
> >
> > I know, I had something shorter here originally, but I've decided to
> > rename it, so that it would have the same prefix... But if you really
> > want to get rid of the wrap, maybe we could use "ngx_ssl_md()" here?
> > What do you think?
>
> The "ngx_ssl_md()" looks wrong for me, as it's a message digest
> used for session tickets, not something global for our ssl
> implementation.
>
> > > Shouldn't it be ngx_memcmp(), as it checks binary data now?
> >
> > Good catch, thanks! That was leftover from my previous implementation.
> >
> > > Adding "goto found" instead of "break" would allow to avoid this
> > > additional check.  Up to you though.
> >
> > Personally, I prefer the explicit "end-of-the-loop" check, but I don't
> > mind either way. Changed to "goto found".
>
> Minor nit: labels should be indented to match blocks, not
> unindented.  E.g.,
>
> if (foo) {
> if (bar) {
> goto found;
> }
>
> found:
>
> ...
> }
>
> > Updated patch attached, with slightly changed commit message (better
> > file names in the example).
> >
> > Please note, that it doesn't have any session timeout logic, so it
> > should be committed after the timeout patch :)
>
> Sure.
>
> > # HG changeset patch
> > # User Piotr Sikora 
> > # Date 1381532724 25200
> > #  Fri Oct 11 16:05:24 2013 -0700
> > # Node ID 296805806a43f4b222c4cf34dd6489b37394e315
> > # Parent  5483d9e77b3287b00b1104a07688bda37bc7351e
> > SSL: added ability to set keys used for Session Tickets (RFC5077).
> >
> > In order to support key rollover, ssl_session_ticket_key can be defined
> > multiple times. The first key will be used to issue and resume Session
> > Tickets, while the rest will be used only to resume them.
> >
> > ssl_session_ticket_key  session_tickets/current.key;
> > ssl_session_ticket_key  session_tickets/prev-1h.key;
> > ssl_session_ticket_key  session_tickets/prev-2h.key;
> >
> > Please note that nginx supports Session Tickets even without explicit
> > configuration of the keys and this feature should be only used in setups
> > where SSL traffic is distributed across multiple nginx servers.
> >
> > Signed-off-by: Piotr Sikora 
>
> [...]
>
> Committed with the followin minor tweaks:
>
> --- a/src/event/ngx_event_openssl.c
> +++ b/src/event/ngx_event_openssl.c
> @@ -2415,8 +2415,8 @@ ngx_ssl_session_ticket_key_callback(ngx_
>
>  RAND_pseudo_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);
> +HMAC_Init_ex(

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-14 Thread Maxim Dounin
Hello!

On Fri, Oct 11, 2013 at 04:22:07PM -0700, Piotr Sikora wrote:

> Hey Maxim,
> 
> > Wouldn't it better to move ngx_ssl_session_ticket_md defines
> > to ngx_ssl_session_ticket_key_callback() implementation?
> 
> You mean inside the function or just above it? I moved them just above it.

I'm fine with either variant.

> > Do we really need these #ifdef's?  I don't think saving several
> > bytes in ancient OpenSSL versions worth it (and the
> > ngx_ssl_stapling_index doesn't have #ifdef's).
> 
> Probably not, removed.
> 
> While there, I moved the definitions and initialization right after
> ngx_ssl_session_cache_index, so that the two session resumption
> indexes are together, hopefully that's alright.

Looks good.

> > Wouldn't ngx_ssl_ticket_key_t be better?  Up to you, but
> > "ngx_ssl_session_ticket_key_t" looks a bit too long.
> 
> It's a bit too long, yes, but I prefer to keep everything with the
> same prefix, so either rename everything to "ngx_ssl_ticket_" (which I
> don't like that much) or keep long names.

I think it would be fine to name functions ngx_ssl_session_ticket_keys() 
and ngx_ssl_session_ticket_key_callback(), but use shorter names for 
the rest of the identifiers.  Especially keeping in mind OpenSSL 
calls relevant call SSL_CTX_set_tlsext_ticket_key_cb() anyway.  
But I don't insist, up to you.

> > What about something like this:
> >
> > ngx_log_debug3(NGX_LOG_DEBUG_HTTP, 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");
> >
> > ?
> >
> > (Well, actually I'm not sure we need key name logged, but it
> > probably doesn't matter much.)
> 
> That's much better, thanks.
> 
> It's used only for the debugging, so I think it's fine to print it.

Sometimes too much debugging is bad, too.  But let's keep it as is 
for now.

> > Just in case, using a shorter name "ngx_ssl_ticket_md()" would
> > save us from wrapping here and in decrypt case.
> 
> I know, I had something shorter here originally, but I've decided to
> rename it, so that it would have the same prefix... But if you really
> want to get rid of the wrap, maybe we could use "ngx_ssl_md()" here?
> What do you think?

The "ngx_ssl_md()" looks wrong for me, as it's a message digest 
used for session tickets, not something global for our ssl 
implementation.

> > Shouldn't it be ngx_memcmp(), as it checks binary data now?
> 
> Good catch, thanks! That was leftover from my previous implementation.
> 
> > Adding "goto found" instead of "break" would allow to avoid this
> > additional check.  Up to you though.
> 
> Personally, I prefer the explicit "end-of-the-loop" check, but I don't
> mind either way. Changed to "goto found".

Minor nit: labels should be indented to match blocks, not 
unindented.  E.g.,

if (foo) {
if (bar) {
goto found;
}

found:

...
}

> Updated patch attached, with slightly changed commit message (better
> file names in the example).
> 
> Please note, that it doesn't have any session timeout logic, so it
> should be committed after the timeout patch :)

Sure.

> # HG changeset patch
> # User Piotr Sikora 
> # Date 1381532724 25200
> #  Fri Oct 11 16:05:24 2013 -0700
> # Node ID 296805806a43f4b222c4cf34dd6489b37394e315
> # Parent  5483d9e77b3287b00b1104a07688bda37bc7351e
> SSL: added ability to set keys used for Session Tickets (RFC5077).
> 
> In order to support key rollover, ssl_session_ticket_key can be defined
> multiple times. The first key will be used to issue and resume Session
> Tickets, while the rest will be used only to resume them.
> 
> ssl_session_ticket_key  session_tickets/current.key;
> ssl_session_ticket_key  session_tickets/prev-1h.key;
> ssl_session_ticket_key  session_tickets/prev-2h.key;
> 
> Please note that nginx supports Session Tickets even without explicit
> configuration of the keys and this feature should be only used in setups
> where SSL traffic is distributed across multiple nginx servers.
> 
> Signed-off-by: Piotr Sikora 

[...]

Committed with the followin minor tweaks:

--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -2415,8 +2415,8 @@ ngx_ssl_session_ticket_key_callback(ngx_
 
 RAND_pseudo_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);
+HMAC_Init_ex(hctx, key[0].hmac_key, 16,
+ ngx_ssl_session_ticket_md(), NULL);
 memcpy(name, key[0].name, 16);
 
 return 0;
@@ -2436,15 +2436,15 @@ ngx_ssl_session_ticket_key_callback(ngx_
 
 return 0;
 
-found:
+found:
 
 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
"ssl session ticket decrypt, key: \"%*

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-11 Thread Piotr Sikora
Hey Maxim,

> Wouldn't it better to move ngx_ssl_session_ticket_md defines
> to ngx_ssl_session_ticket_key_callback() implementation?

You mean inside the function or just above it? I moved them just above it.

> Do we really need these #ifdef's?  I don't think saving several
> bytes in ancient OpenSSL versions worth it (and the
> ngx_ssl_stapling_index doesn't have #ifdef's).

Probably not, removed.

While there, I moved the definitions and initialization right after
ngx_ssl_session_cache_index, so that the two session resumption
indexes are together, hopefully that's alright.

> Wouldn't ngx_ssl_ticket_key_t be better?  Up to you, but
> "ngx_ssl_session_ticket_key_t" looks a bit too long.

It's a bit too long, yes, but I prefer to keep everything with the
same prefix, so either rename everything to "ngx_ssl_ticket_" (which I
don't like that much) or keep long names.

> What about something like this:
>
> ngx_log_debug3(NGX_LOG_DEBUG_HTTP, 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");
>
> ?
>
> (Well, actually I'm not sure we need key name logged, but it
> probably doesn't matter much.)

That's much better, thanks.

It's used only for the debugging, so I think it's fine to print it.

> Just in case, using a shorter name "ngx_ssl_ticket_md()" would
> save us from wrapping here and in decrypt case.

I know, I had something shorter here originally, but I've decided to
rename it, so that it would have the same prefix... But if you really
want to get rid of the wrap, maybe we could use "ngx_ssl_md()" here?
What do you think?

> Shouldn't it be ngx_memcmp(), as it checks binary data now?

Good catch, thanks! That was leftover from my previous implementation.

> Adding "goto found" instead of "break" would allow to avoid this
> additional check.  Up to you though.

Personally, I prefer the explicit "end-of-the-loop" check, but I don't
mind either way. Changed to "goto found".

Updated patch attached, with slightly changed commit message (better
file names in the example).

Please note, that it doesn't have any session timeout logic, so it
should be committed after the timeout patch :)

Best regards,
Piotr Sikora


# HG changeset patch
# User Piotr Sikora 
# Date 1381532724 25200
#  Fri Oct 11 16:05:24 2013 -0700
# Node ID 296805806a43f4b222c4cf34dd6489b37394e315
# Parent  5483d9e77b3287b00b1104a07688bda37bc7351e
SSL: added ability to set keys used for Session Tickets (RFC5077).

In order to support key rollover, ssl_session_ticket_key can be defined
multiple times. The first key will be used to issue and resume Session
Tickets, while the rest will be used only to resume them.

ssl_session_ticket_key  session_tickets/current.key;
ssl_session_ticket_key  session_tickets/prev-1h.key;
ssl_session_ticket_key  session_tickets/prev-2h.key;

Please note that nginx supports Session Tickets even without explicit
configuration of the keys and this feature should be only used in setups
where SSL traffic is distributed across multiple nginx servers.

Signed-off-by: Piotr Sikora 

diff -r 5483d9e77b32 -r 296805806a43 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Wed Oct 02 15:07:17 2013 +0400
+++ b/src/event/ngx_event_openssl.c Fri Oct 11 16:05:24 2013 -0700
@@ -38,6 +38,12 @@ static void ngx_ssl_expire_sessions(ngx_
 static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+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
+
 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);
 static void ngx_openssl_exit(ngx_cycle_t *cycle);
@@ -82,6 +88,7 @@ ngx_module_t  ngx_openssl_module = {
 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_certificate_index;
 int  ngx_ssl_stapling_index;

@@ -139,6 +146,14 @@ ngx_ssl_init(ngx_log_t *log)
 return NGX_ERROR;
 }

+ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
+ NULL, NULL);
+if (ngx_ssl_session_ticket_keys_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) {
@@ -2240,6 +2255,218 @@ ngx_ssl_session_rbtree_insert_value(ng

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-11 Thread Maxim Dounin
Hello!

On Thu, Oct 10, 2013 at 04:33:34PM -0700, Piotr Sikora wrote:

> Oops, one line was 81 chars long... Fixed patch below.
> 
> # HG changeset patch
> # User Piotr Sikora 
> # Date 1381447913 25200
> #  Thu Oct 10 16:31:53 2013 -0700
> # Node ID 4617733b2d7130313241253ef22958790d6fc902
> # Parent  5483d9e77b3287b00b1104a07688bda37bc7351e
> SSL: added ability to set keys used for Session Tickets (RFC5077).
> 
> In order to support key rollover, ssl_session_ticket_key can be defined
> multiple times. The first key will be used to issue and resume Session
> Tickets, while the rest will be used only to resume them.
> 
> ssl_session_ticket_key   session_ticket_current.key;
> ssl_session_ticket_key   session_ticket_curr-1h.key;
> ssl_session_ticket_key   session_ticket_curr-2h.key;
> 
> Please note that nginx supports Session Tickets even without explicit
> configuration of the keys and this feature should be only used in setups
> where SSL traffic is distributed across multiple nginx servers.

Looks almost good, see some minor nits below.

[...]

> --- a/src/event/ngx_event_openssl.c Wed Oct 02 15:07:17 2013 +0400
> +++ b/src/event/ngx_event_openssl.c Thu Oct 10 16:31:53 2013 -0700
> @@ -38,6 +38,18 @@ static void ngx_ssl_expire_sessions(ngx_
>  static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
>  ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
> 
> +#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
> +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);
> +
> +#ifdef OPENSSL_NO_SHA256
> +#define ngx_ssl_session_ticket_md  EVP_sha1
> +#else
> +#define ngx_ssl_session_ticket_md  EVP_sha256
> +#endif
> +#endif
> +

Wouldn't it better to move ngx_ssl_session_ticket_md defines 
to ngx_ssl_session_ticket_key_callback() implementation?

[...]

> @@ -84,6 +96,9 @@ int  ngx_ssl_server_conf_index;
>  int  ngx_ssl_session_cache_index;
>  int  ngx_ssl_certificate_index;
>  int  ngx_ssl_stapling_index;
> +#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
> +int  ngx_ssl_session_ticket_keys_index;
> +#endif
> 
> 
>  ngx_int_t
> @@ -155,6 +170,18 @@ ngx_ssl_init(ngx_log_t *log)
>  return NGX_ERROR;
>  }
> 
> +#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
> +
> +ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, 
> NULL,
> + NULL, NULL);
> +if (ngx_ssl_session_ticket_keys_index == -1) {
> +ngx_ssl_error(NGX_LOG_ALERT, log, 0,
> +  "SSL_CTX_get_ex_new_index() failed");
> +return NGX_ERROR;
> +}
> +
> +#endif
> +

Do we really need these #ifdef's?  I don't think saving several 
bytes in ancient OpenSSL versions worth it (and the 
ngx_ssl_stapling_index doesn't have #ifdef's).

[...]

> +ngx_int_t
> +ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t 
> *paths)
> +{
> +u_char buf[48];
> +ssize_tn;
> +ngx_str_t *path;
> +ngx_file_t file;
> +ngx_uint_t i;
> +ngx_array_t   *keys;
> +ngx_file_info_tfi;
> +ngx_ssl_session_ticket_key_t  *key;

Wouldn't ngx_ssl_ticket_key_t be better?  Up to you, but 
"ngx_ssl_session_ticket_key_t" looks a bit too long.

[...]

> +if (enc == 1) {
> +/* encrypt session ticket */
> +
> +#if (NGX_DEBUG)
> +ngx_hex_dump(buf, key[0].name, 16);
> +
> +ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
> +   "ssl session ticket encrypt, key: \"%*s\" (%s 
> session)",
> +   32, buf,
> +   SSL_session_reused(ssl_conn) ? "reused" : "new");
> +#endif

What about something like this:

ngx_log_debug3(NGX_LOG_DEBUG_HTTP, 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");

?

(Well, actually I'm not sure we need key name logged, but it 
probably doesn't matter much.)

> +
> +RAND_pseudo_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);

Just in case, using a shorter name "ngx_ssl_ticket_md()" would 
save us from wrapping here and in decrypt case.

> +memcpy(name, key[0].name, 16);
> +
> +return 0;
> +
> +} else {
> +/* decrypt session ticket */
> +
> +for (i = 0; i < keys->nelts; i++) {
> +if (ngx_strncmp(name, key[i].name, 16) == 0) {

Shouldn't it be ngx_memcmp(), as it checks binary data now?

> +break;
> +}
> +}
> +

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-10 Thread Piotr Sikora
Oops, one line was 81 chars long... Fixed patch below.

# HG changeset patch
# User Piotr Sikora 
# Date 1381447913 25200
#  Thu Oct 10 16:31:53 2013 -0700
# Node ID 4617733b2d7130313241253ef22958790d6fc902
# Parent  5483d9e77b3287b00b1104a07688bda37bc7351e
SSL: added ability to set keys used for Session Tickets (RFC5077).

In order to support key rollover, ssl_session_ticket_key can be defined
multiple times. The first key will be used to issue and resume Session
Tickets, while the rest will be used only to resume them.

ssl_session_ticket_key   session_ticket_current.key;
ssl_session_ticket_key   session_ticket_curr-1h.key;
ssl_session_ticket_key   session_ticket_curr-2h.key;

Please note that nginx supports Session Tickets even without explicit
configuration of the keys and this feature should be only used in setups
where SSL traffic is distributed across multiple nginx servers.

Signed-off-by: Piotr Sikora 

diff -r 5483d9e77b32 -r 4617733b2d71 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Wed Oct 02 15:07:17 2013 +0400
+++ b/src/event/ngx_event_openssl.c Thu Oct 10 16:31:53 2013 -0700
@@ -38,6 +38,18 @@ static void ngx_ssl_expire_sessions(ngx_
 static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+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);
+
+#ifdef OPENSSL_NO_SHA256
+#define ngx_ssl_session_ticket_md  EVP_sha1
+#else
+#define ngx_ssl_session_ticket_md  EVP_sha256
+#endif
+#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);
 static void ngx_openssl_exit(ngx_cycle_t *cycle);
@@ -84,6 +96,9 @@ int  ngx_ssl_server_conf_index;
 int  ngx_ssl_session_cache_index;
 int  ngx_ssl_certificate_index;
 int  ngx_ssl_stapling_index;
+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+int  ngx_ssl_session_ticket_keys_index;
+#endif


 ngx_int_t
@@ -155,6 +170,18 @@ ngx_ssl_init(ngx_log_t *log)
 return NGX_ERROR;
 }

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+
+ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
+ NULL, NULL);
+if (ngx_ssl_session_ticket_keys_index == -1) {
+ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+  "SSL_CTX_get_ex_new_index() failed");
+return NGX_ERROR;
+}
+
+#endif
+
 return NGX_OK;
 }

@@ -2240,6 +2267,219 @@ ngx_ssl_session_rbtree_insert_value(ngx_
 }


+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+
+ngx_int_t
+ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
+{
+u_char buf[48];
+ssize_tn;
+ngx_str_t *path;
+ngx_file_t file;
+ngx_uint_t i;
+ngx_array_t   *keys;
+ngx_file_info_tfi;
+ngx_ssl_session_ticket_key_t  *key;
+
+if (paths == NULL) {
+return NGX_OK;
+}
+
+keys = ngx_array_create(cf->pool, paths->nelts,
+sizeof(ngx_ssl_session_ticket_key_t));
+if (keys == NULL) {
+return NGX_ERROR;
+}
+
+path = paths->elts;
+for (i = 0; i < paths->nelts; i++) {
+
+if (ngx_conf_full_name(cf->cycle, &path[i], 1) != NGX_OK) {
+return NGX_ERROR;
+}
+
+ngx_memzero(&file, sizeof(ngx_file_t));
+file.name = path[i];
+file.log = cf->log;
+
+file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, 0, 0);
+if (file.fd == NGX_INVALID_FILE) {
+ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
+   ngx_open_file_n " \"%V\" failed", &file.name);
+return NGX_ERROR;
+}
+
+if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
+ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+   ngx_fd_info_n " \"%V\" failed", &file.name);
+goto failed;
+}
+
+if (ngx_file_size(&fi) != 48) {
+ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+   "\"%V\" must be 48 bytes", &file.name);
+goto failed;
+}
+
+n = ngx_read_file(&file, buf, 48, 0);
+
+if (n == NGX_ERROR) {
+ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+   ngx_read_file_n " \"%V\" failed", &file.name);
+goto failed;
+}
+
+if (n != 48) {
+ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
+   ngx_read_file_n " \"%V\" returned only "
+   "%z bytes instead of 48", &file.name, n);
+goto failed;
+}
+

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-10 Thread Piotr Sikora
# HG changeset patch
# User Piotr Sikora 
# Date 1381446441 25200
#  Thu Oct 10 16:07:21 2013 -0700
# Node ID 7132c555e445419008520563da63d3b122772b97
# Parent  5483d9e77b3287b00b1104a07688bda37bc7351e
SSL: added ability to set keys used for Session Tickets (RFC5077).

In order to support key rollover, ssl_session_ticket_key can be defined
multiple times. The first key will be used to issue and resume Session
Tickets, while the rest will be used only to resume them.

ssl_session_ticket_key   session_ticket_current.key;
ssl_session_ticket_key   session_ticket_curr-1h.key;
ssl_session_ticket_key   session_ticket_curr-2h.key;

Please note that nginx supports Session Tickets even without explicit
configuration of the keys and this feature should be only used in setups
where SSL traffic is distributed across multiple nginx servers.

Signed-off-by: Piotr Sikora 

diff -r 5483d9e77b32 -r 7132c555e445 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Wed Oct 02 15:07:17 2013 +0400
+++ b/src/event/ngx_event_openssl.c Thu Oct 10 16:07:21 2013 -0700
@@ -38,6 +38,18 @@ static void ngx_ssl_expire_sessions(ngx_
 static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+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);
+
+#ifdef OPENSSL_NO_SHA256
+#define ngx_ssl_session_ticket_md  EVP_sha1
+#else
+#define ngx_ssl_session_ticket_md  EVP_sha256
+#endif
+#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);
 static void ngx_openssl_exit(ngx_cycle_t *cycle);
@@ -84,6 +96,9 @@ int  ngx_ssl_server_conf_index;
 int  ngx_ssl_session_cache_index;
 int  ngx_ssl_certificate_index;
 int  ngx_ssl_stapling_index;
+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+int  ngx_ssl_session_ticket_keys_index;
+#endif


 ngx_int_t
@@ -155,6 +170,18 @@ ngx_ssl_init(ngx_log_t *log)
 return NGX_ERROR;
 }

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+
+ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
+ NULL, NULL);
+if (ngx_ssl_session_ticket_keys_index == -1) {
+ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+  "SSL_CTX_get_ex_new_index() failed");
+return NGX_ERROR;
+}
+
+#endif
+
 return NGX_OK;
 }

@@ -2240,6 +2267,219 @@ ngx_ssl_session_rbtree_insert_value(ngx_
 }


+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+
+ngx_int_t
+ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths)
+{
+u_char buf[48];
+ssize_tn;
+ngx_str_t *path;
+ngx_file_t file;
+ngx_uint_t i;
+ngx_array_t   *keys;
+ngx_file_info_tfi;
+ngx_ssl_session_ticket_key_t  *key;
+
+if (paths == NULL) {
+return NGX_OK;
+}
+
+keys = ngx_array_create(cf->pool, paths->nelts,
+sizeof(ngx_ssl_session_ticket_key_t));
+if (keys == NULL) {
+return NGX_ERROR;
+}
+
+path = paths->elts;
+for (i = 0; i < paths->nelts; i++) {
+
+if (ngx_conf_full_name(cf->cycle, &path[i], 1) != NGX_OK) {
+return NGX_ERROR;
+}
+
+ngx_memzero(&file, sizeof(ngx_file_t));
+file.name = path[i];
+file.log = cf->log;
+
+file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, 0, 0);
+if (file.fd == NGX_INVALID_FILE) {
+ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
+   ngx_open_file_n " \"%V\" failed", &file.name);
+return NGX_ERROR;
+}
+
+if (ngx_fd_info(file.fd, &fi) == NGX_FILE_ERROR) {
+ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+   ngx_fd_info_n " \"%V\" failed", &file.name);
+goto failed;
+}
+
+if (ngx_file_size(&fi) != 48) {
+ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+   "\"%V\" must be 48 bytes", &file.name);
+goto failed;
+}
+
+n = ngx_read_file(&file, buf, 48, 0);
+
+if (n == NGX_ERROR) {
+ngx_conf_log_error(NGX_LOG_CRIT, cf, ngx_errno,
+   ngx_read_file_n " \"%V\" failed", &file.name);
+goto failed;
+}
+
+if (n != 48) {
+ngx_conf_log_error(NGX_LOG_CRIT, cf, 0,
+   ngx_read_file_n " \"%V\" returned only
%z bytes "
+   "instead of 48", &file.name, n);
+goto failed;
+}
+
+key = ngx_array_push(keys);
+if (key =

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-03 Thread Maxim Dounin
Hello!

On Wed, Oct 02, 2013 at 01:47:10AM -0700, Piotr Sikora wrote:

[...]

> > But actually I doubt we at all need an explicit mark for default
> > key.  Just using first one for encryption would probably be good
> > enough.
> 
> I tend to think that being overly explicit isn't always a bad thing.
> In this particular case, users would need to know that the first key
> on the list is "active/default" while the rest of them is just old
> keys, which is an implementation detail and might not be obvious to
> everybody.

While being explicit is a good thing, this will require (lots of) 
custom code in a configuration parsing and subsequent handling.  
On the other hand, ngx_conf_set_str_array_slot() should be enough 
otherwise.

I don't think the explicitness here deserves custom code it 
requires.  YMMV. 

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-02 Thread kyprizel
If we have multiple keyfiles - I like the idea of marking some key as
default.


On Wed, Oct 2, 2013 at 12:47 PM, Piotr Sikora  wrote:

> Hello Maxim,
>
> > As previously noted, the patch description is wrong.  It also
> > make sense to add some description of the directive added.
>
> Yeah, will do.
>
> > This makes the directive unavailable without any meaningfull
> > diagnostics if nginx was build with old OpenSSL, which isn't very
> > user-friendly.
>
> I'll fix that, it makes sense to be a bit more user-friendly :)
>
> > But actually I doubt we at all need an explicit mark for default
> > key.  Just using first one for encryption would probably be good
> > enough.
>
> I tend to think that being overly explicit isn't always a bad thing.
> In this particular case, users would need to know that the first key
> on the list is "active/default" while the rest of them is just old
> keys, which is an implementation detail and might not be obvious to
> everybody.
>
> > I also think it would be better to don't rely on an explicitly
> > written name, which will make automatic key rotation a pain - as
> > one will have to update both name in a configuration file and a
> > file with keys.   E.g. Apache uses a binary file with 48 bytes of
> > random data, which is much easier to generate and rotate if
> > needed.
>
> The reason why I went with the key name in nginx.conf is because it
> allows users to use a naming scheme for the keys (ex. MMDDHH, if
> you rotate keys hourly, etc.) instead of random and meaningless names.
>
> Having said that, I don't mind pushing key name back to the file.
>
> > Not sure if this code should be here.  Other file operations are
> > handled in the ngx_event_openssl.c, and doing the same for session
> > tickets might be a good idea as well.  Especially if you'll
> > consider adding relevant directives to the mail module.
>
> Sure, sounds reasonable.
>
> I'll send updated patch in a few days.
>
> Best regards,
> Piotr Sikora
>
> ___
> nginx-devel mailing list
> nginx-devel@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-10-02 Thread Piotr Sikora
Hello Maxim,

> As previously noted, the patch description is wrong.  It also
> make sense to add some description of the directive added.

Yeah, will do.

> This makes the directive unavailable without any meaningfull
> diagnostics if nginx was build with old OpenSSL, which isn't very
> user-friendly.

I'll fix that, it makes sense to be a bit more user-friendly :)

> But actually I doubt we at all need an explicit mark for default
> key.  Just using first one for encryption would probably be good
> enough.

I tend to think that being overly explicit isn't always a bad thing.
In this particular case, users would need to know that the first key
on the list is "active/default" while the rest of them is just old
keys, which is an implementation detail and might not be obvious to
everybody.

> I also think it would be better to don't rely on an explicitly
> written name, which will make automatic key rotation a pain - as
> one will have to update both name in a configuration file and a
> file with keys.   E.g. Apache uses a binary file with 48 bytes of
> random data, which is much easier to generate and rotate if
> needed.

The reason why I went with the key name in nginx.conf is because it
allows users to use a naming scheme for the keys (ex. MMDDHH, if
you rotate keys hourly, etc.) instead of random and meaningless names.

Having said that, I don't mind pushing key name back to the file.

> Not sure if this code should be here.  Other file operations are
> handled in the ngx_event_openssl.c, and doing the same for session
> tickets might be a good idea as well.  Especially if you'll
> consider adding relevant directives to the mail module.

Sure, sounds reasonable.

I'll send updated patch in a few days.

Best regards,
Piotr Sikora

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-09-30 Thread Maxim Dounin
Hello!

On Sat, Sep 28, 2013 at 02:55:36AM -0700, Piotr Sikora wrote:

> # HG changeset patch
> # User Piotr Sikora 
> # Date 1380361691 25200
> #  Sat Sep 28 02:48:11 2013 -0700
> # Node ID 6d3710969a18e2d0d817e297c2e17f941a58cd40
> # Parent  a720f0b0e08345ebb01353250f4031bb6e141385
> SSL: added support for TLS Session Tickets (RFC5077).

As previously noted, the patch description is wrong.  It also 
make sense to add some description of the directive added.

See below for some code comments.

[...]

> +#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
> +
> +typedef struct {
> +size_t name_len;
> +u_char name[16];
> +
> +u_char aes_key[16];
> +u_char hmac_key[16];
> +} ngx_ssl_session_ticket_key_t;
> +
> +
> +typedef struct {
> +ngx_ssl_session_ticket_key_t  *default_key;
> +ngx_array_tkeys;
> +} ngx_ssl_session_ticket_keys_t;
> +
> +#endif

This looks needlessly complicated, see below.

[...]

> @@ -153,6 +158,17 @@ static ngx_command_t  ngx_http_ssl_comma
>0,
>NULL },
> 
> +#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
> +
> +{ ngx_string("ssl_session_ticket_key"),
> +  NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE23,
> +  ngx_http_ssl_session_ticket_key,
> +  NGX_HTTP_SRV_CONF_OFFSET,
> +  0,
> +  NULL },
> +
> +#endif
> +

This makes the directive unavailable without any meaningfull 
diagnostics if nginx was build with old OpenSSL, which isn't very 
user-friendly.

[...]

> @@ -769,6 +810,146 @@ invalid:
>  return NGX_CONF_ERROR;
>  }
> 
> +#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB

Style, there should be 2 blank lines before #ifdef.

[...]

> +if (value[1].len > 16) {
> +ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
> +   "\"ssl_session_ticket_key\" name \"%V\" too long, 
> "
> +   "it cannot exceed 16 characters", &value[1]);
> +return NGX_CONF_ERROR;
> +}
> +
> +if (cf->args->nelts == 4) {
> +
> +if (ngx_strcmp(value[3].data, "default")) {

Style: as ngx_strcmp() doesn't return a boolean value, I would 
recommend using "!= 0" test instead.

But actually I doubt we at all need an explicit mark for default 
key.  Just using first one for encryption would probably be good 
enough.

I also think it would be better to don't rely on an explicitly 
written name, which will make automatic key rotation a pain - as 
one will have to update both name in a configuration file and a 
file with keys.   E.g. Apache uses a binary file with 48 bytes of 
random data, which is much easier to generate and rotate if 
needed.

[...]

> +if (ngx_conf_full_name(cf->cycle, &value[2], 1) != NGX_OK) {
> +return NGX_CONF_ERROR;
> +}
> +
> +ngx_memzero(&file, sizeof(ngx_file_t));
> +file.name = value[2];
> +file.log = cf->log;
> +
> +file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, 0, 0);
> +if (file.fd == NGX_INVALID_FILE) {
> +ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
> +   ngx_open_file_n " \"%V\" failed", &file.name);
> +
> +return NGX_CONF_ERROR;
> +}

Not sure if this code should be here.  Other file operations are 
handled in the ngx_event_openssl.c, and doing the same for session 
tickets might be a good idea as well.  Especially if you'll 
consider adding relevant directives to the mail module.

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-09-28 Thread Piotr Sikora
Hi Maxim,

> I haven't looked into the code yet, but commit log is certainly
> misleading.  There is support for TLS session tickets already.

You're right. That's what I get for changing commit message at the last minute.

- SSL: added support for TLS Session Tickets (RFC5077).
+ SSL: added ability to set keys used for TLS Session Tickets (RFC5077).

Best regards,
Piotr Sikora

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-09-28 Thread Maxim Dounin
Hello!

On Sat, Sep 28, 2013 at 02:55:36AM -0700, Piotr Sikora wrote:

> # HG changeset patch
> # User Piotr Sikora 
> # Date 1380361691 25200
> #  Sat Sep 28 02:48:11 2013 -0700
> # Node ID 6d3710969a18e2d0d817e297c2e17f941a58cd40
> # Parent  a720f0b0e08345ebb01353250f4031bb6e141385
> SSL: added support for TLS Session Tickets (RFC5077).

I haven't looked into the code yet, but commit log is certainly 
misleading.  There is support for TLS session tickets already.

-- 
Maxim Dounin
http://nginx.org/en/donation.html

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


[PATCH] SSL: added support for TLS Session Tickets (RFC5077).

2013-09-28 Thread Piotr Sikora
# HG changeset patch
# User Piotr Sikora 
# Date 1380361691 25200
#  Sat Sep 28 02:48:11 2013 -0700
# Node ID 6d3710969a18e2d0d817e297c2e17f941a58cd40
# Parent  a720f0b0e08345ebb01353250f4031bb6e141385
SSL: added support for TLS Session Tickets (RFC5077).

Signed-off-by: Piotr Sikora 

diff -r a720f0b0e083 -r 6d3710969a18 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Fri Sep 27 19:39:33 2013 +0400
+++ b/src/event/ngx_event_openssl.c Sat Sep 28 02:48:11 2013 -0700
@@ -38,6 +38,12 @@ static void ngx_ssl_expire_sessions(ngx_
 static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp,
 ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+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
+
 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);
 static void ngx_openssl_exit(ngx_cycle_t *cycle);
@@ -84,6 +90,9 @@ int  ngx_ssl_server_conf_index;
 int  ngx_ssl_session_cache_index;
 int  ngx_ssl_certificate_index;
 int  ngx_ssl_stapling_index;
+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+int  ngx_ssl_session_ticket_keys_index;
+#endif


 ngx_int_t
@@ -155,6 +164,18 @@ ngx_ssl_init(ngx_log_t *log)
 return NGX_ERROR;
 }

+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+
+ngx_ssl_session_ticket_keys_index = SSL_CTX_get_ex_new_index(0, NULL, NULL,
+ NULL, NULL);
+if (ngx_ssl_session_ticket_keys_index == -1) {
+ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+  "SSL_CTX_get_ex_new_index() failed");
+return NGX_ERROR;
+}
+
+#endif
+
 return NGX_OK;
 }

@@ -2240,6 +2261,122 @@ ngx_ssl_session_rbtree_insert_value(ngx_
 }


+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+
+ngx_int_t
+ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl,
+ngx_ssl_session_ticket_keys_t *keys, time_t timeout)
+{
+if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_session_ticket_keys_index, keys)
+== 0)
+{
+ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+  "SSL_CTX_set_ex_data() failed");
+return NGX_ERROR;
+}
+
+SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
+
+if (SSL_CTX_set_tlsext_ticket_key_cb(ssl->ctx,
+ ngx_ssl_session_ticket_key_callback)
+== 0)
+{
+ngx_log_error(NGX_LOG_WARN, cf->log, 0,
+  "nginx was built with Session Tickets support, however, "
+  "now it is linked dynamically to an OpenSSL library "
+  "which has no tlsext support, therefore Session Tickets "
+  "are not available");
+}
+
+return NGX_OK;
+}
+
+
+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)
+{
+int rc;
+SSL_CTX*ssl_ctx;
+ngx_uint_t  i;
+ngx_ssl_session_ticket_key_t   *key;
+ngx_ssl_session_ticket_keys_t  *keys;
+#if (NGX_DEBUG)
+ngx_connection_t   *c;
+#endif
+
+ssl_ctx = SSL_get_SSL_CTX(ssl_conn);
+
+keys = SSL_CTX_get_ex_data(ssl_ctx, ngx_ssl_session_ticket_keys_index);
+if (keys == NULL) {
+return -1;
+}
+
+#if (NGX_DEBUG)
+c = ngx_ssl_get_connection(ssl_conn);
+#endif
+
+if (enc == 1) {
+/* encrypt session ticket */
+
+key = keys->default_key;
+
+ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
+   "ssl session ticket encrypt, key: \"%*s\" (%s session)",
+   key->name_len, key->name,
+   SSL_session_reused(ssl_conn) ? "reused" : "new");
+
+RAND_pseudo_bytes(iv, 16);
+EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, key->aes_key, iv);
+HMAC_Init_ex(hctx, key->hmac_key, 16, ngx_ssl_session_ticket_md(),
+ NULL);
+memcpy(name, key->name, 16);
+
+return 0;
+
+} else {
+/* decrypt session ticket */
+
+if (ngx_strncmp(name, keys->default_key->name, 16)) {
+
+key = keys->keys.elts;
+for (i = 0; i < keys->keys.nelts; i++) {
+if (ngx_strncmp(name, key[i].name, 16) == 0) {
+break;
+}
+}
+
+if (i == keys->keys.nelts) {
+ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+   "ssl session ticket decrypt, key: \"%*s\" "
+   "not found", 16, name);
+return 0;
+}
+
+key = &key[i];
+rc = 2; /* success, renew */
+
+} else {
+