@dwn-protocol/id-sdk 0.2.5 → 0.2.6
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/package.json +2 -3
- package/src/agent/app-data-store.ts +0 -365
- package/src/agent/did-manager.ts +0 -393
- package/src/agent/dwn-manager.ts +0 -548
- package/src/agent/identity-manager.ts +0 -165
- package/src/agent/index.ts +0 -19
- package/src/agent/json-rpc.ts +0 -107
- package/src/agent/key-manager.ts +0 -302
- package/src/agent/kms-local.ts +0 -412
- package/src/agent/outbox.ts +0 -128
- package/src/agent/rpc-client.ts +0 -223
- package/src/agent/store-managed-did.ts +0 -295
- package/src/agent/store-managed-identity.ts +0 -243
- package/src/agent/store-managed-key.ts +0 -754
- package/src/agent/sync-manager.ts +0 -631
- package/src/agent/test-managed-agent.ts +0 -299
- package/src/agent/types/agent.ts +0 -145
- package/src/agent/types/managed-key.ts +0 -442
- package/src/agent/utils.ts +0 -190
- package/src/common/convert.ts +0 -424
- package/src/common/index.ts +0 -9
- package/src/common/multicodec.ts +0 -176
- package/src/common/object.ts +0 -43
- package/src/common/stores.ts +0 -125
- package/src/common/stream-node.ts +0 -381
- package/src/common/stream.ts +0 -406
- package/src/common/type-utils.ts +0 -117
- package/src/common/types.ts +0 -48
- package/src/credentials/credential-bbs.ts +0 -419
- package/src/credentials/credential.ts +0 -324
- package/src/credentials/index.ts +0 -5
- package/src/credentials/presentation.ts +0 -182
- package/src/credentials/status-list.ts +0 -365
- package/src/credentials/utils.ts +0 -58
- package/src/credentials/validators.ts +0 -52
- package/src/crypto/algorithms-api/aes/base.ts +0 -49
- package/src/crypto/algorithms-api/aes/ctr.ts +0 -51
- package/src/crypto/algorithms-api/aes/index.ts +0 -2
- package/src/crypto/algorithms-api/crypto-algorithm.ts +0 -127
- package/src/crypto/algorithms-api/crypto-key.ts +0 -56
- package/src/crypto/algorithms-api/ec/base.ts +0 -39
- package/src/crypto/algorithms-api/ec/ecdh.ts +0 -53
- package/src/crypto/algorithms-api/ec/ecdsa.ts +0 -37
- package/src/crypto/algorithms-api/ec/eddsa.ts +0 -30
- package/src/crypto/algorithms-api/ec/index.ts +0 -4
- package/src/crypto/algorithms-api/errors.ts +0 -29
- package/src/crypto/algorithms-api/index.ts +0 -6
- package/src/crypto/algorithms-api/pbkdf/index.ts +0 -1
- package/src/crypto/algorithms-api/pbkdf/pbkdf2.ts +0 -91
- package/src/crypto/crypto-algorithms/aes-ctr.ts +0 -70
- package/src/crypto/crypto-algorithms/bbs.ts +0 -110
- package/src/crypto/crypto-algorithms/ecdh.ts +0 -115
- package/src/crypto/crypto-algorithms/ecdsa.ts +0 -111
- package/src/crypto/crypto-algorithms/eddsa.ts +0 -110
- package/src/crypto/crypto-algorithms/index.ts +0 -6
- package/src/crypto/crypto-algorithms/pbkdf2.ts +0 -54
- package/src/crypto/crypto-primitives/aes-ctr.ts +0 -131
- package/src/crypto/crypto-primitives/aes-gcm.ts +0 -138
- package/src/crypto/crypto-primitives/bbs.ts +0 -183
- package/src/crypto/crypto-primitives/concat-kdf.ts +0 -207
- package/src/crypto/crypto-primitives/ed25519.ts +0 -201
- package/src/crypto/crypto-primitives/index.ts +0 -10
- package/src/crypto/crypto-primitives/pbkdf2.ts +0 -78
- package/src/crypto/crypto-primitives/secp256k1.ts +0 -322
- package/src/crypto/crypto-primitives/x25519.ts +0 -101
- package/src/crypto/crypto-primitives/xchacha20-poly1305.ts +0 -46
- package/src/crypto/crypto-primitives/xchacha20.ts +0 -34
- package/src/crypto/index.ts +0 -8
- package/src/crypto/jose.ts +0 -948
- package/src/crypto/types/crypto-key.ts +0 -4
- package/src/crypto/types/iddwn-crypto.ts +0 -119
- package/src/crypto/utils.ts +0 -200
- package/src/did-api.ts +0 -72
- package/src/dids/dht.ts +0 -412
- package/src/dids/did-dht.ts +0 -436
- package/src/dids/did-ion.ts +0 -613
- package/src/dids/did-key.ts +0 -791
- package/src/dids/did-resolver.ts +0 -107
- package/src/dids/index.ts +0 -9
- package/src/dids/resolver-cache-level.ts +0 -82
- package/src/dids/resolver-cache-noop.ts +0 -25
- package/src/dids/types.ts +0 -278
- package/src/dids/utils.ts +0 -129
- package/src/dwn-api.ts +0 -584
- package/src/iddwn.ts +0 -241
- package/src/identity-agent/index.ts +0 -270
- package/src/index.ts +0 -26
- package/src/interfaces/metadata.ts +0 -163
- package/src/interfaces/queue.ts +0 -108
- package/src/interfaces/services.ts +0 -122
- package/src/interfaces/transactions.ts +0 -220
- package/src/protocol.ts +0 -68
- package/src/proxy-agent/index.ts +0 -255
- package/src/record.ts +0 -521
- package/src/service-options.ts +0 -62
- package/src/typings/decentralized-identity__ion-pow-sdk.d.ts +0 -7
- package/src/user-agent/index.ts +0 -295
- package/src/utils.ts +0 -29
- package/src/vc-api.ts +0 -505
package/src/crypto/jose.ts
DELETED
|
@@ -1,948 +0,0 @@
|
|
|
1
|
-
import { sha256 } from '@noble/hashes/sha256';
|
|
2
|
-
import { Convert, Multicodec, MulticodecCode, MulticodecDefinition, removeUndefinedProperties } from '../common/index.js';
|
|
3
|
-
|
|
4
|
-
import type { IDCrypto } from './types/iddwn-crypto.js';
|
|
5
|
-
|
|
6
|
-
import { keyToMultibaseId } from './utils.js';
|
|
7
|
-
import { CryptoKey } from './algorithms-api/index.js';
|
|
8
|
-
import { Ed25519, Secp256k1, X25519 } from './crypto-primitives/index.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* JSON Web Key Operations
|
|
12
|
-
*
|
|
13
|
-
* decrypt : Decrypt content and validate decryption, if applicable
|
|
14
|
-
* deriveBits : Derive bits not to be used as a key
|
|
15
|
-
* deriveKey : Derive key
|
|
16
|
-
* encrypt : Encrypt content
|
|
17
|
-
* sign : Compute digital signature or MAC
|
|
18
|
-
* unwrapKey : Decrypt key and validate decryption, if applicable
|
|
19
|
-
* verify : Verify digital signature or MAC
|
|
20
|
-
* wrapKey : Encrypt key
|
|
21
|
-
*/
|
|
22
|
-
export type JwkOperation = IDCrypto.KeyUsage[] | string[];
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* JSON Web Key Use
|
|
26
|
-
*
|
|
27
|
-
* sig : Digital Signature or MAC
|
|
28
|
-
* enc : Encryption
|
|
29
|
-
*/
|
|
30
|
-
export type JwkUse = 'sig' | 'enc' | string;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* JSON Web Key Types
|
|
34
|
-
*/
|
|
35
|
-
export type JwkType =
|
|
36
|
-
/**
|
|
37
|
-
* Elliptic Curve
|
|
38
|
-
* Used with Elliptic Curve Digital Signature Algorithm (ECDSA) and Elliptic
|
|
39
|
-
* Curve Diffie-Hellman (ECDH), including secp256k1, P-256, P-384, and P-521.
|
|
40
|
-
*/
|
|
41
|
-
| 'EC'
|
|
42
|
-
/**
|
|
43
|
-
* RSA
|
|
44
|
-
* Widely used for encryption and digital signatures. RSA keys are used in
|
|
45
|
-
* various algorithms like RS256, RS384, RS512, etc.
|
|
46
|
-
*/
|
|
47
|
-
| 'RSA'
|
|
48
|
-
/**
|
|
49
|
-
* Octet sequence
|
|
50
|
-
* Used with symmetric signing (e.g., HMAC HS256, HS512, etc.) and
|
|
51
|
-
* symmetric encryption (e.g., A256CBC-HS512, A256GCM, etc.) algorithms.
|
|
52
|
-
*/
|
|
53
|
-
| 'oct'
|
|
54
|
-
/**
|
|
55
|
-
* Octet string key pairs (OKP)
|
|
56
|
-
* A type of public key that is used with algorithms such as EdDSA (Ed25519 and
|
|
57
|
-
* Ed448 curves) and ECDH (X25519 and X448 curves).
|
|
58
|
-
*/
|
|
59
|
-
| 'OKP'
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* JSON Web Key Elliptic Curve
|
|
63
|
-
*/
|
|
64
|
-
export type JwkNamedCurves =
|
|
65
|
-
// P-256 Curve
|
|
66
|
-
| 'P-256'
|
|
67
|
-
// P-384 Curve
|
|
68
|
-
| 'P-384'
|
|
69
|
-
// P-521 Curve
|
|
70
|
-
| 'P-521'
|
|
71
|
-
// Ed25519 signature algorithm key pairs
|
|
72
|
-
| 'Ed25519'
|
|
73
|
-
// Ed448 signature algorithm key pairs
|
|
74
|
-
| 'Ed448'
|
|
75
|
-
// X25519 function key pairs
|
|
76
|
-
| 'X25519'
|
|
77
|
-
// X448 function key pairs
|
|
78
|
-
| 'X448'
|
|
79
|
-
// SECG secp256k1 curve
|
|
80
|
-
| 'secp256k1';
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* JSON Web Key Parameters
|
|
84
|
-
*/
|
|
85
|
-
|
|
86
|
-
// Used with any "kty" (key type) value.
|
|
87
|
-
export type JwkParamsAnyKeyType = {
|
|
88
|
-
// The algorithm intended for use with the key
|
|
89
|
-
alg?: string;
|
|
90
|
-
// Extractable
|
|
91
|
-
ext?: 'true' | 'false';
|
|
92
|
-
// Key Operations
|
|
93
|
-
key_ops?: JwkOperation;
|
|
94
|
-
// Key ID
|
|
95
|
-
kid?: string;
|
|
96
|
-
// Key Type
|
|
97
|
-
kty: JwkType;
|
|
98
|
-
// Public Key Use
|
|
99
|
-
use?: JwkUse;
|
|
100
|
-
// X.509 Certificate Chain
|
|
101
|
-
x5c?: string;
|
|
102
|
-
// X.509 Certificate SHA-1 Thumbprint
|
|
103
|
-
x5t?: string;
|
|
104
|
-
// X.509 Certificate SHA-256 Thumbprint
|
|
105
|
-
'x5t#S256'?: string;
|
|
106
|
-
// X.509 URL
|
|
107
|
-
x5u?: string;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Used with "EC" (elliptic curve) public keys.
|
|
111
|
-
export type JwkParamsEcPublic = Omit<JwkParamsAnyKeyType, 'alg' | 'kty'> & {
|
|
112
|
-
/**
|
|
113
|
-
* The algorithm intended for use with the key.
|
|
114
|
-
* ES256 : ECDSA using P-256 and SHA-256
|
|
115
|
-
* ES256K : ECDSA using secp256k1 curve and SHA-256
|
|
116
|
-
* ES384 : ECDSA using P-384 and SHA-384
|
|
117
|
-
* ES512 : ECDSA using P-521 and SHA-512
|
|
118
|
-
*/
|
|
119
|
-
alg?: 'ES256' | 'ES256K' | 'ES384' | 'ES512';
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Elliptic Curve key pair.
|
|
123
|
-
*/
|
|
124
|
-
kty: 'EC';
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* The cryptographic curve used with the key.
|
|
128
|
-
* MUST be present for all EC public keys.
|
|
129
|
-
*/
|
|
130
|
-
crv: 'secp256k1' | 'P-256' | 'P-384' | 'P-521';
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* The x-coordinate for the Elliptic Curve point.
|
|
134
|
-
* Represented as the base64url encoding of the octet string
|
|
135
|
-
* representation of the coordinate.
|
|
136
|
-
* MUST be present for all EC public keys
|
|
137
|
-
*/
|
|
138
|
-
x: string;
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* The y-coordinate for the Elliptic Curve point.
|
|
142
|
-
* Represented as the base64url encoding of the octet string
|
|
143
|
-
* representation of the coordinate.
|
|
144
|
-
* MUST be present only for secp256k1 public keys.
|
|
145
|
-
*/
|
|
146
|
-
y?: string;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Used with "EC" (elliptic curve) private keys.
|
|
150
|
-
export type JwkParamsEcPrivate = JwkParamsEcPublic & {
|
|
151
|
-
/**
|
|
152
|
-
* The d-coordinate for the Elliptic Curve point.
|
|
153
|
-
* Represented as the base64url encoding of the octet string
|
|
154
|
-
* representation of the coordinate.
|
|
155
|
-
* MUST be present for all EC private keys.
|
|
156
|
-
*/
|
|
157
|
-
d: string;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Used with "OKP" (octet key pair) public keys.
|
|
161
|
-
export type JwkParamsOkpPublic =
|
|
162
|
-
Omit<JwkParamsAnyKeyType, 'kty' | 'alg' | 'crv'> &
|
|
163
|
-
Pick<JwkParamsEcPublic, 'x'> & {
|
|
164
|
-
/**
|
|
165
|
-
* The algorithm intended for use with the key.
|
|
166
|
-
* EdDSA: Edwards Curve Digital Signature Algorithm
|
|
167
|
-
*/
|
|
168
|
-
alg?: 'EdDSA';
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* The cryptographic curve used with the key.
|
|
172
|
-
* MUST be present for all OKP public keys.
|
|
173
|
-
*/
|
|
174
|
-
crv: 'Ed25519' | 'Ed448' | 'X25519' | 'X448';
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Key type
|
|
178
|
-
* OKP (Octet Key Pair) is defined for public key algorithms that use octet
|
|
179
|
-
* strings as private and public keys.
|
|
180
|
-
*/
|
|
181
|
-
kty: 'OKP';
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Used with "OKP" (octet key pair) private keys.
|
|
185
|
-
export type JwkParamsOkpPrivate = JwkParamsOkpPublic & {
|
|
186
|
-
/**
|
|
187
|
-
* The d-coordinate for the Edwards Curve point.
|
|
188
|
-
* Represented as the base64url encoding of the octet string
|
|
189
|
-
* representation of the coordinate.
|
|
190
|
-
* MUST be present for all EC private keys.
|
|
191
|
-
*/
|
|
192
|
-
d: string;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// Used with "oct" (octet sequence) private keys.
|
|
196
|
-
export type JwkParamsOctPrivate = Omit<JwkParamsAnyKeyType, 'alg' | 'kty'> & {
|
|
197
|
-
/**
|
|
198
|
-
* The algorithm intended for use with the key.
|
|
199
|
-
* Used with symmetric signing (e.g., HMAC HS256, etc.) and
|
|
200
|
-
* symmetric encryption (e.g., A256GCM, etc.) algorithms.
|
|
201
|
-
*/
|
|
202
|
-
alg?:
|
|
203
|
-
// AES CBC using 128-bit key
|
|
204
|
-
| 'A128CBC'
|
|
205
|
-
// AES CBC using 192-bit key
|
|
206
|
-
| 'A192CBC'
|
|
207
|
-
// AES CBC using 256-bit key
|
|
208
|
-
| 'A256CBC'
|
|
209
|
-
// AES CTR using 128-bit key
|
|
210
|
-
| 'A128CTR'
|
|
211
|
-
// AES CTR using 192-bit key
|
|
212
|
-
| 'A192CTR'
|
|
213
|
-
// AES CTR using 256-bit key
|
|
214
|
-
| 'A256CTR'
|
|
215
|
-
// AES GCM using a 128-bit key
|
|
216
|
-
| 'A128GCM'
|
|
217
|
-
// AES GCM using a 192-bit key
|
|
218
|
-
| 'A192GCM'
|
|
219
|
-
// AES GCM using a 256-bit key
|
|
220
|
-
| 'A256GCM'
|
|
221
|
-
// HMAC using SHA-256
|
|
222
|
-
| 'HS256'
|
|
223
|
-
// HMAC using SHA-384
|
|
224
|
-
| 'HS384'
|
|
225
|
-
// HMAC using SHA-512
|
|
226
|
-
| 'HS512'
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* The "k" (key value) parameter contains the value of the symmetric
|
|
230
|
-
* (or other single-valued) key. It is represented as the base64url
|
|
231
|
-
* encoding of the octet sequence containing the key value.
|
|
232
|
-
*/
|
|
233
|
-
k: string;
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Key type
|
|
237
|
-
* oct (Octet Sequence) is defined for symmetric encryption and
|
|
238
|
-
* symmetric signature algorithms.
|
|
239
|
-
*/
|
|
240
|
-
kty: 'oct';
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Used with "RSA" public keys.
|
|
244
|
-
export type JwkParamsRsaPublic = Omit<JwkParamsAnyKeyType, 'kty'> & {
|
|
245
|
-
// Public exponent for RSA
|
|
246
|
-
e: string;
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Key type
|
|
250
|
-
* RSA is widely used for encryption and digital signatures.
|
|
251
|
-
*/
|
|
252
|
-
kty: 'RSA';
|
|
253
|
-
|
|
254
|
-
// Modulus for RSA
|
|
255
|
-
n: string;
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
// Used with "RSA" private keys.
|
|
259
|
-
export type JwkParamsRsaPrivate = JwkParamsRsaPublic & {
|
|
260
|
-
// Private exponent for RSA
|
|
261
|
-
d: string;
|
|
262
|
-
// First prime factor for RSA
|
|
263
|
-
p?: string;
|
|
264
|
-
// Second prime factor for RSA
|
|
265
|
-
q?: string;
|
|
266
|
-
// First factor's CRT exponent for RSA
|
|
267
|
-
dp?: string;
|
|
268
|
-
// Second factor's CRT exponent for RSA
|
|
269
|
-
dq?: string;
|
|
270
|
-
// First CRT coefficient for RSA
|
|
271
|
-
qi?: string;
|
|
272
|
-
// Other primes information (optional in RFC 7518)
|
|
273
|
-
oth?: {
|
|
274
|
-
r: string;
|
|
275
|
-
d: string;
|
|
276
|
-
t: string;
|
|
277
|
-
}[];
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
export type PublicKeyJwk = JwkParamsEcPublic | JwkParamsOkpPublic | JwkParamsRsaPublic;
|
|
281
|
-
|
|
282
|
-
export type PrivateKeyJwk = JwkParamsEcPrivate | JwkParamsOkpPrivate | JwkParamsOctPrivate | JwkParamsRsaPrivate;
|
|
283
|
-
|
|
284
|
-
export type JwkKeyPair = {
|
|
285
|
-
publicKeyJwk: PublicKeyJwk;
|
|
286
|
-
privateKeyJwk: PrivateKeyJwk;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export type JsonWebKey = PrivateKeyJwk | PublicKeyJwk;
|
|
290
|
-
|
|
291
|
-
export interface JoseHeaderParams {
|
|
292
|
-
// Content Type
|
|
293
|
-
cty?: string;
|
|
294
|
-
// JWK Set URL
|
|
295
|
-
jku?: string;
|
|
296
|
-
// JSON Web Key
|
|
297
|
-
jwk?: PublicKeyJwk;
|
|
298
|
-
// Key ID
|
|
299
|
-
kid?: string;
|
|
300
|
-
// Type
|
|
301
|
-
typ?: string;
|
|
302
|
-
// X.509 Certificate Chain
|
|
303
|
-
x5c?: string[];
|
|
304
|
-
// X.509 Certificate SHA-1 Thumbprint
|
|
305
|
-
x5t?: string;
|
|
306
|
-
// X.509 URL
|
|
307
|
-
x5u?: string;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export interface JwsHeaderParams extends JoseHeaderParams {
|
|
311
|
-
alg:
|
|
312
|
-
// Edwards curve digital signature algorithm (e.g., Ed25519)
|
|
313
|
-
| 'EdDSA'
|
|
314
|
-
// ECDSA using P-256 and SHA-256
|
|
315
|
-
| 'ES256'
|
|
316
|
-
// ECDSA using secp256k1 curve and SHA-256
|
|
317
|
-
| 'ES256K'
|
|
318
|
-
// ECDSA using P-384 and SHA-384
|
|
319
|
-
| 'ES384'
|
|
320
|
-
// ECDSA using P-521 and SHA-512
|
|
321
|
-
| 'ES512'
|
|
322
|
-
// HMAC using SHA-256
|
|
323
|
-
| 'HS256'
|
|
324
|
-
// HMAC using SHA-384
|
|
325
|
-
| 'HS384'
|
|
326
|
-
// HMAC using SHA-512
|
|
327
|
-
| 'HS512';
|
|
328
|
-
|
|
329
|
-
// Indicates that extensions to JOSE RFCs are being used
|
|
330
|
-
// that MUST be understood and processed.
|
|
331
|
-
crit?: string[]
|
|
332
|
-
|
|
333
|
-
// Additional Public or Private Header Parameter names.
|
|
334
|
-
[key: string]: unknown
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export interface JweHeaderParams extends JoseHeaderParams {
|
|
338
|
-
alg:
|
|
339
|
-
// AES Key Wrap with default initial value using 128-bit key
|
|
340
|
-
| 'A128KW'
|
|
341
|
-
// AES Key Wrap with default initial value using 192-bit key
|
|
342
|
-
| 'A192KW'
|
|
343
|
-
// AES Key Wrap with default initial value using 256-bit key
|
|
344
|
-
| 'A256KW'
|
|
345
|
-
// Direct use of a shared symmetric key as the CEK
|
|
346
|
-
| 'dir'
|
|
347
|
-
// Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF
|
|
348
|
-
| 'ECDH-ES'
|
|
349
|
-
// ECDH-ES using Concat KDF and CEK wrapped with "A128KW"
|
|
350
|
-
| 'ECDH-ES+A128KW'
|
|
351
|
-
// ECDH-ES using Concat KDF and CEK wrapped with "A192KW"
|
|
352
|
-
| 'ECDH-ES+A192KW'
|
|
353
|
-
// ECDH-ES using Concat KDF and CEK wrapped with "A256KW"
|
|
354
|
-
| 'ECDH-ES+A256KW'
|
|
355
|
-
// Key wrapping with AES GCM using 128-bit key
|
|
356
|
-
| 'A128GCMKW'
|
|
357
|
-
// Key wrapping with AES GCM using 192-bit key
|
|
358
|
-
| 'A192GCMKW'
|
|
359
|
-
// Key wrapping with AES GCM using 256-bit key
|
|
360
|
-
| 'A256GCMKW'
|
|
361
|
-
// PBES2 with HMAC SHA-256 and "A128KW" wrapping
|
|
362
|
-
| 'PBES2-HS256+A128KW'
|
|
363
|
-
// PBES2 with HMAC SHA-384 and "A192KW" wrapping
|
|
364
|
-
| 'PBES2-HS384+A192KW'
|
|
365
|
-
// PBES2 with HMAC SHA-512 and "A256KW" wrapping
|
|
366
|
-
| 'PBES2-HS512+A256KW'
|
|
367
|
-
// PBES2 with HMAC SHA-512 and "XC20PKW" wrapping
|
|
368
|
-
| 'PBES2-HS512+XC20PKW';
|
|
369
|
-
|
|
370
|
-
apu?: Uint8Array;
|
|
371
|
-
|
|
372
|
-
apv?: Uint8Array;
|
|
373
|
-
|
|
374
|
-
// Indicates that extensions to JOSE RFCs are being used
|
|
375
|
-
// that MUST be understood and processed.
|
|
376
|
-
crit?: string[]
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Cryptographic Algorithms for Content Encryption
|
|
380
|
-
* JWE uses cryptographic algorithms to encrypt and integrity-protect the
|
|
381
|
-
* plaintext and to integrity-protect the Additional Authenticated Data.
|
|
382
|
-
*/
|
|
383
|
-
enc:
|
|
384
|
-
// AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm,
|
|
385
|
-
// as defined in RFC 7518, Section 5.2.3
|
|
386
|
-
| 'A128CBC-HS256'
|
|
387
|
-
// AES_192_CBC_HMAC_SHA_384 authenticated encryption algorithm,
|
|
388
|
-
// as defined in RFC 7518, Section 5.2.4
|
|
389
|
-
| 'A192CBC-HS384'
|
|
390
|
-
// AES_256_CBC_HMAC_SHA_512 authenticated encryption algorithm,
|
|
391
|
-
// as defined in RFC 7518, Section 5.2.5
|
|
392
|
-
| 'A256CBC-HS512'
|
|
393
|
-
// AES GCM using 128-bit key
|
|
394
|
-
| 'A128GCM'
|
|
395
|
-
// AES GCM using 192-bit key
|
|
396
|
-
| 'A192GCM'
|
|
397
|
-
// AES GCM using 256-bit key
|
|
398
|
-
| 'A256GCM'
|
|
399
|
-
// XChaCha20-Poly1305 authenticated encryption algorithm
|
|
400
|
-
| 'XC20P';
|
|
401
|
-
|
|
402
|
-
epk?: Uint8Array;
|
|
403
|
-
|
|
404
|
-
iv?: Uint8Array;
|
|
405
|
-
|
|
406
|
-
p2c?: number;
|
|
407
|
-
|
|
408
|
-
p2s?: string;
|
|
409
|
-
|
|
410
|
-
// Additional Public or Private Header Parameter names.
|
|
411
|
-
[key: string]: unknown
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
const joseToWebCryptoMapping: { [key: string]: IDCrypto.GenerateKeyOptions } = {
|
|
415
|
-
'Ed25519' : { name: 'EdDSA', namedCurve: 'Ed25519' },
|
|
416
|
-
'Ed448' : { name: 'EdDSA', namedCurve: 'Ed448' },
|
|
417
|
-
'X25519' : { name: 'ECDH', namedCurve: 'X25519' },
|
|
418
|
-
'secp256k1:ES256K' : { name: 'ECDSA', namedCurve: 'secp256k1' },
|
|
419
|
-
'secp256k1' : { name: 'ECDH', namedCurve: 'secp256k1' },
|
|
420
|
-
'P-256' : { name: 'ECDSA', namedCurve: 'P-256' },
|
|
421
|
-
'P-384' : { name: 'ECDSA', namedCurve: 'P-384' },
|
|
422
|
-
'P-521' : { name: 'ECDSA', namedCurve: 'P-521' },
|
|
423
|
-
'A128CBC' : { name: 'AES-CBC', length: 128 },
|
|
424
|
-
'A192CBC' : { name: 'AES-CBC', length: 192 },
|
|
425
|
-
'A256CBC' : { name: 'AES-CBC', length: 256 },
|
|
426
|
-
'A128CTR' : { name: 'AES-CTR', length: 128 },
|
|
427
|
-
'A192CTR' : { name: 'AES-CTR', length: 192 },
|
|
428
|
-
'A256CTR' : { name: 'AES-CTR', length: 256 },
|
|
429
|
-
'A128GCM' : { name: 'AES-GCM', length: 128 },
|
|
430
|
-
'A192GCM' : { name: 'AES-GCM', length: 192 },
|
|
431
|
-
'A256GCM' : { name: 'AES-GCM', length: 256 },
|
|
432
|
-
'HS256' : { name: 'HMAC', hash: { name: 'SHA-256' } },
|
|
433
|
-
'HS384' : { name: 'HMAC', hash: { name: 'SHA-384' } },
|
|
434
|
-
'HS512' : { name: 'HMAC', hash: { name: 'SHA-512' } },
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
const webCryptoToJoseMapping: { [key: string]: Partial<JsonWebKey> } = {
|
|
438
|
-
'EdDSA:Ed25519' : { alg: 'EdDSA', crv: 'Ed25519', kty: 'OKP' },
|
|
439
|
-
'EdDSA:Ed448' : { alg: 'EdDSA', crv: 'Ed448', kty: 'OKP' },
|
|
440
|
-
'ECDH:X25519' : { crv: 'X25519', kty: 'OKP' },
|
|
441
|
-
'ECDSA:secp256k1' : { alg: 'ES256K', crv: 'secp256k1', kty: 'EC' },
|
|
442
|
-
'ECDH:secp256k1' : { crv: 'secp256k1', kty: 'EC' },
|
|
443
|
-
'ECDSA:P-256' : { alg: 'ES256', crv: 'P-256', kty: 'EC' },
|
|
444
|
-
'ECDSA:P-384' : { alg: 'ES384', crv: 'P-384', kty: 'EC' },
|
|
445
|
-
'ECDSA:P-521' : { alg: 'ES512', crv: 'P-521', kty: 'EC' },
|
|
446
|
-
'AES-CBC:128' : { alg: 'A128CBC', kty: 'oct' },
|
|
447
|
-
'AES-CBC:192' : { alg: 'A192CBC', kty: 'oct' },
|
|
448
|
-
'AES-CBC:256' : { alg: 'A256CBC', kty: 'oct' },
|
|
449
|
-
'AES-CTR:128' : { alg: 'A128CTR', kty: 'oct' },
|
|
450
|
-
'AES-CTR:192' : { alg: 'A192CTR', kty: 'oct' },
|
|
451
|
-
'AES-CTR:256' : { alg: 'A256CTR', kty: 'oct' },
|
|
452
|
-
'AES-GCM:128' : { alg: 'A128GCM', kty: 'oct' },
|
|
453
|
-
'AES-GCM:192' : { alg: 'A192GCM', kty: 'oct' },
|
|
454
|
-
'AES-GCM:256' : { alg: 'A256GCM', kty: 'oct' },
|
|
455
|
-
'HMAC:SHA-256' : { alg: 'HS256', kty: 'oct' },
|
|
456
|
-
'HMAC:SHA-384' : { alg: 'HS384', kty: 'oct' },
|
|
457
|
-
'HMAC:SHA-512' : { alg: 'HS512', kty: 'oct' },
|
|
458
|
-
};
|
|
459
|
-
|
|
460
|
-
const multicodecToJoseMapping: { [key: string]: JsonWebKey } = {
|
|
461
|
-
'ed25519-pub' : { alg: 'EdDSA', crv: 'Ed25519', kty: 'OKP', x: '' },
|
|
462
|
-
'ed25519-priv' : { alg: 'EdDSA', crv: 'Ed25519', kty: 'OKP', x: '', d: '' },
|
|
463
|
-
'secp256k1-pub' : { alg: 'ES256K', crv: 'secp256k1', kty: 'EC', x: '', y: ''},
|
|
464
|
-
'secp256k1-priv' : { alg: 'ES256K', crv: 'secp256k1', kty: 'EC', x: '', y: '', d: '' },
|
|
465
|
-
'x25519-pub' : { crv: 'X25519', kty: 'OKP', x: '' },
|
|
466
|
-
'x25519-priv' : { crv: 'X25519', kty: 'OKP', x: '', d: '' },
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
const joseToMulticodecMapping: { [key: string]: string } = {
|
|
470
|
-
'Ed25519:public' : 'ed25519-pub',
|
|
471
|
-
'Ed25519:private' : 'ed25519-priv',
|
|
472
|
-
'secp256k1:public' : 'secp256k1-pub',
|
|
473
|
-
'secp256k1:private' : 'secp256k1-priv',
|
|
474
|
-
'X25519:public' : 'x25519-pub',
|
|
475
|
-
'X25519:private' : 'x25519-priv',
|
|
476
|
-
};
|
|
477
|
-
|
|
478
|
-
export class Jose {
|
|
479
|
-
|
|
480
|
-
public static async cryptoKeyToJwk(options: {
|
|
481
|
-
key: IDCrypto.CryptoKey,
|
|
482
|
-
}): Promise<JsonWebKey> {
|
|
483
|
-
const { algorithm, extractable, material, type, usages } = options.key;
|
|
484
|
-
|
|
485
|
-
// Translate WebCrypto algorithm to JOSE format.
|
|
486
|
-
let jsonWebKey = Jose.webCryptoToJose(algorithm) as JsonWebKey;
|
|
487
|
-
|
|
488
|
-
// Set extractable parameter.
|
|
489
|
-
jsonWebKey.ext = extractable ? 'true' : 'false';
|
|
490
|
-
|
|
491
|
-
// Set key use parameter.
|
|
492
|
-
jsonWebKey.key_ops = usages;
|
|
493
|
-
|
|
494
|
-
jsonWebKey = await Jose.keyToJwk({
|
|
495
|
-
keyMaterial : material,
|
|
496
|
-
keyType : type,
|
|
497
|
-
...jsonWebKey
|
|
498
|
-
});
|
|
499
|
-
|
|
500
|
-
return { ...jsonWebKey };
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
public static async cryptoKeyToJwkPair(options: {
|
|
504
|
-
keyPair: IDCrypto.CryptoKeyPair,
|
|
505
|
-
}): Promise<JwkKeyPair> {
|
|
506
|
-
const { keyPair } = options;
|
|
507
|
-
|
|
508
|
-
// Convert public and private keys into JSON Web Key format.
|
|
509
|
-
const privateKeyJwk = await Jose.cryptoKeyToJwk({ key: keyPair.privateKey }) as PrivateKeyJwk;
|
|
510
|
-
const publicKeyJwk = await Jose.cryptoKeyToJwk({ key: keyPair.publicKey }) as PublicKeyJwk;
|
|
511
|
-
|
|
512
|
-
// Assemble as a JWK key pair
|
|
513
|
-
const jwkKeyPair: JwkKeyPair = { privateKeyJwk, publicKeyJwk };
|
|
514
|
-
|
|
515
|
-
return { ...jwkKeyPair };
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
public static async joseToMulticodec(options: {
|
|
519
|
-
key: JsonWebKey
|
|
520
|
-
}): Promise<MulticodecDefinition<MulticodecCode>> {
|
|
521
|
-
const jsonWebKey = options.key;
|
|
522
|
-
|
|
523
|
-
const params: string[] = [];
|
|
524
|
-
|
|
525
|
-
if ('crv' in jsonWebKey) {
|
|
526
|
-
params.push(jsonWebKey.crv);
|
|
527
|
-
if ('d' in jsonWebKey) {
|
|
528
|
-
params.push('private');
|
|
529
|
-
} else {
|
|
530
|
-
params.push('public');
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
const lookupKey = params.join(':');
|
|
535
|
-
const name = joseToMulticodecMapping[lookupKey];
|
|
536
|
-
|
|
537
|
-
if (name === undefined) {
|
|
538
|
-
throw new Error(`Unsupported JOSE to Multicodec conversion: '${lookupKey}'`);
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
const code = Multicodec.getCodeFromName({ name });
|
|
542
|
-
|
|
543
|
-
return { code, name };
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
public static joseToWebCrypto(options:
|
|
547
|
-
Partial<JsonWebKey>
|
|
548
|
-
): IDCrypto.GenerateKeyOptions {
|
|
549
|
-
const params: string[] = [];
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* All Elliptic Curve (EC) and Octet Key Pair (OKP) JSON Web Keys
|
|
553
|
-
* set a value for the "crv" parameter.
|
|
554
|
-
*/
|
|
555
|
-
if ('crv' in options && options.crv) {
|
|
556
|
-
params.push(options.crv);
|
|
557
|
-
// Special case for secp256k1. If alg is "ES256K", then ECDSA. Else ECDH.
|
|
558
|
-
if (options.crv === 'secp256k1' && options.alg === 'ES256K') {
|
|
559
|
-
params.push(options.alg);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* All Octet Sequence (oct) JSON Web Keys omit "crv" and
|
|
564
|
-
* set a value for the "alg" parameter.
|
|
565
|
-
*/
|
|
566
|
-
} else if (options.alg !== undefined) {
|
|
567
|
-
params.push(options.alg);
|
|
568
|
-
|
|
569
|
-
} else {
|
|
570
|
-
throw new TypeError(`One or more parameters missing: 'alg' or 'crv'`);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const lookupKey = params.join(':');
|
|
574
|
-
const webCrypto = joseToWebCryptoMapping[lookupKey];
|
|
575
|
-
|
|
576
|
-
if (webCrypto === undefined) {
|
|
577
|
-
throw new Error(`Unsupported JOSE to WebCrypto conversion: '${lookupKey}'`);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
return { ...webCrypto };
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
/**
|
|
584
|
-
* Computes the thumbprint of a JSON Web Key (JWK) using the method
|
|
585
|
-
* specified in RFC 7638. This function accepts RSA, EC, OKP, and oct keys
|
|
586
|
-
* and returns the thumbprint as a base64url encoded SHA-256 hash of the
|
|
587
|
-
* JWK's required members, serialized and sorted lexicographically.
|
|
588
|
-
*
|
|
589
|
-
* Purpose:
|
|
590
|
-
* - Uniquely Identifying Keys: The thumbprint allows the unique
|
|
591
|
-
* identification of a specific JWK within a set of JWKs. It provides a
|
|
592
|
-
* deterministic way to generate a value that can be used as a key
|
|
593
|
-
* identifier (kid) or to match a specific key.
|
|
594
|
-
*
|
|
595
|
-
* - Simplifying Key Management: In systems where multiple keys are used,
|
|
596
|
-
* managing and identifying individual keys can become complex. The
|
|
597
|
-
* thumbprint method simplifies this by creating a standardized, unique
|
|
598
|
-
* identifier for each key.
|
|
599
|
-
*
|
|
600
|
-
* - Enabling Interoperability: By standardizing the method to compute a
|
|
601
|
-
* thumbprint, different systems can compute the same thumbprint value for
|
|
602
|
-
* a given JWK. This enables interoperability among systems that use JWKs.
|
|
603
|
-
*
|
|
604
|
-
* - Secure Comparison: The thumbprint provides a way to securely compare
|
|
605
|
-
* JWKs to determine if they are equivalent.
|
|
606
|
-
*
|
|
607
|
-
* @param jwk - The JSON Web Key for which the thumbprint will be computed.
|
|
608
|
-
* This must be an RSA, EC, OKP, or oct key.
|
|
609
|
-
* @returns The thumbprint as a base64url encoded string.
|
|
610
|
-
* @throws {Error} Throws an error if the provided key type is unsupported.
|
|
611
|
-
*
|
|
612
|
-
* @example
|
|
613
|
-
* const jwk: PublicKeyJwk = {
|
|
614
|
-
* 'kty': 'EC',
|
|
615
|
-
* 'crv': 'secp256k1',
|
|
616
|
-
* 'x': '61iPYuGefxotzBdQZtDvv6cWHZmXrTTscY-u7Y2pFZc',
|
|
617
|
-
* 'y': '88nPCVLfrAY9i-wg5ORcwVbHWC_tbeAd1JE2e0co0lU'
|
|
618
|
-
* };
|
|
619
|
-
*
|
|
620
|
-
* const thumbprint = jwkThumbprint(jwk);
|
|
621
|
-
* console.log(`JWK thumbprint: ${thumbprint}`);
|
|
622
|
-
*
|
|
623
|
-
* @see {@link https://datatracker.ietf.org/doc/html/rfc7638 | RFC7638} for
|
|
624
|
-
* the specification of JWK thumbprint computation.
|
|
625
|
-
*/
|
|
626
|
-
public static async jwkThumbprint(options: {
|
|
627
|
-
key: JsonWebKey
|
|
628
|
-
}): Promise<string> {
|
|
629
|
-
const { key } = options;
|
|
630
|
-
|
|
631
|
-
/** Step 1 - Normalization: The JWK is normalized to include only specific
|
|
632
|
-
* members and in lexicographic order.
|
|
633
|
-
*/
|
|
634
|
-
const keyType = key.kty;
|
|
635
|
-
let normalizedJwk: Partial<JsonWebKey>;
|
|
636
|
-
if (keyType === 'EC') {
|
|
637
|
-
normalizedJwk = { crv: key.crv, kty: key.kty, x: key.x, y: key.y };
|
|
638
|
-
} else if (keyType === 'oct') {
|
|
639
|
-
normalizedJwk = { k: key.k, kty: key.kty };
|
|
640
|
-
} else if (keyType === 'OKP') {
|
|
641
|
-
normalizedJwk = { crv: key.crv, kty: key.kty, x: key.x };
|
|
642
|
-
} else if (keyType === 'RSA') {
|
|
643
|
-
normalizedJwk = { e: key.e, kty: key.kty, n: key.n };
|
|
644
|
-
} else {
|
|
645
|
-
throw new Error(`Unsupported key type: ${keyType}`);
|
|
646
|
-
}
|
|
647
|
-
removeUndefinedProperties(normalizedJwk);
|
|
648
|
-
|
|
649
|
-
/** Step 2 - Serialization: The normalized JWK is serialized to a UTF-8
|
|
650
|
-
* representation of its JSON encoding. */
|
|
651
|
-
const serializedJwk = Jose.canonicalize(normalizedJwk);
|
|
652
|
-
|
|
653
|
-
/** Step 3 - Digest Calculation: A cryptographic hash function
|
|
654
|
-
* (SHA-256 is recommended) is applied to the serialized JWK,
|
|
655
|
-
* resulting in the thumbprint. */
|
|
656
|
-
const utf8Bytes = Convert.string(serializedJwk).toUint8Array();
|
|
657
|
-
const digest = sha256(utf8Bytes);
|
|
658
|
-
|
|
659
|
-
// Encode as Base64Url.
|
|
660
|
-
const thumbprint = Convert.uint8Array(digest).toBase64Url();
|
|
661
|
-
|
|
662
|
-
return thumbprint;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
public static async jwkToCryptoKey(options: {
|
|
666
|
-
key: JsonWebKey
|
|
667
|
-
}): Promise<IDCrypto.CryptoKey> {
|
|
668
|
-
const jsonWebKey = options.key;
|
|
669
|
-
|
|
670
|
-
const { keyMaterial, keyType } = await Jose.jwkToKey({ key: jsonWebKey });
|
|
671
|
-
|
|
672
|
-
// Translate JOSE format to WebCrypto algorithm.
|
|
673
|
-
let algorithm = Jose.joseToWebCrypto(jsonWebKey) as IDCrypto.GenerateKeyOptions;
|
|
674
|
-
|
|
675
|
-
// Set extractable parameter.
|
|
676
|
-
let extractable: boolean;
|
|
677
|
-
if ('ext' in jsonWebKey && jsonWebKey.ext !== undefined) {
|
|
678
|
-
extractable = jsonWebKey.ext === 'true' ? true : false;
|
|
679
|
-
} else {
|
|
680
|
-
throw new Error(`Conversion from JWK to CryptoKey failed. Required parameter missing: 'ext'`);
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// Set key use parameter.
|
|
684
|
-
let keyUsage: IDCrypto.KeyUsage[];
|
|
685
|
-
if ('key_ops' in jsonWebKey && jsonWebKey.key_ops !== undefined) {
|
|
686
|
-
keyUsage = jsonWebKey.key_ops as IDCrypto.KeyUsage[];
|
|
687
|
-
} else {
|
|
688
|
-
throw new Error(`Conversion from JWK to CryptoKey failed. Required parameter missing: 'key_ops'`);
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
const cryptoKey = new CryptoKey(
|
|
692
|
-
algorithm,
|
|
693
|
-
extractable,
|
|
694
|
-
keyMaterial,
|
|
695
|
-
keyType,
|
|
696
|
-
keyUsage
|
|
697
|
-
);
|
|
698
|
-
|
|
699
|
-
return cryptoKey;
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
public static async jwkToKey(options: {
|
|
703
|
-
key: JsonWebKey
|
|
704
|
-
}): Promise<{ keyMaterial: Uint8Array, keyType: IDCrypto.KeyType }> {
|
|
705
|
-
const jsonWebKey = options.key;
|
|
706
|
-
|
|
707
|
-
let keyMaterial: Uint8Array;
|
|
708
|
-
let keyType: IDCrypto.KeyType;
|
|
709
|
-
|
|
710
|
-
// Asymmetric private key ("EC" or "OKP" - Curve25519 or SECG curves).
|
|
711
|
-
if ('d' in jsonWebKey) {
|
|
712
|
-
keyMaterial = Convert.base64Url(jsonWebKey.d).toUint8Array();
|
|
713
|
-
keyType = 'private';
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
// Asymmetric public key ("EC" - secp256k1, secp256r1, secp384r1, secp521r1).
|
|
717
|
-
else if ('y' in jsonWebKey && jsonWebKey.y) {
|
|
718
|
-
const prefix = new Uint8Array([0x04]); // Designates an uncompressed key.
|
|
719
|
-
const x = Convert.base64Url(jsonWebKey.x).toUint8Array();
|
|
720
|
-
const y = Convert.base64Url(jsonWebKey.y).toUint8Array();
|
|
721
|
-
|
|
722
|
-
const publicKey = new Uint8Array([...prefix, ...x, ...y]);
|
|
723
|
-
keyMaterial = publicKey;
|
|
724
|
-
keyType = 'public';
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// Asymmetric public key ("OKP" - Ed25519, X25519).
|
|
728
|
-
else if ('x' in jsonWebKey) {
|
|
729
|
-
keyMaterial = Convert.base64Url(jsonWebKey.x).toUint8Array();
|
|
730
|
-
keyType = 'public';
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
// Symmetric encryption or signature key ("oct" - AES, HMAC)
|
|
734
|
-
else if ('k' in jsonWebKey) {
|
|
735
|
-
keyMaterial = Convert.base64Url(jsonWebKey.k).toUint8Array();
|
|
736
|
-
keyType = 'private';
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
else {
|
|
740
|
-
throw new Error('Jose: Unknown JSON Web Key format.');
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
return { keyMaterial, keyType };
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
/**
|
|
747
|
-
* Note: All secp public keys are converted to compressed point encoding
|
|
748
|
-
* before the multibase identifier is computed.
|
|
749
|
-
*
|
|
750
|
-
* Per {@link https://github.com/multiformats/multicodec/blob/master/table.csv | Multicodec table}:
|
|
751
|
-
* public keys for Elliptic Curve cryptography algorithms (e.g., secp256k1,
|
|
752
|
-
* secp256k1r1, secp384r1, etc.) are always represented with compressed point
|
|
753
|
-
* encoding (e.g., secp256k1-pub, p256-pub, p384-pub, etc.).
|
|
754
|
-
*
|
|
755
|
-
* Per {@link https://datatracker.ietf.org/doc/html/rfc8812#name-jose-and-cose-secp256k1-cur | RFC 8812}:
|
|
756
|
-
* "As a compressed point encoding representation is not defined for JWK
|
|
757
|
-
* elliptic curve points, the uncompressed point encoding defined there
|
|
758
|
-
* MUST be used. The x and y values represented MUST both be exactly
|
|
759
|
-
* 256 bits, with any leading zeros preserved.
|
|
760
|
-
*
|
|
761
|
-
*/
|
|
762
|
-
public static async jwkToMultibaseId(options: {
|
|
763
|
-
key: JsonWebKey
|
|
764
|
-
}): Promise<string> {
|
|
765
|
-
const jsonWebKey = options.key;
|
|
766
|
-
|
|
767
|
-
// Convert the algorithm into Multicodec name format.
|
|
768
|
-
const { name: multicodecName } = await Jose.joseToMulticodec({ key: jsonWebKey });
|
|
769
|
-
|
|
770
|
-
// Decode the key as a raw binary data from the JWK.
|
|
771
|
-
let { keyMaterial } = await Jose.jwkToKey({ key: jsonWebKey });
|
|
772
|
-
|
|
773
|
-
// Convert secp256k1 public keys to compressed format.
|
|
774
|
-
if ('crv' in jsonWebKey && !('d' in jsonWebKey)) {
|
|
775
|
-
switch (jsonWebKey.crv) {
|
|
776
|
-
case 'secp256k1': {
|
|
777
|
-
keyMaterial = await Secp256k1.convertPublicKey({
|
|
778
|
-
publicKey : keyMaterial,
|
|
779
|
-
compressedPublicKey : true
|
|
780
|
-
});
|
|
781
|
-
break;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
// Compute the multibase identifier based on the provided key.
|
|
787
|
-
const multibaseId = keyToMultibaseId({ key: keyMaterial, multicodecName });
|
|
788
|
-
|
|
789
|
-
return multibaseId;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
public static async keyToJwk(options:
|
|
793
|
-
Partial<JsonWebKey> & {
|
|
794
|
-
keyMaterial: Uint8Array,
|
|
795
|
-
keyType: IDCrypto.KeyType,
|
|
796
|
-
}): Promise<JsonWebKey> {
|
|
797
|
-
const { keyMaterial, keyType, ...jsonWebKeyOptions } = options;
|
|
798
|
-
|
|
799
|
-
let jsonWebKey = { ...jsonWebKeyOptions } as JsonWebKey;
|
|
800
|
-
|
|
801
|
-
/**
|
|
802
|
-
* All Elliptic Curve (EC) and Octet Key Pair (OKP) keys
|
|
803
|
-
* specify a "crv" (named curve) parameter.
|
|
804
|
-
*/
|
|
805
|
-
if ('crv' in jsonWebKey) {
|
|
806
|
-
switch (jsonWebKey.crv) {
|
|
807
|
-
|
|
808
|
-
case 'Ed25519': {
|
|
809
|
-
const publicKey = (keyType === 'private')
|
|
810
|
-
? await Ed25519.getPublicKey({ privateKey: keyMaterial })
|
|
811
|
-
: keyMaterial;
|
|
812
|
-
jsonWebKey.x = Convert.uint8Array(publicKey).toBase64Url();
|
|
813
|
-
jsonWebKey.kty ??= 'OKP';
|
|
814
|
-
break;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
case 'X25519': {
|
|
818
|
-
const publicKey = (keyType === 'private')
|
|
819
|
-
? await X25519.getPublicKey({ privateKey: keyMaterial })
|
|
820
|
-
: keyMaterial;
|
|
821
|
-
jsonWebKey.x = Convert.uint8Array(publicKey).toBase64Url();
|
|
822
|
-
jsonWebKey.kty ??= 'OKP';
|
|
823
|
-
break;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
case 'secp256k1': {
|
|
827
|
-
const points = await Secp256k1.getCurvePoints({ key: keyMaterial });
|
|
828
|
-
jsonWebKey.x = Convert.uint8Array(points.x).toBase64Url();
|
|
829
|
-
jsonWebKey.y = Convert.uint8Array(points.y).toBase64Url();
|
|
830
|
-
jsonWebKey.kty ??= 'EC';
|
|
831
|
-
break;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
default: {
|
|
835
|
-
throw new Error(`Unsupported key to JWK conversion: ${jsonWebKey.crv}`);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
if (keyType === 'private') {
|
|
840
|
-
jsonWebKey = {
|
|
841
|
-
d: Convert.uint8Array(keyMaterial).toBase64Url(),
|
|
842
|
-
...jsonWebKey
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
/**
|
|
848
|
-
* All Octet Sequence (oct) symmetric encryption and signature keys
|
|
849
|
-
* specify only an "alg" parameter.
|
|
850
|
-
*/
|
|
851
|
-
if (!('crv' in jsonWebKey) && jsonWebKey.kty === 'oct') {
|
|
852
|
-
jsonWebKey.k = Convert.uint8Array(keyMaterial).toBase64Url();
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
return { ...jsonWebKey };
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
public static async multicodecToJose(options: {
|
|
859
|
-
code?: MulticodecCode,
|
|
860
|
-
name?: string
|
|
861
|
-
}): Promise<JsonWebKey> {
|
|
862
|
-
let { code, name } = options;
|
|
863
|
-
|
|
864
|
-
// Either code or name must be specified, but not both.
|
|
865
|
-
if (!(name ? !code : code)) {
|
|
866
|
-
throw new Error(`Either 'name' or 'code' must be defined, but not both.`);
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
// If name is undefined, lookup by code.
|
|
870
|
-
name = (name === undefined ) ? Multicodec.getNameFromCode({ code: code! }) : name;
|
|
871
|
-
|
|
872
|
-
const lookupKey: any = name;
|
|
873
|
-
const jose = multicodecToJoseMapping[lookupKey];
|
|
874
|
-
|
|
875
|
-
if (jose === undefined) {
|
|
876
|
-
throw new Error(`Unsupported Multicodec to JOSE conversion: '${options.name}'`);
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
return { ...jose };
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
public static webCryptoToJose(options:
|
|
883
|
-
IDCrypto.Algorithm | IDCrypto.GenerateKeyOptions
|
|
884
|
-
): Partial<JsonWebKey> {
|
|
885
|
-
const params: string[] = [];
|
|
886
|
-
|
|
887
|
-
/**
|
|
888
|
-
* All WebCrypto algorithms have the "named" parameter.
|
|
889
|
-
*/
|
|
890
|
-
params.push(options.name);
|
|
891
|
-
|
|
892
|
-
/**
|
|
893
|
-
* All Elliptic Curve (EC) WebCrypto algorithms
|
|
894
|
-
* set a value for the "namedCurve" parameter.
|
|
895
|
-
*/
|
|
896
|
-
if ('namedCurve' in options) {
|
|
897
|
-
params.push(options.namedCurve);
|
|
898
|
-
|
|
899
|
-
/**
|
|
900
|
-
* All symmetric encryption (AES) WebCrypto algorithms
|
|
901
|
-
* set a value for the "length" parameter.
|
|
902
|
-
*/
|
|
903
|
-
} else if ('length' in options && options.length !== undefined) {
|
|
904
|
-
params.push(options.length.toString());
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* All symmetric signature (HMAC) WebCrypto algorithms
|
|
908
|
-
* set a value for the "hash" parameter.
|
|
909
|
-
*/
|
|
910
|
-
} else if ('hash' in options) {
|
|
911
|
-
params.push(options.hash.name);
|
|
912
|
-
|
|
913
|
-
} else {
|
|
914
|
-
throw new TypeError(`One or more parameters missing: 'name', 'namedCurve', 'length', or 'hash'`);
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
const lookupKey = params.join(':');
|
|
918
|
-
const jose = webCryptoToJoseMapping[lookupKey];
|
|
919
|
-
|
|
920
|
-
if (jose === undefined) {
|
|
921
|
-
throw new Error(`Unsupported WebCrypto to JOSE conversion: '${lookupKey}'`);
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
return { ...jose };
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
private static canonicalize(obj: { [key: string]: any }): string {
|
|
928
|
-
const sortedKeys = Object.keys(obj).sort();
|
|
929
|
-
const sortedObj = sortedKeys.reduce<{ [key: string]: any }>((acc, key) => {
|
|
930
|
-
acc[key] = obj[key];
|
|
931
|
-
return acc;
|
|
932
|
-
}, {});
|
|
933
|
-
return JSON.stringify(sortedObj);
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
type Constructable = new (...args: any[]) => object;
|
|
938
|
-
|
|
939
|
-
export function CryptoKeyToJwkMixin<T extends Constructable>(Base: T) {
|
|
940
|
-
return class extends Base {
|
|
941
|
-
public async toJwk(): Promise<JsonWebKey> {
|
|
942
|
-
const jwk = Jose.cryptoKeyToJwk({ key: (this as unknown) as CryptoKey });
|
|
943
|
-
return jwk;
|
|
944
|
-
}
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
export const CryptoKeyWithJwk = CryptoKeyToJwkMixin(CryptoKey);
|