Skip to main content

structured_pkix/hybrid/
request.rs

1//! DER PKCS#10 with independent native and alternative proofs of possession.
2//! Alternative attributes follow Bouncy Castle's single-valued convention;
3//! RFC2986 defines the surrounding structure, not this hybrid extension profile.
4//! <https://www.rfc-editor.org/rfc/rfc2986#section-4>
5
6use super::components::{self, Component, Components};
7use super::{
8    ALT_SIGNATURE_ALGORITHM, ALT_SIGNATURE_VALUE, AlternativeVerifier, CheckError, FIELD, Prepared,
9    SUBJECT_ALT_PUBLIC_KEY_INFO, Signatures, alternative, preimage, required,
10};
11use crate::algorithm::{self, AlgorithmIdentifier};
12use crate::error::Located;
13use crate::path::{Verify, WorkingKey};
14use crate::signature::SignatureValue;
15use crate::{Error, ErrorCode, Name, PublicKeyInfo, Result};
16use structured_asn1::memory::{OwnedVec, Work};
17use structured_asn1::{Element, Encoding, Oid, Parser, Reader, Span, Tag, universal};
18
19mod attributes;
20
21/// Original attribute identity and complete encoding. Values remain borrowed.
22#[derive(Debug, Clone, Copy)]
23pub struct Attribute<'a> {
24    kind: Oid<'a>,
25    element: Element<'a>,
26    values: Element<'a>,
27}
28impl<'a> Attribute<'a> {
29    /// Attribute type from the original DER.
30    #[must_use]
31    pub fn kind(self) -> Oid<'a> {
32        self.kind
33    }
34    /// Original complete Attribute TLV, not its enclosing IMPLICIT SET.
35    #[must_use]
36    pub fn element(self) -> Element<'a> {
37        self.element
38    }
39    /// Original SET OF values, whose DER and order have been checked.
40    #[must_use]
41    pub fn values(self) -> Element<'a> {
42        self.values
43    }
44}
45
46/// A request whose native signature and original attribute catalogue are readable.
47/// Alternative faults/absence remain in `components`, without erasing native facts.
48#[derive(Debug)]
49pub struct Request<'a> {
50    element: Element<'a>,
51    cri: Element<'a>,
52    attributes_element: Element<'a>,
53    subject: Name<'a>,
54    key: PublicKeyInfo<'a>,
55    algorithm: AlgorithmIdentifier<'a>,
56    signature: SignatureValue<'a>,
57    attributes: OwnedVec<Attribute<'a>>,
58    components: Components<'a>,
59    parser: &'a Parser,
60    depth: u32,
61}
62impl<'a> Request<'a> {
63    /// Read a complete original DER request under the supplied parser limits.
64    pub fn read(parser: &'a Parser, bytes: &'a [u8], base: u64) -> Result<Self> {
65        let mut reader = parser.read(bytes, base).field(FIELD)?;
66        let element = required(&mut reader, Tag::constructed(universal::SEQUENCE))?;
67        components::end(&reader)?;
68        Self::read_element(&reader, &element)
69    }
70    /// Read an embedded request, preserving its real source, depth and budget.
71    pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
72        let mut strict = parent.reread(element, Encoding::Der).field(FIELD)?;
73        let element = required(&mut strict, Tag::constructed(universal::SEQUENCE))?;
74        crate::der::conforms(&strict, &element, FIELD)?;
75        let mut inside = strict.enter(&element).field(FIELD)?;
76        let cri = required(&mut inside, Tag::constructed(universal::SEQUENCE))?;
77        let mut fields = inside.enter(&cri).field(FIELD)?;
78        let version = required(&mut fields, Tag::primitive(universal::INTEGER))?;
79        fields.charge(9).field(FIELD)?;
80        if fields.integer(&version).field(FIELD)?.as_u64() != Some(0) {
81            return Err(Error::new(
82                ErrorCode::UnsupportedVersion,
83                FIELD,
84                version.span().start,
85            ));
86        }
87        let name = required(&mut fields, Tag::constructed(universal::SEQUENCE))?;
88        let subject = crate::name::read(&fields, &name, FIELD)?;
89        let key = required(&mut fields, Tag::constructed(universal::SEQUENCE))?;
90        let key = PublicKeyInfo::read_element(&fields, &key, FIELD)?;
91        let attributes_element = required(&mut fields, Tag::context(true, 0))?;
92        components::end(&fields)?;
93        let (attributes, components) = attributes::read(&fields, &attributes_element)?;
94        let identifier = required(&mut inside, Tag::constructed(universal::SEQUENCE))?;
95        let algorithm = algorithm::read(&inside, &identifier, FIELD)?;
96        let signature = SignatureValue::read(&mut inside, FIELD)?;
97        components::end(&inside)?;
98        Ok(Self {
99            element,
100            cri,
101            attributes_element,
102            subject,
103            key,
104            algorithm,
105            signature,
106            attributes,
107            components,
108            parser: inside.parser(),
109            depth: inside.depth(),
110        })
111    }
112    /// Original whole request location.
113    #[must_use]
114    pub fn span(&self) -> Span {
115        self.element.span()
116    }
117    /// Original complete request DER.
118    #[must_use]
119    pub fn as_bytes(&self) -> &'a [u8] {
120        self.element.as_bytes()
121    }
122    /// Exact native proof input, including the alternative-value attribute.
123    #[must_use]
124    pub fn signed_bytes(&self) -> &'a [u8] {
125        self.cri.as_bytes()
126    }
127    /// Original requested subject, without application identity policy.
128    #[must_use]
129    pub fn subject(&self) -> &Name<'a> {
130        &self.subject
131    }
132    /// Original native key used for the native proof of possession.
133    #[must_use]
134    pub fn public_key(&self) -> PublicKeyInfo<'a> {
135        self.key
136    }
137    /// All original attributes, with no product-specific allowlist or normalization.
138    /// This raw catalogue borrow performs no traversal; callers fund their scans.
139    #[must_use]
140    pub fn attributes(&self) -> &[Attribute<'a>] {
141        &self.attributes
142    }
143    /// Independent alternative components, including located faults and absence.
144    #[must_use]
145    pub fn components(&self) -> &Components<'a> {
146        &self.components
147    }
148    /// Strict preparation: all three single-valued attributes must be readable.
149    pub fn prepare<W: Work>(&self, work: &W) -> Result<Prepared<'a>> {
150        self.algorithm
151            .query_in(work)
152            .charge_work(1)
153            .map_err(|e| Error::resource(e, FIELD, self.span().start))?;
154        super::validate_key(self.components.key.require()?, work)?;
155        let (algorithm, signature, remove) = self.components.signature_fields()?;
156        let reader = work
157            .read_scoped_source(
158                self.parser,
159                self.element.as_bytes(),
160                self.element.span().start,
161                Encoding::Der,
162                self.depth - 1,
163            )
164            .field(FIELD)?;
165        let preimage = preimage::request(&reader, self.cri, self.attributes_element, remove)?;
166        Ok(Prepared {
167            algorithm,
168            signature,
169            preimage,
170        })
171    }
172    /// Evaluate both proofs independently; a two-key enrollment caller requires Both.
173    pub fn check<W: Work, N: Verify<W>, A: AlternativeVerifier<W>>(
174        &self,
175        native: &N,
176        verifier: &A,
177        work: &W,
178    ) -> core::result::Result<Signatures, CheckError<N::Error, A::Error>> {
179        self.algorithm
180            .query_in(work)
181            .charge_work(1)
182            .map_err(|e| Error::resource(e, FIELD, self.span().start))?;
183        let native = native
184            .verify(
185                &self.algorithm,
186                WorkingKey::standing(self.key),
187                self.signed_bytes(),
188                self.signature,
189                work,
190            )
191            .map_err(CheckError::Native)?;
192        let alternative = match self.components.key.require() {
193            Ok(key) => alternative(self.prepare(work), key, verifier, work),
194            Err(error) if super::terminal(&error) => return Err(CheckError::Processing(error)),
195            Err(error) => {
196                return Ok(Signatures {
197                    native,
198                    alternative: super::Alternative::Nonconforming(super::Fault::of(&error)),
199                });
200            }
201        }
202        .map_err(|e| match e {
203            crate::error::CallbackError::Processing(e) => CheckError::Processing(e),
204            crate::error::CallbackError::Callback(e) => CheckError::Alternative(e),
205        })?;
206        Ok(Signatures {
207            native,
208            alternative,
209        })
210    }
211}
212fn single<'a, 'q>(
213    reader: &structured_asn1::ScopedReader<'a, 'q>,
214    set: &Element<'a>,
215) -> Result<(structured_asn1::ScopedReader<'a, 'q>, Element<'a>)> {
216    let mut values = reader.enter(set).field(FIELD)?;
217    let value = components::one(&mut values)?;
218    Ok((values, value))
219}