ssl client again

Igor Sysoev is at rambler-co.ru
Tue Aug 8 16:56:59 MSD 2006


On Tue, 8 Aug 2006, Andrey Y. Ostanovsky wrote:

> Igor Sysoev wrote:
>> On Tue, 8 Aug 2006, Andrey Y. Ostanovsky wrote:
>>
>>> Igor Sysoev wrote:
>>>>> С несколькими сертификатами все еще хуже.:( При наличии двух
>>>>> сертификатов "А" и "Б" - файрфокс, похоже, отдает их по алфавиту, т.е.
>>>>> теперь на сайте "А" я авторизуюсь нормально, на сайте "Б" - SSL:
>>>>> error:140890B2:SSL routines. Удаляю сертификат "А" - и авторизация на
>>>>> "Б" проходит безо всяких ошибок.
>>>> А если попробовать 0.3.56 ?
>>> А там делается запрос типа SSL_get_client_CA_list? Есть ощущение, что не
>>> обрабатывается весь массив сертификатов, а идет сброс в состояние ERROR
>>> после проверки первого сертификата. Хотя, попробовать собрать 0.3.56,
>>> конечно, можно.
>> Нет, SSL_get_client_CA_list делает сам openssl. До 0.3.56 не было
>> callback'а, который бы игнорировал ошибку на первом сертификате и
>> без которого соединение сразу же рвалось.
> Обновил из порта до 0.3.56.
> 2006/08/08 13:16:22 [info] 66168#0: *82 client SSL certificate verify
> error: (21:unable to verify the first certificate)  while reading client
> request headers, client:
> Ну, то есть массив таки не обрабатывается. :( Грабли.

Прилагаемый патч должен исправить эту ошибку.


Игорь Сысоев
http://sysoev.ru
-------------- next part --------------
--- src/event/ngx_event_openssl.c	Sat May  6 18:31:43 2006
+++ src/event/ngx_event_openssl.c	Tue Aug  8 16:51:39 2006
@@ -83,6 +83,9 @@
 };
 
 
+int  ngx_connection_index;
+
+
 ngx_int_t
 ngx_ssl_init(ngx_log_t *log)
 {
@@ -93,6 +96,13 @@
     ENGINE_load_builtin_engines();
 #endif
 
+    ngx_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+
+    if (ngx_connection_index == -1) {
+        ngx_ssl_error(NGX_LOG_ALERT, log, 0, "SSL_get_ex_new_index() failed");
+        return NGX_ERROR;
+    }
+
     return NGX_OK;
 }
 
@@ -179,6 +189,8 @@
 ngx_int_t
 ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert)
 {
+    STACK_OF(X509_NAME)  *list;
+
     if (ngx_conf_full_name(cf->cycle, cert) == NGX_ERROR) {
         return NGX_ERROR;
     }
@@ -192,6 +204,16 @@
         return NGX_ERROR;
     }
 
+    list = SSL_load_client_CA_file((char *) cert->data);
+
+    if (list == NULL) {
+        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                      "SSL_load_client_CA_file(\"%s\") failed", cert->data);
+        return NGX_ERROR;
+    }
+
+    SSL_CTX_set_client_CA_list(ssl->ctx, list);
+
     return NGX_OK;
 }
 
@@ -252,6 +274,11 @@
 
     } else {
         SSL_set_accept_state(sc->connection);
+    }
+
+    if (SSL_set_ex_data(sc->connection, ngx_connection_index, c) == 0) {
+        ngx_ssl_error(NGX_LOG_ALERT, c->log, 0, "SSL_set_ex_data() failed");
+        return NGX_ERROR;
     }
 
     c->ssl = sc;
--- src/event/ngx_event_openssl.h	Sat May  6 18:35:51 2006
+++ src/event/ngx_event_openssl.h	Tue Aug  8 14:04:32 2006
@@ -22,6 +22,10 @@
 #define NGX_SSL_NAME     "OpenSSL"
 
 
+#define ngx_ssl_session_t       SSL_SESSION
+#define ngx_ssl_conn_t          SSL
+
+
 typedef struct {
     SSL_CTX                    *ctx;
     RSA                        *rsa512_key;
@@ -30,7 +34,7 @@
 
 
 typedef struct {
-    SSL                        *connection;
+    ngx_ssl_conn_t             *connection;
 
     ngx_int_t                   last;
     ngx_buf_t                  *buf;
@@ -47,9 +51,6 @@
 } ngx_ssl_connection_t;
 
 
-#define ngx_ssl_session_t       SSL_SESSION
-
-
 #define NGX_SSL_SSLv2    2
 #define NGX_SSL_SSLv3    4
 #define NGX_SSL_TLSv1    8
@@ -77,6 +78,7 @@
 ngx_int_t ngx_ssl_set_session(ngx_connection_t *c, ngx_ssl_session_t *session);
 #define ngx_ssl_get_session(c)      SSL_get1_session(c->ssl->connection)
 #define ngx_ssl_free_session        SSL_SESSION_free
+#define ngx_ssl_get_connection(sc)  SSL_get_ex_data(sc, ngx_connection_index)
 
 
 u_char *ngx_ssl_get_protocol(ngx_connection_t *c);
@@ -98,6 +100,9 @@
 void ngx_cdecl ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
     char *fmt, ...);
 void ngx_ssl_cleanup_ctx(void *data);
+
+
+extern int  ngx_connection_index;
 
 
 #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */
--- src/http/modules/ngx_http_ssl_module.c	Wed Aug  2 23:06:40 2006
+++ src/http/modules/ngx_http_ssl_module.c	Tue Aug  8 14:53:17 2006
@@ -427,6 +427,33 @@
 static int
 ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
 {
+    char              *subject, *issuer;
+    int                err, depth;
+    X509              *cert;
+    X509_NAME         *name;
+    ngx_connection_t  *c;
+    ngx_ssl_conn_t    *ssl_conn;
+
+    ssl_conn = X509_STORE_CTX_get_ex_data(x509_store,
+                                          SSL_get_ex_data_X509_STORE_CTX_idx());
+
+    c = ngx_ssl_get_connection(ssl_conn);
+
+    cert = X509_STORE_CTX_get_current_cert(x509_store);
+    err = X509_STORE_CTX_get_error(x509_store);
+    depth = X509_STORE_CTX_get_error_depth(x509_store);
+
+    name = X509_get_subject_name(cert);
+    subject = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
+
+    name = X509_get_issuer_name(cert);
+    issuer = name ? X509_NAME_oneline(name, NULL, 0) : "(none)";
+
+    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "verify:%d, error:%d, depth:%d, "
+                   "subject:\"%s\",issuer: \"%s\"",
+                   ok, err, depth, subject, issuer);
+
     return 1;
 }
 
--- src/http/ngx_http_script.c	Tue Aug  1 16:34:40 2006
+++ src/http/ngx_http_script.c	Sat Aug  5 09:51:51 2006
@@ -960,13 +960,16 @@
         }
 
         switch (code->op) {
+
         case ngx_http_script_file_plain:
         case ngx_http_script_file_dir:
         case ngx_http_script_file_exists:
         case ngx_http_script_file_exec:
              goto false;
+
         case ngx_http_script_file_not_plain:
         case ngx_http_script_file_not_dir:
+        case ngx_http_script_file_not_exists:
         case ngx_http_script_file_not_exec:
              goto true;
         }


More information about the nginx-ru mailing list