move util.lisp to directory util, move crypto functions to separate package util/crypt
This commit is contained in:
parent
ae46e97fc4
commit
923982369e
7 changed files with 46 additions and 33 deletions
|
@ -4,6 +4,7 @@
|
||||||
(:use :common-lisp)
|
(:use :common-lisp)
|
||||||
(:local-nicknames (:config :scopes/config)
|
(:local-nicknames (:config :scopes/config)
|
||||||
(:core :scopes/core)
|
(:core :scopes/core)
|
||||||
|
(:crypt :scopes/util/crypt)
|
||||||
(:shape :scopes/shape)
|
(:shape :scopes/shape)
|
||||||
(:util :scopes/util)
|
(:util :scopes/util)
|
||||||
(:b64 :qbase64))
|
(:b64 :qbase64))
|
||||||
|
@ -45,7 +46,7 @@
|
||||||
|
|
||||||
(defun make-credentials (name pw &optional (cls 'simple-credentials))
|
(defun make-credentials (name pw &optional (cls 'simple-credentials))
|
||||||
(make-instance cls :name (util:to-keyword name)
|
(make-instance cls :name (util:to-keyword name)
|
||||||
:password (util:digest pw)))
|
:password (crypt:digest pw)))
|
||||||
|
|
||||||
(defmethod print-object ((cred simple-credentials) stream)
|
(defmethod print-object ((cred simple-credentials) stream)
|
||||||
(print-unreadable-object (cred stream :type t)
|
(print-unreadable-object (cred stream :type t)
|
||||||
|
|
|
@ -8,16 +8,17 @@
|
||||||
:description "Core packages of the scopes project."
|
:description "Core packages of the scopes project."
|
||||||
:depends-on (:alexandria :cl-dotenv :com.inuoe.jzon
|
:depends-on (:alexandria :cl-dotenv :com.inuoe.jzon
|
||||||
:flexi-streams :ironclad :local-time :log4cl :qbase64 :str)
|
:flexi-streams :ironclad :local-time :log4cl :qbase64 :str)
|
||||||
:components ((:file "config" :depends-on ("util"))
|
:components ((:file "config" :depends-on ("util/util"))
|
||||||
(:file "core/core"
|
(:file "core/core"
|
||||||
:depends-on ("core/message" "config"
|
:depends-on ("core/message" "config"
|
||||||
"forge/forge" "logging" "util"))
|
"forge/forge" "logging" "util/util"))
|
||||||
(:file "core/message" :depends-on ("shape/shape"))
|
(:file "core/message" :depends-on ("shape/shape"))
|
||||||
(:file "forge/forge")
|
(:file "forge/forge")
|
||||||
(:file "logging" :depends-on ("config" "util"))
|
(:file "logging" :depends-on ("config" "util/util"))
|
||||||
(:file "shape/shape")
|
(:file "shape/shape")
|
||||||
(:file "util")
|
(:file "util/util")
|
||||||
(:file "testing" :depends-on ("util")))
|
(:file "util/crypt" :depends-on ("util/util"))
|
||||||
|
(:file "testing" :depends-on ("util/util")))
|
||||||
:long-description "scopes/core: The core packages of the scopes project."
|
:long-description "scopes/core: The core packages of the scopes project."
|
||||||
:in-order-to ((test-op (test-op "scopes-core/test"))))
|
:in-order-to ((test-op (test-op "scopes-core/test"))))
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
(:local-nicknames (:alx :alexandria)
|
(:local-nicknames (:alx :alexandria)
|
||||||
(:config :scopes/config)
|
(:config :scopes/config)
|
||||||
(:core :scopes/core)
|
(:core :scopes/core)
|
||||||
|
(:crypt :scopes/util/crypt)
|
||||||
(:logging :scopes/logging)
|
(:logging :scopes/logging)
|
||||||
(:message :scopes/core/message)
|
(:message :scopes/core/message)
|
||||||
(:shape :scopes/shape)
|
(:shape :scopes/shape)
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
(t:show-result))))
|
(t:show-result))))
|
||||||
|
|
||||||
(deftest test-util ()
|
(deftest test-util ()
|
||||||
(util:lgi (util:create-secret))
|
(util:lgi (crypt:create-secret))
|
||||||
(let ((now (get-universal-time)))
|
(let ((now (get-universal-time)))
|
||||||
(== (util:from-unix-time (util:to-unix-time now)) now))
|
(== (util:from-unix-time (util:to-unix-time now)) now))
|
||||||
(== (util:rfill '(1 2 3 4 5) '(a b c)) '(a b c nil nil))
|
(== (util:rfill '(1 2 3 4 5) '(a b c)) '(a b c nil nil))
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
(:core :scopes/core)
|
(:core :scopes/core)
|
||||||
(:client :scopes/web/client)
|
(:client :scopes/web/client)
|
||||||
(:cs-hx :scopes/frontend/cs-hx)
|
(:cs-hx :scopes/frontend/cs-hx)
|
||||||
|
(:crypt :scopes/util/crypt)
|
||||||
(:dom :scopes/web/dom)
|
(:dom :scopes/web/dom)
|
||||||
(:jwt :scopes/web/jwt)
|
(:jwt :scopes/web/jwt)
|
||||||
(:logging :scopes/logging)
|
(:logging :scopes/logging)
|
||||||
|
@ -48,7 +49,7 @@
|
||||||
class=\"demo-link plain\">Link to example.com</a>")))
|
class=\"demo-link plain\">Link to example.com</a>")))
|
||||||
|
|
||||||
(deftest test-jwt ()
|
(deftest test-jwt ()
|
||||||
(let ((secret (util:create-secret))
|
(let ((secret (crypt:create-secret))
|
||||||
;(secret "5Hw3zlpoVbFGRNZcp7Dymw")
|
;(secret "5Hw3zlpoVbFGRNZcp7Dymw")
|
||||||
tok1 jwtdata)
|
tok1 jwtdata)
|
||||||
(setf tok1 (jwt:create secret :admin))
|
(setf tok1 (jwt:create secret :admin))
|
||||||
|
|
26
util/crypt.lisp
Normal file
26
util/crypt.lisp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
;;;; cl-scopes/util/crypt - common cryptographic utilities, e.g. for signing texts
|
||||||
|
|
||||||
|
(defpackage :scopes/util/crypt
|
||||||
|
(:use :common-lisp)
|
||||||
|
(:local-nicknames (:util :scopes/util)
|
||||||
|
(:b64 :qbase64))
|
||||||
|
(:export #:create-secret #:digest #:sign))
|
||||||
|
|
||||||
|
(in-package :scopes/util/crypt)
|
||||||
|
|
||||||
|
(defun create-secret (&key (bytes 16) (scheme :uri))
|
||||||
|
(util:b64-encode (ironclad:random-data bytes) :scheme scheme))
|
||||||
|
|
||||||
|
(defun digest (tx &key (scheme :original) (alg :sha256))
|
||||||
|
(b64:encode-bytes (ironclad:digest-sequence alg (util:to-bytes tx)) :scheme scheme))
|
||||||
|
|
||||||
|
(defun sign (tx key)
|
||||||
|
(let* ((binp (util:to-bytes tx))
|
||||||
|
(bkey (util:to-bytes key))
|
||||||
|
;(bkey (make-array 16 :element-type '(unsigned-byte 8)
|
||||||
|
; :initial-contents (b64:decode-string key)))
|
||||||
|
(mac (ironclad:make-mac :hmac bkey :sha256)))
|
||||||
|
(ironclad:update-mac mac binp)
|
||||||
|
(util:b64-encode (ironclad:produce-mac mac) :scheme :uri)))
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,9 @@
|
||||||
#+sbcl (:import-from :sb-ext #:add-package-local-nickname)
|
#+sbcl (:import-from :sb-ext #:add-package-local-nickname)
|
||||||
(:export #:make-vars-format #:lg #:lgd #:lgi
|
(:export #:make-vars-format #:lg #:lgd #:lgi
|
||||||
#:from-unix-time #:to-unix-time
|
#:from-unix-time #:to-unix-time
|
||||||
#:create-secret #:digest #:sign
|
|
||||||
#:rfill #:rtrim #:loop-plist #:filter-plist #:plist-pairs #:plist-equal
|
#:rfill #:rtrim #:loop-plist #:filter-plist #:plist-pairs #:plist-equal
|
||||||
#:flatten-str #:to-keyword #:keyword-to-string #:to-integer #:to-string
|
#:flatten-str #:to-keyword #:keyword-to-string #:to-integer #:to-string
|
||||||
#:from-bytes #:to-bytes #:from-b64 #:to-b64
|
#:from-bytes #:to-bytes #:b64-decode #:b64-encode #:from-b64 #:to-b64
|
||||||
#:absolute-dir #:check-dir #:ensure-dir #:home-path #:path-from-string
|
#:absolute-dir #:check-dir #:ensure-dir #:home-path #:path-from-string
|
||||||
#:relative-path #:runtime-path #:system-path
|
#:relative-path #:runtime-path #:system-path
|
||||||
#:add-package-local-nickname))
|
#:add-package-local-nickname))
|
||||||
|
@ -31,30 +30,13 @@
|
||||||
|
|
||||||
;;;; date and time manipulations
|
;;;; date and time manipulations
|
||||||
|
|
||||||
(defconstant *unix-time-base* (encode-universal-time 0 0 0 1 1 1970 0))
|
(defconstant +unix-time-base+ (encode-universal-time 0 0 0 1 1 1970 0))
|
||||||
|
|
||||||
(defun from-unix-time (time)
|
(defun from-unix-time (time)
|
||||||
(when time (+ time *unix-time-base*)))
|
(when time (+ time +unix-time-base+)))
|
||||||
|
|
||||||
(defun to-unix-time (time)
|
(defun to-unix-time (time)
|
||||||
(when time (- time *unix-time-base*)))
|
(when time (- time +unix-time-base+)))
|
||||||
|
|
||||||
;;;; secrets, digests, and other crypto stuff
|
|
||||||
|
|
||||||
(defun create-secret (&key (bytes 16) (scheme :uri))
|
|
||||||
(b64-encode (ironclad:random-data bytes) :scheme scheme))
|
|
||||||
|
|
||||||
(defun digest (tx &key (scheme :original) (alg :sha256))
|
|
||||||
(b64:encode-bytes (ironclad:digest-sequence alg (to-bytes tx)) :scheme scheme))
|
|
||||||
|
|
||||||
(defun sign (tx key)
|
|
||||||
(let* ((binp (to-bytes tx))
|
|
||||||
(bkey (to-bytes key))
|
|
||||||
;(bkey (make-array 16 :element-type '(unsigned-byte 8)
|
|
||||||
; :initial-contents (b64:decode-string key)))
|
|
||||||
(mac (ironclad:make-mac :hmac bkey :sha256)))
|
|
||||||
(ironclad:update-mac mac binp)
|
|
||||||
(b64-encode (ironclad:produce-mac mac) :scheme :uri)))
|
|
||||||
|
|
||||||
;;;; lists and loops
|
;;;; lists and loops
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
(defpackage :scopes/web/jwt
|
(defpackage :scopes/web/jwt
|
||||||
(:use :common-lisp)
|
(:use :common-lisp)
|
||||||
(:local-nicknames (:util :scopes/util)
|
(:local-nicknames (:crypt :scopes/util/crypt)
|
||||||
|
(:util :scopes/util)
|
||||||
(:jzon :com.inuoe.jzon))
|
(:jzon :com.inuoe.jzon))
|
||||||
(:export #:create #:decode))
|
(:export #:create #:decode))
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@
|
||||||
(util:keyword-to-string name) exp)
|
(util:keyword-to-string name) exp)
|
||||||
:scheme :uri))
|
:scheme :uri))
|
||||||
(data (str:join "." (list *header* payload)))
|
(data (str:join "." (list *header* payload)))
|
||||||
(sig (util:sign data secret)))
|
(sig (crypt:sign data secret)))
|
||||||
(str:join "." (list data sig))))
|
(str:join "." (list data sig))))
|
||||||
|
|
||||||
(defun decode (token secret)
|
(defun decode (token secret)
|
||||||
|
@ -30,7 +31,7 @@
|
||||||
(destructuring-bind (data &optional sig) (str:rsplit "." token :limit 2)
|
(destructuring-bind (data &optional sig) (str:rsplit "." token :limit 2)
|
||||||
(unless sig
|
(unless sig
|
||||||
(return-from decode (values nil :malformed-token token)))
|
(return-from decode (values nil :malformed-token token)))
|
||||||
(unless (equal sig (util:sign data secret))
|
(unless (equal sig (crypt:sign data secret))
|
||||||
(return-from decode (values nil :invalid-signature (list data sig))))
|
(return-from decode (values nil :invalid-signature (list data sig))))
|
||||||
(destructuring-bind (hjson &optional pjson) (str:split "." data)
|
(destructuring-bind (hjson &optional pjson) (str:split "." data)
|
||||||
(setf payload (jzon:parse (util:from-b64 pjson)))
|
(setf payload (jzon:parse (util:from-b64 pjson)))
|
||||||
|
|
Loading…
Add table
Reference in a new issue