fxa_client/internal/
util.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use crate::{Error, Result};
6use base64::{engine::general_purpose::URL_SAFE_NO_PAD, Engine};
7use rc_crypto::rand;
8use std::time::{SystemTime, UNIX_EPOCH};
9
10// Gets the unix epoch in ms.
11pub fn now() -> u64 {
12    let since_epoch = SystemTime::now()
13        .duration_since(UNIX_EPOCH)
14        .expect("Something is very wrong.");
15    since_epoch.as_secs() * 1000 + u64::from(since_epoch.subsec_nanos()) / 1_000_000
16}
17
18pub fn now_secs() -> u64 {
19    let since_epoch = SystemTime::now()
20        .duration_since(UNIX_EPOCH)
21        .expect("Something is very wrong.");
22    since_epoch.as_secs()
23}
24
25/// Gets unix timestamp at `days` days ago
26pub fn past_timestamp(days: u64) -> u64 {
27    // 1000 milliseconds, 60 seconds, 60 minutes, 24 hours
28    now() - (1000 * 60 * 60 * 24 * days)
29}
30
31pub fn random_base64_url_string(len: usize) -> Result<String> {
32    let mut out = vec![0u8; len];
33    rand::fill(&mut out)?;
34    Ok(URL_SAFE_NO_PAD.encode(&out))
35}
36
37pub trait Xorable {
38    #[allow(dead_code)]
39    fn xored_with(&self, other: &[u8]) -> Result<Vec<u8>>;
40}
41
42impl Xorable for [u8] {
43    fn xored_with(&self, other: &[u8]) -> Result<Vec<u8>> {
44        if self.len() != other.len() {
45            Err(Error::XorLengthMismatch(self.len(), other.len()))
46        } else {
47            Ok(self
48                .iter()
49                .zip(other.iter())
50                .map(|(&x, &y)| x ^ y)
51                .collect())
52        }
53    }
54}