diff --git a/Cargo.toml b/Cargo.toml
index 53ca541..a4ecdac 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,22 +34,21 @@ harness = false
default = ["binary-build"]
binary-build = ["instant"]
benchmark-helpers = ["instant"]
-bpsec = ["dep:sha2", "dep:hmac", "dep:hex-literal"]
+bpsec = ["dep:sha2", "dep:hmac"]
[dependencies]
humantime = "2.1.0"
-serde = { version = "1.0.193", features = ["derive"] }
+serde = { version = "1.0.216", features = ["derive"] }
serde_cbor = "0.11.1"
-serde_json = "1.0.61"
-serde_bytes = "0.11.5"
-crc = "3.0.1"
-thiserror = "1.0.23"
-bitflags = "2.2.1"
+serde_json = "1.0.133"
+serde_bytes = "0.11.15"
+crc = "3.2.1"
+thiserror = "2.0.7"
+bitflags = "2.6.0"
# bpsec dependencies
-sha2 = { version ="0.10.6", optional = true }
-hmac = { version ="0.12.1", optional = true }
-hex-literal = { version ="0.3.4", optional = true }
+sha2 = { version = "0.10.6", optional = true }
+hmac = { version = "0.12.1", optional = true }
# non wasm config
diff --git a/src/security.rs b/src/security.rs
index cb6dfc9..484b3d3 100644
--- a/src/security.rs
+++ b/src/security.rs
@@ -19,16 +19,13 @@ use thiserror::Error;
// use aes_kw::Kek;
-
-use sha2::{Sha256, Sha384, Sha512};
use hmac::{Hmac, Mac};
+use sha2::{Sha256, Sha384, Sha512};
use serde::de::{SeqAccess, Visitor};
use serde::ser::{SerializeSeq, Serializer};
use serde::{de, Deserialize, Deserializer, Serialize};
-
-
// https://www.rfc-editor.org/rfc/rfc9172.html#BlockType
pub const INTEGRITY_BLOCK: CanonicalBlockType = 11;
pub const CONFIDENTIALITY_BLOCK: CanonicalBlockType = 12;
@@ -37,7 +34,7 @@ pub const CONFIDENTIALITY_BLOCK: CanonicalBlockType = 12;
// https://www.rfc-editor.org/rfc/rfc9173.html#name-sha-variant
pub type ShaVariantType = u16;
pub const HMAC_SHA_256: ShaVariantType = 5;
-pub const HMAC_SHA_384: ShaVariantType = 6; // default
+pub const HMAC_SHA_384: ShaVariantType = 6; // default
pub const HMAC_SHA_512: ShaVariantType = 7;
// Security Context Id
@@ -48,12 +45,11 @@ pub const BIB_HMAC_SHA2_ID: SecurityContextId = 1; // BIB-HMAC-SHA2
pub const BCB_AES_GCM_ID: SecurityContextId = 2; // BCB-AES-GCM
// Security Context Flags
-//
+//
pub type SecurityContextFlag = u8;
pub const SEC_CONTEXT_ABSENT: SecurityContextFlag = 0; // Security context parameters should be empty
pub const SEC_CONTEXT_PRESENT: SecurityContextFlag = 1; // Security context parameters are defined
-
// AES Variant
// https://www.rfc-editor.org/rfc/rfc9173.html#name-aes-gcm
pub type AesVariantType = u16;
@@ -75,7 +71,7 @@ pub struct IpptBuilder {
impl IpptBuilder {
pub fn new() -> IpptBuilder {
IpptBuilder {
- scope_flags: 0x0007, // default value
+ scope_flags: 0x0007, // default value
primary_block: None,
security_header: None,
security_target_contents: Vec::new(),
@@ -98,7 +94,6 @@ impl IpptBuilder {
self
}
pub fn build(self) -> IntegrityProtectedPlaintext {
-
IntegrityProtectedPlaintext {
scope_flags: self.scope_flags,
primary_block: self.primary_block,
@@ -108,13 +103,12 @@ impl IpptBuilder {
}
}
-
-/// Structure to hold the Integrity Protected Plaintext. The content
-/// of the IPPT is constructed as the concatenation of information
+/// Structure to hold the Integrity Protected Plaintext. The content
+/// of the IPPT is constructed as the concatenation of information
/// whose integrity is being preserved. Can optionally protect the integrity of
/// the primary block, the payload block header, the security block header.
/// The payload of the security target itself is always protected.
-///
+///
/// To function correctly the scope_flags have to be set accordingly.
/// The default value is 0x0007, which means all flags are set. The
/// other options for the scope_flags are:
@@ -122,20 +116,20 @@ impl IpptBuilder {
/// Bit 1 (0x0002): Include target header flag
/// Bit 2 (0x0004): Include security header flag
/// Bits 3-15: Unassigned. Do NOT set.
-///
+///
/// # Fields
/// * `scope_flags` - Bit field
/// * `primary_block` - A reference to the primary block
-/// * `security_header` - A tuple with the values of the block_type,
-/// the block_number and the block_control_flags
+/// * `security_header` - A tuple with the values of the block_type,
+/// the block_number and the block_control_flags
/// * `security_target_contents` - A Vector with the result values
-///
+///
/// # RFC references
/// [IPPT](https://www.rfc-editor.org/rfc/rfc9173.html#name-scope)
-///
+///
/// # Results
-///
-/// # Example
+///
+/// # Example
/// TODO: example
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct IntegrityProtectedPlaintext {
@@ -149,7 +143,7 @@ pub struct IntegrityProtectedPlaintext {
impl IntegrityProtectedPlaintext {
pub fn new() -> IntegrityProtectedPlaintext {
IntegrityProtectedPlaintext {
- scope_flags: 0x0007, // default value
+ scope_flags: 0x0007, // default value
primary_block: None,
security_header: None,
security_target_contents: Vec::new(),
@@ -160,55 +154,68 @@ impl IntegrityProtectedPlaintext {
// If header data is not none and corresponding flag is set, include in MAC
let mut optional_ippt_data = Vec::::new();
- if self.scope_flags.contains(IntegrityScopeFlags::INTEGRITY_PRIMARY_HEADER) {
+ if self
+ .scope_flags
+ .contains(IntegrityScopeFlags::INTEGRITY_PRIMARY_HEADER)
+ {
if let Some(pb) = &self.primary_block {
optional_ippt_data.append(
serde_cbor::to_vec(pb)
.expect("Error creating canonical form of primary block")
- .as_mut()
+ .as_mut(),
);
} else {
eprintln!("Primary header flag set but no primary header given!")
}
}
- if self.scope_flags.contains(IntegrityScopeFlags::INTEGRITY_PAYLOAD_HEADER) {
+ if self
+ .scope_flags
+ .contains(IntegrityScopeFlags::INTEGRITY_PAYLOAD_HEADER)
+ {
optional_ippt_data.append(
- self.construct_payload_header(&payload_block)
+ self.construct_payload_header(payload_block)
.expect("Error constructing payload header")
- .as_mut()
+ .as_mut(),
);
}
- if self.scope_flags.contains(IntegrityScopeFlags::INTEGRITY_SECURITY_HEADER) {
+ if self
+ .scope_flags
+ .contains(IntegrityScopeFlags::INTEGRITY_SECURITY_HEADER)
+ {
if let Some(sh) = &self.security_header {
optional_ippt_data.append(
self.construct_security_header(sh)
.expect("Error constructing security header")
- .as_mut()
+ .as_mut(),
);
} else {
eprintln!("Security header flag set but no security header given!")
}
}
-
-
self.security_target_contents = serde_cbor::to_vec(&payload_block.data()).unwrap();
-
+
// create canonical form of other data
if !matches!(payload_block.data(), CanonicalData::Data(_)) {
- let temp_bytes = serde_bytes::Bytes::new(&self.security_target_contents.as_slice());
+ let temp_bytes = serde_bytes::Bytes::new(self.security_target_contents.as_slice());
self.security_target_contents = serde_cbor::to_vec(&temp_bytes).unwrap();
}
let mut ippt = Vec::::new();
- ippt.append(&mut serde_cbor::to_vec(&self.scope_flags).expect("Error creating canonical form of scope flags"));
+ ippt.append(
+ &mut serde_cbor::to_vec(&self.scope_flags)
+ .expect("Error creating canonical form of scope flags"),
+ );
ippt.append(&mut optional_ippt_data);
ippt.append(&mut self.security_target_contents);
println!("ippt hex {:?}", hexify(&ippt));
ippt
}
- fn construct_payload_header(&self, payload_block: &CanonicalBlock) -> Result{
+ fn construct_payload_header(
+ &self,
+ payload_block: &CanonicalBlock,
+ ) -> Result {
let mut header = Vec::::new();
header.append(&mut serde_cbor::to_vec(&payload_block.block_type)?);
header.append(&mut serde_cbor::to_vec(&payload_block.block_number)?);
@@ -217,17 +224,18 @@ impl IntegrityProtectedPlaintext {
Ok(header)
}
- fn construct_security_header(&self, security_block_parameter: &SecurityBlockHeader) -> Result{
+ fn construct_security_header(
+ &self,
+ security_block_parameter: &SecurityBlockHeader,
+ ) -> Result {
let mut header = Vec::::new();
header.append(&mut serde_cbor::to_vec(&security_block_parameter.0)?);
header.append(&mut serde_cbor::to_vec(&security_block_parameter.1)?);
- header.append(&mut serde_cbor::to_vec(&security_block_parameter.2)?);
+ header.append(&mut serde_cbor::to_vec(&security_block_parameter.2)?);
Ok(header)
}
-
}
-
impl Default for IntegrityProtectedPlaintext {
fn default() -> Self {
IntegrityProtectedPlaintext::new()
@@ -240,9 +248,6 @@ impl Default for IpptBuilder {
}
}
-
-
-
// Integrity Scope Flags
// https://www.rfc-editor.org/rfc/rfc9173.html#name-integrity-scope-flags
pub type IntegrityScopeFlagsType = u16;
@@ -274,11 +279,9 @@ impl ScopeValidation for IntegrityScopeFlagsType {
}
}
-
// Abstract Security Block
// https://www.rfc-editor.org/rfc/rfc9172.html#name-abstract-security-block
-
// Security Context Parameters
// https://www.rfc-editor.org/rfc/rfc9173.html#name-enumerations
@@ -292,9 +295,9 @@ pub struct BibSecurityContextParameter {
impl BibSecurityContextParameter {
pub fn new(
- sha_variant: Option<(u8, ShaVariantType)>,
+ sha_variant: Option<(u8, ShaVariantType)>,
wrapped_key: Option<(u8, Vec)>,
- integrity_scope_flags: Option<(u8, IntegrityScopeFlagsType)>
+ integrity_scope_flags: Option<(u8, IntegrityScopeFlagsType)>,
) -> Self {
Self {
sha_variant,
@@ -307,7 +310,7 @@ impl BibSecurityContextParameter {
impl Default for BibSecurityContextParameter {
fn default() -> Self {
BibSecurityContextParameter {
- sha_variant: Some((1, HMAC_SHA_384)),
+ sha_variant: Some((1, HMAC_SHA_384)),
wrapped_key: None,
integrity_scope_flags: Some((3, 0x0007)),
}
@@ -320,19 +323,25 @@ impl Serialize for BibSecurityContextParameter {
S: Serializer,
{
let mut num_elems = 0;
- if self.sha_variant.is_some() { num_elems+=1}
- if self.wrapped_key.is_some() { num_elems+=1}
- if self.integrity_scope_flags.is_some() { num_elems+=1}
+ if self.sha_variant.is_some() {
+ num_elems += 1
+ }
+ if self.wrapped_key.is_some() {
+ num_elems += 1
+ }
+ if self.integrity_scope_flags.is_some() {
+ num_elems += 1
+ }
let mut seq = serializer.serialize_seq(Some(num_elems))?;
-
- if let Some(sv) = &self.sha_variant{
+
+ if let Some(sv) = &self.sha_variant {
seq.serialize_element(sv)?;
}
- if let Some(wk) = &self.wrapped_key{
+ if let Some(wk) = &self.wrapped_key {
seq.serialize_element(&(wk.0, serde_bytes::Bytes::new(&wk.1)))?;
}
- if let Some(isf) = &self.integrity_scope_flags{
+ if let Some(isf) = &self.integrity_scope_flags {
seq.serialize_element(isf)?;
}
@@ -340,7 +349,6 @@ impl Serialize for BibSecurityContextParameter {
}
}
-
impl<'de> Deserialize<'de> for BibSecurityContextParameter {
fn deserialize(deserializer: D) -> Result
where
@@ -359,12 +367,14 @@ impl<'de> Deserialize<'de> for BibSecurityContextParameter {
where
S: SeqAccess<'de>,
{
- let sha_variant = seq.next_element()?
+ let sha_variant = seq
+ .next_element()?
.ok_or_else(|| de::Error::invalid_length(0, &self))?;
// TODO: deal with wrapped key
let wrapped_key = None;
- let integrity_scope_flags = seq.next_element()?
- .ok_or_else(|| de::Error::invalid_length(2, &self))?;
+ let integrity_scope_flags = seq
+ .next_element()?
+ .ok_or_else(|| de::Error::invalid_length(2, &self))?;
Ok(BibSecurityContextParameter {
sha_variant,
@@ -378,12 +388,6 @@ impl<'de> Deserialize<'de> for BibSecurityContextParameter {
}
}
-
-
-
-
-
-
#[derive(Error, Debug)]
pub enum IntegrityBlockBuilderError {
#[error("Security Tragets MUST have at least one enrty")]
@@ -392,29 +396,28 @@ pub enum IntegrityBlockBuilderError {
FlagSetButNoParameter,
}
-
#[derive(Debug, Clone, PartialEq)]
pub struct IntegrityBlockBuilder {
- security_targets: Option>, // array of block numbers TODO: MUST represent the block number of a block that exists in the bundle
+ security_targets: Option>, // array of block numbers TODO: MUST represent the block number of a block that exists in the bundle
security_context_id: SecurityContextId,
security_context_flags: SecurityContextFlag, // bit field
security_source: EndpointID,
security_context_parameters: Option, // optional
- security_results: Vec>, // output of security operations
+ security_results: Vec>, // output of security operations
}
impl IntegrityBlockBuilder {
pub fn new() -> IntegrityBlockBuilder {
IntegrityBlockBuilder {
- security_targets: None,
- security_context_id: BIB_HMAC_SHA2_ID,
- security_context_flags: SEC_CONTEXT_ABSENT,
- security_source: EndpointID::none(),
- security_context_parameters: None,
- security_results: Vec::new(),
+ security_targets: None,
+ security_context_id: BIB_HMAC_SHA2_ID,
+ security_context_flags: SEC_CONTEXT_ABSENT,
+ security_source: EndpointID::none(),
+ security_context_parameters: None,
+ security_results: Vec::new(),
}
}
-
+
pub fn security_targets(mut self, security_targets: Vec) -> Self {
self.security_targets = Some(security_targets);
self
@@ -432,7 +435,10 @@ impl IntegrityBlockBuilder {
self.security_source = security_source;
self
}
- pub fn security_context_parameters(mut self, security_context_parameters: BibSecurityContextParameter) -> Self {
+ pub fn security_context_parameters(
+ mut self,
+ security_context_parameters: BibSecurityContextParameter,
+ ) -> Self {
self.security_context_parameters = Some(security_context_parameters);
self
}
@@ -462,32 +468,30 @@ impl IntegrityBlockBuilder {
#[derive(Debug, Clone, PartialEq)]
pub struct IntegrityBlock {
- pub security_targets: Vec, // array of block numbers
+ pub security_targets: Vec, // array of block numbers
pub security_context_id: SecurityContextId,
pub security_context_flags: SecurityContextFlag, // bit field
pub security_source: EndpointID,
- pub security_context_parameters: Option,
- pub security_results: Vec>, // output of security operations
+ pub security_context_parameters: Option,
+ pub security_results: Vec>, // output of security operations
}
-
impl IntegrityBlock {
pub fn new() -> IntegrityBlock {
IntegrityBlock {
security_targets: Vec::new(),
- security_context_id: BIB_HMAC_SHA2_ID,
+ security_context_id: BIB_HMAC_SHA2_ID,
security_context_flags: SEC_CONTEXT_ABSENT,
security_source: EndpointID::none(),
security_context_parameters: None,
security_results: Vec::new(),
-
}
}
- fn hmac_sha384_compute(&self, key_bytes: &[u8; 16], payload: &ByteBuffer) -> Vec{
- let mut mac = as Mac>::new_from_slice(key_bytes).expect("HMAC can take key of any size");
- mac.update(&payload);
+ fn hmac_sha384_compute(&self, key_bytes: &[u8; 16], payload: &ByteBuffer) -> Vec {
+ let mut mac = as Mac>::new_from_slice(key_bytes)
+ .expect("HMAC can take key of any size");
+ mac.update(payload);
mac.finalize().into_bytes().to_vec()
-
// for testing only
//
@@ -497,45 +501,49 @@ impl IntegrityBlock {
// code_bytes.to_vec()
}
- fn hmac_sha256_compute(&self, key_bytes: &[u8; 16], payload: &ByteBuffer) -> Vec{
- let mut mac = as Mac>::new_from_slice(key_bytes).expect("HMAC can take key of any size");
+ fn hmac_sha256_compute(&self, key_bytes: &[u8; 16], payload: &ByteBuffer) -> Vec {
+ let mut mac = as Mac>::new_from_slice(key_bytes)
+ .expect("HMAC can take key of any size");
//let mut mac = Hmac::::new_from_slice(key_bytes).expect("HMAC can take key of any size");
-
- mac.update(&payload);
+
+ mac.update(payload);
mac.finalize().into_bytes().to_vec()
}
- fn hmac_sha512_compute(&self, key_bytes: &[u8; 16], payload: &ByteBuffer) -> Vec{
- let mut mac = as Mac>::new_from_slice(key_bytes).expect("HMAC can take key of any size");
+ fn hmac_sha512_compute(&self, key_bytes: &[u8; 16], payload: &ByteBuffer) -> Vec {
+ let mut mac = as Mac>::new_from_slice(key_bytes)
+ .expect("HMAC can take key of any size");
//let mut mac = Hmac::::new_from_slice(key_bytes).expect("HMAC can take key of any size");
- mac.update(&payload);
+ mac.update(payload);
mac.finalize().into_bytes().to_vec()
}
-
- pub fn compute_hmac(&mut self, key_bytes: [u8; 16], ippt_list: Vec<(u64, &ByteBuffer)>){
-
+ pub fn compute_hmac(&mut self, key_bytes: [u8; 16], ippt_list: Vec<(u64, &ByteBuffer)>) {
// match ippt_list values to security targets
- self.security_results = vec![];
+ self.security_results = vec![];
for ippt in ippt_list {
if self.security_targets.contains(&ippt.0) {
//let key_bytes = hex!("1a2b1a2b1a2b1a2b1a2b1a2b1a2b1a2b");
- let result_value = match self.security_context_parameters.as_ref().unwrap().sha_variant.unwrap().1{
+ let result_value = match self
+ .security_context_parameters
+ .as_ref()
+ .unwrap()
+ .sha_variant
+ .unwrap()
+ .1
+ {
5 => self.hmac_sha256_compute(&key_bytes, ippt.1),
6 => self.hmac_sha384_compute(&key_bytes, ippt.1),
7 => self.hmac_sha512_compute(&key_bytes, ippt.1),
_ => panic!("Undefined Sha Variant."),
};
-
-
-
-
+
// Integrity Security Context BIB-HMAC-SHA2 has only one result field
- // that means for every target there will be only one vector entry
- // with the result id set to 1 and the result value being the
+ // that means for every target there will be only one vector entry
+ // with the result id set to 1 and the result value being the
// outcome of the security operation (-> the MAC)
- // result_id always 1 https://www.rfc-editor.org/rfc/rfc9173.html#name-results
+ // result_id always 1 https://www.rfc-editor.org/rfc/rfc9173.html#name-results
// +--------------------------+ +---------------------------+
// | Target 1 | | Target N |
// +----------+----+----------+ +---------------------------+
@@ -543,39 +551,32 @@ impl IntegrityBlock {
// +----+-----+ .. +----+-----+ +---+------+ .. +----+------+
// | Id |Value| | Id |Value| | Id |Value| | Id | Value|
// +----+-----+ +----+-----+ +----+-----+ +----+------+
-
+
self.security_results.push(vec![(ippt.0, result_value)]);
} else {
eprint!("Security Target and Ippt mismatch. Make sure there is an ippt for each target.")
}
}
-
-
}
pub fn to_cbor(&self) -> ByteBuffer {
-
let mut cbor_format = Vec::::new();
-
+
cbor_format.append(&mut serde_cbor::to_vec(&self.security_targets).unwrap());
cbor_format.append(&mut serde_cbor::to_vec(&self.security_context_id).unwrap());
cbor_format.append(&mut serde_cbor::to_vec(&self.security_context_flags).unwrap());
cbor_format.append(&mut serde_cbor::to_vec(&self.security_source).unwrap());
cbor_format.append(&mut serde_cbor::to_vec(&self.security_context_parameters).unwrap());
-
// iterate through each target. Create bytes for each signature and onstruct security results format again
let mut res = Vec::new();
- for i in 0..self.security_targets.len(){
-
+ for i in 0..self.security_targets.len() {
let next_result = &self.security_results[i];
let temp_mac = serde_bytes::Bytes::new(&next_result[0].1);
res.push(vec![(&next_result[0].0, temp_mac)]);
-
}
cbor_format.append(&mut serde_cbor::to_vec(&res).unwrap());
cbor_format
-
}
}
@@ -591,7 +592,7 @@ impl Default for IntegrityBlockBuilder {
}
}
-/*
+/*
impl Serialize for IntegrityBlock {
fn serialize(&self, serializer: S) -> Result
where
@@ -636,10 +637,9 @@ impl<'de> Deserialize<'de> for IntegrityBlock {
where
S: SeqAccess<'de>,
{
-
- let security_targets: Vec = seq.next_element()?
- .ok_or_else(|| de::Error::invalid_length(0, &self))?;
-
+ let security_targets: Vec = seq
+ .next_element()?
+ .ok_or_else(|| de::Error::invalid_length(0, &self))?;
let security_context_id = seq.next_element()?.unwrap();
let security_context_flags = seq.next_element()?.unwrap();
@@ -648,17 +648,14 @@ impl<'de> Deserialize<'de> for IntegrityBlock {
let security_context_parameters = seq.next_element()?.unwrap();
// TODO: deal with multiple targets
- let results: Vec>;
- results = seq.next_element()?.unwrap();
+ let results: Vec> = seq.next_element()?.unwrap();
let mut security_results = Vec::new();
- for i in 0..security_targets.len(){
-
- let next_result = &results[i];
- let temp_mac = next_result[0].1.to_vec();
- security_results.push(vec![(next_result[0].0, temp_mac)]);
-
- }
+ (0..security_targets.len()).for_each(|i| {
+ let next_result = &results[i];
+ let temp_mac = next_result[0].1.to_vec();
+ security_results.push(vec![(next_result[0].0, temp_mac)]);
+ });
Ok(IntegrityBlock {
security_targets,
security_context_id,
@@ -674,19 +671,16 @@ impl<'de> Deserialize<'de> for IntegrityBlock {
}
}
-
pub fn new_integrity_block(
- block_number: u64,
- bcf: BlockControlFlags,
- security_block: ByteBuffer
+ block_number: u64,
+ bcf: BlockControlFlags,
+ security_block: ByteBuffer,
) -> CanonicalBlock {
CanonicalBlockBuilder::default()
- .block_type(INTEGRITY_BLOCK)
- .block_number(block_number)
+ .block_type(INTEGRITY_BLOCK)
+ .block_number(block_number)
.block_control_flags(bcf.bits())
- .data(CanonicalData::Unknown(security_block)) // The deserializer doesn't know the integrity block type, with no changes made this also has to be encoded as Unknown
+ .data(CanonicalData::Unknown(security_block)) // The deserializer doesn't know the integrity block type, with no changes made this also has to be encoded as Unknown
.build()
.unwrap()
}
-
-
diff --git a/tests/security_tests.rs b/tests/security_tests.rs
index 96b3afc..d9b4333 100644
--- a/tests/security_tests.rs
+++ b/tests/security_tests.rs
@@ -1,17 +1,14 @@
use bp7::flags::*;
-use helpers::*;
+#[cfg(feature = "bpsec")]
+use bp7::security::*;
use bp7::*;
-use std::convert::TryFrom;
+use helpers::*;
use std::convert::TryInto;
-use bp7::dtntime::DtnTimeHelpers;
use std::time::Duration;
-#[cfg(feature = "bpsec")]
-use hex_literal::hex;
-use bp7::security::*;
//use bp7::security::AES_128_GCM;
-use bp7::bundle::Block;
#[test]
+#[cfg(feature = "bpsec")]
fn security_data_tests() {
let data = CanonicalData::Data(b"bla".to_vec());
let encoded_data = serde_cbor::to_vec(&data).expect("encoding error");
@@ -33,12 +30,15 @@ fn encode_decode_test_canonical(data: CanonicalBlock) {
}
#[test]
+#[cfg(feature = "bpsec")]
fn canonical_block_tests() {
- let data = bp7::security::new_integrity_block(1, BlockControlFlags::empty(), b"ABCDEFG".to_vec());
+ let data =
+ bp7::security::new_integrity_block(1, BlockControlFlags::empty(), b"ABCDEFG".to_vec());
encode_decode_test_canonical(data);
}
#[test]
+#[cfg(feature = "bpsec")]
fn rfc_example_tests() {
simple_integrity_test();
@@ -46,9 +46,6 @@ fn rfc_example_tests() {
//multiple_sources_test();
-
-
-
// Example 4 - Security Blocks with Full Scope
// https://www.rfc-editor.org/rfc/rfc9173.html#name-example-4-security-blocks-w
//println!("Security Blocks with Full Scope");
@@ -56,8 +53,10 @@ fn rfc_example_tests() {
//full_scope_test();
}
+#[test]
+#[cfg(feature = "bpsec")]
/// # Example 1 - Simple Integrity
-///
+///
/// ## Original Bundle
///
/// ```
@@ -85,17 +84,14 @@ fn rfc_example_tests() {
///
/// see rfc for more details:
/// https://www.rfc-editor.org/rfc/rfc9173.html#name-example-1-simple-integrity
-fn simple_integrity_test(){
-
+fn simple_integrity_test() {
println!("Simple Integrity Test");
-
-
// Create Original bundle
- let dst = eid::EndpointID::with_ipn(1,2).unwrap();
- let src = eid::EndpointID::with_ipn(2,1).unwrap();
+ let dst = eid::EndpointID::with_ipn(1, 2).unwrap();
+ let src = eid::EndpointID::with_ipn(2, 1).unwrap();
let now = dtntime::CreationTimestamp::with_time_and_seq(0, 40);
-
+
let primary_block = primary::PrimaryBlockBuilder::default()
.destination(dst)
.source(src.clone())
@@ -110,27 +106,33 @@ fn simple_integrity_test(){
assert_eq!(cbor_primary, example_cbor_primary);
let payload_block = bp7::new_payload_block(
- BlockControlFlags::empty(),
- b"Ready to generate a 32-byte payload".to_vec());
+ BlockControlFlags::empty(),
+ b"Ready to generate a 32-byte payload".to_vec(),
+ );
let cbor_payload = serde_cbor::to_vec(&payload_block).unwrap();
let cbor_payload = hexify(&cbor_payload);
- let example_cbor_payload = "85010100005823526561647920746f2067656e657261746520612033322d62797465207061796c6f6164";
+ let example_cbor_payload =
+ "85010100005823526561647920746f2067656e657261746520612033322d62797465207061796c6f6164";
assert_eq!(cbor_payload, example_cbor_payload);
// Create Block Integrity Block
// Two Parts: First create IPPT then ASB
-
+
// First Create Integrity-Protected Plaintext
- let sec_block_header: (CanonicalBlockType, u64, bp7::flags::BlockControlFlagsType) = (bp7::security::INTEGRITY_BLOCK, 2, BlockControlFlags::empty().bits());
-
- let sec_ctx_para = BibSecurityContextParameter {
- sha_variant: Some((1, HMAC_SHA_512)),
+ let sec_block_header: (CanonicalBlockType, u64, bp7::flags::BlockControlFlagsType) = (
+ bp7::security::INTEGRITY_BLOCK,
+ 2,
+ BlockControlFlags::empty().bits(),
+ );
+
+ let _sec_ctx_para = BibSecurityContextParameter {
+ sha_variant: Some((1, HMAC_SHA_512)),
wrapped_key: None,
integrity_scope_flags: Some((3, 0x0000)),
};
let mut ippt = bp7::security::IpptBuilder::default()
- .primary_block(primary_block.clone())
+ .primary_block(primary_block.clone())
.security_header(sec_block_header)
.scope_flags(0x0000)
.build();
@@ -138,23 +140,25 @@ fn simple_integrity_test(){
let ippt_list = vec![(payload_block.block_number, &ippt_complete)];
let cbor_ippt_complete = hexify(&ippt_complete);
- let example_ippt_complete = "005823526561647920746f2067656e657261746520612033322d62797465207061796c6f6164";
+ let example_ippt_complete =
+ "005823526561647920746f2067656e657261746520612033322d62797465207061796c6f6164";
//println!("{:?}", cbor_ippt_complete);
-
- assert_eq!(cbor_ippt_complete, example_ippt_complete);
+ assert_eq!(cbor_ippt_complete, example_ippt_complete);
// Second Create Abstract Security Block
- let sec_ctx_para = bp7::security::BibSecurityContextParameter::new(Some((1,7)),None,Some((3,0x0000)));
+ let sec_ctx_para =
+ bp7::security::BibSecurityContextParameter::new(Some((1, 7)), None, Some((3, 0x0000)));
let mut sec_block_payload = bp7::security::IntegrityBlockBuilder::default()
- .security_targets(vec![1]) // Payload block
- .security_context_flags(1) // Parameters Present
- .security_source(EndpointID::with_ipn(2,1).unwrap()) // ipn:2.1
+ .security_targets(vec![1]) // Payload block
+ .security_context_flags(1) // Parameters Present
+ .security_source(EndpointID::with_ipn(2, 1).unwrap()) // ipn:2.1
.security_context_parameters(sec_ctx_para) // 2 Parameters: HMAC 512/512 and No Additional Scope
.build()
.unwrap();
- let key = hex!("1a2b1a2b1a2b1a2b1a2b1a2b1a2b1a2b");
- sec_block_payload.compute_hmac(key, ippt_list);
+ let key = unhexify("1a2b1a2b1a2b1a2b1a2b1a2b1a2b1a2b").unwrap();
+ let key_array: [u8; 16] = key.try_into().expect("slice with incorrect length");
+ sec_block_payload.compute_hmac(key_array, ippt_list);
// TODO: key mgmt
// used key: 1a2b1a2b1a2b1a2b1a2b1a2b1a2b1a2b
@@ -164,22 +168,20 @@ fn simple_integrity_test(){
assert_eq!(signature, example_signature);
//println!("{:?}", hexify(&sec_block_payload.security_results[0][0].1));
-
// The CBOR encoding of the BIB block-type-specific data field (the abstract security block):
let canonical_payload = sec_block_payload.to_cbor();
let cbor_canonical_payload = hexify(&canonical_payload);
let example_canonical_payload = "810101018202820201828201078203008181820158403bdc69b3a34a2b5d3a8554368bd1e808f606219d2a10a846eae3886ae4ecc83c4ee550fdfb1cc636b904e2f1a73e303dcd4b6ccece003e95e8164dcc89a156e1";
assert_eq!(cbor_canonical_payload, example_canonical_payload);
-
-
+
// The BIB
- let block_integrity_block = bp7::security::new_integrity_block(2, BlockControlFlags::empty(), canonical_payload);
+ let block_integrity_block =
+ bp7::security::new_integrity_block(2, BlockControlFlags::empty(), canonical_payload);
let cbor_bib = serde_cbor::to_vec(&block_integrity_block).unwrap();
let cbor_bib = hexify(&cbor_bib);
let example_bib = "850b0200005856810101018202820201828201078203008181820158403bdc69b3a34a2b5d3a8554368bd1e808f606219d2a10a846eae3886ae4ecc83c4ee550fdfb1cc636b904e2f1a73e303dcd4b6ccece003e95e8164dcc89a156e1";
assert_eq!(cbor_bib, example_bib);
-
// The CBOR encoding of the full output bundle, with the BIB:
let mut b = bundle::BundleBuilder::default()
.primary(primary_block)