aboutsummaryrefslogtreecommitdiff
path: root/src/request.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/request.rs')
-rw-r--r--src/request.rs139
1 files changed, 112 insertions, 27 deletions
diff --git a/src/request.rs b/src/request.rs
index 6ab16cf..50478d8 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -1,24 +1,34 @@
//! PKCS#10 Certification Request types
-use crate::ext::Extension;
-use crate::{attr::Attributes, name::Name};
+use crate::{
+ attr::{Attribute, AttributeValue, Attributes},
+ ext::Extension,
+ name::Name,
+};
use alloc::vec::Vec;
use const_oid::db::rfc5912::ID_EXTENSION_REQ;
use const_oid::{AssociatedOid, ObjectIdentifier};
-use der::asn1::BitStringRef;
-use der::{Decode, Enumerated, Sequence};
-use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo};
+use der::asn1::BitString;
+use der::{
+ asn1::{Any, SetOfVec},
+ Decode, Enumerated, Sequence,
+};
+use spki::{AlgorithmIdentifierOwned, SubjectPublicKeyInfoOwned};
+
+#[cfg(feature = "pem")]
+use der::pem::PemLabel;
/// Version identifier for certification request information.
///
/// (RFC 2986 designates `0` as the only valid version)
-#[derive(Clone, Debug, Copy, PartialEq, Eq, Enumerated)]
+#[derive(Clone, Debug, Copy, PartialEq, Eq, Enumerated, Default)]
#[asn1(type = "INTEGER")]
#[repr(u8)]
pub enum Version {
/// Denotes PKCS#8 v1
+ #[default]
V1 = 0,
}
@@ -35,27 +45,19 @@ pub enum Version {
///
/// [RFC 2986 Section 4]: https://datatracker.ietf.org/doc/html/rfc2986#section-4
#[derive(Clone, Debug, PartialEq, Eq, Sequence)]
-pub struct CertReqInfo<'a> {
+pub struct CertReqInfo {
/// Certification request version.
pub version: Version,
/// Subject name.
- pub subject: Name<'a>,
+ pub subject: Name,
/// Subject public key info.
- pub public_key: SubjectPublicKeyInfo<'a>,
+ pub public_key: SubjectPublicKeyInfoOwned,
/// Request attributes.
#[asn1(context_specific = "0", tag_mode = "IMPLICIT")]
- pub attributes: Attributes<'a>,
-}
-
-impl<'a> TryFrom<&'a [u8]> for CertReqInfo<'a> {
- type Error = der::Error;
-
- fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
- Self::from_der(bytes)
- }
+ pub attributes: Attributes,
}
/// PKCS#10 `CertificationRequest` as defined in [RFC 2986 Section 4].
@@ -70,18 +72,23 @@ impl<'a> TryFrom<&'a [u8]> for CertReqInfo<'a> {
///
/// [RFC 2986 Section 4]: https://datatracker.ietf.org/doc/html/rfc2986#section-4
#[derive(Clone, Debug, PartialEq, Eq, Sequence)]
-pub struct CertReq<'a> {
+pub struct CertReq {
/// Certification request information.
- pub info: CertReqInfo<'a>,
+ pub info: CertReqInfo,
/// Signature algorithm identifier.
- pub algorithm: AlgorithmIdentifier<'a>,
+ pub algorithm: AlgorithmIdentifierOwned,
/// Signature.
- pub signature: BitStringRef<'a>,
+ pub signature: BitString,
}
-impl<'a> TryFrom<&'a [u8]> for CertReq<'a> {
+#[cfg(feature = "pem")]
+impl PemLabel for CertReq {
+ const PEM_LABEL: &'static str = "CERTIFICATE REQUEST";
+}
+
+impl<'a> TryFrom<&'a [u8]> for CertReq {
type Error = der::Error;
fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
@@ -96,11 +103,89 @@ impl<'a> TryFrom<&'a [u8]> for CertReq<'a> {
/// ```
///
/// [RFC 5272 Section 3.1]: https://datatracker.ietf.org/doc/html/rfc5272#section-3.1
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct ExtensionReq<'a>(pub Vec<Extension<'a>>);
+#[derive(Clone, Debug, PartialEq, Eq, Default)]
+pub struct ExtensionReq(pub Vec<Extension>);
-impl<'a> AssociatedOid for ExtensionReq<'a> {
+impl AssociatedOid for ExtensionReq {
const OID: ObjectIdentifier = ID_EXTENSION_REQ;
}
-impl_newtype!(ExtensionReq<'a>, Vec<Extension<'a>>);
+impl_newtype!(ExtensionReq, Vec<Extension>);
+
+impl TryFrom<ExtensionReq> for Attribute {
+ type Error = der::Error;
+
+ fn try_from(extension_req: ExtensionReq) -> der::Result<Attribute> {
+ let mut values: SetOfVec<AttributeValue> = Default::default();
+ values.insert(Any::encode_from(&extension_req.0)?)?;
+
+ Ok(Attribute {
+ oid: ExtensionReq::OID,
+ values,
+ })
+ }
+}
+
+pub mod attributes {
+ //! Set of attributes that may be associated to a request
+
+ use alloc::vec;
+ use const_oid::AssociatedOid;
+ use der::{
+ asn1::{Any, ObjectIdentifier, SetOfVec},
+ EncodeValue, Length, Result, Tag, Tagged, Writer,
+ };
+
+ use crate::{attr::Attribute, ext::pkix::name::DirectoryString};
+
+ /// Trait to be implement by request attributes
+ pub trait AsAttribute: AssociatedOid + Tagged + EncodeValue + Sized {
+ /// Returns the Attribute with the content encoded.
+ fn to_attribute(&self) -> Result<Attribute> {
+ let inner: Any = der::asn1::Any::encode_from(self)?;
+
+ let values = SetOfVec::try_from(vec![inner])?;
+
+ Ok(Attribute {
+ oid: Self::OID,
+ values,
+ })
+ }
+ }
+
+ /// `ChallengePassword` as defined in [RFC 2985 Section 5.4.1]
+ ///
+ /// ```text
+ /// challengePassword ATTRIBUTE ::= {
+ /// WITH SYNTAX DirectoryString {pkcs-9-ub-challengePassword}
+ /// EQUALITY MATCHING RULE caseExactMatch
+ /// SINGLE VALUE TRUE
+ /// ID pkcs-9-at-challengePassword
+ /// }
+ /// ```
+ ///
+ /// [RFC 2985 Section 5.4.1]: https://www.rfc-editor.org/rfc/rfc2985#page-16
+ pub struct ChallengePassword(pub DirectoryString);
+
+ impl AsAttribute for ChallengePassword {}
+
+ impl AssociatedOid for ChallengePassword {
+ const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.113549.1.9.7");
+ }
+
+ impl Tagged for ChallengePassword {
+ fn tag(&self) -> Tag {
+ self.0.tag()
+ }
+ }
+
+ impl EncodeValue for ChallengePassword {
+ fn value_len(&self) -> Result<Length> {
+ self.0.value_len()
+ }
+
+ fn encode_value(&self, encoder: &mut impl Writer) -> Result<()> {
+ self.0.encode_value(encoder)
+ }
+ }
+}