1 //! Defines all Krill server side errors
2 
3 use std::{fmt, fmt::Display, io};
4 
5 use hyper::StatusCode;
6 
7 use rpki::{
8     repository::{crypto::KeyIdentifier, x509::ValidationError},
9     uri,
10 };
11 
12 use crate::{
13     commons::{
14         api::{
15             rrdp::PublicationDeltaError, AspaCustomer, AspaProvidersUpdateConflict, ChildHandle, ErrorResponse, Handle,
16             ParentHandle, PublisherHandle, ResourceClassName, ResourceSetError, RoaDefinition,
17         },
18         eventsourcing::{AggregateStoreError, KeyValueError},
19         remote::{
20             rfc6492::{self, NotPerformedResponse},
21             rfc8181::{self, ReportErrorCode},
22         },
23         util::{httpclient, softsigner::SignerError},
24     },
25     daemon::{ca::RouteAuthorization, http::tls_keys},
26     upgrades::UpgradeError,
27 };
28 
29 //------------ RoaDeltaError -----------------------------------------------
30 
31 /// This type contains a detailed error report for a ROA delta
32 /// that could not be applied.
33 #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
34 pub struct RoaDeltaError {
35     duplicates: Vec<RoaDefinition>,
36     notheld: Vec<RoaDefinition>,
37     unknowns: Vec<RoaDefinition>,
38     invalid_length: Vec<RoaDefinition>,
39 }
40 
41 impl Default for RoaDeltaError {
default() -> Self42     fn default() -> Self {
43         RoaDeltaError {
44             duplicates: vec![],
45             notheld: vec![],
46             unknowns: vec![],
47             invalid_length: vec![],
48         }
49     }
50 }
51 
52 impl RoaDeltaError {
add_duplicate(&mut self, addition: RoaDefinition)53     pub fn add_duplicate(&mut self, addition: RoaDefinition) {
54         self.duplicates.push(addition);
55     }
56 
add_notheld(&mut self, addition: RoaDefinition)57     pub fn add_notheld(&mut self, addition: RoaDefinition) {
58         self.notheld.push(addition);
59     }
60 
add_unknown(&mut self, removal: RoaDefinition)61     pub fn add_unknown(&mut self, removal: RoaDefinition) {
62         self.unknowns.push(removal);
63     }
64 
add_invalid_length(&mut self, invalid: RoaDefinition)65     pub fn add_invalid_length(&mut self, invalid: RoaDefinition) {
66         self.invalid_length.push(invalid);
67     }
68 
combine(&mut self, mut other: Self)69     pub fn combine(&mut self, mut other: Self) {
70         self.duplicates.append(&mut other.duplicates);
71         self.notheld.append(&mut other.notheld);
72         self.unknowns.append(&mut other.unknowns);
73         self.invalid_length.append(&mut other.invalid_length);
74     }
75 
is_empty(&self) -> bool76     pub fn is_empty(&self) -> bool {
77         self.duplicates.is_empty()
78             && self.notheld.is_empty()
79             && self.unknowns.is_empty()
80             && self.invalid_length.is_empty()
81     }
82 }
83 
84 impl fmt::Display for RoaDeltaError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result85     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86         if !self.duplicates.is_empty() {
87             writeln!(f, "Cannot add the following duplicate ROAs:")?;
88             for dup in self.duplicates.iter() {
89                 writeln!(f, "  {}", dup)?;
90             }
91         }
92         if !self.notheld.is_empty() {
93             writeln!(
94                 f,
95                 "Cannot add the following ROAs with prefixes not on any of your certificates:"
96             )?;
97             for not in self.notheld.iter() {
98                 writeln!(f, "  {}", not)?;
99             }
100         }
101         if !self.unknowns.is_empty() {
102             writeln!(f, "Cannot remove the following unknown ROAs:")?;
103             for unk in self.unknowns.iter() {
104                 writeln!(f, "  {}", unk)?;
105             }
106         }
107         if !self.invalid_length.is_empty() {
108             writeln!(
109                 f,
110                 "The following ROAs have a max length which is invalid for the prefix:"
111             )?;
112             for unk in self.invalid_length.iter() {
113                 writeln!(f, "  {}", unk)?;
114             }
115         }
116         Ok(())
117     }
118 }
119 
120 //------------ ApiAuthError ------------------------------------------------
121 
122 // ApiAuthError is *also* implemented as a separate enum,
123 // so that we don't have to implement the Clone trait for
124 // all of the Error enum.
125 // Also it makes kind of sense to keep these errors separate
126 // container, since they all originate in interactions
127 // with the Auth provider (or lack thereof).
128 #[derive(Debug, Clone)]
129 pub enum ApiAuthError {
130     ApiInvalidCredentials(String),
131     ApiLoginError(String),
132     ApiAuthPermanentError(String),
133     ApiAuthTransientError(String),
134     ApiAuthSessionExpired(String),
135     ApiInsufficientRights(String),
136 }
137 
138 impl Display for ApiAuthError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result139     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140         match self {
141             ApiAuthError::ApiInvalidCredentials(err)
142             | ApiAuthError::ApiLoginError(err)
143             | ApiAuthError::ApiAuthPermanentError(err)
144             | ApiAuthError::ApiAuthTransientError(err)
145             | ApiAuthError::ApiAuthSessionExpired(err)
146             | ApiAuthError::ApiInsufficientRights(err) => write!(f, "{}", &err),
147         }
148     }
149 }
150 
151 impl From<Error> for ApiAuthError {
from(e: Error) -> Self152     fn from(e: Error) -> Self {
153         match e {
154             Error::ApiAuthPermanentError(e) => ApiAuthError::ApiAuthPermanentError(e),
155             Error::ApiLoginError(e) => ApiAuthError::ApiLoginError(e),
156             Error::ApiInsufficientRights(e) => ApiAuthError::ApiInsufficientRights(e),
157             Error::ApiAuthTransientError(e) => ApiAuthError::ApiAuthTransientError(e),
158             Error::ApiAuthSessionExpired(e) => ApiAuthError::ApiAuthSessionExpired(e),
159             Error::ApiInvalidCredentials(e) => ApiAuthError::ApiInvalidCredentials(e),
160             _ => ApiAuthError::ApiAuthPermanentError(e.to_string()),
161         }
162     }
163 }
164 
165 //------------ Error -------------------------------------------------------
166 
167 #[derive(Debug)]
168 #[allow(clippy::large_enum_variant)]
169 pub enum Error {
170     //-----------------------------------------------------------------
171     // System Issues
172     //-----------------------------------------------------------------
173     IoError(KrillIoError),
174     KeyValueError(KeyValueError),
175     AggregateStoreError(AggregateStoreError),
176     SignerError(String),
177     HttpsSetup(String),
178     HttpClientError(httpclient::Error),
179     ConfigError(String),
180     UpgradeError(UpgradeError),
181 
182     //-----------------------------------------------------------------
183     // General API Client Issues
184     //-----------------------------------------------------------------
185     JsonError(serde_json::Error),
186     NonAsciiCharsInput,
187     InvalidUtf8Input,
188     ApiUnknownMethod,
189     ApiUnknownResource,
190     ApiInvalidHandle,
191     ApiInvalidSeconds,
192     PostTooBig,
193     PostCannotRead,
194     ApiInvalidCredentials(String),
195     ApiLoginError(String),
196     ApiAuthPermanentError(String),
197     ApiAuthTransientError(String),
198     ApiAuthSessionExpired(String),
199     ApiInsufficientRights(String),
200 
201     //-----------------------------------------------------------------
202     // Repository Issues
203     //-----------------------------------------------------------------
204     RepoNotSet,
205 
206     //-----------------------------------------------------------------
207     // Publisher Issues
208     //-----------------------------------------------------------------
209     PublisherUnknown(PublisherHandle),
210     PublisherUriOutsideBase(String, String),
211     PublisherBaseUriNoSlash(String),
212     PublisherDuplicate(PublisherHandle),
213 
214     //-----------------------------------------------------------------
215     // Repository Server Issues
216     //-----------------------------------------------------------------
217     RepositoryServerNotInitialized,
218     RepositoryServerHasPublishers,
219     RepositoryServerAlreadyInitialized,
220 
221     //-----------------------------------------------------------------
222     // Publishing
223     //-----------------------------------------------------------------
224     Rfc8181Validation(ValidationError),
225     Rfc8181Decode(String),
226     Rfc8181MessageError(rfc8181::MessageError),
227     Rfc8181Delta(PublicationDeltaError),
228     PublishingObjects(String),
229 
230     //-----------------------------------------------------------------
231     // CA Issues
232     //-----------------------------------------------------------------
233     CaDuplicate(Handle),
234     CaUnknown(Handle),
235 
236     // CA Repo Issues
237     CaRepoInUse(Handle),
238     CaRepoIssue(Handle, String),
239     CaRepoResponseInvalidXml(Handle, String),
240     CaRepoResponseWrongXml(Handle),
241 
242     // CA Parent Issues
243     CaParentDuplicateName(Handle, ParentHandle),
244     CaParentDuplicateInfo(Handle, ParentHandle),
245     CaParentUnknown(Handle, ParentHandle),
246     CaParentIssue(Handle, ParentHandle, String),
247     CaParentResponseInvalidXml(Handle, String),
248     CaParentResponseWrongXml(Handle),
249     CaParentAddNotResponsive(Handle, ParentHandle),
250     CaParentSyncError(Handle, ParentHandle, ResourceClassName, String),
251 
252     //-----------------------------------------------------------------
253     // RFC6492 (requesting resources)
254     //-----------------------------------------------------------------
255     Rfc6492(rfc6492::Error),
256     Rfc6492NotPerformed(NotPerformedResponse),
257     Rfc6492InvalidCsrSent(String),
258     Rfc6492SignatureInvalid,
259 
260     //-----------------------------------------------------------------
261     // CA Child Issues
262     //-----------------------------------------------------------------
263     CaChildDuplicate(Handle, ChildHandle),
264     CaChildUnknown(Handle, ChildHandle),
265     CaChildMustHaveResources(Handle, ChildHandle),
266     CaChildExtraResources(Handle, ChildHandle),
267     CaChildUnauthorized(Handle, ChildHandle),
268 
269     //-----------------------------------------------------------------
270     // RouteAuthorizations - ROAs
271     //-----------------------------------------------------------------
272     CaAuthorizationUnknown(Handle, RouteAuthorization),
273     CaAuthorizationDuplicate(Handle, RouteAuthorization),
274     CaAuthorizationInvalidMaxLength(Handle, RouteAuthorization),
275     CaAuthorizationNotEntitled(Handle, RouteAuthorization),
276     RoaDeltaError(Handle, RoaDeltaError),
277 
278     //-----------------------------------------------------------------
279     // Autonomous System Provider Authorization - ASPA
280     //-----------------------------------------------------------------
281     AspaCustomerAsNotEntitled(Handle, AspaCustomer),
282     AspaCustomerAlreadyPresent(Handle, AspaCustomer),
283     AspaCustomerUnknown(Handle, AspaCustomer),
284     AspaProvidersUpdateEmpty(Handle, AspaCustomer),
285     AspaProvidersUpdateConflict(Handle, AspaProvidersUpdateConflict),
286 
287     //-----------------------------------------------------------------
288     // Key Usage Issues
289     //-----------------------------------------------------------------
290     KeyUseAttemptReuse,
291     KeyUseNoNewKey,
292     KeyUseNoCurrentKey,
293     KeyUseNoOldKey,
294     KeyUseNoIssuedCert,
295     KeyUseNoMatch(KeyIdentifier),
296     KeyRollNotAllowed,
297 
298     //-----------------------------------------------------------------
299     // Resource Issues
300     //-----------------------------------------------------------------
301     ResourceClassUnknown(ResourceClassName),
302     ResourceSetError(ResourceSetError),
303     MissingResources,
304 
305     //-----------------------------------------------------------------
306     // Embedded (test) TA issues
307     //-----------------------------------------------------------------
308     TaNotAllowed,
309     TaNameReserved,
310     TaAlreadyInitialized,
311 
312     //-----------------------------------------------------------------
313     // Resource Tagged Attestation issues
314     //-----------------------------------------------------------------
315     RtaResourcesNotHeld,
316 
317     //-----------------------------------------------------------------
318     // If we really don't know any more..
319     //-----------------------------------------------------------------
320     Custom(String),
321     Multiple(Vec<Error>),
322 }
323 
324 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result325     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
326         match self {
327             //-----------------------------------------------------------------
328             // System Issues
329             //-----------------------------------------------------------------
330             Error::IoError(e) => write!(f, "I/O error: {}", e),
331             Error::KeyValueError(e) => write!(f, "Key/Value error: {}", e),
332             Error::AggregateStoreError(e) => write!(f, "Persistence error: {}", e),
333             Error::SignerError(e) => write!(f, "Signing issue: {}", e),
334             Error::HttpsSetup(e) => write!(f, "Cannot set up HTTPS: {}", e),
335             Error::HttpClientError(e) => write!(f, "HTTP client error: {}", e),
336             Error::ConfigError(e) => write!(f, "Configuration error: {}", e),
337             Error::UpgradeError(e) => write!(f, "Could not upgrade Krill: {}", e),
338 
339             //-----------------------------------------------------------------
340             // General API Client Issues
341             //-----------------------------------------------------------------
342             Error::JsonError(e) => write!(f,"Invalid JSON: {}", e),
343             Error::NonAsciiCharsInput => write!(f, "Input contains non-ASCII chars (maybe whitespace?)"),
344             Error::InvalidUtf8Input => write!(f, "Submitted bytes are invalid UTF8"),
345             Error::ApiUnknownMethod => write!(f,"Unknown API method"),
346             Error::ApiUnknownResource => write!(f, "Unknown resource"),
347             Error::ApiInvalidHandle => write!(f, "Invalid path argument for handle"),
348             Error::ApiInvalidSeconds => write!(f, "Invalid path argument for seconds"),
349             Error::PostTooBig => write!(f, "POST body exceeds configured limit"),
350             Error::PostCannotRead => write!(f, "POST body cannot be read"),
351             Error::ApiInvalidCredentials(e) => write!(f, "Invalid credentials: {}", e),
352             Error::ApiLoginError(e) => write!(f, "Login error: {}", e),
353             Error::ApiAuthPermanentError(e) => write!(f, "Authentication error: {}", e),
354             Error::ApiAuthTransientError(e) => write!(f, "Transient authentication error: {}", e),
355             Error::ApiAuthSessionExpired(e) => write!(f, "Session expired: {}", e),
356             Error::ApiInsufficientRights(e) => write!(f, "Insufficient rights: {}", e),
357 
358             //-----------------------------------------------------------------
359             // Repository Issues
360             //-----------------------------------------------------------------
361             Error::RepoNotSet => write!(f, "No repository configured for CA"),
362 
363 
364             //-----------------------------------------------------------------
365             // Publisher Issues
366             //-----------------------------------------------------------------
367             Error::PublisherUnknown(pbl) => write!(f, "Unknown publisher '{}'", pbl),
368             Error::PublisherUriOutsideBase(uri, jail) => write!(f, "Publishing uri '{}' outside repository uri '{}'", uri, jail),
369             Error::PublisherBaseUriNoSlash(uri) => write!(f, "Publisher uri '{}' must have a trailing slash", uri),
370             Error::PublisherDuplicate(pbl) => write!(f, "Duplicate publisher '{}'", pbl),
371 
372             //-----------------------------------------------------------------
373             // Repository Server Issues
374             //-----------------------------------------------------------------
375             Error::RepositoryServerNotInitialized => write!(f, "Publication Server not initialized, see 'krillc pubserver server init --help'"),
376             Error::RepositoryServerHasPublishers => write!(f, "Publication Server cannot be removed, still has publishers"),
377             Error::RepositoryServerAlreadyInitialized => write!(f, "Publication Server already initialized"),
378 
379             //-----------------------------------------------------------------
380             // RFC 8181 (publishing)
381             //-----------------------------------------------------------------
382             Error::Rfc8181Validation(req) => write!(f, "Issue with RFC8181 request: {}", req),
383             Error::Rfc8181Decode(req) => write!(f, "Issue with decoding RFC8181 request: {}", req),
384             Error::Rfc8181MessageError(e) => e.fmt(f),
385             Error::Rfc8181Delta(e) => e.fmt(f),
386             Error::PublishingObjects(msg) => write!(f, "Issue generating repository objects: '{}'", msg),
387 
388 
389             //-----------------------------------------------------------------
390             // CA Issues
391             //-----------------------------------------------------------------
392             Error::CaDuplicate(ca) => write!(f, "CA '{}' was already initialized", ca),
393             Error::CaUnknown(ca) => write!(f, "CA '{}' is unknown", ca),
394 
395             // CA Repo Issues
396             Error::CaRepoInUse(ca) => write!(f, "CA '{}' already uses this repository", ca),
397             Error::CaRepoIssue(ca, e) => write!(f, "CA '{}' cannot get response from repository '{}'. Is the 'service_uri' in the XML reachable? Note that when upgrading Krill you should re-use existing configuration and data. For a fresh \
398             re-install of Krill you will need to send XML to all other parties again: parent(s), children, and repository", ca,        e),
399             Error::CaRepoResponseInvalidXml(ca, e) => write!(f, "CA '{}' got invalid repository response xml: {}", ca, e),
400             Error::CaRepoResponseWrongXml(ca) => write!(f, "CA '{}' got parent instead of repository response", ca),
401 
402             // CA Parent Issues
403             Error::CaParentDuplicateName(ca, parent) => write!(f, "CA '{}' already has a parent named '{}'", ca, parent),
404             Error::CaParentDuplicateInfo(ca, parent) => write!(f, "CA '{}' already has a parent named '{}' for this XML", ca, parent),
405             Error::CaParentUnknown(ca, parent) => write!(f, "CA '{}' does not have a parent named '{}'", ca, parent),
406             Error::CaParentIssue(ca, parent, e) => write!(f, "CA '{}' got error from parent '{}': {}", ca, parent, e),
407             Error::CaParentResponseInvalidXml(ca, e) => write!(f, "CA '{}' got invalid parent response xml: {}", ca, e),
408             Error::CaParentResponseWrongXml(ca) => write!(f, "CA '{}' got repository response when adding parent", ca),
409             Error::CaParentAddNotResponsive(ca, parent) => write!(f, "CA '{}' cannot get response from parent '{}'. Is the 'service_uri' in the XML reachable? Note that when upgrading Krill you should re-use existing configuration and data. For a fresh re-install of Krill you will need to send XML to all other parties again: parent(s), children, and repository",        ca, parent),
410             Error::CaParentSyncError(ca, parent, rcn, error_msg) => {
411                 write!(
412                     f,
413                     "CA '{}' could not sync with parent '{}', for resource class '{}', error: {}",
414                     ca,
415                     parent,
416                     rcn,
417                     error_msg
418                 )
419             }
420 
421 
422             //-----------------------------------------------------------------
423             // RFC6492 (requesting resources)
424             //-----------------------------------------------------------------
425             Error::Rfc6492(e) => write!(f, "RFC 6492 Issue: {}", e),
426             Error::Rfc6492NotPerformed(not) => write!(f, "RFC 6492 Not Performed: {}", not),
427             Error::Rfc6492InvalidCsrSent(e) => write!(f, "Invalid CSR received: {}", e),
428             Error::Rfc6492SignatureInvalid => write!(f, "Invalidly signed RFC 6492 CMS"),
429 
430             //-----------------------------------------------------------------
431             // CA Child Issues
432             //-----------------------------------------------------------------
433             Error::CaChildDuplicate(ca, child) => write!(f, "CA '{}' already has a child named '{}'", ca, child),
434             Error::CaChildUnknown(ca, child) => write!(f, "CA '{}' does not have a child named '{}'", ca, child),
435             Error::CaChildMustHaveResources(ca, child) => write!(f, "Child '{}' for CA '{}' MUST have resources specified", child, ca),
436             Error::CaChildExtraResources(ca, child) => write!(f, "Child '{}' cannot have resources not held by CA '{}'", child, ca),
437             Error::CaChildUnauthorized(ca, child) => write!(f, "CA '{}' does not know id certificate for child '{}'", ca, child),
438 
439             //-----------------------------------------------------------------
440             // RouteAuthorizations - ROAs
441             //-----------------------------------------------------------------
442             Error::CaAuthorizationUnknown(_ca, roa) => write!(f, "Cannot remove unknown ROA '{}'", roa),
443             Error::CaAuthorizationDuplicate(_ca, roa) => write!(f, "ROA '{}' already present", roa),
444             Error::CaAuthorizationInvalidMaxLength(_ca, roa) => write!(f, "Invalid max length in ROA: '{}'", roa),
445             Error::CaAuthorizationNotEntitled(_ca, roa) => write!(f, "Prefix in ROA '{}' not held by you", roa),
446             Error::RoaDeltaError(_ca, e) => write!(f, "ROA delta rejected:\n\n'{}' ", e),
447 
448             //-----------------------------------------------------------------
449             // Autonomous System Provider Authorization - ASPAs
450             //-----------------------------------------------------------------
451             Error::AspaCustomerAsNotEntitled(_ca, asn) => write!(f, "Customer AS '{}' is not held by you", asn),
452             Error::AspaCustomerAlreadyPresent(_ca, asn) => write!(f, "ASPA already exists for customer AS '{}'", asn),
453             Error::AspaCustomerUnknown(_ca, asn) => write!(f, "No current ASPA exists for customer AS '{}'", asn),
454             Error::AspaProvidersUpdateEmpty(_ca, asn) => write!(f, "Received empty update for ASPA for customer AS '{}'", asn),
455             Error::AspaProvidersUpdateConflict(_ca, e) => write!(f, "ASPA delta rejected:\n\n'{}'", e),
456 
457             //-----------------------------------------------------------------
458             // Key Usage Issues
459             //-----------------------------------------------------------------
460             Error::KeyUseAttemptReuse => write!(f, "Attempt at re-using keys"),
461             Error::KeyUseNoNewKey => write!(f, "No new key in resource class"),
462             Error::KeyUseNoCurrentKey => write!(f, "No current key in resource class"),
463             Error::KeyUseNoOldKey => write!(f, "No old key in resource class"),
464             Error::KeyUseNoIssuedCert => write!(f, "No issued cert matching pub key"),
465             Error::KeyUseNoMatch(ki) => write!(f, "No key found matching key identifier: '{}'", ki),
466             Error::KeyRollNotAllowed => write!(f, "Key roll in progress"),
467 
468             //-----------------------------------------------------------------
469             // Resource Issues
470             //-----------------------------------------------------------------
471             Error::ResourceClassUnknown(rcn) => write!(f, "Unknown resource class: '{}'", rcn),
472             Error::ResourceSetError(e) => e.fmt(f),
473             Error::MissingResources => write!(f, "Requester is not entitled to all requested resources"),
474 
475 
476             //-----------------------------------------------------------------
477             // Embedded (test) TA issues
478             //-----------------------------------------------------------------
479             Error::TaNotAllowed => write!(f, "Functionality not supported for Trust Anchor"),
480             Error::TaNameReserved => write!(f, "Name reserved for embedded Trust Anchor"),
481             Error::TaAlreadyInitialized => write!(f, "TrustAnchor was already initialized"),
482 
483             //-----------------------------------------------------------------
484             // Resource Tagged Attestation issues
485             //-----------------------------------------------------------------
486             Error::RtaResourcesNotHeld => write!(f, "Your CA does not hold the requested resources"),
487 
488             //-----------------------------------------------------------------
489             // If we really don't know any more..
490             //-----------------------------------------------------------------
491             Error::Custom(s) => s.fmt(f),
492 
493             Error::Multiple(errors) => {
494                 let error_strings: Vec<String> = errors.iter().map(|e| e.to_string()).collect();
495                 write!(f, "Multiple errors: {}", error_strings.join(", "))
496             }
497         }
498     }
499 }
500 
501 impl From<KrillIoError> for Error {
from(e: KrillIoError) -> Self502     fn from(e: KrillIoError) -> Self {
503         Error::IoError(e)
504     }
505 }
506 
507 impl From<KeyValueError> for Error {
from(e: KeyValueError) -> Self508     fn from(e: KeyValueError) -> Self {
509         Error::KeyValueError(e)
510     }
511 }
512 
513 impl From<AggregateStoreError> for Error {
from(e: AggregateStoreError) -> Self514     fn from(e: AggregateStoreError) -> Self {
515         Error::AggregateStoreError(e)
516     }
517 }
518 
519 impl From<SignerError> for Error {
from(e: SignerError) -> Self520     fn from(e: SignerError) -> Self {
521         Error::SignerError(e.to_string())
522     }
523 }
524 
525 impl From<rfc6492::Error> for Error {
from(e: rfc6492::Error) -> Self526     fn from(e: rfc6492::Error) -> Self {
527         Error::Rfc6492(e)
528     }
529 }
530 
531 impl From<rfc8181::MessageError> for Error {
from(e: rfc8181::MessageError) -> Self532     fn from(e: rfc8181::MessageError) -> Self {
533         Error::Rfc8181MessageError(e)
534     }
535 }
536 
537 impl From<ResourceSetError> for Error {
from(e: ResourceSetError) -> Self538     fn from(e: ResourceSetError) -> Self {
539         Error::ResourceSetError(e)
540     }
541 }
542 
543 impl From<tls_keys::Error> for Error {
from(e: tls_keys::Error) -> Self544     fn from(e: tls_keys::Error) -> Self {
545         Error::HttpsSetup(e.to_string())
546     }
547 }
548 
549 impl From<crate::commons::crypto::Error> for Error {
from(e: crate::commons::crypto::Error) -> Self550     fn from(e: crate::commons::crypto::Error) -> Self {
551         Error::signer(e)
552     }
553 }
554 
555 impl From<ApiAuthError> for Error {
from(e: ApiAuthError) -> Self556     fn from(e: ApiAuthError) -> Self {
557         match e {
558             ApiAuthError::ApiAuthPermanentError(e) => Error::ApiAuthPermanentError(e),
559             ApiAuthError::ApiLoginError(e) => Error::ApiLoginError(e),
560             ApiAuthError::ApiInsufficientRights(e) => Error::ApiInsufficientRights(e),
561             ApiAuthError::ApiAuthTransientError(e) => Error::ApiAuthTransientError(e),
562             ApiAuthError::ApiAuthSessionExpired(e) => Error::ApiAuthSessionExpired(e),
563             ApiAuthError::ApiInvalidCredentials(e) => Error::ApiInvalidCredentials(e),
564         }
565     }
566 }
567 
568 impl From<PublicationDeltaError> for Error {
from(e: PublicationDeltaError) -> Self569     fn from(e: PublicationDeltaError) -> Self {
570         Error::Rfc8181Delta(e)
571     }
572 }
573 
574 impl From<UpgradeError> for Error {
from(e: UpgradeError) -> Self575     fn from(e: UpgradeError) -> Self {
576         Error::UpgradeError(e)
577     }
578 }
579 
580 impl Error {
signer(e: impl Display) -> Self581     pub fn signer(e: impl Display) -> Self {
582         Error::SignerError(e.to_string())
583     }
584 
invalid_csr(msg: &str) -> Self585     pub fn invalid_csr(msg: &str) -> Self {
586         Error::Rfc6492InvalidCsrSent(msg.to_string())
587     }
588 
publishing_outside_jail(uri: &uri::Rsync, jail: &uri::Rsync) -> Self589     pub fn publishing_outside_jail(uri: &uri::Rsync, jail: &uri::Rsync) -> Self {
590         Error::PublisherUriOutsideBase(uri.to_string(), jail.to_string())
591     }
592 
publishing(msg: impl fmt::Display) -> Self593     pub fn publishing(msg: impl fmt::Display) -> Self {
594         Error::PublishingObjects(msg.to_string())
595     }
596 
custom(msg: impl fmt::Display) -> Self597     pub fn custom(msg: impl fmt::Display) -> Self {
598         Error::Custom(msg.to_string())
599     }
600 
io_error_with_context(context: String, cause: io::Error) -> Self601     pub fn io_error_with_context(context: String, cause: io::Error) -> Self {
602         Error::IoError(KrillIoError::new(context, cause))
603     }
604 }
605 
606 impl std::error::Error for Error {}
607 
608 /// Translate an error to an HTTP Status Code
609 impl Error {
status(&self) -> StatusCode610     pub fn status(&self) -> StatusCode {
611         match self {
612             // Most is bad requests by users, so just mapping the things that are not
613             Error::IoError(_) | Error::SignerError(_) | Error::AggregateStoreError(_) | Error::PublishingObjects(_) => {
614                 StatusCode::INTERNAL_SERVER_ERROR
615             }
616             Error::PublisherUnknown(_)
617             | Error::CaUnknown(_)
618             | Error::CaChildUnknown(_, _)
619             | Error::CaParentUnknown(_, _)
620             | Error::ApiUnknownResource => StatusCode::NOT_FOUND,
621 
622             Error::ApiInvalidCredentials(_)
623             | Error::ApiAuthPermanentError(_)
624             | Error::ApiAuthTransientError(_)
625             | Error::ApiAuthSessionExpired(_)
626             | Error::ApiLoginError(_) => StatusCode::UNAUTHORIZED,
627             Error::ApiInsufficientRights(_) => StatusCode::FORBIDDEN,
628 
629             _ => StatusCode::BAD_REQUEST,
630         }
631     }
632 
to_error_response(&self) -> ErrorResponse633     pub fn to_error_response(&self) -> ErrorResponse {
634         match self {
635             //-----------------------------------------------------------------
636             // System Issues (label: sys-*)
637             //-----------------------------------------------------------------
638 
639             // internal server error
640             Error::IoError(e) => ErrorResponse::new("sys-io", &self).with_cause(e),
641 
642             // internal server error
643             Error::KeyValueError(e) => ErrorResponse::new("sys-kv", &self).with_cause(e),
644 
645             // internal server error
646             Error::AggregateStoreError(e) => ErrorResponse::new("sys-store", &self).with_cause(e),
647 
648             // internal server error
649             Error::SignerError(e) => ErrorResponse::new("sys-signer", &self).with_cause(e),
650 
651             // internal server error
652             Error::HttpsSetup(e) => ErrorResponse::new("sys-https", &self).with_cause(e),
653 
654             // internal server error
655             Error::HttpClientError(e) => ErrorResponse::new("sys-http-client", &self).with_cause(e),
656 
657             // internal configuration error
658             Error::ConfigError(e) => ErrorResponse::new("sys-config", &self).with_cause(e),
659 
660             // upgrade error
661             Error::UpgradeError(e) => ErrorResponse::new("sys-upgrade", &self).with_cause(e),
662 
663             //-----------------------------------------------------------------
664             // General API Client Issues (label: api-*)
665             //-----------------------------------------------------------------
666             Error::JsonError(e) => ErrorResponse::new("api-json", &self).with_cause(e),
667 
668             Error::NonAsciiCharsInput => ErrorResponse::new("api-non-ascii", &self),
669 
670             Error::InvalidUtf8Input => ErrorResponse::new("api-invalid-utf8", &self),
671 
672             Error::ApiUnknownMethod => ErrorResponse::new("api-unknown-method", &self),
673 
674             // NOT FOUND (generic API not found)
675             Error::ApiUnknownResource => ErrorResponse::new("api-unknown-resource", &self),
676 
677             Error::ApiInvalidHandle => ErrorResponse::new("api-invalid-path-handle", &self),
678 
679             Error::ApiInvalidSeconds => ErrorResponse::new("api-invalid-path-seconds", &self),
680 
681             Error::PostTooBig => ErrorResponse::new("api-post-body-exceeds-limit", &self),
682 
683             Error::PostCannotRead => ErrorResponse::new("api-post-body-cannot-read", &self),
684 
685             Error::ApiInvalidCredentials(e) => ErrorResponse::new("api-invalid-credentials", &self).with_cause(e),
686 
687             Error::ApiLoginError(e) => ErrorResponse::new("api-login-error", &self).with_cause(e),
688 
689             Error::ApiAuthPermanentError(e) => ErrorResponse::new("api-auth-permanent-error", &self).with_cause(e),
690 
691             Error::ApiAuthTransientError(e) => ErrorResponse::new("api-auth-transient-error", &self).with_cause(e),
692 
693             Error::ApiAuthSessionExpired(e) => ErrorResponse::new("api-auth-session-expired", &self).with_cause(e),
694 
695             Error::ApiInsufficientRights(e) => ErrorResponse::new("api-insufficient-rights", &self).with_cause(e),
696 
697             //-----------------------------------------------------------------
698             // Repository Issues (label: repo-*)
699             //-----------------------------------------------------------------
700 
701             // 2100
702             Error::RepoNotSet => ErrorResponse::new("repo-not-set", &self),
703 
704             //-----------------------------------------------------------------
705             // Publisher Issues (label: pub-*)
706             //-----------------------------------------------------------------
707             Error::PublisherUnknown(p) => ErrorResponse::new("pub-unknown", &self).with_publisher(p),
708 
709             Error::PublisherDuplicate(p) => ErrorResponse::new("pub-duplicate", &self).with_publisher(p),
710 
711             Error::PublisherUriOutsideBase(uri, base) => ErrorResponse::new("pub-outside-jail", &self)
712                 .with_uri(uri)
713                 .with_base_uri(base),
714 
715             Error::PublisherBaseUriNoSlash(uri) => ErrorResponse::new("pub-uri-no-slash", &self).with_uri(uri),
716 
717             //-----------------------------------------------------------------
718             // Repository Server Issues
719             //-----------------------------------------------------------------
720             Error::RepositoryServerNotInitialized => ErrorResponse::new("pub-repo-not-initialized", &self),
721             Error::RepositoryServerHasPublishers => ErrorResponse::new("pub-repo-has-publishers", &self),
722             Error::RepositoryServerAlreadyInitialized => ErrorResponse::new("pub-repo-initialized", &self),
723 
724             //-----------------------------------------------------------------
725             // Publishing
726             //-----------------------------------------------------------------
727             Error::Rfc8181Validation(e) => ErrorResponse::new("rfc8181-validation", &self).with_cause(e),
728             Error::Rfc8181Decode(e) => ErrorResponse::new("rfc8181-decode", &self).with_cause(e),
729             Error::Rfc8181MessageError(e) => ErrorResponse::new("rfc8181-protocol-message", &self).with_cause(e),
730             Error::Rfc8181Delta(e) => ErrorResponse::new("rfc8181-delta", &self).with_cause(e),
731             Error::PublishingObjects(msg) => {
732                 ErrorResponse::new("publishing-generate-repository-objects", &self).with_cause(msg)
733             }
734 
735             //-----------------------------------------------------------------
736             // CA Issues (label: ca-*)
737             //-----------------------------------------------------------------
738             Error::CaDuplicate(ca) => ErrorResponse::new("ca-duplicate", &self).with_ca(ca),
739 
740             Error::CaUnknown(ca) => ErrorResponse::new("ca-unknown", &self).with_ca(ca),
741 
742             Error::CaRepoInUse(ca) => ErrorResponse::new("ca-repo-same", &self).with_ca(ca),
743 
744             Error::CaRepoIssue(ca, err) => ErrorResponse::new("ca-repo-issue", &self).with_ca(ca).with_cause(err),
745 
746             Error::CaRepoResponseInvalidXml(ca, err) => ErrorResponse::new("ca-repo-response-invalid-xml", &self)
747                 .with_ca(ca)
748                 .with_cause(err),
749 
750             Error::CaRepoResponseWrongXml(ca) => ErrorResponse::new("ca-repo-response-wrong-xml", &self).with_ca(ca),
751 
752             Error::CaParentDuplicateName(ca, parent) => ErrorResponse::new("ca-parent-duplicate", &self)
753                 .with_ca(ca)
754                 .with_parent(parent),
755 
756             Error::CaParentDuplicateInfo(ca, parent) => ErrorResponse::new("ca-parent-xml-duplicate", &self)
757                 .with_ca(ca)
758                 .with_parent(parent),
759 
760             Error::CaParentUnknown(ca, parent) => ErrorResponse::new("ca-parent-unknown", &self)
761                 .with_ca(ca)
762                 .with_parent(parent),
763 
764             Error::CaParentIssue(ca, parent, err) => ErrorResponse::new("ca-parent-issue", &self)
765                 .with_ca(ca)
766                 .with_parent(parent)
767                 .with_cause(err),
768 
769             Error::CaParentResponseInvalidXml(ca, err) => ErrorResponse::new("ca-parent-response-invalid-xml", &self)
770                 .with_ca(ca)
771                 .with_cause(err),
772 
773             Error::CaParentResponseWrongXml(ca) => {
774                 ErrorResponse::new("ca-parent-response-wrong-xml", &self).with_ca(ca)
775             }
776 
777             Error::CaParentAddNotResponsive(ca, parent) => ErrorResponse::new("ca-parent-add-unresponsive", &self)
778                 .with_ca(ca)
779                 .with_parent(parent),
780 
781             Error::CaParentSyncError(ca, parent, rcn, _errors) => ErrorResponse::new("ca-parent-sync", &self)
782                 .with_ca(ca)
783                 .with_parent(parent)
784                 .with_resource_class(rcn),
785 
786             //-----------------------------------------------------------------
787             // RFC6492 (requesting resources, not on JSON api)
788             //-----------------------------------------------------------------
789             Error::Rfc6492(e) => ErrorResponse::new("rfc6492-protocol", &self).with_cause(e),
790             Error::Rfc6492NotPerformed(e) => ErrorResponse::new("rfc6492-not-performed-response", &self).with_cause(e),
791             Error::Rfc6492InvalidCsrSent(e) => ErrorResponse::new("rfc6492-invalid-csr", &self).with_cause(e),
792             Error::Rfc6492SignatureInvalid => ErrorResponse::new("rfc6492-invalid-signature", &self),
793 
794             // CA Child Issues
795             Error::CaChildDuplicate(ca, child) => ErrorResponse::new("ca-child-duplicate", &self)
796                 .with_ca(ca)
797                 .with_child(child),
798             Error::CaChildUnknown(ca, child) => ErrorResponse::new("ca-child-unknown", &self)
799                 .with_ca(ca)
800                 .with_child(child),
801             Error::CaChildMustHaveResources(ca, child) => ErrorResponse::new("ca-child-resources-required", &self)
802                 .with_ca(ca)
803                 .with_child(child),
804             Error::CaChildExtraResources(ca, child) => ErrorResponse::new("ca-child-resources-extra", &self)
805                 .with_ca(ca)
806                 .with_child(child),
807             Error::CaChildUnauthorized(ca, child) => ErrorResponse::new("ca-child-unauthorized", &self)
808                 .with_ca(ca)
809                 .with_child(child),
810 
811             // RouteAuthorizations
812             Error::CaAuthorizationUnknown(ca, auth) => {
813                 ErrorResponse::new("ca-roa-unknown", &self).with_ca(ca).with_auth(auth)
814             }
815             Error::CaAuthorizationDuplicate(ca, auth) => ErrorResponse::new("ca-roa-duplicate", &self)
816                 .with_ca(ca)
817                 .with_auth(auth),
818 
819             Error::CaAuthorizationInvalidMaxLength(ca, auth) => ErrorResponse::new("ca-roa-invalid-max-length", &self)
820                 .with_ca(ca)
821                 .with_auth(auth),
822 
823             Error::CaAuthorizationNotEntitled(ca, auth) => ErrorResponse::new("ca-roa-not-entitled", &self)
824                 .with_ca(ca)
825                 .with_auth(auth),
826 
827             Error::RoaDeltaError(ca, roa_delta_error) => ErrorResponse::new("ca-roa-delta-error", &self)
828                 .with_ca(ca)
829                 .with_roa_delta_error(roa_delta_error),
830 
831             //-----------------------------------------------------------------
832             // Autonomous System Provider Authorization - ASPA
833             //-----------------------------------------------------------------
834             Error::AspaCustomerAsNotEntitled(ca, asn) => ErrorResponse::new("ca-aspa-not-entitled", &self)
835                 .with_ca(ca)
836                 .with_asn(*asn),
837             Error::AspaCustomerAlreadyPresent(ca, asn) => ErrorResponse::new("ca-aspa-customer-as-duplicate", &self)
838                 .with_ca(ca)
839                 .with_asn(*asn),
840             Error::AspaCustomerUnknown(ca, asn) => ErrorResponse::new("ca-aspa-unknown-customer-as", &self)
841                 .with_ca(ca)
842                 .with_asn(*asn),
843             Error::AspaProvidersUpdateEmpty(ca, asn) => ErrorResponse::new("ca-aspa-delta-empty", &self)
844                 .with_ca(ca)
845                 .with_asn(*asn),
846             Error::AspaProvidersUpdateConflict(ca, conflict) => ErrorResponse::new("ca-aspa-delta-error", &self)
847                 .with_ca(ca)
848                 .with_aspa_providers_conflict(conflict),
849 
850             //-----------------------------------------------------------------
851             // Key Usage Issues (key-*)
852             //-----------------------------------------------------------------
853             Error::KeyUseAttemptReuse => ErrorResponse::new("key-re-use", &self),
854             Error::KeyUseNoNewKey => ErrorResponse::new("key-no-new", &self),
855             Error::KeyUseNoCurrentKey => ErrorResponse::new("key-no-current", &self),
856             Error::KeyUseNoOldKey => ErrorResponse::new("key-no-old", &self),
857             Error::KeyUseNoIssuedCert => ErrorResponse::new("key-no-cert", &self),
858             Error::KeyUseNoMatch(ki) => ErrorResponse::new("key-no-match", &self).with_key_identifier(ki),
859             Error::KeyRollNotAllowed => ErrorResponse::new("key-roll-disallowed", &self),
860 
861             //-----------------------------------------------------------------
862             // Resource Issues (label: rc-*)
863             //-----------------------------------------------------------------
864             Error::ResourceClassUnknown(name) => ErrorResponse::new("rc-unknown", &self).with_resource_class(name),
865             Error::ResourceSetError(e) => ErrorResponse::new("rc-resources", &self).with_cause(e),
866             Error::MissingResources => ErrorResponse::new("rc-missing-resources", &self),
867 
868             //-----------------------------------------------------------------
869             // Embedded (test) TA issues (label: ta-*)
870             //-----------------------------------------------------------------
871             Error::TaNotAllowed => ErrorResponse::new("ta-not-allowed", &self),
872             Error::TaNameReserved => ErrorResponse::new("ta-name-reserved", &self),
873             Error::TaAlreadyInitialized => ErrorResponse::new("ta-initialized", &self),
874 
875             //-----------------------------------------------------------------
876             // Resource Tagged Attestation issues
877             //-----------------------------------------------------------------
878             Error::RtaResourcesNotHeld => ErrorResponse::new("rta-resources-not-held", &self),
879 
880             //-----------------------------------------------------------------
881             // If we really don't know any more..
882             //-----------------------------------------------------------------
883             Error::Custom(_msg) => ErrorResponse::new("general-error", &self),
884             Error::Multiple(_errors) => ErrorResponse::new("multiple-errors", &self),
885         }
886     }
887 
to_rfc8181_error_code(&self) -> ReportErrorCode888     pub fn to_rfc8181_error_code(&self) -> ReportErrorCode {
889         match self {
890             Error::Rfc8181Validation(_) | Error::PublisherUnknown(_) => ReportErrorCode::PermissionFailure,
891             Error::Rfc8181MessageError(_) => ReportErrorCode::XmlError,
892             Error::Rfc8181Delta(e) => match e {
893                 PublicationDeltaError::UriOutsideJail(_, _) => ReportErrorCode::PermissionFailure,
894                 PublicationDeltaError::NoObjectForHashAndOrUri(_) => ReportErrorCode::NoObjectPresent,
895                 PublicationDeltaError::ObjectAlreadyPresent(_) => ReportErrorCode::ObjectAlreadyPresent,
896             },
897             _ => ReportErrorCode::OtherError,
898         }
899     }
900 }
901 
902 #[derive(Debug)]
903 pub struct KrillIoError {
904     context: String,
905     cause: io::Error,
906 }
907 
908 impl KrillIoError {
new(context: String, cause: io::Error) -> Self909     pub fn new(context: String, cause: io::Error) -> Self {
910         KrillIoError { context, cause }
911     }
912 }
913 
914 impl fmt::Display for KrillIoError {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result915     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
916         write!(f, "context: {}, underlying io::Error: {}", self.context, self.cause)
917     }
918 }
919 
920 //------------ Tests ---------------------------------------------------------
921 
922 #[cfg(test)]
923 mod tests {
924 
925     use std::str::FromStr;
926 
927     use crate::commons::api::RoaDefinition;
928 
929     use super::*;
930     use crate::test::definition;
931     use crate::test::test_id_certificate;
932 
verify(expected_json: &str, e: Error)933     fn verify(expected_json: &str, e: Error) {
934         let actual = e.to_error_response();
935         let expected: ErrorResponse = serde_json::from_str(expected_json).unwrap();
936         assert_eq!(actual, expected);
937 
938         // check that serde works too
939         let serialized = serde_json::to_string(&actual).unwrap();
940         let des = serde_json::from_str(&serialized).unwrap();
941         assert_eq!(actual, des);
942     }
943 
944     #[test]
error_response_json_regression()945     fn error_response_json_regression() {
946         let ca = Handle::from_str("ca").unwrap();
947         let parent = ParentHandle::from_str("parent").unwrap();
948         let child = ChildHandle::from_str("child").unwrap();
949         let publisher = PublisherHandle::from_str("publisher").unwrap();
950 
951         let auth = RouteAuthorization::new(RoaDefinition::from_str("192.168.0.0/16-24 => 64496").unwrap());
952 
953         //-----------------------------------------------------------------
954         // System Issues
955         //-----------------------------------------------------------------
956 
957         let krill_io_err = KrillIoError::new(
958             "Trouble reading 'foo'".to_string(),
959             io::Error::new(io::ErrorKind::Other, "can't read file"),
960         );
961 
962         verify(
963             include_str!("../../test-resources/errors/sys-io.json"),
964             Error::IoError(krill_io_err),
965         );
966 
967         verify(
968             include_str!("../../test-resources/errors/sys-store.json"),
969             Error::AggregateStoreError(AggregateStoreError::InitError(ca.clone())),
970         );
971         verify(
972             include_str!("../../test-resources/errors/sys-signer.json"),
973             Error::SignerError("signer issue".to_string()),
974         );
975         verify(
976             include_str!("../../test-resources/errors/sys-https.json"),
977             Error::HttpsSetup("can't find pem file".to_string()),
978         );
979         verify(
980             include_str!("../../test-resources/errors/sys-http-client.json"),
981             Error::HttpClientError(httpclient::Error::Forbidden),
982         );
983 
984         //-----------------------------------------------------------------
985         // General API Client Issues
986         //-----------------------------------------------------------------
987         let invalid_rsync_json = "\"https://host/module/folder\"";
988         let json_err = serde_json::from_str::<uri::Rsync>(invalid_rsync_json).err().unwrap();
989         verify(
990             include_str!("../../test-resources/errors/api-json.json"),
991             Error::JsonError(json_err),
992         );
993         verify(
994             include_str!("../../test-resources/errors/api-unknown-method.json"),
995             Error::ApiUnknownMethod,
996         );
997         verify(
998             include_str!("../../test-resources/errors/api-unknown-resource.json"),
999             Error::ApiUnknownResource,
1000         );
1001 
1002         //-----------------------------------------------------------------
1003         // Repository Issues
1004         //-----------------------------------------------------------------
1005         verify(
1006             include_str!("../../test-resources/errors/repo-not-set.json"),
1007             Error::RepoNotSet,
1008         );
1009 
1010         //-----------------------------------------------------------------
1011         // Publisher Issues
1012         //-----------------------------------------------------------------
1013         verify(
1014             include_str!("../../test-resources/errors/pub-unknown.json"),
1015             Error::PublisherUnknown(publisher.clone()),
1016         );
1017         verify(
1018             include_str!("../../test-resources/errors/pub-duplicate.json"),
1019             Error::PublisherDuplicate(publisher),
1020         );
1021         verify(
1022             include_str!("../../test-resources/errors/pub-outside-jail.json"),
1023             Error::PublisherUriOutsideBase(
1024                 "rsync://somehost/module/folder".to_string(),
1025                 "rsync://otherhost/module/folder".to_string(),
1026             ),
1027         );
1028         verify(
1029             include_str!("../../test-resources/errors/pub-uri-no-slash.json"),
1030             Error::PublisherBaseUriNoSlash("rsync://host/module/folder".to_string()),
1031         );
1032 
1033         //-----------------------------------------------------------------
1034         // RFC 8181
1035         //-----------------------------------------------------------------
1036         verify(
1037             include_str!("../../test-resources/errors/rfc8181-validation.json"),
1038             Error::Rfc8181Validation(ValidationError),
1039         );
1040         verify(
1041             include_str!("../../test-resources/errors/rfc8181-decode.json"),
1042             Error::Rfc8181Decode("could not parse CMS".to_string()),
1043         );
1044         verify(
1045             include_str!("../../test-resources/errors/rfc8181-protocol-message.json"),
1046             Error::Rfc8181MessageError(rfc8181::MessageError::InvalidVersion),
1047         );
1048         verify(
1049             include_str!("../../test-resources/errors/rfc8181-delta.json"),
1050             Error::Rfc8181Delta(PublicationDeltaError::ObjectAlreadyPresent(
1051                 uri::Rsync::from_str("rsync://host/module/file.cer").unwrap(),
1052             )),
1053         );
1054 
1055         //-----------------------------------------------------------------
1056         // CA Issues (label: ca-*)
1057         //-----------------------------------------------------------------
1058         verify(
1059             include_str!("../../test-resources/errors/ca-duplicate.json"),
1060             Error::CaDuplicate(ca.clone()),
1061         );
1062         verify(
1063             include_str!("../../test-resources/errors/ca-unknown.json"),
1064             Error::CaUnknown(ca.clone()),
1065         );
1066 
1067         verify(
1068             include_str!("../../test-resources/errors/ca-repo-same.json"),
1069             Error::CaRepoInUse(ca.clone()),
1070         );
1071         verify(
1072             include_str!("../../test-resources/errors/ca-repo-issue.json"),
1073             Error::CaRepoIssue(ca.clone(), "cannot connect".to_string()),
1074         );
1075         verify(
1076             include_str!("../../test-resources/errors/ca-repo-response-invalid-xml.json"),
1077             Error::CaRepoResponseInvalidXml(ca.clone(), "expected some tag".to_string()),
1078         );
1079         verify(
1080             include_str!("../../test-resources/errors/ca-repo-response-wrong-xml.json"),
1081             Error::CaRepoResponseWrongXml(ca.clone()),
1082         );
1083 
1084         verify(
1085             include_str!("../../test-resources/errors/ca-parent-duplicate.json"),
1086             Error::CaParentDuplicateName(ca.clone(), parent.clone()),
1087         );
1088         verify(
1089             include_str!("../../test-resources/errors/ca-parent-unknown.json"),
1090             Error::CaParentUnknown(ca.clone(), parent.clone()),
1091         );
1092         verify(
1093             include_str!("../../test-resources/errors/ca-parent-issue.json"),
1094             Error::CaParentIssue(ca.clone(), parent, "connection refused".to_string()),
1095         );
1096         verify(
1097             include_str!("../../test-resources/errors/ca-parent-response-invalid-xml.json"),
1098             Error::CaParentResponseInvalidXml(ca.clone(), "expected something".to_string()),
1099         );
1100         verify(
1101             include_str!("../../test-resources/errors/ca-parent-response-wrong-xml.json"),
1102             Error::CaParentResponseWrongXml(ca.clone()),
1103         );
1104 
1105         verify(
1106             include_str!("../../test-resources/errors/rfc6492-protocol.json"),
1107             Error::Rfc6492(rfc6492::Error::InvalidVersion),
1108         );
1109         verify(
1110             include_str!("../../test-resources/errors/rfc6492-invalid-csr.json"),
1111             Error::Rfc6492InvalidCsrSent("invalid signature".to_string()),
1112         );
1113         verify(
1114             include_str!("../../test-resources/errors/rfc6492-invalid-signature.json"),
1115             Error::Rfc6492SignatureInvalid,
1116         );
1117 
1118         verify(
1119             include_str!("../../test-resources/errors/ca-child-duplicate.json"),
1120             Error::CaChildDuplicate(ca.clone(), child.clone()),
1121         );
1122         verify(
1123             include_str!("../../test-resources/errors/ca-child-unknown.json"),
1124             Error::CaChildUnknown(ca.clone(), child.clone()),
1125         );
1126         verify(
1127             include_str!("../../test-resources/errors/ca-child-resources-required.json"),
1128             Error::CaChildMustHaveResources(ca.clone(), child.clone()),
1129         );
1130         verify(
1131             include_str!("../../test-resources/errors/ca-child-resources-extra.json"),
1132             Error::CaChildExtraResources(ca.clone(), child.clone()),
1133         );
1134         verify(
1135             include_str!("../../test-resources/errors/ca-child-unauthorized.json"),
1136             Error::CaChildUnauthorized(ca.clone(), child),
1137         );
1138 
1139         verify(
1140             include_str!("../../test-resources/errors/ca-roa-unknown.json"),
1141             Error::CaAuthorizationUnknown(ca.clone(), auth),
1142         );
1143         verify(
1144             include_str!("../../test-resources/errors/ca-roa-duplicate.json"),
1145             Error::CaAuthorizationDuplicate(ca.clone(), auth),
1146         );
1147 
1148         verify(
1149             include_str!("../../test-resources/errors/ca-roa-invalid-max-length.json"),
1150             Error::CaAuthorizationInvalidMaxLength(ca.clone(), auth),
1151         );
1152         verify(
1153             include_str!("../../test-resources/errors/ca-roa-not-entitled.json"),
1154             Error::CaAuthorizationNotEntitled(ca, auth),
1155         );
1156 
1157         verify(
1158             include_str!("../../test-resources/errors/key-re-use.json"),
1159             Error::KeyUseAttemptReuse,
1160         );
1161         verify(
1162             include_str!("../../test-resources/errors/key-no-new.json"),
1163             Error::KeyUseNoNewKey,
1164         );
1165         verify(
1166             include_str!("../../test-resources/errors/key-no-current.json"),
1167             Error::KeyUseNoCurrentKey,
1168         );
1169         verify(
1170             include_str!("../../test-resources/errors/key-no-old.json"),
1171             Error::KeyUseNoOldKey,
1172         );
1173         verify(
1174             include_str!("../../test-resources/errors/key-no-cert.json"),
1175             Error::KeyUseNoIssuedCert,
1176         );
1177         let ki = test_id_certificate().subject_public_key_info().key_identifier();
1178         verify(
1179             include_str!("../../test-resources/errors/key-no-match.json"),
1180             Error::KeyUseNoMatch(ki),
1181         );
1182 
1183         verify(
1184             include_str!("../../test-resources/errors/rc-unknown.json"),
1185             Error::ResourceClassUnknown(ResourceClassName::from("RC0")),
1186         );
1187         verify(
1188             include_str!("../../test-resources/errors/rc-resources.json"),
1189             Error::ResourceSetError(ResourceSetError::Mix),
1190         );
1191         verify(
1192             include_str!("../../test-resources/errors/rc-missing-resources.json"),
1193             Error::MissingResources,
1194         );
1195 
1196         verify(
1197             include_str!("../../test-resources/errors/ta-not-allowed.json"),
1198             Error::TaNotAllowed,
1199         );
1200         verify(
1201             include_str!("../../test-resources/errors/ta-name-reserved.json"),
1202             Error::TaNameReserved,
1203         );
1204         verify(
1205             include_str!("../../test-resources/errors/ta-initialized.json"),
1206             Error::TaAlreadyInitialized,
1207         );
1208 
1209         verify(
1210             include_str!("../../test-resources/errors/general-error.json"),
1211             Error::custom("some unlikely corner case"),
1212         );
1213     }
1214 
1215     #[test]
roa_delta_json()1216     fn roa_delta_json() {
1217         let mut error = RoaDeltaError::default();
1218 
1219         let duplicate = definition("10.0.0.0/20-24 => 1");
1220         let not_held = definition("10.128.0.0/9 => 1");
1221         let invalid_length = definition("10.0.1.0/25 => 1");
1222         let unknown = definition("192.168.0.0/16 => 1");
1223 
1224         error.add_duplicate(duplicate);
1225         error.add_notheld(not_held);
1226         error.add_invalid_length(invalid_length);
1227         error.add_unknown(unknown);
1228 
1229         let ca = Handle::from_str("ca").unwrap();
1230 
1231         let error = Error::RoaDeltaError(ca, error);
1232 
1233         verify(
1234             include_str!("../../test-resources/errors/ca-roa-delta-error.json"),
1235             error,
1236         );
1237     }
1238 }
1239