diff options
author | Vivien Kraus <vivien@planete-kraus.eu> | 2021-08-09 18:46:48 +0200 |
---|---|---|
committer | Vivien Kraus <vivien@planete-kraus.eu> | 2021-08-13 01:06:38 +0200 |
commit | ded10e28782f289ad3db15320bcf619ab4336876 (patch) | |
tree | 32609fd9f1eb0d2f8a23105e09f193827d16a275 /src/scm/webid-oidc/stubs.scm | |
parent | 7b62790238902e10edb83c07286cf0643b097997 (diff) |
Switch to a more sensible error reporting system
Diffstat (limited to 'src/scm/webid-oidc/stubs.scm')
-rw-r--r-- | src/scm/webid-oidc/stubs.scm | 242 |
1 files changed, 191 insertions, 51 deletions
diff --git a/src/scm/webid-oidc/stubs.scm b/src/scm/webid-oidc/stubs.scm index 08d15aa..e029b7c 100644 --- a/src/scm/webid-oidc/stubs.scm +++ b/src/scm/webid-oidc/stubs.scm @@ -1,4 +1,4 @@ -;; webid-oidc, implementation of the Solid specification +;; disfluid, implementation of the Solid specification ;; Copyright (C) 2020, 2021 Vivien Kraus ;; This program is free software: you can redistribute it and/or modify @@ -16,84 +16,201 @@ (define-module (webid-oidc stubs) #:use-module (webid-oidc config) - #:use-module (webid-oidc errors) + #:use-module (ice-9 exceptions) + #:use-module (ice-9 i18n) #:use-module (webid-oidc parameters) - #:use-module (json)) + #:use-module (json) + #:export + ( + + &invalid-base64-data + make-invalid-base64-data + invalid-base64-data? + error-base64-data + + &unsupported-elliptic-curve + make-unsupported-elliptic-curve + unsupported-elliptic-curve? + unsupported-elliptic-curve-value + + &unsupported-algorithm + make-unsupported-algorithm + unsupported-algorithm? + unsupported-algorithm-alg + unsupported-algorithm-application + + &invalid-signature + make-invalid-signature + invalid-signature? + invalid-signature-alg + invalid-signature-key + invalid-signature-payload + invalid-signature-signature + + &invalid-json + make-invalid-json + invalid-json? + invalid-json-input + + base64-encode + (fix-base64-decode . base64-decode) + random + (fix-random-init! . random-init!) + (fix-generate-key . generate-key) + kty + strip-key + (fix-hash . hash) + jkt + (fix-sign . sign) + (fix-verify . verify) + (fixed:json-string->scm . json-string->scm) + (fixed:json->scm . json->scm) + (fixed:scm->json-string . scm->json-string) + (fixed:scm->json . scm->json) + + mkdir-p + open-output-file* + call-with-output-file* + atomically-update-file + + )) + +(define (G_ text) + (let ((out (gettext text))) + (if (string=? out text) + ;; No translation, disambiguate + (car (reverse (string-split text #\|))) + out))) (load-extension (format #f "~a/libwebidoidc" libdir) "init_webidoidc") +(define-exception-type + &invalid-base64-data + &external-error + make-invalid-base64-data + invalid-base64-data? + (data error-base64-data)) + +(define (summarize str) + (if (> (string-length str) 10) + (format #f "~s" + (string-append + (substring str 0 10) + "...")) + (format #f "~s" str))) + (define (fix-base64-decode data) (catch 'base64-decoding-error (lambda () (base64-decode data)) (lambda error - (raise-not-base64 data error)))) + (let ((final-message + (format #f (G_ "invalid base64 data: ~a") + (summarize data)))) + (raise-exception + (make-exception + (make-invalid-base64-data data) + (make-exception-with-message final-message) + (make-exception-with-irritants (list data)))))))) + +(define-exception-type + &unsupported-elliptic-curve + &external-error + make-unsupported-elliptic-curve + unsupported-elliptic-curve? + (curve unsupported-elliptic-curve-value)) + +(define (unsupported-crv crv) + (let ((final-message + (format #f (G_ "~s is not a recognized elliptic curve") + crv))) + (raise-exception + (make-exception + (make-unsupported-elliptic-curve crv) + (make-exception-with-message final-message) + (make-exception-with-irritants (list crv)))))) (define (fix-generate-key . args) (catch 'unsupported-crv (lambda () (apply generate-key args)) - (lambda (error) - (raise-unsupported-crv (cadr error))))) - -(define (fix-kty key) - (catch 'unsupported-crv - (lambda () - (let ((ret (kty key))) - (unless ret - (raise-not-a-jwk key #f)) - ret)) (lambda error - (raise-unsupported-crv (cadr error))))) + (unsupported-crv (cadr error))))) + +(define-exception-type + &unsupported-algorithm + &external-error + make-unsupported-algorithm + unsupported-algorithm? + (alg unsupported-algorithm-alg) + ;; 'sign or 'hash: + (application unsupported-algorithm-application)) + +(define (unsupported-alg alg application) + (let ((final-message + (case application + ((sign) + (format #f (G_ "~s is not a supported signature algorithm") + alg)) + ((hash) + (format #f (G_ "~s is not a supported hash algorithm") + alg))))) + (raise-exception + (make-exception + (make-unsupported-algorithm alg application) + (make-exception-with-message final-message) + (make-exception-with-irritants (list alg)))))) (define (fix-hash alg payload) (catch 'unsupported-alg (lambda () (hash alg payload)) (lambda error - (raise-unsupported-alg (cadr error))))) + (unsupported-alg alg 'hash)))) (define (fix-sign alg key payload) (catch 'unsupported-alg (lambda () (sign alg key payload)) (lambda error - (raise-unsupported-alg (cadr error))))) + (unsupported-alg alg 'sign)))) + +(define-exception-type + &invalid-signature + &external-error + make-invalid-signature + invalid-signature? + (alg invalid-signature-alg) + (key invalid-signature-key) + (payload invalid-signature-payload) + (signature invalid-signature-signature)) (define (fix-verify alg key payload signature) (catch 'unsupported-alg (lambda () - (let ((ok - (verify alg key payload signature))) + (let ((ok (verify alg key payload signature))) (unless ok - (raise-invalid-signature key payload signature)))) + (let ((final-message + (format #f (G_ "the signature is invalid")))) + (raise-exception + (make-exception + (make-invalid-signature alg key payload signature) + (make-exception-with-message final-message) + (make-exception-with-irritants (list alg key payload signature)))))))) (lambda error - (raise-unsupported-alg (cadr error))))) + (unsupported-alg alg 'sign)))) (define (fix-random-init!) (setenv "XDG_CACHE_HOME" (cache-home)) (setenv "DISFLUID_APPLICATION_NAME" ".") (random-init!)) -(export - base64-encode - (fix-base64-decode . base64-decode) - random - (fix-random-init! . random-init!) - (fix-generate-key . generate-key) - (fix-kty . kty) - strip-key - (fix-hash . hash) - jkt - (fix-sign . sign) - (fix-verify . verify)) - ;; json reader from guile-json will not behave consistently with ;; SRFI-180 with objects: keys will be mapped to strings, not ;; symbols. So we fix alist keys to be symbols. -(define-public (fix-alists data) +(define (fix-alists data) (define (fix-an-alist rest alist) (if (null? alist) (reverse rest) @@ -117,33 +234,47 @@ (fix-a-vector data)) (else data))) +(define-exception-type + &invalid-json + &external-error + make-invalid-json + invalid-json? + (input invalid-json-input)) + (define (fixed:json-string->scm str) (with-exception-handler - (lambda (err) - (raise-not-json str err)) + (lambda (exn) + (let ((final-message + (format #f (G_ "invalid JSON data: ~a") + (summarize str)))) + (raise-exception + (make-exception + (make-invalid-json str) + (make-exception-with-message final-message) + (make-exception-with-irritants (list str)) + exn)))) (lambda () (fix-alists (json-string->scm str))))) -(export (fixed:json-string->scm . json-string->scm)) - (define (fixed:json->scm port) (with-exception-handler (lambda (err) - (raise-not-json "(input)" err)) + (let ((final-message + (format #f (G_ "invalid JSON data in input port")))) + (raise-exception + (make-exception + (make-invalid-json "(input)") + (make-exception-with-message final-message) + (make-exception-with-irritants (list port)) + exn)))) (lambda () (fix-alists (json->scm port))))) -(export (fixed:json->scm . json->scm)) - (define fixed:scm->json-string scm->json-string) -(export (fixed:scm->json-string . scm->json-string)) - (define fixed:scm->json scm->json) -(export (fixed:scm->json . scm->json)) - -(define-public (mkdir-p name) +(define (mkdir-p name) (catch 'system-error (lambda () (mkdir name)) @@ -159,15 +290,15 @@ (else (throw key subr message args rest)))))) -(define-public (open-output-file* filename . args) +(define (open-output-file* filename . args) (mkdir-p (dirname filename)) (apply open-output-file filename args)) -(define-public (call-with-output-file* filename . args) +(define (call-with-output-file* filename . args) (mkdir-p (dirname filename)) (apply call-with-output-file filename args)) -(define-public (atomically-update-file file lock-file-name f) +(define (atomically-update-file file lock-file-name f) ;; Call f with an output port. If f returns #f, delete the original ;; file. Otherwise, replace it. (let ((updating-file-name (string-append file "~"))) @@ -187,7 +318,16 @@ (with-exception-handler (lambda (error) (false-if-exception (delete-file updating-file-name)) - (raise-exception error)) + (let ((final-message + (if (exception-with-message? error) + (format #f (G_ "while updating file ~s: ~a") + file (exception-message error)) + (format #f (G_ "an error happened while updating file ~s") + file)))) + (raise-exception + (make-exception + (make-exception-with-message final-message) + error)))) (lambda () (let ((ok (f port))) (fsync port) |