3个不稳定版本
0.5.1 | 2023年3月28日 |
---|---|
0.4.3 | 2022年12月19日 |
0.4.2 |
|
0.4.1 | 2022年12月12日 |
#1515 in 编码
每月下载量
225KB
3.5K SLoC
TPS-MINICBOR
一个针对相对受限的嵌入式系统设计的CBOR实现,其中Serde实现可能并不完全适合。
许可证
tps_minicbor
是MIT许可。请参阅LICENSE。
特性
- 专为需要
#[no_std]
支持的受限嵌入式环境设计。 - 高级编码和解码API使得序列化和反序列化流程更容易正确编写。
- 支持大多数CBOR结构(见限制)
- 所有原始类型(正负整数,tstr,bstr,简单类型,标签,浮点数(包括16位浮点数)。
- 支持数组和映射的任意嵌套,并自动计算正确的项目数。
- 支持标准标签的子集(日期/时间和Unix纪元)。请注意,这些需要可分配器可用。
- 支持与Rust原始类型的转换。
- 自动为整数和浮点数提供首选序列化。
- 在反序列化时支持数组和映射的迭代器和索引。
- 广泛的测试用例,包括RFC8949中所有支持的特性的测试用例。
- 请注意,浮点数+Infinity,NaN和-Infinity总是序列化为f16格式,因为这是最喜欢的表示。反序列化适用于所有情况。
- 支持非首选表示的反序列化。
当前限制
- 不支持规范CBOR
- 不支持数组和映射的首选序列化
- 不支持不定长编码
- 不直接支持大数,十进制分数或大浮点数
测试
您可以通过以下方式运行测试用例
cargotest --features=full
请注意,当前的一个限制是,不能仅通过cargo test单独执行测试,因为特性化不允许这样做。
API的示例
CBOR编码
尽管内存占用小,但CBOR序列化API相当高级,支持数组和映射的任意嵌套。
以下示例是实现IETF正在开发中的实体证明令牌规范草案14中的简单TEE证明。
在CBOR诊断格式中,这表示为
{
/ nonce / 10: h'948f8860d13a463e',
/ UEID / 256: h'0198f50a4ff6c05861c8860d13a638ea',
/ OEMID / 258: 64242, / Private Enterprise Number /
/ security-level / 261: 3, / hardware level security /
/ secure-boot / 262: true,
/ debug-status / 263: 3, / disabled-permanently /
/ HW version / 260: [ "3.1", 1 ] / Type is multipartnumeric /
}
这以tps_minicbor编码为
fn encode_tee_eat() -> Result<(), CBORError> {
// Encode-decode round trip test
println!("<========================== encode_tee_eat =========================>");
let mut bytes = [0u8; 1024];
let nonce: &[u8] = &[0x94, 0x8f, 0x88, 0x60, 0xd1, 0x3a, 0x46, 0x3e];
let ueid: &[u8] = &[
0x01, 0x98, 0xf5, 0x0a, 0x4f, 0xf6, 0xc0, 0x58, 0x61, 0xc8, 0x86, 0x0d, 0x13,
0xa6, 0x38, 0xea,
];
let mut encoded_cbor = CBORBuilder::new(&mut bytes);
encoded_cbor.insert(&map(|buff| {
buff.insert_key_value(&10, &nonce)?
.insert_key_value(&256, &ueid)?
.insert_key_value(&258, &64242)?
.insert_key_value(&261, &3)?
.insert_key_value(&262, &true)?
.insert_key_value(&263, &3)?
.insert_key_value(&260, &array(|buf| buf.insert(&"3.1")?.insert(&1)))
}))?;
// do_something_with(encoded_cbor.encoded()?);
Ok(())
}
唯一需要手动操作的工作是将bstr
值转换为合适的引用。
CBOR解码
以下示例展示了解码上述生成的有效载荷的一种方法。
fn decode_tee_eat() -> Result<(), CBORError> {
let mut input: &[u8] = &[
167, 10, 72, 148, 143, 136, 96, 209, 58, 70, 62, 25, 1, 0, 80, 1, 152, 245,
10, 79, 246, 192, 88, 97, 200, 134, 13, 19, 166, 56, 234, 25, 1, 2, 25, 250,
242, 25, 1, 5, 3, 25, 1, 6, 245, 25, 1, 7, 3, 25, 1, 4, 130, 99, 51, 46,
49, 1,
];
let mut nonce = None;
let mut ueid = None;
let mut oemid = None;
let mut sec_level = None;
let mut sec_boot = None;
let mut debug_state = None;
let mut hw_ver_int = None;
let mut decoder = CBORDecoder::from_slice(&mut input);
decoder.decode_with(is_map(), |cbor| {
if let CBOR::Map(map) = cbor {
nonce = map.get_int(10);
ueid = map.get_int(256);
oemid = map.get_int(258);
sec_level = map.get_int(261);
sec_boot = map.get_int(262);
debug_state = map.get_int(263);
if let Some(CBOR::Array(ab)) = map.get_int(260) {
hw_ver_int = match ab.index(1) {
None => None,
Some(CBOR::UInt(vi)) => Some(vi.clone()),
_ => None
};
}
}
Ok(())
})?;
Ok(())
}
示例
解码
decode
示例是低级解码API使用的一个非常短的样本。
要运行示例,从tps_minicbor
的顶层目录开始
cargo run --example decode --features=full
预期的输出是
v1 = Ok(1000), v2 = Ok(1000), v3 = Ok(1000), v4 = Err(OutOfRange)
r1 = UInt(1000), e = Some(Eof)
Value: UInt(1000)
trivial_cose
trivial_cose
示例是实现RFC9052附录C.2.1中的COSE_Sign1
单签名示例的实现。密钥、待签消息和加密配置的其他方面均硬编码到附录中的值。
虽然这个示例被称为trivial_cose
,因为它只实现了最简单的COSE示例,但它确实是一个如何编码和解码中等复杂CBOR结构的良好示例。所有输入和输出都与示例精确对应,这归功于签名中使用的确定性ECDSA。
该代码还作为使用Rust加密特性执行ECDSA的简单示例,这是现实中示例很少的情况。
注意:用于ECDSA的p256 crate尚未经过审计。请参阅p256 crate中的警告,并在生产中使用之前自行进行尽职调查。
要运行示例,从tps_minicbor
的顶层目录开始
cargo run --example trivial_cose --features=full
预期的输出是
To be signed 846a5369676e61747572653143a101264054546869732069732074686520636f6e74656e742e
Signature 8eb33e4ca31d1c465ab05aac34cc6b23d58fef5c083106c4d25a91aef0b0117e2af9a291aa32e14ab834dc56ed2a223444547e01f11d3b0916e5a4c345cacb36
Output d28443a10126a10242313154546869732069732074686520636f6e74656e742e58408eb33e4ca31d1c465ab05aac34cc6b23d58fef5c083106c4d25a91aef0b0117e2af9a291aa32e14ab834dc56ed2a223444547e01f11d3b0916e5a4c345cacb36
18( [
h'a10126' ,
{
2 : h'3131' ,
}
,
h'546869732069732074686520636f6e74656e742e' ,
h'8eb33e4ca31d1c465ab05aac34cc6b23d58fef5c083106c4d25a91aef0b0117e2af9a291aa32e14ab834dc56ed2a223444547e01f11d3b0916e5a4c345cacb36' ,
],
)
To be verified 846a5369676e61747572653143a101264054546869732069732074686520636f6e74656e742e
Verification succeeded: message content [84, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 99, 111, 110, 116, 101, 110, 116, 46]
依赖项
~3.5MB
~77K SLoC