5 个版本 (破坏性更新)

0.5.0 2021年9月6日
0.4.0 2021年3月25日
0.3.0 2020年11月2日
0.2.0 2020年7月8日
0.1.0 2020年2月18日

过程宏 中排名第1852

Download history 7006/week @ 2024-03-14 7408/week @ 2024-03-21 6388/week @ 2024-03-28 6482/week @ 2024-04-04 8521/week @ 2024-04-11 8516/week @ 2024-04-18 8928/week @ 2024-04-25 8687/week @ 2024-05-02 6100/week @ 2024-05-09 7026/week @ 2024-05-16 6402/week @ 2024-05-23 6455/week @ 2024-05-30 6359/week @ 2024-06-06 6142/week @ 2024-06-13 7556/week @ 2024-06-20 6037/week @ 2024-06-27

每月下载量 27,293

MIT/Apache

5KB
79 代码行

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

BER/DER解析器

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

它完全用Rust编写,速度快,并广泛使用零拷贝。为了确保此crate的安全性,投入了大量精力,包括设计(递归限制、防御性编程)、测试和模糊测试。它还旨在无panic。

历史上,此解析器最初旨在仅用于DER,后来添加了对BER的支持。这可能会在一些命名方案中反映出来,但不会有其他后果:在此crate中使用的 BerObjectDerObject 是类型别名,因此所有函数都是兼容的。

DER解析函数还有额外的约束验证。

还添加了序列化(见序列化

代码在Github上可用,并是Rusticata项目的一部分。

BER/DER解析器

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

X.690还定义了区分编码规则(DER),它是添加了规则以确保对象在二进制中表示为规范且明确的BER。

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

请参阅相关模块以了解对象定义、函数和示例

  • [ber]: 基本编码规则
  • [der]: 区分编码规则

示例

解析两个BER整数(见 BER/DER 整数

use der_parser::ber::parse_ber_integer;

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

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

解析DER整数序列

use der_parser::der::{parse_der_integer, parse_der_sequence_of};

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

let (rem, seq) = parse_der_sequence_of(parse_der_integer)(&bytes)
                    .expect("parsing failed");

注意:所有解析函数返回剩余的(未解析的)字节和解析的对象,或者一个错误。

DER解析器设计

解析函数灵感来自 nom,并遵循相同的接口。最常用的返回类型是 BerResult,它存储剩余的字节和解析的 BerObject,或者一个错误。阅读nom文档可能有助于理解如何编写解析器和使用输出。

解析DER对象有两种不同的方法:只要知道标签,就递归地读取对象,或者指定预期对象的描述(通常来自ASN.1描述)。

第一种解析方法可以使用 parse_berparse_der 方法完成。当解码任意DER对象时很有用。然而,它不能完全解析所有对象,特别是包含IMPLICIT、OPTIONAL或DEFINED BY项的对象。

use der_parser::parse_der;

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

let parsed = parse_der(&bytes);

第二种(也是首选的)解析方法是递归地指定预期对象。以下函数可以使用

例如,要读取包含两个整数的BER序列

use der_parser::ber::*;
use der_parser::error::BerResult;

fn localparse_seq(i:&[u8]) -> BerResult {
    parse_ber_sequence_defined(|data| {
        let (rem, a) = parse_ber_integer(data)?;
        let (rem, b) = parse_ber_integer(rem)?;
        Ok((rem, vec![a, b]))
    })(i)
}

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

let (_, parsed) = localparse_seq(&bytes).expect("parsing failed");

assert_eq!(parsed[0].as_u64(), Ok(65537));
assert_eq!(parsed[1].as_u64(), Ok(65536));

所有函数返回一个 BerResult 对象:解析的 BerObject、一个 Incomplete 值,或一个错误。

请注意,此类型也是 Result,因此可以使用常规函数(例如 mapunwrap 等)。

备注

BER/DER 整数

DER整数可以是任何大小,因此不能将它们作为简单的整数存储(它们作为原始字节存储)。

请注意,默认情况下,BER/DER整数是带符号的。提供了函数来请求读取无符号值,但如果整数值为负,它们将失败。

要获取所有可能的整数符号和大小的整数值,请使用 BerObject::as_bigint(需要 bigint 功能)。

要获取一个预期在已知范围内的简单值,可以使用类似的方法,例如 BerObject::as_i32BerObject::as_i64(或无符号版本 BerObject::as_u32BerObject::as_u64),它们将返回值或错误(如果整数过大或为负数)。

use der_parser::ber::*;

let data = &[0x02, 0x03, 0x01, 0x00, 0x01];

let (_, object) = parse_ber_integer(data).expect("parsing failed");
assert_eq!(object.as_u64(), Ok(65537));

#[cfg(feature = "bigint")]
assert_eq!(object.as_bigint(), Ok(65537.into()))

可以使用 as_slice 方法访问原始值。

解析器、组合器、宏

一些解析工具(例如标记对象)以不同的形式提供

  • 解析器:(常规)接受输入并创建对象的函数
  • 组合器:接受解析器(或组合器)作为输入的函数,并返回一个函数(通常是解析器)。它们用作构建块(组合)以创建更复杂的解析器。
  • 宏:这些通常是解析器的先前(历史)版本,保留以供兼容性使用。它们有时可以减少编写代码的数量,但很难调试。如果可能,应优先考虑解析器。

其他注意事项

  • 如果使用 parse_der,则验证 DER 约束。
  • BerObjectDerObject 是相同的对象(类型别名)。唯一的区别是在解析期间验证约束。

Rust 版本要求

der-parser 的 9.0 系列要求 Rustc 版本 1.63 或更高,基于 asn1-rsnom 7 依赖项。

序列化

目前正在测试对 BER/DER 对象的编码支持,可以通过激活 serialize 功能来使用。请注意,当前状态是 实验性的

请参阅 ber 模块中的 ber_encode_* 函数,以及 BerObject::to_vec

参考

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

基本编码规则(BER)、规范编码规则(CER)和选择编码规则(DER)。

变更

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

许可证

根据您的选择,许可协议为

贡献

除非您明确声明,否则您有意提交的任何贡献,根据 Apache-2.0 许可证的定义,都应按照上述方式双重许可,不附加任何额外条款或条件。

依赖项

~2MB
~45K SLoC