Skip to content

Commit

Permalink
OCSP stapling: loading OCSP responses.
Browse files Browse the repository at this point in the history
This includes the ssl_stapling_responder directive (defaults to OCSP
responder set in certificate's AIA extension).

OCSP response for a given certificate is requested once we get at least
one connection with certificate_status extension in ClientHello, and
certificate status won't be sent in the connection in question.  This due
to limitations in the OpenSSL API (certificate status callback is blocking).

Note: SSL_CTX_use_certificate_chain_file() was reimplemented as it doesn't
allow to access the certificate loaded via SSL_CTX.
  • Loading branch information
mdounin committed Oct 1, 2012
1 parent f7ec295 commit 74ad449
Show file tree
Hide file tree
Showing 6 changed files with 1,764 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/core/ngx_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#include <ngx_slab.h>
#include <ngx_inet.h>
#include <ngx_cycle.h>
#include <ngx_resolver.h>
#if (NGX_OPENSSL)
#include <ngx_event_openssl.h>
#endif
#include <ngx_process_cycle.h>
#include <ngx_conf_file.h>
#include <ngx_resolver.h>
#include <ngx_open_file_cache.h>
#include <ngx_os.h>
#include <ngx_connection.h>
Expand Down
94 changes: 91 additions & 3 deletions src/event/ngx_event_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -137,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;
}

Expand Down Expand Up @@ -218,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;
}
Expand Down
7 changes: 6 additions & 1 deletion src/event/ngx_event_openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_int_t depth);
ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *responder, ngx_str_t *file);
ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
RSA *ngx_ssl_rsa512_key_callback(SSL *ssl, int is_export, int key_length);
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
Expand Down Expand Up @@ -161,6 +164,8 @@ void ngx_ssl_cleanup_ctx(void *data);
extern int ngx_ssl_connection_index;
extern int ngx_ssl_server_conf_index;
extern int ngx_ssl_session_cache_index;
extern int ngx_ssl_certificate_index;
extern int ngx_ssl_stapling_index;


#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */
Loading

0 comments on commit 74ad449

Please sign in to comment.