示例#1
0
    def _pick_certificate_cb(self, connection: SSL.Connection) -> None:
        """SNI certificate callback.

        This method will set a new OpenSSL context object for this
        connection when an incoming connection provides an SNI name
        (in order to serve the appropriate certificate, if any).

        :param connection: The TLS connection object on which the SNI
            extension was received.
        :type connection: :class:`OpenSSL.Connection`

        """
        pair = self.cert_selection(connection)
        if pair is None:
            logger.debug(
                "Certificate selection for server name %s failed, dropping SSL",
                connection.get_servername())
            return
        key, cert = pair
        new_context = SSL.Context(self.method)
        new_context.set_options(SSL.OP_NO_SSLv2)
        new_context.set_options(SSL.OP_NO_SSLv3)
        new_context.use_privatekey(key)
        new_context.use_certificate(cert)
        if self.alpn_selection is not None:
            new_context.set_alpn_select_callback(self.alpn_selection)
        connection.set_context(new_context)
示例#2
0
 def __call__(
     self, connection: SSL.Connection
 ) -> Optional[Tuple[crypto.PKey, crypto.X509]]:
     server_name = connection.get_servername()
     if server_name:
         return self.certs.get(server_name, None)
     return None  # pragma: no cover
示例#3
0
 def _cert_selection(
     self, connection: SSL.Connection
 ) -> Optional[Tuple[crypto.PKey, crypto.X509]]:  # pragma: no cover
     """Callback selecting certificate for connection."""
     server_name = connection.get_servername()
     if server_name:
         return self.certs.get(server_name, None)
     return None
示例#4
0
 def _cert_selection(self, connection: SSL.Connection) -> Tuple[crypto.PKey, crypto.X509]:
     # TODO: We would like to serve challenge cert only if asked for it via
     # ALPN. To do this, we need to retrieve the list of protos from client
     # hello, but this is currently impossible with openssl [0], and ALPN
     # negotiation is done after cert selection.
     # Therefore, currently we always return challenge cert, and terminate
     # handshake in alpn_selection() if ALPN protos are not what we expect.
     # [0] https://github.com/openssl/openssl/issues/4952
     server_name = connection.get_servername()
     logger.debug("Serving challenge cert for server name %s", server_name)
     return self.challenge_certs[server_name]
示例#5
0
def main():
    """
    Connect to an SNI-enabled server and request a specific hostname, specified by argv[1], of it.
    """
    if len(argv) < 2:
        print 'Usage: %s <hostname> [port]' % (argv[0], )
        return 1

    port = 443
    if len(argv) == 3:
        port = int(argv[2])

    hostname = argv[1]
    client = socket()
    #client.settimeout(2)

    #print 'Connecting...',
    stdout.flush()
    client.connect((hostname, port))
    #print 'connected', client.getpeername()

    client_ssl = Connection(Context(TLSv1_METHOD), client)
    client_ssl.set_connect_state()
    client_ssl.set_tlsext_host_name(hostname)
    client_ssl.do_handshake()

    host = client_ssl.getpeername()
    servername = client_ssl.get_servername()
    x509 = client_ssl.get_peer_certificate()
    notAfter = datetime.strptime(x509.get_notAfter(), '%Y%m%d%H%M%SZ')
    cert_chain = client_ssl.get_peer_cert_chain()

    now = datetime.now()
    timedelta = notAfter - now

    DNS = ''
    for i in xrange(x509.get_extension_count()):
        ret = str(x509.get_extension(i))
        if re.match('^DNS:', ret):
            DNS = ret.replace('DNS:', '')

    print "servername: %s, host: %s, port: %s" % (servername, host[0], host[1])
    print "\tnotAfter: %s, remain: %s days" % (notAfter, timedelta.days)
    print "\tDNS: ", DNS
    print '\tCert Chain:'

    for i, v in enumerate(cert_chain):
        print '\t%s,i,%s' % (i, v.get_subject())
        print '\t%s,s,%s' % (i, v.get_issuer())

    client_ssl.close()