diff options
| author | Teddy Wing | 2018-10-22 14:57:02 +0200 | 
|---|---|---|
| committer | Teddy Wing | 2018-10-22 14:57:02 +0200 | 
| commit | a709acca8ba41f21e0222debdbe39186c5106beb (patch) | |
| tree | 3feb79648ff0263028d860cbc1321769bcd10e0f /src/trial.rs | |
| parent | ff244b2e9b7705534ea37ff727be205274ea9ae3 (diff) | |
| download | dome-key-map-a709acca8ba41f21e0222debdbe39186c5106beb.tar.bz2 | |
trial: Encrypt and decrypt timestamp
Add functions to encrypt and decrypt a timestamp. We'll be using those
functions to write the encrypted timestamp of the first trial launch
date to a file.
Decided to go for some light encryption instead of just storing a plain
or base64-encoded value. Still need to come up with a key, but that will
be stored as a plain string in the binary.
Need a way to capture the results so we don't end up panicking. Trouble
is, 'magic-crypt' doesn't implement the required `Error` traits, so I
can't just slot it into 'error-chain'. Still trying to work out how to
deal with that.
Also add a function to get the days remaining from now.
Diffstat (limited to 'src/trial.rs')
| -rw-r--r-- | src/trial.rs | 51 | 
1 files changed, 48 insertions, 3 deletions
| diff --git a/src/trial.rs b/src/trial.rs index 9604f62..e716559 100644 --- a/src/trial.rs +++ b/src/trial.rs @@ -1,18 +1,22 @@ -use chrono::{DateTime, Local, TimeZone}; +use std::result; -use errors::DurationError; +use chrono::{DateTime, FixedOffset, Local, TimeZone}; +use magic_crypt::{self, MagicCrypt}; + +use errors::*;  // Start timestamp on October 1 at 23h  // Trial should be valid until November 1 00h  const DAYS_REMAINING: u8 = 30; +const KEY: &'static str = "TODO SECRET";  fn days_remaining(      start: DateTime<Local>,      now: DateTime<Local>,      days_available: u8, -) -> Result<u8, DurationError> { +) -> result::Result<u8, DurationError> {      let duration = (now.date() - start.date()).num_days() as u8;      if duration > days_available { @@ -24,6 +28,47 @@ fn days_remaining(      }  } +fn days_remaining_from_now( +    start: DateTime<Local> +) -> result::Result<u8, DurationError> { +    days_remaining(start, Local::now(), DAYS_REMAINING) +} + +fn encode_datetime(d: DateTime<Local>) -> String { +    let iv = initialization_vector(); + +    let mut mc = MagicCrypt::new(KEY, magic_crypt::SecureBit::Bit64, Some(&iv)); + +    let timestamp = mc.encrypt_str_to_base64(&d.to_rfc3339()); + +    format!("{}//{}", timestamp, iv) +} + +fn decode_datetime(s: &str) -> DateTime<FixedOffset> { +    let encrypted: Vec<_> = s.rsplitn(2, "//").collect(); +    let timestamp = encrypted[0]; +    let iv = encrypted[1]; + +    let mut mc = MagicCrypt::new(KEY, magic_crypt::SecureBit::Bit64, Some(&iv)); + +    let timestamp = mc.decrypt_base64_to_string(×tamp) +        .expect("unable to read trial key"); + +    DateTime::parse_from_rfc3339(×tamp) +        .expect("unable to parse timestamp") +} + +fn initialization_vector() -> String { +    // Multiplied by 2 for no good reason other than to make the value +    // different from the actual timestamp. +    (Local::now().timestamp_millis() * 2).to_string() +} + +// initialize_trial_start +// encode_datetime +// check_days_remaining +// days_remaining_from_now +  #[cfg(test)]  mod tests { | 
