From f8e41e305f9a37b049b1636b5d379e1fa54a5ca7 Mon Sep 17 00:00:00 2001 From: Tim Bruijnzeels Date: Tue, 9 Jun 2020 17:01:56 +0200 Subject: [PATCH] Prevent the creation of ROAs that are redundant / make other ROAs redundant. (#198) --- src/commons/api/roas.rs | 36 ++-- src/commons/error.rs | 194 +++++++++--------- src/daemon/ca/certauth.rs | 6 +- src/daemon/ca/routes.rs | 4 + .../{v0_6_0 => }/errors/api-json.json | 0 .../errors/api-unknown-method.json | 0 .../errors/api-unknown-resource.json | 0 .../errors/ca-child-duplicate.json | 0 .../errors/ca-child-resources-extra.json | 0 .../errors/ca-child-resources-required.json | 0 .../errors/ca-child-unauthorized.json | 0 .../{v0_6_0 => }/errors/ca-child-unknown.json | 0 .../{v0_6_0 => }/errors/ca-duplicate.json | 0 .../errors/ca-parent-duplicate.json | 0 .../{v0_6_0 => }/errors/ca-parent-issue.json | 0 .../ca-parent-response-invalid-xml.json | 0 .../errors/ca-parent-response-wrong-xml.json | 0 .../errors/ca-parent-unknown.json | 0 .../{v0_6_0 => }/errors/ca-repo-issue.json | 0 .../errors/ca-repo-response-invalid-xml.json | 0 .../errors/ca-repo-response-wrong-xml.json | 0 .../{v0_6_0 => }/errors/ca-repo-same.json | 0 .../regressions/errors/ca-roa-duplicate.json | 1 + .../regressions/errors/ca-roa-includes.json | 1 + .../errors/ca-roa-invalid-max-length.json | 1 + .../errors/ca-roa-not-entitled.json | 1 + .../regressions/errors/ca-roa-redundant.json | 1 + .../regressions/errors/ca-roa-unknown.json | 1 + .../{v0_6_0 => }/errors/ca-unknown.json | 0 .../{v0_6_0 => }/errors/general-error.json | 0 .../{v0_6_0 => }/errors/key-no-cert.json | 0 .../{v0_6_0 => }/errors/key-no-current.json | 0 .../{v0_6_0 => }/errors/key-no-match.json | 0 .../{v0_6_0 => }/errors/key-no-new.json | 0 .../{v0_6_0 => }/errors/key-no-old.json | 0 .../{v0_6_0 => }/errors/key-re-use.json | 0 .../{v0_6_0 => }/errors/pub-duplicate.json | 0 .../errors/pub-no-embedded-repo.json | 0 .../{v0_6_0 => }/errors/pub-outside-jail.json | 0 .../{v0_6_0 => }/errors/pub-unknown.json | 0 .../{v0_6_0 => }/errors/pub-uri-no-slash.json | 0 .../errors/rc-missing-resources.json | 0 .../{v0_6_0 => }/errors/rc-resources.json | 0 .../{v0_6_0 => }/errors/rc-unknown.json | 0 .../{v0_6_0 => }/errors/repo-not-set.json | 0 .../errors/rfc6492-invalid-csr.json | 0 .../errors/rfc6492-invalid-signature.json | 0 .../{v0_6_0 => }/errors/rfc6492-protocol.json | 0 .../{v0_6_0 => }/errors/rfc8181-decode.json | 0 .../{v0_6_0 => }/errors/rfc8181-delta.json | 0 .../errors/rfc8181-protocol-message.json | 0 .../errors/rfc8181-validation.json | 0 .../{v0_6_0 => }/errors/sys-http-client.json | 0 .../{v0_6_0 => }/errors/sys-https.json | 0 .../{v0_6_0 => }/errors/sys-io.json | 0 .../{v0_6_0 => }/errors/sys-signer.json | 0 .../{v0_6_0 => }/errors/sys-store.json | 0 .../{v0_6_0 => }/errors/ta-initialised.json | 0 .../{v0_6_0 => }/errors/ta-name-reserved.json | 0 .../{v0_6_0 => }/errors/ta-not-allowed.json | 0 .../v0_6_0/errors/ca-roa-duplicate.json | 1 - .../errors/ca-roa-invalid-max-length.json | 1 - .../v0_6_0/errors/ca-roa-not-entitled.json | 1 - .../v0_6_0/errors/ca-roa-unknown.json | 1 - tests/ca_roas.rs | 24 ++- 65 files changed, 159 insertions(+), 115 deletions(-) rename test-resources/api/regressions/{v0_6_0 => }/errors/api-json.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/api-unknown-method.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/api-unknown-resource.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-child-duplicate.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-child-resources-extra.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-child-resources-required.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-child-unauthorized.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-child-unknown.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-duplicate.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-parent-duplicate.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-parent-issue.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-parent-response-invalid-xml.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-parent-response-wrong-xml.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-parent-unknown.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-repo-issue.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-repo-response-invalid-xml.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-repo-response-wrong-xml.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-repo-same.json (100%) create mode 100644 test-resources/api/regressions/errors/ca-roa-duplicate.json create mode 100644 test-resources/api/regressions/errors/ca-roa-includes.json create mode 100644 test-resources/api/regressions/errors/ca-roa-invalid-max-length.json create mode 100644 test-resources/api/regressions/errors/ca-roa-not-entitled.json create mode 100644 test-resources/api/regressions/errors/ca-roa-redundant.json create mode 100644 test-resources/api/regressions/errors/ca-roa-unknown.json rename test-resources/api/regressions/{v0_6_0 => }/errors/ca-unknown.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/general-error.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/key-no-cert.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/key-no-current.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/key-no-match.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/key-no-new.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/key-no-old.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/key-re-use.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/pub-duplicate.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/pub-no-embedded-repo.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/pub-outside-jail.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/pub-unknown.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/pub-uri-no-slash.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rc-missing-resources.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rc-resources.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rc-unknown.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/repo-not-set.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc6492-invalid-csr.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc6492-invalid-signature.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc6492-protocol.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc8181-decode.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc8181-delta.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc8181-protocol-message.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/rfc8181-validation.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/sys-http-client.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/sys-https.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/sys-io.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/sys-signer.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/sys-store.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ta-initialised.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ta-name-reserved.json (100%) rename test-resources/api/regressions/{v0_6_0 => }/errors/ta-not-allowed.json (100%) delete mode 100644 test-resources/api/regressions/v0_6_0/errors/ca-roa-duplicate.json delete mode 100644 test-resources/api/regressions/v0_6_0/errors/ca-roa-invalid-max-length.json delete mode 100644 test-resources/api/regressions/v0_6_0/errors/ca-roa-not-entitled.json delete mode 100644 test-resources/api/regressions/v0_6_0/errors/ca-roa-unknown.json diff --git a/src/commons/api/roas.rs b/src/commons/api/roas.rs index abd4fd5f..a262eb5f 100644 --- a/src/commons/api/roas.rs +++ b/src/commons/api/roas.rs @@ -33,6 +33,14 @@ impl RoaDefinition { } } + pub fn explicit_max_length(self) -> Self { + RoaDefinition { + asn: self.asn, + prefix: self.prefix, + max_length: Some(self.effective_max_length()), + } + } + pub fn asn(&self) -> AsNumber { self.asn } @@ -63,12 +71,11 @@ impl RoaDefinition { } } - /// Returns `true` if the this definition covers the other or vice versa. Only one of - /// the two should be included. - pub fn conflicts(&self, other: &RoaDefinition) -> bool { + /// Returns `true` if the this definition includes the other definition. + pub fn includes(&self, other: &RoaDefinition) -> bool { self.asn == other.asn - && (self.prefix.matching_or_less_specific(&other.prefix) - || other.prefix.matching_or_less_specific(&self.prefix)) + && self.prefix.matching_or_less_specific(&other.prefix) + && self.effective_max_length() >= other.effective_max_length() } } @@ -640,18 +647,21 @@ mod tests { } #[test] - fn roa_conflicts() { - let covering = definition("192.168.0.0/16 => 64496"); + fn roa_includes() { + let covering = definition("192.168.0.0/16-20 => 64496"); + + let included_no_ml = definition("192.168.0.0/16 => 64496"); + let included_more_specific = definition("192.168.0.0/20 => 64496"); - let explicit_max_l = definition("192.168.0.0/16-16 => 64496"); let allowing_more_specific = definition("192.168.0.0/16-24 => 64496"); let more_specific = definition("192.168.3.0/24 => 64496"); - let other_asn = definition("192.168.3.0/24 => 64497"); - assert!(covering.conflicts(&explicit_max_l)); - assert!(covering.conflicts(&more_specific)); - assert!(covering.conflicts(&allowing_more_specific)); - assert!(!covering.conflicts(&other_asn)); + assert!(covering.includes(&included_no_ml)); + assert!(covering.includes(&included_more_specific)); + + assert!(!covering.includes(&more_specific)); + assert!(!covering.includes(&allowing_more_specific)); + assert!(!covering.includes(&other_asn)); } } diff --git a/src/commons/error.rs b/src/commons/error.rs index 7d38e79d..0945f05b 100644 --- a/src/commons/error.rs +++ b/src/commons/error.rs @@ -189,16 +189,25 @@ pub enum Error { CaChildUpdateOneThing(Handle, ChildHandle), // RouteAuthorizations - ROAs - #[display(fmt = "Cannot remove unknown ROA '{}' from CA '{}'", _0, _1)] + #[display(fmt = "Cannot remove unknown ROA '{}'", _1)] CaAuthorizationUnknown(Handle, RouteAuthorization), - #[display(fmt = "Duplicate ROA '{}' for CA '{}'", _1, _0)] + #[display(fmt = "ROA '{}' already present", _1)] CaAuthorizationDuplicate(Handle, RouteAuthorization), - #[display(fmt = "Invalid max length in ROA: '{}' for CA '{}", _1, _0)] + #[display(fmt = "ROA '{}' was not added because it is redundant", _1)] + CaAuthorizationRedundant(Handle, RouteAuthorization), + + #[display( + fmt = "ROA '{}' was not added because it would make existing ROAs redundant", + _1 + )] + CaAuthorizationIncludes(Handle, RouteAuthorization), + + #[display(fmt = "Invalid max length in ROA: '{}'", _1)] CaAuthorizationInvalidMaxlength(Handle, RouteAuthorization), - #[display(fmt = "Prefix in ROA '{}' not held by CA '{}'.", _1, _0)] + #[display(fmt = "Prefix in ROA '{}' not held by you", _1)] CaAuthorizationNotEntitled(Handle, RouteAuthorization), //----------------------------------------------------------------- @@ -519,6 +528,18 @@ impl Error { .with_auth(auth) } + Error::CaAuthorizationRedundant(ca, auth) => { + ErrorResponse::new("ca-roa-redundant", &self) + .with_ca(ca) + .with_auth(auth) + } + + Error::CaAuthorizationIncludes(ca, auth) => { + ErrorResponse::new("ca-roa-includes", &self) + .with_ca(ca) + .with_auth(auth) + } + Error::CaAuthorizationInvalidMaxlength(ca, auth) => { ErrorResponse::new("ca-roa-invalid-max-length", &self) .with_ca(ca) @@ -611,7 +632,7 @@ mod tests { fn verify(expected_json: &str, e: Error) { let actual = e.to_error_response(); let expected: ErrorResponse = serde_json::from_str(expected_json).unwrap(); - assert_eq!(expected, actual); + assert_eq!(actual, expected); // check that serde works too let serialized = serde_json::to_string(&actual).unwrap(); @@ -625,24 +646,24 @@ mod tests { let io_err = io::Error::new(io::ErrorKind::Other, "can't read file"); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/sys-io.json"), + include_str!("../../test-resources/api/regressions/errors/sys-io.json"), Error::IoError(io_err), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/sys-store.json"), + include_str!("../../test-resources/api/regressions/errors/sys-store.json"), Error::AggregateStoreError(AggregateStoreError::InitError), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/sys-signer.json"), + include_str!("../../test-resources/api/regressions/errors/sys-signer.json"), Error::SignerError("signer issue".to_string()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/sys-https.json"), + include_str!("../../test-resources/api/regressions/errors/sys-https.json"), Error::HttpsSetup("can't find pem file".to_string()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/sys-http-client.json"), + include_str!("../../test-resources/api/regressions/errors/sys-http-client.json"), Error::HttpClientError(httpclient::Error::Forbidden), ); @@ -654,19 +675,15 @@ mod tests { .err() .unwrap(); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/api-json.json"), + include_str!("../../test-resources/api/regressions/errors/api-json.json"), Error::JsonError(json_err), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/api-unknown-method.json" - ), + include_str!("../../test-resources/api/regressions/errors/api-unknown-method.json"), Error::ApiUnknownMethod, ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/api-unknown-resource.json" - ), + include_str!("../../test-resources/api/regressions/errors/api-unknown-resource.json"), Error::ApiUnknownResource, ); @@ -674,7 +691,7 @@ mod tests { // Repository Issues //----------------------------------------------------------------- verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/repo-not-set.json"), + include_str!("../../test-resources/api/regressions/errors/repo-not-set.json"), Error::RepoNotSet, ); @@ -682,32 +699,26 @@ mod tests { // Publisher Issues //----------------------------------------------------------------- verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/pub-unknown.json"), + include_str!("../../test-resources/api/regressions/errors/pub-unknown.json"), Error::PublisherUnknown(publisher.clone()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/pub-duplicate.json"), + include_str!("../../test-resources/api/regressions/errors/pub-duplicate.json"), Error::PublisherDuplicate(publisher), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/pub-outside-jail.json" - ), + include_str!("../../test-resources/api/regressions/errors/pub-outside-jail.json"), Error::PublisherUriOutsideBase( "rsync://somehost/module/folder".to_string(), "rsync://otherhost/module/folder".to_string(), ), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/pub-uri-no-slash.json" - ), + include_str!("../../test-resources/api/regressions/errors/pub-uri-no-slash.json"), Error::PublisherBaseUriNoSlash("rsync://host/module/folder".to_string()), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/pub-no-embedded-repo.json" - ), + include_str!("../../test-resources/api/regressions/errors/pub-no-embedded-repo.json"), Error::PublisherNoEmbeddedRepo, ); @@ -715,23 +726,21 @@ mod tests { // RFC 8181 //----------------------------------------------------------------- verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/rfc8181-validation.json" - ), + include_str!("../../test-resources/api/regressions/errors/rfc8181-validation.json"), Error::Rfc8181Validation(ValidationError), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/rfc8181-decode.json"), + include_str!("../../test-resources/api/regressions/errors/rfc8181-decode.json"), Error::Rfc8181Decode("could not parse CMS".to_string()), ); verify( include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/rfc8181-protocol-message.json" + "../../test-resources/api/regressions/errors/rfc8181-protocol-message.json" ), Error::Rfc8181MessageError(rfc8181::MessageError::InvalidVersion), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/rfc8181-delta.json"), + include_str!("../../test-resources/api/regressions/errors/rfc8181-delta.json"), Error::Rfc8181Delta(PublicationDeltaError::ObjectAlreadyPresent( uri::Rsync::from_str("rsync://host/module/file.cer").unwrap(), )), @@ -741,187 +750,184 @@ mod tests { // CA Issues (label: ca-*) //----------------------------------------------------------------- verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-duplicate.json"), + include_str!("../../test-resources/api/regressions/errors/ca-duplicate.json"), Error::CaDuplicate(ca.clone()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-unknown.json"), + include_str!("../../test-resources/api/regressions/errors/ca-unknown.json"), Error::CaUnknown(ca.clone()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-repo-same.json"), + include_str!("../../test-resources/api/regressions/errors/ca-repo-same.json"), Error::CaRepoInUse(ca.clone()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-repo-issue.json"), + include_str!("../../test-resources/api/regressions/errors/ca-repo-issue.json"), Error::CaRepoIssue(ca.clone(), "cannot connect".to_string()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-repo-response-invalid-xml.json"), + include_str!( + "../../test-resources/api/regressions/errors/ca-repo-response-invalid-xml.json" + ), Error::CaRepoResponseInvalidXml(ca.clone(), "expected some tag".to_string()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-repo-response-wrong-xml.json"), + include_str!( + "../../test-resources/api/regressions/errors/ca-repo-response-wrong-xml.json" + ), Error::CaRepoResponseWrongXml(ca.clone()), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-parent-duplicate.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-parent-duplicate.json"), Error::CaParentDuplicate(ca.clone(), parent.clone()), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-parent-unknown.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-parent-unknown.json"), Error::CaParentUnknown(ca.clone(), parent.clone()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-parent-issue.json"), + include_str!("../../test-resources/api/regressions/errors/ca-parent-issue.json"), Error::CaParentIssue(ca.clone(), parent, "connection refused".to_string()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-parent-response-invalid-xml.json"), + include_str!( + "../../test-resources/api/regressions/errors/ca-parent-response-invalid-xml.json" + ), Error::CaParentResponseInvalidXml(ca.clone(), "expected something".to_string()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-parent-response-wrong-xml.json"), + include_str!( + "../../test-resources/api/regressions/errors/ca-parent-response-wrong-xml.json" + ), Error::CaParentResponseWrongXml(ca.clone()), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/rfc6492-protocol.json" - ), + include_str!("../../test-resources/api/regressions/errors/rfc6492-protocol.json"), Error::Rfc6492(rfc6492::Error::InvalidVersion), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/rfc6492-invalid-csr.json" - ), + include_str!("../../test-resources/api/regressions/errors/rfc6492-invalid-csr.json"), Error::Rfc6492InvalidCsrSent("invalid signature".to_string()), ); verify( include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/rfc6492-invalid-signature.json" + "../../test-resources/api/regressions/errors/rfc6492-invalid-signature.json" ), Error::Rfc6492SignatureInvalid, ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-child-duplicate.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-child-duplicate.json"), Error::CaChildDuplicate(ca.clone(), child.clone()), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-child-unknown.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-child-unknown.json"), Error::CaChildUnknown(ca.clone(), child.clone()), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-child-resources-required.json"), + include_str!( + "../../test-resources/api/regressions/errors/ca-child-resources-required.json" + ), Error::CaChildMustHaveResources(ca.clone(), child.clone()), ); verify( include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-child-resources-extra.json" + "../../test-resources/api/regressions/errors/ca-child-resources-extra.json" ), Error::CaChildExtraResources(ca.clone(), child.clone()), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-child-unauthorized.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-child-unauthorized.json"), Error::CaChildUnauthorized(ca.clone(), child), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ca-roa-unknown.json"), + include_str!("../../test-resources/api/regressions/errors/ca-roa-unknown.json"), Error::CaAuthorizationUnknown(ca.clone(), auth), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-roa-duplicate.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-roa-duplicate.json"), Error::CaAuthorizationDuplicate(ca.clone(), auth), ); + verify( + include_str!("../../test-resources/api/regressions/errors/ca-roa-redundant.json"), + Error::CaAuthorizationRedundant(ca.clone(), auth), + ); + verify( + include_str!("../../test-resources/api/regressions/errors/ca-roa-includes.json"), + Error::CaAuthorizationIncludes(ca.clone(), auth), + ); + verify( include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-roa-invalid-max-length.json" + "../../test-resources/api/regressions/errors/ca-roa-invalid-max-length.json" ), Error::CaAuthorizationInvalidMaxlength(ca.clone(), auth), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ca-roa-not-entitled.json" - ), + include_str!("../../test-resources/api/regressions/errors/ca-roa-not-entitled.json"), Error::CaAuthorizationNotEntitled(ca, auth), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/key-re-use.json"), + include_str!("../../test-resources/api/regressions/errors/key-re-use.json"), Error::KeyUseAttemptReuse, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/key-no-new.json"), + include_str!("../../test-resources/api/regressions/errors/key-no-new.json"), Error::KeyUseNoNewKey, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/key-no-current.json"), + include_str!("../../test-resources/api/regressions/errors/key-no-current.json"), Error::KeyUseNoCurrentKey, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/key-no-old.json"), + include_str!("../../test-resources/api/regressions/errors/key-no-old.json"), Error::KeyUseNoOldKey, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/key-no-cert.json"), + include_str!("../../test-resources/api/regressions/errors/key-no-cert.json"), Error::KeyUseNoIssuedCert, ); let ki = test_id_certificate() .subject_public_key_info() .key_identifier(); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/key-no-match.json"), + include_str!("../../test-resources/api/regressions/errors/key-no-match.json"), Error::KeyUseNoMatch(ki), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/rc-unknown.json"), + include_str!("../../test-resources/api/regressions/errors/rc-unknown.json"), Error::ResourceClassUnknown(ResourceClassName::from("RC0")), ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/rc-resources.json"), + include_str!("../../test-resources/api/regressions/errors/rc-resources.json"), Error::ResourceSetError(ResourceSetError::Mix), ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/rc-missing-resources.json" - ), + include_str!("../../test-resources/api/regressions/errors/rc-missing-resources.json"), Error::MissingResources, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ta-not-allowed.json"), + include_str!("../../test-resources/api/regressions/errors/ta-not-allowed.json"), Error::TaNotAllowed, ); verify( - include_str!( - "../../test-resources/api/regressions/v0_6_0/errors/ta-name-reserved.json" - ), + include_str!("../../test-resources/api/regressions/errors/ta-name-reserved.json"), Error::TaNameReserved, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/ta-initialised.json"), + include_str!("../../test-resources/api/regressions/errors/ta-initialised.json"), Error::TaAlreadyInitialised, ); verify( - include_str!("../../test-resources/api/regressions/v0_6_0/errors/general-error.json"), + include_str!("../../test-resources/api/regressions/errors/general-error.json"), Error::custom("some unlikely corner case"), ); @@ -929,7 +935,7 @@ mod tests { // for e in errs { // let error_response = e.to_error_response(); // - // let path = format!("test-resources/api/regressions/v0_6_0/errors/{}.json", error_response.label()); + // let path = format!("test-resources/api/regressions/errors/{}.json", error_response.label()); // let path = PathBuf::from(&path); // // file::save_json(&error_response, &path).unwrap(); diff --git a/src/daemon/ca/certauth.rs b/src/daemon/ca/certauth.rs index 6398dea5..ed095df5 100644 --- a/src/daemon/ca/certauth.rs +++ b/src/daemon/ca/certauth.rs @@ -1511,8 +1511,12 @@ impl CertAuth { return Err(Error::CaAuthorizationDuplicate(self.handle.clone(), auth)); } else if !all_resources.contains(&auth.prefix().into()) { return Err(Error::CaAuthorizationNotEntitled(self.handle.clone(), auth)); + } else if current_auths.iter().any(|a| a.includes(auth.as_ref())) { + return Err(Error::CaAuthorizationRedundant(self.handle.clone(), auth)); + } else if current_auths.iter().any(|a| auth.includes(a.as_ref())) { + return Err(Error::CaAuthorizationIncludes(self.handle.clone(), auth)); } else { - current_auths.insert(auth); + current_auths.insert(auth.explicit_length()); res.push(StoredEvent::new( self.handle(), version, diff --git a/src/daemon/ca/routes.rs b/src/daemon/ca/routes.rs index 8abf77a9..dbe0660b 100644 --- a/src/daemon/ca/routes.rs +++ b/src/daemon/ca/routes.rs @@ -29,6 +29,10 @@ impl RouteAuthorization { pub fn new(definition: RoaDefinition) -> Self { RouteAuthorization(definition) } + + pub fn explicit_length(self) -> Self { + RouteAuthorization(self.0.explicit_max_length()) + } } impl AsRef for RouteAuthorization { diff --git a/test-resources/api/regressions/v0_6_0/errors/api-json.json b/test-resources/api/regressions/errors/api-json.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/api-json.json rename to test-resources/api/regressions/errors/api-json.json diff --git a/test-resources/api/regressions/v0_6_0/errors/api-unknown-method.json b/test-resources/api/regressions/errors/api-unknown-method.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/api-unknown-method.json rename to test-resources/api/regressions/errors/api-unknown-method.json diff --git a/test-resources/api/regressions/v0_6_0/errors/api-unknown-resource.json b/test-resources/api/regressions/errors/api-unknown-resource.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/api-unknown-resource.json rename to test-resources/api/regressions/errors/api-unknown-resource.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-child-duplicate.json b/test-resources/api/regressions/errors/ca-child-duplicate.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-child-duplicate.json rename to test-resources/api/regressions/errors/ca-child-duplicate.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-child-resources-extra.json b/test-resources/api/regressions/errors/ca-child-resources-extra.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-child-resources-extra.json rename to test-resources/api/regressions/errors/ca-child-resources-extra.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-child-resources-required.json b/test-resources/api/regressions/errors/ca-child-resources-required.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-child-resources-required.json rename to test-resources/api/regressions/errors/ca-child-resources-required.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-child-unauthorized.json b/test-resources/api/regressions/errors/ca-child-unauthorized.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-child-unauthorized.json rename to test-resources/api/regressions/errors/ca-child-unauthorized.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-child-unknown.json b/test-resources/api/regressions/errors/ca-child-unknown.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-child-unknown.json rename to test-resources/api/regressions/errors/ca-child-unknown.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-duplicate.json b/test-resources/api/regressions/errors/ca-duplicate.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-duplicate.json rename to test-resources/api/regressions/errors/ca-duplicate.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-parent-duplicate.json b/test-resources/api/regressions/errors/ca-parent-duplicate.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-parent-duplicate.json rename to test-resources/api/regressions/errors/ca-parent-duplicate.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-parent-issue.json b/test-resources/api/regressions/errors/ca-parent-issue.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-parent-issue.json rename to test-resources/api/regressions/errors/ca-parent-issue.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-parent-response-invalid-xml.json b/test-resources/api/regressions/errors/ca-parent-response-invalid-xml.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-parent-response-invalid-xml.json rename to test-resources/api/regressions/errors/ca-parent-response-invalid-xml.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-parent-response-wrong-xml.json b/test-resources/api/regressions/errors/ca-parent-response-wrong-xml.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-parent-response-wrong-xml.json rename to test-resources/api/regressions/errors/ca-parent-response-wrong-xml.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-parent-unknown.json b/test-resources/api/regressions/errors/ca-parent-unknown.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-parent-unknown.json rename to test-resources/api/regressions/errors/ca-parent-unknown.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-repo-issue.json b/test-resources/api/regressions/errors/ca-repo-issue.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-repo-issue.json rename to test-resources/api/regressions/errors/ca-repo-issue.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-repo-response-invalid-xml.json b/test-resources/api/regressions/errors/ca-repo-response-invalid-xml.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-repo-response-invalid-xml.json rename to test-resources/api/regressions/errors/ca-repo-response-invalid-xml.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-repo-response-wrong-xml.json b/test-resources/api/regressions/errors/ca-repo-response-wrong-xml.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-repo-response-wrong-xml.json rename to test-resources/api/regressions/errors/ca-repo-response-wrong-xml.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-repo-same.json b/test-resources/api/regressions/errors/ca-repo-same.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-repo-same.json rename to test-resources/api/regressions/errors/ca-repo-same.json diff --git a/test-resources/api/regressions/errors/ca-roa-duplicate.json b/test-resources/api/regressions/errors/ca-roa-duplicate.json new file mode 100644 index 00000000..17a10752 --- /dev/null +++ b/test-resources/api/regressions/errors/ca-roa-duplicate.json @@ -0,0 +1 @@ +{"label":"ca-roa-duplicate","msg":"ROA '192.168.0.0/16-24 => 64496' already present", "args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/api/regressions/errors/ca-roa-includes.json b/test-resources/api/regressions/errors/ca-roa-includes.json new file mode 100644 index 00000000..c6b32735 --- /dev/null +++ b/test-resources/api/regressions/errors/ca-roa-includes.json @@ -0,0 +1 @@ +{"label":"ca-roa-includes","msg":"ROA '192.168.0.0/16-24 => 64496' was not added because it would make existing ROAs redundant", "args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/api/regressions/errors/ca-roa-invalid-max-length.json b/test-resources/api/regressions/errors/ca-roa-invalid-max-length.json new file mode 100644 index 00000000..e4da7f02 --- /dev/null +++ b/test-resources/api/regressions/errors/ca-roa-invalid-max-length.json @@ -0,0 +1 @@ +{"label":"ca-roa-invalid-max-length","msg":"Invalid max length in ROA: '192.168.0.0/16-24 => 64496'","args":{"ca":"ca","prefix":"192.168.0.0/16","max_length":"24","asn":"64496"}} \ No newline at end of file diff --git a/test-resources/api/regressions/errors/ca-roa-not-entitled.json b/test-resources/api/regressions/errors/ca-roa-not-entitled.json new file mode 100644 index 00000000..90842cf4 --- /dev/null +++ b/test-resources/api/regressions/errors/ca-roa-not-entitled.json @@ -0,0 +1 @@ +{"label":"ca-roa-not-entitled","msg":"Prefix in ROA '192.168.0.0/16-24 => 64496' not held by you", "args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/api/regressions/errors/ca-roa-redundant.json b/test-resources/api/regressions/errors/ca-roa-redundant.json new file mode 100644 index 00000000..a87f60e6 --- /dev/null +++ b/test-resources/api/regressions/errors/ca-roa-redundant.json @@ -0,0 +1 @@ +{"label":"ca-roa-redundant","msg":"ROA '192.168.0.0/16-24 => 64496' was not added because it is redundant", "args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/api/regressions/errors/ca-roa-unknown.json b/test-resources/api/regressions/errors/ca-roa-unknown.json new file mode 100644 index 00000000..fd4bc9f4 --- /dev/null +++ b/test-resources/api/regressions/errors/ca-roa-unknown.json @@ -0,0 +1 @@ +{"label":"ca-roa-unknown","msg":"Cannot remove unknown ROA '192.168.0.0/16-24 => 64496'","args":{"ca":"ca","max_length":"24","asn":"64496","prefix":"192.168.0.0/16"}} \ No newline at end of file diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-unknown.json b/test-resources/api/regressions/errors/ca-unknown.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ca-unknown.json rename to test-resources/api/regressions/errors/ca-unknown.json diff --git a/test-resources/api/regressions/v0_6_0/errors/general-error.json b/test-resources/api/regressions/errors/general-error.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/general-error.json rename to test-resources/api/regressions/errors/general-error.json diff --git a/test-resources/api/regressions/v0_6_0/errors/key-no-cert.json b/test-resources/api/regressions/errors/key-no-cert.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/key-no-cert.json rename to test-resources/api/regressions/errors/key-no-cert.json diff --git a/test-resources/api/regressions/v0_6_0/errors/key-no-current.json b/test-resources/api/regressions/errors/key-no-current.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/key-no-current.json rename to test-resources/api/regressions/errors/key-no-current.json diff --git a/test-resources/api/regressions/v0_6_0/errors/key-no-match.json b/test-resources/api/regressions/errors/key-no-match.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/key-no-match.json rename to test-resources/api/regressions/errors/key-no-match.json diff --git a/test-resources/api/regressions/v0_6_0/errors/key-no-new.json b/test-resources/api/regressions/errors/key-no-new.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/key-no-new.json rename to test-resources/api/regressions/errors/key-no-new.json diff --git a/test-resources/api/regressions/v0_6_0/errors/key-no-old.json b/test-resources/api/regressions/errors/key-no-old.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/key-no-old.json rename to test-resources/api/regressions/errors/key-no-old.json diff --git a/test-resources/api/regressions/v0_6_0/errors/key-re-use.json b/test-resources/api/regressions/errors/key-re-use.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/key-re-use.json rename to test-resources/api/regressions/errors/key-re-use.json diff --git a/test-resources/api/regressions/v0_6_0/errors/pub-duplicate.json b/test-resources/api/regressions/errors/pub-duplicate.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/pub-duplicate.json rename to test-resources/api/regressions/errors/pub-duplicate.json diff --git a/test-resources/api/regressions/v0_6_0/errors/pub-no-embedded-repo.json b/test-resources/api/regressions/errors/pub-no-embedded-repo.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/pub-no-embedded-repo.json rename to test-resources/api/regressions/errors/pub-no-embedded-repo.json diff --git a/test-resources/api/regressions/v0_6_0/errors/pub-outside-jail.json b/test-resources/api/regressions/errors/pub-outside-jail.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/pub-outside-jail.json rename to test-resources/api/regressions/errors/pub-outside-jail.json diff --git a/test-resources/api/regressions/v0_6_0/errors/pub-unknown.json b/test-resources/api/regressions/errors/pub-unknown.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/pub-unknown.json rename to test-resources/api/regressions/errors/pub-unknown.json diff --git a/test-resources/api/regressions/v0_6_0/errors/pub-uri-no-slash.json b/test-resources/api/regressions/errors/pub-uri-no-slash.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/pub-uri-no-slash.json rename to test-resources/api/regressions/errors/pub-uri-no-slash.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rc-missing-resources.json b/test-resources/api/regressions/errors/rc-missing-resources.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rc-missing-resources.json rename to test-resources/api/regressions/errors/rc-missing-resources.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rc-resources.json b/test-resources/api/regressions/errors/rc-resources.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rc-resources.json rename to test-resources/api/regressions/errors/rc-resources.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rc-unknown.json b/test-resources/api/regressions/errors/rc-unknown.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rc-unknown.json rename to test-resources/api/regressions/errors/rc-unknown.json diff --git a/test-resources/api/regressions/v0_6_0/errors/repo-not-set.json b/test-resources/api/regressions/errors/repo-not-set.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/repo-not-set.json rename to test-resources/api/regressions/errors/repo-not-set.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc6492-invalid-csr.json b/test-resources/api/regressions/errors/rfc6492-invalid-csr.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc6492-invalid-csr.json rename to test-resources/api/regressions/errors/rfc6492-invalid-csr.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc6492-invalid-signature.json b/test-resources/api/regressions/errors/rfc6492-invalid-signature.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc6492-invalid-signature.json rename to test-resources/api/regressions/errors/rfc6492-invalid-signature.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc6492-protocol.json b/test-resources/api/regressions/errors/rfc6492-protocol.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc6492-protocol.json rename to test-resources/api/regressions/errors/rfc6492-protocol.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc8181-decode.json b/test-resources/api/regressions/errors/rfc8181-decode.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc8181-decode.json rename to test-resources/api/regressions/errors/rfc8181-decode.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc8181-delta.json b/test-resources/api/regressions/errors/rfc8181-delta.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc8181-delta.json rename to test-resources/api/regressions/errors/rfc8181-delta.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc8181-protocol-message.json b/test-resources/api/regressions/errors/rfc8181-protocol-message.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc8181-protocol-message.json rename to test-resources/api/regressions/errors/rfc8181-protocol-message.json diff --git a/test-resources/api/regressions/v0_6_0/errors/rfc8181-validation.json b/test-resources/api/regressions/errors/rfc8181-validation.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/rfc8181-validation.json rename to test-resources/api/regressions/errors/rfc8181-validation.json diff --git a/test-resources/api/regressions/v0_6_0/errors/sys-http-client.json b/test-resources/api/regressions/errors/sys-http-client.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/sys-http-client.json rename to test-resources/api/regressions/errors/sys-http-client.json diff --git a/test-resources/api/regressions/v0_6_0/errors/sys-https.json b/test-resources/api/regressions/errors/sys-https.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/sys-https.json rename to test-resources/api/regressions/errors/sys-https.json diff --git a/test-resources/api/regressions/v0_6_0/errors/sys-io.json b/test-resources/api/regressions/errors/sys-io.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/sys-io.json rename to test-resources/api/regressions/errors/sys-io.json diff --git a/test-resources/api/regressions/v0_6_0/errors/sys-signer.json b/test-resources/api/regressions/errors/sys-signer.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/sys-signer.json rename to test-resources/api/regressions/errors/sys-signer.json diff --git a/test-resources/api/regressions/v0_6_0/errors/sys-store.json b/test-resources/api/regressions/errors/sys-store.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/sys-store.json rename to test-resources/api/regressions/errors/sys-store.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ta-initialised.json b/test-resources/api/regressions/errors/ta-initialised.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ta-initialised.json rename to test-resources/api/regressions/errors/ta-initialised.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ta-name-reserved.json b/test-resources/api/regressions/errors/ta-name-reserved.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ta-name-reserved.json rename to test-resources/api/regressions/errors/ta-name-reserved.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ta-not-allowed.json b/test-resources/api/regressions/errors/ta-not-allowed.json similarity index 100% rename from test-resources/api/regressions/v0_6_0/errors/ta-not-allowed.json rename to test-resources/api/regressions/errors/ta-not-allowed.json diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-roa-duplicate.json b/test-resources/api/regressions/v0_6_0/errors/ca-roa-duplicate.json deleted file mode 100644 index 0fc371c0..00000000 --- a/test-resources/api/regressions/v0_6_0/errors/ca-roa-duplicate.json +++ /dev/null @@ -1 +0,0 @@ -{"label":"ca-roa-duplicate","msg":"Duplicate ROA '192.168.0.0/16-24 => 64496' for CA 'ca'","args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-roa-invalid-max-length.json b/test-resources/api/regressions/v0_6_0/errors/ca-roa-invalid-max-length.json deleted file mode 100644 index f1806ecc..00000000 --- a/test-resources/api/regressions/v0_6_0/errors/ca-roa-invalid-max-length.json +++ /dev/null @@ -1 +0,0 @@ -{"label":"ca-roa-invalid-max-length","msg":"Invalid max length in ROA: '192.168.0.0/16-24 => 64496' for CA 'ca","args":{"ca":"ca","prefix":"192.168.0.0/16","max_length":"24","asn":"64496"}} \ No newline at end of file diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-roa-not-entitled.json b/test-resources/api/regressions/v0_6_0/errors/ca-roa-not-entitled.json deleted file mode 100644 index 4b1a2aef..00000000 --- a/test-resources/api/regressions/v0_6_0/errors/ca-roa-not-entitled.json +++ /dev/null @@ -1 +0,0 @@ -{"label":"ca-roa-not-entitled","msg":"Prefix in ROA '192.168.0.0/16-24 => 64496' not held by CA 'ca'.","args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/api/regressions/v0_6_0/errors/ca-roa-unknown.json b/test-resources/api/regressions/v0_6_0/errors/ca-roa-unknown.json deleted file mode 100644 index 3b13402b..00000000 --- a/test-resources/api/regressions/v0_6_0/errors/ca-roa-unknown.json +++ /dev/null @@ -1 +0,0 @@ -{"label":"ca-roa-unknown","msg":"Cannot remove unknown ROA 'ca' from CA '192.168.0.0/16-24 => 64496'","args":{"ca":"ca","max_length":"24","asn":"64496","prefix":"192.168.0.0/16"}} \ No newline at end of file diff --git a/tests/ca_roas.rs b/tests/ca_roas.rs index e04a0edf..17cb042f 100644 --- a/tests/ca_roas.rs +++ b/tests/ca_roas.rs @@ -33,9 +33,9 @@ async fn ca_roas() { } // Add some Route Authorizations - let route_1 = RoaDefinition::from_str("10.0.0.0/24 => 64496").unwrap(); + let route_1 = RoaDefinition::from_str("10.0.0.0/16-24 => 64496").unwrap(); let route_2 = RoaDefinition::from_str("2001:DB8::/32-48 => 64496").unwrap(); - let route_3 = RoaDefinition::from_str("192.168.0.0/24 => 64496").unwrap(); + let route_3 = RoaDefinition::from_str("192.168.0.0/20-24 => 64496").unwrap(); let crl_file = ".crl"; let mft_file = ".mft"; @@ -87,10 +87,28 @@ async fn ca_roas() { rc_state_becomes_active(&child).await; will_publish_objects(&child, &[crl_file, mft_file, route3_file]).await; - let route_invalid_length = RoaDefinition::from_str("10.0.0.0/24-33 => 64496").unwrap(); + // Do not allow adding a ROA with invalid length + let route_invalid_length = RoaDefinition::from_str("192.168.0.0/24-33 => 64496").unwrap(); let mut updates = RoaDefinitionUpdates::empty(); updates.add(route_invalid_length); ca_route_authorizations_update_expect_error(&child, updates).await; + // Do not allow adding a ROA that is duplicate + let mut updates = RoaDefinitionUpdates::empty(); + updates.add(route_3); + ca_route_authorizations_update_expect_error(&child, updates).await; + + // Do not allow adding a ROA that is made redundant by an existing ROA + let route_redundant = RoaDefinition::from_str("192.168.0.0/24 => 64496").unwrap(); + let mut updates = RoaDefinitionUpdates::empty(); + updates.add(route_redundant); + ca_route_authorizations_update_expect_error(&child, updates).await; + + // Do not allow adding a ROA that would make an existing ROA redundant + let route_including = RoaDefinition::from_str("192.168.0.0/16-24 => 64496").unwrap(); + let mut updates = RoaDefinitionUpdates::empty(); + updates.add(route_including); + ca_route_authorizations_update_expect_error(&child, updates).await; + let _ = fs::remove_dir_all(dir); }