コード例 #1
0
    def test(self):
        leaf_path = os.path.join(os.path.dirname(__file__), '..', 'utils',
                                 'github.com.pem')
        with open(leaf_path, 'rb') as leaf_file:
            leaf_pem = leaf_file.read()

        certificate = load_pem_x509_certificate(leaf_pem, default_backend())

        self.assertIsNone(
            CertificateUtils.matches_hostname(certificate, 'www.github.com'))
        with self.assertRaises(ssl.CertificateError):
            self.assertFalse(
                CertificateUtils.matches_hostname(certificate,
                                                  'notgithub.com'))

        self.assertEqual(
            CertificateUtils.get_common_names(certificate.subject),
            ['github.com'])
        self.assertEqual(
            CertificateUtils.get_dns_subject_alternative_names(certificate),
            ['github.com', 'www.github.com'])

        self.assertEqual(
            CertificateUtils.get_printable_name(certificate.issuer),
            'DigiCert SHA2 Extended Validation Server CA')
コード例 #2
0
    def _certificate_chain_to_xml(certificate_chain: List[Certificate]) -> List[Element]:
        cert_xml_list = []
        for certificate in certificate_chain:
            cert_xml = Element('certificate', attrib={
                'sha1Fingerprint': binascii.hexlify(certificate.fingerprint(hashes.SHA1())).decode('ascii'),
                'hpkpSha256Pin': CertificateUtils.get_hpkp_pin(certificate)
            })

            # Add the PEM cert
            cert_as_pem_xml = Element('asPEM')
            cert_as_pem_xml.text = certificate.public_bytes(Encoding.PEM).decode('ascii')
            cert_xml.append(cert_as_pem_xml)

            # Add some of the fields of the cert
            elem_xml = Element('subject')
            elem_xml.text = CertificateUtils.get_name_as_text(certificate.subject)
            cert_xml.append(elem_xml)

            elem_xml = Element('issuer')
            elem_xml.text = CertificateUtils.get_name_as_text(certificate.issuer)
            cert_xml.append(elem_xml)

            elem_xml = Element('serialNumber')
            elem_xml.text = str(certificate.serial_number)
            cert_xml.append(elem_xml)

            elem_xml = Element('notBefore')
            elem_xml.text = certificate.not_valid_before.strftime("%Y-%m-%d %H:%M:%S")
            cert_xml.append(elem_xml)

            elem_xml = Element('notAfter')
            elem_xml.text = certificate.not_valid_after.strftime("%Y-%m-%d %H:%M:%S")
            cert_xml.append(elem_xml)

            elem_xml = Element('signatureAlgorithm')
            elem_xml.text = certificate.signature_hash_algorithm.name
            cert_xml.append(elem_xml)

            key_attrs = {'algorithm': CertificateUtils.get_public_key_type(certificate)}
            public_key = certificate.public_key()
            key_attrs['size'] = str(public_key.key_size)
            if isinstance(public_key, EllipticCurvePublicKey):
                key_attrs['curve'] = public_key.curve.name
            else:
                key_attrs['exponent'] = str(public_key.public_numbers().e)

            elem_xml = Element('publicKey', attrib=key_attrs)
            cert_xml.append(elem_xml)

            dns_alt_names = CertificateUtils.get_dns_subject_alternative_names(certificate)
            if dns_alt_names:
                san_xml = Element('subjectAlternativeName')
                for dns_name in dns_alt_names:
                    dns_xml = Element('DNS')
                    dns_xml.text = dns_name
                    san_xml.append(dns_xml)
                cert_xml.append(san_xml)

            cert_xml_list.append(cert_xml)
        return cert_xml_list
コード例 #3
0
    def _get_basic_certificate_text(self) -> List[str]:
        certificate = self.certificate_chain[0]
        public_key = self.certificate_chain[0].public_key()
        text_output = [
            self._format_field('SHA1 Fingerprint:',
                               binascii.hexlify(certificate.fingerprint(hashes.SHA1())).decode('ascii')),
            self._format_field('Common Name:', CertificateUtils.get_name_as_short_text(certificate.subject)),
            self._format_field('Issuer:', CertificateUtils.get_name_as_short_text(certificate.issuer)),
            self._format_field('Serial Number:', certificate.serial_number),
            self._format_field('Not Before:', certificate.not_valid_before),
            self._format_field('Not After:', certificate.not_valid_after),
            self._format_field('Signature Algorithm:', certificate.signature_hash_algorithm.name),
            self._format_field('Public Key Algorithm:', CertificateUtils.get_public_key_type(certificate))]

        if isinstance(public_key, EllipticCurvePublicKey):
            text_output.append(self._format_field('Key Size:', public_key.curve.key_size))
            text_output.append(self._format_field('Curve:', public_key.curve.name))
        elif isinstance(public_key, RSAPublicKey):
            text_output.append(self._format_field('Key Size:', public_key.key_size))
            text_output.append(self._format_field('Exponent:', '{0} (0x{0:x})'.format(public_key.public_numbers().e)))
        else:
            # DSA Key? https://github.com/nabla-c0d3/sslyze/issues/314
            pass

        try:
            # Print the SAN extension if there's one
            text_output.append(self._format_field('DNS Subject Alternative Names:',
                                                  str(CertificateUtils.get_dns_subject_alternative_names(certificate))))
        except KeyError:
            pass

        return text_output
コード例 #4
0
    def _get_basic_certificate_text(self) -> List[str]:
        certificate = self.certificate_chain[0]
        public_key = self.certificate_chain[0].public_key()
        text_output = [
            self._format_field('SHA1 Fingerprint:',
                               binascii.hexlify(certificate.fingerprint(hashes.SHA1())).decode('ascii')),
            self._format_field('Common Name:', CertificateUtils.get_name_as_short_text(certificate.subject)),
            self._format_field('Issuer:', CertificateUtils.get_name_as_short_text(certificate.issuer)),
            self._format_field('Serial Number:', certificate.serial_number),
            self._format_field('Not Before:', certificate.not_valid_before),
            self._format_field('Not After:', certificate.not_valid_after),
            self._format_field('Signature Algorithm:', certificate.signature_hash_algorithm.name),
            self._format_field('Public Key Algorithm:', CertificateUtils.get_public_key_type(certificate))]

        if isinstance(public_key, EllipticCurvePublicKey):
            text_output.append(self._format_field('Key Size:', public_key.curve.key_size))
            text_output.append(self._format_field('Curve:', public_key.curve.name))
        elif isinstance(public_key, RSAPublicKey):
            text_output.append(self._format_field('Key Size:', public_key.key_size))
            text_output.append(self._format_field('Exponent:', '{0} (0x{0:x})'.format(public_key.public_numbers().e)))
        else:
            # DSA Key? https://github.com/nabla-c0d3/sslyze/issues/314
            pass

        try:
            # Print the SAN extension if there's one
            text_output.append(self._format_field('DNS Subject Alternative Names:',
                                                  str(CertificateUtils.get_dns_subject_alternative_names(certificate))))
        except KeyError:
            pass

        return text_output
コード例 #5
0
def _object_to_json_dict(obj):
    """Convert an object to a dictionary suitable for the JSON output.
    """
    if isinstance(obj, Enum):
        # Properly serialize Enums (such as OpenSslVersionEnum)
        result = obj.name
    elif isinstance(obj, x509._Certificate):
        # Properly serialize certificates
        certificate = obj
        result = {
            # Add general info
            'as_pem': obj.public_bytes(Encoding.PEM).decode('ascii'),
            'hpkp_pin': CertificateUtils.get_hpkp_pin(obj),

            # Add some of the fields of the cert
            'subject': CertificateUtils.get_name_as_text(certificate.subject),
            'issuer': CertificateUtils.get_name_as_text(certificate.issuer),
            'serialNumber': str(certificate.serial_number),
            'notBefore':
            certificate.not_valid_before.strftime("%Y-%m-%d %H:%M:%S"),
            'notAfter':
            certificate.not_valid_after.strftime("%Y-%m-%d %H:%M:%S"),
            'signatureAlgorithm': certificate.signature_hash_algorithm.name,
            'publicKey': {
                'algorithm': CertificateUtils.get_public_key_type(certificate)
            },
        }

        dns_alt_names = CertificateUtils.get_dns_subject_alternative_names(
            certificate)
        if dns_alt_names:
            result['subjectAlternativeName'] = {'DNS': dns_alt_names}

        # Add some info about the public key
        public_key = certificate.public_key()
        if isinstance(public_key, EllipticCurvePublicKey):
            result['publicKey']['size'] = str(public_key.curve.key_size)
            result['publicKey']['curve'] = public_key.curve.name
        else:
            result['publicKey']['size'] = str(public_key.key_size)
            result['publicKey']['exponent'] = str(
                public_key.public_numbers().e)

    elif isinstance(obj, object):
        if hasattr(obj, '__dict__'):
            result = {}
            for key, value in obj.__dict__.items():
                # Remove private attributes
                if key.startswith('_'):
                    continue

                result[key] = _object_to_json_dict(value)
        else:
            # Simple object like a string
            result = obj

    else:
        raise TypeError('Unknown type: {}'.format(repr(obj)))

    return result
コード例 #6
0
    def _certificate_chain_to_xml(certificate_chain: List[Certificate]) -> List[Element]:
        cert_xml_list = []
        for certificate in certificate_chain:
            cert_xml = Element('certificate', attrib={
                'sha1Fingerprint': binascii.hexlify(certificate.fingerprint(hashes.SHA1())).decode('ascii'),
                'hpkpSha256Pin': CertificateUtils.get_hpkp_pin(certificate)
            })

            # Add the PEM cert
            cert_as_pem_xml = Element('asPEM')
            cert_as_pem_xml.text = certificate.public_bytes(Encoding.PEM).decode('ascii')
            cert_xml.append(cert_as_pem_xml)

            # Add some of the fields of the cert
            elem_xml = Element('subject')
            elem_xml.text = CertificateUtils.get_name_as_text(certificate.subject)
            cert_xml.append(elem_xml)

            elem_xml = Element('issuer')
            elem_xml.text = CertificateUtils.get_name_as_text(certificate.issuer)
            cert_xml.append(elem_xml)

            elem_xml = Element('serialNumber')
            elem_xml.text = str(certificate.serial_number)
            cert_xml.append(elem_xml)

            elem_xml = Element('notBefore')
            elem_xml.text = certificate.not_valid_before.strftime("%Y-%m-%d %H:%M:%S")
            cert_xml.append(elem_xml)

            elem_xml = Element('notAfter')
            elem_xml.text = certificate.not_valid_after.strftime("%Y-%m-%d %H:%M:%S")
            cert_xml.append(elem_xml)

            elem_xml = Element('signatureAlgorithm')
            elem_xml.text = certificate.signature_hash_algorithm.name
            cert_xml.append(elem_xml)

            key_attrs = {'algorithm': CertificateUtils.get_public_key_type(certificate)}
            public_key = certificate.public_key()
            key_attrs['size'] = str(public_key.key_size)
            if isinstance(public_key, EllipticCurvePublicKey):
                key_attrs['curve'] = public_key.curve.name
            else:
                key_attrs['exponent'] = str(public_key.public_numbers().e)

            elem_xml = Element('publicKey', attrib=key_attrs)
            cert_xml.append(elem_xml)

            dns_alt_names = CertificateUtils.get_dns_subject_alternative_names(certificate)
            if dns_alt_names:
                san_xml = Element('subjectAlternativeName')
                for dns_name in dns_alt_names:
                    dns_xml = Element('DNS')
                    dns_xml.text = dns_name
                    san_xml.append(dns_xml)
                cert_xml.append(san_xml)

            cert_xml_list.append(cert_xml)
        return cert_xml_list
コード例 #7
0
def _object_to_json_dict(obj: Any) -> Union[bool, int, float, str, Dict[str, Any]]:
    """Convert an object to a dictionary suitable for the JSON output.
    """
    if isinstance(obj, Enum):
        # Properly serialize Enums (such as OpenSslVersionEnum)
        result = obj.name

    elif isinstance(obj, x509._Certificate):
        # Properly serialize certificates
        certificate = obj
        result = {  # type: ignore
            # Add general info
            'as_pem': obj.public_bytes(Encoding.PEM).decode('ascii'),
            'hpkp_pin': CertificateUtils.get_hpkp_pin(obj),

            # Add some of the fields of the cert
            'subject': CertificateUtils.get_name_as_text(certificate.subject),
            'issuer': CertificateUtils.get_name_as_text(certificate.issuer),
            'serialNumber': str(certificate.serial_number),
            'notBefore': certificate.not_valid_before.strftime("%Y-%m-%d %H:%M:%S"),
            'notAfter': certificate.not_valid_after.strftime("%Y-%m-%d %H:%M:%S"),
            'signatureAlgorithm': certificate.signature_hash_algorithm.name,
            'publicKey': {
                'algorithm': CertificateUtils.get_public_key_type(certificate)
            },
        }

        dns_alt_names = CertificateUtils.get_dns_subject_alternative_names(certificate)
        if dns_alt_names:
            result['subjectAlternativeName'] = {'DNS': dns_alt_names}  # type: ignore

        # Add some info about the public key
        public_key = certificate.public_key()
        if isinstance(public_key, EllipticCurvePublicKey):
            result['publicKey']['size'] = str(public_key.curve.key_size)  # type: ignore
            result['publicKey']['curve'] = public_key.curve.name  # type: ignore
        else:
            result['publicKey']['size'] = str(public_key.key_size)
            result['publicKey']['exponent'] = str(public_key.public_numbers().e)

    elif isinstance(obj, object):
        # Some objects (like str) don't have a __dict__
        if hasattr(obj, '__dict__'):
            result = {}
            for key, value in obj.__dict__.items():
                # Remove private attributes
                if key.startswith('_'):
                    continue

                result[key] = _object_to_json_dict(value)
        else:
            # Simple object like a bool
            result = obj

    else:
        raise TypeError('Unknown type: {}'.format(repr(obj)))

    return result
コード例 #8
0
    def test(self):
        leaf_path = Path(__file__).absolute().parent / '..' / 'utils' / 'github.com.pem'
        leaf_pem = leaf_path.read_bytes()
        certificate = load_pem_x509_certificate(leaf_pem, default_backend())

        assert CertificateUtils.matches_hostname(certificate, 'www.github.com') is None

        with pytest.raises(ssl.CertificateError):
            assert not CertificateUtils.matches_hostname(certificate, 'notgithub.com')

        assert CertificateUtils.get_common_names(certificate.subject) == ['github.com']
        assert CertificateUtils.get_dns_subject_alternative_names(certificate) == [
            'github.com', 'www.github.com'
        ]

        expected_name = 'DigiCert SHA2 Extended Validation Server CA'
        assert CertificateUtils.get_name_as_short_text(certificate.issuer) == expected_name
コード例 #9
0
    def test(self):
        leaf_path = os.path.join(os.path.dirname(__file__), '..', 'utils', 'github.com.pem')
        with open(leaf_path, 'rb') as leaf_file:
            leaf_pem = leaf_file.read()

        certificate = load_pem_x509_certificate(leaf_pem, default_backend())

        self.assertIsNone(CertificateUtils.matches_hostname(certificate, 'www.github.com'))
        with self.assertRaises(ssl.CertificateError):
            self.assertFalse(CertificateUtils.matches_hostname(certificate, 'notgithub.com'))

        self.assertEqual(CertificateUtils.get_common_names(certificate.subject), ['github.com'])
        self.assertEqual(CertificateUtils.get_dns_subject_alternative_names(certificate), ['github.com',
                                                                                           'www.github.com'])

        self.assertEqual(CertificateUtils.get_name_as_short_text(certificate.issuer),
                         'DigiCert SHA2 Extended Validation Server CA')
コード例 #10
0
    def _get_basic_certificate_text(self):
        certificate = self.certificate_chain[0]
        public_key = self.certificate_chain[0].public_key()
        text_output = [
            self._format_field(
                'SHA1 Fingerprint:',
                binascii.hexlify(certificate.fingerprint(
                    hashes.SHA1())).decode('ascii')),
            self._format_field(
                'Common Name:',
                CertificateUtils.get_printable_name(certificate.subject)),
            self._format_field(
                'Issuer:',
                CertificateUtils.get_printable_name(certificate.issuer)),
            self._format_field('Serial Number:', certificate.serial_number),
            self._format_field('Not Before:', certificate.not_valid_before),
            self._format_field('Not After:', certificate.not_valid_after),
            self._format_field('Signature Algorithm:',
                               certificate.signature_hash_algorithm.name),
            self._format_field('Public Key Algorithm:',
                               public_key.__class__.__name__),
            self._format_field('Key Size:', public_key.key_size)
        ]

        try:
            # Print the Public key exponent if there's one; EC public keys don't have one for example
            text_output.append(
                self._format_field(
                    'Exponent:',
                    '{0} (0x{0:x})'.format(public_key.public_numbers().e)))
        except KeyError:
            pass

        try:
            # Print the SAN extension if there's one
            text_output.append(
                self._format_field(
                    'DNS Subject Alternative Names:',
                    str(
                        CertificateUtils.get_dns_subject_alternative_names(
                            certificate))))
        except KeyError:
            pass

        return text_output
コード例 #11
0
    def test(self):
        leaf_path = Path(
            __file__).absolute().parent / '..' / 'utils' / 'github.com.pem'
        leaf_pem = leaf_path.read_bytes()
        certificate = load_pem_x509_certificate(leaf_pem, default_backend())

        assert CertificateUtils.matches_hostname(certificate,
                                                 'www.github.com') is None

        with pytest.raises(ssl.CertificateError):
            assert not CertificateUtils.matches_hostname(
                certificate, 'notgithub.com')

        assert CertificateUtils.get_common_names(
            certificate.subject) == ['github.com']
        assert CertificateUtils.get_dns_subject_alternative_names(
            certificate) == ['github.com', 'www.github.com']

        expected_name = 'DigiCert SHA2 Extended Validation Server CA'
        assert CertificateUtils.get_name_as_short_text(
            certificate.issuer) == expected_name
コード例 #12
0
ファイル: json_output.py プロジェクト: yunsoul/sslyze
    def default(self,
                obj: Any) -> Union[bool, int, float, str, Dict[str, Any]]:
        result: Union[bool, int, float, str, Dict[str, Any]]

        if isinstance(obj, Enum):
            result = obj.name

        elif isinstance(obj, ObjectIdentifier):
            result = obj.dotted_string

        elif isinstance(obj, x509._Certificate):
            certificate = obj
            result = {
                # Add general info
                "as_pem":
                obj.public_bytes(Encoding.PEM).decode("ascii"),
                "hpkp_pin":
                CertificateUtils.get_hpkp_pin(obj),
                # Add some of the fields of the cert
                "subject":
                CertificateUtils.get_name_as_text(certificate.subject),
                "issuer":
                CertificateUtils.get_name_as_text(certificate.issuer),
                "serialNumber":
                str(certificate.serial_number),
                "notBefore":
                certificate.not_valid_before.strftime("%Y-%m-%d %H:%M:%S"),
                "notAfter":
                certificate.not_valid_after.strftime("%Y-%m-%d %H:%M:%S"),
                "signatureAlgorithm":
                certificate.signature_hash_algorithm.name,
                "publicKey": {
                    "algorithm":
                    CertificateUtils.get_public_key_type(certificate)
                },
            }

            dns_alt_names = CertificateUtils.get_dns_subject_alternative_names(
                certificate)
            if dns_alt_names:
                result["subjectAlternativeName"] = {
                    "DNS": dns_alt_names
                }  # type: ignore

            # Add some info about the public key
            public_key = certificate.public_key()
            if isinstance(public_key, EllipticCurvePublicKey):
                result["publicKey"]["size"] = str(
                    public_key.curve.key_size)  # type: ignore
                result["publicKey"][
                    "curve"] = public_key.curve.name  # type: ignore
            else:
                result["publicKey"]["size"] = str(public_key.key_size)
                result["publicKey"]["exponent"] = str(
                    public_key.public_numbers().e)

        elif isinstance(obj, Path):
            result = str(obj)

        elif isinstance(obj, object):
            # Some objects (like str) don't have a __dict__
            if hasattr(obj, "__dict__"):
                result = {}
                for key, value in obj.__dict__.items():
                    # Remove private attributes
                    if key.startswith("_"):
                        continue

                    result[key] = self.default(value)
            else:
                # Simple object like a bool
                result = obj  # type: ignore

        else:
            raise TypeError("Unknown type: {}".format(repr(obj)))

        return result