Skip to content

spki: make SubjectPublicKeyInfo own the public key #778

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

Closed
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
2 changes: 1 addition & 1 deletion der/src/asn1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mod videotex_string;

pub use self::{
any::AnyRef,
bit_string::{BitStringIter, BitStringRef},
bit_string::{BitStringIter, BitStringLike, BitStringRef},
choice::Choice,
context_specific::{ContextSpecific, ContextSpecificRef},
generalized_time::GeneralizedTime,
Expand Down
20 changes: 16 additions & 4 deletions der/src/asn1/bit_string.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! ASN.1 `BIT STRING` support.

use crate::{
asn1::AnyRef, ByteSlice, DecodeValue, DerOrd, EncodeValue, Error, ErrorKind, FixedTag, Header,
Length, Reader, Result, Tag, ValueOrd, Writer,
asn1::AnyRef, ByteSlice, Decode, DecodeValue, DerOrd, Encode, EncodeValue, Error, ErrorKind,
FixedTag, Header, Length, Reader, Result, Tag, ValueOrd, Writer,
};
use core::{cmp::Ordering, iter::FusedIterator};

Expand Down Expand Up @@ -153,8 +153,8 @@ impl ValueOrd for BitStringRef<'_> {
}
}

impl<'a> From<&BitStringRef<'a>> for BitStringRef<'a> {
fn from(value: &BitStringRef<'a>) -> BitStringRef<'a> {
impl<'a, 'k> From<&'k BitStringRef<'a>> for BitStringRef<'a> {
fn from(value: &'k BitStringRef<'a>) -> BitStringRef<'a> {
*value
}
}
Expand Down Expand Up @@ -441,6 +441,18 @@ where
}
}

/// Trait used as a marker to ensure the type can hold the content of a Bit String
pub trait BitStringLike<'der>
where
Self: Decode<'der> + Encode + FixedTag,
{
}

impl<'der> BitStringLike<'der> for BitStringRef<'der> {}

#[cfg(feature = "alloc")]
impl<'a> BitStringLike<'a> for BitString {}

#[cfg(test)]
mod tests {
use super::{BitStringRef, Result, Tag};
Expand Down
2 changes: 1 addition & 1 deletion pkcs1/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub const ALGORITHM_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.84
/// `AlgorithmIdentifier` for RSA.
#[cfg(feature = "pkcs8")]
#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
pub const ALGORITHM_ID: pkcs8::AlgorithmIdentifier<'static> = pkcs8::AlgorithmIdentifier {
pub const ALGORITHM_ID: pkcs8::AlgorithmIdentifierRef<'static> = pkcs8::AlgorithmIdentifierRef {
oid: ALGORITHM_OID,
parameters: Some(der::asn1::AnyRef::NULL),
};
22 changes: 11 additions & 11 deletions pkcs1/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use der::{
asn1::ContextSpecificRef, Decode, DecodeValue, Encode, EncodeValue, FixedTag, Reader, Sequence,
Tag, TagMode, TagNumber, Writer,
};
use spki::AlgorithmIdentifier;
use spki::AlgorithmIdentifierRef;

const OID_SHA_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
const OID_MGF_1: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.8");
Expand All @@ -15,7 +15,7 @@ const OID_PSPECIFIED: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.1
// TODO(tarcieri): make `AlgorithmIdentifier` generic around params; use `OID_SHA_1`
const SEQ_OID_SHA_1_DER: &[u8] = &[0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a];

const SHA_1_AI: AlgorithmIdentifier<'_> = AlgorithmIdentifier {
const SHA_1_AI: AlgorithmIdentifierRef<'_> = AlgorithmIdentifierRef {
oid: OID_SHA_1,
parameters: None,
};
Expand Down Expand Up @@ -81,10 +81,10 @@ impl FixedTag for TrailerField {
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RsaPssParams<'a> {
/// Hash Algorithm
pub hash: AlgorithmIdentifier<'a>,
pub hash: AlgorithmIdentifierRef<'a>,

/// Mask Generation Function (MGF)
pub mask_gen: AlgorithmIdentifier<'a>,
pub mask_gen: AlgorithmIdentifierRef<'a>,

/// Salt length
pub salt_len: u8,
Expand Down Expand Up @@ -180,8 +180,8 @@ impl<'a> TryFrom<&'a [u8]> for RsaPssParams<'a> {
}

/// Default Mask Generation Function (MGF): SHA-1.
fn default_mgf1_sha1<'a>() -> AlgorithmIdentifier<'a> {
AlgorithmIdentifier {
fn default_mgf1_sha1<'a>() -> AlgorithmIdentifierRef<'a> {
AlgorithmIdentifierRef {
oid: OID_MGF_1,
parameters: Some(
AnyRef::new(Tag::Sequence, SEQ_OID_SHA_1_DER)
Expand All @@ -208,13 +208,13 @@ fn default_mgf1_sha1<'a>() -> AlgorithmIdentifier<'a> {
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RsaOaepParams<'a> {
/// Hash Algorithm
pub hash: AlgorithmIdentifier<'a>,
pub hash: AlgorithmIdentifierRef<'a>,

/// Mask Generation Function (MGF)
pub mask_gen: AlgorithmIdentifier<'a>,
pub mask_gen: AlgorithmIdentifierRef<'a>,

/// The source (and possibly the value) of the label L
pub p_source: AlgorithmIdentifier<'a>,
pub p_source: AlgorithmIdentifierRef<'a>,
}

impl<'a> Default for RsaOaepParams<'a> {
Expand Down Expand Up @@ -291,8 +291,8 @@ impl<'a> TryFrom<&'a [u8]> for RsaOaepParams<'a> {
}

/// Default Source Algorithm, empty string
fn default_pempty_string<'a>() -> AlgorithmIdentifier<'a> {
AlgorithmIdentifier {
fn default_pempty_string<'a>() -> AlgorithmIdentifierRef<'a> {
AlgorithmIdentifierRef {
oid: OID_PSPECIFIED,
parameters: Some(
AnyRef::new(Tag::OctetString, &[]).expect("error creating default OAEP params"),
Expand Down
13 changes: 8 additions & 5 deletions pkcs1/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ use {
};

#[cfg(feature = "pkcs8")]
use crate::{ALGORITHM_ID, ALGORITHM_OID};
use {
crate::{ALGORITHM_ID, ALGORITHM_OID},
der::asn1::BitStringRef,
};

#[cfg(feature = "std")]
use std::path::Path;
Expand Down Expand Up @@ -183,9 +186,9 @@ impl<T: pkcs8::DecodePrivateKey> DecodeRsaPrivateKey for T {
#[cfg_attr(docsrs, doc(cfg(feature = "pkcs8")))]
impl<T: pkcs8::DecodePublicKey> DecodeRsaPublicKey for T {
fn from_pkcs1_der(public_key: &[u8]) -> Result<Self> {
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfo {
Ok(Self::try_from(pkcs8::SubjectPublicKeyInfoRef {
algorithm: ALGORITHM_ID,
subject_public_key: public_key,
subject_public_key: BitStringRef::from_bytes(public_key)?,
})?)
}
}
Expand All @@ -206,8 +209,8 @@ impl<T: pkcs8::EncodePrivateKey> EncodeRsaPrivateKey for T {
impl<T: pkcs8::EncodePublicKey> EncodeRsaPublicKey for T {
fn to_pkcs1_der(&self) -> Result<Document> {
let doc = self.to_public_key_der()?;
let spki = pkcs8::SubjectPublicKeyInfo::from_der(doc.as_bytes())?;
let spki = pkcs8::SubjectPublicKeyInfoRef::from_der(doc.as_bytes())?;
spki.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
RsaPublicKey::from_der(spki.subject_public_key)?.try_into()
RsaPublicKey::from_der(spki.subject_public_key.raw_bytes())?.try_into()
}
}
12 changes: 6 additions & 6 deletions pkcs5/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//!
//! The main API for this crate is the [`EncryptionScheme`] enum, which impls
//! the [`Decode`] and [`Encode`] traits from the [`der`] crate, and can be
//! used for decoding/encoding PKCS#5 [`AlgorithmIdentifier`] fields.
//! used for decoding/encoding PKCS#5 `AlgorithmIdentifier` fields.
//!
//! [RFC 8018]: https://tools.ietf.org/html/rfc8018

Expand All @@ -26,7 +26,7 @@ pub mod pbes2;

pub use crate::error::{Error, Result};
pub use der::{self, asn1::ObjectIdentifier};
pub use spki::AlgorithmIdentifier;
pub use spki::AlgorithmIdentifierRef;

use der::{Decode, DecodeValue, Encode, Header, Reader, Sequence, Tag};

Expand Down Expand Up @@ -136,7 +136,7 @@ impl<'a> EncryptionScheme<'a> {

impl<'a> DecodeValue<'a> for EncryptionScheme<'a> {
fn decode_value<R: Reader<'a>>(decoder: &mut R, header: Header) -> der::Result<Self> {
AlgorithmIdentifier::decode_value(decoder, header)?.try_into()
AlgorithmIdentifierRef::decode_value(decoder, header)?.try_into()
}
}

Expand Down Expand Up @@ -164,10 +164,10 @@ impl<'a> From<pbes2::Parameters<'a>> for EncryptionScheme<'a> {
}
}

impl<'a> TryFrom<AlgorithmIdentifier<'a>> for EncryptionScheme<'a> {
impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifier<'a>) -> der::Result<EncryptionScheme<'_>> {
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<EncryptionScheme<'_>> {
if alg.oid == pbes2::PBES2_OID {
match alg.parameters {
Some(params) => pbes2::Parameters::try_from(params).map(Into::into),
Expand All @@ -183,6 +183,6 @@ impl<'a> TryFrom<&'a [u8]> for EncryptionScheme<'a> {
type Error = der::Error;

fn try_from(bytes: &'a [u8]) -> der::Result<EncryptionScheme<'a>> {
AlgorithmIdentifier::from_der(bytes)?.try_into()
AlgorithmIdentifierRef::from_der(bytes)?.try_into()
}
}
8 changes: 4 additions & 4 deletions pkcs5/src/pbes1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! [RFC 8018 Section 6.1]: https://tools.ietf.org/html/rfc8018#section-6.1

use crate::AlgorithmIdentifier;
use crate::AlgorithmIdentifierRef;
use der::{
asn1::{AnyRef, ObjectIdentifier, OctetStringRef},
Decode, Encode, ErrorKind, Length, Reader, Sequence, Tag, Writer,
Expand Down Expand Up @@ -68,7 +68,7 @@ impl Algorithm {

impl<'a> Decode<'a> for Algorithm {
fn decode<R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
AlgorithmIdentifier::decode(decoder)?.try_into()
AlgorithmIdentifierRef::decode(decoder)?.try_into()
}
}

Expand All @@ -81,10 +81,10 @@ impl Sequence<'_> for Algorithm {
}
}

impl<'a> TryFrom<AlgorithmIdentifier<'a>> for Algorithm {
impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for Algorithm {
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifier<'a>) -> der::Result<Self> {
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
// Ensure that we have a supported PBES1 algorithm identifier
let encryption = EncryptionScheme::try_from(alg.oid)
.map_err(|_| der::Tag::ObjectIdentifier.value_error())?;
Expand Down
20 changes: 10 additions & 10 deletions pkcs5/src/pbes2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub use self::kdf::{
PBKDF2_OID, SCRYPT_OID,
};

use crate::{AlgorithmIdentifier, Error, Result};
use crate::{AlgorithmIdentifierRef, Error, Result};
use der::{
asn1::{AnyRef, ObjectIdentifier, OctetStringRef},
Decode, Encode, ErrorKind, Length, Reader, Sequence, Tag, Writer,
Expand Down Expand Up @@ -220,8 +220,8 @@ impl<'a> TryFrom<AnyRef<'a>> for Parameters<'a> {

fn try_from(any: AnyRef<'a>) -> der::Result<Self> {
any.sequence(|params| {
let kdf = AlgorithmIdentifier::decode(params)?;
let encryption = AlgorithmIdentifier::decode(params)?;
let kdf = AlgorithmIdentifierRef::decode(params)?;
let encryption = AlgorithmIdentifierRef::decode(params)?;

Ok(Self {
kdf: kdf.try_into()?,
Expand Down Expand Up @@ -305,14 +305,14 @@ impl<'a> EncryptionScheme<'a> {

impl<'a> Decode<'a> for EncryptionScheme<'a> {
fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
AlgorithmIdentifier::decode(reader).and_then(TryInto::try_into)
AlgorithmIdentifierRef::decode(reader).and_then(TryInto::try_into)
}
}

impl<'a> TryFrom<AlgorithmIdentifier<'a>> for EncryptionScheme<'a> {
impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for EncryptionScheme<'a> {
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifier<'a>) -> der::Result<Self> {
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
// TODO(tarcieri): support for non-AES algorithms?
let iv = match alg.parameters {
Some(params) => params.octet_string()?.as_bytes(),
Expand Down Expand Up @@ -352,7 +352,7 @@ impl<'a> TryFrom<AlgorithmIdentifier<'a>> for EncryptionScheme<'a> {
}
}

impl<'a> TryFrom<EncryptionScheme<'a>> for AlgorithmIdentifier<'a> {
impl<'a> TryFrom<EncryptionScheme<'a>> for AlgorithmIdentifierRef<'a> {
type Error = der::Error;

fn try_from(scheme: EncryptionScheme<'a>) -> der::Result<Self> {
Expand All @@ -366,7 +366,7 @@ impl<'a> TryFrom<EncryptionScheme<'a>> for AlgorithmIdentifier<'a> {
EncryptionScheme::DesEde3Cbc { iv } => iv,
})?;

Ok(AlgorithmIdentifier {
Ok(AlgorithmIdentifierRef {
oid: scheme.oid(),
parameters: Some(parameters.into()),
})
Expand All @@ -375,10 +375,10 @@ impl<'a> TryFrom<EncryptionScheme<'a>> for AlgorithmIdentifier<'a> {

impl<'a> Encode for EncryptionScheme<'a> {
fn encoded_len(&self) -> der::Result<Length> {
AlgorithmIdentifier::try_from(*self)?.encoded_len()
AlgorithmIdentifierRef::try_from(*self)?.encoded_len()
}

fn encode(&self, writer: &mut dyn Writer) -> der::Result<()> {
AlgorithmIdentifier::try_from(*self)?.encode(writer)
AlgorithmIdentifierRef::try_from(*self)?.encode(writer)
}
}
22 changes: 11 additions & 11 deletions pkcs5/src/pbes2/kdf.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Key derivation functions.

use crate::{AlgorithmIdentifier, Error, Result};
use crate::{AlgorithmIdentifierRef, Error, Result};
use der::{
asn1::{AnyRef, ObjectIdentifier, OctetStringRef},
Decode, Encode, ErrorKind, Length, Reader, Sequence, Tag, Tagged, Writer,
Expand Down Expand Up @@ -100,7 +100,7 @@ impl<'a> Kdf<'a> {

impl<'a> Decode<'a> for Kdf<'a> {
fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
AlgorithmIdentifier::decode(reader)?.try_into()
AlgorithmIdentifierRef::decode(reader)?.try_into()
}
}

Expand Down Expand Up @@ -128,10 +128,10 @@ impl<'a> From<ScryptParams<'a>> for Kdf<'a> {
}
}

impl<'a> TryFrom<AlgorithmIdentifier<'a>> for Kdf<'a> {
impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for Kdf<'a> {
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifier<'a>) -> der::Result<Self> {
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
if let Some(params) = alg.parameters {
match alg.oid {
PBKDF2_OID => params.try_into().map(Self::Pbkdf2),
Expand Down Expand Up @@ -242,7 +242,7 @@ impl<'a> TryFrom<AnyRef<'a>> for Pbkdf2Params<'a> {
salt: OctetStringRef::decode(reader)?.as_bytes(),
iteration_count: reader.decode()?,
key_length: reader.decode()?,
prf: Option::<AlgorithmIdentifier<'_>>::decode(reader)?
prf: Option::<AlgorithmIdentifierRef<'_>>::decode(reader)?
.map(TryInto::try_into)
.transpose()?
.unwrap_or_default(),
Expand Down Expand Up @@ -298,10 +298,10 @@ impl Default for Pbkdf2Prf {
}
}

impl<'a> TryFrom<AlgorithmIdentifier<'a>> for Pbkdf2Prf {
impl<'a> TryFrom<AlgorithmIdentifierRef<'a>> for Pbkdf2Prf {
type Error = der::Error;

fn try_from(alg: AlgorithmIdentifier<'a>) -> der::Result<Self> {
fn try_from(alg: AlgorithmIdentifierRef<'a>) -> der::Result<Self> {
if let Some(params) = alg.parameters {
// TODO(tarcieri): support non-NULL parameters?
if !params.is_null() {
Expand All @@ -323,12 +323,12 @@ impl<'a> TryFrom<AlgorithmIdentifier<'a>> for Pbkdf2Prf {
}
}

impl<'a> From<Pbkdf2Prf> for AlgorithmIdentifier<'a> {
impl<'a> From<Pbkdf2Prf> for AlgorithmIdentifierRef<'a> {
fn from(prf: Pbkdf2Prf) -> Self {
// TODO(tarcieri): support non-NULL parameters?
let parameters = der::asn1::Null;

AlgorithmIdentifier {
AlgorithmIdentifierRef {
oid: prf.oid(),
parameters: Some(parameters.into()),
}
Expand All @@ -337,11 +337,11 @@ impl<'a> From<Pbkdf2Prf> for AlgorithmIdentifier<'a> {

impl Encode for Pbkdf2Prf {
fn encoded_len(&self) -> der::Result<Length> {
AlgorithmIdentifier::try_from(*self)?.encoded_len()
AlgorithmIdentifierRef::try_from(*self)?.encoded_len()
}

fn encode(&self, writer: &mut dyn Writer) -> der::Result<()> {
AlgorithmIdentifier::try_from(*self)?.encode(writer)
AlgorithmIdentifierRef::try_from(*self)?.encode(writer)
}
}

Expand Down
Loading