В какой версии ссылок пользователь с именем "bytepool" может найти этот обходной путь? Обратитесь по ссылке ниже.

Как заставить `links` игнорировать просроченный SSL-сертификат и продолжить?

Он пишет: «Я быстро заглянул в код, и похоже, что соответствующая функция - verify_cert в https.c. .... Так что для быстрого решения моей проблемы я просто создал собственную версию, в которой verify_cert всегда возвращает true, т.е. проверка сертификата просто полностью обойдена ».

Дальнейшее редактирование по barlop

Зайдя на http://links.twibright.com/download.php и скачав и распаковав http://links.twibright.com/download/links-2.8.tar.gz, я вижу, что это содержимое https.c, которое я вижу нет функции verify_cert

Here is the contents of https.c
/* https.c
 * HTTPS protocol client implementation
 * (c) 2002 Mikulas Patocka
 * This file is a part of the Links program, released under GPL.

 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 * You must obey the GNU General Public License in all respects
 * for all of the code used other than OpenSSL.  If you modify
 * file(s) with this exception, you may extend this exception to your
 * version of the file(s), but you are not obligated to do so.  If you
 * do not wish to do so, delete this exception statement from your
 * version.  If you delete this exception statement from all source
 * files in the program, then also delete it here.
 */

#include "links.h"

#ifndef PATH_MAX
#define PATH_MAX 255
#endif

#ifdef HAVE_SSL

static SSL_CTX *context = NULL;

SSL *getSSL(void)
{
    if (!context) {
        const SSL_METHOD *m;
        unsigned char f_randfile[PATH_MAX];
        unsigned char *os_pool;
        unsigned os_pool_size;

        const unsigned char *f = (const unsigned char *)RAND_file_name(cast_char f_randfile, sizeof(f_randfile));
        if (f && RAND_egd(cast_const_char f) < 0) {
            /* Not an EGD, so read and write to it */
            if (RAND_load_file(cast_const_char f_randfile, -1))
                RAND_write_file(cast_const_char f_randfile);
        }

        os_seed_random(&os_pool, &os_pool_size);
        if (os_pool_size) RAND_add(os_pool, os_pool_size, os_pool_size);
        mem_free(os_pool);

/* needed for systems without /dev/random, but obviously kills security. */
        /*{
            static unsigned char pool[32768];
            int i;
            int rs;
            struct timeval tv;
            EINTRLOOP(rs, gettimeofday(&tv, NULL));
            for (i = 0; i < (int)sizeof pool; i++) pool[i] = random() ^ tv.tv_sec ^ tv.tv_usec;
            RAND_add(pool, sizeof pool, sizeof pool);
        }*/

        SSLeay_add_ssl_algorithms();
        m = SSLv23_client_method();
        if (!m) return NULL;
        context = SSL_CTX_new((void *)m);
        if (!context) return NULL;
        SSL_CTX_set_options(context, SSL_OP_ALL);
        SSL_CTX_set_default_verify_paths(context);

    }
    return (SSL_new(context));
}
void ssl_finish(void)
{
    if (context) SSL_CTX_free(context);
}

void https_func(struct connection *c)
{
    c->ssl = DUMMY;
    http_func(c);
}

#else

void https_func(struct connection *c)
{
    setcstate(c, S_NO_SSL);
    abort_connection(c);
}

#endif

2 ответа2

0

Это должна быть очень старая версия, поскольку ни одна из загружаемых версий не содержит такого кода. Кроме того, вы можете просто полностью отключить проверку, используя SSL_CTX_set_verify. Хотя это небезопасно, на самом деле это не намного небезопаснее, чем нормальное поведение ссылок, то есть проверка пути сертификации, но не проверка соответствия запрашиваемого имени хоста сертификату. Это облегчает атаку «человек посередине», потому что вы можете просто использовать любой сертификат, подписанный доверенным центром сертификации, вместо реального.

0

В какой версии ссылок пользователь с именем "bytepool" может найти этот обходной путь? Обратитесь по ссылке ниже.

Неизвестный.


Он пишет: «Я быстро заглянул в код, и похоже, что соответствующая функция - verify_cert в https.c. .... Так что для быстрого решения моей проблемы я просто создал собственную версию, в которой verify_cert всегда возвращает true, т.е. проверка сертификата просто полностью обойдена ».

Плохая идея.


Следующий код должен справиться с задачей, если все, что вы хотите сделать, это успешно для сертификата с истекшим сроком действия.

По сути, вы добавляете функцию https_verify_cb а затем указываете контексту использовать обратный вызов. Затем, когда OpenSSL встретит сертификат, он вызовет ваш обратный вызов после некоторой собственной обработки.

Код ниже позволяет истечь срок действия любого сертификата, включая ЦС и промежуточные продукты. Вы можете ограничить его сертификатами конечных объектов (т. Е. Сертификатами серверов), используя depth == 0 .

$ diff -u https.c.orig https.c
--- https.c.orig    2013-09-20 17:17:00.000000000 -0400
+++ https.c 2014-11-13 17:42:40.000000000 -0500
@@ -23,10 +23,34 @@
 #define PATH_MAX 255
 #endif

+#ifndef NDEBUG
+# include <stdio.h>
+#endif
+
 #ifdef HAVE_SSL

+#include <openssl/ssl.h>
+#include <openssl/x509_vfy.h>
+
 static SSL_CTX *context = NULL;

+int https_verify_cb(int preverify, X509_STORE_CTX* x509_ctx)
+{
+    /* For error codes, see http://www.openssl.org/docs/apps/verify.html  */
+    
+    const int depth = X509_STORE_CTX_get_error_depth(x509_ctx);
+    const int err = X509_STORE_CTX_get_error(x509_ctx);
+    
+#ifndef NDEBUG
+    fprintf(stdout, "https_verify_cb (depth=%d)(preverify=%d)(error=%d)\n", depth, preverify, err);
+#endif
+    
+    /* We return the result of `preverify`, which is the result of customary  */
+    /* X509 verifcation. If all goes well, the value will be 1. If preverify  */
+    /* failed, then we return success if the certifcate is expired.           */
+    return preverify || (err == X509_V_ERR_CERT_HAS_EXPIRED);
+}
+
 SSL *getSSL(void)
 {
    if (!context) {
@@ -62,7 +86,12 @@
        if (!m) return NULL;
        context = SSL_CTX_new((void *)m);
        if (!context) return NULL;
-       SSL_CTX_set_options(context, SSL_OP_ALL);
+        
+       /* SSL_CTX_set_options(context, SSL_OP_ALL); */
+        const long flags = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION;
+        long old_opts = SSL_CTX_set_options(context, flags);
+        
+        SSL_CTX_set_verify(context, SSL_VERIFY_PEER, https_verify_cb);
        SSL_CTX_set_default_verify_paths(context);

    }

Обратите внимание, что OpenSSL до 1.1.0 не выполняет сопоставление имени хоста, поэтому библиотека преуспеет в построении пути, даже если имена не совпадают. См. Справочную страницу для X509_check_host(3).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .