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() # 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): # The data attribute self.content_type = asn1.oids.OID_TO_CLASS.get( self.data['data']['type']) self.image_data = None if 'value' in self.data['data'] and self.data['data']['value'].isValue: self.image_data = None # TODO: not parsed #image_data = _guarded_ber_decode((self.data['data']['value'], asn1_spec=self.content_type()) self.digest_algorithm = _get_digest_algorithm( self.data['messageDigest']['digestAlgorithm'], location="SpcIndirectDataContent.digestAlgorithm") self.digest = bytes(self.data['messageDigest']['digest'])
def _parse(self): super()._parse() self.subject_usage = self.content['subjectUsage'][0] self.list_identifier = bytes( self.content['listIdentifier'] ) if self.content['listIdentifier'].isValue else None self.sequence_number = self.content['sequenceNumber'] self.this_update = time_to_python(self.content['ctlThisUpdate']) self.next_update = time_to_python(self.content['ctlNextUpdate']) self.subject_algorithm = _get_digest_algorithm( self.content['subjectAlgorithm'], location="CertificateTrustList.subjectAlgorithm") self._subjects = {} for subj in (CertificateTrustSubject(subject) for subject in self.content['trustedSubjects']): self._subjects[subj.identifier.hex().lower()] = subj
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): # digestAlgorithms if len(self.data['digestAlgorithms']) != 1: raise ParseError( "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") # contentType if isinstance(self.data, rfc2315.SignedData): self.content_type = asn1.oids.get( self.data['contentInfo']['contentType']) content = self.data['contentInfo']['content'] elif isinstance(self.data, rfc5652.SignedData): self.content_type = asn1.oids.get( self.data['encapContentInfo']['eContentType']) content = self.data['encapContentInfo']['eContent'] else: raise ParseError("Unknown SignedData data type {}".format( _print_type(self.data))) if self.content_type is not self._expected_content_type: raise ParseError("SignedData.contentInfo does not contain %s" % _print_type(self._expected_content_type)) # Content self.content = guarded_ber_decode( content, asn1_spec=self._expected_content_type()) # Certificates self.certificates = CertificateStore([ Certificate(cert) for cert in self.data['certificates'] if Certificate.is_certificate(cert) ]) # SignerInfo if self._signerinfo_class is not None: self.signer_infos = [ self._signerinfo_class(si) for si in self.data['signerInfos'] ]
def test_null_parameters(self): sha1 = DigestAlgorithmIdentifier() sha1['algorithm'] = (1, 3, 14, 3, 2, 26) sha1['parameters'] = "\x05\0" # null value self.assertEqual(_get_digest_algorithm(sha1, location="test"), hashlib.sha1)
def test_acceptable_oid(self): sha1 = DigestAlgorithmIdentifier() sha1['algorithm'] = (1, 3, 14, 3, 2, 26) self.assertEqual(_get_digest_algorithm(sha1, location="test"), hashlib.sha1)