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]
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])
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)
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.")
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.")
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()
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