1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::sync::Arc;
use tink_core::{utils::wrap_err, TinkError};
pub fn new_verifier(
h: &tink_core::keyset::Handle,
) -> Result<Box<dyn tink_core::Verifier>, TinkError> {
new_verifier_with_key_manager(h, None)
}
fn new_verifier_with_key_manager(
h: &tink_core::keyset::Handle,
km: Option<Arc<dyn tink_core::registry::KeyManager>>,
) -> Result<Box<dyn tink_core::Verifier>, TinkError> {
let ps = h
.primitives_with_key_manager(km)
.map_err(|e| wrap_err("verifier::factory: cannot obtain primitive set", e))?;
let ret = WrappedVerifier::new(ps)?;
Ok(Box::new(ret))
}
#[derive(Clone)]
struct WrappedVerifier {
ps: tink_core::primitiveset::TypedPrimitiveSet<Box<dyn tink_core::Verifier>>,
}
impl WrappedVerifier {
fn new(ps: tink_core::primitiveset::PrimitiveSet) -> Result<WrappedVerifier, TinkError> {
let primary = match &ps.primary {
None => return Err("verifier::factory: no primary primitive".into()),
Some(p) => p,
};
match primary.primitive {
tink_core::Primitive::Verifier(_) => {}
_ => return Err("verifier::factory: not a Verifier primitive".into()),
};
for (_, primitives) in ps.entries.iter() {
for p in primitives {
match p.primitive {
tink_core::Primitive::Verifier(_) => {}
_ => return Err("verifier::factory: not a Verifier primitive".into()),
};
}
}
Ok(WrappedVerifier { ps: ps.into() })
}
}
impl tink_core::Verifier for WrappedVerifier {
fn verify(&self, signature: &[u8], data: &[u8]) -> Result<(), TinkError> {
let prefix_size = tink_core::cryptofmt::NON_RAW_PREFIX_SIZE;
if signature.len() < prefix_size {
return Err("verifier::factory: invalid signature".into());
}
let prefix = &signature[..prefix_size];
let signature_no_prefix = &signature[prefix_size..];
if let Some(entries) = self.ps.entries_for_prefix(&prefix) {
for entry in entries {
let result = if entry.prefix_type == tink_proto::OutputPrefixType::Legacy {
let mut signed_data_copy = Vec::with_capacity(data.len() + 1);
signed_data_copy.extend_from_slice(data);
signed_data_copy.push(tink_core::cryptofmt::LEGACY_START_BYTE);
entry
.primitive
.verify(signature_no_prefix, &signed_data_copy)
} else {
entry.primitive.verify(signature_no_prefix, data)
};
if result.is_ok() {
return Ok(());
}
}
}
if let Some(entries) = self.ps.raw_entries() {
for entry in entries {
if entry.primitive.verify(signature, data).is_ok() {
return Ok(());
}
}
}
Err("verifier::factory: invalid signature".into())
}
}