Example #1
0
    def __init__(
        self, server_info, plugin_command, plugin_options, hsts_header, hpkp_header, hpkp_report_only, certificate_chain
    ):
        super(HttpHeadersResult, self).__init__(server_info, plugin_command, plugin_options)
        self.hsts_header = ParsedHstsHeader(hsts_header) if hsts_header else None
        self.hpkp_header = ParsedHpkpHeader(hpkp_header, hpkp_report_only) if hpkp_header else None

        # Hack: use function in CertificateInfoPlugin to get the verified certificate chain so we can check the pins
        self.verified_certificate_chain = None
        parsed_certificate_chain = [Certificate(x509_cert) for x509_cert in certificate_chain]
        if CertInfoFullResult._is_certificate_chain_order_valid(parsed_certificate_chain):
            self.verified_certificate_chain = CertInfoFullResult._build_verified_certificate_chain(
                parsed_certificate_chain
            )

        # Is the pinning configuration valid?
        self.is_valid_pin_configured = None
        self.is_backup_pin_configured = None
        if self.verified_certificate_chain and self.hpkp_header:
            # Is one of the configured pins in the current server chain?
            self.is_valid_pin_configured = False
            server_pin_list = [cert.hpkp_pin for cert in self.verified_certificate_chain]
            for pin in self.hpkp_header.pin_sha256_list:
                if pin in server_pin_list:
                    self.is_valid_pin_configured = True
                    break

            # Is a backup pin configured?
            self.is_backup_pin_configured = set(self.hpkp_header.pin_sha256_list) != set(server_pin_list)
Example #2
0
    def as_text(self):
        txt_result = [self._format_title(u"HTTP Strict Transport Security (HSTS)")]

        if self.hsts_header:
            txt_result.append(self._format_field(u"Max Age:", self.hsts_header.max_age))
            txt_result.append(self._format_field(u"Include Subdomains:", self.hsts_header.include_subdomains))
            txt_result.append(self._format_field(u"Preload:", self.hsts_header.preload))
        else:
            txt_result.append(self._format_field(u"NOT SUPPORTED - Server did not send an HSTS header", u""))

        computed_hpkp_pins_text = ["", self._format_title("Computed HPKP Pins for Current Chain")]
        if self.verified_certificate_chain:
            for index, cert in enumerate(self.verified_certificate_chain, start=0):
                cert_subject = CertInfoFullResult._extract_subject_cn_or_oun(cert)
                if len(cert_subject) > 40:
                    # Make the CN shorter when displaying it
                    cert_subject = "{}...".format(cert_subject[:40])
                computed_hpkp_pins_text.append(
                    self.PIN_TXT_FORMAT(("{} - {}".format(index, cert_subject)), cert.hpkp_pin)
                )
        else:
            computed_hpkp_pins_text.append(self._format_field(CertInfoFullResult.NO_VERIFIED_CHAIN_ERROR_TXT, u""))

        txt_result.extend(["", self._format_title(u"HTTP Public Key Pinning (HPKP)")])
        if self.hpkp_header:
            txt_result.append(self._format_field(u"Max Age:", self.hpkp_header.max_age))
            txt_result.append(self._format_field(u"Include Subdomains:", self.hpkp_header.include_subdomains))
            txt_result.append(self._format_field(u"Report URI:", self.hpkp_header.report_uri))
            txt_result.append(self._format_field(u"Report Only:", self.hpkp_header.report_only))
            txt_result.append(self._format_field(u"SHA-256 Pin List:", ", ".join(self.hpkp_header.pin_sha256_list)))

            if self.verified_certificate_chain:
                pin_validation_txt = (
                    u"OK - One of the configured pins was found in the certificate chain"
                    if self.is_valid_pin_configured
                    else u"FAILED - Could NOT find any of the configured pins in the certificate chain!"
                )
                txt_result.append(self._format_field(u"Valid Pin:", pin_validation_txt))

                backup_txt = (
                    u"OK - Backup pin found in the configured pins"
                    if self.is_backup_pin_configured
                    else u"FAILED - No backup pin found: all the configured pins are in the certificate chain!"
                )
                txt_result.append(self._format_field(u"Backup Pin:", backup_txt))

        else:
            txt_result.append(self._format_field(u"NOT SUPPORTED - Server did not send an HPKP header", u""))

        # Dispay computed HPKP pins last
        txt_result.extend(computed_hpkp_pins_text)

        return txt_result
Example #3
0
    def __init__(self, server_info, plugin_command, plugin_options,
                 hsts_header, hpkp_header, hpkp_report_only,
                 certificate_chain):
        super(HttpHeadersResult, self).__init__(server_info, plugin_command,
                                                plugin_options)
        self.hsts_header = ParsedHstsHeader(
            hsts_header) if hsts_header else None
        self.hpkp_header = ParsedHpkpHeader(
            hpkp_header, hpkp_report_only) if hpkp_header else None

        # Hack: use function in CertificateInfoPlugin to get the verified certificate chain so we can check the pins
        self.verified_certificate_chain = None
        parsed_certificate_chain = [
            Certificate(x509_cert) for x509_cert in certificate_chain
        ]
        if CertInfoFullResult._is_certificate_chain_order_valid(
                parsed_certificate_chain):
            self.verified_certificate_chain = CertInfoFullResult._build_verified_certificate_chain(
                parsed_certificate_chain)

        # Is the pinning configuration valid?
        self.is_valid_pin_configured = None
        self.is_backup_pin_configured = None
        if self.verified_certificate_chain and self.hpkp_header:
            # Is one of the configured pins in the current server chain?
            self.is_valid_pin_configured = False
            server_pin_list = [
                cert.hpkp_pin for cert in self.verified_certificate_chain
            ]
            for pin in self.hpkp_header.pin_sha256_list:
                if pin in server_pin_list:
                    self.is_valid_pin_configured = True
                    break

            # Is a backup pin configured?
            self.is_backup_pin_configured = set(
                self.hpkp_header.pin_sha256_list) != set(server_pin_list)
Example #4
0
    def as_text(self):
        txt_result = [
            self.PLUGIN_TITLE_FORMAT('HTTP Strict Transport Security (HSTS)')
        ]

        if self.hsts_header:
            txt_result.append(
                self.FIELD_FORMAT("Max Age:", self.hsts_header.max_age))
            txt_result.append(
                self.FIELD_FORMAT("Include Subdomains:",
                                  self.hsts_header.include_subdomains))
            txt_result.append(
                self.FIELD_FORMAT("Preload:", self.hsts_header.preload))
        else:
            txt_result.append(
                self.FIELD_FORMAT(
                    "NOT SUPPORTED - Server did not send an HSTS header", ""))

        computed_hpkp_pins_text = [
            '',
            self.PLUGIN_TITLE_FORMAT('Computed HPKP Pins for Current Chain')
        ]
        if self.verified_certificate_chain:
            for index, cert in enumerate(self.verified_certificate_chain,
                                         start=0):
                cert_subject = CertInfoFullResult._extract_subject_cn_or_oun(
                    cert)
                if len(cert_subject) > 40:
                    # Make the CN shorter when displaying it
                    cert_subject = '{}...'.format(cert_subject[:40])
                computed_hpkp_pins_text.append(
                    self.PIN_TXT_FORMAT(
                        ('{} - {}'.format(index, cert_subject)),
                        cert.hpkp_pin))
        else:
            computed_hpkp_pins_text.append(
                self.FIELD_FORMAT(
                    CertInfoFullResult.NO_VERIFIED_CHAIN_ERROR_TXT, ""))

        txt_result.extend(
            ['',
             self.PLUGIN_TITLE_FORMAT('HTTP Public Key Pinning (HPKP)')])
        if self.hpkp_header:
            txt_result.append(
                self.FIELD_FORMAT("Max Age:", self.hpkp_header.max_age))
            txt_result.append(
                self.FIELD_FORMAT("Include Subdomains:",
                                  self.hpkp_header.include_subdomains))
            txt_result.append(
                self.FIELD_FORMAT("Report URI:", self.hpkp_header.report_uri))
            txt_result.append(
                self.FIELD_FORMAT("Report Only:",
                                  self.hpkp_header.report_only))
            txt_result.append(
                self.FIELD_FORMAT("SHA-256 Pin List:",
                                  ', '.join(self.hpkp_header.pin_sha256_list)))

            if self.verified_certificate_chain:
                pin_validation_txt = 'OK - One of the configured pins was found in the certificate chain' \
                    if self.is_valid_pin_configured \
                    else 'FAILED - Could NOT find any of the configured pins in the certificate chain!'
                txt_result.append(
                    self.FIELD_FORMAT("Valid Pin:", pin_validation_txt))

                backup_txt = 'OK - Backup pin found in the configured pins' \
                    if self.is_backup_pin_configured \
                    else 'FAILED - No backup pin found: all the configured pins are in the certificate chain!'
                txt_result.append(self.FIELD_FORMAT("Backup Pin:", backup_txt))

        else:
            txt_result.append(
                self.FIELD_FORMAT(
                    "NOT SUPPORTED - Server did not send an HPKP header", ""))

        # Dispay computed HPKP pins last
        txt_result.extend(computed_hpkp_pins_text)

        return txt_result