Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions der/src/asn1/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
asn1::*, ByteSlice, Choice, Decode, DecodeValue, Decoder, DerOrd, EncodeValue, Encoder, Error,
ErrorKind, FixedTag, Header, Length, Result, Tag, Tagged, ValueOrd,
ErrorKind, FixedTag, Header, Length, Result, Tag, Tagged, ValueOrd, Writer,
};
use core::cmp::Ordering;

Expand Down Expand Up @@ -168,7 +168,7 @@ impl EncodeValue for Any<'_> {
}

fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
encoder.bytes(self.value())
encoder.write(self.value())
}
}

Expand Down
6 changes: 3 additions & 3 deletions der/src/asn1/bit_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
asn1::Any, ByteSlice, DecodeValue, Decoder, DerOrd, EncodeValue, Encoder, Error, ErrorKind,
FixedTag, Header, Length, Result, Tag, ValueOrd,
FixedTag, Header, Length, Result, Tag, ValueOrd, Writer,
};
use core::{cmp::Ordering, iter::FusedIterator};

Expand Down Expand Up @@ -134,8 +134,8 @@ impl EncodeValue for BitString<'_> {
}

fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
encoder.byte(self.unused_bits)?;
encoder.bytes(self.raw_bytes())
encoder.write_byte(self.unused_bits)?;
encoder.write(self.raw_bytes())
}
}

Expand Down
4 changes: 2 additions & 2 deletions der/src/asn1/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
asn1::Any, ord::OrdIsValueOrd, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error,
ErrorKind, FixedTag, Header, Length, Result, Tag,
ErrorKind, FixedTag, Header, Length, Result, Tag, Writer,
};

/// Byte used to encode `true` in ASN.1 DER. From X.690 Section 11.1:
Expand Down Expand Up @@ -34,7 +34,7 @@ impl EncodeValue for bool {
}

fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
encoder.byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
encoder.write_byte(if *self { TRUE_OCTET } else { FALSE_OCTET })
}
}

Expand Down
4 changes: 2 additions & 2 deletions der/src/asn1/generalized_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
datetime::{self, DateTime},
ord::OrdIsValueOrd,
ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, ErrorKind, FixedTag, Header,
Length, Result, Tag,
Length, Result, Tag, Writer,
};
use core::time::Duration;

Expand Down Expand Up @@ -115,7 +115,7 @@ impl EncodeValue for GeneralizedTime {
datetime::encode_decimal(encoder, Self::TAG, self.0.hour())?;
datetime::encode_decimal(encoder, Self::TAG, self.0.minutes())?;
datetime::encode_decimal(encoder, Self::TAG, self.0.seconds())?;
encoder.byte(b'Z')
encoder.write_byte(b'Z')
}
}

Expand Down
6 changes: 3 additions & 3 deletions der/src/asn1/integer/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::uint;
use crate::{
asn1::Any, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, ErrorKind, FixedTag,
Header, Length, Result, Tag,
Header, Length, Result, Tag, Writer,
};

/// "Big" unsigned ASN.1 `INTEGER` type.
Expand Down Expand Up @@ -67,10 +67,10 @@ impl<'a> EncodeValue for UIntBytes<'a> {
fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
// Add leading `0x00` byte if required
if self.value_len()? > self.len() {
encoder.byte(0)?;
encoder.write_byte(0)?;
}

encoder.bytes(self.as_bytes())
encoder.write(self.as_bytes())
}
}

Expand Down
4 changes: 2 additions & 2 deletions der/src/asn1/integer/int.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Support for encoding negative integers

use super::is_highest_bit_set;
use crate::{Encoder, ErrorKind, Length, Result};
use crate::{Encoder, ErrorKind, Length, Result, Writer};

/// Decode an unsigned integer of the specified size.
///
Expand All @@ -28,7 +28,7 @@ pub(super) fn decode_to_array<const N: usize>(bytes: &[u8]) -> Result<[u8; N]> {

/// Encode the given big endian bytes representing an integer as ASN.1 DER.
pub(super) fn encode_bytes(encoder: &mut Encoder<'_>, bytes: &[u8]) -> Result<()> {
encoder.bytes(strip_leading_ones(bytes))
encoder.write(strip_leading_ones(bytes))
}

/// Get the encoded length for the given unsigned integer serialized as bytes.
Expand Down
6 changes: 3 additions & 3 deletions der/src/asn1/integer/uint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Unsigned integer decoders/encoders.

use crate::{Encoder, Length, Result, Tag};
use crate::{Encoder, Length, Result, Tag, Writer};

/// Decode an unsigned integer into a big endian byte slice with all leading
/// zeroes removed.
Expand Down Expand Up @@ -44,10 +44,10 @@ pub(crate) fn encode_bytes(encoder: &mut Encoder<'_>, bytes: &[u8]) -> Result<()
let bytes = strip_leading_zeroes(bytes);

if needs_leading_zero(bytes) {
encoder.byte(0)?;
encoder.write_byte(0)?;
}

encoder.bytes(bytes)
encoder.write(bytes)
}

/// Get the encoded length for the given unsigned integer serialized as bytes.
Expand Down
4 changes: 2 additions & 2 deletions der/src/asn1/oid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
asn1::Any, ord::OrdIsValueOrd, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error,
FixedTag, Header, Length, Result, Tag, Tagged,
FixedTag, Header, Length, Result, Tag, Tagged, Writer,
};
use const_oid::ObjectIdentifier;

Expand All @@ -19,7 +19,7 @@ impl EncodeValue for ObjectIdentifier {
}

fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
encoder.bytes(self.as_bytes())
encoder.write(self.as_bytes())
}
}

Expand Down
16 changes: 8 additions & 8 deletions der/src/asn1/real.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

use crate::{
str_slice::StrSlice, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, FixedTag, Header,
Length, Result, Tag,
Length, Result, Tag, Writer,
};

use super::integer::uint::strip_leading_zeroes;
Expand Down Expand Up @@ -136,18 +136,18 @@ impl EncodeValue for f64 {
return Ok(());
} else if self.is_nan() {
// Not a number
encoder.bytes(&[0b0100_0010])?;
encoder.write_byte(0b0100_0010)?;
} else if self.is_infinite() {
if self.is_sign_negative() {
// Negative infinity
encoder.bytes(&[0b0100_0001])?;
encoder.write_byte(0b0100_0001)?;
} else {
// Plus infinity
encoder.bytes(&[0b0100_0000])?;
encoder.write_byte(0b0100_0000)?;
}
} else {
// Minus zero
encoder.bytes(&[0b0100_0011])?;
encoder.write_byte(0b0100_0011)?;
}
} else {
// Always use binary encoding, set bit 8 to 1
Expand Down Expand Up @@ -178,16 +178,16 @@ impl EncodeValue for f64 {
}
}

encoder.bytes(&[first_byte])?;
encoder.write_byte(first_byte)?;

// Encode both bytes or just the last one, handled by encode_bytes directly
// Rust already encodes the data as two's complement, so no further processing is needed
encoder.bytes(ebytes)?;
encoder.write(ebytes)?;

// Now, encode the mantissa as unsigned binary number
let mantissa_bytes = mantissa.to_be_bytes();
let mbytes = strip_leading_zeroes(&mantissa_bytes);
encoder.bytes(mbytes)?;
encoder.write(mbytes)?;
}
Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions der/src/asn1/utc_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
datetime::{self, DateTime},
ord::OrdIsValueOrd,
ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, ErrorKind, FixedTag, Header,
Length, Result, Tag,
Length, Result, Tag, Writer,
};
use core::time::Duration;

Expand Down Expand Up @@ -128,7 +128,7 @@ impl EncodeValue for UtcTime {
datetime::encode_decimal(encoder, Self::TAG, self.0.hour())?;
datetime::encode_decimal(encoder, Self::TAG, self.0.minutes())?;
datetime::encode_decimal(encoder, Self::TAG, self.0.seconds())?;
encoder.byte(b'Z')
encoder.write_byte(b'Z')
}
}

Expand Down
4 changes: 2 additions & 2 deletions der/src/byte_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::{
str_slice::StrSlice, DecodeValue, Decoder, DerOrd, EncodeValue, Encoder, Error, Header, Length,
Result,
Result, Writer,
};
use core::cmp::Ordering;

Expand Down Expand Up @@ -67,7 +67,7 @@ impl EncodeValue for ByteSlice<'_> {
}

fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
encoder.bytes(self.as_ref())
encoder.write(self.as_ref())
}
}

Expand Down
8 changes: 3 additions & 5 deletions der/src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Copyright (c) 2016 The humantime Developers
// Released under the MIT OR Apache 2.0 licenses

use crate::{Encoder, Error, ErrorKind, Result, Tag};
use crate::{Encoder, Error, ErrorKind, Result, Tag, Writer};
use core::{fmt, str::FromStr, time::Duration};

#[cfg(feature = "std")]
Expand Down Expand Up @@ -372,17 +372,15 @@ pub(crate) fn decode_decimal(tag: Tag, hi: u8, lo: u8) -> Result<u8> {
}

/// Encode 2-digit decimal value
// TODO(tarcieri): checked arithmetic
#[allow(clippy::integer_arithmetic)]
pub(crate) fn encode_decimal(encoder: &mut Encoder<'_>, tag: Tag, value: u8) -> Result<()> {
let hi_val = value / 10;

if hi_val >= 10 {
return Err(tag.value_error());
}

encoder.byte(hi_val + b'0')?;
encoder.byte((value % 10) + b'0')
encoder.write_byte(b'0'.checked_add(hi_val).ok_or(ErrorKind::Overflow)?)?;
encoder.write_byte(b'0'.checked_add(value % 10).ok_or(ErrorKind::Overflow)?)
}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions der/src/document.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! ASN.1 DER-encoded documents stored on the heap.

use crate::{Decode, Decoder, Encode, Encoder, Error, FixedTag, Length, Result, Tag};
use crate::{Decode, Decoder, Encode, Encoder, Error, FixedTag, Length, Result, Tag, Writer};
use alloc::vec::Vec;
use core::fmt::{self, Debug};

Expand Down Expand Up @@ -166,7 +166,7 @@ impl Encode for Document {
}

fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()> {
encoder.bytes(self.as_bytes())
encoder.write(self.as_bytes())
}
}

Expand Down
26 changes: 8 additions & 18 deletions der/src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
asn1::*, Encode, EncodeRef, EncodeValue, Error, ErrorKind, Header, Length, Result, Tag,
TagMode, TagNumber, Tagged,
TagMode, TagNumber, Tagged, Writer,
};

/// DER encoder.
Expand Down Expand Up @@ -213,23 +213,6 @@ impl<'a> Encoder<'a> {
Ok(slice)
}

/// Encode a single byte into the backing buffer.
pub(crate) fn byte(&mut self, byte: u8) -> Result<()> {
match self.reserve(1u8)?.first_mut() {
Some(b) => {
*b = byte;
Ok(())
}
None => self.error(ErrorKind::Overlength),
}
}

/// Encode the provided byte slice into the backing buffer.
pub(crate) fn bytes(&mut self, slice: &[u8]) -> Result<()> {
self.reserve(slice.len())?.copy_from_slice(slice);
Ok(())
}

/// Get the size of the buffer in bytes.
fn buffer_len(&self) -> Result<Length> {
self.bytes
Expand All @@ -250,6 +233,13 @@ impl<'a> Encoder<'a> {
}
}

impl<'a> Writer for Encoder<'a> {
fn write(&mut self, slice: &[u8]) -> Result<()> {
self.reserve(slice.len())?.copy_from_slice(slice);
Ok(())
}
}

#[cfg(test)]
mod tests {
use hex_literal::hex;
Expand Down
14 changes: 7 additions & 7 deletions der/src/length.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Length calculations for encoded ASN.1 DER values

use crate::{Decode, Decoder, DerOrd, Encode, Encoder, Error, ErrorKind, Result};
use crate::{Decode, Decoder, DerOrd, Encode, Encoder, Error, ErrorKind, Result, Writer};
use core::{
cmp::Ordering,
fmt,
Expand Down Expand Up @@ -241,17 +241,17 @@ impl Encode for Length {
#[allow(clippy::cast_possible_truncation)]
fn encode(&self, encoder: &mut Encoder<'_>) -> Result<()> {
if let Some(tag_byte) = self.initial_octet() {
encoder.byte(tag_byte)?;
encoder.write_byte(tag_byte)?;

// Strip leading zeroes
match self.0.to_be_bytes() {
[0, 0, 0, byte] => encoder.byte(byte),
[0, 0, bytes @ ..] => encoder.bytes(&bytes),
[0, bytes @ ..] => encoder.bytes(&bytes),
bytes => encoder.bytes(&bytes),
[0, 0, 0, byte] => encoder.write_byte(byte),
[0, 0, bytes @ ..] => encoder.write(&bytes),
[0, bytes @ ..] => encoder.write(&bytes),
bytes => encoder.write(&bytes),
}
} else {
encoder.byte(self.0 as u8)
encoder.write_byte(self.0 as u8)
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions der/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ mod length;
mod ord;
mod str_slice;
mod tag;
mod writer;

#[cfg(feature = "alloc")]
mod document;
Expand All @@ -376,6 +377,7 @@ pub use crate::{
length::Length,
ord::{DerOrd, ValueOrd},
tag::{Class, FixedTag, Tag, TagMode, TagNumber, Tagged},
writer::Writer,
};

#[cfg(feature = "alloc")]
Expand Down
Loading