Ejemplo n.º 1
0
def make_signed_attrs(digest: bytes, hash_type: int) -> CMSAttributes:
    content_type = CMSAttribute({
        "type": CMSAttributeType.unmap("content_type"),
        "values": [ContentType.unmap("data")],
    })

    time_now = UTCTime()
    time_now.set(datetime.now(timezone.utc))
    signing_time = CMSAttribute({
        "type": CMSAttributeType.unmap("signing_time"),
        "values": [time_now]
    })

    message_digest = CMSAttribute({
        "type":
        CMSAttributeType.unmap("message_digest"),
        "values": [OctetString(digest)],
    })

    ha_v1 = make_hash_agility_v1(digest)

    ha_v2 = make_hash_agility_v2(digest, hash_type)

    return CMSAttributes(
        [content_type, signing_time, message_digest, ha_v1, ha_v2])
Ejemplo n.º 2
0
    def make_signature(self):
        assert self.sig.code_dir_blob

        # Redo the code hashes
        self._set_code_hashes()

        # Make the signature
        signed_attrs: CMSAttributes = make_signed_attrs(
            self.sig.code_dir_blob.get_hash(self.hash_type), self.hash_type)
        actual_privkey = load_private_key(self.privkey)
        signature = rsa_pkcs1v15_sign(actual_privkey, signed_attrs.dump(),
                                      self.hash_type_str)

        # Get the timestamp from Apple
        digest = get_hash(signature, self.hash_type)
        tst = CMSAttribute({
            "type":
            CMSAttributeType("signature_time_stamp_token"),
            "values": [get_timestamp_token(digest, self.hash_type)],
        })

        # Make the CMS
        self.sig.sig_blob = SignatureBlob()
        self.sig.sig_blob.cms = make_cms(self.cert, self.hash_type,
                                         signed_attrs, signature,
                                         CMSAttributes([tst]))

        # Get the CodeSignature section. It should be the last in the binary
        cs_sec = self.macho.sect[-1]
        assert cs_sec == self.get_linkedit_segment().sect[-1]
        assert isinstance(cs_sec, CodeSignature)
        sig_cmd = self.get_sig_command()

        # Serialize the signature
        f = BytesIO()
        self.sig.serialize(f)
        f.write((sig_cmd.datasize - f.tell()) * b"\x00")

        if self.detach_target:
            target_dir = os.path.join(self.detach_target, "Contents", "MacOS")
            os.makedirs(target_dir, exist_ok=True)
            target_file = os.path.join(
                target_dir,
                os.path.basename(self.filename) +
                f".{CPU_NAMES[self.macho.Mhdr.cputype]}sign",
            )
            with open(target_file, "wb") as tf:
                tf.write(f.getvalue())
                self.files_modified.append(target_file)
        else:
            # Set the section's content to be the signature
            cs_sec.content = StrPatchwork(f.getvalue())
Ejemplo n.º 3
0
    def sign(self):
        h = hashes.Hash(hashes.SHA256(), backend=default_backend())
        h.update(self._content_mime.as_bytes())
        message_digest = h.finalize()

        cs = CertificateSet()
        cs.append(load(self._certificate.public_bytes(Encoding.DER)))

        for ca_cert in self._ca:
            cs.append(load(ca_cert.public_bytes(Encoding.DER)))

        ec = ContentInfo({
            'content_type': ContentType('data'),
        })

        sident = SignerIdentifier({
            'issuer_and_serial_number':
            IssuerAndSerialNumber({
                'issuer':
                load(self._issuer_name.public_bytes(default_backend())),
                'serial_number':
                self._cert_serial,
            })
        })

        certv2 = ESSCertIDv2({
            'hash_algorithm':
            DigestAlgorithm({'algorithm': DigestAlgorithmId('sha256')}),
            'cert_hash':
            OctetString(self._certificate.fingerprint(hashes.SHA256())),
            'issuer_serial':
            IssuerSerial({
                'issuer':
                load(self._issuer_name.public_bytes(default_backend())),
                'serial_number':
                self._cert_serial,
            }),
        })

        now = datetime.now().replace(microsecond=0,
                                     tzinfo=pytz.utc)  # .isoformat()

        sattrs = CMSAttributes({
            CMSAttribute({
                'type': CMSAttributeType('content_type'),
                'values': ["data"]
            }),
            CMSAttribute({
                'type': CMSAttributeType('message_digest'),
                'values': [message_digest]
            }),
            CMSAttribute({
                'type': CMSAttributeType('signing_time'),
                'values': (Time({'utc_time': UTCTime(now)}), )
            }),
            CMSAttribute({
                'type':
                CMSAttributeType('signing_certificate_v2'),
                'values': [SigningCertificateV2({'certs': (certv2, )})]
            })
        })

        signature = self._private_key.sign(sattrs.dump(), padding.PKCS1v15(),
                                           hashes.SHA256())  #

        si = SignerInfo({
            'version':
            'v1',
            'sid':
            sident,
            'digest_algorithm':
            DigestAlgorithm({'algorithm': DigestAlgorithmId('sha256')}),
            'signed_attrs':
            sattrs,
            'signature_algorithm':
            SignedDigestAlgorithm(
                {'algorithm': SignedDigestAlgorithmId('rsassa_pkcs1v15')}),
            'signature':
            signature,
        })

        da = DigestAlgorithms(
            (DigestAlgorithm({'algorithm': DigestAlgorithmId('sha256')}), ))
        signed_data = SignedData({
            'version': 'v1',
            'encap_content_info': ec,
            'certificates': cs,
            'digest_algorithms': da,
            'signer_infos': SignerInfos((si, ))
        })

        ci = ContentInfo({
            'content_type': ContentType('signed_data'),
            'content': signed_data
        })

        self._signature_mime = MIMEApplication(ci.dump(),
                                               _subtype="pkcs7-signature",
                                               name="smime.p7s",
                                               policy=email.policy.SMTPUTF8)
        self._signature_mime.add_header('Content-Disposition',
                                        'attachment; filename=smime.p7s')

        super(CADESMIMESignature, self).attach(self._content_mime)
        super(CADESMIMESignature, self).attach(self._signature_mime)
Ejemplo n.º 4
0
    def sign(self):
        h = hashes.Hash(hashes.SHA256(), backend=default_backend())
        h.update(self._content_mime.as_bytes())
        message_digest = h.finalize()

        cs = CertificateSet()
        cs.append(load(self._certificate.public_bytes(Encoding.DER)))

        for ca_cert in self._ca:
            cs.append(load(ca_cert.public_bytes(Encoding.DER)))

        ec = EncapsulatedContentInfo({
            'content_type':
            ContentType('data'),
            'content':
            ParsableOctetString(self._content_mime.as_bytes())
        })

        sident = SignerIdentifier({
            'issuer_and_serial_number':
            IssuerAndSerialNumber({
                'issuer':
                load(self._issuer_name.public_bytes(default_backend())),
                'serial_number':
                self._cert_serial,
            })
        })

        certv2 = ESSCertIDv2({
            'hash_algorithm':
            DigestAlgorithm({'algorithm': DigestAlgorithmId('sha256')}),
            'cert_hash':
            OctetString(self._certificate.fingerprint(hashes.SHA256())),
            'issuer_serial':
            IssuerSerial({
                'issuer':
                load(
                    self._issuer_name.public_bytes(default_backend())
                ),  #[GeneralName({'directory_name': self._issuer_name.public_bytes(default_backend())})],
                'serial_number':
                self._cert_serial,
            }),
        })

        now = datetime.now().replace(microsecond=0, tzinfo=pytz.utc)

        sattrs = CMSAttributes({
            CMSAttribute({
                'type': CMSAttributeType('content_type'),
                'values': ["data"]
            }),
            CMSAttribute({
                'type': CMSAttributeType('message_digest'),
                'values': [message_digest]
            }),
            CMSAttribute({
                'type': CMSAttributeType('signing_time'),
                'values': (Time({'utc_time': UTCTime(now)}), )
            }),
            # isti k v
            CMSAttribute({
                'type':
                CMSAttributeType('signing_certificate_v2'),
                'values': [SigningCertificateV2({'certs': (certv2, )})]
            })
        })

        signature = self._private_key.sign(sattrs.dump(), padding.PKCS1v15(),
                                           hashes.SHA256())

        si = SignerInfo({
            'version':
            'v1',
            'sid':
            sident,
            'digest_algorithm':
            DigestAlgorithm({'algorithm': DigestAlgorithmId('sha256')}),
            'signed_attrs':
            sattrs,
            'signature_algorithm':
            SignedDigestAlgorithm(
                {'algorithm': SignedDigestAlgorithmId('rsassa_pkcs1v15')}),
            'signature':
            signature,
        })

        da = DigestAlgorithms(
            (DigestAlgorithm({'algorithm': DigestAlgorithmId('sha256')}), ))
        signed_data = SignedData({
            'version': 'v3',
            'encap_content_info': ec,
            'certificates': cs,
            'digest_algorithms': da,
            'signer_infos': SignerInfos((si, ))
        })

        ci = ContentInfo({
            'content_type': ContentType('signed_data'),
            'content': signed_data
        })

        self.set_payload(ci.dump())
        encode_base64(self)
Ejemplo n.º 5
0
    SignatureBlob,
)
from .certs import APPLE_INTERMEDIATES, APPLE_ROOTS
from .reqs import (
    AndOrExpr,
    ArgMatchExpr,
    CertificateMatch,
    ExprOp,
    Expr,
    MatchOP,
    Requirement,
    SingleArgExpr,
)
from .utils import get_bundle_exec, get_hash, get_macho_list, hash_file, round_up

HASH_AGILITY_V1_OID = CMSAttributeType("1.2.840.113635.100.9.1")
HASH_AGILITY_V2_OID = CMSAttributeType("1.2.840.113635.100.9.2")

PAGE_SIZES = {
    0x01000007: 0x1000,  # AMD64
    0x0100000C: 0x4000,  # ARM64
}

CPU_NAMES = {
    0x01000007: "x86_64",  # AMD64
    0x0100000C: "arm64",  # ARM64
}

CPU_NAME_TO_TYPE = {
    "x86_64": 0x01000007,  # AMD64
    "arm64": 0x0100000C,  # ARM64