From 2b750a3bcbcef213648bac0e9def8239ad3b4c36 Mon Sep 17 00:00:00 2001 From: Daniel Petranek Date: Wed, 16 Nov 2022 16:02:30 -0600 Subject: [PATCH 1/5] Use EcdsaSecp256k1RecoverySignature2020 for verifiable credentials This is just the jvm implementation, cljs is a bit thornier. --- deps.edn | 2 +- src/fluree/db/did.cljc | 43 +++++- src/fluree/db/json_ld/credential.cljc | 194 ++++++-------------------- src/fluree/db/util/core.cljc | 2 +- 4 files changed, 88 insertions(+), 153 deletions(-) diff --git a/deps.edn b/deps.edn index abe6fd9d7..49f693262 100644 --- a/deps.edn +++ b/deps.edn @@ -10,7 +10,7 @@ cheshire/cheshire {:mvn/version "5.11.0"} instaparse/instaparse {:mvn/version "1.4.12"} com.fluree/json-ld {:git/url "https://github.com/fluree/json-ld.git" - :sha "edb189ce94282b1ea27fd04bb999c91f1492bf4b"} + :sha "d8aa2ebbfc87f201dbbafc66034f3cedc3c06ddf"} ;; logging org.clojure/tools.logging {:mvn/version "1.2.4"} diff --git a/src/fluree/db/did.cljc b/src/fluree/db/did.cljc index d146e57e0..0d5b93ec0 100644 --- a/src/fluree/db/did.cljc +++ b/src/fluree/db/did.cljc @@ -1,5 +1,8 @@ (ns fluree.db.did - (:require [fluree.crypto :as crypto])) + (:require [fluree.crypto :as crypto] + [alphabase.core :as alphabase] + [alphabase.base58 :as base58] + [clojure.string :as str])) ;; did operations @@ -28,4 +31,40 @@ (let [public (crypto/pub-key-from-private private-key) auth-id (crypto/account-id-from-public public) did-id (auth-id->did auth-id)] - (did-map did-id public private-key))) \ No newline at end of file + (did-map did-id public private-key))) + +;; https://github.com/multiformats/multicodec/blob/master/table.csv +(def secp256k1-pub + "The multicodec prefix for a secp256k1 public key." + "e7") + +(defn encode-did-key + "Encodes a secp256k1 public key as a base58 multibase did:key." + [pubkey] + (let [pubkey-header secp256k1-pub] + (str "did:key:z" (base58/encode (alphabase/hex->bytes (str pubkey-header pubkey)))))) + +;; https://github.com/multiformats/multibase/blob/master/multibase.csv +(def base58btc + "The multibase prefix for a base58btc encoded string." + "z") + +(defn decode-did-key + "Return the hex encoded public key from a did:key, or nil if it is not a properly + encoded secp256k1 public key." + [did] + (let [[_ _ multibase-value] (str/split did #":") + prefix (str (first multibase-value)) + base-key (subs multibase-value 1) + _ (when (not= prefix base58btc) + (throw (ex-info (str "The prefix " (pr-str prefix) " does not map to a supported multibase encoding." + {:value multibase-value + :prefix prefix})))) + multicodec (alphabase/bytes->hex (base58/decode base-key)) + pubkey-header (subs multicodec 0 2) + pubkey (subs multicodec 2)] + (when (not= pubkey-header secp256k1-pub) + (throw (ex-info (str "The multicodec header " (pr-str pubkey-header) " does not map to a supported multicodec encoding." + {:value multicodec + :header pubkey-header}))) + pubkey))) diff --git a/src/fluree/db/json_ld/credential.cljc b/src/fluree/db/json_ld/credential.cljc index a84ad374b..66c3411ba 100644 --- a/src/fluree/db/json_ld/credential.cljc +++ b/src/fluree/db/json_ld/credential.cljc @@ -1,13 +1,11 @@ (ns fluree.db.json-ld.credential - (:require [fluree.db.util.json :as json] - [fluree.db.util.core :as util #?(:clj :refer :cljs :refer-macros) [try* catch*]] + (:require [fluree.db.util.core :as util #?(:clj :refer :cljs :refer-macros) [try* catch*]] [fluree.crypto :as crypto] [alphabase.core :as alphabase] [clojure.string :as str] [fluree.json-ld :as json-ld] - [fluree.db.util.core :as util] - [fluree.db.util.log :as log :include-macros true] - [fluree.db.constants :as const])) + [fluree.json-ld.processor.api :as jld-processor] + [fluree.db.did :as did])) #?(:clj (set! *warn-on-reflection* true)) @@ -22,33 +20,13 @@ (def jws-header-json (json-ld/normalize-data jws-header {:algorithm :basic :format :application/json})) - (def jws-header-b64 (alphabase/base-to-base jws-header-json :string :base64url)) -#_(defn credential-json - "Takes final credential response object (as returned by sign-credential) - and formats JSON document ready for publishing." - [credential-object] - (let [{:keys [credential normalized]} credential-object - proof (get credential "proof") - ;; TODO: implement URDNA2015 - proof-normalized (json-ld/normalize-data proof)] - (str (subs normalized 0 (dec (count normalized))) ;; remove trailing '}', then add back - ",\"proof\":" proof-normalized "}"))) - - -(defn signing-input - "JOSE JWS signing input is b64URL of header, + '.' + b64URL of json to be signed. - The resulting input is hashed with SHA-256, and that result is what is signed." - [payload] - (str jws-header-b64 "." (alphabase/base-to-base payload :string :base64url))) - - (defn serialize-jws "Serialize a JWS according to the JOSE specification, compact form." - [signing-input signature] - (str signing-input "." signature)) + [signature] + (str jws-header-b64 ".." signature)) (defn deserialize-jws @@ -63,142 +41,60 @@ (defn sign "Given a payload and a signing key, returns a JOSE JSON Web Signature." [payload signing-key] - (let [signing-input (signing-input payload) - signature (crypto/sign-message signing-input signing-key) + (let [signature (crypto/sign-message payload signing-key) b64-signature (alphabase/base-to-base signature :hex :base64url)] - (serialize-jws signing-input b64-signature))) - + (serialize-jws b64-signature))) (defn create-proof "Given a canonicalized credential-subject, create a proof for it." - ;; TODO: this is using a custom proof @type, and it should use EcdsaSecp256k1RecoverySignature2020 which requires RDF normalization [credential-subject issuer signing-key] - {"type" "https://flur.ee/ns/v1#EcdsaSecp256k1RecoverySignature2020" + {"type" "EcdsaSecp256k1RecoverySignature2020" "created" (util/current-time-iso) "verificationMethod" issuer "proofPurpose" "assertionMethod" - "jws" (sign credential-subject signing-key)}) - + "jws" (sign (crypto/sha2-256 credential-subject) signing-key)}) (defn generate "Generate a VerifiableCredential given a subject and some issuer opts." - ([credential-subject private] (generate credential-subject private nil)) + ([credential-subject private] (generate credential-subject private (did/private->did-map private))) ([credential-subject private did] - (let [[c-subj ctx] (if-let [ctx (get credential-subject "@context")] - [(dissoc credential-subject "@context") ctx] - [credential-subject nil]) - did* (or did - (str "did:fluree:" (crypto/account-id-from-private private)))] - {"@context" (if ctx - ["https://www.w3.org/2018/credentials/v1" ctx] - "https://www.w3.org/2018/credentials/v1") - "id" "" - "type" ["VerifiableCredential" "CommitProof"] - "issuer" did* - "issuanceDate" (util/current-time-iso) - "credentialSubject" c-subj - "proof" (create-proof (json-ld/normalize-data credential-subject) did* private)}))) - + {"@context" "https://www.w3.org/2018/credentials/v1" + "id" "" + "type" ["VerifiableCredential" "CommitProof"] + "issuer" (:id did) + "issuanceDate" (util/current-time-iso) + "credentialSubject" credential-subject + ;; note: canonize/expand will remove keys not specified in the context + "proof" (create-proof (jld-processor/canonize credential-subject) + (did/encode-did-key (:public did)) + private)})) (defn verify - "Takes a credential" + "Takes a credential and returns true if it verifies." [credential] (try* - (let [proof-did (get-in credential ["proof" "verificationMethod"]) - jws (get-in credential ["proof" "jws"]) - {:keys [header payload signature]} (deserialize-jws jws) - signing-input (signing-input payload) - key-id (crypto/account-id-from-message signing-input signature) - derived-did (str "did:fluree:" key-id)] - (cond-> {:credential credential} - (not= jws-header-json header) - (update :errors (fnil conj []) - {:error :credential/unknown-signing-algorithm - :message (str "Unsupported jws header in credential: " header)}) - - (not= derived-did proof-did) - (update :errors (fnil conj []) - {:error :credential/invalid-signature - :message (str "Derived did from signature does not match did in 'proof' of credential. Derived: " - derived-did ", proof verificationMethod: " proof-did)}))) + (let [jws (get-in credential ["proof" "jws"]) + {:keys [header signature]} (deserialize-jws jws) + + signing-input (-> (get credential "credentialSubject") + (jld-processor/canonize) + (crypto/sha2-256)) + + proof-did (get-in credential ["proof" "verificationMethod"]) + pubkey (did/decode-did-key proof-did)] + (when (not= jws-header-json header) + (throw (ex-info "Unsupported jws header in credential." + {:error :credential/unknown-signing-algorithm + :supported-header jws-header-json + :header header + :credential credential}))) + + (when (not (crypto/verify-signature pubkey signing-input signature)) + (throw (ex-info "Verification failed." {:error :credential/invalid-signature :credential credential}))) + ;; everything is good + true) (catch* e - {:credential credential - :errors [{:error :credential/unverifiable - :message e}]}))) - -(comment - (def in "{\"@context\":[\"https://www.w3.org/2018/credentials/v1\",\"https://flur.ee/ns/block\"],\"credentialSubject\":{\"@context\":[\"https://flur.ee/ns/block\"],\"@type\":[\"https://flur.ee/ns/block/Commit\"],\"https://flur.ee/ns/block/branchName\":\"main\",\"https://flur.ee/ns/block/time\":\"2022-03-16T06:06:49.426747Z\",\"https://flur.ee/ns/block/tx-hash\":\"urn:sha256:3d97c6550bfb7e8e33e9d884ec753016857f680a2790a9f85cdfdc08d516458d\",\"https://flur.ee/ns/block/txs\":[{\"@context\":{},\"https://flur.ee/ns/tx/assert\":[{\"@id\":\"eb1332cb-3395-4ecc-a526-4129f0cbeaea\",\"book/author\":\"Neal Stephenson\",\"book/title\":\"Anathem\"}],\"https://flur.ee/ns/tx/t\":1},{\"@context\":{},\"https://flur.ee/ns/tx/assert\":[{\"@id\":\"fee1ea15-7caf-4b40-a069-2110cded0600\",\"book/author\":\"Neal Stephenson\",\"book/title\":\"Cryptonomicon\"}],\"https://flur.ee/ns/tx/t\":2},{\"@context\":{},\"https://flur.ee/ns/tx/assert\":[{\"@id\":\"b3e2cf9d-dbe5-4e93-bae5-def04fbdb69f\",\"book/author\":\"brandon sanderson\",\"book/title\":\"mistborn\"}],\"https://flur.ee/ns/tx/t\":3},{\"@context\":{},\"https://flur.ee/ns/tx/assert\":[{\"@id\":\"b3e2cf9d-dbe5-4e93-bae5-def04fbdb69f\",\"book/author\":\"Brandon Sanderson\",\"book/title\":\"Mistborn\"}],\"https://flur.ee/ns/tx/retract\":[{\"@id\":\"b3e2cf9d-dbe5-4e93-bae5-def04fbdb69f\",\"book/author\":\"brandon sanderson\",\"book/title\":\"mistborn\"}],\"https://flur.ee/ns/tx/t\":4},{\"@context\":{},\"https://flur.ee/ns/tx/assert\":[{\"@id\":\"49ad3fc7-64ae-4f68-85d6-5cb7f5a58fd9\",\"book/author\":\"China Mieville\",\"book/title\":\"The City & The City\"}],\"https://flur.ee/ns/tx/t\":5}]},\"id\":\"https://flur.ee/ns/credential\",\"issuanceDate\":\"2022-03-16T06:06:49.429686Z\",\"issuer\":\"did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6\",\"proof\":{\"created\":\"2022-03-16T06:06:49.430023Z\",\"jws\":\"eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19.eyJAY29udGV4dCI6WyJodHRwczovL2ZsdXIuZWUvbnMvYmxvY2siXSwiQHR5cGUiOlsiaHR0cHM6Ly9mbHVyLmVlL25zL2Jsb2NrL0NvbW1pdCJdLCJodHRwczovL2ZsdXIuZWUvbnMvYmxvY2svYnJhbmNoTmFtZSI6Im1haW4iLCJodHRwczovL2ZsdXIuZWUvbnMvYmxvY2svdGltZSI6IjIwMjItMDMtMTZUMDY6MDY6NDkuNDI2NzQ3WiIsImh0dHBzOi8vZmx1ci5lZS9ucy9ibG9jay90eC1oYXNoIjoidXJuOnNoYTI1NjozZDk3YzY1NTBiZmI3ZThlMzNlOWQ4ODRlYzc1MzAxNjg1N2Y2ODBhMjc5MGE5Zjg1Y2RmZGMwOGQ1MTY0NThkIiwiaHR0cHM6Ly9mbHVyLmVlL25zL2Jsb2NrL3R4cyI6W3siQGNvbnRleHQiOnt9LCJodHRwczovL2ZsdXIuZWUvbnMvdHgvYXNzZXJ0IjpbeyJAaWQiOiJlYjEzMzJjYi0zMzk1LTRlY2MtYTUyNi00MTI5ZjBjYmVhZWEiLCJib29rL2F1dGhvciI6Ik5lYWwgU3RlcGhlbnNvbiIsImJvb2svdGl0bGUiOiJBbmF0aGVtIn1dLCJodHRwczovL2ZsdXIuZWUvbnMvdHgvdCI6MX0seyJAY29udGV4dCI6e30sImh0dHBzOi8vZmx1ci5lZS9ucy90eC9hc3NlcnQiOlt7IkBpZCI6ImZlZTFlYTE1LTdjYWYtNGI0MC1hMDY5LTIxMTBjZGVkMDYwMCIsImJvb2svYXV0aG9yIjoiTmVhbCBTdGVwaGVuc29uIiwiYm9vay90aXRsZSI6IkNyeXB0b25vbWljb24ifV0sImh0dHBzOi8vZmx1ci5lZS9ucy90eC90IjoyfSx7IkBjb250ZXh0Ijp7fSwiaHR0cHM6Ly9mbHVyLmVlL25zL3R4L2Fzc2VydCI6W3siQGlkIjoiYjNlMmNmOWQtZGJlNS00ZTkzLWJhZTUtZGVmMDRmYmRiNjlmIiwiYm9vay9hdXRob3IiOiJicmFuZG9uIHNhbmRlcnNvbiIsImJvb2svdGl0bGUiOiJtaXN0Ym9ybiJ9XSwiaHR0cHM6Ly9mbHVyLmVlL25zL3R4L3QiOjN9LHsiQGNvbnRleHQiOnt9LCJodHRwczovL2ZsdXIuZWUvbnMvdHgvYXNzZXJ0IjpbeyJAaWQiOiJiM2UyY2Y5ZC1kYmU1LTRlOTMtYmFlNS1kZWYwNGZiZGI2OWYiLCJib29rL2F1dGhvciI6IkJyYW5kb24gU2FuZGVyc29uIiwiYm9vay90aXRsZSI6Ik1pc3Rib3JuIn1dLCJodHRwczovL2ZsdXIuZWUvbnMvdHgvcmV0cmFjdCI6W3siQGlkIjoiYjNlMmNmOWQtZGJlNS00ZTkzLWJhZTUtZGVmMDRmYmRiNjlmIiwiYm9vay9hdXRob3IiOiJicmFuZG9uIHNhbmRlcnNvbiIsImJvb2svdGl0bGUiOiJtaXN0Ym9ybiJ9XSwiaHR0cHM6Ly9mbHVyLmVlL25zL3R4L3QiOjR9LHsiQGNvbnRleHQiOnt9LCJodHRwczovL2ZsdXIuZWUvbnMvdHgvYXNzZXJ0IjpbeyJAaWQiOiI0OWFkM2ZjNy02NGFlLTRmNjgtODVkNi01Y2I3ZjVhNThmZDkiLCJib29rL2F1dGhvciI6IkNoaW5hIE1pZXZpbGxlIiwiYm9vay90aXRsZSI6IlRoZSBDaXR5ICYgVGhlIENpdHkifV0sImh0dHBzOi8vZmx1ci5lZS9ucy90eC90Ijo1fV19.HDBEAiA4cRt_SxUN6QrD_5TVsP0usSO-xQO5V0oGoaN_djW0PAIgWTo3nNcgqds93a4Cn5i83PvN52BQ-MdksY-aC9ikAjc=\",\"proofPurpose\":\"assertionMethod\",\"type\":\"https://flur.ee/ns/v1#EcdsaSecp256k1RecoverySignature2020\",\"verificationMethod\":\"did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6\"},\"type\":[\"VerifiableCredential\"]}") - - (def did {:id "did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6" - :private "8ce4eca704d653dec594703c81a84c403c39f262e54ed014ed857438933a2e1c" - :public "030be728546a7fe37bb527749e19515bd178ba8a5485ebd1c37cdf093cf2c247ca"}) - - (verify (json/parse in false)) - - - - - - (def kp (crypto/generate-key-pair)) - (def payload {"@context" ["https://www.w3.org/2018/credentials/v1" "https://flur.ee/ns/block"], - "id" "blah", - "type" ["VerifiableCredential" "Commit"], - "issuer" "did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6", - "issuanceDate" "SOMEDATE", - "credentialSubject" {"@context" ["https://flur.ee/ns/block" - {"id" "@id" , - "type" "@type" , - "rdfs" "http://www.w3.org/2000/01/rdf-schema#" , - "schema" "http://schema.org/" , - "wiki" "https://www.wikidata.org/wiki/" , - "schema:isBasedOn" {"@type" "@id"} , - "schema:author" {"@type" "@id"}}] , - "type" ["Commit"] , - "branch" "main" , - "t" 1, - "message" "Initial commit" , - "assert" [{"type" "rdfs:Class" , "id" "schema:Movie"} - {"type" "rdfs:Class" , "id" "schema:Book"} - {"type" "rdfs:Class" , "id" "schema:Person"} - {"schema:isBasedOn" "wiki:Q3107329" , - "schema:titleEIDR" "10.5240/B752-5B47-DBBE-E5D4-5A3F-N" , - "schema:disambiguatingDescription" "2005 British-American comic science fiction film directed by Garth Jennings" , - "schema:name" "The Hitchhiker's Guide to the Galaxy" , - "type" "schema:Movie" , - "id" "wiki:Q836821"} - {"schema:author" "wiki:Q42" , - "schema:isbn" "0-330-25864-8" , - "schema:name" "The Hitchhiker's Guide to the Galaxy" , - "type" "schema:Book" , - "id" "wiki:Q3107329"} - {"schema:name" "Douglas Adams" , "type" "schema:Person" , "id" "wiki:Q42"}]}}) - - (def cred (sign payload (:private kp))) - - (verify-jws (:credential cred)) - - (def jws (-> cred :credential (get "proof") (get "jws"))) - - (= (json-ld/normalize-data payload) - (:payload (jose-deserialize-compact jws))) - - (verify-jws (:credential cred)) - ["did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6" "did:fluree:Tf25LUDWuX57vWi2ZddXxmkQLWv5TD5UR5h"] - - - - - (-> (:credential cred) - (json/stringify ) - (json/parse false) - (get "proof") - (dissoc "jws")) - {"type" "https://flur.ee/ns/v1#EcdsaSecp256k1RecoverySignature2020", "created" "2022-01-26T17:41:18.374232Z", "verificationMethod" "did:fluree:TfCzWTrXqF16hvKGjcYiLxRoYJ1B8a6UMH6", "proofPurpose" "assertionMethod"} - - - (:normalized cred) - - - - (verify cred) - ,) + (throw (ex-info "Unverifiable credential" + {:credential credential + :error :credential/unverifiable + :message e}))))) diff --git a/src/fluree/db/util/core.cljc b/src/fluree/db/util/core.cljc index 670e60b54..9b443b79b 100644 --- a/src/fluree/db/util/core.cljc +++ b/src/fluree/db/util/core.cljc @@ -387,4 +387,4 @@ ([vol f arg1 arg2] (clojure.core/vswap! vol f arg1 arg2)) ([vol f arg1 arg2 arg3] - (clojure.core/vswap! vol f arg1 arg2 arg3))) \ No newline at end of file + (clojure.core/vswap! vol f arg1 arg2 arg3))) From 46bb2553df16dfd651fce6d9e5be3669a1a636b4 Mon Sep 17 00:00:00 2001 From: Daniel Petranek Date: Thu, 17 Nov 2022 11:30:49 -0600 Subject: [PATCH 2/5] Add cljs support for EcdsaSecp256k1RecoverySignature2020 The jld-processor/canonize function has differing calling conventions for cljs and clj - in cljs it returns a promise, in clj it is synchronous. This wraps the calls in an core async go block and reads the promise with the handy did-map private))) ([credential-subject private did] - {"@context" "https://www.w3.org/2018/credentials/v1" - "id" "" - "type" ["VerifiableCredential" "CommitProof"] - "issuer" (:id did) - "issuanceDate" (util/current-time-iso) - "credentialSubject" credential-subject - ;; note: canonize/expand will remove keys not specified in the context - "proof" (create-proof (jld-processor/canonize credential-subject) - (did/encode-did-key (:public did)) - private)})) + (go-try + {"@context" "https://www.w3.org/2018/credentials/v1" + "id" "" + "type" ["VerifiableCredential" "CommitProof"] + "issuer" (:id did) + "issuanceDate" (util/current-time-iso) + "credentialSubject" credential-subject + "proof" #?(:clj (create-proof (-> (jld-processor/canonize credential-subject) + (crypto/sha2-256)) + (did/encode-did-key (:public did)) + private) + :cljs (let [canonicalized ( (get credential "credentialSubject") - (jld-processor/canonize) - (crypto/sha2-256)) - - proof-did (get-in credential ["proof" "verificationMethod"]) - pubkey (did/decode-did-key proof-did)] - (when (not= jws-header-json header) - (throw (ex-info "Unsupported jws header in credential." - {:error :credential/unknown-signing-algorithm - :supported-header jws-header-json - :header header - :credential credential}))) - - (when (not (crypto/verify-signature pubkey signing-input signature)) - (throw (ex-info "Verification failed." {:error :credential/invalid-signature :credential credential}))) - ;; everything is good - true) - (catch* e - (throw (ex-info "Unverifiable credential" - {:credential credential - :error :credential/unverifiable - :message e}))))) + (go-try + (try* + (let [jws (get-in credential ["proof" "jws"]) + {:keys [header signature]} (deserialize-jws jws) + + signing-input #?(:clj (-> (get credential "credentialSubject") + (jld-processor/canonize) + (crypto/sha2-256)) + :cljs ( (get credential "credentialSubject") + (jld-processor/canonize) + (.then (fn [res] (crypto/sha2-256 res)))))) + + proof-did (get-in credential ["proof" "verificationMethod"]) + pubkey (did/decode-did-key proof-did)] + (when (not= jws-header-json header) + (throw (ex-info "Unsupported jws header in credential." + {:error :credential/unknown-signing-algorithm + :supported-header jws-header-json + :header header + :credential credential}))) + + (when (not (crypto/verify-signature pubkey signing-input signature)) + (throw (ex-info "Verification failed." {:error :credential/invalid-signature :credential credential}))) + ;; everything is good + true) + (catch* e + (throw (ex-info "Unverifiable credential" + {:credential credential + :error :credential/unverifiable + :message e})))))) diff --git a/test/fluree/db/json_ld/credential_test.cljc b/test/fluree/db/json_ld/credential_test.cljc new file mode 100644 index 000000000..653c6c0d0 --- /dev/null +++ b/test/fluree/db/json_ld/credential_test.cljc @@ -0,0 +1,90 @@ +(ns fluree.db.json-ld.credential-test + (:require [fluree.db.json-ld.credential :as cred] + [clojure.core.async :as async] + #?(:clj [clojure.test :as t :refer [deftest testing is]] + :cljs [cljs.test :as t :refer [deftest testing is] :include-macros true]))) + +(def auth + {:id "did:fluree:TfHgFTQQiJMHaK1r1qxVPZ3Ridj9pCozqnh" + :public "03b160698617e3b4cd621afd96c0591e33824cb9753ab2f1dace567884b4e242b0" + :private "509553eece84d5a410f1012e8e19e84e938f226aa3ad144e2d12f36df0f51c1e"}) + +(def example-cred-subject {"@context" {"a" "http://a.com/"} "a:foo" "bar"}) + +(def clj-generated-jws + "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..HDBFAiEA80-G5gUH6BT9D1Mc-YyWbjuwbL7nKfWj6BrsHS6whQ0CIAcjzJvo0sW52FIlgvxy0hPBKNWolIwLvoedG_4HQu_V") + +(def cljs-generated-jws + "eyJhbGciOiJFUzI1NkstUiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..HDBFAiEAy9MuRjVn_vwvEgQlsCJNnSYwCJEWU_UOg5U_R8--87wCID-qficJv-aCUotctcFGX-xTky1E08W2Y7utUCJZ3AZY") + +(def expected-credential + {"@context" "https://www.w3.org/2018/credentials/v1" + "id" "" + "type" ["VerifiableCredential" "CommitProof"] + "issuer" "did:fluree:TfHgFTQQiJMHaK1r1qxVPZ3Ridj9pCozqnh" + "issuanceDate" "1970-01-01T00:00:00.00000Z" + "credentialSubject" {"@context" {"a" "http://a.com/"} "a:foo" "bar"} + "proof" {"type" "EcdsaSecp256k1RecoverySignature2020" + "created" "1970-01-01T00:00:00.00000Z" + "verificationMethod" "did:key:z6DuABnw7XPbMksZo5wY4HweN8wPkEd7rCQM4YGgu8hPqrd5" + "proofPurpose" "assertionMethod" + "jws" #?(:clj clj-generated-jws + :cljs cljs-generated-jws)}}) + +#?(:clj + (deftest credential-test + (with-redefs [fluree.db.util.core/current-time-iso (constantly "1970-01-01T00:00:00.00000Z")] + (testing "generate" + (let [cred (async/ (async/map) + (:cause))))))))) + +#?(:cljs + (deftest generate + (t/async done + (async/go + (with-redefs [fluree.db.util.core/current-time-iso (constantly "1970-01-01T00:00:00.00000Z")] + (let [cred (async/ (async/ Date: Tue, 29 Nov 2022 16:37:43 -0600 Subject: [PATCH 3/5] Update json-ld dep, fix compile warnings Accidentally wrapped the ex-info info in the `str` call. --- deps.edn | 2 +- src/deps.cljs | 2 +- src/fluree/db/did.cljc | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/deps.edn b/deps.edn index e94f2afe8..8a179fa2a 100644 --- a/deps.edn +++ b/deps.edn @@ -10,7 +10,7 @@ cheshire/cheshire {:mvn/version "5.11.0"} instaparse/instaparse {:mvn/version "1.4.12"} com.fluree/json-ld {:git/url "https://github.com/fluree/json-ld.git" - :sha "353e90d7fe3fb4452c70a6c873edb684df662a03"} + :sha "b888d07683ebc03e9d0475c2f9bb87fe0106d774"} ;; logging org.clojure/tools.logging {:mvn/version "1.2.4"} diff --git a/src/deps.cljs b/src/deps.cljs index ba9bf902b..b3470c210 100644 --- a/src/deps.cljs +++ b/src/deps.cljs @@ -1,3 +1,3 @@ ;; This file is auto-generated by target-bundle-libs. DO NOT EDIT! -{:npm-deps {"bufferutil" "^4.0.7", "utf-8-validate" "^5.0.10", "axios" "^0.27.2", "@cljs-oss/module-deps" "^1.1.1", "seedrandom" "^3.0.5", "source-map-support" "^0.5.21", "js-sha3" "^0.8.0", "scrypt-js" "^3.0.1", "ws" "^8.8.0", "form-data" "^4.0.0", "@fluree/sjcl" "^1.0.8-3"}} \ No newline at end of file +{:npm-deps {"bufferutil" "^4.0.7", "utf-8-validate" "^5.0.10", "axios" "^0.27.2", "jsonld" "^8.1.0", "@cljs-oss/module-deps" "^1.1.1", "seedrandom" "^3.0.5", "source-map-support" "^0.5.21", "js-sha3" "^0.8.0", "scrypt-js" "^3.0.1", "ws" "^8.8.0", "form-data" "^4.0.0", "@fluree/sjcl" "^1.0.8-3"}} \ No newline at end of file diff --git a/src/fluree/db/did.cljc b/src/fluree/db/did.cljc index 25d8f660f..82b540eb1 100644 --- a/src/fluree/db/did.cljc +++ b/src/fluree/db/did.cljc @@ -57,14 +57,14 @@ prefix (str (first multibase-value)) base-key (subs multibase-value 1) _ (when (not= prefix base58btc) - (throw (ex-info (str "The prefix " (pr-str prefix) " does not map to a supported multibase encoding." - {:value multibase-value - :prefix prefix})))) + (throw (ex-info (str "The prefix " (pr-str prefix) " does not map to a supported multibase encoding.") + {:value multibase-value + :prefix prefix}))) multicodec (alphabase/bytes->hex (base58/decode base-key)) pubkey-header (subs multicodec 0 2) pubkey (subs multicodec 2)] (when (not= pubkey-header secp256k1-pub) - (throw (ex-info (str "The multicodec header " (pr-str pubkey-header) " does not map to a supported multicodec encoding." - {:value multicodec - :header pubkey-header})))) + (throw (ex-info (str "The multicodec header " (pr-str pubkey-header) " does not map to a supported multicodec encoding.") + {:value multicodec + :header pubkey-header}))) pubkey)) From be7aa70f9807807eb901dcd857cad6322b9ae62c Mon Sep 17 00:00:00 2001 From: Daniel Petranek Date: Tue, 29 Nov 2022 17:14:24 -0600 Subject: [PATCH 4/5] Configure nodejs test to use ESM https://jestjs.io/docs/ecmascript-modules It was failing without this. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6f65f1a79..440a7afea 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ cljs-node-test: node_modules package-lock.json npx shadow-cljs release node-test nodejs-test: out/flureenjs.js - cd test/nodejs && npm install && npm test + cd test/nodejs && npm install && node --experimental-vm-modules node_modules/jest/bin/jest.js browser-test: out/flureedb.js cd test/browser && npm install && npm ci From 0fd9268de16d7d9c5afa5873dc465fabd1e8a6ae Mon Sep 17 00:00:00 2001 From: Daniel Petranek Date: Wed, 30 Nov 2022 15:45:34 -0600 Subject: [PATCH 5/5] Update json-ld dep --- deps.edn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps.edn b/deps.edn index 8a179fa2a..57dd14ffe 100644 --- a/deps.edn +++ b/deps.edn @@ -10,7 +10,7 @@ cheshire/cheshire {:mvn/version "5.11.0"} instaparse/instaparse {:mvn/version "1.4.12"} com.fluree/json-ld {:git/url "https://github.com/fluree/json-ld.git" - :sha "b888d07683ebc03e9d0475c2f9bb87fe0106d774"} + :sha "2e69362f611def8cc6793c6ddf24e4671fb6f397"} ;; logging org.clojure/tools.logging {:mvn/version "1.2.4"}