From 396ec03bae2c1dfb5b3dc31f239ef00665c414ef Mon Sep 17 00:00:00 2001 From: Patrick Robertson Date: Mon, 24 Mar 2025 15:26:22 +0400 Subject: [PATCH] Tidy up unit tests further + make more non-download --- .../timestamping_enricher.py | 3 -- tests/conftest.py | 2 +- tests/data/timestamping/digicert.tsr | Bin 0 -> 6012 bytes tests/enrichers/test_timestamping_enricher.py | 26 ++++++++++-------- 4 files changed, 15 insertions(+), 16 deletions(-) create mode 100644 tests/data/timestamping/digicert.tsr diff --git a/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py b/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py index 756c1c9..93d3ae8 100644 --- a/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py +++ b/src/auto_archiver/modules/timestamping_enricher/timestamping_enricher.py @@ -78,7 +78,6 @@ class TimestampingEnricher(Enricher): try: message = bytes(data_to_sign, encoding='utf8') - print(tsa_url) logger.debug(f"Timestamping {url=} with {tsa_url=}") signed: TimeStampResponse = self.sign_data(tsa_url, message) @@ -118,8 +117,6 @@ class TimestampingEnricher(Enricher): f.write(timestamp_token) return tst_path - trust_roots = [] - with open(certifi.where(), "rb") as f: def verify_signed(self, timestamp_response: TimeStampResponse, message: bytes) -> x509.Certificate: """ Verify a Signed Timestamp Response is trusted by a known Certificate Authority. diff --git a/tests/conftest.py b/tests/conftest.py index a9f9ff8..44d8058 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -145,7 +145,7 @@ def sample_media(tmp_path) -> Media: """Fixture creating a Media object with temporary source file""" src_file = tmp_path / "source.txt" src_file.write_text("test content") - return Media(key="subdir/test.txt", filename=str(src_file)) + return Media(_key="subdir/test.txt", filename=str(src_file)) @pytest.fixture diff --git a/tests/data/timestamping/digicert.tsr b/tests/data/timestamping/digicert.tsr new file mode 100644 index 0000000000000000000000000000000000000000..1648bdb4086e7dcce70041df967f3ba59efd817f GIT binary patch literal 6012 zcmchbc|6oz`^U{<-*;KZzVjV>WSx;EvW-0?QnoC!kliFp_GB%LvPMEhp)8SIvWqBd zqDV@T`i;tc>wfOv?|z=w@AZ1-ukShMI_F&1e7~RbKGy}{*#iLx7(@c#*?q_;C8G7C zw`f7+U;>`~B(duR7zBaS1GHq6C!_U2ry)=q`EF`1;Wl6~Zf)XOHKqFIu$Rscb z^wThU*NYqknEhoQRBOktm?Yn)U{mcj#)GoQiGeZD8StEdl77~adg24>bm2Qo8_2KC;Pqvq#bMnwV z2Y&?uq9z9B0;dKj$sm?cGG?%)1)LpV-D^-W(;?l@xFb&cW29gP=UimqYQW*W0SL3) z{s0W+k40lnyTbGoVCELu3cz6{n1#N!oT3s8wfMG451D1veU{D$K{lO zA3r;GT6sk{TuxC=Uh%NvVLL$QcPAJD`kziv?C%AK0lYuAXW#Gou?c!_6BzOTPyp~? zfrGJuNJ$`gFg@`lgQ>uH;@f`YfzJPw&R?DZ)Z2S6+TOVLdN-Aiqb*j=BYUo>WtR$o zA($Rfv|)}0G{vvnf-ju+Hn4G)tdx%*$fF(zO4qZNKc+T}xTd?NL80TmgTbkFi>(#V zy-V_zSrKl3zN>Rv>1>HOWTN`h0i%*z&sPn72png8wvXoJ9 zQQq^1w##O=$&ZXI-uLB9!tUC1heY+%5007*h}l^`N{kNNT7`2MhnoeChD2S+3XWY^ z`|^2g;5Oq${fe*(Wn;OHWcz|+m03=wCNx>@7nE#G*N5_2ztLw;4mxZTsE1lhBol|I z85EiGVJ4wXjITr3Ka#q0VxL|qLB3ko&ri{2!-h#h-Xlk7CChBmyzbcwl-57u7ka@Y zXUM7O#NPvh#D)4jIAZ9I#*POv?zC5?8|SX5pdI7l#M{r%+`3{0loXehE;C>@G zUqE;jf8B*=`jq#U`{HV+V;=nw>3qbb2E|&dd$WfHGB9n8{|%WiE{~L=Q_^8DBcz{p z@a+Q?Eg8mJUEQL7_Q`_HoUtO;MFL**>2bXnDJe6Ub42PkH+Z3FbQ?V?+O?EKZjT;U zT2hi@>5W(BSJYWHH6&TKfByENH3i?j+gy_pr{07n_wI^XzVTu+5l!#O2p2il%a%RR zbB%EK9ux!65x*uLdJyP46bb>8M*uW?ZRWi;7$5=I z_FBSwEgFD|j6#wOL`q5yp#Wfe{V?bufE}P9BRdmG10tGJA3Ol~_ACUU8~|GcOFi3! zxA8?;v^XwD7MtJ!OU~=`0eJQd=%8#+mV9d|NC2G}Yl>Tui{m?!%X~P3Jz%#t%m=j~ zo+Ks&W5Tg$gR>Znud1x9i@%q=j4M%-E<{brxcGR>?hE0U4D}R#iSVZe4@wZBEkm3R zM5gSA0s=uJF94AdfY5#q0E*`LwUdtv+V{7e0GmIoz|ltg{y6VBg8t3$KXnOnP_V?q zh$vVPiTW*GK3ul_oJtgv-UK4`6XWF7;}ks4#7v$JO$A3D6LBmL9E?xRJnyp8CQx7{ zF)b$EdS{Ky&7smV(nou(OkLp`DieQNlIDiFPC*(jtE1}cBkAHIV{Zv7wP7-L@?K_{ zySy=d%Z}Kp*4`7tJz=aKca|D2mY3PVBn=Zbz|Jw>Z_;Q{VAi@*V=82YMpW^E=T#f< znkW|VNArd_3Dgp$Rlb6AqBN|5MAd|Y8vk4924x& z#gxAIbfsSZ0`vZJ+yO^lb250m+m;ZtkI~b(SZ>b#Rw-3yK5T$7sW+<7zkrOmSx_f_cUpIU*d$MvDuH{=SK-Ao(;s+k#C9X1*M zflL`+$Nde{w5#YEqvO^fswvnn_mT6WnI(Xq(p3!x0LRIgDZM#p51xQvMr^46|XTOAgxE4np zp39dx+>Lt9_#Rz-=bdCk)FlCqnU&}2ZS3LYha@$0rp_e2 zF;ib3wHjU$lU^CBzK31nBRidVMSN&t)qQ3nCFUqe@FY?@ZYspXI%r+_e7-|P&+91H zyXG4>y)EYphh8|{MN#vgJ*UjypjF{iGi?~!|M4)>nKim17q9u^cAh>Z+7ly-T%|3p z7_E|K|MvRheAV}CjL&}?OGc+vNFAOn(jQ%~f-{#{i)V<+e2ghhK8|Cx6!Fax2`6ys z!4Pu@mxy5OIZ@%1EL9c8JD)z~EvnhCMotT`OyDItE;kXT=QOUPzbx_Dd0p8sPiK_0 z!DxwX436!>oP;9d>FhN3{1RGrETwWHx()iSh zsnO)6#I2S)9L3I_ykSEL5+k9DLcQx>cIb2jm>wR@yElY;Fi7W_O*1Hex37AiZw^Gh z*#b;^9QnaB3V@6Vvc2o>pXm8pG95(M>ew89(9gluXh!CY=2CrDB{#jv@5}^6|4|)(f0HoU`?COWwBmn2m_3E+DG=#~0T6o;^FfaQs(=bXiJ%ZIx4+Im zk@Js5y#5Wq|9*Y`L99^Qq~^3*pR6*Z04U6Dbev!3RTYN}gE8|{z@op2W2eK^VfL8# zj_)Pfo8s>Q_FIAK5L9rGm$CaeHI(^t!s;nQYnbc%@M*Al#qsuBjKW^h&8FV+bUzIaajH?hKgGsx#WjC{k(VG|Ayd~W>Gw{GFz0ZT!>esrEXec zpc-Y3#T&xtYsFcX04{I>*p?IbHX~T;f?Af;6zU#_OStK(s;?-~G8Tz@PB4FKDtz|AdZH2f1wSn}1C3iJ>2qk^ z9uN#Cp`OQqMJCoy<8+F}V<`0`7sELVFVcU_%J^i7lH`l{(!4<@xiGp@CW~Y>Tw<$u(hL~}k{{Iq72oU&5 zEUrI@rHw{o{fViV0TT8DTEB8GIY0$~{|PN(zDP{Me&t;M4RHPwvziuD&}XL`<{b== z00Mx!{Az27uuK=f`o^Vk+tyd&CF(ZixSYPqV6G_IHh}K~SD^~qiq(@$Z=Uj+^Bdia zgY!u@;3r$}h8Kv$gcUeKyUvwWc1M?SYoN@{9q=ATxviKpwS-QSL9mw0iF7#Zr0ZM zD4Qf2$vTq~V8ZHMcd*0Utu7PC1;r(J&+|0LsifqH=e4O>S}Err2X@p}x83vLP=PQc zjt?sr%8-V}e#C1qr23Xy;WN-hZ2A<%6?6^_i2*J`2|vok1c zT`VJ+Lk{pEEgF1H*^_w+H| zB|4YN#o@KfmsRuBr%2{?h2v^-kcTA0ny=g)boO46pJ<;s1|{hY0us;RMcu?r-Le-5;eOThqM`)>=zhJSK#g4{%iu2Ga*J;O_x=Er#6_Gr%!cx zbi7IHsIF5k>}vsUdvo&j>M$yi?2q&AvRORRA1BIccow+!nWai(meP-;|0lCZ0SJ*< z2Y~grJUR$0-IeRNH!t_#;nHUDB_;g1AG|y1{{>j*_bEeUlQ-b`Z?XxoKa0pF<$b37 zU)j$uF&ZHEr1&HE!T`EI>7)S=`9vV{DOzEFrT>*q|GJD9z__;z3`zwMsZItZK9c<9 zbb;VOAQE3f6XJyBl8O`I28K($mThdS$(sCOPDMeC)apgYGR_8p&oP|tD1osx> zIaxND4TEH*>r~b@zehayT(Gs_KP}W~4(U8TATj+#+Un`{=2is|loMa$IQ;Y(0(lj| zzmnl!pno^JC)cEe48j~BiX2`Fe{Ea3-Xu$1yu6`sWOWPD5mP#7q;*K~sE0eM>VAP$ z(rV#|`s?bcUGDMC0J{^Y1fR76Q}wSn%Ck}VKHZbBM8%WbU`P+Fs=|gqr{&U~CD2l1 z`_a<#sc5+uuHQ#cdNa(=L(o&;JJWrXv}oA4>co0&OvbMLvlA5@kB#%ub)d3*>zj^Z zvk$Jo@sJDv54lV%&H(}cl?vD2*Vzsf5DAg*0nR@vZa^0zG;lmNVL5!pnT9+7A^*e07POyVK`iV z>4u9eAA(v{5U3or!hRb=Pm+$Fen6U*g-Fhs1Wf+)0SecFYK2oIC}T^F^?EJt*Nhj9 zA--xUp2FDztC)A2Yp>L`gp5}`2dGsL&icxy6j~Urer_O<7s=8-{vs2*)8BZm{kQC% zSdN3@!6a;_⪚iW3DDi@Xl(!?A)rDY{d-DA@5Io%N=$A+Aeo^y2D!iOjK(j16S>)QuQHvgL%xF@#WD_S|l4cHl-MMTKRG9ikMw0^^|A>Ri`4e&oh*l)p4*SVewfVH*&4A+Muw8 zTk&?PXN#$JU(zx%mhL@^U$0cptul`;g^916*B{0^nx>DlR7o z`+R)S99pYGP8FDwbHlsR|Pdrm8f IWWDZx01j4BE&u=k literal 0 HcmV?d00001 diff --git a/tests/enrichers/test_timestamping_enricher.py b/tests/enrichers/test_timestamping_enricher.py index 706678d..22cab06 100644 --- a/tests/enrichers/test_timestamping_enricher.py +++ b/tests/enrichers/test_timestamping_enricher.py @@ -29,6 +29,12 @@ def selfsigned_response() -> TimeStampResponse: return decode_timestamp_response(f.read()) +@pytest.fixture +def digicert_response() -> TimeStampResponse: + with open("tests/data/timestamping/digicert.tsr", "rb") as f: + return f.read() + + @pytest.fixture def filehash(): return "4b7b4e39f12b8c725e6e603e6d4422500316df94211070682ef10260ff5759ef" @@ -65,7 +71,6 @@ def test_full_enriching_selfsigned(setup_module, sample_media, mocker, selfsigne # set self-signed on tsp tsp.allow_selfsigned = True - tsp.enrich(metadata) assert len(metadata.media) @@ -131,12 +136,15 @@ def test_full_enriching_multiple_tsa(setup_module, sample_media, mocker, timesta assert len(timestamp_token_media.get("cert_chain")) == 3 -@pytest.mark.download -def test_fails_for_digicert(setup_module): +def test_fails_for_digicert(setup_module, mocker, digicert_response): """ Digicert TSRs are not compliant with RFC 3161. See https://github.com/trailofbits/rfc3161-client/issues/104#issuecomment-2621960840 """ + mocker.patch("requests.sessions.Session.post", return_value=requests.Response()) + mocker.patch("requests.Response.raise_for_status") + mocker.patch("requests.Response.content", new_callable=mocker.PropertyMock, return_value=digicert_response) + tsa_url = "http://timestamp.digicert.com" tsp: TimestampingEnricher = setup_module("timestamping_enricher") @@ -191,16 +199,10 @@ def test_order_crt_correctly(setup_module, wrong_order_timestamp_response): assert ordered_certs[1].subject.rfc4514_string() == "CN=TrustID Timestamping CA 3,O=IdenTrust,C=US" -def test_invalid_tsa_404(setup_module, mocker): - tsp = setup_module("timestamping_enricher") - post_mock = mocker.patch("requests.sessions.Session.post") - post_mock.side_effect = Exception("error") - with pytest.raises(Exception, match="error"): - tsp.sign_data("http://bellingcat.com/", b"my-message") - - -@pytest.mark.download def test_invalid_tsa_invalid_response(setup_module, mocker): + mocker.patch("requests.sessions.Session.post", return_value=requests.Response()) + raise_for_status = mocker.patch("requests.Response.raise_for_status") + raise_for_status.side_effect = requests.exceptions.HTTPError("404 Client Error") tsp = setup_module("timestamping_enricher") with pytest.raises(requests.exceptions.HTTPError, match="404 Client Error"):