2021-06-03 22:05:04 +00:00
|
|
|
#lang racket/base
|
2021-06-04 14:20:14 +00:00
|
|
|
;;; SPDX-License-Identifier: LGPL-3.0-or-later
|
2023-01-16 14:57:29 +00:00
|
|
|
;;; SPDX-FileCopyrightText: Copyright © 2021-2023 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
2021-06-04 14:20:14 +00:00
|
|
|
|
2021-06-03 22:05:04 +00:00
|
|
|
;; Basically Macaroons [1] in a Dataspace context
|
|
|
|
;;
|
|
|
|
;; [1]: Birgisson, Arnar, Joe Gibbs Politz, Úlfar Erlingsson, Ankur
|
|
|
|
;; Taly, Michael Vrable, and Mark Lentczner. “Macaroons: Cookies with
|
|
|
|
;; Contextual Caveats for Decentralized Authorization in the Cloud.”
|
|
|
|
;; In Network and Distributed System Security Symposium. San Diego,
|
|
|
|
;; California: Internet Society, 2014.
|
|
|
|
|
|
|
|
(provide KEY_LENGTH
|
|
|
|
new-key
|
|
|
|
sturdy-encode
|
|
|
|
sturdy-decode
|
|
|
|
mint
|
2021-06-08 07:21:54 +00:00
|
|
|
attenuate-sturdy
|
2021-06-03 22:05:04 +00:00
|
|
|
SturdyRef-valid?
|
2023-02-10 11:04:21 +00:00
|
|
|
SturdyRef-caveatChain
|
|
|
|
CaveatsField-caveats
|
2021-06-03 22:05:04 +00:00
|
|
|
validate
|
2021-07-01 07:40:52 +00:00
|
|
|
(all-from-out "schemas/sturdy.rkt"))
|
2021-06-03 22:05:04 +00:00
|
|
|
|
|
|
|
(require racket/match)
|
2023-02-06 15:31:04 +00:00
|
|
|
(require (only-in libb2 blake2s BLAKE2S_BLOCKLEN))
|
|
|
|
(require (only-in noise-protocol/hmac make-hmac))
|
2021-06-03 22:05:04 +00:00
|
|
|
(require (only-in racket/random crypto-random-bytes))
|
|
|
|
(require preserves)
|
2021-06-08 13:38:24 +00:00
|
|
|
(require preserves-schema)
|
2021-07-01 07:40:52 +00:00
|
|
|
(require "schemas/sturdy.rkt")
|
2021-06-03 22:05:04 +00:00
|
|
|
|
|
|
|
(define KEY_LENGTH 16) ;; 128 bits
|
|
|
|
|
|
|
|
(define (new-key) (crypto-random-bytes KEY_LENGTH))
|
|
|
|
|
|
|
|
(define (embedded-not-allowed _)
|
|
|
|
(error 'embedded-not-allowed "Embedded Ref not permitted in SturdyRef"))
|
|
|
|
|
|
|
|
(define (sturdy-encode v)
|
|
|
|
(preserve->bytes v
|
|
|
|
#:canonicalizing? #t
|
|
|
|
#:encode-embedded embedded-not-allowed
|
|
|
|
#:write-annotations? #f))
|
|
|
|
|
|
|
|
(define (sturdy-decode bs)
|
|
|
|
(bytes->preserve bs
|
|
|
|
#:read-syntax? #f
|
|
|
|
#:decode-embedded embedded-not-allowed))
|
|
|
|
|
2023-02-06 15:31:04 +00:00
|
|
|
(define hmac-BLAKE2s (make-hmac blake2s BLAKE2S_BLOCKLEN))
|
|
|
|
|
2021-06-08 07:28:48 +00:00
|
|
|
(define (signature key data)
|
2023-02-06 15:31:04 +00:00
|
|
|
(subbytes (hmac-BLAKE2s key data) 0 KEY_LENGTH))
|
2021-06-08 07:28:48 +00:00
|
|
|
|
2021-06-03 22:05:04 +00:00
|
|
|
(define (mint oid key)
|
2023-02-10 11:04:21 +00:00
|
|
|
(SturdyRef (Parameters oid (signature key (sturdy-encode oid)) (CaveatsField-absent))))
|
2021-06-03 22:05:04 +00:00
|
|
|
|
2023-02-06 11:01:34 +00:00
|
|
|
(define (update-signature sig caveats)
|
|
|
|
(for/fold [(sig sig)] [(caveat (in-list caveats))]
|
|
|
|
(signature sig (sturdy-encode (->preserve caveat)))))
|
|
|
|
|
|
|
|
(define (attenuate-sturdy r . caveats)
|
2023-02-10 11:04:21 +00:00
|
|
|
(if (null? caveats)
|
|
|
|
r
|
|
|
|
(match r
|
|
|
|
[(SturdyRef (Parameters oid sig cs))
|
|
|
|
(SturdyRef (Parameters oid
|
|
|
|
(update-signature sig caveats)
|
|
|
|
(CaveatsField-present
|
|
|
|
(append (CaveatsField-caveats cs) caveats))))])))
|
2021-06-03 22:05:04 +00:00
|
|
|
|
|
|
|
(define (SturdyRef-valid? r key)
|
2023-02-10 11:04:21 +00:00
|
|
|
(match-define (SturdyRef (Parameters oid actual-sig cs)) r)
|
|
|
|
(define expected-sig (update-signature (signature key (sturdy-encode oid)) (CaveatsField-caveats cs)))
|
2021-06-03 22:05:04 +00:00
|
|
|
(equal? expected-sig actual-sig))
|
|
|
|
|
2023-02-10 11:04:21 +00:00
|
|
|
(define (SturdyRef-caveatChain r)
|
|
|
|
(CaveatsField-caveats (Parameters-caveats (SturdyRef-parameters r))))
|
|
|
|
|
|
|
|
(define (CaveatsField-caveats c)
|
|
|
|
(match c
|
|
|
|
[(CaveatsField-absent) '()]
|
|
|
|
[(CaveatsField-present cs) cs]
|
|
|
|
[(CaveatsField-invalid _) (error 'CaveatsField-caveats "Invalid caveats field")]))
|
|
|
|
|
2021-06-03 22:05:04 +00:00
|
|
|
(define (validate r key)
|
|
|
|
(when (not (SturdyRef-valid? r key))
|
|
|
|
(error 'validate "Invalid SturdyRef"))
|
|
|
|
r)
|