def cacheContext(self): # Unfortunate code duplication. ctx = SSLContext(self.sslmethod) # Always disable SSLv2/SSLv3/Compression ctx.set_options(OP_NO_SSLv2) ctx.set_options(OP_NO_SSLv3) ctx.set_options(_OP_NO_COMPRESSION) if self.ciphers is not None: ctx.set_cipher_list(self.ciphers) ctx.set_options(OP_CIPHER_SERVER_PREFERENCE) if self.passwdCallback is not None: ctx.set_passwd_cb(self.passwdCallback) if self.keychainIdentity and hasattr(ctx, "use_keychain_identity"): ctx.use_keychain_identity(self.keychainIdentity) else: if self.certificateFileName: ctx.use_certificate_file(self.certificateFileName) if self.privateKeyFileName: ctx.use_privatekey_file(self.privateKeyFileName) if self.certificateChainFile: ctx.use_certificate_chain_file(self.certificateChainFile) verifyFlags = VERIFY_NONE if self.verifyClient: verifyFlags = VERIFY_PEER if self.requireClientCertificate: verifyFlags |= VERIFY_FAIL_IF_NO_PEER_CERT if self.verifyClientOnce: verifyFlags |= VERIFY_CLIENT_ONCE if self.clientCACertFileNames: store = ctx.get_cert_store() for cert in self.clientCACertFileNames: with open(cert) as f: certpem = f.read() cert = Certificate.loadPEM(certpem) store.add_cert(cert.original) if self.sendCAsToClient: ctx.add_client_ca(cert.original) # When a client certificate is used we also need to set a session context id # to avoid openssl SSL_F_SSL_GET_PREV_SESSION,SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED # errors ctx.set_session_id(str(uuid.uuid4()).replace("-", "")) # It'd be nice if pyOpenSSL let us pass None here for this behavior (as # the underlying OpenSSL API call allows NULL to be passed). It # doesn't, so we'll supply a function which does the same thing. def _verifyCallback(conn, cert, errno, depth, preverify_ok): return preverify_ok ctx.set_verify(verifyFlags, _verifyCallback) if self.verifyClientDepth is not None: ctx.set_verify_depth(self.verifyClientDepth) self._context = ctx
def test_set_default_verify_paths(self): """ L{Context.set_default_verify_paths} causes the platform-specific CA certificate locations to be used for verification purposes. """ # Testing this requires a server with a certificate signed by one of # the CAs in the platform CA location. Getting one of those costs # money. Fortunately (or unfortunately, depending on your # perspective), it's easy to think of a public server on the # internet which has such a certificate. Connecting to the network # in a unit test is bad, but it's the only way I can think of to # really test this. -exarkun # Arg, verisign.com doesn't speak TLSv1 context = Context(SSLv3_METHOD) context.set_default_verify_paths() context.set_verify( VERIFY_PEER, lambda conn, cert, errno, depth, preverify_ok: preverify_ok) client = socket() client.connect(('verisign.com', 443)) clientSSL = Connection(context, client) clientSSL.set_connect_state() clientSSL.do_handshake() clientSSL.send('GET / HTTP/1.0\r\n\r\n') self.assertTrue(clientSSL.recv(1024))
def getContext(self): ctx = Context(SSLv23_METHOD) ctx.load_verify_locations(ca_certs_pem, '/etc/ssl/certs') ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verifyCertificate) ctx.set_options(OP_NO_SSLv2) if self.hostname: ctx.set_info_callback(self.handshake_callback) return ctx
def getServerContext(self): """ Generate a new L{OpenSSL.SSL.Context} object configured to use a certificate signed by C{self.ca} and only accept connections from peers which are also using a certificate signed by C{self.ca}. """ # Generate a new key for the server and have the CA sign a certificate # for it. key = KeyPair.generate(size=512) req = key.certificateRequest(DN(commonName='localhost')) certData = self.ca.signCertificateRequest(req, lambda dn: True, 1) cert = PrivateCertificate.load(certData, key) # Use the new key/certificate context = Context(TLSv1_METHOD) context.use_privatekey(key.original) context.use_certificate(cert.original) context.check_privatekey() # Allow peer certificates signed by the CA store = context.get_cert_store() store.add_cert(self.ca.original) # Verify the peer certificate and require that they have one. def verify(conn, cert, errno, depth, preverify_ok): return preverify_ok context.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify) return context
def getContext(self): ctx = Context(TLSv1_METHOD) store = ctx.get_cert_store() for value in certificateAuthorityMap.values(): store.add_cert(value) ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verifyHostname) ctx.set_options(OP_NO_SSLv2) return ctx
def getContext(self): ctx = Context(TLSv1_METHOD) store = ctx.get_cert_store() store.add_cert(self.cert) ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verifyHostname) ctx.set_options(OP_NO_SSLv2) return ctx
def getContext(self): ctx = Context(TLSv1_METHOD) store = ctx.get_cert_store() for value in certificateAuthorityMap.values(): store.add_cert(value) ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verify) ctx.set_options(OP_NO_SSLv2) return ctx
def getContext(self, hostname=None, port=None): ''' Returns a context pre-populated with x509 decoded root certs to validate against. ''' context = Context(TLSv1_METHOD) store = context.get_cert_store() for cert in self.root_certs: store.add_cert(cert) context.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.check_cn) context.set_options(OP_NO_SSLv2) return context
def __init__(self, server_address, HandlerClass, bind_and_activate=True): socketserver.TCPServer.__init__(self, server_address, HandlerClass) ctx = Context(TLSv1_2_METHOD) ctx.use_privatekey_file (settings.ssl_key_path) ctx.use_certificate_file(settings.ssl_cert_path) # only allow clients with cert: ctx.set_verify(VERIFY_PEER | VERIFY_CLIENT_ONCE | VERIFY_FAIL_IF_NO_PEER_CERT, self._accept) #ctx.set_verify(VERIFY_PEER | VERIFY_CLIENT_ONCE, self._accept) self.socket = Connection(ctx, socket.socket(self.address_family, self.socket_type)) if bind_and_activate: self.server_bind() self.server_activate()
def verify_cert(host, ca, timeout): server_ctx = Context(TLSv1_METHOD) server_cert_chain = [] if os.path.isdir(ca): server_ctx.load_verify_locations(None, ca) else: server_ctx.load_verify_locations(ca, None) def verify_cb(conn, cert, errnum, depth, ok): server_cert_chain.append(cert) return ok server_ctx.set_verify(VERIFY_PEER, verify_cb) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(1) sock.settimeout(timeout) sock.connect((host, 443)) server_conn = Connection(server_ctx, sock) server_conn.set_connect_state() def iosock_try(): ok = True try: server_conn.do_handshake() sleep(0.5) except SSLWantReadError as e: ok = False pass except Exception as e: raise e return ok try: while True: if iosock_try(): break server_subject = server_cert_chain[-1].get_subject() if host != server_subject.CN: raise SSLError('Server certificate CN does not match %s' % host) except SSLError as e: raise e finally: server_conn.shutdown() server_conn.close() return True
def server_ok(serverarg, capath, timeout): "Check if the server is active and responsive" server_ctx = Context(TLSv1_METHOD) server_ctx.load_verify_locations(None, capath) def verify_cb(conn, cert, errnum, depth, ok): return ok server_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) serverarg = re.split("/*", serverarg)[1] if ':' in serverarg: serverarg = serverarg.split(':') server = serverarg[0] port = int(serverarg[1] if not '?' in serverarg[1] else serverarg[1].split('?')[0]) else: server = serverarg port = DEFAULT_PORT try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((server, port)) server_conn = Connection(server_ctx, sock) server_conn.set_connect_state() try: def handler(signum, frame): raise socket.error([('Timeout', 'after', str(timeout) + 's')]) signal.signal(signal.SIGALRM, handler) signal.alarm(timeout) server_conn.do_handshake() signal.alarm(0) except socket.timeout as e: nagios_out('Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e)),2) server_conn.shutdown() server_conn.close() except (SSLError, socket.error) as e: if 'sslv3 alert handshake failure' in errmsg_from_excp(e): pass else: nagios_out('Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e)), 2) return True
def getContext(self): """Create an SSL context. This is a sample implementation that loads a certificate from a file called 'server.pem'.""" ctx = SSL_Context(SSLv23_METHOD) ctx.use_certificate_file(self.certificateFileName) ctx.use_privatekey_file(self.privateKeyFileName) ctx.load_client_ca(self.certificateChainFile) ctx.load_verify_locations(self.certificateChainFile) ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT, self._verify) ctx.set_verify_depth(10) return ctx
def server_ok(serverarg, capath, timeout): server_ctx = Context(TLSv1_METHOD) server_ctx.load_verify_locations(None, capath) def verify_cb(conn, cert, errnum, depth, ok): return ok server_ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) serverarg = re.split("/*", serverarg)[1] if ':' in serverarg: serverarg = serverarg.split(':') server = serverarg[0] port = int(serverarg[1] if not '?' in serverarg[1] else serverarg[1]. split('?')[0]) else: server = serverarg port = DEFAULT_PORT try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((server, port)) server_conn = Connection(server_ctx, sock) server_conn.set_connect_state() try: def handler(signum, frame): raise socket.error([('Timeout', 'after', str(timeout) + 's')]) signal.signal(signal.SIGALRM, handler) signal.alarm(timeout) server_conn.do_handshake() signal.alarm(0) except socket.timeout as e: nagios_out( 'Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e)), 2) server_conn.shutdown() server_conn.close() except (SSLError, socket.error) as e: if 'sslv3 alert handshake failure' in errmsg_from_excp(e): pass else: nagios_out( 'Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e)), 2) return True
def __init__(self, server_address, HandlerClass, bind_and_activate=True): socketserver.TCPServer.__init__(self, server_address, HandlerClass) ctx = Context(TLSv1_2_METHOD) ctx.use_privatekey_file(settings.ssl_key_path) ctx.use_certificate_file(settings.ssl_cert_path) # only allow clients with cert: ctx.set_verify( VERIFY_PEER | VERIFY_CLIENT_ONCE | VERIFY_FAIL_IF_NO_PEER_CERT, self._accept) #ctx.set_verify(VERIFY_PEER | VERIFY_CLIENT_ONCE, self._accept) self.socket = Connection( ctx, socket.socket(self.address_family, self.socket_type)) if bind_and_activate: self.server_bind() self.server_activate()
def getContext(self): ctx = Context(TLSv1_METHOD) store = ctx.get_cert_store() data = open("ssl-keys/ca.crt").read() x509 = load_certificate(FILETYPE_PEM, data) store.add_cert(x509) ctx.use_privatekey_file('ssl-keys/server.key.insecure', FILETYPE_PEM) ctx.use_certificate_file('ssl-keys/server.crt', FILETYPE_PEM) # throws an error if private and public key not match ctx.check_privatekey() ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verifyHostname) ctx.set_options(OP_NO_SSLv3) return ctx
def verify_servercert(host, timeout, capath): server_ctx = Context(TLSv1_METHOD) server_ctx.load_verify_locations(None, capath) server_cert_chain = [] def verify_cb(conn, cert, errnum, depth, ok): server_cert_chain.append(cert) return ok server_ctx.set_verify(VERIFY_PEER, verify_cb) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(1) sock.settimeout(timeout) sock.connect((host, 443)) server_conn = Connection(server_ctx, sock) server_conn.set_connect_state() def iosock_try(): ok = True try: server_conn.do_handshake() sleep(0.5) except SSLWantReadError as e: ok = False pass except Exception as e: raise e return ok try: while True: if iosock_try(): break global server_expire server_expire = server_cert_chain[-1].get_notAfter() except PyOpenSSLError as e: raise e finally: server_conn.shutdown() server_conn.close() return True
def _load_verify_locations_test(self, *args): port = socket() port.bind(('', 0)) port.listen(1) client = socket() client.setblocking(False) client.connect_ex(port.getsockname()) clientContext = Context(TLSv1_METHOD) clientContext.load_verify_locations(*args) # Require that the server certificate verify properly or the # connection will fail. clientContext.set_verify( VERIFY_PEER, lambda conn, cert, errno, depth, preverify_ok: preverify_ok) clientSSL = Connection(clientContext, client) clientSSL.set_connect_state() server, _ = port.accept() server.setblocking(False) serverContext = Context(TLSv1_METHOD) serverContext.use_certificate( load_certificate(FILETYPE_PEM, cleartextCertificatePEM)) serverContext.use_privatekey( load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)) serverSSL = Connection(serverContext, server) serverSSL.set_accept_state() for i in range(3): for ssl in clientSSL, serverSSL: try: # Without load_verify_locations above, the handshake # will fail: # Error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', # 'certificate verify failed')] ssl.do_handshake() except WantReadError: pass cert = clientSSL.get_peer_certificate() self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
def _client(self, sock): """ Create a new client-side SSL L{Connection} object wrapped around C{sock}. """ # Now create the client side Connection. Similar boilerplate to the # above. client_ctx = Context(TLSv1_METHOD) client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE ) client_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb) client_store = client_ctx.get_cert_store() client_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, client_key_pem)) client_ctx.use_certificate(load_certificate(FILETYPE_PEM, client_cert_pem)) client_ctx.check_privatekey() client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem)) client_conn = Connection(client_ctx, sock) client_conn.set_connect_state() return client_conn
def getContext(self): """Creates a context. This will make contexts using ``SSLv23_METHOD``. This is because OpenSSL thought it would be a good idea to have ``TLSv1_METHOD`` mean "only use TLSv1.0" -- specifically, it disables TLSv1.2. Since we don't want to use SSLv2 and v3, we set OP_NO_SSLv2|OP_NO_SSLv3. Additionally, we set OP_SINGLE_DH_USE. """ ctx = Context(SSLv23_METHOD) ctx.use_certificate_file("cert.pem") ctx.use_privatekey_file("key.pem") ctx.load_tmp_dh("dhparam.pem") ctx.set_options(OP_SINGLE_DH_USE|OP_NO_SSLv2|OP_NO_SSLv3) ctx.set_verify(VERIFY_PEER, self._verify) return ctx
def _server(self, sock): """ Create a new server-side SSL L{Connection} object wrapped around C{sock}. """ # Create the server side Connection. This is mostly setup boilerplate # - use TLSv1, use a particular certificate, etc. server_ctx = Context(TLSv1_METHOD) server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE ) server_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb) server_store = server_ctx.get_cert_store() server_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem)) server_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem)) server_ctx.check_privatekey() server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem)) # Here the Connection is actually created. If None is passed as the 2nd # parameter, it indicates a memory BIO should be created. server_conn = Connection(server_ctx, sock) server_conn.set_accept_state() return server_conn
def go(): port = socket() port.bind(('', 0)) port.listen(1) called = [] def info(*args): print count.next() called.append(None) return 1 context = Context(TLSv1_METHOD) context.set_verify(VERIFY_PEER, info) context.use_certificate( load_certificate(FILETYPE_PEM, cleartextCertificatePEM)) context.use_privatekey( load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)) while 1: client = socket() client.setblocking(False) client.connect_ex(port.getsockname()) clientSSL = Connection(context, client) clientSSL.set_connect_state() server, ignored = port.accept() server.setblocking(False) serverSSL = Connection(context, server) serverSSL.set_accept_state() del called[:] while not called: for ssl in clientSSL, serverSSL: try: ssl.send('foo') except WantReadError, e: pass
def _client(self, sock): """ Create a new client-side SSL L{Connection} object wrapped around C{sock}. """ # Now create the client side Connection. Similar boilerplate to the # above. client_ctx = Context(TLSv1_METHOD) client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE) client_ctx.set_verify( VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT | VERIFY_CLIENT_ONCE, verify_cb) client_store = client_ctx.get_cert_store() client_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, client_key_pem)) client_ctx.use_certificate( load_certificate(FILETYPE_PEM, client_cert_pem)) client_ctx.check_privatekey() client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem)) client_conn = Connection(client_ctx, sock) client_conn.set_connect_state() return client_conn
def _server(self, sock): """ Create a new server-side SSL L{Connection} object wrapped around C{sock}. """ # Create the server side Connection. This is mostly setup boilerplate # - use TLSv1, use a particular certificate, etc. server_ctx = Context(TLSv1_METHOD) server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE) server_ctx.set_verify( VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT | VERIFY_CLIENT_ONCE, verify_cb) server_store = server_ctx.get_cert_store() server_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem)) server_ctx.use_certificate( load_certificate(FILETYPE_PEM, server_cert_pem)) server_ctx.check_privatekey() server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem)) # Here the Connection is actually created. If None is passed as the 2nd # parameter, it indicates a memory BIO should be created. server_conn = Connection(server_ctx, sock) server_conn.set_accept_state() return server_conn
def _load_verify_locations_test(self, *args): (server, client) = socket_pair() clientContext = Context(TLSv1_METHOD) clientContext.load_verify_locations(*args) # Require that the server certificate verify properly or the # connection will fail. clientContext.set_verify( VERIFY_PEER, lambda conn, cert, errno, depth, preverify_ok: preverify_ok) clientSSL = Connection(clientContext, client) clientSSL.set_connect_state() serverContext = Context(TLSv1_METHOD) serverContext.use_certificate( load_certificate(FILETYPE_PEM, cleartextCertificatePEM)) serverContext.use_privatekey( load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)) serverSSL = Connection(serverContext, server) serverSSL.set_accept_state() for i in range(3): for ssl in clientSSL, serverSSL: try: # Without load_verify_locations above, the handshake # will fail: # Error: [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', # 'certificate verify failed')] ssl.do_handshake() except WantReadError: pass cert = clientSSL.get_peer_certificate() self.assertEqual(cert.get_subject().CN, 'Testing Root CA')
def getContext(self): ctx = Context(SSLv23_METHOD) ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verifyCertificate) ctx.set_options(OP_NO_SSLv2) return ctx
def verify_cert(host, capath, timeout, cncheck=True): server_ctx = Context(TLSv1_METHOD) server_cert_chain = [] server_ctx.load_verify_locations(None, capath) host = re.split("/*", host)[1] if ':' in host: host = host.split(':') server = host[0] port = int(host[1] if not '?' in host[1] else host[1].split('?')[0]) else: server = host port = 443 def verify_cb(conn, cert, errnum, depth, ok): server_cert_chain.append(cert) return ok server_ctx.set_verify(VERIFY_PEER, verify_cb) try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(1) sock.settimeout(timeout) sock.connect((server, port)) except (socket.error, socket.timeout) as e: nagios_out( 'Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e)), 2) server_conn = Connection(server_ctx, sock) server_conn.set_connect_state() def iosock_try(): ok = True try: server_conn.do_handshake() sleep(0.5) except SSLWantReadError as e: ok = False pass except Exception as e: raise e return ok try: while True: if iosock_try(): break if cncheck: server_subject = server_cert_chain[-1].get_subject() if server != server_subject.CN: nagios_out( 'Critical', 'Server certificate CN %s does not match %s' % (server_subject.CN, server), 2) except SSLError as e: if 'sslv3 alert handshake failure' in errmsg_from_excp(e): pass else: nagios_out( 'Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e, level=1)), 2) finally: server_conn.shutdown() server_conn.close() return True
def verify_cert(host, capath, timeout, cncheck=True): server_ctx = Context(TLSv1_METHOD) server_cert_chain = [] server_ctx.load_verify_locations(None, capath) host = re.split("/*", host)[1] if ':' in host: host = host.split(':') server = host[0] port = int(host[1] if not '?' in host[1] else host[1].split('?')[0]) else: server = host port = 443 def verify_cb(conn, cert, errnum, depth, ok): server_cert_chain.append(cert) return ok server_ctx.set_verify(VERIFY_PEER, verify_cb) try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(1) sock.settimeout(timeout) sock.connect((server, port)) except (socket.error, socket.timeout) as e: nagios_out('Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e)), 2) server_conn = Connection(server_ctx, sock) server_conn.set_connect_state() def iosock_try(): ok = True try: server_conn.do_handshake() sleep(0.5) except SSLWantReadError as e: ok = False pass except Exception as e: raise e return ok try: while True: if iosock_try(): break if cncheck: server_subject = server_cert_chain[-1].get_subject() if server != server_subject.CN: nagios_out('Critical', 'Server certificate CN %s does not match %s' % (server_subject.CN, server), 2) except SSLError as e: if 'sslv3 alert handshake failure' in errmsg_from_excp(e): pass else: nagios_out('Critical', 'Connection error %s - %s' % (server + ':' + str(port), errmsg_from_excp(e, level=1)), 2) finally: server_conn.shutdown() server_conn.close() return True
def getContext(self): ctx = Context(SSLv23_METHOD) ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.fetch) return ctx