Beispiel #1
0
 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)
Beispiel #2
0
    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)
Beispiel #3
0
  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)
Beispiel #4
0
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)
Beispiel #5
0
    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())
Beispiel #6
0
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)
Beispiel #7
0
 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())])
Beispiel #8
0
        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)
Beispiel #9
0
    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
Beispiel #10
0
 def dataReceived(self, data):
     certificate = Certificate(self.transport.getPeerCertificate())
     print("OK:", certificate)
     self.transport.abortConnection()