From ded10e28782f289ad3db15320bcf619ab4336876 Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Mon, 9 Aug 2021 18:46:48 +0200 Subject: Switch to a more sensible error reporting system --- doc/disfluid.texi | 535 ++++-------------------------------------------------- 1 file changed, 33 insertions(+), 502 deletions(-) (limited to 'doc') diff --git a/doc/disfluid.texi b/doc/disfluid.texi index 2841052..0a2c489 100644 --- a/doc/disfluid.texi +++ b/doc/disfluid.texi @@ -401,12 +401,8 @@ configuration of the claimed issuer, and check the signature against the published keys. The @code{http-get} optional keyword argument can set a different implementation of @code{http-get} from @emph{(web client)}, for instance to re-use the what has been obtained -by the ID token validation. Return @code{#f} if it failed, or the -decoded token otherwise. -@end deffn - -@deffn function access-token-encode @var{token} @var{key} -Encode @var{token} and sign it with the issuer’s @var{key}. +by the ID token validation. Return the decoded access token, or raise +an exception. @end deffn @deffn function issue-access-token @var{issuer-key} @var{#alg} @var{#webid} @var{#iss} @var{#:validity} @var{[#client-key} @var{|} @var{#cnf/jkt]} @var{#client-id} @@ -1045,504 +1041,39 @@ point to where to a presentation of your application. The library will raise an exception whenever something fishy occurs. For instance, if a signature is invalid, or the expiration -date has passed. All exception types are defined in -@code{(webid-oidc errors)}. - -@deffn function error->str @var{error} @var{[#depth]} -Return a string explaining the @var{error}. You can limit the -@var{depth} of the explanation as an integer. +date has passed. + +When the client is responsible for an error, such as presenting an +invalid access token, a compound exception is raised. It is sometimes +useful for the user to understand what happened, because it could +indicate a problem in a part of the web they need to change. For +instance, if the access token cannot be decoded because the identity +provider is down, then maybe informing the user of that fact is +useful. + +However, presenting too much information is a security risk. For +instance, if the system administrator also runs a private server on +the same machine, and a malicious client tries to pretend that this +private server is an identity provider, then the public server will +try to query the private server. If an error happens and the public +server displays some information to the client, then a part of the +information comes from the private server. Thus, a balance needs to be +found so that not too much is revealed. + +The module @emph{(webid-oidc errors)} defines an exception type that +indicates a message that is safe to display to the user. + +@deftp {Exception type} &message-for-the-user @var{message} +Indicate that @var{message} can be safely displayed to the user. It is +an XHTML paragraph (or equivalent), presented as SXML. +@end deftp + +@deffn function make-message-for-the-user @var{message} +@deffnx user-message @var{exception} +Constructor and accessor for the @code{&message-for-the-user} +exception type. @end deffn -@menu -* Invalid data format:: -* Invalid JWT:: -* Cannot fetch data on the web:: -* Other errors in the protocol or from a reasonable implementation:: -* Server-side errors:: -@end menu - -@node Invalid data format -@section Invalid data format -There are a few JSON objects with required fields. This exceptions -usually occur as the cause of a higher-level exception. - -@deftp {exception type} ¬-base64 @var{value} @var{cause} -This exception is raised when the base64 decoding function -failed. @var{value} is the incorrect input, and @var{cause} is a -low-level error. -@end deftp - -@deftp {exception type} ¬-json @var{value} @var{cause} -Cannot decode @var{value} to a JSON object. -@end deftp - -@deftp {exception type} ¬-turtle @var{value} @var{cause} -Cannot decode @var{value} to a RDF graph. -@end deftp - -@deftp {exception type} &incorrect-webid-field @var{value} -The @var{value} of the webid field in the JWT is missing (if -@code{#f}), or not an acceptable value. -@end deftp - -@deftp {exception type} &incorrect-iss-field @var{value} -The @var{value} of the iss field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-aud-field @var{value} -The @var{value} of the aud field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-iat-field @var{value} -The @var{value} of the iat field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-exp-field @var{value} -The @var{value} of the exp field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-cnf/jkt-field @var{value} -The @var{value} of the cnf/jkt field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-client-id-field @var{value} -The @var{value} of the client-id field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-typ-field @var{value} -The @var{value} of the typ field in the DPoP proof header is -incorrect. -@end deftp - -@deftp {exception type} &incorrect-jwk-field @var{value} @var{cause} -The @var{value} of the jwk field in the DPoP proof header is -incorrect. -@end deftp - -@deftp {exception type} &incorrect-jti-field @var{value} -The @var{value} of the jti field in the DPoP proof is incorrect. -@end deftp - -@deftp {exception type} &incorrect-htm-field @var{value} -The @var{value} of the htm field in the DPoP proof is incorrect. -@end deftp - -@deftp {exception type} &incorrect-htu-field @var{value} -The @var{value} of the htu field in the DPoP proof is incorrect. -@end deftp - -@deftp {exception type} &incorrect-ath-field @var{value} -The @var{value} of the ath field is not the hash of the access token. -@end deftp - -@deftp {exception type} &incorrect-redirect-uris-field @var{value} -The @var{value} of the redirect-uris field of a client manifest is -incorrect. -@end deftp - -@deftp {exception type} &incorrect-typ-field @var{value} -The @var{value} of the typ field in the DPoP proof header is -incorrect. -@end deftp - -@deftp {exception type} &incorrect-sub-field @var{value} -The @var{value} of the sub field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-iss-field @var{value} -The @var{value} of the iss field is incorrect. -@end deftp - -@deftp {exception type} &incorrect-nonce-field @var{value} -The @var{value} of the nonce field in the DPoP proof is incorrect. -@end deftp - -@deftp {exception type} &incorrect-htm-field @var{value} -The @var{value} of the htm field in the DPoP proof is incorrect. -@end deftp - -@deftp {exception type} ¬-a-client-manifest @var{value} @var{cause} -The @var{client-manifest} is incorrect. -@end deftp - -@node Invalid JWT -@section Invalid JWT -Each JWT type – access token, DPoP proof, ID token, authorization code -(this is internal to the identity provider) has different validation -rules, and can fail in different ways. - -@deftp {exception type} &unsupported-crv @var{crv} -The identifier @var{crv} does not identify an elliptic curve. -@end deftp - -@deftp {exception type} ¬-a-jwk @var{value} @var{cause} -@var{value} does not identify a JWK. -@end deftp - -@deftp {exception type} ¬-a-public-jwk @var{value} @var{cause} -@var{value} does not identify a public JWK. -@end deftp - -@deftp {exception type} ¬-a-private-jwk @var{value} @var{cause} -@var{value} does not identify a private JWK. -@end deftp - -@deftp {exception type} ¬-a-jwks @var{value} @var{cause} -@var{value} does not identify a set of public keys. -@end deftp - -@deftp {exception type} &unsupported-alg @var{value} -@var{value} does not identify a valid hash algorithm. -@end deftp - -@deftp {exception type} &invalid-signature @var{key} @var{payload} @var{signature} -@var{key} has not signed @var{payload} with @var{signature}. -@end deftp - -@deftp {exception type} &missing-alist-key @var{value} @var{key} -@var{value} isn’t an alist, or is missing a value with @var{key}. -@end deftp - -@deftp {exception type} ¬-a-jws-header @var{value} @var{cause} -@var{value} does not identify a decoded JWS header. -@end deftp - -@deftp {exception type} ¬-a-jws-payload @var{value} @var{cause} -@var{value} does not identify a decoded JWS payload. -@end deftp - -@deftp {exception type} ¬-a-jws @var{value} @var{cause} -@var{value} does not identify a decoded JWS. -@end deftp - -@deftp {exception type} ¬-in-3-parts @var{string} @var{separator} -@var{string} cannot be split into 3 parts with @var{separator}. -@end deftp - -@deftp {exception type} &no-matching-key @var{candidates} @var{alg} @var{payload} @var{signature} -No key among @var{candidates} could verify @var{signature} signed with -@var{alg} for @var{payload}, because the signature mismatched for all -keys. -@end deftp - -@deftp {exception type} &cannot-decode-jws @var{value} @var{cause} -The @var{value} string is not an encoding of a valid JWS. -@end deftp - -@deftp {exception type} &cannot-encode-jws @var{jws} @var{key} @var{cause} -The @var{jws} cannot be signed. -@end deftp - -@deftp {exception type} ¬-an-access-token @var{value} @var{cause} -The @var{value} is not an access token. -@end deftp - -@deftp {exception type} ¬-an-access-token-header @var{value} @var{cause} -The @var{value} is not an access token header. -@end deftp - -@deftp {exception type} ¬-an-access-token-payload @var{value} @var{cause} -The @var{value} is not an access token payload. -@end deftp - -@deftp {exception type} &cannot-decode-access-token @var{value} @var{cause} -The @var{value} string is not an encoding of a valid access token. -@end deftp - -@deftp {exception type} &cannot-encode-access-token @var{access-token} @var{key} @var{cause} -The @var{access-token} cannot be signed. -@end deftp - -@deftp {exception type} ¬-a-dpop-proof @var{value} @var{cause} -The @var{value} is not a DPoP proof. -@end deftp - -@deftp {exception type} ¬-a-dpop-proof-header @var{value} @var{cause} -The @var{value} is not a DPoP proof header. -@end deftp - -@deftp {exception type} ¬-a-dpop-proof-payload @var{value} @var{cause} -The @var{value} is not a DPoP proof payload. -@end deftp - -@deftp {exception type} &cannot-decode-dpop-proof @var{value} @var{cause} -The @var{value} string is not an encoding of a valid DPoP proof. -@end deftp - -@deftp {exception type} &cannot-encode-dpop-proof @var{dpop-proof} @var{key} @var{cause} -The @var{dpop-proof} cannot be signed. -@end deftp - -@deftp {exception type} ¬-an-authorization-code @var{value} @var{cause} -The @var{value} is not an authorization code. -@end deftp - -@deftp {exception type} ¬-an-authorization-code-header @var{value} @var{cause} -The @var{value} is not an authorization code header. -@end deftp - -@deftp {exception type} ¬-an-authorization-code-payload @var{value} @var{cause} -The @var{value} is not an authorization code payload. -@end deftp - -@deftp {exception type} &cannot-decode-authorization-code @var{value} @var{cause} -The @var{value} string is not an encoding of a valid authorization -code. -@end deftp - -@deftp {exception type} &cannot-encode-authorization-code @var{authorization-code} @var{key} @var{cause} -The @var{authorization-code} cannot be signed. -@end deftp - -@deftp {exception type} ¬-an-id-token @var{value} @var{cause} -The @var{value} is not an ID token. -@end deftp - -@deftp {exception type} ¬-an-id-token-header @var{value} @var{cause} -The @var{value} is not an ID token header. -@end deftp - -@deftp {exception type} ¬-an-id-token-payload @var{value} @var{cause} -The @var{value} is not an ID token payload. -@end deftp - -@deftp {exception type} &cannot-decode-id-token @var{value} @var{cause} -The @var{value} string is not an encoding of a valid ID token. -@end deftp - -@deftp {exception type} &cannot-encode-id-token @var{id-token} @var{key} @var{cause} -The @var{id-token} cannot be signed. -@end deftp - -@node Cannot fetch data on the web -@section Cannot fetch data on the web -In the client (local and public parts), resource server and identity -provider, the protocol requires to fetch data on the web. - -@deftp {exception type} &request-failed-unexpectedly @var{response-code} @var{response-reason-phrase} -We expected the request to succeed, but the server sent a non-OK -@var{response-code}. -@end deftp - -@deftp {exception type} &unexpected-header-value @var{header} @var{value} -We did not expect the server to respond with @var{header} set to -@var{value}. -@end deftp - -@deftp {exception type} &unexpected-response @var{response} @var{cause} -The @var{response} (from @emph{(web response)}) is not appropriate. -@end deftp - -@deftp {exception type} ¬-an-oidc-configuration @var{value} @var{cause} -The @var{value} is not appropriate an OIDC configuration. -@end deftp - -@deftp {exception type} &cannot-fetch-issuer-configuration @var{issuer} @var{cause} -It is impossible to fetch the configuration of @var{issuer}. -@end deftp - -@deftp {exception type} &cannot-fetch-jwks @var{issuer} @var{uri} @var{cause} -It is impossible to fetch the keys of @var{issuer} at @var{uri}. -@end deftp - -@deftp {exception type} &cannot-fetch-linked-data @var{uri} @var{cause} -Could not fetch the graph referenced by @var{uri}. -@end deftp - -@deftp {exception type} &cannot-fetch-client-manifest @var{id} @var{cause} -Could not fetch a client manifest at @var{id}. -@end deftp - -@node Other errors in the protocol or from a reasonable implementation -@section Other errors in the protocol or from a reasonable implementation -The protocol does not rely solely on JWT validation, so these errors -may happen too. - -@deftp {exception type} &dpop-method-mismatch @var{signed} @var{requested} -The method value @var{signed} in the DPoP proof does not match the -method that is @var{requested} on the server. -@end deftp - -@deftp {exception type} &dpop-uri-mismatch @var{signed} @var{requested} -The URI value @var{signed} in the DPoP proof does not match the URI -that is @var{requested} on the server. -@end deftp - -@deftp {exception type} &dpop-signed-in-future @var{signed} @var{current} -The proof is @var{signed} for a date which is too much ahead of the -@var{current} time. -@end deftp - -@deftp {exception type} &dpop-too-old @var{signed} @var{current} -The proof was @var{signed} at a past date of @var{current}. -@end deftp - -@deftp {exception type} &dpop-unconfirmed-key @var{key} @var{expected} @var{cause} -The confirmation of @var{key} is not what is @var{expected}, or (if a -function was passed as @var{cnf/check}) the @var{cause} exception -occurred while confirming. -@end deftp - -@deftp {exception type} &dpop-invalid-access-token-hash @var{hash} @var{access-token} -The @var{access-token} passed to the resource server does not match -the @var{hash} provided in the DPoP proof. -@end deftp - -@deftp {exception type} &jti-found @var{jti} @var{cause} -The @var{jti} of the proof has already been issued in a recent past. -@end deftp - -@deftp {exception type} &unauthorized-redirection-uri @var{manifest} @var{uri} -The authorization @var{uri} is not advertised in @var{manifest}. -@end deftp - -@deftp {exception type} &cannot-serve-public-manifest -You cannot serve the public client manifest. -@end deftp - -@deftp {exception type} &no-client-manifest-registration @var{id} -The @var{id} client manifest does not have a registration triple in -its document. -@end deftp - -@deftp {exception type} &inconsistent-client-manifest-id @var{id} @var{advertised-id} -The client @var{manifest} is being fetched at @var{id}, but it is -valid for another client @var{advertised-id}. -@end deftp - -@deftp {exception type} &authorization-code-expired @var{exp} @var{current-time} -The authorization code has expired at @var{exp}, it is now -@var{current-time}. -@end deftp - -@deftp {exception type} &invalid-refresh-token @var{refresh-token} -The @var{refresh-token} is unknown to the identity provider. -@end deftp - -@deftp {exception type} &invalid-key-for-refresh-token @var{key} @var{jkt} -The refresh token was issued for @var{jkt}, but it is used with -@var{key}. -@end deftp - -@deftp {exception type} &unknown-client-locale @var{web-locale} @var{c-locale} -The @var{web-locale} of the client, translated to C as @var{c-locale}, -cannot be set. This exception is always continuable; if the handler -returns, then the page will be served in the english locale. -@end deftp - -@deftp {exception type} &unsupported-grant-type @var{value} -The token request failed to indicate a @var{value} for the grant type, -or indicated an unsupported grant type. -@end deftp - -@deftp {exception type} &no-authorization-code -The token request forgot to put an authorization code. -@end deftp - -@deftp {exception type} &no-refresh-token -The token request forgot to put a refresh token with the request. -@end deftp - -@deftp {exception type} &unconfirmed-provider @var{subject} @var{provider} -@var{provider} is not confirmed by @var{subject} as an identity -provider. -@end deftp - -@deftp {exception type} &no-provider-candidates @var{webid} @var{causes} -The @var{webid} cannot be certified by any identity providers. The -@var{causes} alist indicates an error for each candidates. -@end deftp - -@deftp {exception type} &neither-identity-provider-nor-webid @var{uri} @var{why-not-identity-provider} @var{why-not-webid} -The @var{uri} you passed to get an authorization code is neither an -identity provider (because @var{why-not-identity-provider}) nor a -webid (because @var{why-not-webid}). -@end deftp - -@deftp {exception type} &token-request-failed @var{cause} -The token request failed on the server. -@end deftp - -@deftp {exception type} &profile-not-found @var{webid} @var{iss} @var{dir} -The @var{webid}, as certified by @var{iss}, cannot be refreshed -because we don’t have a refresh token stored in @var{dir}. -@end deftp - -@node Server-side errors -@section Server-side errors -The resource server implementation may encounter some more exceptional -conditions. - -@deftp {exception type} &path-not-found @var{path} -There is no registered resource at @var{path}. -@end deftp - -@deftp {exception type} &auxiliary-resource-absent @var{path} @var{kind} -The auxiliary resource of given @var{kind} is not instanciated on the -server for the base resource @var{path}. -@end deftp - -@deftp {exception type} &uri-slash-semantics-error @var{path} @var{expected-path} -While the resource at @var{path} does not exist, the resource at -@var{expected-path} does, and @var{path} and @var{expected-path} -differ only by a trailing slash. This exception may be raised along -with @code{&path-not-found}. - -Beware that even if it is true at the time when the exception is -created, maybe the resource has been created by the time it is -handled. -@end deftp - -@deftp {exception type} &cannot-delete-root -There was a request to delete the root storage, which is an error. -@end deftp - -@deftp {exception type} &container-not-empty @var{path} -There was a request to delete a non-empty container. -@end deftp - -@deftp {exception type} &cannot-fetch-group @var{group-uri} @var{cause} -The access control could not fetch the group @var{group-uri} (with a -known @var{cause}). This warning is continuable every time it is -raised. If the handler returns, then the group will be considered -empty. -@end deftp - -@deftp {exception type} &incorrect-containment-triples @var{path} -The client wanted to create or update a resource, and by that it tried -to change the containment triples at @var{path}. -@end deftp - -@deftp {exception type} &unsupported-media-type @var{content-type} -The client wanted to create a resource with the given -@var{content-type}, but it is not accepted, because @var{content-type} -is not recognized as an RDF content type. -@end deftp - -@deftp {exception type} &path-is-auxiliary @var{path} -The client wanted to create a resource that targets an auxiliary -resource, at @var{path}. -@end deftp - -@deftp {exception type} &forbidden @var{path} @var{user} @var{owner} @var{mode} -The @var{user} wanted to do something under @var{path} requiring -@var{mode}, but it is not the @var{owner} and it is forbidden by WAC. -@end deftp - -@deftp {exception type} &precondition-failed @var{path} @var{if-match} @var{if-none-match} @var{real-etag} -The resource under @var{path} has a @var{real-etag} that does not -match the request headers @var{if-match} and @var{if-none-match}. - -If the resource does not exist, @var{real-etag} is set to -@code{#f}. In this case, an exception of type @code{&path-not-found} -is also thrown. -@end deftp - -@deftp {exception type} ¬-acceptable @var{client-accepts} @var{path} @var{content-type} -The client wanted a response with a specific set of -@var{client-accept}ed content-types, but the real @var{content-type} -of the resource under @var{path} cannot be converted to one of them. -@end deftp @node GNU Free Documentation License @appendix GNU Free Documentation License -- cgit v1.2.3