Skip to main content

structured_pkix/ocsp/
request.rs

1//! Original RFC6960 requests, independently of transport and server policy.
2//!
3//! The complete DER request and signed TBS are borrowed. Certificates are
4//! candidates, not trust anchors; signature, name, extension, nonce and response
5//! identity facts never imply server authorization or certificate status.
6
7use super::{CertId, end, extensions_element, read_id, required, sequence};
8use crate::Certificate;
9use crate::algorithm::{self, AlgorithmIdentifier};
10use crate::error::{Error, ErrorCode, Located, Result};
11use crate::extension::Extensions;
12use crate::general_name::{self, GeneralName};
13use crate::signature::SignatureValue;
14use structured_asn1::memory::{Execution, OwnedVec, Work};
15use structured_asn1::{Element, Encoding, Parser, Reader, Span, Tag, universal};
16
17mod authentication;
18mod binding;
19pub use authentication::{
20    RequestAuthentication, RequestSignatureError, RequestSignatureFailure, RequestorBinding,
21    SignedRequest,
22};
23pub use binding::{BoundResponse, RequestLookup};
24
25const FIELD: &str = "ocspRequest";
26const TBS: &str = "ocspRequest.tbsRequest";
27const ENTRY: &str = "ocspRequest.requestList";
28const SIGNATURE: &str = "ocspRequest.signature";
29
30/// One original certificate-status request, including its own extension scope.
31#[derive(Debug)]
32pub struct RequestEntry<'a> {
33    id: CertId<'a>,
34    extensions: Extensions<'a>,
35    span: Span,
36}
37impl<'a> RequestEntry<'a> {
38    /// Original certificate identity; does not authenticate its issuer.
39    #[must_use]
40    pub fn id(&self) -> CertId<'a> {
41        self.id
42    }
43    /// Only this entry's extensions, distinct from request-wide extensions.
44    #[must_use]
45    pub fn extensions(&self) -> &Extensions<'a> {
46        &self.extensions
47    }
48    /// Whole original entry range.
49    #[must_use]
50    pub fn span(&self) -> Span {
51        self.span
52    }
53}
54
55/// Original optional signature and untrusted certificate candidates.
56#[derive(Debug)]
57pub struct RequestSignature<'a> {
58    algorithm: AlgorithmIdentifier<'a>,
59    value: SignatureValue<'a>,
60    certificates: OwnedVec<Certificate<'a>>,
61}
62impl<'a> RequestSignature<'a> {
63    /// Original algorithm and parameters, without selecting a backend.
64    #[must_use]
65    pub fn algorithm(&self) -> AlgorithmIdentifier<'a> {
66        self.algorithm
67    }
68    /// Original BIT STRING with its producing source context.
69    #[must_use]
70    pub fn value(&self) -> SignatureValue<'a> {
71        self.value
72    }
73    /// Included candidates; none is trusted or selected automatically.
74    #[must_use]
75    pub fn certificates(&self) -> &[Certificate<'a>] {
76        &self.certificates
77    }
78}
79
80/// A complete version-one `OCSPRequest` with exact original signed bytes.
81#[derive(Debug)]
82pub struct OcspRequest<'a> {
83    bytes: &'a [u8],
84    signed: Element<'a>,
85    span: Span,
86    parser: &'a Parser,
87    requestor: Option<GeneralName<'a>>,
88    entries: OwnedVec<RequestEntry<'a>>,
89    extensions: Extensions<'a>,
90    signature: Option<RequestSignature<'a>>,
91}
92
93impl<'a> OcspRequest<'a> {
94    /// Decode one complete request window. No signing, fetching, randomness,
95    /// default-budget parser or certificate selection is performed.
96    pub fn read(parser: &'a Parser, bytes: &'a [u8], base: u64) -> Result<Self> {
97        let mut reader = parser.read(bytes, base).field(FIELD)?;
98        let element = required(&mut reader, FIELD)?;
99        let request = Self::read_element(&reader, &element)?;
100        end(&reader, FIELD)?;
101        Ok(request)
102    }
103
104    /// Decode an embedded request under DER and its actual producing session.
105    /// RFC6960 §§4/4.1.1–4.1.2 require DER TBS, explicit wrappers, at least
106    /// one request, and a requestorName when a signature is present.
107    /// <https://www.rfc-editor.org/rfc/rfc6960#section-4.1.1>
108    pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
109        let mut der = parent.reread(element, Encoding::Der).field(FIELD)?;
110        let root = der
111            .expect(Tag::constructed(universal::SEQUENCE))
112            .field(FIELD)?;
113        let mut outer = der.enter(&root).field(FIELD)?;
114        let signed = required(&mut outer, TBS)?;
115        let mut tbs = sequence(&outer, &signed, TBS)?;
116        let mut next = required(&mut tbs, TBS)?;
117        if next.tag() == Tag::context(true, 0) {
118            let mut explicit = tbs.enter(&next).field(TBS)?;
119            let version = explicit.read_integer().field(TBS)?;
120            explicit.charge(9).field(TBS)?;
121            end(&explicit, TBS)?;
122            // X.690 §11.5: a DER DEFAULT value must be omitted. Unknown
123            // versions are unsupported, not silently treated as version one.
124            return Err(Error::new(
125                if version.as_u64() == Some(0) {
126                    ErrorCode::MalformedValue
127                } else {
128                    ErrorCode::UnsupportedVersion
129                },
130                TBS,
131                next.span().start,
132            ));
133        }
134        let requestor = if next.tag() == Tag::context(true, 1) {
135            let mut explicit = tbs.enter(&next).field(TBS)?;
136            let name = required(&mut explicit, TBS)?;
137            end(&explicit, TBS)?;
138            let name = general_name::read(&explicit, &name, TBS)?;
139            next = required(&mut tbs, TBS)?;
140            Some(name)
141        } else {
142            None
143        };
144        let mut requests = sequence(&tbs, &next, ENTRY)?;
145        let work = parent.execution();
146        let mut entries = work.vector();
147        while let Some(element) = requests.next_element().field(ENTRY)? {
148            let mut entry = sequence(&requests, &element, ENTRY)?;
149            let id = required(&mut entry, ENTRY)?;
150            let id = read_id(&entry, &id, "ocspRequest.certID")?;
151            let extra = entry.next_element().field(ENTRY)?;
152            let extensions = extensions_element(&entry, extra.as_ref(), 0, ENTRY)?;
153            end(&entry, ENTRY)?;
154            entries
155                .try_push(RequestEntry {
156                    id,
157                    extensions,
158                    span: element.span(),
159                })
160                .map_err(|reason| Error::resource(reason, ENTRY, element.span().start))?;
161        }
162        if entries.is_empty() {
163            return Err(Error::new(
164                ErrorCode::EmptySequence,
165                ENTRY,
166                next.span().start,
167            ));
168        }
169        let extra = tbs.next_element().field(TBS)?;
170        let extensions = extensions_element(&tbs, extra.as_ref(), 2, TBS)?;
171        end(&tbs, TBS)?;
172        let signature = if let Some(wrapper) = outer.next_element().field(SIGNATURE)? {
173            if wrapper.tag() != Tag::context(true, 0) {
174                return Err(Error::new(
175                    ErrorCode::UnexpectedField,
176                    SIGNATURE,
177                    wrapper.span().start,
178                ));
179            }
180            if requestor.is_none() {
181                return Err(Error::new(
182                    ErrorCode::MissingField,
183                    TBS,
184                    signed.span().start,
185                ));
186            }
187            Some(read_signature(&outer, &wrapper)?)
188        } else {
189            None
190        };
191        end(&outer, FIELD)?;
192        Ok(Self {
193            bytes: element.as_bytes(),
194            signed,
195            span: element.span(),
196            parser: parent.parser(),
197            requestor,
198            entries: entries.into_owned(),
199            extensions,
200            signature,
201        })
202    }
203
204    /// Whole original request DER; no re-encoding or copy.
205    #[must_use]
206    pub fn as_bytes(&self) -> &'a [u8] {
207        self.bytes
208    }
209    /// Exact DER `TBSRequest` signed by the optional signature, excluding its wrapper.
210    #[must_use]
211    pub fn signed_bytes(&self) -> &'a [u8] {
212        self.signed.as_bytes()
213    }
214    /// Original whole TBS range.
215    #[must_use]
216    pub fn signed_span(&self) -> Span {
217        self.signed.span()
218    }
219    /// Original whole request range.
220    #[must_use]
221    pub fn span(&self) -> Span {
222        self.span
223    }
224    /// Original optional requestor name; not an authenticated identity by itself.
225    #[must_use]
226    pub fn requestor(&self) -> Option<&GeneralName<'a>> {
227        self.requestor.as_ref()
228    }
229    /// Every original entry in wire order, including duplicate `CertIDs`.
230    #[must_use]
231    pub fn requests(&self) -> &[RequestEntry<'a>] {
232        &self.entries
233    }
234    /// Request-wide extensions, independently of each entry's extensions.
235    #[must_use]
236    pub fn extensions(&self) -> &Extensions<'a> {
237        &self.extensions
238    }
239    /// Optional original signature; absent never means an authenticated request.
240    #[must_use]
241    pub fn signature(&self) -> Option<&RequestSignature<'a>> {
242        self.signature.as_ref()
243    }
244    /// Attach this original request to the current operation without scanning,
245    /// cloning an account, or discarding either operation's cumulative ceiling.
246    pub fn execution_in<'op, W: Work>(&self, current: &'op W) -> Execution<'op>
247    where
248        'a: 'op,
249    {
250        current.execution_for(self.parser)
251    }
252}
253
254fn read_signature<'a>(parent: &Reader<'a>, wrapper: &Element<'a>) -> Result<RequestSignature<'a>> {
255    let mut explicit = parent.enter(wrapper).field(SIGNATURE)?;
256    let element = required(&mut explicit, SIGNATURE)?;
257    end(&explicit, SIGNATURE)?;
258    let mut inside = sequence(&explicit, &element, SIGNATURE)?;
259    let algorithm = required(&mut inside, SIGNATURE)?;
260    let algorithm = algorithm::read(&inside, &algorithm, SIGNATURE)?;
261    let value = SignatureValue::read(&mut inside, SIGNATURE)?;
262    let certificates = if let Some(wrapper) = inside.next_element().field(SIGNATURE)? {
263        read_certificates(&inside, &wrapper, SIGNATURE)?
264    } else {
265        parent.execution().vector().into_owned()
266    };
267    end(&inside, SIGNATURE)?;
268    Ok(RequestSignature {
269        algorithm,
270        value,
271        certificates,
272    })
273}
274
275pub(super) fn read_certificates<'a>(
276    parent: &Reader<'a>,
277    wrapper: &Element<'a>,
278    field: &'static str,
279) -> Result<OwnedVec<Certificate<'a>>> {
280    if wrapper.tag() != Tag::context(true, 0) {
281        return Err(Error::new(
282            ErrorCode::UnexpectedField,
283            field,
284            wrapper.span().start,
285        ));
286    }
287    let mut explicit = parent.enter(wrapper).field(field)?;
288    let element = required(&mut explicit, field)?;
289    end(&explicit, field)?;
290    let mut sequence = sequence(&explicit, &element, field)?;
291    let work = parent.execution();
292    let mut certificates = work.vector();
293    while let Some(element) = sequence.next_element().field(field)? {
294        certificates
295            .try_push(Certificate::read_element(&sequence, &element)?)
296            .map_err(|reason| Error::resource(reason, field, element.span().start))?;
297    }
298    Ok(certificates.into_owned())
299}