#编码规则 #BER-DER #ASN-1 #NOM #BER #DER

不依赖std asn1-rs

ASN.1 BER/DER 数据的解析器/编码器

13个版本

0.6.2 2024年7月31日
0.6.1 2024年2月27日
0.5.2 2023年3月7日
0.5.1 2022年6月20日
0.2.0 2021年7月20日

#145解析器实现

Download history 208075/week @ 2024-05-03 225671/week @ 2024-05-10 248305/week @ 2024-05-17 253049/week @ 2024-05-24 272648/week @ 2024-05-31 257253/week @ 2024-06-07 244441/week @ 2024-06-14 272787/week @ 2024-06-21 244880/week @ 2024-06-28 269958/week @ 2024-07-05 308545/week @ 2024-07-12 331111/week @ 2024-07-19 313171/week @ 2024-07-26 337735/week @ 2024-08-02 365168/week @ 2024-08-09 313489/week @ 2024-08-16

1,390,819 每月下载量
用于 1,015 个crate(14 个直接)

MIT/Apache

320KB
7K SLoC

License: MIT Apache License 2.0 docs.rs crates.io Download numbers Github CI Minimum rustc version

BER/DER 解析器/编码器

一套用于基本编码规则(BER [X.690]) 和区分编码规则(DER [X.690]) 格式的解析器/编码器,使用 nom 解析器组合框架实现。

它完全用Rust编写,速度快,并且大量使用零拷贝。对安全性和安全性进行了大量关注,包括设计(递归限制、防御性编程)、测试和模糊测试。它还旨在无panic。

该crate是der-parser的重写,旨在提供一个更面向数据的API,并添加对序列化的通用支持。

许多想法借鉴了crypto/utils/der crate(如Any/TryFrom/FromDer机制),进行了修改并合并到通用的BER/DER crate中。感谢Tony Arcieri编写原始crate。

BER/DER解析器

BER代表基本编码规则,由 [X.690] 定义。它定义了一套规则来编码和解码二进制中的ASN.1 [X.680] 对象。

[X.690] 还定义了区分编码规则(DER),它是BER,增加了规则以确保对象的规范和明确的二进制表示。

选择使用哪一个通常由基于BER或DER的数据格式规范指导:例如,X.509使用DER作为编码表示。

解析的主要特征是FromBerFromDer特性。这些特性提供了解析二进制输入的方法,并返回剩余的(未解析的)字节和解析对象,或者一个错误。

解析器遵循nom的接口,而ParseResult对象是nom::IResult的专用版本。这意味着大多数nom组合器(如mapmany0等)可以组合使用该包的对象和方法。阅读nom文档可能有助于理解如何编写和组合解析器以及使用输出。

最低支持的Rust版本: 1.63.0

食谱

有关更多示例和食谱,请参阅doc::recipesdoc::derive

有关调试解析器的建议和工具,请参阅doc::debug

示例

解析2个BER整数

use asn1_rs::{Integer, FromBer};

let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,
];

let (rem, obj1) = Integer::from_ber(&bytes).expect("parsing failed");
let (rem, obj2) = Integer::from_ber(&bytes).expect("parsing failed");

assert_eq!(obj1, Integer::from_u32(65537));

在上面的示例中,使用了泛型Integer类型。此类型可以包含任意大小的整数,但不提供简单的API来操作这些数字。

在大多数情况下,整数要么有限制,要么预期可以适合原始类型。要获取简单值,只需使用原始类型上的from_ber/from_der方法即可。

use asn1_rs::FromBer;

let bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,
              0x02, 0x03, 0x01, 0x00, 0x00,
];

let (rem, obj1) = u32::from_ber(&bytes).expect("parsing failed");
let (rem, obj2) = u32::from_ber(&rem).expect("parsing failed");

assert_eq!(obj1, 65537);
assert_eq!(obj2, 65536);

如果解析成功,但整数无法适合预期的类型,该方法将返回一个IntegerTooLarge错误。

BER/DER编码器

BER/DER编码与解码是对称的,使用ToBerToDer特性。这些特性提供了将编码内容写入具有io::Write特质的对象的方法,或者返回一个包含编码数据的分配的Vec<u8>。如果序列化失败,则返回一个错误。

示例

写入2个BER整数

use asn1_rs::{Integer, ToDer};

let mut writer = Vec::new();

let obj1 = Integer::from_u32(65537);
let obj2 = Integer::from_u32(65536);

let _ = obj1.write_der(&mut writer).expect("serialization failed");
let _ = obj2.write_der(&mut writer).expect("serialization failed");

let bytes = &[ 0x02, 0x03, 0x01, 0x00, 0x01,
               0x02, 0x03, 0x01, 0x00, 0x00,
];
assert_eq!(&writer, bytes);

FromBer/FromDer类似,也实现了对原始类型的序列化方法。

use asn1_rs::ToDer;

let mut writer = Vec::new();

let _ = 65537.write_der(&mut writer).expect("serialization failed");
let _ = 65536.write_der(&mut writer).expect("serialization failed");

let bytes = &[ 0x02, 0x03, 0x01, 0x00, 0x01,
               0x02, 0x03, 0x01, 0x00, 0x00,
];
assert_eq!(&writer, bytes);

如果解析成功,但整数无法适合预期的类型,该方法将返回一个IntegerTooLarge错误。

更改

请参阅CHANGELOG.md

参考

  • [X.680] 抽象语法符号一(ASN.1):基本符号的规范。
  • [X.690] ASN.1编码规则:基本编码规则(BER)、规范编码规则(CER)和区分编码规则(DER)的规范。

更改

有关升级主版本的说明,请参阅CHANGELOG.mdUPGRADING.md

许可证

根据您的选择,许可如下:

贡献

除非您明确声明,否则根据Apache-2.0许可证定义的,您有意提交以包含在作品中的任何贡献,均应双授权,没有任何附加条款或条件。

依赖项

~1–12MB
~92K SLoC