Optional feature to capture stacktrace on error
This commit is contained in:
parent
3dccc0d710
commit
974ac4d1d8
58 changed files with 531 additions and 384 deletions
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use matter::data_model::sdm::dev_att::{DataType, DevAttDataFetcher};
|
use matter::data_model::sdm::dev_att::{DataType, DevAttDataFetcher};
|
||||||
use matter::error::Error;
|
use matter::error::{Error, ErrorCode};
|
||||||
|
|
||||||
pub struct HardCodedDevAtt {}
|
pub struct HardCodedDevAtt {}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ impl DevAttDataFetcher for HardCodedDevAtt {
|
||||||
data.copy_from_slice(src);
|
data.copy_from_slice(src);
|
||||||
Ok(src.len())
|
Ok(src.len())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
use log::info;
|
||||||
use matter::core::{CommissioningData, Matter};
|
use matter::core::{CommissioningData, Matter};
|
||||||
use matter::data_model::cluster_basic_information::BasicInfoConfig;
|
use matter::data_model::cluster_basic_information::BasicInfoConfig;
|
||||||
use matter::data_model::cluster_on_off;
|
use matter::data_model::cluster_on_off;
|
||||||
|
@ -36,8 +38,10 @@ use matter::transport::{
|
||||||
|
|
||||||
mod dev_att;
|
mod dev_att;
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<(), impl Error> {
|
||||||
env_logger::init();
|
env_logger::init_from_env(
|
||||||
|
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"),
|
||||||
|
);
|
||||||
|
|
||||||
// vid/pid should match those in the DAC
|
// vid/pid should match those in the DAC
|
||||||
let dev_info = BasicInfoConfig {
|
let dev_info = BasicInfoConfig {
|
||||||
|
@ -50,35 +54,37 @@ fn main() {
|
||||||
device_name: "OnOff Light",
|
device_name: "OnOff Light",
|
||||||
};
|
};
|
||||||
|
|
||||||
//let mut mdns = matter::mdns::astro::AstroMdns::new().unwrap();
|
let mut mdns = matter::mdns::astro::AstroMdns::new()?;
|
||||||
let mut mdns = matter::mdns::libmdns::LibMdns::new().unwrap();
|
//let mut mdns = matter::mdns::libmdns::LibMdns::new()?;
|
||||||
|
//let mut mdns = matter::mdns::DummyMdns {};
|
||||||
|
|
||||||
let matter = Matter::new_default(&dev_info, &mut mdns, matter::transport::udp::MATTER_PORT);
|
let matter = Matter::new_default(&dev_info, &mut mdns, matter::transport::udp::MATTER_PORT);
|
||||||
|
|
||||||
let dev_att = dev_att::HardCodedDevAtt::new();
|
let dev_att = dev_att::HardCodedDevAtt::new();
|
||||||
|
|
||||||
let psm = persist::FilePsm::new(std::env::temp_dir().join("matter-iot")).unwrap();
|
let psm_path = std::env::temp_dir().join("matter-iot");
|
||||||
|
info!("Persisting from/to {}", psm_path.display());
|
||||||
|
|
||||||
|
let psm = persist::FilePsm::new(psm_path)?;
|
||||||
|
|
||||||
let mut buf = [0; 4096];
|
let mut buf = [0; 4096];
|
||||||
|
|
||||||
if let Some(data) = psm.load("fabrics", &mut buf).unwrap() {
|
if let Some(data) = psm.load("acls", &mut buf)? {
|
||||||
matter.load_fabrics(data).unwrap();
|
matter.load_acls(data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(data) = psm.load("acls", &mut buf).unwrap() {
|
if let Some(data) = psm.load("fabrics", &mut buf)? {
|
||||||
matter.load_acls(data).unwrap();
|
matter.load_fabrics(data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
matter
|
matter.start::<4096>(
|
||||||
.start::<4096>(
|
CommissioningData {
|
||||||
CommissioningData {
|
// TODO: Hard-coded for now
|
||||||
// TODO: Hard-coded for now
|
verifier: VerifierData::new_with_pw(123456, *matter.borrow()),
|
||||||
verifier: VerifierData::new_with_pw(123456, *matter.borrow()),
|
discriminator: 250,
|
||||||
discriminator: 250,
|
},
|
||||||
},
|
&mut buf,
|
||||||
&mut buf,
|
)?;
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let matter = &matter;
|
let matter = &matter;
|
||||||
let dev_att = &dev_att;
|
let dev_att = &dev_att;
|
||||||
|
@ -86,20 +92,20 @@ fn main() {
|
||||||
let mut transport = TransportMgr::new(matter);
|
let mut transport = TransportMgr::new(matter);
|
||||||
|
|
||||||
smol::block_on(async move {
|
smol::block_on(async move {
|
||||||
let udp = UdpListener::new().await.unwrap();
|
let udp = UdpListener::new().await?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut rx_buf = [0; MAX_RX_BUF_SIZE];
|
let mut rx_buf = [0; MAX_RX_BUF_SIZE];
|
||||||
let mut tx_buf = [0; MAX_TX_BUF_SIZE];
|
let mut tx_buf = [0; MAX_TX_BUF_SIZE];
|
||||||
|
|
||||||
let (len, addr) = udp.recv(&mut rx_buf).await.unwrap();
|
let (len, addr) = udp.recv(&mut rx_buf).await?;
|
||||||
|
|
||||||
let mut completion = transport.recv(addr, &mut rx_buf[..len], &mut tx_buf);
|
let mut completion = transport.recv(addr, &mut rx_buf[..len], &mut tx_buf);
|
||||||
|
|
||||||
while let Some(action) = completion.next_action().unwrap() {
|
while let Some(action) = completion.next_action()? {
|
||||||
match action {
|
match action {
|
||||||
RecvAction::Send(addr, buf) => {
|
RecvAction::Send(addr, buf) => {
|
||||||
udp.send(addr, buf).await.unwrap();
|
udp.send(addr, buf).await?;
|
||||||
}
|
}
|
||||||
RecvAction::Interact(mut ctx) => {
|
RecvAction::Interact(mut ctx) => {
|
||||||
let node = Node {
|
let node = Node {
|
||||||
|
@ -119,24 +125,29 @@ fn main() {
|
||||||
let mut im =
|
let mut im =
|
||||||
InteractionModel(DataModel::new(matter.borrow(), &node, &mut handler));
|
InteractionModel(DataModel::new(matter.borrow(), &node, &mut handler));
|
||||||
|
|
||||||
if im.handle(&mut ctx).unwrap() {
|
if im.handle(&mut ctx)? {
|
||||||
if ctx.send().unwrap() {
|
if ctx.send()? {
|
||||||
udp.send(ctx.tx.peer, ctx.tx.as_slice()).await.unwrap();
|
udp.send(ctx.tx.peer, ctx.tx.as_slice()).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(data) = matter.store_fabrics(&mut buf).unwrap() {
|
if let Some(data) = matter.store_fabrics(&mut buf)? {
|
||||||
psm.store("fabrics", data).unwrap();
|
psm.store("fabrics", data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(data) = matter.store_acls(&mut buf).unwrap() {
|
if let Some(data) = matter.store_acls(&mut buf)? {
|
||||||
psm.store("acls", data).unwrap();
|
psm.store("acls", data)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
#[allow(unreachable_code)]
|
||||||
|
Ok::<_, matter::error::Error>(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok::<_, matter::error::Error>(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handler<'a>(matter: &'a Matter<'a>, dev_att: &'a dyn DevAttDataFetcher) -> impl Handler + 'a {
|
fn handler<'a>(matter: &'a Matter<'a>, dev_att: &'a dyn DevAttDataFetcher) -> impl Handler + 'a {
|
||||||
|
|
|
@ -159,7 +159,7 @@ impl DevAttDataFetcher for HardCodedDevAtt {
|
||||||
data.copy_from_slice(src);
|
data.copy_from_slice(src);
|
||||||
Ok(src.len())
|
Ok(src.len())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,9 @@ name = "matter"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "crypto_mbedtls"]
|
default = ["std", "crypto_mbedtls", "backtrace"]
|
||||||
std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "smol"]
|
std = ["alloc", "env_logger", "chrono", "rand", "qrcode", "libmdns", "simple-mdns", "simple-dns", "smol"]
|
||||||
|
backtrace = []
|
||||||
alloc = []
|
alloc = []
|
||||||
nightly = []
|
nightly = []
|
||||||
crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"]
|
crypto_openssl = ["openssl", "foreign-types", "hmac", "sha2"]
|
||||||
|
@ -32,7 +33,7 @@ heapless = "0.7.16"
|
||||||
num = "0.4"
|
num = "0.4"
|
||||||
num-derive = "0.3.3"
|
num-derive = "0.3.3"
|
||||||
num-traits = "0.2.15"
|
num-traits = "0.2.15"
|
||||||
strum = { version = "0.24", features = ["derive"], default-features = false, no-default-feature = true }
|
strum = { version = "0.24", features = ["derive"], default-features = false }
|
||||||
log = { version = "0.4.17", features = ["max_level_debug", "release_max_level_debug"] }
|
log = { version = "0.4.17", features = ["max_level_debug", "release_max_level_debug"] }
|
||||||
no-std-net = "0.6"
|
no-std-net = "0.6"
|
||||||
subtle = "2.4.1"
|
subtle = "2.4.1"
|
||||||
|
|
|
@ -19,7 +19,7 @@ use core::{cell::RefCell, fmt::Display};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data_model::objects::{Access, ClusterId, EndptId, Privilege},
|
data_model::objects::{Access, ClusterId, EndptId, Privilege},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
fabric,
|
fabric,
|
||||||
interaction_model::messages::GenericPath,
|
interaction_model::messages::GenericPath,
|
||||||
tlv::{FromTLV, TLVElement, TLVList, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, TLVElement, TLVList, TLVWriter, TagType, ToTLV},
|
||||||
|
@ -50,7 +50,7 @@ impl FromTLV<'_> for AuthMode {
|
||||||
{
|
{
|
||||||
num::FromPrimitive::from_u32(t.u32()?)
|
num::FromPrimitive::from_u32(t.u32()?)
|
||||||
.filter(|a| *a != AuthMode::Invalid)
|
.filter(|a| *a != AuthMode::Invalid)
|
||||||
.ok_or(Error::Invalid)
|
.ok_or_else(|| ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ impl AccessorSubjects {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Match the match_subject with any of the current subjects
|
/// Match the match_subject with any of the current subjects
|
||||||
|
@ -314,7 +314,7 @@ impl AclEntry {
|
||||||
.subjects
|
.subjects
|
||||||
.iter()
|
.iter()
|
||||||
.position(|s| s.is_none())
|
.position(|s| s.is_none())
|
||||||
.ok_or(Error::NoSpace)?;
|
.ok_or(ErrorCode::NoSpace)?;
|
||||||
self.subjects[index] = Some(subject);
|
self.subjects[index] = Some(subject);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -328,7 +328,7 @@ impl AclEntry {
|
||||||
.targets
|
.targets
|
||||||
.iter()
|
.iter()
|
||||||
.position(|s| s.is_none())
|
.position(|s| s.is_none())
|
||||||
.ok_or(Error::NoSpace)?;
|
.ok_or(ErrorCode::NoSpace)?;
|
||||||
self.targets[index] = Some(target);
|
self.targets[index] = Some(target);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -425,13 +425,13 @@ impl AclMgr {
|
||||||
.filter(|a| a.fab_idx == entry.fab_idx)
|
.filter(|a| a.fab_idx == entry.fab_idx)
|
||||||
.count();
|
.count();
|
||||||
if cnt >= ENTRIES_PER_FABRIC {
|
if cnt >= ENTRIES_PER_FABRIC {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
let index = self
|
let index = self
|
||||||
.entries
|
.entries
|
||||||
.iter()
|
.iter()
|
||||||
.position(|a| a.is_none())
|
.position(|a| a.is_none())
|
||||||
.ok_or(Error::NoSpace)?;
|
.ok_or(ErrorCode::NoSpace)?;
|
||||||
self.entries[index] = Some(entry);
|
self.entries[index] = Some(entry);
|
||||||
|
|
||||||
self.changed = true;
|
self.changed = true;
|
||||||
|
@ -503,7 +503,7 @@ impl AclMgr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(&mut self, data: &[u8]) -> Result<(), Error> {
|
pub fn load(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
let root = TLVList::new(data).iter().next().ok_or(Error::Invalid)?;
|
let root = TLVList::new(data).iter().next().ok_or(ErrorCode::Invalid)?;
|
||||||
|
|
||||||
self.entries = AclEntries::from_tlv(&root)?;
|
self.entries = AclEntries::from_tlv(&root)?;
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
|
@ -547,7 +547,7 @@ impl AclMgr {
|
||||||
return Ok(entry);
|
return Ok(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Error::NotFound)
|
Err(ErrorCode::NotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
use super::{CertConsumer, MAX_DEPTH};
|
use super::{CertConsumer, MAX_DEPTH};
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
utils::epoch::{UtcCalendar, MATTER_EPOCH_SECS},
|
utils::epoch::{UtcCalendar, MATTER_EPOCH_SECS},
|
||||||
};
|
};
|
||||||
use core::{fmt::Write, time::Duration};
|
use core::{fmt::Write, time::Duration};
|
||||||
|
@ -54,7 +54,7 @@ impl<'a> ASN1Writer<'a> {
|
||||||
self.offset += size;
|
self.offset += size;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append_tlv<F>(&mut self, tag: u8, len: usize, f: F) -> Result<(), Error>
|
pub fn append_tlv<F>(&mut self, tag: u8, len: usize, f: F) -> Result<(), Error>
|
||||||
|
@ -70,7 +70,7 @@ impl<'a> ASN1Writer<'a> {
|
||||||
self.offset += len;
|
self.offset += len;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_compound(&mut self, val: u8) -> Result<(), Error> {
|
fn add_compound(&mut self, val: u8) -> Result<(), Error> {
|
||||||
|
@ -80,7 +80,7 @@ impl<'a> ASN1Writer<'a> {
|
||||||
self.depth[self.current_depth] = self.offset;
|
self.depth[self.current_depth] = self.offset;
|
||||||
self.current_depth += 1;
|
self.current_depth += 1;
|
||||||
if self.current_depth >= MAX_DEPTH {
|
if self.current_depth >= MAX_DEPTH {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ impl<'a> ASN1Writer<'a> {
|
||||||
|
|
||||||
fn end_compound(&mut self) -> Result<(), Error> {
|
fn end_compound(&mut self) -> Result<(), Error> {
|
||||||
if self.current_depth == 0 {
|
if self.current_depth == 0 {
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
let seq_len = self.get_compound_len();
|
let seq_len = self.get_compound_len();
|
||||||
let write_offset = self.get_length_encoding_offset();
|
let write_offset = self.get_length_encoding_offset();
|
||||||
|
@ -148,7 +148,7 @@ impl<'a> ASN1Writer<'a> {
|
||||||
// This is done with an 0xA2 followed by 2 bytes of actual len
|
// This is done with an 0xA2 followed by 2 bytes of actual len
|
||||||
3
|
3
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?
|
||||||
};
|
};
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ use core::fmt::{self, Write};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
crypto::KeyPair,
|
crypto::KeyPair,
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
tlv::{self, FromTLV, OctetStr, TLVArray, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{self, FromTLV, OctetStr, TLVArray, TLVElement, TLVWriter, TagType, ToTLV},
|
||||||
utils::{epoch::UtcCalendar, writebuf::WriteBuf},
|
utils::{epoch::UtcCalendar, writebuf::WriteBuf},
|
||||||
};
|
};
|
||||||
|
@ -349,22 +349,22 @@ impl<'a> FromTLV<'a> for DistNames<'a> {
|
||||||
let mut d = Self {
|
let mut d = Self {
|
||||||
dn: heapless::Vec::new(),
|
dn: heapless::Vec::new(),
|
||||||
};
|
};
|
||||||
let iter = t.confirm_list()?.enter().ok_or(Error::Invalid)?;
|
let iter = t.confirm_list()?.enter().ok_or(ErrorCode::Invalid)?;
|
||||||
for t in iter {
|
for t in iter {
|
||||||
if let TagType::Context(tag) = t.get_tag() {
|
if let TagType::Context(tag) = t.get_tag() {
|
||||||
if let Ok(value) = t.u64() {
|
if let Ok(value) = t.u64() {
|
||||||
d.dn.push((tag, DistNameValue::Uint(value)))
|
d.dn.push((tag, DistNameValue::Uint(value)))
|
||||||
.map_err(|_| Error::BufferTooSmall)?;
|
.map_err(|_| ErrorCode::BufferTooSmall)?;
|
||||||
} else if let Ok(value) = t.slice() {
|
} else if let Ok(value) = t.slice() {
|
||||||
if tag > PRINTABLE_STR_THRESHOLD {
|
if tag > PRINTABLE_STR_THRESHOLD {
|
||||||
d.dn.push((
|
d.dn.push((
|
||||||
tag - PRINTABLE_STR_THRESHOLD,
|
tag - PRINTABLE_STR_THRESHOLD,
|
||||||
DistNameValue::PrintableStr(value),
|
DistNameValue::PrintableStr(value),
|
||||||
))
|
))
|
||||||
.map_err(|_| Error::BufferTooSmall)?;
|
.map_err(|_| ErrorCode::BufferTooSmall)?;
|
||||||
} else {
|
} else {
|
||||||
d.dn.push((tag, DistNameValue::Utf8Str(value)))
|
d.dn.push((tag, DistNameValue::Utf8Str(value)))
|
||||||
.map_err(|_| Error::BufferTooSmall)?;
|
.map_err(|_| ErrorCode::BufferTooSmall)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,7 +531,7 @@ fn encode_dn_value(
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Invalid encoding");
|
error!("Invalid encoding");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
DistNameValue::Utf8Str(v) => {
|
DistNameValue::Utf8Str(v) => {
|
||||||
|
@ -570,7 +570,9 @@ impl<'a> Cert<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_node_id(&self) -> Result<u64, Error> {
|
pub fn get_node_id(&self) -> Result<u64, Error> {
|
||||||
self.subject.u64(DnTags::NodeId).ok_or(Error::NoNodeId)
|
self.subject
|
||||||
|
.u64(DnTags::NodeId)
|
||||||
|
.ok_or_else(|| Error::from(ErrorCode::NoNodeId))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cat_ids(&self, output: &mut [u32]) {
|
pub fn get_cat_ids(&self, output: &mut [u32]) {
|
||||||
|
@ -578,7 +580,9 @@ impl<'a> Cert<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fabric_id(&self) -> Result<u64, Error> {
|
pub fn get_fabric_id(&self) -> Result<u64, Error> {
|
||||||
self.subject.u64(DnTags::FabricId).ok_or(Error::NoFabricId)
|
self.subject
|
||||||
|
.u64(DnTags::FabricId)
|
||||||
|
.ok_or_else(|| Error::from(ErrorCode::NoFabricId))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pubkey(&self) -> &[u8] {
|
pub fn get_pubkey(&self) -> &[u8] {
|
||||||
|
@ -589,7 +593,7 @@ impl<'a> Cert<'a> {
|
||||||
if let Some(id) = self.extensions.subj_key_id.as_ref() {
|
if let Some(id) = self.extensions.subj_key_id.as_ref() {
|
||||||
Ok(id.0)
|
Ok(id.0)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +645,7 @@ impl<'a> Cert<'a> {
|
||||||
w.integer("Serial Num:", self.serial_no.0)?;
|
w.integer("Serial Num:", self.serial_no.0)?;
|
||||||
|
|
||||||
w.start_seq("Signature Algorithm:")?;
|
w.start_seq("Signature Algorithm:")?;
|
||||||
let (str, oid) = match get_sign_algo(self.sign_algo).ok_or(Error::Invalid)? {
|
let (str, oid) = match get_sign_algo(self.sign_algo).ok_or(ErrorCode::Invalid)? {
|
||||||
SignAlgoValue::ECDSAWithSHA256 => ("ECDSA with SHA256", OID_ECDSA_WITH_SHA256),
|
SignAlgoValue::ECDSAWithSHA256 => ("ECDSA with SHA256", OID_ECDSA_WITH_SHA256),
|
||||||
};
|
};
|
||||||
w.oid(str, &oid)?;
|
w.oid(str, &oid)?;
|
||||||
|
@ -660,11 +664,11 @@ impl<'a> Cert<'a> {
|
||||||
|
|
||||||
w.start_seq("")?;
|
w.start_seq("")?;
|
||||||
w.start_seq("Public Key Algorithm")?;
|
w.start_seq("Public Key Algorithm")?;
|
||||||
let (str, pub_key) = match get_pubkey_algo(self.pubkey_algo).ok_or(Error::Invalid)? {
|
let (str, pub_key) = match get_pubkey_algo(self.pubkey_algo).ok_or(ErrorCode::Invalid)? {
|
||||||
PubKeyAlgoValue::EcPubKey => ("ECPubKey", OID_PUB_KEY_ECPUBKEY),
|
PubKeyAlgoValue::EcPubKey => ("ECPubKey", OID_PUB_KEY_ECPUBKEY),
|
||||||
};
|
};
|
||||||
w.oid(str, &pub_key)?;
|
w.oid(str, &pub_key)?;
|
||||||
let (str, curve_id) = match get_ec_curve_id(self.ec_curve_id).ok_or(Error::Invalid)? {
|
let (str, curve_id) = match get_ec_curve_id(self.ec_curve_id).ok_or(ErrorCode::Invalid)? {
|
||||||
EcCurveIdValue::Prime256V1 => ("Prime256v1", OID_EC_TYPE_PRIME256V1),
|
EcCurveIdValue::Prime256V1 => ("Prime256v1", OID_EC_TYPE_PRIME256V1),
|
||||||
};
|
};
|
||||||
w.oid(str, &curve_id)?;
|
w.oid(str, &curve_id)?;
|
||||||
|
@ -704,7 +708,7 @@ impl<'a> CertVerifier<'a> {
|
||||||
|
|
||||||
pub fn add_cert(self, parent: &'a Cert) -> Result<CertVerifier<'a>, Error> {
|
pub fn add_cert(self, parent: &'a Cert) -> Result<CertVerifier<'a>, Error> {
|
||||||
if !self.cert.is_authority(parent)? {
|
if !self.cert.is_authority(parent)? {
|
||||||
return Err(Error::InvalidAuthKey);
|
Err(ErrorCode::InvalidAuthKey)?;
|
||||||
}
|
}
|
||||||
let mut asn1 = [0u8; MAX_ASN1_CERT_SIZE];
|
let mut asn1 = [0u8; MAX_ASN1_CERT_SIZE];
|
||||||
let len = self.cert.as_asn1(&mut asn1, self.utc_calendar)?;
|
let len = self.cert.as_asn1(&mut asn1, self.utc_calendar)?;
|
||||||
|
@ -761,7 +765,6 @@ mod tests {
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::cert::Cert;
|
use crate::cert::Cert;
|
||||||
use crate::error::Error;
|
|
||||||
use crate::tlv::{self, FromTLV, TLVWriter, TagType, ToTLV};
|
use crate::tlv::{self, FromTLV, TLVWriter, TagType, ToTLV};
|
||||||
use crate::utils::writebuf::WriteBuf;
|
use crate::utils::writebuf::WriteBuf;
|
||||||
|
|
||||||
|
@ -815,31 +818,43 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_verify_chain_incomplete() {
|
fn test_verify_chain_incomplete() {
|
||||||
// The chain doesn't lead up to a self-signed certificate
|
// The chain doesn't lead up to a self-signed certificate
|
||||||
|
|
||||||
|
use crate::error::ErrorCode;
|
||||||
let noc = Cert::new(&test_vectors::NOC1_SUCCESS).unwrap();
|
let noc = Cert::new(&test_vectors::NOC1_SUCCESS).unwrap();
|
||||||
let icac = Cert::new(&test_vectors::ICAC1_SUCCESS).unwrap();
|
let icac = Cert::new(&test_vectors::ICAC1_SUCCESS).unwrap();
|
||||||
let a = noc.verify_chain_start(crate::utils::epoch::sys_utc_calendar);
|
let a = noc.verify_chain_start(crate::utils::epoch::sys_utc_calendar);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Err(Error::InvalidAuthKey),
|
Err(ErrorCode::InvalidAuthKey),
|
||||||
a.add_cert(&icac).unwrap().finalise()
|
a.add_cert(&icac).unwrap().finalise().map_err(|e| e.code())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_auth_key_chain_incorrect() {
|
fn test_auth_key_chain_incorrect() {
|
||||||
|
use crate::error::ErrorCode;
|
||||||
|
|
||||||
let noc = Cert::new(&test_vectors::NOC1_AUTH_KEY_FAIL).unwrap();
|
let noc = Cert::new(&test_vectors::NOC1_AUTH_KEY_FAIL).unwrap();
|
||||||
let icac = Cert::new(&test_vectors::ICAC1_SUCCESS).unwrap();
|
let icac = Cert::new(&test_vectors::ICAC1_SUCCESS).unwrap();
|
||||||
let a = noc.verify_chain_start(crate::utils::epoch::sys_utc_calendar);
|
let a = noc.verify_chain_start(crate::utils::epoch::sys_utc_calendar);
|
||||||
assert_eq!(Err(Error::InvalidAuthKey), a.add_cert(&icac).map(|_| ()));
|
assert_eq!(
|
||||||
|
Err(ErrorCode::InvalidAuthKey),
|
||||||
|
a.add_cert(&icac).map(|_| ()).map_err(|e| e.code())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cert_corrupted() {
|
fn test_cert_corrupted() {
|
||||||
|
use crate::error::ErrorCode;
|
||||||
|
|
||||||
let noc = Cert::new(&test_vectors::NOC1_CORRUPT_CERT).unwrap();
|
let noc = Cert::new(&test_vectors::NOC1_CORRUPT_CERT).unwrap();
|
||||||
let icac = Cert::new(&test_vectors::ICAC1_SUCCESS).unwrap();
|
let icac = Cert::new(&test_vectors::ICAC1_SUCCESS).unwrap();
|
||||||
let a = noc.verify_chain_start(crate::utils::epoch::sys_utc_calendar);
|
let a = noc.verify_chain_start(crate::utils::epoch::sys_utc_calendar);
|
||||||
assert_eq!(Err(Error::InvalidSignature), a.add_cert(&icac).map(|_| ()));
|
assert_eq!(
|
||||||
|
Err(ErrorCode::InvalidSignature),
|
||||||
|
a.add_cert(&icac).map(|_| ()).map_err(|e| e.code())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
//! Base38 encoding and decoding functions.
|
//! Base38 encoding and decoding functions.
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
const BASE38_CHARS: [char; 38] = [
|
const BASE38_CHARS: [char; 38] = [
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
|
||||||
|
@ -86,7 +86,7 @@ const RADIX: u32 = BASE38_CHARS.len() as u32;
|
||||||
pub fn encode_string<const N: usize>(bytes: &[u8]) -> Result<heapless::String<N>, Error> {
|
pub fn encode_string<const N: usize>(bytes: &[u8]) -> Result<heapless::String<N>, Error> {
|
||||||
let mut string = heapless::String::new();
|
let mut string = heapless::String::new();
|
||||||
for c in encode(bytes) {
|
for c in encode(bytes) {
|
||||||
string.push(c).map_err(|_| Error::NoSpace)?;
|
string.push(c).map_err(|_| ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(string)
|
Ok(string)
|
||||||
|
@ -135,7 +135,7 @@ pub fn decode_vec<const N: usize>(base38_str: &str) -> Result<heapless::Vec<u8,
|
||||||
let mut vec = heapless::Vec::new();
|
let mut vec = heapless::Vec::new();
|
||||||
|
|
||||||
for byte in decode(base38_str) {
|
for byte in decode(base38_str) {
|
||||||
vec.push(byte?).map_err(|_| Error::NoSpace)?;
|
vec.push(byte?).map_err(|_| ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(vec)
|
Ok(vec)
|
||||||
|
@ -179,19 +179,19 @@ fn decode_base38(chars: &[u8]) -> impl Iterator<Item = Result<u8, Error>> {
|
||||||
match decode_char(*c) {
|
match decode_char(*c) {
|
||||||
Ok(v) => value = value * RADIX + v as u32,
|
Ok(v) => value = value * RADIX + v as u32,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
cerr = Some(err);
|
cerr = Some(err.code());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cerr = Some(Error::InvalidData)
|
cerr = Some(ErrorCode::InvalidData)
|
||||||
}
|
}
|
||||||
|
|
||||||
(0..repeat)
|
(0..repeat)
|
||||||
.map(move |_| {
|
.map(move |_| {
|
||||||
if let Some(err) = cerr {
|
if let Some(err) = cerr {
|
||||||
Err(err)
|
Err(err.into())
|
||||||
} else {
|
} else {
|
||||||
let byte = (value & 0xff) as u8;
|
let byte = (value & 0xff) as u8;
|
||||||
|
|
||||||
|
@ -205,12 +205,12 @@ fn decode_base38(chars: &[u8]) -> impl Iterator<Item = Result<u8, Error>> {
|
||||||
|
|
||||||
fn decode_char(c: u8) -> Result<u8, Error> {
|
fn decode_char(c: u8) -> Result<u8, Error> {
|
||||||
if !(45..=90).contains(&c) {
|
if !(45..=90).contains(&c) {
|
||||||
return Err(Error::InvalidData);
|
Err(ErrorCode::InvalidData)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let c = DECODE_BASE38[c as usize - 45];
|
let c = DECODE_BASE38[c as usize - 45];
|
||||||
if c == UNUSED {
|
if c == UNUSED {
|
||||||
return Err(Error::InvalidData);
|
Err(ErrorCode::InvalidData)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(c)
|
Ok(c)
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
pub fn hkdf_sha256(_salt: &[u8], _ikm: &[u8], _info: &[u8], _key: &mut [u8]) -> Result<(), Error> {
|
pub fn hkdf_sha256(_salt: &[u8], _ikm: &[u8], _info: &[u8], _key: &mut [u8]) -> Result<(), Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
|
@ -79,7 +79,7 @@ impl KeyPair {
|
||||||
|
|
||||||
pub fn get_csr<'a>(&self, _out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> {
|
pub fn get_csr<'a>(&self, _out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_public_key(&self, _pub_key: &mut [u8]) -> Result<usize, Error> {
|
pub fn get_public_key(&self, _pub_key: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
@ -92,17 +92,17 @@ impl KeyPair {
|
||||||
|
|
||||||
pub fn derive_secret(self, _peer_pub_key: &[u8], _secret: &mut [u8]) -> Result<usize, Error> {
|
pub fn derive_secret(self, _peer_pub_key: &[u8], _secret: &mut [u8]) -> Result<usize, Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sign_msg(&self, _msg: &[u8], _signature: &mut [u8]) -> Result<usize, Error> {
|
pub fn sign_msg(&self, _msg: &[u8], _signature: &mut [u8]) -> Result<usize, Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_msg(&self, _msg: &[u8], _signature: &[u8]) -> Result<(), Error> {
|
pub fn verify_msg(&self, _msg: &[u8], _signature: &[u8]) -> Result<(), Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
pub fn hkdf_sha256(_salt: &[u8], _ikm: &[u8], _info: &[u8], _key: &mut [u8]) -> Result<(), Error> {
|
pub fn hkdf_sha256(_salt: &[u8], _ikm: &[u8], _info: &[u8], _key: &mut [u8]) -> Result<(), Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
|
@ -81,7 +81,7 @@ impl KeyPair {
|
||||||
|
|
||||||
pub fn get_csr<'a>(&self, _out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> {
|
pub fn get_csr<'a>(&self, _out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_public_key(&self, _pub_key: &mut [u8]) -> Result<usize, Error> {
|
pub fn get_public_key(&self, _pub_key: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
@ -94,17 +94,17 @@ impl KeyPair {
|
||||||
|
|
||||||
pub fn derive_secret(self, _peer_pub_key: &[u8], _secret: &mut [u8]) -> Result<usize, Error> {
|
pub fn derive_secret(self, _peer_pub_key: &[u8], _secret: &mut [u8]) -> Result<usize, Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sign_msg(&self, _msg: &[u8], _signature: &mut [u8]) -> Result<usize, Error> {
|
pub fn sign_msg(&self, _msg: &[u8], _signature: &mut [u8]) -> Result<usize, Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_msg(&self, _msg: &[u8], _signature: &[u8]) -> Result<(), Error> {
|
pub fn verify_msg(&self, _msg: &[u8], _signature: &[u8]) -> Result<(), Error> {
|
||||||
error!("This API should never get called");
|
error!("This API should never get called");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ use crate::{
|
||||||
// TODO: We should move ASN1Writer out of Cert,
|
// TODO: We should move ASN1Writer out of Cert,
|
||||||
// so Crypto doesn't have to depend on Cert
|
// so Crypto doesn't have to depend on Cert
|
||||||
cert::{ASN1Writer, CertConsumer},
|
cert::{ASN1Writer, CertConsumer},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct HmacSha256 {
|
pub struct HmacSha256 {
|
||||||
|
@ -49,11 +49,13 @@ impl HmacSha256 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
|
pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
self.inner.update(data).map_err(|_| Error::TLSStack)
|
self.inner
|
||||||
|
.update(data)
|
||||||
|
.map_err(|_| ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(self, out: &mut [u8]) -> Result<(), Error> {
|
pub fn finish(self, out: &mut [u8]) -> Result<(), Error> {
|
||||||
self.inner.finish(out).map_err(|_| Error::TLSStack)?;
|
self.inner.finish(out).map_err(|_| ErrorCode::TLSStack)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,11 +104,11 @@ impl KeyPair {
|
||||||
Ok(Some(a)) => Ok(a),
|
Ok(Some(a)) => Ok(a),
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
error!("Error in writing CSR: None received");
|
error!("Error in writing CSR: None received");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error in writing CSR {}", e);
|
error!("Error in writing CSR {}", e);
|
||||||
Err(Error::TLSStack)
|
Err(ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +163,7 @@ impl KeyPair {
|
||||||
let mut ctr_drbg = CtrDrbg::new(Arc::new(OsEntropy::new()), None)?;
|
let mut ctr_drbg = CtrDrbg::new(Arc::new(OsEntropy::new()), None)?;
|
||||||
|
|
||||||
if signature.len() < super::EC_SIGNATURE_LEN_BYTES {
|
if signature.len() < super::EC_SIGNATURE_LEN_BYTES {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
safemem::write_bytes(signature, 0);
|
safemem::write_bytes(signature, 0);
|
||||||
|
|
||||||
|
@ -192,7 +194,7 @@ impl KeyPair {
|
||||||
|
|
||||||
if let Err(e) = tmp_key.verify(hash::Type::Sha256, &msg_hash, mbedtls_sign) {
|
if let Err(e) = tmp_key.verify(hash::Type::Sha256, &msg_hash, mbedtls_sign) {
|
||||||
info!("The error is {}", e);
|
info!("The error is {}", e);
|
||||||
Err(Error::InvalidSignature)
|
Err(ErrorCode::InvalidSignature.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -229,7 +231,7 @@ fn convert_asn1_sign_to_r_s(signature: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
|
||||||
// Type 0x2 is Integer (first integer is r)
|
// Type 0x2 is Integer (first integer is r)
|
||||||
if signature[offset] != 2 {
|
if signature[offset] != 2 {
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
|
@ -254,7 +256,7 @@ fn convert_asn1_sign_to_r_s(signature: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
|
||||||
// Type 0x2 is Integer (this integer is s)
|
// Type 0x2 is Integer (this integer is s)
|
||||||
if signature[offset] != 2 {
|
if signature[offset] != 2 {
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
offset += 1;
|
offset += 1;
|
||||||
|
|
||||||
|
@ -273,17 +275,17 @@ fn convert_asn1_sign_to_r_s(signature: &mut [u8]) -> Result<usize, Error> {
|
||||||
|
|
||||||
Ok(64)
|
Ok(64)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pbkdf2_hmac(pass: &[u8], iter: usize, salt: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
pub fn pbkdf2_hmac(pass: &[u8], iter: usize, salt: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
||||||
mbedtls::hash::pbkdf2_hmac(Type::Sha256, pass, salt, iter as u32, key)
|
mbedtls::hash::pbkdf2_hmac(Type::Sha256, pass, salt, iter as u32, key)
|
||||||
.map_err(|_e| Error::TLSStack)
|
.map_err(|_e| ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hkdf_sha256(salt: &[u8], ikm: &[u8], info: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
pub fn hkdf_sha256(salt: &[u8], ikm: &[u8], info: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
||||||
Hkdf::hkdf(Type::Sha256, salt, ikm, info, key).map_err(|_e| Error::TLSStack)
|
Hkdf::hkdf(Type::Sha256, salt, ikm, info, key).map_err(|_e| ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt_in_place(
|
pub fn encrypt_in_place(
|
||||||
|
@ -304,7 +306,7 @@ pub fn encrypt_in_place(
|
||||||
cipher
|
cipher
|
||||||
.encrypt_auth_inplace(ad, data, tag)
|
.encrypt_auth_inplace(ad, data, tag)
|
||||||
.map(|(len, _)| len)
|
.map(|(len, _)| len)
|
||||||
.map_err(|_e| Error::TLSStack)
|
.map_err(|_e| ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrypt_in_place(
|
pub fn decrypt_in_place(
|
||||||
|
@ -326,7 +328,7 @@ pub fn decrypt_in_place(
|
||||||
.map(|(len, _)| len)
|
.map(|(len, _)| len)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Error during decryption: {:?}", e);
|
error!("Error during decryption: {:?}", e);
|
||||||
Error::TLSStack
|
ErrorCode::TLSStack.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,12 +345,12 @@ impl Sha256 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
|
pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
self.ctx.update(data).map_err(|_| Error::TLSStack)?;
|
self.ctx.update(data).map_err(|_| ErrorCode::TLSStack)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(self, digest: &mut [u8]) -> Result<(), Error> {
|
pub fn finish(self, digest: &mut [u8]) -> Result<(), Error> {
|
||||||
self.ctx.finish(digest).map_err(|_| Error::TLSStack)?;
|
self.ctx.finish(digest).map_err(|_| ErrorCode::TLSStack)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
use foreign_types::ForeignTypeRef;
|
use foreign_types::ForeignTypeRef;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
@ -46,7 +46,8 @@ pub struct HmacSha256 {
|
||||||
impl HmacSha256 {
|
impl HmacSha256 {
|
||||||
pub fn new(key: &[u8]) -> Result<Self, Error> {
|
pub fn new(key: &[u8]) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ctx: Hmac::<sha2::Sha256>::new_from_slice(key).map_err(|_x| Error::InvalidKeyLength)?,
|
ctx: Hmac::<sha2::Sha256>::new_from_slice(key)
|
||||||
|
.map_err(|_x| ErrorCode::InvalidKeyLength)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ impl KeyPair {
|
||||||
|
|
||||||
fn private_key(&self) -> Result<&EcKey<Private>, Error> {
|
fn private_key(&self) -> Result<&EcKey<Private>, Error> {
|
||||||
match &self.key {
|
match &self.key {
|
||||||
KeyType::Public(_) => Err(Error::Invalid),
|
KeyType::Public(_) => Err(ErrorCode::Invalid.into()),
|
||||||
KeyType::Private(k) => Ok(&k),
|
KeyType::Private(k) => Ok(&k),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +168,7 @@ impl KeyPair {
|
||||||
a.copy_from_slice(csr);
|
a.copy_from_slice(csr);
|
||||||
Ok(a)
|
Ok(a)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +179,7 @@ impl KeyPair {
|
||||||
let msg = h.finish()?;
|
let msg = h.finish()?;
|
||||||
|
|
||||||
if signature.len() < super::EC_SIGNATURE_LEN_BYTES {
|
if signature.len() < super::EC_SIGNATURE_LEN_BYTES {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
safemem::write_bytes(signature, 0);
|
safemem::write_bytes(signature, 0);
|
||||||
|
|
||||||
|
@ -205,11 +206,11 @@ impl KeyPair {
|
||||||
KeyType::Public(key) => key,
|
KeyType::Public(key) => key,
|
||||||
_ => {
|
_ => {
|
||||||
error!("Not yet supported");
|
error!("Not yet supported");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if !sig.verify(&msg, k)? {
|
if !sig.verify(&msg, k)? {
|
||||||
Err(Error::InvalidSignature)
|
Err(ErrorCode::InvalidSignature.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -220,7 +221,7 @@ const P256_KEY_LEN: usize = 256 / 8;
|
||||||
pub fn pubkey_from_der<'a>(der: &'a [u8], out_key: &mut [u8]) -> Result<(), Error> {
|
pub fn pubkey_from_der<'a>(der: &'a [u8], out_key: &mut [u8]) -> Result<(), Error> {
|
||||||
if out_key.len() != P256_KEY_LEN {
|
if out_key.len() != P256_KEY_LEN {
|
||||||
error!("Insufficient length");
|
error!("Insufficient length");
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
} else {
|
} else {
|
||||||
let key = X509::from_der(der)?.public_key()?.public_key_to_der()?;
|
let key = X509::from_der(der)?.public_key()?.public_key_to_der()?;
|
||||||
let len = key.len();
|
let len = key.len();
|
||||||
|
@ -232,7 +233,7 @@ pub fn pubkey_from_der<'a>(der: &'a [u8], out_key: &mut [u8]) -> Result<(), Erro
|
||||||
|
|
||||||
pub fn pbkdf2_hmac(pass: &[u8], iter: usize, salt: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
pub fn pbkdf2_hmac(pass: &[u8], iter: usize, salt: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
||||||
openssl::pkcs5::pbkdf2_hmac(pass, salt, iter, MessageDigest::sha256(), key)
|
openssl::pkcs5::pbkdf2_hmac(pass, salt, iter, MessageDigest::sha256(), key)
|
||||||
.map_err(|_e| Error::TLSStack)
|
.map_err(|_e| ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hkdf_sha256(salt: &[u8], ikm: &[u8], info: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
pub fn hkdf_sha256(salt: &[u8], ikm: &[u8], info: &[u8], key: &mut [u8]) -> Result<(), Error> {
|
||||||
|
@ -372,7 +373,9 @@ impl Sha256 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
|
pub fn update(&mut self, data: &[u8]) -> Result<(), Error> {
|
||||||
self.hasher.update(data).map_err(|_| Error::TLSStack)
|
self.hasher
|
||||||
|
.update(data)
|
||||||
|
.map_err(|_| ErrorCode::TLSStack.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(mut self, data: &mut [u8]) -> Result<(), Error> {
|
pub fn finish(mut self, data: &mut [u8]) -> Result<(), Error> {
|
||||||
|
|
|
@ -39,7 +39,7 @@ use x509_cert::{
|
||||||
spki::{AlgorithmIdentifier, SubjectPublicKeyInfoOwned},
|
spki::{AlgorithmIdentifier, SubjectPublicKeyInfoOwned},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
use super::CryptoKeyPair;
|
use super::CryptoKeyPair;
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ impl HmacSha256 {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: HmacSha256I::new_from_slice(key).map_err(|e| {
|
inner: HmacSha256I::new_from_slice(key).map_err(|e| {
|
||||||
error!("Error creating HmacSha256 {:?}", e);
|
error!("Error creating HmacSha256 {:?}", e);
|
||||||
Error::TLSStack
|
ErrorCode::TLSStack
|
||||||
})?,
|
})?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ impl KeyPair {
|
||||||
fn private_key(&self) -> Result<&SecretKey, Error> {
|
fn private_key(&self) -> Result<&SecretKey, Error> {
|
||||||
match &self.key {
|
match &self.key {
|
||||||
KeyType::Private(key) => Ok(key),
|
KeyType::Private(key) => Ok(key),
|
||||||
KeyType::Public(_) => Err(Error::Crypto),
|
KeyType::Public(_) => Err(ErrorCode::Crypto.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ impl CryptoKeyPair for KeyPair {
|
||||||
priv_key[..slice.len()].copy_from_slice(slice);
|
priv_key[..slice.len()].copy_from_slice(slice);
|
||||||
Ok(len)
|
Ok(len)
|
||||||
}
|
}
|
||||||
KeyType::Public(_) => Err(Error::Crypto),
|
KeyType::Public(_) => Err(ErrorCode::Crypto.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_csr<'a>(&self, out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> {
|
fn get_csr<'a>(&self, out_csr: &'a mut [u8]) -> Result<&'a [u8], Error> {
|
||||||
|
@ -251,7 +251,7 @@ impl CryptoKeyPair for KeyPair {
|
||||||
use p256::ecdsa::signature::Signer;
|
use p256::ecdsa::signature::Signer;
|
||||||
|
|
||||||
if signature.len() < super::EC_SIGNATURE_LEN_BYTES {
|
if signature.len() < super::EC_SIGNATURE_LEN_BYTES {
|
||||||
return Err(Error::NoSpace);
|
return Err(ErrorCode::NoSpace.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
match &self.key {
|
match &self.key {
|
||||||
|
@ -274,7 +274,7 @@ impl CryptoKeyPair for KeyPair {
|
||||||
|
|
||||||
verifying_key
|
verifying_key
|
||||||
.verify(msg, &signature)
|
.verify(msg, &signature)
|
||||||
.map_err(|_| Error::InvalidSignature)?;
|
.map_err(|_| ErrorCode::InvalidSignature)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ pub fn hkdf_sha256(salt: &[u8], ikm: &[u8], info: &[u8], key: &mut [u8]) -> Resu
|
||||||
.expand(info, key)
|
.expand(info, key)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("Error with hkdf_sha256 {:?}", e);
|
error!("Error with hkdf_sha256 {:?}", e);
|
||||||
Error::TLSStack
|
ErrorCode::TLSStack.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
tlv::{FromTLV, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, TLVWriter, TagType, ToTLV},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,12 +80,12 @@ impl<'a> FromTLV<'a> for KeyPair {
|
||||||
t.confirm_array()?.enter();
|
t.confirm_array()?.enter();
|
||||||
|
|
||||||
if let Some(mut array) = t.enter() {
|
if let Some(mut array) = t.enter() {
|
||||||
let pub_key = array.next().ok_or(Error::Invalid)?.slice()?;
|
let pub_key = array.next().ok_or(ErrorCode::Invalid)?.slice()?;
|
||||||
let priv_key = array.next().ok_or(Error::Invalid)?.slice()?;
|
let priv_key = array.next().ok_or(ErrorCode::Invalid)?.slice()?;
|
||||||
|
|
||||||
KeyPair::new_from_components(pub_key, priv_key)
|
KeyPair::new_from_components(pub_key, priv_key)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ impl ToTLV for KeyPair {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::error::Error;
|
use crate::error::ErrorCode;
|
||||||
|
|
||||||
use super::KeyPair;
|
use super::KeyPair;
|
||||||
|
|
||||||
|
@ -122,8 +122,9 @@ mod tests {
|
||||||
fn test_verify_msg_fail() {
|
fn test_verify_msg_fail() {
|
||||||
let key = KeyPair::new_from_public(&test_vectors::PUB_KEY1).unwrap();
|
let key = KeyPair::new_from_public(&test_vectors::PUB_KEY1).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
key.verify_msg(&test_vectors::MSG1_FAIL, &test_vectors::SIGNATURE1),
|
key.verify_msg(&test_vectors::MSG1_FAIL, &test_vectors::SIGNATURE1)
|
||||||
Err(Error::InvalidSignature)
|
.map_err(|e| e.code()),
|
||||||
|
Err(ErrorCode::InvalidSignature)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data_model::objects::{Cluster, Handler},
|
data_model::objects::{Cluster, Handler},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
utils::rand::Rand,
|
utils::rand::Rand,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ impl TemplateCluster {
|
||||||
if attr.is_system() {
|
if attr.is_system() {
|
||||||
CLUSTER.read(attr.attr_id, writer)
|
CLUSTER.read(attr.attr_id, writer)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
acl::{AccessReq, Accessor},
|
acl::{AccessReq, Accessor},
|
||||||
attribute_enum,
|
attribute_enum,
|
||||||
data_model::objects::*,
|
data_model::objects::*,
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
interaction_model::{
|
interaction_model::{
|
||||||
core::IMStatusCode,
|
core::IMStatusCode,
|
||||||
messages::{
|
messages::{
|
||||||
|
@ -320,7 +320,7 @@ impl<'a> Cluster<'a> {
|
||||||
GlobalElements::FeatureMap => writer.set(self.feature_map),
|
GlobalElements::FeatureMap => writer.set(self.feature_map),
|
||||||
other => {
|
other => {
|
||||||
error!("This attribute is not yet handled {:?}", other);
|
error!("This attribute is not yet handled {:?}", other);
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use crate::interaction_model::messages::ib::{
|
||||||
use crate::interaction_model::messages::GenericPath;
|
use crate::interaction_model::messages::GenericPath;
|
||||||
use crate::tlv::UtfStr;
|
use crate::tlv::UtfStr;
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
interaction_model::messages::ib::{AttrDataTag, AttrRespTag},
|
interaction_model::messages::ib::{AttrDataTag, AttrRespTag},
|
||||||
tlv::{FromTLV, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, TLVElement, TLVWriter, TagType, ToTLV},
|
||||||
};
|
};
|
||||||
|
@ -135,8 +135,13 @@ impl<'a, 'b, 'c> AttrDataEncoder<'a, 'b, 'c> {
|
||||||
|
|
||||||
match handler.read(&attr, encoder) {
|
match handler.read(&attr, encoder) {
|
||||||
Ok(()) => None,
|
Ok(()) => None,
|
||||||
Err(Error::NoSpace) => return Ok(Some(attr.path().to_gp())),
|
Err(e) => {
|
||||||
Err(error) => attr.status(error.into())?,
|
if e.code() == ErrorCode::NoSpace {
|
||||||
|
return Ok(Some(attr.path().to_gp()));
|
||||||
|
} else {
|
||||||
|
attr.status(e.into())?
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(status) => Some(status),
|
Err(status) => Some(status),
|
||||||
|
@ -181,8 +186,13 @@ impl<'a, 'b, 'c> AttrDataEncoder<'a, 'b, 'c> {
|
||||||
|
|
||||||
match handler.read(&attr, encoder).await {
|
match handler.read(&attr, encoder).await {
|
||||||
Ok(()) => None,
|
Ok(()) => None,
|
||||||
Err(Error::NoSpace) => return Ok(Some(attr.path().to_gp())),
|
Err(e) => {
|
||||||
Err(error) => attr.status(error.into())?,
|
if e.code() == ErrorCode::NoSpace {
|
||||||
|
return Ok(Some(attr.path().to_gp()));
|
||||||
|
} else {
|
||||||
|
attr.status(e.into())?
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(status) => Some(status),
|
Err(status) => Some(status),
|
||||||
|
@ -321,7 +331,7 @@ impl<'a> AttrData<'a> {
|
||||||
pub fn with_dataver(self, dataver: u32) -> Result<&'a TLVElement<'a>, Error> {
|
pub fn with_dataver(self, dataver: u32) -> Result<&'a TLVElement<'a>, Error> {
|
||||||
if let Some(req_dataver) = self.for_dataver {
|
if let Some(req_dataver) = self.for_dataver {
|
||||||
if req_dataver != dataver {
|
if req_dataver != dataver {
|
||||||
return Err(Error::DataVersionMismatch);
|
Err(ErrorCode::DataVersionMismatch)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +567,8 @@ macro_rules! attribute_enum {
|
||||||
type Error = $crate::error::Error;
|
type Error = $crate::error::Error;
|
||||||
|
|
||||||
fn try_from(id: $crate::data_model::objects::AttrId) -> Result<Self, Self::Error> {
|
fn try_from(id: $crate::data_model::objects::AttrId) -> Result<Self, Self::Error> {
|
||||||
<$en>::from_repr(id).ok_or($crate::error::Error::AttributeNotFound)
|
<$en>::from_repr(id)
|
||||||
|
.ok_or_else(|| $crate::error::ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -571,7 +582,7 @@ macro_rules! command_enum {
|
||||||
type Error = $crate::error::Error;
|
type Error = $crate::error::Error;
|
||||||
|
|
||||||
fn try_from(id: $crate::data_model::objects::CmdId) -> Result<Self, Self::Error> {
|
fn try_from(id: $crate::data_model::objects::CmdId) -> Result<Self, Self::Error> {
|
||||||
<$en>::from_repr(id).ok_or($crate::error::Error::CommandNotFound)
|
<$en>::from_repr(id).ok_or_else(|| $crate::error::ErrorCode::CommandNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::{error::Error, interaction_model::core::Transaction, tlv::TLVElement};
|
use crate::{
|
||||||
|
error::{Error, ErrorCode},
|
||||||
|
interaction_model::core::Transaction,
|
||||||
|
tlv::TLVElement,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{AttrData, AttrDataEncoder, AttrDetails, CmdDataEncoder, CmdDetails};
|
use super::{AttrData, AttrDataEncoder, AttrDetails, CmdDataEncoder, CmdDetails};
|
||||||
|
|
||||||
|
@ -27,7 +31,7 @@ pub trait Handler {
|
||||||
fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error>;
|
fn read(&self, attr: &AttrDetails, encoder: AttrDataEncoder) -> Result<(), Error>;
|
||||||
|
|
||||||
fn write(&mut self, _attr: &AttrDetails, _data: AttrData) -> Result<(), Error> {
|
fn write(&mut self, _attr: &AttrDetails, _data: AttrData) -> Result<(), Error> {
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invoke(
|
fn invoke(
|
||||||
|
@ -37,7 +41,7 @@ pub trait Handler {
|
||||||
_data: &TLVElement,
|
_data: &TLVElement,
|
||||||
_encoder: CmdDataEncoder,
|
_encoder: CmdDataEncoder,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Err(Error::CommandNotFound)
|
Err(ErrorCode::CommandNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +92,7 @@ impl EmptyHandler {
|
||||||
|
|
||||||
impl Handler for EmptyHandler {
|
impl Handler for EmptyHandler {
|
||||||
fn read(&self, _attr: &AttrDetails, _encoder: AttrDataEncoder) -> Result<(), Error> {
|
fn read(&self, _attr: &AttrDetails, _encoder: AttrDataEncoder) -> Result<(), Error> {
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +206,7 @@ macro_rules! handler_chain_type {
|
||||||
pub mod asynch {
|
pub mod asynch {
|
||||||
use crate::{
|
use crate::{
|
||||||
data_model::objects::{AttrData, AttrDataEncoder, AttrDetails, CmdDataEncoder, CmdDetails},
|
data_model::objects::{AttrData, AttrDataEncoder, AttrDetails, CmdDataEncoder, CmdDetails},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
interaction_model::core::Transaction,
|
interaction_model::core::Transaction,
|
||||||
tlv::TLVElement,
|
tlv::TLVElement,
|
||||||
};
|
};
|
||||||
|
@ -221,7 +225,7 @@ pub mod asynch {
|
||||||
_attr: &'a AttrDetails<'_>,
|
_attr: &'a AttrDetails<'_>,
|
||||||
_data: AttrData<'a>,
|
_data: AttrData<'a>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn invoke<'a>(
|
async fn invoke<'a>(
|
||||||
|
@ -231,7 +235,7 @@ pub mod asynch {
|
||||||
_data: &'a TLVElement<'_>,
|
_data: &'a TLVElement<'_>,
|
||||||
_encoder: CmdDataEncoder<'a, '_, '_>,
|
_encoder: CmdDataEncoder<'a, '_, '_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Err(Error::CommandNotFound)
|
Err(ErrorCode::CommandNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +309,7 @@ pub mod asynch {
|
||||||
_attr: &'a AttrDetails<'_>,
|
_attr: &'a AttrDetails<'_>,
|
||||||
_encoder: AttrDataEncoder<'a, '_, '_>,
|
_encoder: AttrDataEncoder<'a, '_, '_>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
tlv::{FromTLV, TLVElement, ToTLV},
|
tlv::{FromTLV, TLVElement, ToTLV},
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
@ -47,12 +47,12 @@ impl FromTLV<'_> for Privilege {
|
||||||
1 => Ok(Privilege::VIEW),
|
1 => Ok(Privilege::VIEW),
|
||||||
2 => {
|
2 => {
|
||||||
error!("ProxyView privilege not yet supporteds");
|
error!("ProxyView privilege not yet supporteds");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
3 => Ok(Privilege::OPERATE),
|
3 => Ok(Privilege::OPERATE),
|
||||||
4 => Ok(Privilege::MANAGE),
|
4 => Ok(Privilege::MANAGE),
|
||||||
5 => Ok(Privilege::ADMIN),
|
5 => Ok(Privilege::ADMIN),
|
||||||
_ => Err(Error::Invalid),
|
_ => Err(ErrorCode::Invalid.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ impl<'a> AdminCommCluster<'a> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match cmd.cmd_id.try_into()? {
|
match cmd.cmd_id.try_into()? {
|
||||||
Commands::OpenCommWindow => self.handle_command_opencomm_win(data)?,
|
Commands::OpenCommWindow => self.handle_command_opencomm_win(data)?,
|
||||||
_ => Err(Error::CommandNotFound)?,
|
_ => Err(ErrorCode::CommandNotFound)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.data_ver.changed();
|
self.data_ver.changed();
|
||||||
|
|
|
@ -15,7 +15,10 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::{error::Error, transport::session::SessionMode};
|
use crate::{
|
||||||
|
error::{Error, ErrorCode},
|
||||||
|
transport::session::SessionMode,
|
||||||
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
|
@ -62,7 +65,7 @@ impl FailSafe {
|
||||||
State::Armed(c) => {
|
State::Armed(c) => {
|
||||||
if c.session_mode != session_mode {
|
if c.session_mode != session_mode {
|
||||||
error!("Received Fail-Safe Arm with different session modes; current {:?}, incoming {:?}", c.session_mode, session_mode);
|
error!("Received Fail-Safe Arm with different session modes; current {:?}, incoming {:?}", c.session_mode, session_mode);
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
// re-arm
|
// re-arm
|
||||||
c.timeout = timeout;
|
c.timeout = timeout;
|
||||||
|
@ -75,22 +78,22 @@ impl FailSafe {
|
||||||
match &mut self.state {
|
match &mut self.state {
|
||||||
State::Idle => {
|
State::Idle => {
|
||||||
error!("Received Fail-Safe Disarm without it being armed");
|
error!("Received Fail-Safe Disarm without it being armed");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
State::Armed(c) => {
|
State::Armed(c) => {
|
||||||
match c.noc_state {
|
match c.noc_state {
|
||||||
NocState::NocNotRecvd => return Err(Error::Invalid),
|
NocState::NocNotRecvd => Err(ErrorCode::Invalid)?,
|
||||||
NocState::AddNocRecvd(idx) | NocState::UpdateNocRecvd(idx) => {
|
NocState::AddNocRecvd(idx) | NocState::UpdateNocRecvd(idx) => {
|
||||||
if let SessionMode::Case(c) = session_mode {
|
if let SessionMode::Case(c) = session_mode {
|
||||||
if c.fab_idx != idx {
|
if c.fab_idx != idx {
|
||||||
error!(
|
error!(
|
||||||
"Received disarm in separate session from previous Add/Update NOC"
|
"Received disarm in separate session from previous Add/Update NOC"
|
||||||
);
|
);
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("Received disarm in a non-CASE session");
|
error!("Received disarm in a non-CASE session");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,13 +109,13 @@ impl FailSafe {
|
||||||
|
|
||||||
pub fn record_add_noc(&mut self, fabric_index: u8) -> Result<(), Error> {
|
pub fn record_add_noc(&mut self, fabric_index: u8) -> Result<(), Error> {
|
||||||
match &mut self.state {
|
match &mut self.state {
|
||||||
State::Idle => Err(Error::Invalid),
|
State::Idle => Err(ErrorCode::Invalid.into()),
|
||||||
State::Armed(c) => {
|
State::Armed(c) => {
|
||||||
if c.noc_state == NocState::NocNotRecvd {
|
if c.noc_state == NocState::NocNotRecvd {
|
||||||
c.noc_state = NocState::AddNocRecvd(fabric_index);
|
c.noc_state = NocState::AddNocRecvd(fabric_index);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,9 +235,9 @@ impl<'a> GenCommCluster<'a> {
|
||||||
cmd_enter!("Set Regulatory Config");
|
cmd_enter!("Set Regulatory Config");
|
||||||
let country_code = data
|
let country_code = data
|
||||||
.find_tag(1)
|
.find_tag(1)
|
||||||
.map_err(|_| Error::InvalidCommand)?
|
.map_err(|_| ErrorCode::InvalidCommand)?
|
||||||
.slice()
|
.slice()
|
||||||
.map_err(|_| Error::InvalidCommand)?;
|
.map_err(|_| ErrorCode::InvalidCommand)?;
|
||||||
info!("Received country code: {:?}", country_code);
|
info!("Received country code: {:?}", country_code);
|
||||||
|
|
||||||
let cmd_data = CommonResponse {
|
let cmd_data = CommonResponse {
|
||||||
|
|
|
@ -277,7 +277,7 @@ impl<'a> NocCluster<'a> {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Attribute not supported: this shouldn't happen");
|
error!("Attribute not supported: this shouldn't happen");
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,7 +563,7 @@ impl<'a> NocCluster<'a> {
|
||||||
info!("Received CSR Nonce:{:?}", req.str);
|
info!("Received CSR Nonce:{:?}", req.str);
|
||||||
|
|
||||||
if !self.failsafe.borrow().is_armed() {
|
if !self.failsafe.borrow().is_armed() {
|
||||||
return Err(Error::UnsupportedAccess);
|
Err(ErrorCode::UnsupportedAccess)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let noc_keypair = KeyPair::new()?;
|
let noc_keypair = KeyPair::new()?;
|
||||||
|
@ -602,7 +602,7 @@ impl<'a> NocCluster<'a> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
cmd_enter!("AddTrustedRootCert");
|
cmd_enter!("AddTrustedRootCert");
|
||||||
if !self.failsafe.borrow().is_armed() {
|
if !self.failsafe.borrow().is_armed() {
|
||||||
return Err(Error::UnsupportedAccess);
|
Err(ErrorCode::UnsupportedAccess)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This may happen on CASE or PASE. For PASE, the existence of NOC Data is necessary
|
// This may happen on CASE or PASE. For PASE, the existence of NOC Data is necessary
|
||||||
|
@ -612,13 +612,13 @@ impl<'a> NocCluster<'a> {
|
||||||
let noc_data = transaction
|
let noc_data = transaction
|
||||||
.session_mut()
|
.session_mut()
|
||||||
.get_noc_data::<NocData>()
|
.get_noc_data::<NocData>()
|
||||||
.ok_or(Error::NoSession)?;
|
.ok_or(ErrorCode::NoSession)?;
|
||||||
|
|
||||||
let req = CommonReq::from_tlv(data).map_err(Error::map_invalid_command)?;
|
let req = CommonReq::from_tlv(data).map_err(Error::map_invalid_command)?;
|
||||||
info!("Received Trusted Cert:{:x?}", req.str);
|
info!("Received Trusted Cert:{:x?}", req.str);
|
||||||
|
|
||||||
noc_data.root_ca =
|
noc_data.root_ca =
|
||||||
heapless::Vec::from_slice(req.str.0).map_err(|_| Error::BufferTooSmall)?;
|
heapless::Vec::from_slice(req.str.0).map_err(|_| ErrorCode::BufferTooSmall)?;
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -720,6 +720,6 @@ fn get_certchainrequest_params(data: &TLVElement) -> Result<DataType, Error> {
|
||||||
match cert_type {
|
match cert_type {
|
||||||
CERT_TYPE_DAC => Ok(dev_att::DataType::DAC),
|
CERT_TYPE_DAC => Ok(dev_att::DataType::DAC),
|
||||||
CERT_TYPE_PAI => Ok(dev_att::DataType::PAI),
|
CERT_TYPE_PAI => Ok(dev_att::DataType::PAI),
|
||||||
_ => Err(Error::Invalid),
|
_ => Err(ErrorCode::Invalid.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
AttrDataEncoder, AttrDetails, ChangeNotifier, Cluster, Dataver, Handler,
|
AttrDataEncoder, AttrDetails, ChangeNotifier, Cluster, Dataver, Handler,
|
||||||
NonBlockingHandler, ATTRIBUTE_LIST, FEATURE_MAP,
|
NonBlockingHandler, ATTRIBUTE_LIST, FEATURE_MAP,
|
||||||
},
|
},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
utils::rand::Rand,
|
utils::rand::Rand,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ impl Handler for NwCommCluster {
|
||||||
if attr.is_system() {
|
if attr.is_system() {
|
||||||
CLUSTER.read(attr.attr_id, writer)
|
CLUSTER.read(attr.attr_id, writer)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl<'a> AccessControlCluster<'a> {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("Attribute not yet supported: this shouldn't happen");
|
error!("Attribute not yet supported: this shouldn't happen");
|
||||||
Err(Error::AttributeNotFound)
|
Err(ErrorCode::AttributeNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,7 +229,7 @@ mod tests {
|
||||||
// Test, ACL has fabric index 2, but the accessing fabric is 1
|
// Test, ACL has fabric index 2, but the accessing fabric is 1
|
||||||
// the fabric index in the TLV should be ignored and the ACL should be created with entry 1
|
// the fabric index in the TLV should be ignored and the ACL should be created with entry 1
|
||||||
let result = acl.write_acl_attr(&ListOperation::AddItem, &data, 1);
|
let result = acl.write_acl_attr(&ListOperation::AddItem, &data, 1);
|
||||||
assert_eq!(result, Ok(()));
|
assert!(result.is_ok());
|
||||||
|
|
||||||
let verifier = AclEntry::new(1, Privilege::VIEW, AuthMode::Case);
|
let verifier = AclEntry::new(1, Privilege::VIEW, AuthMode::Case);
|
||||||
acl_mgr
|
acl_mgr
|
||||||
|
@ -268,7 +268,7 @@ mod tests {
|
||||||
let result = acl.write_acl_attr(&ListOperation::EditItem(1), &data, 2);
|
let result = acl.write_acl_attr(&ListOperation::EditItem(1), &data, 2);
|
||||||
// Fabric 2's index 1, is actually our index 2, update the verifier
|
// Fabric 2's index 1, is actually our index 2, update the verifier
|
||||||
verifier[2] = new;
|
verifier[2] = new;
|
||||||
assert_eq!(result, Ok(()));
|
assert!(result.is_ok());
|
||||||
|
|
||||||
// Also validate in the acl_mgr that the entries are in the right order
|
// Also validate in the acl_mgr that the entries are in the right order
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
@ -301,7 +301,7 @@ mod tests {
|
||||||
|
|
||||||
// Test , Delete Fabric 1's index 0
|
// Test , Delete Fabric 1's index 0
|
||||||
let result = acl.write_acl_attr(&ListOperation::DeleteItem(0), &data, 1);
|
let result = acl.write_acl_attr(&ListOperation::DeleteItem(0), &data, 1);
|
||||||
assert_eq!(result, Ok(()));
|
assert!(result.is_ok());
|
||||||
|
|
||||||
let verifier = [input[0], input[2]];
|
let verifier = [input[0], input[2]];
|
||||||
// Also validate in the acl_mgr that the entries are in the right order
|
// Also validate in the acl_mgr that the entries are in the right order
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
use core::{array::TryFromSliceError, fmt, str::Utf8Error};
|
use core::{array::TryFromSliceError, fmt, str::Utf8Error};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
pub enum Error {
|
pub enum ErrorCode {
|
||||||
AttributeNotFound,
|
AttributeNotFound,
|
||||||
AttributeIsCustom,
|
AttributeIsCustom,
|
||||||
BufferTooSmall,
|
BufferTooSmall,
|
||||||
|
@ -73,7 +73,36 @@ pub enum Error {
|
||||||
Utf8Fail,
|
Utf8Fail,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ErrorCode> for Error {
|
||||||
|
fn from(code: ErrorCode) -> Self {
|
||||||
|
Self::new(code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Error {
|
||||||
|
code: ErrorCode,
|
||||||
|
#[cfg(all(feature = "std", feature = "backtrace"))]
|
||||||
|
backtrace: std::backtrace::Backtrace,
|
||||||
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
pub fn new(code: ErrorCode) -> Self {
|
||||||
|
Self {
|
||||||
|
code,
|
||||||
|
#[cfg(all(feature = "std", feature = "backtrace"))]
|
||||||
|
backtrace: std::backtrace::Backtrace::capture(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn code(&self) -> ErrorCode {
|
||||||
|
self.code
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "std", feature = "backtrace"))]
|
||||||
|
pub const fn backtrace(&self) -> &std::backtrace::Backtrace {
|
||||||
|
&self.backtrace
|
||||||
|
}
|
||||||
|
|
||||||
pub fn remap<F>(self, matcher: F, to: Self) -> Self
|
pub fn remap<F>(self, matcher: F, to: Self) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(&Self) -> bool,
|
F: FnOnce(&Self) -> bool,
|
||||||
|
@ -86,19 +115,22 @@ impl Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_invalid(self, to: Self) -> Self {
|
pub fn map_invalid(self, to: Self) -> Self {
|
||||||
self.remap(|e| matches!(e, Self::Invalid | Self::InvalidData), to)
|
self.remap(
|
||||||
|
|e| matches!(e.code(), ErrorCode::Invalid | ErrorCode::InvalidData),
|
||||||
|
to,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_invalid_command(self) -> Self {
|
pub fn map_invalid_command(self) -> Self {
|
||||||
self.map_invalid(Error::InvalidCommand)
|
self.map_invalid(Error::new(ErrorCode::InvalidCommand))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_invalid_action(self) -> Self {
|
pub fn map_invalid_action(self) -> Self {
|
||||||
self.map_invalid(Error::InvalidAction)
|
self.map_invalid(Error::new(ErrorCode::InvalidAction))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_invalid_data_type(self) -> Self {
|
pub fn map_invalid_data_type(self) -> Self {
|
||||||
self.map_invalid(Error::InvalidDataType)
|
self.map_invalid(Error::new(ErrorCode::InvalidDataType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,14 +138,14 @@ impl Error {
|
||||||
impl From<std::io::Error> for Error {
|
impl From<std::io::Error> for Error {
|
||||||
fn from(_e: std::io::Error) -> Self {
|
fn from(_e: std::io::Error) -> Self {
|
||||||
// Keep things simple for now
|
// Keep things simple for now
|
||||||
Self::StdIoError
|
Self::new(ErrorCode::StdIoError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<T> From<std::sync::PoisonError<T>> for Error {
|
impl<T> From<std::sync::PoisonError<T>> for Error {
|
||||||
fn from(_e: std::sync::PoisonError<T>) -> Self {
|
fn from(_e: std::sync::PoisonError<T>) -> Self {
|
||||||
Self::RwLock
|
Self::new(ErrorCode::RwLock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +153,7 @@ impl<T> From<std::sync::PoisonError<T>> for Error {
|
||||||
impl From<openssl::error::ErrorStack> for Error {
|
impl From<openssl::error::ErrorStack> for Error {
|
||||||
fn from(e: openssl::error::ErrorStack) -> Self {
|
fn from(e: openssl::error::ErrorStack) -> Self {
|
||||||
::log::error!("Error in TLS: {}", e);
|
::log::error!("Error in TLS: {}", e);
|
||||||
Self::TLSStack
|
Self::new(ErrorCode::TLSStack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,39 +161,57 @@ impl From<openssl::error::ErrorStack> for Error {
|
||||||
impl From<mbedtls::Error> for Error {
|
impl From<mbedtls::Error> for Error {
|
||||||
fn from(e: mbedtls::Error) -> Self {
|
fn from(e: mbedtls::Error) -> Self {
|
||||||
::log::error!("Error in TLS: {}", e);
|
::log::error!("Error in TLS: {}", e);
|
||||||
Self::TLSStack
|
Self::new(ErrorCode::TLSStack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "crypto_rustcrypto")]
|
#[cfg(feature = "crypto_rustcrypto")]
|
||||||
impl From<ccm::aead::Error> for Error {
|
impl From<ccm::aead::Error> for Error {
|
||||||
fn from(_e: ccm::aead::Error) -> Self {
|
fn from(_e: ccm::aead::Error) -> Self {
|
||||||
Self::Crypto
|
Self::new(ErrorCode::Crypto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl From<std::time::SystemTimeError> for Error {
|
impl From<std::time::SystemTimeError> for Error {
|
||||||
fn from(_e: std::time::SystemTimeError) -> Self {
|
fn from(_e: std::time::SystemTimeError) -> Self {
|
||||||
Self::SysTimeFail
|
Error::new(ErrorCode::SysTimeFail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TryFromSliceError> for Error {
|
impl From<TryFromSliceError> for Error {
|
||||||
fn from(_e: TryFromSliceError) -> Self {
|
fn from(_e: TryFromSliceError) -> Self {
|
||||||
Self::Invalid
|
Self::new(ErrorCode::Invalid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Utf8Error> for Error {
|
impl From<Utf8Error> for Error {
|
||||||
fn from(_e: Utf8Error) -> Self {
|
fn from(_e: Utf8Error) -> Self {
|
||||||
Self::Utf8Fail
|
Self::new(ErrorCode::Utf8Fail)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
#[cfg(not(all(feature = "std", feature = "backtrace")))]
|
||||||
|
{
|
||||||
|
write!(f, "Error::{}", self)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(feature = "std", feature = "backtrace"))]
|
||||||
|
{
|
||||||
|
write!(f, "Error::{} {{\n", self)?;
|
||||||
|
write!(f, "{}", self.backtrace())?;
|
||||||
|
write!(f, "}}\n")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{:?}", self)
|
write!(f, "{:?}", self.code())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@ use log::info;
|
||||||
use crate::{
|
use crate::{
|
||||||
cert::{Cert, MAX_CERT_TLV_LEN},
|
cert::{Cert, MAX_CERT_TLV_LEN},
|
||||||
crypto::{self, hkdf_sha256, HmacSha256, KeyPair},
|
crypto::{self, hkdf_sha256, HmacSha256, KeyPair},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
group_keys::KeySet,
|
group_keys::KeySet,
|
||||||
mdns::{MdnsMgr, ServiceMode},
|
mdns::{MdnsMgr, ServiceMode},
|
||||||
tlv::{FromTLV, OctetStr, TLVElement, TLVList, TLVWriter, TagType, ToTLV, UtfStr},
|
tlv::{FromTLV, OctetStr, TLVList, TLVWriter, TagType, ToTLV, UtfStr},
|
||||||
utils::writebuf::WriteBuf,
|
utils::writebuf::WriteBuf,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ impl Fabric {
|
||||||
0x69, 0x63,
|
0x69, 0x63,
|
||||||
];
|
];
|
||||||
hkdf_sha256(&fabric_id_be, root_pubkey, &COMPRESSED_FABRIC_ID_INFO, out)
|
hkdf_sha256(&fabric_id_be, root_pubkey, &COMPRESSED_FABRIC_ID_INFO, out)
|
||||||
.map_err(|_| Error::NoSpace)
|
.map_err(|_| Error::from(ErrorCode::NoSpace))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_dest_id(&self, random: &[u8], target: &[u8]) -> Result<(), Error> {
|
pub fn match_dest_id(&self, random: &[u8], target: &[u8]) -> Result<(), Error> {
|
||||||
|
@ -144,7 +144,7 @@ impl Fabric {
|
||||||
if id.as_slice() == target {
|
if id.as_slice() == target {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotFound)
|
Err(ErrorCode::NotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ impl FabricMgr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let root = TLVList::new(data).iter().next().ok_or(Error::Invalid)?;
|
let root = TLVList::new(data).iter().next().ok_or(ErrorCode::Invalid)?;
|
||||||
|
|
||||||
self.fabrics = FabricEntries::from_tlv(&root)?;
|
self.fabrics = FabricEntries::from_tlv(&root)?;
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ impl FabricMgr {
|
||||||
if self.changed {
|
if self.changed {
|
||||||
let mut wb = WriteBuf::new(buf);
|
let mut wb = WriteBuf::new(buf);
|
||||||
let mut tw = TLVWriter::new(&mut wb);
|
let mut tw = TLVWriter::new(&mut wb);
|
||||||
|
|
||||||
self.fabrics.to_tlv(&mut tw, TagType::Anonymous)?;
|
self.fabrics.to_tlv(&mut tw, TagType::Anonymous)?;
|
||||||
|
|
||||||
self.changed = false;
|
self.changed = false;
|
||||||
|
@ -252,7 +253,7 @@ impl FabricMgr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(&mut self, fab_idx: u8, mdns_mgr: &mut MdnsMgr) -> Result<(), Error> {
|
pub fn remove(&mut self, fab_idx: u8, mdns_mgr: &mut MdnsMgr) -> Result<(), Error> {
|
||||||
|
@ -262,10 +263,10 @@ impl FabricMgr {
|
||||||
self.changed = true;
|
self.changed = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotFound)
|
Err(ErrorCode::NotFound.into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotFound)
|
Err(ErrorCode::NotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +278,7 @@ impl FabricMgr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Error::NotFound)
|
Err(ErrorCode::NotFound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fabric(&self, idx: usize) -> Result<Option<&Fabric>, Error> {
|
pub fn get_fabric(&self, idx: usize) -> Result<Option<&Fabric>, Error> {
|
||||||
|
@ -317,7 +318,7 @@ impl FabricMgr {
|
||||||
.filter_map(|f| f.as_ref())
|
.filter_map(|f| f.as_ref())
|
||||||
.any(|f| f.label == label)
|
.any(|f| f.label == label)
|
||||||
{
|
{
|
||||||
return Err(Error::Invalid);
|
return Err(ErrorCode::Invalid.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
crypto::{self, SYMM_KEY_LEN_BYTES},
|
crypto::{self, SYMM_KEY_LEN_BYTES},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
tlv::{FromTLV, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, TLVWriter, TagType, ToTLV},
|
||||||
};
|
};
|
||||||
|
|
||||||
type KeySetKey = [u8; SYMM_KEY_LEN_BYTES];
|
type KeySetKey = [u8; SYMM_KEY_LEN_BYTES];
|
||||||
|
@ -42,7 +42,8 @@ impl KeySet {
|
||||||
0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x20, 0x76, 0x31, 0x2e, 0x30,
|
0x47, 0x72, 0x6f, 0x75, 0x70, 0x4b, 0x65, 0x79, 0x20, 0x76, 0x31, 0x2e, 0x30,
|
||||||
];
|
];
|
||||||
|
|
||||||
crypto::hkdf_sha256(compressed_id, ipk, &GRP_KEY_INFO, opkey).map_err(|_| Error::NoSpace)
|
crypto::hkdf_sha256(compressed_id, ipk, &GRP_KEY_INFO, opkey)
|
||||||
|
.map_err(|_| ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_key(&self) -> &[u8] {
|
pub fn op_key(&self) -> &[u8] {
|
||||||
|
|
|
@ -78,27 +78,33 @@ pub enum IMStatusCode {
|
||||||
FailSafeRequired = 0xca,
|
FailSafeRequired = 0xca,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for IMStatusCode {
|
impl From<ErrorCode> for IMStatusCode {
|
||||||
fn from(e: Error) -> Self {
|
fn from(e: ErrorCode) -> Self {
|
||||||
match e {
|
match e {
|
||||||
Error::EndpointNotFound => IMStatusCode::UnsupportedEndpoint,
|
ErrorCode::EndpointNotFound => IMStatusCode::UnsupportedEndpoint,
|
||||||
Error::ClusterNotFound => IMStatusCode::UnsupportedCluster,
|
ErrorCode::ClusterNotFound => IMStatusCode::UnsupportedCluster,
|
||||||
Error::AttributeNotFound => IMStatusCode::UnsupportedAttribute,
|
ErrorCode::AttributeNotFound => IMStatusCode::UnsupportedAttribute,
|
||||||
Error::CommandNotFound => IMStatusCode::UnsupportedCommand,
|
ErrorCode::CommandNotFound => IMStatusCode::UnsupportedCommand,
|
||||||
Error::InvalidAction => IMStatusCode::InvalidAction,
|
ErrorCode::InvalidAction => IMStatusCode::InvalidAction,
|
||||||
Error::InvalidCommand => IMStatusCode::InvalidCommand,
|
ErrorCode::InvalidCommand => IMStatusCode::InvalidCommand,
|
||||||
Error::UnsupportedAccess => IMStatusCode::UnsupportedAccess,
|
ErrorCode::UnsupportedAccess => IMStatusCode::UnsupportedAccess,
|
||||||
Error::Busy => IMStatusCode::Busy,
|
ErrorCode::Busy => IMStatusCode::Busy,
|
||||||
Error::DataVersionMismatch => IMStatusCode::DataVersionMismatch,
|
ErrorCode::DataVersionMismatch => IMStatusCode::DataVersionMismatch,
|
||||||
Error::ResourceExhausted => IMStatusCode::ResourceExhausted,
|
ErrorCode::ResourceExhausted => IMStatusCode::ResourceExhausted,
|
||||||
_ => IMStatusCode::Failure,
|
_ => IMStatusCode::Failure,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Error> for IMStatusCode {
|
||||||
|
fn from(value: Error) -> Self {
|
||||||
|
Self::from(value.code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromTLV<'_> for IMStatusCode {
|
impl FromTLV<'_> for IMStatusCode {
|
||||||
fn from_tlv(t: &TLVElement) -> Result<Self, Error> {
|
fn from_tlv(t: &TLVElement) -> Result<Self, Error> {
|
||||||
num::FromPrimitive::from_u16(t.u16()?).ok_or(Error::Invalid)
|
num::FromPrimitive::from_u16(t.u16()?).ok_or_else(|| ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +229,7 @@ pub enum Interaction<'a> {
|
||||||
impl<'a> Interaction<'a> {
|
impl<'a> Interaction<'a> {
|
||||||
fn new(rx: &'a Packet, transaction: &mut Transaction) -> Result<Option<Self>, Error> {
|
fn new(rx: &'a Packet, transaction: &mut Transaction) -> Result<Option<Self>, Error> {
|
||||||
let opcode: OpCode =
|
let opcode: OpCode =
|
||||||
num::FromPrimitive::from_u8(rx.get_proto_opcode()).ok_or(Error::Invalid)?;
|
num::FromPrimitive::from_u8(rx.get_proto_opcode()).ok_or(ErrorCode::Invalid)?;
|
||||||
|
|
||||||
let rx_data = rx.as_slice();
|
let rx_data = rx.as_slice();
|
||||||
|
|
||||||
|
@ -264,7 +270,7 @@ impl<'a> Interaction<'a> {
|
||||||
)?))),
|
)?))),
|
||||||
_ => {
|
_ => {
|
||||||
error!("Opcode not handled: {:?}", opcode);
|
error!("Opcode not handled: {:?}", opcode);
|
||||||
Err(Error::InvalidOpcode)
|
Err(ErrorCode::InvalidOpcode.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data_model::objects::{ClusterId, EndptId},
|
data_model::objects::{ClusterId, EndptId},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
tlv::{FromTLV, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, TLVWriter, TagType, ToTLV},
|
||||||
};
|
};
|
||||||
|
|
||||||
// A generic path with endpoint, clusters, and a leaf
|
// A generic path with endpoint, clusters, and a leaf
|
||||||
|
@ -48,7 +48,7 @@ impl GenericPath {
|
||||||
cluster: Some(c),
|
cluster: Some(c),
|
||||||
leaf: Some(l),
|
leaf: Some(l),
|
||||||
} => Ok((e, c, l)),
|
} => Ok((e, c, l)),
|
||||||
_ => Err(Error::Invalid),
|
_ => Err(ErrorCode::Invalid.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Returns true, if the path is wildcard
|
/// Returns true, if the path is wildcard
|
||||||
|
@ -69,7 +69,7 @@ pub mod msg {
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::Error,
|
||||||
interaction_model::core::IMStatusCode,
|
interaction_model::core::IMStatusCode,
|
||||||
tlv::{FromTLV, TLVArray, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, TLVArray, TLVWriter, TagType, ToTLV},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::ib::{
|
use super::ib::{
|
||||||
|
@ -259,7 +259,7 @@ pub mod ib {
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data_model::objects::{AttrDetails, AttrId, ClusterId, CmdId, EncodeValue, EndptId},
|
data_model::objects::{AttrDetails, AttrId, ClusterId, CmdId, EncodeValue, EndptId},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
interaction_model::core::IMStatusCode,
|
interaction_model::core::IMStatusCode,
|
||||||
tlv::{FromTLV, Nullable, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{FromTLV, Nullable, TLVElement, TLVWriter, TagType, ToTLV},
|
||||||
};
|
};
|
||||||
|
@ -447,7 +447,7 @@ pub mod ib {
|
||||||
f(ListOperation::DeleteList, data)?;
|
f(ListOperation::DeleteList, data)?;
|
||||||
// Now the data must be a list, that should be added item by item
|
// Now the data must be a list, that should be added item by item
|
||||||
|
|
||||||
let container = data.enter().ok_or(Error::Invalid)?;
|
let container = data.enter().ok_or(ErrorCode::Invalid)?;
|
||||||
for d in container {
|
for d in container {
|
||||||
f(ListOperation::AddItem, &d)?;
|
f(ListOperation::AddItem, &d)?;
|
||||||
}
|
}
|
||||||
|
@ -544,7 +544,7 @@ pub mod ib {
|
||||||
|
|
||||||
if c.path.leaf.is_none() {
|
if c.path.leaf.is_none() {
|
||||||
error!("Wildcard command parameter not supported");
|
error!("Wildcard command parameter not supported");
|
||||||
Err(Error::CommandNotFound)
|
Err(ErrorCode::CommandNotFound.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(c)
|
Ok(c)
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,7 @@ pub mod astro {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::Mdns;
|
use super::Mdns;
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
use astro_dnssd::{DNSServiceBuilder, RegisteredDnsService};
|
use astro_dnssd::{DNSServiceBuilder, RegisteredDnsService};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ pub mod astro {
|
||||||
builder = builder.with_key_value(kvs.0.to_string(), kvs.1.to_string());
|
builder = builder.with_key_value(kvs.0.to_string(), kvs.1.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let svc = builder.register().map_err(|_| Error::MdnsError)?;
|
let svc = builder.register().map_err(|_| ErrorCode::MdnsError)?;
|
||||||
|
|
||||||
self.services.insert(
|
self.services.insert(
|
||||||
ServiceId {
|
ServiceId {
|
||||||
|
@ -348,7 +348,7 @@ pub mod astro {
|
||||||
// use std::collections::HashMap;
|
// use std::collections::HashMap;
|
||||||
|
|
||||||
// use super::Mdns;
|
// use super::Mdns;
|
||||||
// use crate::error::Error;
|
// use crate::error::{Error, ErrorCode};
|
||||||
// use log::info;
|
// use log::info;
|
||||||
// use zeroconf::prelude::*;
|
// use zeroconf::prelude::*;
|
||||||
// use zeroconf::{MdnsService, ServiceType, TxtRecord};
|
// use zeroconf::{MdnsService, ServiceType, TxtRecord};
|
||||||
|
@ -402,7 +402,7 @@ pub mod astro {
|
||||||
|
|
||||||
// svc.set_txt_record(txt);
|
// svc.set_txt_record(txt);
|
||||||
|
|
||||||
// //let event_loop = svc.register().map_err(|_| Error::MdnsError)?;
|
// //let event_loop = svc.register().map_err(|_| ErrorCode::MdnsError)?;
|
||||||
|
|
||||||
// self.services.insert(
|
// self.services.insert(
|
||||||
// ServiceId {
|
// ServiceId {
|
||||||
|
@ -604,7 +604,7 @@ pub mod libmdns {
|
||||||
// pub mod simplemdns {
|
// pub mod simplemdns {
|
||||||
// use std::net::Ipv4Addr;
|
// use std::net::Ipv4Addr;
|
||||||
|
|
||||||
// use crate::error::Error;
|
// use crate::error::{Error, ErrorCode};
|
||||||
// use super::Mdns;
|
// use super::Mdns;
|
||||||
// use log::info;
|
// use log::info;
|
||||||
// use simple_dns::{
|
// use simple_dns::{
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
error::ErrorCode,
|
||||||
tlv::{TLVWriter, TagType},
|
tlv::{TLVWriter, TagType},
|
||||||
utils::writebuf::WriteBuf,
|
utils::writebuf::WriteBuf,
|
||||||
};
|
};
|
||||||
|
@ -134,7 +135,7 @@ impl<'data> QrSetupPayload<'data> {
|
||||||
if is_vendor_tag(tag) {
|
if is_vendor_tag(tag) {
|
||||||
self.add_optional_data(tag, data)
|
self.add_optional_data(tag, data)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidArgument)
|
Err(ErrorCode::InvalidArgument.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +151,7 @@ impl<'data> QrSetupPayload<'data> {
|
||||||
if is_common_tag(tag) {
|
if is_common_tag(tag) {
|
||||||
self.add_optional_data(tag, data)
|
self.add_optional_data(tag, data)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidArgument)
|
Err(ErrorCode::InvalidArgument.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ impl<'data> QrSetupPayload<'data> {
|
||||||
} else {
|
} else {
|
||||||
self.optional_data.push(item)
|
self.optional_data.push(item)
|
||||||
}
|
}
|
||||||
.map_err(|_| Error::NoSpace)
|
.map_err(|_| ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_optional_data(&self) -> &[OptionalQRCodeInfo] {
|
pub fn get_all_optional_data(&self) -> &[OptionalQRCodeInfo] {
|
||||||
|
@ -267,7 +268,7 @@ pub(super) fn payload_base38_representation<const N: usize>(
|
||||||
|
|
||||||
payload_base38_representation_with_tlv(payload, bits_buf, tlv_buf)
|
payload_base38_representation_with_tlv(payload, bits_buf, tlv_buf)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidArgument)
|
Err(ErrorCode::InvalidArgument.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,7 +300,7 @@ pub fn estimate_buffer_size(payload: &QrSetupPayload) -> Result<usize, Error> {
|
||||||
estimate = estimate_struct_overhead(estimate);
|
estimate = estimate_struct_overhead(estimate);
|
||||||
|
|
||||||
if estimate > u32::MAX as usize {
|
if estimate > u32::MAX as usize {
|
||||||
return Err(Error::NoMemory);
|
Err(ErrorCode::NoMemory)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(estimate)
|
Ok(estimate)
|
||||||
|
@ -352,11 +353,11 @@ fn populate_bits(
|
||||||
total_payload_data_size_in_bits: usize,
|
total_payload_data_size_in_bits: usize,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if *offset + number_of_bits > total_payload_data_size_in_bits {
|
if *offset + number_of_bits > total_payload_data_size_in_bits {
|
||||||
return Err(Error::InvalidArgument);
|
Err(ErrorCode::InvalidArgument)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if input >= 1u64 << number_of_bits {
|
if input >= 1u64 << number_of_bits {
|
||||||
return Err(Error::InvalidArgument);
|
Err(ErrorCode::InvalidArgument)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut index = *offset;
|
let mut index = *offset;
|
||||||
|
@ -390,7 +391,7 @@ fn payload_base38_representation_with_tlv<const N: usize>(
|
||||||
let mut base38_encoded: heapless::String<N> = "MT:".into();
|
let mut base38_encoded: heapless::String<N> = "MT:".into();
|
||||||
|
|
||||||
for c in base38::encode(bits) {
|
for c in base38::encode(bits) {
|
||||||
base38_encoded.push(c).map_err(|_| Error::NoSpace)?;
|
base38_encoded.push(c).map_err(|_| ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(base38_encoded)
|
Ok(base38_encoded)
|
||||||
|
@ -431,7 +432,7 @@ fn generate_bit_set<'a>(
|
||||||
TOTAL_PAYLOAD_DATA_SIZE_IN_BITS + tlv_data.map(|tlv_data| tlv_data.len() * 8).unwrap_or(0);
|
TOTAL_PAYLOAD_DATA_SIZE_IN_BITS + tlv_data.map(|tlv_data| tlv_data.len() * 8).unwrap_or(0);
|
||||||
|
|
||||||
if bits_buf.len() * 8 < total_payload_size_in_bits {
|
if bits_buf.len() * 8 < total_payload_size_in_bits {
|
||||||
return Err(Error::BufferTooSmall);
|
Err(ErrorCode::BufferTooSmall)?;
|
||||||
};
|
};
|
||||||
|
|
||||||
let passwd = passwd_from_comm_data(payload.comm_data);
|
let passwd = passwd_from_comm_data(payload.comm_data);
|
||||||
|
|
|
@ -25,7 +25,7 @@ mod file_psm {
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
pub struct FilePsm {
|
pub struct FilePsm {
|
||||||
dir: PathBuf,
|
dir: PathBuf,
|
||||||
|
@ -47,7 +47,7 @@ mod file_psm {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if offset == buf.len() {
|
if offset == buf.len() {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let len = file.read(&mut buf[offset..])?;
|
let len = file.read(&mut buf[offset..])?;
|
||||||
|
|
|
@ -22,11 +22,11 @@ use log::{error, trace};
|
||||||
use crate::{
|
use crate::{
|
||||||
cert::Cert,
|
cert::Cert,
|
||||||
crypto::{self, KeyPair, Sha256},
|
crypto::{self, KeyPair, Sha256},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
fabric::{Fabric, FabricMgr},
|
fabric::{Fabric, FabricMgr},
|
||||||
secure_channel::common::SCStatusCodes,
|
secure_channel::common::SCStatusCodes,
|
||||||
secure_channel::common::{self, OpCode},
|
secure_channel::common::{self, OpCode},
|
||||||
tlv::{get_root_node_struct, FromTLV, OctetStr, TLVElement, TLVWriter, TagType},
|
tlv::{get_root_node_struct, FromTLV, OctetStr, TLVWriter, TagType},
|
||||||
transport::{
|
transport::{
|
||||||
network::Address,
|
network::Address,
|
||||||
proto_ctx::ProtoCtx,
|
proto_ctx::ProtoCtx,
|
||||||
|
@ -90,9 +90,9 @@ impl<'a> Case<'a> {
|
||||||
.exch_ctx
|
.exch_ctx
|
||||||
.exch
|
.exch
|
||||||
.take_case_session::<CaseSession>()
|
.take_case_session::<CaseSession>()
|
||||||
.ok_or(Error::InvalidState)?;
|
.ok_or(ErrorCode::InvalidState)?;
|
||||||
if case_session.state != State::Sigma1Rx {
|
if case_session.state != State::Sigma1Rx {
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
case_session.state = State::Sigma3Rx;
|
case_session.state = State::Sigma3Rx;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ impl<'a> Case<'a> {
|
||||||
let mut decrypted: [u8; 800] = [0; 800];
|
let mut decrypted: [u8; 800] = [0; 800];
|
||||||
if encrypted.len() > decrypted.len() {
|
if encrypted.len() > decrypted.len() {
|
||||||
error!("Data too large");
|
error!("Data too large");
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
let decrypted = &mut decrypted[..encrypted.len()];
|
let decrypted = &mut decrypted[..encrypted.len()];
|
||||||
decrypted.copy_from_slice(encrypted);
|
decrypted.copy_from_slice(encrypted);
|
||||||
|
@ -204,7 +204,7 @@ impl<'a> Case<'a> {
|
||||||
case_session.local_fabric_idx = local_fabric_idx?;
|
case_session.local_fabric_idx = local_fabric_idx?;
|
||||||
if r.peer_pub_key.0.len() != crypto::EC_POINT_LEN_BYTES {
|
if r.peer_pub_key.0.len() != crypto::EC_POINT_LEN_BYTES {
|
||||||
error!("Invalid public key length");
|
error!("Invalid public key length");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
case_session.peer_pub_key.copy_from_slice(r.peer_pub_key.0);
|
case_session.peer_pub_key.copy_from_slice(r.peer_pub_key.0);
|
||||||
trace!(
|
trace!(
|
||||||
|
@ -220,7 +220,7 @@ impl<'a> Case<'a> {
|
||||||
let len = key_pair.derive_secret(r.peer_pub_key.0, &mut case_session.shared_secret)?;
|
let len = key_pair.derive_secret(r.peer_pub_key.0, &mut case_session.shared_secret)?;
|
||||||
if len != 32 {
|
if len != 32 {
|
||||||
error!("Derived secret length incorrect");
|
error!("Derived secret length incorrect");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
// println!("Derived secret: {:x?} len: {}", secret, len);
|
// println!("Derived secret: {:x?} len: {}", secret, len);
|
||||||
|
|
||||||
|
@ -348,14 +348,14 @@ impl<'a> Case<'a> {
|
||||||
let mut verifier = noc.verify_chain_start(utc_calendar);
|
let mut verifier = noc.verify_chain_start(utc_calendar);
|
||||||
|
|
||||||
if fabric.get_fabric_id() != noc.get_fabric_id()? {
|
if fabric.get_fabric_id() != noc.get_fabric_id()? {
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(icac) = icac {
|
if let Some(icac) = icac {
|
||||||
// If ICAC is present handle it
|
// If ICAC is present handle it
|
||||||
if let Ok(fid) = icac.get_fabric_id() {
|
if let Ok(fid) = icac.get_fabric_id() {
|
||||||
if fid != fabric.get_fabric_id() {
|
if fid != fabric.get_fabric_id() {
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verifier = verifier.add_cert(icac)?;
|
verifier = verifier.add_cert(icac)?;
|
||||||
|
@ -377,7 +377,7 @@ impl<'a> Case<'a> {
|
||||||
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73,
|
0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x73,
|
||||||
];
|
];
|
||||||
if key.len() < 48 {
|
if key.len() < 48 {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
let mut salt = heapless::Vec::<u8, 256>::new();
|
let mut salt = heapless::Vec::<u8, 256>::new();
|
||||||
salt.extend_from_slice(ipk).unwrap();
|
salt.extend_from_slice(ipk).unwrap();
|
||||||
|
@ -388,7 +388,7 @@ impl<'a> Case<'a> {
|
||||||
// println!("Session Key: salt: {:x?}, len: {}", salt, salt.len());
|
// println!("Session Key: salt: {:x?}, len: {}", salt, salt.len());
|
||||||
|
|
||||||
crypto::hkdf_sha256(salt.as_slice(), shared_secret, &SEKEYS_INFO, key)
|
crypto::hkdf_sha256(salt.as_slice(), shared_secret, &SEKEYS_INFO, key)
|
||||||
.map_err(|_x| Error::NoSpace)?;
|
.map_err(|_x| ErrorCode::NoSpace)?;
|
||||||
// println!("Session Key: key: {:x?}", key);
|
// println!("Session Key: key: {:x?}", key);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -425,7 +425,7 @@ impl<'a> Case<'a> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
const S3K_INFO: [u8; 6] = [0x53, 0x69, 0x67, 0x6d, 0x61, 0x33];
|
const S3K_INFO: [u8; 6] = [0x53, 0x69, 0x67, 0x6d, 0x61, 0x33];
|
||||||
if key.len() < 16 {
|
if key.len() < 16 {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
let mut salt = heapless::Vec::<u8, 256>::new();
|
let mut salt = heapless::Vec::<u8, 256>::new();
|
||||||
salt.extend_from_slice(ipk).unwrap();
|
salt.extend_from_slice(ipk).unwrap();
|
||||||
|
@ -438,7 +438,7 @@ impl<'a> Case<'a> {
|
||||||
// println!("Sigma3Key: salt: {:x?}, len: {}", salt, salt.len());
|
// println!("Sigma3Key: salt: {:x?}, len: {}", salt, salt.len());
|
||||||
|
|
||||||
crypto::hkdf_sha256(salt.as_slice(), shared_secret, &S3K_INFO, key)
|
crypto::hkdf_sha256(salt.as_slice(), shared_secret, &S3K_INFO, key)
|
||||||
.map_err(|_x| Error::NoSpace)?;
|
.map_err(|_x| ErrorCode::NoSpace)?;
|
||||||
// println!("Sigma3Key: key: {:x?}", key);
|
// println!("Sigma3Key: key: {:x?}", key);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -452,7 +452,7 @@ impl<'a> Case<'a> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
const S2K_INFO: [u8; 6] = [0x53, 0x69, 0x67, 0x6d, 0x61, 0x32];
|
const S2K_INFO: [u8; 6] = [0x53, 0x69, 0x67, 0x6d, 0x61, 0x32];
|
||||||
if key.len() < 16 {
|
if key.len() < 16 {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
let mut salt = heapless::Vec::<u8, 256>::new();
|
let mut salt = heapless::Vec::<u8, 256>::new();
|
||||||
salt.extend_from_slice(ipk).unwrap();
|
salt.extend_from_slice(ipk).unwrap();
|
||||||
|
@ -467,7 +467,7 @@ impl<'a> Case<'a> {
|
||||||
// println!("Sigma2Key: salt: {:x?}, len: {}", salt, salt.len());
|
// println!("Sigma2Key: salt: {:x?}, len: {}", salt, salt.len());
|
||||||
|
|
||||||
crypto::hkdf_sha256(salt.as_slice(), &case_session.shared_secret, &S2K_INFO, key)
|
crypto::hkdf_sha256(salt.as_slice(), &case_session.shared_secret, &S2K_INFO, key)
|
||||||
.map_err(|_x| Error::NoSpace)?;
|
.map_err(|_x| ErrorCode::NoSpace)?;
|
||||||
// println!("Sigma2Key: key: {:x?}", key);
|
// println!("Sigma2Key: key: {:x?}", key);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl<'a> SecureChannel<'a> {
|
||||||
|
|
||||||
pub fn handle(&mut self, ctx: &mut ProtoCtx) -> Result<(bool, Option<CloneData>), Error> {
|
pub fn handle(&mut self, ctx: &mut ProtoCtx) -> Result<(bool, Option<CloneData>), Error> {
|
||||||
let proto_opcode: OpCode =
|
let proto_opcode: OpCode =
|
||||||
num::FromPrimitive::from_u8(ctx.rx.get_proto_opcode()).ok_or(Error::Invalid)?;
|
num::FromPrimitive::from_u8(ctx.rx.get_proto_opcode()).ok_or(ErrorCode::Invalid)?;
|
||||||
ctx.tx.set_proto_id(PROTO_ID_SECURE_CHANNEL);
|
ctx.tx.set_proto_id(PROTO_ID_SECURE_CHANNEL);
|
||||||
info!("Received Opcode: {:?}", proto_opcode);
|
info!("Received Opcode: {:?}", proto_opcode);
|
||||||
info!("Received Data:");
|
info!("Received Data:");
|
||||||
|
@ -82,7 +82,7 @@ impl<'a> SecureChannel<'a> {
|
||||||
OpCode::CASESigma3 => self.case.casesigma3_handler(ctx),
|
OpCode::CASESigma3 => self.case.casesigma3_handler(ctx),
|
||||||
_ => {
|
_ => {
|
||||||
error!("OpCode Not Handled: {:?}", proto_opcode);
|
error!("OpCode Not Handled: {:?}", proto_opcode);
|
||||||
Err(Error::InvalidOpcode)
|
Err(ErrorCode::InvalidOpcode.into())
|
||||||
}
|
}
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
|
||||||
|
@ -29,35 +29,35 @@ impl CryptoSpake2 {
|
||||||
|
|
||||||
// Computes w0 from w0s respectively
|
// Computes w0 from w0s respectively
|
||||||
pub fn set_w0_from_w0s(&mut self, _w0s: &[u8]) -> Result<(), Error> {
|
pub fn set_w0_from_w0s(&mut self, _w0s: &[u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_w1_from_w1s(&mut self, _w1s: &[u8]) -> Result<(), Error> {
|
pub fn set_w1_from_w1s(&mut self, _w1s: &[u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_w0(&mut self, _w0: &[u8]) -> Result<(), Error> {
|
pub fn set_w0(&mut self, _w0: &[u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_w1(&mut self, _w1: &[u8]) -> Result<(), Error> {
|
pub fn set_w1(&mut self, _w1: &[u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set_L(&mut self, _l: &[u8]) -> Result<(), Error> {
|
pub fn set_L(&mut self, _l: &[u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn set_L_from_w1s(&mut self, _w1s: &[u8]) -> Result<(), Error> {
|
pub fn set_L_from_w1s(&mut self, _w1s: &[u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn get_pB(&mut self, _pB: &mut [u8]) -> Result<(), Error> {
|
pub fn get_pB(&mut self, _pB: &mut [u8]) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -68,6 +68,6 @@ impl CryptoSpake2 {
|
||||||
_pB: &[u8],
|
_pB: &[u8],
|
||||||
_out: &mut [u8],
|
_out: &mut [u8],
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use core::ops::{Mul, Sub};
|
use core::ops::{Mul, Sub};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
@ -150,7 +150,7 @@ impl CryptoSpake2 {
|
||||||
let pB_internal = pB_internal.as_slice();
|
let pB_internal = pB_internal.as_slice();
|
||||||
if pB_internal.len() != pB.len() {
|
if pB_internal.len() != pB.len() {
|
||||||
error!("pB length mismatch");
|
error!("pB length mismatch");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
pB.copy_from_slice(pB_internal);
|
pB.copy_from_slice(pB_internal);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
@ -158,7 +158,7 @@ impl CryptoSpake2 {
|
||||||
let pB_internal = pB_internal.as_slice();
|
let pB_internal = pB_internal.as_slice();
|
||||||
if pB_internal.len() != pB.len() {
|
if pB_internal.len() != pB.len() {
|
||||||
error!("pB length mismatch");
|
error!("pB length mismatch");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
pB.copy_from_slice(pB_internal);
|
pB.copy_from_slice(pB_internal);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -23,10 +23,10 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
crypto,
|
crypto,
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
mdns::{MdnsMgr, ServiceMode},
|
mdns::{MdnsMgr, ServiceMode},
|
||||||
secure_channel::common::OpCode,
|
secure_channel::common::OpCode,
|
||||||
tlv::{self, get_root_node_struct, FromTLV, OctetStr, TLVElement, TLVWriter, TagType, ToTLV},
|
tlv::{self, get_root_node_struct, FromTLV, OctetStr, TLVWriter, TagType, ToTLV},
|
||||||
transport::{
|
transport::{
|
||||||
exchange::ExchangeCtx,
|
exchange::ExchangeCtx,
|
||||||
network::Address,
|
network::Address,
|
||||||
|
@ -176,7 +176,7 @@ impl PakeState {
|
||||||
if let PakeState::InProgress(s) = new {
|
if let PakeState::InProgress(s) = new {
|
||||||
Ok(s)
|
Ok(s)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidSignature)
|
Err(ErrorCode::InvalidSignature.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ impl PakeState {
|
||||||
fn take_sess_data(&mut self, exch_ctx: &ExchangeCtx) -> Result<SessionData, Error> {
|
fn take_sess_data(&mut self, exch_ctx: &ExchangeCtx) -> Result<SessionData, Error> {
|
||||||
let sd = self.take()?;
|
let sd = self.take()?;
|
||||||
if sd.exch_id != exch_ctx.exch.get_id() || sd.peer_addr != exch_ctx.sess.get_peer_addr() {
|
if sd.exch_id != exch_ctx.exch.get_id() || sd.peer_addr != exch_ctx.sess.get_peer_addr() {
|
||||||
Err(Error::InvalidState)
|
Err(ErrorCode::InvalidState.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(sd)
|
Ok(sd)
|
||||||
}
|
}
|
||||||
|
@ -240,10 +240,10 @@ impl Pake {
|
||||||
|
|
||||||
let clone_data = if status_code == SCStatusCodes::SessionEstablishmentSuccess {
|
let clone_data = if status_code == SCStatusCodes::SessionEstablishmentSuccess {
|
||||||
// Get the keys
|
// Get the keys
|
||||||
let ke = ke.ok_or(Error::Invalid)?;
|
let ke = ke.ok_or(ErrorCode::Invalid)?;
|
||||||
let mut session_keys: [u8; 48] = [0; 48];
|
let mut session_keys: [u8; 48] = [0; 48];
|
||||||
crypto::hkdf_sha256(&[], ke, &SPAKE2_SESSION_KEYS_INFO, &mut session_keys)
|
crypto::hkdf_sha256(&[], ke, &SPAKE2_SESSION_KEYS_INFO, &mut session_keys)
|
||||||
.map_err(|_x| Error::NoSpace)?;
|
.map_err(|_x| ErrorCode::NoSpace)?;
|
||||||
|
|
||||||
// Create a session
|
// Create a session
|
||||||
let data = sd.spake2p.get_app_data();
|
let data = sd.spake2p.get_app_data();
|
||||||
|
@ -314,7 +314,7 @@ impl Pake {
|
||||||
let a = PBKDFParamReq::from_tlv(&root)?;
|
let a = PBKDFParamReq::from_tlv(&root)?;
|
||||||
if a.passcode_id != 0 {
|
if a.passcode_id != 0 {
|
||||||
error!("Can't yet handle passcode_id != 0");
|
error!("Can't yet handle passcode_id != 0");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut our_random: [u8; 32] = [0; 32];
|
let mut our_random: [u8; 32] = [0; 32];
|
||||||
|
|
|
@ -25,7 +25,7 @@ use subtle::ConstantTimeEq;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
crypto::{pbkdf2_hmac, Sha256},
|
crypto::{pbkdf2_hmac, Sha256},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{common::SCStatusCodes, crypto::CryptoSpake2};
|
use super::{common::SCStatusCodes, crypto::CryptoSpake2};
|
||||||
|
@ -198,7 +198,7 @@ impl Spake2P {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn handle_pA(&mut self, pA: &[u8], pB: &mut [u8], cB: &mut [u8]) -> Result<(), Error> {
|
pub fn handle_pA(&mut self, pA: &[u8], pB: &mut [u8], cB: &mut [u8]) -> Result<(), Error> {
|
||||||
if self.mode != Spake2Mode::Verifier(Spake2VerifierState::Init) {
|
if self.mode != Spake2Mode::Verifier(Spake2VerifierState::Init) {
|
||||||
return Err(Error::InvalidState);
|
Err(ErrorCode::InvalidState)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(crypto_spake2) = &mut self.crypto_spake2 {
|
if let Some(crypto_spake2) = &mut self.crypto_spake2 {
|
||||||
|
@ -251,13 +251,13 @@ impl Spake2P {
|
||||||
if ke_internal.len() == Ke.len() {
|
if ke_internal.len() == Ke.len() {
|
||||||
Ke.copy_from_slice(ke_internal);
|
Ke.copy_from_slice(ke_internal);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: KcA || KcB = KDF(nil, Ka, "ConfirmationKeys")
|
// Step 2: KcA || KcB = KDF(nil, Ka, "ConfirmationKeys")
|
||||||
let mut KcAKcB: [u8; 32] = [0; 32];
|
let mut KcAKcB: [u8; 32] = [0; 32];
|
||||||
crypto::hkdf_sha256(&[], Ka, &SPAKE2P_KEY_CONFIRM_INFO, &mut KcAKcB)
|
crypto::hkdf_sha256(&[], Ka, &SPAKE2P_KEY_CONFIRM_INFO, &mut KcAKcB)
|
||||||
.map_err(|_x| Error::NoSpace)?;
|
.map_err(|_x| ErrorCode::NoSpace)?;
|
||||||
|
|
||||||
let KcA = &KcAKcB[0..(KcAKcB.len() / 2)];
|
let KcA = &KcAKcB[0..(KcAKcB.len() / 2)];
|
||||||
let KcB = &KcAKcB[(KcAKcB.len() / 2)..];
|
let KcB = &KcAKcB[(KcAKcB.len() / 2)..];
|
||||||
|
|
|
@ -46,6 +46,7 @@ pub fn create_status_report(
|
||||||
proto_code: u16,
|
proto_code: u16,
|
||||||
proto_data: Option<&[u8]>,
|
proto_data: Option<&[u8]>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
proto_tx.reset();
|
||||||
proto_tx.set_proto_id(PROTO_ID_SECURE_CHANNEL);
|
proto_tx.set_proto_id(PROTO_ID_SECURE_CHANNEL);
|
||||||
proto_tx.set_proto_opcode(OpCode::StatusReport as u8);
|
proto_tx.set_proto_opcode(OpCode::StatusReport as u8);
|
||||||
let wb = proto_tx.get_writebuf()?;
|
let wb = proto_tx.get_writebuf()?;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
@ -284,7 +284,7 @@ fn read_length_value<'a>(
|
||||||
// We'll consume the current offset (len) + the entire string
|
// We'll consume the current offset (len) + the entire string
|
||||||
if length + size_of_length_field > t.left {
|
if length + size_of_length_field > t.left {
|
||||||
// Return Error
|
// Return Error
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
} else {
|
} else {
|
||||||
Ok((
|
Ok((
|
||||||
// return the additional size only
|
// return the additional size only
|
||||||
|
@ -390,14 +390,14 @@ impl<'a> TLVElement<'a> {
|
||||||
pub fn i8(&self) -> Result<i8, Error> {
|
pub fn i8(&self) -> Result<i8, Error> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::S8(a) => Ok(a),
|
ElementType::S8(a) => Ok(a),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn u8(&self) -> Result<u8, Error> {
|
pub fn u8(&self) -> Result<u8, Error> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::U8(a) => Ok(a),
|
ElementType::U8(a) => Ok(a),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ impl<'a> TLVElement<'a> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::U8(a) => Ok(a.into()),
|
ElementType::U8(a) => Ok(a.into()),
|
||||||
ElementType::U16(a) => Ok(a),
|
ElementType::U16(a) => Ok(a),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,7 +414,7 @@ impl<'a> TLVElement<'a> {
|
||||||
ElementType::U8(a) => Ok(a.into()),
|
ElementType::U8(a) => Ok(a.into()),
|
||||||
ElementType::U16(a) => Ok(a.into()),
|
ElementType::U16(a) => Ok(a.into()),
|
||||||
ElementType::U32(a) => Ok(a),
|
ElementType::U32(a) => Ok(a),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ impl<'a> TLVElement<'a> {
|
||||||
ElementType::U16(a) => Ok(a.into()),
|
ElementType::U16(a) => Ok(a.into()),
|
||||||
ElementType::U32(a) => Ok(a.into()),
|
ElementType::U32(a) => Ok(a.into()),
|
||||||
ElementType::U64(a) => Ok(a),
|
ElementType::U64(a) => Ok(a),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,7 +434,7 @@ impl<'a> TLVElement<'a> {
|
||||||
| ElementType::Utf8l(s)
|
| ElementType::Utf8l(s)
|
||||||
| ElementType::Str16l(s)
|
| ElementType::Str16l(s)
|
||||||
| ElementType::Utf16l(s) => Ok(s),
|
| ElementType::Utf16l(s) => Ok(s),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,9 +444,9 @@ impl<'a> TLVElement<'a> {
|
||||||
| ElementType::Utf8l(s)
|
| ElementType::Utf8l(s)
|
||||||
| ElementType::Str16l(s)
|
| ElementType::Str16l(s)
|
||||||
| ElementType::Utf16l(s) => {
|
| ElementType::Utf16l(s) => {
|
||||||
Ok(core::str::from_utf8(s).map_err(|_| Error::InvalidData)?)
|
Ok(core::str::from_utf8(s).map_err(|_| Error::from(ErrorCode::InvalidData))?)
|
||||||
}
|
}
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,48 +454,48 @@ impl<'a> TLVElement<'a> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::False => Ok(false),
|
ElementType::False => Ok(false),
|
||||||
ElementType::True => Ok(true),
|
ElementType::True => Ok(true),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn null(&self) -> Result<(), Error> {
|
pub fn null(&self) -> Result<(), Error> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::Null => Ok(()),
|
ElementType::Null => Ok(()),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn confirm_struct(&self) -> Result<TLVElement<'a>, Error> {
|
pub fn confirm_struct(&self) -> Result<TLVElement<'a>, Error> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::Struct(_) => Ok(*self),
|
ElementType::Struct(_) => Ok(*self),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn confirm_array(&self) -> Result<TLVElement<'a>, Error> {
|
pub fn confirm_array(&self) -> Result<TLVElement<'a>, Error> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::Array(_) => Ok(*self),
|
ElementType::Array(_) => Ok(*self),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn confirm_list(&self) -> Result<TLVElement<'a>, Error> {
|
pub fn confirm_list(&self) -> Result<TLVElement<'a>, Error> {
|
||||||
match self.element_type {
|
match self.element_type {
|
||||||
ElementType::List(_) => Ok(*self),
|
ElementType::List(_) => Ok(*self),
|
||||||
_ => Err(Error::TLVTypeMismatch),
|
_ => Err(ErrorCode::TLVTypeMismatch.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_tag(&self, tag: u32) -> Result<TLVElement<'a>, Error> {
|
pub fn find_tag(&self, tag: u32) -> Result<TLVElement<'a>, Error> {
|
||||||
let match_tag: TagType = TagType::Context(tag as u8);
|
let match_tag: TagType = TagType::Context(tag as u8);
|
||||||
|
|
||||||
let iter = self.enter().ok_or(Error::TLVTypeMismatch)?;
|
let iter = self.enter().ok_or(ErrorCode::TLVTypeMismatch)?;
|
||||||
for a in iter {
|
for a in iter {
|
||||||
if match_tag == a.tag_type {
|
if match_tag == a.tag_type {
|
||||||
return Ok(a);
|
return Ok(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(Error::NoTagFound)
|
Err(ErrorCode::NoTagFound.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tag(&self) -> TagType {
|
pub fn get_tag(&self) -> TagType {
|
||||||
|
@ -721,14 +721,17 @@ impl<'a> Iterator for TLVContainerIterator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_root_node(b: &[u8]) -> Result<TLVElement, Error> {
|
pub fn get_root_node(b: &[u8]) -> Result<TLVElement, Error> {
|
||||||
TLVList::new(b).iter().next().ok_or(Error::InvalidData)
|
Ok(TLVList::new(b)
|
||||||
|
.iter()
|
||||||
|
.next()
|
||||||
|
.ok_or(ErrorCode::InvalidData)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_root_node_struct(b: &[u8]) -> Result<TLVElement, Error> {
|
pub fn get_root_node_struct(b: &[u8]) -> Result<TLVElement, Error> {
|
||||||
TLVList::new(b)
|
TLVList::new(b)
|
||||||
.iter()
|
.iter()
|
||||||
.next()
|
.next()
|
||||||
.ok_or(Error::InvalidData)?
|
.ok_or(ErrorCode::InvalidData)?
|
||||||
.confirm_struct()
|
.confirm_struct()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,7 +739,7 @@ pub fn get_root_node_list(b: &[u8]) -> Result<TLVElement, Error> {
|
||||||
TLVList::new(b)
|
TLVList::new(b)
|
||||||
.iter()
|
.iter()
|
||||||
.next()
|
.next()
|
||||||
.ok_or(Error::InvalidData)?
|
.ok_or(ErrorCode::InvalidData)?
|
||||||
.confirm_list()
|
.confirm_list()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,7 +805,7 @@ mod tests {
|
||||||
get_root_node_list, get_root_node_struct, ElementType, Pointer, TLVElement, TLVList,
|
get_root_node_list, get_root_node_struct, ElementType, Pointer, TLVElement, TLVList,
|
||||||
TagType,
|
TagType,
|
||||||
};
|
};
|
||||||
use crate::error::Error;
|
use crate::error::ErrorCode;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_short_length_tag() {
|
fn test_short_length_tag() {
|
||||||
|
@ -1146,7 +1149,10 @@ mod tests {
|
||||||
element_type: ElementType::U32(1),
|
element_type: ElementType::U32(1),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
assert_eq!(cmd_path.find_tag(3), Err(Error::NoTagFound));
|
assert_eq!(
|
||||||
|
cmd_path.find_tag(3).map_err(|e| e.code()),
|
||||||
|
Err(ErrorCode::NoTagFound)
|
||||||
|
);
|
||||||
|
|
||||||
// This is the variable of the invoke command
|
// This is the variable of the invoke command
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{ElementType, TLVContainerIterator, TLVElement, TLVWriter, TagType};
|
use super::{ElementType, TLVContainerIterator, TLVElement, TLVWriter, TagType};
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use core::slice::Iter;
|
use core::slice::Iter;
|
||||||
use log::error;
|
use log::error;
|
||||||
|
@ -31,7 +31,7 @@ pub trait FromTLV<'a> {
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
Err(Error::TLVNotFound)
|
Err(ErrorCode::TLVNotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,8 @@ impl<'a, T: FromTLV<'a> + Default, const N: usize> FromTLV<'a> for [T; N] {
|
||||||
let mut a = heapless::Vec::<T, N>::new();
|
let mut a = heapless::Vec::<T, N>::new();
|
||||||
if let Some(tlv_iter) = t.enter() {
|
if let Some(tlv_iter) = t.enter() {
|
||||||
for element in tlv_iter {
|
for element in tlv_iter {
|
||||||
a.push(T::from_tlv(&element)?).map_err(|_| Error::NoSpace)?;
|
a.push(T::from_tlv(&element)?)
|
||||||
|
.map_err(|_| ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +54,10 @@ impl<'a, T: FromTLV<'a> + Default, const N: usize> FromTLV<'a> for [T; N] {
|
||||||
// implementation on top of heapless::Vec (to avoid requiring Copy)
|
// implementation on top of heapless::Vec (to avoid requiring Copy)
|
||||||
// Not sure why we actually need that yet, but without it unit tests fail
|
// Not sure why we actually need that yet, but without it unit tests fail
|
||||||
while a.len() < N {
|
while a.len() < N {
|
||||||
a.push(Default::default()).map_err(|_| Error::NoSpace)?;
|
a.push(Default::default()).map_err(|_| ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.into_array().map_err(|_| Error::Invalid)
|
a.into_array().map_err(|_| ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +132,7 @@ impl<'a> UtfStr<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> Result<&str, Error> {
|
pub fn as_str(&self) -> Result<&str, Error> {
|
||||||
core::str::from_utf8(self.0).map_err(|_| Error::Invalid)
|
core::str::from_utf8(self.0).map_err(|_| ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +173,7 @@ impl<'a> ToTLV for OctetStr<'a> {
|
||||||
/// Implements the Owned version of Octet String
|
/// Implements the Owned version of Octet String
|
||||||
impl<const N: usize> FromTLV<'_> for heapless::Vec<u8, N> {
|
impl<const N: usize> FromTLV<'_> for heapless::Vec<u8, N> {
|
||||||
fn from_tlv(t: &TLVElement) -> Result<heapless::Vec<u8, N>, Error> {
|
fn from_tlv(t: &TLVElement) -> Result<heapless::Vec<u8, N>, Error> {
|
||||||
heapless::Vec::from_slice(t.slice()?).map_err(|_| Error::NoSpace)
|
heapless::Vec::from_slice(t.slice()?).map_err(|_| ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +190,7 @@ impl<const N: usize> FromTLV<'_> for heapless::String<N> {
|
||||||
|
|
||||||
string
|
string
|
||||||
.push_str(core::str::from_utf8(t.slice()?)?)
|
.push_str(core::str::from_utf8(t.slice()?)?)
|
||||||
.map_err(|_| Error::NoSpace)?;
|
.map_err(|_| ErrorCode::NoSpace)?;
|
||||||
|
|
||||||
Ok(string)
|
Ok(string)
|
||||||
}
|
}
|
||||||
|
@ -411,7 +412,7 @@ impl<'a> ToTLV for TLVElement<'a> {
|
||||||
ElementType::EndCnt => tw.end_container(),
|
ElementType::EndCnt => tw.end_container(),
|
||||||
_ => {
|
_ => {
|
||||||
error!("ToTLV Not supported");
|
error!("ToTLV Not supported");
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,7 +420,7 @@ impl<'a> ToTLV for TLVElement<'a> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{FromTLV, OctetStr, TLVElement, TLVWriter, TagType, ToTLV};
|
use super::{FromTLV, OctetStr, TLVWriter, TagType, ToTLV};
|
||||||
use crate::{error::Error, tlv::TLVList, utils::writebuf::WriteBuf};
|
use crate::{error::Error, tlv::TLVList, utils::writebuf::WriteBuf};
|
||||||
use matter_macro_derive::{FromTLV, ToTLV};
|
use matter_macro_derive::{FromTLV, ToTLV};
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ impl<'a, 'b> TLVWriter<'a, 'b> {
|
||||||
pub fn str8(&mut self, tag_type: TagType, data: &[u8]) -> Result<(), Error> {
|
pub fn str8(&mut self, tag_type: TagType, data: &[u8]) -> Result<(), Error> {
|
||||||
if data.len() > 256 {
|
if data.len() > 256 {
|
||||||
error!("use str16() instead");
|
error!("use str16() instead");
|
||||||
return Err(Error::Invalid);
|
return Err(ErrorCode::Invalid.into());
|
||||||
}
|
}
|
||||||
self.put_control_tag(tag_type, WriteElementType::Str8l)?;
|
self.put_control_tag(tag_type, WriteElementType::Str8l)?;
|
||||||
self.buf.le_u8(data.len() as u8)?;
|
self.buf.le_u8(data.len() as u8)?;
|
||||||
|
|
|
@ -21,11 +21,10 @@ use core::fmt;
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use log::{error, info, trace};
|
use log::{error, info, trace};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::{Error, ErrorCode};
|
||||||
use crate::interaction_model::core::{ResumeReadReq, ResumeSubscribeReq};
|
use crate::interaction_model::core::{ResumeReadReq, ResumeSubscribeReq};
|
||||||
use crate::secure_channel;
|
use crate::secure_channel;
|
||||||
use crate::secure_channel::case::CaseSession;
|
use crate::secure_channel::case::CaseSession;
|
||||||
use crate::tlv::print_tlv_list;
|
|
||||||
use crate::utils::epoch::Epoch;
|
use crate::utils::epoch::Epoch;
|
||||||
use crate::utils::rand::Rand;
|
use crate::utils::rand::Rand;
|
||||||
|
|
||||||
|
@ -227,7 +226,8 @@ impl Exchange {
|
||||||
tx.get_proto_id(),
|
tx.get_proto_id(),
|
||||||
tx.get_proto_opcode(),
|
tx.get_proto_opcode(),
|
||||||
);
|
);
|
||||||
print_tlv_list(tx.as_slice());
|
|
||||||
|
//print_tlv_list(tx.as_slice());
|
||||||
|
|
||||||
tx.proto.exch_id = self.id;
|
tx.proto.exch_id = self.id;
|
||||||
if self.role == Role::Initiator {
|
if self.role == Role::Initiator {
|
||||||
|
@ -317,10 +317,10 @@ impl ExchangeMgr {
|
||||||
info!("Creating new exchange");
|
info!("Creating new exchange");
|
||||||
let e = Exchange::new(id, sess_idx, role);
|
let e = Exchange::new(id, sess_idx, role);
|
||||||
if exchanges.insert(id, e).is_err() {
|
if exchanges.insert(id, e).is_err() {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::NoSpace);
|
Err(ErrorCode::NoSpace)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,11 +330,11 @@ impl ExchangeMgr {
|
||||||
if result.get_role() == role && sess_idx == result.sess_idx {
|
if result.get_role() == role && sess_idx == result.sess_idx {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoExchange)
|
Err(ErrorCode::NoExchange.into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("This should never happen");
|
error!("This should never happen");
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ impl ExchangeMgr {
|
||||||
|
|
||||||
pub fn send(&mut self, exch_id: u16, tx: &mut Packet) -> Result<bool, Error> {
|
pub fn send(&mut self, exch_id: u16, tx: &mut Packet) -> Result<bool, Error> {
|
||||||
let exchange =
|
let exchange =
|
||||||
ExchangeMgr::_get_with_id(&mut self.exchanges, exch_id).ok_or(Error::NoExchange)?;
|
ExchangeMgr::_get_with_id(&mut self.exchanges, exch_id).ok_or(ErrorCode::NoExchange)?;
|
||||||
let mut session = self.sess_mgr.get_session_handle(exchange.sess_idx);
|
let mut session = self.sess_mgr.get_session_handle(exchange.sess_idx);
|
||||||
exchange.send(tx, &mut session)
|
exchange.send(tx, &mut session)
|
||||||
}
|
}
|
||||||
|
@ -474,7 +474,7 @@ impl fmt::Display for ExchangeMgr {
|
||||||
#[allow(clippy::bool_assert_comparison)]
|
#[allow(clippy::bool_assert_comparison)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::ErrorCode,
|
||||||
transport::{
|
transport::{
|
||||||
network::Address,
|
network::Address,
|
||||||
session::{CloneData, SessionMode},
|
session::{CloneData, SessionMode},
|
||||||
|
@ -532,9 +532,12 @@ mod tests {
|
||||||
let clone_data = get_clone_data(peer_sess_id, local_sess_id);
|
let clone_data = get_clone_data(peer_sess_id, local_sess_id);
|
||||||
match mgr.add_session(&clone_data) {
|
match mgr.add_session(&clone_data) {
|
||||||
Ok(s) => assert_eq!(peer_sess_id, s.get_peer_sess_id()),
|
Ok(s) => assert_eq!(peer_sess_id, s.get_peer_sess_id()),
|
||||||
Err(Error::NoSpace) => break,
|
Err(e) => {
|
||||||
_ => {
|
if e.code() == ErrorCode::NoSpace {
|
||||||
panic!("Couldn't, create session");
|
break;
|
||||||
|
} else {
|
||||||
|
panic!("Could not create sessions");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local_sess_id += 1;
|
local_sess_id += 1;
|
||||||
|
@ -576,7 +579,10 @@ mod tests {
|
||||||
for i in 1..(MAX_SESSIONS + 1) {
|
for i in 1..(MAX_SESSIONS + 1) {
|
||||||
// Now purposefully overflow the sessions by adding another session
|
// Now purposefully overflow the sessions by adding another session
|
||||||
let result = mgr.add_session(&get_clone_data(new_peer_sess_id, new_local_sess_id));
|
let result = mgr.add_session(&get_clone_data(new_peer_sess_id, new_local_sess_id));
|
||||||
assert!(matches!(result, Err(Error::NoSpace)));
|
assert!(matches!(
|
||||||
|
result.map_err(|e| e.code()),
|
||||||
|
Err(ErrorCode::NoSpace)
|
||||||
|
));
|
||||||
|
|
||||||
let mut buf = [0; MAX_TX_BUF_SIZE];
|
let mut buf = [0; MAX_TX_BUF_SIZE];
|
||||||
let tx = &mut Packet::new_tx(&mut buf);
|
let tx = &mut Packet::new_tx(&mut buf);
|
||||||
|
|
|
@ -109,14 +109,18 @@ impl<'r, 'a, 'p> RecvCompletion<'r, 'a, 'p> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => (RecvState::Ack, None),
|
Ok(None) => (RecvState::Ack, None),
|
||||||
Err(Error::Duplicate) => (RecvState::Ack, None),
|
Err(e) => match e.code() {
|
||||||
Err(Error::NoSpace) => (RecvState::EvictSession, None),
|
ErrorCode::Duplicate => (RecvState::Ack, None),
|
||||||
Err(err) => Err(err)?,
|
ErrorCode::NoSpace => (RecvState::EvictSession, None),
|
||||||
|
_ => Err(e)?,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
RecvState::AddSession(clone_data) => match self.mgr.exch_mgr.add_session(&clone_data) {
|
RecvState::AddSession(clone_data) => match self.mgr.exch_mgr.add_session(&clone_data) {
|
||||||
Ok(_) => (RecvState::Ack, None),
|
Ok(_) => (RecvState::Ack, None),
|
||||||
Err(Error::NoSpace) => (RecvState::EvictSession2(clone_data), None),
|
Err(e) => match e.code() {
|
||||||
Err(err) => Err(err)?,
|
ErrorCode::NoSpace => (RecvState::EvictSession2(clone_data), None),
|
||||||
|
_ => Err(e)?,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
RecvState::EvictSession => {
|
RecvState::EvictSession => {
|
||||||
if self.mgr.exch_mgr.evict_session(&mut self.tx)? {
|
if self.mgr.exch_mgr.evict_session(&mut self.tx)? {
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl AckEntry {
|
||||||
ack_timeout,
|
ack_timeout,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ impl ReliableMessage {
|
||||||
if self.retrans.is_some() {
|
if self.retrans.is_some() {
|
||||||
// This indicates there was some existing entry for same sess-id/exch-id, which shouldnt happen
|
// This indicates there was some existing entry for same sess-id/exch-id, which shouldnt happen
|
||||||
error!("Previous retrans entry for this exchange already exists");
|
error!("Previous retrans entry for this exchange already exists");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.retrans = Some(RetransEntry::new(proto_tx.plain.ctr));
|
self.retrans = Some(RetransEntry::new(proto_tx.plain.ctr));
|
||||||
|
@ -135,7 +135,7 @@ impl ReliableMessage {
|
||||||
pub fn recv(&mut self, proto_rx: &Packet, epoch: Epoch) -> Result<(), Error> {
|
pub fn recv(&mut self, proto_rx: &Packet, epoch: Epoch) -> Result<(), Error> {
|
||||||
if proto_rx.proto.is_ack() {
|
if proto_rx.proto.is_ack() {
|
||||||
// Handle received Acks
|
// Handle received Acks
|
||||||
let ack_msg_ctr = proto_rx.proto.get_ack_msg_ctr().ok_or(Error::Invalid)?;
|
let ack_msg_ctr = proto_rx.proto.get_ack_msg_ctr().ok_or(ErrorCode::Invalid)?;
|
||||||
if let Some(entry) = &self.retrans {
|
if let Some(entry) = &self.retrans {
|
||||||
if entry.get_msg_ctr() != ack_msg_ctr {
|
if entry.get_msg_ctr() != ack_msg_ctr {
|
||||||
// TODO: XXX Fix this
|
// TODO: XXX Fix this
|
||||||
|
@ -150,7 +150,7 @@ impl ReliableMessage {
|
||||||
// This indicates there was some existing entry for same sess-id/exch-id, which shouldnt happen
|
// This indicates there was some existing entry for same sess-id/exch-id, which shouldnt happen
|
||||||
// TODO: As per the spec if this happens, we need to send out the previous ACK and note this new ACK
|
// TODO: As per the spec if this happens, we need to send out the previous ACK and note this new ACK
|
||||||
error!("Previous ACK entry for this exchange already exists");
|
error!("Previous ACK entry for this exchange already exists");
|
||||||
return Err(Error::Invalid);
|
Err(ErrorCode::Invalid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ack = Some(AckEntry::new(proto_rx.plain.ctr, epoch)?);
|
self.ack = Some(AckEntry::new(proto_rx.plain.ctr, epoch)?);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
utils::{parsebuf::ParseBuf, writebuf::WriteBuf},
|
utils::{parsebuf::ParseBuf, writebuf::WriteBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ impl<'a> Packet<'a> {
|
||||||
if let Direction::Rx(pbuf, _) = &mut self.data {
|
if let Direction::Rx(pbuf, _) = &mut self.data {
|
||||||
Ok(pbuf)
|
Ok(pbuf)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ impl<'a> Packet<'a> {
|
||||||
if let Direction::Tx(wbuf) = &mut self.data {
|
if let Direction::Tx(wbuf) = &mut self.data {
|
||||||
Ok(wbuf)
|
Ok(wbuf)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +158,10 @@ impl<'a> Packet<'a> {
|
||||||
.decrypt_and_decode(&self.plain, pb, peer_nodeid, dec_key)
|
.decrypt_and_decode(&self.plain, pb, peer_nodeid, dec_key)
|
||||||
} else {
|
} else {
|
||||||
error!("Invalid state for proto_decode");
|
error!("Invalid state for proto_decode");
|
||||||
Err(Error::InvalidState)
|
Err(ErrorCode::InvalidState.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(Error::InvalidState),
|
_ => Err(ErrorCode::InvalidState.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ impl<'a> Packet<'a> {
|
||||||
RxState::Uninit => Ok(false),
|
RxState::Uninit => Ok(false),
|
||||||
_ => Ok(true),
|
_ => Ok(true),
|
||||||
},
|
},
|
||||||
_ => Err(Error::InvalidState),
|
_ => Err(ErrorCode::InvalidState.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,10 +183,10 @@ impl<'a> Packet<'a> {
|
||||||
self.plain.decode(pb)
|
self.plain.decode(pb)
|
||||||
} else {
|
} else {
|
||||||
error!("Invalid state for plain_decode");
|
error!("Invalid state for plain_decode");
|
||||||
Err(Error::InvalidState)
|
Err(ErrorCode::InvalidState.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(Error::InvalidState),
|
_ => Err(ErrorCode::InvalidState.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl PlainHdr {
|
||||||
impl PlainHdr {
|
impl PlainHdr {
|
||||||
// it will have an additional 'message length' field first
|
// it will have an additional 'message length' field first
|
||||||
pub fn decode(&mut self, msg: &mut ParseBuf) -> Result<(), Error> {
|
pub fn decode(&mut self, msg: &mut ParseBuf) -> Result<(), Error> {
|
||||||
self.flags = MsgFlags::from_bits(msg.le_u8()?).ok_or(Error::Invalid)?;
|
self.flags = MsgFlags::from_bits(msg.le_u8()?).ok_or(ErrorCode::Invalid)?;
|
||||||
self.sess_id = msg.le_u16()?;
|
self.sess_id = msg.le_u16()?;
|
||||||
let _sec_flags = msg.le_u8()?;
|
let _sec_flags = msg.le_u8()?;
|
||||||
self.sess_type = if self.sess_id != 0 {
|
self.sess_type = if self.sess_id != 0 {
|
||||||
|
|
|
@ -105,7 +105,7 @@ impl ProtoHdr {
|
||||||
decrypt_in_place(plain_hdr.ctr, peer_nodeid, parsebuf, d)?;
|
decrypt_in_place(plain_hdr.ctr, peer_nodeid, parsebuf, d)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.exch_flags = ExchFlags::from_bits(parsebuf.le_u8()?).ok_or(Error::Invalid)?;
|
self.exch_flags = ExchFlags::from_bits(parsebuf.le_u8()?).ok_or(ErrorCode::Invalid)?;
|
||||||
self.proto_opcode = parsebuf.le_u8()?;
|
self.proto_opcode = parsebuf.le_u8()?;
|
||||||
self.exch_id = parsebuf.le_u16()?;
|
self.exch_id = parsebuf.le_u16()?;
|
||||||
self.proto_id = parsebuf.le_u16()?;
|
self.proto_id = parsebuf.le_u16()?;
|
||||||
|
@ -128,10 +128,10 @@ impl ProtoHdr {
|
||||||
resp_buf.le_u16(self.exch_id)?;
|
resp_buf.le_u16(self.exch_id)?;
|
||||||
resp_buf.le_u16(self.proto_id)?;
|
resp_buf.le_u16(self.proto_id)?;
|
||||||
if self.is_vendor() {
|
if self.is_vendor() {
|
||||||
resp_buf.le_u16(self.proto_vendor_id.ok_or(Error::Invalid)?)?;
|
resp_buf.le_u16(self.proto_vendor_id.ok_or(ErrorCode::Invalid)?)?;
|
||||||
}
|
}
|
||||||
if self.is_ack() {
|
if self.is_ack() {
|
||||||
resp_buf.le_u32(self.ack_msg_ctr.ok_or(Error::Invalid)?)?;
|
resp_buf.le_u32(self.ack_msg_ctr.ok_or(ErrorCode::Invalid)?)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ fn decrypt_in_place(
|
||||||
// If so, we need to handle it cleanly here.
|
// If so, we need to handle it cleanly here.
|
||||||
aad.copy_from_slice(parsed_slice);
|
aad.copy_from_slice(parsed_slice);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::InvalidAAD);
|
Err(ErrorCode::InvalidAAD)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// IV:
|
// IV:
|
||||||
|
|
|
@ -410,7 +410,7 @@ impl SessionMgr {
|
||||||
self.sessions[index] = Some(session);
|
self.sessions[index] = Some(session);
|
||||||
Ok(index)
|
Ok(index)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ impl SessionMgr {
|
||||||
info!("Creating new session");
|
info!("Creating new session");
|
||||||
self.add(peer_addr, peer_nodeid)
|
self.add(peer_addr, peer_nodeid)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NotFound)
|
Err(ErrorCode::NotFound.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,14 +484,14 @@ impl SessionMgr {
|
||||||
let duplicate = session.rx_ctr_state.recv(rx.plain.ctr, is_encrypted);
|
let duplicate = session.rx_ctr_state.recv(rx.plain.ctr, is_encrypted);
|
||||||
if duplicate {
|
if duplicate {
|
||||||
info!("Dropping duplicate packet");
|
info!("Dropping duplicate packet");
|
||||||
Err(Error::Duplicate)
|
Err(ErrorCode::Duplicate.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(sess_index)
|
Ok(sess_index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode(&mut self, rx: &mut Packet) -> Result<(), Error> {
|
pub fn decode(&mut self, rx: &mut Packet) -> Result<(), Error> {
|
||||||
// let network = self.network.as_ref().ok_or(Error::NoNetworkInterface)?;
|
// let network = self.network.as_ref().ok_or(ErrorCode::NoNetworkInterface)?;
|
||||||
|
|
||||||
// let (len, src) = network.recv(rx.as_borrow_slice()).await?;
|
// let (len, src) = network.recv(rx.as_borrow_slice()).await?;
|
||||||
// rx.get_parsebuf()?.set_len(len);
|
// rx.get_parsebuf()?.set_len(len);
|
||||||
|
@ -507,7 +507,7 @@ impl SessionMgr {
|
||||||
pub fn send(&mut self, sess_idx: usize, tx: &mut Packet) -> Result<(), Error> {
|
pub fn send(&mut self, sess_idx: usize, tx: &mut Packet) -> Result<(), Error> {
|
||||||
self.sessions[sess_idx]
|
self.sessions[sess_idx]
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.ok_or(Error::NoSession)?
|
.ok_or(ErrorCode::NoSession)?
|
||||||
.do_send(self.epoch, tx)?;
|
.do_send(self.epoch, tx)?;
|
||||||
|
|
||||||
// let network = self.network.as_ref().ok_or(Error::NoNetworkInterface)?;
|
// let network = self.network.as_ref().ok_or(Error::NoNetworkInterface)?;
|
||||||
|
|
|
@ -53,7 +53,7 @@ impl UdpListener {
|
||||||
|
|
||||||
let (size, addr) = self.socket.recv_from(in_buf).await.map_err(|e| {
|
let (size, addr) = self.socket.recv_from(in_buf).await.map_err(|e| {
|
||||||
warn!("Error on the network: {:?}", e);
|
warn!("Error on the network: {:?}", e);
|
||||||
Error::Network
|
ErrorCode::Network
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
info!("Got packet: {:?} from addr {:?}", &in_buf[..size], addr);
|
info!("Got packet: {:?} from addr {:?}", &in_buf[..size], addr);
|
||||||
|
@ -66,7 +66,7 @@ impl UdpListener {
|
||||||
Address::Udp(addr) => {
|
Address::Udp(addr) => {
|
||||||
let len = self.socket.send_to(out_buf, addr).await.map_err(|e| {
|
let len = self.socket.send_to(out_buf, addr).await.map_err(|e| {
|
||||||
warn!("Error on the network: {:?}", e);
|
warn!("Error on the network: {:?}", e);
|
||||||
Error::Network
|
ErrorCode::Network
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'a> ParseBuf<'a> {
|
||||||
self.left -= size;
|
self.left -= size;
|
||||||
return Ok(tail);
|
return Ok(tail);
|
||||||
}
|
}
|
||||||
Err(Error::TruncatedPacket)
|
Err(ErrorCode::TruncatedPacket.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance(&mut self, len: usize) {
|
fn advance(&mut self, len: usize) {
|
||||||
|
@ -82,7 +82,7 @@ impl<'a> ParseBuf<'a> {
|
||||||
self.advance(size);
|
self.advance(size);
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
Err(Error::TruncatedPacket)
|
Err(ErrorCode::TruncatedPacket.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn le_u8(&mut self) -> Result<u8, Error> {
|
pub fn le_u8(&mut self) -> Result<u8, Error> {
|
||||||
|
|
|
@ -70,9 +70,9 @@ impl<'a> WriteBuf<'a> {
|
||||||
|
|
||||||
pub fn reserve(&mut self, reserve: usize) -> Result<(), Error> {
|
pub fn reserve(&mut self, reserve: usize) -> Result<(), Error> {
|
||||||
if self.end != 0 || self.start != 0 || self.buf_size != self.buf.len() {
|
if self.end != 0 || self.start != 0 || self.buf_size != self.buf.len() {
|
||||||
Err(Error::Invalid)
|
Err(ErrorCode::Invalid.into())
|
||||||
} else if reserve > self.buf_size {
|
} else if reserve > self.buf_size {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
} else {
|
} else {
|
||||||
self.start = reserve;
|
self.start = reserve;
|
||||||
self.end = reserve;
|
self.end = reserve;
|
||||||
|
@ -85,7 +85,7 @@ impl<'a> WriteBuf<'a> {
|
||||||
self.buf_size -= with;
|
self.buf_size -= with;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ impl<'a> WriteBuf<'a> {
|
||||||
self.buf_size += by;
|
self.buf_size += by;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ impl<'a> WriteBuf<'a> {
|
||||||
self.start -= size;
|
self.start -= size;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepend(&mut self, src: &[u8]) -> Result<(), Error> {
|
pub fn prepend(&mut self, src: &[u8]) -> Result<(), Error> {
|
||||||
|
@ -126,7 +126,7 @@ impl<'a> WriteBuf<'a> {
|
||||||
self.end += size;
|
self.end += size;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(Error::NoSpace)
|
Err(ErrorCode::NoSpace.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append(&mut self, src: &[u8]) -> Result<(), Error> {
|
pub fn append(&mut self, src: &[u8]) -> Result<(), Error> {
|
||||||
|
|
|
@ -27,7 +27,7 @@ use matter::{
|
||||||
Cluster, CmdDataEncoder, CmdDataWriter, CmdDetails, Dataver, Handler, Quality,
|
Cluster, CmdDataEncoder, CmdDataWriter, CmdDetails, Dataver, Handler, Quality,
|
||||||
ATTRIBUTE_LIST, FEATURE_MAP,
|
ATTRIBUTE_LIST, FEATURE_MAP,
|
||||||
},
|
},
|
||||||
error::Error,
|
error::{Error, ErrorCode},
|
||||||
interaction_model::{
|
interaction_model::{
|
||||||
core::Transaction,
|
core::Transaction,
|
||||||
messages::ib::{attr_list_write, ListOperation},
|
messages::ib::{attr_list_write, ListOperation},
|
||||||
|
@ -122,7 +122,7 @@ impl TestChecker {
|
||||||
INIT.call_once(|| {
|
INIT.call_once(|| {
|
||||||
G_TEST_CHECKER = Some(Arc::new(Mutex::new(Self::new())));
|
G_TEST_CHECKER = Some(Arc::new(Mutex::new(Self::new())));
|
||||||
});
|
});
|
||||||
Ok(G_TEST_CHECKER.as_ref().ok_or(Error::Invalid)?.clone())
|
Ok(G_TEST_CHECKER.as_ref().ok_or(ErrorCode::Invalid)?.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ impl EchoCluster {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::ResourceExhausted)
|
Err(ErrorCode::ResourceExhausted.into())
|
||||||
}
|
}
|
||||||
ListOperation::EditItem(index) => {
|
ListOperation::EditItem(index) => {
|
||||||
let data = data.u16()?;
|
let data = data.u16()?;
|
||||||
|
@ -243,7 +243,7 @@ impl EchoCluster {
|
||||||
tc.write_list[*index as usize] = Some(data);
|
tc.write_list[*index as usize] = Some(data);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidAction)
|
Err(ErrorCode::InvalidAction.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListOperation::DeleteItem(index) => {
|
ListOperation::DeleteItem(index) => {
|
||||||
|
@ -251,7 +251,7 @@ impl EchoCluster {
|
||||||
tc.write_list[*index as usize] = None;
|
tc.write_list[*index as usize] = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidAction)
|
Err(ErrorCode::InvalidAction.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListOperation::DeleteList => {
|
ListOperation::DeleteList => {
|
||||||
|
|
|
@ -216,7 +216,7 @@ impl<'a> ImEngine<'a> {
|
||||||
epoch: *self.matter.borrow(),
|
epoch: *self.matter.borrow(),
|
||||||
};
|
};
|
||||||
let mut rx_buf = [0; MAX_RX_BUF_SIZE];
|
let mut rx_buf = [0; MAX_RX_BUF_SIZE];
|
||||||
let mut tx_buf = [0; 1450]; // For the long read tests to run unchanged
|
let mut tx_buf = [0; 1440]; // For the long read tests to run unchanged
|
||||||
let mut rx = Packet::new_rx(&mut rx_buf);
|
let mut rx = Packet::new_rx(&mut rx_buf);
|
||||||
let mut tx = Packet::new_tx(&mut tx_buf);
|
let mut tx = Packet::new_tx(&mut tx_buf);
|
||||||
// Create fake rx packet
|
// Create fake rx packet
|
||||||
|
|
|
@ -11,3 +11,4 @@ proc-macro = true
|
||||||
syn = { version = "1", features = ["extra-traits"]}
|
syn = { version = "1", features = ["extra-traits"]}
|
||||||
quote = "1"
|
quote = "1"
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
|
proc-macro-crate = "1.3"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::Span;
|
use proc_macro2::{Ident, Span};
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use syn::Lit::{Int, Str};
|
use syn::Lit::{Int, Str};
|
||||||
use syn::NestedMeta::{Lit, Meta};
|
use syn::NestedMeta::{Lit, Meta};
|
||||||
|
@ -106,6 +106,18 @@ fn parse_tag_val(field: &syn::Field) -> Option<u8> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_crate_name() -> String {
|
||||||
|
let found_crate = proc_macro_crate::crate_name("matter-iot").unwrap_or_else(|err| {
|
||||||
|
eprintln!("Warning: defaulting to `crate` {err}");
|
||||||
|
proc_macro_crate::FoundCrate::Itself
|
||||||
|
});
|
||||||
|
|
||||||
|
match found_crate {
|
||||||
|
proc_macro_crate::FoundCrate::Itself => String::from("crate"),
|
||||||
|
proc_macro_crate::FoundCrate::Name(name) => name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Generate a ToTlv implementation for a structure
|
/// Generate a ToTlv implementation for a structure
|
||||||
fn gen_totlv_for_struct(
|
fn gen_totlv_for_struct(
|
||||||
fields: &syn::FieldsNamed,
|
fields: &syn::FieldsNamed,
|
||||||
|
@ -187,16 +199,18 @@ fn gen_totlv_for_enum(
|
||||||
tag_start += 1;
|
tag_start += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let krate = Ident::new(&get_crate_name(), Span::call_site());
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
impl #generics ToTLV for #enum_name #generics {
|
impl #generics #krate::tlv::ToTLV for #enum_name #generics {
|
||||||
fn to_tlv(&self, tw: &mut TLVWriter, tag_type: TagType) -> Result<(), Error> {
|
fn to_tlv(&self, tw: &mut #krate::tlv::TLVWriter, tag_type: #krate::tlv::TagType) -> Result<(), #krate::error::Error> {
|
||||||
let anchor = tw.get_tail();
|
let anchor = tw.get_tail();
|
||||||
|
|
||||||
if let Err(err) = (|| {
|
if let Err(err) = (|| {
|
||||||
tw.start_struct(tag_type)?;
|
tw.start_struct(tag_type)?;
|
||||||
match self {
|
match self {
|
||||||
#(
|
#(
|
||||||
Self::#variant_names(c) => { c.to_tlv(tw, TagType::Context(#tags))?; },
|
Self::#variant_names(c) => { c.to_tlv(tw, #krate::tlv::TagType::Context(#tags))?; },
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
tw.end_container()
|
tw.end_container()
|
||||||
|
@ -297,14 +311,16 @@ fn gen_fromtlv_for_struct(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let krate = Ident::new(&get_crate_name(), Span::call_site());
|
||||||
|
|
||||||
// Currently we don't use find_tag() because the tags come in sequential
|
// Currently we don't use find_tag() because the tags come in sequential
|
||||||
// order. If ever the tags start coming out of order, we can use find_tag()
|
// order. If ever the tags start coming out of order, we can use find_tag()
|
||||||
// instead
|
// instead
|
||||||
let expanded = if !tlvargs.unordered {
|
let expanded = if !tlvargs.unordered {
|
||||||
quote! {
|
quote! {
|
||||||
impl #generics FromTLV <#lifetime> for #struct_name #generics {
|
impl #generics #krate::tlv::FromTLV <#lifetime> for #struct_name #generics {
|
||||||
fn from_tlv(t: &TLVElement<#lifetime>) -> Result<Self, Error> {
|
fn from_tlv(t: &#krate::tlv::TLVElement<#lifetime>) -> Result<Self, #krate::error::Error> {
|
||||||
let mut t_iter = t.#datatype ()?.enter().ok_or(Error::Invalid)?;
|
let mut t_iter = t.#datatype ()?.enter().ok_or_else(|| #krate::error::Error::new(#krate::error::ErrorCode::Invalid))?;
|
||||||
let mut item = t_iter.next();
|
let mut item = t_iter.next();
|
||||||
#(
|
#(
|
||||||
let #idents = if Some(true) == item.map(|x| x.check_ctx_tag(#tags)) {
|
let #idents = if Some(true) == item.map(|x| x.check_ctx_tag(#tags)) {
|
||||||
|
@ -324,8 +340,8 @@ fn gen_fromtlv_for_struct(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
impl #generics FromTLV <#lifetime> for #struct_name #generics {
|
impl #generics #krate::tlv::FromTLV <#lifetime> for #struct_name #generics {
|
||||||
fn from_tlv(t: &TLVElement<#lifetime>) -> Result<Self, Error> {
|
fn from_tlv(t: &#krate::tlv::TLVElement<#lifetime>) -> Result<Self, #krate::error::Error> {
|
||||||
#(
|
#(
|
||||||
let #idents = if let Ok(s) = t.find_tag(#tags as u32) {
|
let #idents = if let Ok(s) = t.find_tag(#tags as u32) {
|
||||||
#types::from_tlv(&s)
|
#types::from_tlv(&s)
|
||||||
|
@ -375,20 +391,22 @@ fn gen_fromtlv_for_enum(
|
||||||
tag_start += 1;
|
tag_start += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let krate = Ident::new(&get_crate_name(), Span::call_site());
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
impl #generics FromTLV <#lifetime> for #enum_name #generics {
|
impl #generics #krate::tlv::FromTLV <#lifetime> for #enum_name #generics {
|
||||||
fn from_tlv(t: &TLVElement<#lifetime>) -> Result<Self, Error> {
|
fn from_tlv(t: &#krate::tlv::TLVElement<#lifetime>) -> Result<Self, #krate::error::Error> {
|
||||||
let mut t_iter = t.confirm_struct()?.enter().ok_or(Error::Invalid)?;
|
let mut t_iter = t.confirm_struct()?.enter().ok_or_else(|| #krate::error::Error::new(#krate::error::ErrorCode::Invalid))?;
|
||||||
let mut item = t_iter.next().ok_or(Error::Invalid)?;
|
let mut item = t_iter.next().ok_or_else(|| Error::new(#krate::error::ErrorCode::Invalid))?;
|
||||||
if let TagType::Context(tag) = item.get_tag() {
|
if let TagType::Context(tag) = item.get_tag() {
|
||||||
match tag {
|
match tag {
|
||||||
#(
|
#(
|
||||||
#tags => Ok(Self::#variant_names(#types::from_tlv(&item)?)),
|
#tags => Ok(Self::#variant_names(#types::from_tlv(&item)?)),
|
||||||
)*
|
)*
|
||||||
_ => Err(Error::Invalid),
|
_ => Err(#krate::error::Error::new(#krate::error::ErrorCode::Invalid)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(Error::TLVTypeMismatch)
|
Err(#krate::error::Error::new(#krate::error::ErrorCode::TLVTypeMismatch))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue