#asn-1 #codec #serialization #deserialize #no-panic

no-std asn1_der

此包提供了一个 ASN.1-DER 编解码器

21 个版本

0.7.6 2023年4月6日
0.7.5 2021年10月5日
0.7.4 2021年3月18日
0.7.2 2020年10月28日
0.5.4 2018年6月1日

#159 in 编码

Download history 24058/week @ 2024-04-23 25473/week @ 2024-04-30 25444/week @ 2024-05-07 24594/week @ 2024-05-14 22530/week @ 2024-05-21 20374/week @ 2024-05-28 17475/week @ 2024-06-04 24146/week @ 2024-06-11 16148/week @ 2024-06-18 16499/week @ 2024-06-25 14245/week @ 2024-07-02 16489/week @ 2024-07-09 20958/week @ 2024-07-16 20024/week @ 2024-07-23 18629/week @ 2024-07-30 19767/week @ 2024-08-06

83,415 每月下载量
用于 336 个包 (12 直接使用)

BSD-2-Clause OR MIT

61KB
1K SLoC

docs.rs License BSD-2-Clause License MIT crates.io Download numbers AppVeyor CI dependency status

asn1_der

欢迎使用 asn1_der 🎉

此包提供了一个基本兼容 no_std无 panic零拷贝 的 DER 实现。它旨在可靠且足够快,而不变得太大或牺牲太多舒适度。为此,asn1_der 广泛使用了 no-panic 包,并提供了基于切片的对象视图以避免分配和不必要的复制。

示例

use asn1_der::{
    DerObject,
    typed::{ DerEncodable, DerDecodable }
};

fn main() {
    /// An ASN.1-DER encoded integer `7`
    const INT7: &'static[u8] = b"\x02\x01\x07";

    // Decode an arbitrary DER object
    let object = DerObject::decode(INT7).expect("Failed to decode object");

    // Encode an arbitrary DER object
    let mut encoded_object = Vec::new();
    object.encode(&mut encoded_object).expect("Failed to encode object");

    // Decode a `u8`
    let number = u8::decode(INT7).expect("Failed to decode number");
    assert_eq!(number, 7);

    // Encode a new `u8`
    let mut encoded_number = Vec::new();
    7u8.encode(&mut encoded_number).expect("Failed to encode number");
}

有关通过 derive (序列化和反序列化) 结构体和类似类型的信息,请参阅 serde_asn1_der

类型实现

还有一些针对原生 Rust 类型等效物的直接 DerDecodable/DerEncodable 实现

  • ASN.1 的 BOOLEAN 类型作为 Rust 的 bool
  • ASN.1 的 INTEGER 类型作为 Rust 的 [u8u16u32u64u128usize]
  • ASN.1 的 NULL 类型可以是 ()Option::None(允许编码可选值)
  • ASN.1 的 OctetString 类型作为 Vec<u8>
  • ASN.1 的 SEQUENCE 类型作为 SequenceVec(Vec<T>)
  • ASN.1的UTF8String类型作为String

无恐慌

asn1_der设计得尽可能无恐慌。为此,几乎所有函数都被标记为#[no_panic],这迫使编译器证明函数在给定情况下不会发生恐慌。然而,由于no_panic可能导致大量误报,它目前仅在CI测试中使用,并且在正常构建中默认禁用。如果您想使用带有no_panic的功能,可以通过指定no_panic功能来实现。

无恐慌不涵盖的内容

重要的是要知道no_panic并不是万能的,它不能解决在这个crate中可能发生的某些类型的错误。这特别包括:

  • 动态内存分配错误:由于无法预测内存分配错误,需要动态内存分配的所有内容都与no_panic互斥,如果启用no_panic,则将省略。

    这个crate可能在下述情况下分配内存:

    • 在向动态分配的sink(例如Vec<u8>VecBacking(Vec<u8>))写入时
    • 解码原生拥有类型,例如Vec<u8>SequenceVec(Vec<T>)String
    • 在错误传播过程中

    如果编译这个crate时未启用std,它本身不会直接执行任何动态内存分配 – 然而,传递给这个crate的外部实现可能仍然会分配内存并失败(例如,自定义Sink实现)。

  • 栈溢出:由于栈大小在编译时未必已知,因此无法预测栈溢出错误,例如由递归引起的。

  • 调用abort或类似函数:由于调用abort或类似函数不会触发栈回溯,因此也无法由no_panic检测。**这也意味着,如果构建配置中使用了panic = "abort",则no_panic不起作用**。

    这个crate本身永远不会直接调用abort

由于上述限制,以下函数与no_panic互斥,并在设置no_panic时被禁用

  • 错误堆栈/传播(如果使用no_panic编译,则propagate是一个无操作)
  • 字节向量(impl Sink for Vec<u8>)的接收器实现
  • VecBacking(Vec<u8>) 类型
  • 使用 Vec<u8> 的本地 OctetString 类型(impl<'a> DerDecodable<'a> for Vec<u8>impl DerEncodable for Vec<u8>
  • 基于 Vec 的本地序列类型包装器 SequenceVec
  • 基于 String 的本地 Utf8String 类型(impl<'a> DerDecodable<'a> for Stringimpl DerEncodable for String

零拷贝

该软件包被设计为尽可能实现零拷贝。实际上,这意味着 DerObject 类型以及所有类型视图都是基于底层切片的零拷贝视图。当然,零拷贝并不总是合理的:构造函数不是零拷贝,因为它们在接收器中构造新对象,而本地类型实现不是零拷贝,因为它们要么是 Copy 类型(例如 u128)或者拥有者(例如 String)。

asn1_der_derive 发生了什么?

从版本 0.7.0 开始,asn1_der_derive-crates 已弃用,转而使用 serde_asn1_der。如果您有不能使用 serde 的特定用例,请告诉我;可能不是很难复活 asn1_der_derive 😊

依赖关系

~115KB