Skip to content

Commit 5500e6c

Browse files
committed
WIP documentation
Missing some in TOTP, but I need to sleep
1 parent cb5384d commit 5500e6c

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

src/hotp.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use crate::util::{base32_decode, get_code, hash_generic, MacDigest};
44

55
/// A HOTP Generator
66
///
7-
/// Follows the specification listed in [RFC4226]. Needs a secret on
8-
/// initialization, with other single generation-specific items being
9-
/// provided when [`HOTP::get_otp`] is called.
7+
/// Follows the specification listed in [RFC4226]. Needs a secret and a number of digits on initialization.
8+
/// The HOTP can then be generated using [`HOTP::get_otp`].
109
///
1110
/// # Example
1211
/// See the top-level README for an example of HOTP usage
@@ -21,65 +20,69 @@ pub struct HOTP {
2120
/// The secret key used in the HMAC process.
2221
///
2322
/// Often given as a Base32 key, which can be conveniently initialize using
24-
/// the [`HOTP::from_base32`] initializers
23+
/// the [`HOTP::from_base32`] constructors.
2524
secret: Vec<u8>,
2625

26+
/// The number of digits of the code generated.
27+
///
28+
/// This value defaults to 6 if not specified in a constructor.
2729
digits: u32,
2830
}
2931

3032
/// All initializer implementations for the [`HOTP`] struct.
3133
impl HOTP {
3234
/// Creates a new HOTP instance with a byte-array representation
33-
/// of the secret
35+
/// of the secret and the number of digits.
3436
///
3537
/// Since only SHA1 was specified in the reference implementation and
36-
/// RFC specification, there's no need to initialize with a digest object
38+
/// RFC specification, there's no need to initialize with a digest object.
3739
pub fn new(secret: &[u8], digits: u32) -> Self {
3840
HOTP {
3941
secret: secret.to_vec(),
4042
digits,
4143
}
4244
}
4345

46+
/// Creates a new HOTP instance from a utf8-encoded string secret and the number of digits.
4447
pub fn new_from_utf8(secret: &str, digits: u32) -> Self {
4548
HOTP::new(secret.as_bytes(), digits)
4649
}
4750

51+
/// Creates a new HOTP instance from a base32-encoded string secret and the number of digits.
52+
///
53+
/// # Panics
54+
/// This method panics if the provided string is not correctly base32 encoded.
4855
pub fn new_from_base32(secret: &str, digits: u32) -> Self {
4956
let decoded = base32_decode(secret).expect("Failed to decode base32 string");
5057
HOTP::new(&decoded, digits)
5158
}
5259

53-
/// Creates a new HOTP instance from a utf8-encoded string secret
54-
///
55-
/// Internally calls [`HOTP::new`] with the string's byte representation
60+
/// Creates a new HOTP instance from a utf8-encoded string secret and a default number of 6 digits.
5661
pub fn from_utf8(secret: &str) -> Self {
5762
HOTP::new_from_utf8(secret, 6)
5863
}
5964

60-
/// Creates a new HOTP instance from a base32-encoded string secret
61-
///
62-
/// Internally calls [`HOTP::new`] after decoding the string
65+
/// Creates a new HOTP instance from a base32-encoded string secret and a default number of 6 digits.
6366
///
6467
/// # Panics
65-
/// This method panics if the provided string is not correctly base32
66-
/// encoded.
68+
/// This method panics if the provided string is not correctly base32 encoded.
6769
pub fn from_base32(secret: &str) -> Self {
6870
HOTP::new_from_base32(secret, 6)
6971
}
7072
}
7173

7274
impl HOTP {
75+
/// Gets the number of digits of the code.
7376
pub fn get_digits(&self) -> u32 {
7477
self.digits
7578
}
7679
}
7780

7881
/// All otp generation methods for the [`HOTP`] struct.
7982
impl HOTP {
80-
/// Generates and returns the HOTP value
83+
/// Generates and returns the HOTP value.
8184
///
82-
/// Uses the given counter value with the specified digit count
85+
/// Uses the given counter value.
8386
///
8487
/// # Panics
8588
/// This method panics if the hash's secret is incorrectly given.

src/totp.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ use crate::util::{base32_decode, get_code, hash_generic, MacDigest};
22

33
/// A TOTP generator
44
///
5-
/// Follows the specification listed in [RFC6238]. Needs a secret
6-
/// and digest algorithm on initialization, with other single
7-
/// generation-specific items being provided when the [`TOTP::get_otp`] or
8-
/// [`TOTP::get_otp_with_custom`] is called.
5+
/// Follows the specification listed in [RFC6238]. Needs a secret,
6+
/// a digest algorithm, a number of digits and a period on initialization.
7+
/// The TOTP can then be generated using [`TOTP::get_otp`] or
8+
/// [`TOTP::get_otp_with_custom_time_start`].
99
///
1010
/// # Example
1111
/// See the top-level README for an example of TOTP usage
@@ -14,28 +14,31 @@ use crate::util::{base32_decode, get_code, hash_generic, MacDigest};
1414
/// utilized in a similar manner.
1515
///
1616
/// [RFC6238]: https://datatracker.ietf.org/doc/html/rfc6238
17-
1817
#[derive(Debug, Clone, Hash)]
1918
pub struct TOTP {
2019
/// The secret key used in the HMAC process.
2120
///
22-
/// Often given as a Base32 key, which can be conveniently initialize using
23-
/// the [`TOTP::from_base32`] or [`TOTP::from_base32_with_digest`]
24-
/// initializers.
21+
/// Often given as a Base32 key, which can be conveniently initialized using
22+
/// [`TOTP::from_base32`] constructors.
2523
secret: Vec<u8>,
2624

2725
/// The digest to use in the HMAC process.
2826
///
29-
/// Unless an initializer ending in 'with_digest' is used, this value
30-
/// defaults to [`MacDigest::SHA1`]
27+
/// This value defaults to [`MacDigest::SHA1`] if not specified in a constructor.
3128
mac_digest: MacDigest,
3229

30+
/// The number of digits of the code generated.
31+
///
32+
/// This value defaults to 6 if not specified in a constructor.
3333
digits: u32,
3434

35+
/// The period in seconds between two different generated code.
36+
///
37+
/// This value defaults to 30 if not specified in a constructor.
3538
period: u64,
3639
}
3740

38-
/// All initializer implementations for the [`TOTP`] struct
41+
// All initializer implementations for the [`TOTP`] struct
3942
impl TOTP {
4043
pub fn new(secret: &[u8], mac_digest: MacDigest, digits: u32, period: u64) -> Self {
4144
TOTP {
@@ -112,21 +115,25 @@ impl TOTP {
112115
}
113116
}
114117

118+
// All getters
115119
impl TOTP {
120+
/// Gets the algorithm used for code generation.
116121
pub fn get_digest(&self) -> MacDigest {
117122
self.mac_digest
118123
}
119124

125+
/// Gets the number of digits of the code.
120126
pub fn get_digits(&self) -> u32 {
121127
self.digits
122128
}
123129

130+
/// Gets the period between different generated code.
124131
pub fn get_period(&self) -> u64 {
125132
self.period
126133
}
127134
}
128135

129-
/// All otp generation methods for the [`TOTP`] struct.
136+
// All otp generation methods for the [`TOTP`] struct.
130137
impl TOTP {
131138
/// Generates and returns the TOTP value for the time with the
132139
/// specified digits.

src/util.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use url::Url;
88
use crate::hotp::HOTP;
99
use crate::totp::TOTP;
1010

11-
/// The digest to use with TOTP
11+
/// The digest to use with TOTP.
1212
///
1313
/// All three digests referenced in [RFC6238] are supported:
1414
/// - SHA1
@@ -27,10 +27,9 @@ pub enum MacDigest {
2727
}
2828

2929
/// A generic method to convert the [H/T]OTP byte-array into the
30-
/// requested decimal-based code
30+
/// requested decimal-based code.
3131
///
32-
/// Needs the bytes to convert and the amount of digits the code should be
33-
32+
/// Needs the bytes to convert and the amount of digits the code should be.
3433
pub(crate) fn get_code(bytes: [u8; 4], digits: u32) -> u32 {
3534
let code = (((bytes[0] & 0x7f) as u32) << 24)
3635
| ((bytes[1] as u32) << 16)
@@ -42,11 +41,10 @@ pub(crate) fn get_code(bytes: [u8; 4], digits: u32) -> u32 {
4241
/// A method to hash a message with a given secret and digest.
4342
///
4443
/// The only time [`MacDigest`] is not [`MacDigest::SHA1`] is when the
45-
/// TOTP instance's mac_digest is set otherwise
44+
/// TOTP instance's mac_digest is set otherwise.
4645
///
4746
/// Calls the underlying [`hash_internal`] function with the correctly
4847
/// HMAC-mapped algorithm.
49-
5048
pub(crate) fn hash_generic(msg: &[u8], secret: &[u8], digest: &MacDigest) -> Vec<u8> {
5149
match *digest {
5250
MacDigest::SHA1 => hash_internal::<Hmac<Sha1>>(msg, secret),
@@ -55,32 +53,36 @@ pub(crate) fn hash_generic(msg: &[u8], secret: &[u8], digest: &MacDigest) -> Vec
5553
}
5654
}
5755

58-
/// A generic method to HMAC a message using the given type
56+
/// A generic method to HMAC a message using the given type.
5957
///
6058
/// This is mainly a private method made for added convenience and code
6159
/// readability to reduce the duplicate code with different
62-
/// underlying digests
60+
/// underlying digests.
6361
///
6462
/// # Panics
6563
/// The method will panic if the provided secret is invalid and a hash
66-
/// cannot be generated
67-
64+
/// cannot be generated.
6865
fn hash_internal<D: Mac>(msg: &[u8], secret: &[u8]) -> Vec<u8> {
6966
let mut hmac = <D>::new_from_slice(secret).expect("Failed to initialize HMAC");
7067
hmac.update(msg);
7168
hmac.finalize().into_bytes()[..].into()
7269
}
7370

71+
/// Decodes a base32 string according to RFC4648.
7472
pub(crate) fn base32_decode(data: &str) -> Option<Vec<u8>> {
7573
base32::decode(Alphabet::RFC4648 { padding: false }, data)
7674
}
7775

76+
/// Result of an otpauth URI parsing.
77+
///
78+
/// It's either a TOTP or a HOTP with its current counter.
7879
#[derive(Debug)]
7980
pub enum ParseResult {
8081
TOTP(TOTP),
8182
HOTP(HOTP, u64),
8283
}
8384

85+
/// Different error types of the optauth URI parsing.
8486
#[derive(Debug)]
8587
pub enum ParseError {
8688
UriParseError(url::ParseError),
@@ -96,6 +98,8 @@ pub enum ParseError {
9698
InvalidPeriod(String),
9799
}
98100

101+
/// Parses an otpauth URI, which is the string format of the QR codes usually given by platforms for TOTP.
102+
/// This method is safe and shouldn't panic.
99103
pub fn parse_otpauth_uri(uri: &str) -> Result<ParseResult, ParseError> {
100104
use ParseError::*;
101105

0 commit comments

Comments
 (0)