yasna/lib.rs
1// Copyright 2016 Masaki Hara
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! A library for reading and writing ASN.1 data.
10//!
11//! # Examples
12//!
13//! ## Encoding/decoding simple data
14//!
15//! A type implementing [`DEREncodable`] can be easily encoded:
16//!
17//! ```
18//! fn main() {
19//! let der = yasna::encode_der(&(10, true));
20//! println!("(10, true) = {:?}", der);
21//! }
22//! ```
23//!
24//! Similarly, a type implementing [`BERDecodable`] can be
25//! easily decoded:
26//!
27//! ```
28//! fn main() {
29//! let asn: (i64, bool) = yasna::decode_der(
30//! &[48, 6, 2, 1, 10, 1, 1, 255]).unwrap();
31//! println!("{:?} = [48, 6, 2, 1, 10, 1, 1, 255]", asn);
32//! }
33//! ```
34//!
35//! ## Encoding/decoding by hand
36//!
37//! The default [`DEREncodable`]/[`BERDecodable`] implementations can't handle
38//! all ASN.1 types. In many cases you have to write your reader/writer
39//! by hand.
40//!
41//! To serialize ASN.1 data, you can use [`construct_der`].
42//!
43//! ```
44//! fn main() {
45//! let der = yasna::construct_der(|writer| {
46//! writer.write_sequence(|writer| {
47//! writer.next().write_i64(10);
48//! writer.next().write_bool(true);
49//! })
50//! });
51//! println!("(10, true) = {:?}", der);
52//! }
53//! ```
54//!
55//! To deserialize ASN.1 data, you can use [`parse_ber`] or [`parse_der`].
56//!
57//! ```
58//! fn main() {
59//! let asn = yasna::parse_der(&[48, 6, 2, 1, 10, 1, 1, 255], |reader| {
60//! reader.read_sequence(|reader| {
61//! let i = reader.next().read_i64()?;
62//! let b = reader.next().read_bool()?;
63//! return Ok((i, b));
64//! })
65//! }).unwrap();
66//! println!("{:?} = [48, 6, 2, 1, 10, 1, 1, 255]", asn);
67//! }
68//! ```
69
70#![forbid(unsafe_code)]
71#![deny(missing_docs)]
72#![no_std]
73
74extern crate alloc;
75#[cfg(any(test, feature = "std"))]
76extern crate std;
77
78pub mod tags;
79pub mod models;
80mod writer;
81mod reader;
82mod deserializer;
83mod serializer;
84
85pub use crate::writer::{construct_der,try_construct_der};
86pub use crate::writer::{construct_der_seq,try_construct_der_seq};
87pub use crate::writer::{DERWriter,DERWriterSeq,DERWriterSet};
88pub use crate::reader::{parse_ber_general,parse_ber,parse_der,BERMode};
89pub use crate::reader::{BERReader,BERReaderSeq,BERReaderSet};
90pub use crate::reader::{ASN1Error,ASN1ErrorKind,ASN1Result};
91pub use crate::deserializer::{BERDecodable,decode_ber_general,decode_ber,decode_der};
92pub use crate::serializer::{DEREncodable,encode_der};
93
94/// A value of the ASN.1 primitive/constructed ("P/C") bit.
95#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
96pub enum PCBit {
97 /// The bit's value is "Primitive"
98 Primitive = 0,
99 /// The bit's value is "Constructed"
100 Constructed = 1,
101}
102
103/// An ASN.1 tag class, used in [`Tag`].
104///
105/// A tag class is one of:
106///
107/// - UNIVERSAL
108/// - APPLICATION
109/// - context specific
110/// - PRIVATE
111#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
112pub enum TagClass {
113 /// The UNIVERSAL tag class
114 Universal = 0,
115 /// The APPLICATION tag class
116 Application = 1,
117 /// The CONTEXT-SPECIFIC tag class
118 ContextSpecific = 2,
119 /// The PRIVATE tag class
120 Private = 3,
121}
122
123const TAG_CLASSES : [TagClass; 4] = [
124 TagClass::Universal,
125 TagClass::Application,
126 TagClass::ContextSpecific,
127 TagClass::Private,
128];
129
130/// An ASN.1 tag.
131///
132/// An ASN.1 tag is a pair of a tag class and a tag number.
133///
134/// - A tag class is one of:
135/// - UNIVERSAL
136/// - APPLICATION
137/// - context specific
138/// - PRIVATE
139/// - A tag number is a nonnegative integer.
140/// In this library, tag numbers are assumed to fit into `u64`.
141#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
142pub struct Tag {
143 /// The tag class
144 pub tag_class: TagClass,
145 /// The tag number
146 pub tag_number: u64,
147}
148
149impl Tag {
150 /// Constructs an APPLICATION tag, namely \[APPLICATION n\].
151 pub fn application(tag_number: u64) -> Tag {
152 return Tag {
153 tag_class: TagClass::Application,
154 tag_number,
155 }
156 }
157 /// Constructs a context specific tag, namely \[n\].
158 pub fn context(tag_number: u64) -> Tag {
159 return Tag {
160 tag_class: TagClass::ContextSpecific,
161 tag_number,
162 }
163 }
164 /// Constructs a PRIVATE tag, namely \[PRIVATE n\].
165 pub fn private(tag_number: u64) -> Tag {
166 return Tag {
167 tag_class: TagClass::Private,
168 tag_number,
169 }
170 }
171}