diff --git a/src/auto_archiver/modules/timestamping_enricher/__manifest__.py b/src/auto_archiver/modules/timestamping_enricher/__manifest__.py index 2c81dbb..c16502d 100644 --- a/src/auto_archiver/modules/timestamping_enricher/__manifest__.py +++ b/src/auto_archiver/modules/timestamping_enricher/__manifest__.py @@ -18,18 +18,17 @@ # See https://github.com/trailofbits/rfc3161-client/issues/46 for a list of valid TSAs # Full list of TSAs: https://gist.github.com/Manouchehri/fd754e402d98430243455713efada710 "http://timestamp.identrust.com", - "http://timestamp.ssl.trustwave.com", #timeouts + "http://timestamp.ssl.trustwave.com", "http://zeitstempel.dfn.de", "http://ts.ssl.com", - "http://tsa.izenpe.com", + # "http://tsa.izenpe.com", # self-signed "http://tsa.lex-persona.com/tsa", - "http://ca.signfiles.com/TSAServer.aspx", - "http://aloahacoin.chain-provider.com/tsa.aspx", - "http://tsa.sinpe.fi.cr/tsaHttp/", - "http://tsa.cra.ge/signserver/tsa?workerName=qtsa", + # "http://ca.signfiles.com/TSAServer.aspx", # self-signed + # "http://tsa.sinpe.fi.cr/tsaHttp/", # self-signed + # "http://tsa.cra.ge/signserver/tsa?workerName=qtsa", # self-signed "http://tss.cnbs.gob.hn/TSS/HttpTspServer", "http://dss.nowina.lu/pki-factory/tsa/good-tsa", - "https://freetsa.org/tsr", + # "https://freetsa.org/tsr", # self-signed ], "help": "List of RFC3161 Time Stamp Authorities to use, separate with commas if passed via the command line.", }, @@ -37,6 +36,12 @@ "default": None, "help": "Path to a file containing trusted Certificate Authorities (CAs) in PEM format. If empty, the default system authorities are used.", "type": "str", + }, + "allow_selfsigned": { + "default": False, + "help": "Whether or not to allow and save self-signed Timestamping certificates. This allows for a greater range of timestamping servers to be used, \ +but they are not trusted authorities", + "type": "bool" } }, "description": """ diff --git a/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py b/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py index 6f9aa56..1f376da 100644 --- a/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py +++ b/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py @@ -82,7 +82,10 @@ class TimestampingEnricher(Enricher): # fail if there's any issue with the certificates, uses certifi list of trusted CAs or the user-defined `cert_authorities` root_cert = self.verify_signed(signed, message) if not root_cert: - raise ValueError(f"No valid root certificate found for {tsa_url=}. Are you sure it's a trusted TSA? Or define an alternative trusted root with `cert_authorities`. (tried: {self.cert_authorities or certifi.where()})") + if self.allow_selfsigned: + logger.warning(f"Allowing self-signed certificat from TSA {tsa_url=}") + else: + raise ValueError(f"No valid root certificate found for {tsa_url=}. Are you sure it's a trusted TSA? Or define an alternative trusted root with `cert_authorities`. (tried: {self.cert_authorities or certifi.where()})") # save the timestamping certificate cert_chain = self.save_certificate(signed, root_cert) diff --git a/tests/enrichers/test_timestamping_enricher.py b/tests/enrichers/test_timestamping_enricher.py index 850096a..2f78551 100644 --- a/tests/enrichers/test_timestamping_enricher.py +++ b/tests/enrichers/test_timestamping_enricher.py @@ -29,6 +29,41 @@ def selfsigned_response() -> TimeStampResponse: def filehash(): return "4b7b4e39f12b8c725e6e603e6d4422500316df94211070682ef10260ff5759ef" +@pytest.mark.download +def test_enriching(setup_module, sample_media): + tsp: TimestampingEnricher = setup_module("timestamping_enricher") + + # tests the current TSAs set as default in the __manifest__ to make sure they are all still working + + # test the enrich method + metadata = Metadata().set_url("https://example.com") + sample_media.set('hash', "4b7b4e39f12b8c725e6e603e6d4422500316df94211070682ef10260ff5759ef") + metadata.add_media(sample_media) + tsp.enrich(metadata) + + +def test_full_enriching_selfsigned(setup_module, sample_media, mocker, selfsigned_response, filehash): + mock_post = mocker.patch("requests.sessions.Session.post") + mock_post.return_value.status_code = 200 + mock_decode_timestamp_response = mocker.patch("auto_archiver.modules.timestamping_enricher.timestamping_enricher.decode_timestamp_response") + mock_decode_timestamp_response.return_value = selfsigned_response + + tsp: TimestampingEnricher = setup_module("timestamping_enricher", {"tsa_urls": ["http://timestamp.identrust.com"]}) + metadata = Metadata().set_url("https://example.com") + sample_media.set('hash', filehash) + metadata.add_media(sample_media) + tsp.enrich(metadata) + + assert len(metadata.media) == 1 # doesn't allow self-signed + + # set self-signed on tsp + tsp.allow_selfsigned = True + + tsp.enrich(metadata) + + assert len(metadata.media) + + def test_full_enriching(setup_module, sample_media, mocker, timestamp_response, filehash): mock_post = mocker.patch("requests.sessions.Session.post") mock_post.return_value.status_code = 200 @@ -81,24 +116,6 @@ def test_full_enriching_multiple_tsa(setup_module, sample_media, mocker, timesta assert Path(timestamp_token_media.filename).read_bytes() == timestamp_response.time_stamp_token() assert len(timestamp_token_media.get('cert_chain')) == 3 - - - - - - - - - -def test_enriching(setup_module, sample_media): - tsp: TimestampingEnricher = setup_module("timestamping_enricher") - - # test the enrich method - metadata = Metadata().set_url("https://example.com") - sample_media.set('hash', "4b7b4e39f12b8c725e6e603e6d4422500316df94211070682ef10260ff5759ef") - metadata.add_media(sample_media) - tsp.enrich(metadata) - @pytest.mark.download def test_fails_for_digicert(setup_module): """