@bananalink-sdk/protocol 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +604 -0
- package/dist/chunk-32OWUOZ3.js +308 -0
- package/dist/chunk-32OWUOZ3.js.map +1 -0
- package/dist/chunk-65HNHRJK.cjs +123 -0
- package/dist/chunk-65HNHRJK.cjs.map +1 -0
- package/dist/chunk-7KYDLL3B.js +480 -0
- package/dist/chunk-7KYDLL3B.js.map +1 -0
- package/dist/chunk-A6FLEJ7R.cjs +62 -0
- package/dist/chunk-A6FLEJ7R.cjs.map +1 -0
- package/dist/chunk-CUJK7ZTS.js +217 -0
- package/dist/chunk-CUJK7ZTS.js.map +1 -0
- package/dist/chunk-GI3BUPIH.cjs +236 -0
- package/dist/chunk-GI3BUPIH.cjs.map +1 -0
- package/dist/chunk-JXHV66Q4.js +106 -0
- package/dist/chunk-JXHV66Q4.js.map +1 -0
- package/dist/chunk-KNGZKGRS.cjs +552 -0
- package/dist/chunk-KNGZKGRS.cjs.map +1 -0
- package/dist/chunk-LELPCIE7.js +840 -0
- package/dist/chunk-LELPCIE7.js.map +1 -0
- package/dist/chunk-MCZG7QEM.cjs +310 -0
- package/dist/chunk-MCZG7QEM.cjs.map +1 -0
- package/dist/chunk-TCVKC227.js +56 -0
- package/dist/chunk-TCVKC227.js.map +1 -0
- package/dist/chunk-VXLUSU5B.cjs +856 -0
- package/dist/chunk-VXLUSU5B.cjs.map +1 -0
- package/dist/chunk-WCQVDF3K.js +12 -0
- package/dist/chunk-WCQVDF3K.js.map +1 -0
- package/dist/chunk-WGEGR3DF.cjs +15 -0
- package/dist/chunk-WGEGR3DF.cjs.map +1 -0
- package/dist/client-session-claim-3QF3noOr.d.ts +197 -0
- package/dist/client-session-claim-C4lUik3b.d.cts +197 -0
- package/dist/core-DMhuNfoz.d.cts +62 -0
- package/dist/core-DMhuNfoz.d.ts +62 -0
- package/dist/crypto/providers/noble-provider.cjs +14 -0
- package/dist/crypto/providers/noble-provider.cjs.map +1 -0
- package/dist/crypto/providers/noble-provider.d.cts +30 -0
- package/dist/crypto/providers/noble-provider.d.ts +30 -0
- package/dist/crypto/providers/noble-provider.js +5 -0
- package/dist/crypto/providers/noble-provider.js.map +1 -0
- package/dist/crypto/providers/node-provider.cjs +308 -0
- package/dist/crypto/providers/node-provider.cjs.map +1 -0
- package/dist/crypto/providers/node-provider.d.cts +32 -0
- package/dist/crypto/providers/node-provider.d.ts +32 -0
- package/dist/crypto/providers/node-provider.js +306 -0
- package/dist/crypto/providers/node-provider.js.map +1 -0
- package/dist/crypto/providers/quickcrypto-provider.cjs +339 -0
- package/dist/crypto/providers/quickcrypto-provider.cjs.map +1 -0
- package/dist/crypto/providers/quickcrypto-provider.d.cts +34 -0
- package/dist/crypto/providers/quickcrypto-provider.d.ts +34 -0
- package/dist/crypto/providers/quickcrypto-provider.js +337 -0
- package/dist/crypto/providers/quickcrypto-provider.js.map +1 -0
- package/dist/crypto/providers/webcrypto-provider.cjs +310 -0
- package/dist/crypto/providers/webcrypto-provider.cjs.map +1 -0
- package/dist/crypto/providers/webcrypto-provider.d.cts +30 -0
- package/dist/crypto/providers/webcrypto-provider.d.ts +30 -0
- package/dist/crypto/providers/webcrypto-provider.js +308 -0
- package/dist/crypto/providers/webcrypto-provider.js.map +1 -0
- package/dist/crypto-BUS06Qz-.d.cts +40 -0
- package/dist/crypto-BUS06Qz-.d.ts +40 -0
- package/dist/crypto-export.cjs +790 -0
- package/dist/crypto-export.cjs.map +1 -0
- package/dist/crypto-export.d.cts +257 -0
- package/dist/crypto-export.d.ts +257 -0
- package/dist/crypto-export.js +709 -0
- package/dist/crypto-export.js.map +1 -0
- package/dist/crypto-provider-deYoVIxi.d.cts +36 -0
- package/dist/crypto-provider-deYoVIxi.d.ts +36 -0
- package/dist/index.cjs +615 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +379 -0
- package/dist/index.d.ts +379 -0
- package/dist/index.js +504 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas-export.cjs +294 -0
- package/dist/schemas-export.cjs.map +1 -0
- package/dist/schemas-export.d.cts +1598 -0
- package/dist/schemas-export.d.ts +1598 -0
- package/dist/schemas-export.js +5 -0
- package/dist/schemas-export.js.map +1 -0
- package/dist/siwe-export.cjs +237 -0
- package/dist/siwe-export.cjs.map +1 -0
- package/dist/siwe-export.d.cts +27 -0
- package/dist/siwe-export.d.ts +27 -0
- package/dist/siwe-export.js +228 -0
- package/dist/siwe-export.js.map +1 -0
- package/dist/testing.cjs +54 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +20 -0
- package/dist/testing.d.ts +20 -0
- package/dist/testing.js +51 -0
- package/dist/testing.js.map +1 -0
- package/dist/validation-export.cjs +359 -0
- package/dist/validation-export.cjs.map +1 -0
- package/dist/validation-export.d.cts +3 -0
- package/dist/validation-export.d.ts +3 -0
- package/dist/validation-export.js +6 -0
- package/dist/validation-export.js.map +1 -0
- package/dist/validators-export.cjs +73 -0
- package/dist/validators-export.cjs.map +1 -0
- package/dist/validators-export.d.cts +37 -0
- package/dist/validators-export.d.ts +37 -0
- package/dist/validators-export.js +4 -0
- package/dist/validators-export.js.map +1 -0
- package/package.json +140 -0
- package/src/constants/index.ts +205 -0
- package/src/crypto/context.ts +228 -0
- package/src/crypto/diagnostics.ts +772 -0
- package/src/crypto/errors.ts +114 -0
- package/src/crypto/index.ts +89 -0
- package/src/crypto/payload-handler.ts +102 -0
- package/src/crypto/providers/compliance-provider.ts +579 -0
- package/src/crypto/providers/factory.ts +204 -0
- package/src/crypto/providers/index.ts +44 -0
- package/src/crypto/providers/noble-provider.ts +392 -0
- package/src/crypto/providers/node-provider.ts +433 -0
- package/src/crypto/providers/quickcrypto-provider.ts +483 -0
- package/src/crypto/providers/registry.ts +129 -0
- package/src/crypto/providers/webcrypto-provider.ts +364 -0
- package/src/crypto/session-security.ts +185 -0
- package/src/crypto/types.ts +93 -0
- package/src/crypto/utils.ts +190 -0
- package/src/crypto-export.ts +21 -0
- package/src/index.ts +38 -0
- package/src/schemas/auth.ts +60 -0
- package/src/schemas/client-messages.ts +57 -0
- package/src/schemas/core.ts +144 -0
- package/src/schemas/crypto.ts +65 -0
- package/src/schemas/discovery.ts +79 -0
- package/src/schemas/index.ts +239 -0
- package/src/schemas/relay-messages.ts +45 -0
- package/src/schemas/wallet-messages.ts +177 -0
- package/src/schemas-export.ts +23 -0
- package/src/siwe-export.ts +27 -0
- package/src/testing.ts +71 -0
- package/src/types/auth.ts +60 -0
- package/src/types/client-messages.ts +84 -0
- package/src/types/core.ts +131 -0
- package/src/types/crypto-provider.ts +264 -0
- package/src/types/crypto.ts +90 -0
- package/src/types/discovery.ts +50 -0
- package/src/types/errors.ts +87 -0
- package/src/types/index.ts +197 -0
- package/src/types/post-auth-operations.ts +363 -0
- package/src/types/providers.ts +72 -0
- package/src/types/relay-messages.ts +60 -0
- package/src/types/request-lifecycle.ts +161 -0
- package/src/types/signing-operations.ts +99 -0
- package/src/types/wallet-messages.ts +251 -0
- package/src/utils/client-session-claim.ts +188 -0
- package/src/utils/index.ts +54 -0
- package/src/utils/public-keys.ts +49 -0
- package/src/utils/siwe.ts +362 -0
- package/src/utils/url-decoding.ts +126 -0
- package/src/utils/url-encoding.ts +144 -0
- package/src/utils/wallet-session-claim.ts +188 -0
- package/src/validation-export.ts +32 -0
- package/src/validators/index.ts +222 -0
- package/src/validators-export.ts +8 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { registerCryptoProvider } from '../../chunk-TCVKC227.js';
|
|
2
|
+
import { __name, __require } from '../../chunk-WCQVDF3K.js';
|
|
3
|
+
|
|
4
|
+
// src/crypto/providers/node-provider.ts
|
|
5
|
+
var _NodeCryptoKeyWrapper = class _NodeCryptoKeyWrapper {
|
|
6
|
+
constructor(keyObject, keyType) {
|
|
7
|
+
this.keyObject = keyObject;
|
|
8
|
+
this.keyType = keyType;
|
|
9
|
+
}
|
|
10
|
+
get type() {
|
|
11
|
+
return this.keyType;
|
|
12
|
+
}
|
|
13
|
+
get algorithm() {
|
|
14
|
+
return "ECDH-P256";
|
|
15
|
+
}
|
|
16
|
+
get extractable() {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
get usages() {
|
|
20
|
+
return this.keyType === "secret" ? ["encrypt", "decrypt"] : ["deriveKey"];
|
|
21
|
+
}
|
|
22
|
+
get nativeKey() {
|
|
23
|
+
return this.keyObject;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
__name(_NodeCryptoKeyWrapper, "NodeCryptoKeyWrapper");
|
|
27
|
+
var NodeCryptoKeyWrapper = _NodeCryptoKeyWrapper;
|
|
28
|
+
function unwrapKeyObject(keyLike) {
|
|
29
|
+
if (keyLike instanceof NodeCryptoKeyWrapper) {
|
|
30
|
+
return keyLike.nativeKey;
|
|
31
|
+
}
|
|
32
|
+
return keyLike;
|
|
33
|
+
}
|
|
34
|
+
__name(unwrapKeyObject, "unwrapKeyObject");
|
|
35
|
+
var _NodeCryptoProvider = class _NodeCryptoProvider {
|
|
36
|
+
constructor(logger) {
|
|
37
|
+
this.name = "NodeCrypto";
|
|
38
|
+
this.cryptoModule = null;
|
|
39
|
+
if (!this.isAvailable) {
|
|
40
|
+
throw new Error("Node.js crypto module not available in this environment");
|
|
41
|
+
}
|
|
42
|
+
this.logger = logger?.child({ component: "NodeCryptoProvider" });
|
|
43
|
+
}
|
|
44
|
+
get isAvailable() {
|
|
45
|
+
try {
|
|
46
|
+
if (typeof process === "undefined" || !process.versions?.node) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
} catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get crypto module instance via dynamic import
|
|
56
|
+
* This prevents Metro bundler from trying to resolve 'crypto' at build time
|
|
57
|
+
*/
|
|
58
|
+
async getCrypto() {
|
|
59
|
+
if (!this.cryptoModule) {
|
|
60
|
+
try {
|
|
61
|
+
this.cryptoModule = await import('crypto');
|
|
62
|
+
} catch {
|
|
63
|
+
throw new Error(
|
|
64
|
+
"Failed to load Node.js crypto module. This provider requires a Node.js environment."
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return this.cryptoModule;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate ECDH P-256 key pair using Node.js crypto
|
|
72
|
+
*/
|
|
73
|
+
async generateKeyPair() {
|
|
74
|
+
this.logger?.debug("Generating ECDH P-256 key pair with Node.js crypto");
|
|
75
|
+
const cryptoModule = await this.getCrypto();
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
cryptoModule.generateKeyPair(
|
|
78
|
+
"ec",
|
|
79
|
+
{
|
|
80
|
+
namedCurve: "prime256v1",
|
|
81
|
+
// P-256
|
|
82
|
+
publicKeyEncoding: { type: "spki", format: "der" },
|
|
83
|
+
privateKeyEncoding: { type: "pkcs8", format: "der" }
|
|
84
|
+
},
|
|
85
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
86
|
+
(err, publicKey, privateKey) => {
|
|
87
|
+
if (err) {
|
|
88
|
+
this.logger?.error("Key pair generation failed", { error: err });
|
|
89
|
+
reject(err);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.logger?.debug("Key pair generation completed");
|
|
93
|
+
resolve({
|
|
94
|
+
publicKey: new NodeCryptoKeyWrapper(publicKey, "public"),
|
|
95
|
+
privateKey: new NodeCryptoKeyWrapper(privateKey, "private")
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Export public key to raw ArrayBuffer format (65 bytes uncompressed)
|
|
103
|
+
*/
|
|
104
|
+
async exportPublicKey(publicKey) {
|
|
105
|
+
this.logger?.debug("Exporting public key");
|
|
106
|
+
const cryptoModule = await this.getCrypto();
|
|
107
|
+
const keyObject = unwrapKeyObject(publicKey);
|
|
108
|
+
const keyObj = keyObject instanceof Buffer ? cryptoModule.createPublicKey({ key: keyObject, format: "der", type: "spki" }) : keyObject;
|
|
109
|
+
const jwk = keyObj.export({ format: "jwk" });
|
|
110
|
+
const x = Buffer.from(jwk.x, "base64url");
|
|
111
|
+
const y = Buffer.from(jwk.y, "base64url");
|
|
112
|
+
const uncompressed = Buffer.concat([Buffer.from([4]), x, y]);
|
|
113
|
+
return await Promise.resolve(
|
|
114
|
+
uncompressed.buffer.slice(
|
|
115
|
+
uncompressed.byteOffset,
|
|
116
|
+
uncompressed.byteOffset + uncompressed.byteLength
|
|
117
|
+
)
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Export private key to raw ArrayBuffer format (32 bytes)
|
|
122
|
+
*/
|
|
123
|
+
async exportPrivateKey(privateKey) {
|
|
124
|
+
this.logger?.debug("Exporting private key");
|
|
125
|
+
const cryptoModule = await this.getCrypto();
|
|
126
|
+
const keyObject = unwrapKeyObject(privateKey);
|
|
127
|
+
const keyBuffer = keyObject instanceof Buffer ? keyObject : Buffer.from(keyObject);
|
|
128
|
+
const keyObj = cryptoModule.createPrivateKey({
|
|
129
|
+
key: keyBuffer,
|
|
130
|
+
format: "der",
|
|
131
|
+
type: "pkcs8"
|
|
132
|
+
});
|
|
133
|
+
const jwk = keyObj.export({ format: "jwk" });
|
|
134
|
+
const dValue = Buffer.from(jwk.d, "base64url");
|
|
135
|
+
return await Promise.resolve(
|
|
136
|
+
dValue.buffer.slice(dValue.byteOffset, dValue.byteOffset + dValue.byteLength)
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Import public key from raw ArrayBuffer format
|
|
141
|
+
*/
|
|
142
|
+
async importPublicKey(keyData) {
|
|
143
|
+
this.logger?.debug("Importing public key");
|
|
144
|
+
const cryptoModule = await this.getCrypto();
|
|
145
|
+
const keyBuffer = Buffer.from(keyData);
|
|
146
|
+
if (keyBuffer.length !== 65 || keyBuffer[0] !== 4) {
|
|
147
|
+
throw new Error("Invalid public key format: expected 65 bytes uncompressed point");
|
|
148
|
+
}
|
|
149
|
+
const x = keyBuffer.slice(1, 33);
|
|
150
|
+
const y = keyBuffer.slice(33, 65);
|
|
151
|
+
const jwk = {
|
|
152
|
+
kty: "EC",
|
|
153
|
+
crv: "P-256",
|
|
154
|
+
x: x.toString("base64url"),
|
|
155
|
+
y: y.toString("base64url")
|
|
156
|
+
};
|
|
157
|
+
const keyObject = cryptoModule.createPublicKey({ key: jwk, format: "jwk" });
|
|
158
|
+
return await Promise.resolve(new NodeCryptoKeyWrapper(keyObject, "public"));
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Import private key from raw ArrayBuffer format
|
|
162
|
+
*/
|
|
163
|
+
async importPrivateKey(keyData) {
|
|
164
|
+
this.logger?.debug("Importing private key");
|
|
165
|
+
const cryptoModule = await this.getCrypto();
|
|
166
|
+
const keyBuffer = Buffer.from(keyData);
|
|
167
|
+
if (keyBuffer.length !== 32) {
|
|
168
|
+
throw new Error("Invalid private key format: expected 32 bytes");
|
|
169
|
+
}
|
|
170
|
+
const jwk = {
|
|
171
|
+
kty: "EC",
|
|
172
|
+
crv: "P-256",
|
|
173
|
+
d: keyBuffer.toString("base64url")
|
|
174
|
+
};
|
|
175
|
+
const keyObject = cryptoModule.createPrivateKey({ key: jwk, format: "jwk" });
|
|
176
|
+
return await Promise.resolve(new NodeCryptoKeyWrapper(keyObject, "private"));
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Derive shared secret using ECDH
|
|
180
|
+
*/
|
|
181
|
+
async deriveSharedSecret(privateKey, publicKey) {
|
|
182
|
+
this.logger?.debug("Deriving shared secret");
|
|
183
|
+
const cryptoModule = await this.getCrypto();
|
|
184
|
+
const ecdh = cryptoModule.createECDH("prime256v1");
|
|
185
|
+
const privateRaw = await this.exportPrivateKey(privateKey);
|
|
186
|
+
ecdh.setPrivateKey(Buffer.from(privateRaw));
|
|
187
|
+
const publicRaw = await this.exportPublicKey(publicKey);
|
|
188
|
+
const sharedSecret = ecdh.computeSecret(Buffer.from(publicRaw));
|
|
189
|
+
const keyObject = cryptoModule.createSecretKey(sharedSecret);
|
|
190
|
+
return new NodeCryptoKeyWrapper(keyObject, "secret");
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Derive AES-GCM encryption key using HKDF-SHA256
|
|
194
|
+
*/
|
|
195
|
+
async deriveEncryptionKey(sharedSecret, salt, info) {
|
|
196
|
+
this.logger?.debug("Deriving AES-GCM encryption key");
|
|
197
|
+
const cryptoModule = await this.getCrypto();
|
|
198
|
+
const keyObject = unwrapKeyObject(sharedSecret);
|
|
199
|
+
const sharedSecretRaw = keyObject.export();
|
|
200
|
+
const derivedKey = cryptoModule.hkdfSync(
|
|
201
|
+
"sha256",
|
|
202
|
+
Buffer.isBuffer(sharedSecretRaw) ? sharedSecretRaw : Buffer.from(sharedSecretRaw),
|
|
203
|
+
Buffer.from(salt),
|
|
204
|
+
Buffer.from(info),
|
|
205
|
+
32
|
|
206
|
+
// 256 bits
|
|
207
|
+
);
|
|
208
|
+
const aesKeyObject = cryptoModule.createSecretKey(derivedKey);
|
|
209
|
+
return await Promise.resolve(new NodeCryptoKeyWrapper(aesKeyObject, "secret"));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Encrypt data using AES-256-GCM
|
|
213
|
+
*/
|
|
214
|
+
async encrypt(key, data, iv) {
|
|
215
|
+
this.logger?.debug("Encrypting with AES-256-GCM");
|
|
216
|
+
const cryptoModule = await this.getCrypto();
|
|
217
|
+
const keyObject = unwrapKeyObject(key);
|
|
218
|
+
const cipher = cryptoModule.createCipheriv(
|
|
219
|
+
"aes-256-gcm",
|
|
220
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
221
|
+
keyObject.export(),
|
|
222
|
+
Buffer.from(iv)
|
|
223
|
+
);
|
|
224
|
+
const encrypted = Buffer.concat([
|
|
225
|
+
cipher.update(Buffer.from(data)),
|
|
226
|
+
cipher.final(),
|
|
227
|
+
cipher.getAuthTag()
|
|
228
|
+
]);
|
|
229
|
+
return await Promise.resolve(
|
|
230
|
+
encrypted.buffer.slice(
|
|
231
|
+
encrypted.byteOffset,
|
|
232
|
+
encrypted.byteOffset + encrypted.byteLength
|
|
233
|
+
)
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Decrypt data using AES-256-GCM
|
|
238
|
+
*/
|
|
239
|
+
async decrypt(key, data, iv) {
|
|
240
|
+
this.logger?.debug("Decrypting with AES-256-GCM");
|
|
241
|
+
const cryptoModule = await this.getCrypto();
|
|
242
|
+
const keyObject = unwrapKeyObject(key);
|
|
243
|
+
const dataBuffer = Buffer.from(data);
|
|
244
|
+
const authTag = dataBuffer.slice(-16);
|
|
245
|
+
const ciphertext = dataBuffer.slice(0, -16);
|
|
246
|
+
const decipher = cryptoModule.createDecipheriv(
|
|
247
|
+
"aes-256-gcm",
|
|
248
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
249
|
+
keyObject.export(),
|
|
250
|
+
Buffer.from(iv)
|
|
251
|
+
);
|
|
252
|
+
decipher.setAuthTag(authTag);
|
|
253
|
+
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
254
|
+
return await Promise.resolve(
|
|
255
|
+
decrypted.buffer.slice(
|
|
256
|
+
decrypted.byteOffset,
|
|
257
|
+
decrypted.byteOffset + decrypted.byteLength
|
|
258
|
+
)
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Generate HMAC-SHA256 authentication code
|
|
263
|
+
*/
|
|
264
|
+
async generateHMAC(key, data) {
|
|
265
|
+
this.logger?.debug("Generating HMAC-SHA256");
|
|
266
|
+
const cryptoModule = await this.getCrypto();
|
|
267
|
+
const keyObject = unwrapKeyObject(key);
|
|
268
|
+
const hmac = cryptoModule.createHmac("sha256", keyObject.export());
|
|
269
|
+
hmac.update(Buffer.from(data));
|
|
270
|
+
const mac = hmac.digest();
|
|
271
|
+
return await Promise.resolve(mac.buffer.slice(mac.byteOffset, mac.byteOffset + mac.byteLength));
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Verify HMAC-SHA256 authentication code
|
|
275
|
+
*/
|
|
276
|
+
async verifyHMAC(key, data, mac) {
|
|
277
|
+
this.logger?.debug("Verifying HMAC-SHA256");
|
|
278
|
+
const cryptoModule = await this.getCrypto();
|
|
279
|
+
const computed = await this.generateHMAC(key, data);
|
|
280
|
+
const expected = new Uint8Array(mac);
|
|
281
|
+
const actual = new Uint8Array(computed);
|
|
282
|
+
if (expected.length !== actual.length) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
return cryptoModule.timingSafeEqual(
|
|
286
|
+
Buffer.from(expected),
|
|
287
|
+
Buffer.from(actual)
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Generate cryptographically secure random bytes
|
|
292
|
+
* Note: This is a synchronous method, so it uses require() instead of dynamic import
|
|
293
|
+
*/
|
|
294
|
+
randomBytes(length) {
|
|
295
|
+
const cryptoModule = this.cryptoModule ?? __require("crypto");
|
|
296
|
+
const buffer = cryptoModule.randomBytes(length);
|
|
297
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
__name(_NodeCryptoProvider, "NodeCryptoProvider");
|
|
301
|
+
var NodeCryptoProvider = _NodeCryptoProvider;
|
|
302
|
+
registerCryptoProvider("node", (logger) => new NodeCryptoProvider(logger));
|
|
303
|
+
|
|
304
|
+
export { NodeCryptoProvider };
|
|
305
|
+
//# sourceMappingURL=node-provider.js.map
|
|
306
|
+
//# sourceMappingURL=node-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/crypto/providers/node-provider.ts"],"names":[],"mappings":"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","file":"node-provider.js","sourcesContent":["import type { Logger } from '@bananalink-sdk/logger';\nimport type { CryptoProvider, CryptoKeyLike, ProviderKeyPair } from '../../types/crypto-provider';\nimport { registerCryptoProvider } from './registry';\n\n/**\n * Type definition for Node.js crypto module (loaded dynamically to prevent Metro bundling)\n */\ntype NodeCrypto = typeof import('crypto');\n\n/**\n * Node.js crypto.KeyObject wrapper to implement CryptoKeyLike interface\n * Note: keyObject type is unknown at compile time (crypto.KeyObject | Buffer at runtime)\n */\nclass NodeCryptoKeyWrapper implements CryptoKeyLike {\n constructor(\n private readonly keyObject: unknown, // crypto.KeyObject | Buffer at runtime\n private readonly keyType: 'public' | 'private' | 'secret'\n ) {}\n\n get type(): 'public' | 'private' | 'secret' {\n return this.keyType;\n }\n\n get algorithm(): string {\n return 'ECDH-P256';\n }\n\n get extractable(): boolean {\n return true;\n }\n\n get usages(): readonly string[] {\n return this.keyType === 'secret' ? ['encrypt', 'decrypt'] : ['deriveKey'];\n }\n\n get nativeKey(): unknown {\n return this.keyObject;\n }\n}\n\n/**\n * Helper function to unwrap CryptoKeyLike to native KeyObject or Buffer\n */\nfunction unwrapKeyObject(keyLike: CryptoKeyLike): unknown {\n if (keyLike instanceof NodeCryptoKeyWrapper) {\n return keyLike.nativeKey;\n }\n // Assume it's already a KeyObject\n return keyLike;\n}\n\n/**\n * Node.js crypto module implementation of CryptoProvider\n * Optimized for backend services with native crypto performance\n *\n * This provider uses the native Node.js crypto module which provides:\n * - Superior performance compared to Web Crypto API in Node.js\n * - Direct access to OpenSSL optimizations\n * - Zero additional dependencies\n * - Full support for ECDH P-256 and AES-256-GCM\n *\n * @example\n * ```typescript\n * import { NodeCryptoProvider } from '@bananalink-sdk/protocol/crypto/provider/node';\n * const provider = new NodeCryptoProvider();\n * const keyPair = await provider.generateKeyPair();\n * ```\n */\nexport class NodeCryptoProvider implements CryptoProvider {\n public readonly name = 'NodeCrypto';\n private readonly logger?: Logger;\n private cryptoModule: NodeCrypto | null = null;\n\n public get isAvailable(): boolean {\n try {\n // Check if we're in Node.js environment\n if (typeof process === 'undefined' || !process.versions?.node) {\n return false;\n }\n // Crypto module availability will be checked when getCrypto() is called\n return true;\n } catch {\n return false;\n }\n }\n\n constructor(logger?: Logger) {\n if (!this.isAvailable) {\n throw new Error('Node.js crypto module not available in this environment');\n }\n this.logger = logger?.child({ component: 'NodeCryptoProvider' });\n }\n\n /**\n * Get crypto module instance via dynamic import\n * This prevents Metro bundler from trying to resolve 'crypto' at build time\n */\n private async getCrypto(): Promise<NodeCrypto> {\n if (!this.cryptoModule) {\n try {\n // Dynamic import prevents static analysis by bundlers\n this.cryptoModule = await import('crypto');\n } catch {\n throw new Error(\n 'Failed to load Node.js crypto module. ' +\n 'This provider requires a Node.js environment.'\n );\n }\n }\n return this.cryptoModule;\n }\n\n /**\n * Generate ECDH P-256 key pair using Node.js crypto\n */\n async generateKeyPair(): Promise<ProviderKeyPair> {\n this.logger?.debug('Generating ECDH P-256 key pair with Node.js crypto');\n const cryptoModule = await this.getCrypto();\n\n return new Promise((resolve, reject) => {\n cryptoModule.generateKeyPair(\n 'ec',\n {\n namedCurve: 'prime256v1', // P-256\n publicKeyEncoding: { type: 'spki', format: 'der' },\n privateKeyEncoding: { type: 'pkcs8', format: 'der' },\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (err: Error | null, publicKey: any, privateKey: any) => {\n if (err) {\n this.logger?.error('Key pair generation failed', { error: err });\n reject(err);\n return;\n }\n\n this.logger?.debug('Key pair generation completed');\n resolve({\n publicKey: new NodeCryptoKeyWrapper(publicKey, 'public'),\n privateKey: new NodeCryptoKeyWrapper(privateKey, 'private'),\n });\n }\n );\n });\n }\n\n /**\n * Export public key to raw ArrayBuffer format (65 bytes uncompressed)\n */\n async exportPublicKey(publicKey: CryptoKeyLike): Promise<ArrayBuffer> {\n this.logger?.debug('Exporting public key');\n const cryptoModule = await this.getCrypto();\n const keyObject = unwrapKeyObject(publicKey);\n\n // If it's a Buffer (DER format from generateKeyPair), convert to KeyObject first\n const keyObj = keyObject instanceof Buffer\n ? cryptoModule.createPublicKey({ key: keyObject, format: 'der', type: 'spki' })\n : keyObject;\n\n // Export as JWK to get X/Y coordinates\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const jwk = (keyObj as any).export({ format: 'jwk' });\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const x = Buffer.from(jwk.x as string, 'base64url');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const y = Buffer.from(jwk.y as string, 'base64url');\n\n // Construct 65-byte uncompressed point: 0x04 + X (32 bytes) + Y (32 bytes)\n const uncompressed = Buffer.concat([Buffer.from([0x04]), x, y]);\n\n return await Promise.resolve(\n uncompressed.buffer.slice(\n uncompressed.byteOffset,\n uncompressed.byteOffset + uncompressed.byteLength\n )\n );\n }\n\n /**\n * Export private key to raw ArrayBuffer format (32 bytes)\n */\n async exportPrivateKey(privateKey: CryptoKeyLike): Promise<ArrayBuffer> {\n this.logger?.debug('Exporting private key');\n const cryptoModule = await this.getCrypto();\n const keyObject = unwrapKeyObject(privateKey);\n\n // Convert KeyObject to raw format\n const keyBuffer = keyObject instanceof Buffer ? keyObject : Buffer.from(keyObject as ArrayBuffer);\n const keyObj = cryptoModule.createPrivateKey({\n key: keyBuffer,\n format: 'der',\n type: 'pkcs8',\n });\n\n // Export as raw scalar (32 bytes)\n const jwk = keyObj.export({ format: 'jwk' });\n const dValue = Buffer.from(jwk.d as string, 'base64url');\n\n return await Promise.resolve(\n dValue.buffer.slice(dValue.byteOffset, dValue.byteOffset + dValue.byteLength)\n );\n }\n\n /**\n * Import public key from raw ArrayBuffer format\n */\n async importPublicKey(keyData: ArrayBuffer): Promise<CryptoKeyLike> {\n this.logger?.debug('Importing public key');\n const cryptoModule = await this.getCrypto();\n const keyBuffer = Buffer.from(keyData);\n\n // Ensure it's uncompressed format (65 bytes starting with 0x04)\n if (keyBuffer.length !== 65 || keyBuffer[0] !== 0x04) {\n throw new Error('Invalid public key format: expected 65 bytes uncompressed point');\n }\n\n // Create KeyObject from raw uncompressed point\n // We need to wrap it in DER format\n const x = keyBuffer.slice(1, 33);\n const y = keyBuffer.slice(33, 65);\n\n // Create JWK representation\n const jwk = {\n kty: 'EC' as const,\n crv: 'P-256' as const,\n x: x.toString('base64url'),\n y: y.toString('base64url'),\n };\n\n const keyObject = cryptoModule.createPublicKey({ key: jwk, format: 'jwk' });\n return await Promise.resolve(new NodeCryptoKeyWrapper(keyObject, 'public'));\n }\n\n /**\n * Import private key from raw ArrayBuffer format\n */\n async importPrivateKey(keyData: ArrayBuffer): Promise<CryptoKeyLike> {\n this.logger?.debug('Importing private key');\n const cryptoModule = await this.getCrypto();\n const keyBuffer = Buffer.from(keyData);\n\n if (keyBuffer.length !== 32) {\n throw new Error('Invalid private key format: expected 32 bytes');\n }\n\n // Create JWK representation\n const jwk = {\n kty: 'EC' as const,\n crv: 'P-256' as const,\n d: keyBuffer.toString('base64url'),\n };\n\n const keyObject = cryptoModule.createPrivateKey({ key: jwk, format: 'jwk' });\n return await Promise.resolve(new NodeCryptoKeyWrapper(keyObject, 'private'));\n }\n\n /**\n * Derive shared secret using ECDH\n */\n async deriveSharedSecret(privateKey: CryptoKeyLike, publicKey: CryptoKeyLike): Promise<CryptoKeyLike> {\n this.logger?.debug('Deriving shared secret');\n const cryptoModule = await this.getCrypto();\n\n // Create ECDH object\n const ecdh = cryptoModule.createECDH('prime256v1');\n\n // Set private key\n const privateRaw = await this.exportPrivateKey(privateKey);\n ecdh.setPrivateKey(Buffer.from(privateRaw));\n\n // Compute shared secret\n const publicRaw = await this.exportPublicKey(publicKey);\n const sharedSecret = ecdh.computeSecret(Buffer.from(publicRaw));\n\n // Wrap as secret key\n const keyObject = cryptoModule.createSecretKey(sharedSecret);\n return new NodeCryptoKeyWrapper(keyObject, 'secret');\n }\n\n /**\n * Derive AES-GCM encryption key using HKDF-SHA256\n */\n async deriveEncryptionKey(\n sharedSecret: CryptoKeyLike,\n salt: ArrayBuffer,\n info: ArrayBuffer\n ): Promise<CryptoKeyLike> {\n this.logger?.debug('Deriving AES-GCM encryption key');\n const cryptoModule = await this.getCrypto();\n\n // Extract raw shared secret\n const keyObject = unwrapKeyObject(sharedSecret);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const sharedSecretRaw = (keyObject as any).export();\n\n // Use HKDF to derive 32-byte key\n const derivedKey = cryptoModule.hkdfSync(\n 'sha256',\n Buffer.isBuffer(sharedSecretRaw) ? sharedSecretRaw : Buffer.from(sharedSecretRaw),\n Buffer.from(salt),\n Buffer.from(info),\n 32 // 256 bits\n ) as Buffer;\n\n // Create secret key object\n const aesKeyObject = cryptoModule.createSecretKey(derivedKey);\n return await Promise.resolve(new NodeCryptoKeyWrapper(aesKeyObject, 'secret'));\n }\n\n /**\n * Encrypt data using AES-256-GCM\n */\n async encrypt(key: CryptoKeyLike, data: ArrayBuffer, iv: ArrayBuffer): Promise<ArrayBuffer> {\n this.logger?.debug('Encrypting with AES-256-GCM');\n const cryptoModule = await this.getCrypto();\n const keyObject = unwrapKeyObject(key);\n\n const cipher = cryptoModule.createCipheriv(\n 'aes-256-gcm',\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n (keyObject as any).export(),\n Buffer.from(iv)\n );\n\n const encrypted = Buffer.concat([\n cipher.update(Buffer.from(data)),\n cipher.final(),\n cipher.getAuthTag(),\n ]);\n\n return await Promise.resolve(\n encrypted.buffer.slice(\n encrypted.byteOffset,\n encrypted.byteOffset + encrypted.byteLength\n )\n );\n }\n\n /**\n * Decrypt data using AES-256-GCM\n */\n async decrypt(key: CryptoKeyLike, data: ArrayBuffer, iv: ArrayBuffer): Promise<ArrayBuffer> {\n this.logger?.debug('Decrypting with AES-256-GCM');\n const cryptoModule = await this.getCrypto();\n const keyObject = unwrapKeyObject(key);\n const dataBuffer = Buffer.from(data);\n\n // Last 16 bytes are the auth tag\n const authTag = dataBuffer.slice(-16);\n const ciphertext = dataBuffer.slice(0, -16);\n\n const decipher = cryptoModule.createDecipheriv(\n 'aes-256-gcm',\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n (keyObject as any).export(),\n Buffer.from(iv)\n );\n decipher.setAuthTag(authTag);\n\n const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);\n\n return await Promise.resolve(\n decrypted.buffer.slice(\n decrypted.byteOffset,\n decrypted.byteOffset + decrypted.byteLength\n )\n );\n }\n\n /**\n * Generate HMAC-SHA256 authentication code\n */\n async generateHMAC(key: CryptoKeyLike, data: ArrayBuffer): Promise<ArrayBuffer> {\n this.logger?.debug('Generating HMAC-SHA256');\n const cryptoModule = await this.getCrypto();\n const keyObject = unwrapKeyObject(key);\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const hmac = cryptoModule.createHmac('sha256', (keyObject as any).export());\n hmac.update(Buffer.from(data));\n const mac = hmac.digest();\n\n return await Promise.resolve(mac.buffer.slice(mac.byteOffset, mac.byteOffset + mac.byteLength));\n }\n\n /**\n * Verify HMAC-SHA256 authentication code\n */\n async verifyHMAC(key: CryptoKeyLike, data: ArrayBuffer, mac: ArrayBuffer): Promise<boolean> {\n this.logger?.debug('Verifying HMAC-SHA256');\n const cryptoModule = await this.getCrypto();\n const computed = await this.generateHMAC(key, data);\n const expected = new Uint8Array(mac);\n const actual = new Uint8Array(computed);\n\n if (expected.length !== actual.length) {\n return false;\n }\n\n // Constant-time comparison\n return cryptoModule.timingSafeEqual(\n Buffer.from(expected),\n Buffer.from(actual)\n );\n }\n\n /**\n * Generate cryptographically secure random bytes\n * Note: This is a synchronous method, so it uses require() instead of dynamic import\n */\n randomBytes(length: number): ArrayBuffer {\n // Use cached module if available, otherwise use synchronous require\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cryptoModule = this.cryptoModule ?? require('crypto') as NodeCrypto;\n const buffer = cryptoModule.randomBytes(length);\n return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);\n }\n}\n\n/**\n * Self-register Node provider on import\n * This allows the provider to be available when explicitly imported\n */\nregisterCryptoProvider('node', (logger) => new NodeCryptoProvider(logger));\n\n// TypeScript module augmentation to track this provider is available\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace BananaLink {\n interface RegisteredCryptoProviders {\n node: true;\n }\n }\n}\n"]}
|