Expand description
A streaming BER/DER reader for the certificate, CMS and timestamp parsers.
What this is for, and what it deliberately is not: it reads the structure of an encoding and hands back the bytes each element occupies. It does not decide what those elements mean. A schema layer above does that, and keeping the two apart is what lets a signature be checked over the bytes as they arrived rather than over a re-encoding of what somebody understood.
Three things shape the design.
Nothing is copied. Elements borrow from the document and carry the range they occupy in it, so a caller holding one gigabyte does not become a caller holding two.
Nothing recurses. Depth is bounded by a budget the caller sets, not by the thread’s stack, so a deeply nested document is refused rather than fatal.
A refusal to finish is not a verdict about the document. Running out of
budget reports ErrorCode::LimitExceeded, which is distinct from every
code that says the bytes are malformed, because telling somebody their
document is broken when the truth is that this device gave up is a different
statement and a worse one.
use std::sync::Arc;
use structured_asn1::{Parser, Tag, universal};
use structured_asn1::memory::{Memory, MemoryAccount};
// SEQUENCE { INTEGER 1 }
let document = [0x30, 0x03, 0x02, 0x01, 0x01];
let memory = Memory::new(Arc::new(MemoryAccount::new(1024, 1024)));
let parser = Parser::der(memory);
let mut reader = parser.read(&document, 0)?;
let sequence = reader.expect(Tag::constructed(universal::SEQUENCE))?;
let mut inside = reader.enter(&sequence)?;
let integer = inside.expect(Tag::primitive(universal::INTEGER))?;
assert_eq!(integer.contents(), &[0x01]);
// The range the value occupies in the document, for a signature to cover.
assert_eq!(integer.span().start, 2);
assert_eq!(integer.span().length, 3);Re-exports§
pub use error::Error;pub use error::ErrorCode;pub use error::Limit;pub use error::Path;pub use error::Result;pub use length::Encoding;pub use length::Length;pub use limits::Limits;pub use reader::Element;pub use reader::IntegerReading;pub use reader::Parser;pub use reader::Reader;pub use reader::Span;pub use tag::Class;pub use tag::Tag;pub use tag::universal;pub use value::Arcs;pub use value::BitString;pub use value::Integer;pub use value::Oid;pub use value::OwnedOid;
Modules§
- error
- What went wrong, where, and under which element.
- length
- Length octets, in both the definite and the indefinite form.
- limits
- What the caller is willing to spend on one parse.
- memory
- Shared storage accounting for independently owned results.
- reader
- Reading elements in sequence, and descending into the constructed ones.
- tag
- Identifier octets: the class, whether the element is constructed, and the number.
- value
- The contents of primitive elements, read without copying them.