chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

469
vendor/yasna/src/deserializer/mod.rs vendored Normal file
View File

@@ -0,0 +1,469 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![forbid(missing_docs)]
use alloc::vec::Vec;
use alloc::string::String;
#[cfg(feature = "num-bigint")]
use num_bigint::{BigInt,BigUint};
#[cfg(feature = "bit-vec")]
use bit_vec::BitVec;
use super::{ASN1Result,BERMode,BERReader,parse_ber_general};
use super::models::{ObjectIdentifier,TaggedDerValue};
#[cfg(feature = "time")]
use super::models::{UTCTime,GeneralizedTime};
/// Types decodable in BER.
///
/// # Examples
///
/// ```
/// use yasna;
/// let asn : i64 = yasna::decode_der(&[2, 3, 0, 255, 255]).unwrap();
/// assert_eq!(asn, 65535);
/// ```
///
/// # Limitations
///
/// Rust types don't correspond to ASN.1 types one-to-one. Not all kinds
/// of ASN.1 types can be decoded via default `BERDecodable` implementation.
///
/// If you want to decode ASN.1, you may implement `BERDecodable` for your
/// own types or use [`parse_der`](crate::parse_der)/
/// [`parse_ber`](crate::parse_ber).
///
/// # Default implementations
///
/// - The decoder for `Vec<T>` is implemented as SEQUENCE OF decoder.
/// - `()` as NULL decoder.
/// - Tuples (except `()`) as SEQUENCE decoder.
/// - `Vec<u8>` as OCTETSTRING decoder.
/// - `BitVec` as BITSTRING decoder.
/// - `String` as UTF8String decoder.
/// - `i64`, `u64`, `i32`, `u32`, `i16`, `u16`, `BigInt`, `BigUint`
/// as INTEGER decoder. (`u8` is avoided because of confliction.)
/// - `bool` as BOOLEAN decoder.
/// - `ObjectIdentifier` as OBJECTT IDENTIFIER decoder.
/// - `UTCTime`/`GeneralizedTime` as UTCTime/GeneralizedTime decoder.
pub trait BERDecodable: Sized {
/// Reads an ASN.1 value from `BERReader` and converts it to `Self`.
///
/// # Examples
///
/// ```
/// use yasna::{BERDecodable,BERReader,ASN1Result};
/// struct Entry {
/// name: String,
/// age: i64,
/// }
///
/// impl BERDecodable for Entry {
/// fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
/// reader.read_sequence(|reader| {
/// let name = reader.next().read_visible_string()?;
/// let age = reader.next().read_i64()?;
/// return Ok(Entry {
/// name: name,
/// age: age,
/// });
/// })
/// }
/// }
/// fn main() {
/// let entry : Entry = yasna::decode_der(
/// &[48, 9, 26, 4, 74, 111, 104, 110, 2, 1, 32]).unwrap();
/// assert_eq!(entry.name, "John");
/// assert_eq!(entry.age, 32);
/// }
/// ```
fn decode_ber<'a, 'b>(reader: BERReader<'a, 'b>) -> ASN1Result<Self>;
}
/// Decodes DER/BER-encoded data.
///
/// [`decode_ber`] and [`decode_der`] are shorthands
/// for this function.
pub fn decode_ber_general<T:BERDecodable>(src: &[u8], mode: BERMode)
-> ASN1Result<T> {
parse_ber_general(src, mode, |reader| {
T::decode_ber(reader)
})
}
/// Reads an ASN.1 value from `&[u8]`.
///
/// If you want to accept only DER-encoded data,
/// use [`decode_der`].
///
/// # Examples
///
/// ```
/// use yasna;
/// let asn : i64 = yasna::decode_ber(&[2, 3, 0, 255, 255]).unwrap();
/// assert_eq!(asn, 65535);
/// ```
pub fn decode_ber<T:BERDecodable>(src: &[u8]) -> ASN1Result<T> {
decode_ber_general(src, BERMode::Ber)
}
/// Reads an ASN.1 value from `&[u8]`.
///
/// If you want to decode BER-encoded data in general,
/// use [`decode_ber`].
///
/// # Examples
///
/// ```
/// use yasna;
/// let asn : i64 = yasna::decode_der(&[2, 3, 0, 255, 255]).unwrap();
/// assert_eq!(asn, 65535);
/// ```
pub fn decode_der<T:BERDecodable>(src: &[u8]) -> ASN1Result<T> {
decode_ber_general(src, BERMode::Der)
}
impl<T> BERDecodable for Vec<T> where T: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let mut ret = Vec::new();
loop {
let result = reader.read_optional(|reader| {
T::decode_ber(reader)
})?;
match result {
Some(result) => {
ret.push(result);
},
None => {
break;
}
};
}
return Ok(ret);
})
}
}
impl BERDecodable for i64 {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_i64()
}
}
impl BERDecodable for u64 {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_u64()
}
}
impl BERDecodable for i32 {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_i32()
}
}
impl BERDecodable for u32 {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_u32()
}
}
impl BERDecodable for i16 {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_i16()
}
}
impl BERDecodable for u16 {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_u16()
}
}
#[cfg(feature = "num-bigint")]
impl BERDecodable for BigInt {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_bigint()
}
}
#[cfg(feature = "num-bigint")]
impl BERDecodable for BigUint {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_biguint()
}
}
impl BERDecodable for bool {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_bool()
}
}
#[cfg(feature = "bit-vec")]
impl BERDecodable for BitVec {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_bitvec()
}
}
impl BERDecodable for Vec<u8> {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_bytes()
}
}
impl BERDecodable for String {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_utf8string()
}
}
impl BERDecodable for ObjectIdentifier {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_oid()
}
}
#[cfg(feature = "time")]
impl BERDecodable for UTCTime {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_utctime()
}
}
#[cfg(feature = "time")]
impl BERDecodable for GeneralizedTime {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_generalized_time()
}
}
impl BERDecodable for () {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_null()
}
}
impl<T0> BERDecodable for (T0,)
where T0: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
return Ok((t0,));
})
}
}
impl<T0, T1> BERDecodable for (T0, T1)
where T0: BERDecodable, T1: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
return Ok((t0, t1));
})
}
}
impl<T0, T1, T2> BERDecodable for (T0, T1, T2)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
return Ok((t0, t1, t2));
})
}
}
impl<T0, T1, T2, T3> BERDecodable for (T0, T1, T2, T3)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3));
})
}
}
impl<T0, T1, T2, T3, T4> BERDecodable for (T0, T1, T2, T3, T4)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4));
})
}
}
impl<T0, T1, T2, T3, T4, T5> BERDecodable for (T0, T1, T2, T3, T4, T5)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5));
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6> BERDecodable for (T0, T1, T2, T3, T4, T5, T6)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable,
T6: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
let t6 = T6::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5, t6));
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7> BERDecodable
for (T0, T1, T2, T3, T4, T5, T6, T7)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable,
T6: BERDecodable, T7: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
let t6 = T6::decode_ber(reader.next())?;
let t7 = T7::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5, t6, t7));
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> BERDecodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable,
T6: BERDecodable, T7: BERDecodable, T8: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
let t6 = T6::decode_ber(reader.next())?;
let t7 = T7::decode_ber(reader.next())?;
let t8 = T8::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5, t6, t7, t8));
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> BERDecodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable,
T6: BERDecodable, T7: BERDecodable, T8: BERDecodable,
T9: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
let t6 = T6::decode_ber(reader.next())?;
let t7 = T7::decode_ber(reader.next())?;
let t8 = T8::decode_ber(reader.next())?;
let t9 = T9::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5, t6, t7, t8, t9));
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> BERDecodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable,
T6: BERDecodable, T7: BERDecodable, T8: BERDecodable,
T9: BERDecodable, T10: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
let t6 = T6::decode_ber(reader.next())?;
let t7 = T7::decode_ber(reader.next())?;
let t8 = T8::decode_ber(reader.next())?;
let t9 = T9::decode_ber(reader.next())?;
let t10 = T10::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10));
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> BERDecodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
where T0: BERDecodable, T1: BERDecodable, T2: BERDecodable,
T3: BERDecodable, T4: BERDecodable, T5: BERDecodable,
T6: BERDecodable, T7: BERDecodable, T8: BERDecodable,
T9: BERDecodable, T10: BERDecodable, T11: BERDecodable {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_sequence(|reader| {
let t0 = T0::decode_ber(reader.next())?;
let t1 = T1::decode_ber(reader.next())?;
let t2 = T2::decode_ber(reader.next())?;
let t3 = T3::decode_ber(reader.next())?;
let t4 = T4::decode_ber(reader.next())?;
let t5 = T5::decode_ber(reader.next())?;
let t6 = T6::decode_ber(reader.next())?;
let t7 = T7::decode_ber(reader.next())?;
let t8 = T8::decode_ber(reader.next())?;
let t9 = T9::decode_ber(reader.next())?;
let t10 = T10::decode_ber(reader.next())?;
let t11 = T11::decode_ber(reader.next())?;
return Ok((t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11));
})
}
}
impl BERDecodable for TaggedDerValue {
fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
reader.read_tagged_der()
}
}

171
vendor/yasna/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,171 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A library for reading and writing ASN.1 data.
//!
//! # Examples
//!
//! ## Encoding/decoding simple data
//!
//! A type implementing [`DEREncodable`] can be easily encoded:
//!
//! ```
//! fn main() {
//! let der = yasna::encode_der(&(10, true));
//! println!("(10, true) = {:?}", der);
//! }
//! ```
//!
//! Similarly, a type implementing [`BERDecodable`] can be
//! easily decoded:
//!
//! ```
//! fn main() {
//! let asn: (i64, bool) = yasna::decode_der(
//! &[48, 6, 2, 1, 10, 1, 1, 255]).unwrap();
//! println!("{:?} = [48, 6, 2, 1, 10, 1, 1, 255]", asn);
//! }
//! ```
//!
//! ## Encoding/decoding by hand
//!
//! The default [`DEREncodable`]/[`BERDecodable`] implementations can't handle
//! all ASN.1 types. In many cases you have to write your reader/writer
//! by hand.
//!
//! To serialize ASN.1 data, you can use [`construct_der`].
//!
//! ```
//! fn main() {
//! let der = yasna::construct_der(|writer| {
//! writer.write_sequence(|writer| {
//! writer.next().write_i64(10);
//! writer.next().write_bool(true);
//! })
//! });
//! println!("(10, true) = {:?}", der);
//! }
//! ```
//!
//! To deserialize ASN.1 data, you can use [`parse_ber`] or [`parse_der`].
//!
//! ```
//! fn main() {
//! let asn = yasna::parse_der(&[48, 6, 2, 1, 10, 1, 1, 255], |reader| {
//! reader.read_sequence(|reader| {
//! let i = reader.next().read_i64()?;
//! let b = reader.next().read_bool()?;
//! return Ok((i, b));
//! })
//! }).unwrap();
//! println!("{:?} = [48, 6, 2, 1, 10, 1, 1, 255]", asn);
//! }
//! ```
#![forbid(unsafe_code)]
#![deny(missing_docs)]
#![no_std]
extern crate alloc;
#[cfg(any(test, feature = "std"))]
extern crate std;
pub mod tags;
pub mod models;
mod writer;
mod reader;
mod deserializer;
mod serializer;
pub use crate::writer::{construct_der,try_construct_der};
pub use crate::writer::{construct_der_seq,try_construct_der_seq};
pub use crate::writer::{DERWriter,DERWriterSeq,DERWriterSet};
pub use crate::reader::{parse_ber_general,parse_ber,parse_der,BERMode};
pub use crate::reader::{BERReader,BERReaderSeq,BERReaderSet};
pub use crate::reader::{ASN1Error,ASN1ErrorKind,ASN1Result};
pub use crate::deserializer::{BERDecodable,decode_ber_general,decode_ber,decode_der};
pub use crate::serializer::{DEREncodable,encode_der};
/// A value of the ASN.1 primitive/constructed ("P/C") bit.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum PCBit {
/// The bit's value is "Primitive"
Primitive = 0,
/// The bit's value is "Constructed"
Constructed = 1,
}
/// An ASN.1 tag class, used in [`Tag`].
///
/// A tag class is one of:
///
/// - UNIVERSAL
/// - APPLICATION
/// - context specific
/// - PRIVATE
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum TagClass {
/// The UNIVERSAL tag class
Universal = 0,
/// The APPLICATION tag class
Application = 1,
/// The CONTEXT-SPECIFIC tag class
ContextSpecific = 2,
/// The PRIVATE tag class
Private = 3,
}
const TAG_CLASSES : [TagClass; 4] = [
TagClass::Universal,
TagClass::Application,
TagClass::ContextSpecific,
TagClass::Private,
];
/// An ASN.1 tag.
///
/// An ASN.1 tag is a pair of a tag class and a tag number.
///
/// - A tag class is one of:
/// - UNIVERSAL
/// - APPLICATION
/// - context specific
/// - PRIVATE
/// - A tag number is a nonnegative integer.
/// In this library, tag numbers are assumed to fit into `u64`.
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Tag {
/// The tag class
pub tag_class: TagClass,
/// The tag number
pub tag_number: u64,
}
impl Tag {
/// Constructs an APPLICATION tag, namely \[APPLICATION n\].
pub fn application(tag_number: u64) -> Tag {
return Tag {
tag_class: TagClass::Application,
tag_number,
}
}
/// Constructs a context specific tag, namely \[n\].
pub fn context(tag_number: u64) -> Tag {
return Tag {
tag_class: TagClass::ContextSpecific,
tag_number,
}
}
/// Constructs a PRIVATE tag, namely \[PRIVATE n\].
pub fn private(tag_number: u64) -> Tag {
return Tag {
tag_class: TagClass::Private,
tag_number,
}
}
}

110
vendor/yasna/src/models/der.rs vendored Normal file
View File

@@ -0,0 +1,110 @@
// Copyright 2017 Fortanix, Inc.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use alloc::vec::Vec;
use super::super::{PCBit, Tag};
use super::super::tags::*;
/// Container for a tag and arbitrary DER value.
///
/// When obtained by `BERReader::read_tagged_der` in DER mode,
/// the reader verifies that the payload is actually valid DER.
/// When constructed from bytes, the caller is responsible for
/// providing valid DER.
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct TaggedDerValue {
tag: Tag,
pcbit: PCBit,
value: Vec<u8>,
}
impl TaggedDerValue {
/// Constructs a new `TaggedDerValue` as an octet string
pub fn from_octetstring(bytes: Vec<u8>) -> Self {
TaggedDerValue {
tag: TAG_OCTETSTRING,
pcbit: PCBit::Primitive,
value: bytes,
}
}
/// Constructs a new `TaggedDerValue` from its tag and content
pub fn from_tag_and_bytes(tag: Tag, bytes: Vec<u8>) -> Self {
let pcbit = match tag {
TAG_SEQUENCE | TAG_SET => PCBit::Constructed,
_ => PCBit::Primitive,
};
TaggedDerValue {
tag,
pcbit,
value: bytes,
}
}
/// Constructs a new `TaggedDerValue` from its tag,
/// primitive/constructed bit, and content
pub fn from_tag_pc_and_bytes(tag: Tag, pcbit: PCBit, bytes: Vec<u8>) -> Self {
TaggedDerValue {
tag,
pcbit,
value: bytes,
}
}
/// Returns the tag
pub fn tag(&self) -> Tag {
self.tag
}
/// Returns the primitive/constructed bit
pub fn pcbit(&self) -> PCBit {
self.pcbit
}
/// Returns the value
pub fn value(&self) -> &[u8] {
&self.value
}
/// If the value is something that contains raw bytes,
/// returns its content.
///
/// # Examples
/// ```
/// use yasna::models::TaggedDerValue;
/// let value = TaggedDerValue::from_octetstring(vec![1, 2, 3, 4, 5, 6]);
/// assert!(value.as_bytes() == Some(&[1, 2, 3, 4, 5, 6]));
/// ```
pub fn as_bytes(&self) -> Option<&[u8]> {
match (self.tag, self.pcbit) {
(TAG_BITSTRING, PCBit::Primitive) => {
// First byte of bitstring value is number of unused bits.
// We only accept bitstrings that are multiples of bytes.
if let Some(&0) = self.value.first() {
Some(&self.value[1..])
} else {
None
}
},
(TAG_OCTETSTRING, PCBit::Primitive) => Some(&self.value),
_ => None
}
}
/// If the value is something string-like, returns it as string.
pub fn as_str(&self) -> Option<&str> {
use alloc::str::from_utf8;
match (self.tag, self.pcbit) {
(TAG_IA5STRING, PCBit::Primitive) => from_utf8(&self.value).ok(),
(TAG_PRINTABLESTRING, PCBit::Primitive) => from_utf8(&self.value).ok(),
(TAG_UTF8STRING, PCBit::Primitive) => from_utf8(&self.value).ok(),
_ => None
}
}
}

21
vendor/yasna/src/models/mod.rs vendored Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Provides datatypes which correspond to ASN.1 types.
#![forbid(missing_docs)]
mod oid;
#[cfg(feature = "time")]
mod time;
mod der;
pub use self::oid::{ObjectIdentifier, ParseOidError};
#[cfg(feature = "time")]
pub use self::time::{UTCTime,GeneralizedTime};
pub use self::der::TaggedDerValue;

173
vendor/yasna/src/models/oid.rs vendored Normal file
View File

@@ -0,0 +1,173 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::fmt::{self, Display};
#[cfg(feature = "std")]
use std::error::Error;
use alloc::str::FromStr;
use alloc::vec::Vec;
/// A type that represents object identifiers.
///
/// This is actually a thin wrapper of `Vec<u64>`.
///
/// # Examples
///
/// ```
/// use yasna::models::ObjectIdentifier;
/// let sha384WithRSAEncryption = ObjectIdentifier::from_slice(&
/// [1, 2, 840, 113549, 1, 1, 12]);
/// println!("{}", sha384WithRSAEncryption);
/// ```
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ObjectIdentifier {
components: Vec<u64>,
}
impl ObjectIdentifier {
/// Constructs a new `ObjectIdentifier` from `Vec<u64>`.
///
/// # Examples
///
/// ```
/// use yasna::models::ObjectIdentifier;
/// let pkcs1 = ObjectIdentifier::new(
/// [1, 2, 840, 113549, 1, 1].to_vec());
/// println!("{}", pkcs1);
/// ```
pub fn new(components: Vec<u64>) -> Self {
return ObjectIdentifier {
components,
};
}
/// Constructs a new `ObjectIdentifier` from `&[u64]`.
///
/// # Examples
///
/// ```
/// use yasna::models::ObjectIdentifier;
/// let pkcs1 = ObjectIdentifier::from_slice(&
/// [1, 2, 840, 113549, 1, 1]);
/// println!("{}", pkcs1);
/// ```
pub fn from_slice(components: &[u64]) -> Self {
return ObjectIdentifier {
components: components.to_vec(),
};
}
/// Borrows its internal vector of components.
///
/// # Examples
///
/// ```
/// use yasna::models::ObjectIdentifier;
/// let pkcs1 = ObjectIdentifier::from_slice(&
/// [1, 2, 840, 113549, 1, 1]);
/// let components : &Vec<u64> = pkcs1.components();
/// ```
pub fn components(&self) -> &Vec<u64> {
&self.components
}
/// Mutably borrows its internal vector of components.
///
/// # Examples
///
/// ```
/// use yasna::models::ObjectIdentifier;
/// let mut pkcs1 = ObjectIdentifier::from_slice(&
/// [1, 2, 840, 113549, 1, 1]);
/// let components : &mut Vec<u64> = pkcs1.components_mut();
/// ```
pub fn components_mut(&mut self) -> &mut Vec<u64> {
&mut self.components
}
/// Extracts its internal vector of components.
///
/// # Examples
///
/// ```
/// use yasna::models::ObjectIdentifier;
/// let pkcs1 = ObjectIdentifier::from_slice(&
/// [1, 2, 840, 113549, 1, 1]);
/// let mut components : Vec<u64> = pkcs1.into_components();
/// ```
pub fn into_components(self) -> Vec<u64> {
self.components
}
}
impl Display for ObjectIdentifier {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let mut fst = true;
for &component in &self.components {
if fst {
write!(f, "{}", component)?;
} else {
write!(f, ".{}", component)?;
}
fst = false;
}
return Ok(());
}
}
#[derive(Debug, Clone)]
/// An error indicating failure to parse an Object identifier
pub struct ParseOidError(());
#[cfg(feature = "std")]
impl Error for ParseOidError {}
impl Display for ParseOidError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
f.write_str("Failed to parse OID")
}
}
impl FromStr for ObjectIdentifier {
type Err = ParseOidError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.split(".")
.map(|s| s.parse().map_err(|_| ParseOidError(()) ))
.collect::<Result<_, _>>()
.map(ObjectIdentifier::new)
}
}
impl AsRef<[u64]> for ObjectIdentifier {
fn as_ref(&self) -> &[u64] {
&self.components
}
}
impl From<Vec<u64>> for ObjectIdentifier {
fn from(components: Vec<u64>) -> ObjectIdentifier {
Self::new(components)
}
}
#[test]
fn test_display_oid() {
use alloc::format;
let pkcs1 = ObjectIdentifier::from_slice(&[1, 2, 840, 113549, 1, 1]);
assert_eq!(format!("{}", pkcs1), "1.2.840.113549.1.1");
}
#[test]
fn parse_oid() {
assert_eq!("1.2.840.113549.1.1".parse::<ObjectIdentifier>().unwrap().components(), &[1, 2, 840, 113549, 1, 1]);
"1.2.840.113549.1.1.".parse::<ObjectIdentifier>().unwrap_err();
"1.2.840.113549.1.1x".parse::<ObjectIdentifier>().unwrap_err();
"".parse::<ObjectIdentifier>().unwrap_err();
}

666
vendor/yasna/src/models/time.rs vendored Normal file
View File

@@ -0,0 +1,666 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use alloc::string::String;
use alloc::vec::Vec;
use core::convert::TryFrom;
use time::{Date, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
/// Date and time between 1950-01-01T00:00:00Z and 2049-12-31T23:59:59Z.
/// It cannot express fractional seconds and leap seconds.
/// It doesn't carry timezone information.
///
/// Corresponds to ASN.1 UTCTime type. Often used in conjunction with
/// [`GeneralizedTime`].
///
/// # Features
///
/// This struct is enabled by `time` feature.
///
/// ```toml
/// [dependencies]
/// yasna = { version = "*", features = ["time"] }
/// ```
///
/// # Examples
///
/// ```
/// # fn main() {
/// use yasna::models::UTCTime;
/// let datetime = *UTCTime::parse(b"8201021200Z").unwrap().datetime();
/// assert_eq!(datetime.year(), 1982);
/// assert_eq!(datetime.month() as u8, 1);
/// assert_eq!(datetime.day(), 2);
/// assert_eq!(datetime.hour(), 12);
/// assert_eq!(datetime.minute(), 0);
/// assert_eq!(datetime.second(), 0);
/// assert_eq!(datetime.nanosecond(), 0);
/// # }
/// ```
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct UTCTime {
datetime: OffsetDateTime,
}
impl UTCTime {
/// Parses ASN.1 string representation of UTCTime.
///
/// # Examples
///
/// ```
/// use yasna::models::UTCTime;
/// let datetime = UTCTime::parse(b"000229123456Z").unwrap();
/// assert_eq!(&datetime.to_string(), "000229123456Z");
/// ```
///
/// # Errors
///
/// It returns `None` if the given string does not specify a correct
/// datetime.
///
/// # Interpretation
///
/// While neither X.680 nor X.690 specify interpretation of 2-digits year,
/// X.501 specifies that UTCTime in Time shall be interpreted as between
/// 1950 and 2049. This method parses the string according to the X.501
/// rule.
pub fn parse(buf: &[u8]) -> Option<Self> {
if buf.len() < 11 {
return None;
}
// i: a position of [Z+-].
let i = if [b'+', b'-', b'Z'].contains(&buf[10]) { 10 } else { 12 };
if buf.len() < i+1 || ![b'+', b'-', b'Z'].contains(&buf[i]) {
return None;
}
let len = if buf[i] == b'Z' { i+1 } else { i+5 };
if len != buf.len() {
return None;
}
if !buf[..i].iter().all(|&b| b'0' <= b && b <= b'9') ||
!buf[i+1..].iter().all(|&b| b'0' <= b && b <= b'9')
{
return None;
}
let year_short: i32 =
((buf[0] - b'0') as i32) * 10 + ((buf[1] - b'0') as i32);
let year = if year_short < 50 {
year_short + 2000
} else {
year_short + 1900
};
let month = Month::try_from((buf[2] - b'0') * 10 + (buf[3] - b'0')).ok()?;
let day = (buf[4] - b'0') * 10 + (buf[5] - b'0');
let hour = (buf[6] - b'0') * 10 + (buf[7] - b'0');
let minute = (buf[8] - b'0') * 10 + (buf[9] - b'0');
let second = if i == 12 {
(buf[10] - b'0') * 10 + (buf[11] - b'0')
} else {
0
};
let offset_hour: i8 = if buf[i] == b'Z' {
0
} else {
((buf[i+1] - b'0') as i8) * 10 + ((buf[i+2] - b'0') as i8)
};
let offset_minute: i8 = if buf[i] == b'Z' {
0
} else {
((buf[i+3] - b'0') as i8) * 10 + ((buf[i+4] - b'0') as i8)
};
let date = Date::from_calendar_date(year, month, day).ok()?;
let time = Time::from_hms(hour, minute, second).ok()?;
let datetime = PrimitiveDateTime::new(date, time);
if !(offset_hour < 24 && offset_minute < 60) {
return None;
}
let offset = if buf[i] == b'+' {
UtcOffset::from_hms(offset_hour, offset_minute, 0).ok()?
} else {
UtcOffset::from_hms(-offset_hour, -offset_minute, 0).ok()?
};
let datetime = datetime.assume_offset(offset).to_offset(UtcOffset::UTC);
// While the given local datatime is in [1950, 2050) by definition,
// the UTC datetime can be out of bounds. We check this.
if !(1950 <= datetime.year() && datetime.year() < 2050) {
return None;
}
return Some(UTCTime {
datetime: datetime,
});
}
/// Constructs `UTCTime` from an `OffsetDateTime`.
///
/// # Panics
///
/// Panics when UTCTime can't represent the datetime. That is:
///
/// - The year is not between 1950 and 2049.
/// - It is in a leap second.
/// - It has a non-zero nanosecond value.
pub fn from_datetime(datetime: OffsetDateTime) -> Self {
let datetime = datetime.to_offset(UtcOffset::UTC);
assert!(1950 <= datetime.year() && datetime.year() < 2050,
"Can't express a year {:?} in UTCTime", datetime.year());
assert!(datetime.nanosecond() < 1_000_000_000,
"Can't express a leap second in UTCTime");
assert!(datetime.nanosecond() == 0,
"Can't express a non-zero nanosecond in UTCTime");
return UTCTime {
datetime: datetime,
};
}
/// Constructs `UTCTime` from an `OffsetDateTime`.
///
/// # Errors
///
/// It returns `None` when UTCTime can't represent the datetime. That is:
///
/// - The year is not between 1950 and 2049.
/// - It is in a leap second.
/// - It has a non-zero nanosecond value.
pub fn from_datetime_opt(datetime: OffsetDateTime) -> Option<Self> {
let datetime = datetime.to_offset(UtcOffset::UTC);
if !(1950 <= datetime.year() && datetime.year() < 2050) {
return None;
}
if !(datetime.nanosecond() == 0) {
return None;
}
return Some(UTCTime {
datetime: datetime,
});
}
/// Returns the `OffsetDateTime` it represents.
pub fn datetime(&self) -> &OffsetDateTime {
&self.datetime
}
/// Returns ASN.1 canonical representation of the datetime as `Vec<u8>`.
pub fn to_bytes(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(13);
buf.push((self.datetime.year() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.year() % 10) as u8 + b'0');
buf.push((self.datetime.month() as u8 / 10 % 10) + b'0');
buf.push((self.datetime.month() as u8 % 10) + b'0');
buf.push((self.datetime.day() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.day() % 10) as u8 + b'0');
buf.push((self.datetime.hour() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.hour() % 10) as u8 + b'0');
buf.push((self.datetime.minute() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.minute() % 10) as u8 + b'0');
buf.push((self.datetime.second() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.second() % 10) as u8 + b'0');
buf.push(b'Z');
return buf;
}
/// Returns ASN.1 canonical representation of the datetime as `String`.
pub fn to_string(&self) -> String {
String::from_utf8(self.to_bytes()).unwrap()
}
}
/// Date and time between 0000-01-01T00:00:00Z and 9999-12-31T23:59:60.999...Z.
///
/// It can contain arbitrary length of decimal fractional seconds.
/// However, it doesn't carry accuracy information.
/// It can also contain leap seconds.
///
/// The datetime is canonicalized to UTC.
/// It doesn't carry timezone information.
///
/// Corresponds to ASN.1 GeneralizedTime type. Often used in conjunction with
/// [`UTCTime`].
///
/// # Features
///
/// This struct is enabled by `time` feature.
///
/// ```toml
/// [dependencies]
/// yasna = { version = "*", features = ["time"] }
/// ```
///
/// # Examples
///
/// ```
/// # fn main() {
/// use yasna::models::GeneralizedTime;
/// let datetime =
/// *GeneralizedTime::parse(b"19851106210627.3Z").unwrap().datetime();
/// assert_eq!(datetime.year(), 1985);
/// assert_eq!(datetime.month() as u8, 11);
/// assert_eq!(datetime.day(), 6);
/// assert_eq!(datetime.hour(), 21);
/// assert_eq!(datetime.minute(), 6);
/// assert_eq!(datetime.second(), 27);
/// assert_eq!(datetime.nanosecond(), 300_000_000);
/// # }
/// ```
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct GeneralizedTime {
datetime: OffsetDateTime,
sub_nano: Vec<u8>,
// TODO: time does not support leap seconds. This is a simple hack to support round-tripping.
is_leap_second: bool,
}
impl GeneralizedTime {
/// Almost same as `parse`. It takes `default_offset` however.
/// GeneralizedTime value can omit offset in local time.
/// In that case, `default_offset` is used instead.
fn parse_general(buf: &[u8], default_offset: Option<UtcOffset>) -> Option<Self> {
if buf.len() < 10 {
return None;
}
if !buf[..10].iter().all(|&b| b'0' <= b && b <= b'9') {
return None;
}
let year: i32 =
((buf[0] - b'0') as i32) * 1000 + ((buf[1] - b'0') as i32) * 100
+ ((buf[2] - b'0') as i32) * 10 + ((buf[3] - b'0') as i32);
let month = Month::try_from((buf[4] - b'0') * 10 + (buf[5] - b'0')).ok()?;
let day = (buf[6] - b'0') * 10 + (buf[7] - b'0');
let hour = (buf[8] - b'0') * 10 + (buf[9] - b'0');
// i: current position on `buf`
let mut i = 10;
// The factor to scale the fraction part to nanoseconds.
let mut fraction_scale : i64 = 1_000_000_000;
let mut minute: u8;
if i+2 <= buf.len() &&
buf[i..i+2].iter().all(|&b| b'0' <= b && b <= b'9') {
minute = (buf[i] - b'0') * 10 + (buf[i + 1] - b'0');
i += 2;
} else {
fraction_scale = 3_600_000_000_000;
minute = 0;
}
let mut second: u8;
if i+2 <= buf.len() &&
buf[i..i+2].iter().all(|&b| b'0' <= b && b <= b'9') {
second = (buf[i] - b'0') * 10 + (buf[i + 1] - b'0');
i += 2;
} else {
if fraction_scale == 1_000_000_000 {
fraction_scale = 60_000_000_000;
}
second = 0;
}
let mut nanosecond = 0;
let mut sub_nano = Vec::new();
if i+2 <= buf.len() && (buf[i] == b'.' || buf[i] == b',')
&& b'0' <= buf[i+1] && buf[i+1] <= b'9' {
i += 1;
let mut j = 0;
while i+j < buf.len() && b'0' <= buf[i+j] && buf[i+j] <= b'9' {
sub_nano.push(b'0');
j += 1;
}
let mut carry : i64 = 0;
for k in (0..j).rev() {
let digit = (buf[i+k] - b'0') as i64;
let sum = digit * fraction_scale + carry;
carry = sum / 10;
sub_nano[k] = b'0' + ((sum % 10) as u8);
}
nanosecond = (carry % 1_000_000_000) as u32;
second += (carry / 1_000_000_000 % 60) as u8;
minute += (carry / 60_000_000_000) as u8;
while let Some(&digit) = sub_nano.last() {
if digit == b'0' {
sub_nano.pop();
} else {
break;
}
}
i += j;
}
let mut is_leap_second = false;
if second == 60 {
// TODO: `time` doesn't accept leap seconds, so we use a flag to preserve
is_leap_second = true;
second = 59;
}
let date = Date::from_calendar_date(year, month, day).ok()?;
let time = Time::from_hms_nano(hour, minute, second, nanosecond).ok()?;
let naive_datetime = PrimitiveDateTime::new(date, time);
let datetime: OffsetDateTime;
if i == buf.len() {
// Local datetime with no timezone information.
datetime = naive_datetime
.assume_offset(default_offset?)
.to_offset(UtcOffset::UTC);
} else if i < buf.len() && buf[i] == b'Z' {
// UTC time.
datetime = naive_datetime.assume_utc();
i += 1;
} else if i < buf.len() && (buf[i] == b'+' || buf[i] == b'-') {
// Local datetime with offset information.
let offset_sign = buf[i];
i += 1;
if !(i+2 <= buf.len() &&
buf[i..i+2].iter().all(|&b| b'0' <= b && b <= b'9')) {
return None;
}
let offset_hour =
((buf[i] - b'0') as i8) * 10 + ((buf[i+1] - b'0') as i8);
i += 2;
let offset_minute;
if i+2 <= buf.len() &&
buf[i..i+2].iter().all(|&b| b'0' <= b && b <= b'9') {
offset_minute =
((buf[i] - b'0') as i8) * 10 + ((buf[i+1] - b'0') as i8);
i += 2;
} else {
offset_minute = 0;
}
if !(offset_hour < 24 && offset_minute < 60) {
return None;
}
let offset = if offset_sign == b'+' {
UtcOffset::from_hms(offset_hour, offset_minute, 0)
} else {
UtcOffset::from_hms(-offset_hour, -offset_minute, 0)
};
datetime = naive_datetime
.assume_offset(offset.ok()?)
.to_offset(UtcOffset::UTC);
} else {
return None;
}
if i != buf.len() {
return None;
}
// While the given local datatime is in [0, 10000) by definition,
// the UTC datetime can be out of bounds. We check this.
if !(0 <= datetime.year() && datetime.year() < 10000) {
return None;
}
return Some(GeneralizedTime {
datetime: datetime,
sub_nano: sub_nano,
is_leap_second,
});
}
/// Parses ASN.1 string representation of GeneralizedTime.
///
/// # Examples
///
/// ```
/// use yasna::models::GeneralizedTime;
/// let datetime = GeneralizedTime::parse(b"1985110621.14159Z").unwrap();
/// assert_eq!(&datetime.to_string(), "19851106210829.724Z");
/// ```
///
/// # Errors
///
/// It returns `None` if the given string does not specify a correct
/// datetime.
pub fn parse(buf: &[u8]) -> Option<Self> {
Self::parse_general(buf, None)
}
/// Parses ASN.1 string representation of GeneralizedTime, with the
/// default timezone for local time given.
///
/// # Examples
///
/// ```
/// use yasna::models::GeneralizedTime;
/// let datetime = GeneralizedTime::parse(b"1985110621.14159Z").unwrap();
/// assert_eq!(&datetime.to_string(), "19851106210829.724Z");
/// ```
///
/// # Errors
///
/// It returns `None` if the given string does not specify a correct
/// datetime.
pub fn parse_with_offset(buf: &[u8], default_offset: UtcOffset) -> Option<Self> {
Self::parse_general(buf, Some(default_offset))
}
/// Constructs `GeneralizedTime` from an `OffsetDateTime`.
///
/// # Panics
///
/// Panics when GeneralizedTime can't represent the datetime. That is:
///
/// - The year is not between 0 and 9999.
pub fn from_datetime(datetime: OffsetDateTime) -> Self {
let datetime = datetime.to_offset(UtcOffset::UTC);
assert!(0 <= datetime.year() && datetime.year() < 10000,
"Can't express a year {:?} in GeneralizedTime", datetime.year());
return GeneralizedTime {
datetime: datetime,
sub_nano: Vec::new(),
is_leap_second: false,
};
}
/// Constructs `GeneralizedTime` from an `OffsetDateTime`.
///
/// # Errors
///
/// It returns `None` when GeneralizedTime can't represent the datetime.
/// That is:
///
/// - The year is not between 0 and 9999.
pub fn from_datetime_opt(datetime: OffsetDateTime) -> Option<Self> {
let datetime = datetime.to_offset(UtcOffset::UTC);
if !(0 <= datetime.year() && datetime.year() < 10000) {
return None;
}
return Some(GeneralizedTime {
datetime: datetime,
sub_nano: Vec::new(),
is_leap_second: false,
});
}
/// Constructs `GeneralizedTime` from an `OffsetDateTime` and sub-nanoseconds
/// digits.
///
/// # Panics
///
/// Panics when GeneralizedTime can't represent the datetime. That is:
///
/// - The year is not between 0 and 9999.
///
/// It also panics if `sub_nano` contains a non-digit character.
pub fn from_datetime_and_sub_nano(datetime: OffsetDateTime, sub_nano: &[u8]) -> Self {
let datetime = datetime.to_offset(UtcOffset::UTC);
assert!(0 <= datetime.year() && datetime.year() < 10000,
"Can't express a year {:?} in GeneralizedTime", datetime.year());
assert!(sub_nano.iter().all(|&b| b'0' <= b && b <= b'9'),
"sub_nano contains a non-digit character");
let mut sub_nano = sub_nano.to_vec();
while sub_nano.len() > 0 && *sub_nano.last().unwrap() == b'0' {
sub_nano.pop();
}
return GeneralizedTime {
datetime: datetime,
sub_nano: sub_nano,
is_leap_second: false,
};
}
/// Constructs `GeneralizedTime` from an `OffsetDateTime` and sub-nanoseconds
/// digits.
///
/// # Errors
///
/// It returns `None` when GeneralizedTime can't represent the datetime.
/// That is:
///
/// - The year is not between 0 and 9999.
///
/// It also returns `None` if `sub_nano` contains a non-digit character.
pub fn from_datetime_and_sub_nano_opt(
datetime: OffsetDateTime,
sub_nano: &[u8],
) -> Option<Self> {
let datetime = datetime.to_offset(UtcOffset::UTC);
if !(0 <= datetime.year() && datetime.year() < 10000) {
return None;
}
if !(sub_nano.iter().all(|&b| b'0' <= b && b <= b'9')) {
return None;
}
let mut sub_nano = sub_nano.to_vec();
while sub_nano.len() > 0 && *sub_nano.last().unwrap() == b'0' {
sub_nano.pop();
}
return Some(GeneralizedTime {
datetime: datetime,
sub_nano: sub_nano,
is_leap_second: false,
});
}
/// Returns the `OffsetDateTime` it represents.
///
/// Leap seconds and sub-nanoseconds digits will be discarded.
pub fn datetime(&self) -> &OffsetDateTime {
&self.datetime
}
/// Returns sub-nanoseconds digits of the datetime.
pub fn sub_nano(&self) -> &[u8] {
&self.sub_nano
}
/// Returns ASN.1 canonical representation of the datetime as `Vec<u8>`.
pub fn to_bytes(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(24);
buf.push((self.datetime.year() / 1000 % 10) as u8 + b'0');
buf.push((self.datetime.year() / 100 % 10) as u8 + b'0');
buf.push((self.datetime.year() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.year() % 10) as u8 + b'0');
buf.push((self.datetime.month() as u8 / 10 % 10) + b'0');
buf.push((self.datetime.month() as u8 % 10) + b'0');
buf.push((self.datetime.day() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.day() % 10) as u8 + b'0');
buf.push((self.datetime.hour() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.hour() % 10) as u8 + b'0');
buf.push((self.datetime.minute() / 10 % 10) as u8 + b'0');
buf.push((self.datetime.minute() % 10) as u8 + b'0');
let mut second = self.datetime.second();
let nanosecond = self.datetime.nanosecond();
// Cope with leap seconds.
if self.is_leap_second {
debug_assert!(second == 59,
"is_leap_second is set, but second = {}", second);
second += 1;
}
buf.push((second / 10 % 10) as u8 + b'0');
buf.push((second % 10) as u8 + b'0');
buf.push(b'.');
buf.push((nanosecond / 100_000_000 % 10) as u8 + b'0');
buf.push((nanosecond / 10_000_000 % 10) as u8 + b'0');
buf.push((nanosecond / 1_000_000 % 10) as u8 + b'0');
buf.push((nanosecond / 100_000 % 10) as u8 + b'0');
buf.push((nanosecond / 10_000 % 10) as u8 + b'0');
buf.push((nanosecond / 1_000 % 10) as u8 + b'0');
buf.push((nanosecond / 100 % 10) as u8 + b'0');
buf.push((nanosecond / 10 % 10) as u8 + b'0');
buf.push((nanosecond % 10) as u8 + b'0');
buf.extend_from_slice(&self.sub_nano);
// Truncates trailing zeros.
while buf.len() > 14 && {
let b = *buf.last().unwrap(); b == b'0' || b == b'.' } {
buf.pop();
}
buf.push(b'Z');
return buf;
}
/// Returns ASN.1 canonical representation of the datetime as `String`.
pub fn to_string(&self) -> String {
String::from_utf8(self.to_bytes()).unwrap()
}
}
#[test]
fn test_utctime_parse() {
let datetime = *UTCTime::parse(b"8201021200Z").unwrap().datetime();
assert_eq!(datetime.year(), 1982);
assert_eq!(datetime.month() as u8, 1);
assert_eq!(datetime.day(), 2);
assert_eq!(datetime.hour(), 12);
assert_eq!(datetime.minute(), 0);
assert_eq!(datetime.second(), 0);
assert_eq!(datetime.nanosecond(), 0);
let datetime = *UTCTime::parse(b"0101021200Z").unwrap().datetime();
assert_eq!(datetime.year(), 2001);
assert_eq!(datetime.month() as u8, 1);
assert_eq!(datetime.day(), 2);
assert_eq!(datetime.hour(), 12);
assert_eq!(datetime.minute(), 0);
assert_eq!(datetime.second(), 0);
assert_eq!(datetime.nanosecond(), 0);
let datetime = UTCTime::parse(b"8201021200Z").unwrap();
assert_eq!(&datetime.to_string(), "820102120000Z");
let datetime = UTCTime::parse(b"8201020700-0500").unwrap();
assert_eq!(&datetime.to_string(), "820102120000Z");
let datetime = UTCTime::parse(b"0101021200Z").unwrap();
assert_eq!(&datetime.to_string(), "010102120000Z");
let datetime = UTCTime::parse(b"010102120034Z").unwrap();
assert_eq!(&datetime.to_string(), "010102120034Z");
let datetime = UTCTime::parse(b"000229123456Z").unwrap();
assert_eq!(&datetime.to_string(), "000229123456Z");
}
#[test]
fn test_generalized_time_parse() {
let datetime =
*GeneralizedTime::parse(b"19851106210627.3Z").unwrap().datetime();
assert_eq!(datetime.year(), 1985);
assert_eq!(datetime.month() as u8, 11);
assert_eq!(datetime.day(), 6);
assert_eq!(datetime.hour(), 21);
assert_eq!(datetime.minute(), 6);
assert_eq!(datetime.second(), 27);
assert_eq!(datetime.nanosecond(), 300_000_000);
let datetime = GeneralizedTime::parse(b"19851106210627.3-0500").unwrap();
assert_eq!(&datetime.to_string(), "19851107020627.3Z");
let datetime = GeneralizedTime::parse(b"198511062106Z").unwrap();
assert_eq!(&datetime.to_string(), "19851106210600Z");
let datetime = GeneralizedTime::parse(b"198511062106.456Z").unwrap();
assert_eq!(&datetime.to_string(), "19851106210627.36Z");
let datetime = GeneralizedTime::parse(b"1985110621Z").unwrap();
assert_eq!(&datetime.to_string(), "19851106210000Z");
let datetime = GeneralizedTime::parse(b"1985110621.14159Z").unwrap();
assert_eq!(&datetime.to_string(), "19851106210829.724Z");
let datetime =
GeneralizedTime::parse(b"19990101085960.1234+0900").unwrap();
assert_eq!(&datetime.to_string(), "19981231235960.1234Z");
let datetime =
GeneralizedTime::parse(
b"20080229033411.3625431984612391672391625532918636000680000-0500"
).unwrap();
assert_eq!(&datetime.to_string(),
"20080229083411.362543198461239167239162553291863600068Z");
}

61
vendor/yasna/src/reader/error.rs vendored Normal file
View File

@@ -0,0 +1,61 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[cfg(feature = "std")]
use std::{error::Error, io};
use core::fmt::{self, Display};
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct ASN1Error {
kind: ASN1ErrorKind,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum ASN1ErrorKind {
Eof, Extra, IntegerOverflow, StackOverflow, Invalid,
}
pub type ASN1Result<T> = Result<T, ASN1Error>;
impl ASN1Error {
pub fn new(kind: ASN1ErrorKind) -> Self {
ASN1Error {
kind,
}
}
pub fn kind(&self) -> ASN1ErrorKind {
self.kind
}
}
impl Display for ASN1Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{:?}", self)?;
return Ok(());
}
}
#[cfg(feature = "std")]
impl Error for ASN1Error {
fn description(&self) -> &str {
match self.kind {
ASN1ErrorKind::Eof => "End of file",
ASN1ErrorKind::Extra => "Extra data in file",
ASN1ErrorKind::IntegerOverflow => "Integer overflow",
ASN1ErrorKind::StackOverflow => "Stack overflow",
ASN1ErrorKind::Invalid => "Invalid data",
}
}
}
#[cfg(feature = "std")]
impl From<ASN1Error> for io::Error {
fn from(e: ASN1Error) -> Self {
return io::Error::new(io::ErrorKind::InvalidData, e);
}
}

1890
vendor/yasna/src/reader/mod.rs vendored Normal file

File diff suppressed because it is too large Load Diff

1666
vendor/yasna/src/reader/tests.rs vendored Normal file

File diff suppressed because it is too large Load Diff

421
vendor/yasna/src/serializer/mod.rs vendored Normal file
View File

@@ -0,0 +1,421 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![forbid(missing_docs)]
use alloc::vec::Vec;
use alloc::string::String;
#[cfg(feature = "num-bigint")]
use num_bigint::{BigInt,BigUint};
#[cfg(feature = "bit-vec")]
use bit_vec::BitVec;
use super::{DERWriter,construct_der};
use super::models::ObjectIdentifier;
#[cfg(feature = "time")]
use super::models::{UTCTime,GeneralizedTime};
/// Types encodable in DER.
///
/// # Examples
///
/// ```
/// use yasna;
/// let der = yasna::encode_der::<i64>(&65535);
/// assert_eq!(&der, &[2, 3, 0, 255, 255]);
/// ```
///
/// # Limitations
///
/// Rust types don't correspond to ASN.1 types one-to-one. Not all kinds
/// of ASN.1 types can be encoded via default `DEREncodable` implementation.
///
/// If you want to encode ASN.1, you may implement `DEREncodable` for your
/// own types or use [`construct_der`].
///
/// # Default implementations
///
/// - The encoder for `Vec<T>`/`[T]` is implemented as SEQUENCE OF encoder.
/// - `()` as NULL encoder.
/// - Tuples (except `()`) as SEQUENCE encoder.
/// - `Vec<u8>`/`[u8]` as OCTETSTRING encoder.
/// - `BitVec` as BITSTRING encoder.
/// - `String`/`str` as UTF8String encoder.
/// - `i64`, `u64`, `i32`, `u32`, `i16`, `u16`, `BigInt`, `BigUint`
/// as INTEGER encoder. (`u8` is avoided because of confliction.)
/// - `bool` as BOOLEAN encoder.
/// - `ObjectIdentifier` as OBJECTT IDENTIFIER encoder.
/// - `UTCTime`/`GeneralizedTime` as UTCTime/GeneralizedTime encoder.
pub trait DEREncodable {
/// Writes the value as an DER-encoded ASN.1 value.
///
/// # Examples
///
/// ```
/// use yasna::{DEREncodable,DERWriter};
/// struct Entry {
/// name: String,
/// age: i64,
/// }
///
/// impl DEREncodable for Entry {
/// fn encode_der(&self, writer: DERWriter) {
/// writer.write_sequence(|writer| {
/// writer.next().write_visible_string(&self.name);
/// writer.next().write_i64(self.age);
/// })
/// }
/// }
/// fn main() {
/// let entry = Entry {
/// name: String::from("John"),
/// age: 32,
/// };
/// let der = yasna::encode_der(&entry);
/// assert_eq!(&der, &[48, 9, 26, 4, 74, 111, 104, 110, 2, 1, 32]);
/// }
/// ```
fn encode_der<'a>(&self, writer: DERWriter<'a>);
}
/// Encodes a value to DER-encoded ASN.1 data.
pub fn encode_der<T:DEREncodable>(value: &T) -> Vec<u8> {
construct_der(|writer| {
value.encode_der(writer)
})
}
impl<T> DEREncodable for Vec<T> where T: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
for elem in self.iter() {
elem.encode_der(writer.next());
}
})
}
}
impl<T> DEREncodable for [T] where T: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
for elem in self.iter() {
elem.encode_der(writer.next());
}
})
}
}
impl DEREncodable for i64 {
fn encode_der(&self, writer: DERWriter) {
writer.write_i64(*self)
}
}
impl DEREncodable for u64 {
fn encode_der(&self, writer: DERWriter) {
writer.write_u64(*self)
}
}
impl DEREncodable for i32 {
fn encode_der(&self, writer: DERWriter) {
writer.write_i32(*self)
}
}
impl DEREncodable for u32 {
fn encode_der(&self, writer: DERWriter) {
writer.write_u32(*self)
}
}
impl DEREncodable for i16 {
fn encode_der(&self, writer: DERWriter) {
writer.write_i16(*self)
}
}
impl DEREncodable for u16 {
fn encode_der(&self, writer: DERWriter) {
writer.write_u16(*self)
}
}
#[cfg(feature = "num-bigint")]
impl DEREncodable for BigInt {
fn encode_der(&self, writer: DERWriter) {
writer.write_bigint(self)
}
}
#[cfg(feature = "num-bigint")]
impl DEREncodable for BigUint {
fn encode_der(&self, writer: DERWriter) {
writer.write_biguint(self)
}
}
impl DEREncodable for bool {
fn encode_der(&self, writer: DERWriter) {
writer.write_bool(*self)
}
}
#[cfg(feature = "bit-vec")]
impl DEREncodable for BitVec {
fn encode_der(&self, writer: DERWriter) {
writer.write_bitvec(self)
}
}
impl DEREncodable for Vec<u8> {
fn encode_der(&self, writer: DERWriter) {
writer.write_bytes(self)
}
}
impl DEREncodable for [u8] {
fn encode_der(&self, writer: DERWriter) {
writer.write_bytes(self)
}
}
impl DEREncodable for String {
fn encode_der(&self, writer: DERWriter) {
writer.write_utf8string(self)
}
}
impl DEREncodable for str {
fn encode_der(&self, writer: DERWriter) {
writer.write_utf8string(self)
}
}
impl DEREncodable for ObjectIdentifier {
fn encode_der(&self, writer: DERWriter) {
writer.write_oid(self)
}
}
#[cfg(feature = "time")]
impl DEREncodable for UTCTime {
fn encode_der(&self, writer: DERWriter) {
writer.write_utctime(self)
}
}
#[cfg(feature = "time")]
impl DEREncodable for GeneralizedTime{
fn encode_der(&self, writer: DERWriter) {
writer.write_generalized_time(self)
}
}
impl DEREncodable for () {
fn encode_der(&self, writer: DERWriter) {
writer.write_null()
}
}
impl<T0> DEREncodable for (T0,) where T0: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
})
}
}
impl<T0, T1> DEREncodable for (T0, T1)
where T0: DEREncodable, T1: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
})
}
}
impl<T0, T1, T2> DEREncodable for (T0, T1, T2)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3> DEREncodable for (T0, T1, T2, T3)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4> DEREncodable for (T0, T1, T2, T3, T4)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5> DEREncodable for (T0, T1, T2, T3, T4, T5)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6> DEREncodable for (T0, T1, T2, T3, T4, T5, T6)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable,
T6: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
self.6.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7> DEREncodable
for (T0, T1, T2, T3, T4, T5, T6, T7)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable,
T6: DEREncodable, T7: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
self.6.encode_der(writer.next());
self.7.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8> DEREncodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable,
T6: DEREncodable, T7: DEREncodable, T8: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
self.6.encode_der(writer.next());
self.7.encode_der(writer.next());
self.8.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> DEREncodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable,
T6: DEREncodable, T7: DEREncodable, T8: DEREncodable,
T9: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
self.6.encode_der(writer.next());
self.7.encode_der(writer.next());
self.8.encode_der(writer.next());
self.9.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> DEREncodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable,
T6: DEREncodable, T7: DEREncodable, T8: DEREncodable,
T9: DEREncodable, T10: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
self.6.encode_der(writer.next());
self.7.encode_der(writer.next());
self.8.encode_der(writer.next());
self.9.encode_der(writer.next());
self.10.encode_der(writer.next());
})
}
}
impl<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> DEREncodable
for (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)
where T0: DEREncodable, T1: DEREncodable, T2: DEREncodable,
T3: DEREncodable, T4: DEREncodable, T5: DEREncodable,
T6: DEREncodable, T7: DEREncodable, T8: DEREncodable,
T9: DEREncodable, T10: DEREncodable, T11: DEREncodable {
fn encode_der(&self, writer: DERWriter) {
writer.write_sequence(|writer| {
self.0.encode_der(writer.next());
self.1.encode_der(writer.next());
self.2.encode_der(writer.next());
self.3.encode_der(writer.next());
self.4.encode_der(writer.next());
self.5.encode_der(writer.next());
self.6.encode_der(writer.next());
self.7.encode_der(writer.next());
self.8.encode_der(writer.next());
self.9.encode_der(writer.next());
self.10.encode_der(writer.next());
self.11.encode_der(writer.next());
})
}
}

221
vendor/yasna/src/tags/mod.rs vendored Normal file
View File

@@ -0,0 +1,221 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Provides universal tag constants.
use super::{Tag,TagClass};
/// A special tag representing "end of contents".
pub const TAG_EOC : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 0,
};
/// A universal tag for BOOLEAN.
pub const TAG_BOOLEAN : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 1,
};
/// A universal tag for INTEGER.
pub const TAG_INTEGER : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 2,
};
/// A universal tag for BITSTRING.
pub const TAG_BITSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 3,
};
/// A universal tag for OCTETSTRING.
pub const TAG_OCTETSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 4,
};
/// A universal tag for NULL.
pub const TAG_NULL : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 5,
};
/// A universal tag for object identifiers.
pub const TAG_OID : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 6,
};
/// A universal tag for object descriptors.
pub const TAG_OBJECT_DESCRIPTOR : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 7,
};
/// A universal tag for external/instance-of types.
pub const TAG_EXT : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 8,
};
/// A universal tag for REAL.
pub const TAG_REAL : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 9,
};
/// A universal tag for enumerated types.
pub const TAG_ENUM : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 10,
};
/// A universal tag for embedded-pdv types.
pub const TAG_EMBEDDED_PDV : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 11,
};
/// A universal tag for UTF8String.
pub const TAG_UTF8STRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 12,
};
/// A universal tag for relative object identifiers.
pub const TAG_RELATIVE_OID : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 13,
};
/// A universal tag for TIME.
pub const TAG_TIME : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 14,
};
/// A universal tag for SEQUENCE/SEQUENCE OF.
pub const TAG_SEQUENCE : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 16,
};
/// A universal tag for SET/SET OF.
pub const TAG_SET : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 17,
};
/// A universal tag for NumericString.
pub const TAG_NUMERICSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 18,
};
/// A universal tag for PrintableString.
pub const TAG_PRINTABLESTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 19,
};
/// A universal tag for TeletexString.
pub const TAG_TELETEXSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 20,
};
/// A universal tag for VideotexString.
pub const TAG_VIDEOTEXSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 21,
};
/// A universal tag for IA5String.
pub const TAG_IA5STRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 22,
};
/// A universal tag for UTCTime.
pub const TAG_UTCTIME : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 23,
};
/// A universal tag for GeneralizedTime.
pub const TAG_GENERALIZEDTIME : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 24,
};
/// A universal tag for GraphicString.
pub const TAG_GRAPHICSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 25,
};
/// A universal tag for VisibleString.
pub const TAG_VISIBLESTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 26,
};
/// A universal tag for GeneralString.
pub const TAG_GENERALSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 27,
};
/// A universal tag for UniversalString.
pub const TAG_UNIVERSALSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 28,
};
/// A universal tag for BMPString.
pub const TAG_BMPSTRING : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 30,
};
/// A universal tag for DATE.
pub const TAG_DATE : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 31,
};
/// A universal tag for TIME-OF-DAY.
pub const TAG_TIME_OF_DAY : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 32,
};
/// A universal tag for DATE-TIME.
pub const TAG_DATE_TIME : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 33,
};
/// A universal tag for DURATION.
pub const TAG_DURATION : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 34,
};
/// A universal tag for OID internationalized resource identifiers.
pub const TAG_OID_INTL_RESID : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 35,
};
/// A universal tag for relative OID internationalized resource identifiers.
pub const TAG_RELATIVE_OID_INTL_RESID : Tag = Tag {
tag_class: TagClass::Universal,
tag_number: 36,
};

1256
vendor/yasna/src/writer/mod.rs vendored Normal file

File diff suppressed because it is too large Load Diff

479
vendor/yasna/src/writer/tests.rs vendored Normal file
View File

@@ -0,0 +1,479 @@
// Copyright 2016 Masaki Hara
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use alloc::vec;
#[cfg(feature = "num-bigint")]
use num_bigint::{BigUint, BigInt};
use super::super::Tag;
use super::*;
#[test]
fn test_der_write_bool() {
let tests : &[(bool, &[u8])] = &[
(false, &[1, 1, 0]),
(true, &[1, 1, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_bool(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_i64() {
let tests : &[(i64, &[u8])] = &[
(-9223372036854775808, &[2, 8, 128, 0, 0, 0, 0, 0, 0, 0]),
(-65537, &[2, 3, 254, 255, 255]),
(-65536, &[2, 3, 255, 0, 0]),
(-32769, &[2, 3, 255, 127, 255]),
(-32768, &[2, 2, 128, 0]),
(-129, &[2, 2, 255, 127]),
(-128, &[2, 1, 128]),
(-1, &[2, 1, 255]),
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
(65536, &[2, 3, 1, 0, 0]),
(9223372036854775807, &[2, 8, 127, 255, 255, 255, 255, 255, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_i64(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_u64() {
let tests : &[(u64, &[u8])] = &[
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
(65536, &[2, 3, 1, 0, 0]),
(9223372036854775807, &[2, 8, 127, 255, 255, 255, 255, 255, 255, 255]),
(18446744073709551615,
&[2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_u64(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_i32() {
let tests : &[(i32, &[u8])] = &[
(-2147483648, &[2, 4, 128, 0, 0, 0]),
(-65537, &[2, 3, 254, 255, 255]),
(-65536, &[2, 3, 255, 0, 0]),
(-32769, &[2, 3, 255, 127, 255]),
(-32768, &[2, 2, 128, 0]),
(-129, &[2, 2, 255, 127]),
(-128, &[2, 1, 128]),
(-1, &[2, 1, 255]),
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
(65536, &[2, 3, 1, 0, 0]),
(2147483647, &[2, 4, 127, 255, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_i32(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_u32() {
let tests : &[(u32, &[u8])] = &[
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
(65536, &[2, 3, 1, 0, 0]),
(2147483647, &[2, 4, 127, 255, 255, 255]),
(4294967295, &[2, 5, 0, 255, 255, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_u32(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_i16() {
let tests : &[(i16, &[u8])] = &[
(-32768, &[2, 2, 128, 0]),
(-129, &[2, 2, 255, 127]),
(-128, &[2, 1, 128]),
(-1, &[2, 1, 255]),
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_i16(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_u16() {
let tests : &[(u16, &[u8])] = &[
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_u16(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_i8() {
let tests : &[(i8, &[u8])] = &[
(-128, &[2, 1, 128]),
(-1, &[2, 1, 255]),
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_i8(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_u8() {
let tests : &[(u8, &[u8])] = &[
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(255, &[2, 2, 0, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_u8(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_bigint_bytes() {
let tests: &[(_, &[_], &[_])] = &[
// First group: identical to test_der_write_bigint
(false, &(-9223372036854775808_i64).to_be_bytes(), &[2, 8, 128, 0, 0, 0, 0, 0, 0, 0]),
(false, &(-65537_i32).to_be_bytes(), &[2, 3, 254, 255, 255]),
(false, &(-65536_i32).to_be_bytes(), &[2, 3, 255, 0, 0]),
(false, &(-32769_i32).to_be_bytes(), &[2, 3, 255, 127, 255]),
(false, &(-32768_i32).to_be_bytes(), &[2, 2, 128, 0]),
(false, &(-129_i16).to_be_bytes(), &[2, 2, 255, 127]),
(false, &(-128_i16).to_be_bytes(), &[2, 1, 128]),
(false, &(-1_i16).to_be_bytes(), &[2, 1, 255]),
(false, &[0], &[2, 1, 0]),
(true, &[1], &[2, 1, 1]),
(true, &127_i16.to_be_bytes(), &[2, 1, 127]),
(true, &128_i16.to_be_bytes(), &[2, 2, 0, 128]),
(true, &32767_u16.to_be_bytes(), &[2, 2, 127, 255]),
(true, &32768_u16.to_be_bytes(), &[2, 3, 0, 128, 0]),
(true, &65535_u16.to_be_bytes(), &[2, 3, 0, 255, 255]),
(true, &65536_u32.to_be_bytes(), &[2, 3, 1, 0, 0]),
(true, &9223372036854775807_u64.to_be_bytes(), &[2, 8, 127, 255, 255, 255, 255, 255, 255, 255]),
// Second group: more special tests
// Leading zeros are stripped:
(true, &[0, 1, 2, 3], &[2, 3, 1, 2, 3]),
(true, &[0, 0, 1, 2, 3], &[2, 3, 1, 2, 3]),
(true, &[0, 0, 0, 1, 2, 3], &[2, 3, 1, 2, 3]),
// [255, 0] is a fixpoint of normalization (it encodes -256):
(false, &[255, 0], &[2, 2, 255, 0]),
];
for &(is_nonnegative, ref value, edata) in tests {
let data = construct_der(|writer| {
writer.write_bigint_bytes(*value, is_nonnegative)
});
assert_eq!(data, edata);
}
}
#[cfg(feature = "num-bigint")]
#[test]
fn test_der_write_bigint() {
use num_traits::FromPrimitive;
let tests : &[(i64, &[u8])] = &[
(-9223372036854775808, &[2, 8, 128, 0, 0, 0, 0, 0, 0, 0]),
(-65537, &[2, 3, 254, 255, 255]),
(-65536, &[2, 3, 255, 0, 0]),
(-32769, &[2, 3, 255, 127, 255]),
(-32768, &[2, 2, 128, 0]),
(-129, &[2, 2, 255, 127]),
(-128, &[2, 1, 128]),
(-1, &[2, 1, 255]),
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
(65536, &[2, 3, 1, 0, 0]),
(9223372036854775807, &[2, 8, 127, 255, 255, 255, 255, 255, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_bigint(&BigInt::from_i64(value).unwrap())
});
assert_eq!(data, edata);
}
let tests : &[(BigInt, &[u8])] = &[
(BigInt::parse_bytes(
b"1234567890123456789012345678901234567890", 10).unwrap(),
&[2, 17, 3, 160, 201, 32, 117, 192, 219,
243, 184, 172, 188, 95, 150, 206, 63, 10, 210]),
(BigInt::parse_bytes(
b"-1234567890123456789012345678901234567890", 10).unwrap(),
&[2, 17, 252, 95, 54, 223, 138, 63, 36,
12, 71, 83, 67, 160, 105, 49, 192, 245, 46]),
];
for &(ref value, edata) in tests {
let data = construct_der(|writer| {
writer.write_bigint(value)
});
assert_eq!(data, edata);
}
}
#[cfg(feature = "num-bigint")]
#[test]
fn test_der_write_biguint() {
use num_traits::FromPrimitive;
let tests : &[(u64, &[u8])] = &[
(0, &[2, 1, 0]),
(1, &[2, 1, 1]),
(127, &[2, 1, 127]),
(128, &[2, 2, 0, 128]),
(32767, &[2, 2, 127, 255]),
(32768, &[2, 3, 0, 128, 0]),
(65535, &[2, 3, 0, 255, 255]),
(65536, &[2, 3, 1, 0, 0]),
(9223372036854775807, &[2, 8, 127, 255, 255, 255, 255, 255, 255, 255]),
(18446744073709551615,
&[2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_biguint(&BigUint::from_u64(value).unwrap())
});
assert_eq!(data, edata);
}
let tests : &[(BigUint, &[u8])] = &[
(BigUint::parse_bytes(
b"1234567890123456789012345678901234567890", 10).unwrap(),
&[2, 17, 3, 160, 201, 32, 117, 192, 219,
243, 184, 172, 188, 95, 150, 206, 63, 10, 210]),
];
for &(ref value, edata) in tests {
let data = construct_der(|writer| {
writer.write_biguint(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_bytes() {
let tests : &[(&[u8], &[u8])] = &[
(&[1, 0, 100, 255], &[4, 4, 1, 0, 100, 255]),
(&[], &[4, 0]),
(&[4, 4, 4, 4], &[4, 4, 4, 4, 4, 4]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_bytes(value)
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_null() {
let data = construct_der(|writer| {
writer.write_null()
});
assert_eq!(data, vec![5, 0]);
}
#[test]
fn test_der_write_sequence_small() {
let data = construct_der(|writer| {
writer.write_sequence(|_| {})
});
assert_eq!(data, vec![48, 0]);
let data = construct_der(|writer| {
writer.write_sequence(|writer| {
writer.next().write_bytes(&vec![91; 20]);
})
});
assert_eq!(data, vec![
48, 22, 4, 20, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91]);
let data = construct_der(|writer| {
writer.write_sequence(|writer| {
writer.next().write_bytes(&vec![91; 200]);
})
});
assert_eq!(data[0..9].to_vec(),
vec![48, 129, 203, 4, 129, 200, 91, 91, 91]);
assert_eq!(data.len(), 206);
let data = construct_der(|writer| {
writer.write_sequence(|writer| {
writer.next().write_bytes(&vec![91; 2000]);
})
});
assert_eq!(data[0..11].to_vec(),
vec![48, 130, 7, 212, 4, 130, 7, 208, 91, 91, 91]);
assert_eq!(data.len(), 2008);
}
#[test]
fn test_der_write_sequence_medium() {
let data = construct_der(|writer| {
writer.write_sequence(|writer| {
writer.next().write_bytes(&vec![91; 200000]);
})
});
assert_eq!(data[0..13].to_vec(),
vec![48, 131, 3, 13, 69, 4, 131, 3, 13, 64, 91, 91, 91]);
assert_eq!(data.len(), 200010);
}
#[test]
#[ignore]
fn test_der_write_sequence_large() {
let data = construct_der(|writer| {
writer.write_sequence(|writer| {
writer.next().write_bytes(&vec![91; 20000000]);
})
});
assert_eq!(data[0..15].to_vec(),
vec![48, 132, 1, 49, 45, 6, 4, 132, 1, 49, 45, 0, 91, 91, 91]);
assert_eq!(data.len(), 20000012);
}
#[test]
fn test_der_write_set() {
let data = construct_der(|writer| {
writer.write_set(|writer| {
writer.next().write_tagged_implicit(Tag::context(28), |writer| {
writer.write_i64(456789)
});
writer.next().write_tagged(Tag::context(345678), |writer| {
writer.write_bytes(b"Foo")
});
writer.next().write_tagged(Tag::context(27), |writer| {
writer.write_i64(456790)
});
writer.next().write_tagged(Tag::context(345677), |writer| {
writer.write_bytes(b"Bar")
});
})
});
assert_eq!(data, vec![
49, 32, 187, 5, 2, 3, 6, 248, 86, 156, 3, 6, 248, 85, 191, 149, 140,
77, 5, 4, 3, 66, 97, 114, 191, 149, 140, 78, 5, 4, 3, 70, 111, 111]);
}
#[test]
fn test_der_write_set_of() {
let tests : &[(&[i64], &[u8])] = &[
(&[-129, -128, 127, 128], &[
49, 14, 2, 1, 127, 2, 1, 128, 2, 2, 0, 128, 2, 2, 255, 127]),
(&[-128, 127, 128], &[
49, 10, 2, 1, 127, 2, 1, 128, 2, 2, 0, 128]),
(&[-129, -128, 127, 128, 32768], &[
49, 19, 2, 1, 127, 2, 1, 128, 2, 2, 0, 128, 2, 2, 255, 127,
2, 3, 0, 128, 0]),
];
for &(value, edata) in tests {
let data = construct_der(|writer| {
writer.write_set_of(|writer| {
for &x in value {
writer.next().write_i64(x);
}
})
});
assert_eq!(data, edata);
}
}
#[test]
fn test_der_write_tagged() {
let data = construct_der(|writer| {
writer.write_tagged(Tag::context(3), |writer| {
writer.write_i64(10)
})
});
assert_eq!(data, vec![163, 3, 2, 1, 10]);
}
#[test]
fn test_der_write_tagged_implicit() {
let data = construct_der(|writer| {
writer.write_tagged_implicit(Tag::context(3), |writer| {
writer.write_i64(10)
})
});
assert_eq!(data, vec![131, 1, 10]);
}