rfc5652.rs (44263B)
1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, v. 2.0. If a copy of the MPL was not distributed with this 3 // file, You can obtain one at https://mozilla.org/MPL/2.0/. 4 5 /*! ASN.1 data structures defined by RFC 5652. 6 7 The types defined in this module are intended to be extremely low-level 8 and only to be used for (de)serialization. See types outside the 9 `asn1` module tree for higher-level functionality. 10 11 Some RFC 5652 types are defined in the `x509-certificate` crate, which 12 this crate relies on for certificate parsing functionality. 13 */ 14 15 use std::{ 16 fmt::{Debug, Formatter}, 17 io::Write, 18 ops::{Deref, DerefMut}, 19 }; 20 21 use bcder::{ 22 decode::{Constructed, DecodeError, Source}, 23 encode, 24 encode::{PrimitiveContent, Values}, 25 BitString, Captured, ConstOid, Integer, Mode, OctetString, Oid, Tag, 26 }; 27 use x509_certificate::{asn1time::*, rfc3280::*, rfc5280::*, rfc5652::*}; 28 29 use crate::asn1::rfc3281::AttributeCertificate; 30 31 /// The data content type. 32 /// 33 /// `id-data` in the specification. 34 /// 35 /// 1.2.840.113549.1.7.1 36 pub const OID_ID_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 1]); 37 38 /// The signed-data content type. 39 /// 40 /// 1.2.840.113549.1.7.2 41 pub const OID_ID_SIGNED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 2]); 42 43 /// Enveloped data content type. 44 /// 45 /// 1.2.840.113549.1.7.3 46 pub const OID_ENVELOPE_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 3]); 47 48 /// Digested-data content type. 49 /// 50 /// 1.2.840.113549.1.7.5 51 pub const OID_DIGESTED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 5]); 52 53 /// Encrypted-data content type. 54 /// 55 /// 1.2.840.113549.1.7.6 56 pub const OID_ENCRYPTED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 7, 6]); 57 58 /// Authenticated-data content type. 59 /// 60 /// 1.2.840.113549.1.9.16.1.2 61 pub const OID_AUTHENTICATED_DATA: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 16, 1, 2]); 62 63 /// Identifies the content-type attribute. 64 /// 65 /// 1.2.840.113549.1.9.3 66 pub const OID_CONTENT_TYPE: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 3]); 67 68 /// Identifies the message-digest attribute. 69 /// 70 /// 1.2.840.113549.1.9.4 71 pub const OID_MESSAGE_DIGEST: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 4]); 72 73 /// Identifies the signing-time attribute. 74 /// 75 /// 1.2.840.113549.1.9.5 76 pub const OID_SIGNING_TIME: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 5]); 77 78 /// Identifies the countersignature attribute. 79 /// 80 /// 1.2.840.113549.1.9.6 81 pub const OID_COUNTER_SIGNATURE: ConstOid = Oid(&[42, 134, 72, 134, 247, 13, 1, 9, 6]); 82 83 /// Content info. 84 /// 85 /// ```ASN.1 86 /// ContentInfo ::= SEQUENCE { 87 /// contentType ContentType, 88 /// content [0] EXPLICIT ANY DEFINED BY contentType } 89 /// ``` 90 #[derive(Clone, Debug)] 91 pub struct ContentInfo { 92 pub content_type: ContentType, 93 pub content: Captured, 94 } 95 96 impl PartialEq for ContentInfo { 97 fn eq(&self, other: &Self) -> bool { 98 self.content_type == other.content_type 99 && self.content.as_slice() == other.content.as_slice() 100 } 101 } 102 103 impl Eq for ContentInfo {} 104 105 impl ContentInfo { 106 pub fn take_opt_from<S: Source>( 107 cons: &mut Constructed<S>, 108 ) -> Result<Option<Self>, DecodeError<S::Error>> { 109 cons.take_opt_sequence(|cons| Self::from_sequence(cons)) 110 } 111 112 pub fn from_sequence<S: Source>( 113 cons: &mut Constructed<S>, 114 ) -> Result<Self, DecodeError<S::Error>> { 115 let content_type = ContentType::take_from(cons)?; 116 let content = cons.take_constructed_if(Tag::CTX_0, |cons| cons.capture_all())?; 117 118 Ok(Self { 119 content_type, 120 content, 121 }) 122 } 123 } 124 125 impl Values for ContentInfo { 126 fn encoded_len(&self, mode: Mode) -> usize { 127 encode::sequence((self.content_type.encode_ref(), &self.content)).encoded_len(mode) 128 } 129 130 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> { 131 encode::sequence((self.content_type.encode_ref(), &self.content)) 132 .write_encoded(mode, target) 133 } 134 } 135 136 /// Represents signed data. 137 /// 138 /// ASN.1 type specification: 139 /// 140 /// ```ASN.1 141 /// SignedData ::= SEQUENCE { 142 /// version CMSVersion, 143 /// digestAlgorithms DigestAlgorithmIdentifiers, 144 /// encapContentInfo EncapsulatedContentInfo, 145 /// certificates [0] IMPLICIT CertificateSet OPTIONAL, 146 /// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, 147 /// signerInfos SignerInfos } 148 /// ``` 149 #[derive(Clone, Debug, Eq, PartialEq)] 150 pub struct SignedData { 151 pub version: CmsVersion, 152 pub digest_algorithms: DigestAlgorithmIdentifiers, 153 pub content_info: EncapsulatedContentInfo, 154 pub certificates: Option<CertificateSet>, 155 pub crls: Option<RevocationInfoChoices>, 156 pub signer_infos: SignerInfos, 157 } 158 159 impl SignedData { 160 /// Attempt to decode BER encoded bytes to a parsed data structure. 161 pub fn decode_ber(data: &[u8]) -> Result<Self, DecodeError<std::convert::Infallible>> { 162 Constructed::decode(data, bcder::Mode::Ber, Self::decode) 163 } 164 165 pub fn decode<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 166 cons.take_sequence(|cons| { 167 let oid = Oid::take_from(cons)?; 168 169 if oid != OID_ID_SIGNED_DATA { 170 return Err(cons.content_err("expected signed data OID")); 171 } 172 173 cons.take_constructed_if(Tag::CTX_0, Self::take_from) 174 }) 175 } 176 177 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 178 cons.take_sequence(|cons| { 179 let version = CmsVersion::take_from(cons)?; 180 let digest_algorithms = DigestAlgorithmIdentifiers::take_from(cons)?; 181 let content_info = EncapsulatedContentInfo::take_from(cons)?; 182 let certificates = 183 cons.take_opt_constructed_if(Tag::CTX_0, |cons| CertificateSet::take_from(cons))?; 184 let crls = cons.take_opt_constructed_if(Tag::CTX_1, |cons| { 185 RevocationInfoChoices::take_from(cons) 186 })?; 187 let signer_infos = SignerInfos::take_from(cons)?; 188 189 Ok(Self { 190 version, 191 digest_algorithms, 192 content_info, 193 certificates, 194 crls, 195 signer_infos, 196 }) 197 }) 198 } 199 200 pub fn encode_ref(&self) -> impl Values + '_ { 201 encode::sequence(( 202 OID_ID_SIGNED_DATA.encode_ref(), 203 encode::sequence_as( 204 Tag::CTX_0, 205 encode::sequence(( 206 self.version.encode(), 207 self.digest_algorithms.encode_ref(), 208 self.content_info.encode_ref(), 209 self.certificates 210 .as_ref() 211 .map(|certs| certs.encode_ref_as(Tag::CTX_0)), 212 // TODO crls. 213 self.signer_infos.encode_ref(), 214 )), 215 ), 216 )) 217 } 218 } 219 220 /// Digest algorithm identifiers. 221 /// 222 /// ```ASN.1 223 /// DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier 224 /// ``` 225 #[derive(Clone, Debug, Default, Eq, PartialEq)] 226 pub struct DigestAlgorithmIdentifiers(Vec<DigestAlgorithmIdentifier>); 227 228 impl Deref for DigestAlgorithmIdentifiers { 229 type Target = Vec<DigestAlgorithmIdentifier>; 230 231 fn deref(&self) -> &Self::Target { 232 &self.0 233 } 234 } 235 236 impl DerefMut for DigestAlgorithmIdentifiers { 237 fn deref_mut(&mut self) -> &mut Self::Target { 238 &mut self.0 239 } 240 } 241 242 impl DigestAlgorithmIdentifiers { 243 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 244 cons.take_set(|cons| { 245 let mut identifiers = Vec::new(); 246 247 while let Some(identifier) = AlgorithmIdentifier::take_opt_from(cons)? { 248 identifiers.push(identifier); 249 } 250 251 Ok(Self(identifiers)) 252 }) 253 } 254 255 pub fn encode_ref(&self) -> impl Values + '_ { 256 encode::set(&self.0) 257 } 258 } 259 260 pub type DigestAlgorithmIdentifier = AlgorithmIdentifier; 261 262 /// Signer infos. 263 /// 264 /// ```ASN.1 265 /// SignerInfos ::= SET OF SignerInfo 266 /// ``` 267 #[derive(Clone, Debug, Default, Eq, PartialEq)] 268 pub struct SignerInfos(Vec<SignerInfo>); 269 270 impl Deref for SignerInfos { 271 type Target = Vec<SignerInfo>; 272 273 fn deref(&self) -> &Self::Target { 274 &self.0 275 } 276 } 277 278 impl DerefMut for SignerInfos { 279 fn deref_mut(&mut self) -> &mut Self::Target { 280 &mut self.0 281 } 282 } 283 284 impl SignerInfos { 285 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 286 cons.take_set(|cons| { 287 let mut infos = Vec::new(); 288 289 while let Some(info) = SignerInfo::take_opt_from(cons)? { 290 infos.push(info); 291 } 292 293 Ok(Self(infos)) 294 }) 295 } 296 297 pub fn encode_ref(&self) -> impl Values + '_ { 298 encode::set(&self.0) 299 } 300 } 301 302 /// Encapsulated content info. 303 /// 304 /// ```ASN.1 305 /// EncapsulatedContentInfo ::= SEQUENCE { 306 /// eContentType ContentType, 307 /// eContent [0] EXPLICIT OCTET STRING OPTIONAL } 308 /// ``` 309 #[derive(Clone, Eq, PartialEq)] 310 pub struct EncapsulatedContentInfo { 311 pub content_type: ContentType, 312 pub content: Option<OctetString>, 313 } 314 315 impl Debug for EncapsulatedContentInfo { 316 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 317 let mut s = f.debug_struct("EncapsulatedContentInfo"); 318 s.field("content_type", &format_args!("{}", self.content_type)); 319 s.field( 320 "content", 321 &format_args!( 322 "{:?}", 323 self.content 324 .as_ref() 325 .map(|x| hex::encode(x.clone().to_bytes().as_ref())) 326 ), 327 ); 328 s.finish() 329 } 330 } 331 332 impl EncapsulatedContentInfo { 333 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 334 cons.take_sequence(|cons| { 335 let content_type = ContentType::take_from(cons)?; 336 let content = 337 cons.take_opt_constructed_if(Tag::CTX_0, |cons| OctetString::take_from(cons))?; 338 339 Ok(Self { 340 content_type, 341 content, 342 }) 343 }) 344 } 345 346 pub fn encode_ref(&self) -> impl Values + '_ { 347 encode::sequence(( 348 self.content_type.encode_ref(), 349 self.content 350 .as_ref() 351 .map(|content| encode::sequence_as(Tag::CTX_0, content.encode_ref())), 352 )) 353 } 354 } 355 356 /// Per-signer information. 357 /// 358 /// ```ASN.1 359 /// SignerInfo ::= SEQUENCE { 360 /// version CMSVersion, 361 /// sid SignerIdentifier, 362 /// digestAlgorithm DigestAlgorithmIdentifier, 363 /// signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, 364 /// signatureAlgorithm SignatureAlgorithmIdentifier, 365 /// signature SignatureValue, 366 /// unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } 367 /// ``` 368 #[derive(Clone, Eq, PartialEq)] 369 pub struct SignerInfo { 370 pub version: CmsVersion, 371 pub sid: SignerIdentifier, 372 pub digest_algorithm: DigestAlgorithmIdentifier, 373 pub signed_attributes: Option<SignedAttributes>, 374 pub signature_algorithm: SignatureAlgorithmIdentifier, 375 pub signature: SignatureValue, 376 pub unsigned_attributes: Option<UnsignedAttributes>, 377 378 /// Raw bytes backing signed attributes data. 379 /// 380 /// Does not include constructed tag or length bytes. 381 pub signed_attributes_data: Option<Vec<u8>>, 382 } 383 384 impl SignerInfo { 385 pub fn take_opt_from<S: Source>( 386 cons: &mut Constructed<S>, 387 ) -> Result<Option<Self>, DecodeError<S::Error>> { 388 cons.take_opt_sequence(|cons| Self::from_sequence(cons)) 389 } 390 391 pub fn from_sequence<S: Source>( 392 cons: &mut Constructed<S>, 393 ) -> Result<Self, DecodeError<S::Error>> { 394 let version = CmsVersion::take_from(cons)?; 395 let sid = SignerIdentifier::take_from(cons)?; 396 let digest_algorithm = DigestAlgorithmIdentifier::take_from(cons)?; 397 let signed_attributes = cons.take_opt_constructed_if(Tag::CTX_0, |cons| { 398 // RFC 5652 Section 5.3: SignedAttributes MUST be DER encoded, even if the 399 // rest of the structure is BER encoded. So buffer all data so we can 400 // feed into a new decoder. 401 let der = cons.capture_all()?; 402 403 // But wait there's more! The raw data constituting the signed 404 // attributes is also digested and used for content/signature 405 // verification. Because our DER serialization may not roundtrip 406 // losslessly, we stash away a copy of these bytes so they may be 407 // referenced as part of verification. 408 let der_data = der.as_slice().to_vec(); 409 410 Ok(( 411 Constructed::decode(der.as_slice(), bcder::Mode::Der, |cons| { 412 SignedAttributes::take_from_set(cons) 413 }) 414 .map_err(|e| e.convert())?, 415 der_data, 416 )) 417 })?; 418 419 let (signed_attributes, signed_attributes_data) = if let Some((x, y)) = signed_attributes { 420 (Some(x), Some(y)) 421 } else { 422 (None, None) 423 }; 424 425 let signature_algorithm = SignatureAlgorithmIdentifier::take_from(cons)?; 426 let signature = SignatureValue::take_from(cons)?; 427 let unsigned_attributes = cons 428 .take_opt_constructed_if(Tag::CTX_1, |cons| UnsignedAttributes::take_from_set(cons))?; 429 430 Ok(Self { 431 version, 432 sid, 433 digest_algorithm, 434 signed_attributes, 435 signature_algorithm, 436 signature, 437 unsigned_attributes, 438 signed_attributes_data, 439 }) 440 } 441 442 pub fn encode_ref(&self) -> impl Values + '_ { 443 encode::sequence(( 444 u8::from(self.version).encode(), 445 &self.sid, 446 &self.digest_algorithm, 447 // Always write signed attributes with DER encoding per RFC 5652. 448 self.signed_attributes 449 .as_ref() 450 .map(|attrs| SignedAttributesDer::new(attrs.clone(), Some(Tag::CTX_0))), 451 &self.signature_algorithm, 452 self.signature.encode_ref(), 453 self.unsigned_attributes 454 .as_ref() 455 .map(|attrs| attrs.encode_ref_as(Tag::CTX_1)), 456 )) 457 } 458 459 /// Obtain content representing the signed attributes data to be digested. 460 /// 461 /// Computing the content to go into the digest calculation is nuanced. 462 /// From RFC 5652: 463 /// 464 /// The result of the message digest calculation process depends on 465 /// whether the signedAttrs field is present. When the field is absent, 466 /// the result is just the message digest of the content as described 467 /// above. When the field is present, however, the result is the message 468 /// digest of the complete DER encoding of the SignedAttrs value 469 /// contained in the signedAttrs field. Since the SignedAttrs value, 470 /// when present, must contain the content-type and the message-digest 471 /// attributes, those values are indirectly included in the result. The 472 /// content-type attribute MUST NOT be included in a countersignature 473 /// unsigned attribute as defined in Section 11.4. A separate encoding 474 /// of the signedAttrs field is performed for message digest calculation. 475 /// The `IMPLICIT [0]` tag in the signedAttrs is not used for the DER 476 /// encoding, rather an EXPLICIT SET OF tag is used. That is, the DER 477 /// encoding of the EXPLICIT SET OF tag, rather than of the `IMPLICIT [0]` 478 /// tag, MUST be included in the message digest calculation along with 479 /// the length and content octets of the SignedAttributes value. 480 /// 481 /// A few things to note here: 482 /// 483 /// * We must ensure DER (not BER) encoding of the entire SignedAttrs values. 484 /// * The SignedAttr tag must use `EXPLICIT SET OF` instead of `IMPLICIT [0]`, 485 /// so default encoding is not appropriate. 486 /// * If this instance came into existence via a parse, we stashed away the 487 /// raw bytes constituting SignedAttributes to ensure we can do a lossless 488 /// copy. 489 pub fn signed_attributes_digested_content(&self) -> Result<Option<Vec<u8>>, std::io::Error> { 490 if let Some(signed_attributes) = &self.signed_attributes { 491 if let Some(existing_data) = &self.signed_attributes_data { 492 // +8 should be enough for tag + length. 493 let mut buffer = Vec::with_capacity(existing_data.len() + 8); 494 // EXPLICIT SET OF. 495 buffer.write_all(&[0x31])?; 496 497 // Length isn't exported by bcder :/ So do length encoding manually. 498 if existing_data.len() < 0x80 { 499 buffer.write_all(&[existing_data.len() as u8])?; 500 } else if existing_data.len() < 0x100 { 501 buffer.write_all(&[0x81, existing_data.len() as u8])?; 502 } else if existing_data.len() < 0x10000 { 503 buffer.write_all(&[ 504 0x82, 505 (existing_data.len() >> 8) as u8, 506 existing_data.len() as u8, 507 ])?; 508 } else if existing_data.len() < 0x1000000 { 509 buffer.write_all(&[ 510 0x83, 511 (existing_data.len() >> 16) as u8, 512 (existing_data.len() >> 8) as u8, 513 existing_data.len() as u8, 514 ])?; 515 } else { 516 return Err(std::io::Error::new( 517 std::io::ErrorKind::InvalidData, 518 "signed attributes length too long", 519 )); 520 } 521 522 buffer.write_all(existing_data)?; 523 524 Ok(Some(buffer)) 525 } else { 526 // No existing copy present. Serialize from raw data structures. 527 // But we obtain a sorted instance of those attributes first, because 528 // bcder doesn't appear to follow DER encoding rules for sets. 529 let signed_attributes = signed_attributes.as_sorted()?; 530 let mut der = Vec::new(); 531 // The mode argument here is actually ignored. 532 signed_attributes.write_encoded(Mode::Der, &mut der)?; 533 534 Ok(Some(der)) 535 } 536 } else { 537 Ok(None) 538 } 539 } 540 } 541 542 impl Debug for SignerInfo { 543 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 544 let mut s = f.debug_struct("SignerInfo"); 545 546 s.field("version", &self.version); 547 s.field("sid", &self.sid); 548 s.field("digest_algorithm", &self.digest_algorithm); 549 s.field("signed_attributes", &self.signed_attributes); 550 s.field("signature_algorithm", &self.signature_algorithm); 551 s.field( 552 "signature", 553 &format_args!( 554 "{}", 555 hex::encode(self.signature.clone().into_bytes().as_ref()) 556 ), 557 ); 558 s.field("unsigned_attributes", &self.unsigned_attributes); 559 s.field( 560 "signed_attributes_data", 561 &format_args!( 562 "{:?}", 563 self.signed_attributes_data.as_ref().map(hex::encode) 564 ), 565 ); 566 s.finish() 567 } 568 } 569 570 impl Values for SignerInfo { 571 fn encoded_len(&self, mode: Mode) -> usize { 572 self.encode_ref().encoded_len(mode) 573 } 574 575 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> { 576 self.encode_ref().write_encoded(mode, target) 577 } 578 } 579 580 /// Identifies the signer. 581 /// 582 /// ```ASN.1 583 /// SignerIdentifier ::= CHOICE { 584 /// issuerAndSerialNumber IssuerAndSerialNumber, 585 /// subjectKeyIdentifier [0] SubjectKeyIdentifier } 586 #[derive(Clone, Debug, Eq, PartialEq)] 587 pub enum SignerIdentifier { 588 IssuerAndSerialNumber(IssuerAndSerialNumber), 589 SubjectKeyIdentifier(SubjectKeyIdentifier), 590 } 591 592 impl SignerIdentifier { 593 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 594 if let Some(identifier) = 595 cons.take_opt_constructed_if(Tag::CTX_0, |cons| SubjectKeyIdentifier::take_from(cons))? 596 { 597 Ok(Self::SubjectKeyIdentifier(identifier)) 598 } else { 599 Ok(Self::IssuerAndSerialNumber( 600 IssuerAndSerialNumber::take_from(cons)?, 601 )) 602 } 603 } 604 } 605 606 impl Values for SignerIdentifier { 607 fn encoded_len(&self, mode: Mode) -> usize { 608 match self { 609 Self::IssuerAndSerialNumber(v) => v.encode_ref().encoded_len(mode), 610 Self::SubjectKeyIdentifier(v) => v.encode_ref_as(Tag::CTX_0).encoded_len(mode), 611 } 612 } 613 614 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> { 615 match self { 616 Self::IssuerAndSerialNumber(v) => v.encode_ref().write_encoded(mode, target), 617 Self::SubjectKeyIdentifier(v) => { 618 v.encode_ref_as(Tag::CTX_0).write_encoded(mode, target) 619 } 620 } 621 } 622 } 623 624 /// Signed attributes. 625 /// 626 /// ```ASN.1 627 /// SignedAttributes ::= SET SIZE (1..MAX) OF Attribute 628 /// ``` 629 #[derive(Clone, Debug, Default, Eq, PartialEq)] 630 pub struct SignedAttributes(Vec<Attribute>); 631 632 impl Deref for SignedAttributes { 633 type Target = Vec<Attribute>; 634 635 fn deref(&self) -> &Self::Target { 636 &self.0 637 } 638 } 639 640 impl DerefMut for SignedAttributes { 641 fn deref_mut(&mut self) -> &mut Self::Target { 642 &mut self.0 643 } 644 } 645 646 impl SignedAttributes { 647 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 648 cons.take_set(|cons| Self::take_from_set(cons)) 649 } 650 651 pub fn take_from_set<S: Source>( 652 cons: &mut Constructed<S>, 653 ) -> Result<Self, DecodeError<S::Error>> { 654 let mut attributes = Vec::new(); 655 656 while let Some(attribute) = Attribute::take_opt_from(cons)? { 657 attributes.push(attribute); 658 } 659 660 Ok(Self(attributes)) 661 } 662 663 /// Obtain an instance where the attributes are sorted according to DER 664 /// rules. See the comment in [SignerInfo::signed_attributes_digested_content]. 665 pub fn as_sorted(&self) -> Result<Self, std::io::Error> { 666 // All elements of the set have the same type. So sorting is based on encoded 667 // values, with shorter elements padded with 0s. Rust will sort a shorter value 668 // with a prefix match against a longer value as less than, so we can avoid the 669 // padding. 670 671 let mut attributes = self 672 .0 673 .iter() 674 .map(|x| { 675 let mut encoded = vec![]; 676 x.values.write_encoded(Mode::Der, &mut encoded)?; 677 678 Ok((encoded, x.clone())) 679 }) 680 .collect::<Result<Vec<(_, _)>, std::io::Error>>()?; 681 682 attributes.sort_by(|(a, _), (b, _)| a.cmp(b)); 683 684 Ok(Self( 685 attributes.into_iter().map(|(_, x)| x).collect::<Vec<_>>(), 686 )) 687 } 688 689 fn encode_ref(&self) -> impl Values + '_ { 690 encode::set(encode::slice(&self.0, |x| x.clone().encode())) 691 } 692 693 fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ { 694 encode::set_as(tag, encode::slice(&self.0, |x| x.clone().encode())) 695 } 696 } 697 698 impl Values for SignedAttributes { 699 // SignedAttributes are always written as DER encoded. 700 fn encoded_len(&self, _: Mode) -> usize { 701 self.encode_ref().encoded_len(Mode::Der) 702 } 703 704 fn write_encoded<W: Write>(&self, _: Mode, target: &mut W) -> Result<(), std::io::Error> { 705 self.encode_ref().write_encoded(Mode::Der, target) 706 } 707 } 708 709 pub struct SignedAttributesDer(SignedAttributes, Option<Tag>); 710 711 impl SignedAttributesDer { 712 pub const fn new(sa: SignedAttributes, tag: Option<Tag>) -> Self { 713 Self(sa, tag) 714 } 715 } 716 717 impl Values for SignedAttributesDer { 718 fn encoded_len(&self, _: Mode) -> usize { 719 if let Some(tag) = &self.1 { 720 self.0.encode_ref_as(*tag).encoded_len(Mode::Der) 721 } else { 722 self.0.encode_ref().encoded_len(Mode::Der) 723 } 724 } 725 726 fn write_encoded<W: Write>(&self, _: Mode, target: &mut W) -> Result<(), std::io::Error> { 727 if let Some(tag) = &self.1 { 728 self.0.encode_ref_as(*tag).write_encoded(Mode::Der, target) 729 } else { 730 self.0.encode_ref().write_encoded(Mode::Der, target) 731 } 732 } 733 } 734 735 /// Unsigned attributes. 736 /// 737 /// ```ASN.1 738 /// UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute 739 /// ``` 740 #[derive(Clone, Debug, Default, Eq, PartialEq)] 741 pub struct UnsignedAttributes(Vec<Attribute>); 742 743 impl Deref for UnsignedAttributes { 744 type Target = Vec<Attribute>; 745 746 fn deref(&self) -> &Self::Target { 747 &self.0 748 } 749 } 750 751 impl DerefMut for UnsignedAttributes { 752 fn deref_mut(&mut self) -> &mut Self::Target { 753 &mut self.0 754 } 755 } 756 757 impl UnsignedAttributes { 758 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 759 cons.take_set(|cons| Self::take_from_set(cons)) 760 } 761 762 pub fn take_from_set<S: Source>( 763 cons: &mut Constructed<S>, 764 ) -> Result<Self, DecodeError<S::Error>> { 765 let mut attributes = Vec::new(); 766 767 while let Some(attribute) = Attribute::take_opt_from(cons)? { 768 attributes.push(attribute); 769 } 770 771 Ok(Self(attributes)) 772 } 773 774 pub fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ { 775 encode::set_as(tag, encode::slice(&self.0, |x| x.clone().encode())) 776 } 777 } 778 779 pub type SignatureValue = OctetString; 780 781 /// Enveloped-data content type. 782 /// 783 /// ```ASN.1 784 /// EnvelopedData ::= SEQUENCE { 785 /// version CMSVersion, 786 /// originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, 787 /// recipientInfos RecipientInfos, 788 /// encryptedContentInfo EncryptedContentInfo, 789 /// unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL } 790 /// ``` 791 #[derive(Clone, Debug, Eq, PartialEq)] 792 pub struct EnvelopedData { 793 pub version: CmsVersion, 794 pub originator_info: Option<OriginatorInfo>, 795 pub recipient_infos: RecipientInfos, 796 pub encrypted_content_info: EncryptedContentInfo, 797 pub unprotected_attributes: Option<UnprotectedAttributes>, 798 } 799 800 /// Originator info. 801 /// 802 /// ```ASN.1 803 /// OriginatorInfo ::= SEQUENCE { 804 /// certs [0] IMPLICIT CertificateSet OPTIONAL, 805 /// crls [1] IMPLICIT RevocationInfoChoices OPTIONAL } 806 /// ``` 807 #[derive(Clone, Debug, Eq, PartialEq)] 808 pub struct OriginatorInfo { 809 pub certs: Option<CertificateSet>, 810 pub crls: Option<RevocationInfoChoices>, 811 } 812 813 pub type RecipientInfos = Vec<RecipientInfo>; 814 815 /// Encrypted content info. 816 /// 817 /// ```ASN.1 818 /// EncryptedContentInfo ::= SEQUENCE { 819 /// contentType ContentType, 820 /// contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, 821 /// encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL } 822 /// ``` 823 #[derive(Clone, Debug, Eq, PartialEq)] 824 pub struct EncryptedContentInfo { 825 pub content_type: ContentType, 826 pub content_encryption_algorithms: ContentEncryptionAlgorithmIdentifier, 827 pub encrypted_content: Option<EncryptedContent>, 828 } 829 830 pub type EncryptedContent = OctetString; 831 832 pub type UnprotectedAttributes = Vec<Attribute>; 833 834 /// Recipient info. 835 /// 836 /// ```ASN.1 837 /// RecipientInfo ::= CHOICE { 838 /// ktri KeyTransRecipientInfo, 839 /// kari [1] KeyAgreeRecipientInfo, 840 /// kekri [2] KEKRecipientInfo, 841 /// pwri [3] PasswordRecipientinfo, 842 /// ori [4] OtherRecipientInfo } 843 /// ``` 844 #[derive(Clone, Debug, Eq, PartialEq)] 845 pub enum RecipientInfo { 846 KeyTransRecipientInfo(KeyTransRecipientInfo), 847 KeyAgreeRecipientInfo(KeyAgreeRecipientInfo), 848 KekRecipientInfo(KekRecipientInfo), 849 PasswordRecipientInfo(PasswordRecipientInfo), 850 OtherRecipientInfo(OtherRecipientInfo), 851 } 852 853 pub type EncryptedKey = OctetString; 854 855 /// Key trans recipient info. 856 /// 857 /// ```ASN.1 858 /// KeyTransRecipientInfo ::= SEQUENCE { 859 /// version CMSVersion, -- always set to 0 or 2 860 /// rid RecipientIdentifier, 861 /// keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, 862 /// encryptedKey EncryptedKey } 863 /// ``` 864 #[derive(Clone, Debug, Eq, PartialEq)] 865 pub struct KeyTransRecipientInfo { 866 pub version: CmsVersion, 867 pub rid: RecipientIdentifier, 868 pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier, 869 pub encrypted_key: EncryptedKey, 870 } 871 872 /// Recipient identifier. 873 /// 874 /// ```ASN.1 875 /// RecipientIdentifier ::= CHOICE { 876 /// issuerAndSerialNumber IssuerAndSerialNumber, 877 /// subjectKeyIdentifier [0] SubjectKeyIdentifier } 878 /// ``` 879 #[derive(Clone, Debug, Eq, PartialEq)] 880 pub enum RecipientIdentifier { 881 IssuerAndSerialNumber(IssuerAndSerialNumber), 882 SubjectKeyIdentifier(SubjectKeyIdentifier), 883 } 884 885 /// Key agreement recipient info. 886 /// 887 /// ```ASN.1 888 /// KeyAgreeRecipientInfo ::= SEQUENCE { 889 /// version CMSVersion, -- always set to 3 890 /// originator [0] EXPLICIT OriginatorIdentifierOrKey, 891 /// ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL, 892 /// keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, 893 /// recipientEncryptedKeys RecipientEncryptedKeys } 894 /// ``` 895 #[derive(Clone, Debug, Eq, PartialEq)] 896 pub struct KeyAgreeRecipientInfo { 897 pub version: CmsVersion, 898 pub originator: OriginatorIdentifierOrKey, 899 pub ukm: Option<UserKeyingMaterial>, 900 pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier, 901 pub recipient_encrypted_keys: RecipientEncryptedKeys, 902 } 903 904 /// Originator identifier or key. 905 /// 906 /// ```ASN.1 907 /// OriginatorIdentifierOrKey ::= CHOICE { 908 /// issuerAndSerialNumber IssuerAndSerialNumber, 909 /// subjectKeyIdentifier [0] SubjectKeyIdentifier, 910 /// originatorKey [1] OriginatorPublicKey } 911 /// ``` 912 #[derive(Clone, Debug, Eq, PartialEq)] 913 pub enum OriginatorIdentifierOrKey { 914 IssuerAndSerialNumber(IssuerAndSerialNumber), 915 SubjectKeyIdentifier(SubjectKeyIdentifier), 916 OriginatorKey(OriginatorPublicKey), 917 } 918 919 /// Originator public key. 920 /// 921 /// ```ASN.1 922 /// OriginatorPublicKey ::= SEQUENCE { 923 /// algorithm AlgorithmIdentifier, 924 /// publicKey BIT STRING } 925 /// ``` 926 #[derive(Clone, Debug, Eq, PartialEq)] 927 pub struct OriginatorPublicKey { 928 pub algorithm: AlgorithmIdentifier, 929 pub public_key: BitString, 930 } 931 932 /// SEQUENCE of RecipientEncryptedKey. 933 type RecipientEncryptedKeys = Vec<RecipientEncryptedKey>; 934 935 /// Recipient encrypted key. 936 /// 937 /// ```ASN.1 938 /// RecipientEncryptedKey ::= SEQUENCE { 939 /// rid KeyAgreeRecipientIdentifier, 940 /// encryptedKey EncryptedKey } 941 /// ``` 942 #[derive(Clone, Debug, Eq, PartialEq)] 943 pub struct RecipientEncryptedKey { 944 pub rid: KeyAgreeRecipientInfo, 945 pub encrypted_key: EncryptedKey, 946 } 947 948 /// Key agreement recipient identifier. 949 /// 950 /// ```ASN.1 951 /// KeyAgreeRecipientIdentifier ::= CHOICE { 952 /// issuerAndSerialNumber IssuerAndSerialNumber, 953 /// rKeyId [0] IMPLICIT RecipientKeyIdentifier } 954 /// ``` 955 #[derive(Clone, Debug, Eq, PartialEq)] 956 pub enum KeyAgreeRecipientIdentifier { 957 IssuerAndSerialNumber(IssuerAndSerialNumber), 958 RKeyId(RecipientKeyIdentifier), 959 } 960 961 /// Recipient key identifier. 962 /// 963 /// ```ASN.1 964 /// RecipientKeyIdentifier ::= SEQUENCE { 965 /// subjectKeyIdentifier SubjectKeyIdentifier, 966 /// date GeneralizedTime OPTIONAL, 967 /// other OtherKeyAttribute OPTIONAL } 968 /// ``` 969 #[derive(Clone, Debug, Eq, PartialEq)] 970 pub struct RecipientKeyIdentifier { 971 pub subject_key_identifier: SubjectKeyIdentifier, 972 pub date: Option<GeneralizedTime>, 973 pub other: Option<OtherKeyAttribute>, 974 } 975 976 type SubjectKeyIdentifier = OctetString; 977 978 /// Key encryption key recipient info. 979 /// 980 /// ```ASN.1 981 /// KEKRecipientInfo ::= SEQUENCE { 982 /// version CMSVersion, -- always set to 4 983 /// kekid KEKIdentifier, 984 /// keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, 985 /// encryptedKey EncryptedKey } 986 /// ``` 987 #[derive(Clone, Debug, Eq, PartialEq)] 988 pub struct KekRecipientInfo { 989 pub version: CmsVersion, 990 pub kek_id: KekIdentifier, 991 pub kek_encryption_algorithm: KeyEncryptionAlgorithmIdentifier, 992 pub encrypted_key: EncryptedKey, 993 } 994 995 /// Key encryption key identifier. 996 /// 997 /// ```ASN.1 998 /// KEKIdentifier ::= SEQUENCE { 999 /// keyIdentifier OCTET STRING, 1000 /// date GeneralizedTime OPTIONAL, 1001 /// other OtherKeyAttribute OPTIONAL } 1002 /// ``` 1003 #[derive(Clone, Debug, Eq, PartialEq)] 1004 pub struct KekIdentifier { 1005 pub key_identifier: OctetString, 1006 pub date: Option<GeneralizedTime>, 1007 pub other: Option<OtherKeyAttribute>, 1008 } 1009 1010 /// Password recipient info. 1011 /// 1012 /// ```ASN.1 1013 /// PasswordRecipientInfo ::= SEQUENCE { 1014 /// version CMSVersion, -- Always set to 0 1015 /// keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier 1016 /// OPTIONAL, 1017 /// keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, 1018 /// encryptedKey EncryptedKey } 1019 /// ``` 1020 #[derive(Clone, Debug, Eq, PartialEq)] 1021 pub struct PasswordRecipientInfo { 1022 pub version: CmsVersion, 1023 pub key_derivation_algorithm: Option<KeyDerivationAlgorithmIdentifier>, 1024 pub key_encryption_algorithm: KeyEncryptionAlgorithmIdentifier, 1025 pub encrypted_key: EncryptedKey, 1026 } 1027 1028 #[derive(Clone, Debug, Eq, PartialEq)] 1029 pub struct OtherRecipientInfo { 1030 pub ori_type: Oid, 1031 // TODO Any 1032 pub ori_value: Option<()>, 1033 } 1034 1035 /// Digested data. 1036 /// 1037 /// ```ASN.1 1038 /// DigestedData ::= SEQUENCE { 1039 /// version CMSVersion, 1040 /// digestAlgorithm DigestAlgorithmIdentifier, 1041 /// encapContentInfo EncapsulatedContentInfo, 1042 /// digest Digest } 1043 /// ``` 1044 #[derive(Clone, Debug, Eq, PartialEq)] 1045 pub struct DigestedData { 1046 pub version: CmsVersion, 1047 pub digest_algorithm: DigestAlgorithmIdentifier, 1048 pub content_type: EncapsulatedContentInfo, 1049 pub digest: Digest, 1050 } 1051 1052 pub type Digest = OctetString; 1053 1054 /// Encrypted data. 1055 /// 1056 /// ```ASN.1 1057 /// EncryptedData ::= SEQUENCE { 1058 /// version CMSVersion, 1059 /// encryptedContentInfo EncryptedContentInfo, 1060 /// unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL } 1061 /// ``` 1062 #[derive(Clone, Debug, Eq, PartialEq)] 1063 pub struct EncryptedData { 1064 pub version: CmsVersion, 1065 pub encrypted_content_info: EncryptedContentInfo, 1066 pub unprotected_attributes: Option<UnprotectedAttributes>, 1067 } 1068 1069 /// Authenticated data. 1070 /// 1071 /// ```ASN.1 1072 /// AuthenticatedData ::= SEQUENCE { 1073 /// version CMSVersion, 1074 /// originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, 1075 /// recipientInfos RecipientInfos, 1076 /// macAlgorithm MessageAuthenticationCodeAlgorithm, 1077 /// digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL, 1078 /// encapContentInfo EncapsulatedContentInfo, 1079 /// authAttrs [2] IMPLICIT AuthAttributes OPTIONAL, 1080 /// mac MessageAuthenticationCode, 1081 /// unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL } 1082 /// ``` 1083 #[derive(Clone, Debug, Eq, PartialEq)] 1084 pub struct AuthenticatedData { 1085 pub version: CmsVersion, 1086 pub originator_info: Option<OriginatorInfo>, 1087 pub recipient_infos: RecipientInfos, 1088 pub mac_algorithm: MessageAuthenticationCodeAlgorithm, 1089 pub digest_algorithm: Option<DigestAlgorithmIdentifier>, 1090 pub content_info: EncapsulatedContentInfo, 1091 pub authenticated_attributes: Option<AuthAttributes>, 1092 pub mac: MessageAuthenticationCode, 1093 pub unauthenticated_attributes: Option<UnauthAttributes>, 1094 } 1095 1096 pub type AuthAttributes = Vec<Attribute>; 1097 1098 pub type UnauthAttributes = Vec<Attribute>; 1099 1100 pub type MessageAuthenticationCode = OctetString; 1101 1102 pub type SignatureAlgorithmIdentifier = AlgorithmIdentifier; 1103 1104 pub type KeyEncryptionAlgorithmIdentifier = AlgorithmIdentifier; 1105 1106 pub type ContentEncryptionAlgorithmIdentifier = AlgorithmIdentifier; 1107 1108 pub type MessageAuthenticationCodeAlgorithm = AlgorithmIdentifier; 1109 1110 pub type KeyDerivationAlgorithmIdentifier = AlgorithmIdentifier; 1111 1112 /// Revocation info choices. 1113 /// 1114 /// ```ASN.1 1115 /// RevocationInfoChoices ::= SET OF RevocationInfoChoice 1116 /// ``` 1117 #[derive(Clone, Debug, Eq, PartialEq)] 1118 pub struct RevocationInfoChoices(Vec<RevocationInfoChoice>); 1119 1120 impl RevocationInfoChoices { 1121 pub fn take_from<S: Source>(cons: &Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 1122 Err(cons.content_err("RevocationInfoChoices parsing not implemented")) 1123 } 1124 } 1125 1126 /// Revocation info choice. 1127 /// 1128 /// ```ASN.1 1129 /// RevocationInfoChoice ::= CHOICE { 1130 /// crl CertificateList, 1131 /// other [1] IMPLICIT OtherRevocationInfoFormat } 1132 /// ``` 1133 #[derive(Clone, Debug, Eq, PartialEq)] 1134 pub enum RevocationInfoChoice { 1135 Crl(Box<CertificateList>), 1136 Other(OtherRevocationInfoFormat), 1137 } 1138 1139 /// Other revocation info format. 1140 /// 1141 /// ```ASN.1 1142 /// OtherRevocationInfoFormat ::= SEQUENCE { 1143 /// otherRevInfoFormat OBJECT IDENTIFIER, 1144 /// otherRevInfo ANY DEFINED BY otherRevInfoFormat } 1145 /// ``` 1146 #[derive(Clone, Debug, Eq, PartialEq)] 1147 pub struct OtherRevocationInfoFormat { 1148 pub other_rev_info_info_format: Oid, 1149 // TODO Any 1150 pub other_rev_info: Option<()>, 1151 } 1152 1153 /// Certificate choices. 1154 /// 1155 /// ```ASN.1 1156 /// CertificateChoices ::= CHOICE { 1157 /// certificate Certificate, 1158 /// extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete 1159 /// v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete 1160 /// v2AttrCert [2] IMPLICIT AttributeCertificateV2, 1161 /// other [3] IMPLICIT OtherCertificateFormat } 1162 /// ``` 1163 #[derive(Clone, Debug, Eq, PartialEq)] 1164 pub enum CertificateChoices { 1165 Certificate(Box<Certificate>), 1166 // ExtendedCertificate(ExtendedCertificate), 1167 // AttributeCertificateV1(AttributeCertificateV1), 1168 AttributeCertificateV2(Box<AttributeCertificateV2>), 1169 Other(Box<OtherCertificateFormat>), 1170 } 1171 1172 impl CertificateChoices { 1173 pub fn take_opt_from<S: Source>( 1174 cons: &mut Constructed<S>, 1175 ) -> Result<Option<Self>, DecodeError<S::Error>> { 1176 cons.take_opt_constructed_if(Tag::CTX_0, |cons| -> Result<(), DecodeError<S::Error>> { 1177 Err(cons.content_err("ExtendedCertificate parsing not implemented")) 1178 })?; 1179 cons.take_opt_constructed_if(Tag::CTX_1, |cons| -> Result<(), DecodeError<S::Error>> { 1180 Err(cons.content_err("AttributeCertificateV1 parsing not implemented")) 1181 })?; 1182 1183 // TODO these first 2 need methods that parse an already entered SEQUENCE. 1184 if let Some(certificate) = cons 1185 .take_opt_constructed_if(Tag::CTX_2, |cons| AttributeCertificateV2::take_from(cons))? 1186 { 1187 Ok(Some(Self::AttributeCertificateV2(Box::new(certificate)))) 1188 } else if let Some(certificate) = cons 1189 .take_opt_constructed_if(Tag::CTX_3, |cons| OtherCertificateFormat::take_from(cons))? 1190 { 1191 Ok(Some(Self::Other(Box::new(certificate)))) 1192 } else if let Some(certificate) = 1193 cons.take_opt_constructed(|_, cons| Certificate::from_sequence(cons))? 1194 { 1195 Ok(Some(Self::Certificate(Box::new(certificate)))) 1196 } else { 1197 Ok(None) 1198 } 1199 } 1200 1201 pub fn encode_ref(&self) -> impl Values + '_ { 1202 match self { 1203 Self::Certificate(cert) => cert.encode_ref(), 1204 Self::AttributeCertificateV2(_) => unimplemented!(), 1205 Self::Other(_) => unimplemented!(), 1206 } 1207 } 1208 } 1209 1210 impl Values for CertificateChoices { 1211 fn encoded_len(&self, mode: Mode) -> usize { 1212 self.encode_ref().encoded_len(mode) 1213 } 1214 1215 fn write_encoded<W: Write>(&self, mode: Mode, target: &mut W) -> Result<(), std::io::Error> { 1216 self.encode_ref().write_encoded(mode, target) 1217 } 1218 } 1219 1220 /// Other certificate format. 1221 /// 1222 /// ```ASN.1 1223 /// OtherCertificateFormat ::= SEQUENCE { 1224 /// otherCertFormat OBJECT IDENTIFIER, 1225 /// otherCert ANY DEFINED BY otherCertFormat } 1226 /// ``` 1227 #[derive(Clone, Debug, Eq, PartialEq)] 1228 pub struct OtherCertificateFormat { 1229 pub other_cert_format: Oid, 1230 // TODO Any 1231 pub other_cert: Option<()>, 1232 } 1233 1234 impl OtherCertificateFormat { 1235 pub fn take_from<S: Source>(cons: &Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 1236 Err(cons.content_err("OtherCertificateFormat parsing not implemented")) 1237 } 1238 } 1239 1240 #[derive(Clone, Debug, Default, Eq, PartialEq)] 1241 pub struct CertificateSet(Vec<CertificateChoices>); 1242 1243 impl Deref for CertificateSet { 1244 type Target = Vec<CertificateChoices>; 1245 1246 fn deref(&self) -> &Self::Target { 1247 &self.0 1248 } 1249 } 1250 1251 impl DerefMut for CertificateSet { 1252 fn deref_mut(&mut self) -> &mut Self::Target { 1253 &mut self.0 1254 } 1255 } 1256 1257 impl CertificateSet { 1258 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 1259 let mut certs = Vec::new(); 1260 1261 while let Some(cert) = CertificateChoices::take_opt_from(cons)? { 1262 certs.push(cert); 1263 } 1264 1265 Ok(Self(certs)) 1266 } 1267 1268 pub fn encode_ref_as(&self, tag: Tag) -> impl Values + '_ { 1269 encode::set_as(tag, &self.0) 1270 } 1271 } 1272 1273 /// Issuer and serial number. 1274 /// 1275 /// ```ASN.1 1276 /// IssuerAndSerialNumber ::= SEQUENCE { 1277 /// issuer Name, 1278 /// serialNumber CertificateSerialNumber } 1279 /// ``` 1280 #[derive(Clone, Debug, Eq, PartialEq)] 1281 pub struct IssuerAndSerialNumber { 1282 pub issuer: Name, 1283 pub serial_number: CertificateSerialNumber, 1284 } 1285 1286 impl IssuerAndSerialNumber { 1287 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 1288 cons.take_sequence(|cons| { 1289 let issuer = Name::take_from(cons)?; 1290 let serial_number = Integer::take_from(cons)?; 1291 1292 Ok(Self { 1293 issuer, 1294 serial_number, 1295 }) 1296 }) 1297 } 1298 1299 pub fn encode_ref(&self) -> impl Values + '_ { 1300 encode::sequence((self.issuer.encode_ref(), (&self.serial_number).encode())) 1301 } 1302 } 1303 1304 pub type CertificateSerialNumber = Integer; 1305 1306 /// Version number. 1307 /// 1308 /// ```ASN.1 1309 /// CMSVersion ::= INTEGER 1310 /// { v0(0), v1(1), v2(2), v3(3), v4(4), v5(5) } 1311 /// ``` 1312 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 1313 pub enum CmsVersion { 1314 V0 = 0, 1315 V1 = 1, 1316 V2 = 2, 1317 V3 = 3, 1318 V4 = 4, 1319 V5 = 5, 1320 } 1321 1322 impl CmsVersion { 1323 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 1324 match cons.take_primitive_if(Tag::INTEGER, Integer::i8_from_primitive)? { 1325 0 => Ok(Self::V0), 1326 1 => Ok(Self::V1), 1327 2 => Ok(Self::V2), 1328 3 => Ok(Self::V3), 1329 4 => Ok(Self::V4), 1330 5 => Ok(Self::V5), 1331 _ => Err(cons.content_err("unexpected CMSVersion")), 1332 } 1333 } 1334 1335 pub fn encode(self) -> impl Values { 1336 u8::from(self).encode() 1337 } 1338 } 1339 1340 impl From<CmsVersion> for u8 { 1341 fn from(v: CmsVersion) -> u8 { 1342 match v { 1343 CmsVersion::V0 => 0, 1344 CmsVersion::V1 => 1, 1345 CmsVersion::V2 => 2, 1346 CmsVersion::V3 => 3, 1347 CmsVersion::V4 => 4, 1348 CmsVersion::V5 => 5, 1349 } 1350 } 1351 } 1352 1353 pub type UserKeyingMaterial = OctetString; 1354 1355 /// Other key attribute. 1356 /// 1357 /// ```ASN.1 1358 /// OtherKeyAttribute ::= SEQUENCE { 1359 /// keyAttrId OBJECT IDENTIFIER, 1360 /// keyAttr ANY DEFINED BY keyAttrId OPTIONAL } 1361 /// ``` 1362 #[derive(Clone, Debug, Eq, PartialEq)] 1363 pub struct OtherKeyAttribute { 1364 pub key_attribute_id: Oid, 1365 // TODO Any 1366 pub key_attribute: Option<()>, 1367 } 1368 1369 pub type ContentType = Oid; 1370 1371 pub type MessageDigest = OctetString; 1372 1373 pub type SigningTime = Time; 1374 1375 /// Time variant. 1376 /// 1377 /// ```ASN.1 1378 /// Time ::= CHOICE { 1379 /// utcTime UTCTime, 1380 /// generalizedTime GeneralizedTime } 1381 /// ``` 1382 #[derive(Clone, Debug, Eq, PartialEq)] 1383 pub enum Time { 1384 UtcTime(UtcTime), 1385 GeneralizedTime(GeneralizedTime), 1386 } 1387 1388 impl Time { 1389 pub fn take_from<S: Source>(cons: &mut Constructed<S>) -> Result<Self, DecodeError<S::Error>> { 1390 if let Some(utc) = 1391 cons.take_opt_primitive_if(Tag::UTC_TIME, |prim| UtcTime::from_primitive(prim))? 1392 { 1393 Ok(Self::UtcTime(utc)) 1394 } else if let Some(generalized) = cons 1395 .take_opt_primitive_if(Tag::GENERALIZED_TIME, |prim| { 1396 GeneralizedTime::from_primitive_no_fractional_or_timezone_offsets(prim) 1397 })? 1398 { 1399 Ok(Self::GeneralizedTime(generalized)) 1400 } else { 1401 Err(cons.content_err("invalid Time value")) 1402 } 1403 } 1404 } 1405 1406 impl From<Time> for chrono::DateTime<chrono::Utc> { 1407 fn from(t: Time) -> Self { 1408 match t { 1409 Time::UtcTime(utc) => *utc, 1410 Time::GeneralizedTime(gt) => gt.into(), 1411 } 1412 } 1413 } 1414 1415 pub type CounterSignature = SignerInfo; 1416 1417 pub type AttributeCertificateV2 = AttributeCertificate;