1 use crate::Result; 2 use crate::cert::prelude::*; 3 use crate::packet::{key, Signature, Tag}; 4 use crate::serialize::{ 5 PacketRef, 6 Marshal, MarshalInto, 7 generic_serialize_into, generic_export_into, 8 }; 9 10 11 impl Cert { 12 /// Serializes or exports the Cert. 13 /// 14 /// If `export` is true, then non-exportable signatures are not 15 /// written, and components without any exportable binding 16 /// signature or revocation are not exported. 17 /// 18 /// The signatures are ordered from authenticated and most 19 /// important to not authenticated and most likely to be abused. 20 /// The order is: 21 /// 22 /// - Self revocations first. They are authenticated and the 23 /// most important information. 24 /// - Self signatures. They are authenticated. 25 /// - Other signatures. They are not authenticated at this point. 26 /// - Other revocations. They are not authenticated, and likely 27 /// not well supported in other implementations, hence the 28 /// least reliable way of revoking keys and therefore least 29 /// useful and most likely to be abused. serialize_common(&self, o: &mut dyn std::io::Write, export: bool) -> Result<()>30 fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool) 31 -> Result<()> 32 { 33 let primary = self.primary_key(); 34 PacketRef::PublicKey(primary.key()) 35 .serialize(o)?; 36 37 // Writes a signature if it is exportable or `! export`. 38 let serialize_sig = 39 |o: &mut dyn std::io::Write, sig: &Signature| -> Result<()> 40 { 41 if export { 42 if sig.exportable().is_ok() { 43 PacketRef::Signature(sig).export(o)?; 44 } 45 } else { 46 PacketRef::Signature(sig).serialize(o)?; 47 } 48 Ok(()) 49 }; 50 51 for s in primary.self_revocations() { 52 serialize_sig(o, s)?; 53 } 54 for s in primary.self_signatures() { 55 serialize_sig(o, s)?; 56 } 57 for s in primary.certifications() { 58 serialize_sig(o, s)?; 59 } 60 for s in primary.other_revocations() { 61 serialize_sig(o, s)?; 62 } 63 64 for u in self.userids() { 65 if export && ! u.self_signatures().iter().chain(u.self_revocations()).any( 66 |s| s.exportable().is_ok()) 67 { 68 // No exportable selfsig on this component, skip it. 69 continue; 70 } 71 72 PacketRef::UserID(u.userid()).serialize(o)?; 73 for s in u.self_revocations() { 74 serialize_sig(o, s)?; 75 } 76 for s in u.self_signatures() { 77 serialize_sig(o, s)?; 78 } 79 for s in u.certifications() { 80 serialize_sig(o, s)?; 81 } 82 for s in u.other_revocations() { 83 serialize_sig(o, s)?; 84 } 85 } 86 87 for u in self.user_attributes() { 88 if export && ! u.self_signatures().iter().chain(u.self_revocations()).any( 89 |s| s.exportable().is_ok()) 90 { 91 // No exportable selfsig on this component, skip it. 92 continue; 93 } 94 95 PacketRef::UserAttribute(u.user_attribute()).serialize(o)?; 96 for s in u.self_revocations() { 97 serialize_sig(o, s)?; 98 } 99 for s in u.self_signatures() { 100 serialize_sig(o, s)?; 101 } 102 for s in u.certifications() { 103 serialize_sig(o, s)?; 104 } 105 for s in u.other_revocations() { 106 serialize_sig(o, s)?; 107 } 108 } 109 110 for k in self.subkeys() { 111 if export && ! k.self_signatures().iter().chain(k.self_revocations()).any( 112 |s| s.exportable().is_ok()) 113 { 114 // No exportable selfsig on this component, skip it. 115 continue; 116 } 117 118 PacketRef::PublicSubkey(k.key()).serialize(o)?; 119 for s in k.self_revocations() { 120 serialize_sig(o, s)?; 121 } 122 for s in k.self_signatures() { 123 serialize_sig(o, s)?; 124 } 125 for s in k.certifications() { 126 serialize_sig(o, s)?; 127 } 128 for s in k.other_revocations() { 129 serialize_sig(o, s)?; 130 } 131 } 132 133 for u in self.unknowns() { 134 if export && ! u.certifications().iter().any( 135 |s| s.exportable().is_ok()) 136 { 137 // No exportable selfsig on this component, skip it. 138 continue; 139 } 140 141 PacketRef::Unknown(u.unknown()).serialize(o)?; 142 143 for s in u.self_revocations() { 144 serialize_sig(o, s)?; 145 } 146 for s in u.self_signatures() { 147 serialize_sig(o, s)?; 148 } 149 for s in u.certifications() { 150 serialize_sig(o, s)?; 151 } 152 for s in u.other_revocations() { 153 serialize_sig(o, s)?; 154 } 155 } 156 157 for s in self.bad_signatures() { 158 serialize_sig(o, s)?; 159 } 160 161 Ok(()) 162 } 163 } 164 165 impl crate::serialize::Serialize for Cert {} 166 167 impl Marshal for Cert { serialize(&self, o: &mut dyn std::io::Write) -> Result<()>168 fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> { 169 self.serialize_common(o, false) 170 } 171 export(&self, o: &mut dyn std::io::Write) -> Result<()>172 fn export(&self, o: &mut dyn std::io::Write) -> Result<()> { 173 self.serialize_common(o, true) 174 } 175 } 176 177 impl crate::serialize::SerializeInto for Cert {} 178 179 impl MarshalInto for Cert { serialized_len(&self) -> usize180 fn serialized_len(&self) -> usize { 181 let mut l = 0; 182 let primary = self.primary_key(); 183 l += PacketRef::PublicKey(primary.key()).serialized_len(); 184 185 for s in primary.self_revocations() { 186 l += PacketRef::Signature(s).serialized_len(); 187 } 188 for s in primary.self_signatures() { 189 l += PacketRef::Signature(s).serialized_len(); 190 } 191 for s in primary.certifications() { 192 l += PacketRef::Signature(s).serialized_len(); 193 } 194 for s in primary.other_revocations() { 195 l += PacketRef::Signature(s).serialized_len(); 196 } 197 198 for u in self.userids() { 199 l += PacketRef::UserID(u.userid()).serialized_len(); 200 201 for s in u.self_revocations() { 202 l += PacketRef::Signature(s).serialized_len(); 203 } 204 for s in u.self_signatures() { 205 l += PacketRef::Signature(s).serialized_len(); 206 } 207 for s in u.certifications() { 208 l += PacketRef::Signature(s).serialized_len(); 209 } 210 for s in u.other_revocations() { 211 l += PacketRef::Signature(s).serialized_len(); 212 } 213 } 214 215 for u in self.user_attributes() { 216 l += PacketRef::UserAttribute(u.user_attribute()).serialized_len(); 217 218 for s in u.self_revocations() { 219 l += PacketRef::Signature(s).serialized_len(); 220 } 221 for s in u.self_signatures() { 222 l += PacketRef::Signature(s).serialized_len(); 223 } 224 for s in u.certifications() { 225 l += PacketRef::Signature(s).serialized_len(); 226 } 227 for s in u.other_revocations() { 228 l += PacketRef::Signature(s).serialized_len(); 229 } 230 } 231 232 for k in self.subkeys() { 233 l += PacketRef::PublicSubkey(k.key()).serialized_len(); 234 235 for s in k.self_revocations() { 236 l += PacketRef::Signature(s).serialized_len(); 237 } 238 for s in k.self_signatures() { 239 l += PacketRef::Signature(s).serialized_len(); 240 } 241 for s in k.certifications() { 242 l += PacketRef::Signature(s).serialized_len(); 243 } 244 for s in k.other_revocations() { 245 l += PacketRef::Signature(s).serialized_len(); 246 } 247 } 248 249 for u in self.unknowns() { 250 l += PacketRef::Unknown(u.unknown()).serialized_len(); 251 252 for s in u.self_revocations() { 253 l += PacketRef::Signature(s).serialized_len(); 254 } 255 for s in u.self_signatures() { 256 l += PacketRef::Signature(s).serialized_len(); 257 } 258 for s in u.certifications() { 259 l += PacketRef::Signature(s).serialized_len(); 260 } 261 for s in u.other_revocations() { 262 l += PacketRef::Signature(s).serialized_len(); 263 } 264 } 265 266 for s in self.bad_signatures() { 267 l += PacketRef::Signature(s).serialized_len(); 268 } 269 270 l 271 } 272 serialize_into(&self, buf: &mut [u8]) -> Result<usize>273 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> { 274 generic_serialize_into(self, self.serialized_len(), buf) 275 } 276 export_into(&self, buf: &mut [u8]) -> Result<usize>277 fn export_into(&self, buf: &mut [u8]) -> Result<usize> { 278 generic_export_into(self, self.serialized_len(), buf) 279 } 280 } 281 282 impl Cert { 283 /// Derive a [`TSK`] object from this key. 284 /// 285 /// This object writes out secret keys during serialization. 286 /// 287 /// [`TSK`]: ../serialize/struct.TSK.html as_tsk<'a>(&'a self) -> TSK<'a>288 pub fn as_tsk<'a>(&'a self) -> TSK<'a> { 289 TSK::new(self) 290 } 291 } 292 293 /// A reference to a Cert that allows serialization of secret keys. 294 /// 295 /// To avoid accidental leakage, secret keys are not serialized when a 296 /// serializing a [`Cert`]. To serialize [`Cert`]s with secret keys, 297 /// use [`Cert::as_tsk()`] to create a `TSK`, which is a shim on top 298 /// of the `Cert`, and serialize this. 299 /// 300 /// [`Cert`]: ../cert/struct.Cert.html 301 /// [`Cert::as_tsk()`]: ../cert/struct.Cert.html#method.as_tsk 302 /// 303 /// # Example 304 /// ``` 305 /// # use sequoia_openpgp::{*, cert::*, parse::Parse, serialize::Serialize}; 306 /// # f().unwrap(); 307 /// # fn f() -> Result<()> { 308 /// let (cert, _) = CertBuilder::new().generate()?; 309 /// assert!(cert.is_tsk()); 310 /// 311 /// let mut buf = Vec::new(); 312 /// cert.as_tsk().serialize(&mut buf)?; 313 /// 314 /// let cert_ = Cert::from_bytes(&buf)?; 315 /// assert!(cert_.is_tsk()); 316 /// assert_eq!(cert, cert_); 317 /// # Ok(()) } 318 pub struct TSK<'a> { 319 cert: &'a Cert, 320 filter: Option<Box<dyn Fn(&'a key::UnspecifiedSecret) -> bool + 'a>>, 321 } 322 323 impl<'a> TSK<'a> { 324 /// Creates a new view for the given `Cert`. new(cert: &'a Cert) -> Self325 fn new(cert: &'a Cert) -> Self { 326 Self { 327 cert, 328 filter: None, 329 } 330 } 331 332 /// Filters which secret keys to export using the given predicate. 333 /// 334 /// Note that the given filter replaces any existing filter. 335 /// 336 /// # Example 337 /// ``` 338 /// # use sequoia_openpgp::{*, cert::*, parse::Parse, serialize::Serialize}; 339 /// use sequoia_openpgp::policy::StandardPolicy; 340 /// 341 /// # f().unwrap(); 342 /// # fn f() -> Result<()> { 343 /// let p = &StandardPolicy::new(); 344 /// 345 /// let (cert, _) = CertBuilder::new().add_signing_subkey().generate()?; 346 /// assert_eq!(cert.keys().with_policy(p, None).alive().revoked(false).secret().count(), 2); 347 /// 348 /// // Only write out the primary key's secret. 349 /// let mut buf = Vec::new(); 350 /// cert.as_tsk() 351 /// .set_filter(|k| k.fingerprint() == cert.fingerprint()) 352 /// .serialize(&mut buf)?; 353 /// 354 /// let cert_ = Cert::from_bytes(&buf)?; 355 /// assert_eq!(cert_.keys().with_policy(p, None).alive().revoked(false).secret().count(), 1); 356 /// assert!(cert_.primary_key().has_secret()); 357 /// # Ok(()) } set_filter<P>(mut self, predicate: P) -> Self where P: 'a + Fn(&'a key::UnspecifiedSecret) -> bool358 pub fn set_filter<P>(mut self, predicate: P) -> Self 359 where P: 'a + Fn(&'a key::UnspecifiedSecret) -> bool 360 { 361 self.filter = Some(Box::new(predicate)); 362 self 363 } 364 365 /// Serializes or exports the Cert. 366 /// 367 /// If `export` is true, then non-exportable signatures are not 368 /// written, and components without any exportable binding 369 /// signature or revocation are not exported. serialize_common(&self, o: &mut dyn std::io::Write, export: bool) -> Result<()>370 fn serialize_common(&self, o: &mut dyn std::io::Write, export: bool) 371 -> Result<()> 372 { 373 // Writes a signature if it is exportable or `! export`. 374 let serialize_sig = 375 |o: &mut dyn std::io::Write, sig: &Signature| -> Result<()> 376 { 377 if export { 378 if sig.exportable().is_ok() { 379 PacketRef::Signature(sig).export(o)?; 380 } 381 } else { 382 PacketRef::Signature(sig).serialize(o)?; 383 } 384 Ok(()) 385 }; 386 387 // Serializes public or secret key depending on the filter. 388 let serialize_key = 389 |o: &mut dyn std::io::Write, key: &'a key::UnspecifiedSecret, 390 tag_public, tag_secret| 391 { 392 let tag = if key.has_secret() 393 && self.filter.as_ref().map(|f| f(key)).unwrap_or(true) { 394 tag_secret 395 } else { 396 tag_public 397 }; 398 399 match tag { 400 Tag::PublicKey => 401 PacketRef::PublicKey(key.into()).serialize(o), 402 Tag::PublicSubkey => 403 PacketRef::PublicSubkey(key.into()).serialize(o), 404 Tag::SecretKey => 405 PacketRef::SecretKey(key.into()).serialize(o), 406 Tag::SecretSubkey => 407 PacketRef::SecretSubkey(key.into()).serialize(o), 408 _ => unreachable!(), 409 } 410 }; 411 412 let primary = self.cert.primary_key(); 413 serialize_key(o, primary.key().into(), 414 Tag::PublicKey, Tag::SecretKey)?; 415 416 for s in primary.self_signatures() { 417 serialize_sig(o, s)?; 418 } 419 for s in primary.self_revocations() { 420 serialize_sig(o, s)?; 421 } 422 for s in primary.certifications() { 423 serialize_sig(o, s)?; 424 } 425 for s in primary.other_revocations() { 426 serialize_sig(o, s)?; 427 } 428 429 for u in self.cert.userids() { 430 if export && ! u.self_signatures().iter().chain(u.self_revocations()).any( 431 |s| s.exportable().is_ok()) 432 { 433 // No exportable selfsig on this component, skip it. 434 continue; 435 } 436 437 PacketRef::UserID(u.userid()).serialize(o)?; 438 for s in u.self_revocations() { 439 serialize_sig(o, s)?; 440 } 441 for s in u.self_signatures() { 442 serialize_sig(o, s)?; 443 } 444 for s in u.other_revocations() { 445 serialize_sig(o, s)?; 446 } 447 for s in u.certifications() { 448 serialize_sig(o, s)?; 449 } 450 } 451 452 for u in self.cert.user_attributes() { 453 if export && ! u.self_signatures().iter().chain(u.self_revocations()).any( 454 |s| s.exportable().is_ok()) 455 { 456 // No exportable selfsig on this component, skip it. 457 continue; 458 } 459 460 PacketRef::UserAttribute(u.user_attribute()).serialize(o)?; 461 for s in u.self_revocations() { 462 serialize_sig(o, s)?; 463 } 464 for s in u.self_signatures() { 465 serialize_sig(o, s)?; 466 } 467 for s in u.other_revocations() { 468 serialize_sig(o, s)?; 469 } 470 for s in u.certifications() { 471 serialize_sig(o, s)?; 472 } 473 } 474 475 for k in self.cert.subkeys() { 476 if export && ! k.self_signatures().iter().chain(k.self_revocations()).any( 477 |s| s.exportable().is_ok()) 478 { 479 // No exportable selfsig on this component, skip it. 480 continue; 481 } 482 483 serialize_key(o, k.key().into(), 484 Tag::PublicSubkey, Tag::SecretSubkey)?; 485 for s in k.self_revocations() { 486 serialize_sig(o, s)?; 487 } 488 for s in k.self_signatures() { 489 serialize_sig(o, s)?; 490 } 491 for s in k.other_revocations() { 492 serialize_sig(o, s)?; 493 } 494 for s in k.certifications() { 495 serialize_sig(o, s)?; 496 } 497 } 498 499 for u in self.cert.unknowns() { 500 if export && ! u.certifications().iter().any( 501 |s| s.exportable().is_ok()) 502 { 503 // No exportable selfsig on this component, skip it. 504 continue; 505 } 506 507 PacketRef::Unknown(&u.unknown()).serialize(o)?; 508 509 for s in u.self_revocations() { 510 serialize_sig(o, s)?; 511 } 512 for s in u.self_signatures() { 513 serialize_sig(o, s)?; 514 } 515 for s in u.other_revocations() { 516 serialize_sig(o, s)?; 517 } 518 for s in u.certifications() { 519 serialize_sig(o, s)?; 520 } 521 } 522 523 for s in self.cert.bad_signatures() { 524 serialize_sig(o, s)?; 525 } 526 527 Ok(()) 528 } 529 } 530 531 impl<'a> crate::serialize::Serialize for TSK<'a> {} 532 533 impl<'a> Marshal for TSK<'a> { serialize(&self, o: &mut dyn std::io::Write) -> Result<()>534 fn serialize(&self, o: &mut dyn std::io::Write) -> Result<()> { 535 self.serialize_common(o, false) 536 } 537 export(&self, o: &mut dyn std::io::Write) -> Result<()>538 fn export(&self, o: &mut dyn std::io::Write) -> Result<()> { 539 self.serialize_common(o, true) 540 } 541 } 542 543 impl<'a> crate::serialize::SerializeInto for TSK<'a> {} 544 545 impl<'a> MarshalInto for TSK<'a> { serialized_len(&self) -> usize546 fn serialized_len(&self) -> usize { 547 let mut l = 0; 548 549 // Serializes public or secret key depending on the filter. 550 let serialized_len_key 551 = |key: &'a key::UnspecifiedSecret, tag_public, tag_secret| 552 { 553 let tag = if key.has_secret() 554 && self.filter.as_ref().map(|f| f(key)).unwrap_or(true) { 555 tag_secret 556 } else { 557 tag_public 558 }; 559 560 let packet = match tag { 561 Tag::PublicKey => PacketRef::PublicKey(key.into()), 562 Tag::PublicSubkey => PacketRef::PublicSubkey(key.into()), 563 Tag::SecretKey => PacketRef::SecretKey(key.into()), 564 Tag::SecretSubkey => PacketRef::SecretSubkey(key.into()), 565 _ => unreachable!(), 566 }; 567 568 packet.serialized_len() 569 }; 570 571 let primary = self.cert.primary_key(); 572 l += serialized_len_key(primary.key().into(), 573 Tag::PublicKey, Tag::SecretKey); 574 575 for s in primary.self_signatures() { 576 l += PacketRef::Signature(s).serialized_len(); 577 } 578 for s in primary.self_revocations() { 579 l += PacketRef::Signature(s).serialized_len(); 580 } 581 for s in primary.other_revocations() { 582 l += PacketRef::Signature(s).serialized_len(); 583 } 584 for s in primary.certifications() { 585 l += PacketRef::Signature(s).serialized_len(); 586 } 587 588 for u in self.cert.userids() { 589 l += PacketRef::UserID(u.userid()).serialized_len(); 590 591 for s in u.self_revocations() { 592 l += PacketRef::Signature(s).serialized_len(); 593 } 594 for s in u.self_signatures() { 595 l += PacketRef::Signature(s).serialized_len(); 596 } 597 for s in u.other_revocations() { 598 l += PacketRef::Signature(s).serialized_len(); 599 } 600 for s in u.certifications() { 601 l += PacketRef::Signature(s).serialized_len(); 602 } 603 } 604 605 for u in self.cert.user_attributes() { 606 l += PacketRef::UserAttribute(u.user_attribute()).serialized_len(); 607 608 for s in u.self_revocations() { 609 l += PacketRef::Signature(s).serialized_len(); 610 } 611 for s in u.self_signatures() { 612 l += PacketRef::Signature(s).serialized_len(); 613 } 614 for s in u.other_revocations() { 615 l += PacketRef::Signature(s).serialized_len(); 616 } 617 for s in u.certifications() { 618 l += PacketRef::Signature(s).serialized_len(); 619 } 620 } 621 622 for k in self.cert.subkeys() { 623 l += serialized_len_key(k.key().into(), 624 Tag::PublicSubkey, Tag::SecretSubkey); 625 626 for s in k.self_revocations() { 627 l += PacketRef::Signature(s).serialized_len(); 628 } 629 for s in k.self_signatures() { 630 l += PacketRef::Signature(s).serialized_len(); 631 } 632 for s in k.other_revocations() { 633 l += PacketRef::Signature(s).serialized_len(); 634 } 635 for s in k.certifications() { 636 l += PacketRef::Signature(s).serialized_len(); 637 } 638 } 639 640 for u in self.cert.unknowns() { 641 l += PacketRef::Unknown(u.unknown()).serialized_len(); 642 643 for s in u.self_revocations() { 644 l += PacketRef::Signature(s).serialized_len(); 645 } 646 for s in u.self_signatures() { 647 l += PacketRef::Signature(s).serialized_len(); 648 } 649 for s in u.other_revocations() { 650 l += PacketRef::Signature(s).serialized_len(); 651 } 652 for s in u.certifications() { 653 l += PacketRef::Signature(s).serialized_len(); 654 } 655 } 656 657 for s in self.cert.bad_signatures() { 658 l += PacketRef::Signature(s).serialized_len(); 659 } 660 661 l 662 } 663 serialize_into(&self, buf: &mut [u8]) -> Result<usize>664 fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> { 665 generic_serialize_into(self, self.serialized_len(), buf) 666 } 667 export_into(&self, buf: &mut [u8]) -> Result<usize>668 fn export_into(&self, buf: &mut [u8]) -> Result<usize> { 669 generic_export_into(self, self.serialized_len(), buf) 670 } 671 } 672 673 #[cfg(test)] 674 mod test { 675 use super::*; 676 use crate::vec_truncate; 677 use crate::parse::Parse; 678 use crate::packet::key; 679 use crate::policy::StandardPolicy as P; 680 681 /// Demonstrates that public keys and all components are 682 /// serialized. 683 #[test] roundtrip_cert()684 fn roundtrip_cert() { 685 for test in crate::tests::CERTS { 686 let cert = match Cert::from_bytes(test.bytes) { 687 Ok(t) => t, 688 Err(_) => continue, 689 }; 690 assert!(! cert.is_tsk()); 691 let buf = cert.as_tsk().to_vec().unwrap(); 692 let cert_ = Cert::from_bytes(&buf).unwrap(); 693 694 assert_eq!(cert, cert_, "roundtripping {}.pgp failed", test); 695 } 696 } 697 698 /// Demonstrates that secret keys and all components are 699 /// serialized. 700 #[test] roundtrip_tsk()701 fn roundtrip_tsk() { 702 for test in crate::tests::TSKS { 703 let cert = Cert::from_bytes(test.bytes).unwrap(); 704 assert!(cert.is_tsk()); 705 706 let mut buf = Vec::new(); 707 cert.as_tsk().serialize(&mut buf).unwrap(); 708 let cert_ = Cert::from_bytes(&buf).unwrap(); 709 710 assert_eq!(cert, cert_, "roundtripping {}-private.pgp failed", test); 711 712 // This time, use a trivial filter. 713 let mut buf = Vec::new(); 714 cert.as_tsk().set_filter(|_| true).serialize(&mut buf).unwrap(); 715 let cert_ = Cert::from_bytes(&buf).unwrap(); 716 717 assert_eq!(cert, cert_, "roundtripping {}-private.pgp failed", test); 718 } 719 } 720 721 /// Demonstrates that TSK::serialize() with the right filter 722 /// reduces to Cert::serialize(). 723 #[test] reduce_to_cert_serialize()724 fn reduce_to_cert_serialize() { 725 for test in crate::tests::TSKS { 726 let cert = Cert::from_bytes(test.bytes).unwrap(); 727 assert!(cert.is_tsk()); 728 729 // First, use Cert::serialize(). 730 let mut buf_cert = Vec::new(); 731 cert.serialize(&mut buf_cert).unwrap(); 732 733 // When serializing using TSK::serialize, filter out all 734 // secret keys. 735 let mut buf_tsk = Vec::new(); 736 cert.as_tsk().set_filter(|_| false).serialize(&mut buf_tsk).unwrap(); 737 738 // Check for equality. 739 let cert_ = Cert::from_bytes(&buf_cert).unwrap(); 740 let tsk_ = Cert::from_bytes(&buf_tsk).unwrap(); 741 assert_eq!(cert_, tsk_, 742 "reducing failed on {}-private.pgp: not Cert::eq", 743 test); 744 745 // Check for identinty. 746 assert_eq!(buf_cert, buf_tsk, 747 "reducing failed on {}-private.pgp: serialized identity", 748 test); 749 } 750 } 751 752 #[test] export()753 fn export() { 754 use crate::Packet; 755 use crate::cert::prelude::*; 756 use crate::types::{Curve, KeyFlags, SignatureType}; 757 use crate::packet::{ 758 signature, UserID, user_attribute::{UserAttribute, Subpacket}, 759 key::Key4, 760 }; 761 762 let p = &P::new(); 763 764 let (cert, _) = CertBuilder::new().generate().unwrap(); 765 let mut keypair = cert.primary_key().key().clone().parts_into_secret() 766 .unwrap().into_keypair().unwrap(); 767 768 let key: key::SecretSubkey = 769 Key4::generate_ecc(false, Curve::Cv25519).unwrap().into(); 770 let key_binding = key.bind( 771 &mut keypair, &cert, 772 signature::SignatureBuilder::new(SignatureType::SubkeyBinding) 773 .set_key_flags( 774 &KeyFlags::empty().set_transport_encryption()) 775 .unwrap() 776 .set_exportable_certification(false).unwrap()).unwrap(); 777 778 let uid = UserID::from("foo"); 779 let uid_binding = uid.bind( 780 &mut keypair, &cert, 781 signature::SignatureBuilder::from( 782 cert.primary_key().with_policy(p, None).unwrap() 783 .direct_key_signature().unwrap().clone()) 784 .set_type(SignatureType::PositiveCertification) 785 .preserve_signature_creation_time().unwrap() 786 .set_exportable_certification(false).unwrap()).unwrap(); 787 788 let ua = UserAttribute::new(&[ 789 Subpacket::Unknown(2, b"foo".to_vec().into_boxed_slice()), 790 ]).unwrap(); 791 let ua_binding = ua.bind( 792 &mut keypair, &cert, 793 signature::SignatureBuilder::from( 794 cert.primary_key().with_policy(p, None).unwrap() 795 .direct_key_signature().unwrap().clone()) 796 .set_type(SignatureType::PositiveCertification) 797 .preserve_signature_creation_time().unwrap() 798 .set_exportable_certification(false).unwrap()).unwrap(); 799 800 let cert = cert.merge_packets(vec![ 801 Packet::SecretSubkey(key), key_binding.into(), 802 uid.into(), uid_binding.into(), 803 ua.into(), ua_binding.into(), 804 ]).unwrap(); 805 806 assert_eq!(cert.subkeys().count(), 1); 807 cert.subkeys().nth(0).unwrap().binding_signature(p, None).unwrap(); 808 assert_eq!(cert.userids().count(), 1); 809 assert!(cert.userids().with_policy(p, None).nth(0).is_some()); 810 assert_eq!(cert.user_attributes().count(), 1); 811 assert!(cert.user_attributes().with_policy(p, None).nth(0).is_some()); 812 813 // The binding signature is not exportable, so when we export 814 // and re-parse, we expect the userid to be gone. 815 let mut buf = Vec::new(); 816 cert.export(&mut buf).unwrap(); 817 let cert_ = Cert::from_bytes(&buf).unwrap(); 818 assert_eq!(cert_.subkeys().count(), 0); 819 assert_eq!(cert_.userids().count(), 0); 820 assert_eq!(cert_.user_attributes().count(), 0); 821 822 let mut buf = vec![0; cert.serialized_len()]; 823 let l = cert.export_into(&mut buf).unwrap(); 824 vec_truncate(&mut buf, l); 825 let cert_ = Cert::from_bytes(&buf).unwrap(); 826 assert_eq!(cert_.subkeys().count(), 0); 827 assert_eq!(cert_.userids().count(), 0); 828 assert_eq!(cert_.user_attributes().count(), 0); 829 830 let cert_ = Cert::from_bytes(&cert.export_to_vec().unwrap()).unwrap(); 831 assert_eq!(cert_.subkeys().count(), 0); 832 assert_eq!(cert_.userids().count(), 0); 833 assert_eq!(cert_.user_attributes().count(), 0); 834 835 // Same, this time using the armor encoder. 836 let mut buf = Vec::new(); 837 cert.armored().export(&mut buf).unwrap(); 838 let cert_ = Cert::from_bytes(&buf).unwrap(); 839 assert_eq!(cert_.subkeys().count(), 0); 840 assert_eq!(cert_.userids().count(), 0); 841 assert_eq!(cert_.user_attributes().count(), 0); 842 843 let mut buf = vec![0; cert.serialized_len()]; 844 let l = cert.armored().export_into(&mut buf).unwrap(); 845 vec_truncate(&mut buf, l); 846 let cert_ = Cert::from_bytes(&buf).unwrap(); 847 assert_eq!(cert_.subkeys().count(), 0); 848 assert_eq!(cert_.userids().count(), 0); 849 assert_eq!(cert_.user_attributes().count(), 0); 850 851 let cert_ = 852 Cert::from_bytes(&cert.armored().export_to_vec().unwrap()).unwrap(); 853 assert_eq!(cert_.subkeys().count(), 0); 854 assert_eq!(cert_.userids().count(), 0); 855 assert_eq!(cert_.user_attributes().count(), 0); 856 857 // Same, this time as TSKs. 858 let mut buf = Vec::new(); 859 cert.as_tsk().export(&mut buf).unwrap(); 860 let cert_ = Cert::from_bytes(&buf).unwrap(); 861 assert_eq!(cert_.subkeys().count(), 0); 862 assert_eq!(cert_.userids().count(), 0); 863 assert_eq!(cert_.user_attributes().count(), 0); 864 865 let mut buf = vec![0; cert.serialized_len()]; 866 let l = cert.as_tsk().export_into(&mut buf).unwrap(); 867 vec_truncate(&mut buf, l); 868 let cert_ = Cert::from_bytes(&buf).unwrap(); 869 assert_eq!(cert_.subkeys().count(), 0); 870 assert_eq!(cert_.userids().count(), 0); 871 assert_eq!(cert_.user_attributes().count(), 0); 872 873 let cert_ = 874 Cert::from_bytes(&cert.as_tsk().export_to_vec().unwrap()).unwrap(); 875 assert_eq!(cert_.subkeys().count(), 0); 876 assert_eq!(cert_.userids().count(), 0); 877 assert_eq!(cert_.user_attributes().count(), 0); 878 } 879 } 880