Mercurial > hg > nginx-vendor-current
comparison src/event/ngx_event_openssl.c @ 688:f31b19fe7f48 NGINX_1_3_7
nginx 1.3.7
*) Feature: OCSP stapling support.
Thanks to Comodo, DigiCert and GlobalSign for sponsoring this work.
*) Feature: the "ssl_trusted_certificate" directive.
*) Feature: resolver now randomly rotates addresses returned from cache.
Thanks to Anton Jouline.
*) Bugfix: OpenSSL 0.9.7 compatibility.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 02 Oct 2012 00:00:00 +0400 |
parents | 981b4c44593b |
children |
comparison
equal
deleted
inserted
replaced
687:a7305f494f1c | 688:f31b19fe7f48 |
---|---|
80 | 80 |
81 | 81 |
82 int ngx_ssl_connection_index; | 82 int ngx_ssl_connection_index; |
83 int ngx_ssl_server_conf_index; | 83 int ngx_ssl_server_conf_index; |
84 int ngx_ssl_session_cache_index; | 84 int ngx_ssl_session_cache_index; |
85 int ngx_ssl_certificate_index; | |
86 int ngx_ssl_stapling_index; | |
85 | 87 |
86 | 88 |
87 ngx_int_t | 89 ngx_int_t |
88 ngx_ssl_init(ngx_log_t *log) | 90 ngx_ssl_init(ngx_log_t *log) |
89 { | 91 { |
92 SSL_library_init(); | 94 SSL_library_init(); |
93 SSL_load_error_strings(); | 95 SSL_load_error_strings(); |
94 | 96 |
95 OpenSSL_add_all_algorithms(); | 97 OpenSSL_add_all_algorithms(); |
96 | 98 |
99 #if OPENSSL_VERSION_NUMBER >= 0x0090800fL | |
97 #ifndef SSL_OP_NO_COMPRESSION | 100 #ifndef SSL_OP_NO_COMPRESSION |
98 { | 101 { |
99 /* | 102 /* |
100 * Disable gzip compression in OpenSSL prior to 1.0.0 version, | 103 * Disable gzip compression in OpenSSL prior to 1.0.0 version, |
101 * this saves about 522K per connection. | 104 * this saves about 522K per connection. |
102 */ | 105 */ |
103 int i, n; | 106 int n; |
104 STACK_OF(SSL_COMP) *ssl_comp_methods; | 107 STACK_OF(SSL_COMP) *ssl_comp_methods; |
105 | 108 |
106 ssl_comp_methods = SSL_COMP_get_compression_methods(); | 109 ssl_comp_methods = SSL_COMP_get_compression_methods(); |
107 n = sk_SSL_COMP_num(ssl_comp_methods); | 110 n = sk_SSL_COMP_num(ssl_comp_methods); |
108 | 111 |
109 for (i = 0; i < n; i++) { | 112 while (n--) { |
110 (void) sk_SSL_COMP_delete(ssl_comp_methods, i); | 113 (void) sk_SSL_COMP_pop(ssl_comp_methods); |
111 } | 114 } |
112 } | 115 } |
116 #endif | |
113 #endif | 117 #endif |
114 | 118 |
115 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); | 119 ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); |
116 | 120 |
117 if (ngx_ssl_connection_index == -1) { | 121 if (ngx_ssl_connection_index == -1) { |
133 ngx_ssl_error(NGX_LOG_ALERT, log, 0, | 137 ngx_ssl_error(NGX_LOG_ALERT, log, 0, |
134 "SSL_CTX_get_ex_new_index() failed"); | 138 "SSL_CTX_get_ex_new_index() failed"); |
135 return NGX_ERROR; | 139 return NGX_ERROR; |
136 } | 140 } |
137 | 141 |
142 ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, | |
143 NULL); | |
144 if (ngx_ssl_certificate_index == -1) { | |
145 ngx_ssl_error(NGX_LOG_ALERT, log, 0, | |
146 "SSL_CTX_get_ex_new_index() failed"); | |
147 return NGX_ERROR; | |
148 } | |
149 | |
150 ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, | |
151 NULL); | |
152 if (ngx_ssl_stapling_index == -1) { | |
153 ngx_ssl_error(NGX_LOG_ALERT, log, 0, | |
154 "SSL_CTX_get_ex_new_index() failed"); | |
155 return NGX_ERROR; | |
156 } | |
157 | |
138 return NGX_OK; | 158 return NGX_OK; |
139 } | 159 } |
140 | 160 |
141 | 161 |
142 ngx_int_t | 162 ngx_int_t |
214 | 234 |
215 ngx_int_t | 235 ngx_int_t |
216 ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, | 236 ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, |
217 ngx_str_t *key) | 237 ngx_str_t *key) |
218 { | 238 { |
239 BIO *bio; | |
240 X509 *x509; | |
241 u_long n; | |
242 | |
219 if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { | 243 if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { |
220 return NGX_ERROR; | 244 return NGX_ERROR; |
221 } | 245 } |
222 | 246 |
223 if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert->data) | 247 /* |
248 * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't | |
249 * allow to access certificate later from SSL_CTX, so we reimplement | |
250 * it here | |
251 */ | |
252 | |
253 bio = BIO_new_file((char *) cert->data, "r"); | |
254 if (bio == NULL) { | |
255 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
256 "BIO_new_file(\"%s\") failed", cert->data); | |
257 return NGX_ERROR; | |
258 } | |
259 | |
260 x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL); | |
261 if (x509 == NULL) { | |
262 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
263 "PEM_read_bio_X509_AUX(\"%s\") failed", cert->data); | |
264 BIO_free(bio); | |
265 return NGX_ERROR; | |
266 } | |
267 | |
268 if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) { | |
269 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
270 "SSL_CTX_use_certificate(\"%s\") failed", cert->data); | |
271 X509_free(x509); | |
272 BIO_free(bio); | |
273 return NGX_ERROR; | |
274 } | |
275 | |
276 if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509) | |
224 == 0) | 277 == 0) |
225 { | 278 { |
226 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | 279 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, |
227 "SSL_CTX_use_certificate_chain_file(\"%s\") failed", | 280 "SSL_CTX_set_ex_data() failed"); |
228 cert->data); | 281 return NGX_ERROR; |
229 return NGX_ERROR; | 282 } |
230 } | 283 |
284 X509_free(x509); | |
285 | |
286 /* read rest of the chain */ | |
287 | |
288 for ( ;; ) { | |
289 | |
290 x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); | |
291 if (x509 == NULL) { | |
292 n = ERR_peek_last_error(); | |
293 | |
294 if (ERR_GET_LIB(n) == ERR_LIB_PEM | |
295 && ERR_GET_REASON(n) == PEM_R_NO_START_LINE) | |
296 { | |
297 /* end of file */ | |
298 ERR_clear_error(); | |
299 break; | |
300 } | |
301 | |
302 /* some real error */ | |
303 | |
304 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
305 "PEM_read_bio_X509(\"%s\") failed", cert->data); | |
306 BIO_free(bio); | |
307 return NGX_ERROR; | |
308 } | |
309 | |
310 if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) { | |
311 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
312 "SSL_CTX_add_extra_chain_cert(\"%s\") failed", | |
313 cert->data); | |
314 X509_free(x509); | |
315 BIO_free(bio); | |
316 return NGX_ERROR; | |
317 } | |
318 } | |
319 | |
320 BIO_free(bio); | |
231 | 321 |
232 if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) { | 322 if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) { |
233 return NGX_ERROR; | 323 return NGX_ERROR; |
234 } | 324 } |
235 | 325 |
287 */ | 377 */ |
288 | 378 |
289 ERR_clear_error(); | 379 ERR_clear_error(); |
290 | 380 |
291 SSL_CTX_set_client_CA_list(ssl->ctx, list); | 381 SSL_CTX_set_client_CA_list(ssl->ctx, list); |
382 | |
383 return NGX_OK; | |
384 } | |
385 | |
386 | |
387 ngx_int_t | |
388 ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, | |
389 ngx_int_t depth) | |
390 { | |
391 SSL_CTX_set_verify_depth(ssl->ctx, depth); | |
392 | |
393 if (cert->len == 0) { | |
394 return NGX_OK; | |
395 } | |
396 | |
397 if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { | |
398 return NGX_ERROR; | |
399 } | |
400 | |
401 if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL) | |
402 == 0) | |
403 { | |
404 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | |
405 "SSL_CTX_load_verify_locations(\"%s\") failed", | |
406 cert->data); | |
407 return NGX_ERROR; | |
408 } | |
292 | 409 |
293 return NGX_OK; | 410 return NGX_OK; |
294 } | 411 } |
295 | 412 |
296 | 413 |
1471 | 1588 |
1472 | 1589 |
1473 void ngx_cdecl | 1590 void ngx_cdecl |
1474 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) | 1591 ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...) |
1475 { | 1592 { |
1476 u_long n; | 1593 int flags; |
1477 va_list args; | 1594 u_long n; |
1478 u_char *p, *last; | 1595 va_list args; |
1479 u_char errstr[NGX_MAX_CONF_ERRSTR]; | 1596 u_char *p, *last; |
1597 u_char errstr[NGX_MAX_CONF_ERRSTR]; | |
1598 const char *data; | |
1480 | 1599 |
1481 last = errstr + NGX_MAX_CONF_ERRSTR; | 1600 last = errstr + NGX_MAX_CONF_ERRSTR; |
1482 | 1601 |
1483 va_start(args, fmt); | 1602 va_start(args, fmt); |
1484 p = ngx_vslprintf(errstr, last - 1, fmt, args); | 1603 p = ngx_vslprintf(errstr, last - 1, fmt, args); |
1486 | 1605 |
1487 p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); | 1606 p = ngx_cpystrn(p, (u_char *) " (SSL:", last - p); |
1488 | 1607 |
1489 for ( ;; ) { | 1608 for ( ;; ) { |
1490 | 1609 |
1491 n = ERR_get_error(); | 1610 n = ERR_peek_error_line_data(NULL, NULL, &data, &flags); |
1492 | 1611 |
1493 if (n == 0) { | 1612 if (n == 0) { |
1494 break; | 1613 break; |
1495 } | 1614 } |
1496 | 1615 |
1497 if (p >= last) { | 1616 if (p >= last) { |
1498 continue; | 1617 goto next; |
1499 } | 1618 } |
1500 | 1619 |
1501 *p++ = ' '; | 1620 *p++ = ' '; |
1502 | 1621 |
1503 ERR_error_string_n(n, (char *) p, last - p); | 1622 ERR_error_string_n(n, (char *) p, last - p); |
1504 | 1623 |
1505 while (p < last && *p) { | 1624 while (p < last && *p) { |
1506 p++; | 1625 p++; |
1507 } | 1626 } |
1627 | |
1628 if (p < last && *data && (flags & ERR_TXT_STRING)) { | |
1629 *p++ = ':'; | |
1630 p = ngx_cpystrn(p, (u_char *) data, last - p); | |
1631 } | |
1632 | |
1633 next: | |
1634 | |
1635 (void) ERR_get_error(); | |
1508 } | 1636 } |
1509 | 1637 |
1510 ngx_log_error(level, log, err, "%s)", errstr); | 1638 ngx_log_error(level, log, err, "%s)", errstr); |
1511 } | 1639 } |
1512 | 1640 |