toiljs 0.0.53 → 0.0.55
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/CHANGELOG.md +10 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/devserver/.tsbuildinfo +1 -1
- package/build/devserver/database.d.ts +8 -0
- package/build/devserver/database.js +334 -0
- package/build/devserver/host.d.ts +2 -0
- package/build/devserver/host.js +3 -2
- package/build/devserver/module.js +7 -1
- package/examples/basic/client/routes/rest.tsx +52 -1
- package/examples/basic/server/core/AppHandler.ts +0 -18
- package/examples/basic/server/main.ts +1 -0
- package/examples/basic/server/models/GuestEntry.ts +12 -0
- package/examples/basic/server/models/GuestbookView.ts +10 -0
- package/examples/basic/server/models/NewMessage.ts +6 -0
- package/examples/basic/server/routes/Auth.ts +39 -163
- package/examples/basic/server/routes/Guestbook.ts +62 -0
- package/examples/basic/server/routes/Session.ts +5 -5
- package/package.json +2 -2
- package/server/globals/auth.ts +113 -57
- package/server/globals/twofactor.ts +2 -1
- package/server/runtime/http/securecookies.ts +3 -2
- package/src/devserver/database.ts +459 -0
- package/src/devserver/host.ts +9 -5
- package/src/devserver/module.ts +9 -3
- package/test/devserver-database.test.ts +304 -0
- package/test/devserver-pqauth.test.ts +5 -65
- package/test/example-guestbook.test.ts +78 -0
- package/test/pqauth-e2e.test.ts +6 -6
- package/build/devserver/kv.d.ts +0 -3
- package/build/devserver/kv.js +0 -53
- package/src/devserver/kv.ts +0 -93
package/server/globals/auth.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// and the toiljs dev-server mock).
|
|
11
11
|
|
|
12
12
|
import { DataWriter, DataReader } from 'data';
|
|
13
|
-
import { HmacImportParams, HmacParams, ALG_SHA_256, USAGE_SIGN, USAGE_VERIFY } from 'crypto';
|
|
13
|
+
import { HmacImportParams, HmacParams, ALG_SHA_256, FMT_RAW, USAGE_SIGN, USAGE_VERIFY } from 'crypto';
|
|
14
14
|
|
|
15
15
|
import {
|
|
16
16
|
Server,
|
|
@@ -70,46 +70,97 @@ declare function __toilVoprfEvaluate(
|
|
|
70
70
|
outPtr: usize,
|
|
71
71
|
): i32;
|
|
72
72
|
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
73
|
+
// Secret configuration is AUTOMATIC. Every secret below resolves on first use
|
|
74
|
+
// from, in order: (1) an explicit `set*()` override, (2) the tenant's env store
|
|
75
|
+
// (`Environment.getSecure`, backed by `.env.secrets` / the dashboard) under the
|
|
76
|
+
// key named below, then (3) a well-known, clearly-insecure DEV fallback so local
|
|
77
|
+
// dev and the examples run with zero config. The resolved value is cached in the
|
|
78
|
+
// module global. Because every request runs in a FRESH wasm instance that reads
|
|
79
|
+
// the SAME env value the SAME way, there is no per-route / per-instance secret to
|
|
80
|
+
// keep in sync by hand: a cookie minted by one route can never fail to verify in
|
|
81
|
+
// another for want of a `setSecret` call. A real deployment sets the env values
|
|
82
|
+
// (and pins its own server KEM public key in the client); the DEV fallbacks are
|
|
83
|
+
// never a place to put a real secret.
|
|
84
|
+
|
|
85
|
+
/** Env-store keys the framework reads automatically (tenant-set secrets). */
|
|
86
|
+
const ENV_SESSION_SECRET: string = 'AUTH_SESSION_SECRET';
|
|
87
|
+
const ENV_OPRF_SEED: string = 'AUTH_OPRF_SEED';
|
|
88
|
+
const ENV_KEM_SK: string = 'AUTH_KEM_SK';
|
|
89
|
+
|
|
90
|
+
/** Well-known DEV fallbacks (insecure; overridden by env or `set*()`). */
|
|
91
|
+
const DEV_SESSION_SECRET: string = 'toil-dev-insecure-session-secret-CHANGE-ME';
|
|
92
|
+
const DEV_OPRF_SEED_SRC: string = 'toil-dev-oprf-seed-v1';
|
|
93
|
+
// A well-known DEV ML-KEM-768 decapsulation key (hex). Its public half (the `ek`
|
|
94
|
+
// at bytes [1152, 2336) of the dk) is PINNED in the client (`src/client/auth.ts`,
|
|
95
|
+
// `SERVER_KEM_PUBLIC_KEY`), so the PQ-auth example runs with zero config. A real
|
|
96
|
+
// deployment sets `AUTH_KEM_SK` and pins its own public key; never treat this as
|
|
97
|
+
// secret. Tree-shaken away unless a server actually calls the ML-KEM path.
|
|
98
|
+
const DEV_KEM_SK_HEX: string = '3156a8eb11c62bdb4af9fc57bef470f880ae340373bcc61662748a9742a639b9ad6bc55a77a82e0caa99ede237b4783ce70ab08ecc5802a9478c4ca3de67acd7a2147db43fdba408e9765443f37e9e90cc09f836d53879b890126bd6c33d55a6d97636a28ba10e18ac919aa9d37c2e4d07b6c930a5cb3238c8338fbb1abe7dac124c93462ebc5ae81cb132947993a74f9602610eab68b7fc9407b58e958aca054443246240c484c650962408168632c303cfc738d3b918ee04a37c2436b6f7300b8c6e7bd528bc5c229673c3a1bc4ae4265772f654ed8377b285626c67a4ef715a5a04a56804c3fae93ca5e3219cd68649622ee0d77bcb664a68e377260a3a38c2739b81c3c9ec510b66acde5041f3b52922a17019dc9afaec71c3e3c3102686ceb019da138b22463ad7f452640526d1d8b21c9111ca844149d1391c937b84287f1a228342c06ccb87c31cb14227e175007c5c4497c11e8647377234a84ab2640aa8ee7acb54954f99155cf7d768446b104ac149f59ca1d0029401570db9341c93db0041d52fbbd62726a75f9ab177e4ea5176e675d28a1f9852c28b38074c91cec8064b6ba116db8b59c0434fbd1b207cd921fbf29b06740b53c7304b17b253652ad469b2cb10bf7ed3bcc5b1b6168c2d30a889f67a01ae79455100ac582ba2f764a4a4b134b9115d7c548032d55d4916ce25c0ce7c42160e446298fb10f747302e781a70b2b7962b0b54f3c0e3a4677e99cc02e41e66b0861d02d072b94ce3f8a04fd20d2ec220cea3737922808f00080186421e60b7d1076e5ca40099d54da33033021349e31bb65e12aa259b37bc975582aa6441ab2fabdc9cee0aab0c11c7e3489b93bab26e13bf399ab8a37949baba3c2f8a94fd97a9a551c96d582b5c1ba97b4547701656ee02567dd6a8362c1043c5874760c7d1133292f05c9d3689beccb903d4bd65f09e3e3255d0229daf9050ebaa107e51371fc9248393239575466a9c45b4a239e1b29b07d9701cf1bb488a95a004a98fcb1f6d548cc8554a3eb25a5fc90892618e5d33b04938567e748ab9ba79b0d39d611864b2140666c1791e79c5c0943a03038f7306551db3b271b08dec32443ae14674e16d6c42956ef36499348e7424bbc4883c37675a4f8bb28cd68f30b532ba80104e7214b9a4886045a152d161821a006ae03ae3742e36f63d997c858b850119e1004f4022a04a9533749d993641763a83dce5256f3826ae9b0584c72d69c77d6784444737a0192789e0d63a2f2808ce88b07c33383e588f68b13b892ac6998c9f2db14ba3e10eee4b9717761efc298e026974231a143b89009a724a7121292bb9292662b87502beadb9cbea3cc89de1997b376575f466b6693e18eb70630ba1823cae5f03698ae662190207156ca8d1a4a3cb926d20c92b524180c0804f057491c292024641bf9b21b52214bf2a2b42d16596e22935317bc712e64f64c143b257ca6f663223a1a2b6537b55746a2a739b2adbbfa004354a1555cc8b8215aa06413b27b7fa8c860386c13876b8d55b743860a13c0005dc4ac5e003cd3431c7a29edcc73c50b991e56a12423ac1f2842ed2999b7b31b6e01aaa83c01af658bae959b2cb256f1e7bba29d765e8083182891302569b3712a856e564fdd484b0706b0c68568d5ab7edc742cf74459d64595455a60f267973aa55e43c5be61925a3822eafcca445e36dc4655636e31e6fc9bec338b253f94290008ef7f40dbddb49c15c690f6755a23a1b3c85cfd5207e71a607086a6fc6d74a05080f43276901a19cafdb8de7771d58ea07f0f1056b905127b22223d08e75173199f13ab13c5dcd3b51ac784f84e520484a262b845a897c41cf27324ab6ba545c78c9ccab361051e0bba53498af26240fa0d566d1572684f4b42e253e6d052c848650915063c35641e1121ef8d9cfd17b667b351103c56d195007c9376d0c08aa268396814490eab4c364175a94533267a1933862cc4c33bcf0a13d1fa2b9d6c5082eeca1480672f2526cbe013beff14dc908a386e0b633c8761023cbed760deac6709bc328d865ac82e12307b673d96711dbb27a4d939230d25b53d594169a318be0200fa33550e9418e2a3b30e9719edc09d5fc4306f1abfd021eab14637a8a72c5931d25dc9b56db0e6ab677522b10f25307dbb804a6774ce05b87b0976a4b227bfe6caf20a79e64004fbd27b1eea018b3ab8ffa629f2dc87f19278f95168e94e44660a3370c537795678eb2f056260609769740583b51b291862927a1938737c6a37f40b78f00671cccbcb88ac3427b37915ed58782998f84051647707d48995472baad3f64a7cca54e1c0734db08751c614a34f28b84f2c1b5a6817355ab61957c486b7acffbc092bc8a7b46387f33b53ed372f7168d31a71cd008539928b0cdf91e835aa97f6a2be6d327b87a6ae478701d75a59a25179cb14997bb2552853014724170a1c49b82c2bcebc3279024e1fa44c53c7afdc43f0bd22116490f3b74c90e7296be58b9a91168f2fa0c3d378a3bcac959f357825c9976a8c9ee944f29b45e96d7345d9b478431a20cf1c5d3a3227c717fd204619777636c0cb140db5c50d2a3302334461030bee34e4eb1a6f02b733f9ccda4290fa168bc039568373241542728d00030d1f251e83737cb215adbdc1de75978675a0cd0d75b12748abdda7a9852629c63697d145af2c69854b06e03f37c4b064e4c9a4c03f2ad4d081e70180e9547247921918118086b62b4f7727f46b24e3e79ba3f28209f32b5102035bf935856232f83642268c0292ec6bf8e9462382163d30a20b4bcb7b4439310ec9d0a148193907fc07697342967cf1a16c6b3c71558951fa915400736cf699262b54b723abb2ecc27b74b68ee494287595ef818388adb49e883c67bfa5c226c0eef037a0851a29d34675912c1ea1068310b6dfcd017c809c8fbfc2c3ae78dfef07299960eeefba182662a90fa422c1790f356a2ea909012b15623a9b9e450a282cb530589a68368b3583159d9010ac3e52cc974753c342e58279516339dfb691df94b13a223ad97eb6a09c21dafe6304a3642d6d2067b5238497661fe88ad1227ca3557be2a576b6e17c5a7f997ea07929e76407e376aba74c44cd8504804776f39bbb8327624188a63501e83b404d9438cade0b11dc3ac61856447fb072b91761c228878f01b2eb6b4b21ba664c2c75882431603b25a449ffeb8410b910558581777562aa9b2181fd9c04713ad9326462d3e842121c4997f9aa932417c67851625816de66e0d65637434629f39d157cc40cbafccc4429c35caeda482299013baf565d0f38b8f2886b9641ae6bea5b2bfccd9e6f3000d1a2734414e5b6875828f9ca9b6c3d0ddeaf704111e2b38';
|
|
99
|
+
|
|
100
|
+
// Resolved-and-cached per instance; `null` = not yet resolved and not overridden.
|
|
101
|
+
let __sessionSecret: Uint8Array | null = null;
|
|
102
|
+
let __oprfSeed: Uint8Array | null = null;
|
|
103
|
+
let __serverKemSk: Uint8Array | null = null;
|
|
104
|
+
let __serverKemPk: Uint8Array | null = null;
|
|
105
|
+
|
|
106
|
+
function __hexNibble(c: i32): i32 {
|
|
107
|
+
if (c >= 48 && c <= 57) return c - 48; // 0-9
|
|
108
|
+
if (c >= 97 && c <= 102) return c - 87; // a-f
|
|
109
|
+
if (c >= 65 && c <= 70) return c - 55; // A-F
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
function __fromHex(s: string): Uint8Array {
|
|
113
|
+
const out = new Uint8Array(s.length >> 1);
|
|
114
|
+
for (let i = 0; i < out.length; i++) {
|
|
115
|
+
out[i] = <u8>((__hexNibble(s.charCodeAt(i * 2)) << 4) | __hexNibble(s.charCodeAt(i * 2 + 1)));
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** The session HMAC secret (UTF-8 of the env value or the DEV fallback). */
|
|
121
|
+
function __resolveSessionSecret(): Uint8Array {
|
|
122
|
+
let s = __sessionSecret;
|
|
123
|
+
if (s != null) return s;
|
|
124
|
+
const v = Environment.getSecure(ENV_SESSION_SECRET);
|
|
125
|
+
s = Uint8Array.wrap(String.UTF8.encode(v != null ? v : DEV_SESSION_SECRET));
|
|
126
|
+
__sessionSecret = s;
|
|
127
|
+
return s;
|
|
128
|
+
}
|
|
129
|
+
/** The OPRF master seed, hashed to 32 bytes (RFC 9497 Ns) so any env value works. */
|
|
130
|
+
function __resolveOprfSeed(): Uint8Array {
|
|
131
|
+
let s = __oprfSeed;
|
|
132
|
+
if (s != null) return s;
|
|
133
|
+
const v = Environment.getSecure(ENV_OPRF_SEED);
|
|
134
|
+
s = crypto.sha256Text(v != null ? v : DEV_OPRF_SEED_SRC);
|
|
135
|
+
__oprfSeed = s;
|
|
136
|
+
return s;
|
|
137
|
+
}
|
|
138
|
+
/** The server static ML-KEM-768 secret (decapsulation) key (2400 bytes). */
|
|
139
|
+
function __resolveServerKemSk(): Uint8Array {
|
|
140
|
+
let s = __serverKemSk;
|
|
141
|
+
if (s != null) return s;
|
|
142
|
+
const v = Environment.getSecure(ENV_KEM_SK);
|
|
143
|
+
s = __fromHex(v != null ? v : DEV_KEM_SK_HEX);
|
|
144
|
+
__serverKemSk = s;
|
|
145
|
+
return s;
|
|
146
|
+
}
|
|
147
|
+
/** The server static ML-KEM-768 PUBLIC key (the `ek` embedded in the dk at bytes
|
|
148
|
+
* [1152, 2336), FIPS 203 layout), used for the key id bound into the login
|
|
149
|
+
* transcript. The client pins the same key. */
|
|
150
|
+
function __resolveServerKemPk(): Uint8Array {
|
|
151
|
+
let s = __serverKemPk;
|
|
152
|
+
if (s != null) return s;
|
|
153
|
+
s = __resolveServerKemSk().slice(1152, 2336);
|
|
154
|
+
__serverKemPk = s;
|
|
155
|
+
return s;
|
|
156
|
+
}
|
|
106
157
|
|
|
107
158
|
// HMAC-SHA256(key, msg) via the ambient Web Crypto (same path SecureCookies
|
|
108
159
|
// uses). The session-key derivation and the mutual-auth confirmation tag are
|
|
109
160
|
// both keyed PRFs over the transcript; the client mirrors this with hash-wasm.
|
|
110
161
|
function __hmacSha256(key: Uint8Array, msg: Uint8Array): Uint8Array {
|
|
111
162
|
const k = crypto.subtle.importKey(
|
|
112
|
-
|
|
163
|
+
FMT_RAW,
|
|
113
164
|
key,
|
|
114
165
|
new HmacImportParams(ALG_SHA_256),
|
|
115
166
|
false,
|
|
@@ -165,9 +216,10 @@ export namespace AuthService {
|
|
|
165
216
|
export const DEFAULT_SESSION_TTL_SECS: u64 = 86400; // 24h
|
|
166
217
|
|
|
167
218
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
219
|
+
* Override the session-signing secret programmatically. OPTIONAL: by default
|
|
220
|
+
* AuthService reads `AUTH_SESSION_SECRET` from the env store (with a DEV
|
|
221
|
+
* fallback), so most apps never call this. An override takes precedence over
|
|
222
|
+
* the env value for the current request; keep it out of any client bundle.
|
|
171
223
|
*/
|
|
172
224
|
export function setSecret(secret: Uint8Array): void {
|
|
173
225
|
__sessionSecret = secret;
|
|
@@ -183,7 +235,7 @@ export namespace AuthService {
|
|
|
183
235
|
const req = Server.currentRequest;
|
|
184
236
|
if (req == null) return null;
|
|
185
237
|
|
|
186
|
-
const sealed = SecureCookies.signed(
|
|
238
|
+
const sealed = SecureCookies.signed(__resolveSessionSecret()).open(
|
|
187
239
|
req.cookies(),
|
|
188
240
|
sessionCookieName(__reqIsSecure()),
|
|
189
241
|
);
|
|
@@ -246,7 +298,7 @@ export namespace AuthService {
|
|
|
246
298
|
.sameSite(SameSite.Lax)
|
|
247
299
|
.maxAge(<i64>ttlSecs);
|
|
248
300
|
cookie = secure ? cookie.asHostPrefixed() : cookie.path('/');
|
|
249
|
-
return SecureCookies.signed(
|
|
301
|
+
return SecureCookies.signed(__resolveSessionSecret()).seal(cookie);
|
|
250
302
|
}
|
|
251
303
|
|
|
252
304
|
/** A `Set-Cookie` that immediately clears the session (logout). */
|
|
@@ -384,28 +436,30 @@ export namespace AuthService {
|
|
|
384
436
|
export const OPRF_SEED_LEN: i32 = 32;
|
|
385
437
|
|
|
386
438
|
/**
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
439
|
+
* Override the OPRF master seed (32 bytes) programmatically. OPTIONAL: by
|
|
440
|
+
* default AuthService reads `AUTH_OPRF_SEED` from the env store (hashed to 32
|
|
441
|
+
* bytes, with a DEV fallback). Per-user OPRF keys derive from this + the
|
|
442
|
+
* username; keep it out of any client bundle.
|
|
390
443
|
*/
|
|
391
444
|
export function setOprfSeed(seed: Uint8Array): void {
|
|
392
445
|
__oprfSeed = seed;
|
|
393
446
|
}
|
|
394
447
|
|
|
395
448
|
/**
|
|
396
|
-
*
|
|
397
|
-
* bytes).
|
|
398
|
-
*
|
|
449
|
+
* Override the server static ML-KEM-768 secret (decapsulation) key (2400
|
|
450
|
+
* bytes) programmatically. OPTIONAL: by default AuthService reads `AUTH_KEM_SK`
|
|
451
|
+
* (hex) from the env store, with a DEV fallback whose public half is pinned in
|
|
452
|
+
* the client. Never put this in a client bundle.
|
|
399
453
|
*/
|
|
400
454
|
export function setServerKemSecretKey(secretKey: Uint8Array): void {
|
|
401
455
|
__serverKemSk = secretKey;
|
|
402
456
|
}
|
|
403
457
|
|
|
404
458
|
/**
|
|
405
|
-
*
|
|
406
|
-
* compute {@link serverKemKeyId}.
|
|
407
|
-
* `ek` embedded
|
|
408
|
-
*
|
|
459
|
+
* Override the server static ML-KEM-768 PUBLIC key (1184 bytes), used to
|
|
460
|
+
* compute {@link serverKemKeyId}. OPTIONAL: by default it is derived from the
|
|
461
|
+
* secret key (the `ek` embedded at bytes [1152, 2336) of the dk), so setting
|
|
462
|
+
* the secret key is enough. Must be the key the client pins.
|
|
409
463
|
*/
|
|
410
464
|
export function setServerKemPublicKey(publicKey: Uint8Array): void {
|
|
411
465
|
__serverKemPk = publicKey;
|
|
@@ -421,9 +475,10 @@ export namespace AuthService {
|
|
|
421
475
|
if (blinded.length != OPRF_ELEMENT_LEN) return new Uint8Array(0);
|
|
422
476
|
const info = Uint8Array.wrap(String.UTF8.encode(username));
|
|
423
477
|
const out = new Uint8Array(OPRF_ELEMENT_LEN);
|
|
478
|
+
const seed = __resolveOprfSeed();
|
|
424
479
|
const rc = __toilVoprfEvaluate(
|
|
425
|
-
|
|
426
|
-
|
|
480
|
+
seed.dataStart,
|
|
481
|
+
seed.length,
|
|
427
482
|
info.dataStart,
|
|
428
483
|
info.length,
|
|
429
484
|
blinded.dataStart,
|
|
@@ -439,15 +494,16 @@ export namespace AuthService {
|
|
|
439
494
|
* Only the genuine server can produce this, so it underpins mutual auth.
|
|
440
495
|
*/
|
|
441
496
|
export function mlkemDecapsulate(ciphertext: Uint8Array): Uint8Array {
|
|
442
|
-
|
|
497
|
+
const sk = __resolveServerKemSk();
|
|
498
|
+
if (sk.length != KEM_SECRET_KEY_LEN || ciphertext.length != KEM_CIPHERTEXT_LEN) {
|
|
443
499
|
return new Uint8Array(0);
|
|
444
500
|
}
|
|
445
501
|
const out = new Uint8Array(SHARED_SECRET_LEN);
|
|
446
502
|
const rc = __toilMlkemDecapsulate(
|
|
447
503
|
ciphertext.dataStart,
|
|
448
504
|
ciphertext.length,
|
|
449
|
-
|
|
450
|
-
|
|
505
|
+
sk.dataStart,
|
|
506
|
+
sk.length,
|
|
451
507
|
out.dataStart,
|
|
452
508
|
);
|
|
453
509
|
return rc == 0 ? out : new Uint8Array(0);
|
|
@@ -455,14 +511,14 @@ export namespace AuthService {
|
|
|
455
511
|
|
|
456
512
|
/** SHA-256 over `data` (ambient Web Crypto), for transcript/confirm hashing. */
|
|
457
513
|
export function sha256(data: Uint8Array): Uint8Array {
|
|
458
|
-
return crypto.subtle.digest(
|
|
514
|
+
return crypto.subtle.digest(ALG_SHA_256, data);
|
|
459
515
|
}
|
|
460
516
|
|
|
461
517
|
/** `SHA-256(serverKemPublicKey)` -- the key identity bound into the login
|
|
462
518
|
* message, so the signature commits to which server key the client
|
|
463
519
|
* encapsulated to. The client computes the same hash over its pinned key. */
|
|
464
520
|
export function serverKemKeyId(): Uint8Array {
|
|
465
|
-
return sha256(
|
|
521
|
+
return sha256(__resolveServerKemPk());
|
|
466
522
|
}
|
|
467
523
|
|
|
468
524
|
/** Domain separators for the session-key derivation and confirmation tag. */
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
HmacImportParams,
|
|
25
25
|
HmacParams,
|
|
26
26
|
ALG_SHA_256,
|
|
27
|
+
FMT_RAW,
|
|
27
28
|
USAGE_SIGN,
|
|
28
29
|
USAGE_VERIFY,
|
|
29
30
|
} from 'crypto';
|
|
@@ -45,7 +46,7 @@ const TWOFA_VERSION: u8 = 1;
|
|
|
45
46
|
|
|
46
47
|
function importHmac(key: Uint8Array): CryptoKey {
|
|
47
48
|
return crypto.subtle.importKey(
|
|
48
|
-
|
|
49
|
+
FMT_RAW,
|
|
49
50
|
key,
|
|
50
51
|
new HmacImportParams(ALG_SHA_256),
|
|
51
52
|
false,
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
HmacParams,
|
|
31
31
|
ALG_AES_GCM,
|
|
32
32
|
ALG_SHA_256,
|
|
33
|
+
FMT_RAW,
|
|
33
34
|
USAGE_SIGN,
|
|
34
35
|
USAGE_VERIFY,
|
|
35
36
|
USAGE_ENCRYPT,
|
|
@@ -104,7 +105,7 @@ export class SecureCookies {
|
|
|
104
105
|
|
|
105
106
|
private importHmac(key: Uint8Array): CryptoKey {
|
|
106
107
|
return crypto.subtle.importKey(
|
|
107
|
-
|
|
108
|
+
FMT_RAW,
|
|
108
109
|
key,
|
|
109
110
|
new HmacImportParams(ALG_SHA_256),
|
|
110
111
|
false,
|
|
@@ -114,7 +115,7 @@ export class SecureCookies {
|
|
|
114
115
|
|
|
115
116
|
private importAes(key: Uint8Array): CryptoKey {
|
|
116
117
|
return crypto.subtle.importKey(
|
|
117
|
-
|
|
118
|
+
FMT_RAW,
|
|
118
119
|
key,
|
|
119
120
|
new AesKeyParams(),
|
|
120
121
|
false,
|