From fb6593ab973e837fa936222b65f24acf26f776f0 Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Wed, 2 Dec 2020 09:31:05 +0100 Subject: Add the refresh token code --- doc/webid-oidc.texi | 9 ++ po/fr.po | 226 +++++++++++++++++---------------- po/webid-oidc.pot | 212 ++++++++++++++++--------------- src/scm/webid-oidc/Makefile.am | 6 +- src/scm/webid-oidc/errors.scm | 34 ++++- src/scm/webid-oidc/refresh-token.scm | 111 ++++++++++++++++ src/scm/webid-oidc/testing.scm | 4 +- tests/Makefile.am | 6 +- tests/refresh-token-with-wrong-key.scm | 29 +++++ tests/refresh-token.scm | 52 ++++++++ tests/too-many-refresh-tokens.scm | 50 ++++++++ 11 files changed, 519 insertions(+), 220 deletions(-) create mode 100644 src/scm/webid-oidc/refresh-token.scm create mode 100644 tests/refresh-token-with-wrong-key.scm create mode 100644 tests/refresh-token.scm create mode 100644 tests/too-many-refresh-tokens.scm diff --git a/doc/webid-oidc.texi b/doc/webid-oidc.texi index f8e4208..70df6d4 100644 --- a/doc/webid-oidc.texi +++ b/doc/webid-oidc.texi @@ -629,6 +629,15 @@ 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 + @node GNU Free Documentation License @appendix GNU Free Documentation License diff --git a/po/fr.po b/po/fr.po index 50cffce..ae51015 100644 --- a/po/fr.po +++ b/po/fr.po @@ -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:698 +#: src/scm/webid-oidc/errors.scm:718 msgid "that’s how it is" msgstr "c’est comme ça" -#: src/scm/webid-oidc/errors.scm:703 +#: src/scm/webid-oidc/errors.scm:723 #, 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:706 +#: src/scm/webid-oidc/errors.scm:726 #, 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:709 +#: src/scm/webid-oidc/errors.scm:729 #, 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:712 +#: src/scm/webid-oidc/errors.scm:732 #, 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:717 +#: src/scm/webid-oidc/errors.scm:737 #, 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:719 +#: src/scm/webid-oidc/errors.scm:739 #, 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:724 +#: src/scm/webid-oidc/errors.scm:744 #, 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:726 +#: src/scm/webid-oidc/errors.scm:746 #, 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:731 +#: src/scm/webid-oidc/errors.scm:751 #, 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:733 +#: src/scm/webid-oidc/errors.scm:753 #, 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:738 +#: src/scm/webid-oidc/errors.scm:758 #, 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:740 +#: src/scm/webid-oidc/errors.scm:760 #, 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:743 +#: src/scm/webid-oidc/errors.scm:763 #, 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:746 +#: src/scm/webid-oidc/errors.scm:766 #, 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:749 +#: src/scm/webid-oidc/errors.scm:769 #, 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:752 +#: src/scm/webid-oidc/errors.scm:772 #, 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:755 +#: src/scm/webid-oidc/errors.scm:775 #, 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:758 +#: src/scm/webid-oidc/errors.scm:778 #, 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:761 +#: src/scm/webid-oidc/errors.scm:781 #, 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:764 +#: src/scm/webid-oidc/errors.scm:784 #, 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:767 +#: src/scm/webid-oidc/errors.scm:787 #, 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:770 +#: src/scm/webid-oidc/errors.scm:790 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" @@ -247,372 +247,386 @@ 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:775 +#: src/scm/webid-oidc/errors.scm:795 #, 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:777 +#: src/scm/webid-oidc/errors.scm:797 #, 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:780 +#: src/scm/webid-oidc/errors.scm:800 #, 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:786 +#: src/scm/webid-oidc/errors.scm:806 #, 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:791 +#: src/scm/webid-oidc/errors.scm:811 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "le champ webid est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:792 +#: src/scm/webid-oidc/errors.scm:812 msgid "the webid field is missing" msgstr "le champ webid est manquant" -#: src/scm/webid-oidc/errors.scm:796 +#: src/scm/webid-oidc/errors.scm:816 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "le champ iss est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:797 +#: src/scm/webid-oidc/errors.scm:817 msgid "the iss field is missing" msgstr "le champ iss est manquant" -#: src/scm/webid-oidc/errors.scm:801 +#: src/scm/webid-oidc/errors.scm:821 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "le champ aud est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:802 +#: src/scm/webid-oidc/errors.scm:822 msgid "the aud field is missing" msgstr "le champ aud est manquant" -#: src/scm/webid-oidc/errors.scm:806 +#: src/scm/webid-oidc/errors.scm:826 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "le champ iat est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:807 +#: src/scm/webid-oidc/errors.scm:827 msgid "the iat field is missing" msgstr "le champ iat est manquant" -#: src/scm/webid-oidc/errors.scm:811 +#: src/scm/webid-oidc/errors.scm:831 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "le champ exp est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:812 +#: src/scm/webid-oidc/errors.scm:832 msgid "the exp field is missing" msgstr "le champ exp est manquant" -#: src/scm/webid-oidc/errors.scm:816 +#: src/scm/webid-oidc/errors.scm:836 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "le champ cnf/jkt est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:817 +#: src/scm/webid-oidc/errors.scm:837 msgid "the cnf/jkt field is missing" msgstr "le champ cnf/jkt est manquant" -#: src/scm/webid-oidc/errors.scm:821 +#: src/scm/webid-oidc/errors.scm:841 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "le champ client-id est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:822 +#: src/scm/webid-oidc/errors.scm:842 msgid "the client-id field is missing" msgstr "le champ client-id est manquant" -#: src/scm/webid-oidc/errors.scm:826 +#: src/scm/webid-oidc/errors.scm:846 #, scheme-format msgid "the redirect_uris field is incorrect: ~s" msgstr "le champ redirect_uris est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:827 +#: src/scm/webid-oidc/errors.scm:847 msgid "the redirect_uris field is missing" msgstr "le champ redirect_uris est manquant" -#: src/scm/webid-oidc/errors.scm:831 +#: src/scm/webid-oidc/errors.scm:851 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "le champ typ est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:832 +#: src/scm/webid-oidc/errors.scm:852 msgid "the typ field is missing" msgstr "le champ typ est manquant" -#: src/scm/webid-oidc/errors.scm:836 +#: src/scm/webid-oidc/errors.scm:856 #, 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:838 +#: src/scm/webid-oidc/errors.scm:858 msgid "the jwk field is missing" msgstr "le champ jwk est manquant" -#: src/scm/webid-oidc/errors.scm:842 +#: src/scm/webid-oidc/errors.scm:862 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "le champ jti est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:843 +#: src/scm/webid-oidc/errors.scm:863 msgid "the jti field is missing" msgstr "le champ jti est manquant" -#: src/scm/webid-oidc/errors.scm:847 +#: src/scm/webid-oidc/errors.scm:867 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "le champ htm est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:848 +#: src/scm/webid-oidc/errors.scm:868 msgid "the htm field is missing" msgstr "le champ htm est manquant" -#: src/scm/webid-oidc/errors.scm:852 +#: src/scm/webid-oidc/errors.scm:872 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "le champ htu est incorrect : ~s" -#: src/scm/webid-oidc/errors.scm:853 +#: src/scm/webid-oidc/errors.scm:873 msgid "the htu field is missing" msgstr "le champ htu est manquant" -#: src/scm/webid-oidc/errors.scm:855 +#: src/scm/webid-oidc/errors.scm:875 #, 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:858 +#: src/scm/webid-oidc/errors.scm:878 #, 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:861 +#: src/scm/webid-oidc/errors.scm:881 #, 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:864 +#: src/scm/webid-oidc/errors.scm:884 #, 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:867 +#: src/scm/webid-oidc/errors.scm:887 #, 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:870 +#: src/scm/webid-oidc/errors.scm:890 #, 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:873 +#: src/scm/webid-oidc/errors.scm:893 #, 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:880 +#: src/scm/webid-oidc/errors.scm:900 #, 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:891 +#: src/scm/webid-oidc/errors.scm:911 #, 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:894 +#: src/scm/webid-oidc/errors.scm:914 #, 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:897 +#: src/scm/webid-oidc/errors.scm:917 #, 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:901 +#: src/scm/webid-oidc/errors.scm:921 #, 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:910 +#: src/scm/webid-oidc/errors.scm:930 #, 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:912 +#: src/scm/webid-oidc/errors.scm:932 #, 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:914 +#: src/scm/webid-oidc/errors.scm:934 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "la confirmation de la clé ~s a échoué" -#: src/scm/webid-oidc/errors.scm:916 +#: src/scm/webid-oidc/errors.scm:936 #, 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:919 +#: src/scm/webid-oidc/errors.scm:939 #, 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:922 +#: src/scm/webid-oidc/errors.scm:942 #, scheme-format msgid "I cannot encode ~s as an access token with key ~s (because ~a)" msgstr "" "je n’ai pas pu encoder ~s comme un jeton d’accès avec la clé ~s (parce que " "~a)" -#: src/scm/webid-oidc/errors.scm:925 +#: src/scm/webid-oidc/errors.scm:945 #, 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:928 +#: src/scm/webid-oidc/errors.scm:948 #, 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:931 +#: src/scm/webid-oidc/errors.scm:951 #, 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:934 +#: src/scm/webid-oidc/errors.scm:954 #, 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:937 +#: src/scm/webid-oidc/errors.scm:957 #, 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:940 +#: src/scm/webid-oidc/errors.scm:960 msgid "I cannot serve a public manifest" msgstr "je ne peux pas servir un manifeste public" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:962 #, 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:945 +#: src/scm/webid-oidc/errors.scm:965 #, 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:948 +#: src/scm/webid-oidc/errors.scm:968 #, 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:951 +#: src/scm/webid-oidc/errors.scm:971 #, 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:954 +#: src/scm/webid-oidc/errors.scm:974 #, 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:957 +#: src/scm/webid-oidc/errors.scm:977 #, 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:960 +#: src/scm/webid-oidc/errors.scm:980 #, 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:964 +#: src/scm/webid-oidc/errors.scm:984 #, 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:967 +#: src/scm/webid-oidc/errors.scm:987 #, 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:972 +#: src/scm/webid-oidc/errors.scm:990 +#, 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 +#, 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 " +"utilisé avec la clé ~s" + +#: src/scm/webid-oidc/errors.scm:998 msgid "that’s it" msgstr "c’est tout" -#: src/scm/webid-oidc/errors.scm:976 +#: src/scm/webid-oidc/errors.scm:1002 #, scheme-format msgid "~a and ~a" msgstr "~a et ~a" -#: src/scm/webid-oidc/errors.scm:979 +#: src/scm/webid-oidc/errors.scm:1005 #, scheme-format msgid "~a, ~a" msgstr "~a, ~a" -#: src/scm/webid-oidc/errors.scm:983 +#: src/scm/webid-oidc/errors.scm:1009 #, 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:986 +#: src/scm/webid-oidc/errors.scm:1012 msgid "there is an undefined variable" msgstr "il y a une variable non définie" -#: src/scm/webid-oidc/errors.scm:988 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "the origin is ~a" msgstr "l’origine est ~a" -#: src/scm/webid-oidc/errors.scm:991 +#: src/scm/webid-oidc/errors.scm:1017 #, scheme-format msgid "a message is attached: ~a" msgstr "un message est attaché : ~a" -#: src/scm/webid-oidc/errors.scm:994 +#: src/scm/webid-oidc/errors.scm:1020 #, scheme-format msgid "the values ~s are problematic" msgstr "les valeurs ~s sont problématiques" -#: src/scm/webid-oidc/errors.scm:997 +#: src/scm/webid-oidc/errors.scm:1023 msgid "there is a kind and args" msgstr "il y a un type et des arguments" -#: src/scm/webid-oidc/errors.scm:999 +#: src/scm/webid-oidc/errors.scm:1025 msgid "there is an assertion failure" msgstr "il y a un échec d’assertion" -#: src/scm/webid-oidc/errors.scm:1001 +#: src/scm/webid-oidc/errors.scm:1027 #, scheme-format msgid "the program quits with code ~a" msgstr "le programme quitte avec le code ~a" -#: src/scm/webid-oidc/errors.scm:1004 +#: src/scm/webid-oidc/errors.scm:1030 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:1006 +#: src/scm/webid-oidc/errors.scm:1032 msgid "there is an error" msgstr "il y a une erreur" -#: src/scm/webid-oidc/errors.scm:1008 +#: src/scm/webid-oidc/errors.scm:1034 #, scheme-format msgid "Unhandled exception type ~a." msgstr "Type d’exception non pris en charge ~a." @@ -631,18 +645,6 @@ msgstr "Type d’exception non pris en charge ~a." #~ msgid "the nonce field is missing" #~ msgstr "le champ nonce est manquant" -#, scheme-format -#~ msgid "there is no such refresh token as ~s" -#~ msgstr "il n’y a pas de jeton de rafraîchissement ~s" - -#, 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 utilisé avec la clé ~s" - #, 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)" diff --git a/po/webid-oidc.pot b/po/webid-oidc.pot index 21b10a6..d79d173 100644 --- a/po/webid-oidc.pot +++ b/po/webid-oidc.pot @@ -122,484 +122,496 @@ msgstr "" msgid "Usage: generate-key [NUMBER OF BITS | CURVE]\n" msgstr "" -#: src/scm/webid-oidc/errors.scm:698 +#: src/scm/webid-oidc/errors.scm:718 msgid "that’s how it is" msgstr "" -#: src/scm/webid-oidc/errors.scm:703 +#: src/scm/webid-oidc/errors.scm:723 #, scheme-format msgid "the value ~s is not a base64 string (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:706 +#: src/scm/webid-oidc/errors.scm:726 #, scheme-format msgid "the value ~s is not JSON (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:709 +#: src/scm/webid-oidc/errors.scm:729 #, scheme-format msgid "the value ~s is not Turtle (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:712 +#: src/scm/webid-oidc/errors.scm:732 #, scheme-format msgid "the value ~s does not identify an elleptic curve" msgstr "" -#: src/scm/webid-oidc/errors.scm:717 +#: src/scm/webid-oidc/errors.scm:737 #, scheme-format msgid "the value ~s does not identify a JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:719 +#: src/scm/webid-oidc/errors.scm:739 #, scheme-format msgid "the value ~s does not identify a JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:724 +#: src/scm/webid-oidc/errors.scm:744 #, scheme-format msgid "the value ~s does not identify a public JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:726 +#: src/scm/webid-oidc/errors.scm:746 #, scheme-format msgid "the value ~s does not identify a public JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:731 +#: src/scm/webid-oidc/errors.scm:751 #, scheme-format msgid "the value ~s does not identify a private JWK (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:733 +#: src/scm/webid-oidc/errors.scm:753 #, scheme-format msgid "the value ~s does not identify a private JWK" msgstr "" -#: src/scm/webid-oidc/errors.scm:738 +#: src/scm/webid-oidc/errors.scm:758 #, scheme-format msgid "the value ~s does not identify a JWKS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:740 +#: src/scm/webid-oidc/errors.scm:760 #, scheme-format msgid "the value ~s does not identify a JWKS" msgstr "" -#: src/scm/webid-oidc/errors.scm:743 +#: src/scm/webid-oidc/errors.scm:763 #, scheme-format msgid "the value ~s does not identify a hash algorithm" msgstr "" -#: src/scm/webid-oidc/errors.scm:746 +#: src/scm/webid-oidc/errors.scm:766 #, scheme-format msgid "the value ~s is not an alist or misses key ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:749 +#: src/scm/webid-oidc/errors.scm:769 #, scheme-format msgid "the value ~s is not a JWS header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:752 +#: src/scm/webid-oidc/errors.scm:772 #, scheme-format msgid "the value ~s is not a JWS payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:755 +#: src/scm/webid-oidc/errors.scm:775 #, scheme-format msgid "the value ~s is not a JWS (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:758 +#: src/scm/webid-oidc/errors.scm:778 #, scheme-format msgid "the string ~s cannot be split in 3 parts with ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:761 +#: src/scm/webid-oidc/errors.scm:781 #, 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:764 +#: src/scm/webid-oidc/errors.scm:784 #, scheme-format msgid "I cannot decode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:767 +#: src/scm/webid-oidc/errors.scm:787 #, scheme-format msgid "I cannot encode JWS ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:770 +#: src/scm/webid-oidc/errors.scm:790 #, scheme-format msgid "" "the server request unexpectedly failed with code ~a and reason phrase ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:775 +#: src/scm/webid-oidc/errors.scm:795 #, scheme-format msgid "the header ~a should not have the value ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:777 +#: src/scm/webid-oidc/errors.scm:797 #, scheme-format msgid "the header ~a should be present" msgstr "" -#: src/scm/webid-oidc/errors.scm:780 +#: src/scm/webid-oidc/errors.scm:800 #, scheme-format msgid "the server response wasn't expected: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:786 +#: src/scm/webid-oidc/errors.scm:806 #, scheme-format msgid "the value ~s is not an OIDC configuration (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:791 +#: src/scm/webid-oidc/errors.scm:811 #, scheme-format msgid "the webid field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:792 +#: src/scm/webid-oidc/errors.scm:812 msgid "the webid field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:796 +#: src/scm/webid-oidc/errors.scm:816 #, scheme-format msgid "the iss field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:797 +#: src/scm/webid-oidc/errors.scm:817 msgid "the iss field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:801 +#: src/scm/webid-oidc/errors.scm:821 #, scheme-format msgid "the aud field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:802 +#: src/scm/webid-oidc/errors.scm:822 msgid "the aud field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:806 +#: src/scm/webid-oidc/errors.scm:826 #, scheme-format msgid "the iat field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:807 +#: src/scm/webid-oidc/errors.scm:827 msgid "the iat field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:811 +#: src/scm/webid-oidc/errors.scm:831 #, scheme-format msgid "the exp field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:812 +#: src/scm/webid-oidc/errors.scm:832 msgid "the exp field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:816 +#: src/scm/webid-oidc/errors.scm:836 #, scheme-format msgid "the cnf/jkt field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:817 +#: src/scm/webid-oidc/errors.scm:837 msgid "the cnf/jkt field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:821 +#: src/scm/webid-oidc/errors.scm:841 #, scheme-format msgid "the client-id field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:822 +#: src/scm/webid-oidc/errors.scm:842 msgid "the client-id field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:826 +#: src/scm/webid-oidc/errors.scm:846 #, scheme-format msgid "the redirect_uris field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:827 +#: src/scm/webid-oidc/errors.scm:847 msgid "the redirect_uris field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:831 +#: src/scm/webid-oidc/errors.scm:851 #, scheme-format msgid "the typ field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:832 +#: src/scm/webid-oidc/errors.scm:852 msgid "the typ field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:836 +#: src/scm/webid-oidc/errors.scm:856 #, scheme-format msgid "the jwk field is incorrect: ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:838 +#: src/scm/webid-oidc/errors.scm:858 msgid "the jwk field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:842 +#: src/scm/webid-oidc/errors.scm:862 #, scheme-format msgid "the jti field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:843 +#: src/scm/webid-oidc/errors.scm:863 msgid "the jti field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:847 +#: src/scm/webid-oidc/errors.scm:867 #, scheme-format msgid "the htm field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:848 +#: src/scm/webid-oidc/errors.scm:868 msgid "the htm field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:852 +#: src/scm/webid-oidc/errors.scm:872 #, scheme-format msgid "the htu field is incorrect: ~s" msgstr "" -#: src/scm/webid-oidc/errors.scm:853 +#: src/scm/webid-oidc/errors.scm:873 msgid "the htu field is missing" msgstr "" -#: src/scm/webid-oidc/errors.scm:855 +#: src/scm/webid-oidc/errors.scm:875 #, scheme-format msgid "~s is not an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:858 +#: src/scm/webid-oidc/errors.scm:878 #, scheme-format msgid "~s is not an access token header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:861 +#: src/scm/webid-oidc/errors.scm:881 #, scheme-format msgid "~s is not an access token payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:864 +#: src/scm/webid-oidc/errors.scm:884 #, scheme-format msgid "~s is not a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:867 +#: src/scm/webid-oidc/errors.scm:887 #, scheme-format msgid "~s is not a DPoP proof header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:870 +#: src/scm/webid-oidc/errors.scm:890 #, scheme-format msgid "~s is not a DPoP proof payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:873 +#: src/scm/webid-oidc/errors.scm:893 #, scheme-format msgid "I cannot fetch the issuer configuration of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:880 +#: src/scm/webid-oidc/errors.scm:900 #, scheme-format msgid "I cannot fetch the JWKS of ~a at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:891 +#: src/scm/webid-oidc/errors.scm:911 #, scheme-format msgid "the HTTP method is signed for ~s, but ~s was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:894 +#: src/scm/webid-oidc/errors.scm:914 #, scheme-format msgid "the HTTP uri is signed for ~a, but ~a was requested" msgstr "" -#: src/scm/webid-oidc/errors.scm:897 +#: src/scm/webid-oidc/errors.scm:917 #, 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:901 +#: src/scm/webid-oidc/errors.scm:921 #, 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:910 +#: src/scm/webid-oidc/errors.scm:930 #, scheme-format msgid "the key ~s does not hash to ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:912 +#: src/scm/webid-oidc/errors.scm:932 #, scheme-format msgid "the key confirmation of ~s failed (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:914 +#: src/scm/webid-oidc/errors.scm:934 #, scheme-format msgid "the key confirmation of ~s failed" msgstr "" -#: src/scm/webid-oidc/errors.scm:916 +#: src/scm/webid-oidc/errors.scm:936 #, scheme-format msgid "the jti ~s has already been found (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:919 +#: src/scm/webid-oidc/errors.scm:939 #, scheme-format msgid "I cannot decode ~s as an access token (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:922 +#: src/scm/webid-oidc/errors.scm:942 #, scheme-format msgid "I cannot encode ~s as an access token with key ~s (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:925 +#: src/scm/webid-oidc/errors.scm:945 #, scheme-format msgid "I cannot decode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:928 +#: src/scm/webid-oidc/errors.scm:948 #, scheme-format msgid "I cannot encode ~s as a DPoP proof (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:931 +#: src/scm/webid-oidc/errors.scm:951 #, scheme-format msgid "I could not fetch a RDF graph at ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:934 +#: src/scm/webid-oidc/errors.scm:954 #, scheme-format msgid "~s is not a client manifest (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:937 +#: src/scm/webid-oidc/errors.scm:957 #, scheme-format msgid "~s does not authorize redirection URI ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:940 +#: src/scm/webid-oidc/errors.scm:960 msgid "I cannot serve a public manifest" msgstr "" -#: src/scm/webid-oidc/errors.scm:942 +#: src/scm/webid-oidc/errors.scm:962 #, scheme-format msgid "~a does not have a client manifest registration triple" msgstr "" -#: src/scm/webid-oidc/errors.scm:945 +#: src/scm/webid-oidc/errors.scm:965 #, scheme-format msgid "the client manifest at ~a is advertised for ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:948 +#: src/scm/webid-oidc/errors.scm:968 #, scheme-format msgid "I could not fetch the client manifest of ~a (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:951 +#: src/scm/webid-oidc/errors.scm:971 #, scheme-format msgid "~s is not an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:954 +#: src/scm/webid-oidc/errors.scm:974 #, scheme-format msgid "~s is not an authorization code header (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:957 +#: src/scm/webid-oidc/errors.scm:977 #, scheme-format msgid "~s is not an authorization code payload (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:960 +#: src/scm/webid-oidc/errors.scm:980 #, scheme-format msgid "the current time is ~a, and the authorization code expired at ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:964 +#: src/scm/webid-oidc/errors.scm:984 #, scheme-format msgid "I cannot decode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:967 +#: src/scm/webid-oidc/errors.scm:987 #, scheme-format msgid "I cannot encode ~s as an authorization code (because ~a)" msgstr "" -#: src/scm/webid-oidc/errors.scm:972 +#: src/scm/webid-oidc/errors.scm:990 +#, scheme-format +msgid "there is no such refresh token as ~s" +msgstr "" + +#: src/scm/webid-oidc/errors.scm:993 +#, 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 msgid "that’s it" msgstr "" -#: src/scm/webid-oidc/errors.scm:976 +#: src/scm/webid-oidc/errors.scm:1002 #, scheme-format msgid "~a and ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:979 +#: src/scm/webid-oidc/errors.scm:1005 #, scheme-format msgid "~a, ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:983 +#: src/scm/webid-oidc/errors.scm:1009 #, scheme-format msgid "the signature ~a does not match key ~s with payload ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:986 +#: src/scm/webid-oidc/errors.scm:1012 msgid "there is an undefined variable" msgstr "" -#: src/scm/webid-oidc/errors.scm:988 +#: src/scm/webid-oidc/errors.scm:1014 #, scheme-format msgid "the origin is ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:991 +#: src/scm/webid-oidc/errors.scm:1017 #, scheme-format msgid "a message is attached: ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:994 +#: src/scm/webid-oidc/errors.scm:1020 #, scheme-format msgid "the values ~s are problematic" msgstr "" -#: src/scm/webid-oidc/errors.scm:997 +#: src/scm/webid-oidc/errors.scm:1023 msgid "there is a kind and args" msgstr "" -#: src/scm/webid-oidc/errors.scm:999 +#: src/scm/webid-oidc/errors.scm:1025 msgid "there is an assertion failure" msgstr "" -#: src/scm/webid-oidc/errors.scm:1001 +#: src/scm/webid-oidc/errors.scm:1027 #, scheme-format msgid "the program quits with code ~a" msgstr "" -#: src/scm/webid-oidc/errors.scm:1004 +#: src/scm/webid-oidc/errors.scm:1030 msgid "the program cannot recover from this exception" msgstr "" -#: src/scm/webid-oidc/errors.scm:1006 +#: src/scm/webid-oidc/errors.scm:1032 msgid "there is an error" msgstr "" -#: src/scm/webid-oidc/errors.scm:1008 +#: src/scm/webid-oidc/errors.scm:1034 #, 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 6736595..d18d5fc 100644 --- a/src/scm/webid-oidc/Makefile.am +++ b/src/scm/webid-oidc/Makefile.am @@ -11,7 +11,8 @@ dist_webidoidcmod_DATA += \ %reldir%/dpop-proof.scm \ %reldir%/fetch.scm \ %reldir%/client-manifest.scm \ - %reldir%/authorization-code.scm + %reldir%/authorization-code.scm \ + %reldir%/refresh-token.scm webidoidcgo_DATA += \ %reldir%/errors.go \ %reldir%/stubs.go \ @@ -25,4 +26,5 @@ webidoidcgo_DATA += \ %reldir%/dpop-proof.go \ %reldir%/fetch.go \ %reldir%/client-manifest.go \ - %reldir%/authorization-code.go + %reldir%/authorization-code.go \ + %reldir%/refresh-token.go diff --git a/src/scm/webid-oidc/errors.scm b/src/scm/webid-oidc/errors.scm index 879b23c..e8ab5af 100644 --- a/src/scm/webid-oidc/errors.scm +++ b/src/scm/webid-oidc/errors.scm @@ -687,6 +687,26 @@ (raise-exception ((record-constructor &cannot-encode-authorization-code) authorization-code key cause))) +(define-public &invalid-refresh-token + (make-exception-type + '&invalid-refresh-token + &external-error + '(refresh-token))) + +(define-public (raise-invalid-refresh-token refresh-token) + (raise-exception + ((record-constructor &invalid-refresh-token) refresh-token))) + +(define-public &invalid-key-for-refresh-token + (make-exception-type + '&invalid-key-for-refresh-token + &external-error + '(key jkt))) + +(define-public (raise-invalid-key-for-refresh-token key jkt) + (raise-exception + ((record-constructor &invalid-key-for-refresh-token) key jkt))) + (define*-public (error->str err #:key (max-depth #f)) (if (record? err) (let* ((type (record-type-descriptor err)) @@ -956,16 +976,22 @@ ((¬-an-authorization-code-payload) (format #f (G_ "~s is not an authorization code payload (because ~a)") (get 'value) (recurse (get 'cause)))) - ((&authorization-code-expired) - (format #f (G_ "the current time is ~a, and the authorization code expired at ~a") - (time-second (date->time-utc (get 'current-time))) - (time-second (date->time-utc (get 'exp))))) + ((&authorization-code-expired) + (format #f (G_ "the current time is ~a, and the authorization code expired at ~a") + (time-second (date->time-utc (get 'current-time))) + (time-second (date->time-utc (get 'exp))))) ((&cannot-decode-authorization-code) (format #f (G_ "I cannot decode ~s as an authorization code (because ~a)") (get 'value) (recurse (get 'cause)))) ((&cannot-encode-authorization-code) (format #f (G_ "I cannot encode ~s as an authorization code (because ~a)") (get 'value) (recurse (get 'cause)))) + ((&invalid-refresh-token) + (format #f (G_ "there is no such refresh token as ~s") + (get 'refresh-token))) + ((&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))) ((&compound-exception) (let ((components (get 'components))) (if (null? components) diff --git a/src/scm/webid-oidc/refresh-token.scm b/src/scm/webid-oidc/refresh-token.scm new file mode 100644 index 0000000..d2a7da6 --- /dev/null +++ b/src/scm/webid-oidc/refresh-token.scm @@ -0,0 +1,111 @@ +(define-module (webid-oidc refresh-token) + #:use-module (webid-oidc errors) + #:use-module ((webid-oidc stubs) #:prefix stubs:) + #:use-module (webid-oidc jwk) + #:use-module (web uri) + #:use-module (ice-9 optargs) + #:use-module (ice-9 threads) + #:use-module (srfi srfi-19)) + +(define-public (default-dir) + (let ((xdg-data-home (or + (getenv "XDG_DATA_HOME") + (format #f "~a/.local/share" + (getenv "HOME"))))) + (format #f "~a/webid-oidc" xdg-data-home))) + +(define*-public (list-refresh-tokens + #:key + (dir default-dir)) + (when (thunk? dir) + (set! dir (dir))) + (catch #t + (lambda () + (with-input-from-file (format #f "~a/refresh-tokens.scm" dir) + read)) + (lambda errors + '()))) + +(define mutex (make-mutex)) + +(define* (set-refresh-token-list list + #:key (dir default-dir)) + (when (thunk? dir) + (set! dir (dir))) + (define old-file (format #f "~a/refresh-tokens.scm" dir)) + (define new-file (format #f "~a/refresh-tokens.scm~" dir)) + (stubs:call-with-output-file* + new-file + (lambda (port) + (write list port) + (close-port port))) + (rename-file new-file old-file)) + +(define*-public (update-refresh-token-list f + #:key (dir default-dir)) + (with-mutex mutex + (let ((old (list-refresh-tokens #:dir dir))) + (let ((new (f old))) + (set-refresh-token-list new #:dir dir))))) + +(define (remove sub aud) + (lambda (old) + (filter (lambda (o) + (not (and (equal? (assq-ref o 'sub) + (uri->string sub)) + (equal? (assq-ref o 'aud) + (uri->string aud))))) + old))) + +(define (keep-n n list) + (cond + ((<= n 0) '()) + ((null? list) '()) + (else (cons (car list) (keep-n (- n 1) (cdr list)))))) + +(define (insert sub aud jkt jti) + (define remover (remove sub aud)) + (lambda (old) + (keep-n + 20 + (cons `((sub . ,(uri->string sub)) + (aud . ,(uri->string aud)) + (jkt . ,jkt) + (refresh_token . ,jti)) + (remover old))))) + +(define*-public (issue-refresh-token sub aud jkt + #:key + (dir default-dir)) + (define jti (stubs:random 12)) + (update-refresh-token-list (insert sub aud jkt jti) + #:dir dir) + jti) + +(define*-public (with-refresh-token refresh-token + key + f + #:key + (dir default-dir)) + (let ((list (list-refresh-tokens #:dir dir))) + (define (check list) + (if (null? list) + (raise-invalid-refresh-token refresh-token) + (let ((hd (car list)) + (tl (cdr list))) + (let ((sub (string->uri (assq-ref hd 'sub))) + (aud (string->uri (assq-ref hd 'aud))) + (cnf/jkt (assq-ref hd 'jkt)) + (the-refresh-token (assq-ref hd 'refresh_token))) + (if (string=? refresh-token the-refresh-token) + (begin + (unless (equal? (jkt key) cnf/jkt) + (raise-invalid-key-for-refresh-token key cnf/jkt)) + (f sub aud)) + (check tl)))))) + (check list))) + +(define*-public (remove-refresh-token sub aud + #:key + (dir default-dir)) + (update-refresh-token-list (remove sub aud) #:dir dir)) diff --git a/src/scm/webid-oidc/testing.scm b/src/scm/webid-oidc/testing.scm index d4b7f4d..aecb2a3 100644 --- a/src/scm/webid-oidc/testing.scm +++ b/src/scm/webid-oidc/testing.scm @@ -5,8 +5,10 @@ ;; This module is used only when running tests. (define-public (with-test-environment test-name f) - (let ((cache-dir (format #f "tests/~a.cache" test-name))) + (let ((cache-dir (format #f "tests/~a.cache" test-name)) + (data-dir (format #f "tests/~a.home" test-name))) (setenv "XDG_CACHE_HOME" cache-dir) + (setenv "XDG_DATA_HOME" data-dir) (catch #t (lambda () (mkdir cache-dir)) (lambda err #t)) diff --git a/tests/Makefile.am b/tests/Makefile.am index 8ccfa68..a42529b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,7 +26,10 @@ TESTS = %reldir%/load-library.scm \ %reldir%/dpop-proof-replay.scm \ %reldir%/client-manifest-public.scm \ %reldir%/client-manifest.scm \ - %reldir%/client-manifest-fraudulent.scm + %reldir%/client-manifest-fraudulent.scm \ + %reldir%/refresh-token.scm \ + %reldir%/too-many-refresh-tokens.scm \ + %reldir%/refresh-token-with-wrong-key.scm EXTRA_DIST += $(TESTS) @@ -38,6 +41,7 @@ clean-local: %canon_reldir%-clean-local %canon_reldir%-clean-local: rm -rf %reldir%/*.cache + rm -rf %reldir%/*.home AM_TESTS_ENVIRONMENT = $(top_builddir)/pre-inst-env SCM_LOG_COMPILER = $(GUILE) diff --git a/tests/refresh-token-with-wrong-key.scm b/tests/refresh-token-with-wrong-key.scm new file mode 100644 index 0000000..2609e1e --- /dev/null +++ b/tests/refresh-token-with-wrong-key.scm @@ -0,0 +1,29 @@ +(use-modules (webid-oidc refresh-token) + (webid-oidc testing) + (webid-oidc jwk) + (webid-oidc errors) + (web uri) + (srfi srfi-19) + (web response) + (ice-9 optargs) + (ice-9 receive)) + +(with-test-environment + "refresh-token-with-wrong-key" + (lambda () + (define first-key (generate-key #:n-size 2048)) + (define second-key (generate-key #:n-size 2048)) + (define sub (string->uri "https://subject")) + (define aud (string->uri "https://audience")) + (define refresh-token (issue-refresh-token sub aud (jkt first-key))) + (with-exception-handler + (lambda (error) + (unless ((record-predicate &invalid-key-for-refresh-token) error) + (exit 1))) + (lambda () + (with-refresh-token refresh-token second-key + (lambda (sub aud) + (exit 2))) + (exit 3)) + #:unwind? #t + #:unwind-for-type &invalid-key-for-refresh-token))) diff --git a/tests/refresh-token.scm b/tests/refresh-token.scm new file mode 100644 index 0000000..1586d4f --- /dev/null +++ b/tests/refresh-token.scm @@ -0,0 +1,52 @@ +(use-modules (webid-oidc refresh-token) + (webid-oidc testing) + (webid-oidc errors) + (webid-oidc jwk) + (web uri) + (srfi srfi-19) + (web response) + (ice-9 optargs) + (ice-9 receive)) + +(with-test-environment + "refresh-token" + (lambda () + (define sub-a (string->uri "https://subject.a")) + (define sub-b (string->uri "https://subject.b")) + (define aud-a (string->uri "https://client.a")) + (define aud-b (string->uri "https://client.b")) + (define key-a (generate-key #:n-size 2048)) + (define key-b (generate-key #:n-size 2048)) + (define refresh-a (issue-refresh-token sub-a aud-a (jkt key-a))) + (define refresh-b (issue-refresh-token sub-b aud-b (jkt key-b))) + (unless (string? refresh-a) + (exit 2)) + (unless (string? refresh-b) + (exit 3)) + (unless + (with-refresh-token refresh-a key-a + (lambda (sub aud) + (unless (equal? sub-a sub) + (exit 4)) + (unless (equal? aud-a aud) + (exit 5)))) + (exit 6)) + (unless + (with-refresh-token refresh-b key-b + (lambda (sub aud) + (unless (equal? sub-b sub) + (exit 7)) + (unless (equal? aud-b aud) + (exit 8)))) + (exit 9)) + (remove-refresh-token sub-b aud-b) + (with-exception-handler + (lambda (error) + (unless ((record-predicate &invalid-refresh-token) error) + (exit 10))) + (lambda () + (with-refresh-token refresh-b key-b + (lambda (sub aud) + (exit 11)))) + #:unwind? #t + #:unwind-for-type &invalid-refresh-token))) diff --git a/tests/too-many-refresh-tokens.scm b/tests/too-many-refresh-tokens.scm new file mode 100644 index 0000000..cd1cbdc --- /dev/null +++ b/tests/too-many-refresh-tokens.scm @@ -0,0 +1,50 @@ +(use-modules (webid-oidc refresh-token) + (webid-oidc testing) + (webid-oidc errors) + (webid-oidc jwk) + (web uri) + (srfi srfi-19) + (web response) + (ice-9 optargs) + (ice-9 receive)) + +(define (issue-n-refresh-tokens key n) + (if (<= n 0) + '() + (let ((next + (issue-refresh-token + (string->uri (format #f "https://subject-~a.com" (+ n 1))) + (string->uri (format #f "https://client-~a.com" (+ n 1))) + (jkt key)))) + (cons next + (issue-n-refresh-tokens key (- n 1)))))) + +(with-test-environment + "too-many-refresh-tokens" + (lambda () + (let* ((key (generate-key #:n-size 2048)) + (refresh-tokens (list->vector (issue-n-refresh-tokens key 21)))) + (let ((first-refresh-token (vector-ref refresh-tokens 0)) + (second-refresh-token (vector-ref refresh-tokens 20))) + (with-exception-handler + (lambda (error) + (unless ((record-predicate &invalid-refresh-token) error) + (exit 1))) + (lambda () + (with-refresh-token first-refresh-token key + (lambda (sub aud) + ;; It has been made invalid! + (exit 1)))) + #:unwind? #t + #:unwind-for-type &invalid-refresh-token) + (unless (with-refresh-token second-refresh-token key + (lambda (sub aud) + (format (current-error-port) + "~a / ~a\n" + (uri->string sub) + (uri->string aud)) + (unless (equal? sub (string->uri "https://subject-2.com")) + (exit 2)) + (unless (equal? aud (string->uri "https://client-2.com")) + (exit 3)))) + (exit 4)))))) -- cgit v1.2.3