1 //! Support for signing mft, crl, certificates, roas.. 2 //! Common objects for TAs and CAs 3 use std::{ 4 ops::Deref, 5 sync::{Arc, RwLock}, 6 {convert::TryFrom, path::Path}, 7 }; 8 9 use bcder::Captured; 10 use bytes::Bytes; 11 12 use rpki::{ 13 repository::{ 14 aspa::{Aspa, AspaBuilder}, 15 cert::{Cert, KeyUsage, Overclaim, TbsCert}, 16 crl::{Crl, CrlEntry, TbsCertList}, 17 crypto::{DigestAlgorithm, KeyIdentifier, PublicKey, PublicKeyFormat, Signature, SignatureAlgorithm, Signer}, 18 csr::Csr, 19 manifest::{FileAndHash, Manifest, ManifestContent}, 20 roa::{Roa, RoaBuilder}, 21 rta, 22 sigobj::SignedObjectBuilder, 23 x509::{Name, Serial, Time, Validity}, 24 }, 25 uri, 26 }; 27 28 #[cfg(feature = "hsm")] 29 use crate::commons::util::dummysigner::DummySigner; 30 31 use crate::{ 32 commons::{ 33 api::{IssuedCert, RcvdCert, ReplacedObject, RepoInfo, RequestResourceLimit, ResourceSet}, 34 crypto::{self, CryptoResult}, 35 error::Error, 36 util::{softsigner::OpenSslSigner, AllowedUri}, 37 KrillResult, 38 }, 39 daemon::ca::CertifiedKey, 40 }; 41 42 //------------ Signer -------------------------------------------------------- 43 44 #[derive(Clone, Debug)] 45 enum SignerProvider { 46 OpenSsl(OpenSslSigner), 47 48 #[cfg(feature = "hsm")] 49 #[allow(dead_code)] 50 Dummy(DummySigner), 51 } 52 53 impl SignerProvider { create_key(&mut self) -> CryptoResult<KeyIdentifier>54 pub fn create_key(&mut self) -> CryptoResult<KeyIdentifier> { 55 match self { 56 SignerProvider::OpenSsl(signer) => signer.create_key(PublicKeyFormat::Rsa), 57 #[cfg(feature = "hsm")] 58 SignerProvider::Dummy(signer) => signer.create_key(PublicKeyFormat::Rsa), 59 } 60 .map_err(crypto::Error::signer) 61 } 62 destroy_key(&mut self, key_id: &KeyIdentifier) -> CryptoResult<()>63 pub fn destroy_key(&mut self, key_id: &KeyIdentifier) -> CryptoResult<()> { 64 match self { 65 SignerProvider::OpenSsl(signer) => signer.destroy_key(key_id), 66 #[cfg(feature = "hsm")] 67 SignerProvider::Dummy(signer) => signer.destroy_key(key_id), 68 } 69 .map_err(crypto::Error::key_error) 70 } 71 get_key_info(&self, key_id: &KeyIdentifier) -> CryptoResult<PublicKey>72 pub fn get_key_info(&self, key_id: &KeyIdentifier) -> CryptoResult<PublicKey> { 73 match self { 74 SignerProvider::OpenSsl(signer) => signer.get_key_info(key_id), 75 #[cfg(feature = "hsm")] 76 SignerProvider::Dummy(signer) => signer.get_key_info(key_id), 77 } 78 .map_err(crypto::Error::key_error) 79 } 80 random_serial(&self) -> CryptoResult<Serial>81 pub fn random_serial(&self) -> CryptoResult<Serial> { 82 match self { 83 SignerProvider::OpenSsl(signer) => Serial::random(signer.deref()), 84 #[cfg(feature = "hsm")] 85 SignerProvider::Dummy(signer) => Serial::random(signer.deref()), 86 } 87 .map_err(crypto::Error::signer) 88 } 89 sign<D: AsRef<[u8]> + ?Sized>( &self, key_id: &KeyIdentifier, sig_alg: SignatureAlgorithm, data: &D, ) -> CryptoResult<Signature>90 pub fn sign<D: AsRef<[u8]> + ?Sized>( 91 &self, 92 key_id: &KeyIdentifier, 93 sig_alg: SignatureAlgorithm, 94 data: &D, 95 ) -> CryptoResult<Signature> { 96 match self { 97 SignerProvider::OpenSsl(signer) => signer.sign(key_id, sig_alg, data), 98 #[cfg(feature = "hsm")] 99 SignerProvider::Dummy(signer) => signer.sign(key_id, sig_alg, data), 100 } 101 .map_err(crypto::Error::signing) 102 } 103 sign_one_off<D: AsRef<[u8]> + ?Sized>( &self, sig_alg: SignatureAlgorithm, data: &D, ) -> CryptoResult<(Signature, PublicKey)>104 pub fn sign_one_off<D: AsRef<[u8]> + ?Sized>( 105 &self, 106 sig_alg: SignatureAlgorithm, 107 data: &D, 108 ) -> CryptoResult<(Signature, PublicKey)> { 109 match self { 110 SignerProvider::OpenSsl(signer) => signer.sign_one_off(sig_alg, data), 111 #[cfg(feature = "hsm")] 112 SignerProvider::Dummy(signer) => signer.sign_one_off(sig_alg, data), 113 } 114 .map_err(crypto::Error::signer) 115 } 116 sign_csr(&self, base_repo: &RepoInfo, name_space: &str, key: &KeyIdentifier) -> CryptoResult<Csr>117 pub fn sign_csr(&self, base_repo: &RepoInfo, name_space: &str, key: &KeyIdentifier) -> CryptoResult<Csr> { 118 fn func<T>(signer: &T, base_repo: &RepoInfo, name_space: &str, key: &KeyIdentifier) -> CryptoResult<Captured> 119 where 120 T: Signer<KeyId = KeyIdentifier>, 121 { 122 let pub_key = signer.get_key_info(key).map_err(crypto::Error::key_error)?; 123 Csr::construct( 124 signer.deref(), 125 key, 126 &base_repo.ca_repository(name_space).join(&[]).unwrap(), // force trailing slash 127 &base_repo.rpki_manifest(name_space, &pub_key.key_identifier()), 128 Some(&base_repo.rpki_notify()), 129 ) 130 .map_err(crypto::Error::signing) 131 } 132 133 let enc = match self { 134 SignerProvider::OpenSsl(signer) => func(signer.deref(), base_repo, name_space, key), 135 #[cfg(feature = "hsm")] 136 SignerProvider::Dummy(signer) => func(signer.deref(), base_repo, name_space, key), 137 }?; 138 139 Ok(Csr::decode(enc.as_slice())?) 140 } 141 sign_cert(&self, tbs: TbsCert, key_id: &KeyIdentifier) -> CryptoResult<Cert>142 pub fn sign_cert(&self, tbs: TbsCert, key_id: &KeyIdentifier) -> CryptoResult<Cert> { 143 match self { 144 SignerProvider::OpenSsl(signer) => tbs.into_cert(signer.deref(), key_id), 145 #[cfg(feature = "hsm")] 146 SignerProvider::Dummy(signer) => tbs.into_cert(signer.deref(), key_id), 147 } 148 .map_err(crypto::Error::signing) 149 } 150 sign_crl(&self, tbs: TbsCertList<Vec<CrlEntry>>, key_id: &KeyIdentifier) -> CryptoResult<Crl>151 pub fn sign_crl(&self, tbs: TbsCertList<Vec<CrlEntry>>, key_id: &KeyIdentifier) -> CryptoResult<Crl> { 152 match self { 153 SignerProvider::OpenSsl(signer) => tbs.into_crl(signer.deref(), key_id), 154 #[cfg(feature = "hsm")] 155 SignerProvider::Dummy(signer) => tbs.into_crl(signer.deref(), key_id), 156 } 157 .map_err(crypto::Error::signing) 158 } 159 sign_manifest( &self, content: ManifestContent, builder: SignedObjectBuilder, key_id: &KeyIdentifier, ) -> CryptoResult<Manifest>160 pub fn sign_manifest( 161 &self, 162 content: ManifestContent, 163 builder: SignedObjectBuilder, 164 key_id: &KeyIdentifier, 165 ) -> CryptoResult<Manifest> { 166 match self { 167 SignerProvider::OpenSsl(signer) => content.into_manifest(builder, signer.deref(), key_id), 168 #[cfg(feature = "hsm")] 169 SignerProvider::Dummy(signer) => content.into_manifest(builder, signer.deref(), key_id), 170 } 171 .map_err(crypto::Error::signing) 172 } 173 sign_roa( &self, roa_builder: RoaBuilder, object_builder: SignedObjectBuilder, key_id: &KeyIdentifier, ) -> CryptoResult<Roa>174 pub fn sign_roa( 175 &self, 176 roa_builder: RoaBuilder, 177 object_builder: SignedObjectBuilder, 178 key_id: &KeyIdentifier, 179 ) -> CryptoResult<Roa> { 180 match self { 181 SignerProvider::OpenSsl(signer) => roa_builder.finalize(object_builder, signer.deref(), key_id), 182 #[cfg(feature = "hsm")] 183 SignerProvider::Dummy(signer) => roa_builder.finalize(object_builder, signer.deref(), key_id), 184 } 185 .map_err(crypto::Error::signing) 186 } 187 sign_aspa( &self, aspa_builder: AspaBuilder, object_builder: SignedObjectBuilder, key_id: &KeyIdentifier, ) -> CryptoResult<Aspa>188 pub fn sign_aspa( 189 &self, 190 aspa_builder: AspaBuilder, 191 object_builder: SignedObjectBuilder, 192 key_id: &KeyIdentifier, 193 ) -> CryptoResult<Aspa> { 194 match self { 195 SignerProvider::OpenSsl(signer) => aspa_builder.finalize(object_builder, signer.deref(), key_id), 196 #[cfg(feature = "hsm")] 197 SignerProvider::Dummy(signer) => aspa_builder.finalize(object_builder, signer.deref(), key_id), 198 } 199 .map_err(crypto::Error::signing) 200 } 201 sign_rta(&self, rta_builder: &mut rta::RtaBuilder, ee: Cert) -> CryptoResult<()>202 pub fn sign_rta(&self, rta_builder: &mut rta::RtaBuilder, ee: Cert) -> CryptoResult<()> { 203 let key = ee.subject_key_identifier(); 204 rta_builder.push_cert(ee); 205 206 match self { 207 SignerProvider::OpenSsl(signer) => rta_builder.sign(signer.deref(), &key, None, None), 208 #[cfg(feature = "hsm")] 209 SignerProvider::Dummy(signer) => rta_builder.sign(signer.deref(), &key, None, None), 210 } 211 .map_err(crypto::Error::signing) 212 } 213 } 214 215 #[derive(Clone, Debug)] 216 pub struct KrillSigner { 217 // KrillSigner chooses which signer to use when. The noise of handling the enum based dispatch is handled by the 218 // SignerProvider type defined above, patterned after the existing AuthProvider enum based approach. 219 // 220 // Use Arc references so that we can use refer to the same signer instance more than once if that signer should be 221 // used for multiple purposes, e.g. as both general_signer and one_off_signer in this case. 222 // 223 // Use an RwLock because the Signer trait from the rpki-rs crate uses &mut self for create_key() and destroy_key() 224 // operations. In future we might move the responsibility for locking into the signer so that it can lock only what 225 // actually needs to be locked raet 226 227 // The general signer is used for all signing operations except one off signing. 228 general_signer: Arc<RwLock<SignerProvider>>, 229 230 // As the security of a HSM isn't needed for one off keys, and HSMs are slow, by default this should be an instance 231 // of OpenSslSigner. However, if users think the perceived extra security is warranted let them use a different 232 // Signer for one off keys if that's what they want. 233 one_off_signer: Arc<RwLock<SignerProvider>>, 234 } 235 236 impl KrillSigner { build(work_dir: &Path) -> KrillResult<Self>237 pub fn build(work_dir: &Path) -> KrillResult<Self> { 238 // The types of signer to initialize, the details needed to initialize them and the intended purpose for each 239 // signer (e.g. signer for past keys, currently used signer, signer to use for a key roll, etc.) should come 240 // from the configuration file. KrillSigner should combine that input its own rules, e.g. to dispatch a signing 241 // request to the correct signer we will need to determine which signer possesses the signing key, and the 242 // signer to use to create a new key depends on whether the key is one-off or not and whether or not it is 243 // being created for a key roll. For now the capability for different signers for different purposes exists but 244 // is not yet used. 245 246 let openssl_signer = OpenSslSigner::build(work_dir)?; 247 let openssl_signer = Arc::new(RwLock::new(SignerProvider::OpenSsl(openssl_signer))); 248 let general_signer = openssl_signer.clone(); 249 let one_off_signer = openssl_signer; 250 Ok(KrillSigner { 251 general_signer, 252 one_off_signer, 253 }) 254 } 255 create_key(&self) -> CryptoResult<KeyIdentifier>256 pub fn create_key(&self) -> CryptoResult<KeyIdentifier> { 257 self.general_signer.write().unwrap().create_key() 258 } 259 destroy_key(&self, key_id: &KeyIdentifier) -> CryptoResult<()>260 pub fn destroy_key(&self, key_id: &KeyIdentifier) -> CryptoResult<()> { 261 self.general_signer.write().unwrap().destroy_key(key_id) 262 } 263 get_key_info(&self, key_id: &KeyIdentifier) -> CryptoResult<PublicKey>264 pub fn get_key_info(&self, key_id: &KeyIdentifier) -> CryptoResult<PublicKey> { 265 self.general_signer.read().unwrap().get_key_info(key_id) 266 } 267 random_serial(&self) -> CryptoResult<Serial>268 pub fn random_serial(&self) -> CryptoResult<Serial> { 269 self.general_signer.read().unwrap().random_serial() 270 } 271 sign<D: AsRef<[u8]> + ?Sized>(&self, key_id: &KeyIdentifier, data: &D) -> CryptoResult<Signature>272 pub fn sign<D: AsRef<[u8]> + ?Sized>(&self, key_id: &KeyIdentifier, data: &D) -> CryptoResult<Signature> { 273 self.general_signer 274 .read() 275 .unwrap() 276 .sign(key_id, SignatureAlgorithm::default(), data) 277 } 278 sign_one_off<D: AsRef<[u8]> + ?Sized>(&self, data: &D) -> CryptoResult<(Signature, PublicKey)>279 pub fn sign_one_off<D: AsRef<[u8]> + ?Sized>(&self, data: &D) -> CryptoResult<(Signature, PublicKey)> { 280 self.one_off_signer 281 .read() 282 .unwrap() 283 .sign_one_off(SignatureAlgorithm::default(), data) 284 } 285 sign_csr(&self, base_repo: &RepoInfo, name_space: &str, key: &KeyIdentifier) -> CryptoResult<Csr>286 pub fn sign_csr(&self, base_repo: &RepoInfo, name_space: &str, key: &KeyIdentifier) -> CryptoResult<Csr> { 287 self.general_signer.read().unwrap().sign_csr(base_repo, name_space, key) 288 } 289 sign_cert(&self, tbs: TbsCert, key_id: &KeyIdentifier) -> CryptoResult<Cert>290 pub fn sign_cert(&self, tbs: TbsCert, key_id: &KeyIdentifier) -> CryptoResult<Cert> { 291 self.general_signer.read().unwrap().sign_cert(tbs, key_id) 292 } 293 sign_crl(&self, tbs: TbsCertList<Vec<CrlEntry>>, key_id: &KeyIdentifier) -> CryptoResult<Crl>294 pub fn sign_crl(&self, tbs: TbsCertList<Vec<CrlEntry>>, key_id: &KeyIdentifier) -> CryptoResult<Crl> { 295 self.general_signer.read().unwrap().sign_crl(tbs, key_id) 296 } 297 sign_manifest( &self, content: ManifestContent, builder: SignedObjectBuilder, key_id: &KeyIdentifier, ) -> CryptoResult<Manifest>298 pub fn sign_manifest( 299 &self, 300 content: ManifestContent, 301 builder: SignedObjectBuilder, 302 key_id: &KeyIdentifier, 303 ) -> CryptoResult<Manifest> { 304 self.general_signer 305 .read() 306 .unwrap() 307 .sign_manifest(content, builder, key_id) 308 } 309 sign_roa( &self, roa_builder: RoaBuilder, object_builder: SignedObjectBuilder, key_id: &KeyIdentifier, ) -> CryptoResult<Roa>310 pub fn sign_roa( 311 &self, 312 roa_builder: RoaBuilder, 313 object_builder: SignedObjectBuilder, 314 key_id: &KeyIdentifier, 315 ) -> CryptoResult<Roa> { 316 self.general_signer 317 .read() 318 .unwrap() 319 .sign_roa(roa_builder, object_builder, key_id) 320 } 321 sign_aspa( &self, aspa_builder: AspaBuilder, object_builder: SignedObjectBuilder, key_id: &KeyIdentifier, ) -> CryptoResult<Aspa>322 pub fn sign_aspa( 323 &self, 324 aspa_builder: AspaBuilder, 325 object_builder: SignedObjectBuilder, 326 key_id: &KeyIdentifier, 327 ) -> CryptoResult<Aspa> { 328 self.general_signer 329 .read() 330 .unwrap() 331 .sign_aspa(aspa_builder, object_builder, key_id) 332 } 333 sign_rta(&self, rta_builder: &mut rta::RtaBuilder, ee: Cert) -> CryptoResult<()>334 pub fn sign_rta(&self, rta_builder: &mut rta::RtaBuilder, ee: Cert) -> CryptoResult<()> { 335 self.general_signer.read().unwrap().sign_rta(rta_builder, ee) 336 } 337 } 338 339 // //------------ Signer -------------------------------------------------------- 340 // 341 // pub trait Signer: crypto::Signer<KeyId = KeyIdentifier> + Clone + Sized + Sync + Send + 'static {} 342 // impl<T: crypto::Signer<KeyId = KeyIdentifier> + Clone + Sized + Sync + Send + 'static> Signer for T {} 343 344 //------------ CsrInfo ------------------------------------------------------- 345 346 pub type CaRepository = uri::Rsync; 347 pub type RpkiManifest = uri::Rsync; 348 pub type RpkiNotify = uri::Https; 349 350 pub struct CsrInfo { 351 ca_repository: CaRepository, 352 rpki_manifest: RpkiManifest, 353 rpki_notify: Option<RpkiNotify>, 354 key: PublicKey, 355 } 356 357 impl CsrInfo { new( ca_repository: CaRepository, rpki_manifest: RpkiManifest, rpki_notify: Option<RpkiNotify>, key: PublicKey, ) -> Self358 pub fn new( 359 ca_repository: CaRepository, 360 rpki_manifest: RpkiManifest, 361 rpki_notify: Option<RpkiNotify>, 362 key: PublicKey, 363 ) -> Self { 364 CsrInfo { 365 ca_repository, 366 rpki_manifest, 367 rpki_notify, 368 key, 369 } 370 } 371 global_uris(&self) -> bool372 pub fn global_uris(&self) -> bool { 373 self.ca_repository.seems_global_uri() 374 && self.rpki_manifest.seems_global_uri() 375 && self 376 .rpki_notify 377 .as_ref() 378 .map(|uri| uri.seems_global_uri()) 379 .unwrap_or_else(|| true) 380 } 381 unpack(self) -> (CaRepository, RpkiManifest, Option<RpkiNotify>, PublicKey)382 pub fn unpack(self) -> (CaRepository, RpkiManifest, Option<RpkiNotify>, PublicKey) { 383 (self.ca_repository, self.rpki_manifest, self.rpki_notify, self.key) 384 } 385 key_id(&self) -> KeyIdentifier386 pub fn key_id(&self) -> KeyIdentifier { 387 self.key.key_identifier() 388 } 389 } 390 391 impl TryFrom<&Csr> for CsrInfo { 392 type Error = Error; 393 try_from(csr: &Csr) -> KrillResult<CsrInfo>394 fn try_from(csr: &Csr) -> KrillResult<CsrInfo> { 395 csr.validate().map_err(|_| Error::invalid_csr("invalid signature"))?; 396 let ca_repository = csr 397 .ca_repository() 398 .cloned() 399 .ok_or_else(|| Error::invalid_csr("missing ca repository"))?; 400 let rpki_manifest = csr 401 .rpki_manifest() 402 .cloned() 403 .ok_or_else(|| Error::invalid_csr("missing rpki manifest"))?; 404 let rpki_notify = csr.rpki_notify().cloned(); 405 let key = csr.public_key().clone(); 406 Ok(CsrInfo { 407 ca_repository, 408 rpki_manifest, 409 rpki_notify, 410 key, 411 }) 412 } 413 } 414 415 impl From<&Cert> for CsrInfo { from(issued: &Cert) -> Self416 fn from(issued: &Cert) -> Self { 417 let ca_repository = issued.ca_repository().cloned().unwrap(); 418 let rpki_manifest = issued.rpki_manifest().cloned().unwrap(); 419 let rpki_notify = issued.rpki_notify().cloned(); 420 let key = issued.subject_public_key_info().clone(); 421 CsrInfo { 422 ca_repository, 423 rpki_manifest, 424 rpki_notify, 425 key, 426 } 427 } 428 } 429 430 //------------ CaSignSupport ------------------------------------------------- 431 432 /// Support signing by CAs 433 pub struct SignSupport; 434 435 impl SignSupport { 436 /// Create an IssuedCert make_issued_cert( csr: CsrInfo, resources: &ResourceSet, limit: RequestResourceLimit, replaces: Option<ReplacedObject>, signing_key: &CertifiedKey, weeks: i64, signer: &KrillSigner, ) -> KrillResult<IssuedCert>437 pub fn make_issued_cert( 438 csr: CsrInfo, 439 resources: &ResourceSet, 440 limit: RequestResourceLimit, 441 replaces: Option<ReplacedObject>, 442 signing_key: &CertifiedKey, 443 weeks: i64, 444 signer: &KrillSigner, 445 ) -> KrillResult<IssuedCert> { 446 let signing_cert = signing_key.incoming_cert(); 447 let resources = resources.apply_limit(&limit)?; 448 if !signing_cert.resources().contains(&resources) { 449 return Err(Error::MissingResources); 450 } 451 452 let validity = Self::sign_validity_weeks(weeks); 453 let request = CertRequest::Ca(csr, validity); 454 455 let tbs = Self::make_tbs_cert(&resources, signing_cert, request, signer)?; 456 let cert = signer.sign_cert(tbs, signing_key.key_id())?; 457 458 let cert_uri = signing_cert.uri_for_object(&cert); 459 460 Ok(IssuedCert::new(cert_uri, limit, resources, cert, replaces)) 461 } 462 463 /// Create an EE certificate for use in ResourceTaggedAttestations. 464 /// Note that for RPKI signed objects such as ROAs and Manifests, the 465 /// EE certificate is created by the rpki.rs library instead. make_rta_ee_cert( resources: &ResourceSet, signing_key: &CertifiedKey, validity: Validity, pub_key: PublicKey, signer: &KrillSigner, ) -> KrillResult<Cert>466 pub fn make_rta_ee_cert( 467 resources: &ResourceSet, 468 signing_key: &CertifiedKey, 469 validity: Validity, 470 pub_key: PublicKey, 471 signer: &KrillSigner, 472 ) -> KrillResult<Cert> { 473 let signing_cert = signing_key.incoming_cert(); 474 let request = CertRequest::Ee(pub_key, validity); 475 let tbs = Self::make_tbs_cert(resources, signing_cert, request, signer)?; 476 477 let cert = signer.sign_cert(tbs, signing_key.key_id())?; 478 Ok(cert) 479 } 480 make_tbs_cert( resources: &ResourceSet, signing_cert: &RcvdCert, request: CertRequest, signer: &KrillSigner, ) -> KrillResult<TbsCert>481 fn make_tbs_cert( 482 resources: &ResourceSet, 483 signing_cert: &RcvdCert, 484 request: CertRequest, 485 signer: &KrillSigner, 486 ) -> KrillResult<TbsCert> { 487 let serial = signer.random_serial()?; 488 let issuer = signing_cert.cert().subject().clone(); 489 490 let validity = match &request { 491 CertRequest::Ca(_, validity) => *validity, 492 CertRequest::Ee(_, validity) => *validity, 493 }; 494 495 let pub_key = match &request { 496 CertRequest::Ca(info, _) => info.key.clone(), 497 CertRequest::Ee(key, _) => key.clone(), 498 }; 499 500 let subject = Some(Name::from_pub_key(&pub_key)); 501 502 let key_usage = match &request { 503 CertRequest::Ca(_, _) => KeyUsage::Ca, 504 CertRequest::Ee(_, _) => KeyUsage::Ee, 505 }; 506 507 let overclaim = Overclaim::Refuse; 508 509 let mut cert = TbsCert::new(serial, issuer, validity, subject, pub_key, key_usage, overclaim); 510 511 let asns = resources.to_as_resources(); 512 if asns.is_inherited() || !asns.to_blocks().unwrap().is_empty() { 513 cert.set_as_resources(asns); 514 } 515 516 let ipv4 = resources.to_ip_resources_v4(); 517 if ipv4.is_inherited() || !ipv4.to_blocks().unwrap().is_empty() { 518 cert.set_v4_resources(ipv4); 519 } 520 521 let ipv6 = resources.to_ip_resources_v6(); 522 if ipv6.is_inherited() || !ipv6.to_blocks().unwrap().is_empty() { 523 cert.set_v6_resources(ipv6); 524 } 525 526 cert.set_authority_key_identifier(Some(signing_cert.cert().subject_key_identifier())); 527 cert.set_ca_issuer(Some(signing_cert.uri().clone())); 528 cert.set_crl_uri(Some(signing_cert.crl_uri())); 529 530 match request { 531 CertRequest::Ca(csr, _) => { 532 let (ca_repository, rpki_manifest, rpki_notify, _pub_key) = csr.unpack(); 533 cert.set_basic_ca(Some(true)); 534 cert.set_ca_repository(Some(ca_repository)); 535 cert.set_rpki_manifest(Some(rpki_manifest)); 536 cert.set_rpki_notify(rpki_notify); 537 } 538 CertRequest::Ee(_, _) => { 539 // cert.set_signed_object() ?? 540 } 541 } 542 543 Ok(cert) 544 } 545 546 /// Returns a validity period from 5 minutes ago (in case of NTP mess-up), to 547 /// X weeks from now. sign_validity_weeks(weeks: i64) -> Validity548 pub fn sign_validity_weeks(weeks: i64) -> Validity { 549 let from = Time::five_minutes_ago(); 550 let until = Time::now() + chrono::Duration::weeks(weeks); 551 Validity::new(from, until) 552 } 553 sign_validity_days(days: i64) -> Validity554 pub fn sign_validity_days(days: i64) -> Validity { 555 let from = Time::five_minutes_ago(); 556 let until = Time::now() + chrono::Duration::days(days); 557 Validity::new(from, until) 558 } 559 } 560 561 #[allow(clippy::large_enum_variant)] 562 enum CertRequest { 563 Ca(CsrInfo, Validity), 564 Ee(PublicKey, Validity), 565 } 566 567 trait ManifestEntry { mft_bytes(&self) -> Bytes568 fn mft_bytes(&self) -> Bytes; mft_hash(&self) -> Bytes569 fn mft_hash(&self) -> Bytes { 570 let digest = DigestAlgorithm::default().digest(self.mft_bytes().as_ref()); 571 Bytes::copy_from_slice(digest.as_ref()) 572 } mft_entry(&self, name: &str) -> FileAndHash<Bytes, Bytes>573 fn mft_entry(&self, name: &str) -> FileAndHash<Bytes, Bytes> { 574 FileAndHash::new(Bytes::copy_from_slice(name.as_bytes()), self.mft_hash()) 575 } 576 } 577 578 impl ManifestEntry for Crl { mft_bytes(&self) -> Bytes579 fn mft_bytes(&self) -> Bytes { 580 self.to_captured().into_bytes() 581 } 582 } 583