2016-10-08 8 views
2

Я пытаюсь проверить сертификат IRC-сервера на UTN_USERFirst_Hardware CA. Я столкнулся с кодом ошибки 20 от SSL_get_verify_result (что, если я прав, означает, что ему не удалось получить сертификат сверстника?). Кроме того, я не слишком уверен в том, какой приоритет «шагов» в этом процессе.SSL_get_verify_result возвращает ошибку 20 для irc.freenode.net

Вот что я починил:

int tallis_ssl_verify(tallis_t *tallis, X509 *cert) 
{ 
    int rv; 

    X509_VERIFY_PARAM_set_hostflags(
      tallis->param, 
      X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); 

    SSL_CTX_set_default_verify_paths(tallis->ssl_context); 

    ERR_clear_error(); 
    rv = SSL_CTX_load_verify_locations(
      tallis->ssl_context, 
      "/etc/ssl/certs/AddTrust_External_Root.pem", 
      "/etc/ssl/certs"); 

    if (!rv) 
    { 
     fprintf(stderr, ERR_error_string(ERR_get_error(), NULL)); 
     return 1; 
    } 

    X509_VERIFY_PARAM_set1_host(tallis->param, tallis->host, 0); 
    SSL_CTX_set_verify(tallis->ssl_context, SSL_VERIFY_PEER, NULL); 
    SSL_set_verify(tallis->ssl_connection, SSL_VERIFY_PEER, NULL); 

    ERR_clear_error(); 
    rv = SSL_get_verify_result(tallis->ssl_connection); 

    if (rv != X509_V_OK) 
    { 
     printf("%d\n", rv); 
     fprintf(stderr, ERR_error_string(ERR_get_error(), NULL)); 
     return 1; 
    } 

    ERR_clear_error(); 
    X509_STORE_CTX *ctx = X509_STORE_CTX_new(); 

    if (!ctx) 
    { 
     fprintf(stderr, ERR_error_string(ERR_get_error(), NULL)); 
     return 1; 
    } 

    ERR_clear_error(); 
    X509_STORE *store = X509_STORE_new(); 

    if (!store) 
    { 
     X509_STORE_free(store); 
     fprintf(stderr, ERR_error_string(ERR_get_error(), NULL)); 
     return 1; 
    } 

    ERR_clear_error(); 
    rv = X509_STORE_CTX_init(ctx, store, cert, NULL); 

    if (!rv) 
    { 
     X509_STORE_free(store); 
     fprintf(stderr, ERR_error_string(ERR_get_error(), NULL)); 
     return 1; 
    } 

    X509_STORE_set_flags(store, X509_V_FLAG_CB_ISSUER_CHECK); 
    X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); 

    X509_STORE_load_locations(
      store, 
      "/etc/ssl/certs/AddTrust_External_Root.pem", 
      NULL); 

    X509_STORE_set_default_paths(store); 

    X509_LOOKUP_load_file(
      lookup, 
      "/etc/ssl/certs/AddTrust_External_Root.pem", 
      X509_FILETYPE_PEM); 

    X509_STORE_add_cert(store, cert); 

    ERR_clear_error(); 
    rv = X509_verify_cert(ctx); 

    if (rv != 1) 
    { 
     X509_STORE_free(store); 
     fprintf(
       stderr, 
       "%s\n%s\n", 
       ERR_error_string(ERR_get_error(), NULL), 
       X509_verify_cert_error_string(ctx->error)); 

     return 1; 
    } 

    return 0; 
} 

И вызывающий рутина для контекста:

int main(int argc, char *argv[]) 
{ 
    tallis_t *tallis = malloc(sizeof(tallis_t)); 
    tallis->host = "irc.freenode.net"; 
    tallis->port = "6697"; 
    tallis->bio = NULL; 
    tallis->ssl_connection = NULL; 
    ssl_init(tallis->ssl_connection); 
    tallis->ssl_context = SSL_CTX_new(TLSv1_2_client_method()); 
    tallis->ssl_connection = SSL_new(tallis->ssl_context); 
    tallis->param = SSL_get0_param(tallis->ssl_connection); 

    int rv; 

    rv = tallis_connect(tallis); 

    if (rv) 
     DIE("%s\n", "connection failed"); 

    ERR_clear_error(); 
    X509 *cert = SSL_get_peer_certificate(tallis->ssl_connection); 

    if (!cert) 
     DIE("%s\n", ERR_error_string(ERR_get_error(), NULL)); 

    rv = tallis_ssl_verify(tallis, cert); 

    X509_free(cert); 

    if (rv) 
     DIE("%s\n", "certificate verificiation failed"); 
    else 
     printf("%s\n", "certificate verification succeeded"); 

    rv = tallis_loop(tallis); 

    if (rv) 
     DIE("%s\n", "socket connection terminated"); 

    rv = ssl_shutdown(tallis); 

    if (rv) 
     DIE("%s\n", "ssl shutdown failed"); 
} 

Так, как он стоит мой поток заключается в следующем: Установить соединение на сокет (BIO) -> вызов SSL_get_peer_certificate -> проверить сертификат, это правильно?

В чем разница между SSL_get_verify_result и X509_verify_cert и какой из них следует использовать в первую очередь? Извините, если это слишком общее, мне нужно небольшое руководство, и документы - это просто страницы с малой информацией с не очень соответствующей корреляционной информацией, мне сложно получить организованный вид OpenSSL.

Как насчет «Как проверить сертификат однорангового соединения в OpenSSL как можно проще?»

+0

Код подтверждения подтверждения 20 «* не может получить сертификат местного эмитента» *. Коды определены в 'x509_vfy.h', а 20 -' X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY'. На странице руководства OpenSSL, которая их обсуждает, есть ['openssl verify'] (http://www.openssl.org/docs/manmaster/apps/verify.html). См. [OpenSSL Verify return code: 20 (невозможно получить сертификат локального эмитента)] (http://stackoverflow.com/q/11548336) в разделе «Переполнение стека». Также см. [SSL/TLS Client] (http://wiki.openssl.org/index.php/SSL/TLS_Client) в вики OpenSSL. Страница вики будет отвечать * «Как проверить сертификат однорангового узла ...» * – jww

ответ

1

Я пытаюсь проверить сертификат сервера IRC против UTN_USERFirst_Hardware CA

Я считаю, что это неправильно Root CA.


Как насчет "Как проверить сертификат партнера в OpenSSL как можно проще?

Я думаю, вы находитесь именно там, где вам нужно быть. Вам нужно всего лишь несколько настроек.

Когда я анализирую верхний Эмитент в цепи (s: указывает Subject, а i: указывает эмитента):

$ openssl s_client -connect irc.freenode.net:6697 -servername irc.freenode.net -tls1_2 
CONNECTED(00000005) 
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority 
verify error:num=20:unable to get local issuer certificate 
Server did acknowledge servername extension. 
--- 
Certificate chain 
0 s:/OU=Domain Control Validated/OU=Gandi Standard Wildcard SSL/CN=*.freenode.net 
    i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2 
1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2 
    i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority 
2 s:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority 
    i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root 
... 

<skip certificate and lots of other stuff> 

... 
Start Time: 1475924259 
Timeout : 7200 (sec) 
Verify return code: 20 (unable to get local issuer certificate) 

Похоже, что вы хотите, чтобы ваш корень доверительного управления при CN=AddTrust External CA Root; не UTN_USERFirst_Hardware_Root_CA. Вы можете найти его на сайте Comodo по адресу [Root] AddTrust External CA Root.

Файл addtrustexternalcaroot.crt в формате PEM.Вам нужно только указать опцию -CAfile, чтобы команда успешно завершена (X509_V_OK):

$ openssl s_client -connect irc.freenode.net:6697 -servername irc.freenode.net -tls1_2 -CAfile addtrustexternalcaroot.crt 
CONNECTED(00000005) 
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root 
verify return:1 
depth=2 C = US, ST = New Jersey, L = Jersey City, O = The USERTRUST Network, CN = USERTrust RSA Certification Authority 
verify return:1 
depth=1 C = FR, ST = Paris, L = Paris, O = Gandi, CN = Gandi Standard SSL CA 2 
verify return:1 
depth=0 OU = Domain Control Validated, OU = Gandi Standard Wildcard SSL, CN = *.freenode.net 
verify return:1 
Server did acknowledge servername extension. 
--- 
Certificate chain 
0 s:/OU=Domain Control Validated/OU=Gandi Standard Wildcard SSL/CN=*.freenode.net 
    i:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2 
1 s:/C=FR/ST=Paris/L=Paris/O=Gandi/CN=Gandi Standard SSL CA 2 
    i:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority 
2 s:/C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority 
    i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root 
... 

<skip certificate and lots of other stuff> 

... 
Start Time: 1475924761 
Timeout : 7200 (sec) 
Verify return code: 0 (ok) 
Extended master secret: no 

Теперь, когда вы знаете, как проверить это и то, что хороший тест выглядит, вот как это исправить в вашем коде:

rv = SSL_CTX_load_verify_locations(
     ssl_context, 
     ".../addtrustexternalcaroot.crt", 
     NULL; 

Вот что выглядит CA Root, как:

$ cat addtrustexternalcaroot.crt | openssl x509 -text -noout 
Certificate: 
    Data: 
     Version: 3 (0x2) 
     Serial Number: 1 (0x1) 
    Signature Algorithm: sha1WithRSAEncryption 
     Issuer: C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root 
     Validity 
      Not Before: May 30 10:48:38 2000 GMT 
      Not After : May 30 10:48:38 2020 GMT 
     Subject: C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root 
     Subject Public Key Info: 
      Public Key Algorithm: rsaEncryption 
       Public-Key: (2048 bit) 
       Modulus: 
        00:b7:f7:1a:33:e6:f2:00:04:2d:39:e0:4e:5b:ed: 
        1f:bc:6c:0f:cd:b5:fa:23:b6:ce:de:9b:11:33:97: 
        a4:29:4c:7d:93:9f:bd:4a:bc:93:ed:03:1a:e3:8f: 
        cf:e5:6d:50:5a:d6:97:29:94:5a:80:b0:49:7a:db: 
        2e:95:fd:b8:ca:bf:37:38:2d:1e:3e:91:41:ad:70: 
        56:c7:f0:4f:3f:e8:32:9e:74:ca:c8:90:54:e9:c6: 
        5f:0f:78:9d:9a:40:3c:0e:ac:61:aa:5e:14:8f:9e: 
        87:a1:6a:50:dc:d7:9a:4e:af:05:b3:a6:71:94:9c: 
        71:b3:50:60:0a:c7:13:9d:38:07:86:02:a8:e9:a8: 
        69:26:18:90:ab:4c:b0:4f:23:ab:3a:4f:84:d8:df: 
        ce:9f:e1:69:6f:bb:d7:42:d7:6b:44:e4:c7:ad:ee: 
        6d:41:5f:72:5a:71:08:37:b3:79:65:a4:59:a0:94: 
        37:f7:00:2f:0d:c2:92:72:da:d0:38:72:db:14:a8: 
        45:c4:5d:2a:7d:b7:b4:d6:c4:ee:ac:cd:13:44:b7: 
        c9:2b:dd:43:00:25:fa:61:b9:69:6a:58:23:11:b7: 
        a7:33:8f:56:75:59:f5:cd:29:d7:46:b7:0a:2b:65: 
        b6:d3:42:6f:15:b2:b8:7b:fb:ef:e9:5d:53:d5:34: 
        5a:27 
       Exponent: 65537 (0x10001) 
     X509v3 extensions: 
      X509v3 Subject Key Identifier: 
       AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A 
      X509v3 Key Usage: 
       Certificate Sign, CRL Sign 
      X509v3 Basic Constraints: critical 
       CA:TRUE 
      X509v3 Authority Key Identifier: 
       keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A 
       DirName:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root 
       serial:01 

    Signature Algorithm: sha1WithRSAEncryption 
     b0:9b:e0:85:25:c2:d6:23:e2:0f:96:06:92:9d:41:98:9c:d9: 
     84:79:81:d9:1e:5b:14:07:23:36:65:8f:b0:d8:77:bb:ac:41: 
     6c:47:60:83:51:b0:f9:32:3d:e7:fc:f6:26:13:c7:80:16:a5: 
     bf:5a:fc:87:cf:78:79:89:21:9a:e2:4c:07:0a:86:35:bc:f2: 
     de:51:c4:d2:96:b7:dc:7e:4e:ee:70:fd:1c:39:eb:0c:02:51: 
     14:2d:8e:bd:16:e0:c1:df:46:75:e7:24:ad:ec:f4:42:b4:85: 
     93:70:10:67:ba:9d:06:35:4a:18:d3:2b:7a:cc:51:42:a1:7a: 
     63:d1:e6:bb:a1:c5:2b:c2:36:be:13:0d:e6:bd:63:7e:79:7b: 
     a7:09:0d:40:ab:6a:dd:8f:8a:c3:f6:f6:8c:1a:42:05:51:d4: 
     45:f5:9f:a7:62:21:68:15:20:43:3c:99:e7:7c:bd:24:d8:a9: 
     91:17:73:88:3f:56:1b:31:38:18:b4:71:0f:9a:cd:c8:0e:9e: 
     8e:2e:1b:e1:8c:98:83:cb:1f:31:f1:44:4c:c6:04:73:49:76: 
     60:0f:c7:f8:bd:17:80:6b:2e:e9:cc:4c:0e:5a:9a:79:0f:20: 
     0a:2e:d5:9e:63:26:1e:55:92:94:d8:82:17:5a:7b:d0:bc:c7: 
     8f:4e:86:04 
+0

Спасибо, я не знаю, почему я использовал этот CA m ( Я исправил эту проблему, но я все еще получаю ошибку 20 как раньше. –

+0

Я дважды проверил его, и да, я поступил по вашему совету и загрузил CA и использовал его точно так же, как вы его там, но по какой-то причине SSL_get_verify_result по-прежнему возвращает 20. –

+0

Хорошо. : http://pastebin.com/2sspScj8 Насколько я знаю, этого кода достаточно, чтобы установить соединение и проверить сертификат однорангового узла. –

 Смежные вопросы

  • Нет связанных вопросов^_^