@opentdf/sdk 0.9.0-beta.91 → 0.9.0-beta.93

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.
Files changed (182) hide show
  1. package/dist/cjs/src/access/access-fetch.js +1 -2
  2. package/dist/cjs/src/access/access-rpc.js +1 -3
  3. package/dist/cjs/src/access.js +1 -14
  4. package/dist/cjs/src/auth/auth.js +13 -10
  5. package/dist/cjs/src/auth/dpop.js +121 -0
  6. package/dist/cjs/src/auth/oidc-clientcredentials-provider.js +37 -3
  7. package/dist/cjs/src/auth/oidc-externaljwt-provider.js +37 -3
  8. package/dist/cjs/src/auth/oidc-refreshtoken-provider.js +37 -3
  9. package/dist/cjs/src/auth/oidc.js +10 -8
  10. package/dist/cjs/src/auth/providers.js +35 -12
  11. package/dist/cjs/src/crypto/index.js +16 -2
  12. package/dist/cjs/src/crypto/pemPublicToCrypto.js +17 -11
  13. package/dist/cjs/src/opentdf.js +40 -10
  14. package/dist/cjs/tdf3/index.js +4 -2
  15. package/dist/cjs/tdf3/src/assertions.js +71 -31
  16. package/dist/cjs/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
  17. package/dist/cjs/tdf3/src/ciphers/symmetric-cipher-base.js +4 -2
  18. package/dist/cjs/tdf3/src/client/index.js +23 -33
  19. package/dist/cjs/tdf3/src/crypto/crypto-utils.js +12 -5
  20. package/dist/cjs/tdf3/src/crypto/declarations.js +1 -1
  21. package/dist/cjs/tdf3/src/crypto/index.js +849 -88
  22. package/dist/cjs/tdf3/src/crypto/jose/jwt-claims-set.js +11 -0
  23. package/dist/cjs/tdf3/src/crypto/jose/validate-crit.js +8 -0
  24. package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/buffer_utils.js +41 -0
  25. package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/epoch.js +6 -0
  26. package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/is_object.js +21 -0
  27. package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.js +112 -0
  28. package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/secs.js +60 -0
  29. package/dist/cjs/tdf3/src/crypto/jose/vendor/lib/validate_crit.js +38 -0
  30. package/dist/cjs/tdf3/src/crypto/jose/vendor/util/errors.js +135 -0
  31. package/dist/cjs/tdf3/src/crypto/jwt.js +183 -0
  32. package/dist/cjs/tdf3/src/crypto/salt.js +14 -8
  33. package/dist/cjs/tdf3/src/models/encryption-information.js +17 -20
  34. package/dist/cjs/tdf3/src/models/key-access.js +43 -63
  35. package/dist/cjs/tdf3/src/tdf.js +75 -75
  36. package/dist/cjs/tdf3/src/utils/index.js +5 -39
  37. package/dist/types/src/access/access-fetch.d.ts.map +1 -1
  38. package/dist/types/src/access/access-rpc.d.ts.map +1 -1
  39. package/dist/types/src/access.d.ts +0 -5
  40. package/dist/types/src/access.d.ts.map +1 -1
  41. package/dist/types/src/auth/auth.d.ts +9 -6
  42. package/dist/types/src/auth/auth.d.ts.map +1 -1
  43. package/dist/types/src/auth/dpop.d.ts +60 -0
  44. package/dist/types/src/auth/dpop.d.ts.map +1 -0
  45. package/dist/types/src/auth/oidc-clientcredentials-provider.d.ts +3 -2
  46. package/dist/types/src/auth/oidc-clientcredentials-provider.d.ts.map +1 -1
  47. package/dist/types/src/auth/oidc-externaljwt-provider.d.ts +3 -2
  48. package/dist/types/src/auth/oidc-externaljwt-provider.d.ts.map +1 -1
  49. package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts +3 -2
  50. package/dist/types/src/auth/oidc-refreshtoken-provider.d.ts.map +1 -1
  51. package/dist/types/src/auth/oidc.d.ts +6 -4
  52. package/dist/types/src/auth/oidc.d.ts.map +1 -1
  53. package/dist/types/src/auth/providers.d.ts +5 -4
  54. package/dist/types/src/auth/providers.d.ts.map +1 -1
  55. package/dist/types/src/crypto/index.d.ts +2 -1
  56. package/dist/types/src/crypto/index.d.ts.map +1 -1
  57. package/dist/types/src/crypto/pemPublicToCrypto.d.ts +18 -0
  58. package/dist/types/src/crypto/pemPublicToCrypto.d.ts.map +1 -1
  59. package/dist/types/src/opentdf.d.ts +13 -4
  60. package/dist/types/src/opentdf.d.ts.map +1 -1
  61. package/dist/types/tdf3/index.d.ts +3 -3
  62. package/dist/types/tdf3/index.d.ts.map +1 -1
  63. package/dist/types/tdf3/src/assertions.d.ts +23 -8
  64. package/dist/types/tdf3/src/assertions.d.ts.map +1 -1
  65. package/dist/types/tdf3/src/ciphers/aes-gcm-cipher.d.ts +3 -3
  66. package/dist/types/tdf3/src/ciphers/aes-gcm-cipher.d.ts.map +1 -1
  67. package/dist/types/tdf3/src/ciphers/symmetric-cipher-base.d.ts +4 -4
  68. package/dist/types/tdf3/src/ciphers/symmetric-cipher-base.d.ts.map +1 -1
  69. package/dist/types/tdf3/src/client/builders.d.ts +2 -2
  70. package/dist/types/tdf3/src/client/builders.d.ts.map +1 -1
  71. package/dist/types/tdf3/src/client/index.d.ts +6 -5
  72. package/dist/types/tdf3/src/client/index.d.ts.map +1 -1
  73. package/dist/types/tdf3/src/crypto/crypto-utils.d.ts +14 -4
  74. package/dist/types/tdf3/src/crypto/crypto-utils.d.ts.map +1 -1
  75. package/dist/types/tdf3/src/crypto/declarations.d.ts +283 -18
  76. package/dist/types/tdf3/src/crypto/declarations.d.ts.map +1 -1
  77. package/dist/types/tdf3/src/crypto/index.d.ts +105 -28
  78. package/dist/types/tdf3/src/crypto/index.d.ts.map +1 -1
  79. package/dist/types/tdf3/src/crypto/jose/jwt-claims-set.d.ts +3 -0
  80. package/dist/types/tdf3/src/crypto/jose/jwt-claims-set.d.ts.map +1 -0
  81. package/dist/types/tdf3/src/crypto/jose/validate-crit.d.ts +5 -0
  82. package/dist/types/tdf3/src/crypto/jose/validate-crit.d.ts.map +1 -0
  83. package/dist/types/tdf3/src/crypto/jose/vendor/lib/buffer_utils.d.ts +6 -0
  84. package/dist/types/tdf3/src/crypto/jose/vendor/lib/buffer_utils.d.ts.map +1 -0
  85. package/dist/types/tdf3/src/crypto/jose/vendor/lib/epoch.d.ts +3 -0
  86. package/dist/types/tdf3/src/crypto/jose/vendor/lib/epoch.d.ts.map +1 -0
  87. package/dist/types/tdf3/src/crypto/jose/vendor/lib/is_object.d.ts +3 -0
  88. package/dist/types/tdf3/src/crypto/jose/vendor/lib/is_object.d.ts.map +1 -0
  89. package/dist/types/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.d.ts +3 -0
  90. package/dist/types/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.d.ts.map +1 -0
  91. package/dist/types/tdf3/src/crypto/jose/vendor/lib/secs.d.ts +3 -0
  92. package/dist/types/tdf3/src/crypto/jose/vendor/lib/secs.d.ts.map +1 -0
  93. package/dist/types/tdf3/src/crypto/jose/vendor/lib/validate_crit.d.ts +3 -0
  94. package/dist/types/tdf3/src/crypto/jose/vendor/lib/validate_crit.d.ts.map +1 -0
  95. package/dist/types/tdf3/src/crypto/jose/vendor/util/errors.d.ts +76 -0
  96. package/dist/types/tdf3/src/crypto/jose/vendor/util/errors.d.ts.map +1 -0
  97. package/dist/types/tdf3/src/crypto/jwt.d.ts +76 -0
  98. package/dist/types/tdf3/src/crypto/jwt.d.ts.map +1 -0
  99. package/dist/types/tdf3/src/crypto/salt.d.ts +6 -1
  100. package/dist/types/tdf3/src/crypto/salt.d.ts.map +1 -1
  101. package/dist/types/tdf3/src/models/encryption-information.d.ts +4 -4
  102. package/dist/types/tdf3/src/models/encryption-information.d.ts.map +1 -1
  103. package/dist/types/tdf3/src/models/key-access.d.ts +8 -5
  104. package/dist/types/tdf3/src/models/key-access.d.ts.map +1 -1
  105. package/dist/types/tdf3/src/tdf.d.ts +8 -8
  106. package/dist/types/tdf3/src/tdf.d.ts.map +1 -1
  107. package/dist/types/tdf3/src/utils/index.d.ts +4 -3
  108. package/dist/types/tdf3/src/utils/index.d.ts.map +1 -1
  109. package/dist/web/src/access/access-fetch.js +3 -4
  110. package/dist/web/src/access/access-rpc.js +3 -5
  111. package/dist/web/src/access.js +1 -13
  112. package/dist/web/src/auth/auth.js +13 -10
  113. package/dist/web/src/auth/dpop.js +118 -0
  114. package/dist/web/src/auth/oidc-clientcredentials-provider.js +4 -3
  115. package/dist/web/src/auth/oidc-externaljwt-provider.js +4 -3
  116. package/dist/web/src/auth/oidc-refreshtoken-provider.js +4 -3
  117. package/dist/web/src/auth/oidc.js +11 -9
  118. package/dist/web/src/auth/providers.js +13 -12
  119. package/dist/web/src/crypto/index.js +4 -2
  120. package/dist/web/src/crypto/pemPublicToCrypto.js +11 -9
  121. package/dist/web/src/opentdf.js +7 -10
  122. package/dist/web/tdf3/index.js +3 -2
  123. package/dist/web/tdf3/src/assertions.js +71 -31
  124. package/dist/web/tdf3/src/ciphers/aes-gcm-cipher.js +1 -1
  125. package/dist/web/tdf3/src/ciphers/symmetric-cipher-base.js +4 -2
  126. package/dist/web/tdf3/src/client/index.js +25 -35
  127. package/dist/web/tdf3/src/crypto/crypto-utils.js +12 -5
  128. package/dist/web/tdf3/src/crypto/declarations.js +1 -1
  129. package/dist/web/tdf3/src/crypto/index.js +830 -84
  130. package/dist/web/tdf3/src/crypto/jose/jwt-claims-set.js +5 -0
  131. package/dist/web/tdf3/src/crypto/jose/validate-crit.js +3 -0
  132. package/dist/web/tdf3/src/crypto/jose/vendor/lib/buffer_utils.js +35 -0
  133. package/dist/web/tdf3/src/crypto/jose/vendor/lib/epoch.js +4 -0
  134. package/dist/web/tdf3/src/crypto/jose/vendor/lib/is_object.js +19 -0
  135. package/dist/web/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.js +107 -0
  136. package/dist/web/tdf3/src/crypto/jose/vendor/lib/secs.js +58 -0
  137. package/dist/web/tdf3/src/crypto/jose/vendor/lib/validate_crit.js +36 -0
  138. package/dist/web/tdf3/src/crypto/jose/vendor/util/errors.js +117 -0
  139. package/dist/web/tdf3/src/crypto/jwt.js +174 -0
  140. package/dist/web/tdf3/src/crypto/salt.js +13 -7
  141. package/dist/web/tdf3/src/models/encryption-information.js +11 -14
  142. package/dist/web/tdf3/src/models/key-access.js +44 -31
  143. package/dist/web/tdf3/src/tdf.js +71 -71
  144. package/dist/web/tdf3/src/utils/index.js +5 -6
  145. package/package.json +11 -4
  146. package/src/access/access-fetch.ts +2 -8
  147. package/src/access/access-rpc.ts +0 -7
  148. package/src/access.ts +0 -17
  149. package/src/auth/auth.ts +21 -12
  150. package/src/auth/dpop.ts +222 -0
  151. package/src/auth/oidc-clientcredentials-provider.ts +23 -15
  152. package/src/auth/oidc-externaljwt-provider.ts +23 -15
  153. package/src/auth/oidc-refreshtoken-provider.ts +23 -15
  154. package/src/auth/oidc.ts +21 -10
  155. package/src/auth/providers.ts +46 -29
  156. package/src/crypto/index.ts +21 -1
  157. package/src/crypto/pemPublicToCrypto.ts +11 -9
  158. package/src/opentdf.ts +19 -14
  159. package/tdf3/index.ts +32 -5
  160. package/tdf3/src/assertions.ts +99 -30
  161. package/tdf3/src/ciphers/aes-gcm-cipher.ts +7 -2
  162. package/tdf3/src/ciphers/symmetric-cipher-base.ts +7 -4
  163. package/tdf3/src/client/builders.ts +2 -2
  164. package/tdf3/src/client/index.ts +60 -59
  165. package/tdf3/src/crypto/crypto-utils.ts +15 -8
  166. package/tdf3/src/crypto/declarations.ts +338 -22
  167. package/tdf3/src/crypto/index.ts +1021 -118
  168. package/tdf3/src/crypto/jose/jwt-claims-set.ts +10 -0
  169. package/tdf3/src/crypto/jose/validate-crit.ts +9 -0
  170. package/tdf3/src/crypto/jose/vendor/lib/buffer_utils.ts +34 -0
  171. package/tdf3/src/crypto/jose/vendor/lib/epoch.ts +3 -0
  172. package/tdf3/src/crypto/jose/vendor/lib/is_object.ts +18 -0
  173. package/tdf3/src/crypto/jose/vendor/lib/jwt_claims_set.ts +106 -0
  174. package/tdf3/src/crypto/jose/vendor/lib/secs.ts +57 -0
  175. package/tdf3/src/crypto/jose/vendor/lib/validate_crit.ts +35 -0
  176. package/tdf3/src/crypto/jose/vendor/util/errors.ts +101 -0
  177. package/tdf3/src/crypto/jwt.ts +256 -0
  178. package/tdf3/src/crypto/salt.ts +16 -8
  179. package/tdf3/src/models/encryption-information.ts +14 -21
  180. package/tdf3/src/models/key-access.ts +57 -41
  181. package/tdf3/src/tdf.ts +110 -93
  182. package/tdf3/src/utils/index.ts +5 -6
@@ -10,8 +10,12 @@ import { ConfigurationError, DecryptError } from '../../../src/errors.js';
10
10
  import { formatAsPem, removePemFormatting } from './crypto-utils.js';
11
11
  import { encodeArrayBuffer as hexEncode } from '../../../src/encodings/hex.js';
12
12
  import { decodeArrayBuffer as base64Decode } from '../../../src/encodings/base64.js';
13
+ import { exportSPKI, importX509 } from 'jose';
14
+ import { toJwsAlg, guessAlgorithmName, guessCurveName, } from '../../../src/crypto/pemPublicToCrypto.js';
15
+ import { keySplit, keyMerge } from '../utils/keysplit.js';
13
16
  // Used to pass into native crypto functions
14
- const METHODS = ['encrypt', 'decrypt'];
17
+ const ENC_DEC_METHODS = ['encrypt', 'decrypt'];
18
+ const SIGN_VERIFY_METHODS = ['sign', 'verify'];
15
19
  export const isSupported = typeof globalThis?.crypto !== 'undefined';
16
20
  export const method = 'http://www.w3.org/2001/04/xmlenc#aes256-cbc';
17
21
  export const name = 'BrowserNativeCryptoService';
@@ -46,11 +50,93 @@ export function rsaPkcs1Sha256(modulusLength = MIN_ASYMMETRIC_KEY_SIZE_BITS) {
46
50
  };
47
51
  }
48
52
  /**
49
- * Generate a random hex key
50
- * @return New key as a hex string
53
+ * Generate a random symmetric key (opaque).
54
+ * @param length - Key length in bytes (default 32 for AES-256)
55
+ * @return Opaque symmetric key
51
56
  */
52
57
  export async function generateKey(length) {
53
- return randomBytesAsHex(length || 32);
58
+ const keyBytes = await randomBytes(length || 32);
59
+ return wrapSymmetricKey(keyBytes);
60
+ }
61
+ // ============================================================
62
+ // Opaque Key Wrapping/Unwrapping Helpers
63
+ // ============================================================
64
+ /**
65
+ * Wrap a CryptoKey as an opaque PublicKey.
66
+ * @internal
67
+ */
68
+ function wrapPublicKey(key, algorithm) {
69
+ const result = {
70
+ _brand: 'PublicKey',
71
+ algorithm,
72
+ _internal: key,
73
+ };
74
+ if (algorithm.startsWith('rsa:')) {
75
+ result.modulusBits = parseInt(algorithm.split(':')[1], 10);
76
+ }
77
+ else if (algorithm.startsWith('ec:')) {
78
+ const curvePart = algorithm.split(':')[1];
79
+ result.curve =
80
+ curvePart === 'secp256r1'
81
+ ? 'P-256'
82
+ : curvePart === 'secp384r1'
83
+ ? 'P-384'
84
+ : curvePart === 'secp521r1'
85
+ ? 'P-521'
86
+ : undefined;
87
+ }
88
+ return result;
89
+ }
90
+ /**
91
+ * Wrap a CryptoKey as an opaque PrivateKey.
92
+ * @internal
93
+ */
94
+ function wrapPrivateKey(key, algorithm) {
95
+ const result = {
96
+ _brand: 'PrivateKey',
97
+ algorithm,
98
+ _internal: key,
99
+ };
100
+ if (algorithm.startsWith('rsa:')) {
101
+ result.modulusBits = parseInt(algorithm.split(':')[1], 10);
102
+ }
103
+ else if (algorithm.startsWith('ec:')) {
104
+ const curvePart = algorithm.split(':')[1];
105
+ result.curve =
106
+ curvePart === 'secp256r1'
107
+ ? 'P-256'
108
+ : curvePart === 'secp384r1'
109
+ ? 'P-384'
110
+ : curvePart === 'secp521r1'
111
+ ? 'P-521'
112
+ : undefined;
113
+ }
114
+ return result;
115
+ }
116
+ /**
117
+ * Unwrap an opaque key to get the internal CryptoKey.
118
+ * @internal
119
+ */
120
+ function unwrapKey(key) {
121
+ return key._internal;
122
+ }
123
+ /**
124
+ * Wrap raw key bytes as an opaque SymmetricKey.
125
+ * @internal
126
+ */
127
+ function wrapSymmetricKey(keyBytes) {
128
+ return {
129
+ _brand: 'SymmetricKey',
130
+ length: keyBytes.length * 8, // bits
131
+ _internal: keyBytes,
132
+ };
133
+ }
134
+ /**
135
+ * Unwrap an opaque SymmetricKey to get raw bytes.
136
+ * @internal
137
+ */
138
+ function unwrapSymmetricKey(key) {
139
+ return key._internal;
54
140
  }
55
141
  /**
56
142
  * Generate an RSA key pair
@@ -58,61 +144,60 @@ export async function generateKey(length) {
58
144
  * @param size in bits
59
145
  */
60
146
  export async function generateKeyPair(size) {
61
- const algoDomString = rsaOaepSha1(size || MIN_ASYMMETRIC_KEY_SIZE_BITS);
62
- return crypto.subtle.generateKey(algoDomString, true, METHODS);
147
+ const keySize = size || MIN_ASYMMETRIC_KEY_SIZE_BITS;
148
+ const algoDomString = rsaOaepSha1(keySize);
149
+ const keyPair = await crypto.subtle.generateKey(algoDomString, true, ENC_DEC_METHODS);
150
+ // Map to supported algorithm sizes
151
+ let algorithm;
152
+ if (keySize === 2048) {
153
+ algorithm = 'rsa:2048';
154
+ }
155
+ else if (keySize === 4096) {
156
+ algorithm = 'rsa:4096';
157
+ }
158
+ else {
159
+ throw new ConfigurationError(`Unsupported RSA key size: ${keySize}. Only 2048 and 4096 are supported.`);
160
+ }
161
+ return {
162
+ publicKey: wrapPublicKey(keyPair.publicKey, algorithm),
163
+ privateKey: wrapPrivateKey(keyPair.privateKey, algorithm),
164
+ };
63
165
  }
64
166
  /**
65
167
  * Generate an RSA key pair suitable for signatures
66
168
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey}
67
169
  */
68
170
  export async function generateSigningKeyPair() {
69
- return crypto.subtle.generateKey({
70
- name: 'RSASSA-PKCS1-v1_5',
71
- hash: 'SHA-256',
72
- modulusLength: 2048,
73
- publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
74
- }, true, ['sign', 'verify']);
75
- }
76
- export async function cryptoToPemPair(keysMaybe) {
77
- const keys = keysMaybe;
78
- if (!keys.privateKey || !keys.publicKey) {
79
- // These are only ever generated here, so this should not happen
80
- throw new Error('internal: invalid keys');
81
- }
82
- const [exPublic, exPrivate] = await Promise.all([
83
- crypto.subtle.exportKey('spki', keys.publicKey),
84
- crypto.subtle.exportKey('pkcs8', keys.privateKey),
85
- ]);
171
+ const rsaParams = rsaPkcs1Sha256(2048);
172
+ const keyPair = await crypto.subtle.generateKey(rsaParams, true, SIGN_VERIFY_METHODS);
173
+ const algorithm = 'rsa:2048';
86
174
  return {
87
- publicKey: formatAsPem(exPublic, 'PUBLIC KEY'),
88
- privateKey: formatAsPem(exPrivate, 'PRIVATE KEY'),
175
+ publicKey: wrapPublicKey(keyPair.publicKey, algorithm),
176
+ privateKey: wrapPrivateKey(keyPair.privateKey, algorithm),
89
177
  };
90
178
  }
91
179
  /**
92
- * Encrypt using a public key
93
- * @param payload Payload to encrypt
94
- * @param publicKey PEM formatted public key
180
+ * Encrypt using a public key (RSA-OAEP).
181
+ * Accepts Binary or SymmetricKey for key wrapping.
182
+ * @param payload Payload to encrypt (Binary) or symmetric key to wrap (SymmetricKey)
183
+ * @param publicKey Opaque public key
95
184
  * @return Encrypted payload
96
185
  */
97
186
  export async function encryptWithPublicKey(payload, publicKey) {
98
- console.assert(typeof payload === 'object');
99
- console.assert(typeof publicKey === 'string');
100
- const algoDomString = rsaOaepSha1();
101
- // Web Crypto APIs don't work with PEM formatted strings
102
- publicKey = removePemFormatting(publicKey);
103
- const keyBuffer = base64Decode(publicKey);
104
- const cryptoKey = await crypto.subtle.importKey('spki', keyBuffer, algoDomString, false, [
105
- 'encrypt',
106
- ]);
107
- const result = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, cryptoKey, payload.asArrayBuffer());
187
+ let payloadBuffer;
188
+ // Handle SymmetricKey unwrapping
189
+ if ('_brand' in payload && payload._brand === 'SymmetricKey') {
190
+ // Pass Uint8Array directly — Web Crypto respects byteOffset/byteLength on typed array views.
191
+ payloadBuffer = unwrapSymmetricKey(payload);
192
+ }
193
+ else {
194
+ // Binary payload
195
+ payloadBuffer = payload.asArrayBuffer();
196
+ }
197
+ const cryptoKey = unwrapKey(publicKey);
198
+ const result = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, cryptoKey, payloadBuffer);
108
199
  return Binary.fromArrayBuffer(result);
109
200
  }
110
- /**
111
- * Generate a 16-byte initialization vector
112
- */
113
- export async function generateInitializationVector(length) {
114
- return randomBytesAsHex(length || 16);
115
- }
116
201
  export async function randomBytes(byteLength) {
117
202
  const r = new Uint8Array(byteLength);
118
203
  crypto.getRandomValues(r);
@@ -137,25 +222,20 @@ export async function randomBytesAsHex(length) {
137
222
  /**
138
223
  * Decrypt a public-key encrypted payload with a private key
139
224
  * @param encryptedPayload Payload to decrypt
140
- * @param privateKey PEM formatted private keynpmv
225
+ * @param privateKey Opaque private key
141
226
  * @return Decrypted payload
142
227
  */
143
228
  export async function decryptWithPrivateKey(encryptedPayload, privateKey) {
144
229
  console.assert(typeof encryptedPayload === 'object', 'encryptedPayload must be object');
145
- console.assert(typeof privateKey === 'string', 'privateKey must be string');
146
- const algoDomString = rsaOaepSha1();
147
- // Web Crypto APIs don't work with PEM formatted strings
148
- const keyDataString = removePemFormatting(privateKey);
149
- const keyData = base64Decode(keyDataString);
150
- const key = await crypto.subtle.importKey('pkcs8', keyData, algoDomString, false, ['decrypt']);
151
- const payload = await crypto.subtle.decrypt({ name: 'RSA-OAEP' }, key, encryptedPayload.asArrayBuffer());
230
+ const cryptoKey = unwrapKey(privateKey);
231
+ const payload = await crypto.subtle.decrypt({ name: 'RSA-OAEP' }, cryptoKey, encryptedPayload.asArrayBuffer());
152
232
  const bufferView = new Uint8Array(payload);
153
233
  return Binary.fromArrayBuffer(bufferView.buffer);
154
234
  }
155
235
  /**
156
236
  * Decrypt content synchronously
157
237
  * @param payload The payload to decrypt
158
- * @param key The encryption key
238
+ * @param key The symmetric encryption key (opaque)
159
239
  * @param iv The initialization vector
160
240
  * @param algorithm The algorithm to use for encryption
161
241
  * @param authTag The authentication tag for authenticated crypto.
@@ -177,9 +257,20 @@ async function _doEncrypt(payload, key, iv, algorithm) {
177
257
  console.assert(payload != null);
178
258
  console.assert(key != null);
179
259
  console.assert(iv != null);
180
- const payloadBuffer = payload.asArrayBuffer();
260
+ // Handle both Binary and SymmetricKey payloads
261
+ let payloadBuffer;
262
+ if ('_brand' in payload && payload._brand === 'SymmetricKey') {
263
+ // Pass Uint8Array directly — Web Crypto respects byteOffset/byteLength on typed array views.
264
+ payloadBuffer = unwrapSymmetricKey(payload);
265
+ }
266
+ else {
267
+ // Binary payload
268
+ payloadBuffer = payload.asArrayBuffer();
269
+ }
181
270
  const algoDomString = getSymmetricAlgoDomString(iv, algorithm);
182
- const importedKey = await _importKey(key, algoDomString);
271
+ // Unwrap symmetric key to get raw bytes
272
+ const keyBytes = unwrapSymmetricKey(key);
273
+ const importedKey = await _importKey(keyBytes, algoDomString);
183
274
  const encrypted = await crypto.subtle.encrypt(algoDomString, importedKey, payloadBuffer);
184
275
  if (algoDomString.name === 'AES-GCM') {
185
276
  return {
@@ -205,7 +296,9 @@ async function _doDecrypt(payload, key, iv, algorithm, authTag) {
205
296
  payloadBuffer = gcmPayload.buffer;
206
297
  }
207
298
  const algoDomString = getSymmetricAlgoDomString(iv, algorithm);
208
- const importedKey = await _importKey(key, algoDomString);
299
+ // Unwrap symmetric key to get raw bytes
300
+ const keyBytes = unwrapSymmetricKey(key);
301
+ const importedKey = await _importKey(keyBytes, algoDomString);
209
302
  algoDomString.iv = iv.asArrayBuffer();
210
303
  const decrypted = await crypto.subtle
211
304
  .decrypt(algoDomString, importedKey, payloadBuffer)
@@ -218,8 +311,8 @@ async function _doDecrypt(payload, key, iv, algorithm, authTag) {
218
311
  });
219
312
  return { payload: Binary.fromArrayBuffer(decrypted) };
220
313
  }
221
- function _importKey(key, algorithm) {
222
- return crypto.subtle.importKey('raw', key.asArrayBuffer(), algorithm, true, METHODS);
314
+ function _importKey(keyBytes, algorithm) {
315
+ return crypto.subtle.importKey('raw', keyBytes, algorithm, true, ENC_DEC_METHODS);
223
316
  }
224
317
  /**
225
318
  * Get a DOMString representing the algorithm to use for a crypto
@@ -243,27 +336,6 @@ function getSymmetricAlgoDomString(iv, algorithm) {
243
336
  * @param content String content
244
337
  * @return Hex hash
245
338
  */
246
- export async function sha256(content) {
247
- const buffer = new TextEncoder().encode(content);
248
- const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
249
- return hexEncode(hashBuffer);
250
- }
251
- /**
252
- * Create an HMAC SHA256 hash
253
- * @param key Key string
254
- * @param content Content string
255
- * @return Hex hash
256
- */
257
- export async function hmac(key, content) {
258
- const contentBuffer = new TextEncoder().encode(content);
259
- const keyBuffer = hex2Ab(key);
260
- const cryptoKey = await crypto.subtle.importKey('raw', keyBuffer, {
261
- name: 'HMAC',
262
- hash: { name: 'SHA-256' },
263
- }, true, ['sign', 'verify']);
264
- const hashBuffer = await crypto.subtle.sign('HMAC', cryptoKey, contentBuffer);
265
- return hexEncode(hashBuffer);
266
- }
267
339
  /**
268
340
  * Create an ArrayBuffer from a hex string.
269
341
  * https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String?hl=en
@@ -277,20 +349,694 @@ export function hex2Ab(hex) {
277
349
  }
278
350
  return buffer;
279
351
  }
352
+ /**
353
+ * Get the Web Crypto algorithm parameters for a signing algorithm.
354
+ */
355
+ function getSigningAlgorithmParams(algorithm) {
356
+ switch (algorithm) {
357
+ case 'RS256':
358
+ return {
359
+ importParams: { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },
360
+ signParams: 'RSASSA-PKCS1-v1_5',
361
+ };
362
+ case 'ES256':
363
+ return {
364
+ importParams: { name: 'ECDSA', namedCurve: 'P-256' },
365
+ signParams: { name: 'ECDSA', hash: 'SHA-256' },
366
+ };
367
+ case 'ES384':
368
+ return {
369
+ importParams: { name: 'ECDSA', namedCurve: 'P-384' },
370
+ signParams: { name: 'ECDSA', hash: 'SHA-384' },
371
+ };
372
+ case 'ES512':
373
+ return {
374
+ importParams: { name: 'ECDSA', namedCurve: 'P-521' },
375
+ signParams: { name: 'ECDSA', hash: 'SHA-512' },
376
+ };
377
+ default:
378
+ throw new ConfigurationError(`Unsupported signing algorithm: ${algorithm}`);
379
+ }
380
+ }
381
+ /**
382
+ * Convert IEEE P1363 signature format (used by WebCrypto ECDSA) to DER format (used by JWT).
383
+ * RS256 signatures don't need conversion.
384
+ */
385
+ function ieeeP1363ToDer(signature, algorithm) {
386
+ if (algorithm === 'RS256') {
387
+ return signature;
388
+ }
389
+ // IEEE P1363: r || s where each is padded to key size
390
+ const halfLen = signature.length / 2;
391
+ const r = signature.slice(0, halfLen);
392
+ const s = signature.slice(halfLen);
393
+ // Remove leading zeros but keep one if the high bit is set
394
+ const trimLeadingZeros = (arr) => {
395
+ let i = 0;
396
+ while (i < arr.length - 1 && arr[i] === 0)
397
+ i++;
398
+ return arr.slice(i);
399
+ };
400
+ let rTrimmed = trimLeadingZeros(r);
401
+ let sTrimmed = trimLeadingZeros(s);
402
+ // Add leading zero if high bit is set (to keep positive in DER)
403
+ if (rTrimmed[0] & 0x80) {
404
+ const padded = new Uint8Array(rTrimmed.length + 1);
405
+ padded.set(rTrimmed, 1);
406
+ rTrimmed = padded;
407
+ }
408
+ if (sTrimmed[0] & 0x80) {
409
+ const padded = new Uint8Array(sTrimmed.length + 1);
410
+ padded.set(sTrimmed, 1);
411
+ sTrimmed = padded;
412
+ }
413
+ // DER SEQUENCE: 0x30 [length] [r INTEGER] [s INTEGER]
414
+ // INTEGER: 0x02 [length] [value]
415
+ const rDer = new Uint8Array([0x02, rTrimmed.length, ...rTrimmed]);
416
+ const sDer = new Uint8Array([0x02, sTrimmed.length, ...sTrimmed]);
417
+ const seqLen = rDer.length + sDer.length;
418
+ // DER length: short-form for < 128, long-form (0x81 nn) for 128-255.
419
+ // ECDSA sequences never exceed 255 bytes for any supported curve.
420
+ const lenBytes = seqLen < 128 ? new Uint8Array([seqLen]) : new Uint8Array([0x81, seqLen]);
421
+ const result = new Uint8Array(1 + lenBytes.length + seqLen);
422
+ result[0] = 0x30;
423
+ result.set(lenBytes, 1);
424
+ result.set(rDer, 1 + lenBytes.length);
425
+ result.set(sDer, 1 + lenBytes.length + rDer.length);
426
+ return result;
427
+ }
428
+ /**
429
+ * Convert DER signature format (used by JWT) to IEEE P1363 format (used by WebCrypto ECDSA).
430
+ * RS256 signatures don't need conversion.
431
+ */
432
+ function derToIeeeP1363(signature, algorithm) {
433
+ if (algorithm === 'RS256') {
434
+ return signature;
435
+ }
436
+ // Determine the expected component length based on algorithm
437
+ let componentLen;
438
+ switch (algorithm) {
439
+ case 'ES256':
440
+ componentLen = 32;
441
+ break;
442
+ case 'ES384':
443
+ componentLen = 48;
444
+ break;
445
+ case 'ES512':
446
+ componentLen = 66;
447
+ break;
448
+ default:
449
+ throw new ConfigurationError(`Unsupported algorithm for DER conversion: ${algorithm}`);
450
+ }
451
+ // Parse DER: SEQUENCE { INTEGER r, INTEGER s }
452
+ if (signature[0] !== 0x30) {
453
+ throw new ConfigurationError('Invalid DER signature: expected SEQUENCE');
454
+ }
455
+ // Skip SEQUENCE tag, then parse DER length (short- or long-form).
456
+ let offset = 1;
457
+ if (signature[offset] & 0x80) {
458
+ // Long-form: low 7 bits = number of subsequent length bytes.
459
+ const lenBytesCount = signature[offset] & 0x7f;
460
+ if (lenBytesCount === 0 || lenBytesCount > 4) {
461
+ throw new ConfigurationError('Invalid DER signature: invalid long-form length');
462
+ }
463
+ offset += 1 + lenBytesCount;
464
+ if (offset > signature.length) {
465
+ throw new ConfigurationError('Invalid DER signature: length bytes exceed signature length');
466
+ }
467
+ }
468
+ else {
469
+ // Short-form: single length byte.
470
+ offset += 1;
471
+ }
472
+ // Parse r INTEGER
473
+ if (signature[offset] !== 0x02) {
474
+ throw new ConfigurationError('Invalid DER signature: expected INTEGER for r');
475
+ }
476
+ const rLen = signature[offset + 1];
477
+ offset += 2;
478
+ let r = signature.slice(offset, offset + rLen);
479
+ offset += rLen;
480
+ // Parse s INTEGER
481
+ if (signature[offset] !== 0x02) {
482
+ throw new ConfigurationError('Invalid DER signature: expected INTEGER for s');
483
+ }
484
+ const sLen = signature[offset + 1];
485
+ offset += 2;
486
+ let s = signature.slice(offset, offset + sLen);
487
+ // Remove leading zero padding if present
488
+ if (r[0] === 0 && r.length > componentLen) {
489
+ r = r.slice(1);
490
+ }
491
+ if (s[0] === 0 && s.length > componentLen) {
492
+ s = s.slice(1);
493
+ }
494
+ // Pad to component length
495
+ const result = new Uint8Array(componentLen * 2);
496
+ result.set(r, componentLen - r.length);
497
+ result.set(s, componentLen * 2 - s.length);
498
+ return result;
499
+ }
500
+ /**
501
+ * Sign data with an asymmetric private key.
502
+ */
503
+ export async function sign(data, privateKey, algorithm) {
504
+ const { signParams } = getSigningAlgorithmParams(algorithm);
505
+ // Unwrap the internal CryptoKey
506
+ const key = unwrapKey(privateKey);
507
+ // Sign the data
508
+ const signature = await crypto.subtle.sign(signParams, key, data);
509
+ // Convert from IEEE P1363 to DER for EC algorithms
510
+ return ieeeP1363ToDer(new Uint8Array(signature), algorithm);
511
+ }
512
+ /**
513
+ * Verify signature with an asymmetric public key.
514
+ */
515
+ export async function verify(data, signature, publicKey, algorithm) {
516
+ const { signParams } = getSigningAlgorithmParams(algorithm);
517
+ // Unwrap the internal CryptoKey
518
+ const key = unwrapKey(publicKey);
519
+ // Convert from DER to IEEE P1363 for EC algorithms
520
+ const ieeeSignature = derToIeeeP1363(signature, algorithm);
521
+ // Verify the signature
522
+ return crypto.subtle.verify(signParams, key, ieeeSignature, data);
523
+ }
524
+ /**
525
+ * Compute hash digest.
526
+ */
527
+ export async function digest(algorithm, data) {
528
+ // Validate algorithm and map to Web Crypto name
529
+ const validAlgorithms = ['SHA-256', 'SHA-384', 'SHA-512'];
530
+ if (!validAlgorithms.includes(algorithm)) {
531
+ throw new ConfigurationError(`Unsupported hash algorithm: ${algorithm}`);
532
+ }
533
+ const hashBuffer = await crypto.subtle.digest(algorithm, data);
534
+ return new Uint8Array(hashBuffer);
535
+ }
536
+ /**
537
+ * Extract PEM public key from X.509 certificate or return PEM key as-is.
538
+ *
539
+ * @param certOrPem - A PEM-encoded X.509 certificate or public key
540
+ * @param jwaAlgorithm - JWA algorithm hint for certificate parsing (RS256, RS512, ES256, ES384, ES512).
541
+ * If not provided for a certificate, will attempt to auto-detect from OIDs.
542
+ */
543
+ export async function extractPublicKeyPem(certOrPem, jwaAlgorithm) {
544
+ // If it's a certificate, extract the public key
545
+ if (certOrPem.includes('-----BEGIN CERTIFICATE-----')) {
546
+ let alg = jwaAlgorithm;
547
+ if (!alg) {
548
+ // Auto-detect algorithm from certificate OIDs
549
+ const certBody = certOrPem.replace(/-----(BEGIN|END) CERTIFICATE-----|\s/g, '');
550
+ const certBytes = base64Decode(certBody);
551
+ const hex = hexEncode(certBytes);
552
+ alg = toJwsAlg(hex);
553
+ }
554
+ const cert = await importX509(certOrPem, alg, { extractable: true });
555
+ return exportSPKI(cert);
556
+ }
557
+ // If it's already a PEM public key, return as-is
558
+ if (certOrPem.includes('-----BEGIN PUBLIC KEY-----')) {
559
+ return certOrPem;
560
+ }
561
+ throw new ConfigurationError('Input must be a PEM-encoded certificate or public key');
562
+ }
563
+ /**
564
+ * Map ECCurve to Web Crypto named curve.
565
+ */
566
+ function curveToNamedCurve(curve) {
567
+ switch (curve) {
568
+ case 'P-256':
569
+ return 'P-256';
570
+ case 'P-384':
571
+ return 'P-384';
572
+ case 'P-521':
573
+ return 'P-521';
574
+ default:
575
+ throw new ConfigurationError(`Unsupported curve: ${curve}`);
576
+ }
577
+ }
578
+ /**
579
+ * Generate an EC key pair for ECDH key agreement.
580
+ */
581
+ export async function generateECKeyPair(curve = 'P-256') {
582
+ const namedCurve = curveToNamedCurve(curve);
583
+ // Generate key pair for ECDH key agreement
584
+ const keyPair = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve }, true, [
585
+ 'deriveBits',
586
+ ]);
587
+ // Map to KeyAlgorithm literal type
588
+ let algorithm;
589
+ switch (namedCurve) {
590
+ case 'P-256':
591
+ algorithm = 'ec:secp256r1';
592
+ break;
593
+ case 'P-384':
594
+ algorithm = 'ec:secp384r1';
595
+ break;
596
+ case 'P-521':
597
+ algorithm = 'ec:secp521r1';
598
+ break;
599
+ default:
600
+ throw new ConfigurationError(`Unsupported curve: ${namedCurve}`);
601
+ }
602
+ return {
603
+ publicKey: wrapPublicKey(keyPair.publicKey, algorithm),
604
+ privateKey: wrapPrivateKey(keyPair.privateKey, algorithm),
605
+ };
606
+ }
607
+ /**
608
+ * Supported EC curves.
609
+ */
610
+ const SUPPORTED_EC_CURVES = ['P-256', 'P-384', 'P-521'];
611
+ /**
612
+ * Decode base64url string and return byte length.
613
+ * Uses the existing base64 decoder which handles both standard and URL-safe encoding.
614
+ */
615
+ function base64urlByteLength(base64url) {
616
+ // Add padding if needed (base64url omits padding)
617
+ const padding = (4 - (base64url.length % 4)) % 4;
618
+ const padded = base64url + '='.repeat(padding);
619
+ return base64Decode(padded).byteLength;
620
+ }
621
+ /**
622
+ * Extract EC curve from a public key by parsing ASN.1 OIDs.
623
+ * Reuses the existing guessCurveName function that checks for curve OIDs.
624
+ */
625
+ function extractEcCurveFromPublicKey(keyData) {
626
+ // Convert to hex for OID parsing
627
+ const hexKey = hexEncode(keyData);
628
+ // Use existing OID parser (returns 'P-256', 'P-384', or 'P-521')
629
+ const curveName = guessCurveName(hexKey);
630
+ return curveName;
631
+ }
632
+ /**
633
+ * Perform ECDH key agreement followed by HKDF key derivation.
634
+ * Returns opaque symmetric key for symmetric encryption.
635
+ */
636
+ export async function deriveKeyFromECDH(privateKey, publicKey, hkdfParams) {
637
+ // Unwrap the internal CryptoKeys
638
+ const privateKeyCrypto = unwrapKey(privateKey);
639
+ const publicKeyCrypto = unwrapKey(publicKey);
640
+ // Get curve from key metadata
641
+ const curve = publicKey.curve;
642
+ if (!curve) {
643
+ throw new ConfigurationError('EC curve not found on public key');
644
+ }
645
+ // Determine bits based on curve
646
+ const curveBits = {
647
+ 'P-256': 256,
648
+ 'P-384': 384,
649
+ 'P-521': 528, // P-521 derives 528 bits (66 bytes)
650
+ };
651
+ const bits = curveBits[curve];
652
+ // Perform ECDH to get shared secret
653
+ const sharedSecret = await crypto.subtle.deriveBits({ name: 'ECDH', public: publicKeyCrypto }, privateKeyCrypto, bits);
654
+ // Import shared secret as HKDF key material
655
+ const hkdfKey = await crypto.subtle.importKey('raw', sharedSecret, 'HKDF', false, ['deriveKey']);
656
+ // Derive the final key using HKDF
657
+ const keyLength = hkdfParams.keyLength ?? 256;
658
+ const derivedKey = await crypto.subtle.deriveKey({
659
+ name: 'HKDF',
660
+ hash: hkdfParams.hash,
661
+ salt: hkdfParams.salt,
662
+ info: hkdfParams.info ?? new Uint8Array(0),
663
+ }, hkdfKey, { name: 'AES-GCM', length: keyLength }, true, ['encrypt', 'decrypt']);
664
+ // Export the derived key as raw bytes and wrap as SymmetricKey
665
+ const keyBytes = await crypto.subtle.exportKey('raw', derivedKey);
666
+ return wrapSymmetricKey(new Uint8Array(keyBytes));
667
+ }
668
+ /**
669
+ * Compute HMAC-SHA256 of data with a symmetric key.
670
+ */
671
+ export async function hmac(data, key) {
672
+ // Unwrap symmetric key to get raw bytes
673
+ const keyBytes = unwrapSymmetricKey(key);
674
+ const cryptoKey = await crypto.subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
675
+ const signature = await crypto.subtle.sign('HMAC', cryptoKey, data);
676
+ return new Uint8Array(signature);
677
+ }
678
+ /**
679
+ * Verify HMAC-SHA256. Standalone utility — not part of CryptoService interface.
680
+ */
681
+ export async function verifyHmac(data, signature, key) {
682
+ const keyBytes = unwrapSymmetricKey(key);
683
+ const cryptoKey = await crypto.subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
684
+ return crypto.subtle.verify('HMAC', cryptoKey, signature, data);
685
+ }
686
+ /**
687
+ * Extract RSA modulus bit length by importing key and exporting as JWK.
688
+ * Uses Web Crypto's built-in ASN.1 parsing for robustness.
689
+ */
690
+ async function extractRsaModulusBitLength(keyData) {
691
+ const key = await crypto.subtle.importKey('spki', keyData, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, // extractable
692
+ ['encrypt']);
693
+ const jwk = await crypto.subtle.exportKey('jwk', key);
694
+ if (!jwk.n) {
695
+ throw new ConfigurationError('Invalid RSA key: missing modulus');
696
+ }
697
+ // JWK 'n' is base64url-encoded modulus
698
+ // Decode and count bytes, multiply by 8 for bits
699
+ return base64urlByteLength(jwk.n) * 8;
700
+ }
701
+ /**
702
+ * Import and validate a PEM public key, returning algorithm info.
703
+ * Uses JWK export for robust key parameter detection.
704
+ */
705
+ export async function parsePublicKeyPem(pem) {
706
+ // First extract public key if it's a certificate
707
+ let publicKeyPem = pem;
708
+ if (pem.includes('-----BEGIN CERTIFICATE-----')) {
709
+ publicKeyPem = await extractPublicKeyPem(pem);
710
+ }
711
+ if (!publicKeyPem.includes('-----BEGIN PUBLIC KEY-----')) {
712
+ throw new ConfigurationError('Input must be a PEM-encoded public key or certificate');
713
+ }
714
+ const keyData = base64Decode(removePemFormatting(publicKeyPem));
715
+ // Try RSA first - use JWK export to get modulus size
716
+ try {
717
+ const modulusBits = await extractRsaModulusBitLength(keyData);
718
+ let algorithm;
719
+ if (modulusBits < MIN_ASYMMETRIC_KEY_SIZE_BITS) {
720
+ throw new ConfigurationError(`RSA key size ${modulusBits} bits is below the minimum of ${MIN_ASYMMETRIC_KEY_SIZE_BITS} bits`);
721
+ }
722
+ else if (modulusBits <= 2048) {
723
+ algorithm = 'rsa:2048';
724
+ }
725
+ else if (modulusBits <= 4096) {
726
+ algorithm = 'rsa:4096';
727
+ }
728
+ else {
729
+ throw new ConfigurationError(`Unsupported RSA key size: ${modulusBits} bits`);
730
+ }
731
+ return { algorithm, pem: publicKeyPem };
732
+ }
733
+ catch (e) {
734
+ // If it's our own ConfigurationError, rethrow
735
+ if (e instanceof ConfigurationError) {
736
+ throw e;
737
+ }
738
+ // Not an RSA key, try EC next
739
+ }
740
+ // Try EC - parse curve from OID
741
+ try {
742
+ const detectedCurve = extractEcCurveFromPublicKey(keyData);
743
+ const curveMap = {
744
+ 'P-256': 'ec:secp256r1',
745
+ 'P-384': 'ec:secp384r1',
746
+ 'P-521': 'ec:secp521r1',
747
+ };
748
+ return { algorithm: curveMap[detectedCurve], pem: publicKeyPem };
749
+ }
750
+ catch {
751
+ // Not a valid EC key
752
+ }
753
+ throw new ConfigurationError('Unable to determine public key algorithm - unsupported key type');
754
+ }
755
+ /**
756
+ * Convert a JWK (JSON Web Key) to PEM format.
757
+ */
758
+ export async function jwkToPublicKeyPem(jwk) {
759
+ let key;
760
+ if (jwk.kty === 'RSA') {
761
+ // RSA key
762
+ key = await crypto.subtle.importKey('jwk', jwk, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, [
763
+ 'encrypt',
764
+ ]);
765
+ }
766
+ else if (jwk.kty === 'EC') {
767
+ // EC key
768
+ const crv = jwk.crv;
769
+ if (!crv || !['P-256', 'P-384', 'P-521'].includes(crv)) {
770
+ throw new ConfigurationError(`Unsupported EC curve: ${crv}`);
771
+ }
772
+ key = await crypto.subtle.importKey('jwk', jwk, { name: 'ECDH', namedCurve: crv }, true, []);
773
+ }
774
+ else {
775
+ throw new ConfigurationError(`Unsupported JWK key type: ${jwk.kty}`);
776
+ }
777
+ const spkiBuffer = await crypto.subtle.exportKey('spki', key);
778
+ return formatAsPem(spkiBuffer, 'PUBLIC KEY');
779
+ }
780
+ /**
781
+ * Convert a PEM public key to JWK format.
782
+ * Returns only public key components (no private key data).
783
+ */
784
+ export async function publicKeyPemToJwk(publicKeyPem) {
785
+ const keyDataBase64 = removePemFormatting(publicKeyPem);
786
+ const keyBuffer = base64Decode(keyDataBase64);
787
+ const hex = hexEncode(keyBuffer);
788
+ // Detect key type using OID
789
+ const algorithmName = guessAlgorithmName(hex);
790
+ if (algorithmName === 'ECDH' || algorithmName === 'ECDSA') {
791
+ // EC key - detect curve from OID
792
+ const namedCurve = guessCurveName(hex);
793
+ const key = await crypto.subtle.importKey('spki', keyBuffer, { name: 'ECDSA', namedCurve }, true, ['verify']);
794
+ const jwk = await crypto.subtle.exportKey('jwk', key);
795
+ // Return only public key components
796
+ const { kty, crv, x, y } = jwk;
797
+ return { kty, crv, x, y };
798
+ }
799
+ else {
800
+ // RSA key
801
+ const key = await crypto.subtle.importKey('spki', keyBuffer, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, true, ['verify']);
802
+ const jwk = await crypto.subtle.exportKey('jwk', key);
803
+ // Return only public key components
804
+ const { kty, e, n } = jwk;
805
+ return { kty, e, n };
806
+ }
807
+ }
808
+ // ============================================================
809
+ // Key Import Functions (PEM → Opaque)
810
+ // ============================================================
811
+ /**
812
+ * Import a PEM public key as an opaque key.
813
+ */
814
+ export async function importPublicKey(pem, options) {
815
+ const { usage = 'encrypt', extractable = true, algorithmHint } = options;
816
+ // Detect algorithm from PEM; also normalises certificates → plain SPKI PEM.
817
+ const keyInfo = await parsePublicKeyPem(pem);
818
+ const algorithm = algorithmHint || keyInfo.algorithm;
819
+ // Use keyInfo.pem (normalised SPKI) not the original pem, which may be a certificate.
820
+ // Passing raw X.509 DER bytes to crypto.subtle.importKey('spki') would throw DataError.
821
+ const keyData = removePemFormatting(keyInfo.pem);
822
+ const keyBuffer = base64Decode(keyData);
823
+ // Determine Web Crypto algorithm and usages based on key type and usage
824
+ let cryptoAlgorithm;
825
+ let keyUsages;
826
+ if (algorithm.startsWith('rsa:')) {
827
+ if (usage === 'encrypt') {
828
+ cryptoAlgorithm = rsaOaepSha1();
829
+ keyUsages = ['encrypt'];
830
+ }
831
+ else if (usage === 'sign') {
832
+ cryptoAlgorithm = { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };
833
+ keyUsages = ['verify'];
834
+ }
835
+ else {
836
+ throw new ConfigurationError('RSA keys only support usage: encrypt or sign');
837
+ }
838
+ }
839
+ else if (algorithm.startsWith('ec:')) {
840
+ const curve = algorithm.split(':')[1];
841
+ const namedCurve = curve === 'secp256r1'
842
+ ? 'P-256'
843
+ : curve === 'secp384r1'
844
+ ? 'P-384'
845
+ : curve === 'secp521r1'
846
+ ? 'P-521'
847
+ : (() => {
848
+ throw new ConfigurationError(`Unsupported EC curve: ${curve}`);
849
+ })();
850
+ if (usage === 'derive') {
851
+ cryptoAlgorithm = { name: 'ECDH', namedCurve };
852
+ keyUsages = [];
853
+ }
854
+ else if (usage === 'sign') {
855
+ cryptoAlgorithm = { name: 'ECDSA', namedCurve };
856
+ keyUsages = ['verify'];
857
+ }
858
+ else {
859
+ throw new ConfigurationError('EC keys only support usage: derive or sign');
860
+ }
861
+ }
862
+ else {
863
+ throw new ConfigurationError(`Unsupported algorithm: ${algorithm}`);
864
+ }
865
+ // Import as CryptoKey
866
+ const cryptoKey = await crypto.subtle.importKey('spki', keyBuffer, cryptoAlgorithm, extractable, keyUsages);
867
+ return wrapPublicKey(cryptoKey, algorithm);
868
+ }
869
+ /**
870
+ * Import a PEM private key as an opaque key.
871
+ */
872
+ export async function importPrivateKey(pem, options) {
873
+ const { usage = 'encrypt', extractable = true, algorithmHint } = options;
874
+ // Detect algorithm from PEM structure (similar to public key detection)
875
+ // For now, use algorithmHint if provided, otherwise detect from key structure
876
+ let algorithm;
877
+ const keyData = removePemFormatting(pem);
878
+ const keyBuffer = base64Decode(keyData);
879
+ if (algorithmHint) {
880
+ algorithm = algorithmHint;
881
+ }
882
+ else {
883
+ // PKCS#8 PrivateKeyInfo embeds the same AlgorithmIdentifier OIDs as SPKI,
884
+ // so guessAlgorithmName / guessCurveName work on private key bytes too.
885
+ const hex = hexEncode(keyBuffer);
886
+ const algorithmName = guessAlgorithmName(hex); // throws on unrecognised OID
887
+ if (algorithmName === 'ECDH' || algorithmName === 'ECDSA') {
888
+ const namedCurve = guessCurveName(hex);
889
+ const curveMap = {
890
+ 'P-256': 'ec:secp256r1',
891
+ 'P-384': 'ec:secp384r1',
892
+ 'P-521': 'ec:secp521r1',
893
+ };
894
+ const mapped = curveMap[namedCurve];
895
+ if (!mapped)
896
+ throw new ConfigurationError(`Unsupported EC curve in private key: ${namedCurve}`);
897
+ algorithm = mapped;
898
+ }
899
+ else {
900
+ // RSA — determine key size by importing and reading modulus length from JWK
901
+ const tempKey = await crypto.subtle.importKey('pkcs8', keyBuffer, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, true, ['sign']);
902
+ const jwk = await crypto.subtle.exportKey('jwk', tempKey);
903
+ if (!jwk.n) {
904
+ throw new ConfigurationError('Invalid RSA private key: missing modulus');
905
+ }
906
+ const modulusBits = base64urlByteLength(jwk.n) * 8;
907
+ if (modulusBits < MIN_ASYMMETRIC_KEY_SIZE_BITS) {
908
+ throw new ConfigurationError(`RSA key size ${modulusBits} bits is below the minimum of ${MIN_ASYMMETRIC_KEY_SIZE_BITS} bits`);
909
+ }
910
+ algorithm = modulusBits <= 2048 ? 'rsa:2048' : 'rsa:4096';
911
+ }
912
+ }
913
+ // Determine Web Crypto algorithm and usages
914
+ let cryptoAlgorithm;
915
+ let keyUsages;
916
+ if (algorithm.startsWith('rsa:')) {
917
+ if (usage === 'encrypt') {
918
+ cryptoAlgorithm = rsaOaepSha1();
919
+ keyUsages = ['decrypt'];
920
+ }
921
+ else if (usage === 'sign') {
922
+ cryptoAlgorithm = { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };
923
+ keyUsages = ['sign'];
924
+ }
925
+ else {
926
+ throw new ConfigurationError('RSA keys only support usage: encrypt or sign');
927
+ }
928
+ }
929
+ else if (algorithm.startsWith('ec:')) {
930
+ const curve = algorithm.split(':')[1];
931
+ const namedCurve = curve === 'secp256r1'
932
+ ? 'P-256'
933
+ : curve === 'secp384r1'
934
+ ? 'P-384'
935
+ : curve === 'secp521r1'
936
+ ? 'P-521'
937
+ : (() => {
938
+ throw new ConfigurationError(`Unsupported EC curve: ${curve}`);
939
+ })();
940
+ if (usage === 'derive') {
941
+ cryptoAlgorithm = { name: 'ECDH', namedCurve };
942
+ keyUsages = ['deriveBits'];
943
+ }
944
+ else if (usage === 'sign') {
945
+ cryptoAlgorithm = { name: 'ECDSA', namedCurve };
946
+ keyUsages = ['sign'];
947
+ }
948
+ else {
949
+ throw new ConfigurationError('EC keys only support usage: derive or sign');
950
+ }
951
+ }
952
+ else {
953
+ throw new ConfigurationError(`Unsupported algorithm: ${algorithm}`);
954
+ }
955
+ // Import as CryptoKey
956
+ const cryptoKey = await crypto.subtle.importKey('pkcs8', keyBuffer, cryptoAlgorithm, extractable, keyUsages);
957
+ return wrapPrivateKey(cryptoKey, algorithm);
958
+ }
959
+ // ============================================================
960
+ // Key Export Functions (Opaque → PEM/JWK)
961
+ // ============================================================
962
+ /**
963
+ * Export an opaque public key to PEM format.
964
+ */
965
+ export async function exportPublicKeyPem(key) {
966
+ const cryptoKey = unwrapKey(key);
967
+ const keyBuffer = await crypto.subtle.exportKey('spki', cryptoKey);
968
+ return formatAsPem(keyBuffer, 'PUBLIC KEY');
969
+ }
970
+ /**
971
+ * Export an opaque private key to PEM format.
972
+ * ONLY USE FOR TESTING/DEVELOPMENT. Private keys should NOT be exportable in secure environments.
973
+ */
974
+ export async function exportPrivateKeyPem(key) {
975
+ const cryptoKey = unwrapKey(key);
976
+ const keyBuffer = await crypto.subtle.exportKey('pkcs8', cryptoKey);
977
+ return formatAsPem(keyBuffer, 'PRIVATE KEY');
978
+ }
979
+ /**
980
+ * Export an opaque public key to JWK format.
981
+ */
982
+ export async function exportPublicKeyJwk(key) {
983
+ const cryptoKey = unwrapKey(key);
984
+ return await crypto.subtle.exportKey('jwk', cryptoKey);
985
+ }
986
+ /**
987
+ * Import raw key bytes as an opaque symmetric key.
988
+ * Used for external keys (e.g., unwrapped from KAS).
989
+ */
990
+ export async function importSymmetricKey(keyBytes) {
991
+ return wrapSymmetricKey(keyBytes);
992
+ }
993
+ /**
994
+ * Split a symmetric key into N shares using XOR secret sharing.
995
+ * Key bytes are extracted internally for splitting.
996
+ * HSM implementations cannot extract bytes and should throw ConfigurationError.
997
+ */
998
+ export async function splitSymmetricKey(key, numShares) {
999
+ const keyBytes = unwrapSymmetricKey(key);
1000
+ const splits = await keySplit(keyBytes, numShares, DefaultCryptoService);
1001
+ return splits.map(wrapSymmetricKey);
1002
+ }
1003
+ /**
1004
+ * Merge symmetric key shares back into the original key using XOR.
1005
+ * Key bytes are extracted internally for merging.
1006
+ */
1007
+ export async function mergeSymmetricKeys(shares) {
1008
+ const splitBytes = shares.map(unwrapSymmetricKey);
1009
+ const merged = keyMerge(splitBytes);
1010
+ return wrapSymmetricKey(merged);
1011
+ }
280
1012
  export const DefaultCryptoService = {
281
1013
  name,
282
1014
  method,
283
- cryptoToPemPair,
284
1015
  decrypt,
285
1016
  decryptWithPrivateKey,
1017
+ deriveKeyFromECDH,
1018
+ digest,
286
1019
  encrypt,
287
1020
  encryptWithPublicKey,
288
- generateInitializationVector,
1021
+ exportPublicKeyJwk,
1022
+ exportPrivateKeyPem,
1023
+ exportPublicKeyPem,
1024
+ extractPublicKeyPem,
1025
+ generateECKeyPair,
289
1026
  generateKey,
290
1027
  generateKeyPair,
291
1028
  generateSigningKeyPair,
292
- hmac,
1029
+ importPrivateKey,
1030
+ importPublicKey,
1031
+ importSymmetricKey,
1032
+ jwkToPublicKeyPem,
1033
+ mergeSymmetricKeys,
1034
+ parsePublicKeyPem,
293
1035
  randomBytes,
294
- sha256,
1036
+ hmac,
1037
+ verifyHmac,
1038
+ sign,
1039
+ splitSymmetricKey,
1040
+ verify,
295
1041
  };
296
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZGYzL3NyYy9jcnlwdG8vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFJTCw0QkFBNEIsR0FFN0IsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsSUFBSSxTQUFTLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsaUJBQWlCLElBQUksWUFBWSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFHckYsNENBQTRDO0FBQzVDLE1BQU0sT0FBTyxHQUFlLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ25ELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxPQUFPLFVBQVUsRUFBRSxNQUFNLEtBQUssV0FBVyxDQUFDO0FBRXJFLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyw2Q0FBNkMsQ0FBQztBQUNwRSxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQUcsNEJBQTRCLENBQUM7QUFFakQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FDekIsZ0JBQXdCLDRCQUE0QjtJQUVwRCxJQUFJLENBQUMsYUFBYSxJQUFJLGFBQWEsR0FBRyw0QkFBNEIsRUFBRSxDQUFDO1FBQ25FLE1BQU0sSUFBSSxrQkFBa0IsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFDRCxPQUFPO1FBQ0wsSUFBSSxFQUFFLFVBQVU7UUFDaEIs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
1042
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi90ZGYzL3NyYy9jcnlwdG8vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFXTCw0QkFBNEIsR0FLN0IsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsSUFBSSxTQUFTLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsaUJBQWlCLElBQUksWUFBWSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFckYsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDOUMsT0FBTyxFQUNMLFFBQVEsRUFDUixrQkFBa0IsRUFDbEIsY0FBYyxHQUNmLE1BQU0sMENBQTBDLENBQUM7QUFDbEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUxRCw0Q0FBNEM7QUFDNUMsTUFBTSxlQUFlLEdBQWUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDM0QsTUFBTSxtQkFBbUIsR0FBZSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMzRCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsT0FBTyxVQUFVLEVBQUUsTUFBTSxLQUFLLFdBQVcsQ0FBQztBQUVyRSxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsNkNBQTZDLENBQUM7QUFDcEUsTUFBTSxDQUFDLE1B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