Example #1
0
 def builder(
     *, config: SigningConfig, certificate: Certificate, element_id: str
 ) -> Element:
     return ds.Signature(
         ds.SignedInfo(
             ds.CanonicalizationMethod(Algorithm=XML_EXC_C14N),
             ds.SignatureMethod(
                 Algorithm=utils.signature_method_algorithm(config.signature_method)
             ),
             ds.Reference(
                 ds.Transforms(
                     ds.Transform(Algorithm=XMLDSIG_ENVELOPED_SIGNATURE),
                     ds.Transform(Algorithm=XML_EXC_C14N),
                 ),
                 ds.DigestMethod(
                     Algorithm=utils.digest_method_algorithm(config.digest_method)
                 ),
                 ds.DigestValue(),
                 URI="#" + element_id,
             ),
         ),
         ds.SignatureValue(),
         ds.KeyInfo(
             ds.X509Data(utils.ascii_b64(certificate.public_bytes(Encoding.DER)))
         ),
     )
Example #2
0
    def put_certificate(
        cls,
        session: "core.AuthSession",
        object_id: int,
        label: str,
        domains: int,
        capabilities: CAPABILITY,
        certificate: x509.Certificate,
    ) -> "Opaque":
        """Import an X509 certificate into the YubiHSM as an Opaque.

        :param session: The session to import via.
        :param object_id: The ID to set for the object. Set to 0 to let the
            YubiHSM designate an ID.
        :param label: A text label to give the object.
        :param domains: The set of domains to assign the object to.
        :param capabilities: The set of capabilities to give the object.
        :param certificate: A certificate to import.
        :return: A reference to the newly created object.
        """
        encoded_cert = certificate.public_bytes(Encoding.DER)
        return cls.put(
            session,
            object_id,
            label,
            domains,
            capabilities,
            ALGORITHM.OPAQUE_X509_CERTIFICATE,
            encoded_cert,
        )
Example #3
0
    def _save(
            cls, key: PrivateKey, cert: x509.Certificate, directory: str,
            name: str, key_format: Encoding
    ) -> ((str, bytes), (str, bytes), (str, bytes)):

        private_file = f'{name}.{key_format.name.lower()}'
        private_path = join(directory, private_file)
        private_bytes = key.private_bytes(key_format, PrivateFormat.PKCS8,
                                          NoEncryption())

        public_file = f'{name}.pub.{key_format.name.lower()}'
        public_path = join(directory, public_file)
        public_bytes = cert.public_key().public_bytes(key_format,
                                                      PublicFormat.PKCS1)

        cert_file = f'{name}.cert.{key_format.name.lower()}'
        cert_path = join(directory, cert_file)
        cert_bytes = cert.public_bytes(key_format)

        serialized = ((private_path, private_bytes),
                      (public_path, public_bytes), (cert_path, cert_bytes))

        for file_path, file_bytes in serialized:
            with open(file_path, 'wb') as out:
                out.write(file_bytes)

        return serialized
Example #4
0
    def _write_tls_certificate(
            self,
            port: int,  # used to avoid duplicate certs with the same IP
            certificate: Certificate,
            force: bool = True) -> Path:

        # Read
        x509 = OpenSSL.crypto.X509.from_cryptography(certificate)
        subject_components = x509.get_subject().get_components()
        common_name_as_bytes = subject_components[0][1]
        common_name_on_certificate = common_name_as_bytes.decode()
        host = common_name_on_certificate

        certificate_filepath = self.generate_certificate_filepath(host=host,
                                                                  port=port)
        certificate_already_exists = certificate_filepath.is_file()
        if force is False and certificate_already_exists:
            raise FileExistsError(
                'A TLS certificate already exists at {}.'.format(
                    certificate_filepath))

        # Write
        certificate_filepath.parent.mkdir(parents=True, exist_ok=True)
        with open(certificate_filepath, 'wb') as certificate_file:
            public_pem_bytes = certificate.public_bytes(
                self.TLS_CERTIFICATE_ENCODING)
            certificate_file.write(public_pem_bytes)

        self.log.debug(
            f"Saved TLS certificate for {host} to {certificate_filepath}")
        return certificate_filepath
Example #5
0
def create_degenerate_certificate(certificate: x509.Certificate) -> ContentInfo:
    """Produce a PKCS#7 Degenerate case with a single certificate.

    Args:
          certificate (x509.Certificate): The certificate to attach to the degenerate pkcs#7 payload.
    Returns:
          ContentInfo: The ContentInfo containing a SignedData structure.
    """
    der_bytes = certificate.public_bytes(
        serialization.Encoding.DER
    )
    asn1cert = parse_certificate(der_bytes)

    empty = ContentInfo({
        'content_type': ContentType('data')
    })
    
    sd = SignedData({
        'version': CMSVersion(1),
        'encap_content_info': empty,
        'digest_algorithms': DigestAlgorithms([]),
        'certificates': CertificateSet([CertificateChoices('certificate', asn1cert)]),
        'signer_infos': SignerInfos([]),
        'crls': RevocationInfoChoices([]),
    })

    return ContentInfo({
        'content_type': ContentType('signed_data'),
        'content': sd,
    })
Example #6
0
def test_decode_base64_cert_ok(
    trusted_cert_b64: str,
    trusted_cert: Certificate,
) -> None:
    assert _decode_base64_cert(trusted_cert_b64).public_bytes(
        Encoding.DER
    ) == trusted_cert.public_bytes(Encoding.DER)
Example #7
0
def x509_certificate_to_json(certificate: x509.Certificate) -> Dict[str, Any]:
    public_key = certificate.public_key()

    try:
        public_key_size = public_key.key_size  # type: ignore
    except AttributeError:
        public_key_size = None

    public_key_json = _PublicKeyAsJson(
        algorithm=public_key.__class__.__name__,
        key_size=public_key_size,
        # EC-only fields
        ec_curve_name=public_key.curve.name if isinstance(public_key, EllipticCurvePublicKey) else None,
        ec_x=public_key.public_numbers().x if isinstance(public_key, EllipticCurvePublicKey) else None,
        ec_y=public_key.public_numbers().y if isinstance(public_key, EllipticCurvePublicKey) else None,
        # RSA-only fields
        rsa_e=public_key.public_numbers().e if isinstance(public_key, RSAPublicKey) else None,
        rsa_n=public_key.public_numbers().n if isinstance(public_key, RSAPublicKey) else None,
    )

    signature_hash_algorithm: Optional[_HashAlgorithmAsJson]
    if certificate.signature_hash_algorithm:
        signature_hash_algorithm = _HashAlgorithmAsJson(
            name=certificate.signature_hash_algorithm.name,
            digest_size=certificate.signature_hash_algorithm.digest_size,
        )
    else:
        signature_hash_algorithm = None

    # We may get garbage/invalid certificates so we need to handle ValueErrors.
    # See https://github.com/nabla-c0d3/sslyze/issues/403 for more information
    subject_field: Optional[x509.name.Name]
    try:
        subject_field = certificate.subject
    except ValueError:
        subject_field = None

    issuer_field: Optional[x509.name.Name]
    try:
        issuer_field = certificate.issuer
    except ValueError:
        issuer_field = None

    cert_as_json = _X509CertificateAsJson(
        as_pem=certificate.public_bytes(Encoding.PEM).decode("ascii"),
        hpkp_pin=b64encode(get_public_key_sha256(certificate)).decode("ascii"),
        fingerprint_sha1=b64encode(certificate.fingerprint(hashes.SHA1())).decode("ascii"),
        fingerprint_sha256=b64encode(certificate.fingerprint(hashes.SHA256())).decode("ascii"),
        serial_number=certificate.serial_number,
        not_valid_before=certificate.not_valid_before,
        not_valid_after=certificate.not_valid_after,
        subject_alternative_name=_SubjAltNameAsJson(dns=extract_dns_subject_alternative_names(certificate)),
        signature_hash_algorithm=signature_hash_algorithm,
        signature_algorithm_oid=certificate.signature_algorithm_oid,
        subject=subject_field,
        issuer=issuer_field,
        public_key=public_key_json,
    )
    return asdict(cert_as_json)
Example #8
0
    def _write_tls_certificate(self,
                               certificate: Certificate,
                               host: str = None,
                               force: bool = True) -> str:

        # Read
        x509 = OpenSSL.crypto.X509.from_cryptography(certificate)
        subject_components = x509.get_subject().get_components()
        common_name_as_bytes = subject_components[0][1]
        common_name_on_certificate = common_name_as_bytes.decode()
        if not host:
            host = common_name_on_certificate

        try:
            pseudonym = certificate.subject.get_attributes_for_oid(
                NameOID.PSEUDONYM)[0]
        except IndexError:
            raise self.InvalidNodeCertificate(
                f"Missing checksum address on certificate for host '{host}'. "
                f"Does this certificate belong to an Ursula?")
        else:
            checksum_address = pseudonym.value

        if not is_checksum_address(checksum_address):
            raise self.InvalidNodeCertificate(
                "Invalid certificate wallet address encountered: {}".format(
                    checksum_address))

        # Validate
        # TODO: It's better for us to have checked this a while ago so that this situation is impossible.  #443
        if host and (host != common_name_on_certificate):
            raise ValueError(
                f"You passed a hostname ('{host}') that does not match the certificate's common name."
            )

        certificate_filepath = self.generate_certificate_filepath(
            checksum_address=checksum_address)
        certificate_already_exists = os.path.isfile(certificate_filepath)
        if force is False and certificate_already_exists:
            raise FileExistsError(
                'A TLS certificate already exists at {}.'.format(
                    certificate_filepath))

        # Write
        os.makedirs(os.path.dirname(certificate_filepath), exist_ok=True)
        with open(certificate_filepath, 'wb') as certificate_file:
            public_pem_bytes = certificate.public_bytes(
                self.TLS_CERTIFICATE_ENCODING)
            certificate_file.write(public_pem_bytes)

        nickname, pairs = nickname_from_seed(checksum_address)
        self.log.debug(
            f"Saved TLS certificate for {nickname} {checksum_address}: {certificate_filepath}"
        )

        return certificate_filepath
Example #9
0
def to_pem(certificate: x509.Certificate) -> str:
    """Convert an instance of x509.Certificate to a PEM string
    
    Args:
          certificate (x509.Certificate): Cert to convert
    Returns:
          PEM string
    """
    serialized = certificate.public_bytes(encoding=serialization.Encoding.PEM)

    return serialized
def _write_tls_certificate(certificate: Certificate,
                           full_filepath: str,
                           force: bool = False,
                           ) -> str:
    cert_already_exists = os.path.isfile(full_filepath)
    if force is False and cert_already_exists:
        raise FileExistsError('A TLS certificate already exists at {}.'.format(full_filepath))

    with open(full_filepath, 'wb') as certificate_file:
        public_pem_bytes = certificate.public_bytes(TLS_CERTIFICATE_ENCODING)
        certificate_file.write(public_pem_bytes)
    return full_filepath
Example #11
0
 def convert_cert_pem(cert: Certificate, include_info: bool = True) -> str:
     pem_return = None
     if cert:
         if include_info:
             pem_return = "################################################################\n"
             pem_return += f"Subject: {X509Utils.cert_get_subject(cert)}\n"
             pem_return += f"Issuer:  {X509Utils.cert_get_issuer(cert)}\n"
             pem_return += f"Valid From: {X509Utils.cert_get_valid_from(cert)} GMT\n"
             pem_return += f"Valid To:   {X509Utils.cert_get_valid_to(cert)} GMT\n"
         pem_return += cert.public_bytes(
             encoding=serialization.Encoding.PEM).decode("ascii")
     return pem_return
Example #12
0
def certificate_to_context(
        certificate: x509.Certificate) -> Common.Certificate:
    """
    certificate_to_context function
    Translates an X509 certificate into a Common.Certificate object

    :type certificate: ``x509.Certificate``
    :param oid: Certificate Extension OID

    :return: Certificate represented as a Common.Certificate object
    :rtype: ``Common.Certificate``
    """
    spkisha256 = hashes.Hash(hashes.SHA256(), backends.default_backend())
    spkisha256.update(certificate.public_key().public_bytes(
        encoding=serialization.Encoding.DER,
        format=serialization.PublicFormat.SubjectPublicKeyInfo))

    extensions_contexts: List[Common.CertificateExtension] = []
    for extension in certificate.extensions:
        extension_oid = cast(oid.ObjectIdentifier, extension.oid)
        extensions_contexts.append(
            extension_context(oid=extension_oid.dotted_string,
                              extension_name=extension_oid._name,
                              critical=extension.critical,
                              extension_value=extension.value))

    indicator = certificate.fingerprint(hashes.SHA256()).hex()
    cert = Common.Certificate(
        subject_dn=certificate.subject.rfc4514_string(),
        issuer_dn=certificate.issuer.rfc4514_string(),
        serial_number=str(certificate.serial_number),
        validity_not_before=certificate.not_valid_before.strftime(
            "%Y-%m-%dT%H:%M:%S.000Z"),
        validity_not_after=certificate.not_valid_after.strftime(
            "%Y-%m-%dT%H:%M:%S.000Z"),
        sha256=certificate.fingerprint(hashes.SHA256()).hex(),
        sha1=certificate.fingerprint(hashes.SHA1()).hex(),
        md5=certificate.fingerprint(hashes.MD5()).hex(),
        spki_sha256=spkisha256.finalize().hex(),
        extensions=extensions_contexts,
        signature_algorithm=certificate.signature_hash_algorithm.
        name,  # type: ignore[union-attr]
        signature=certificate.signature.hex(),
        publickey=public_key_context(certificate.public_key()),  # type: ignore
        dbot_score=Common.DBotScore(indicator=indicator,
                                    indicator_type=DBotScoreType.CERTIFICATE,
                                    integration_name="X509Certificate",
                                    score=Common.DBotScore.NONE),
        pem=certificate.public_bytes(
            serialization.Encoding.PEM).decode('ascii'))

    return cert
Example #13
0
    def store_certificate(self, certificate: Certificate) -> Path:
        """Store the supplied certificate as a PEM file.
        """
        # A given certificate's path is always <SHA-256>.pem.
        cert_file_name = hexlify(certificate.fingerprint(SHA256())).decode('ascii')
        cert_path = self._path / f'{cert_file_name}.pem'

        # If the cert is NOT already there, add it
        if not cert_path.exists():
            with open(cert_path, 'w') as cert_file:
                cert_file.write(certificate.public_bytes(Encoding.PEM).decode('ascii'))

        return cert_path
Example #14
0
 def _write_private_key_and_cert(
     self, key: ec.EllipticCurvePrivateKey, cert: x509.Certificate, disk_folder: str
 ) -> None:
     cert_file = os.path.join(disk_folder, self.private_cert_file_name)
     with open(cert_file, "w+") as file:
         file.write(
             key.private_bytes(
                 serialization.Encoding.PEM,
                 serialization.PrivateFormat.TraditionalOpenSSL,
                 serialization.NoEncryption(),
             ).decode("UTF-8")
         )
         file.write(cert.public_bytes(serialization.Encoding.PEM).decode("UTF-8"))
Example #15
0
def x509_certificate_to_json(certificate: x509.Certificate) -> Dict[str, Any]:
    result: Dict[str, Union[None, str, Dict[str, Any]]] = {
        # Add general info
        "as_pem": certificate.public_bytes(Encoding.PEM).decode("ascii"),
        "hpkp_pin": b64encode(
            get_public_key_sha256(certificate)).decode("utf-8"),  # RFC 7469
        # Add some of the fields of the cert
        "serialNumber": str(certificate.serial_number),
        "notBefore": certificate.not_valid_before.isoformat(),
        "notAfter": certificate.not_valid_after.isoformat(),
        "subjectAlternativeName": {
            "DNS": extract_dns_subject_alternative_names(certificate)
        },
    }

    if certificate.signature_hash_algorithm:
        # The signature_hash_algorithm can be None if signature did not use separate hash (ED25519, ED448)
        # https://cryptography.io/en/latest/x509/reference/#cryptography.x509.Certificate.signature_hash_algorithm
        result[
            "signatureAlgorithm"] = certificate.signature_hash_algorithm.name
    else:
        result["signatureAlgorithm"] = None

    # We may get garbage/invalid certificates so we need to handle ValueErrors.
    # See https://github.com/nabla-c0d3/sslyze/issues/403 for more information
    for name_field in ["subject", "issuer"]:
        try:
            result[name_field] = getattr(certificate, name_field)
        except ValueError as e:
            x509name_as_json = _X509NameAsJson(rfc4514_string=None,
                                               attributes=None,
                                               parsing_error=e.args[0])
            result[name_field] = asdict(x509name_as_json)

    # Add some info about the public key
    public_key = certificate.public_key()
    public_key_dict: Dict[str, Union[str, int]] = {
        "algorithm": public_key.__class__.__name__
    }
    if isinstance(public_key, EllipticCurvePublicKey):
        public_key_dict["size"] = public_key.curve.key_size
        public_key_dict["curve"] = public_key.curve.name
    elif isinstance(public_key, RSAPublicKey):
        public_key_dict["size"] = public_key.key_size
        public_key_dict["exponent"] = public_key.public_numbers().e
    else:
        # DSA Key? https://github.com/nabla-c0d3/sslyze/issues/402
        pass

    result["publicKey"] = public_key_dict
    return result
Example #16
0
def to_der(certificate: x509.Certificate) -> bytes:
    """Convert an instance of x509.Certificate to DER bytes
    
    Args:
          certificate (x509.Certificate): Cert to convert
    Returns:
          DER bytes    
    """
    serialized = certificate.public_bytes(
        encoding=serialization.Encoding.DER,
        format=serialization.PublicFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption())

    return serialized
Example #17
0
    def cert_as_string(self, cert: Certificate = None) -> str:
        if not cert:
            cert = self.signed_cert

        cert_info = (
            f'# Issuer {cert.issuer}\n'
            f'# Subject {cert.subject}\n'
            f'# Valid from {cert.not_valid_before} to {cert.not_valid_after}\n'
        )
        data = cert_info
        data += cert.public_bytes(serialization.Encoding.PEM).decode('utf-8')
        data += '\n'

        return data
Example #18
0
def _save_tls_certificate(
        certificate: Certificate,
        full_filepath: str,
        force:
    bool = True,  # TODO: Make configurable, or set to False by default.
) -> str:
    if force is False and os.path.isfile(full_filepath):
        raise FileExistsError(
            'A TLS certificate already exists at {}.'.format(full_filepath))

    with open(full_filepath, 'wb') as certificate_file:
        public_pem_bytes = certificate.public_bytes(Encoding.PEM)
        certificate_file.write(public_pem_bytes)

    return full_filepath
Example #19
0
    def from_crypto_type(cls, certificate: x509.Certificate, certtype: CertificateType):
        # type: (certtype, x509.Certificate, CertificateType) -> Certificate
        m = cls()
        m.pem_data = certificate.public_bytes(serialization.Encoding.PEM)
        m.not_after = certificate.not_valid_after
        m.not_before = certificate.not_valid_before
        m.fingerprint = certificate.fingerprint(hashes.SHA256())
        m.discriminator = certtype.value

        subject: x509.Name = certificate.subject
        cns = subject.get_attributes_for_oid(NameOID.COMMON_NAME)
        if cns is not None:
            m.x509_cn = cns[0].value

        return m
Example #20
0
async def write_certs(key: rsa.RSAPrivateKey, cert: x509.Certificate,
                      name: str):

    assert len(name) > 0

    with open(f"{name:s}.key", "wb") as f:
        f.write(
            key.private_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PrivateFormat.TraditionalOpenSSL,
                encryption_algorithm=serialization.NoEncryption(),  # ?
            ))

    with open(f"{name:s}.crt", "wb") as f:
        f.write(cert.public_bytes(encoding=serialization.Encoding.PEM, ))
Example #21
0
    def from_crypto(cls, certificate: x509.Certificate):
        # TODO: sometimes serial numbers are too large even for SQLite BIGINT
        m = cls()
        m.pem_data = certificate.public_bytes(
            encoding=serialization.Encoding.PEM)
        m.not_after = certificate.not_valid_after
        m.not_before = certificate.not_valid_before
        m.fingerprint = certificate.fingerprint(hashes.SHA256())

        subject: x509.Name = certificate.subject

        cns = subject.get_attributes_for_oid(NameOID.COMMON_NAME)
        if cns is not None:
            m.x509_cn = cns[0].value
        return m
Example #22
0
def sign(
    *,
    element: Element,
    private_key: RSAPrivateKey,
    certificate: Certificate,
    config: SigningConfig = SigningConfig.default(),
    index: int = 0,
) -> bytes:
    try:
        element_id = element.attrib["ID"]
    except KeyError:
        raise NoIDAttribute(element)
    # Generate the digest value of the element/content to be signed
    content_digest_value = utils.ascii_b64(
        utils.hash_digest(config.digest_method, utils.serialize_xml(element)))
    # Build the SignedInfo tag, referencing the element we got passed,
    # including the digest value we just created.
    signed_info = ds.SignedInfo(
        ds.CanonicalizationMethod(Algorithm=XML_EXC_C14N),
        ds.SignatureMethod(Algorithm=utils.signature_method_algorithm(
            config.signature_method)),
        ds.Reference(
            ds.Transforms(
                ds.Transform(Algorithm=XMLDSIG_ENVELOPED_SIGNATURE),
                ds.Transform(Algorithm=XML_EXC_C14N),
            ),
            ds.DigestMethod(
                Algorithm=utils.digest_method_algorithm(config.digest_method)),
            ds.DigestValue(content_digest_value),  # Embed the digest value
            URI="#" + element_id,  # Reference the element to sign
        ),
    )
    # Sign the digest of the SignedInfo element
    signature = utils.sign(utils.serialize_xml(signed_info), private_key,
                           config.signature_method)
    signature_value = utils.ascii_b64(signature)
    # Encode the certificate to embed into the signature.
    cert_data = utils.ascii_b64(certificate.public_bytes(Encoding.DER))
    signature_element = ds.Signature(
        signed_info,
        ds.SignatureValue(signature_value),
        ds.KeyInfo(ds.X509Data(ds.X509Certificate(cert_data))),
    )
    element.insert(index, signature_element)
    root = utils.get_root(element)
    result = utils.serialize_xml(root)
    element.remove(signature_element)
    return result
Example #23
0
    def _write_tls_certificate(self,
                               certificate: Certificate,
                               host: str = None,
                               force: bool = True) -> str:

        # Read
        x509 = OpenSSL.crypto.X509.from_cryptography(certificate)
        subject_components = x509.get_subject().get_components()
        common_name_as_bytes = subject_components[0][1]
        common_name_on_certificate = common_name_as_bytes.decode()
        if not host:
            host = common_name_on_certificate

        pseudonym = certificate.subject.get_attributes_for_oid(
            NameOID.PSEUDONYM)[0]
        checksum_address = pseudonym.value

        if not is_checksum_address(checksum_address):  # TODO: more?
            raise RuntimeError(
                "Invalid certificate checksum address encountered: {}".format(
                    checksum_address))

        # Validate
        # TODO: It's better for us to have checked this a while ago so that this situation is impossible.  #443
        if host and (host != common_name_on_certificate):
            raise ValueError(
                'You passed a hostname ("{}") that does not match the certificat\'s common name.'
                .format(host))

        certificate_filepath = self.generate_certificate_filepath(
            checksum_address=checksum_address)
        certificate_already_exists = os.path.isfile(certificate_filepath)
        if force is False and certificate_already_exists:
            raise FileExistsError(
                'A TLS certificate already exists at {}.'.format(
                    certificate_filepath))

        # Write
        with open(certificate_filepath, 'wb') as certificate_file:
            public_pem_bytes = certificate.public_bytes(
                self.TLS_CERTIFICATE_ENCODING)
            certificate_file.write(public_pem_bytes)

        self.certificate_filepath = certificate_filepath
        self.log.info("Saved TLS certificate for {}: {}".format(
            self, certificate_filepath))

        return certificate_filepath
def serialize_certificate(certificate: Certificate,
                          encoding: serialization.Encoding) -> bytes:
    """Serializes an X.509 certificate using the specified encoding.

    Args:
        certificate: Certificate object to be serialized to bytes.
        encoding: The serialization format to use to save the certificate.

    Raises:
        X509CertificateError: In case it cannot get the bytes from the certificate object.
    """
    try:
        cert_bytes = certificate.public_bytes(encoding)
    except Exception as err:
        raise X509CertificateError(
            'Could not get bytes from object: {}'.format(str(err)))

    return cert_bytes
Example #25
0
    def from_crypto(cls, certificate: x509.Certificate):
        m = cls()
        m.pem_data = certificate.public_bytes(
            encoding=serialization.Encoding.PEM)
        m.not_after = certificate.not_valid_after
        m.not_before = certificate.not_valid_before
        m.fingerprint = certificate.fingerprint(hashes.SHA1())

        subject: x509.Name = certificate.subject

        m.x509_cn = subject.get_attributes_for_oid(
            NameOID.COMMON_NAME)[0].value
        # m.x509_c = subject.get_attributes_for_oid(NameOID.COUNTRY_NAME)
        # m.x509_o = subject.get_attributes_for_oid(NameOID.ORGANIZATION_NAME)
        # m.x509_ou = subject.get_attributes_for_oid(NameOID.ORGANIZATIONAL_UNIT_NAME)
        # m.x509_st = subject.get_attributes_for_oid(NameOID.STATE_OR_PROVINCE_NAME)

        return m
Example #26
0
    def from_orm(cls, certificate: x509.Certificate) -> "_CertificateAsJson":
        signature_hash_algorithm: Optional[_HashAlgorithmAsJson]
        if certificate.signature_hash_algorithm:
            signature_hash_algorithm = _HashAlgorithmAsJson.from_orm(
                certificate.signature_hash_algorithm)
        else:
            signature_hash_algorithm = None

        # We may get garbage/invalid certificates so we need to handle ValueErrors.
        # See https://github.com/nabla-c0d3/sslyze/issues/403 for more information
        subject_field: Optional[_X509NameAsJson]
        try:
            subject_field = _X509NameAsJson.from_orm(certificate.subject)
        except ValueError:
            subject_field = None

        issuer_field: Optional[_X509NameAsJson]
        try:
            issuer_field = _X509NameAsJson.from_orm(certificate.issuer)
        except ValueError:
            issuer_field = None

        return cls(
            as_pem=certificate.public_bytes(Encoding.PEM).decode("ascii"),
            hpkp_pin=b64encode(
                get_public_key_sha256(certificate)).decode("ascii"),
            fingerprint_sha1=b64encode(certificate.fingerprint(
                hashes.SHA1())).decode("ascii"),
            fingerprint_sha256=b64encode(
                certificate.fingerprint(hashes.SHA256())).decode("ascii"),
            serial_number=certificate.serial_number,
            not_valid_before=certificate.not_valid_before,
            not_valid_after=certificate.not_valid_after,
            subject_alternative_name=_SubjAltNameAsJson(
                dns=extract_dns_subject_alternative_names(certificate)),
            signature_hash_algorithm=signature_hash_algorithm,
            signature_algorithm_oid=certificate.signature_algorithm_oid,
            subject=subject_field,
            issuer=issuer_field,
            public_key=_PublicKeyAsJson.from_orm(certificate.public_key()),
        )
Example #27
0
    def storePublicKey(self, certName: str, cert: x509.Certificate) -> None:
        path = self.conf.getCertPath(certName=certName,
                                     ext="signed_certificate")
        certConf = self.conf.getCert(certName=certName)
        format = certConf.get("public_key").get("format", None)

        try:
            if type(format) == str and format.lower() == "openssh":
                content = serialization.ssh.serialize_ssh_public_key(
                    cert.public_key())
                with open(path, "wb") as f:
                    f.write(content)
            # DER or PEM encodings
            else:
                encoding, _ = self._getParamsForPublicBytes(certConf=certConf)
                content = cert.public_bytes(encoding)
                with open(path, "wb") as f:
                    f.write(content)

        except OSError:
            logging.error(f"can't save public key in {path}")
            sys.exit()
Example #28
0
    def _build_recipient_info(self, symmetric_key: bytes,
                              recipient: x509.Certificate) -> RecipientInfo:
        """Build an ASN.1 data structure containing the encrypted symmetric key for the encrypted_content.
        
        NOTE: The recipient is always identified by issuerAndSerialNumber
        NOTE: 

        Args:
            symmetric_key (bytes): Typically the randomly generated 3DES key for the encrypted_content.
            recipient (x509.Certificate): The certificate which will be used to encrypt the symmetric key.

        Returns:
              RecipientInfo: Instance of ASN.1 data structure with required attributes and encrypted key.
        """
        encrypted_symkey = recipient.public_key().encrypt(
            symmetric_key, asympad.PKCS1v15())
        asn1cert = parse_certificate(
            recipient.public_bytes(serialization.Encoding.DER))
        ias = IssuerAndSerialNumber({
            'issuer': asn1cert.issuer,
            'serial_number': asn1cert.serial_number
        })

        ri = RecipientInfo(
            'ktri',
            KeyTransRecipientInfo({
                'version':
                0,
                'rid':
                RecipientIdentifier('issuer_and_serial_number', ias),
                'key_encryption_algorithm':
                KeyEncryptionAlgorithm(
                    {'algorithm': KeyEncryptionAlgorithmId('rsa')}),
                'encrypted_key':
                encrypted_symkey,
            }))

        return ri
Example #29
0
def submit_mdmcert_request(email: str,
                           csr: x509.CertificateSigningRequest,
                           encrypt_with: x509.Certificate,
                           api_key: str = MDMCERT_API_KEY) -> Dict:
    """Submit a CSR signing request to mdmcert.download.

    Args:
          email (str): Your registered mdmcert.download e-mail address.
          api_key (str): Your registered mdmcert.download API key.
          csr (cryptography.x509.CertificateSigningRequest): The MDM CSR to sign.
          encrypt_with (cryptography.x509.Certificate): The certificate which will be used to encrypt the response.

    Returns:
          dict: Response from the mdmcert.download service.
    """
    base64_csr = b64encode(csr.public_bytes(serialization.Encoding.PEM))
    base64_recipient = b64encode(
        encrypt_with.public_bytes(serialization.Encoding.PEM))

    mdmcert_dict = {
        'csr': base64_csr.decode('utf8'),
        'email': email,
        'key': api_key,
        'encrypt': base64_recipient.decode('utf8'),
    }

    req = urllib.request.Request(MDMCERT_REQ_URL,
                                 json.dumps(mdmcert_dict).encode('utf8'), {
                                     'Content-Type': 'application/json',
                                     'User-Agent': 'coMmanDMent/0.1'
                                 })

    f = urllib.request.urlopen(req)
    resp = f.read()
    f.close()

    return json.loads(resp)
Example #30
0
def fixture_untrusted_cert_b64(untrusted_cert: Certificate) -> str:
    return urlsafe_b64encode(untrusted_cert.public_bytes(
        Encoding.DER)).decode()