diff options
author | Andrew Walbran <qwandor@google.com> | 2023-12-19 15:13:41 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-12-19 15:13:41 +0000 |
commit | 0ca0749343e521589c33ecfe090ab7385843156d (patch) | |
tree | 860d80f94633b4178d21d2f35303896992541d53 | |
parent | 1520d2aadbc66803aef27cc6a816c3bb63952687 (diff) | |
parent | 9a875ec6d98e8729c64a17085a39213157be7db1 (diff) | |
download | sec1-0ca0749343e521589c33ecfe090ab7385843156d.tar.gz |
Upgrade sec1 to 0.7.3 am: 3b65df0b6f am: 9a875ec6d9
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/sec1/+/2877561
Change-Id: I57ef9387953abef572ed0c1255eea6bb5bf1cd1b
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 4 | ||||
-rw-r--r-- | CHANGELOG.md | 41 | ||||
-rw-r--r-- | Cargo.toml | 39 | ||||
-rw-r--r-- | Cargo.toml.orig | 27 | ||||
-rw-r--r-- | LICENSE-MIT | 25 | ||||
-rw-r--r-- | METADATA | 26 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | src/error.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 21 | ||||
-rw-r--r-- | src/parameters.rs | 3 | ||||
-rw-r--r-- | src/point.rs | 23 | ||||
-rw-r--r-- | src/private_key.rs | 75 | ||||
-rw-r--r-- | src/traits.rs | 19 | ||||
-rw-r--r-- | tests/private_key.rs | 11 | ||||
-rw-r--r-- | tests/traits.rs | 2 |
16 files changed, 211 insertions, 113 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index eac35cf..246b3ff 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "2e3a6ab6d9b3d541604711aadb9bc1d5f53abc02" + "sha1": "c07eecfb9565ae5268ae484f9d6f5e913959c301" }, "path_in_vcs": "sec1" }
\ No newline at end of file @@ -35,7 +35,7 @@ rust_library_host { name: "libsec1", crate_name: "sec1", cargo_env_compat: true, - cargo_pkg_version: "0.3.0", + cargo_pkg_version: "0.7.3", srcs: ["src/lib.rs"], edition: "2021", features: [ @@ -55,7 +55,7 @@ rust_library_rlib { name: "libsec1_nostd", crate_name: "sec1", cargo_env_compat: true, - cargo_pkg_version: "0.3.0", + cargo_pkg_version: "0.7.3", srcs: ["src/lib.rs"], edition: "2021", features: [ diff --git a/CHANGELOG.md b/CHANGELOG.md index eb96da0..44a0fc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,47 @@ 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-07-16) +### Added +- Impl `Hash` for `EncodedPoint` ([#1102]) + +[#1102]: https://github.com/RustCrypto/formats/pull/1102 + +## 0.7.2 (2023-04-09) +### Added +- Impl `ModulusSize` for `U24` ([#995]) + +[#995]: https://github.com/RustCrypto/formats/pull/995 + +## 0.7.1 (2023-02-27) +### Fixed +- Encode `ECPrivateKey` version ([#908]) + +[#908]: https://github.com/RustCrypto/formats/pull/908 + +## 0.7.0 (2023-02-26) [YANKED] +### Changed +- MSRV 1.65 ([#805]) +- Bump `serdect` to v0.2 ([#893]) +- Bump `der` dependency to v0.7 ([#899]) +- Bump `spki` dependency to v0.7 ([#900]) +- Bump `pkcs8` to v0.10 ([#902]) + +[#805]: https://github.com/RustCrypto/formats/pull/805 +[#893]: https://github.com/RustCrypto/formats/pull/893 +[#899]: https://github.com/RustCrypto/formats/pull/899 +[#900]: https://github.com/RustCrypto/formats/pull/900 +[#902]: https://github.com/RustCrypto/formats/pull/902 + +## 0.6.0 (Skipped) +- Skipped to synchronize version number with `der` and `spki` + +## 0.5.0 (Skipped) +- Skipped to synchronize version number with `der` and `spki` + +## 0.4.0 (Skipped) +- Skipped to synchronize version number with `der` and `spki` + ## 0.3.0 (2022-05-08) ### Added - Make `der` feature optional but on-by-default ([#497]) @@ -11,9 +11,9 @@ [package] edition = "2021" -rust-version = "1.57" +rust-version = "1.65" name = "sec1" -version = "0.3.0" +version = "0.7.3" authors = ["RustCrypto Developers"] description = """ Pure Rust implementation of SEC1: Elliptic Curve Cryptography encoding formats @@ -36,7 +36,6 @@ categories = [ ] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/formats/tree/master/sec1" -resolver = "2" [package.metadata.docs.rs] all-features = true @@ -46,27 +45,27 @@ rustdoc-args = [ ] [dependencies.base16ct] -version = "0.1.1" +version = "0.2" optional = true default-features = false [dependencies.der] -version = "0.6" +version = "0.7" features = ["oid"] optional = true [dependencies.generic-array] -version = "0.14.4" +version = "0.14.7" optional = true default-features = false [dependencies.pkcs8] -version = "0.9" +version = "0.10" optional = true default-features = false [dependencies.serdect] -version = "0.1" +version = "0.2" features = ["alloc"] optional = true default-features = false @@ -82,32 +81,40 @@ optional = true default-features = false [dev-dependencies.hex-literal] -version = "0.3" +version = "0.4" [dev-dependencies.tempfile] version = "3" [features] alloc = [ - "der/alloc", - "pkcs8/alloc", - "zeroize/alloc", + "der?/alloc", + "pkcs8?/alloc", + "zeroize?/alloc", ] default = [ "der", "point", ] +der = [ + "dep:der", + "zeroize", +] pem = [ "alloc", "der/pem", "pkcs8/pem", ] point = [ - "base16ct", - "generic-array", + "dep:base16ct", + "dep:generic-array", ] -serde = ["serdect"] +serde = ["dep:serdect"] std = [ - "der/std", "alloc", + "der?/std", +] +zeroize = [ + "dep:zeroize", + "der?/zeroize", ] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index f1ee649..eaa20b9 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "sec1" -version = "0.3.0" +version = "0.7.3" description = """ Pure Rust implementation of SEC1: Elliptic Curve Cryptography encoding formats including ASN.1 DER-serialized private keys as well as the @@ -13,28 +13,31 @@ categories = ["cryptography", "data-structures", "encoding", "no-std", "parser-i keywords = ["crypto", "key", "elliptic-curve", "secg"] readme = "README.md" edition = "2021" -rust-version = "1.57" +rust-version = "1.65" [dependencies] -base16ct = { version = "0.1.1", optional = true, default-features = false, path = "../base16ct" } -der = { version = "0.6", optional = true, features = ["oid"], path = "../der" } -generic-array = { version = "0.14.4", optional = true, default-features = false } -pkcs8 = { version = "0.9", optional = true, default-features = false, path = "../pkcs8" } -serdect = { version = "0.1", optional = true, default-features = false, features = ["alloc"], path = "../serdect" } +base16ct = { version = "0.2", optional = true, default-features = false } +der = { version = "0.7", optional = true, features = ["oid"] } +generic-array = { version = "0.14.7", optional = true, default-features = false } +pkcs8 = { version = "0.10", optional = true, default-features = false } +serdect = { version = "0.2", optional = true, default-features = false, features = ["alloc"] } subtle = { version = "2", optional = true, default-features = false } zeroize = { version = "1", optional = true, default-features = false } [dev-dependencies] -hex-literal = "0.3" +hex-literal = "0.4" tempfile = "3" [features] default = ["der", "point"] -alloc = ["der/alloc", "pkcs8/alloc", "zeroize/alloc"] +alloc = ["der?/alloc", "pkcs8?/alloc", "zeroize?/alloc"] +std = ["alloc", "der?/std"] + +der = ["dep:der", "zeroize"] pem = ["alloc", "der/pem", "pkcs8/pem"] -point = ["base16ct", "generic-array"] -serde = ["serdect"] -std = ["der/std", "alloc"] +point = ["dep:base16ct", "dep:generic-array"] +serde = ["dep:serdect"] +zeroize = ["dep:zeroize", "der?/zeroize"] [package.metadata.docs.rs] all-features = true diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..68ddaa3 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2021-2022 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. @@ -1,20 +1,20 @@ +# This project was upgraded with external_updater. +# Usage: tools/external_updater/updater.sh update rust/crates/sec1 +# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md + name: "sec1" description: "Pure Rust implementation of SEC1: Elliptic Curve Cryptography encoding formats including ASN.1 DER-serialized private keys (also described in RFC5915) as well as the Elliptic-Curve-Point-to-Octet-String and Octet-String-to-Elliptic Curve-Point encoding algorithms." third_party { - url { - type: HOMEPAGE - value: "https://crates.io/crates/sec1" - } - url { - type: ARCHIVE - value: "https://static.crates.io/crates/sec1/sec1-0.3.0.crate" - } - version: "0.3.0" - # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same. license_type: NOTICE last_upgrade_date { - year: 2022 - month: 9 - day: 6 + year: 2023 + month: 12 + day: 15 + } + homepage: "https://crates.io/crates/sec1" + identifier { + type: "Archive" + value: "https://static.crates.io/crates/sec1/sec1-0.7.3.crate" + version: "0.7.3" } } @@ -18,7 +18,7 @@ formats including ASN.1 DER-serialized private keys (also described in ## Minimum Supported Rust Version -This crate requires **Rust 1.57** at a minimum. +This crate requires **Rust 1.65** 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. [docs-image]: https://docs.rs/sec1/badge.svg [docs-link]: https://docs.rs/sec1/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.57+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-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/sec1/badge.svg?branch=master&event=push diff --git a/src/error.rs b/src/error.rs index 3700ac5..0d8bc8b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,7 +14,6 @@ pub type Result<T> = core::result::Result<T, Error>; pub enum Error { /// ASN.1 DER-related errors. #[cfg(feature = "der")] - #[cfg_attr(docsrs, doc(cfg(feature = "der")))] Asn1(der::Error), /// Cryptographic errors. @@ -52,7 +51,6 @@ impl fmt::Display for Error { } #[cfg(feature = "der")] -#[cfg_attr(docsrs, doc(cfg(feature = "der")))] impl From<der::Error> for Error { fn from(err: der::Error) -> Error { Error::Asn1(err) @@ -1,12 +1,18 @@ #![no_std] -#![cfg_attr(docsrs, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc = include_str!("../README.md")] #![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" + 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_qualifications )] -#![forbid(unsafe_code, clippy::unwrap_used)] -#![warn(missing_docs, rust_2018_idioms, unused_qualifications)] //! ## `serde` support //! @@ -52,15 +58,13 @@ pub use generic_array::typenum::consts; #[cfg(feature = "der")] pub use crate::{parameters::EcParameters, private_key::EcPrivateKey, traits::DecodeEcPrivateKey}; -#[cfg(feature = "alloc")] +#[cfg(all(feature = "alloc", feature = "der"))] pub use crate::traits::EncodeEcPrivateKey; #[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] pub use der::pem::{self, LineEnding}; #[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub use pkcs8; #[cfg(feature = "pkcs8")] @@ -74,5 +78,4 @@ use serdect::serde; /// /// <http://oid-info.com/get/1.2.840.10045.2.1> #[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] pub const ALGORITHM_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10045.2.1"); diff --git a/src/parameters.rs b/src/parameters.rs index ed9d152..20458e6 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -18,7 +18,6 @@ use der::{ /// -- with ANSI X9. /// ``` #[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[cfg_attr(docsrs, doc(cfg(feature = "der")))] pub enum EcParameters { /// Elliptic curve named by a particular OID. /// @@ -41,7 +40,7 @@ impl EncodeValue for EcParameters { } } - fn encode_value(&self, writer: &mut dyn Writer) -> der::Result<()> { + fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { match self { Self::NamedCurve(oid) => oid.encode_value(writer), } diff --git a/src/point.rs b/src/point.rs index eb0d2ca..818f5bd 100644 --- a/src/point.rs +++ b/src/point.rs @@ -10,11 +10,12 @@ use base16ct::HexDisplay; use core::{ cmp::Ordering, fmt::{self, Debug}, + hash::{Hash, Hasher}, ops::Add, str, }; use generic_array::{ - typenum::{U1, U28, U32, U48, U66}, + typenum::{U1, U24, U28, U32, U48, U66}, ArrayLength, GenericArray, }; @@ -59,7 +60,7 @@ macro_rules! impl_modulus_size { } } -impl_modulus_size!(U28, U32, U48, U66); +impl_modulus_size!(U24, U28, U32, U48, U66); /// SEC1 encoded curve point. /// @@ -157,7 +158,6 @@ where /// Get boxed byte slice containing the serialized [`EncodedPoint`] #[cfg(feature = "alloc")] - #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] pub fn to_bytes(&self) -> Box<[u8]> { self.as_bytes().to_vec().into_boxed_slice() } @@ -295,6 +295,15 @@ where } } +impl<Size> Hash for EncodedPoint<Size> +where + Size: ModulusSize, +{ + fn hash<H: Hasher>(&self, state: &mut H) { + self.as_bytes().hash(state) + } +} + impl<Size: ModulusSize> PartialOrd for EncodedPoint<Size> where Size: ModulusSize, @@ -381,7 +390,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<Size> Serialize for EncodedPoint<Size> where Size: ModulusSize, @@ -395,7 +403,6 @@ where } #[cfg(feature = "serde")] -#[cfg_attr(docsrs, doc(cfg(feature = "serde")))] impl<'de, Size> Deserialize<'de> for EncodedPoint<Size> where Size: ModulusSize, @@ -405,7 +412,7 @@ where D: de::Deserializer<'de>, { let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; - Self::from_bytes(&bytes).map_err(de::Error::custom) + Self::from_bytes(bytes).map_err(de::Error::custom) } } @@ -663,8 +670,8 @@ mod tests { #[test] fn decode_invalid_tag() { - let mut compressed_bytes = COMPRESSED_BYTES.clone(); - let mut uncompressed_bytes = UNCOMPRESSED_BYTES.clone(); + let mut compressed_bytes = COMPRESSED_BYTES; + let mut uncompressed_bytes = UNCOMPRESSED_BYTES; for bytes in &mut [&mut compressed_bytes[..], &mut uncompressed_bytes[..]] { for tag in 0..=0xFF { diff --git a/src/private_key.rs b/src/private_key.rs index 2362432..5315799 100644 --- a/src/private_key.rs +++ b/src/private_key.rs @@ -8,11 +8,12 @@ use crate::{EcParameters, Error, Result}; use core::fmt; use der::{ - asn1::{BitStringRef, ContextSpecific, OctetStringRef}, - Decode, DecodeValue, Encode, Header, Reader, Sequence, Tag, TagMode, TagNumber, + asn1::{BitStringRef, ContextSpecific, ContextSpecificRef, OctetStringRef}, + Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, TagMode, + TagNumber, Writer, }; -#[cfg(feature = "alloc")] +#[cfg(all(feature = "alloc", feature = "zeroize"))] use der::SecretDocument; #[cfg(feature = "pem")] @@ -58,7 +59,6 @@ const PUBLIC_KEY_TAG: TagNumber = TagNumber::new(1); /// [SEC1: Elliptic Curve Cryptography (Version 2.0)]: https://www.secg.org/sec1-v2.pdf /// [RFC5915 Section 3]: https://datatracker.ietf.org/doc/html/rfc5915#section-3 #[derive(Clone)] -#[cfg_attr(docsrs, doc(cfg(feature = "der")))] pub struct EcPrivateKey<'a> { /// Private key data. pub private_key: &'a [u8], @@ -70,6 +70,30 @@ pub struct EcPrivateKey<'a> { pub public_key: Option<&'a [u8]>, } +impl<'a> EcPrivateKey<'a> { + fn context_specific_parameters(&self) -> Option<ContextSpecificRef<'_, EcParameters>> { + self.parameters.as_ref().map(|params| ContextSpecificRef { + tag_number: EC_PARAMETERS_TAG, + tag_mode: TagMode::Explicit, + value: params, + }) + } + + fn context_specific_public_key( + &self, + ) -> der::Result<Option<ContextSpecific<BitStringRef<'a>>>> { + self.public_key + .map(|pk| { + BitStringRef::from_bytes(pk).map(|value| ContextSpecific { + tag_number: PUBLIC_KEY_TAG, + tag_mode: TagMode::Explicit, + value, + }) + }) + .transpose() + } +} + impl<'a> DecodeValue<'a> for EcPrivateKey<'a> { fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> { reader.read_nested(header.length, |reader| { @@ -93,33 +117,25 @@ impl<'a> DecodeValue<'a> for EcPrivateKey<'a> { } } -impl<'a> Sequence<'a> for EcPrivateKey<'a> { - fn fields<F, T>(&self, f: F) -> der::Result<T> - where - F: FnOnce(&[&dyn Encode]) -> der::Result<T>, - { - f(&[ - &VERSION, - &OctetStringRef::new(self.private_key)?, - &self.parameters.as_ref().map(|params| ContextSpecific { - tag_number: EC_PARAMETERS_TAG, - tag_mode: TagMode::Explicit, - value: *params, - }), - &self - .public_key - .map(|pk| { - BitStringRef::from_bytes(pk).map(|value| ContextSpecific { - tag_number: PUBLIC_KEY_TAG, - tag_mode: TagMode::Explicit, - value, - }) - }) - .transpose()?, - ]) +impl EncodeValue for EcPrivateKey<'_> { + fn value_len(&self) -> der::Result<Length> { + VERSION.encoded_len()? + + OctetStringRef::new(self.private_key)?.encoded_len()? + + self.context_specific_parameters().encoded_len()? + + self.context_specific_public_key()?.encoded_len()? + } + + fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { + VERSION.encode(writer)?; + OctetStringRef::new(self.private_key)?.encode(writer)?; + self.context_specific_parameters().encode(writer)?; + self.context_specific_public_key()?.encode(writer)?; + Ok(()) } } +impl<'a> Sequence<'a> for EcPrivateKey<'a> {} + impl<'a> TryFrom<&'a [u8]> for EcPrivateKey<'a> { type Error = Error; @@ -138,7 +154,6 @@ impl<'a> fmt::Debug for EcPrivateKey<'a> { } #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl TryFrom<EcPrivateKey<'_>> for SecretDocument { type Error = Error; @@ -148,7 +163,6 @@ impl TryFrom<EcPrivateKey<'_>> for SecretDocument { } #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] impl TryFrom<&EcPrivateKey<'_>> for SecretDocument { type Error = Error; @@ -158,7 +172,6 @@ impl TryFrom<&EcPrivateKey<'_>> for SecretDocument { } #[cfg(feature = "pem")] -#[cfg_attr(docsrs, doc(cfg(feature = "pem")))] impl PemLabel for EcPrivateKey<'_> { const PEM_LABEL: &'static str = "EC PRIVATE KEY"; } diff --git a/src/traits.rs b/src/traits.rs index cf0d971..304019e 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -21,7 +21,6 @@ use std::path::Path; use zeroize::Zeroizing; /// Parse an [`EcPrivateKey`] from a SEC1-encoded document. -#[cfg_attr(docsrs, doc(cfg(feature = "der")))] pub trait DecodeEcPrivateKey: Sized { /// Deserialize SEC1 private key from ASN.1 DER-encoded data /// (binary format). @@ -35,7 +34,6 @@ pub trait DecodeEcPrivateKey: Sized { /// -----BEGIN EC PRIVATE KEY----- /// ``` #[cfg(feature = "pem")] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] fn from_sec1_pem(s: &str) -> Result<Self> { let (label, doc) = SecretDocument::from_pem(s)?; EcPrivateKey::validate_pem_label(label)?; @@ -45,15 +43,12 @@ pub trait DecodeEcPrivateKey: Sized { /// Load SEC1 private key 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_sec1_der_file(path: impl AsRef<Path>) -> Result<Self> { Self::from_sec1_der(SecretDocument::read_der_file(path)?.as_bytes()) } /// Load SEC1 private key from a PEM-encoded file on the local filesystem. #[cfg(all(feature = "pem", feature = "std"))] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn read_sec1_pem_file(path: impl AsRef<Path>) -> Result<Self> { let (label, doc) = SecretDocument::read_pem_file(path)?; EcPrivateKey::validate_pem_label(&label)?; @@ -63,7 +58,6 @@ pub trait DecodeEcPrivateKey: Sized { /// Serialize a [`EcPrivateKey`] to a SEC1 encoded document. #[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "der"))))] pub trait EncodeEcPrivateKey { /// Serialize a [`SecretDocument`] containing a SEC1-encoded private key. fn to_sec1_der(&self) -> Result<SecretDocument>; @@ -72,7 +66,6 @@ pub trait EncodeEcPrivateKey { /// /// To use the OS's native line endings, pass `Default::default()`. #[cfg(feature = "pem")] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] fn to_sec1_pem(&self, line_ending: LineEnding) -> Result<Zeroizing<String>> { let doc = self.to_sec1_der()?; Ok(doc.to_pem(EcPrivateKey::PEM_LABEL, line_ending)?) @@ -80,15 +73,12 @@ pub trait EncodeEcPrivateKey { /// Write ASN.1 DER-encoded SEC1 private key to the given path. #[cfg(feature = "std")] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn write_sec1_der_file(&self, path: impl AsRef<Path>) -> Result<()> { Ok(self.to_sec1_der()?.write_der_file(path)?) } /// Write ASN.1 DER-encoded SEC1 private key to the given path. #[cfg(all(feature = "pem", feature = "std"))] - #[cfg_attr(docsrs, doc(cfg(feature = "pem")))] - #[cfg_attr(docsrs, doc(cfg(feature = "std")))] fn write_sec1_pem_file(&self, path: impl AsRef<Path>, line_ending: LineEnding) -> Result<()> { let doc = self.to_sec1_der()?; Ok(doc.write_pem_file(path, EcPrivateKey::PEM_LABEL, line_ending)?) @@ -96,14 +86,16 @@ pub trait EncodeEcPrivateKey { } #[cfg(feature = "pkcs8")] -#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))] -impl<T: pkcs8::DecodePrivateKey> DecodeEcPrivateKey for T { +impl<T> DecodeEcPrivateKey for T +where + T: for<'a> TryFrom<pkcs8::PrivateKeyInfo<'a>, Error = pkcs8::Error>, +{ fn from_sec1_der(private_key: &[u8]) -> Result<Self> { let params_oid = EcPrivateKey::from_der(private_key)? .parameters .and_then(|params| params.named_curve()); - let algorithm = pkcs8::AlgorithmIdentifier { + let algorithm = pkcs8::AlgorithmIdentifierRef { oid: ALGORITHM_OID, parameters: params_oid.as_ref().map(Into::into), }; @@ -117,7 +109,6 @@ impl<T: pkcs8::DecodePrivateKey> DecodeEcPrivateKey for T { } #[cfg(all(feature = "alloc", feature = "pkcs8"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "pkcs8"))))] impl<T: pkcs8::EncodePrivateKey> EncodeEcPrivateKey for T { fn to_sec1_der(&self) -> Result<SecretDocument> { let doc = self.to_pkcs8_der()?; diff --git a/tests/private_key.rs b/tests/private_key.rs index 5b985da..224a947 100644 --- a/tests/private_key.rs +++ b/tests/private_key.rs @@ -6,6 +6,9 @@ use der::asn1::ObjectIdentifier; use hex_literal::hex; use sec1::{EcParameters, EcPrivateKey}; +#[cfg(feature = "alloc")] +use der::Encode; + /// NIST P-256 SEC1 private key encoded as ASN.1 DER. /// /// Note: this key is extracted from the corresponding `p256-priv.der` @@ -30,3 +33,11 @@ fn decode_p256_der() { ); assert_eq!(key.public_key, Some(hex!("041CACFFB55F2F2CEFD89D89EB374B2681152452802DEEA09916068137D839CF7FC481A44492304D7EF66AC117BEFE83A8D08F155F2B52F9F618DD447029048E0F").as_ref())); } + +#[cfg(feature = "alloc")] +#[test] +fn encode_p256_der() { + let key = EcPrivateKey::try_from(P256_DER_EXAMPLE).unwrap(); + let key_encoded = key.to_der().unwrap(); + assert_eq!(P256_DER_EXAMPLE, key_encoded); +} diff --git a/tests/traits.rs b/tests/traits.rs index 4bcd679..ab6e09a 100644 --- a/tests/traits.rs +++ b/tests/traits.rs @@ -1,6 +1,6 @@ //! Tests for SEC1 encoding/decoding traits. -#![cfg(any(feature = "pem", feature = "std"))] +#![cfg(any(feature = "pem", all(feature = "der", feature = "std")))] use der::SecretDocument; use sec1::{DecodeEcPrivateKey, EncodeEcPrivateKey, Result}; |