{"id":26794625,"url":"https://github.com/rusticata/der-parser","last_synced_at":"2025-05-15T08:06:17.378Z","repository":{"id":11744775,"uuid":"70425563","full_name":"rusticata/der-parser","owner":"rusticata","description":"BER/DER parser written in pure Rust. Fast, zero-copy, safe.","archived":false,"fork":false,"pushed_at":"2025-03-18T04:10:42.000Z","size":771,"stargazers_count":88,"open_issues_count":7,"forks_count":28,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-31T16:57:14.178Z","etag":null,"topics":["asn1","ber","der","der-parser","parse","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rusticata.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-09T19:29:01.000Z","updated_at":"2025-03-27T20:00:01.000Z","dependencies_parsed_at":"2024-04-04T10:26:25.456Z","dependency_job_id":"de1c4431-256f-49fb-95f8-672c6f9f8907","html_url":"https://github.com/rusticata/der-parser","commit_stats":{"total_commits":485,"total_committers":19,"mean_commits":"25.526315789473685","dds":"0.12989690721649483","last_synced_commit":"2493f174003e1e0a253c3574ba8ba6d10626c4bf"},"previous_names":[],"tags_count":62,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusticata%2Fder-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusticata%2Fder-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusticata%2Fder-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rusticata%2Fder-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rusticata","download_url":"https://codeload.github.com/rusticata/der-parser/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248397372,"owners_count":21097097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asn1","ber","der","der-parser","parse","rust"],"created_at":"2025-03-29T17:28:19.771Z","updated_at":"2025-04-12T19:41:03.548Z","avatar_url":"https://github.com/rusticata.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- cargo-sync-readme start --\u003e\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT)\n[![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE)\n[![docs.rs](https://docs.rs/der-parser/badge.svg)](https://docs.rs/der-parser)\n[![crates.io](https://img.shields.io/crates/v/der-parser.svg)](https://crates.io/crates/der-parser)\n[![Download numbers](https://img.shields.io/crates/d/der-parser.svg)](https://crates.io/crates/der-parser)\n[![dependency status](https://deps.rs/crate/der-parser/9.0.0/status.svg)](https://deps.rs/crate/der-parser/9.0.0)\n[![Github CI](https://github.com/rusticata/der-parser/actions/workflows/rust.yml/badge.svg)](https://github.com/rusticata/der-parser/actions/workflows/rust.yml)\n[![Minimum rustc version](https://img.shields.io/badge/rustc-1.63.0+-lightgray.svg)](#rust-version-requirements)\n\n# BER/DER Parser\n\nA parser for Basic Encoding Rules (BER [[X.690]]) and Distinguished Encoding Rules(DER\n[[X.690]]), implemented with the [nom](https://github.com/Geal/nom) parser combinator\nframework.\n\nIt is written in pure Rust, fast, and makes extensive use of zero-copy. A lot of care is taken\nto ensure security and safety of this crate, including design (recursion limit, defensive\nprogramming), tests, and fuzzing. It also aims to be panic-free.\n\nHistorically, this parser was intended for DER only, and BER support was added later. This may\nstill reflect on some naming schemes, but has no other consequence: the `BerObject` and\n`DerObject` used in this crate are type aliases, so all functions are compatible.\n\nDER parsing functions have additional constraints verification, however.\n\nSerialization has also been added (see [Serialization](#serialization) )\n\nThe code is available on [Github](https://github.com/rusticata/der-parser)\nand is part of the [Rusticata](https://github.com/rusticata) project.\n\n# BER/DER parsers\n\nBER stands for Basic Encoding Rules, and is defined in [X.690]. It defines a set of rules to\nencode and decode ASN.1 objects in binary.\n\n[X.690] also defines Distinguished Encoding Rules (DER), which is BER with added rules to\nensure canonical and unequivocal binary representation of objects.\n\nThe choice of which one to use is usually guided by the speficication of the data format based\non BER or DER: for example, X.509 uses DER as encoding representation.\n\nSee the related modules for object definitions, functions, and example:\n- [`ber`]: Basic Encoding Rules\n- [`der`]: Distinguished Encoding Rules\n\n## Examples\n\nParse two BER integers (see [BER/DER Integers](#berder-integers)):\n\n```rust\nuse der_parser::ber::parse_ber_integer;\n\nlet bytes = [ 0x02, 0x03, 0x01, 0x00, 0x01,\n              0x02, 0x03, 0x01, 0x00, 0x00,\n];\n\nlet (rem, obj1) = parse_ber_integer(\u0026bytes).expect(\"parsing failed\");\nlet (rem, obj2) = parse_ber_integer(\u0026rem).expect(\"parsing failed\");\n```\n\nParse a DER sequence of integers:\n\n```rust\nuse der_parser::der::{parse_der_integer, parse_der_sequence_of};\n\nlet bytes = [ 0x30, 0x0a,\n              0x02, 0x03, 0x01, 0x00, 0x01,\n              0x02, 0x03, 0x01, 0x00, 0x00,\n];\n\nlet (rem, seq) = parse_der_sequence_of(parse_der_integer)(\u0026bytes)\n                    .expect(\"parsing failed\");\n```\n\nNote: all parsing functions return the remaining (unparsed) bytes and the parsed object, or an\nerror.\n\n# DER parser design\n\nParsing functions are inspired from `nom`, and follow the same interface. The most common\nreturn type is [`BerResult`](https://docs.rs/der-parser/latest/der_parser/error/type.BerResult.html), that stores the remaining bytes and\nparsed [`BerObject`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html), or an error. Reading the nom documentation may\nhelp understanding how to write parsers and use the output.\n\nThere are two different approaches for parsing DER objects: reading the objects recursively as\nlong as the tags are known, or specifying a description of the expected objects (generally from\nthe [ASN.1][X.680] description).\n\nThe first parsing method can be done using the [`parse_ber`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber.html) and\n[`parse_der`](https://docs.rs/der-parser/latest/der_parser/der/fn.parse_der.html) methods.\nIt is useful when decoding an arbitrary DER object.\nHowever, it cannot fully parse all objects, especially those containing IMPLICIT, OPTIONAL, or\nDEFINED BY items.\n\n```rust\nuse der_parser::parse_der;\n\nlet bytes = [ 0x30, 0x0a,\n              0x02, 0x03, 0x01, 0x00, 0x01,\n              0x02, 0x03, 0x01, 0x00, 0x00,\n];\n\nlet parsed = parse_der(\u0026bytes);\n```\n\nThe second (and preferred) parsing method is to specify the expected objects recursively. The\nfollowing functions can be used:\n\n- [`parse_ber_sequence_defined`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_sequence_defined.html) and similar functions\n\nfor sequences and sets variants\n\n- [`parse_ber_tagged_explicit`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_tagged_explicit.html) for tagged explicit\n- [`parse_ber_tagged_implicit`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_tagged_implicit.html) for tagged implicit\n- [`parse_ber_container`](https://docs.rs/der-parser/latest/der_parser/ber/fn.parse_ber_container.html) for generic parsing, etc.\n- DER objects use the `_der_` variants\n\nFor example, to read a BER sequence containing two integers:\n\n```rust\nuse der_parser::ber::*;\nuse der_parser::error::BerResult;\n\nfn localparse_seq(i:\u0026[u8]) -\u003e BerResult {\n    parse_ber_sequence_defined(|data| {\n        let (rem, a) = parse_ber_integer(data)?;\n        let (rem, b) = parse_ber_integer(rem)?;\n        Ok((rem, vec![a, b]))\n    })(i)\n}\n\nlet bytes = [ 0x30, 0x0a,\n              0x02, 0x03, 0x01, 0x00, 0x01,\n              0x02, 0x03, 0x01, 0x00, 0x00,\n];\n\nlet (_, parsed) = localparse_seq(\u0026bytes).expect(\"parsing failed\");\n\nassert_eq!(parsed[0].as_u64(), Ok(65537));\nassert_eq!(parsed[1].as_u64(), Ok(65536));\n```\n\nAll functions return a [`BerResult`](https://docs.rs/der-parser/latest/der_parser/error/type.BerResult.html) object: the parsed\n[`BerObject`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html), an `Incomplete` value, or an error.\n\nNote that this type is also a `Result`, so usual functions (`map`, `unwrap` etc.) are available.\n\n# Notes\n\n## BER/DER Integers\n\nDER integers can be of any size, so it is not possible to store them as simple integers (they\nare stored as raw bytes).\n\nNote that, by default, BER/DER integers are signed. Functions are provided to request reading\nunsigned values, but they will fail if the integer value is negative.\n\nTo get the integer value for all possible integer sign and size, use\n[`BerObject::as_bigint`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html#method.as_bigint)) (requires the `bigint` feature).\n\nTo get a simple value expected to be in a known range, use methods like\n[`BerObject::as_i32`](ber/struct.BerObject.html#method.as_i32)) and\n[`BerObject::as_i64`](ber/struct.BerObject.html#method.as_i64) (or the unsigned versions\n[`BerObject::as_u32`](ber/struct.BerObject.html#method.as_u32) and\n[`BerObject::as_u64`](ber/struct.BerObject.html#method.as_u64)\n),\nwhich will return the value, or an error if the integer is too large (or is negative).\n\n```rust\nuse der_parser::ber::*;\n\nlet data = \u0026[0x02, 0x03, 0x01, 0x00, 0x01];\n\nlet (_, object) = parse_ber_integer(data).expect(\"parsing failed\");\nassert_eq!(object.as_u64(), Ok(65537));\n\n#[cfg(feature = \"bigint\")]\nassert_eq!(object.as_bigint(), Ok(65537.into()))\n```\n\nAccess to the raw value is possible using the `as_slice` method.\n\n## Parsers, combinators, macros\n\nSome parsing tools (for ex for tagged objects) are available in different forms:\n- parsers: (regular) functions that takes input and create an object\n- combinators: functions that takes parsers (or combinators) as input, and return a function\n  (usually, the parser). They are used (combined) as building blocks to create more complex\n  parsers.\n- macros: these are generally previous (historic) versions of parsers, kept for compatibility.\n  They can sometime reduce the amount of code to write, but are hard to debug.\n  Parsers should be preferred when possible.\n\n## Misc Notes\n\n- The DER constraints are verified if using `parse_der`.\n- `BerObject` and `DerObject` are the same objects (type alias). The only difference is the\n  verification of constraints *during parsing*.\n\n## Rust version requirements\n\nThe 9.0 series of `der-parser` requires **Rustc version 1.63 or greater**, based on `asn1-rs`\nand `nom` 7 dependencies.\n\n# Serialization\n\nSupport for encoding BER/DER objects is currently being tested and can be used by activating the `serialize` feature.\nNote that current status is **experimental**.\n\nSee the `ber_encode_*` functions in the [`ber`](https://docs.rs/der-parser/latest/der_parser/ber/index.html) module, and\n[`BerObject::to_vec`](https://docs.rs/der-parser/latest/der_parser/ber/struct.BerObject.html#method.to_vec)\n\n# References\n\n- [[X.680]] Abstract Syntax Notation One (ASN.1): Specification of basic notation.\n- [[X.690]] ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical\n  Encoding Rules (CER) and Distinguished Encoding Rules (DER).\n\n[X.680]: http://www.itu.int/rec/T-REC-X.680/en \"Abstract Syntax Notation One (ASN.1):\n  Specification of basic notation.\"\n[X.690]: https://www.itu.int/rec/T-REC-X.690/en \"ASN.1 encoding rules: Specification of\n  Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules\n  (DER).\"\n\u003c!-- cargo-sync-readme end --\u003e\n\n## Changes\n\nSee `CHANGELOG.md`, and `UPGRADING.md` for instructions for upgrading major versions.\n\n## License\n\nLicensed under either of\n\n * Apache License, Version 2.0\n   ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n * MIT license\n   ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frusticata%2Fder-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frusticata%2Fder-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frusticata%2Fder-parser/lists"}