Esempio n. 1
0
 def statistic_error(self, error):
     """统计错误次数,同种达到一定错误次数就终止服务"""
     error = str(error)
     count = self.error_container.get(error, 0)
     count += 1
     if count >= self.error_counts:
         logger.warn('同种错误发生次数达到最大')
         os._exit(0)
     self.error_container[error] = count
Esempio n. 2
0
    def check_for_wildcards(self):
        #TODO: Das ist in der Prüfung von CA Zertifkaten anders. Die Funktion hier steigt leider aus wenn es die AlternativeNames extension nich gitb und daher kann man sie eigentlich für ein CA-ZErt nicht verwenden. Und es müssen auch noch mehr Felder (subject) geprüft werden.
        for entry in self.cert.subject._attributes:
            for attr in entry:
                if attr.oid._name == "commonName":
                    logger.info(
                        "commonName im subject des Zertifikat hat den Wert: " +
                        attr.value)
                    # test auf stern in cn
                    if re.search(r"\*+", attr.value) != None:
                        logger.error(
                            "Der CN enthält mindestens ein *. Das ist nicht OK"
                        )

        try:
            name_extension = self.cert.extensions.get_extension_for_class(
                x509.SubjectAlternativeName)
            logger.info("Das Zertifikat hat eine AlternativeName Extension")

            # liste der san
            altname_list = name_extension.value.get_values_for_type(
                x509.DNSName)
            # keine san enthalten
            if len(altname_list) < 1:
                logger.warn("Die Liste der Alernative Names ist leer.")
                return

            # test auf stern in san
            for altname in altname_list:
                if re.search(r"\*+", altname) != None:
                    logger.error(
                        "Die AlternativeName-Extension enthält mindestens ein *. Das ist nicht OK"
                    )
                    return
            logger.info(
                "Die AlternativeName-Extension enthält keine Wildcards. Das ist  OK"
            )

        except Exception as err:
            # eine fehlende SAN-Extension an sich sollte kein Fehler sein
            # bitte prüfen
            logger.info("Es existiert keine AlternativeName-Extension")
Esempio n. 3
0
    def check_cert_for_crl(self):
        try:
            crl_extension = self.cert.extensions.get_extension_for_class(
                x509.CRLDistributionPoints)
            logger.info(
                "Das Zertifikat hat eine CRLDistributionPoint Extension")
            logger.info(
                "Der Inhalt der CRLDistributionPoint Extension lautet:")
            logger.info(str(crl_extension))
            #TODO: Die Ausgabe der Extension könnte etwas schöner werden

        except x509.extensions.ExtensionNotFound as err:
            logger.warn(
                "Das Zertifikat besitzt keine CRLDistributionPoint-Extension")

        except Exception as err:
            logger.warn(
                "Unbekannter Fehler beim Lesen der CRLDistributionPoint-Extension"
            )
            print err
Esempio n. 4
0
    def check_cert_for_aia(self):
        try:
            aia_extension = self.cert.extensions.get_extension_for_class(
                x509.AuthorityInformationAccess)
            logger.info(
                "Das Zertifikat hat eine AuthorityInformationAccess Extension")
            logger.info(
                "Der Inhalt der AuthorityInformationAccess Extension lautet:")
            logger.info(str(aia_extension))
            #TODO: Die Ausgabe der Extension könnte etwas schöner werden

        except x509.extensions.ExtensionNotFound as err:
            logger.warn(
                "Das Zertifikat besitzt keine AuthorityInformationAccess-Extension"
            )

        except Exception as err:
            logger.warn(
                "Unbekannter Fehler beim Lesen der AuthorityInformationAccess-Extension"
            )
            print err
Esempio n. 5
0
    def test_key_exchange(self):
        #Anforderung 2.4.1

        # key exchange dh Länge anzeigen
        openssl_cmd_getcert = "echo | openssl s_client -msg -connect " + self.hostname + ":" + str(
            self.port
        ) + self.openssl_client_proxy_part + " | grep 'Server Temp Key:'"

        proc = subprocess.Popen([openssl_cmd_getcert],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                shell=True)
        (out, err) = proc.communicate()

        out_list = out.splitlines()
        if len(out_list) < 1:
            logger.warn("Parameter konnten nicht gelesen werden")
            logger.warn(out)
            return

        if "Server Temp Key: DH," in out_list[0]:
            bits = int(out_list[0].split()[-2])
            if bits < 2048:
                logger.error(
                    "Verwendete Keylänge ist kleiner als 2048 bit. Das ist nicht OK"
                )
                logger.warn(out)
            else:
                logger.info(
                    "Verwendete Keylänge beträgt mind. 2048 bit. Das ist so OK."
                )
                logger.info(out)
            return

        elif "Server Temp Key: ECDH" in out_list[0]:

            # verwendete ecc Kurve anzeigen
            # http://crypto.stackexchange.com/questions/11310/with-openssl-and-ecdhe-how-to-show-the-actual-curve-being-used
            # openssl key exchange short description

            openssl_cmd_getcert = "echo | openssl s_client -msg -connect " + self.hostname + ":" + str(
                self.port
            ) + self.openssl_client_proxy_part + " | grep 'ServerKey' -A 5"

            proc = subprocess.Popen([openssl_cmd_getcert],
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE,
                                    shell=True)
            (out, err) = proc.communicate()

            out_list = out.splitlines()
            if len(out_list) < 2:
                logger.warn("Parameter konnten nicht gelesen werden")
                logger.warn(out)
                return

            param_list = out_list[1].strip().split()
            if param_list[0] != "0c" or param_list[4] != "03":
                logger.warn("Parameter passen nicht zu ECDH Werten")
                logger.warn(out)
                return

            decimal_curve_id = int(param_list[5] + param_list[6], 16)
            if decimal_curve_id in self.ec_curve_names:
                logger.info("Verwendete ECDHE Kurve: " +
                            self.ec_curve_names[decimal_curve_id] +
                            ". Das ist so OK.")
            else:
                logger.warn(
                    "Verwendete ECDHE Kurve unbekannt, bitte manuell prüfen")
                logger.warn(out)

        else:
            logger.warn(
                "Verwendeter Key Exchange unbekannt, bitte manuell überprüfen")
            logger.warn(out)
            return
Esempio n. 6
0
    def test_supported_cipher_suites(self):
        #Anforderung 2.3.2/2.3.3/2.3.4
        #TODO: Funktioniert aktuell nur mit RSA
        crypto_type = "RSA"
        openssl_cmd_getcert = "openssl ciphers"
        proc = subprocess.Popen([openssl_cmd_getcert],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                shell=True)
        (out, err) = proc.communicate()

        out = out.replace('\n', '').replace('\r', '')
        all_ciphers = out.split(":")
        all_ciphers = filter(None, all_ciphers)
        all_ciphers = filter(None, all_ciphers)

        for cipher in all_ciphers:
            cipher_list = [
                x for x in self.cipher_suites
                if x[1] == cipher and x[2] == crypto_type
            ]
            allowed = should = must = optional = False

            if len(cipher_list) == 0:
                allowed = False
            elif cipher_list[0][3] == "MUST":
                must = True
                allowed = True
            elif cipher_list[0][3] == "SHOULD":
                should = True
                allowed = True
            elif cipher_list[0][3] == "OPTIONAL":
                optional = True
                allowed = True

            context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
            context.set_ciphers(cipher)
            if self.insecure:
                context.verify_mode = ssl.CERT_NONE
                context.check_hostname = False
            else:
                context.verify_mode = ssl.CERT_REQUIRED
                context.check_hostname = True

            if self.ca_file:
                context.load_verify_locations(cafile=self.ca_file)
            else:
                context.load_default_certs()
            if self.clientcert_file:
                context.load_cert_chain(certfile=self.clientcert_file)

            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                ssl_sock = context.wrap_socket(s,
                                               server_hostname=self.hostname)
                ssl_sock.connect((self.hostname, self.port))
                priority = ssl_sock.cipher()[2]

                if not allowed:
                    logger.error(
                        "Server unterstützt verbotene cipher-suite: " +
                        cipher + " mit Priorität" + str(priority) +
                        " Das sollte nicht der Fall sein")

                elif must or should or optional:
                    logger.warning(cipher + " wird unterstützt mit Priorität" +
                                   str(priority) +
                                   ". Bitte in der Checkliste prüfen.")

            # Zertifikatfehler
            except ssl.CertificateError as err:
                logger.error("Zertifikatfehler bei Überprüfung von %s" %
                             (cipher))
                print(err)

            # ssl Verbindungsabbruch
            except ssl.SSLError as err:
                if len(err.args) > 1:
                    if "SSLV3_ALERT_HANDSHAKE_FAILURE" in err.args[
                            1] or "NO_CIPHERS_AVAILABLE" in err.args[
                                1] or "EOF occurred in violation of protocol" in err.args[
                                    1]:
                        if must:
                            logger.error(
                                cipher +
                                " wird nicht unterstützt aber von der Checkliste gefordert"
                            )
                        else:
                            logger.info(
                                cipher +
                                " wird nicht unterstützt. Das scheint OK zu sein."
                            )
                    # DH Key zu klein
                    elif "dh key too small" in err.args[1]:
                        logger.warn(cipher + " " + err.args[1])
                    # sonstiger Grund
                    else:
                        logger.warn(cipher +
                                    " verursacht einen Verbindungsfehler")
                        print(err.args[1])
                if len(err.args) == 1:
                    if must:
                        logger.error(
                            cipher +
                            " wird nicht unterstützt aber von der Checkliste gefordert"
                        )
                    else:
                        logger.info(
                            cipher +
                            " wird nicht unterstützt. Das scheint OK zu sein.")

            # socket Fehler
            except socket.error as err:
                if must:
                    logger.error(
                        cipher +
                        " wird nicht unterstützt aber von der Checkliste gefordert"
                    )
                else:
                    logger.info(
                        cipher +
                        " wird nicht unterstützt. Das scheint OK zu sein.")