From f11f09997600121da1773aeb334a8c112f874b6f Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Tue, 19 Dec 2023 01:22:27 +0000 Subject: Revert "Upgrade spki to 0.7.3" Revert submission 2877402-der_derive-0.7.2 Reason for revert: b/316953077 Reverted changes: /q/submissionid:2877402-der_derive-0.7.2 Change-Id: I0670fa3dd149fe25fdfdafc27cf534ad43df920f --- .cargo_vcs_info.json | 2 +- Android.bp | 4 +- CHANGELOG.md | 49 ---------------- Cargo.toml | 20 ++----- Cargo.toml.orig | 16 ++--- LICENSE-MIT | 25 -------- METADATA | 26 ++++----- README.md | 4 +- patches/std.diff | 26 +++++++++ src/algorithm.rs | 134 ++++++++++++------------------------------ src/fingerprint.rs | 1 + src/lib.rs | 40 ++++--------- src/spki.rs | 162 ++++++++++++++------------------------------------- src/traits.rs | 128 ++++++---------------------------------- tests/spki.rs | 49 +++++++--------- tests/traits.rs | 14 +++-- 16 files changed, 198 insertions(+), 502 deletions(-) delete mode 100644 LICENSE-MIT diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index a390d72..66cdc9c 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "15ea461dc3484d48710deed932e4d3d9052c1f9b" + "sha1": "d91ca33448c5a3fa8952651160046a37f6b5eef9" }, "path_in_vcs": "spki" } \ No newline at end of file diff --git a/Android.bp b/Android.bp index 7d7b447..f35a356 100644 --- a/Android.bp +++ b/Android.bp @@ -35,7 +35,7 @@ rust_library_host { name: "libspki", crate_name: "spki", cargo_env_compat: true, - cargo_pkg_version: "0.7.3", + cargo_pkg_version: "0.6.0", srcs: ["src/lib.rs"], edition: "2021", features: ["alloc"], @@ -46,7 +46,7 @@ rust_library_rlib { name: "libspki_nostd", crate_name: "spki", cargo_env_compat: true, - cargo_pkg_version: "0.7.3", + cargo_pkg_version: "0.6.0", srcs: ["src/lib.rs"], edition: "2021", features: ["alloc"], diff --git a/CHANGELOG.md b/CHANGELOG.md index cf3722d..ce0f5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,55 +4,6 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 0.7.3 (2023-11-28) -### Added -- public key to `SubjectPublicKeyInfoOwned` helper ([#1269]) - -[#1269]: https://github.com/RustCrypto/formats/pull/1269 - -## 0.7.2 (2023-05-04) - -### Added -- `AlgorithmIdentifierWithOid` trait ([#986]) -- `SignatureBitStringEncoding` trait ([#1047]) - -### Changed -- Bump `hex-literal` to v0.4.1 ([#999]) - -[#986]: https://github.com/RustCrypto/formats/pull/986 -[#999]: https://github.com/RustCrypto/formats/pull/999 -[#1047]: https://github.com/RustCrypto/formats/pull/1047 - - -## 0.7.1 (2023-04-04) -### Added -- `AssociatedAlgorithmIdentifier` trait ([#962], [#966]) -- `DynAssociatedAlgorithmIdentifier` trait ([#962]) -- `SignatureAlgorithmIdentifier` trait ([#967]) -- `DynSignatureAlgorithmIdentifier` trait ([#967]) - -### Changed -- Bump `der` dependency to v0.7.2 ([#979]) - -[#962]: https://github.com/RustCrypto/formats/pull/962 -[#966]: https://github.com/RustCrypto/formats/pull/966 -[#967]: https://github.com/RustCrypto/formats/pull/967 -[#979]: https://github.com/RustCrypto/formats/pull/979 - -## 0.7.0 (2023-02-26) -### Changed -- Make `AlgorithmIdentifier` generic around `Params` ([#769]) -- Use blanket impls for `Decode*` traits ([#785]) -- Make `SubjectPublicKeyInfo` own the public key ([#790]) -- Rename `to_owned` method ([#835]) -- Bump `der` dependency to v0.7 ([#899]) - -[#769]: https://github.com/RustCrypto/formats/pull/769 -[#785]: https://github.com/RustCrypto/formats/pull/785 -[#790]: https://github.com/RustCrypto/formats/pull/790 -[#835]: https://github.com/RustCrypto/formats/pull/835 -[#899]: https://github.com/RustCrypto/formats/pull/899 - ## 0.6.0 (2022-05-08) ### Added - `AlgorithmIdentifier::oids()` helper function ([#443]) diff --git a/Cargo.toml b/Cargo.toml index 1c7f305..20147e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,9 @@ [package] edition = "2021" -rust-version = "1.65" +rust-version = "1.57" name = "spki" -version = "0.7.3" +version = "0.6.0" authors = ["RustCrypto Developers"] description = """ X.509 Subject Public Key Info (RFC5280) describing public keys as well as their @@ -32,6 +32,7 @@ categories = [ ] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/formats/tree/master/spki" +resolver = "2" [package.metadata.docs.rs] all-features = true @@ -40,18 +41,13 @@ rustdoc-args = [ "docsrs", ] -[dependencies.arbitrary] -version = "1.2" -features = ["derive"] -optional = true - [dependencies.base64ct] version = "1" optional = true default-features = false [dependencies.der] -version = "0.7.2" +version = "0.6" features = ["oid"] [dependencies.sha2] @@ -60,7 +56,7 @@ optional = true default-features = false [dev-dependencies.hex-literal] -version = "0.4" +version = "0.3" [dev-dependencies.tempfile] version = "3" @@ -70,12 +66,6 @@ alloc = [ "base64ct?/alloc", "der/alloc", ] -arbitrary = [ - "std", - "dep:arbitrary", - "der/arbitrary", -] -base64 = ["dep:base64ct"] fingerprint = ["sha2"] pem = [ "alloc", diff --git a/Cargo.toml.orig b/Cargo.toml.orig index e9e2687..bb49bd8 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "spki" -version = "0.7.3" +version = "0.6.0" description = """ X.509 Subject Public Key Info (RFC5280) describing public keys as well as their associated AlgorithmIdentifiers (i.e. OIDs) @@ -12,28 +12,24 @@ categories = ["cryptography", "data-structures", "encoding", "no-std"] keywords = ["crypto", "x509"] readme = "README.md" edition = "2021" -rust-version = "1.65" +rust-version = "1.57" [dependencies] -der = { version = "0.7.2", features = ["oid"] } +der = { version = "0.6", features = ["oid"], path = "../der" } # Optional dependencies -arbitrary = { version = "1.2", features = ["derive"], optional = true } -base64ct = { version = "1", optional = true, default-features = false } sha2 = { version = "0.10", optional = true, default-features = false } +base64ct = { version = "1", path = "../base64ct", optional = true, default-features = false } [dev-dependencies] -hex-literal = "0.4" +hex-literal = "0.3" tempfile = "3" [features] alloc = ["base64ct?/alloc", "der/alloc"] -std = ["der/std", "alloc"] - -arbitrary = ["std", "dep:arbitrary", "der/arbitrary"] -base64 = ["dep:base64ct"] fingerprint = ["sha2"] pem = ["alloc", "der/pem"] +std = ["der/std", "alloc"] [package.metadata.docs.rs] all-features = true diff --git a/LICENSE-MIT b/LICENSE-MIT deleted file mode 100644 index 3294d74..0000000 --- a/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2021-2023 The RustCrypto Project Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/METADATA b/METADATA index 0fa8081..6ce048a 100644 --- a/METADATA +++ b/METADATA @@ -1,20 +1,20 @@ -# This project was upgraded with external_updater. -# Usage: tools/external_updater/updater.sh update rust/crates/spki -# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md - name: "spki" description: "X.509 Subject Public Key Info types describing public keys as well as their associated AlgorithmIdentifiers (i.e. OIDs)." third_party { + url { + type: HOMEPAGE + value: "https://crates.io/crates/spki" + } + url { + type: ARCHIVE + value: "https://static.crates.io/crates/spki/spki-0.6.0.crate" + } + version: "0.6.0" + # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same. license_type: NOTICE last_upgrade_date { - year: 2023 - month: 12 - day: 15 - } - homepage: "https://crates.io/crates/spki" - identifier { - type: "Archive" - value: "https://static.crates.io/crates/spki/spki-0.7.3.crate" - version: "0.7.3" + year: 2022 + month: 9 + day: 6 } } diff --git a/README.md b/README.md index 4ac8554..caa01cc 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Specified in [RFC 5280 § 4.1]. ## Minimum Supported Rust Version -This crate requires **Rust 1.65** at a minimum. +This crate requires **Rust 1.57** at a minimum. We may change the MSRV in the future, but it will be accompanied by a minor version bump. @@ -45,7 +45,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/formats/actions/workflows/spki.yml/badge.svg [build-link]: https://github.com/RustCrypto/formats/actions/workflows/spki.yml [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.57+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/300570-formats diff --git a/patches/std.diff b/patches/std.diff index 7ef1d49..cf6bd2e 100644 --- a/patches/std.diff +++ b/patches/std.diff @@ -1,3 +1,16 @@ +diff --git a/Cargo.toml b/Cargo.toml +index 13205cb..20147e1 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -63,7 +63,7 @@ version = "3" + + [features] + alloc = [ +- "base64ct/alloc", ++ "base64ct?/alloc", + "der/alloc", + ] + fingerprint = ["sha2"] diff --git a/src/lib.rs b/src/lib.rs index f466756..995f3bd 100644 --- a/src/lib.rs @@ -12,3 +25,16 @@ index f466756..995f3bd 100644 + #[cfg(feature = "alloc")] pub use {crate::traits::EncodePublicKey, der::Document}; +diff --git a/Cargo.toml.orig b/Cargo.toml.orig +index e7138a7..be1a9f6 100644 +--- a/Cargo.toml.orig ++++ b/Cargo.toml.orig +@@ -26,7 +26,7 @@ hex-literal = "0.3" + tempfile = "3" + + [features] +-alloc = ["base64ct/alloc", "der/alloc"] ++alloc = ["base64ct?/alloc", "der/alloc"] + fingerprint = ["sha2"] + pem = ["alloc", "der/pem"] + std = ["der/std", "alloc"] diff --git a/src/algorithm.rs b/src/algorithm.rs index 5f4b5e8..2a8b6c7 100644 --- a/src/algorithm.rs +++ b/src/algorithm.rs @@ -2,14 +2,8 @@ use crate::{Error, Result}; use core::cmp::Ordering; -use der::{ - asn1::{AnyRef, Choice, ObjectIdentifier}, - Decode, DecodeValue, DerOrd, Encode, EncodeValue, Header, Length, Reader, Sequence, ValueOrd, - Writer, -}; - -#[cfg(feature = "alloc")] -use der::asn1::Any; +use der::asn1::{AnyRef, ObjectIdentifier}; +use der::{Decode, DecodeValue, DerOrd, Encode, Header, Reader, Sequence, ValueOrd}; /// X.509 `AlgorithmIdentifier` as defined in [RFC 5280 Section 4.1.1.2]. /// @@ -20,82 +14,17 @@ use der::asn1::Any; /// ``` /// /// [RFC 5280 Section 4.1.1.2]: https://tools.ietf.org/html/rfc5280#section-4.1.1.2 -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] -pub struct AlgorithmIdentifier { +pub struct AlgorithmIdentifier<'a> { /// Algorithm OID, i.e. the `algorithm` field in the `AlgorithmIdentifier` /// ASN.1 schema. pub oid: ObjectIdentifier, /// Algorithm `parameters`. - pub parameters: Option, -} - -impl<'a, Params> DecodeValue<'a> for AlgorithmIdentifier -where - Params: Choice<'a>, -{ - fn decode_value>(reader: &mut R, header: Header) -> der::Result { - reader.read_nested(header.length, |reader| { - Ok(Self { - oid: reader.decode()?, - parameters: reader.decode()?, - }) - }) - } -} - -impl EncodeValue for AlgorithmIdentifier -where - Params: Encode, -{ - fn value_len(&self) -> der::Result { - self.oid.encoded_len()? + self.parameters.encoded_len()? - } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - self.oid.encode(writer)?; - self.parameters.encode(writer)?; - Ok(()) - } + pub parameters: Option>, } -impl<'a, Params> Sequence<'a> for AlgorithmIdentifier where Params: Choice<'a> + Encode {} - -impl<'a, Params> TryFrom<&'a [u8]> for AlgorithmIdentifier -where - Params: Choice<'a> + Encode, -{ - type Error = Error; - - fn try_from(bytes: &'a [u8]) -> Result { - Ok(Self::from_der(bytes)?) - } -} - -impl ValueOrd for AlgorithmIdentifier -where - Params: DerOrd, -{ - fn value_cmp(&self, other: &Self) -> der::Result { - match self.oid.der_cmp(&other.oid)? { - Ordering::Equal => self.parameters.der_cmp(&other.parameters), - other => Ok(other), - } - } -} - -/// `AlgorithmIdentifier` reference which has `AnyRef` parameters. -pub type AlgorithmIdentifierRef<'a> = AlgorithmIdentifier>; - -/// `AlgorithmIdentifier` with `ObjectIdentifier` parameters. -pub type AlgorithmIdentifierWithOid = AlgorithmIdentifier; - -/// `AlgorithmIdentifier` reference which has `Any` parameters. -#[cfg(feature = "alloc")] -pub type AlgorithmIdentifierOwned = AlgorithmIdentifier; - -impl AlgorithmIdentifier { +impl<'a> AlgorithmIdentifier<'a> { /// Assert the `algorithm` OID is an expected value. pub fn assert_algorithm_oid(&self, expected_oid: ObjectIdentifier) -> Result { if self.oid == expected_oid { @@ -104,9 +33,7 @@ impl AlgorithmIdentifier { Err(Error::OidUnknown { oid: expected_oid }) } } -} -impl<'a> AlgorithmIdentifierRef<'a> { /// Assert `parameters` is an OID and has the expected value. pub fn assert_parameters_oid( &self, @@ -160,35 +87,46 @@ impl<'a> AlgorithmIdentifierRef<'a> { None => None, Some(p) => match p { AnyRef::NULL => None, - _ => Some(p.decode_as::()?), + _ => Some(p.oid()?), }, }, )) } } -#[cfg(feature = "alloc")] -mod allocating { - use super::*; - use der::referenced::*; +impl<'a> DecodeValue<'a> for AlgorithmIdentifier<'a> { + fn decode_value>(reader: &mut R, header: Header) -> der::Result { + reader.read_nested(header.length, |reader| { + Ok(Self { + oid: reader.decode()?, + parameters: reader.decode()?, + }) + }) + } +} - impl<'a> RefToOwned<'a> for AlgorithmIdentifierRef<'a> { - type Owned = AlgorithmIdentifierOwned; - fn ref_to_owned(&self) -> Self::Owned { - AlgorithmIdentifier { - oid: self.oid, - parameters: self.parameters.ref_to_owned(), - } - } +impl<'a> Sequence<'a> for AlgorithmIdentifier<'a> { + fn fields(&self, f: F) -> der::Result + where + F: FnOnce(&[&dyn Encode]) -> der::Result, + { + f(&[&self.oid, &self.parameters]) + } +} + +impl<'a> TryFrom<&'a [u8]> for AlgorithmIdentifier<'a> { + type Error = Error; + + fn try_from(bytes: &'a [u8]) -> Result { + Ok(Self::from_der(bytes)?) } +} - impl OwnedToRef for AlgorithmIdentifierOwned { - type Borrowed<'a> = AlgorithmIdentifierRef<'a>; - fn owned_to_ref(&self) -> Self::Borrowed<'_> { - AlgorithmIdentifier { - oid: self.oid, - parameters: self.parameters.owned_to_ref(), - } +impl ValueOrd for AlgorithmIdentifier<'_> { + fn value_cmp(&self, other: &Self) -> der::Result { + match self.oid.der_cmp(&other.oid)? { + Ordering::Equal => self.parameters.der_cmp(&other.parameters), + other => Ok(other), } } } diff --git a/src/fingerprint.rs b/src/fingerprint.rs index ba06e62..6a3901f 100644 --- a/src/fingerprint.rs +++ b/src/fingerprint.rs @@ -12,6 +12,7 @@ pub(crate) const SIZE: usize = 32; /// See [RFC7469 § 2.1.1] for more information. /// /// [RFC7469 § 2.1.1]: https://datatracker.ietf.org/doc/html/rfc7469#section-2.1.1 +#[cfg_attr(docsrs, doc(cfg(feature = "fingerprint")))] pub type FingerprintBytes = [u8; SIZE]; /// Writer newtype which accepts DER being serialized on-the-fly and computes a diff --git a/src/lib.rs b/src/lib.rs index a8b7653..995f3bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,19 +1,13 @@ #![no_std] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc = include_str!("../README.md")] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" -)] -#![forbid(unsafe_code)] -#![warn( - clippy::mod_module_files, - clippy::unwrap_used, - missing_docs, - rust_2018_idioms, - unused_lifetimes, - unused_qualifications + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] +#![forbid(unsafe_code, clippy::unwrap_used)] +#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] + //! # Usage //! The following example demonstrates how to use an OID as the `parameters` //! of an [`AlgorithmIdentifier`]. @@ -21,14 +15,14 @@ //! Borrow the [`ObjectIdentifier`] first then use [`der::AnyRef::from`] or `.into()`: //! //! ``` -//! use spki::{AlgorithmIdentifier, ObjectIdentifier}; +//! use spki::{AlgorithmIdentifier, ObjectIdentifier, der::AnyRef}; //! //! let alg_oid = "1.2.840.10045.2.1".parse::().unwrap(); //! let params_oid = "1.2.840.10045.3.1.7".parse::().unwrap(); //! //! let alg_id = AlgorithmIdentifier { //! oid: alg_oid, -//! parameters: Some(params_oid) +//! parameters: Some(AnyRef::from(¶ms_oid)) //! }; //! ``` @@ -47,10 +41,10 @@ mod traits; mod fingerprint; pub use crate::{ - algorithm::{AlgorithmIdentifier, AlgorithmIdentifierRef, AlgorithmIdentifierWithOid}, + algorithm::AlgorithmIdentifier, error::{Error, Result}, - spki::{SubjectPublicKeyInfo, SubjectPublicKeyInfoRef}, - traits::{AssociatedAlgorithmIdentifier, DecodePublicKey, SignatureAlgorithmIdentifier}, + spki::SubjectPublicKeyInfo, + traits::DecodePublicKey, }; pub use der::{self, asn1::ObjectIdentifier}; @@ -59,17 +53,7 @@ pub use der::{self, asn1::ObjectIdentifier}; extern crate std; #[cfg(feature = "alloc")] -pub use { - crate::{ - algorithm::AlgorithmIdentifierOwned, - spki::SubjectPublicKeyInfoOwned, - traits::{ - DynAssociatedAlgorithmIdentifier, DynSignatureAlgorithmIdentifier, EncodePublicKey, - SignatureBitStringEncoding, - }, - }, - der::Document, -}; +pub use {crate::traits::EncodePublicKey, der::Document}; #[cfg(feature = "fingerprint")] pub use crate::fingerprint::FingerprintBytes; diff --git a/src/spki.rs b/src/spki.rs index b7e4c92..9058e49 100644 --- a/src/spki.rs +++ b/src/spki.rs @@ -3,30 +3,24 @@ use crate::{AlgorithmIdentifier, Error, Result}; use core::cmp::Ordering; use der::{ - asn1::{AnyRef, BitStringRef}, - Choice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag, Header, Length, Reader, - Sequence, ValueOrd, Writer, + asn1::BitStringRef, Decode, DecodeValue, DerOrd, Encode, Header, Reader, Sequence, ValueOrd, }; #[cfg(feature = "alloc")] -use der::{ - asn1::{Any, BitString}, - Document, -}; +use der::Document; #[cfg(feature = "fingerprint")] use crate::{fingerprint, FingerprintBytes}; +#[cfg(all(feature = "alloc", feature = "fingerprint"))] +use { + alloc::string::String, + base64ct::{Base64, Encoding}, +}; + #[cfg(feature = "pem")] use der::pem::PemLabel; -/// [`SubjectPublicKeyInfo`] with [`AnyRef`] algorithm parameters, and [`BitStringRef`] params. -pub type SubjectPublicKeyInfoRef<'a> = SubjectPublicKeyInfo, BitStringRef<'a>>; - -/// [`SubjectPublicKeyInfo`] with [`Any`] algorithm parameters, and [`BitString`] params. -#[cfg(feature = "alloc")] -pub type SubjectPublicKeyInfoOwned = SubjectPublicKeyInfo; - /// X.509 `SubjectPublicKeyInfo` (SPKI) as defined in [RFC 5280 § 4.1.2.7]. /// /// ASN.1 structure containing an [`AlgorithmIdentifier`] and public key @@ -39,32 +33,25 @@ pub type SubjectPublicKeyInfoOwned = SubjectPublicKeyInfo; /// ``` /// /// [RFC 5280 § 4.1.2.7]: https://tools.ietf.org/html/rfc5280#section-4.1.2.7 -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SubjectPublicKeyInfo { +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct SubjectPublicKeyInfo<'a> { /// X.509 [`AlgorithmIdentifier`] for the public key type - pub algorithm: AlgorithmIdentifier, + pub algorithm: AlgorithmIdentifier<'a>, /// Public key data - pub subject_public_key: Key, + pub subject_public_key: &'a [u8], } -impl<'a, Params, Key> SubjectPublicKeyInfo -where - Params: Choice<'a> + Encode, - // TODO: replace FixedTag with FixedTag once - // https://github.com/rust-lang/rust/issues/92827 is fixed - Key: Decode<'a> + Encode + FixedTag, -{ +impl<'a> SubjectPublicKeyInfo<'a> { /// Calculate the SHA-256 fingerprint of this [`SubjectPublicKeyInfo`] and /// encode it as a Base64 string. /// /// See [RFC7469 § 2.1.1] for more information. /// /// [RFC7469 § 2.1.1]: https://datatracker.ietf.org/doc/html/rfc7469#section-2.1.1 - #[cfg(all(feature = "fingerprint", feature = "alloc", feature = "base64"))] - pub fn fingerprint_base64(&self) -> Result { - use base64ct::{Base64, Encoding}; + #[cfg(all(feature = "fingerprint", feature = "alloc"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "fingerprint", feature = "alloc"))))] + pub fn fingerprint_base64(&self) -> Result { Ok(Base64::encode_string(&self.fingerprint_bytes()?)) } @@ -75,56 +62,42 @@ where /// /// [RFC7469 § 2.1.1]: https://datatracker.ietf.org/doc/html/rfc7469#section-2.1.1 #[cfg(feature = "fingerprint")] + #[cfg_attr(docsrs, doc(cfg(feature = "fingerprint")))] pub fn fingerprint_bytes(&self) -> Result { let mut builder = fingerprint::Builder::new(); self.encode(&mut builder)?; Ok(builder.finish()) } + + /// Get a [`BitString`] representing the `subject_public_key` + fn bitstring(&self) -> der::Result> { + BitStringRef::from_bytes(self.subject_public_key) + } } -impl<'a: 'k, 'k, Params, Key: 'k> DecodeValue<'a> for SubjectPublicKeyInfo -where - Params: Choice<'a> + Encode, - Key: Decode<'a>, -{ +impl<'a> DecodeValue<'a> for SubjectPublicKeyInfo<'a> { fn decode_value>(reader: &mut R, header: Header) -> der::Result { reader.read_nested(header.length, |reader| { Ok(Self { algorithm: reader.decode()?, - subject_public_key: Key::decode(reader)?, + subject_public_key: BitStringRef::decode(reader)? + .as_bytes() + .ok_or_else(|| der::Tag::BitString.value_error())?, }) }) } } -impl<'a, Params, Key> EncodeValue for SubjectPublicKeyInfo -where - Params: Choice<'a> + Encode, - Key: Encode, -{ - fn value_len(&self) -> der::Result { - self.algorithm.encoded_len()? + self.subject_public_key.encoded_len()? +impl<'a> Sequence<'a> for SubjectPublicKeyInfo<'a> { + fn fields(&self, f: F) -> der::Result + where + F: FnOnce(&[&dyn Encode]) -> der::Result, + { + f(&[&self.algorithm, &self.bitstring()?]) } - - fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { - self.algorithm.encode(writer)?; - self.subject_public_key.encode(writer)?; - Ok(()) - } -} - -impl<'a, Params, Key> Sequence<'a> for SubjectPublicKeyInfo -where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, -{ } -impl<'a, Params, Key> TryFrom<&'a [u8]> for SubjectPublicKeyInfo -where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, -{ +impl<'a> TryFrom<&'a [u8]> for SubjectPublicKeyInfo<'a> { type Error = Error; fn try_from(bytes: &'a [u8]) -> Result { @@ -132,86 +105,37 @@ where } } -impl<'a, Params, Key> ValueOrd for SubjectPublicKeyInfo -where - Params: Choice<'a> + DerOrd + Encode, - Key: ValueOrd, -{ +impl ValueOrd for SubjectPublicKeyInfo<'_> { fn value_cmp(&self, other: &Self) -> der::Result { match self.algorithm.der_cmp(&other.algorithm)? { - Ordering::Equal => self.subject_public_key.value_cmp(&other.subject_public_key), + Ordering::Equal => self.bitstring()?.der_cmp(&other.bitstring()?), other => Ok(other), } } } #[cfg(feature = "alloc")] -impl<'a: 'k, 'k, Params, Key: 'k> TryFrom> for Document -where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, - BitStringRef<'a>: From<&'k Key>, -{ +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +impl TryFrom> for Document { type Error = Error; - fn try_from(spki: SubjectPublicKeyInfo) -> Result { + fn try_from(spki: SubjectPublicKeyInfo<'_>) -> Result { Self::try_from(&spki) } } #[cfg(feature = "alloc")] -impl<'a: 'k, 'k, Params, Key: 'k> TryFrom<&SubjectPublicKeyInfo> for Document -where - Params: Choice<'a> + Encode, - Key: Decode<'a> + Encode + FixedTag, - BitStringRef<'a>: From<&'k Key>, -{ +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] +impl TryFrom<&SubjectPublicKeyInfo<'_>> for Document { type Error = Error; - fn try_from(spki: &SubjectPublicKeyInfo) -> Result { + fn try_from(spki: &SubjectPublicKeyInfo<'_>) -> Result { Ok(Self::encode_msg(spki)?) } } #[cfg(feature = "pem")] -impl PemLabel for SubjectPublicKeyInfo { +#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] +impl PemLabel for SubjectPublicKeyInfo<'_> { const PEM_LABEL: &'static str = "PUBLIC KEY"; } - -#[cfg(feature = "alloc")] -mod allocating { - use super::*; - use crate::EncodePublicKey; - use der::referenced::*; - - impl<'a> RefToOwned<'a> for SubjectPublicKeyInfoRef<'a> { - type Owned = SubjectPublicKeyInfoOwned; - fn ref_to_owned(&self) -> Self::Owned { - SubjectPublicKeyInfo { - algorithm: self.algorithm.ref_to_owned(), - subject_public_key: self.subject_public_key.ref_to_owned(), - } - } - } - - impl OwnedToRef for SubjectPublicKeyInfoOwned { - type Borrowed<'a> = SubjectPublicKeyInfoRef<'a>; - fn owned_to_ref(&self) -> Self::Borrowed<'_> { - SubjectPublicKeyInfo { - algorithm: self.algorithm.owned_to_ref(), - subject_public_key: self.subject_public_key.owned_to_ref(), - } - } - } - - impl SubjectPublicKeyInfoOwned { - /// Create a [`SubjectPublicKeyInfoOwned`] from any object that implements - /// [`EncodePublicKey`]. - pub fn from_key(source: T) -> Result - where - T: EncodePublicKey, - { - Ok(source.to_public_key_der()?.decode_msg::()?) - } - } -} diff --git a/src/traits.rs b/src/traits.rs index 764b02a..c16e397 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,13 +1,9 @@ //! Traits for encoding/decoding SPKI public keys. -use crate::{AlgorithmIdentifier, Error, Result, SubjectPublicKeyInfoRef}; -use der::{EncodeValue, Tagged}; +use crate::{Error, Result, SubjectPublicKeyInfo}; #[cfg(feature = "alloc")] -use { - crate::AlgorithmIdentifierOwned, - der::{asn1::BitString, Any, Document}, -}; +use der::Document; #[cfg(feature = "pem")] use { @@ -18,14 +14,15 @@ use { #[cfg(feature = "std")] use std::path::Path; -#[cfg(doc)] -use crate::SubjectPublicKeyInfo; - /// Parse a public key object from an encoded SPKI document. -pub trait DecodePublicKey: Sized { +pub trait DecodePublicKey: + for<'a> TryFrom, Error = Error> + Sized +{ /// Deserialize object from ASN.1 DER-encoded [`SubjectPublicKeyInfo`] /// (binary format). - fn from_public_key_der(bytes: &[u8]) -> Result; + fn from_public_key_der(bytes: &[u8]) -> Result { + Self::try_from(SubjectPublicKeyInfo::try_from(bytes)?) + } /// Deserialize PEM-encoded [`SubjectPublicKeyInfo`]. /// @@ -35,15 +32,17 @@ pub trait DecodePublicKey: Sized { /// -----BEGIN PUBLIC KEY----- /// ``` #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] fn from_public_key_pem(s: &str) -> Result { let (label, doc) = Document::from_pem(s)?; - SubjectPublicKeyInfoRef::validate_pem_label(label)?; + SubjectPublicKeyInfo::validate_pem_label(label)?; Self::from_public_key_der(doc.as_bytes()) } /// Load public key object from an ASN.1 DER-encoded file on the local /// filesystem (binary format). #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn read_public_key_der_file(path: impl AsRef) -> Result { let doc = Document::read_der_file(path)?; Self::from_public_key_der(doc.as_bytes()) @@ -51,134 +50,45 @@ pub trait DecodePublicKey: Sized { /// Load public key object from a PEM-encoded file on the local filesystem. #[cfg(all(feature = "pem", feature = "std"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "std"))))] fn read_public_key_pem_file(path: impl AsRef) -> Result { let (label, doc) = Document::read_pem_file(path)?; - SubjectPublicKeyInfoRef::validate_pem_label(&label)?; + SubjectPublicKeyInfo::validate_pem_label(&label)?; Self::from_public_key_der(doc.as_bytes()) } } -impl DecodePublicKey for T -where - T: for<'a> TryFrom, Error = Error>, -{ - fn from_public_key_der(bytes: &[u8]) -> Result { - Self::try_from(SubjectPublicKeyInfoRef::try_from(bytes)?) - } -} - /// Serialize a public key object to a SPKI-encoded document. #[cfg(feature = "alloc")] +#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub trait EncodePublicKey { /// Serialize a [`Document`] containing a SPKI-encoded public key. fn to_public_key_der(&self) -> Result; /// Serialize this public key as PEM-encoded SPKI with the given [`LineEnding`]. #[cfg(feature = "pem")] + #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] fn to_public_key_pem(&self, line_ending: LineEnding) -> Result { let doc = self.to_public_key_der()?; - Ok(doc.to_pem(SubjectPublicKeyInfoRef::PEM_LABEL, line_ending)?) + Ok(doc.to_pem(SubjectPublicKeyInfo::PEM_LABEL, line_ending)?) } /// Write ASN.1 DER-encoded public key to the given path #[cfg(feature = "std")] + #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn write_public_key_der_file(&self, path: impl AsRef) -> Result<()> { Ok(self.to_public_key_der()?.write_der_file(path)?) } /// Write ASN.1 DER-encoded public key to the given path #[cfg(all(feature = "pem", feature = "std"))] + #[cfg_attr(docsrs, doc(cfg(all(feature = "pem", feature = "std"))))] fn write_public_key_pem_file( &self, path: impl AsRef, line_ending: LineEnding, ) -> Result<()> { let doc = self.to_public_key_der()?; - Ok(doc.write_pem_file(path, SubjectPublicKeyInfoRef::PEM_LABEL, line_ending)?) - } -} - -/// Returns `AlgorithmIdentifier` associated with the structure. -/// -/// This is useful for e.g. keys for digital signature algorithms. -pub trait AssociatedAlgorithmIdentifier { - /// Algorithm parameters. - type Params: Tagged + EncodeValue; - - /// `AlgorithmIdentifier` for this structure. - const ALGORITHM_IDENTIFIER: AlgorithmIdentifier; -} - -/// Returns `AlgorithmIdentifier` associated with the structure. -/// -/// This is useful for e.g. keys for digital signature algorithms. -#[cfg(feature = "alloc")] -pub trait DynAssociatedAlgorithmIdentifier { - /// `AlgorithmIdentifier` for this structure. - fn algorithm_identifier(&self) -> Result; -} - -#[cfg(feature = "alloc")] -impl DynAssociatedAlgorithmIdentifier for T -where - T: AssociatedAlgorithmIdentifier, -{ - fn algorithm_identifier(&self) -> Result { - Ok(AlgorithmIdentifierOwned { - oid: T::ALGORITHM_IDENTIFIER.oid, - parameters: T::ALGORITHM_IDENTIFIER - .parameters - .as_ref() - .map(Any::encode_from) - .transpose()?, - }) - } -} - -/// Returns `AlgorithmIdentifier` associated with the signature system. -/// -/// Unlike AssociatedAlgorithmIdentifier this is intended to be implemented for public and/or -/// private keys. -pub trait SignatureAlgorithmIdentifier { - /// Algorithm parameters. - type Params: Tagged + EncodeValue; - - /// `AlgorithmIdentifier` for the corresponding singature system. - const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier; -} - -/// Returns `AlgorithmIdentifier` associated with the signature system. -/// -/// Unlike AssociatedAlgorithmIdentifier this is intended to be implemented for public and/or -/// private keys. -#[cfg(feature = "alloc")] -pub trait DynSignatureAlgorithmIdentifier { - /// `AlgorithmIdentifier` for the corresponding singature system. - fn signature_algorithm_identifier(&self) -> Result; -} - -#[cfg(feature = "alloc")] -impl DynSignatureAlgorithmIdentifier for T -where - T: SignatureAlgorithmIdentifier, -{ - fn signature_algorithm_identifier(&self) -> Result { - Ok(AlgorithmIdentifierOwned { - oid: T::SIGNATURE_ALGORITHM_IDENTIFIER.oid, - parameters: T::SIGNATURE_ALGORITHM_IDENTIFIER - .parameters - .as_ref() - .map(Any::encode_from) - .transpose()?, - }) + Ok(doc.write_pem_file(path, SubjectPublicKeyInfo::PEM_LABEL, line_ending)?) } } - -/// Returns the `BitString` encoding of the signature. -/// -/// X.509 and CSR structures require signatures to be BitString encoded. -#[cfg(feature = "alloc")] -pub trait SignatureBitStringEncoding { - /// `BitString` encoding for this signature. - fn to_bitstring(&self) -> der::Result; -} diff --git a/tests/spki.rs b/tests/spki.rs index f912d48..3d6b19f 100644 --- a/tests/spki.rs +++ b/tests/spki.rs @@ -1,8 +1,7 @@ //! `SubjectPublicKeyInfo` tests. -use der::asn1::ObjectIdentifier; use hex_literal::hex; -use spki::SubjectPublicKeyInfoRef; +use spki::SubjectPublicKeyInfo; #[cfg(feature = "alloc")] use der::Encode; @@ -35,44 +34,40 @@ const RSA_2048_PEM_EXAMPLE: &str = include_str!("examples/rsa2048-pub.pem"); /// The SPKI fingerprint for `ED25519_SPKI_FINGERPRINT` as a Base64 string /// /// Generated using `cat ed25519-pub.der | openssl dgst -binary -sha256 | base64` -#[cfg(all(feature = "alloc", feature = "base64", feature = "fingerprint"))] +#[cfg(all(feature = "fingerprint", feature = "alloc"))] const ED25519_SPKI_FINGERPRINT_BASE64: &str = "Vd1MdLDkhTTi9OFzzs61DfjyenrCqomRzHrpFOAwvO0="; /// The SPKI fingerprint for `ED25519_SPKI_FINGERPRINT` as straight hash bytes /// /// Generated using `cat ed25519-pub.der | openssl dgst -sha256` -#[cfg(feature = "fingerprint")] +#[cfg(all(feature = "fingerprint"))] const ED25519_SPKI_FINGERPRINT: &[u8] = &hex!("55dd4c74b0e48534e2f4e173ceceb50df8f27a7ac2aa8991cc7ae914e030bced"); #[test] fn decode_ec_p256_der() { - let spki = SubjectPublicKeyInfoRef::try_from(EC_P256_DER_EXAMPLE).unwrap(); + let spki = SubjectPublicKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap(); assert_eq!(spki.algorithm.oid, "1.2.840.10045.2.1".parse().unwrap()); assert_eq!( - spki.algorithm - .parameters - .unwrap() - .decode_as::() - .unwrap(), + spki.algorithm.parameters.unwrap().oid().unwrap(), "1.2.840.10045.3.1.7".parse().unwrap() ); - assert_eq!(spki.subject_public_key.raw_bytes(), &hex!("041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F")[..]); + assert_eq!(spki.subject_public_key, &hex!("041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F")[..]); } #[test] #[cfg(feature = "fingerprint")] fn decode_ed25519_and_fingerprint_spki() { // Repeat the decode test from the pkcs8 crate - let spki = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap(); + let spki = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap(); assert_eq!(spki.algorithm.oid, "1.3.101.112".parse().unwrap()); assert_eq!(spki.algorithm.parameters, None); assert_eq!( - spki.subject_public_key.raw_bytes(), + spki.subject_public_key, &hex!("4D29167F3F1912A6F7ADFA293A051A15C05EC67B8F17267B1C5550DCE853BD0D")[..] ); @@ -84,15 +79,15 @@ fn decode_ed25519_and_fingerprint_spki() { } #[test] -#[cfg(all(feature = "alloc", feature = "base64", feature = "fingerprint"))] +#[cfg(all(feature = "fingerprint", feature = "alloc"))] fn decode_ed25519_and_fingerprint_base64() { // Repeat the decode test from the pkcs8 crate - let spki = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap(); + let spki = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap(); assert_eq!(spki.algorithm.oid, "1.3.101.112".parse().unwrap()); assert_eq!(spki.algorithm.parameters, None); assert_eq!( - spki.subject_public_key.raw_bytes(), + spki.subject_public_key, &hex!("4D29167F3F1912A6F7ADFA293A051A15C05EC67B8F17267B1C5550DCE853BD0D")[..] ); @@ -105,41 +100,41 @@ fn decode_ed25519_and_fingerprint_base64() { #[test] fn decode_rsa_2048_der() { - let spki = SubjectPublicKeyInfoRef::try_from(RSA_2048_DER_EXAMPLE).unwrap(); + let spki = SubjectPublicKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap(); assert_eq!(spki.algorithm.oid, "1.2.840.113549.1.1.1".parse().unwrap()); assert!(spki.algorithm.parameters.unwrap().is_null()); - assert_eq!(spki.subject_public_key.raw_bytes(), &hex!("3082010A0282010100B6C42C515F10A6AAF282C63EDBE24243A170F3FA2633BD4833637F47CA4F6F36E03A5D29EFC3191AC80F390D874B39E30F414FCEC1FCA0ED81E547EDC2CD382C76F61C9018973DB9FA537972A7C701F6B77E0982DFC15FC01927EE5E7CD94B4F599FF07013A7C8281BDF22DCBC9AD7CABB7C4311C982F58EDB7213AD4558B332266D743AED8192D1884CADB8B14739A8DADA66DC970806D9C7AC450CB13D0D7C575FB198534FC61BC41BC0F0574E0E0130C7BBBFBDFDC9F6A6E2E3E2AFF1CBEAC89BA57884528D55CFB08327A1E8C89F4E003CF2888E933241D9D695BCBBACDC90B44E3E095FA37058EA25B13F5E295CBEAC6DE838AB8C50AF61E298975B872F0203010001")[..]); + assert_eq!(spki.subject_public_key, &hex!("3082010A0282010100B6C42C515F10A6AAF282C63EDBE24243A170F3FA2633BD4833637F47CA4F6F36E03A5D29EFC3191AC80F390D874B39E30F414FCEC1FCA0ED81E547EDC2CD382C76F61C9018973DB9FA537972A7C701F6B77E0982DFC15FC01927EE5E7CD94B4F599FF07013A7C8281BDF22DCBC9AD7CABB7C4311C982F58EDB7213AD4558B332266D743AED8192D1884CADB8B14739A8DADA66DC970806D9C7AC450CB13D0D7C575FB198534FC61BC41BC0F0574E0E0130C7BBBFBDFDC9F6A6E2E3E2AFF1CBEAC89BA57884528D55CFB08327A1E8C89F4E003CF2888E933241D9D695BCBBACDC90B44E3E095FA37058EA25B13F5E295CBEAC6DE838AB8C50AF61E298975B872F0203010001")[..]); } #[test] #[cfg(feature = "alloc")] fn encode_ec_p256_der() { - let pk = SubjectPublicKeyInfoRef::try_from(EC_P256_DER_EXAMPLE).unwrap(); - let pk_encoded = pk.to_der().unwrap(); + let pk = SubjectPublicKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap(); + let pk_encoded = pk.to_vec().unwrap(); assert_eq!(EC_P256_DER_EXAMPLE, pk_encoded.as_slice()); } #[test] #[cfg(feature = "alloc")] fn encode_ed25519_der() { - let pk = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap(); - let pk_encoded = pk.to_der().unwrap(); + let pk = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap(); + let pk_encoded = pk.to_vec().unwrap(); assert_eq!(ED25519_DER_EXAMPLE, pk_encoded.as_slice()); } #[test] #[cfg(feature = "alloc")] fn encode_rsa_2048_der() { - let pk = SubjectPublicKeyInfoRef::try_from(RSA_2048_DER_EXAMPLE).unwrap(); - let pk_encoded = pk.to_der().unwrap(); + let pk = SubjectPublicKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap(); + let pk_encoded = pk.to_vec().unwrap(); assert_eq!(RSA_2048_DER_EXAMPLE, pk_encoded.as_slice()); } #[test] #[cfg(feature = "pem")] fn encode_ec_p256_pem() { - let pk = SubjectPublicKeyInfoRef::try_from(EC_P256_DER_EXAMPLE).unwrap(); + let pk = SubjectPublicKeyInfo::try_from(EC_P256_DER_EXAMPLE).unwrap(); let pk_encoded = pk.to_pem(LineEnding::LF).unwrap(); assert_eq!(EC_P256_PEM_EXAMPLE, pk_encoded); } @@ -147,7 +142,7 @@ fn encode_ec_p256_pem() { #[test] #[cfg(feature = "pem")] fn encode_ed25519_pem() { - let pk = SubjectPublicKeyInfoRef::try_from(ED25519_DER_EXAMPLE).unwrap(); + let pk = SubjectPublicKeyInfo::try_from(ED25519_DER_EXAMPLE).unwrap(); let pk_encoded = pk.to_pem(LineEnding::LF).unwrap(); assert_eq!(ED25519_PEM_EXAMPLE, pk_encoded); } @@ -155,7 +150,7 @@ fn encode_ed25519_pem() { #[test] #[cfg(feature = "pem")] fn encode_rsa_2048_pem() { - let pk = SubjectPublicKeyInfoRef::try_from(RSA_2048_DER_EXAMPLE).unwrap(); + let pk = SubjectPublicKeyInfo::try_from(RSA_2048_DER_EXAMPLE).unwrap(); let pk_encoded = pk.to_pem(LineEnding::LF).unwrap(); assert_eq!(RSA_2048_PEM_EXAMPLE, pk_encoded); } diff --git a/tests/traits.rs b/tests/traits.rs index 1114333..597399e 100644 --- a/tests/traits.rs +++ b/tests/traits.rs @@ -3,7 +3,7 @@ #![cfg(any(feature = "pem", feature = "std"))] use der::{Decode, Encode}; -use spki::{DecodePublicKey, Document, EncodePublicKey, Error, Result, SubjectPublicKeyInfoRef}; +use spki::{DecodePublicKey, Document, EncodePublicKey, Error, Result, SubjectPublicKeyInfo}; #[cfg(feature = "pem")] use spki::der::pem::LineEnding; @@ -30,17 +30,23 @@ impl AsRef<[u8]> for MockKey { } } +impl DecodePublicKey for MockKey { + fn from_public_key_der(bytes: &[u8]) -> Result { + Ok(MockKey(bytes.to_vec())) + } +} + impl EncodePublicKey for MockKey { fn to_public_key_der(&self) -> Result { Ok(Document::from_der(self.as_ref())?) } } -impl TryFrom> for MockKey { +impl TryFrom> for MockKey { type Error = Error; - fn try_from(spki: SubjectPublicKeyInfoRef<'_>) -> Result { - Ok(MockKey(spki.to_der()?)) + fn try_from(spki: SubjectPublicKeyInfo<'_>) -> Result { + Ok(MockKey(spki.to_vec()?)) } } -- cgit v1.2.3