예제 #1
0
    def _parse(self):
        super()._parse()

        # Get the tst_info
        self.tst_info = guarded_der_decode(
            self.data['encapContentInfo']['eContent'],
            asn1_spec=rfc3161.TSTInfo())

        if self.tst_info['version'] != 1:
            raise AuthenticodeParseError("TSTInfo.version must be 1, not %d" %
                                         self.data['version'])

        self.policy = self.tst_info['policy']  # TODO
        self.hash_algorithm = _get_digest_algorithm(
            self.tst_info['messageImprint']['hashAlgorithm'],
            location="TSTInfo.messageImprint.hashAlgorithm")
        self.message_digest = bytes(
            self.tst_info['messageImprint']['hashedMessage'])
        self.serial_number = self.tst_info['serialNumber']
        self.signing_time = self.tst_info['genTime'].asDateTime
        self.signing_time_accuracy = accuracy_to_python(
            self.tst_info['accuracy'])
        # TODO handle case where directoryName is not a rdnSequence
        self.signing_authority = CertificateName(
            self.tst_info['tsa']['directoryName']['rdnSequence'])

        # signerInfos
        if len(self.signer_infos) != 1:
            raise AuthenticodeParseError(
                "RFC3161 SignedData.signerInfos must contain exactly 1 signer, not %d"
                % len(self.signer_infos))

        self.signer_info = self.signer_infos[0]
예제 #2
0
    def _parse(self):
        # digestAlgorithms
        if len(self.data['digestAlgorithms']) != 1:
            raise AuthenticodeParseError(
                "RFC3161 SignedData.digestAlgorithms must contain exactly 1 algorithm, not "
                "%d" % len(self.data['digestAlgorithms']))
        self.digest_algorithm = _get_digest_algorithm(
            self.data['digestAlgorithms'][0], "SignedData.digestAlgorithm")

        # Get the tst_info
        self.content_type = asn1.oids.get(
            self.data['encapContentInfo']['eContentType'])
        if self.content_type is not rfc3161.TSTInfo:
            raise AuthenticodeParseError(
                "RFC3161 SignedData.contentInfo does not contain TSTInfo")

        self.tst_info = guarded_der_decode(
            self.data['encapContentInfo']['eContent'],
            asn1_spec=rfc3161.TSTInfo())

        if self.tst_info['version'] != 1:
            raise AuthenticodeParseError("TSTInfo.version must be 1, not %d" %
                                         self.data['version'])

        self.policy = self.tst_info['policy']  # TODO
        self.hash_algorithm = _get_digest_algorithm(
            self.tst_info['messageImprint']['hashAlgorithm'],
            location="TSTInfo.messageImprint.hashAlgorithm")
        self.message_digest = bytes(
            self.tst_info['messageImprint']['hashedMessage'])
        self.serial_number = self.tst_info['serialNumber']
        self.signing_time = self.tst_info['genTime'].asDateTime
        self.signing_time_accuracy = accuracy_to_python(
            self.tst_info['accuracy'])
        # TODO handle case where directoryName is not a rdnSequence
        self.signing_authority = CertificateName(
            self.tst_info['tsa']['directoryName']['rdnSequence'])

        # Certificates
        self.certificates = CertificateStore(
            [Certificate(cert) for cert in self.data['certificates']])

        # signerInfos
        if len(self.data['signerInfos']) != 1:
            raise AuthenticodeParseError(
                "RFC3161 SignedData.signerInfos must contain exactly 1 signer, not %d"
                % len(self.data['signerInfos']))

        self.signer_info = RFC3161SignerInfo(self.data['signerInfos'][0])
예제 #3
0
    def _parse(self):
        super()._parse()

        # - Retrieve object from SpcSpOpusInfo from the authenticated attributes (for normal signer)
        self.program_name = self.more_info = None
        if asn1.spc.SpcSpOpusInfo in self.authenticated_attributes:
            if len(self.authenticated_attributes[asn1.spc.SpcSpOpusInfo]) != 1:
                raise AuthenticodeParseError(
                    "Only one SpcSpOpusInfo expected in SignerInfo.authenticatedAttributes"
                )

            self.program_name = self.authenticated_attributes[
                asn1.spc.SpcSpOpusInfo][0]['programName'].to_python()
            self.more_info = self.authenticated_attributes[
                asn1.spc.SpcSpOpusInfo][0]['moreInfo'].to_python()

        # - Authenticode can be signed using a RFC-3161 timestamp, so we discover this possibility here
        if pkcs7.Countersignature in self.unauthenticated_attributes \
                and asn1.spc.SpcRfc3161Timestamp in self.unauthenticated_attributes:
            raise AuthenticodeParseError(
                "Countersignature and RFC-3161 timestamp present in "
                "SignerInfo.unauthenticatedAttributes")

        if asn1.spc.SpcRfc3161Timestamp in self.unauthenticated_attributes:
            if len(self.unauthenticated_attributes[
                    asn1.spc.SpcRfc3161Timestamp]) != 1:
                raise AuthenticodeParseError(
                    "Only one RFC-3161 timestamp expected in "
                    "SignerInfo.unauthenticatedAttributes")

            ts_data = self.unauthenticated_attributes[
                asn1.spc.SpcRfc3161Timestamp][0]
            content_type = asn1.oids.get(ts_data['contentType'])
            if content_type is not rfc2315.SignedData:
                raise AuthenticodeParseError(
                    "RFC-3161 Timestamp does not contain SignedData structure")
            # Note that we expect rfc5652 compatible data here
            # This is a work-around for incorrectly tagged v2AttrCerts in the BER-encoded blob,
            # see the docstring for patch_rfc5652_signeddata for more details
            try:
                signed_data = guarded_ber_decode(
                    ts_data['content'], asn1_spec=rfc5652.SignedData())
            except ParseError:
                with patch_rfc5652_signeddata() as asn1_spec:
                    signed_data = guarded_ber_decode(ts_data['content'],
                                                     asn1_spec=asn1_spec)
            self.countersigner = RFC3161SignedData(signed_data)
예제 #4
0
    def _parse(self):
        # Parse the fields of the SignedData structure
        if self.data['version'] != 1:
            raise AuthenticodeParseError(
                "SignedData.version must be 1, not %d" % self.data['version'])

        # digestAlgorithms
        if len(self.data['digestAlgorithms']) != 1:
            raise AuthenticodeParseError(
                "SignedData.digestAlgorithms must contain exactly 1 algorithm, not %d"
                % len(self.data['digestAlgorithms']))
        self.digest_algorithm = _get_digest_algorithm(
            self.data['digestAlgorithms'][0], "SignedData.digestAlgorithm")

        # SpcIndirectDataContent
        self.content_type = asn1.oids.get(
            self.data['contentInfo']['contentType'])
        if self.content_type is not asn1.spc.SpcIndirectDataContent:
            raise AuthenticodeParseError(
                "SignedData.contentInfo does not contain SpcIndirectDataContent"
            )
        spc_info = guarded_ber_decode(
            self.data['contentInfo']['content'],
            asn1_spec=asn1.spc.SpcIndirectDataContent())
        self.spc_info = SpcInfo(spc_info)

        # Certificates
        self.certificates = CertificateStore(
            [Certificate(cert) for cert in self.data['certificates']])

        # signerInfos
        if len(self.data['signerInfos']) != 1:
            raise AuthenticodeParseError(
                "SignedData.signerInfos must contain exactly 1 signer, not %d"
                % len(self.data['signerInfos']))

        self.signer_info = AuthenticodeSignerInfo(self.data['signerInfos'][0])

        # CRLs
        if 'crls' in self.data and self.data['crls'].isValue:
            raise AuthenticodeParseError(
                "SignedData.crls is present, but that is unexpected.")
예제 #5
0
    def _parse(self):
        # Parse the fields of the SignedData structure
        if self.data['version'] != 1:
            raise AuthenticodeParseError(
                "SignedData.version must be 1, not %d" % self.data['version'])

        super()._parse()
        self.spc_info = SpcInfo(self.content)

        # signerInfos
        if len(self.signer_infos) != 1:
            raise AuthenticodeParseError(
                "SignedData.signerInfos must contain exactly 1 signer, not %d"
                % len(self.signer_infos))

        self.signer_info = self.signer_infos[0]

        # CRLs
        if 'crls' in self.data and self.data['crls'].isValue:
            raise AuthenticodeParseError(
                "SignedData.crls is present, but that is unexpected.")
예제 #6
0
    def _parse(self):
        super()._parse()

        # - Retrieve object from SpcSpOpusInfo from the authenticated attributes (for normal signer)
        self.program_name = self.more_info = None
        if asn1.spc.SpcSpOpusInfo in self.authenticated_attributes:
            if len(self.authenticated_attributes[asn1.spc.SpcSpOpusInfo]) != 1:
                raise AuthenticodeParseError(
                    "Only one SpcSpOpusInfo expected in SignerInfo.authenticatedAttributes"
                )

            self.program_name = self.authenticated_attributes[
                asn1.spc.SpcSpOpusInfo][0]['programName'].to_python()
            self.more_info = self.authenticated_attributes[
                asn1.spc.SpcSpOpusInfo][0]['moreInfo'].to_python()
예제 #7
0
    def from_certificate(cls, data, *args, **kwargs):
        """Loads a :class:`SignedData` object from raw data that contains ContentInfo.

        :param bytes data: The bytes to parse
        """
        # This one is not guarded, which is intentional
        content, rest = ber_decoder.decode(data,
                                           asn1Spec=asn1.pkcs7.ContentInfo())
        if asn1.oids.get(content['contentType']) is not asn1.pkcs7.SignedData:
            raise AuthenticodeParseError(
                "ContentInfo does not contain SignedData")

        data = guarded_ber_decode(content['content'],
                                  asn1_spec=asn1.pkcs7.SignedData())

        signed_data = SignedData(data, *args, **kwargs)
        signed_data._rest_data = rest
        return signed_data