summaryrefslogtreecommitdiff
path: root/src/event/ngx_event_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/event/ngx_event_openssl.c')
-rw-r--r--src/event/ngx_event_openssl.c152
1 files changed, 140 insertions, 12 deletions
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 4356a05ef..81da708f3 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -82,6 +82,8 @@ 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_certificate_index;
+int ngx_ssl_stapling_index;
ngx_int_t
@@ -94,23 +96,25 @@ ngx_ssl_init(ngx_log_t *log)
OpenSSL_add_all_algorithms();
+#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef SSL_OP_NO_COMPRESSION
{
/*
* Disable gzip compression in OpenSSL prior to 1.0.0 version,
* this saves about 522K per connection.
*/
- int i, n;
+ int n;
STACK_OF(SSL_COMP) *ssl_comp_methods;
ssl_comp_methods = SSL_COMP_get_compression_methods();
n = sk_SSL_COMP_num(ssl_comp_methods);
- for (i = 0; i < n; i++) {
- (void) sk_SSL_COMP_delete(ssl_comp_methods, i);
+ while (n--) {
+ (void) sk_SSL_COMP_pop(ssl_comp_methods);
}
}
#endif
+#endif
ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
@@ -135,6 +139,22 @@ ngx_ssl_init(ngx_log_t *log)
return NGX_ERROR;
}
+ ngx_ssl_certificate_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
+ NULL);
+ if (ngx_ssl_certificate_index == -1) {
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+ "SSL_CTX_get_ex_new_index() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_ssl_stapling_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL,
+ NULL);
+ if (ngx_ssl_stapling_index == -1) {
+ ngx_ssl_error(NGX_LOG_ALERT, log, 0,
+ "SSL_CTX_get_ex_new_index() failed");
+ return NGX_ERROR;
+ }
+
return NGX_OK;
}
@@ -216,19 +236,89 @@ ngx_int_t
ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
ngx_str_t *key)
{
+ BIO *bio;
+ X509 *x509;
+ u_long n;
+
if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
return NGX_ERROR;
}
- if (SSL_CTX_use_certificate_chain_file(ssl->ctx, (char *) cert->data)
+ /*
+ * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't
+ * allow to access certificate later from SSL_CTX, so we reimplement
+ * it here
+ */
+
+ bio = BIO_new_file((char *) cert->data, "r");
+ if (bio == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "BIO_new_file(\"%s\") failed", cert->data);
+ return NGX_ERROR;
+ }
+
+ x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
+ if (x509 == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "PEM_read_bio_X509_AUX(\"%s\") failed", cert->data);
+ BIO_free(bio);
+ return NGX_ERROR;
+ }
+
+ if (SSL_CTX_use_certificate(ssl->ctx, x509) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_use_certificate(\"%s\") failed", cert->data);
+ X509_free(x509);
+ BIO_free(bio);
+ return NGX_ERROR;
+ }
+
+ if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_certificate_index, x509)
== 0)
{
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "SSL_CTX_use_certificate_chain_file(\"%s\") failed",
- cert->data);
+ "SSL_CTX_set_ex_data() failed");
return NGX_ERROR;
}
+ X509_free(x509);
+
+ /* read rest of the chain */
+
+ for ( ;; ) {
+
+ x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+ if (x509 == NULL) {
+ n = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(n) == ERR_LIB_PEM
+ && ERR_GET_REASON(n) == PEM_R_NO_START_LINE)
+ {
+ /* end of file */
+ ERR_clear_error();
+ break;
+ }
+
+ /* some real error */
+
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "PEM_read_bio_X509(\"%s\") failed", cert->data);
+ BIO_free(bio);
+ return NGX_ERROR;
+ }
+
+ if (SSL_CTX_add_extra_chain_cert(ssl->ctx, x509) == 0) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_add_extra_chain_cert(\"%s\") failed",
+ cert->data);
+ X509_free(x509);
+ BIO_free(bio);
+ return NGX_ERROR;
+ }
+ }
+
+ BIO_free(bio);
+
if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
return NGX_ERROR;
}
@@ -295,6 +385,33 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
ngx_int_t
+ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
+ ngx_int_t depth)
+{
+ SSL_CTX_set_verify_depth(ssl->ctx, depth);
+
+ if (cert->len == 0) {
+ return NGX_OK;
+ }
+
+ if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (SSL_CTX_load_verify_locations(ssl->ctx, (char *) cert->data, NULL)
+ == 0)
+ {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_load_verify_locations(\"%s\") failed",
+ cert->data);
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
{
X509_STORE *store;
@@ -1473,10 +1590,12 @@ ngx_ssl_clear_error(ngx_log_t *log)
void ngx_cdecl
ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
{
- u_long n;
- va_list args;
- u_char *p, *last;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ int flags;
+ u_long n;
+ va_list args;
+ u_char *p, *last;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
+ const char *data;
last = errstr + NGX_MAX_CONF_ERRSTR;
@@ -1488,14 +1607,14 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
for ( ;; ) {
- n = ERR_get_error();
+ n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
if (n == 0) {
break;
}
if (p >= last) {
- continue;
+ goto next;
}
*p++ = ' ';
@@ -1505,6 +1624,15 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
while (p < last && *p) {
p++;
}
+
+ if (p < last && *data && (flags & ERR_TXT_STRING)) {
+ *p++ = ':';
+ p = ngx_cpystrn(p, (u_char *) data, last - p);
+ }
+
+ next:
+
+ (void) ERR_get_error();
}
ngx_log_error(level, log, err, "%s)", errstr);