Пример #1
0
    def __init__(self, content):
        self.container, rest = decoder.decode(content,
                                              asn1Spec=pkcs7.ContentInfo())
        if rest:
            self.trailing_data = rest

        self.signed_data, rest = decoder.decode(self.container['content'],
                                                asn1Spec=pkcs7.SignedData())
        if rest: raise Asn1Error('Extra unparsed content.')

        digest_algorithm_oid = self.signed_data['digestAlgorithms'][0][
            'algorithm']
        self.digest_algorithm = oids.OID_TO_CLASS.get(digest_algorithm_oid)

        spc_blob = self.signed_data['contentInfo']['content']
        self.spc_info, rest = decoder.decode(
            spc_blob, asn1Spec=spc.SpcIndirectDataContent())
        if rest: raise Asn1Error('Extra unparsed content.')
        # Currently not parsing the SpcIndirectDataContent 'data' field.
        # It used to contain information about the software publisher, but now
        # is set to default content, or under Vista+, may hold page hashes.

        self.certificates = self._ParseCerts(self.signed_data['certificates'])

        self.signer_info = self.signed_data['signerInfos'][0]

        self.signing_cert_id = self._ParseIssuerInfo(
            self.signer_info['issuerAndSerialNumber'])

        # Parse out mandatory fields in authenticated attributes.
        self.auth_attrs, self.computed_auth_attrs_for_hash = (
            self._ParseAuthAttrs(self.signer_info['authenticatedAttributes'],
                                 required=[
                                     pkcs7.ContentType, pkcs7.DigestInfo,
                                     spc.SpcSpOpusInfo
                                 ]))
        hashval, rest = decoder.decode(self.auth_attrs[pkcs7.DigestInfo][0])
        if rest: raise Asn1Error('Extra unparsed content.')
        if hashval.__class__ is not univ.OctetString:
            raise Asn1Error('Hash value expected to be OctetString.')
        self.expected_spc_info_hash = str(hashval)

        opus_info_asn1 = self.auth_attrs[spc.SpcSpOpusInfo][0]
        self.program_name, self.program_url = self._ParseOpusInfo(
            opus_info_asn1)

        self.encrypted_digest = str(self.signer_info['encryptedDigest'])

        unauth_attrs = self.signer_info['unauthenticatedAttributes']
        if unauth_attrs is None:
            self.has_countersignature = False
            return

        self.has_countersignature = True
        self.counter_sig_info = self._ParseCountersig(unauth_attrs)
        self.counter_sig_cert_id = self._ParseIssuerInfo(
            self.counter_sig_info['issuerAndSerialNumber'])

        # Parse out mandatory fields in countersig authenticated attributes.
        self.counter_attrs, self.computed_counter_attrs_for_hash = (
            self._ParseAuthAttrs(
                self.counter_sig_info['authenticatedAttributes'],
                required=[
                    pkcs7.ContentType, pkcs7.SigningTime, pkcs7.DigestInfo
                ]))

        hashval, rest = decoder.decode(self.counter_attrs[pkcs7.DigestInfo][0])
        if rest: raise Asn1Error('Extra unparsed content.')
        if hashval.__class__ is not univ.OctetString:
            raise Asn1Error('Hash value expected to be OctetString.')
        self.expected_auth_attrs_hash = str(hashval)

        self.counter_timestamp = self._ParseTimestamp(
            self.counter_attrs[pkcs7.SigningTime][0])

        self.encrypted_counter_digest = str(
            self.counter_sig_info['encryptedDigest'])
Пример #2
0
    def __init__(self, content):
        self.container, rest = decoder.decode(content,
                                              asn1Spec=pkcs7.ContentInfo())
        if rest:
            self.trailing_data = rest

        self.signed_data, rest = decoder.decode(self.container['content'],
                                                asn1Spec=pkcs7.SignedData())
        if rest: raise Asn1Error('Extra unparsed content.')

        digest_algorithm_oid = self.signed_data['digestAlgorithms'][0][
            'algorithm']
        self.digest_algorithm = oids.OID_TO_CLASS.get(digest_algorithm_oid)

        spc_blob = self.signed_data['contentInfo']['content']
        self.spc_info, rest = decoder.decode(
            spc_blob, asn1Spec=spc.SpcIndirectDataContent())
        if rest: raise Asn1Error('Extra unparsed content.')
        # Currently not parsing the SpcIndirectDataContent 'data' field.
        # It used to contain information about the software publisher, but now
        # is set to default content, or under Vista+, may hold page hashes.

        self.certificates = self._ParseCerts(self.signed_data['certificates'])

        self.signer_info = self.signed_data['signerInfos'][0]

        self.signing_cert_id = self._ParseIssuerInfo(
            self.signer_info['issuerAndSerialNumber'])

        # Parse out mandatory fields in authenticated attributes.
        self.auth_attrs, self.computed_auth_attrs_for_hash = (
            self._ParseAuthAttrs(
                self.signer_info['authenticatedAttributes'],
                required=[pkcs7.ContentType, pkcs7.DigestInfo]))
        hashval, rest = decoder.decode(self.auth_attrs[pkcs7.DigestInfo][0])
        if rest: raise Asn1Error('Extra unparsed content.')
        if hashval.__class__ is not univ.OctetString:
            raise Asn1Error('Hash value expected to be OctetString.')
        self.expected_spc_info_hash = str(hashval)

        #spc.SpcSpOpusInfo might not there in real world
        #spc.SpcSpOpusInfo is used for program name and url. it can not be required in realworld
        if spc.SpcSpOpusInfo in self.auth_attrs:
            opus_info_asn1 = self.auth_attrs[spc.SpcSpOpusInfo][0]
            self.program_name, self.program_url = self._ParseOpusInfo(
                opus_info_asn1)
        else:
            self.program_name, self.program_url = None, None

        self.encrypted_digest = str(self.signer_info['encryptedDigest'])

        unauth_attrs = self.signer_info['unauthenticatedAttributes']
        if unauth_attrs is None:
            self.has_countersignature = False
            return

        knowns_unauth_attr = [
            oun for oun in unauth_attrs
            if oids.OID_TO_CLASS.get(oun[0]) is not None
        ]
        if len(knowns_unauth_attr) == 0:
            self.has_countersignature = False
            return

        target_unauth_attr = knowns_unauth_attr[0]
        #this is useless . for 1, 3, 6, 1, 4, 1, 311, 3, 3, 1 not in oids.OID_TO_CLASS.get
        #will keep it for futher remove
        if list(unauth_attrs[0][0]) == [1, 3, 6, 1, 4, 1, 311, 3, 3, 1]:
            # TODO: we will skip m$ timestamp for now. shell be fixed later
            # TODO: see what 1.3.6.1.4.1.311.2.4.1 is. which is unauthenticatedAttributes
            self.has_countersignature = False
            return

        self.has_countersignature = True
        self.counter_sig_info = self._ParseCountersig(target_unauth_attr)
        self.counter_sig_cert_id = self._ParseIssuerInfo(
            self.counter_sig_info['issuerAndSerialNumber'])

        # Parse out mandatory fields in countersig authenticated attributes.
        self.counter_attrs, self.computed_counter_attrs_for_hash = (
            self._ParseAuthAttrs(
                self.counter_sig_info['authenticatedAttributes'],
                required=[
                    pkcs7.ContentType, pkcs7.SigningTime, pkcs7.DigestInfo
                ]))

        hashval, rest = decoder.decode(self.counter_attrs[pkcs7.DigestInfo][0])
        if rest: raise Asn1Error('Extra unparsed content.')
        if hashval.__class__ is not univ.OctetString:
            raise Asn1Error('Hash value expected to be OctetString.')
        self.expected_auth_attrs_hash = str(hashval)

        self.counter_timestamp = self._ParseTimestamp(
            self.counter_attrs[pkcs7.SigningTime][0])

        self.encrypted_counter_digest = str(
            self.counter_sig_info['encryptedDigest'])