有人可以为SSL证书解释这个回调函数吗?

时间:2016-04-12 01:36:31

标签: python-3.x ssl tls1.2 pyopenssl

如果这不是正确的SO(信息安全或加密),我很抱歉。不管怎样,我试图弄清楚如何在Python中验证SSL证书客户端。我找到了一个回调函数here,看起来类似于我在网上看过的其他功能。但是,在我的代码中,我不确定它是如何(或为什么,真的)它的工作原理。它似乎在我运行我的代码时起作用,但为什么(在PyCharm中)前四个参数变灰,只有白色的第五个参数?有没有办法可以使用这个回调函数来检查特定的证书错误?

这是我运行时的输出

Certs are fine
Certs are fine
Certs are fine
b'HTTP/1.1 200 OK\r\nDate: Tue, 12 Apr 2016...etc

我认为" Certs的每一行都很好"验证链中的每个证书?

import socket
from OpenSSL import SSL

HOST = "www.google.com"
PORT = 443

def verify_callback(connection, x509, errnum, errdepth, ok):
        if not ok:
            print("Bad Certs")
        else:
            print("Certs are fine")
        return ok


context = SSL.Context(SSL.TLSv1_2_METHOD)
context.load_verify_locations("cacerts.pem")
context.set_options(SSL.OP_NO_SSLv2)
context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback)


# create socket and connect to server
sock = socket.socket()
sock = SSL.Connection(context, sock)
sock.connect((HOST, PORT))
sock.do_handshake()
sock.sendall("GET / HTTP/1.1\r\n\r\n")

1 个答案:

答案 0 :(得分:0)

pyOpenSSL docs对此非常稀疏,但此函数是相应OpenSSL函数的包装器,其文档为much better

  

verify_callback函数用于控制设置SSL_VERIFY_PEER标志时的行为。它必须由应用程序提供并接收两个参数:preverify_ok表示是否通过了验证(preverify_ok = 1)(preverify_ok = 0)(preverify_ok = 0)。 x509_ctx是指向用于证书链验证的完整上下文的指针。

     

从最深的嵌套级别(根CA证书)开始检查证书链,并向上处理到对等证书。在每个级别检查签名和颁发者属性。每当发现验证错误时,错误号存储在x509_ctx中,并且使用preverify_ok = 0调用verify_callback。通过应用X509_CTX_store_ *函数,verify_callback可以找到有问题的证书并执行其他步骤(请参阅示例)。如果没有找到证书的错误,则在进入下一级别之前使用preverify_ok = 1调用verify_callback。

     

verify_callback的返回值控制进一步验证过程的策略。如果verify_callback返回0,则验证过程立即停止,并且#34;验证失败"州。如果设置了SSL_VERIFY_PEER,则会向对等方发送验证失败警报​​,并终止TLS / SSL握手。如果verify_callback返回1,则继续验证过程。如果verify_callback始终返回1,则不会因验证失败而终止TLS / SSL握手,并且将建立连接。但是,调用进程可以使用SSL_get_verify_result(3)或通过维护由verify_callback管理的自己的错误存储来检索上次验证错误的错误代码。

     

如果未指定verify_callback,则将使用默认回调。它的返回值与preverify_ok相同,因此如果设置了SSL_VERIFY_PEER,任何验证失败都会导致TLS / SSL握手终止并发出警报消息。

文档还有一个解释良好的示例验证函数,用于检查被验证的链是否太长。如果链太长,则记录错误,然后,根据用户设置的值,回调要么返回0以导致验证失败,要么返回1(即忽略错误并验证无论如何)。

此外,this blog post有一个pyOpenSSL示例,它只检查一些特定错误,并在发生时验证失败。