From fb33935c9b33ae114f8056d8783a58f5b3b69250 Mon Sep 17 00:00:00 2001 From: Timo Keller Date: Tue, 21 Jul 2026 18:08:38 +0200 Subject: [PATCH] pvsecret: test using hybrid keys Add unite tests and (binary) test asses for the hybrid key patch. Co-developed-by: Marc Hartmayer Signed-off-by: Marc Hartmayer Signed-off-by: Timo Keller Reviewed-by: Steffen Eiden Signed-off-by: Steffen Eiden --- rust/pv/src/uvsecret/asrcb.rs | 81 +++++++++ rust/pv/tests/add_secret_request.rs | 161 ++++++++++++++++++ .../exp/asrcb/assoc_derived_default_cuid_two | Bin 0 -> 2968 bytes .../exp/asrcb/assoc_none_default_cuid_two | Bin 0 -> 2968 bytes .../exp/asrcb/assoc_simple_default_cuid_two | Bin 0 -> 2968 bytes .../exp/asrcb/null_derived_default_cuid_two | Bin 0 -> 2936 bytes .../asrcb/null_none_default_cuid_seven_two | Bin 0 -> 13016 bytes .../exp/asrcb/null_none_default_cuid_two | Bin 0 -> 2936 bytes .../exp/asrcb/null_none_default_ncuid_two | Bin 0 -> 2936 bytes .../assets/exp/asrcb/null_none_dump_cuid_two | Bin 0 -> 2936 bytes .../exp/asrcb/null_simple_default_cuid_two | Bin 0 -> 2936 bytes 11 files changed, 242 insertions(+) create mode 100644 rust/pv/tests/assets/exp/asrcb/assoc_derived_default_cuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/assoc_none_default_cuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/assoc_simple_default_cuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/null_derived_default_cuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/null_none_default_cuid_seven_two create mode 100644 rust/pv/tests/assets/exp/asrcb/null_none_default_cuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/null_none_default_ncuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/null_none_dump_cuid_two create mode 100644 rust/pv/tests/assets/exp/asrcb/null_simple_default_cuid_two diff --git a/rust/pv/src/uvsecret/asrcb.rs b/rust/pv/src/uvsecret/asrcb.rs index f3516a26..73371889 100644 --- a/rust/pv/src/uvsecret/asrcb.rs +++ b/rust/pv/src/uvsecret/asrcb.rs @@ -528,3 +528,84 @@ impl Request for AddSecretRequest { Ok(()) } } + +#[cfg(test)] +mod test { + use super::*; + use crate::request::SeHdrVersion; + + #[test] + fn add_secret_version_v1() { + // Test V1 version constant + assert_eq!(AddSecretVersion::One as u32, 0x0100); + } + + #[test] + fn add_secret_version_v2() { + // Test V2 version constant + assert_eq!(AddSecretVersion::Two as u32, 0x0200); + } + + #[test] + fn add_secret_version_conversion_v1() { + // Test conversion from SeHdrVersion to AddSecretVersion for V1 + let v1: AddSecretVersion = SeHdrVersion::One.into(); + assert_eq!(v1, AddSecretVersion::One); + } + + #[test] + fn add_secret_version_conversion_v2() { + // Test conversion from SeHdrVersion to AddSecretVersion for V2 + let v2: AddSecretVersion = SeHdrVersion::Two.into(); + assert_eq!(v2, AddSecretVersion::Two); + } + + #[test] + fn add_secret_version_into_request_version() { + // Test conversion from AddSecretVersion to RequestVersion + let v1: RequestVersion = AddSecretVersion::One.into(); + assert_eq!(v1, 0x0100); + + let v2: RequestVersion = AddSecretVersion::Two.into(); + assert_eq!(v2, 0x0200); + } + + #[test] + fn add_secret_flags_default() { + // Test default flags have no bits set + let flags = AddSecretFlags::default(); + let uv_flags: UvFlags = flags.into(); + + // Default should have all bits cleared + assert_eq!(uv_flags.as_bytes(), &[0u8; 8]); + } + + #[test] + fn add_secret_flags_disable_dump() { + // Test disable dump flag sets bit 0 + let mut flags = AddSecretFlags::default(); + flags.set_disable_dump(); + + let uv_flags: UvFlags = flags.into(); + + // Bit 0 should be set, so bytes should not be all zeros + assert_ne!(uv_flags.as_bytes(), &[0u8; 8]); + } + + #[test] + fn req_auth_data_size() { + // Test ReqAuthData size constant + use std::mem::size_of; + + assert_eq!(size_of::(), 0x1e8); + } + + #[test] + #[cfg(any(debug_assertions, test))] + fn add_secret_version_inv_for_testing() { + // Test that invalid version exists for testing + assert_eq!(AddSecretVersion::Inv as u32, 0); + assert_ne!(AddSecretVersion::Inv, AddSecretVersion::One); + assert_ne!(AddSecretVersion::Inv, AddSecretVersion::Two); + } +} diff --git a/rust/pv/tests/add_secret_request.rs b/rust/pv/tests/add_secret_request.rs index b8dd2097..f24f663e 100644 --- a/rust/pv/tests/add_secret_request.rs +++ b/rust/pv/tests/add_secret_request.rs @@ -305,3 +305,164 @@ fn verify_no_user_data() { Ok(None) )) } + +// V2 tests (using hybrid keys) + +#[test] +fn null_none_default_ncuid_two_user_unsgn() { + let _guard = DeterministicTestRandGuard::install(&[0x42; 4096], &[0x11; 32]).unwrap(); + let user_data_orig = vec![0x56; 0x183]; + let (host_key, ctx) = get_crypto_v2(); + let mut asrcb = + AddSecretRequest::new(AddSecretVersion::Two, GuestSecret::Null, TAGS, no_flag()) + .expect("AddSecretRequest::new failed"); + + asrcb.add_hostkey(host_key).unwrap(); + asrcb.set_user_data(user_data_orig.clone(), None).unwrap(); + let asrcb = asrcb.encrypt(&ctx).unwrap(); + + let user_data = verify_asrcb_and_get_user_data(asrcb, None).unwrap(); + + assert_eq!( + user_data_orig.as_slice(), + &user_data.as_ref().unwrap()[..user_data_orig.len()] + ); +} + +#[test] +fn null_none_default_ncuid_two_user_ec() { + let _guard = DeterministicTestRandGuard::install(&[0x42; 4096], &[0x11; 32]).unwrap(); + let (usr_sgn_key, _) = get_test_keys(); + + let usr_vrfy_key = usr_sgn_key.ec_key().unwrap(); + let usr_vrfy_key = usr_vrfy_key.public_key(); + let usr_vrfy_key = PKey::from_ec_key( + EcKey::from_public_key( + &EcGroup::from_curve_name(Nid::SECP521R1).unwrap(), + usr_vrfy_key, + ) + .unwrap(), + ) + .unwrap(); + + let user_data_orig = vec![0x56; 0x100]; + let asrcb = create_signed_asrcb_v2(usr_sgn_key, user_data_orig.clone()); + + let user_data = verify_asrcb_and_get_user_data(asrcb, Some(usr_vrfy_key)).unwrap(); + assert_eq!( + user_data_orig.as_slice(), + &user_data.as_ref().unwrap()[..user_data_orig.len()] + ); +} + +#[test] +fn null_none_default_ncuid_two_user_rsa2048() { + let _guard = DeterministicTestRandGuard::install(&[0x42; 4096], &[0x11; 32]).unwrap(); + let usr_sgn_key = get_test_asset!("keys/rsa2048key.pem"); + let usr_sgn_key = PKey::private_key_from_pem(usr_sgn_key).unwrap(); + let user_data_orig = vec![0x56; 0x100]; + let asrcb = create_signed_asrcb_v2(usr_sgn_key, user_data_orig.clone()); + + let usr_vrfy_key = get_test_asset!("keys/rsa2048key.pub.pem"); + let usr_vrfy_key = PKey::public_key_from_pem(usr_vrfy_key).unwrap(); + + let user_data = verify_asrcb_and_get_user_data(asrcb, Some(usr_vrfy_key)).unwrap(); + assert_eq!( + user_data_orig.as_slice(), + &user_data.as_ref().unwrap()[..user_data_orig.len()] + ); +} + +#[test] +fn null_none_default_ncuid_two_user_rsa3072() { + let _guard = DeterministicTestRandGuard::install(&[0x42; 4096], &[0x11; 32]).unwrap(); + let usr_sgn_key = get_test_asset!("keys/rsa3072key.pem"); + let usr_sgn_key = PKey::private_key_from_pem(usr_sgn_key).unwrap(); + let user_data_orig = vec![0x56; 0x80]; + let asrcb = create_signed_asrcb_v2(usr_sgn_key, user_data_orig.clone()); + + let usr_vrfy_key = get_test_asset!("keys/rsa3072key.pub.pem"); + let usr_vrfy_key = PKey::public_key_from_pem(usr_vrfy_key).unwrap(); + + let user_data = verify_asrcb_and_get_user_data(asrcb, Some(usr_vrfy_key)).unwrap(); + assert_eq!( + user_data_orig.as_slice(), + &user_data.as_ref().unwrap()[..user_data_orig.len()] + ); +} + +#[test] +fn null_none_default_cuid_two() { + let _guard = DeterministicTestRandGuard::install(&[0x42; 4096], &[0x11; 32]).unwrap(); + let asrcb = gen_asrcb_v2(GuestSecret::Null, None, no_flag(), true).unwrap(); + let exp = get_test_asset!("exp/asrcb/null_none_default_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn assoc_none_default_cuid_two() { + let asrcb = gen_asrcb_v2(association(), None, no_flag(), true).unwrap(); + let exp = get_test_asset!("exp/asrcb/assoc_none_default_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn null_simple_default_cuid_two() { + let asrcb = gen_asrcb_v2(GuestSecret::Null, ext_simple(), no_flag(), true).unwrap(); + let exp = get_test_asset!("exp/asrcb/null_simple_default_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn assoc_simple_default_cuid_two() { + let asrcb = gen_asrcb_v2(association(), ext_simple(), no_flag(), true).unwrap(); + let exp = get_test_asset!("exp/asrcb/assoc_simple_default_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn null_derived_default_cuid_two() { + let asrcb = gen_asrcb_v2(GuestSecret::Null, ext_derived(), no_flag(), true).unwrap(); + let exp = get_test_asset!("exp/asrcb/null_derived_default_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn assoc_derived_default_cuid_two() { + let asrcb = gen_asrcb_v2(association(), ext_derived(), no_flag(), true).unwrap(); + let exp = get_test_asset!("exp/asrcb/assoc_derived_default_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn null_none_dump_cuid_two() { + let mut flags = no_flag(); + flags.set_disable_dump(); + let asrcb = gen_asrcb_v2(GuestSecret::Null, None, flags, true).unwrap(); + let exp = get_test_asset!("exp/asrcb/null_none_dump_cuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn null_none_default_ncuid_two() { + let asrcb = gen_asrcb_v2(GuestSecret::Null, None, no_flag(), false).unwrap(); + let exp = get_test_asset!("exp/asrcb/null_none_default_ncuid_two"); + assert_eq!(asrcb, exp); +} + +#[test] +fn null_none_default_cuid_seven_two() { + let _guard = DeterministicTestRandGuard::install(&[0x42; 4096], &[0x11; 32]).unwrap(); + let (hkd, ctx) = get_crypto_v2(); + let mut asrcb = + AddSecretRequest::new(AddSecretVersion::Two, GuestSecret::Null, TAGS, no_flag()) + .expect("AddSecretRequest::new failed"); + for _ in 0..7 { + asrcb.add_hostkey(hkd.clone()).unwrap() + } + asrcb.set_cuid(CUID); + let asrcb = asrcb.encrypt(&ctx).unwrap(); + + let exp = get_test_asset!("exp/asrcb/null_none_default_cuid_seven_two"); + assert_eq!(asrcb, exp); +} diff --git a/rust/pv/tests/assets/exp/asrcb/assoc_derived_default_cuid_two b/rust/pv/tests/assets/exp/asrcb/assoc_derived_default_cuid_two new file mode 100644 index 0000000000000000000000000000000000000000..4c7dd9e43ab5884407d1e25c84b8ea0bddcaf30a GIT binary patch literal 2968 zcmeH@S5Om(8igfvk_8h82thz0DzHe8Qk0G~k={cI3Mvbth#1NO0YcdTQY2&zhK`}v z1tlm&VNpUa2}Oa}D3OwYbk?2Oy>sur`gUi(nSajAng8W{J|TB}QJ0T=1MuyDxsLzE zpY308{FVCuDLB3lz<0v=opAjF!+-E?=bu7k{@xor9h!Pudd1rv1{1qmSX>c&RA$lg z#|FYu+gK4^@*er`zkl;z1OJBxdXO61qIOdz5kMKDX>mre^?Y5BY$t7UP1HXHwQj{w zdqwc#GYRmk3mkLHe8s!Qkobzb`s8f50}Lu`16>DT|JMnJevC`mT1l4;-d-C(K9BzN z*8kZVV1L}ThGK#ckb@TGzIK6c@i3vm}FgAYAl zXimRWh9en^*Ep&xj1`hRzL@cVFMpb=7JW+@723)$`}r5}!W{AJ0v-XVahW(^y@lJV z1wpL#K*O1aViB9Ef~I-qk<{RJyL=YlS8PUYmK1#kS-w&Nmugq`j4c5ruYekRR`VOF zp$ldYdUH13~IOTH!z?R?gKYE?T2=>&Pk4U&g@7KR;V+U?bow6qIFs&E38Z`M46 zLS^LWyie3_D4wXsopX^`u-!+YpPObnJmXPs0_f0`thwymppCvOT?Z#BB7Nk7!qQMt zrpxN>GJNB+*T_m$$(`1BX056z35+tb^4fEu47&4yP>x1Q`$vsfIleRSpZy)3#H}@1 z0UZ!OPWw^rz1cNh>hzOlA-KkK5PxpuutDx{kFD2g>dR%m?U}n61&zVUM%cE_2DBt? z5ohU|wDTwr^lL7qp23W~RU60nQY`9XLsy{NWZwfNd1;yq#aXy_?0?7vYDWq4ebB9A zTgZF3U(}xw8Dnsr5v_Z)oK*tj^5w!mvNOYr`Zc$&L#}611E2>kVkVnf^zFz^L=pRx z#l!K2dlxaAC zEVPD`Dlhl(H>?vNDRw^$;|BQYw6&Ymz^-?8l}#${kxPzXNGZ+f{!>I2(cz}l(&8PM z7#K z<&2eJmA3kfGE{A4H^nE0NH<3XA9fVE9kc&fPwT|oBipK~W_b70gs_Sj@gRrOHSd~- zBDhQ0!ma@2c}^s;$cV@U>zMd@$~5Zhhgkl&mZL}p%SF-RJviA%?Hk$+5(b5dU|q!V zeJ12_M%w2rfIBoJs*hE$5rmuSH(eSjOSvAum1jVpDMwM6$7;+~6nolb%Ni11;C~KOKns zjkO@Paaw_rCyD;liQYj2CHGMHFOla{Zr*Ku1GQX<7rv;d02+6mqm!}C9cwi>xvVWG z9_>-H;3Mas#2D{a&E=M*9QZ^qiW0k3Ra3SXH>`7T-6obXDcP;F-l^NLeCglk4{04p8(cAG$%{scqh2gA#k?JHdkXTztYsr2}#>~DyYCR zvw&9X=-rlb3oVNK%MZJzMaGOTmqH$GX8H_5H!emiUx}m36Ev74T@-};kjEhrpj2Km z)*CH01bDo(+I47!XuGX;zg8x|a{sVe9k<2w*> zo7~kOJp!ebLXv~BO(hT-x7(Cl4<^5MToNY8HmEXtYIoDULb^D^3s}>q{j#v)mBnR2 z5i@m?%U4UDH7K<;TUA64{WNVqkc2{5!6{mKeStYmL0a4rPfh|uIa{(Gg|l}jI7a55 zj^FPewR}^J6G0*eB!$BH?NI^hukq6gUf|T!-iQ0=$mPsZ4-XO7$TGhIXCD`ljT)I- zM*!{OdcO(GmlVE}Wp%feC1VF1R{6Y=rAgW&1)ezwO2&Ra5rb}@G2ixZZyAZ}r#6$i z%9VeJmewfTezB}XWZdtyX!HJpuKrh2BZ@)hPK3~rG literal 0 HcmV?d00001 diff --git a/rust/pv/tests/assets/exp/asrcb/assoc_none_default_cuid_two b/rust/pv/tests/assets/exp/asrcb/assoc_none_default_cuid_two new file mode 100644 index 0000000000000000000000000000000000000000..5724758c3a9d80f69046bbccf863998a87f80125 GIT binary patch literal 2968 zcmeH@X)qfIAI6DWvNR!-C|Xj*DuT3*mex^M)qO=A(b86_R+Ttb1t~UE&|pzFjjPT@ zMeAr;Epb=kXpy$+NP}SAwmY-?&in4yetTzsGyi#Jp80=yeqKR$y)lH@4tWZUjzS#271t%+hVqp#^FHO9Ft;VvDI8{fLteSVpYsH5wm8= zK)lZK;5YX3sr4UoO?}O`%8>k>aP{fwFnbtO#2UH=!2hokPJ;)|WveA!)){s>0PX6x;IH}Iu_xxV$nE9YX)O#~jg zztoy~r3yzg7O!zuR~RY9yL~m~1z(<@trmMv85Q0ln*Q`Ncwsi@^g;#_@XUGqfc+kB zg9w0F?tz9=FN%k6CJCA3nnm;nw%g{j0l(mhHEGiHX>>WO1TNjK>K|VrAZpgudtM4Hr43hAp{Ln|sgd_iQL_N?^VDSlQdIiM>a- zyf$%F4il|k+%!YaCMR5zfp$LcKDnYpLOVj9^MDlL?u8*on6`U$dD=RKqE!UJ%D1cT z0l~8JbiSvE8_LJ431^%o7i{)1*cT?L_Ro1W8UeaA6)SFAS7?JbtLxx+MTD1pKu9ts z(qvhqU6%jd%r&w~RYIrL-5JYjN*tq%th)L_m`Haz5GH9Rwtv=)mgheO|H;?EQNl`# z?biYE;j$a$*_&DA>z{hsBn;Pl0TRfJ7`~7>++*XhlJshse|!2KPDyicq5-z8y8$gp zUL;t!#P4M1f_}-Q)G?S5w`*b;UyH?@t?5d1>-77ecn>Y(p%`;i$Nr~OpiZO+|0liL zb#p~G)Omwx(J==1DY4q@<+KtQw>Ni2wykM~m`_vt8svIvzaR9#S=@M2o4y^fi7Z+_ zX+EBUP)U}jIV+eLI^#I``&aUY`xlscHZ_5jtyosKGFbgg`A7Dlr71QtcL%+DMuI!q zuuB@wYbm%=cbJhVe<;h0E5xA$z8d1W9cSxHC%IGjBDXAJk!LlS)ICpuK|<7{2HE-p z$U&9NTTfz!-N3=I&Jl4zkk;U+sZ~YRK$`47*a}e3~fQC<=EepURt~h z6UPqk#s_QFN@b;hO*IT^> zMj9)@t8Dcd64hcIWBZgkzo!KtZVG;F56&W5M=S=DoL3PmXD;xx^b-^v8!*t5H~221J*+x z+h;80Z>q4WFNa=BY-eTHCY-dOS~Stm3twJrW)DLOqi1RnA#~w?wxTCIY|hO zB%E%ZmKIb!L8vk~sdjmpT6Ej`^rx_obn@!Z&2RJ|r3ZV;WO(IinO3ld4F`Jt^FJ@u$Sq+Wly;^3mcwVdChXyD ztT=hFZvCXzzz(>C>BZHAh`oC_4!>{=>wzvs@cr4!~?HzM$yA=b@jyU#SJSGp}a?tx+xO83Jdh%c4ta+80{7H z3+kt)!Lwd#79w^gaj&`bHskCFz6``Dw&d>5vt2~L?Wj)iz@#;y38fg3jYnozIv>td zY?Gt&vn(!3f({x+KUL!M!bT^d$BqMQ9-EORNuF`8bO?N1ZJWCxT0mv;=D3v2eKm}K znW!qOV%~Y>J=*Iad)hjV{#Vk!`o*o85e#~qC5TH_C zGS(X(_d<>~oq&3HY>{ZZWqUdK(@brll_A^uT){ z{0_N`8Z`o?l|m8%(oH0hns?e%Tn;9F@3w@ z1%yx6N-bY4d0wy5)?`@`HFRsrZXh0mw1iW%bNl>BjRD#`l21cB=*BbI z+Z=#)3H@IM=Sm7c$g#WI$`bGc_AC4z2{L&)BL(gxB!#$7&B0;Yr_HwAP|YJT)c&Tt zu5#5MVt8YHv8VQSb{+POE{+_%u12ak-&=t03w@P0*yH(;b&T~OM<_-Dmb<;b(~%yh zoA`!h!8+NAgWl)?_6W!34hB`loNj8Gk jQ8f=3FYx-H5JWHvy~XL@5_I0aPk+HSv9APK&$9mm&2-C% literal 0 HcmV?d00001 diff --git a/rust/pv/tests/assets/exp/asrcb/assoc_simple_default_cuid_two b/rust/pv/tests/assets/exp/asrcb/assoc_simple_default_cuid_two new file mode 100644 index 0000000000000000000000000000000000000000..a4b8274f20acc8300fb475e56c7c2a9c61ebb9ff GIT binary patch literal 2968 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 literal 0 HcmV?d00001 diff --git a/rust/pv/tests/assets/exp/asrcb/null_none_default_cuid_seven_two b/rust/pv/tests/assets/exp/asrcb/null_none_default_cuid_seven_two new file mode 100644 index 0000000000000000000000000000000000000000..af2d2a64fac8db8d74530f0fcf28e2c2ab6e1d74 GIT binary patch literal 13016 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 TURYqB0?~%!`m(h2wr1cTvRkah literal 0 HcmV?d00001 diff --git a/rust/pv/tests/assets/exp/asrcb/null_none_default_ncuid_two b/rust/pv/tests/assets/exp/asrcb/null_none_default_ncuid_two new file mode 100644 index 0000000000000000000000000000000000000000..c6e4b41af173d47b55193004ef82adb747d33659 GIT binary patch literal 2936 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 V7n0vkwZFNEJ~v(Qw7u za^;2~b+`bk-Z1XYI)oy&YBDc~vpPCEbaaIBjORNe`?03iJD za3bb6yvhV6Os5=IV*vda?(@6g=Ldmo{Ds-*B*14rPd-+B#~74bA=~`? z3wU~xdU!eq1$g2$yd``GcSeLk95z7xnWvQEmT$>g=h?=yB3fMXg@9iPN@B1>sV24yRwhy3pt3Crbwb_D7k_*0W4)XuxuErTa+J7c?^FSO)RJUTE9%4y}1(3dRHSTpXkg_brUx z#dq1Lp&1z$DpZnWD&7cu!=ltRxsneNmk#ZFOgieNJng)R#l5i3bbBswq#j_x(RCDa zIR~u^oMUe7dlVm_85W&^O|YIl(xNW)cH#nEx02ZAcy+?zF(Z{%M%NR(kRx+Fx8x|u z^p;P^Bu%M<@SlU-Jz$Q8!jM)-kf`gR_{M}lk~Q|QK@N_50g}EK-+%I6f2XtG{H^v` zsnzjo$vVj1kvf%ClOciXlv~GUP1R5vEOMNu0UbNFj`ExeLNq*(K`e%3VK)VV66q6s(GaR_X1 zwETl`+rb8xkhg|eKME5|vS6ygB^+etYqoRJHMiCIsfEct(%&oyVjh#VrK4hZBokKb zQ&7i_@Yx&w(!Hd_+jZ)-Taf9dSX#xIZt2>ETu8dh&VEvlG?yc|%nD_`cd4k?_lciz z2SZ9Z9x=~QSyZ>nYBOK2swm<5*VCd5t5tLFfURG!Rc`9=4hTKUfo3m*ywSv9lZ@Fn z)X&>$;vR-34)r6Ai%`UQ8)t0meq#%Y9Jr7ZJ@f{l^5FO-Le6iN!FD|$@glVjRc-A6 z%=%EO_GFDkzI#fhNLQf2GZo5E2|;(I+k$N1tg#Fm?xS5El)c+pbZ)onry5RM@^!ki zfdSc{&5PKwtGbbMr|1e+eju=wQtR zP6}FdahGdt%gNMUc`DcxwP%wLc|gwik_GUAk`uax1xsP1QMUEWKw0|5l$E@bxg5O& z7N0l<`;gftL+_gKiq;~CjRdY3gH%ggzexpj-EXerp97#6B=3tPe__sD;^TYgEkR6jy=3#xmh`RuPl8lAdXjbv%|n3ef8^-BZXAn zsm)%Nj}oXv1c~|b)pl5J6tQH?GPB^huaJd^wbA5PqNdBKuB2cdVh~qy^_NK|Ib=1l zO)28mg6xP6UViDe?b)`Q6OUHuN%^_Nze1 zzNo({R+l8LJ9>Fo)%m(UHnhwpq{%UHy|LWRh~d-zaoxJelK1U&IXl20?mLg;rT+-?GN%S(p35|#P@4`$|>+YYGaD~L;4jOqA+Z{6y;yLpse z&M!ry6};oif(kqXycCw6sE6+Ww7|@s%1o6MzSj_TG?x(xJ#O<-e#E^rHMLxWB=j%bDchC7mX?X=h-LaaB|PRDOpe<62bXWFr~m)} literal 0 HcmV?d00001