def test_ssl(self): """ When passed an SSL strports description, L{clientFromString} returns a L{SSL4ClientEndpoint} instance initialized with the values from the string. """ reactor = object() client = endpoints.clientFromString( reactor, "ssl:host=example.net:port=4321:privateKey=%s:" "certKey=%s:bindAddress=10.0.0.3:timeout=3:caCertsDir=%s" % (escapedPEMPathName, escapedPEMPathName, escapedCAsPathName)) self.assertIsInstance(client, endpoints.SSL4ClientEndpoint) self.assertIdentical(client._reactor, reactor) self.assertEquals(client._host, "example.net") self.assertEquals(client._port, 4321) self.assertEquals(client._timeout, 3) self.assertEquals(client._bindAddress, "10.0.0.3") certOptions = client._sslContextFactory self.assertIsInstance(certOptions, CertificateOptions) ctx = certOptions.getContext() self.assertIsInstance(ctx, ContextType) self.assertEquals(Certificate(certOptions.certificate), testCertificate) privateCert = PrivateCertificate(certOptions.certificate) privateCert._setPrivateKey(KeyPair(certOptions.privateKey)) self.assertEquals(privateCert, testPrivateCertificate) expectedCerts = [ Certificate.loadPEM(x.getContent()) for x in [casPath.child("thing1.pem"), casPath.child("thing2.pem")] if x.basename().lower().endswith('.pem') ] self.assertEquals([Certificate(x) for x in certOptions.caCerts], expectedCerts)
def _identityVerifyingInfoCallback(self, connection, where, ret): """ Override the base implementation to provide better hostname verification. @param connection: the connection which is handshaking. @type connection: L{OpenSSL.SSL.Connection} @param where: flags indicating progress through a TLS handshake. @type where: L{int} @param ret: ignored @type ret: ignored """ if where & SSL_CB_HANDSHAKE_START: _maybeSetHostNameIndication(connection, self._hostnameBytes) elif where & SSL_CB_HANDSHAKE_DONE: if self._ctx.get_verify_mode() != SSL.VERIFY_NONE: try: peer_cert = Certificate(connection.get_peer_certificate()) _matchHostname(peer_cert, self._hostname) except CertMatchError as ex: log.error(str(ex)) f = Failure() transport = connection.get_app_data() transport.failVerification(f)
def _handlePairing(self, packet): self._cancelTimeout() if packet.get("pair") is True: if self.status == InternalStatus.REQUESTED: info("Pair answer") certificate = Certificate(self.transport.getPeerCertificate()).dumpPEM() self.status = InternalStatus.PAIRED if self.isTrusted(): self.factory.database.updateDevice(self.identifier, self.name, self.device) else: self.factory.database.pairDevice(self.identifier, certificate, self.name, self.device) else: info("Pair request") pair = Packet.createPair(False) if self.status == InternalStatus.PAIRED or self.isTrusted(): info("I'm already paired, but they think I'm not") self.factory.database.updateDevice(self.identifier, self.name, self.device) pair.set("pair", True) else: info("Pairing started by the other end, rejecting their request") self._sendPacket(pair) else: info("Unpair request") if self.status == InternalStatus.REQUESTED: info("Canceled by other peer") self.status = InternalStatus.NOT_PAIRED self.factory.database.unpairDevice(self.identifier)
def create_certificate_authority(keypair, dn, request, serial, validity_period, digest, start=None): """ Sign a CertificateRequest with extensions for use as a CA certificate. See https://www.openssl.org/docs/apps/x509v3_config.html#Basic-Constraints for further information. This code based on ``twisted.internet.ssl.KeyPair.signRequestObject`` :param KeyPair keypair: The private/public key pair. :param DistinguishedName dn: The ``DistinguishedName`` for the certificate. :param CertificateRequest request: The signing request object. :param int serial: The certificate serial number. :param int validity_period: The number of seconds from ``start`` after which the certificate expires. :param bytes digest: The digest algorithm to use. :param datetime start: The datetime from which the certificate is valid. Defaults to current date and time. """ if start is None: start = datetime.datetime.utcnow() expire = start + datetime.timedelta(seconds=validity_period) start = start.strftime(b"%Y%m%d%H%M%SZ") expire = expire.strftime(b"%Y%m%d%H%M%SZ") req = request.original cert = crypto.X509() cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.set_notBefore(start) cert.set_notAfter(expire) cert.set_serial_number(serial) cert.add_extensions([ crypto.X509Extension("basicConstraints", True, "CA:TRUE, pathlen:0"), crypto.X509Extension("keyUsage", True, "keyCertSign, cRLSign"), crypto.X509Extension("subjectKeyIdentifier", False, "hash", subject=cert), ]) cert.add_extensions([ crypto.X509Extension( "authorityKeyIdentifier", False, "keyid:always", issuer=cert ) ]) cert.set_issuer(cert.get_subject()) cert.sign(keypair.original, digest) return Certificate(cert)
def settings_acknowledged(self, event: SettingsAcknowledged) -> None: self.metadata['settings_acknowledged'] = True # Send off all the pending requests as now we have # established a proper HTTP/2 connection self._send_pending_requests() # Update certificate when our HTTP/2 connection is established self.metadata['certificate'] = Certificate(self.transport.getPeerCertificate())
def sign_certificate_request(keypair, dn, request, serial, validity_period, digest, start=None, additional_extensions=()): """ Sign a CertificateRequest and return a Certificate. This code based on ``twisted.internet.ssl.KeyPair.signRequestObject`` :param KeyPair keypair: The private/public key pair. :param X509Name dn: The distinguished name for the certificate. :param CertificateRequest request: The signing request object. :param int serial: The certificate serial number. :param int validity_period: The number of seconds from ``start`` after which the certificate expires. :param bytes digest: The digest algorithm to use. :param datetime start: The datetime from which the certificate is valid. Defaults to current date and time. :param additional_extensions: A sequence of additional ``X509Extension`` objects to add to the certificate. """ if start is None: start = datetime.datetime.utcnow() expire = start + datetime.timedelta(seconds=validity_period) start = start.strftime(b"%Y%m%d%H%M%SZ") expire = expire.strftime(b"%Y%m%d%H%M%SZ") req = request.original cert = crypto.X509() cert.set_issuer(dn) cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.set_notBefore(start) cert.set_notAfter(expire) cert.set_serial_number(serial) cert.add_extensions(additional_extensions) cert.sign(keypair.original, digest) return Certificate(cert)
def test_unreadableCertificate(self): """ If a certificate in the directory is unreadable, L{endpoints._loadCAsFromDir} will ignore that certificate. """ class UnreadableFilePath(FilePath): def getContent(self): data = FilePath.getContent(self) # There is a duplicate of thing2.pem, so ignore anything that # looks like it. if data == casPath.child("thing2.pem").getContent(): raise IOError(EPERM) else: return data casPathClone = casPath.child("ignored").parent() casPathClone.clonePath = UnreadableFilePath self.assertEqual( [Certificate(x) for x in endpoints._loadCAsFromDir(casPathClone)], [Certificate.loadPEM(casPath.child("thing1.pem").getContent())])
def sign_ca_cert(key, requestObject, dn): from OpenSSL.crypto import X509, X509Extension from twisted.internet.ssl import Certificate req = requestObject.original cert = X509() dn._copyInto(cert.get_issuer()) cert.set_subject(req.get_subject()) cert.set_pubkey(req.get_pubkey()) cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notAfter(60 * 60) cert.set_serial_number(1) cert.add_extensions([ X509Extension(b"basicConstraints", True, b"CA:TRUE"), # Not necessarily a good way to populate subjectAltName but it # quiets the deprecation warning we get from service_identity. X509Extension(b"subjectAltName", True, b"DNS:" + dn.commonName), ]) cert.sign(key.original, "sha256") return Certificate(cert)
def get_certificate_options(self) -> CertificateOptions: """ Return certificate options With certificate generated and signed with peer private key """ certificate = self.get_certificate() openssl_certificate = X509.from_cryptography(certificate) openssl_pkey = PKey.from_cryptography_key(self.private_key) with open(settings.CA_FILEPATH, 'rb') as f: ca = x509.load_pem_x509_certificate(data=f.read(), backend=default_backend()) openssl_ca = X509.from_cryptography(ca) ca_cert = Certificate(openssl_ca) trust_root = trustRootFromCertificates([ca_cert]) # We should not use a ContextFactory # https://twistedmatrix.com/documents/19.7.0/api/twisted.protocols.tls.TLSMemoryBIOFactory.html certificate_options = CertificateOptions( privateKey=openssl_pkey, certificate=openssl_certificate, trustRoot=trust_root, raiseMinimumTo=TLSVersion.TLSv1_3) return certificate_options
def dataReceived(self, data): certificate = Certificate(self.transport.getPeerCertificate()) print("OK:", certificate) self.transport.abortConnection()