summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2020-12-02 09:31:05 +0100
committerVivien Kraus <vivien@planete-kraus.eu>2021-06-05 16:15:35 +0200
commit9e4ffd421e33679ab4ae7a3e605dd64d8ff693e1 (patch)
treeedc8d6cc7e925c4917444a014236ed8c683615cc
parent8bf760384074e90dcc27c10d2c688cb5ac3dfa2f (diff)
Add the refresh token code
-rw-r--r--doc/webid-oidc.texi9
-rw-r--r--po/fr.po226
-rw-r--r--po/webid-oidc.pot212
-rw-r--r--src/scm/webid-oidc/Makefile.am6
-rw-r--r--src/scm/webid-oidc/errors.scm34
-rw-r--r--src/scm/webid-oidc/refresh-token.scm111
-rw-r--r--src/scm/webid-oidc/testing.scm4
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/refresh-token-with-wrong-key.scm29
-rw-r--r--tests/refresh-token.scm52
-rw-r--r--tests/too-many-refresh-tokens.scm50
11 files changed, 519 insertions, 220 deletions
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."
@@ -632,18 +646,6 @@ msgstr "Type d’exception non pris en charge ~a."
#~ 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 @@
((&not-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 bce5c10..1a23201 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))))))