@sphereon/ssi-sdk-ext.key-utils 0.34.1-fix.80 → 0.34.1-next.299
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/index.cjs +30 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +31 -16
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/functions.ts +47 -30
- package/src/types/key-util-types.ts +1 -0
package/src/functions.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from '@ethersproject/random'
|
|
2
2
|
// Do not change these require statements to imports before we change to ESM. Breaks external CJS packages depending on this module
|
|
3
3
|
import { bls12_381 } from '@noble/curves/bls12-381'
|
|
4
|
-
import { ed25519 } from '@noble/curves/ed25519'
|
|
4
|
+
import { ed25519, x25519 } from '@noble/curves/ed25519'
|
|
5
5
|
import { p256 } from '@noble/curves/p256'
|
|
6
6
|
import { p384 } from '@noble/curves/p384'
|
|
7
7
|
import { p521 } from '@noble/curves/p521'
|
|
@@ -115,19 +115,25 @@ export async function importProvidedOrGeneratedKey(
|
|
|
115
115
|
args: IImportProvidedOrGeneratedKeyArgs & {
|
|
116
116
|
kms: string
|
|
117
117
|
},
|
|
118
|
-
context: IAgentContext<IKeyManager
|
|
118
|
+
context: IAgentContext<IKeyManager>,
|
|
119
119
|
): Promise<IKey> {
|
|
120
120
|
// @ts-ignore
|
|
121
121
|
const type = args.options?.type ?? args.options?.key?.type ?? args.options?.keyType ?? 'Secp256r1'
|
|
122
122
|
const key = args?.options?.key
|
|
123
|
-
|
|
124
|
-
if (args.options?.x509 && key) {
|
|
123
|
+
if (key) {
|
|
125
124
|
key.meta = {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
125
|
+
providerName: args.providerName,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Make sure x509 options are also set on the metadata as that is what the kms will look for
|
|
129
|
+
if (args.options?.x509) {
|
|
130
|
+
key.meta = {
|
|
131
|
+
...key.meta,
|
|
132
|
+
x509: {
|
|
133
|
+
...args.options.x509,
|
|
134
|
+
...key.meta?.x509,
|
|
135
|
+
},
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
}
|
|
133
139
|
|
|
@@ -172,8 +178,8 @@ export const calculateJwkThumbprintForKey = (args: {
|
|
|
172
178
|
const jwk = key.publicKeyHex
|
|
173
179
|
? toJwk(key.publicKeyHex, key.type, { key: key, isPrivateKey: false })
|
|
174
180
|
: 'privateKeyHex' in key && key.privateKeyHex
|
|
175
|
-
|
|
176
|
-
|
|
181
|
+
? toJwk(key.privateKeyHex, key.type, { isPrivateKey: true })
|
|
182
|
+
: undefined
|
|
177
183
|
if (!jwk) {
|
|
178
184
|
throw Error(`Could not determine jwk from key ${key.kid}`)
|
|
179
185
|
}
|
|
@@ -231,7 +237,7 @@ export const toJwkFromKey = (
|
|
|
231
237
|
opts?: {
|
|
232
238
|
use?: JwkKeyUse
|
|
233
239
|
noKidThumbprint?: boolean
|
|
234
|
-
}
|
|
240
|
+
},
|
|
235
241
|
): JWK => {
|
|
236
242
|
const isPrivateKey = 'privateKeyHex' in key
|
|
237
243
|
return toJwk(key.publicKeyHex!, key.type, { ...opts, key, isPrivateKey })
|
|
@@ -247,7 +253,7 @@ export const toJwkFromKey = (
|
|
|
247
253
|
export const toJwk = (
|
|
248
254
|
publicKeyHex: string,
|
|
249
255
|
type: TKeyType,
|
|
250
|
-
opts?: { use?: JwkKeyUse; key?: IKey | MinimalImportableKey; isPrivateKey?: boolean; noKidThumbprint?: boolean }
|
|
256
|
+
opts?: { use?: JwkKeyUse; key?: IKey | MinimalImportableKey; isPrivateKey?: boolean; noKidThumbprint?: boolean },
|
|
251
257
|
): JWK => {
|
|
252
258
|
const { key, noKidThumbprint = false } = opts ?? {}
|
|
253
259
|
if (key && key.publicKeyHex !== publicKeyHex && opts?.isPrivateKey !== true) {
|
|
@@ -367,7 +373,7 @@ export function rsaJwkToRawHexKey(jwk: JsonWebKey): string {
|
|
|
367
373
|
// We are converting from base64 to base64url to be sure. The spec uses base64url, but in the wild we sometimes encounter a base64 string
|
|
368
374
|
const modulus = fromString(jwk.n.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url') // 'n' is the modulus
|
|
369
375
|
const exponent = fromString(jwk.e.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url') // 'e' is the exponent
|
|
370
|
-
|
|
376
|
+
|
|
371
377
|
return toString(modulus, 'hex') + toString(exponent, 'hex')*/
|
|
372
378
|
}
|
|
373
379
|
|
|
@@ -423,6 +429,17 @@ function octJwkToRawHexKey(jwk: JsonWebKey): string {
|
|
|
423
429
|
return toString(key, 'hex')
|
|
424
430
|
}
|
|
425
431
|
|
|
432
|
+
export function x25519PublicHexFromPrivateHex(privateKeyHex: string): string {
|
|
433
|
+
if (!/^[0-9a-fA-F]{64}$/.test(privateKeyHex)) {
|
|
434
|
+
throw new Error('Private key must be 32-byte hex (64 chars)')
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const priv = Uint8Array.from(Buffer.from(privateKeyHex, 'hex'))
|
|
438
|
+
const pub = x25519.getPublicKey(priv)
|
|
439
|
+
|
|
440
|
+
return Buffer.from(pub).toString('hex')
|
|
441
|
+
}
|
|
442
|
+
|
|
426
443
|
/**
|
|
427
444
|
* Determines the use param based upon the key/signature type or supplied use value.
|
|
428
445
|
*
|
|
@@ -433,10 +450,10 @@ export const jwkDetermineUse = (type: TKeyType, suppliedUse?: JwkKeyUse): JwkKey
|
|
|
433
450
|
return suppliedUse
|
|
434
451
|
? suppliedUse
|
|
435
452
|
: SIG_KEY_ALGS.includes(type)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
453
|
+
? JwkKeyUse.Signature
|
|
454
|
+
: ENC_KEY_ALGS.includes(type)
|
|
455
|
+
? JwkKeyUse.Encryption
|
|
456
|
+
: undefined
|
|
440
457
|
}
|
|
441
458
|
|
|
442
459
|
/**
|
|
@@ -451,7 +468,7 @@ const assertProperKeyLength = (keyHex: string, expectedKeyLength: number | numbe
|
|
|
451
468
|
throw Error(
|
|
452
469
|
`Invalid key length. Needs to be a hex string with length from ${JSON.stringify(expectedKeyLength)} instead of ${
|
|
453
470
|
keyHex.length
|
|
454
|
-
}. Input: ${keyHex}
|
|
471
|
+
}. Input: ${keyHex}`,
|
|
455
472
|
)
|
|
456
473
|
}
|
|
457
474
|
} else if (keyHex.length !== expectedKeyLength) {
|
|
@@ -484,8 +501,8 @@ const toSecp256k1Jwk = (keyHex: string, opts?: { use?: JwkKeyUse; isPrivateKey?:
|
|
|
484
501
|
...(use !== undefined && { use }),
|
|
485
502
|
kty: JwkKeyType.EC,
|
|
486
503
|
crv: JoseCurve.secp256k1,
|
|
487
|
-
x: hexToBase64(pubPoint.getX().toString('hex'), 'base64url'),
|
|
488
|
-
y: hexToBase64(pubPoint.getY().toString('hex'), 'base64url'),
|
|
504
|
+
x: hexToBase64(pubPoint.getX().toString('hex').padStart(64, '0'), 'base64url'),
|
|
505
|
+
y: hexToBase64(pubPoint.getY().toString('hex').padStart(64, '0'), 'base64url'),
|
|
489
506
|
...(opts?.isPrivateKey && { d: hexToBase64(keyPair.getPrivate('hex'), 'base64url') }),
|
|
490
507
|
})
|
|
491
508
|
}
|
|
@@ -515,8 +532,8 @@ const toSecp256r1Jwk = (keyHex: string, opts?: { use?: JwkKeyUse; isPrivateKey?:
|
|
|
515
532
|
...(use !== undefined && { use }),
|
|
516
533
|
kty: JwkKeyType.EC,
|
|
517
534
|
crv: JoseCurve.P_256,
|
|
518
|
-
x: hexToBase64(pubPoint.getX().toString('hex'), 'base64url'),
|
|
519
|
-
y: hexToBase64(pubPoint.getY().toString('hex'), 'base64url'),
|
|
535
|
+
x: hexToBase64(pubPoint.getX().toString('hex').padStart(64, '0'), 'base64url'),
|
|
536
|
+
y: hexToBase64(pubPoint.getY().toString('hex').padStart(64, '0'), 'base64url'),
|
|
520
537
|
...(opts?.isPrivateKey && { d: hexToBase64(keyPair.getPrivate('hex'), 'base64url') }),
|
|
521
538
|
})
|
|
522
539
|
}
|
|
@@ -532,7 +549,7 @@ const toEd25519OrX25519Jwk = (
|
|
|
532
549
|
opts: {
|
|
533
550
|
use?: JwkKeyUse
|
|
534
551
|
crv: JoseCurve.Ed25519 | JoseCurve.X25519
|
|
535
|
-
}
|
|
552
|
+
},
|
|
536
553
|
): JWK => {
|
|
537
554
|
assertProperKeyLength(publicKeyHex, 64)
|
|
538
555
|
const { use } = opts ?? {}
|
|
@@ -954,8 +971,8 @@ export async function verifyRawSignature({
|
|
|
954
971
|
signatureAlgorithm === JoseSignatureAlgorithm.RS512 || signatureAlgorithm === JoseSignatureAlgorithm.PS512
|
|
955
972
|
? sha512
|
|
956
973
|
: signatureAlgorithm === JoseSignatureAlgorithm.RS384 || signatureAlgorithm === JoseSignatureAlgorithm.PS384
|
|
957
|
-
|
|
958
|
-
|
|
974
|
+
? sha384
|
|
975
|
+
: sha256
|
|
959
976
|
switch (signatureAlgorithm) {
|
|
960
977
|
case JoseSignatureAlgorithm.RS256:
|
|
961
978
|
return rsa.PKCS1_SHA256.verify(
|
|
@@ -964,7 +981,7 @@ export async function verifyRawSignature({
|
|
|
964
981
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
965
982
|
},
|
|
966
983
|
data,
|
|
967
|
-
signature
|
|
984
|
+
signature,
|
|
968
985
|
)
|
|
969
986
|
case JoseSignatureAlgorithm.RS384:
|
|
970
987
|
return rsa.PKCS1_SHA384.verify(
|
|
@@ -973,7 +990,7 @@ export async function verifyRawSignature({
|
|
|
973
990
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
974
991
|
},
|
|
975
992
|
data,
|
|
976
|
-
signature
|
|
993
|
+
signature,
|
|
977
994
|
)
|
|
978
995
|
case JoseSignatureAlgorithm.RS512:
|
|
979
996
|
return rsa.PKCS1_SHA512.verify(
|
|
@@ -982,7 +999,7 @@ export async function verifyRawSignature({
|
|
|
982
999
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
983
1000
|
},
|
|
984
1001
|
data,
|
|
985
|
-
signature
|
|
1002
|
+
signature,
|
|
986
1003
|
)
|
|
987
1004
|
case JoseSignatureAlgorithm.PS256:
|
|
988
1005
|
case JoseSignatureAlgorithm.PS384:
|
|
@@ -1002,7 +1019,7 @@ export async function verifyRawSignature({
|
|
|
1002
1019
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
1003
1020
|
},
|
|
1004
1021
|
data,
|
|
1005
|
-
signature
|
|
1022
|
+
signature,
|
|
1006
1023
|
)
|
|
1007
1024
|
}
|
|
1008
1025
|
}
|