@@ -18,7 +18,9 @@ static char *ngx_tcp_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
18
18
void * conf );
19
19
static char * ngx_tcp_ssl_session_cache (ngx_conf_t * cf , ngx_command_t * cmd ,
20
20
void * conf );
21
-
21
+ static ngx_int_t ngx_tcp_ssl_client_certificate (ngx_conf_t * cf , ngx_ssl_t * ssl ,
22
+ ngx_str_t * cert , ngx_int_t depth , ngx_int_t optional );
23
+ static int ngx_tcp_ssl_verify_callback (int ok , X509_STORE_CTX * x509_store );
22
24
23
25
static ngx_conf_bitmask_t ngx_tcp_ssl_protocols [] = {
24
26
{ ngx_string ("SSLv2" ), NGX_SSL_SSLv2 },
@@ -358,9 +360,10 @@ ngx_tcp_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
358
360
return NGX_CONF_ERROR ;
359
361
}
360
362
361
- if (ngx_ssl_client_certificate (cf , & conf -> ssl ,
363
+ if (ngx_tcp_ssl_client_certificate (cf , & conf -> ssl ,
362
364
& conf -> client_certificate ,
363
- conf -> verify_depth )
365
+ conf -> verify_depth ,
366
+ conf -> verify == 2 ? 1 : 0 )
364
367
!= NGX_OK )
365
368
{
366
369
return NGX_CONF_ERROR ;
@@ -539,3 +542,109 @@ ngx_tcp_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
539
542
540
543
return NGX_CONF_ERROR ;
541
544
}
545
+
546
+ // borrowed from original ngx_event_openssl.c v1.7.1
547
+ ngx_int_t
548
+ ngx_tcp_ssl_client_certificate (ngx_conf_t * cf , ngx_ssl_t * ssl , ngx_str_t * cert ,
549
+ ngx_int_t depth , ngx_int_t optional )
550
+ {
551
+ STACK_OF (X509_NAME ) * list ;
552
+
553
+ /* @see https://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
554
+ * When proxying tcp connection, you expect handshake to fail if no
555
+ * client certificate was send by client and ssl_verify_client=on.
556
+ * But by default nginx allowed connection by any client.
557
+ */
558
+ int ossl_verify_mode = optional ? SSL_VERIFY_PEER
559
+ : SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT ;
560
+
561
+ SSL_CTX_set_verify (ssl -> ctx , ossl_verify_mode , ngx_tcp_ssl_verify_callback );
562
+
563
+ SSL_CTX_set_verify_depth (ssl -> ctx , depth );
564
+
565
+ if (cert -> len == 0 ) {
566
+ return NGX_OK ;
567
+ }
568
+
569
+ if (ngx_conf_full_name (cf -> cycle , cert , 1 ) != NGX_OK ) {
570
+ return NGX_ERROR ;
571
+ }
572
+
573
+ if (SSL_CTX_load_verify_locations (ssl -> ctx , (char * ) cert -> data , NULL )
574
+ == 0 )
575
+ {
576
+ ngx_ssl_error (NGX_LOG_EMERG , ssl -> log , 0 ,
577
+ "SSL_CTX_load_verify_locations(\"%s\") failed" ,
578
+ cert -> data );
579
+ return NGX_ERROR ;
580
+ }
581
+
582
+ /*
583
+ * SSL_CTX_load_verify_locations() may leave errors in the error queue
584
+ * while returning success
585
+ */
586
+
587
+ ERR_clear_error ();
588
+
589
+ list = SSL_load_client_CA_file ((char * ) cert -> data );
590
+
591
+ if (list == NULL ) {
592
+ ngx_ssl_error (NGX_LOG_EMERG , ssl -> log , 0 ,
593
+ "SSL_load_client_CA_file(\"%s\") failed" , cert -> data );
594
+ return NGX_ERROR ;
595
+ }
596
+
597
+ /*
598
+ * before 0.9.7h and 0.9.8 SSL_load_client_CA_file()
599
+ * always leaved an error in the error queue
600
+ */
601
+
602
+ ERR_clear_error ();
603
+
604
+ SSL_CTX_set_client_CA_list (ssl -> ctx , list );
605
+
606
+ return NGX_OK ;
607
+ }
608
+
609
+ static int
610
+ ngx_tcp_ssl_verify_callback (int ok , X509_STORE_CTX * x509_store )
611
+ {
612
+ #if (NGX_DEBUG )
613
+ char * subject , * issuer ;
614
+ int err , depth ;
615
+ X509 * cert ;
616
+ X509_NAME * sname , * iname ;
617
+ ngx_connection_t * c ;
618
+ ngx_ssl_conn_t * ssl_conn ;
619
+
620
+ ssl_conn = X509_STORE_CTX_get_ex_data (x509_store ,
621
+ SSL_get_ex_data_X509_STORE_CTX_idx ());
622
+
623
+ c = ngx_ssl_get_connection (ssl_conn );
624
+
625
+ cert = X509_STORE_CTX_get_current_cert (x509_store );
626
+ err = X509_STORE_CTX_get_error (x509_store );
627
+ depth = X509_STORE_CTX_get_error_depth (x509_store );
628
+
629
+ sname = X509_get_subject_name (cert );
630
+ subject = sname ? X509_NAME_oneline (sname , NULL , 0 ) : "(none)" ;
631
+
632
+ iname = X509_get_issuer_name (cert );
633
+ issuer = iname ? X509_NAME_oneline (iname , NULL , 0 ) : "(none)" ;
634
+
635
+ ngx_log_debug5 (NGX_LOG_DEBUG_EVENT , c -> log , 0 ,
636
+ "verify:%d, error:%d, depth:%d, "
637
+ "subject:\"%s\",issuer: \"%s\"" ,
638
+ ok , err , depth , subject , issuer );
639
+
640
+ if (sname ) {
641
+ OPENSSL_free (subject );
642
+ }
643
+
644
+ if (iname ) {
645
+ OPENSSL_free (issuer );
646
+ }
647
+ #endif
648
+
649
+ return ok ;
650
+ }
0 commit comments