Skip to content

Commit

Permalink
Use seconds in RFC MIDP and RADI values; test that tags are ordered
Browse files Browse the repository at this point in the history
  • Loading branch information
int08h committed Mar 16, 2024
1 parent bc4fa6f commit fe76da7
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 22 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ simple_logger = "1"
yaml-rust = "0.4"
zeroize = "1.4"
data-encoding = "2.3"
enum-iterator = "2.0"

# Used by 'awskms' and 'gcpkms'
futures = { version = "^0.3", optional = true }
Expand Down
3 changes: 2 additions & 1 deletion benches/roughenough-bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use criterion::Throughput::Elements;
use roughenough::merkle::MerkleTree;
use roughenough::{RtMessage, Tag};
use roughenough::key::OnlineKey;
use roughenough::version::Version;

fn create_signed_srep_tags(c: &mut Criterion) {
let mut group = c.benchmark_group("signing");
Expand All @@ -18,7 +19,7 @@ fn create_signed_srep_tags(c: &mut Criterion) {
group.throughput(Elements(1));
group.bench_function("create signed SREP tag", |b| {
let now = SystemTime::now();
b.iter(|| black_box(key.make_srep(now, data.as_ref())))
b.iter(|| black_box(key.make_srep(Version::Rfc, now, data.as_ref(), )))
});
group.finish();
}
Expand Down
4 changes: 2 additions & 2 deletions src/bin/roughenough-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,17 @@ fn make_request(ver: Version, nonce: &Nonce, text_dump: bool) -> Vec<u8> {
msg.encode().unwrap()
}
Version::Rfc => {
msg.add_field(Tag::PAD_RFC, &[]).unwrap();
msg.add_field(Tag::VER, ver.wire_bytes()).unwrap();
msg.add_field(Tag::NONC, nonce).unwrap();
msg.add_field(Tag::ZZZZ, &[]).unwrap();

let padding_needed = msg.calculate_padding_length();
let padding: Vec<u8> = (0..padding_needed).map(|_| 0).collect();

msg.clear();
msg.add_field(Tag::PAD_RFC, &padding).unwrap();
msg.add_field(Tag::VER, ver.wire_bytes()).unwrap();
msg.add_field(Tag::NONC, nonce).unwrap();
msg.add_field(Tag::ZZZZ, &padding).unwrap();

if text_dump {
eprintln!("Request = {}", msg);
Expand Down
41 changes: 29 additions & 12 deletions src/key/online.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::message::RtMessage;
use crate::sign::Signer;
use crate::SIGNED_RESPONSE_CONTEXT;
use crate::tag::Tag;
use crate::version::Version;

///
/// Represents the delegated Roughtime ephemeral online key.
Expand Down Expand Up @@ -57,26 +58,42 @@ impl OnlineKey {
dele_msg
}

/// Classic protocol, epoch time in microseconds
fn classic_midp(&self, now: SystemTime) -> u64 {
let d = now
.duration_since(UNIX_EPOCH)
.expect("duration since epoch");
let secs = d.as_secs() * 1_000_000;
let nsecs = (d.subsec_nanos() as u64) / 1_000;

secs + nsecs
}

/// RFC protocol, a uint64 count of seconds since the Unix epoch in UTC.
fn rfc_midp(&self, now: SystemTime) -> u64 {
now.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}

/// Create an SREP response containing the provided time and Merkle root,
/// signed by this online key.
pub fn make_srep(&mut self, now: SystemTime, merkle_root: &[u8]) -> RtMessage {
pub fn make_srep(&mut self, ver: Version, now: SystemTime, merkle_root: &[u8]) -> RtMessage {
let mut radi = [0; 4];
let mut midp = [0; 8];

// one second (in microseconds)
let radi_time = match ver {
Version::Classic => 1_000_000, // one second in microseconds
Version::Rfc => 1, // one second
};

(&mut radi as &mut [u8])
.write_u32::<LittleEndian>(1_000_000)
.write_u32::<LittleEndian>(radi_time)
.unwrap();

// current epoch time in microseconds
let midp_time = {
let d = now
.duration_since(UNIX_EPOCH)
.expect("duration since epoch");
let secs = d.as_secs() * 1_000_000;
let nsecs = (d.subsec_nanos() as u64) / 1_000;

secs + nsecs
let midp_time = match ver {
Version::Classic => self.classic_midp(now),
Version::Rfc => self.rfc_midp(now),
};

(&mut midp as &mut [u8])
Expand Down
2 changes: 1 addition & 1 deletion src/responder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl Responder {
let merkle_root = self.merkle.compute_root();

// The SREP tag is identical for each response
let srep = self.online_key.make_srep(SystemTime::now(), &merkle_root);
let srep = self.online_key.make_srep(self.version, SystemTime::now(), &merkle_root);

for (idx, &(ref nonce, ref src_addr)) in self.requests.iter().enumerate() {
let paths = self.merkle.get_paths(idx);
Expand Down
31 changes: 25 additions & 6 deletions src/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@
// limitations under the License.

use std::fmt::{Display, Formatter};
use enum_iterator::Sequence;

use crate::error::Error;

/// An unsigned 32-bit value (key) that maps to a byte-string (value).
#[allow(non_camel_case_types)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Hash, Clone, Copy)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Hash, Clone, Copy, Sequence)]
pub enum Tag {
// Enforcement of the "tags in strictly increasing order" rule is done using the
// little-endian encoding of the ASCII tag value; e.g. 'SIG\x00' is 0x00474953 and
// 'NONC' is 0x434e4f4e.
//
// Tags are written here in ascending order
PAD_RFC,
SIG,
VER,
DUT1,
Expand All @@ -43,6 +43,7 @@ pub enum Tag {
CERT,
MAXT,
INDX,
ZZZZ,
PAD_CLASSIC,
}

Expand All @@ -55,7 +56,6 @@ impl Tag {
const BYTES_MINT: &'static [u8] = b"MINT";
const BYTES_NONC: &'static [u8] = b"NONC";
const BYTES_PAD_CLASSIC: &'static [u8] = b"PAD\xff";
const BYTES_PAD_RFC: &'static [u8] = b"PAD\x00";
const BYTES_PATH: &'static [u8] = b"PATH";
const BYTES_PUBK: &'static [u8] = b"PUBK";
const BYTES_RADI: &'static [u8] = b"RADI";
Expand All @@ -66,6 +66,7 @@ impl Tag {
const BYTES_DUT1: &'static [u8] = b"DUT1";
const BYTES_DTAI: &'static [u8] = b"DTAI";
const BYTES_LEAP: &'static [u8] = b"LEAP";
const BYTES_ZZZZ: &'static [u8] = b"ZZZZ";

/// Translates a tag into its on-the-wire representation
pub fn wire_value(self) -> &'static [u8] {
Expand All @@ -78,7 +79,6 @@ impl Tag {
Tag::MINT => Tag::BYTES_MINT,
Tag::NONC => Tag::BYTES_NONC,
Tag::PAD_CLASSIC => Tag::BYTES_PAD_CLASSIC,
Tag::PAD_RFC => Tag::BYTES_PAD_RFC,
Tag::PATH => Tag::BYTES_PATH,
Tag::PUBK => Tag::BYTES_PUBK,
Tag::RADI => Tag::BYTES_RADI,
Expand All @@ -89,6 +89,7 @@ impl Tag {
Tag::DUT1 => Tag::BYTES_DUT1,
Tag::DTAI => Tag::BYTES_DTAI,
Tag::LEAP => Tag::BYTES_LEAP,
Tag::ZZZZ => Tag::BYTES_ZZZZ,
}
}

Expand All @@ -104,7 +105,6 @@ impl Tag {
Tag::BYTES_MINT => Ok(Tag::MINT),
Tag::BYTES_NONC => Ok(Tag::NONC),
Tag::BYTES_PAD_CLASSIC => Ok(Tag::PAD_CLASSIC),
Tag::BYTES_PAD_RFC => Ok(Tag::PAD_RFC),
Tag::BYTES_PATH => Ok(Tag::PATH),
Tag::BYTES_PUBK => Ok(Tag::PUBK),
Tag::BYTES_RADI => Ok(Tag::RADI),
Expand All @@ -115,6 +115,7 @@ impl Tag {
Tag::BYTES_DUT1 => Ok(Tag::DUT1),
Tag::BYTES_DTAI => Ok(Tag::DTAI),
Tag::BYTES_LEAP => Ok(Tag::LEAP),
Tag::BYTES_ZZZZ => Ok(Tag::ZZZZ),
_ => Err(Error::InvalidTag(Box::from(bytes))),
}
}
Expand All @@ -127,7 +128,6 @@ impl Tag {
/// A short (non canonical) string representation of the tag
fn to_string(&self) -> String {
match self {
Tag::PAD_RFC => String::from("PAD00"),
Tag::PAD_CLASSIC => String::from("PADff"),
Tag::SIG => String::from("SIG"),
Tag::VER => String::from("VER"),
Expand All @@ -141,3 +141,22 @@ impl Display for Tag {
write!(f, "{}", self.to_string())
}
}


#[cfg(test)]
mod test {
use super::*;
use enum_iterator;

#[test]
fn tags_in_increasing_order() {
let values = enum_iterator::all::<Tag>().collect::<Vec<_>>();
for (idx, _) in values.iter().enumerate() {
if idx == 0 {
continue
}
assert!(values[idx - 1] < values[idx]);
}

}
}

0 comments on commit fe76da7

Please sign in to comment.