comparison src/stream/ngx_stream_ssl_module.c @ 7464:e970de27966a

SSL: dynamic certificate loading in the stream module.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 25 Feb 2019 16:42:43 +0300
parents 7f955d3b9a0d
children 6708bec13757
comparison
equal deleted inserted replaced
7463:180df83473a4 7464:e970de27966a
20 20
21 static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s); 21 static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s);
22 static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, 22 static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl,
23 ngx_connection_t *c); 23 ngx_connection_t *c);
24 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c); 24 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c);
25 #ifdef SSL_R_CERT_CB_ERROR
26 static int ngx_stream_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg);
27 #endif
25 static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s, 28 static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
26 ngx_stream_variable_value_t *v, uintptr_t data); 29 ngx_stream_variable_value_t *v, uintptr_t data);
27 static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s, 30 static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s,
28 ngx_stream_variable_value_t *v, uintptr_t data); 31 ngx_stream_variable_value_t *v, uintptr_t data);
29 32
30 static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf); 33 static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf);
31 static void *ngx_stream_ssl_create_conf(ngx_conf_t *cf); 34 static void *ngx_stream_ssl_create_conf(ngx_conf_t *cf);
32 static char *ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, 35 static char *ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent,
33 void *child); 36 void *child);
37
38 static ngx_int_t ngx_stream_ssl_compile_certificates(ngx_conf_t *cf,
39 ngx_stream_ssl_conf_t *conf);
34 40
35 static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, 41 static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
36 void *conf); 42 void *conf);
37 static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, 43 static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
38 void *conf); 44 void *conf);
406 412
407 ngx_stream_core_run_phases(s); 413 ngx_stream_core_run_phases(s);
408 } 414 }
409 415
410 416
417 #ifdef SSL_R_CERT_CB_ERROR
418
419 int
420 ngx_stream_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
421 {
422 ngx_str_t cert, key;
423 ngx_uint_t i, nelts;
424 ngx_connection_t *c;
425 ngx_stream_session_t *s;
426 ngx_stream_ssl_conf_t *sslcf;
427 ngx_stream_complex_value_t *certs, *keys;
428
429 c = ngx_ssl_get_connection(ssl_conn);
430
431 if (c->ssl->handshaked) {
432 return 0;
433 }
434
435 s = c->data;
436
437 sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
438
439 nelts = sslcf->certificate_values->nelts;
440 certs = sslcf->certificate_values->elts;
441 keys = sslcf->certificate_key_values->elts;
442
443 for (i = 0; i < nelts; i++) {
444
445 if (ngx_stream_complex_value(s, &certs[i], &cert) != NGX_OK) {
446 return 0;
447 }
448
449 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
450 "ssl cert: \"%s\"", cert.data);
451
452 if (ngx_stream_complex_value(s, &keys[i], &key) != NGX_OK) {
453 return 0;
454 }
455
456 ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
457 "ssl key: \"%s\"", key.data);
458
459 if (ngx_ssl_connection_certificate(c, c->pool, &cert, &key,
460 sslcf->passwords)
461 != NGX_OK)
462 {
463 return 0;
464 }
465 }
466
467 return 1;
468 }
469
470 #endif
471
472
411 static ngx_int_t 473 static ngx_int_t
412 ngx_stream_ssl_static_variable(ngx_stream_session_t *s, 474 ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
413 ngx_stream_variable_value_t *v, uintptr_t data) 475 ngx_stream_variable_value_t *v, uintptr_t data)
414 { 476 {
415 ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; 477 ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
503 /* 565 /*
504 * set by ngx_pcalloc(): 566 * set by ngx_pcalloc():
505 * 567 *
506 * scf->listen = 0; 568 * scf->listen = 0;
507 * scf->protocols = 0; 569 * scf->protocols = 0;
570 * scf->certificate_values = NULL;
508 * scf->dhparam = { 0, NULL }; 571 * scf->dhparam = { 0, NULL };
509 * scf->ecdh_curve = { 0, NULL }; 572 * scf->ecdh_curve = { 0, NULL };
510 * scf->client_certificate = { 0, NULL }; 573 * scf->client_certificate = { 0, NULL };
511 * scf->trusted_certificate = { 0, NULL }; 574 * scf->trusted_certificate = { 0, NULL };
512 * scf->crl = { 0, NULL }; 575 * scf->crl = { 0, NULL };
617 } 680 }
618 681
619 cln->handler = ngx_ssl_cleanup_ctx; 682 cln->handler = ngx_ssl_cleanup_ctx;
620 cln->data = &conf->ssl; 683 cln->data = &conf->ssl;
621 684
622 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, 685 if (ngx_stream_ssl_compile_certificates(cf, conf) != NGX_OK) {
623 conf->certificate_keys, conf->passwords) 686 return NGX_CONF_ERROR;
624 != NGX_OK) 687 }
625 { 688
626 return NGX_CONF_ERROR; 689 if (conf->certificate_values) {
690
691 #ifdef SSL_R_CERT_CB_ERROR
692
693 /* install callback to lookup certificates */
694
695 SSL_CTX_set_cert_cb(conf->ssl.ctx, ngx_stream_ssl_certificate, NULL);
696
697 #else
698 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
699 "variables in "
700 "\"ssl_certificate\" and \"ssl_certificate_key\" "
701 "directives are not supported on this platform");
702 return NGX_CONF_ERROR;
703 #endif
704
705 } else {
706
707 /* configure certificates */
708
709 if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
710 conf->certificate_keys, conf->passwords)
711 != NGX_OK)
712 {
713 return NGX_CONF_ERROR;
714 }
627 } 715 }
628 716
629 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, 717 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
630 conf->prefer_server_ciphers) 718 conf->prefer_server_ciphers)
631 != NGX_OK) 719 != NGX_OK)
705 793
706 return NGX_CONF_OK; 794 return NGX_CONF_OK;
707 } 795 }
708 796
709 797
798 static ngx_int_t
799 ngx_stream_ssl_compile_certificates(ngx_conf_t *cf,
800 ngx_stream_ssl_conf_t *conf)
801 {
802 ngx_str_t *cert, *key;
803 ngx_uint_t i, nelts;
804 ngx_stream_complex_value_t *cv;
805 ngx_stream_compile_complex_value_t ccv;
806
807 cert = conf->certificates->elts;
808 key = conf->certificate_keys->elts;
809 nelts = conf->certificates->nelts;
810
811 for (i = 0; i < nelts; i++) {
812
813 if (ngx_stream_script_variables_count(&cert[i])) {
814 goto found;
815 }
816
817 if (ngx_stream_script_variables_count(&key[i])) {
818 goto found;
819 }
820 }
821
822 return NGX_OK;
823
824 found:
825
826 conf->certificate_values = ngx_array_create(cf->pool, nelts,
827 sizeof(ngx_stream_complex_value_t));
828 if (conf->certificate_values == NULL) {
829 return NGX_ERROR;
830 }
831
832 conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
833 sizeof(ngx_stream_complex_value_t));
834 if (conf->certificate_key_values == NULL) {
835 return NGX_ERROR;
836 }
837
838 for (i = 0; i < nelts; i++) {
839
840 cv = ngx_array_push(conf->certificate_values);
841 if (cv == NULL) {
842 return NGX_ERROR;
843 }
844
845 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
846
847 ccv.cf = cf;
848 ccv.value = &cert[i];
849 ccv.complex_value = cv;
850 ccv.zero = 1;
851
852 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
853 return NGX_ERROR;
854 }
855
856 cv = ngx_array_push(conf->certificate_key_values);
857 if (cv == NULL) {
858 return NGX_ERROR;
859 }
860
861 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
862
863 ccv.cf = cf;
864 ccv.value = &key[i];
865 ccv.complex_value = cv;
866 ccv.zero = 1;
867
868 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
869 return NGX_ERROR;
870 }
871 }
872
873 conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
874 if (conf->passwords == NULL) {
875 return NGX_ERROR;
876 }
877
878 return NGX_OK;
879 }
880
881
710 static char * 882 static char *
711 ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 883 ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
712 { 884 {
713 ngx_stream_ssl_conf_t *scf = conf; 885 ngx_stream_ssl_conf_t *scf = conf;
714 886