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'])
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'])