Upgraded to Bouncy Castle 1.50 and removed direct calls to addProvider
This commit is contained in:
parent
284727d150
commit
e13b665c1b
6 changed files with 146 additions and 101 deletions
|
@ -6,9 +6,8 @@
|
||||||
:dependencies [[org.clojure/clojure "1.6.0"]
|
:dependencies [[org.clojure/clojure "1.6.0"]
|
||||||
[org.clojure/data.json "0.2.6"]
|
[org.clojure/data.json "0.2.6"]
|
||||||
[org.clojure/data.codec "0.1.0"]
|
[org.clojure/data.codec "0.1.0"]
|
||||||
[org.bouncycastle/bcprov-jdk15 "1.46"]
|
[org.bouncycastle/bcpkix-jdk15on "1.50"]
|
||||||
[crypto-equality "1.0.0"]
|
[crypto-equality "1.0.0"]
|
||||||
[clj-time "0.9.0"]]
|
[clj-time "0.9.0"]]
|
||||||
|
|
||||||
:profiles {:dev {:dependencies [[midje "1.6.3" :exclusions [org.clojure/clojure]]]}}
|
:profiles {:dev {:dependencies [[midje "1.6.3" :exclusions [org.clojure/clojure]]]}}
|
||||||
:plugins [[lein-midje "3.1.3"]])
|
:plugins [[lein-midje "3.1.3"]])
|
||||||
|
|
|
@ -1,44 +1,84 @@
|
||||||
(ns clj-jwt.key
|
(ns clj-jwt.key
|
||||||
(:require [clojure.java.io :as io])
|
(:require [clojure.java.io :as io])
|
||||||
(:import [org.bouncycastle.openssl PasswordFinder PEMReader]
|
(:import [org.bouncycastle.openssl PEMParser PEMKeyPair PEMEncryptedKeyPair]
|
||||||
|
[org.bouncycastle.openssl.jcajce JcaPEMKeyConverter JcePEMDecryptorProviderBuilder]
|
||||||
|
[org.bouncycastle.asn1.pkcs PrivateKeyInfo]
|
||||||
|
[org.bouncycastle.asn1.x509 SubjectPublicKeyInfo]
|
||||||
|
[org.bouncycastle.cert X509CertificateHolder]
|
||||||
[java.io StringReader]))
|
[java.io StringReader]))
|
||||||
|
|
||||||
(java.security.Security/addProvider
|
(defprotocol GetPrivateKey
|
||||||
(org.bouncycastle.jce.provider.BouncyCastleProvider.))
|
(-get-private-key [key-info password]))
|
||||||
|
|
||||||
(defn- password-finder [s]
|
(defprotocol GetPublicKey
|
||||||
(reify PasswordFinder
|
(-get-public-key [key-info password]))
|
||||||
(getPassword [this] (.toCharArray s))))
|
|
||||||
|
|
||||||
(defn- pem->key
|
(defn ^JcaPEMKeyConverter pem-converter []
|
||||||
[reader pass-phrase]
|
(JcaPEMKeyConverter.))
|
||||||
(if pass-phrase
|
|
||||||
(.readObject (PEMReader. reader (password-finder pass-phrase)))
|
(extend-protocol GetPrivateKey
|
||||||
(.readObject (PEMReader. reader))))
|
PrivateKeyInfo
|
||||||
|
(-get-private-key [key-info _]
|
||||||
|
(.getPrivateKey (pem-converter) key-info)))
|
||||||
|
|
||||||
|
(extend-protocol GetPublicKey
|
||||||
|
SubjectPublicKeyInfo
|
||||||
|
(-get-public-key [key-info _]
|
||||||
|
(.getPublicKey (pem-converter) key-info))
|
||||||
|
X509CertificateHolder
|
||||||
|
(-get-public-key [key-info password]
|
||||||
|
(-get-public-key (.getSubjectPublicKeyInfo key-info) password)))
|
||||||
|
|
||||||
|
(extend-type PEMKeyPair
|
||||||
|
GetPrivateKey
|
||||||
|
(-get-private-key [key-info _]
|
||||||
|
(-> (pem-converter)
|
||||||
|
(.getKeyPair key-info)
|
||||||
|
.getPrivate))
|
||||||
|
|
||||||
|
GetPublicKey
|
||||||
|
(-get-public-key [key-info _]
|
||||||
|
(-> (pem-converter)
|
||||||
|
(.getKeyPair key-info)
|
||||||
|
.getPublic)))
|
||||||
|
|
||||||
|
(extend-type PEMEncryptedKeyPair
|
||||||
|
GetPrivateKey
|
||||||
|
(-get-private-key [key-info ^String password]
|
||||||
|
(let [dec-prov (-> (JcePEMDecryptorProviderBuilder.)
|
||||||
|
(.build (.toCharArray password)))]
|
||||||
|
(-get-private-key (-> key-info
|
||||||
|
(.decryptKeyPair dec-prov)) nil)))
|
||||||
|
GetPublicKey
|
||||||
|
(-get-public-key [key-info ^String password]
|
||||||
|
(let [dec-prov (-> (JcePEMDecryptorProviderBuilder.)
|
||||||
|
(.build (.toCharArray password)))]
|
||||||
|
(-get-public-key (-> key-info
|
||||||
|
(.decryptKeyPair dec-prov)) nil))))
|
||||||
|
|
||||||
|
(defn pem->public-key [reader pass-phrase]
|
||||||
|
(some-> reader
|
||||||
|
PEMParser.
|
||||||
|
.readObject
|
||||||
|
(-get-public-key pass-phrase)))
|
||||||
|
|
||||||
|
(defn pem->private-key [reader pass-phrase]
|
||||||
|
(some-> reader
|
||||||
|
PEMParser.
|
||||||
|
.readObject
|
||||||
|
(-get-private-key pass-phrase)))
|
||||||
|
|
||||||
(defn private-key
|
(defn private-key
|
||||||
[filename & [pass-phrase]]
|
[filename & [pass-phrase]]
|
||||||
(with-open [r (io/reader filename)]
|
(with-open [r (io/reader filename)]
|
||||||
(.getPrivate
|
(pem->private-key r pass-phrase)))
|
||||||
(pem->key r pass-phrase))))
|
|
||||||
|
|
||||||
(defn- public-key? [k]
|
|
||||||
(let [typ (type k)]
|
|
||||||
(or (= org.bouncycastle.jce.provider.JCERSAPublicKey typ)
|
|
||||||
(= org.bouncycastle.jce.provider.JCEECPublicKey typ))))
|
|
||||||
|
|
||||||
(defn public-key
|
(defn public-key
|
||||||
[filename & [pass-phrase]]
|
[filename & [pass-phrase]]
|
||||||
(with-open [r (io/reader filename)]
|
(with-open [r (io/reader filename)]
|
||||||
(let [res (pem->key r pass-phrase)]
|
(pem->public-key r pass-phrase)))
|
||||||
(if (public-key? res)
|
|
||||||
res
|
|
||||||
(.getPublic res)))))
|
|
||||||
|
|
||||||
(defn public-key-from-string
|
(defn public-key-from-string
|
||||||
[key-str & [pass-phrase]]
|
[key-str & [pass-phrase]]
|
||||||
(with-open [r (StringReader. key-str)]
|
(with-open [r (StringReader. key-str)]
|
||||||
(when-let [res (pem->key r pass-phrase)]
|
(pem->public-key r pass-phrase)))
|
||||||
(if (public-key? res)
|
|
||||||
res
|
|
||||||
(.getPublic res)))))
|
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
[clj-jwt.base64 :refer [url-safe-encode-str url-safe-decode]]
|
[clj-jwt.base64 :refer [url-safe-encode-str url-safe-decode]]
|
||||||
[crypto.equality :refer [eq?]]))
|
[crypto.equality :refer [eq?]]))
|
||||||
|
|
||||||
(java.security.Security/addProvider
|
|
||||||
(org.bouncycastle.jce.provider.BouncyCastleProvider.))
|
|
||||||
|
|
||||||
; HMAC
|
; HMAC
|
||||||
(defn- hmac-sign
|
(defn- hmac-sign
|
||||||
"Function to sign data with HMAC algorithm."
|
"Function to sign data with HMAC algorithm."
|
||||||
|
@ -24,7 +21,7 @@
|
||||||
(defn- rsa-sign
|
(defn- rsa-sign
|
||||||
"Function to sign data with RSA algorithm."
|
"Function to sign data with RSA algorithm."
|
||||||
[alg key body & {:keys [charset] :or {charset "UTF-8"}}]
|
[alg key body & {:keys [charset] :or {charset "UTF-8"}}]
|
||||||
(let [sig (doto (java.security.Signature/getInstance alg "BC")
|
(let [sig (doto (java.security.Signature/getInstance alg)
|
||||||
(.initSign key (java.security.SecureRandom.))
|
(.initSign key (java.security.SecureRandom.))
|
||||||
(.update (.getBytes body charset)))]
|
(.update (.getBytes body charset)))]
|
||||||
(url-safe-encode-str (.sign sig))))
|
(url-safe-encode-str (.sign sig))))
|
||||||
|
@ -32,7 +29,7 @@
|
||||||
(defn- rsa-verify
|
(defn- rsa-verify
|
||||||
"Function to verify data and signature with RSA algorithm."
|
"Function to verify data and signature with RSA algorithm."
|
||||||
[alg key body signature & {:keys [charset] :or {charset "UTF-8"}}]
|
[alg key body signature & {:keys [charset] :or {charset "UTF-8"}}]
|
||||||
(let [sig (doto (java.security.Signature/getInstance alg "BC")
|
(let [sig (doto (java.security.Signature/getInstance alg)
|
||||||
(.initVerify key)
|
(.initVerify key)
|
||||||
(.update (.getBytes body charset)))]
|
(.update (.getBytes body charset)))]
|
||||||
(.verify sig (url-safe-decode signature))))
|
(.verify sig (url-safe-decode signature))))
|
||||||
|
|
|
@ -3,7 +3,17 @@
|
||||||
[clj-jwt.core :refer :all]
|
[clj-jwt.core :refer :all]
|
||||||
[clj-jwt.key :refer [private-key public-key]]
|
[clj-jwt.key :refer [private-key public-key]]
|
||||||
[clj-time.core :refer [date-time plus days now]]
|
[clj-time.core :refer [date-time plus days now]]
|
||||||
[midje.sweet :refer :all]))
|
[midje.sweet :refer :all])
|
||||||
|
(:import
|
||||||
|
[java.security Security]
|
||||||
|
[org.bouncycastle.jce.provider BouncyCastleProvider]))
|
||||||
|
|
||||||
|
(defn with-bc-provider-fn [f]
|
||||||
|
(try
|
||||||
|
(Security/insertProviderAt (BouncyCastleProvider.) 1)
|
||||||
|
(f)
|
||||||
|
(finally
|
||||||
|
(java.security.Security/removeProvider "BC"))))
|
||||||
|
|
||||||
(def claim {:iss "foo"})
|
(def claim {:iss "foo"})
|
||||||
(def rsa-prv-key (private-key "test/files/rsa/no_pass.key"))
|
(def rsa-prv-key (private-key "test/files/rsa/no_pass.key"))
|
||||||
|
@ -12,9 +22,9 @@
|
||||||
(def rsa-enc-pub-key (public-key "test/files/rsa/3des.pub.key"))
|
(def rsa-enc-pub-key (public-key "test/files/rsa/3des.pub.key"))
|
||||||
(def rsa-dmy-key (public-key "test/files/rsa/dummy.key"))
|
(def rsa-dmy-key (public-key "test/files/rsa/dummy.key"))
|
||||||
|
|
||||||
(def ec-prv-key (private-key "test/files/ec/private.key"))
|
(def ec-prv-key (with-bc-provider-fn #(private-key "test/files/ec/private.key")))
|
||||||
(def ec-pub-key (public-key "test/files/ec/public.key"))
|
(def ec-pub-key (with-bc-provider-fn #(public-key "test/files/ec/public.key")))
|
||||||
(def ec-dmy-key (public-key "test/files/ec/dummy.key"))
|
(def ec-dmy-key (with-bc-provider-fn #(public-key "test/files/ec/dummy.key")))
|
||||||
|
|
||||||
(facts "JWT tokenize"
|
(facts "JWT tokenize"
|
||||||
(fact "Plain JWT should be generated."
|
(fact "Plain JWT should be generated."
|
||||||
|
@ -157,23 +167,23 @@
|
||||||
(-> claim jwt (sign :RS512 rsa-enc-prv-key) to-str str->jwt (verify rsa-enc-pub-key)) => true
|
(-> claim jwt (sign :RS512 rsa-enc-prv-key) to-str str->jwt (verify rsa-enc-pub-key)) => true
|
||||||
(-> claim jwt (sign :RS512 rsa-enc-prv-key) (verify rsa-dmy-key)) => false)
|
(-> claim jwt (sign :RS512 rsa-enc-prv-key) (verify rsa-dmy-key)) => false)
|
||||||
|
|
||||||
(fact "ES256 signed JWT shoud be verified."
|
(with-state-changes [(around :facts (with-bc-provider-fn (fn [] ?form)))]
|
||||||
|
(fact "ES256 signed JWT should be verified."
|
||||||
(-> claim jwt (sign :ES256 ec-prv-key) (verify ec-pub-key)) => true
|
(-> claim jwt (sign :ES256 ec-prv-key) (verify ec-pub-key)) => true
|
||||||
(-> claim jwt (sign :ES256 ec-prv-key) (verify :ES256 ec-pub-key)) => true
|
(-> claim jwt (sign :ES256 ec-prv-key) (verify :ES256 ec-pub-key)) => true
|
||||||
(-> claim jwt (sign :ES256 ec-prv-key) (verify :ES384 ec-pub-key)) => false
|
(-> claim jwt (sign :ES256 ec-prv-key) (verify :ES384 ec-pub-key)) => false
|
||||||
(-> claim jwt (sign :ES256 ec-prv-key) to-str str->jwt (verify ec-pub-key)) => true)
|
(-> claim jwt (sign :ES256 ec-prv-key) to-str str->jwt (verify ec-pub-key)) => true)
|
||||||
|
(fact "ES384 signed JWT should be verified."
|
||||||
(fact "ES384 signed JWT shoud be verified."
|
|
||||||
(-> claim jwt (sign :ES384 ec-prv-key) (verify ec-pub-key)) => true
|
(-> claim jwt (sign :ES384 ec-prv-key) (verify ec-pub-key)) => true
|
||||||
(-> claim jwt (sign :ES384 ec-prv-key) (verify :ES384 ec-pub-key)) => true
|
(-> claim jwt (sign :ES384 ec-prv-key) (verify :ES384 ec-pub-key)) => true
|
||||||
(-> claim jwt (sign :ES384 ec-prv-key) (verify :ES256 ec-pub-key)) => false
|
(-> claim jwt (sign :ES384 ec-prv-key) (verify :ES256 ec-pub-key)) => false
|
||||||
(-> claim jwt (sign :ES384 ec-prv-key) to-str str->jwt (verify ec-pub-key)) => true)
|
(-> claim jwt (sign :ES384 ec-prv-key) to-str str->jwt (verify ec-pub-key)) => true)
|
||||||
|
|
||||||
(fact "ES512 signed JWT shoud be verified."
|
(fact "ES512 signed JWT should be verified."
|
||||||
(-> claim jwt (sign :ES512 ec-prv-key) (verify ec-pub-key)) => true
|
(-> claim jwt (sign :ES512 ec-prv-key) (verify ec-pub-key)) => true
|
||||||
(-> claim jwt (sign :ES512 ec-prv-key) (verify :ES512 ec-pub-key)) => true
|
(-> claim jwt (sign :ES512 ec-prv-key) (verify :ES512 ec-pub-key)) => true
|
||||||
(-> claim jwt (sign :ES512 ec-prv-key) (verify :ES256 ec-pub-key)) => false
|
(-> claim jwt (sign :ES512 ec-prv-key) (verify :ES256 ec-pub-key)) => false
|
||||||
(-> claim jwt (sign :ES512 ec-prv-key) to-str str->jwt (verify ec-pub-key)) => true)
|
(-> claim jwt (sign :ES512 ec-prv-key) to-str str->jwt (verify ec-pub-key)) => true))
|
||||||
|
|
||||||
(fact "Claims containing string key should be verified"
|
(fact "Claims containing string key should be verified"
|
||||||
(let [sclaim {"a/b" "c"}
|
(let [sclaim {"a/b" "c"}
|
||||||
|
|
|
@ -1,34 +1,36 @@
|
||||||
(ns clj-jwt.key-test
|
(ns clj-jwt.key-test
|
||||||
(:require
|
(:require
|
||||||
[clj-jwt.key :refer :all]
|
[clj-jwt.key :refer :all]
|
||||||
[midje.sweet :refer :all]))
|
[midje.sweet :refer :all]
|
||||||
|
[clj-jwt.core-test :refer [with-bc-provider-fn]]))
|
||||||
|
|
||||||
(facts "rsa private key"
|
(with-state-changes [(around :facts (with-bc-provider-fn (fn [] ?form)))]
|
||||||
|
(facts "rsa private key"
|
||||||
(fact "non encrypt key"
|
(fact "non encrypt key"
|
||||||
(type (private-key "test/files/rsa/no_pass.key"))
|
(type (private-key "test/files/rsa/no_pass.key"))
|
||||||
=> org.bouncycastle.jce.provider.JCERSAPrivateCrtKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey)
|
||||||
|
|
||||||
(fact "crypted key"
|
(fact "crypted key"
|
||||||
(type (private-key "test/files/rsa/3des.key" "pass phrase"))
|
(type (private-key "test/files/rsa/3des.key" "pass phrase"))
|
||||||
=> org.bouncycastle.jce.provider.JCERSAPrivateCrtKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey)
|
||||||
|
|
||||||
(fact "crypted key wrong pass-phrase"
|
(fact "crypted key wrong pass-phrase"
|
||||||
(private-key "test/files/rsa/3des.key" "wrong pass phrase")
|
(private-key "test/files/rsa/3des.key" "wrong pass phrase")
|
||||||
=> (throws org.bouncycastle.openssl.EncryptionException)))
|
=> (throws org.bouncycastle.openssl.EncryptionException)))
|
||||||
|
|
||||||
(facts "ecdsa private key"
|
(facts "ecdsa private key"
|
||||||
(fact "ecdsa key"
|
(fact "ecdsa key"
|
||||||
(type (private-key "test/files/ec/private.key"))
|
(type (private-key "test/files/ec/private.key"))
|
||||||
=> org.bouncycastle.jce.provider.JCEECPrivateKey))
|
=> org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey))
|
||||||
|
|
||||||
(facts "rsa public key"
|
(facts "rsa public key"
|
||||||
(fact "rsa non encrypted key"
|
(fact "rsa non encrypted key"
|
||||||
(type (public-key "test/files/rsa/no_pass.key"))
|
(type (public-key "test/files/rsa/no_pass.key"))
|
||||||
=> org.bouncycastle.jce.provider.JCERSAPublicKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey)
|
||||||
|
|
||||||
(fact "rsa encrypted key"
|
(fact "rsa encrypted key"
|
||||||
(type (public-key "test/files/rsa/3des.key" "pass phrase"))
|
(type (public-key "test/files/rsa/3des.key" "pass phrase"))
|
||||||
=> org.bouncycastle.jce.provider.JCERSAPublicKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey)
|
||||||
|
|
||||||
(fact "rsa encrypted key with wrong pass phrase"
|
(fact "rsa encrypted key with wrong pass phrase"
|
||||||
(type (public-key "test/files/rsa/3des.key" "wrong pass phrase"))
|
(type (public-key "test/files/rsa/3des.key" "wrong pass phrase"))
|
||||||
|
@ -36,11 +38,11 @@
|
||||||
|
|
||||||
(fact "rsa non encrypted key from string"
|
(fact "rsa non encrypted key from string"
|
||||||
(-> "test/files/rsa/no_pass.key" slurp public-key-from-string type)
|
(-> "test/files/rsa/no_pass.key" slurp public-key-from-string type)
|
||||||
=> org.bouncycastle.jce.provider.JCERSAPublicKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey)
|
||||||
|
|
||||||
(fact "rsa encrypted key from string"
|
(fact "rsa encrypted key from string"
|
||||||
(-> "test/files/rsa/3des.key" slurp (public-key-from-string "pass phrase") type)
|
(-> "test/files/rsa/3des.key" slurp (public-key-from-string "pass phrase") type)
|
||||||
=> org.bouncycastle.jce.provider.JCERSAPublicKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey)
|
||||||
|
|
||||||
(fact "rsa encrypted key with wrong pass phrase from string"
|
(fact "rsa encrypted key with wrong pass phrase from string"
|
||||||
(-> "test/files/rsa/3des.key" slurp (public-key-from-string "wrong pass phrase") type)
|
(-> "test/files/rsa/3des.key" slurp (public-key-from-string "wrong pass phrase") type)
|
||||||
|
@ -49,13 +51,11 @@
|
||||||
(fact "invalid key string"
|
(fact "invalid key string"
|
||||||
(public-key-from-string "foobar") => nil))
|
(public-key-from-string "foobar") => nil))
|
||||||
|
|
||||||
(facts "ecdsa public key"
|
(facts "ecdsa public key"
|
||||||
(fact "ecdsa public key"
|
(fact "ecdsa public key"
|
||||||
(type (public-key "test/files/ec/public.key"))
|
(type (public-key "test/files/ec/public.key"))
|
||||||
=> org.bouncycastle.jce.provider.JCEECPublicKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey)
|
||||||
|
|
||||||
(fact "ecdsa public key from string"
|
(fact "ecdsa public key from string"
|
||||||
(-> "test/files/ec/public.key" slurp public-key-from-string type)
|
(-> "test/files/ec/public.key" slurp public-key-from-string type)
|
||||||
=> org.bouncycastle.jce.provider.JCEECPublicKey)
|
=> org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey)))
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
[clj-jwt.sign :refer :all]
|
[clj-jwt.sign :refer :all]
|
||||||
[clj-jwt.base64 :refer [url-safe-encode-str]]
|
[clj-jwt.base64 :refer [url-safe-encode-str]]
|
||||||
[clj-jwt.key :refer [private-key]]
|
[clj-jwt.key :refer [private-key]]
|
||||||
[midje.sweet :refer :all]))
|
[midje.sweet :refer :all]
|
||||||
|
[clj-jwt.core-test :refer [with-bc-provider-fn]]))
|
||||||
|
|
||||||
(facts "HMAC"
|
(facts "HMAC"
|
||||||
(let [[hs256 hs384 hs512] (map get-signature-fn [:HS256 :HS384 :HS512])
|
(let [[hs256 hs384 hs512] (map get-signature-fn [:HS256 :HS384 :HS512])
|
||||||
|
@ -37,7 +38,8 @@
|
||||||
"A-Z1j3LeLKFWhryRRAjzW--Ut5rs5t0MjJ4OgUUhXAEXXAeJfbeEVxzBv4C-F"
|
"A-Z1j3LeLKFWhryRRAjzW--Ut5rs5t0MjJ4OgUUhXAEXXAeJfbeEVxzBv4C-F"
|
||||||
"e9avjnNjUgcPlJgQAMQbrLirSo8Z8hb1Iqz9f7pUuNLTkAQJA"))))
|
"e9avjnNjUgcPlJgQAMQbrLirSo8Z8hb1Iqz9f7pUuNLTkAQJA"))))
|
||||||
|
|
||||||
(facts "EC"
|
(with-state-changes [(around :facts (with-bc-provider-fn (fn [] ?form)))]
|
||||||
|
(facts "EC"
|
||||||
(let [[es256 es384 es512] (map get-signature-fn [:ES256 :ES384 :ES512])
|
(let [[es256 es384 es512] (map get-signature-fn [:ES256 :ES384 :ES512])
|
||||||
key (private-key "test/files/ec/private.key")
|
key (private-key "test/files/ec/private.key")
|
||||||
body "foo"]
|
body "foo"]
|
||||||
|
@ -46,7 +48,4 @@
|
||||||
(fact "ES384"
|
(fact "ES384"
|
||||||
(es384 key body) => string?)
|
(es384 key body) => string?)
|
||||||
(fact "ES512"
|
(fact "ES512"
|
||||||
(es512 key body) => string?)))
|
(es512 key body) => string?))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue