toilscript 0.1.15 → 0.1.17
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/dist/cli.js +756 -17
- package/dist/cli.js.map +2 -2
- package/dist/importmap.json +2 -2
- package/dist/toilscript.js +32 -13
- package/dist/toilscript.js.map +3 -3
- package/dist/web.js +3 -3
- package/package.json +1 -1
- package/std/assembly/bindings/dom.ts +2 -9
- package/std/assembly/bindings/webcrypto.ts +106 -0
- package/std/assembly/crypto/algorithms.ts +316 -0
- package/std/assembly/crypto/key.ts +38 -0
- package/std/assembly/crypto/subtle.ts +151 -0
- package/std/assembly/crypto.ts +139 -4
package/std/assembly/crypto.ts
CHANGED
|
@@ -1,9 +1,144 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// Web Crypto for ToilScript — a synchronous SubtleCrypto plus ergonomic
|
|
2
|
+
// helpers, backed by metered host functions (see `bindings/webcrypto.ts` and
|
|
3
|
+
// the toil-backend `crypto` host module).
|
|
4
|
+
//
|
|
5
|
+
// Deviations from the web spec (ToilScript has no Promises): every method is
|
|
6
|
+
// synchronous and returns its value directly. Algorithm parameters are small
|
|
7
|
+
// classes (e.g. `AesGcmParams`) rather than object literals, and key usages are
|
|
8
|
+
// an i32 bitmask. RSA, on-host key generation, and the `jwk` format are not
|
|
9
|
+
// provided (RSA was dropped for an unfixable timing side-channel in the only
|
|
10
|
+
// pure-Rust implementation; keys are imported, never generated on-host).
|
|
11
|
+
|
|
12
|
+
import { webcrypto } from "bindings/webcrypto";
|
|
13
|
+
import { SubtleCrypto } from "crypto/subtle";
|
|
14
|
+
import { HmacImportParams, HmacParams, ALG_SHA_256, USAGE_SIGN } from "crypto/algorithms";
|
|
15
|
+
import { Encoding } from "encoding";
|
|
16
|
+
|
|
17
|
+
// Re-export the public surface so guests can import everything from "crypto".
|
|
18
|
+
export { SubtleCrypto } from "./crypto/subtle";
|
|
19
|
+
export { CryptoKey, CryptoKeyPair } from "./crypto/key";
|
|
20
|
+
export {
|
|
21
|
+
AlgorithmParams,
|
|
22
|
+
AesGcmParams,
|
|
23
|
+
AesCbcParams,
|
|
24
|
+
AesCtrParams,
|
|
25
|
+
HmacImportParams,
|
|
26
|
+
HmacParams,
|
|
27
|
+
Pbkdf2Params,
|
|
28
|
+
HkdfParams,
|
|
29
|
+
EcdsaParams,
|
|
30
|
+
EcKeyImportParams,
|
|
31
|
+
Ed25519Params,
|
|
32
|
+
X25519ImportParams,
|
|
33
|
+
EcdhParams,
|
|
34
|
+
algId,
|
|
35
|
+
algName,
|
|
36
|
+
formatId,
|
|
37
|
+
curveId,
|
|
38
|
+
cryptoError,
|
|
39
|
+
ALG_SHA_1,
|
|
40
|
+
ALG_SHA_256,
|
|
41
|
+
ALG_SHA_384,
|
|
42
|
+
ALG_SHA_512,
|
|
43
|
+
ALG_AES_GCM,
|
|
44
|
+
ALG_AES_CBC,
|
|
45
|
+
ALG_AES_CTR,
|
|
46
|
+
ALG_AES_KW,
|
|
47
|
+
ALG_HMAC,
|
|
48
|
+
ALG_ECDSA,
|
|
49
|
+
ALG_ED25519,
|
|
50
|
+
ALG_ECDH,
|
|
51
|
+
ALG_X25519,
|
|
52
|
+
ALG_HKDF,
|
|
53
|
+
ALG_PBKDF2,
|
|
54
|
+
CURVE_P256,
|
|
55
|
+
CURVE_P384,
|
|
56
|
+
USAGE_ENCRYPT,
|
|
57
|
+
USAGE_DECRYPT,
|
|
58
|
+
USAGE_SIGN,
|
|
59
|
+
USAGE_VERIFY,
|
|
60
|
+
USAGE_DERIVE_KEY,
|
|
61
|
+
USAGE_DERIVE_BITS,
|
|
62
|
+
USAGE_WRAP_KEY,
|
|
63
|
+
USAGE_UNWRAP_KEY,
|
|
64
|
+
} from "./crypto/algorithms";
|
|
65
|
+
|
|
66
|
+
function utf8Bytes(s: string): Uint8Array {
|
|
67
|
+
return Uint8Array.wrap(String.UTF8.encode(s));
|
|
68
|
+
}
|
|
4
69
|
|
|
5
70
|
export namespace crypto {
|
|
71
|
+
/// The synchronous SubtleCrypto singleton.
|
|
72
|
+
export const subtle: SubtleCrypto = new SubtleCrypto();
|
|
73
|
+
|
|
74
|
+
/// Fill `array` with cryptographically strong random bytes.
|
|
6
75
|
export function getRandomValues(array: Uint8Array): void {
|
|
7
|
-
|
|
76
|
+
webcrypto.fillRandom(array.dataStart, array.byteLength);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// An RFC 4122 version-4 UUID string.
|
|
80
|
+
export function randomUUID(): string {
|
|
81
|
+
let b = new Uint8Array(16);
|
|
82
|
+
webcrypto.randomUuid(b.dataStart);
|
|
83
|
+
b[6] = (b[6] & 0x0f) | 0x40; // version 4
|
|
84
|
+
b[8] = (b[8] & 0x3f) | 0x80; // variant 10
|
|
85
|
+
let h = toHex(b);
|
|
86
|
+
return (
|
|
87
|
+
h.substring(0, 8) +
|
|
88
|
+
"-" +
|
|
89
|
+
h.substring(8, 12) +
|
|
90
|
+
"-" +
|
|
91
|
+
h.substring(12, 16) +
|
|
92
|
+
"-" +
|
|
93
|
+
h.substring(16, 20) +
|
|
94
|
+
"-" +
|
|
95
|
+
h.substring(20, 32)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// --- Ergonomic digest helpers (thin wrappers over subtle.digest) ----------
|
|
100
|
+
export function sha1(data: Uint8Array): Uint8Array {
|
|
101
|
+
return subtle.digest("SHA-1", data);
|
|
102
|
+
}
|
|
103
|
+
export function sha256(data: Uint8Array): Uint8Array {
|
|
104
|
+
return subtle.digest("SHA-256", data);
|
|
105
|
+
}
|
|
106
|
+
export function sha384(data: Uint8Array): Uint8Array {
|
|
107
|
+
return subtle.digest("SHA-384", data);
|
|
108
|
+
}
|
|
109
|
+
export function sha512(data: Uint8Array): Uint8Array {
|
|
110
|
+
return subtle.digest("SHA-512", data);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// String-input variants (UTF-8 encode, then hash).
|
|
114
|
+
export function sha1Text(s: string): Uint8Array {
|
|
115
|
+
return sha1(utf8Bytes(s));
|
|
116
|
+
}
|
|
117
|
+
export function sha256Text(s: string): Uint8Array {
|
|
118
|
+
return sha256(utf8Bytes(s));
|
|
119
|
+
}
|
|
120
|
+
export function sha384Text(s: string): Uint8Array {
|
|
121
|
+
return sha384(utf8Bytes(s));
|
|
122
|
+
}
|
|
123
|
+
export function sha512Text(s: string): Uint8Array {
|
|
124
|
+
return sha512(utf8Bytes(s));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/// One-shot HMAC-SHA-256 over raw key + message bytes.
|
|
128
|
+
export function hmacSha256(key: Uint8Array, msg: Uint8Array): Uint8Array {
|
|
129
|
+
let k = subtle.importKey("raw", key, new HmacImportParams(ALG_SHA_256), false, USAGE_SIGN);
|
|
130
|
+
return subtle.sign(new HmacParams(), k, msg);
|
|
131
|
+
}
|
|
132
|
+
export function hmacSha256Text(key: Uint8Array, msg: string): Uint8Array {
|
|
133
|
+
return hmacSha256(key, utf8Bytes(msg));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/// Lowercase hex string of `bytes` (handy for displaying digests).
|
|
137
|
+
export function toHex(bytes: Uint8Array): string {
|
|
138
|
+
let hexLen = bytes.length * 2;
|
|
139
|
+
if (hexLen == 0) return "";
|
|
140
|
+
let dst = new Uint8Array(hexLen);
|
|
141
|
+
Encoding.Hex.encode(bytes.dataStart, bytes.length, dst.dataStart);
|
|
142
|
+
return String.UTF8.decode(dst.buffer);
|
|
8
143
|
}
|
|
9
144
|
}
|