Skip to main content

pkix/cmpv2/
body.rs

1/* Copyright (c) Fortanix, Inc.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 */
7
8//! PKIBody type
9
10use yasna::{ASN1Error, ASN1ErrorKind, ASN1Result, BERDecodable, BERReader, DERWriter, Tag};
11
12use crate::{crmf::request::CertReqMessages, types::DerAnyOwned, DerWrite};
13
14/// The `PKIBody` type is defined in [RFC 4210 Section 5.1.2]
15///
16/// ```text
17/// PKIBody ::= CHOICE {       -- message-specific body elements
18///     ir       [0]  CertReqMessages,        --Initialization Request
19///     ip       [1]  CertRepMessage,         --Initialization Response
20///     cr       [2]  CertReqMessages,        --Certification Request
21///     cp       [3]  CertRepMessage,         --Certification Response
22///     p10cr    [4]  CertificationRequest,   --imported from [PKCS10]
23///     popdecc  [5]  POPODecKeyChallContent, --pop Challenge
24///     popdecr  [6]  POPODecKeyRespContent,  --pop Response
25///     kur      [7]  CertReqMessages,        --Key Update Request
26///     kup      [8]  CertRepMessage,         --Key Update Response
27///     krr      [9]  CertReqMessages,        --Key Recovery Request
28///     krp      [10] KeyRecRepContent,       --Key Recovery Response
29///     rr       [11] RevReqContent,          --Revocation Request
30///     rp       [12] RevRepContent,          --Revocation Response
31///     ccr      [13] CertReqMessages,        --Cross-Cert. Request
32///     ccp      [14] CertRepMessage,         --Cross-Cert. Response
33///     ckuann   [15] CAKeyUpdAnnContent,     --CA Key Update Ann.
34///     cann     [16] CertAnnContent,         --Certificate Ann.
35///     rann     [17] RevAnnContent,          --Revocation Ann.
36///     crlann   [18] CRLAnnContent,          --CRL Announcement
37///     pkiconf  [19] PKIConfirmContent,      --Confirmation
38///     nested   [20] NestedMessageContent,   --Nested Message
39///     genm     [21] GenMsgContent,          --General Message
40///     genp     [22] GenRepContent,          --General Response
41///     error    [23] ErrorMsgContent,        --Error Message
42///     certConf [24] CertConfirmContent,     --Certificate confirm
43///     pollReq  [25] PollReqContent,         --Polling request
44///     pollRep  [26] PollRepContent          --Polling response
45/// }
46/// ```
47///
48/// [RFC 4210 Section 5.1.2]: https://datatracker.ietf.org/doc/html/rfc4210#section-5.1.2
49#[derive(Clone, Debug, Eq, PartialEq, Hash)]
50pub enum PkiBody {
51    /// Initialization Request
52    Ir(CertReqMessages),
53    /// Initialization Response
54    Ip(CertRepMessage),
55    /// Certification Request
56    Cr(CertReqMessages),
57    /// Certification Response
58    Cp(CertRepMessage),
59    /// imported from [PKCS10](https://datatracker.ietf.org/doc/html/rfc2986)
60    P10cr(CertReq),
61    /// pop Challenge
62    Popdecc(PopoDecKeyChallContent),
63    /// pop Response
64    Popdecr(PopoDecKeyRespContent),
65    /// Key Update Request
66    KUr(CertReqMessages),
67    /// Key Update Response
68    Kup(CertRepMessage),
69    /// Key Recovery Request
70    Krr(CertReqMessages),
71    /// Key Recovery Response
72    Krp(KeyRecRepContent),
73    /// Revocation Request
74    Rr(RevReqContent),
75    /// Revocation Response
76    Rp(RevRepContent),
77    /// Cross-Cert. Request
78    Ccr(CertReqMessages),
79    /// Cross-Cert. Response
80    Ccp(CertRepMessage),
81    /// CA Key Update Ann.
82    Ckuann(CaKeyUpdAnnContent),
83    /// Certificate Ann.
84    Cann(CertAnnContent),
85    /// Revocation Ann.
86    Rann(RevAnnContent),
87    /// CRL Announcement
88    CrlAnn(CrlAnnContent),
89    /// Confirmation
90    PkiConf(PkiConfirmContent),
91    /// Nested Message
92    Nested(NestedMessageContent),
93    /// General Message
94    GenM(GenMsgContent),
95    /// General Response
96    GenP(GenRepContent),
97    /// Error Message
98    Error(ErrorMsgContent),
99    /// Certificate confirm
100    CertConf(CertConfirmContent),
101    /// Polling request
102    PollReq(PollReqContent),
103    /// Polling response
104    PollRep(PollRepContent),
105}
106
107impl PkiBody {
108    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Initialization Request
109    const TAG_IR: u64 = 0;
110    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Initialization Response
111    const TAG_IP: u64 = 1;
112    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Certification Request
113    const TAG_CR: u64 = 2;
114    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Certification Response
115    const TAG_CP: u64 = 3;
116    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for imported from [PKCS10]
117    const TAG_P10_CR: u64 = 4;
118    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for pop Challenge
119    const TAG_POP_DE_CC: u64 = 5;
120    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for pop Response
121    const TAG_POP_DE_CR: u64 = 6;
122    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Key Update Request
123    const TAG_KUR: u64 = 7;
124    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Key Update Response
125    const TAG_KUP: u64 = 8;
126    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Key Recovery Request
127    const TAG_KRR: u64 = 9;
128    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Key Recovery Response
129    const TAG_KRP: u64 = 10;
130    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Revocation Request
131    const TAG_RR: u64 = 11;
132    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Revocation Response
133    const TAG_RP: u64 = 12;
134    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Cross-Cert. Request
135    const TAG_CCR: u64 = 13;
136    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Cross-Cert. Response
137    const TAG_CCP: u64 = 14;
138    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for CA Key Update Ann.
139    const TAG_CKU_ANN: u64 = 15;
140    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Certificate Ann.
141    const TAG_C_ANN: u64 = 16;
142    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Revocation Ann.
143    const TAG_R_ANN: u64 = 17;
144    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for CRL Announcement
145    const TAG_CRL_ANN: u64 = 18;
146    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Confirmation
147    const TAG_PKI_CONF: u64 = 19;
148    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Nested Message
149    const TAG_NESTED: u64 = 20;
150    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for General Message
151    const TAG_GEN_M: u64 = 21;
152    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for General Response
153    const TAG_GEN_P: u64 = 22;
154    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Error Message
155    const TAG_ERROR: u64 = 23;
156    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Certificate confirm
157    const TAG_CERT_CONF: u64 = 24;
158    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Polling request
159    const TAG_POLL_REQ: u64 = 25;
160    /// EXPLICIT TAG [rfc4210#appendix-F](https://datatracker.ietf.org/doc/html/rfc4210#appendix-F) for Polling response
161    const TAG_POLL_REP: u64 = 26;
162
163    fn tag(&self) -> Tag {
164        match self {
165            PkiBody::Ir(_) => Tag::context(Self::TAG_IR),
166            PkiBody::Ip(_) => Tag::context(Self::TAG_IP),
167            PkiBody::Cr(_) => Tag::context(Self::TAG_CR),
168            PkiBody::Cp(_) => Tag::context(Self::TAG_CP),
169            PkiBody::P10cr(_) => Tag::context(Self::TAG_P10_CR),
170            PkiBody::Popdecc(_) => Tag::context(Self::TAG_POP_DE_CC),
171            PkiBody::Popdecr(_) => Tag::context(Self::TAG_POP_DE_CR),
172            PkiBody::KUr(_) => Tag::context(Self::TAG_KUR),
173            PkiBody::Kup(_) => Tag::context(Self::TAG_KUP),
174            PkiBody::Krr(_) => Tag::context(Self::TAG_KRR),
175            PkiBody::Krp(_) => Tag::context(Self::TAG_KRP),
176            PkiBody::Rr(_) => Tag::context(Self::TAG_RR),
177            PkiBody::Rp(_) => Tag::context(Self::TAG_RP),
178            PkiBody::Ccr(_) => Tag::context(Self::TAG_CCR),
179            PkiBody::Ccp(_) => Tag::context(Self::TAG_CCP),
180            PkiBody::Ckuann(_) => Tag::context(Self::TAG_CKU_ANN),
181            PkiBody::Cann(_) => Tag::context(Self::TAG_C_ANN),
182            PkiBody::Rann(_) => Tag::context(Self::TAG_R_ANN),
183            PkiBody::CrlAnn(_) => Tag::context(Self::TAG_CRL_ANN),
184            PkiBody::PkiConf(_) => Tag::context(Self::TAG_PKI_CONF),
185            PkiBody::Nested(_) => Tag::context(Self::TAG_NESTED),
186            PkiBody::GenM(_) => Tag::context(Self::TAG_GEN_M),
187            PkiBody::GenP(_) => Tag::context(Self::TAG_GEN_P),
188            PkiBody::Error(_) => Tag::context(Self::TAG_ERROR),
189            PkiBody::CertConf(_) => Tag::context(Self::TAG_CERT_CONF),
190            PkiBody::PollReq(_) => Tag::context(Self::TAG_POLL_REQ),
191            PkiBody::PollRep(_) => Tag::context(Self::TAG_POLL_REP),
192        }
193    }
194}
195
196impl DerWrite for PkiBody {
197    #[rustfmt::skip]
198    fn write(&self, writer: DERWriter) {
199        match self {
200            PkiBody::Ir(body)       => writer.write_tagged(self.tag(), |w| body.write(w)),
201            PkiBody::Ip(body)       => writer.write_tagged(self.tag(), |w| body.write(w)),
202            PkiBody::Cr(body)       => writer.write_tagged(self.tag(), |w| body.write(w)),
203            PkiBody::Cp(body)       => writer.write_tagged(self.tag(), |w| body.write(w)),
204            PkiBody::P10cr(body)    => writer.write_tagged(self.tag(), |w| body.write(w)),
205            PkiBody::Popdecc(body)  => writer.write_tagged(self.tag(), |w| body.write(w)),
206            PkiBody::Popdecr(body)  => writer.write_tagged(self.tag(), |w| body.write(w)),
207            PkiBody::KUr(body)      => writer.write_tagged(self.tag(), |w| body.write(w)),
208            PkiBody::Kup(body)      => writer.write_tagged(self.tag(), |w| body.write(w)),
209            PkiBody::Krr(body)      => writer.write_tagged(self.tag(), |w| body.write(w)),
210            PkiBody::Krp(body)      => writer.write_tagged(self.tag(), |w| body.write(w)),
211            PkiBody::Rr(body)       => writer.write_tagged(self.tag(), |w| body.write(w)),
212            PkiBody::Rp(body)       => writer.write_tagged(self.tag(), |w| body.write(w)),
213            PkiBody::Ccr(body)      => writer.write_tagged(self.tag(), |w| body.write(w)),
214            PkiBody::Ccp(body)      => writer.write_tagged(self.tag(), |w| body.write(w)),
215            PkiBody::Ckuann(body)   => writer.write_tagged(self.tag(), |w| body.write(w)),
216            PkiBody::Cann(body)     => writer.write_tagged(self.tag(), |w| body.write(w)),
217            PkiBody::Rann(body)     => writer.write_tagged(self.tag(), |w| body.write(w)),
218            PkiBody::CrlAnn(body)   => writer.write_tagged(self.tag(), |w| body.write(w)),
219            PkiBody::PkiConf(body)  => writer.write_tagged(self.tag(), |w| body.write(w)),
220            PkiBody::Nested(body)   => writer.write_tagged(self.tag(), |w| body.write(w)),
221            PkiBody::GenM(body)     => writer.write_tagged(self.tag(), |w| body.write(w)),
222            PkiBody::GenP(body)     => writer.write_tagged(self.tag(), |w| body.write(w)),
223            PkiBody::Error(body)    => writer.write_tagged(self.tag(), |w| body.write(w)),
224            PkiBody::CertConf(body) => writer.write_tagged(self.tag(), |w| body.write(w)),
225            PkiBody::PollReq(body)  => writer.write_tagged(self.tag(), |w| body.write(w)),
226            PkiBody::PollRep(body)  => writer.write_tagged(self.tag(), |w| body.write(w)),
227        }
228    }
229}
230
231impl BERDecodable for PkiBody {
232    #[rustfmt::skip]
233    fn decode_ber(reader: BERReader) -> ASN1Result<Self> {
234        let tag_number = reader.lookahead_tag()?.tag_number;
235        match tag_number {
236            Self::TAG_IR =>        reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Ir(CertReqMessages::decode_ber(r)?))),
237            Self::TAG_IP =>        reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Ip(CertRepMessage::decode_ber(r)?))),
238            Self::TAG_CR =>        reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Cr(CertReqMessages::decode_ber(r)?))),
239            Self::TAG_CP =>        reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Cp(CertRepMessage::decode_ber(r)?))),
240            Self::TAG_P10_CR =>    reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::P10cr(CertReq::decode_ber(r)?))),
241            Self::TAG_POP_DE_CC => reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Popdecc(PopoDecKeyChallContent::decode_ber(r)?))),
242            Self::TAG_POP_DE_CR => reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Popdecr(PopoDecKeyRespContent::decode_ber(r)?))),
243            Self::TAG_KUR =>       reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::KUr(CertReqMessages::decode_ber(r)?))),
244            Self::TAG_KUP =>       reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Kup(CertRepMessage::decode_ber(r)?))),
245            Self::TAG_KRR =>       reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Krr(CertReqMessages::decode_ber(r)?))),
246            Self::TAG_KRP =>       reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Krp(KeyRecRepContent::decode_ber(r)?))),
247            Self::TAG_RR =>        reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Rr(RevReqContent::decode_ber(r)?))),
248            Self::TAG_RP =>        reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Rp(RevRepContent::decode_ber(r)?))),
249            Self::TAG_CCR =>       reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Ccr(CertReqMessages::decode_ber(r)?))),
250            Self::TAG_CCP =>       reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Ccp(CertRepMessage::decode_ber(r)?))),
251            Self::TAG_CKU_ANN =>   reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Ckuann(CaKeyUpdAnnContent::decode_ber(r)?))),
252            Self::TAG_C_ANN =>     reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Cann(CertAnnContent::decode_ber(r)?))),
253            Self::TAG_R_ANN =>     reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Rann(RevAnnContent::decode_ber(r)?))),
254            Self::TAG_CRL_ANN =>   reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::CrlAnn(CrlAnnContent::decode_ber(r)?))),
255            Self::TAG_PKI_CONF =>  reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::PkiConf(PkiConfirmContent::decode_ber(r)?))),
256            Self::TAG_NESTED =>    reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Nested(NestedMessageContent::decode_ber(r)?))),
257            Self::TAG_GEN_M =>     reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::GenM(GenMsgContent::decode_ber(r)?))),
258            Self::TAG_GEN_P =>     reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::GenP(GenRepContent::decode_ber(r)?))),
259            Self::TAG_ERROR =>     reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::Error(ErrorMsgContent::decode_ber(r)?))),
260            Self::TAG_CERT_CONF => reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::CertConf(CertConfirmContent::decode_ber(r)?))),
261            Self::TAG_POLL_REQ =>  reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::PollReq(PollReqContent::decode_ber(r)?))),
262            Self::TAG_POLL_REP =>  reader.read_tagged(Tag::context(tag_number), |r| Ok(PkiBody::PollRep(PollRepContent::decode_ber(r)?))),
263            _ => Err(ASN1Error::new(ASN1ErrorKind::Invalid)),
264        }
265    }
266}
267
268/// TODO: not yet implemented, tracking issue: #23
269type CertRepMessage = DerAnyOwned;
270/// TODO: not yet implemented, tracking issue: #23
271type CertReq = DerAnyOwned;
272/// TODO: not yet implemented, tracking issue: #23
273type PopoDecKeyChallContent = DerAnyOwned;
274/// TODO: not yet implemented, tracking issue: #23
275type PopoDecKeyRespContent = DerAnyOwned;
276/// TODO: not yet implemented, tracking issue: #23
277type KeyRecRepContent = DerAnyOwned;
278/// TODO: not yet implemented, tracking issue: #23
279type RevReqContent = DerAnyOwned;
280/// TODO: not yet implemented, tracking issue: #23
281type RevRepContent = DerAnyOwned;
282/// TODO: not yet implemented, tracking issue: #23
283type CaKeyUpdAnnContent = DerAnyOwned;
284/// TODO: not yet implemented, tracking issue: #23
285type CertAnnContent = DerAnyOwned;
286/// TODO: not yet implemented, tracking issue: #23
287type RevAnnContent = DerAnyOwned;
288/// TODO: not yet implemented, tracking issue: #23
289type CrlAnnContent = DerAnyOwned;
290/// TODO: not yet implemented, tracking issue: #23
291type PkiConfirmContent = DerAnyOwned;
292/// TODO: not yet implemented, tracking issue: #23
293type NestedMessageContent = DerAnyOwned;
294/// TODO: not yet implemented, tracking issue: #23
295type GenMsgContent = DerAnyOwned;
296/// TODO: not yet implemented, tracking issue: #23
297type GenRepContent = DerAnyOwned;
298/// TODO: not yet implemented, tracking issue: #23
299type ErrorMsgContent = DerAnyOwned;
300/// TODO: not yet implemented, tracking issue: #23
301type CertConfirmContent = DerAnyOwned;
302/// TODO: not yet implemented, tracking issue: #23
303type PollReqContent = DerAnyOwned;
304/// TODO: not yet implemented, tracking issue: #23
305type PollRepContent = DerAnyOwned;