tor-dirmgr: Test for GetCertsState
This commit is contained in:
parent
8956e6cd8b
commit
7e8891b861
|
@ -744,6 +744,8 @@ mod test {
|
|||
atomic::{self, AtomicBool},
|
||||
Arc,
|
||||
};
|
||||
use time::macros::datetime;
|
||||
use tor_netdoc::doc::authcert::AuthCertKeyIds;
|
||||
|
||||
struct DirRcv {
|
||||
cfg: DirMgrConfig,
|
||||
|
@ -796,24 +798,53 @@ mod test {
|
|||
|
||||
// Test data
|
||||
const CONSENSUS: &str = include_str!("../testdata/mdconsensus1.txt");
|
||||
const AUTHCERT_5696: &str = include_str!("../testdata/cert-5696.txt");
|
||||
const AUTHCERT_5A23: &str = include_str!("../testdata/cert-5A23.txt");
|
||||
#[allow(unused)]
|
||||
const AUTHCERT_7C47: &str = include_str!("../testdata/cert-7C47.txt");
|
||||
fn test_time() -> SystemTime {
|
||||
time::macros::datetime!(2020-08-07 12:42:45 UTC).into()
|
||||
datetime!(2020-08-07 12:42:45 UTC).into()
|
||||
}
|
||||
fn rsa(s: &str) -> RsaIdentity {
|
||||
let k = hex::decode(s).unwrap();
|
||||
RsaIdentity::from_bytes(&k[..]).unwrap()
|
||||
}
|
||||
fn test_authorities() -> Vec<Authority> {
|
||||
fn a(s: &str) -> Authority {
|
||||
let k = hex::decode(s).unwrap();
|
||||
Authority::builder()
|
||||
.name("ignore")
|
||||
.v3ident(RsaIdentity::from_bytes(&k[..]).unwrap())
|
||||
.v3ident(rsa(s))
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
vec![
|
||||
a("5696AB38CB3852AFA476A5C07B2D4788963D5567"),
|
||||
a("5A23BA701776C9C1AB1C06E734E92AB3D5350D64"),
|
||||
a("7C47DCB4A90E2C2B7C7AD27BD641D038CF5D7EBE"),
|
||||
// This is an authority according to the consensus, but we'll
|
||||
// pretend we don't recognize it, to make sure that we
|
||||
// don't fetch or accept it.
|
||||
// a("7C47DCB4A90E2C2B7C7AD27BD641D038CF5D7EBE"),
|
||||
]
|
||||
}
|
||||
fn authcert_id_5696() -> AuthCertKeyIds {
|
||||
AuthCertKeyIds {
|
||||
id_fingerprint: rsa("5696ab38cb3852afa476a5c07b2d4788963d5567"),
|
||||
sk_fingerprint: rsa("f6ed4aa64d83caede34e19693a7fcf331aae8a6a"),
|
||||
}
|
||||
}
|
||||
fn authcert_id_5a23() -> AuthCertKeyIds {
|
||||
AuthCertKeyIds {
|
||||
id_fingerprint: rsa("5a23ba701776c9c1ab1c06e734e92ab3d5350d64"),
|
||||
sk_fingerprint: rsa("d08e965cc6dcb6cb6ed776db43e616e93af61177"),
|
||||
}
|
||||
}
|
||||
// remember, we're saying that we don't recognize this one as an authority.
|
||||
fn authcert_id_7c47() -> AuthCertKeyIds {
|
||||
AuthCertKeyIds {
|
||||
id_fingerprint: rsa("7C47DCB4A90E2C2B7C7AD27BD641D038CF5D7EBE"),
|
||||
sk_fingerprint: rsa("D3C013E0E6C82E246090D1C0798B75FCB7ACF120"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_consensus_state() {
|
||||
|
@ -866,10 +897,11 @@ mod test {
|
|||
assert!(outcome.unwrap());
|
||||
|
||||
// And with that, we should be asking for certificates
|
||||
assert!(state.can_advance());
|
||||
let next = Box::new(state).advance().unwrap();
|
||||
assert_eq!(
|
||||
&next.describe(),
|
||||
"Downloading certificates for consensus (we are missing 3/3)."
|
||||
"Downloading certificates for consensus (we are missing 2/2)."
|
||||
);
|
||||
|
||||
// Try again, but this time get the state from the cache.
|
||||
|
@ -880,5 +912,83 @@ mod test {
|
|||
let map = vec![(docid, text.into())].into_iter().collect();
|
||||
let outcome = state.add_from_cache(map, None);
|
||||
assert!(outcome.unwrap());
|
||||
assert!(state.can_advance());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_certs_state() {
|
||||
/// Construct a GetCertsState with our test data
|
||||
fn new_getcerts_state() -> (Arc<DirRcv>, Box<dyn DirState>) {
|
||||
let rcv = Arc::new(DirRcv::new(test_time(), Some(test_authorities())));
|
||||
let mut state =
|
||||
GetConsensusState::new(Arc::downgrade(&rcv), CacheUsage::CacheOkay).unwrap();
|
||||
let req = tor_dirclient::request::ConsensusRequest::new(ConsensusFlavor::Microdesc);
|
||||
let req = crate::docid::ClientRequest::Consensus(req);
|
||||
let outcome = state.add_from_download(CONSENSUS, &req, None);
|
||||
assert!(outcome.unwrap());
|
||||
(rcv, Box::new(state).advance().unwrap())
|
||||
}
|
||||
|
||||
let (_rcv, mut state) = new_getcerts_state();
|
||||
// Basic properties: description, status, reset time.
|
||||
assert_eq!(
|
||||
&state.describe(),
|
||||
"Downloading certificates for consensus (we are missing 2/2)."
|
||||
);
|
||||
assert!(!state.can_advance());
|
||||
assert!(!state.is_ready(Readiness::Complete));
|
||||
assert!(!state.is_ready(Readiness::Usable));
|
||||
let consensus_expires = datetime!(2020-08-07 12:43:20 UTC).into();
|
||||
assert_eq!(state.reset_time(), Some(consensus_expires));
|
||||
|
||||
// Check that we get the right list of missing docs.
|
||||
let missing = state.missing_docs();
|
||||
assert_eq!(missing.len(), 2); // We are missing two certificates.
|
||||
assert!(missing.contains(&DocId::AuthCert(authcert_id_5696())));
|
||||
assert!(missing.contains(&DocId::AuthCert(authcert_id_5a23())));
|
||||
// we don't ask for this one because we don't recognize its authority
|
||||
assert!(!missing.contains(&DocId::AuthCert(authcert_id_7c47())));
|
||||
|
||||
// Add one from the cache; make sure the list is still right
|
||||
let text1: crate::storage::InputString = AUTHCERT_5696.to_owned().into();
|
||||
// let text2: crate::storage::InputString = AUTHCERT_5A23.to_owned().into();
|
||||
let docs = vec![(DocId::AuthCert(authcert_id_5696()), text1.into())]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let outcome = state.add_from_cache(docs, None);
|
||||
assert!(outcome.unwrap()); // no error, and something changed.
|
||||
assert!(!state.can_advance()); // But we aren't done yet.
|
||||
let missing = state.missing_docs();
|
||||
assert_eq!(missing.len(), 1); // Now we're only missing one!
|
||||
assert!(missing.contains(&DocId::AuthCert(authcert_id_5a23())));
|
||||
|
||||
// Now try to add the other from a download ... but fail
|
||||
// because we didn't ask for it.
|
||||
let mut req = tor_dirclient::request::AuthCertRequest::new();
|
||||
req.push(authcert_id_5696()); // it's the wrong id.
|
||||
let req = ClientRequest::AuthCert(req);
|
||||
let outcome = state.add_from_download(AUTHCERT_5A23, &req, None);
|
||||
assert!(!outcome.unwrap()); // no error, but nothing changed.
|
||||
let missing2 = state.missing_docs();
|
||||
assert_eq!(missing, missing2); // No change.
|
||||
|
||||
// Now try to add the other from a download ... for real!
|
||||
let mut req = tor_dirclient::request::AuthCertRequest::new();
|
||||
req.push(authcert_id_5a23()); // Right idea this time!
|
||||
let req = ClientRequest::AuthCert(req);
|
||||
let outcome = state.add_from_download(AUTHCERT_5A23, &req, None);
|
||||
assert!(outcome.unwrap()); // No error, _and_ something changed!
|
||||
let missing3 = state.missing_docs();
|
||||
assert!(missing3.is_empty());
|
||||
assert!(state.can_advance());
|
||||
|
||||
let next = state.advance().unwrap();
|
||||
assert_eq!(
|
||||
&next.describe(),
|
||||
"Downloading microdescriptors (we are missing 6)."
|
||||
);
|
||||
|
||||
// TODO: I'd like even more tests to make sure that we never
|
||||
// accept a certificate for an authority we don't believe in.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
dir-key-certificate-version 3
|
||||
dir-address 127.0.0.1:7001
|
||||
fingerprint 5696AB38CB3852AFA476A5C07B2D4788963D5567
|
||||
dir-key-published 2020-08-07 12:40:25
|
||||
dir-key-expires 2021-08-07 12:40:25
|
||||
dir-identity-key
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBigKCAYEA5uDA8p4NhKPwOX/sMeMn6RtZLmNM2Ye4a1EPk2LQ7LYWQyeBZqsq
|
||||
GzZnQANclC0YbGi7cw7GiGY6NKXZNWtaPxX5rCWOw8IhGjNo56/kSfHJX+Gvtzzp
|
||||
dbxW/9JIYi8WyXQfMBhmfWtUrkdNIEyuW//H08haH+viCMePSv6zmPoc0xV//+XK
|
||||
ycHe/hLQZMKHIhHLGz0k3fRtousy+3y/vQFjw2PVwMB7xXnbHFPc0b+jUU3QO2V6
|
||||
jUAXVdIyHU+y1FzynUPo6C5d8mVQIlz/NcL1k0IKGUn1ItaQicYs28ooC+/I/lvV
|
||||
yub7LHHN7HX2IBwKLf135DQvSwXBWBFYwaYWGKDyN6IOGxCncKp9Cplz+Dk8P93m
|
||||
vTPYdpF0F0M1kP5dmakVqXyivJZMHGsQr2V0qGXr6I1wwu3SOdO0fmogWmEOmeT+
|
||||
3L4elBnC9BjPhCfX7vnzksLp6BZe20Btiu1TqxA0SUTk3t2kOJulwDcgYAyUbKeJ
|
||||
NSKK8YOMyhvrAgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----
|
||||
dir-signing-key
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBCgKCAQEAld61NikA0aqQnT2rO6YRelSnWCZjC3axXlrRV5QP1vJrPOdRRS53
|
||||
xHgkFEo8dX63X1bl67MBiZmgcP+cD/p9aFi9XGJyTU84wdBvmNU65LJ4sH0jKL1E
|
||||
DBt9RiDFCh9MhxqniVBp91is7m5RKV34Cwyco3Ti54uLO0FNGAh49nvNyANO0FlQ
|
||||
YFdM9yRQRciv20rWYO9M6brxK7LQMYVTg899yFnqa/vc+3USonKVLnmXeViNYyui
|
||||
bekkmN6E9EtSujpsfVAwsMSZy73n0n/PTRfXa+58npNgNbxX6mgQ6i7Nhy9KyFP4
|
||||
9BzKA9Q3CmeM/Z339awAtCtSaLoEb0Vh3QIDAQAB
|
||||
-----END RSA PUBLIC KEY-----
|
||||
dir-key-crosscert
|
||||
-----BEGIN ID SIGNATURE-----
|
||||
WKrcO0K/e8XWRhTD0fh7+fqTJvL3A296/Yad16SS6Bdz1yh/QihSpffdS3PBi+ka
|
||||
WhHdXNYZJ68BPr4kNUC6xwlObeVlt0SVVpE2avqpfFtZL1pV6he2dNKZ5MMv6Ctm
|
||||
7BOaavpLwcEyXs2H1XxH6wjQU719FCbvJvBESclAAIq3K3D5fmFg68RNWHHz3r3F
|
||||
MyXnaR5bylKkgQHwwz5Q3HVjWUJ6S7Fz8KTfO1Q7rvfgHpXzYJqAyXivhaGnJmWQ
|
||||
+zHVscRSI3NpGgqnzeqylXkZVqrHWNO5mkVSeMXt2hMYP61Zkm7KO6lqtOBON7Db
|
||||
AKOs+q8j2T3XoR5VD9YtAQ==
|
||||
-----END ID SIGNATURE-----
|
||||
dir-key-certification
|
||||
-----BEGIN SIGNATURE-----
|
||||
fJEeVmr7caG8pfwO9XFeCGnWVgyqKSg90xpIfcWbPHrn5brAXEwJm/+dX7V9tazx
|
||||
8y6i43ULt3MI+7Et2o46A3wYGA0a3OqpxAHdJjxeafJ9bDXRyVETh2MHsd0I337A
|
||||
JhSuufKyGS+K2y20s2VYMPXkX2AFKpN1H0Stc7RdpssGyrmidZSXXzCgTitqn52g
|
||||
Ms9iWjCU6Ra5AjMzp/D93CFZ0fYMhKot42ZXYJga8drQHdY06+5Fb7RSTpFs9vhf
|
||||
t4XdeMef+N9ty/yaLNDmYiLJbKTTAarfkM2czXuuk3s+qwLN7+O4yGUNQz4tPJ8E
|
||||
h7VALUNE80QNDLb4rXiIUE+EI3tCqo9mQ/tnCVVofM6sQyTFjTWyIIRBABnaODlO
|
||||
meOIIEIR6ht2qSseZDe4dme7cg5/misTnIv7BNbErpYO5r9C2yHHFqSe8sivExCo
|
||||
tEkNtxufKS2mn6Tkm7wcJfp1Temxk/INUtvPA6Dlf3wNTnwzuGfk7LWCQ9BPeFqv
|
||||
-----END SIGNATURE-----
|
|
@ -0,0 +1,46 @@
|
|||
dir-key-certificate-version 3
|
||||
dir-address 127.0.0.1:7000
|
||||
fingerprint 5A23BA701776C9C1AB1C06E734E92AB3D5350D64
|
||||
dir-key-published 2020-08-07 12:40:25
|
||||
dir-key-expires 2021-08-07 12:40:25
|
||||
dir-identity-key
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBigKCAYEAtitks3CQo7QOYYhJmYJGOJoA9XOREzl38tl6zrGq4XtwOioTUivP
|
||||
M51l483083x5DsBw6+Ec9LOkVSClETOIHDzjIzg78O4a6uEr7HemTI7JKEbIXUtj
|
||||
bu1/JxOb7Bd8HrA/9Vw6hp3GJT7wqO33K/XhmRVzH2SMhmLP0cZT5MfaaE38QViI
|
||||
eWrTFze+U1Z16RPWx8djaepCgLaVT2tP9WXKtk+6O0Kyjz1toF9wfZUb4jfEHNQ2
|
||||
6Np5IaJcpsMaaovx2ClNOy23MadsLhBQxquCC1IFilMwKDDjVN9BIUd3eZJDBgyy
|
||||
yY4PvO6fMsVxtK+7dlw2pWpdc2YSTGh9TY+UfWyPn+7oUD2AB/liJ/HOSqdXw5kl
|
||||
YLeu2DwVUkv4ZieExUjyCmjmwkAdpEfMRE77hru+hbAV3E/vUj7571I1alMRZQU3
|
||||
PItAQkfygL+0yI0Ysk4kVt0zxkFv19o1YD6yS+vBkY2oVGflBS6TVl2v/YsVDBEU
|
||||
L6ifTkCQ8zIPAgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----
|
||||
dir-signing-key
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBCgKCAQEAuMZaaW/p0CyTxWmr3SkBdrLz1uRiTZFadYNQmVcyeEfHw+siOO2Z
|
||||
GZCpLW14AilxrGgIqacbj4p1bnP1Fqt48SW06TJpfg8LL5u9A0taBTrvl4d+y0PU
|
||||
muk5/Y03QDUQ0Mqa5wFqXwq0gpFYNAF60fUcILU+RfC/eLF8p/8tMH6VqHbYJNvA
|
||||
amHoi5b/cSX26y2AJG9NeRuljx9kGBKcQ3nyIUr5KtNmMAxtznnz6cxsXneCtfxo
|
||||
H4Ubwy3NhSEfrjlSE4B/iASKalXgmQSSXR/PA+iBsG+zZ8+6/kKtxc5MQmnEQ3Qg
|
||||
q6M1hfp9K89K/EzaxQ06PLvY1FylGqpc1wIDAQAB
|
||||
-----END RSA PUBLIC KEY-----
|
||||
dir-key-crosscert
|
||||
-----BEGIN ID SIGNATURE-----
|
||||
UrMAQ97L/Aoz0pY+IahRnlTYFdJ3jLM28WxRvZ3eP8ShCmDHYYN7fMwnstDjZZ8N
|
||||
mGL8PuYP4mYfIRGjCBrMr5doLKtaOoyxnuuE81y08Yd8xWkIt9zelc5baGj1iJjn
|
||||
1kxRCeClli0v05M31Z5zTNAfdMDD+yai4husa/0oEIMBJvjEAmeRcyjxfWIV8R0D
|
||||
e+PR7+GAxprbJFGRL9bn27PlR7Lbm03jZIpBhCdTAeBxyGHyS8wgaXaIJCR7e3GH
|
||||
uJytP7OvPoWLAggHSBp1LwsY++lLayJrTjm3/yoWv7BOXnXP0XHwDoPoXySS519p
|
||||
lxq5rwk1RrSwa93+nwnEXw==
|
||||
-----END ID SIGNATURE-----
|
||||
dir-key-certification
|
||||
-----BEGIN SIGNATURE-----
|
||||
fp1nrLUFamnIg6rZnG/hMuM00SpBVTW6/XgEgMw9QIfE3lQxzR/hKF6iFcasYi2z
|
||||
gg6r2JAvGevQxzajV8nDgKcLSnDurh6Q7OJw9p4v1ksXLJazHbLAhKi+Aa/daSmb
|
||||
6Klp3XVDgVNhYzTleN26/El+Z1oEjbqRs72Vvlazem5lKaOZvm7jolgWQn5TiWZY
|
||||
TQ9D7cP9TDAm7WBvYQ97CUnSDobVJyVBtCQrNb5vppTQw6+FON0U2h75Vl+T/Qhd
|
||||
wugYKJ+UbZhwBCy0EOM23BU7QS6jbYW2bBjeo5I7/K32Cci8YZKuib9N/j3NPuFz
|
||||
7jRAYSgiEd4uwktG4RP55EV7RVTO28/XeEvvlM/iVVYoqS+bMoCRkO8LqHvKB6+0
|
||||
Wkei7KASZzIVe5YcgRHzts/oBt8w59DIaGUtEPQQ2BEIYtkl4N3mfR9VgW5HpTUI
|
||||
2kPs1DjukQslB6Ilz6G+qOaZtJyOhdkWtwdR/fMcDWmTEifLZDbAdiLUpg/xc26p
|
||||
-----END SIGNATURE-----
|
|
@ -0,0 +1,46 @@
|
|||
dir-key-certificate-version 3
|
||||
dir-address 127.0.0.1:7002
|
||||
fingerprint 7C47DCB4A90E2C2B7C7AD27BD641D038CF5D7EBE
|
||||
dir-key-published 2020-08-07 12:40:26
|
||||
dir-key-expires 2021-08-07 12:40:26
|
||||
dir-identity-key
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBigKCAYEAyE1/XqjBgaNCSp36thnqlRzzt/4vEXXUIcutCkGAsI/An408vj+Z
|
||||
tSo844vMMtSb8z1z0xDzApz2GPe7n5BTdPGjV1YQUd3Vr0z3z1j9EolV8NoXlUod
|
||||
Mj9pSa2dB9Hpz1ZooAEX+egRXPXOp6kHb2QyUIVupKUo/kCRwyUcqV6M52oPZ0i4
|
||||
o2uhhExXkExY1f7y6yee7QzLOxIgDhtWpkBhfMjRfa856ULXcRPwsQ99A1RclWTb
|
||||
c1i6aU3NIt+AYthamu6G4jnYTrg4tPUyr7Gc4+j34rT/SwLS5waKZwZFObGNitK0
|
||||
dLMMgPHfeJMW7wVN/scNDXCwZ19XzYEdat+SGP9jUaxPoabdOgzibfQINanw7pzm
|
||||
G5bEmOuqWr1vYy3oRs1rIJJ18vy6yTF379sKdkB1gSau6svSIJfvUpnVA2pjvjL0
|
||||
UGxXCCMozU+ctoe1PtXAEDFTE30vHo2pDe0pvJI+7bO09NAbTpIFfoxILqKRstJ7
|
||||
PcU/6Ncbmfd7AgMBAAE=
|
||||
-----END RSA PUBLIC KEY-----
|
||||
dir-signing-key
|
||||
-----BEGIN RSA PUBLIC KEY-----
|
||||
MIIBCgKCAQEAy+3L8ISKlSQ7nOmHgi1rNSpSp00e4VrMcgXU8+kn0yjYZB6jOSMs
|
||||
/LZDk14eX8jlvPsJg/SIl4c2OD+AYJtiyB1DZnZY/QbZ48faVwi9FkfCcZLkrD1i
|
||||
PiiYmpM+DS+sh1oiBZX/wTSvx0MeEjyd9t8ZhH5R86k7QA7TW7Fe9rRrLshPSGFp
|
||||
4ipj1fG+NuEG58kXeWSLwXJvNl4Hdezvvjii5la9b2S37/D6DZDfRLib35tXfA4T
|
||||
y/zUK1pjzEQaAUeuIOgB+olX6bsOyL2eQORd5y5MtfF4x4FklPcz/e1l7gmahWGp
|
||||
RpSUIRszrEbfxgCA8zCz/ta+jrrXq1lkpQIDAQAB
|
||||
-----END RSA PUBLIC KEY-----
|
||||
dir-key-crosscert
|
||||
-----BEGIN ID SIGNATURE-----
|
||||
HvUJXA95l45NFYuD5y5jSf4aFE0f3TlABjKK159WeSjDD/4Vn1GJQQjX6ske8MDh
|
||||
x54GpTllhLmPLRq5GXn/DRCvxG9TGpyP3vL8pq2TWLBscCVxg4D9xj6OSYvbBKRw
|
||||
QolqW8wfGKPj2OgCnTB3jzvnshP9rDq/ruEzlZfJTrb4pxQrPzOAlwaKEDCoO9zy
|
||||
IW/gmVn1/vGNU/qhuGAKa4FGKUjvTg699MFE2SIF7gLo+oOGkFfL37WhHDlh7HPR
|
||||
JiAHgTp6nHp+2+B/EHR5u94b3g66qPRNN6KxWcTAqcUxX9t0dKlsROZksr1268P6
|
||||
PEN3+GtdwiA4n3reP+Wsxw==
|
||||
-----END ID SIGNATURE-----
|
||||
dir-key-certification
|
||||
-----BEGIN SIGNATURE-----
|
||||
FqKvXdB2bcwFYEWdQDW0eot/5cRTBnb8frAzoA/khWUSLhYIE55b/xtDg2OMWMhx
|
||||
/yBiGuNGHT82+jKDh92RfxVKH8D32/r6p1SP1ot8POGWU/ke6/lABZkd5Aa5xSb7
|
||||
Hcqik24bbnlvePtqze7UlvJQZN3ktYHUV2LTyw4ZbY1NEmMoPGE7FWe1iHSCiAvn
|
||||
I8u3ePREY2gQ4ZzkcjuPzIMX4Th18OEQFTanNgJqmW5l4XDkXO4yAOaO21/7kdTg
|
||||
iTqQnoWn8PfoVRvXVYvrgWKMyRUT/6R2zUnNWaP9z7JKv3SSZSXyMowbcyb5QFTX
|
||||
KKhfO7fLMdGUs/yhXvqVgaQdguOcLfTUU7rV8aZjKsGiDPsFJKTBw9Xt5obGGJN4
|
||||
4CLP+J9lSi/aZ2M4/qD5tkuE0kUNzeHuZuhze3MOObRZxLC5I3skwzTuflODVtTP
|
||||
llMKUqZjbySFnSHEMvs+rhPOiUPNzXDl7/hQAVbWrzIyjjJ0WpoIUyHcIETWsv6Y
|
||||
-----END SIGNATURE-----
|
Loading…
Reference in New Issue