Mercurial > hg > nginx
comparison src/event/ngx_event_openssl.c @ 4875:386a06a22c40
OCSP stapling: loading OCSP responses.
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 01 Oct 2012 12:47:55 +0000 |
parents | 7c3cca603438 |
children | f2e450929c1f |
comparison
equal
deleted
inserted
replaced
4874:d1a20423c425 | 4875:386a06a22c40 |
---|---|
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 { |
135 ngx_ssl_error(NGX_LOG_ALERT, log, 0, | 137 ngx_ssl_error(NGX_LOG_ALERT, log, 0, |
136 "SSL_CTX_get_ex_new_index() failed"); | 138 "SSL_CTX_get_ex_new_index() failed"); |
137 return NGX_ERROR; | 139 return NGX_ERROR; |
138 } | 140 } |
139 | 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 | |
140 return NGX_OK; | 158 return NGX_OK; |
141 } | 159 } |
142 | 160 |
143 | 161 |
144 ngx_int_t | 162 ngx_int_t |
216 | 234 |
217 ngx_int_t | 235 ngx_int_t |
218 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, |
219 ngx_str_t *key) | 237 ngx_str_t *key) |
220 { | 238 { |
239 BIO *bio; | |
240 X509 *x509; | |
241 u_long n; | |
242 | |
221 if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { | 243 if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) { |
222 return NGX_ERROR; | 244 return NGX_ERROR; |
223 } | 245 } |
224 | 246 |
225 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) | |
226 == 0) | 277 == 0) |
227 { | 278 { |
228 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, | 279 ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, |
229 "SSL_CTX_use_certificate_chain_file(\"%s\") failed", | 280 "SSL_CTX_set_ex_data() failed"); |
230 cert->data); | 281 return NGX_ERROR; |
231 return NGX_ERROR; | 282 } |
232 } | 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); | |
233 | 321 |
234 if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) { | 322 if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) { |
235 return NGX_ERROR; | 323 return NGX_ERROR; |
236 } | 324 } |
237 | 325 |