def test_bool_dunders(): bool_true = generic.BooleanObject(True) bool_false = generic.BooleanObject(False) assert bool_true != bool_false assert bool_true != '' assert bool_false != '' assert bool_true assert not bool_false assert bool_true == bool(bool_true) assert bool_false == bool(bool_false) assert repr(bool_true) == str(bool_true) == 'True' assert repr(bool_false) == str(bool_false) == 'False'
def test_tamper_sig_obj(policy, skip_diff): w = IncrementalPdfFileWriter(BytesIO(MINIMAL)) meta = signers.PdfSignatureMetadata(field_name='Sig1') out = signers.sign_pdf(w, meta, signer=FROM_CA) w = IncrementalPdfFileWriter(out) sig_obj = w.prev.embedded_signatures[0].sig_object sig_obj['/Bleh'] = generic.BooleanObject(False) w.update_container(sig_obj) w.write_in_place() r = PdfFileReader(out) emb = r.embedded_signatures[0] status = validate_pdf_signature(emb, diff_policy=policy, skip_diff=skip_diff) if skip_diff: assert emb.diff_result is None else: assert isinstance(emb.diff_result, SuspiciousModification) assert status.coverage == SignatureCoverageLevel.CONTIGUOUS_BLOCK_FROM_START assert status.modification_level == ModificationLevel.OTHER
def test_sv_deserialisation(): sv_input = generic.DictionaryObject({ pdf_name('/SubFilter'): generic.ArrayObject( map(pdf_name, ['/foo', '/adbe.pkcs7.detached', '/bleh'])), pdf_name('/LegalAttestation'): generic.ArrayObject(['xyz', 'abc', 'def']), pdf_name('/AppearanceFilter'): generic.pdf_string('blah'), pdf_name('/LockDocument'): generic.pdf_name('/true') }) sv = fields.SigSeedValueSpec.from_pdf_object(sv_input) assert len(sv.subfilters) == 1 assert len(sv.legal_attestations) == 3 assert sv.lock_document == fields.SeedLockDocument.LOCK sv_output = sv.as_pdf_object() assert sv_output['/AppearanceFilter'] == sv_input['/AppearanceFilter'] assert sv_output['/LockDocument'] == sv_input['/LockDocument'] assert sv_output['/LegalAttestation'] == sv_input['/LegalAttestation'] with pytest.raises(SigningError): fields.SigSeedValueSpec.from_pdf_object( generic.DictionaryObject( {pdf_name('/LockDocument'): generic.pdf_name('/nonsense')})) fields.SigSeedValueSpec.from_pdf_object( generic.DictionaryObject( {pdf_name('/LockDocument'): generic.BooleanObject(True)})) bad_filter = generic.DictionaryObject( {pdf_name('/Filter'): pdf_name('/unsupported')}) # this should run fields.SigSeedValueSpec.from_pdf_object(bad_filter) with pytest.raises(SigningError): bad_filter[pdf_name('/Ff')] = \ generic.NumberObject(fields.SigSeedValFlags.FILTER.value) fields.SigSeedValueSpec.from_pdf_object(bad_filter)
def as_pdf_object(self): """ Render this :class:`.SigSeedValueSpec` object to a PDF dictionary. :return: A :class:`~.generic.DictionaryObject`. """ result = generic.DictionaryObject({ pdf_name('/Type'): pdf_name('/SV'), pdf_name('/Ff'): generic.NumberObject(self.flags.value), }) if self.subfilters is not None: result[pdf_name('/SubFilter')] = generic.ArrayObject( sf.value for sf in self.subfilters) if self.add_rev_info is not None: result[pdf_name('/AddRevInfo')] = generic.BooleanObject( self.add_rev_info) if self.digest_methods is not None: result[pdf_name('/DigestMethod')] = generic.ArrayObject( map(pdf_string, self.digest_methods)) if self.reasons is not None: result[pdf_name('/Reasons')] = generic.ArrayObject( pdf_string(reason) for reason in self.reasons) if self.timestamp_server_url is not None: result[pdf_name('/TimeStamp')] = generic.DictionaryObject({ pdf_name('/URL'): pdf_string(self.timestamp_server_url), pdf_name('/Ff'): generic.NumberObject(1 if self.timestamp_required else 0) }) if self.cert is not None: result[pdf_name('/Cert')] = self.cert.as_pdf_object() return result
def as_pdf_object(self): """ Render this :class:`.SigSeedValueSpec` object to a PDF dictionary. :return: A :class:`~.generic.DictionaryObject`. """ min_version = SeedValueDictVersion.PDF_1_5 result = generic.DictionaryObject({ pdf_name('/Type'): pdf_name('/SV'), pdf_name('/Ff'): generic.NumberObject(self.flags.value), }) if self.subfilters is not None: result[pdf_name('/SubFilter')] = generic.ArrayObject( sf.value for sf in self.subfilters) if self.add_rev_info is not None: min_version = SeedValueDictVersion.PDF_1_7 result[pdf_name('/AddRevInfo')] = generic.BooleanObject( self.add_rev_info) if self.digest_methods is not None: min_version = SeedValueDictVersion.PDF_1_7 result[pdf_name('/DigestMethod')] = generic.ArrayObject( map(pdf_string, self.digest_methods)) if self.reasons is not None: result[pdf_name('/Reasons')] = generic.ArrayObject( pdf_string(reason) for reason in self.reasons) if self.timestamp_server_url is not None: min_version = SeedValueDictVersion.PDF_1_7 result[pdf_name('/TimeStamp')] = generic.DictionaryObject({ pdf_name('/URL'): pdf_string(self.timestamp_server_url), pdf_name('/Ff'): generic.NumberObject(1 if self.timestamp_required else 0) }) if self.cert is not None: result[pdf_name('/Cert')] = self.cert.as_pdf_object() if self.seed_signature_type is not None: mdp_perm = self.seed_signature_type.mdp_perm result[pdf_name('/MDP')] = generic.DictionaryObject({ pdf_name('/P'): generic.NumberObject( mdp_perm.value if mdp_perm is not None else 0) }) if self.legal_attestations is not None: result[pdf_name('/LegalAttestation')] = generic.ArrayObject( pdf_string(att) for att in self.legal_attestations) if self.lock_document is not None: min_version = SeedValueDictVersion.PDF_2_0 result[pdf_name('/LockDocument')] = self.lock_document.value if self.appearance is not None: result[pdf_name('/AppearanceFilter')] = pdf_string(self.appearance) specified_version = self.sv_dict_version if specified_version is not None: result[pdf_name('/V')] = generic.NumberObject( specified_version. value if isinstance(specified_version, SeedValueDictVersion ) else specified_version) else: result[pdf_name('/V')] = generic.NumberObject(min_version.value) return result