@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/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
- // Make sure x509 options are also set on the metadata as that is what the kms will look for
124
- if (args.options?.x509 && key) {
123
+ if (key) {
125
124
  key.meta = {
126
125
  ...key.meta,
127
- x509: {
128
- ...args.options.x509,
129
- ...key.meta?.x509,
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
- ? toJwk(key.privateKeyHex, key.type, { isPrivateKey: true })
176
- : undefined
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
- ? JwkKeyUse.Signature
437
- : ENC_KEY_ALGS.includes(type)
438
- ? JwkKeyUse.Encryption
439
- : undefined
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
- ? sha384
958
- : sha256
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
  }
@@ -30,6 +30,7 @@ export interface X509Opts {
30
30
  }
31
31
 
32
32
  export interface IImportProvidedOrGeneratedKeyArgs {
33
+ providerName: string
33
34
  kms?: string
34
35
  alias?: string
35
36
  options?: IKeyOpts