Skip to content

Commit 92ccc1b

Browse files
Add Hmac bindings
1 parent f9a2127 commit 92ccc1b

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

src/Node/Crypto/Hmac.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as crypto from "node:crypto";
2+
3+
export const newImpl = (algorithm, key) => crypto.createHmac(algorithm, key);
4+
export const updateBufImpl = (hmac, buf) => hmac.update(buf);
5+
export const updateStrImpl = (hmac, str, encoding) => hmac.update(str, encoding);
6+
export const digestBufImpl = (hmac) => hmac.digest();
7+
export const digestStrImpl = (hmac, encoding) => hmac.digest(encoding);

src/Node/Crypto/Hmac.purs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module Node.Crypto.Hmac
2+
( Hmac
3+
, toDuplex
4+
, new
5+
, updateBuf
6+
, updateStr
7+
, digestBuf
8+
, digestStr
9+
) where
10+
11+
import Prelude
12+
13+
import Effect (Effect)
14+
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2, runEffectFn3)
15+
import Node.Buffer (Buffer)
16+
import Node.Encoding (Encoding, encodingToNode)
17+
import Node.Stream (Duplex)
18+
import Unsafe.Coerce (unsafeCoerce)
19+
20+
-- | The Hmac class is a utility for creating cryptographic HMAC digests. It can be used in one of two ways:
21+
-- | - As a stream that is both readable and writable, where data is written to produce a computed HMAC digest on the readable side, or
22+
-- | - Using the hmac.update() and hmac.digest() methods to produce the computed HMAC digest.
23+
foreign import data Hmac :: Type
24+
25+
toDuplex :: Hmac -> Duplex
26+
toDuplex = unsafeCoerce
27+
28+
foreign import newImpl :: EffectFn2 (String) (Buffer) (Hmac)
29+
30+
-- | Creates and returns an Hmac object that uses the given algorithm and key.
31+
-- |
32+
-- | The algorithm is dependent on the available algorithms supported by the version of
33+
-- | OpenSSL on the platform. Examples are 'sha256', 'sha512', etc. On recent releases of OpenSSL,
34+
-- | `openssl list -digest-algorithms` will display the available digest algorithms.
35+
-- |
36+
-- | The key is the HMAC key used to generate the cryptographic HMAC hash.
37+
-- | If it was obtained from a cryptographically secure source of entropy, such as `crypto.randomBytes()` or `crypto.generateKey()`,
38+
-- | its length should not exceed the block size of algorithm (e.g., 512 bits for SHA-256).
39+
new :: String -> Buffer -> Effect Hmac
40+
new algorithm key =
41+
runEffectFn2 newImpl algorithm key
42+
43+
foreign import updateBufImpl :: EffectFn2 (Hmac) (Buffer) (Unit)
44+
45+
-- | Updates the `Hmac` content with the given data.
46+
updateBuf :: Buffer -> Hmac -> Effect Unit
47+
updateBuf buffer hmac =
48+
runEffectFn2 updateBufImpl hmac buffer
49+
50+
foreign import updateStrImpl :: EffectFn3 (Hmac) (String) (Encoding) (Unit)
51+
52+
-- | Updates the `Hmac` content with the given data.
53+
updateStr :: String -> Encoding -> Hmac -> Effect Unit
54+
updateStr string encoding hmac =
55+
runEffectFn3 updateStrImpl hmac string encoding
56+
57+
foreign import digestBufImpl :: EffectFn1 (Hmac) (Buffer)
58+
59+
-- | Calculates the `HMAC` digest of all of the data passed using `hmac.update()`.
60+
-- |
61+
-- | The `Hmac` object can not be used again after `hmac.digest()` has been called. Multiple calls to `hmac.digest()` will result in an error being thrown.
62+
digestBuf :: Hmac -> Effect Buffer
63+
digestBuf hmac = runEffectFn1 digestBufImpl hmac
64+
65+
foreign import digestStrImpl :: EffectFn2 (Hmac) (String) (String)
66+
67+
-- | Calculates the `HMAC` digest of all of the data passed using `hmac.update()`.
68+
-- |
69+
-- | The `Hmac` object can not be used again after `hmac.digest()` has been called. Multiple calls to `hmac.digest()` will result in an error being thrown.
70+
digestStr :: Encoding -> Hmac -> Effect String
71+
digestStr encoding hmac =
72+
runEffectFn2 digestStrImpl hmac (encodingToNode encoding)
73+

0 commit comments

Comments
 (0)