1use std::ops::Deref;
2use std::time::{Duration, SystemTime};
3
4use serde::{de::DeserializeOwned, Serialize};
5use serde_json;
6
7use crate::error::{BadSignature, BadTimedSignature, PayloadError, TimestampExpired};
8use crate::serializer_traits::UnsignToString;
9use crate::timestamp;
10use crate::{
11 base64, AsSigner, Encoding, Separator, Serializer, Signer, TimedSerializer, TimestampSigner,
12};
13
14pub struct NullEncoding;
15pub struct URLSafeEncoding;
16
17pub struct SerializerImpl<TSigner, TEncoding> {
18 signer: TSigner,
19 encoding: TEncoding,
20}
21
22pub struct TimedSerializerImpl<TSigner, TEncoding> {
23 signer: TSigner,
24 encoding: TEncoding,
25}
26
27impl<TSigner, TEncoding> TimedSerializerImpl<TSigner, TEncoding> {
28 pub fn signer(&self) -> &TSigner {
29 &self.signer
30 }
31}
32
33pub fn serializer_with_signer<TSigner, TEncoding>(
34 signer: TSigner,
35 encoding: TEncoding,
36) -> SerializerImpl<TSigner, TEncoding>
37where
38 TSigner: Signer,
39 TEncoding: Encoding,
40{
41 SerializerImpl { signer, encoding }
42}
43
44pub fn timed_serializer_with_signer<TSigner, TEncoding>(
45 signer: TSigner,
46 encoding: TEncoding,
47) -> TimedSerializerImpl<TSigner, TEncoding>
48where
49 TSigner: TimestampSigner,
50 TEncoding: Encoding,
51{
52 TimedSerializerImpl { signer, encoding }
53}
54
55impl Encoding for NullEncoding {
56 fn encode<'a>(&self, serialized_input: String) -> String {
57 serialized_input
58 }
59
60 fn decode<'a>(&self, encoded_input: String) -> Result<String, PayloadError> {
61 Ok(encoded_input)
62 }
63}
64
65impl Encoding for URLSafeEncoding {
66 fn encode<'a>(&self, serialized_input: String) -> String {
67 base64::encode(&serialized_input)
68 }
69
70 fn decode<'a>(&self, encoded_input: String) -> Result<String, PayloadError> {
71 let decoded = base64::decode_str(&encoded_input)?;
73 Ok(String::from_utf8(decoded).map_err(|e| e.utf8_error())?)
74 }
75}
76
77#[inline(always)]
78fn deserialize<'a, T: DeserializeOwned, Encoding: self::Encoding>(
79 value: &'a str,
80 encoding: &Encoding,
81) -> Result<T, BadSignature<'a>> {
82 let decoded = encoding
83 .decode(value.to_string())
84 .map_err(|e| BadSignature::PayloadInvalid {
85 value,
86 error: e.into(),
87 })?;
88 serde_json::from_str(&decoded).map_err(|e| BadSignature::PayloadInvalid {
89 value,
90 error: e.into(),
91 })
92}
93
94impl<TSigner, TEncoding> Serializer for SerializerImpl<TSigner, TEncoding>
95where
96 TSigner: Signer,
97 TEncoding: Encoding,
98{
99 fn sign<T: Serialize>(&self, value: &T) -> serde_json::Result<String> {
100 let serialized = serde_json::to_string(value)?;
101 let encoded = self.encoding.encode(serialized);
102 Ok(self.signer.sign(encoded))
103 }
104
105 fn unsign<'a, T: DeserializeOwned>(&'a self, value: &'a str) -> Result<T, BadSignature<'a>> {
106 let value = self.signer.unsign(value)?;
107 deserialize(value, &self.encoding)
108 }
109}
110
111impl<TSigner, TEncoding> UnsignToString for SerializerImpl<TSigner, TEncoding>
112where
113 TSigner: Signer,
114 TEncoding: Encoding,
115{
116 fn unsign_to_string<'a>(&'a self, value: &'a str) -> Result<String, BadSignature<'a>> {
117 let value = self.signer.unsign(value)?;
118 self.encoding
119 .decode(value.to_string())
120 .map_err(|e| BadSignature::PayloadInvalid {
121 value,
122 error: e.into(),
123 })
124 }
125}
126
127impl<TSigner, TEncoding> AsSigner for SerializerImpl<TSigner, TEncoding>
128where
129 TSigner: Signer,
130{
131 type Signer = TSigner;
132
133 fn as_signer(&self) -> &Self::Signer {
134 &self.signer
135 }
136}
137
138impl<TSigner, TEncoding> TimedSerializer for TimedSerializerImpl<TSigner, TEncoding>
139where
140 TSigner: TimestampSigner,
141 TEncoding: Encoding,
142{
143 fn sign<T: Serialize>(&self, value: &T) -> serde_json::Result<String> {
144 self.sign_with_timestamp(value, SystemTime::now())
145 }
146
147 fn sign_with_timestamp<T: Serialize>(
148 &self,
149 value: &T,
150 timestamp: SystemTime,
151 ) -> serde_json::Result<String> {
152 let serialized = serde_json::to_string(value)?;
153 let encoded = self.encoding.encode(serialized);
154 Ok(self.signer.sign_with_timestamp(encoded, timestamp))
155 }
156
157 fn unsign<'a, T: DeserializeOwned>(
158 &'a self,
159 value: &'a str,
160 ) -> Result<UnsignedTimedSerializerValue<T>, BadTimedSignature<'a>> {
161 let value = self.signer.unsign(value)?;
162 let timestamp = value.timestamp();
163 let value = value.value();
164 let deserialized_value = deserialize(value, &self.encoding)?;
165
166 Ok(UnsignedTimedSerializerValue {
167 value: deserialized_value,
168 timestamp,
169 })
170 }
171}
172
173pub struct UnsignedTimedSerializerValue<T> {
175 value: T,
176 timestamp: SystemTime,
177}
178
179impl<T> UnsignedTimedSerializerValue<T> {
180 pub fn value(self) -> T {
185 self.value
186 }
187
188 pub fn timestamp(&self) -> SystemTime {
195 self.timestamp
196 }
197
198 pub fn value_if_not_expired(self, max_age: Duration) -> Result<T, TimestampExpired<T>> {
203 match self.timestamp.elapsed() {
204 Ok(duration) if duration > max_age => Err(TimestampExpired {
205 timestamp: self.timestamp,
206 value: self.value,
207 max_age,
208 }),
209 Ok(_) | Err(_) => Ok(self.value),
211 }
212 }
213}
214
215impl<T> Deref for UnsignedTimedSerializerValue<T> {
216 type Target = T;
217 fn deref(&self) -> &Self::Target {
218 &self.value
219 }
220}
221
222pub struct UnverifiedValue<'a, T> {
256 unverified_value: T,
257 unverified_raw_value: &'a str,
258 unverified_signature: &'a str,
259}
260
261impl<'a, T: DeserializeOwned> UnverifiedValue<'a, T> {
262 pub fn from_str<TEncoding: Encoding>(
263 separator: Separator,
264 encoding: TEncoding,
265 input: &'a str,
266 ) -> Result<Self, BadSignature> {
267 let (unverified_raw_value, unverified_signature) = separator.split(input)?;
268 let unverified_value = deserialize(unverified_raw_value, &encoding)?;
269
270 Ok(UnverifiedValue {
271 unverified_value,
272 unverified_raw_value,
273 unverified_signature,
274 })
275 }
276
277 pub fn unverified_value(&self) -> &T {
279 &self.unverified_value
280 }
281
282 pub fn verify<TSigner: AsSigner>(self, signer: &TSigner) -> Result<T, BadSignature<'a>> {
283 let value = self.unverified_raw_value;
284 let signature = self.unverified_signature;
285
286 if signer
287 .as_signer()
288 .verify_encoded_signature(value.as_bytes(), signature.as_bytes())
289 {
290 Ok(self.unverified_value)
291 } else {
292 Err(BadSignature::SignatureMismatch { signature, value })
293 }
294 }
295}
296
297pub struct UnverifiedTimedValue<'a, T> {
298 unverified_value: T,
299 unverified_raw_value: &'a str,
300 unverified_signature: &'a str,
301 unverified_timestamp: SystemTime,
302}
303
304impl<'a, T: DeserializeOwned> UnverifiedTimedValue<'a, T> {
305 pub fn from_str<TEncoding: Encoding>(
306 separator: Separator,
307 encoding: TEncoding,
308 input: &'a str,
309 ) -> Result<Self, BadTimedSignature> {
310 let (unverified_raw_value, unverified_signature) = separator.split(input)?;
311 let (unverified_raw_serialized_value, unverified_timestamp) =
312 separator.split(unverified_raw_value)?;
313 let unverified_timestamp = timestamp::decode(unverified_timestamp)?;
314 let unverified_value = deserialize(unverified_raw_serialized_value, &encoding)?;
315
316 Ok(UnverifiedTimedValue {
317 unverified_value,
318 unverified_raw_value,
319 unverified_signature,
320 unverified_timestamp,
321 })
322 }
323
324 pub fn unverified_value(&self) -> &T {
325 &self.unverified_value
326 }
327
328 pub fn unverified_timestamp(&self) -> SystemTime {
329 self.unverified_timestamp
330 }
331
332 pub fn verify<TSigner: TimestampSigner + AsSigner>(
333 self,
334 timestamp_signer: &TSigner,
335 ) -> Result<UnsignedTimedSerializerValue<T>, BadTimedSignature<'a>> {
336 let value = self.unverified_raw_value;
337 let signature = self.unverified_signature;
338
339 if timestamp_signer
340 .as_signer()
341 .verify_encoded_signature(value.as_bytes(), signature.as_bytes())
342 {
343 Ok(UnsignedTimedSerializerValue {
344 value: self.unverified_value,
345 timestamp: self.unverified_timestamp,
346 })
347 } else {
348 Err(BadTimedSignature::SignatureMismatch { signature, value })
349 }
350 }
351}
352
353#[cfg(test)]
354mod tests {
355 use std::time::UNIX_EPOCH;
356
357 use super::*;
358 use crate::{default_builder, IntoTimestampSigner};
359 #[test]
360
361 fn test_null_encoding() {
362 let s = "hello world".to_owned();
363 let encoding = NullEncoding;
364 assert_eq!(encoding.encode(s.clone()), s);
365 assert_eq!(encoding.decode(s.clone()).unwrap(), s);
366 }
367
368 #[test]
369 fn test_url_safe_encoding() {
370 let s = "hello world".to_owned();
371 let encoded = "aGVsbG8gd29ybGQ".to_owned();
372 let encoding = URLSafeEncoding;
373 assert_eq!(encoding.encode(s.clone()), encoded);
374 assert_eq!(encoding.decode(encoded).unwrap(), s);
375 }
376
377 #[test]
378 fn test_sign_null_encoding() {
379 let signer = default_builder("hello world").build();
380 let serializer = serializer_with_signer(signer, NullEncoding);
381 let signed = "[1,2,3].bq_ST5hV4J35lKdovyr_ng-ZIxU";
382 assert_eq!(serializer.sign(&vec![1, 2, 3]).unwrap(), signed);
383 assert_eq!(serializer.unsign::<Vec<u8>>(signed).unwrap(), vec![1, 2, 3]);
384 }
385
386 #[test]
387 fn test_unsign_unverified_good_signature() {
388 let signer = default_builder("hello world").build();
389 let signed = "[1,2,3].bq_ST5hV4J35lKdovyr_ng-ZIxU";
390 let unverified_value: UnverifiedValue<Vec<u8>> =
391 UnverifiedValue::from_str(signer.separator, NullEncoding, signed).unwrap();
392 let expected = vec![1, 2, 3];
393 assert_eq!(unverified_value.unverified_value(), &expected);
394 assert_eq!(unverified_value.verify(&signer).unwrap(), expected);
395 }
396
397 #[test]
398 fn test_unsign_unverified_bad_signature() {
399 let signer = default_builder("not the right key lol").build();
400 let signed = "[1,2,3].bq_ST5hV4J35lKdovyr_ng-ZIxU";
401 let unverified_value: UnverifiedValue<Vec<u8>> =
402 UnverifiedValue::from_str(signer.separator, NullEncoding, signed).unwrap();
403 let expected = vec![1, 2, 3];
404 assert_eq!(unverified_value.unverified_value(), &expected);
405 assert!(unverified_value.verify(&signer).is_err());
406 }
407
408 #[test]
409 fn test_sign_url_safe_encoding() {
410 let signer = default_builder("hello world").build();
411 let serializer = serializer_with_signer(signer, URLSafeEncoding);
412 let signed = "WzEsMiwzXQ.ohh92zNcvFVoWHrPf5uumLp6mbQ";
413 assert_eq!(serializer.sign(&vec![1, 2, 3]).unwrap(), signed);
414 assert_eq!(serializer.unsign::<Vec<u8>>(signed).unwrap(), vec![1, 2, 3]);
415 }
416
417 #[test]
418 fn test_timed_sign_null_encoding() {
419 let signer = default_builder("hello world")
420 .build()
421 .into_timestamp_signer();
422 let serializer = timed_serializer_with_signer(signer, NullEncoding);
423 let timestamp = UNIX_EPOCH + Duration::from_secs(1560181622);
424 let signed = "[1,2,3].XP57dg.azFnnbv1s1cilwCeXmeVlMmbqD4";
425 assert_eq!(
426 serializer
427 .sign_with_timestamp(&vec![1, 2, 3], timestamp)
428 .unwrap(),
429 signed
430 );
431 let unsigned = serializer.unsign::<Vec<u8>>(signed).unwrap();
432 assert_eq!(unsigned.timestamp(), timestamp);
433 assert_eq!(unsigned.value(), vec![1, 2, 3]);
434 }
435
436 #[test]
437 fn test_unverified_timed_good_signature() {
438 let signer = default_builder("hello world")
439 .build()
440 .into_timestamp_signer();
441 let timestamp = UNIX_EPOCH + Duration::from_secs(1560181622);
442 let signed = "[1,2,3].XP57dg.azFnnbv1s1cilwCeXmeVlMmbqD4";
443 let unverified_value: UnverifiedTimedValue<Vec<u8>> =
444 UnverifiedTimedValue::from_str(signer.separator(), NullEncoding, signed).unwrap();
445 let expected = vec![1, 2, 3];
446 assert_eq!(unverified_value.unverified_timestamp(), timestamp);
447 assert_eq!(unverified_value.unverified_value(), &expected);
448 assert_eq!(unverified_value.verify(&signer).unwrap().value(), expected);
449 }
450
451 #[test]
452 fn test_unverified_timed_value_if_not_expired() {
453 let signer = default_builder("hello world")
454 .build()
455 .into_timestamp_signer();
456 let serializer = timed_serializer_with_signer(signer, NullEncoding);
457 let timestamp = SystemTime::now() - Duration::from_secs(30);
458 let signed = serializer
459 .sign_with_timestamp(&vec![1, 2, 3], timestamp)
460 .unwrap();
461
462 let unsigned = serializer.unsign::<Vec<u8>>(&signed).unwrap();
463 assert!(unsigned
464 .value_if_not_expired(Duration::from_secs(15))
465 .is_err());
466
467 let unsigned = serializer.unsign::<Vec<u8>>(&signed).unwrap();
468 assert_eq!(
469 unsigned
470 .value_if_not_expired(Duration::from_secs(60))
471 .unwrap(),
472 vec![1, 2, 3]
473 );
474 }
475
476 #[test]
477 fn test_timed_signer_impl_can_be_used_to_verify() {
478 let signer = default_builder("hello world")
479 .build()
480 .into_timestamp_signer();
481 let separator = signer.separator().clone();
482 let serializer = timed_serializer_with_signer(signer, URLSafeEncoding);
483 let signed = serializer.sign(&"whatever").unwrap();
484 let unverified: UnverifiedTimedValue<String> =
485 UnverifiedTimedValue::from_str(separator, URLSafeEncoding, &signed).unwrap();
486 assert_eq!(unverified.unverified_value(), "whatever");
487 let verified = unverified
488 .verify(serializer.signer())
489 .expect("Failed to verify");
490 assert_eq!(&verified.value(), "whatever");
491 }
492}
493
494#[cfg(all(test, feature = "nightly"))]
495mod bench {
496 use crate::*;
497 extern crate test;
498 use test::Bencher;
499
500 #[bench]
501 fn bench_sign(bench: &mut Bencher) {
502 let signer = default_builder("hello world").build();
503 let serializer = serializer_with_signer(signer, NullEncoding);
504
505 let value = vec![1, 2, 3];
506 bench.iter(|| serializer.sign(&value))
507 }
508
509 #[bench]
510 fn bench_unsign(bench: &mut Bencher) {
511 let signer = default_builder("hello world").build();
512 let serializer = serializer_with_signer(signer, NullEncoding);
513 let signed = "[1,2,3].D-AM9g.nHmuOEE3v5DuwHEW9noSBOvExO0";
514 bench.iter(|| serializer.unsign::<Vec<u8>>(&signed))
515 }
516}