Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for KDF on import and random functions. #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,9 @@ let additions =
}
-------------------------------
-}


let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.13.6-20200423/packages.dhall sha256:c180a06bb5444fd950f8cbdd6605c644fd246deb397e62572b8f4a6b9dbcaf22
https://github.com/purescript/package-sets/releases/download/psc-0.15.0-20220516/packages.dhall
sha256:b0bf932de16a10b7d69c6bbbb31ec9ca575237c43a999fa32e59e35eb8c024a1

let overrides = {=}

Expand Down
12 changes: 10 additions & 2 deletions spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ You can edit this file as you like.
{ name = "subtlecrypto"
, dependencies =
[ "aff"
, "aff-promise"
, "arraybuffer"
, "arraybuffer-types"
, "console"
, "effect"
, "either"
, "exceptions"
, "foreign"
, "functions"
, "maybe"
, "prelude"
, "promises"
, "psci-support"
, "transformers"
, "tuples"
, "unsafe-coerce"
, "web-encoding"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
Expand Down
6 changes: 6 additions & 0 deletions src/Crypto/Random.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function getRandomValuesImpl (typedArray) {
return crypto.getRandomValues(typedArray);
};
export function randomUUID () {
return crypto.randomUUID();
};
18 changes: 18 additions & 0 deletions src/Crypto/Random.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Crypto.Random
( getRandomValues
, randomUUID
)
where


import Data.ArrayBuffer.Typed (class TypedArray)
import Data.ArrayBuffer.Types (ArrayView)
import Effect (Effect)
import Effect.Uncurried (EffectFn1, runEffectFn1)

foreign import getRandomValuesImpl :: forall a . EffectFn1 (ArrayView a) (ArrayView a)

foreign import randomUUID :: Effect String

getRandomValues :: forall a t. TypedArray a t => ArrayView a -> Effect (ArrayView a)
getRandomValues ta = runEffectFn1 getRandomValuesImpl ta
6 changes: 2 additions & 4 deletions src/Crypto/Subtle/Encrypt.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"use strict";

exports.encryptImpl = function encryptImpl (a,k,x) {
export function encryptImpl (a,k,x) {
return crypto.subtle.encrypt(a,k,x);
};
exports.decryptImpl = function decryptImpl (a,k,x) {
export function decryptImpl (a,k,x) {
return crypto.subtle.decrypt(a,k,x);
};
29 changes: 15 additions & 14 deletions src/Crypto/Subtle/Encrypt.purs
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,39 @@ module Crypto.Subtle.Encrypt
, EncryptAlgorithm, rsaOAEP, aesCTR, aesCBC, aesGCM, aesKW
) where

import Crypto.Subtle.Key.Types (CryptoKey)
import Control.Promise (Promise, toAff')
import Crypto.Subtle.Constants.AES (AESTagLength)

import Prelude ((<<<), (<$))
import Data.Function.Uncurried (Fn3, runFn3)
import Data.Tuple (Tuple (..))
import Data.Maybe (Maybe (..))
import Data.Either (Either (..))
import Crypto.Subtle.Key.Types (CryptoKey, errorFromDOMException)
import Data.ArrayBuffer.Types (ArrayBuffer)
import Effect.Promise (Promise, runPromise)
import Effect.Aff (Aff, makeAff, nonCanceler)
import Data.Function.Uncurried (Fn3, runFn3)
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Effect.Aff (Aff)
import Unsafe.Coerce (unsafeCoerce)



foreign import data EncryptAlgorithm :: Type

-- | https://developer.mozilla.org/en-US/docs/Web/API/RsaOaepParams
rsaOAEP :: Maybe ArrayBuffer -- ^ Label
-> EncryptAlgorithm
rsaOAEP mL = case mL of
Nothing -> unsafeCoerce {name: "RSA_OAEP"}
Just l -> unsafeCoerce {name: "RSA_OAEP", label: l}

-- | https://developer.mozilla.org/en-US/docs/Web/API/AesCtrParams
aesCTR :: ArrayBuffer -- ^ Counter
-> Int -- ^ Counter length
-> EncryptAlgorithm
aesCTR c l = unsafeCoerce {name: "AES-CTR", counter: c, length: l}

-- | https://developer.mozilla.org/en-US/docs/Web/API/AesCbcParams
aesCBC :: ArrayBuffer -- ^ Initialization vector
-> EncryptAlgorithm
aesCBC i = unsafeCoerce {name: "AES-CBC", iv: i}

-- | https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams
aesGCM :: ArrayBuffer -- ^ Initialization vector
-> Maybe ArrayBuffer -- ^ Additional data
-> Maybe AESTagLength -- ^ Tag length
Expand All @@ -53,20 +54,20 @@ aesKW = unsafeCoerce {name: "AES-KW"}

foreign import encryptImpl :: Fn3 EncryptAlgorithm CryptoKey ArrayBuffer (Promise ArrayBuffer)

-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt
encrypt :: EncryptAlgorithm
-> CryptoKey
-> ArrayBuffer
-> Aff ArrayBuffer
encrypt a k x = makeAff \resolve ->
nonCanceler <$ runPromise (resolve <<< Right) (resolve <<< Left) (runFn3 encryptImpl a k x)
encrypt a k x = toAff' errorFromDOMException (runFn3 encryptImpl a k x)



foreign import decryptImpl :: Fn3 EncryptAlgorithm CryptoKey ArrayBuffer (Promise ArrayBuffer)

-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/decrypt
decrypt :: EncryptAlgorithm
-> CryptoKey
-> ArrayBuffer
-> Aff (Maybe ArrayBuffer)
decrypt a k x = makeAff \resolve ->
nonCanceler <$ runPromise (resolve <<< Right <<< Just) (\_ -> resolve (Right Nothing)) (runFn3 decryptImpl a k x)
-> Aff ArrayBuffer
decrypt a k x = toAff' errorFromDOMException (runFn3 decryptImpl a k x)
4 changes: 1 addition & 3 deletions src/Crypto/Subtle/Hash.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use strict";

exports.digestImpl = function digestImpl (h,x) {
export function digestImpl (h,x) {
return crypto.subtle.digest(h,x);
};
15 changes: 6 additions & 9 deletions src/Crypto/Subtle/Hash.purs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module Crypto.Subtle.Hash (HashingFunction, sha1, sha256, sha384, sha512, digest) where

import Prelude ((<<<), (<$), class Eq)
import Control.Promise (Promise, toAff')
import Crypto.Subtle.Key.Types (errorFromDOMException)
import Data.ArrayBuffer.Types (ArrayBuffer)
import Data.Function.Uncurried (Fn2, runFn2)
import Data.Either (Either (..))
import Effect.Promise (Promise, runPromise)
import Effect.Aff (Aff, makeAff, nonCanceler)
import Effect.Aff (Aff)
import Prelude (class Eq)



Expand All @@ -25,11 +25,8 @@ sha384 = HashingFunction "SHA-384"
sha512 :: HashingFunction
sha512 = HashingFunction "SHA-512"


foreign import digestImpl :: Fn2 HashingFunction ArrayBuffer (Promise ArrayBuffer)


-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
digest :: HashingFunction -> ArrayBuffer -> Aff ArrayBuffer
digest h x =
let p = runFn2 digestImpl h x
in makeAff \resolve -> nonCanceler <$ runPromise (resolve <<< Right) (resolve <<< Left) p
digest h x = toAff' errorFromDOMException (runFn2 digestImpl h x)
6 changes: 2 additions & 4 deletions src/Crypto/Subtle/Key/Derive.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"use strict";

exports.deriveKeyImpl = function deriveKeyImpl (a,k,t,e,u) {
export function deriveKeyImpl (a,k,t,e,u) {
return crypto.subtle.deriveKey(a,k,t,e,u);
};
exports.deriveBitsImpl = function deriveBitsImpl (a,k,l) {
export function deriveBitsImpl (a,k,l) {
return crypto.subtle.deriveBits(a,k,l);
};
28 changes: 15 additions & 13 deletions src/Crypto/Subtle/Key/Derive.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ module Crypto.Subtle.Key.Derive
, DeriveTargetAlgorithm, hmac, aes
) where

import Crypto.Subtle.Key.Types (CryptoKey, CryptoKeyUsage)
import Crypto.Subtle.Hash (HashingFunction)
import Crypto.Subtle.Constants.EC (ECAlgorithm)
import Control.Promise (Promise, toAff')
import Crypto.Subtle.Constants.AES (AESAlgorithm, AESBitLength)

import Prelude ((<<<), (<$))
import Data.Function.Uncurried (Fn3, Fn5, runFn3, runFn5)
import Crypto.Subtle.Constants.EC (ECAlgorithm)
import Crypto.Subtle.Hash (HashingFunction)
import Crypto.Subtle.Key.Types (CryptoKey, CryptoKeyUsage, errorFromDOMException)
import Data.ArrayBuffer.Types (ArrayBuffer)
import Data.Either (Either (..))
import Effect.Promise (Promise, runPromise)
import Effect.Aff (Aff, makeAff, nonCanceler)
import Data.Function.Uncurried (Fn3, Fn5, runFn3, runFn5)
import Effect.Aff (Aff)
import Unsafe.Coerce (unsafeCoerce)


Expand All @@ -24,38 +21,41 @@ foreign import deriveKeyImpl :: Fn5 DeriveAlgorithm CryptoKey DeriveTargetAlgori
foreign import deriveBitsImpl :: Fn3 DeriveAlgorithm CryptoKey Int (Promise ArrayBuffer)


-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey
deriveKey :: DeriveAlgorithm
-> CryptoKey -- ^ Base key
-> DeriveTargetAlgorithm
-> Boolean -- ^ Extractable
-> Array CryptoKeyUsage
-> Aff CryptoKey
deriveKey a k t e u = makeAff \resolve ->
nonCanceler <$ runPromise (resolve <<< Right) (resolve <<< Left) (runFn5 deriveKeyImpl a k t e u)
deriveKey a k t e u = toAff' errorFromDOMException (runFn5 deriveKeyImpl a k t e u)

-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits
deriveBits :: DeriveAlgorithm
-> CryptoKey -- ^ Base key
-> Int -- ^ Length in bits
-> Aff ArrayBuffer
deriveBits a k l = makeAff \resolve ->
nonCanceler <$ runPromise (resolve <<< Right) (resolve <<< Left) (runFn3 deriveBitsImpl a k l)
deriveBits a k l = toAff' errorFromDOMException (runFn3 deriveBitsImpl a k l)


foreign import data DeriveAlgorithm :: Type
foreign import data DeriveTargetAlgorithm :: Type


-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#ecdh
ec :: ECAlgorithm
-> CryptoKey -- ^ Public key of the other entity
-> DeriveAlgorithm
ec e k = unsafeCoerce {name: e, public: k}

-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#hkdf
hkdf :: HashingFunction
-> ArrayBuffer -- ^ Salt
-> ArrayBuffer -- ^ Info
-> DeriveAlgorithm
hkdf h s i = unsafeCoerce {name: "HKDF", hash: h, salt: s, info: i}

-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#pbkdf2
pbkdf2 :: HashingFunction
-> ArrayBuffer -- ^ Salt
-> Int -- ^ Iterations
Expand All @@ -65,8 +65,10 @@ pbkdf2 h s i = unsafeCoerce {name: "PBKDF2", hash: h, salt: s, iterations: i}



-- | https://developer.mozilla.org/en-US/docs/Web/API/HmacKeyGenParams
hmac :: HashingFunction -> DeriveTargetAlgorithm
hmac h = unsafeCoerce {name: "HMAC", hash: h}

-- | https://developer.mozilla.org/en-US/docs/Web/API/AesKeyGenParams
aes :: AESAlgorithm -> AESBitLength -> DeriveTargetAlgorithm
aes a l = unsafeCoerce {name: a, length: l}
6 changes: 2 additions & 4 deletions src/Crypto/Subtle/Key/Generate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"use strict";

exports.generateKeyImpl = function generateKeyImpl (a,e,u) {
export function generateKeyImpl (a,e,u) {
return crypto.subtle.generateKey(a,e,u);
};
exports.exp65537 = new Uint8Array([0x01,0x00,0x01]);
export const exp65537 = new Uint8Array([0x01,0x00,0x01]);
31 changes: 17 additions & 14 deletions src/Crypto/Subtle/Key/Generate.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ module Crypto.Subtle.Key.Generate
, exp65537
) where

import Crypto.Subtle.Key.Types (CryptoKey, CryptoKeyPair, CryptoKeyUsage)
import Crypto.Subtle.Hash (HashingFunction)
import Crypto.Subtle.Constants.RSA (RSAAlgorithm)
import Crypto.Subtle.Constants.EC (ECAlgorithm, ECCurve)
import Control.Promise (Promise, toAff')
import Crypto.Subtle.Constants.AES (AESAlgorithm, AESBitLength)

import Prelude ((<<<), (<$))
import Data.Function.Uncurried (Fn3, runFn3)
import Crypto.Subtle.Constants.EC (ECAlgorithm, ECCurve)
import Crypto.Subtle.Constants.RSA (RSAAlgorithm)
import Crypto.Subtle.Hash (HashingFunction)
import Crypto.Subtle.Key.Types (CryptoKey, CryptoKeyPair, CryptoKeyUsage, errorFromDOMException)
import Data.ArrayBuffer.Types (Uint8Array)
import Data.Either (Either (..))
import Effect.Promise (Promise, runPromise)
import Effect.Aff (Aff, makeAff, nonCanceler)
import Data.Function.Uncurried (Fn3, runFn3)
import Effect.Aff (Aff)
import Unsafe.Coerce (unsafeCoerce)


Expand All @@ -25,20 +22,22 @@ foreign import generateKeyImpl :: forall a b. Fn3 a Boolean (Array CryptoKeyUsag


-- | Generate a symmetric key
-- |
-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey
generateKey :: SymmetricAlgorithm
-> Boolean -- ^ Extractable
-> Array CryptoKeyUsage
-> Aff CryptoKey
generateKey a e u = makeAff \resolve ->
nonCanceler <$ runPromise (resolve <<< Right) (resolve <<< Left) (runFn3 generateKeyImpl a e u)
generateKey a e u = toAff' errorFromDOMException (runFn3 generateKeyImpl a e u)

-- | Generate an asymmetric keypair
-- |
-- | https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey
generateKeyPair :: AsymmetricAlgorithm
-> Boolean -- ^ Extractable
-> Array CryptoKeyUsage
-> Aff CryptoKeyPair
generateKeyPair a e u = makeAff \resolve ->
nonCanceler <$ runPromise (resolve <<< Right) (resolve <<< Left) (runFn3 generateKeyImpl a e u)
generateKeyPair a e u = toAff' errorFromDOMException (runFn3 generateKeyImpl a e u)


foreign import data SymmetricAlgorithm :: Type
Expand All @@ -48,19 +47,23 @@ foreign import data AsymmetricAlgorithm :: Type
foreign import exp65537 :: Uint8Array


-- | https://developer.mozilla.org/en-US/docs/Web/API/RsaHashedKeyGenParams
rsa :: RSAAlgorithm
-> Int -- ^ Modulus length. Should be at least 2048, or 4096 according to some bozo
-> Uint8Array -- ^ Public exponent. Just use `exp65537`.
-> HashingFunction
-> AsymmetricAlgorithm
rsa r l e h = unsafeCoerce {name: r, modulusLength: l, publicExponent: e, hash: h}

-- | https://developer.mozilla.org/en-US/docs/Web/API/EcKeyGenParams
ec :: ECAlgorithm -> ECCurve -> AsymmetricAlgorithm
ec e c = unsafeCoerce {name: e, namedCurve: c}

-- | https://developer.mozilla.org/en-US/docs/Web/API/HmacKeyGenParams
hmac :: HashingFunction -> SymmetricAlgorithm
hmac h = unsafeCoerce {name: "HMAC", hash: h}

-- | https://developer.mozilla.org/en-US/docs/Web/API/AesKeyGenParams
aes :: AESAlgorithm
-> AESBitLength
-> SymmetricAlgorithm
Expand Down
4 changes: 1 addition & 3 deletions src/Crypto/Subtle/Key/Import.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use strict";

exports.importKeyImpl = function importKeyImpl (f,x,a,e,u) {
export function importKeyImpl (f,x,a,e,u) {
return crypto.subtle.importKey(f,x,a,e,u);
};
Loading