Struct totp_rfc6238::high_level::TotpGenerator[][src]

pub struct TotpGenerator { /* fields omitted */ }
Expand description

TOTP code generator

Example

use totp_rfc6238::{HashAlgorithm, TotpGenerator};
let key = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890+/";
// Create a non-standard TOTP code generator: 8-digit, updating every 60
// seconds, starting at "Jan 01 1970 00:16:40 UTC", using HMAC-SHA512.
let totp_generator = TotpGenerator::new()
    .set_digit(8).unwrap()
    .set_step(60).unwrap()
    .set_t0(1000)
    .set_hash_algorithm(HashAlgorithm::SHA512)
    .build();

let output1 = totp_generator.get_code(key);
println!("Your TOTP code for current time is: {}", output1);

let output2 = totp_generator.get_next_update_time().unwrap();
println!("Next update will be at the unix timestamp of {}", output2);

let output3 = totp_generator.get_code_window(key, -5..=5).unwrap();
println!("Codes for 5 minutes earlier or later are:");
for i in output3 {
    println!("  {}", i);
}

Why this struct doesn’t store the keys?

  • The key is the secret credential of TOTP.
  • For some reasons, programmers may consider keeping TotpGenerator instances in memory for a period of time.
  • However, the keys should not be kept in memory for a long time if they do not need to be used during this time. Especially for those devices with a certain secure storage area, storing the keys in the memory for a long time weakens the security system.
  • Therefore, we recommend: the key is only loaded into memory when needed. And, when the operation is done, use some reliable method to overwrite the memory area corresponding to key. (For example, the crate zeroize might be helpful for this)
  • The details of security can be very complicated, and we can’t include all of them here. If you are interested, you can check the relevant information yourself. If you have better suggestions, please don’t hesitate to discuss on GitHub Issues or start a Pull Request.

Implementations

impl TotpGenerator[src]

pub fn new() -> TotpBuilder[src]

Create a new builder of TotpGenerator.

Default value: digit = 6, step = 30, t0 = 0, HashAlgorithm::SHA1.
These step = 30, t0 = 0 are default values in RFC 6238 Section 4.

pub fn get_code(&self, key: &[u8]) -> String[src]

Generate the TOTP code using the given key bytes.

Panics

Panics if the current system time is earlier than the Unix epoch (1970-01-01T00:00:00Z) and this instance of TotpGenerator is using the system time.

pub fn get_code_with<F: Fn() -> u64>(&self, key: &[u8], func: F) -> String[src]

Generate the TOTP code using a closure to specify the time (For example, getting network time instead of using system time).

pub fn get_code_window<T: Iterator<Item = isize>>(
    &self,
    key: &[u8],
    window: T
) -> Option<Vec<String>>
[src]

Generate a window of contiguous TOTP codes (This may be helpful for time tolerance).
This returns None if the iterator window cannot produce a valid TOTP counter value.

Example

use totp_rfc6238::TotpGenerator;
use std::thread::sleep;
use std::time::Duration;
let shared_key = b"12345678901234567890";
// a fast TOTP that updates every seconds
let client_totp = TotpGenerator::new().set_step(1).unwrap().build();
let client_code = client_totp.get_code(shared_key);

// Let's simulate the time difference.
sleep(Duration::from_millis(800));

let server_totp = TotpGenerator::new().set_step(1).unwrap().build();
// This provides time tolerance of -2 ~ +2 period.
let server_code = server_totp.get_code_window(shared_key, -2..=2).unwrap();
assert!(server_code.iter().any(|x| x == client_code.as_str()));

Panics

Panics if the current system time is earlier than the Unix epoch (1970-01-01T00:00:00Z) and this instance of TotpGenerator is using the system time.

pub fn get_code_window_with<T: Iterator<Item = isize>, F: Fn() -> u64>(
    &self,
    key: &[u8],
    window: T,
    func: F
) -> Option<Vec<String>>
[src]

Generate a window of contiguous TOTP codes using a closure to specify the time.

pub fn get_next_update_time(&self) -> Option<u64>[src]

Get the next timestamp when the TOTP code will be updated.
This returns None if timestamp goes over the maximum of 64-bit unsigned integer.

Panics

Panics if the current system time is earlier than the Unix epoch (1970-01-01T00:00:00Z) and this instance of TotpGenerator is using the system time.

pub fn freeze_time(&mut self, timestamp: u64) -> Option<u64>[src]

Store or update a fixed timestamp and make this instance use that time to generate TOTP codes.
This method returns the previously stored timestamp.

Example

use totp_rfc6238::TotpGenerator;
let mut totp_generator = TotpGenerator::new().set_digit(8).unwrap().build();
let key = b"12345678901234567890";

assert_eq!(totp_generator.freeze_time(59), None);

let output1 = totp_generator.get_code(key);
assert_eq!(output1.as_str(), "94287082");

assert_eq!(totp_generator.release_time(), Some(59));

let output2 = totp_generator.get_code(key);
assert_ne!(output1.as_str(), output2.as_str());

pub fn release_time(&mut self) -> Option<u64>[src]

Remove the stored timestamp. This is the opposite of the TotpGenerator::freeze_time method.
When TotpGenerator::get_code or TotpGenerator::get_code_window are called, the system time at that moment will be used.
This method returns the previously stored timestamp.

pub fn get_frozen_time(&self) -> Option<u64>[src]

Get the previously stored timestamp (but do not remove it).
This returns None if no timestamp is stored.

pub fn get_step(&self) -> u64[src]

Get value of the field step: the update time interval in seconds.

pub fn get_digit(&self) -> usize[src]

Get value of the field digit: the length of the TOTP code.

pub fn get_t0(&self) -> u64[src]

Get value of the field t0: the Unix timestamp of the initial counter time T0.

pub fn get_hash_algorithm(&self) -> HashAlgorithm[src]

Get value of the field hash_algorithm.

Trait Implementations

impl Clone for TotpGenerator[src]

fn clone(&self) -> TotpGenerator[src]

Returns a copy of the value. Read more

fn clone_from(&mut self, source: &Self)1.0.0[src]

Performs copy-assignment from source. Read more

impl Debug for TotpGenerator[src]

fn fmt(&self, f: &mut Formatter<'_>) -> Result[src]

Formats the value using the given formatter. Read more

impl PartialEq<TotpGenerator> for TotpGenerator[src]

fn eq(&self, other: &TotpGenerator) -> bool[src]

This method tests for self and other values to be equal, and is used by ==. Read more

fn ne(&self, other: &TotpGenerator) -> bool[src]

This method tests for !=.

impl Copy for TotpGenerator[src]

impl Eq for TotpGenerator[src]

impl StructuralEq for TotpGenerator[src]

impl StructuralPartialEq for TotpGenerator[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

pub fn type_id(&self) -> TypeId[src]

Gets the TypeId of self. Read more

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

pub fn borrow(&self) -> &T[src]

Immutably borrows from an owned value. Read more

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

pub fn borrow_mut(&mut self) -> &mut T[src]

Mutably borrows from an owned value. Read more

impl<T> From<T> for T[src]

pub fn from(t: T) -> T[src]

Performs the conversion.

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

pub fn into(self) -> U[src]

Performs the conversion.

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

pub fn to_owned(&self) -> T[src]

Creates owned data from borrowed data, usually by cloning. Read more

pub fn clone_into(&self, target: &mut T)[src]

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

Uses borrowed data to replace owned data, usually by cloning. Read more

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]

Performs the conversion.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>[src]

Performs the conversion.