@sphereon/ssi-sdk-ext.key-utils 0.34.1-next.91 → 0.36.1-feat.SSISDK.83.11
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 +29 -11
- 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 +30 -12
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/digest-methods.ts +1 -1
- package/src/functions.ts +48 -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,26 @@ 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
125
|
...key.meta,
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
providerName: args.providerName,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Make sure x509 options are also set on the metadata as that is what the kms will look for
|
|
130
|
+
if (args.options?.x509) {
|
|
131
|
+
key.meta = {
|
|
132
|
+
...key.meta,
|
|
133
|
+
x509: {
|
|
134
|
+
...args.options.x509,
|
|
135
|
+
...key.meta?.x509,
|
|
136
|
+
},
|
|
137
|
+
}
|
|
131
138
|
}
|
|
132
139
|
}
|
|
133
140
|
|
|
@@ -158,7 +165,7 @@ export async function importProvidedOrGeneratedKey(
|
|
|
158
165
|
meta: {
|
|
159
166
|
...key?.meta,
|
|
160
167
|
algorithms: keyMetaAlgorithmsFromKeyType(type),
|
|
161
|
-
keyAlias: args.alias,
|
|
168
|
+
...(key?.meta?.keyAlias ? {} : { keyAlias: args.alias }),
|
|
162
169
|
},
|
|
163
170
|
})
|
|
164
171
|
}
|
|
@@ -172,8 +179,8 @@ export const calculateJwkThumbprintForKey = (args: {
|
|
|
172
179
|
const jwk = key.publicKeyHex
|
|
173
180
|
? toJwk(key.publicKeyHex, key.type, { key: key, isPrivateKey: false })
|
|
174
181
|
: 'privateKeyHex' in key && key.privateKeyHex
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
? toJwk(key.privateKeyHex, key.type, { isPrivateKey: true })
|
|
183
|
+
: undefined
|
|
177
184
|
if (!jwk) {
|
|
178
185
|
throw Error(`Could not determine jwk from key ${key.kid}`)
|
|
179
186
|
}
|
|
@@ -231,7 +238,7 @@ export const toJwkFromKey = (
|
|
|
231
238
|
opts?: {
|
|
232
239
|
use?: JwkKeyUse
|
|
233
240
|
noKidThumbprint?: boolean
|
|
234
|
-
}
|
|
241
|
+
},
|
|
235
242
|
): JWK => {
|
|
236
243
|
const isPrivateKey = 'privateKeyHex' in key
|
|
237
244
|
return toJwk(key.publicKeyHex!, key.type, { ...opts, key, isPrivateKey })
|
|
@@ -247,7 +254,7 @@ export const toJwkFromKey = (
|
|
|
247
254
|
export const toJwk = (
|
|
248
255
|
publicKeyHex: string,
|
|
249
256
|
type: TKeyType,
|
|
250
|
-
opts?: { use?: JwkKeyUse; key?: IKey | MinimalImportableKey; isPrivateKey?: boolean; noKidThumbprint?: boolean }
|
|
257
|
+
opts?: { use?: JwkKeyUse; key?: IKey | MinimalImportableKey; isPrivateKey?: boolean; noKidThumbprint?: boolean },
|
|
251
258
|
): JWK => {
|
|
252
259
|
const { key, noKidThumbprint = false } = opts ?? {}
|
|
253
260
|
if (key && key.publicKeyHex !== publicKeyHex && opts?.isPrivateKey !== true) {
|
|
@@ -367,7 +374,7 @@ export function rsaJwkToRawHexKey(jwk: JsonWebKey): string {
|
|
|
367
374
|
// 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
375
|
const modulus = fromString(jwk.n.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url') // 'n' is the modulus
|
|
369
376
|
const exponent = fromString(jwk.e.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''), 'base64url') // 'e' is the exponent
|
|
370
|
-
|
|
377
|
+
|
|
371
378
|
return toString(modulus, 'hex') + toString(exponent, 'hex')*/
|
|
372
379
|
}
|
|
373
380
|
|
|
@@ -423,6 +430,17 @@ function octJwkToRawHexKey(jwk: JsonWebKey): string {
|
|
|
423
430
|
return toString(key, 'hex')
|
|
424
431
|
}
|
|
425
432
|
|
|
433
|
+
export function x25519PublicHexFromPrivateHex(privateKeyHex: string): string {
|
|
434
|
+
if (!/^[0-9a-fA-F]{64}$/.test(privateKeyHex)) {
|
|
435
|
+
throw new Error('Private key must be 32-byte hex (64 chars)')
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const priv = Uint8Array.from(Buffer.from(privateKeyHex, 'hex'))
|
|
439
|
+
const pub = x25519.getPublicKey(priv)
|
|
440
|
+
|
|
441
|
+
return Buffer.from(pub).toString('hex')
|
|
442
|
+
}
|
|
443
|
+
|
|
426
444
|
/**
|
|
427
445
|
* Determines the use param based upon the key/signature type or supplied use value.
|
|
428
446
|
*
|
|
@@ -433,10 +451,10 @@ export const jwkDetermineUse = (type: TKeyType, suppliedUse?: JwkKeyUse): JwkKey
|
|
|
433
451
|
return suppliedUse
|
|
434
452
|
? suppliedUse
|
|
435
453
|
: SIG_KEY_ALGS.includes(type)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
454
|
+
? JwkKeyUse.Signature
|
|
455
|
+
: ENC_KEY_ALGS.includes(type)
|
|
456
|
+
? JwkKeyUse.Encryption
|
|
457
|
+
: undefined
|
|
440
458
|
}
|
|
441
459
|
|
|
442
460
|
/**
|
|
@@ -451,7 +469,7 @@ const assertProperKeyLength = (keyHex: string, expectedKeyLength: number | numbe
|
|
|
451
469
|
throw Error(
|
|
452
470
|
`Invalid key length. Needs to be a hex string with length from ${JSON.stringify(expectedKeyLength)} instead of ${
|
|
453
471
|
keyHex.length
|
|
454
|
-
}. Input: ${keyHex}
|
|
472
|
+
}. Input: ${keyHex}`,
|
|
455
473
|
)
|
|
456
474
|
}
|
|
457
475
|
} else if (keyHex.length !== expectedKeyLength) {
|
|
@@ -484,8 +502,8 @@ const toSecp256k1Jwk = (keyHex: string, opts?: { use?: JwkKeyUse; isPrivateKey?:
|
|
|
484
502
|
...(use !== undefined && { use }),
|
|
485
503
|
kty: JwkKeyType.EC,
|
|
486
504
|
crv: JoseCurve.secp256k1,
|
|
487
|
-
x: hexToBase64(pubPoint.getX().toString('hex'), 'base64url'),
|
|
488
|
-
y: hexToBase64(pubPoint.getY().toString('hex'), 'base64url'),
|
|
505
|
+
x: hexToBase64(pubPoint.getX().toString('hex').padStart(64, '0'), 'base64url'),
|
|
506
|
+
y: hexToBase64(pubPoint.getY().toString('hex').padStart(64, '0'), 'base64url'),
|
|
489
507
|
...(opts?.isPrivateKey && { d: hexToBase64(keyPair.getPrivate('hex'), 'base64url') }),
|
|
490
508
|
})
|
|
491
509
|
}
|
|
@@ -515,8 +533,8 @@ const toSecp256r1Jwk = (keyHex: string, opts?: { use?: JwkKeyUse; isPrivateKey?:
|
|
|
515
533
|
...(use !== undefined && { use }),
|
|
516
534
|
kty: JwkKeyType.EC,
|
|
517
535
|
crv: JoseCurve.P_256,
|
|
518
|
-
x: hexToBase64(pubPoint.getX().toString('hex'), 'base64url'),
|
|
519
|
-
y: hexToBase64(pubPoint.getY().toString('hex'), 'base64url'),
|
|
536
|
+
x: hexToBase64(pubPoint.getX().toString('hex').padStart(64, '0'), 'base64url'),
|
|
537
|
+
y: hexToBase64(pubPoint.getY().toString('hex').padStart(64, '0'), 'base64url'),
|
|
520
538
|
...(opts?.isPrivateKey && { d: hexToBase64(keyPair.getPrivate('hex'), 'base64url') }),
|
|
521
539
|
})
|
|
522
540
|
}
|
|
@@ -532,7 +550,7 @@ const toEd25519OrX25519Jwk = (
|
|
|
532
550
|
opts: {
|
|
533
551
|
use?: JwkKeyUse
|
|
534
552
|
crv: JoseCurve.Ed25519 | JoseCurve.X25519
|
|
535
|
-
}
|
|
553
|
+
},
|
|
536
554
|
): JWK => {
|
|
537
555
|
assertProperKeyLength(publicKeyHex, 64)
|
|
538
556
|
const { use } = opts ?? {}
|
|
@@ -954,8 +972,8 @@ export async function verifyRawSignature({
|
|
|
954
972
|
signatureAlgorithm === JoseSignatureAlgorithm.RS512 || signatureAlgorithm === JoseSignatureAlgorithm.PS512
|
|
955
973
|
? sha512
|
|
956
974
|
: signatureAlgorithm === JoseSignatureAlgorithm.RS384 || signatureAlgorithm === JoseSignatureAlgorithm.PS384
|
|
957
|
-
|
|
958
|
-
|
|
975
|
+
? sha384
|
|
976
|
+
: sha256
|
|
959
977
|
switch (signatureAlgorithm) {
|
|
960
978
|
case JoseSignatureAlgorithm.RS256:
|
|
961
979
|
return rsa.PKCS1_SHA256.verify(
|
|
@@ -964,7 +982,7 @@ export async function verifyRawSignature({
|
|
|
964
982
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
965
983
|
},
|
|
966
984
|
data,
|
|
967
|
-
signature
|
|
985
|
+
signature,
|
|
968
986
|
)
|
|
969
987
|
case JoseSignatureAlgorithm.RS384:
|
|
970
988
|
return rsa.PKCS1_SHA384.verify(
|
|
@@ -973,7 +991,7 @@ export async function verifyRawSignature({
|
|
|
973
991
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
974
992
|
},
|
|
975
993
|
data,
|
|
976
|
-
signature
|
|
994
|
+
signature,
|
|
977
995
|
)
|
|
978
996
|
case JoseSignatureAlgorithm.RS512:
|
|
979
997
|
return rsa.PKCS1_SHA512.verify(
|
|
@@ -982,7 +1000,7 @@ export async function verifyRawSignature({
|
|
|
982
1000
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
983
1001
|
},
|
|
984
1002
|
data,
|
|
985
|
-
signature
|
|
1003
|
+
signature,
|
|
986
1004
|
)
|
|
987
1005
|
case JoseSignatureAlgorithm.PS256:
|
|
988
1006
|
case JoseSignatureAlgorithm.PS384:
|
|
@@ -1002,7 +1020,7 @@ export async function verifyRawSignature({
|
|
|
1002
1020
|
e: jwkPropertyToBigInt(jwk.e!),
|
|
1003
1021
|
},
|
|
1004
1022
|
data,
|
|
1005
|
-
signature
|
|
1023
|
+
signature,
|
|
1006
1024
|
)
|
|
1007
1025
|
}
|
|
1008
1026
|
}
|