diff --git a/project.clj b/project.clj index b1a5b04..119597d 100644 --- a/project.clj +++ b/project.clj @@ -8,7 +8,7 @@ :url "https://www.eclipse.org/legal/epl-v10.html"} :dependencies - [[com.taoensso/encore "3.68.0"]] + [[com.taoensso/encore "3.69.0"]] :profiles {;; :default [:base :system :user :provided :dev] @@ -25,8 +25,7 @@ *unchecked-math* false #_:warn-on-boxed} :dependencies - [[org.clojure/test.check "1.1.1"] - [com.taoensso/timbre "6.3.1"]]} + [[org.clojure/test.check "1.1.1"]]} :graal-tests {:dependencies [[org.clojure/clojure "1.11.1"] diff --git a/src/taoensso/tempel.clj b/src/taoensso/tempel.clj index 464854b..331ccde 100644 --- a/src/taoensso/tempel.clj +++ b/src/taoensso/tempel.clj @@ -9,8 +9,8 @@ Abbreviations: pbkdf - password based key derivation function - aad - additional associated data (see also `doc-aad`) - akm - additional keying material (see also `doc-akm`) + aad - additional associated data (see also `aad-help`) + akm - additional keying material (see also `akm-help`) kek - key encryption key (key used to encrypt another key) cnt - content ecnt - encrypted content" @@ -18,7 +18,7 @@ {:author "Peter Taoussanis (@ptaoussanis)"} (:require [taoensso.encore :as enc :refer [have have?]] - [taoensso.tempel.bytes :as bytes] + [taoensso.encore.bytes :as bytes] [taoensso.tempel.df :as df] [taoensso.tempel.impl :as impl] [taoensso.tempel.pbkdf :as pbkdf] @@ -26,20 +26,18 @@ (comment (remove-ns 'taoensso.tempel) - (:public (enc/interns-overview))) + (:api (enc/interns-overview))) -(enc/assert-min-encore-version [3 68 0]) +(enc/assert-min-encore-version [3 69 0]) ;;;; TODO -;; - Confirm: would 512-bit (64 byte) keys be possible? -;; - Move bytes API to encore? (For use by Carmine, Nippy, etc.) ;; - General review: API, impln, tests -;; - Initial README and Wiki content (see sketch IMPORT_DOCS.md) -;; - Extra (generative?) tests? - ;; - Check Signal's algos: ;; - "Double Ratchet Algorithm", Ref. ;; - "X3DH", Ref. +;; +;; - Extra (generative?) tests? +;; - Initial README and Wiki content (see sketch IMPORT_DOCS.md) ;;;; Aliases @@ -70,7 +68,7 @@ ;;;; Doc vars -(def doc-aad +(def aad-help "\"Additional Authenticated Data\" (AAD) is optional arbitrary byte[] data that may be provided to many of Tempel's API functions (e.g. `encrypt-with-X` when using an AEAD cipher). @@ -94,9 +92,10 @@ - File or data integrity checks (hashes, etc.) - Cryptographic signatures - Arbitrary Clojure data via Nippy, Ref. " - nil) -(def doc-akm + "See docstring") + +(def akm-help "\"Additional Keying Material\" (AKM) is optional arbitrary byte[] data that may be provided to many of Tempel's API functions (e.g. `encrypt-with-X`). @@ -116,12 +115,13 @@ - Protocol-specific values - Security credentials or certificates - Arbitrary Clojure data via Nippy, Ref. " - nil) + + "See docstring") ;;;; Config (enc/defonce default-keypair-creator_ - "Default stateful KeyPair generator with options: + "Default stateful `KeyPair` generator with options: {:buffer-len 16, :n-threads [:perc 10]}" (delay (impl/keypair-creator {:buffer-len 16, :n-threads [:perc 10]}))) @@ -167,7 +167,7 @@ `:hash-algo` ∈ #{:md5 :sha-1 *:sha-256 :sha-512} Hash algorithm used for internal HMACs, etc. - Default: `:sha-256`, and there's usually no good reason to change this. + Default: `:sha-256`, there's usually no good reason to change this. `:pbkdf-algo` ∈ #{*:scrypt-r8p1-v1 :pbkdf2-hmac-sha-256-v1} Algorithm to use for password-based key stretching. @@ -192,7 +192,7 @@ `:sym-cipher-algo` ∈ #{*:aes-gcm-128-v1 :aes-gcm-256-v1} The symmetric cipher algorithm to use. A cipher that supports \"AEAD\" (Authenticated Encryption with Associated Data) must generally be provided - in order to use `:ba-aad` options (see `doc-aad` docstring). + in order to use `:ba-aad` options (see `aad-help` docstring). Default: `:aes-gcm-128-v1`, a good general-purpose symmetric cipher with AEAD support. @@ -242,7 +242,7 @@ default-config) -(defn get-config "Implementation detail" [opts] (conj (or *config* {}) opts)) +(defn ^:no-doc get-config "Implementation detail" [opts] (enc/fast-merge *config* opts)) (comment (get-config {})) ;;;; Public data @@ -252,7 +252,7 @@ (unencrypted) data embedded in the byte[]. Possible keys: - `:ba-aad` - See `doc-aad` docstring. + `:ba-aad` - See `aad-help` docstring. `:keychain` - Public-key part of encrypted `KeyChain` `:key-id` - See `:embed-key-ids?` option of `encrypt-X` API `:receiver-key-id` - '' @@ -339,8 +339,8 @@ :ba-aad ?ba-aad)) (enc/unexpected-arg! env-kid - :expected :envelope-with-public-data - :context `public-data))))) + {:expected :envelope-with-public-data + :context `public-data}))))) (defn- public-data-test [ba-tempel-output] @@ -367,14 +367,14 @@ :cnt (bytes/utf8-?ba->str ?ba-cnt)) (enc/unexpected-arg! return-kind - :expected #{:ba-content :ba-aad :as-map} - :context context))) + {:expected #{:ba-content :ba-aad :as-map} + :context context}))) (defn encrypt-with-password "Uses a symmetric cipher to encrypt the given byte[] content and return a byte[] that includes: - The encrypted content - - Optional unencrypted AAD (see `doc-aad` docstring) + - Optional unencrypted AAD (see `aad-help` docstring) - Envelope data necessary for decryption (specifies algorithms, etc.) Takes a password (string, byte[], or char[]). @@ -384,8 +384,8 @@ Decrypt output with: `decrypt-with-password`. Options: - `:ba-aad` - See `doc-aad` docstring - `:ba-akm` - See `doc-akm` dosctring + `:ba-aad` - See `aad-help` docstring + `:ba-akm` - See `akm-help` dosctring Relevant `*config*` keys (see that var's docstring for details): `hash-algo`, `sym-cipher-algo`, `pbkdf-algo`, `pbkdf-nwf`, `embed-key-ids?`" @@ -487,15 +487,15 @@ "Uses a symmetric cipher to encrypt the given byte[] content and return a byte[] that includes: - The encrypted content - - Optional unencrypted AAD (see `doc-aad` docstring) + - Optional unencrypted AAD (see `aad-help` docstring) - Envelope data necessary for decryption (specifies algorithms, etc.) Takes a `KeyChain` (see `keychain`) or byte[] key. Decrypt output with: `decrypt-with-symmetric-key`. Options: - `:ba-aad` - See `doc-aad` docstring - `:ba-akm` - See `doc-akm` docstring + `:ba-aad` - See `aad-help` docstring + `:ba-akm` - See `akm-help` docstring Relevant `*config*` keys (see that var's docstring for details): `hash-algo`, `sym-cipher-algo`, `embed-key-ids?`" @@ -584,7 +584,7 @@ "Uses a symmetric or hybrid (symmetric + asymmetric) scheme to encrypt the given content byte[] and return a byte[] that includes: - The encrypted content - - Optional unencrypted AAD (see `doc-aad` docstring) + - Optional unencrypted AAD (see `aad-help` docstring) - Envelope data necessary for decryption (specifies algorithms, etc.) Takes a `KeyChain` (see `keychain`) or `KeyPair` (see `keypair-create`). @@ -597,8 +597,8 @@ Decrypt output byte[] with: `decrypt-with-1-keypair`. Options: - `:ba-aad` - See `doc-aad` docstring - `:ba-akm` - See `doc-akm` docstring + `:ba-aad` - See `aad-help` docstring + `:ba-akm` - See `akm-help` docstring Relevant `*config*` keys (see that var's docstring for details): `hash-algo`, `sym-cipher-algo`, `asym-cipher-algo`, `embed-key-ids`?" @@ -756,10 +756,10 @@ (return-val env-kid return ba-cnt nil)) (enc/unexpected-arg! env-kid - :context `decrypt-with-1-keypair - :expected - {:encrypted-with-1-keypair-hybrid-v1 - :encrypted-with-1-keypair-simple-v1}))))) + {:context `decrypt-with-1-keypair + :expected + #{:encrypted-with-1-keypair-hybrid-v1 + :encrypted-with-1-keypair-simple-v1}}))))) (comment (let [kc (keychain) @@ -770,7 +770,7 @@ "Uses a hybrid (symmetric + asymmetric) scheme to encrypt the given content byte[] and return a byte[] that includes: - The encrypted content - - Optional unencrypted AAD (see `doc-aad` docstring) + - Optional unencrypted AAD (see `aad-help` docstring) - Envelope data necessary for decryption (specifies algorithms, etc.) Takes `KeyChain`s (see `keychain`) and/or `KeyPair`s (see `keypair-create`). @@ -788,8 +788,8 @@ Decrypt output byte[] with: `decrypt-with-2-keypairs`. Options: - `:ba-aad` - See `doc-aad` docstring - `:ba-akm` - See `doc-akm` docstring + `:ba-aad` - See `aad-help` docstring + `:ba-akm` - See `akm-help` docstring Relevant `*config*` keys (see that var's docstring for details): `hash-algo`, `ka-algo`, `sym-cipher-algo`, `embed-key-ids?`" @@ -921,7 +921,7 @@ "Cryptographically signs the given content byte[] and returns a byte[] that includes: - Optional unencrypted content (see `embed-content?` option below) - - Optional unencrypted AAD (see `doc-aad` docstring) + - Optional unencrypted AAD (see `aad-help` docstring) - Envelope data necessary for verification (specifies algorithms, etc.) Basically produces: diff --git a/src/taoensso/tempel/bytes.clj b/src/taoensso/tempel/bytes.clj index 852d068..1490304 100644 --- a/src/taoensso/tempel/bytes.clj +++ b/src/taoensso/tempel/bytes.clj @@ -15,7 +15,7 @@ (comment (remove-ns 'taoensso.tempel.bytes) - (:public (enc/interns-overview))) + (:api (enc/interns-overview))) ;;;; Aliases @@ -205,8 +205,8 @@ (seqable? x) (byte-array x) :else (enc/unexpected-arg! x - :context `as-ba - :expected '#{byte-array string char-array int seqable})))) + {:context `as-ba + :expected '#{byte-array string char-array int seqable}})))) (comment (vec (as-ba 16 "hello"))) @@ -238,8 +238,8 @@ (bytes? x) (.toCharArray ^String (utf8-ba->str x)) :else (enc/unexpected-arg! x - :context `as-ca - :expected '#{char-array string byte-array}))) + {:context `as-ca + :expected '#{char-array string byte-array}}))) ;;;; Byte streams @@ -264,7 +264,8 @@ acc)) 0 spec)) -(defmacro with-out [[dos-sym ?baos-sym] buffer-len & body] +(defmacro with-out + [[dos-sym ?baos-sym] buffer-len & body] (let [baos-sym (or ?baos-sym '__baos) buffer-len (if (vector? buffer-len) @@ -276,7 +277,8 @@ ~(with-meta baos-sym {:tag 'java.io.ByteArrayOutputStream})] ~@body)))) -(defmacro with-in [[din-sym ?bais-sym] ba & body] +(defmacro with-in + [[din-sym ?bais-sym] ba & body] (let [bais-sym (or ?bais-sym '__bais)] `(with-in* ~ba (fn [~(with-meta din-sym {:tag 'java.io.DataInput}) diff --git a/src/taoensso/tempel/df.clj b/src/taoensso/tempel/df.clj index c1ba862..9573523 100644 --- a/src/taoensso/tempel/df.clj +++ b/src/taoensso/tempel/df.clj @@ -12,7 +12,7 @@ (comment (remove-ns 'taoensso.tempel.df) - (:public (enc/interns-overview))) + (:api (enc/interns-overview))) ;;;; IDs ;; - `kid` => keyword id, used to uniquely identify some algo/kit/etc. diff --git a/src/taoensso/tempel/impl.clj b/src/taoensso/tempel/impl.clj index ac7e678..d8f7978 100644 --- a/src/taoensso/tempel/impl.clj +++ b/src/taoensso/tempel/impl.clj @@ -15,7 +15,7 @@ (comment (remove-ns 'taoensso.tempel.impl) - (:public (enc/interns-overview))) + (:api (enc/interns-overview))) ;;;; IDs ;; @@ -130,8 +130,8 @@ :sha-256 @md-sha-256_ :sha-512 @md-sha-512_ (enc/unexpected-arg! hash-algo - :expected #{:md5 :sha-1 :sha-256 :sha-512} - :context `as-message-digest)))) + {:expected #{:md5 :sha-1 :sha-256 :sha-512} + :context `as-message-digest})))) (let [ba0 (byte-array 0)] (defn hash-ba-concat @@ -191,8 +191,8 @@ :sha-256 @hmac-sha-256_ :sha-512 @hmac-sha-512_ (enc/unexpected-arg! hash-algo - :expected #{:md5 :sha-1 :sha-256 :sha-512} - :context `as-hmac)))) + {:expected #{:md5 :sha-1 :sha-256 :sha-512} + :context `as-hmac})))) (defn hmac "Returns HMAC of given byte[] secret and byte[] ?content. @@ -236,8 +236,8 @@ :aes-gcm @cipher-aes-gcm_ :aes-cbc @cipher-aes-cbc_ (enc/unexpected-arg! sym-cipher-algo - :expected #{:aes-gcm :aes-cbc} - :context `as-symmetric-cipher)))) + {:expected #{:aes-gcm :aes-cbc} + :context `as-symmetric-cipher})))) (defprotocol ISymmetricCipherKit "Private protocol, lowest level symmetric API. Zero enveloping." @@ -345,23 +345,23 @@ :aes-cbc-256-v1-deprecated sck-aes-cbc-256-v1-deprecated (enc/unexpected-arg! sym-cipher-algo - :expected expected - :context `as-symmetric-cipher-kit)) + {:expected expected + :context `as-symmetric-cipher-kit})) (enc/satisfies! ISymmetricCipherKit sym-cipher-algo - :expected expected - :context `as-symmetric-cipher-kit)))) + {:expected expected + :context `as-symmetric-cipher-kit})))) ;;;; Asymmetric crypto (defn- key-algo-unknown! [x context] (enc/unexpected-arg! x - :context context - :expected - #{:symmetric - :rsa :rsa- - :dh :dh- - :ec :ec-})) + {:context context + :expected + #{:symmetric + :rsa :rsa- + :dh :dh- + :ec :ec-}})) (defn key-algo-info "Returns ?{:keys [kf-algo ka-algo sig-algo cipher-algo, asymmetric? symmetric? wild?]}. @@ -465,7 +465,7 @@ :ec-secp521r1 (.initialize kpg (java.security.spec.ECGenParameterSpec. "secp521r1") sr) ; NIST-P-521 (enc/unexpected-arg! algo-params - :expected #{:ec-secp256-r1})) + {:expected #{:ec-secp256-r1}})) :else (.initialize kpg ^java.security.spec.AlgorithmParameterSpec algo-params sr)) @@ -501,8 +501,8 @@ :ec-secp521r1 (kpg-get "EC" :ec-secp521r1) (enc/unexpected-arg! key-algo - :expected #{:rsa- :dh- :ec-} - :context `as-keypair-generator)))) + {:expected #{:rsa- :dh- :ec-} + :context `as-keypair-generator})))) (defn ^:public keypair-create "Generates and returns a new `java.security.KeyPair` for given @@ -703,8 +703,8 @@ (:ec :ec-secp256r1 :ec-secp384r1 :ec-secp521r1) @kf-ec_ (enc/unexpected-arg! key-algo - :expected #{:rsa :rsa- :dh :dh- :ec :ec-} - :context `as-key-factory)))) + {:expected #{:rsa :rsa- :dh :dh- :ec :ec-} + :context `as-key-factory})))) (let [decode-prv (fn [^java.security.KeyFactory kf ba-prv] (.generatePrivate kf (java.security.spec.PKCS8EncodedKeySpec. ba-prv))) decode-pub (fn [^java.security.KeyFactory kf ba-pub] (.generatePublic kf (java.security.spec.X509EncodedKeySpec. ba-pub)))] @@ -806,8 +806,8 @@ (case asym-cipher-algo :rsa-oaep-sha-256-mgf1 @cipher-rsa-oaep-sha-256-mgf1_ (enc/unexpected-arg! asym-cipher-algo - :expected #{:rsa-oaep-sha-256-mgf1} - :context `as-asymmetric-cipher)))) + {:expected #{:rsa-oaep-sha-256-mgf1} + :context `as-asymmetric-cipher})))) (defn encrypt-asymmetric "Takes `asym-cipher-algo` ∈ #{:rsa-oaep-sha-256-mgf1}. @@ -856,8 +856,8 @@ :dh @ka-dh_ :ecdh @ka-ecdh_ (enc/unexpected-arg! ka-algo - :expected #{:dh :ecdh} - :context `as-key-agreement)))) + {:expected #{:dh :ecdh} + :context `as-key-agreement})))) (defn key-shared-create "Returns the shared key generated by the given key agreement @@ -894,8 +894,8 @@ :sha-256-ecdsa @sig-sha-256-ecdsa_ :sha-512-ecdsa @sig-sha-512-ecdsa_ (enc/unexpected-arg! sig-algo - :expected #{:sha--rsa :sha--ecdsa} - :context `as-signature)))) + {:expected #{:sha--rsa :sha--ecdsa} + :context `as-signature})))) (defn signature-create "Returns the signature created by signing the given content with the diff --git a/src/taoensso/tempel/keys.clj b/src/taoensso/tempel/keys.clj index 297df34..f8cd746 100644 --- a/src/taoensso/tempel/keys.clj +++ b/src/taoensso/tempel/keys.clj @@ -10,7 +10,7 @@ (comment (remove-ns 'taoensso.tempel.keys) - (:public (enc/interns-overview))) + (:api (enc/interns-overview))) (enc/declare-remote taoensso.tempel/get-config @@ -41,7 +41,7 @@ :sym {:key-type :sym, :key-algo key-algo, :symmetric? true, :key-sym key-cnt} :prv {:key-type :prv, :key-algo key-algo, :asymmetric? true, :private? true, :key-prv key-cnt} :pub {:key-type :pub, :key-algo key-algo, :asymmetric? true, :public? true, :key-pub key-cnt} - (enc/unexpected-arg! key-type :expected #{:sym :pub :prv})) + (enc/unexpected-arg! key-type {:expected #{:sym :pub :prv}})) (enc/assoc-some {:key-cnt key-cnt} :key-id ?key-id)))) @@ -115,8 +115,8 @@ :else (fail! (ex-info "Unexpected `ChainKey` :key-sym type" {:expected 'bytes, :actual (type x-key)}))) (enc/unexpected-arg! key-type - :expected #{:prv :pub :sym} - :context `-chainkey))))) + {:expected #{:prv :pub :sym} + :context `-chainkey}))))) (comment [(-chainkey :sym :symmetric nil nil (impl/rand-ba 32)) @@ -256,8 +256,8 @@ :key-id @auto-key-id_) (enc/unexpected-arg! return - :expected #{:keychain :as-map} - :context `keychain-add-symmetric-key)))) + {:expected #{:keychain :as-map} + :context `keychain-add-symmetric-key})))) (comment (keychain-add-symmetric-key (keychain) :random {:return :as-map})) @@ -320,8 +320,8 @@ :key-id @auto-key-id_) (enc/unexpected-arg! return - :expected #{:keychain :as-map} - :context `keychain-add-asymmetric-keypair)))) + {:expected #{:keychain :as-map} + :context `keychain-add-asymmetric-keypair})))) (comment (keychain-add-asymmetric-keypair (keychain) (impl/keypair-create :rsa-1024))) @@ -547,7 +547,7 @@ )) (enc/unexpected-arg! mode - :expected #{:ba-kc-prv :ba-kc-pub})) + {:expected #{:ba-kc-prv :ba-kc-pub}})) mkc (reduce-kv @@ -615,7 +615,7 @@ :prv [:key-prv (impl/as-key-prv key-algo nil key-ba)] :pub [:key-pub (impl/as-key-pub key-algo nil key-ba)] (enc/unexpected-arg! key-type - :expected #{:sym :prv :pub})) + {:expected #{:sym :prv :pub}})) ckey (ChainKey. (have key-type) (have key-algo) nil key-id key-cnt)] {:key-algo key-algo, :priority priority, key-at ckey}))] @@ -845,7 +845,7 @@ - Unencrypted: - Any public keys in keychain (retrieve with `public-data`) - - Optional AAD (see `doc-aad` docstring) + - Optional AAD (see `aad-help` docstring) - Envelope data necessary for decryption (specifies algorithms, etc.) Output can be safely stored (e.g. in a database). @@ -854,8 +854,8 @@ See Tempel Wiki for detailed usage info, common patterns, examples, etc. Options: - `:ba-aad` - See `doc-aad` docstring - `:ba-akm` - See `doc-akm` docstring + `:ba-aad` - See `aad-help` docstring + `:ba-akm` - See `akm-help` docstring `:ba-content` - Optional additional byte[] content that should be encrypted and included in output for retrieval with `keychain-decrypt`. @@ -1056,8 +1056,8 @@ :cnt (bytes/utf8-?ba->str ?ba-ucnt)) (enc/unexpected-arg! return - :expected #{:keychain :ba-content :ba-aad :as-map} - :context `keychain-decrypt))))))))))) + {:expected #{:keychain :ba-content :ba-aad :as-map} + :context `keychain-decrypt}))))))))))) (comment (keychain-decrypt (keychain-encrypt (keychain) "pwd") "pwd")) diff --git a/src/taoensso/tempel/pbkdf.clj b/src/taoensso/tempel/pbkdf.clj index 39bc839..80b8ae6 100644 --- a/src/taoensso/tempel/pbkdf.clj +++ b/src/taoensso/tempel/pbkdf.clj @@ -9,7 +9,7 @@ (comment (remove-ns 'taoensso.tempel.pbkdf) - (:public (enc/interns-overview))) + (:api (enc/interns-overview))) ;; Other options incl.: ;; - HKDF Ref. , etc. ; RFC 5869 @@ -62,8 +62,8 @@ (case algo-skf :hmac-sha-256 @skf-pbkdf2-hmac-sha-256_ (enc/unexpected-arg! algo-skf - :expected #{:hmac-sha-256} - :context `as-secret-key-factory-pbkdf2)))) + {:expected #{:hmac-sha-256} + :context `as-secret-key-factory-pbkdf2})))) (defn- pbkdf-pbkdf2 "Password-Based Key Derivation Function as per @@ -169,12 +169,12 @@ :pbkdf2-hmac-sha-256-v1 kit-pbkdf2-hmac-sha-256-v1 :sha-512-v1-deprecated kit-sha-512-v1-deprecated (enc/unexpected-arg! pbkdf-algo - :expected expected - :context `as-pbkdf-kit)) + {:expected expected + :context `as-pbkdf-kit})) (enc/satisfies! IPBKDFKit pbkdf-algo - :expected expected - :context `as-pbkdf-kit)))) + {:expected expected + :context `as-pbkdf-kit})))) (comment (as-pbkdf-kit pbkdf-kit-best-available)) @@ -326,13 +326,13 @@ (:ref-5000-msecs :r5000) (get ref-nwfs :r10) (:ref-max :rmax) rmax (enc/unexpected-arg! nwf - :context `pbkdf-nwf-parse - :expected - #{:ref-10-msecs :ref-50-msecs :ref-100-msecs :ref-200-msecs - :ref-500-msecs :ref-1000-msecs :ref-2000-msecs :ref-5000-msecs})) + {:context `pbkdf-nwf-parse + :expected + #{:ref-10-msecs :ref-50-msecs :ref-100-msecs :ref-200-msecs + :ref-500-msecs :ref-1000-msecs :ref-2000-msecs :ref-5000-msecs}})) nwf))] - (if (or (< nwf ^long rmin) (> nwf ^long rmax)) + (if (or (< nwf (long rmin)) (> nwf (long rmax))) (throw (ex-info (str "Invalid PBKDF normalized work factor: " nwf) {:pbkdf-kit (get pbkdf-kit :pbkdf-kit) diff --git a/test/taoensso/tempel_tests.clj b/test/taoensso/tempel_tests.clj index 2060b99..ba12524 100644 --- a/test/taoensso/tempel_tests.clj +++ b/test/taoensso/tempel_tests.clj @@ -2,7 +2,7 @@ (:require [clojure.test :as test :refer [deftest testing is]] [taoensso.encore :as enc :refer [have have? throws?]] - [taoensso.tempel.bytes :as bytes :refer [as-ba ba=]] + [taoensso.encore.bytes :as bytes :refer [as-ba ba=]] [taoensso.tempel.df :as df] [taoensso.tempel.impl :as impl] [taoensso.tempel.pbkdf :as pbkdf] @@ -15,108 +15,13 @@ (remove-ns 'taoensso.tempel-tests) (test/run-tests 'taoensso.tempel-tests)) -;;;; Bytes - -(deftest _ba-lengths - [(is (= (vec (bytes/ba->len 5 (as-ba [1 2 3]))) [1 2 3 0 0])) - (is (-> (vec (bytes/ba->sublen 5 (as-ba [1 2 3]))) throws?))]) - -(deftest _ba-join (is (= (vec (bytes/ba-join nil (as-ba [0]) (as-ba [1 2]) nil (as-ba [3 4 5]) nil nil (as-ba [6]))) [0 1 2 3 4 5 6]))) -(deftest _ba-parts - (let [ba (bytes/ba-join (as-ba [1 2]) (as-ba [3]) (as-ba [5 6]) (as-ba [7 8 9]))] - (is (= (mapv vec (bytes/ba-parts ba 0 2 1 1 0 0 0 1)) [[1 2] [3] [5] [] [] [] [6] [7 8 9]])))) - -(deftest _unsigned-ints - [(let [n Byte/MAX_VALUE] (is (= (bytes/from-ubyte (bytes/to-ubyte n)) n))) - (let [n Short/MAX_VALUE] (is (= (bytes/from-ushort (bytes/to-ushort n)) n))) - - (let [n bytes/ubyte-max] (is (= (bytes/to-ubyte (bytes/from-ubyte n)) n))) - (let [n bytes/ushort-max] (is (= (bytes/to-ushort (bytes/from-ushort n)) n)))]) - -(deftest _strings - [(let [s bytes/utf8-str] (is (= (-> s bytes/str->utf8-ba bytes/utf8-ba->str) s))) - (let [s bytes/utf8-str] (is (= (vec (bytes/as-ba s)) - [-32 -78 -84 -32 -78 -66 32 -32 -78 -121 -32 -78 -78 -32 -77 -115 -32 -78 -78 -32 - -78 -65 32 -32 -78 -72 -32 -78 -126 -32 -78 -83 -32 -78 -75 -32 -78 -65 -32 -78 -72])))]) - -(deftest _chars (let [s @#'bytes/utf8-str] (is (= (String. (bytes/as-ca s)) s)))) -(deftest _parse-buffer-len (is (= (bytes/parse-buffer-len [1 (as-ba 3)]) 4))) - -(deftest _with-io - [(is (= (bytes/with-in [in] (bytes/with-out [out] 1 (.writeByte out 67)) (.readByte in)) 67)) - (is (= (vec (bytes/with-out [out] [0 (as-ba 6)] (.writeByte out 1))) [1]))]) - -(deftest _dynamic-uints - [(let [ba (bytes/with-out [out] 16 (bytes/write-dynamic-uint out 0))] - [(is (= (count ba) 1)) ; 1+0=1 bytes - (is (= (bytes/with-in [in] ba (bytes/read-dynamic-uint in)) 0))]) - - (let [ba (bytes/with-out [out] 16 (bytes/write-dynamic-uint out bytes/ubyte-max))] - [(is (= (count ba) 2)) ; 1+1=2 bytes - (is (= (bytes/with-in [in] ba (bytes/read-dynamic-uint in)) bytes/ubyte-max))])]) - -(deftest _unsigned-io - [(is (= (bytes/with-in [in] (bytes/with-out [out] 2 (bytes/write-ubyte out bytes/ubyte-max)) (bytes/read-ubyte in)) bytes/ubyte-max)) - (is (= (bytes/with-in [in] (bytes/with-out [out] 2 (bytes/write-ushort out bytes/ushort-max)) (bytes/read-ushort in)) bytes/ushort-max))]) - -(deftest _dynamic-bas - [(let [dba (bytes/with-out [out] 1 (dotimes [_ 3] (bytes/write-dynamic-ba out nil)))] - (bytes/with-in [in] dba - (let [x1 (bytes/read-dynamic-ba in) - x2 (bytes/read-dynamic-ba! in) - [x3 n3] (bytes/read-dynamic-ba* in)] - - [(is (= x1 nil)) - (is (ba= x2 (as-ba 0))) - (is (= n3 1)) - (is (= x3 nil))]))) - - (let [dba (bytes/with-out [out] 1 (dotimes [_ 3] (bytes/write-dynamic-ba out (as-ba 0))))] - (bytes/with-in [in] dba - (let [x1 (bytes/read-dynamic-ba in) - x2 (bytes/read-dynamic-ba! in) - [x3 n3] (bytes/read-dynamic-ba* in)] - - [(is (= x1 nil)) - (is (ba= x2 (as-ba 0))) - (is (= n3 1)) - (is (= x3 nil))]))) - - (let [dba (bytes/with-out [out] 1 (dotimes [_ 3] (bytes/write-dynamic-ba out (as-ba [1 2 3]))))] - (bytes/with-in [in] dba - (let [x1 (bytes/read-dynamic-ba in) - x2 (bytes/read-dynamic-ba! in) - [x3 n3] (bytes/read-dynamic-ba* in)] - - [(is (ba= x1 (as-ba [1 2 3]))) - (is (ba= x2 (as-ba [1 2 3]))) - (is (= n3 4)) - (is (ba= x3 (as-ba [1 2 3])))])))]) - -(deftest _dynamic-strs - (let [dba - (bytes/with-out [out] 1 - (bytes/write-dynamic-str out nil) - (bytes/write-dynamic-str out nil) - (bytes/write-dynamic-str out "") - (bytes/write-dynamic-str out "") - (bytes/write-dynamic-str out bytes/utf8-str))] - - (bytes/with-in [in] dba - (let [x1 (bytes/read-dynamic-str in) - x2 (bytes/read-dynamic-str! in) - x3 (bytes/read-dynamic-str in) - x4 (bytes/read-dynamic-str! in) - x5 (bytes/read-dynamic-str in)] - (is (= [x1 x2 x3 x4 x5] [nil "" nil "" bytes/utf8-str])))))) +;;;; Implementation (deftest _headers [(is (= (bytes/with-in [in] (bytes/with-out [out] 4 (df/write-head out) (.write out 1)) (df/read-head! in) (.readByte in)) 1)) (is (->> (bytes/with-in [in] (bytes/with-out [out] 4 (.write out 1)) (df/read-head! in)) (enc/throws? :ex-info {:read {:expected [84 80 76]}})))]) -;;;; Implementation - (deftest _randomness (let [k1 (impl/with-srng-insecure-deterministic!!! 10 (:key-prv (impl/keypair-create* :rsa-2048))) k2 (impl/with-srng-insecure-deterministic!!! 10 (:key-prv (impl/keypair-create* :rsa-2048))) @@ -418,16 +323,13 @@ (def ba-!akm (as-ba "!akm"))) (defmacro is= [form expect & [msg]] - `(let [expect# ~expect - result# (try ~form (catch Throwable t# {:err t#}))] - (is - (if-let [err# (:err result#)] - (when-let [expect# (:err expect#)] - (boolean (enc/-matching-error :any expect# err#))) - (if (map? expect#) - (enc/submap? result# expect#) - (= result# expect#))) - ~msg))) + (if-let [expect-err (:err expect)] + `(let [result-err# (try ~form nil (catch Throwable t# t#))] + (is (enc/-matching-error :any ~expect-err result-err#) ~msg)) + + (if (map? expect) + `(is (enc/submap? ~form ~expect) ~msg) + `(is (= ~form ~expect) ~msg)))) (comment [(is= (/ 1 0) {:err "Divide"}) @@ -484,8 +386,8 @@ (is= (dec (enc ba-cnt kc1 {:ba-aad ba-aad :ba-akm ba-akm}) kc1 {:ba-akm ba-akm }) {:cnt cnt, :aad "aad"} "+AKM, +AAD") - (is= (dec (enc ba-cnt kc1 { }) kc2 { }) {:err "Decryption error"} "Bad key") - (is= (dec (enc ba-cnt kc1 {:ba-akm ba-akm}) kc1 {:ba-akm ba-!akm}) {:err "Tag mismatch"} "Bad AKM") + (is= (dec (enc ba-cnt kc1 { }) kc2 { }) {:err #{"Decryption error" "Message is larger than modulus"}} "Bad key") + (is= (dec (enc ba-cnt kc1 {:ba-akm ba-akm}) kc1 {:ba-akm ba-!akm}) {:err "Tag mismatch"} "Bad AKM") (is= (pd (enc ba-cnt kc1 { })) {:kind :encrypted-with-1-keypair, :key-algo :rsa-1024, :key-id "a" } "Public data") (is= (pd (enc ba-cnt kc1 {:ba-aad ba-aad})) {:kind :encrypted-with-1-keypair, :key-algo :rsa-1024, :key-id "a", :aad "aad"} "Public data +AAD")]))))