diff options
author | Vivien Kraus <vivien@planete-kraus.eu> | 2020-12-02 09:58:55 +0100 |
---|---|---|
committer | Vivien Kraus <vivien@planete-kraus.eu> | 2021-05-11 00:32:08 +0200 |
commit | f4de4d524396c9724311ef5867dcd3ed598eff19 (patch) | |
tree | 9fd6a0b88340501d640e00674e6928d41c9373cd | |
parent | e4fc542a1253f59f70628de162ac331c4b592f23 (diff) |
Parse and issue OIDC ID tokens
-rw-r--r-- | doc/manual.html | 109 | ||||
-rw-r--r-- | po/fr.po | 287 | ||||
-rw-r--r-- | po/webid-oidc.pot | 249 | ||||
-rw-r--r-- | src/scm/webid-oidc/Makefile.am | 6 | ||||
-rw-r--r-- | src/scm/webid-oidc/errors.scm | 95 | ||||
-rw-r--r-- | src/scm/webid-oidc/oidc-id-token.scm | 200 |
6 files changed, 700 insertions, 246 deletions
diff --git a/doc/manual.html b/doc/manual.html index 5ac29bc..3ca857f 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -114,6 +114,74 @@ <emph>strings</emph>, but we hope that in the future SRFI-180 will be more closely respected. </p> + <h2>The ID token</h2> + <p> + The ID token is a special JWT that the application keeps for + itself. It is signed by the identity provider, and contains the + following claims: + </p> + <ul> + <li><emph>webid</emph>, the URI of the user’s webid;</li> + <li><emph>iss</emph>, the URI of the identity provider (issuer);</li> + <li><emph>sub</emph>, the username (the webid-oidc issuer puts the webid again here, but it could be any string);</li> + <li><emph>aud</emph>, the ID of the client application that is intended to receive the ID token;</li> + <li><emph>nonce</emph>, some random data to change the signature;</li> + <li><emph>exp</emph>, an UTC time (in seconds) for when the token expires;</li> + <li><emph>iat</emph>, the time when it was issued.</li> + </ul> + <p> + There are functions to work with ID tokens + in <emph>(webid-oidc oidc-id-token)</emph>. + </p> + <info:deffn type="function" name="id-token?" arguments="object"> + <p> + Check that <info:var>object</info:var> is a decoded ID token. + </p> + </info:deffn> + <p> + The following helper functions convert URIs to the URIs + from <emph>(web uri)</emph> and times + to <emph>(srfi srfi-19)</emph> dates. + </p> + <info:deffn type="function" name="id-token-webid" arguments="token"> + <info:deffnx type="function" name="id-token-iss" arguments="token" /> + <info:deffnx type="function" name="id-token-sub" arguments="token" /> + <info:deffnx type="function" name="id-token-aud" arguments="token" /> + <info:deffnx type="function" name="id-token-nonce" arguments="token" /> + <info:deffnx type="function" name="id-token-exp" arguments="token" /> + <info:deffnx type="function" name="id-token-iat" arguments="token" /> + <p> + Get the suitable field from the payload + of <info:var>token</info:var>. + </p> + </info:deffn> + <p> + ID tokens can be signed and encoded as a string, or decoded. + </p> + <info:deffn type="function" name="id-token-decode" arguments="token [#http-get]"> + <p> + Decode <info:var>token</info:var>, as a string, into a decoded + token. The signature verification will need to fetch the oidc + configuration of the claimed issuer, and check the signature + against the published keys. The <pre>http-get</pre> optional + keyword argument can set a different implementation + of <pre>http-get</pre> + from <emph>(web client)</emph>. Return <pre>#f</pre> if + it failed, or the decoded token otherwise. + </p> + </info:deffn> + <info:deffn type="function" name="id-token-encode" arguments="token key"> + <p> + Encode <info:var>token</info:var> and sign it with the + issuer’s <info:var>key</info:var>. + </p> + </info:deffn> + <info:deffn type="function" name="issue-id-token" arguments="issuer-key #alg #webid #iss #sub #aud #exp #iat"> + <p> + Create an ID token, and encode it with + <info:var>issuer-key</info:var>. + </p> + </info:deffn> <h2>The access token</h2> <p> The access token is obtained by the client through a token @@ -483,6 +551,11 @@ is missing (if <pre>#f</pre>), or not an acceptable value. </p> </info:deftp> + <info:deftp type="exception type" name="&incorrect-sub-field" arguments="value"> + <p> + The <info:var>value</info:var> of the sub field is incorrect. + </p> + </info:deftp> <info:deftp type="exception type" name="&incorrect-iss-field" arguments="value"> <p> The <info:var>value</info:var> of the iss field is incorrect. @@ -537,6 +610,12 @@ proof is incorrect. </p> </info:deftp> + <info:deftp type="exception type" name="&incorrect-nonce-field" arguments="value"> + <p> + The <info:var>value</info:var> of the nonce field in the DPoP + proof is incorrect. + </p> + </info:deftp> <info:deftp type="exception type" name="&incorrect-htm-field" arguments="value"> <p> The <info:var>value</info:var> of the htm field in the DPoP @@ -734,8 +813,34 @@ </info:deftp> <info:deftp type="exception type" name="&invalid-key-for-refresh-token" arguments="key jkt"> <p> - The refresh token was issued for <info:var>jkt</info:var>, but - it is used with <info:var>key</info:var>. + The refresh token was issued for <info:var>jkt</info:var>, but + it is used with <info:var>key</info:var>. + </p> + </info:deftp> + <info:deftp type="exception type" name="&not-an-id-token" arguments="value cause"> + <p> + The <info:var>value</info:var> is not an ID token. + </p> + </info:deftp> + <info:deftp type="exception type" name="&not-an-id-token-header" arguments="value cause"> + <p> + The <info:var>value</info:var> is not an ID token header. + </p> + </info:deftp> + <info:deftp type="exception type" name="&not-an-id-token-payload" arguments="value cause"> + <p> + The <info:var>value</info:var> is not an ID token payload. + </p> + </info:deftp> + <info:deftp type="exception type" name="&cannot-decode-id-token" arguments="value cause"> + <p> + The <info:var>value</info:var> string is not an encoding of a + valid ID token. + </p> + </info:deftp> + <info:deftp type="exception type" name="&cannot-encode-id-token" arguments="id-token key cause"> + <p> + The <info:var>id-token</info:var> cannot be signed. </p> </info:deftp> @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: webid-oidc 0.0.0\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" -"POT-Creation-Date: 2021-05-10 22:43+0200\n" -"PO-Revision-Date: 2021-05-10 22:43+0200\n" +"POT-Creation-Date: 2021-05-10 22:46+0200\n" +"PO-Revision-Date: 2021-05-10 22:46+0200\n" "Last-Translator: Vivien Kraus <vivien@planete-kraus.eu>\n" "Language-Team: French <vivien@planete-kraus.eu>\n" "Language: fr\n" @@ -126,101 +126,101 @@ msgstr "Utilisation : generate-random [NOMBRE D'OCTETS]\n" msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "Utilisation : generate-key [NOMBRE DE BITS | COURBE]\n" -#: src/scm/webid-oidc/errors.scm:718 +#: src/scm/webid-oidc/errors.scm:788 msgid "that’s how it is" msgstr "c’est comme ça" -#: src/scm/webid-oidc/errors.scm:723 +#: src/scm/webid-oidc/errors.scm:793 #, scheme-format msgid "the value ~s is not a base64 string (because ~a)" msgstr "la valeur ~s n’est pas une chaîne base64 (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:726 +#: src/scm/webid-oidc/errors.scm:796 #, scheme-format msgid "the value ~s is not JSON (because ~a)" msgstr "la valeur ~s n’est pas du JSON (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:729 +#: src/scm/webid-oidc/errors.scm:799 #, scheme-format msgid "the value ~s is not Turtle (because ~a)" msgstr "la valeur ~s n’est pas du Turtle (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:732 +#: src/scm/webid-oidc/errors.scm:802 #, scheme-format msgid "the value ~s does not identify an elleptic curve" msgstr "la valeur ~s n’identifie pas une courbe elliptique" -#: src/scm/webid-oidc/errors.scm:737 +#: src/scm/webid-oidc/errors.scm:807 #, scheme-format msgid "the value ~s does not identify a JWK (because ~a)" msgstr "la valeur ~s n’identifie pas une JWK (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:739 +#: src/scm/webid-oidc/errors.scm:809 #, scheme-format msgid "the value ~s does not identify a JWK" msgstr "la valeur ~s n’identifie pas une JWK" -#: src/scm/webid-oidc/errors.scm:744 +#: src/scm/webid-oidc/errors.scm:814 #, scheme-format msgid "the value ~s does not identify a public JWK (because ~a)" msgstr "la valeur ~s n’identifie pas une JWK publique (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:746 +#: src/scm/webid-oidc/errors.scm:816 #, scheme-format msgid "the value ~s does not identify a public JWK" msgstr "la valeur ~s n’identifie pas une JWK publique" -#: src/scm/webid-oidc/errors.scm:751 +#: src/scm/webid-oidc/errors.scm:821 #, scheme-format msgid "the value ~s does not identify a private JWK (because ~a)" msgstr "la valeur ~s n’identifie pas une JWK privée (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:753 +#: src/scm/webid-oidc/errors.scm:823 #, scheme-format msgid "the value ~s does not identify a private JWK" msgstr "la valeur ~s n’identifie pas une JWK privée" -#: src/scm/webid-oidc/errors.scm:758 +#: src/scm/webid-oidc/errors.scm:828 #, scheme-format msgid "the value ~s does not identify a JWKS (because ~a)" msgstr "la valeur ~s n’identifie pas un JWKS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:760 +#: src/scm/webid-oidc/errors.scm:830 #, scheme-format msgid "the value ~s does not identify a JWKS" msgstr "la valeur ~s n’identifie pas un JWKS" -#: src/scm/webid-oidc/errors.scm:763 +#: src/scm/webid-oidc/errors.scm:833 #, scheme-format msgid "the value ~s does not identify a hash algorithm" msgstr "la valeur ~s n’identifie pas un algorithme de hachage" -#: src/scm/webid-oidc/errors.scm:766 +#: src/scm/webid-oidc/errors.scm:836 #, scheme-format msgid "the value ~s is not an alist or misses key ~s" msgstr "la valeur ~s n’est pas une alist ou il manque la clé ~s" -#: src/scm/webid-oidc/errors.scm:769 +#: src/scm/webid-oidc/errors.scm:839 #, scheme-format msgid "the value ~s is not a JWS header (because ~a)" msgstr "la valeur ~s n’est pas un header JWS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:772 +#: src/scm/webid-oidc/errors.scm:842 #, scheme-format msgid "the value ~s is not a JWS payload (because ~a)" msgstr "la valeur ~s n’est pas un contenu JWS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:775 +#: src/scm/webid-oidc/errors.scm:845 #, scheme-format msgid "the value ~s is not a JWS (because ~a)" msgstr "la valeur ~s n’est pas un JWS (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:778 +#: src/scm/webid-oidc/errors.scm:848 #, scheme-format msgid "the string ~s cannot be split in 3 parts with ~s" msgstr "la chaîne ~s ne peut pas être découpée en 3 parties avec ~s" -#: src/scm/webid-oidc/errors.scm:781 +#: src/scm/webid-oidc/errors.scm:851 #, scheme-format msgid "" "all key candidates failed to verify signature ~s with algorithm ~s and " @@ -229,17 +229,17 @@ msgstr "" "aucune clé candidate n’a pu vérifier la signature ~s avec l’algorithme ~s et " "le contenu ~a (il y en avait ~a : ~s)" -#: src/scm/webid-oidc/errors.scm:784 +#: src/scm/webid-oidc/errors.scm:854 #, scheme-format msgid "I cannot decode JWS ~a (because ~a)" msgstr "je n’ai pas pu décoder le JWS encodé par ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:787 +#: src/scm/webid-oidc/errors.scm:857 #, scheme-format msgid "I cannot encode JWS ~a (because ~a)" msgstr "je n’ai pas pu encoder le JWS ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:790 +#: src/scm/webid-oidc/errors.scm:860 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" @@ -247,411 +247,432 @@ msgstr "" "la requête au serveur a échoué de façon inattendue avec un code ~a et une " "raison ~s" -#: src/scm/webid-oidc/errors.scm:795 +#: src/scm/webid-oidc/errors.scm:865 #, scheme-format msgid "the header ~a should not have the value ~s" msgstr "l’en-tête ~a ne devrait pas avoir la valeur ~s" -#: src/scm/webid-oidc/errors.scm:797 +#: src/scm/webid-oidc/errors.scm:867 #, scheme-format msgid "the header ~a should be present" msgstr "l’en-tête ~a devrait être présent" -#: src/scm/webid-oidc/errors.scm:800 +#: src/scm/webid-oidc/errors.scm:870 #, scheme-format msgid "the server response wasn't expected: ~s (because ~a)" msgstr "la réponse du serveur est inattendue : ~s (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:806 +#: src/scm/webid-oidc/errors.scm:876 #, scheme-format msgid "the value ~s is not an OIDC configuration (because ~a)" msgstr "la valeur ~s n’est pas une configuration OIDC (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:811 +#: src/scm/webid-oidc/errors.scm:881 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "le champ webid est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:812 +#: src/scm/webid-oidc/errors.scm:882 msgid "the webid field is missing" msgstr "le champ webid est manquant" -#: src/scm/webid-oidc/errors.scm:816 +#: src/scm/webid-oidc/errors.scm:886 +#, scheme-format +msgid "the sub field is incorrect: ~s" +msgstr "le champ sub est incorrect : ~s" + +#: src/scm/webid-oidc/errors.scm:887 +msgid "the sub field is missing" +msgstr "le champ sub est manquant" + +#: src/scm/webid-oidc/errors.scm:891 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "le champ iss est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:817 +#: src/scm/webid-oidc/errors.scm:892 msgid "the iss field is missing" msgstr "le champ iss est manquant" -#: src/scm/webid-oidc/errors.scm:821 +#: src/scm/webid-oidc/errors.scm:896 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "le champ aud est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:822 +#: src/scm/webid-oidc/errors.scm:897 msgid "the aud field is missing" msgstr "le champ aud est manquant" -#: src/scm/webid-oidc/errors.scm:826 +#: src/scm/webid-oidc/errors.scm:901 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "le champ iat est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:827 +#: src/scm/webid-oidc/errors.scm:902 msgid "the iat field is missing" msgstr "le champ iat est manquant" -#: src/scm/webid-oidc/errors.scm:831 +#: src/scm/webid-oidc/errors.scm:906 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "le champ exp est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:832 +#: src/scm/webid-oidc/errors.scm:907 msgid "the exp field is missing" msgstr "le champ exp est manquant" -#: src/scm/webid-oidc/errors.scm:836 +#: src/scm/webid-oidc/errors.scm:911 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "le champ cnf/jkt est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:837 +#: src/scm/webid-oidc/errors.scm:912 msgid "the cnf/jkt field is missing" msgstr "le champ cnf/jkt est manquant" -#: src/scm/webid-oidc/errors.scm:841 +#: src/scm/webid-oidc/errors.scm:916 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "le champ client-id est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:842 +#: src/scm/webid-oidc/errors.scm:917 msgid "the client-id field is missing" msgstr "le champ client-id est manquant" -#: src/scm/webid-oidc/errors.scm:846 +#: src/scm/webid-oidc/errors.scm:921 #, scheme-format msgid "the redirect_uris field is incorrect: ~s" msgstr "le champ redirect_uris est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:847 +#: src/scm/webid-oidc/errors.scm:922 msgid "the redirect_uris field is missing" msgstr "le champ redirect_uris est manquant" -#: src/scm/webid-oidc/errors.scm:851 +#: src/scm/webid-oidc/errors.scm:926 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "le champ typ est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:852 +#: src/scm/webid-oidc/errors.scm:927 msgid "the typ field is missing" msgstr "le champ typ est manquant" -#: src/scm/webid-oidc/errors.scm:856 +#: src/scm/webid-oidc/errors.scm:931 #, scheme-format msgid "the jwk field is incorrect: ~s (because ~a)" msgstr "le champ jwk est incorrect : ~s (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:858 +#: src/scm/webid-oidc/errors.scm:933 msgid "the jwk field is missing" msgstr "le champ jwk est manquant" -#: src/scm/webid-oidc/errors.scm:862 +#: src/scm/webid-oidc/errors.scm:937 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "le champ jti est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:863 +#: src/scm/webid-oidc/errors.scm:938 msgid "the jti field is missing" msgstr "le champ jti est manquant" -#: src/scm/webid-oidc/errors.scm:867 +#: src/scm/webid-oidc/errors.scm:942 +#, scheme-format +msgid "the nonce field is incorrect: ~s" +msgstr "le champ nonce est incorrect : ~s" + +#: src/scm/webid-oidc/errors.scm:943 +msgid "the nonce field is missing" +msgstr "le champ nonce est manquant" + +#: src/scm/webid-oidc/errors.scm:947 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "le champ htm est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:868 +#: src/scm/webid-oidc/errors.scm:948 msgid "the htm field is missing" msgstr "le champ htm est manquant" -#: src/scm/webid-oidc/errors.scm:872 +#: src/scm/webid-oidc/errors.scm:952 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "le champ htu est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:873 +#: src/scm/webid-oidc/errors.scm:953 msgid "the htu field is missing" msgstr "le champ htu est manquant" -#: src/scm/webid-oidc/errors.scm:875 +#: src/scm/webid-oidc/errors.scm:955 #, scheme-format msgid "~s is not an access token (because ~a)" msgstr "~s n’est pas un jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:878 +#: src/scm/webid-oidc/errors.scm:958 #, scheme-format msgid "~s is not an access token header (because ~a)" msgstr "~s n’est pas un en-tête de jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:881 +#: src/scm/webid-oidc/errors.scm:961 #, scheme-format msgid "~s is not an access token payload (because ~a)" msgstr "~s n’est pas un contenu de jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:884 +#: src/scm/webid-oidc/errors.scm:964 #, scheme-format msgid "~s is not a DPoP proof (because ~a)" msgstr "~s n’est pas une preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:887 +#: src/scm/webid-oidc/errors.scm:967 #, scheme-format msgid "~s is not a DPoP proof header (because ~a)" msgstr "~s n’est pas un en-tête de preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:890 +#: src/scm/webid-oidc/errors.scm:970 #, scheme-format msgid "~s is not a DPoP proof payload (because ~a)" msgstr "~s n’est pas un contenu de preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:893 +#: src/scm/webid-oidc/errors.scm:973 #, scheme-format msgid "I cannot fetch the issuer configuration of ~a (because ~a)" msgstr "" "je n’ai pas pu récupérer la configuration de l’émetteur ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:900 +#: src/scm/webid-oidc/errors.scm:980 #, scheme-format msgid "I cannot fetch the JWKS of ~a at ~a (because ~a)" msgstr "je n’ai pas pu récupérer le JWKS de ~a à ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:911 +#: src/scm/webid-oidc/errors.scm:991 #, scheme-format msgid "the HTTP method is signed for ~s, but ~s was requested" msgstr "la méthode HTTP a été signée pour ~s, mais ~s a été demandé" -#: src/scm/webid-oidc/errors.scm:914 +#: src/scm/webid-oidc/errors.scm:994 #, scheme-format msgid "the HTTP uri is signed for ~a, but ~a was requested" msgstr "l’uri HTTP a été signé pour ~a, mais ~a a été demandé" -#: src/scm/webid-oidc/errors.scm:917 +#: src/scm/webid-oidc/errors.scm:997 #, scheme-format msgid "the date is ~a, but the DPoP proof is signed in the future at ~a" msgstr "la date est ~a, mais la preuve DPoP a été signée dans le futur à ~a" -#: src/scm/webid-oidc/errors.scm:921 +#: src/scm/webid-oidc/errors.scm:1001 #, scheme-format msgid "the date is ~a, but the DPoP proof was signed too long ago at ~a" msgstr "" "la date est ~a, mais la preuve DPoP a été signée il y a trop longtemps à ~a" -#: src/scm/webid-oidc/errors.scm:930 +#: src/scm/webid-oidc/errors.scm:1010 #, scheme-format msgid "the key ~s does not hash to ~a" msgstr "la clé ~s ne donne pas un hash de ~a" -#: src/scm/webid-oidc/errors.scm:932 +#: src/scm/webid-oidc/errors.scm:1012 #, scheme-format msgid "the key confirmation of ~s failed (because ~a)" msgstr "la confirmation de clé de ~s a échoué (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:934 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "la confirmation de la clé ~s a échoué" -#: src/scm/webid-oidc/errors.scm:936 +#: src/scm/webid-oidc/errors.scm:1016 #, scheme-format msgid "the jti ~s has already been found (because ~a)" msgstr "le jti ~s a déjà été trouvé (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:939 +#: src/scm/webid-oidc/errors.scm:1019 #, scheme-format msgid "I cannot decode ~s as an access token (because ~a)" msgstr "je n’ai pas pu décoder ~s comme jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:1022 #, scheme-format msgid "I cannot encode ~s as an access token (because ~a)" msgstr "je n’ai pas pu encoder ~s comme un jeton d’accès (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:945 +#: src/scm/webid-oidc/errors.scm:1025 #, scheme-format msgid "I cannot decode ~s as a DPoP proof (because ~a)" msgstr "je n’ai pas pu décoder ~s comme preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:948 +#: src/scm/webid-oidc/errors.scm:1028 #, scheme-format msgid "I cannot encode ~s as a DPoP proof (because ~a)" msgstr "je n’ai pas pu encoder ~s comme une preuve DPoP (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:951 +#: src/scm/webid-oidc/errors.scm:1031 #, scheme-format msgid "I could not fetch a RDF graph at ~a (because ~a)" msgstr "je n’ai pas pu récupérer de graphe RDF à ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:954 +#: src/scm/webid-oidc/errors.scm:1034 #, scheme-format msgid "~s is not a client manifest (because ~a)" msgstr "~s n’est pas un manifeste client (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:957 +#: src/scm/webid-oidc/errors.scm:1037 #, scheme-format msgid "~s does not authorize redirection URI ~a" msgstr "~s n’autorise pas l’URI de redirection ~a" -#: src/scm/webid-oidc/errors.scm:960 +#: src/scm/webid-oidc/errors.scm:1040 msgid "I cannot serve a public manifest" msgstr "je ne peux pas servir un manifeste public" -#: src/scm/webid-oidc/errors.scm:962 +#: src/scm/webid-oidc/errors.scm:1042 #, scheme-format msgid "~a does not have a client manifest registration triple" msgstr "~a n’a pas de triplet d’enregistrement de manifeste client" -#: src/scm/webid-oidc/errors.scm:965 +#: src/scm/webid-oidc/errors.scm:1045 #, scheme-format msgid "the client manifest at ~a is advertised for ~a" msgstr "le manifeste client ~a est publié pour ~a" -#: src/scm/webid-oidc/errors.scm:968 +#: src/scm/webid-oidc/errors.scm:1048 #, scheme-format msgid "I could not fetch the client manifest of ~a (because ~a)" msgstr "je n’ai pas pu récupérer le manifeste client de ~a (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:971 +#: src/scm/webid-oidc/errors.scm:1051 #, scheme-format msgid "~s is not an authorization code (because ~a)" msgstr "~s n’est pas un code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:974 +#: src/scm/webid-oidc/errors.scm:1054 #, scheme-format msgid "~s is not an authorization code header (because ~a)" msgstr "~s n’est pas un en-tête de code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:977 +#: src/scm/webid-oidc/errors.scm:1057 #, scheme-format msgid "~s is not an authorization code payload (because ~a)" msgstr "~s n’est pas un contenu de code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:980 +#: src/scm/webid-oidc/errors.scm:1060 #, scheme-format msgid "the current time is ~a, and the authorization code expired at ~a" msgstr "" "la date est actuellement ~a, et le code d’autorisation a expiré à la date ~a" -#: src/scm/webid-oidc/errors.scm:984 +#: src/scm/webid-oidc/errors.scm:1064 #, scheme-format msgid "I cannot decode ~s as an authorization code (because ~a)" msgstr "je n’ai pas pu décoder ~s comme un code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:987 +#: src/scm/webid-oidc/errors.scm:1067 #, scheme-format msgid "I cannot encode ~s as an authorization code (because ~a)" msgstr "je n’ai pas pu encoder ~s comme un code d’autorisation (parce que ~a)" -#: src/scm/webid-oidc/errors.scm:990 +#: src/scm/webid-oidc/errors.scm:1070 #, scheme-format msgid "there is no such refresh token as ~s" msgstr "il n’y a pas de jeton de rafraîchissement ~s" -#: src/scm/webid-oidc/errors.scm:993 +#: src/scm/webid-oidc/errors.scm:1073 #, scheme-format msgid "" "the refresh token is bound to a key confirmed as ~s, but it is used with key " "~s" msgstr "" -"le jeton de rafraîchissement est lié à une clé confirmée par ~s, mais il est " +"Le jeton de rafraîchissement est lié à une clé confirmée par ~s, mais il est " "utilisé avec la clé ~s" -#: src/scm/webid-oidc/errors.scm:998 +#: src/scm/webid-oidc/errors.scm:1076 +#, scheme-format +msgid "I cannot decode ~s as an ID token (because ~a)" +msgstr "je n’ai pas pu décoder ~s comme jeton d’identité (parce que ~a)" + +#: src/scm/webid-oidc/errors.scm:1079 +#, scheme-format +msgid "I cannot encode ~s as an ID token (because ~a)" +msgstr "je n’ai pas pu encoder ~s comme un jeton d’identité (parce que ~a)" + +#: src/scm/webid-oidc/errors.scm:1082 +#, scheme-format +msgid "~s is not an ID token (because ~a)" +msgstr "~s n’est pas un jeton d’identité (parce que ~a)" + +#: src/scm/webid-oidc/errors.scm:1085 +#, scheme-format +msgid "~s is not an ID token header (because ~a)" +msgstr "~s n’est pas un en-tête de jeton d’identité (parce que ~a)" + +#: src/scm/webid-oidc/errors.scm:1088 +#, scheme-format +msgid "~s is not an ID token payload (because ~a)" +msgstr "~s n’est pas un contenu de jeton d’identité (parce que ~a)" + +#: src/scm/webid-oidc/errors.scm:1093 msgid "that’s it" msgstr "c’est tout" -#: src/scm/webid-oidc/errors.scm:1002 +#: src/scm/webid-oidc/errors.scm:1097 #, scheme-format msgid "~a and ~a" msgstr "~a et ~a" -#: src/scm/webid-oidc/errors.scm:1005 +#: src/scm/webid-oidc/errors.scm:1100 #, scheme-format msgid "~a, ~a" msgstr "~a, ~a" -#: src/scm/webid-oidc/errors.scm:1009 +#: src/scm/webid-oidc/errors.scm:1104 #, scheme-format msgid "the signature ~a does not match key ~s with payload ~a" msgstr "la signature ~a ne correspond pas à la clé ~s avec le contenu ~a" -#: src/scm/webid-oidc/errors.scm:1012 +#: src/scm/webid-oidc/errors.scm:1107 msgid "there is an undefined variable" msgstr "il y a une variable non définie" -#: src/scm/webid-oidc/errors.scm:1014 +#: src/scm/webid-oidc/errors.scm:1109 #, scheme-format msgid "the origin is ~a" msgstr "l’origine est ~a" -#: src/scm/webid-oidc/errors.scm:1017 +#: src/scm/webid-oidc/errors.scm:1112 #, scheme-format msgid "a message is attached: ~a" msgstr "un message est attaché : ~a" -#: src/scm/webid-oidc/errors.scm:1020 +#: src/scm/webid-oidc/errors.scm:1115 #, scheme-format msgid "the values ~s are problematic" msgstr "les valeurs ~s sont problématiques" -#: src/scm/webid-oidc/errors.scm:1023 +#: src/scm/webid-oidc/errors.scm:1118 msgid "there is a kind and args" msgstr "il y a un type et des arguments" -#: src/scm/webid-oidc/errors.scm:1025 +#: src/scm/webid-oidc/errors.scm:1120 msgid "there is an assertion failure" msgstr "il y a un échec d’assertion" -#: src/scm/webid-oidc/errors.scm:1027 +#: src/scm/webid-oidc/errors.scm:1122 #, scheme-format msgid "the program quits with code ~a" msgstr "le programme quitte avec le code ~a" -#: src/scm/webid-oidc/errors.scm:1030 +#: src/scm/webid-oidc/errors.scm:1125 msgid "the program cannot recover from this exception" msgstr "le programme ne peut pas récupérer après cette exception" -#: src/scm/webid-oidc/errors.scm:1032 +#: src/scm/webid-oidc/errors.scm:1127 msgid "there is an error" msgstr "il y a une erreur" -#: src/scm/webid-oidc/errors.scm:1034 +#: src/scm/webid-oidc/errors.scm:1129 #, scheme-format msgid "Unhandled exception type ~a." msgstr "Type d’exception non pris en charge ~a." #, scheme-format -#~ msgid "the sub field is incorrect: ~s" -#~ msgstr "le champ sub est incorrect : ~s" - -#~ msgid "the sub field is missing" -#~ msgstr "le champ sub est manquant" - -#, scheme-format -#~ msgid "the nonce field is incorrect: ~s" -#~ msgstr "le champ nonce est incorrect : ~s" - -#~ msgid "the nonce field is missing" -#~ msgstr "le champ nonce est manquant" - -#, scheme-format -#~ msgid "I cannot decode ~s as an ID token (because ~a)" -#~ msgstr "je n’ai pas pu décoder ~s comme jeton d’identité (parce que ~a)" - -#, scheme-format -#~ msgid "I cannot encode ~s as an ID token (because ~a)" -#~ msgstr "je n’ai pas pu encoder ~s comme un jeton d’identité (parce que ~a)" - -#, scheme-format #~ msgid "the grant type ~s is not supported" #~ msgstr "le type d’octroi ~s n’est pas supporté " @@ -662,18 +683,6 @@ msgstr "Type d’exception non pris en charge ~a." #~ msgstr "il n’y a pas de jeton de rafraîchissement dans la requête" #, scheme-format -#~ msgid "~s is not an ID token (because ~a)" -#~ msgstr "~s n’est pas un jeton d’identité (parce que ~a)" - -#, scheme-format -#~ msgid "~s is not an ID token header (because ~a)" -#~ msgstr "~s n’est pas un en-tête de jeton d’identité (parce que ~a)" - -#, scheme-format -#~ msgid "~s is not an ID token payload (because ~a)" -#~ msgstr "~s n’est pas un contenu de jeton d’identité (parce que ~a)" - -#, scheme-format #~ msgid "" #~ "I couldn’t set the locale to ~s as an approximation of the client locale " #~ "~s" diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index e645b52..9fadaa3 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: webid-oidc SNAPSHOT\n" "Report-Msgid-Bugs-To: vivien@planete-kraus.eu\n" -"POT-Creation-Date: 2021-05-10 22:43+0200\n" +"POT-Creation-Date: 2021-05-10 22:46+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -122,496 +122,539 @@ msgstr "" msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "" -#: src/scm/webid-oidc/errors.scm:718 +#: src/scm/webid-oidc/errors.scm:788 msgid "that’s how it is" msgstr "" -#: src/scm/webid-oidc/errors.scm:723 +#: src/scm/webid-oidc/errors.scm:793 #, scheme-format msgid "the value ~s is not a base64 string (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:726 +#: src/scm/webid-oidc/errors.scm:796 #, scheme-format msgid "the value ~s is not JSON (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:729 +#: src/scm/webid-oidc/errors.scm:799 #, scheme-format msgid "the value ~s is not Turtle (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:732 +#: src/scm/webid-oidc/errors.scm:802 #, scheme-format msgid "the value ~s does not identify an elleptic curve" msgstr "" -#: src/scm/webid-oidc/errors.scm:737 +#: src/scm/webid-oidc/errors.scm:807 #, scheme-format msgid "the value ~s does not identify a JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:739 +#: src/scm/webid-oidc/errors.scm:809 #, scheme-format msgid "the value ~s does not identify a JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:744 +#: src/scm/webid-oidc/errors.scm:814 #, scheme-format msgid "the value ~s does not identify a public JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:746 +#: src/scm/webid-oidc/errors.scm:816 #, scheme-format msgid "the value ~s does not identify a public JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:751 +#: src/scm/webid-oidc/errors.scm:821 #, scheme-format msgid "the value ~s does not identify a private JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:753 +#: src/scm/webid-oidc/errors.scm:823 #, scheme-format msgid "the value ~s does not identify a private JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:758 +#: src/scm/webid-oidc/errors.scm:828 #, scheme-format msgid "the value ~s does not identify a JWKS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:760 +#: src/scm/webid-oidc/errors.scm:830 #, scheme-format msgid "the value ~s does not identify a JWKS" msgstr "" -#: src/scm/webid-oidc/errors.scm:763 +#: src/scm/webid-oidc/errors.scm:833 #, scheme-format msgid "the value ~s does not identify a hash algorithm" msgstr "" -#: src/scm/webid-oidc/errors.scm:766 +#: src/scm/webid-oidc/errors.scm:836 #, scheme-format msgid "the value ~s is not an alist or misses key ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:769 +#: src/scm/webid-oidc/errors.scm:839 #, scheme-format msgid "the value ~s is not a JWS header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:772 +#: src/scm/webid-oidc/errors.scm:842 #, scheme-format msgid "the value ~s is not a JWS payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:775 +#: src/scm/webid-oidc/errors.scm:845 #, scheme-format msgid "the value ~s is not a JWS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:778 +#: src/scm/webid-oidc/errors.scm:848 #, scheme-format msgid "the string ~s cannot be split in 3 parts with ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:781 +#: src/scm/webid-oidc/errors.scm:851 #, scheme-format msgid "" "all key candidates failed to verify signature ~s with algorithm ~s and " "payload ~a (there were ~a: ~s)" msgstr "" -#: src/scm/webid-oidc/errors.scm:784 +#: src/scm/webid-oidc/errors.scm:854 #, scheme-format msgid "I cannot decode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:787 +#: src/scm/webid-oidc/errors.scm:857 #, scheme-format msgid "I cannot encode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:790 +#: src/scm/webid-oidc/errors.scm:860 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:795 +#: src/scm/webid-oidc/errors.scm:865 #, scheme-format msgid "the header ~a should not have the value ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:797 +#: src/scm/webid-oidc/errors.scm:867 #, scheme-format msgid "the header ~a should be present" msgstr "" -#: src/scm/webid-oidc/errors.scm:800 +#: src/scm/webid-oidc/errors.scm:870 #, scheme-format msgid "the server response wasn't expected: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:806 +#: src/scm/webid-oidc/errors.scm:876 #, scheme-format msgid "the value ~s is not an OIDC configuration (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:811 +#: src/scm/webid-oidc/errors.scm:881 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:812 +#: src/scm/webid-oidc/errors.scm:882 msgid "the webid field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:816 +#: src/scm/webid-oidc/errors.scm:886 +#, scheme-format +msgid "the sub field is incorrect: ~s" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:887 +msgid "the sub field is missing" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:891 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:817 +#: src/scm/webid-oidc/errors.scm:892 msgid "the iss field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:821 +#: src/scm/webid-oidc/errors.scm:896 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:822 +#: src/scm/webid-oidc/errors.scm:897 msgid "the aud field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:826 +#: src/scm/webid-oidc/errors.scm:901 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:827 +#: src/scm/webid-oidc/errors.scm:902 msgid "the iat field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:831 +#: src/scm/webid-oidc/errors.scm:906 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:832 +#: src/scm/webid-oidc/errors.scm:907 msgid "the exp field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:836 +#: src/scm/webid-oidc/errors.scm:911 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:837 +#: src/scm/webid-oidc/errors.scm:912 msgid "the cnf/jkt field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:841 +#: src/scm/webid-oidc/errors.scm:916 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:842 +#: src/scm/webid-oidc/errors.scm:917 msgid "the client-id field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:846 +#: src/scm/webid-oidc/errors.scm:921 #, scheme-format msgid "the redirect_uris field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:847 +#: src/scm/webid-oidc/errors.scm:922 msgid "the redirect_uris field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:851 +#: src/scm/webid-oidc/errors.scm:926 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:852 +#: src/scm/webid-oidc/errors.scm:927 msgid "the typ field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:856 +#: src/scm/webid-oidc/errors.scm:931 #, scheme-format msgid "the jwk field is incorrect: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:858 +#: src/scm/webid-oidc/errors.scm:933 msgid "the jwk field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:862 +#: src/scm/webid-oidc/errors.scm:937 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:863 +#: src/scm/webid-oidc/errors.scm:938 msgid "the jti field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:867 +#: src/scm/webid-oidc/errors.scm:942 +#, scheme-format +msgid "the nonce field is incorrect: ~s" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:943 +msgid "the nonce field is missing" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:947 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:868 +#: src/scm/webid-oidc/errors.scm:948 msgid "the htm field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:872 +#: src/scm/webid-oidc/errors.scm:952 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:873 +#: src/scm/webid-oidc/errors.scm:953 msgid "the htu field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:875 +#: src/scm/webid-oidc/errors.scm:955 #, scheme-format msgid "~s is not an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:878 +#: src/scm/webid-oidc/errors.scm:958 #, scheme-format msgid "~s is not an access token header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:881 +#: src/scm/webid-oidc/errors.scm:961 #, scheme-format msgid "~s is not an access token payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:884 +#: src/scm/webid-oidc/errors.scm:964 #, scheme-format msgid "~s is not a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:887 +#: src/scm/webid-oidc/errors.scm:967 #, scheme-format msgid "~s is not a DPoP proof header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:890 +#: src/scm/webid-oidc/errors.scm:970 #, scheme-format msgid "~s is not a DPoP proof payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:893 +#: src/scm/webid-oidc/errors.scm:973 #, scheme-format msgid "I cannot fetch the issuer configuration of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:900 +#: src/scm/webid-oidc/errors.scm:980 #, scheme-format msgid "I cannot fetch the JWKS of ~a at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:911 +#: src/scm/webid-oidc/errors.scm:991 #, scheme-format msgid "the HTTP method is signed for ~s, but ~s was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:914 +#: src/scm/webid-oidc/errors.scm:994 #, scheme-format msgid "the HTTP uri is signed for ~a, but ~a was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:917 +#: src/scm/webid-oidc/errors.scm:997 #, scheme-format msgid "the date is ~a, but the DPoP proof is signed in the future at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:921 +#: src/scm/webid-oidc/errors.scm:1001 #, scheme-format msgid "the date is ~a, but the DPoP proof was signed too long ago at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:930 +#: src/scm/webid-oidc/errors.scm:1010 #, scheme-format msgid "the key ~s does not hash to ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:932 +#: src/scm/webid-oidc/errors.scm:1012 #, scheme-format msgid "the key confirmation of ~s failed (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:934 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "" -#: src/scm/webid-oidc/errors.scm:936 +#: src/scm/webid-oidc/errors.scm:1016 #, scheme-format msgid "the jti ~s has already been found (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:939 +#: src/scm/webid-oidc/errors.scm:1019 #, scheme-format msgid "I cannot decode ~s as an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:1022 #, scheme-format msgid "I cannot encode ~s as an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:945 +#: src/scm/webid-oidc/errors.scm:1025 #, scheme-format msgid "I cannot decode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:948 +#: src/scm/webid-oidc/errors.scm:1028 #, scheme-format msgid "I cannot encode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:951 +#: src/scm/webid-oidc/errors.scm:1031 #, scheme-format msgid "I could not fetch a RDF graph at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:954 +#: src/scm/webid-oidc/errors.scm:1034 #, scheme-format msgid "~s is not a client manifest (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:957 +#: src/scm/webid-oidc/errors.scm:1037 #, scheme-format msgid "~s does not authorize redirection URI ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:960 +#: src/scm/webid-oidc/errors.scm:1040 msgid "I cannot serve a public manifest" msgstr "" -#: src/scm/webid-oidc/errors.scm:962 +#: src/scm/webid-oidc/errors.scm:1042 #, scheme-format msgid "~a does not have a client manifest registration triple" msgstr "" -#: src/scm/webid-oidc/errors.scm:965 +#: src/scm/webid-oidc/errors.scm:1045 #, scheme-format msgid "the client manifest at ~a is advertised for ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:968 +#: src/scm/webid-oidc/errors.scm:1048 #, scheme-format msgid "I could not fetch the client manifest of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:971 +#: src/scm/webid-oidc/errors.scm:1051 #, scheme-format msgid "~s is not an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:974 +#: src/scm/webid-oidc/errors.scm:1054 #, scheme-format msgid "~s is not an authorization code header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:977 +#: src/scm/webid-oidc/errors.scm:1057 #, scheme-format msgid "~s is not an authorization code payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:980 +#: src/scm/webid-oidc/errors.scm:1060 #, scheme-format msgid "the current time is ~a, and the authorization code expired at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:984 +#: src/scm/webid-oidc/errors.scm:1064 #, scheme-format msgid "I cannot decode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:987 +#: src/scm/webid-oidc/errors.scm:1067 #, scheme-format msgid "I cannot encode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:990 +#: src/scm/webid-oidc/errors.scm:1070 #, scheme-format msgid "there is no such refresh token as ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:993 +#: src/scm/webid-oidc/errors.scm:1073 #, scheme-format msgid "" "the refresh token is bound to a key confirmed as ~s, but it is used with key " "~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:998 +#: src/scm/webid-oidc/errors.scm:1076 +#, scheme-format +msgid "I cannot decode ~s as an ID token (because ~a)" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1079 +#, scheme-format +msgid "I cannot encode ~s as an ID token (because ~a)" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1082 +#, scheme-format +msgid "~s is not an ID token (because ~a)" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1085 +#, scheme-format +msgid "~s is not an ID token header (because ~a)" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1088 +#, scheme-format +msgid "~s is not an ID token payload (because ~a)" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:1093 msgid "that’s it" msgstr "" -#: src/scm/webid-oidc/errors.scm:1002 +#: src/scm/webid-oidc/errors.scm:1097 #, scheme-format msgid "~a and ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1005 +#: src/scm/webid-oidc/errors.scm:1100 #, scheme-format msgid "~a, ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1009 +#: src/scm/webid-oidc/errors.scm:1104 #, scheme-format msgid "the signature ~a does not match key ~s with payload ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1012 +#: src/scm/webid-oidc/errors.scm:1107 msgid "there is an undefined variable" msgstr "" -#: src/scm/webid-oidc/errors.scm:1014 +#: src/scm/webid-oidc/errors.scm:1109 #, scheme-format msgid "the origin is ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1017 +#: src/scm/webid-oidc/errors.scm:1112 #, scheme-format msgid "a message is attached: ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1020 +#: src/scm/webid-oidc/errors.scm:1115 #, scheme-format msgid "the values ~s are problematic" msgstr "" -#: src/scm/webid-oidc/errors.scm:1023 +#: src/scm/webid-oidc/errors.scm:1118 msgid "there is a kind and args" msgstr "" -#: src/scm/webid-oidc/errors.scm:1025 +#: src/scm/webid-oidc/errors.scm:1120 msgid "there is an assertion failure" msgstr "" -#: src/scm/webid-oidc/errors.scm:1027 +#: src/scm/webid-oidc/errors.scm:1122 #, scheme-format msgid "the program quits with code ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1030 +#: src/scm/webid-oidc/errors.scm:1125 msgid "the program cannot recover from this exception" msgstr "" -#: src/scm/webid-oidc/errors.scm:1032 +#: src/scm/webid-oidc/errors.scm:1127 msgid "there is an error" msgstr "" -#: src/scm/webid-oidc/errors.scm:1034 +#: src/scm/webid-oidc/errors.scm:1129 #, scheme-format msgid "Unhandled exception type ~a." msgstr "" diff --git a/src/scm/webid-oidc/Makefile.am b/src/scm/webid-oidc/Makefile.am index d18d5fc..56b50ec 100644 --- a/src/scm/webid-oidc/Makefile.am +++ b/src/scm/webid-oidc/Makefile.am @@ -12,7 +12,8 @@ dist_webidoidcmod_DATA += \ %reldir%/fetch.scm \ %reldir%/client-manifest.scm \ %reldir%/authorization-code.scm \ - %reldir%/refresh-token.scm + %reldir%/refresh-token.scm \ + %reldir%/oidc-id-token.scm webidoidcgo_DATA += \ %reldir%/errors.go \ %reldir%/stubs.go \ @@ -27,4 +28,5 @@ webidoidcgo_DATA += \ %reldir%/fetch.go \ %reldir%/client-manifest.go \ %reldir%/authorization-code.go \ - %reldir%/refresh-token.go + %reldir%/refresh-token.go \ + %reldir%/oidc-id-token.go diff --git a/src/scm/webid-oidc/errors.scm b/src/scm/webid-oidc/errors.scm index 0ff1061..79419d6 100644 --- a/src/scm/webid-oidc/errors.scm +++ b/src/scm/webid-oidc/errors.scm @@ -249,6 +249,16 @@ (raise-exception ((record-constructor &incorrect-webid-field) value))) +(define-public &incorrect-sub-field + (make-exception-type + '&incorrect-sub-field + &external-error + '(value))) + +(define-public (raise-incorrect-sub-field value) + (raise-exception + ((record-constructor &incorrect-sub-field) value))) + (define-public &incorrect-iss-field (make-exception-type '&incorrect-iss-field @@ -349,6 +359,16 @@ (raise-exception ((record-constructor &incorrect-jti-field) value))) +(define-public &incorrect-nonce-field + (make-exception-type + '&incorrect-nonce-field + &external-error + '(value))) + +(define-public (raise-incorrect-nonce-field value) + (raise-exception + ((record-constructor &incorrect-nonce-field) value))) + (define-public &incorrect-htm-field (make-exception-type '&incorrect-htm-field @@ -707,6 +727,56 @@ (raise-exception ((record-constructor &invalid-key-for-refresh-token) key jkt))) +(define-public ¬-an-id-token + (make-exception-type + '¬-an-id-token + &external-error + '(value cause))) + +(define-public (raise-not-an-id-token value cause) + (raise-exception + ((record-constructor ¬-an-id-token) value cause))) + +(define-public ¬-an-id-token-header + (make-exception-type + '¬-an-id-token-header + &external-error + '(value cause))) + +(define-public (raise-not-an-id-token-header value cause) + (raise-exception + ((record-constructor ¬-an-id-token-header) value cause))) + +(define-public ¬-an-id-token-payload + (make-exception-type + '¬-an-id-token-payload + &external-error + '(value cause))) + +(define-public (raise-not-an-id-token-payload value cause) + (raise-exception + ((record-constructor ¬-an-id-token-payload) value cause))) + +(define-public &cannot-decode-id-token + (make-exception-type + '&cannot-decode-id-token + &external-error + '(value cause))) + +(define-public (raise-cannot-decode-id-token value cause) + (raise-exception + ((record-constructor &cannot-decode-id-token) value cause))) + +(define-public &cannot-encode-id-token + (make-exception-type + '&cannot-encode-id-token + &external-error + '(id-token key cause))) + +(define-public (raise-cannot-encode-id-token id-token key cause) + (raise-exception + ((record-constructor &cannot-encode-id-token) id-token key cause))) + (define*-public (error->str err #:key (max-depth #f)) (if (record? err) (let* ((type (record-type-descriptor err)) @@ -810,6 +880,11 @@ (if value (format #f (G_ "the webid field is incorrect: ~s") value) (format #f (G_ "the webid field is missing"))))) + ((&incorrect-sub-field) + (let ((value (get 'value))) + (if value + (format #f (G_ "the sub field is incorrect: ~s") value) + (format #f (G_ "the sub field is missing"))))) ((&incorrect-iss-field) (let ((value (get 'value))) (if value @@ -861,6 +936,11 @@ (if value (format #f (G_ "the jti field is incorrect: ~s") value) (format #f (G_ "the jti field is missing"))))) + ((&incorrect-nonce-field) + (let ((value (get 'value))) + (if value + (format #f (G_ "the nonce field is incorrect: ~s") value) + (format #f (G_ "the nonce field is missing"))))) ((&incorrect-htm-field) (let ((value (get 'value))) (if value @@ -992,6 +1072,21 @@ ((&invalid-key-for-refresh-token) (format #f (G_ "the refresh token is bound to a key confirmed as ~s, but it is used with key ~s") (get 'jkt) (get 'key))) + ((&cannot-decode-id-token) + (format #f (G_ "I cannot decode ~s as an ID token (because ~a)") + (get 'value) (recurse (get 'cause)))) + ((&cannot-encode-id-token) + (format #f (G_ "I cannot encode ~s as an ID token (because ~a)") + (get 'value) (recurse (get 'cause)))) + ((¬-an-id-token) + (format #f (G_ "~s is not an ID token (because ~a)") + (get 'value) (recurse (get 'cause)))) + ((¬-an-id-token-header) + (format #f (G_ "~s is not an ID token header (because ~a)") + (get 'value) (recurse (get 'cause)))) + ((¬-an-id-token-payload) + (format #f (G_ "~s is not an ID token payload (because ~a)") + (get 'value) (recurse (get 'cause)))) ((&compound-exception) (let ((components (get 'components))) (if (null? components) diff --git a/src/scm/webid-oidc/oidc-id-token.scm b/src/scm/webid-oidc/oidc-id-token.scm new file mode 100644 index 0000000..b13df67 --- /dev/null +++ b/src/scm/webid-oidc/oidc-id-token.scm @@ -0,0 +1,200 @@ +(define-module (webid-oidc oidc-id-token) + #:use-module (webid-oidc oidc-configuration) + #:use-module (webid-oidc errors) + #:use-module (webid-oidc jws) + #:use-module (webid-oidc jti) + #:use-module ((webid-oidc stubs) #:prefix stubs:) + #:use-module (web uri) + #:use-module (ice-9 optargs) + #:use-module (srfi srfi-19)) + +(define-public (the-id-token-header x) + (with-exception-handler + (lambda (error) + (raise-not-an-id-token-header x error)) + (lambda () + (the-jws-header x)))) + +(define-public (id-token-header? x) + (false-if-exception + (and (the-id-token-header x) #t))) + +(define-public (the-id-token-payload x) + (with-exception-handler + (lambda (error) + (raise-not-an-id-token-payload x error)) + (lambda () + (let ((x (the-jws-payload x))) + (let ((webid (assq-ref x 'webid)) + (iss (assq-ref x 'iss)) + (sub (assq-ref x 'sub)) + (aud (assq-ref x 'aud)) + (nonce (assq-ref x 'nonce)) + (iat (assq-ref x 'iat)) + (exp (assq-ref x 'exp))) + (unless (and webid (string? webid) (string->uri webid)) + (raise-incorrect-webid-field webid)) + (unless (and iss (string? iss) (string->uri iss)) + (raise-incorrect-iss-field iss)) + (unless (string? sub) + (raise-incorrect-sub-field sub)) + (unless (and aud (string? aud) (string->uri aud)) + (raise-incorrect-aud-field aud)) + (unless (string? nonce) + (raise-incorrect-nonce-field nonce)) + (unless (integer? iat) + (raise-incorrect-iat-field iat)) + (unless (and (integer? exp) (>= exp iat)) + (raise-incorrect-exp-field exp)) + x))))) + +(define-public (id-token-payload? x) + (false-if-exception + (and (the-id-token-header x) #t))) + +(define-public (the-id-token x) + (with-exception-handler + (lambda (cause) + (raise-not-an-id-token x cause)) + (lambda () + (cons (the-id-token-header (car x)) + (the-id-token-payload (cdr x)))))) + +(define-public (id-token? x) + (false-if-exception + (and (the-id-token x) #t))) + +(define-public (make-id-token header payload) + (the-id-token + (cons header payload))) + +(define-public (make-id-token-payload webid iss sub aud nonce exp iat) + (when (date? exp) + (set! exp (date->time-utc exp))) + (when (time? exp) + (set! exp (time-second exp))) + (when (date? iat) + (set! iat (date->time-utc iat))) + (when (time? iat) + (set! iat (time-second iat))) + (when (uri? webid) + (set! webid (uri->string webid))) + (when (uri? iss) + (set! iss (uri->string iss))) + (when (uri? aud) + (set! aud (uri->string aud))) + (the-id-token-payload + `((webid . ,webid) + (iss . ,iss) + (sub . ,sub) + (aud . ,aud) + (nonce . ,nonce) + (exp . ,exp) + (iat . ,iat)))) + +(define-public (id-token-header code) + (car (the-id-token code))) + +(define-public (id-token-payload code) + (cdr (the-id-token code))) + +(define-public (id-token-alg code) + (when (id-token? code) + (set! code (id-token-header code))) + (jws-alg (the-id-token-header code))) + +(define-public (id-token-webid code) + (when (id-token? code) + (set! code (id-token-payload code))) + (string->uri + (assq-ref (the-id-token-payload code) 'webid))) + +(define-public (id-token-iss code) + (when (id-token? code) + (set! code (id-token-payload code))) + (string->uri + (assq-ref (the-id-token-payload code) 'iss))) + +(define-public (id-token-sub code) + (when (id-token? code) + (set! code (id-token-payload code))) + (assq-ref (the-id-token-payload code) 'sub)) + +(define-public (id-token-aud code) + (when (id-token? code) + (set! code (id-token-payload code))) + (string->uri + (assq-ref (the-id-token-payload code) 'aud))) + +(define-public (id-token-nonce code) + (when (id-token? code) + (set! code (id-token-payload code))) + (assq-ref (the-id-token-payload code) 'nonce)) + +(define-public (id-token-exp code) + (when (id-token? code) + (set! code (id-token-payload code))) + (time-utc->date + (make-time time-utc 0 (assq-ref + (the-id-token-payload code) + 'exp)))) + +(define-public (id-token-iat code) + (when (id-token? code) + (set! code (id-token-payload code))) + (time-utc->date + (make-time time-utc 0 (assq-ref + (the-id-token-payload code) + 'iat)))) + +(define*-public (id-token-decode str #:key (http-get http-get)) + (with-exception-handler + (lambda (error) + (raise-cannot-decode-id-token str error)) + (lambda () + (jws-decode + str + (lambda (token) + (let ((iss (id-token-iss token))) + (let ((cfg + (with-exception-handler + (lambda (error) + (raise-cannot-fetch-issuer-configuration iss error)) + (lambda () + (get-oidc-configuration + (uri-host iss) + #:userinfo (uri-userinfo iss) + #:port (uri-port iss) + #:http-get http-get))))) + (with-exception-handler + (lambda (error) + (raise-cannot-fetch-jwks iss + (oidc-configuration-jwks-uri cfg) + error)) + (lambda () + (oidc-configuration-jwks cfg #:http-get http-get)))))))))) + +(define-public (id-token-encode id-token key) + (with-exception-handler + (lambda (error) + (raise-cannot-encode-id-token id-token key error)) + (lambda () + (jws-encode id-token key)))) + +(define*-public (issue-id-token + issuer-key + #:key + (alg #f) + (webid #f) + (iss #f) + (sub #f) + (aud #f) + (exp #f) + (iat #f)) + (unless sub + (set! sub webid)) + (id-token-encode + (make-id-token + `((alg . ,(symbol->string alg))) + (make-id-token-payload webid iss sub aud (stubs:random 12) exp iat)) + issuer-key)) |