@yielded/jose 0.1.0-beta.29 → 0.1.0-beta.31
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 +1 -1
- package/dist/Jwk.d.mts +156 -0
- package/dist/Jwk.mjs +86 -1
- package/dist/Jwk.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Jwk.ts +103 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ application Schema. Schema encoding/decoding failures and services remain in
|
|
|
20
20
|
`E` and `R`; custom Schema diagnostics remain application-owned.
|
|
21
21
|
`Jwt.decodeUnverified` only parses and never establishes trust.
|
|
22
22
|
|
|
23
|
-
The
|
|
23
|
+
The supported profile is compact JWS/JWT with HS256, RS256, PS256, ES256 and EdDSA
|
|
24
24
|
(Ed25519), and compact JWE with `dir` / `A256GCM`. Other algorithms, JSON
|
|
25
25
|
serialization, unencoded/detached payloads, critical extensions and compression
|
|
26
26
|
are unsupported. OAuth, discovery, sessions and account authority belong to
|
package/dist/Jwk.d.mts
CHANGED
|
@@ -84,6 +84,85 @@ export declare const SecretJwk: Schema.Struct<{
|
|
|
84
84
|
readonly k: Schema.String;
|
|
85
85
|
}>;
|
|
86
86
|
export type SecretJwk = typeof SecretJwk.Type;
|
|
87
|
+
export declare const GenerateKeyPairInput: Schema.Union<readonly [Schema.Struct<{
|
|
88
|
+
readonly algorithm: Schema.Literals<readonly ["RS256", "PS256"]>;
|
|
89
|
+
readonly modulusLength: Schema.optionalKey<Schema.Literals<readonly [2048, 3072, 4096]>>;
|
|
90
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
91
|
+
}>, Schema.Struct<{
|
|
92
|
+
readonly algorithm: Schema.Literals<readonly ["ES256", "EdDSA"]>;
|
|
93
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
94
|
+
}>]>;
|
|
95
|
+
export type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;
|
|
96
|
+
export declare const GeneratedKeyPair: Schema.Struct<{
|
|
97
|
+
readonly publicKey: Schema.Union<readonly [Schema.Struct<{
|
|
98
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
99
|
+
readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
|
|
100
|
+
readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
|
|
101
|
+
readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
|
|
102
|
+
readonly kty: Schema.Literal<"RSA">;
|
|
103
|
+
readonly n: Schema.String;
|
|
104
|
+
readonly e: Schema.String;
|
|
105
|
+
readonly d: Schema.optionalKey<Schema.Never>;
|
|
106
|
+
readonly k: Schema.optionalKey<Schema.Never>;
|
|
107
|
+
}>, Schema.Struct<{
|
|
108
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
109
|
+
readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
|
|
110
|
+
readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
|
|
111
|
+
readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
|
|
112
|
+
readonly kty: Schema.Literal<"EC">;
|
|
113
|
+
readonly crv: Schema.Literal<"P-256">;
|
|
114
|
+
readonly x: Schema.String;
|
|
115
|
+
readonly y: Schema.String;
|
|
116
|
+
readonly d: Schema.optionalKey<Schema.Never>;
|
|
117
|
+
readonly k: Schema.optionalKey<Schema.Never>;
|
|
118
|
+
}>, Schema.Struct<{
|
|
119
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
120
|
+
readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
|
|
121
|
+
readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
|
|
122
|
+
readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
|
|
123
|
+
readonly kty: Schema.Literal<"OKP">;
|
|
124
|
+
readonly crv: Schema.Literal<"Ed25519">;
|
|
125
|
+
readonly x: Schema.String;
|
|
126
|
+
readonly d: Schema.optionalKey<Schema.Never>;
|
|
127
|
+
readonly k: Schema.optionalKey<Schema.Never>;
|
|
128
|
+
}>]>;
|
|
129
|
+
readonly privateKey: Schema.Redacted<Schema.Union<readonly [Schema.Struct<{
|
|
130
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
131
|
+
readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
|
|
132
|
+
readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
|
|
133
|
+
readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
|
|
134
|
+
readonly kty: Schema.Literal<"RSA">;
|
|
135
|
+
readonly n: Schema.String;
|
|
136
|
+
readonly e: Schema.String;
|
|
137
|
+
readonly d: Schema.String;
|
|
138
|
+
readonly p: Schema.String;
|
|
139
|
+
readonly q: Schema.String;
|
|
140
|
+
readonly dp: Schema.String;
|
|
141
|
+
readonly dq: Schema.String;
|
|
142
|
+
readonly qi: Schema.String;
|
|
143
|
+
readonly oth: Schema.optionalKey<Schema.Never>;
|
|
144
|
+
}>, Schema.Struct<{
|
|
145
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
146
|
+
readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
|
|
147
|
+
readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
|
|
148
|
+
readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
|
|
149
|
+
readonly kty: Schema.Literal<"EC">;
|
|
150
|
+
readonly crv: Schema.Literal<"P-256">;
|
|
151
|
+
readonly x: Schema.String;
|
|
152
|
+
readonly y: Schema.String;
|
|
153
|
+
readonly d: Schema.String;
|
|
154
|
+
}>, Schema.Struct<{
|
|
155
|
+
readonly kid: Schema.optionalKey<Schema.String>;
|
|
156
|
+
readonly alg: Schema.optionalKey<Schema.NonEmptyString>;
|
|
157
|
+
readonly use: Schema.optionalKey<Schema.Literals<readonly ["sig", "enc"]>>;
|
|
158
|
+
readonly key_ops: Schema.optionalKey<Schema.$Array<Schema.NonEmptyString>>;
|
|
159
|
+
readonly kty: Schema.Literal<"OKP">;
|
|
160
|
+
readonly crv: Schema.Literal<"Ed25519">;
|
|
161
|
+
readonly x: Schema.String;
|
|
162
|
+
readonly d: Schema.String;
|
|
163
|
+
}>]>>;
|
|
164
|
+
}>;
|
|
165
|
+
export type GeneratedKeyPair = typeof GeneratedKeyPair.Type;
|
|
87
166
|
/** Validated, algorithm-bound key snapshots. Private material remains Redacted. */
|
|
88
167
|
export interface PublicKey {
|
|
89
168
|
readonly _tag: "PublicKey";
|
|
@@ -105,6 +184,83 @@ export interface SecretKey {
|
|
|
105
184
|
}
|
|
106
185
|
export type SigningKey = PrivateKey | SecretKey;
|
|
107
186
|
export type VerificationKey = PublicKey | SecretKey;
|
|
187
|
+
/** Generate typed signing JWKs through the selected crypto backend. */
|
|
188
|
+
export declare const generateKeyPair: (input: {
|
|
189
|
+
readonly algorithm: "PS256" | "RS256";
|
|
190
|
+
readonly modulusLength?: 2048 | 3072 | 4096;
|
|
191
|
+
readonly kid?: string;
|
|
192
|
+
} | {
|
|
193
|
+
readonly algorithm: "ES256" | "EdDSA";
|
|
194
|
+
readonly kid?: string;
|
|
195
|
+
}) => Effect.Effect<{
|
|
196
|
+
readonly publicKey: {
|
|
197
|
+
readonly kid?: string;
|
|
198
|
+
readonly alg?: string;
|
|
199
|
+
readonly use?: "enc" | "sig";
|
|
200
|
+
readonly key_ops?: readonly string[];
|
|
201
|
+
readonly kty: "RSA";
|
|
202
|
+
readonly n: string;
|
|
203
|
+
readonly e: string;
|
|
204
|
+
readonly d?: never;
|
|
205
|
+
readonly k?: never;
|
|
206
|
+
} | {
|
|
207
|
+
readonly kid?: string;
|
|
208
|
+
readonly alg?: string;
|
|
209
|
+
readonly use?: "enc" | "sig";
|
|
210
|
+
readonly key_ops?: readonly string[];
|
|
211
|
+
readonly kty: "EC";
|
|
212
|
+
readonly crv: "P-256";
|
|
213
|
+
readonly x: string;
|
|
214
|
+
readonly y: string;
|
|
215
|
+
readonly d?: never;
|
|
216
|
+
readonly k?: never;
|
|
217
|
+
} | {
|
|
218
|
+
readonly kid?: string;
|
|
219
|
+
readonly alg?: string;
|
|
220
|
+
readonly use?: "enc" | "sig";
|
|
221
|
+
readonly key_ops?: readonly string[];
|
|
222
|
+
readonly kty: "OKP";
|
|
223
|
+
readonly crv: "Ed25519";
|
|
224
|
+
readonly x: string;
|
|
225
|
+
readonly d?: never;
|
|
226
|
+
readonly k?: never;
|
|
227
|
+
};
|
|
228
|
+
readonly privateKey: Redacted.Redacted<{
|
|
229
|
+
readonly kid?: string;
|
|
230
|
+
readonly alg?: string;
|
|
231
|
+
readonly use?: "enc" | "sig";
|
|
232
|
+
readonly key_ops?: readonly string[];
|
|
233
|
+
readonly kty: "RSA";
|
|
234
|
+
readonly n: string;
|
|
235
|
+
readonly e: string;
|
|
236
|
+
readonly d: string;
|
|
237
|
+
readonly p: string;
|
|
238
|
+
readonly q: string;
|
|
239
|
+
readonly dp: string;
|
|
240
|
+
readonly dq: string;
|
|
241
|
+
readonly qi: string;
|
|
242
|
+
readonly oth?: never;
|
|
243
|
+
} | {
|
|
244
|
+
readonly kid?: string;
|
|
245
|
+
readonly alg?: string;
|
|
246
|
+
readonly use?: "enc" | "sig";
|
|
247
|
+
readonly key_ops?: readonly string[];
|
|
248
|
+
readonly kty: "EC";
|
|
249
|
+
readonly crv: "P-256";
|
|
250
|
+
readonly x: string;
|
|
251
|
+
readonly y: string;
|
|
252
|
+
readonly d: string;
|
|
253
|
+
} | {
|
|
254
|
+
readonly kid?: string;
|
|
255
|
+
readonly alg?: string;
|
|
256
|
+
readonly use?: "enc" | "sig";
|
|
257
|
+
readonly key_ops?: readonly string[];
|
|
258
|
+
readonly kty: "OKP";
|
|
259
|
+
readonly crv: "Ed25519";
|
|
260
|
+
readonly x: string;
|
|
261
|
+
readonly d: string;
|
|
262
|
+
}>;
|
|
263
|
+
}, InvalidKey | import("@yielded/crypto/Errors").OperationError, Signature$1.Signature>;
|
|
108
264
|
export declare const importPublic: (input: unknown, selected: "ES256" | "EdDSA" | "PS256" | "RS256") => Effect.Effect<Readonly<{
|
|
109
265
|
_tag: "PublicKey";
|
|
110
266
|
algorithm: "ES256" | "EdDSA" | "PS256" | "RS256";
|
package/dist/Jwk.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { decode, reveal } from "./internal/encoding.mjs";
|
|
|
4
4
|
import { detach, jwk } from "./internal/keyInput.mjs";
|
|
5
5
|
import { Effect, Redacted, Schema } from "effect";
|
|
6
6
|
import * as Signature$1 from "@yielded/crypto/Signature";
|
|
7
|
+
import { Base64Url } from "effect/encoding";
|
|
7
8
|
//#region src/Jwk.ts
|
|
8
9
|
const AsymmetricAlgorithm = Schema.Literals([
|
|
9
10
|
"RS256",
|
|
@@ -88,6 +89,90 @@ const SecretJwk = Schema.Struct({
|
|
|
88
89
|
kty: Schema.Literal("oct"),
|
|
89
90
|
k: encodedBytes
|
|
90
91
|
});
|
|
92
|
+
const GenerateKeyPairInput = Schema.Union([Schema.Struct({
|
|
93
|
+
algorithm: Schema.Literals(["RS256", "PS256"]),
|
|
94
|
+
modulusLength: Schema.optionalKey(Signature$1.RsaModulusLength),
|
|
95
|
+
kid: metadata.kid
|
|
96
|
+
}), Schema.Struct({
|
|
97
|
+
algorithm: Schema.Literals(["ES256", "EdDSA"]),
|
|
98
|
+
kid: metadata.kid
|
|
99
|
+
})]);
|
|
100
|
+
const GeneratedKeyPair = Schema.Struct({
|
|
101
|
+
publicKey: PublicJwk,
|
|
102
|
+
privateKey: Schema.Redacted(PrivateJwk, { disallowJsonEncode: true })
|
|
103
|
+
});
|
|
104
|
+
/** Generate typed signing JWKs through the selected crypto backend. */
|
|
105
|
+
const generateKeyPair = Effect.fnUntraced(function* (input) {
|
|
106
|
+
const value = yield* Schema.decodeEffect(GenerateKeyPairInput)(input).pipe(Effect.mapError(() => InvalidKey.make({})));
|
|
107
|
+
const signatures = yield* Signature$1.Signature;
|
|
108
|
+
return yield* Effect.acquireUseRelease(signatures.generateKeyPair({
|
|
109
|
+
algorithm: algorithms[value.algorithm],
|
|
110
|
+
..."modulusLength" in value ? { modulusLength: value.modulusLength } : {}
|
|
111
|
+
}), (pair) => Effect.sync(() => {
|
|
112
|
+
const parameters = Redacted.value(pair.privateKey);
|
|
113
|
+
const meta = {
|
|
114
|
+
alg: value.algorithm,
|
|
115
|
+
use: "sig",
|
|
116
|
+
...value.kid === void 0 ? {} : { kid: value.kid }
|
|
117
|
+
};
|
|
118
|
+
switch (parameters.algorithm) {
|
|
119
|
+
case "RSASSA-PKCS1-v1_5-SHA256":
|
|
120
|
+
case "RSA-PSS-SHA256": {
|
|
121
|
+
const publicKey = {
|
|
122
|
+
...meta,
|
|
123
|
+
kty: "RSA",
|
|
124
|
+
n: Base64Url.encode(parameters.n),
|
|
125
|
+
e: Base64Url.encode(parameters.e)
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
publicKey,
|
|
129
|
+
privateKey: Redacted.make({
|
|
130
|
+
...publicKey,
|
|
131
|
+
d: Base64Url.encode(parameters.d),
|
|
132
|
+
p: Base64Url.encode(parameters.p),
|
|
133
|
+
q: Base64Url.encode(parameters.q),
|
|
134
|
+
dp: Base64Url.encode(parameters.dp),
|
|
135
|
+
dq: Base64Url.encode(parameters.dq),
|
|
136
|
+
qi: Base64Url.encode(parameters.qi)
|
|
137
|
+
})
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
case "ECDSA-P256-SHA256": {
|
|
141
|
+
const publicKey = {
|
|
142
|
+
...meta,
|
|
143
|
+
kty: "EC",
|
|
144
|
+
crv: "P-256",
|
|
145
|
+
x: Base64Url.encode(parameters.x),
|
|
146
|
+
y: Base64Url.encode(parameters.y)
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
publicKey,
|
|
150
|
+
privateKey: Redacted.make({
|
|
151
|
+
...publicKey,
|
|
152
|
+
d: Base64Url.encode(parameters.d)
|
|
153
|
+
})
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
case "Ed25519": {
|
|
157
|
+
const publicKey = {
|
|
158
|
+
...meta,
|
|
159
|
+
kty: "OKP",
|
|
160
|
+
crv: "Ed25519",
|
|
161
|
+
x: Base64Url.encode(parameters.x)
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
publicKey,
|
|
165
|
+
privateKey: Redacted.make({
|
|
166
|
+
...publicKey,
|
|
167
|
+
d: Base64Url.encode(parameters.d)
|
|
168
|
+
})
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}), (pair) => Effect.sync(() => {
|
|
173
|
+
for (const part of Object.values(Redacted.value(pair.privateKey))) if (typeof part !== "string") part.fill(0);
|
|
174
|
+
}));
|
|
175
|
+
});
|
|
91
176
|
const read = (schema, input) => Effect.try({
|
|
92
177
|
try: () => jwk(input),
|
|
93
178
|
catch: () => InvalidKey.make({})
|
|
@@ -190,6 +275,6 @@ const exportPrivate = Effect.fnUntraced(function* (key) {
|
|
|
190
275
|
return Redacted.make(yield* read(Schema.Union([PrivateJwk, SecretJwk]), value));
|
|
191
276
|
});
|
|
192
277
|
//#endregion
|
|
193
|
-
export { Algorithm, AsymmetricAlgorithm, PrivateJwk, PublicJwk, SecretJwk, exportPrivate, exportPublic, importPrivate, importPublic, importSecret };
|
|
278
|
+
export { Algorithm, AsymmetricAlgorithm, GenerateKeyPairInput, GeneratedKeyPair, PrivateJwk, PublicJwk, SecretJwk, exportPrivate, exportPublic, generateKeyPair, importPrivate, importPublic, importSecret };
|
|
194
279
|
|
|
195
280
|
//# sourceMappingURL=Jwk.mjs.map
|
package/dist/Jwk.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Jwk.mjs","names":["KeyInput.jwk","KeyInput.detach","Signature"],"sources":["../src/Jwk.ts"],"sourcesContent":["import * as Signature from \"@yielded/crypto/Signature\";\nimport { Effect, Redacted, Schema } from \"effect\";\n\nimport { InvalidKey } from \"./Errors\";\nimport { algorithms } from \"./internal/algorithms\";\nimport { decode, reveal } from \"./internal/encoding\";\nimport * as KeyInput from \"./internal/keyInput\";\n\nexport const AsymmetricAlgorithm = Schema.Literals([\"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type AsymmetricAlgorithm = typeof AsymmetricAlgorithm.Type;\nexport const Algorithm = Schema.Literals([\"HS256\", \"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type Algorithm = typeof Algorithm.Type;\n\nconst encodedBytes = Schema.String.check(\n Schema.isPattern(/^[A-Za-z0-9_-]+$/),\n Schema.isMaxLength(16384),\n);\n\nconst operations = Schema.Array(Schema.NonEmptyString).check(\n Schema.isMaxLength(KeyInput.maxArrayLength),\n Schema.makeFilter((values) => new Set(values).size === values.length),\n);\n\nconst metadata = {\n kid: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(256))),\n alg: Schema.optionalKey(Schema.NonEmptyString),\n use: Schema.optionalKey(Schema.Literals([\"sig\", \"enc\"])),\n key_ops: Schema.optionalKey(operations),\n};\n\nconst rsa = { ...metadata, kty: Schema.Literal(\"RSA\"), n: encodedBytes, e: encodedBytes };\n\nconst ec = {\n ...metadata,\n kty: Schema.Literal(\"EC\"),\n crv: Schema.Literal(\"P-256\"),\n x: encodedBytes,\n y: encodedBytes,\n};\n\nconst okp = {\n ...metadata,\n kty: Schema.Literal(\"OKP\"),\n crv: Schema.Literal(\"Ed25519\"),\n x: encodedBytes,\n};\n\nconst noSecret = { d: Schema.optionalKey(Schema.Never), k: Schema.optionalKey(Schema.Never) };\n\nexport const PublicJwk = Schema.Union([\n Schema.Struct({ ...rsa, ...noSecret }),\n Schema.Struct({ ...ec, ...noSecret }),\n Schema.Struct({ ...okp, ...noSecret }),\n]);\n\nexport type PublicJwk = typeof PublicJwk.Type;\n\nexport const PrivateJwk = Schema.Union([\n Schema.Struct({\n ...rsa,\n d: encodedBytes,\n p: encodedBytes,\n q: encodedBytes,\n dp: encodedBytes,\n dq: encodedBytes,\n qi: encodedBytes,\n oth: Schema.optionalKey(Schema.Never),\n }),\n Schema.Struct({ ...ec, d: encodedBytes }),\n Schema.Struct({ ...okp, d: encodedBytes }),\n]);\n\nexport type PrivateJwk = typeof PrivateJwk.Type;\n\nexport const SecretJwk = Schema.Struct({\n ...metadata,\n kty: Schema.Literal(\"oct\"),\n k: encodedBytes,\n});\n\nexport type SecretJwk = typeof SecretJwk.Type;\n\n/** Validated, algorithm-bound key snapshots. Private material remains Redacted. */\nexport interface PublicKey {\n readonly _tag: \"PublicKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: PublicJwk;\n readonly material: Uint8Array;\n}\n\nexport interface PrivateKey {\n readonly _tag: \"PrivateKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: Redacted.Redacted<PrivateJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport interface SecretKey {\n readonly _tag: \"SecretKey\";\n readonly algorithm: \"HS256\" | \"dir\";\n readonly jwk: Redacted.Redacted<SecretJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport type SigningKey = PrivateKey | SecretKey;\nexport type VerificationKey = PublicKey | SecretKey;\n\nconst read = <S extends Schema.Constraint>(schema: S, input: unknown) =>\n Effect.try({\n try: () => KeyInput.jwk(input),\n catch: () => InvalidKey.make({}),\n }).pipe(\n Effect.flatMap(Effect.fromResult),\n Effect.flatMap((captured) =>\n Schema.decodeUnknownEffect(schema)(captured, { reportInput: false }).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n ),\n ),\n Effect.map(KeyInput.detach),\n );\n\nconst bytes = (value: string) => decode(value).pipe(Effect.mapError(() => InvalidKey.make({})));\n\nconst snapshot = <A extends PublicJwk | PrivateJwk | SecretJwk>(jwk: A): A => {\n if (jwk.key_ops !== undefined) Object.freeze(jwk.key_ops);\n\n return Object.freeze(jwk);\n};\n\nconst publicParameters = Effect.fnUntraced(function* (\n jwk: PublicJwk | PrivateJwk,\n algorithm: AsymmetricAlgorithm,\n): Effect.fn.Return<Signature.PublicKeyParameters, InvalidKey> {\n if (jwk.alg !== undefined && jwk.alg !== algorithm) return yield* InvalidKey.make({});\n switch (jwk.kty) {\n case \"EC\":\n if (algorithm !== \"ES256\") return yield* InvalidKey.make({});\n\n return { algorithm: \"ECDSA-P256-SHA256\", x: yield* bytes(jwk.x), y: yield* bytes(jwk.y) };\n case \"OKP\":\n if (algorithm !== \"EdDSA\") return yield* InvalidKey.make({});\n\n return { algorithm: \"Ed25519\", x: yield* bytes(jwk.x) };\n case \"RSA\":\n if (algorithm !== \"RS256\" && algorithm !== \"PS256\") return yield* InvalidKey.make({});\n\n return { algorithm: algorithms[algorithm], n: yield* bytes(jwk.n), e: yield* bytes(jwk.e) };\n }\n});\n\nexport const importPublic = Effect.fnUntraced(function* (\n input: unknown,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n const jwk = yield* read(PublicJwk, input);\n const parameters = yield* publicParameters(jwk, algorithm);\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures\n .encodePublicKey(parameters)\n .pipe(Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})));\n\n return Object.freeze({\n _tag: \"PublicKey\",\n algorithm,\n jwk: snapshot(jwk),\n material,\n }) satisfies PublicKey;\n});\n\nexport const importPrivate = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n\n const jwk = yield* read(\n PrivateJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const publicPart = yield* publicParameters(jwk, algorithm);\n const d = yield* bytes(jwk.d);\n\n const parameters = yield* read(Signature.PrivateKeyParameters, {\n ...publicPart,\n d,\n ...(jwk.kty === \"RSA\"\n ? {\n p: yield* bytes(jwk.p),\n q: yield* bytes(jwk.q),\n dp: yield* bytes(jwk.dp),\n dq: yield* bytes(jwk.dq),\n qi: yield* bytes(jwk.qi),\n }\n : {}),\n });\n\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures.encodePrivateKey(Redacted.make(parameters)).pipe(\n Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})),\n Effect.ensuring(\n Effect.sync(() => {\n parameters.d.fill(0);\n if (\"p\" in parameters)\n for (const part of [\n parameters.p,\n parameters.q,\n parameters.dp,\n parameters.dq,\n parameters.qi,\n ])\n part.fill(0);\n }),\n ),\n );\n\n return Object.freeze({\n _tag: \"PrivateKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material,\n }) satisfies PrivateKey;\n});\n\nexport const importSecret = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: \"HS256\" | \"dir\",\n) {\n const algorithm = yield* read(Schema.Literals([\"HS256\", \"dir\"]), selected);\n\n const jwk = yield* read(\n SecretJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const material = yield* bytes(jwk.k);\n\n if (\n (jwk.alg !== undefined && jwk.alg !== algorithm) ||\n material.length < 32 ||\n (algorithm === \"dir\" && material.length !== 32)\n ) {\n material.fill(0);\n\n return yield* InvalidKey.make({});\n }\n\n return Object.freeze({\n _tag: \"SecretKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material: Redacted.make(material),\n }) satisfies SecretKey;\n});\n\nexport const exportPublic = Effect.fnUntraced(function* (key: PublicKey) {\n return yield* read(PublicJwk, key.jwk);\n});\n\nexport const exportPrivate = Effect.fnUntraced(function* (key: PrivateKey | SecretKey) {\n const value = yield* reveal<PrivateJwk | SecretJwk>(key.jwk).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n );\n\n return Redacted.make(yield* read(Schema.Union([PrivateJwk, SecretJwk]), value));\n});\n"],"mappings":";;;;;;;AAQA,MAAa,sBAAsB,OAAO,SAAS;CAAC;CAAS;CAAS;CAAS;AAAO,CAAC;AAEvF,MAAa,YAAY,OAAO,SAAS;CAAC;CAAS;CAAS;CAAS;CAAS;AAAO,CAAC;AAGtF,MAAM,eAAe,OAAO,OAAO,MACjC,OAAO,UAAU,kBAAkB,GACnC,OAAO,YAAY,KAAK,CAC1B;AAEA,MAAM,aAAa,OAAO,MAAM,OAAO,cAAc,CAAC,CAAC,MACrD,OAAO,YAAY,GAAuB,GAC1C,OAAO,YAAY,WAAW,IAAI,IAAI,MAAM,CAAC,CAAC,SAAS,OAAO,MAAM,CACtE;AAEA,MAAM,WAAW;CACf,KAAK,OAAO,YAAY,OAAO,OAAO,MAAM,OAAO,YAAY,GAAG,CAAC,CAAC;CACpE,KAAK,OAAO,YAAY,OAAO,cAAc;CAC7C,KAAK,OAAO,YAAY,OAAO,SAAS,CAAC,OAAO,KAAK,CAAC,CAAC;CACvD,SAAS,OAAO,YAAY,UAAU;AACxC;AAEA,MAAM,MAAM;CAAE,GAAG;CAAU,KAAK,OAAO,QAAQ,KAAK;CAAG,GAAG;CAAc,GAAG;AAAa;AAExF,MAAM,KAAK;CACT,GAAG;CACH,KAAK,OAAO,QAAQ,IAAI;CACxB,KAAK,OAAO,QAAQ,OAAO;CAC3B,GAAG;CACH,GAAG;AACL;AAEA,MAAM,MAAM;CACV,GAAG;CACH,KAAK,OAAO,QAAQ,KAAK;CACzB,KAAK,OAAO,QAAQ,SAAS;CAC7B,GAAG;AACL;AAEA,MAAM,WAAW;CAAE,GAAG,OAAO,YAAY,OAAO,KAAK;CAAG,GAAG,OAAO,YAAY,OAAO,KAAK;AAAE;AAE5F,MAAa,YAAY,OAAO,MAAM;CACpC,OAAO,OAAO;EAAE,GAAG;EAAK,GAAG;CAAS,CAAC;CACrC,OAAO,OAAO;EAAE,GAAG;EAAI,GAAG;CAAS,CAAC;CACpC,OAAO,OAAO;EAAE,GAAG;EAAK,GAAG;CAAS,CAAC;AACvC,CAAC;AAID,MAAa,aAAa,OAAO,MAAM;CACrC,OAAO,OAAO;EACZ,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAG;EACH,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,KAAK,OAAO,YAAY,OAAO,KAAK;CACtC,CAAC;CACD,OAAO,OAAO;EAAE,GAAG;EAAI,GAAG;CAAa,CAAC;CACxC,OAAO,OAAO;EAAE,GAAG;EAAK,GAAG;CAAa,CAAC;AAC3C,CAAC;AAID,MAAa,YAAY,OAAO,OAAO;CACrC,GAAG;CACH,KAAK,OAAO,QAAQ,KAAK;CACzB,GAAG;AACL,CAAC;AA6BD,MAAM,QAAqC,QAAW,UACpD,OAAO,IAAI;CACT,WAAWA,IAAa,KAAK;CAC7B,aAAa,WAAW,KAAK,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC,KACD,OAAO,QAAQ,OAAO,UAAU,GAChC,OAAO,SAAS,aACd,OAAO,oBAAoB,MAAM,CAAC,CAAC,UAAU,EAAE,aAAa,MAAM,CAAC,CAAC,CAAC,KACnE,OAAO,eAAe,WAAW,KAAK,CAAC,CAAC,CAAC,CAC3C,CACF,GACA,OAAO,IAAIC,MAAe,CAC5B;AAEF,MAAM,SAAS,UAAkB,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,eAAe,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC;AAE9F,MAAM,YAA0D,QAAc;CAC5E,IAAI,IAAI,YAAY,KAAA,GAAW,OAAO,OAAO,IAAI,OAAO;CAExD,OAAO,OAAO,OAAO,GAAG;AAC1B;AAEA,MAAM,mBAAmB,OAAO,WAAW,WACzC,KACA,WAC6D;CAC7D,IAAI,IAAI,QAAQ,KAAA,KAAa,IAAI,QAAQ,WAAW,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC;CACpF,QAAQ,IAAI,KAAZ;EACE,KAAK;GACH,IAAI,cAAc,SAAS,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC;GAE3D,OAAO;IAAE,WAAW;IAAqB,GAAG,OAAO,MAAM,IAAI,CAAC;IAAG,GAAG,OAAO,MAAM,IAAI,CAAC;GAAE;EAC1F,KAAK;GACH,IAAI,cAAc,SAAS,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC;GAE3D,OAAO;IAAE,WAAW;IAAW,GAAG,OAAO,MAAM,IAAI,CAAC;GAAE;EACxD,KAAK;GACH,IAAI,cAAc,WAAW,cAAc,SAAS,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC;GAEpF,OAAO;IAAE,WAAW,WAAW;IAAY,GAAG,OAAO,MAAM,IAAI,CAAC;IAAG,GAAG,OAAO,MAAM,IAAI,CAAC;GAAE;CAC9F;AACF,CAAC;AAED,MAAa,eAAe,OAAO,WAAW,WAC5C,OACA,UACA;CACA,MAAM,YAAY,OAAO,KAAK,qBAAqB,QAAQ;CAC3D,MAAM,MAAM,OAAO,KAAK,WAAW,KAAK;CACxC,MAAM,aAAa,OAAO,iBAAiB,KAAK,SAAS;CAGzD,MAAM,WAAW,QAAO,OAFEC,YAAU,UAAA,CAGjC,gBAAgB,UAAU,CAAC,CAC3B,KAAK,OAAO,SAAS,4BAA4B,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC;CAExE,OAAO,OAAO,OAAO;EACnB,MAAM;EACN;EACA,KAAK,SAAS,GAAG;EACjB;CACF,CAAC;AACH,CAAC;AAED,MAAa,gBAAgB,OAAO,WAAW,WAC7C,OACA,UACA;CACA,MAAM,YAAY,OAAO,KAAK,qBAAqB,QAAQ;CAE3D,MAAM,MAAM,OAAO,KACjB,YACA,OAAO,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,eAAe,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CACtE;CAEA,MAAM,aAAa,OAAO,iBAAiB,KAAK,SAAS;CACzD,MAAM,IAAI,OAAO,MAAM,IAAI,CAAC;CAE5B,MAAM,aAAa,OAAO,KAAKA,YAAU,sBAAsB;EAC7D,GAAG;EACH;EACA,GAAI,IAAI,QAAQ,QACZ;GACE,GAAG,OAAO,MAAM,IAAI,CAAC;GACrB,GAAG,OAAO,MAAM,IAAI,CAAC;GACrB,IAAI,OAAO,MAAM,IAAI,EAAE;GACvB,IAAI,OAAO,MAAM,IAAI,EAAE;GACvB,IAAI,OAAO,MAAM,IAAI,EAAE;EACzB,IACA,CAAC;CACP,CAAC;CAID,MAAM,WAAW,QAAO,OAFEA,YAAU,UAAA,CAED,iBAAiB,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,KAC7E,OAAO,SAAS,4BAA4B,WAAW,KAAK,CAAC,CAAC,CAAC,GAC/D,OAAO,SACL,OAAO,WAAW;EAChB,WAAW,EAAE,KAAK,CAAC;EACnB,IAAI,OAAO,YACT,KAAK,MAAM,QAAQ;GACjB,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;EACb,GACE,KAAK,KAAK,CAAC;CACjB,CAAC,CACH,CACF;CAEA,OAAO,OAAO,OAAO;EACnB,MAAM;EACN;EACA,KAAK,SAAS,KAAK,SAAS,GAAG,CAAC;EAChC;CACF,CAAC;AACH,CAAC;AAED,MAAa,eAAe,OAAO,WAAW,WAC5C,OACA,UACA;CACA,MAAM,YAAY,OAAO,KAAK,OAAO,SAAS,CAAC,SAAS,KAAK,CAAC,GAAG,QAAQ;CAEzE,MAAM,MAAM,OAAO,KACjB,WACA,OAAO,OAAO,KAAK,CAAC,CAAC,KAAK,OAAO,eAAe,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CACtE;CAEA,MAAM,WAAW,OAAO,MAAM,IAAI,CAAC;CAEnC,IACG,IAAI,QAAQ,KAAA,KAAa,IAAI,QAAQ,aACtC,SAAS,SAAS,MACjB,cAAc,SAAS,SAAS,WAAW,IAC5C;EACA,SAAS,KAAK,CAAC;EAEf,OAAO,OAAO,WAAW,KAAK,CAAC,CAAC;CAClC;CAEA,OAAO,OAAO,OAAO;EACnB,MAAM;EACN;EACA,KAAK,SAAS,KAAK,SAAS,GAAG,CAAC;EAChC,UAAU,SAAS,KAAK,QAAQ;CAClC,CAAC;AACH,CAAC;AAED,MAAa,eAAe,OAAO,WAAW,WAAW,KAAgB;CACvE,OAAO,OAAO,KAAK,WAAW,IAAI,GAAG;AACvC,CAAC;AAED,MAAa,gBAAgB,OAAO,WAAW,WAAW,KAA6B;CACrF,MAAM,QAAQ,OAAO,OAA+B,IAAI,GAAG,CAAC,CAAC,KAC3D,OAAO,eAAe,WAAW,KAAK,CAAC,CAAC,CAAC,CAC3C;CAEA,OAAO,SAAS,KAAK,OAAO,KAAK,OAAO,MAAM,CAAC,YAAY,SAAS,CAAC,GAAG,KAAK,CAAC;AAChF,CAAC"}
|
|
1
|
+
{"version":3,"file":"Jwk.mjs","names":["Signature","KeyInput.jwk","KeyInput.detach"],"sources":["../src/Jwk.ts"],"sourcesContent":["import * as Signature from \"@yielded/crypto/Signature\";\nimport { Effect, Redacted, Schema } from \"effect\";\nimport { Base64Url } from \"effect/encoding\";\n\nimport { InvalidKey } from \"./Errors\";\nimport { algorithms } from \"./internal/algorithms\";\nimport { decode, reveal } from \"./internal/encoding\";\nimport * as KeyInput from \"./internal/keyInput\";\n\nexport const AsymmetricAlgorithm = Schema.Literals([\"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type AsymmetricAlgorithm = typeof AsymmetricAlgorithm.Type;\nexport const Algorithm = Schema.Literals([\"HS256\", \"RS256\", \"PS256\", \"ES256\", \"EdDSA\"]);\nexport type Algorithm = typeof Algorithm.Type;\n\nconst encodedBytes = Schema.String.check(\n Schema.isPattern(/^[A-Za-z0-9_-]+$/),\n Schema.isMaxLength(16384),\n);\n\nconst operations = Schema.Array(Schema.NonEmptyString).check(\n Schema.isMaxLength(KeyInput.maxArrayLength),\n Schema.makeFilter((values) => new Set(values).size === values.length),\n);\n\nconst metadata = {\n kid: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(256))),\n alg: Schema.optionalKey(Schema.NonEmptyString),\n use: Schema.optionalKey(Schema.Literals([\"sig\", \"enc\"])),\n key_ops: Schema.optionalKey(operations),\n};\n\nconst rsa = { ...metadata, kty: Schema.Literal(\"RSA\"), n: encodedBytes, e: encodedBytes };\n\nconst ec = {\n ...metadata,\n kty: Schema.Literal(\"EC\"),\n crv: Schema.Literal(\"P-256\"),\n x: encodedBytes,\n y: encodedBytes,\n};\n\nconst okp = {\n ...metadata,\n kty: Schema.Literal(\"OKP\"),\n crv: Schema.Literal(\"Ed25519\"),\n x: encodedBytes,\n};\n\nconst noSecret = { d: Schema.optionalKey(Schema.Never), k: Schema.optionalKey(Schema.Never) };\n\nexport const PublicJwk = Schema.Union([\n Schema.Struct({ ...rsa, ...noSecret }),\n Schema.Struct({ ...ec, ...noSecret }),\n Schema.Struct({ ...okp, ...noSecret }),\n]);\n\nexport type PublicJwk = typeof PublicJwk.Type;\n\nexport const PrivateJwk = Schema.Union([\n Schema.Struct({\n ...rsa,\n d: encodedBytes,\n p: encodedBytes,\n q: encodedBytes,\n dp: encodedBytes,\n dq: encodedBytes,\n qi: encodedBytes,\n oth: Schema.optionalKey(Schema.Never),\n }),\n Schema.Struct({ ...ec, d: encodedBytes }),\n Schema.Struct({ ...okp, d: encodedBytes }),\n]);\n\nexport type PrivateJwk = typeof PrivateJwk.Type;\n\nexport const SecretJwk = Schema.Struct({\n ...metadata,\n kty: Schema.Literal(\"oct\"),\n k: encodedBytes,\n});\n\nexport type SecretJwk = typeof SecretJwk.Type;\n\nexport const GenerateKeyPairInput = Schema.Union([\n Schema.Struct({\n algorithm: Schema.Literals([\"RS256\", \"PS256\"]),\n modulusLength: Schema.optionalKey(Signature.RsaModulusLength),\n kid: metadata.kid,\n }),\n Schema.Struct({ algorithm: Schema.Literals([\"ES256\", \"EdDSA\"]), kid: metadata.kid }),\n]);\n\nexport type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;\n\nexport const GeneratedKeyPair = Schema.Struct({\n publicKey: PublicJwk,\n privateKey: Schema.Redacted(PrivateJwk, { disallowJsonEncode: true }),\n});\n\nexport type GeneratedKeyPair = typeof GeneratedKeyPair.Type;\n\n/** Validated, algorithm-bound key snapshots. Private material remains Redacted. */\nexport interface PublicKey {\n readonly _tag: \"PublicKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: PublicJwk;\n readonly material: Uint8Array;\n}\n\nexport interface PrivateKey {\n readonly _tag: \"PrivateKey\";\n readonly algorithm: AsymmetricAlgorithm;\n readonly jwk: Redacted.Redacted<PrivateJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport interface SecretKey {\n readonly _tag: \"SecretKey\";\n readonly algorithm: \"HS256\" | \"dir\";\n readonly jwk: Redacted.Redacted<SecretJwk>;\n readonly material: Redacted.Redacted<Uint8Array>;\n}\n\nexport type SigningKey = PrivateKey | SecretKey;\nexport type VerificationKey = PublicKey | SecretKey;\n\n/** Generate typed signing JWKs through the selected crypto backend. */\nexport const generateKeyPair = Effect.fnUntraced(function* (input: GenerateKeyPairInput) {\n const value = yield* Schema.decodeEffect(GenerateKeyPairInput)(input).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n );\n\n const signatures = yield* Signature.Signature;\n\n return yield* Effect.acquireUseRelease(\n signatures.generateKeyPair({\n algorithm: algorithms[value.algorithm],\n ...(\"modulusLength\" in value ? { modulusLength: value.modulusLength } : {}),\n }),\n (pair) =>\n Effect.sync((): GeneratedKeyPair => {\n const parameters = Redacted.value(pair.privateKey);\n\n const meta = {\n alg: value.algorithm,\n use: \"sig\" as const,\n ...(value.kid === undefined ? {} : { kid: value.kid }),\n };\n\n switch (parameters.algorithm) {\n case \"RSASSA-PKCS1-v1_5-SHA256\":\n case \"RSA-PSS-SHA256\": {\n const publicKey = {\n ...meta,\n kty: \"RSA\" as const,\n n: Base64Url.encode(parameters.n),\n e: Base64Url.encode(parameters.e),\n };\n\n return {\n publicKey,\n privateKey: Redacted.make({\n ...publicKey,\n d: Base64Url.encode(parameters.d),\n p: Base64Url.encode(parameters.p),\n q: Base64Url.encode(parameters.q),\n dp: Base64Url.encode(parameters.dp),\n dq: Base64Url.encode(parameters.dq),\n qi: Base64Url.encode(parameters.qi),\n }),\n };\n }\n case \"ECDSA-P256-SHA256\": {\n const publicKey = {\n ...meta,\n kty: \"EC\" as const,\n crv: \"P-256\" as const,\n x: Base64Url.encode(parameters.x),\n y: Base64Url.encode(parameters.y),\n };\n\n return {\n publicKey,\n privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),\n };\n }\n case \"Ed25519\": {\n const publicKey = {\n ...meta,\n kty: \"OKP\" as const,\n crv: \"Ed25519\" as const,\n x: Base64Url.encode(parameters.x),\n };\n\n return {\n publicKey,\n privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),\n };\n }\n }\n }),\n (pair) =>\n Effect.sync(() => {\n for (const part of Object.values(Redacted.value(pair.privateKey))) {\n if (typeof part !== \"string\") part.fill(0);\n }\n }),\n );\n});\n\nconst read = <S extends Schema.Constraint>(schema: S, input: unknown) =>\n Effect.try({\n try: () => KeyInput.jwk(input),\n catch: () => InvalidKey.make({}),\n }).pipe(\n Effect.flatMap(Effect.fromResult),\n Effect.flatMap((captured) =>\n Schema.decodeUnknownEffect(schema)(captured, { reportInput: false }).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n ),\n ),\n Effect.map(KeyInput.detach),\n );\n\nconst bytes = (value: string) => decode(value).pipe(Effect.mapError(() => InvalidKey.make({})));\n\nconst snapshot = <A extends PublicJwk | PrivateJwk | SecretJwk>(jwk: A): A => {\n if (jwk.key_ops !== undefined) Object.freeze(jwk.key_ops);\n\n return Object.freeze(jwk);\n};\n\nconst publicParameters = Effect.fnUntraced(function* (\n jwk: PublicJwk | PrivateJwk,\n algorithm: AsymmetricAlgorithm,\n): Effect.fn.Return<Signature.PublicKeyParameters, InvalidKey> {\n if (jwk.alg !== undefined && jwk.alg !== algorithm) return yield* InvalidKey.make({});\n switch (jwk.kty) {\n case \"EC\":\n if (algorithm !== \"ES256\") return yield* InvalidKey.make({});\n\n return { algorithm: \"ECDSA-P256-SHA256\", x: yield* bytes(jwk.x), y: yield* bytes(jwk.y) };\n case \"OKP\":\n if (algorithm !== \"EdDSA\") return yield* InvalidKey.make({});\n\n return { algorithm: \"Ed25519\", x: yield* bytes(jwk.x) };\n case \"RSA\":\n if (algorithm !== \"RS256\" && algorithm !== \"PS256\") return yield* InvalidKey.make({});\n\n return { algorithm: algorithms[algorithm], n: yield* bytes(jwk.n), e: yield* bytes(jwk.e) };\n }\n});\n\nexport const importPublic = Effect.fnUntraced(function* (\n input: unknown,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n const jwk = yield* read(PublicJwk, input);\n const parameters = yield* publicParameters(jwk, algorithm);\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures\n .encodePublicKey(parameters)\n .pipe(Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})));\n\n return Object.freeze({\n _tag: \"PublicKey\",\n algorithm,\n jwk: snapshot(jwk),\n material,\n }) satisfies PublicKey;\n});\n\nexport const importPrivate = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: AsymmetricAlgorithm,\n) {\n const algorithm = yield* read(AsymmetricAlgorithm, selected);\n\n const jwk = yield* read(\n PrivateJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const publicPart = yield* publicParameters(jwk, algorithm);\n const d = yield* bytes(jwk.d);\n\n const parameters = yield* read(Signature.PrivateKeyParameters, {\n ...publicPart,\n d,\n ...(jwk.kty === \"RSA\"\n ? {\n p: yield* bytes(jwk.p),\n q: yield* bytes(jwk.q),\n dp: yield* bytes(jwk.dp),\n dq: yield* bytes(jwk.dq),\n qi: yield* bytes(jwk.qi),\n }\n : {}),\n });\n\n const signatures = yield* Signature.Signature;\n\n const material = yield* signatures.encodePrivateKey(Redacted.make(parameters)).pipe(\n Effect.catchTag(\"CryptoInvalidInput\", () => InvalidKey.make({})),\n Effect.ensuring(\n Effect.sync(() => {\n parameters.d.fill(0);\n if (\"p\" in parameters)\n for (const part of [\n parameters.p,\n parameters.q,\n parameters.dp,\n parameters.dq,\n parameters.qi,\n ])\n part.fill(0);\n }),\n ),\n );\n\n return Object.freeze({\n _tag: \"PrivateKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material,\n }) satisfies PrivateKey;\n});\n\nexport const importSecret = Effect.fnUntraced(function* (\n input: Redacted.Redacted<unknown>,\n selected: \"HS256\" | \"dir\",\n) {\n const algorithm = yield* read(Schema.Literals([\"HS256\", \"dir\"]), selected);\n\n const jwk = yield* read(\n SecretJwk,\n yield* reveal(input).pipe(Effect.mapError(() => InvalidKey.make({}))),\n );\n\n const material = yield* bytes(jwk.k);\n\n if (\n (jwk.alg !== undefined && jwk.alg !== algorithm) ||\n material.length < 32 ||\n (algorithm === \"dir\" && material.length !== 32)\n ) {\n material.fill(0);\n\n return yield* InvalidKey.make({});\n }\n\n return Object.freeze({\n _tag: \"SecretKey\",\n algorithm,\n jwk: Redacted.make(snapshot(jwk)),\n material: Redacted.make(material),\n }) satisfies SecretKey;\n});\n\nexport const exportPublic = Effect.fnUntraced(function* (key: PublicKey) {\n return yield* read(PublicJwk, key.jwk);\n});\n\nexport const exportPrivate = Effect.fnUntraced(function* (key: PrivateKey | SecretKey) {\n const value = yield* reveal<PrivateJwk | SecretJwk>(key.jwk).pipe(\n Effect.mapError(() => InvalidKey.make({})),\n );\n\n return Redacted.make(yield* read(Schema.Union([PrivateJwk, SecretJwk]), value));\n});\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@yielded/jose","version":"0.1.0-beta.
|
|
1
|
+
{"name":"@yielded/jose","version":"0.1.0-beta.31","dependencies":{"@yielded/crypto":"0.1.0-beta.31"},"devDependencies":{"@effect/platform-node":"4.0.0","@effect/vitest":"4.0.0","@types/node":"26.1.2","effect":"4.0.0","jose":"6.2.12","typescript":"7.0.2","vite":"npm:@voidzero-dev/vite-plus-core@1.1.0","vite-plus":"1.1.0","vitest":"5.0.3"},"peerDependencies":{"effect":"^4.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./Errors":{"types":"./dist/Errors.d.mts","default":"./dist/Errors.mjs"},"./Jwk":{"types":"./dist/Jwk.d.mts","default":"./dist/Jwk.mjs"},"./Jwks":{"types":"./dist/Jwks.d.mts","default":"./dist/Jwks.mjs"},"./Jws":{"types":"./dist/Jws.d.mts","default":"./dist/Jws.mjs"},"./Jwt":{"types":"./dist/Jwt.d.mts","default":"./dist/Jwt.mjs"},"./Jwe":{"types":"./dist/Jwe.d.mts","default":"./dist/Jwe.mjs"}},"description":"Schema-typed Effect JOSE with explicit keys, cryptography, and remote JWKS trust.","homepage":"https://yielded.dev/auth/","bugs":{"url":"https://github.com/yielded-dev/auth/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/yielded-dev/auth.git","directory":"packages/jose"},"files":["dist","src","THIRD_PARTY_NOTICES.md"],"type":"module","sideEffects":[],"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","check":"tsc --noEmit -p tsconfig.json","test":"vp test"}}
|
package/src/Jwk.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Signature from "@yielded/crypto/Signature";
|
|
2
2
|
import { Effect, Redacted, Schema } from "effect";
|
|
3
|
+
import { Base64Url } from "effect/encoding";
|
|
3
4
|
|
|
4
5
|
import { InvalidKey } from "./Errors";
|
|
5
6
|
import { algorithms } from "./internal/algorithms";
|
|
@@ -80,6 +81,24 @@ export const SecretJwk = Schema.Struct({
|
|
|
80
81
|
|
|
81
82
|
export type SecretJwk = typeof SecretJwk.Type;
|
|
82
83
|
|
|
84
|
+
export const GenerateKeyPairInput = Schema.Union([
|
|
85
|
+
Schema.Struct({
|
|
86
|
+
algorithm: Schema.Literals(["RS256", "PS256"]),
|
|
87
|
+
modulusLength: Schema.optionalKey(Signature.RsaModulusLength),
|
|
88
|
+
kid: metadata.kid,
|
|
89
|
+
}),
|
|
90
|
+
Schema.Struct({ algorithm: Schema.Literals(["ES256", "EdDSA"]), kid: metadata.kid }),
|
|
91
|
+
]);
|
|
92
|
+
|
|
93
|
+
export type GenerateKeyPairInput = typeof GenerateKeyPairInput.Type;
|
|
94
|
+
|
|
95
|
+
export const GeneratedKeyPair = Schema.Struct({
|
|
96
|
+
publicKey: PublicJwk,
|
|
97
|
+
privateKey: Schema.Redacted(PrivateJwk, { disallowJsonEncode: true }),
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
export type GeneratedKeyPair = typeof GeneratedKeyPair.Type;
|
|
101
|
+
|
|
83
102
|
/** Validated, algorithm-bound key snapshots. Private material remains Redacted. */
|
|
84
103
|
export interface PublicKey {
|
|
85
104
|
readonly _tag: "PublicKey";
|
|
@@ -105,6 +124,90 @@ export interface SecretKey {
|
|
|
105
124
|
export type SigningKey = PrivateKey | SecretKey;
|
|
106
125
|
export type VerificationKey = PublicKey | SecretKey;
|
|
107
126
|
|
|
127
|
+
/** Generate typed signing JWKs through the selected crypto backend. */
|
|
128
|
+
export const generateKeyPair = Effect.fnUntraced(function* (input: GenerateKeyPairInput) {
|
|
129
|
+
const value = yield* Schema.decodeEffect(GenerateKeyPairInput)(input).pipe(
|
|
130
|
+
Effect.mapError(() => InvalidKey.make({})),
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const signatures = yield* Signature.Signature;
|
|
134
|
+
|
|
135
|
+
return yield* Effect.acquireUseRelease(
|
|
136
|
+
signatures.generateKeyPair({
|
|
137
|
+
algorithm: algorithms[value.algorithm],
|
|
138
|
+
...("modulusLength" in value ? { modulusLength: value.modulusLength } : {}),
|
|
139
|
+
}),
|
|
140
|
+
(pair) =>
|
|
141
|
+
Effect.sync((): GeneratedKeyPair => {
|
|
142
|
+
const parameters = Redacted.value(pair.privateKey);
|
|
143
|
+
|
|
144
|
+
const meta = {
|
|
145
|
+
alg: value.algorithm,
|
|
146
|
+
use: "sig" as const,
|
|
147
|
+
...(value.kid === undefined ? {} : { kid: value.kid }),
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
switch (parameters.algorithm) {
|
|
151
|
+
case "RSASSA-PKCS1-v1_5-SHA256":
|
|
152
|
+
case "RSA-PSS-SHA256": {
|
|
153
|
+
const publicKey = {
|
|
154
|
+
...meta,
|
|
155
|
+
kty: "RSA" as const,
|
|
156
|
+
n: Base64Url.encode(parameters.n),
|
|
157
|
+
e: Base64Url.encode(parameters.e),
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
publicKey,
|
|
162
|
+
privateKey: Redacted.make({
|
|
163
|
+
...publicKey,
|
|
164
|
+
d: Base64Url.encode(parameters.d),
|
|
165
|
+
p: Base64Url.encode(parameters.p),
|
|
166
|
+
q: Base64Url.encode(parameters.q),
|
|
167
|
+
dp: Base64Url.encode(parameters.dp),
|
|
168
|
+
dq: Base64Url.encode(parameters.dq),
|
|
169
|
+
qi: Base64Url.encode(parameters.qi),
|
|
170
|
+
}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
case "ECDSA-P256-SHA256": {
|
|
174
|
+
const publicKey = {
|
|
175
|
+
...meta,
|
|
176
|
+
kty: "EC" as const,
|
|
177
|
+
crv: "P-256" as const,
|
|
178
|
+
x: Base64Url.encode(parameters.x),
|
|
179
|
+
y: Base64Url.encode(parameters.y),
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
publicKey,
|
|
184
|
+
privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
case "Ed25519": {
|
|
188
|
+
const publicKey = {
|
|
189
|
+
...meta,
|
|
190
|
+
kty: "OKP" as const,
|
|
191
|
+
crv: "Ed25519" as const,
|
|
192
|
+
x: Base64Url.encode(parameters.x),
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
publicKey,
|
|
197
|
+
privateKey: Redacted.make({ ...publicKey, d: Base64Url.encode(parameters.d) }),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}),
|
|
202
|
+
(pair) =>
|
|
203
|
+
Effect.sync(() => {
|
|
204
|
+
for (const part of Object.values(Redacted.value(pair.privateKey))) {
|
|
205
|
+
if (typeof part !== "string") part.fill(0);
|
|
206
|
+
}
|
|
207
|
+
}),
|
|
208
|
+
);
|
|
209
|
+
});
|
|
210
|
+
|
|
108
211
|
const read = <S extends Schema.Constraint>(schema: S, input: unknown) =>
|
|
109
212
|
Effect.try({
|
|
110
213
|
try: () => KeyInput.jwk(input),
|