1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! 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);
//! # Ok::<(), structured_asn1::Error>(())
//! ```
extern crate alloc;
pub use ;
pub use ;
pub use Limits;
pub use ;
pub use ;
pub use ;
pub