Re: [PATCH] SSL: added support for TLS Session Tickets (RFC5077).
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).
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).
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).
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).
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).
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).
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).
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).
# 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).
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).
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).
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).
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).
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).
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).
# 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 { +