Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

const-oid: make ObjectIdentifier::as_bytes a const fn #1303

Merged
merged 1 commit into from
Jan 5, 2024
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 .github/workflows/const-oid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
rust:
- 1.60.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -47,7 +47,7 @@ jobs:
strategy:
matrix:
rust:
- 1.60.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/der.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -51,7 +51,7 @@ jobs:
# 32-bit Linux
- targets: i686-unknown-linux-gnu
platform: ubuntu-latest
rust: 1.65.0 # MSRV
rust: 1.71.0 # MSRV
deps: sudo apt update && sudo apt install gcc-multilib
- targets: i686-unknown-linux-gnu
platform: ubuntu-latest
Expand All @@ -61,7 +61,7 @@ jobs:
# 64-bit Linux
- targets: x86_64-unknown-linux-gnu
platform: ubuntu-latest
rust: 1.65.0 # MSRV
rust: 1.71.0 # MSRV
- targets: x86_64-unknown-linux-gnu
platform: ubuntu-latest
rust: stable
Expand All @@ -70,7 +70,7 @@ jobs:
# 64-bit Windows
#- targets: x86_64-pc-windows-msvc
# platform: windows-latest
# rust: 1.65.0 # MSRV
# rust: 1.71.0 # MSRV
#- targets: x86_64-pc-windows-msvc
# platform: windows-latest
# rust: stable
Expand All @@ -90,7 +90,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pkcs1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -52,7 +52,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pkcs5.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -51,7 +51,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pkcs8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -53,7 +53,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/sec1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
strategy:
matrix:
rust:
- 1.70.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -52,7 +52,7 @@ jobs:
strategy:
matrix:
rust:
- 1.70.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/spki.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -51,7 +51,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.71.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion const-oid/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ categories = ["cryptography", "data-structures", "encoding", "no-std", "parser-i
keywords = ["iso", "iec", "itu", "oid"]
readme = "README.md"
edition = "2021"
rust-version = "1.60"
rust-version = "1.71"

[dependencies]
arbitrary = { version = "1.2", optional = true, features = ["derive"] }
Expand Down
4 changes: 2 additions & 2 deletions const-oid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ well as a runtime OID library.

## Minimum Supported Rust Version

This crate requires **Rust 1.65** at a minimum.
This crate requires **Rust 1.71** at a minimum.

We may change the MSRV in the future, but it will be accompanied by a minor
version bump.
Expand All @@ -84,7 +84,7 @@ dual licensed as above, without any additional terms or conditions.
[docs-image]: https://docs.rs/const-oid/badge.svg
[docs-link]: https://docs.rs/const-oid/
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg
[rustc-image]: https://img.shields.io/badge/rustc-1.71+-blue.svg
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/300570-formats
[build-image]: https://github.com/RustCrypto/formats/workflows/const-oid/badge.svg?branch=master&event=push
Expand Down
4 changes: 2 additions & 2 deletions const-oid/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub struct Buffer<const SIZE: usize> {

impl<const SIZE: usize> Buffer<SIZE> {
/// Borrow the inner byte slice.
pub fn as_bytes(&self) -> &[u8] {
&self.bytes[..self.length as usize]
pub const fn as_bytes(&self) -> &[u8] {
self.bytes.split_at(self.length as usize).0
}

/// Get the length of the BER message.
Expand Down
14 changes: 7 additions & 7 deletions const-oid/src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use crate::{

/// BER/DER encoder
#[derive(Debug)]
pub(crate) struct Encoder {
pub(crate) struct Encoder<const MAX_SIZE: usize> {
/// Current state
state: State,

/// Bytes of the OID being encoded in-progress
bytes: [u8; ObjectIdentifier::MAX_SIZE],
bytes: [u8; MAX_SIZE],

/// Current position within the byte buffer
cursor: usize,
Expand All @@ -31,18 +31,18 @@ enum State {
Body,
}

impl Encoder {
impl<const MAX_SIZE: usize> Encoder<MAX_SIZE> {
/// Create a new encoder initialized to an empty default state.
pub(crate) const fn new() -> Self {
Self {
state: State::Initial,
bytes: [0u8; ObjectIdentifier::MAX_SIZE],
bytes: [0u8; MAX_SIZE],
cursor: 0,
}
}

/// Extend an existing OID.
pub(crate) const fn extend(oid: ObjectIdentifier) -> Self {
pub(crate) const fn extend(oid: ObjectIdentifier<MAX_SIZE>) -> Self {
Self {
state: State::Body,
bytes: oid.buffer.bytes,
Expand Down Expand Up @@ -99,7 +99,7 @@ impl Encoder {
}

/// Finish encoding an OID.
pub(crate) const fn finish(self) -> Result<ObjectIdentifier> {
pub(crate) const fn finish(self) -> Result<ObjectIdentifier<MAX_SIZE>> {
if self.cursor >= 2 {
let bytes = Buffer {
bytes: self.bytes,
Expand Down Expand Up @@ -156,7 +156,7 @@ mod tests {

#[test]
fn encode() {
let encoder = Encoder::new();
let encoder = Encoder::<7>::new();
let encoder = encoder.arc(1).unwrap();
let encoder = encoder.arc(2).unwrap();
let encoder = encoder.arc(840).unwrap();
Expand Down
89 changes: 49 additions & 40 deletions const-oid/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,50 +146,15 @@ impl ObjectIdentifier {

Ok(oid)
}

/// Get the parent OID of this one (if applicable).
pub fn parent(&self) -> Option<Self> {
let num_arcs = self.len().checked_sub(1)?;
Self::from_arcs(self.arcs().take(num_arcs)).ok()
}

/// Push an additional arc onto this OID, returning the child OID.
pub const fn push_arc(self, arc: Arc) -> Result<Self> {
// TODO(tarcieri): use `?` when stable in `const fn`
match Encoder::extend(self).arc(arc) {
Ok(encoder) => encoder.finish(),
Err(err) => Err(err),
}
}

/// Does this OID start with the other OID?
pub fn starts_with(&self, other: ObjectIdentifier) -> bool {
let mut self_arcs = self.arcs();

for other_arc in other.arcs() {
match self_arcs.next() {
Some(arc) => {
if arc != other_arc {
return false;
}
}
None => {
return false;
}
}
}

true
}
}

impl<const MAX_SIZE: usize> ObjectIdentifier<MAX_SIZE> {
/// Get the BER/DER serialization of this OID as bytes.
///
/// Note that this encoding omits the tag/length, and only contains the
/// value portion of the encoded OID.
pub fn as_bytes(&self) -> &[u8] {
self.buffer.as_ref()
/// Note that this encoding omits the tag/length, and only contains the value portion of the
/// encoded OID.
pub const fn as_bytes(&self) -> &[u8] {
self.buffer.as_bytes()
}

/// Return the arc with the given index, if it exists.
Expand All @@ -208,11 +173,55 @@ impl<const MAX_SIZE: usize> ObjectIdentifier<MAX_SIZE> {
pub fn len(&self) -> usize {
self.arcs().count()
}

/// Get the parent OID of this one (if applicable).
pub fn parent(&self) -> Option<Self> {
let num_arcs = self.len().checked_sub(1)?;
let mut encoder = Encoder::new();

for arc in self.arcs().take(num_arcs) {
encoder = encoder.arc(arc).ok()?;
}

encoder.finish().ok()
}

/// Push an additional arc onto this OID, returning the child OID.
pub const fn push_arc(self, arc: Arc) -> Result<Self> {
// TODO(tarcieri): use `?` when stable in `const fn`
match Encoder::extend(self).arc(arc) {
Ok(encoder) => encoder.finish(),
Err(err) => Err(err),
}
}

/// Does this OID start with the other OID?
pub const fn starts_with(&self, other: ObjectIdentifier) -> bool {
let len = other.as_bytes().len();

if self.as_bytes().len() < len {
return false;
}

let mut i = 0;
while i < len {
if self.as_bytes()[i] != other.as_bytes()[i] {
return false;
}

match i.checked_add(1) {
Some(succ) => i = succ,
None => return false,
}
}

true
}
}

impl<const MAX_SIZE: usize> AsRef<[u8]> for ObjectIdentifier<MAX_SIZE> {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
self.buffer.as_bytes()
}
}

Expand Down
2 changes: 1 addition & 1 deletion const-oid/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub(crate) struct Parser {
current_arc: Arc,

/// BER/DER encoder
encoder: Encoder,
encoder: Encoder<{ ObjectIdentifier::MAX_SIZE }>,
}

impl Parser {
Expand Down
2 changes: 1 addition & 1 deletion der/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ categories = ["cryptography", "data-structures", "encoding", "no-std", "parser-i
keywords = ["asn1", "crypto", "itu", "pkcs"]
readme = "README.md"
edition = "2021"
rust-version = "1.65"
rust-version = "1.71"

[dependencies]
arbitrary = { version = "1.3", features = ["derive"], optional = true }
Expand Down
Loading