@reallyme/crypto 0.1.8 → 0.3.0
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/LICENSE +201 -0
- package/README.md +148 -18
- package/dist/aead.d.ts +4 -0
- package/dist/aead.js +40 -16
- package/dist/aesKw.d.ts +8 -2
- package/dist/aesKw.js +69 -12
- package/dist/algorithms.d.ts +12 -4
- package/dist/algorithms.js +8 -2
- package/dist/argon2id.d.ts +3 -0
- package/dist/argon2id.js +18 -3
- package/dist/cryptoFacade.d.ts +66 -5
- package/dist/cryptoFacade.js +99 -38
- package/dist/errors.d.ts +1 -1
- package/dist/hkdf.d.ts +1 -0
- package/dist/hkdf.js +5 -1
- package/dist/hmac.d.ts +3 -0
- package/dist/hmac.js +24 -3
- package/dist/hpke.d.ts +4 -1
- package/dist/hpke.js +45 -14
- package/dist/index.d.ts +14 -13
- package/dist/index.js +12 -10
- package/dist/jwaConcatKdf.js +8 -4
- package/dist/jwk.d.ts +2 -1
- package/dist/jwk.js +158 -122
- package/dist/kmac.d.ts +11 -0
- package/dist/kmac.js +49 -0
- package/dist/memory.d.ts +8 -0
- package/dist/memory.js +13 -0
- package/dist/mlDsa.d.ts +5 -0
- package/dist/mlDsa.js +43 -9
- package/dist/mlKem.d.ts +5 -2
- package/dist/mlKem.js +37 -26
- package/dist/operationResponse.d.ts +16 -0
- package/dist/operationResponse.js +46 -0
- package/dist/p256Ecdh.js +5 -1
- package/dist/p384Ecdh.js +5 -1
- package/dist/p521Ecdh.js +5 -1
- package/dist/pbkdf2.d.ts +6 -8
- package/dist/pbkdf2.js +12 -12
- package/dist/proto/generated/reallyme/crypto/v1/crypto_pb.d.ts +2859 -128
- package/dist/proto/generated/reallyme/crypto/v1/crypto_pb.js +992 -132
- package/dist/proto.d.ts +99 -7
- package/dist/proto.js +741 -16
- package/dist/rsa.d.ts +4 -1
- package/dist/rsa.js +23 -16
- package/dist/slhDsa.d.ts +5 -0
- package/dist/slhDsa.js +40 -9
- package/dist/validateBytes.d.ts +7 -1
- package/dist/validateBytes.js +63 -3
- package/dist/wasm/reallyme_crypto_wasm.js +77 -365
- package/dist/wasm/reallyme_crypto_wasm_bg.wasm +0 -0
- package/dist/wasmModuleTypes.d.ts +9 -21
- package/dist/wasmProvider.d.ts +12 -29
- package/dist/wasmProvider.js +25 -43
- package/dist/xWing.d.ts +5 -4
- package/dist/xWing.js +40 -40
- package/package.json +20 -2
- package/dist/codecs.d.ts +0 -35
- package/dist/codecs.js +0 -216
- package/dist/proto/generated/reallyme/codec/v1/codec_pb.d.ts +0 -253
- package/dist/proto/generated/reallyme/codec/v1/codec_pb.js +0 -160
package/dist/proto.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: Copyright © 2026 ReallyMe LLC. All rights reserved
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
|
4
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { MAX_JWKS_KEYS, ReallyMeJwk } from "./jwk.js";
|
|
7
|
+
import { ensureByteArrayAtMost, MAX_CRYPTO_INPUT_LENGTH, } from "./validateBytes.js";
|
|
8
|
+
export { AeadAlgorithm, AeadAlgorithmSchema, CryptoAlgorithmFamily, CryptoAlgorithmFamilySchema, CryptoAlgorithmIdentifierSchema, CryptoAeadOpenRequestSchema, CryptoAeadOpenResultSchema, CryptoAeadSealRequestSchema, CryptoAeadSealResultSchema, CryptoBackendErrorSchema, CryptoBip340SchnorrSignRequestSchema, CryptoErrorSchema, CryptoErrorReason, CryptoErrorReasonSchema, CryptoHashRequestSchema, CryptoHashResultSchema, CryptoHkdfDeriveRequestSchema, CryptoHkdfDeriveResultSchema, CryptoHpkeOpenRequestSchema, CryptoHpkeOpenResultSchema, CryptoHpkeSealRequestSchema, CryptoHpkeSealedMessageSchema, CryptoJwaConcatKdfSha256DeriveRequestSchema, CryptoJwaConcatKdfSha256DeriveResultSchema, CryptoKdfDeriveKeyRequestSchema, CryptoKdfDeriveKeyResultSchema, CryptoKemEncapsulationSchema, CryptoKemDecapsulateRequestSchema, CryptoKemDecapsulateResultSchema, CryptoKemEncapsulateRequestSchema, CryptoKemDeriveKeyPairRequestSchema, CryptoKemGenerateKeyPairRequestSchema, CryptoKeyAgreementDeriveKeyPairRequestSchema, CryptoKeyAgreementDeriveSharedSecretRequestSchema, CryptoKeyAgreementDeriveSharedSecretResultSchema, CryptoKeyPairSchema, CryptoKeyUnwrapRequestSchema, CryptoKeyUnwrapResultSchema, CryptoKeyWrapRequestSchema, CryptoKeyWrapResultSchema, CryptoMacAuthenticateRequestSchema, CryptoMacAuthenticateResultSchema, CryptoMacVerifyRequestSchema, CryptoOperationRequestSchema, CryptoOperationResponseSchema, CryptoOperationResultSchema, CryptoPrimitiveErrorSchema, CryptoProviderErrorSchema, CryptoProviderCapabilitySchema, CryptoProviderCapabilitySetSchema, CryptoProviderSupportStatus, CryptoProviderSupportStatusSchema, CryptoRsaVerifyRequestSchema, CryptoSignatureDeriveKeyPairRequestSchema, CryptoSignatureGenerateKeyPairRequestSchema, CryptoSignatureSignRequestSchema, CryptoSignatureSignResultSchema, CryptoSignatureVerifyRequestSchema, CryptoVerificationResultSchema, CryptoVerificationStatus, CryptoVerificationStatusSchema, HashAlgorithm, HashAlgorithmSchema, HpkeAeadId, HpkeAeadIdSchema, HpkeKdfId, HpkeKdfIdSchema, HpkeKemId, HpkeKemIdSchema, HpkeSuiteIdentifierSchema, JsonWebKeySchema, JsonWebKeySetSchema, KdfAlgorithm, KdfAlgorithmSchema, KemAlgorithm, KemAlgorithmSchema, KeyAgreementAlgorithm, KeyAgreementAlgorithmSchema, KeyWrapAlgorithm, KeyWrapAlgorithmSchema, MacAlgorithm, MacAlgorithmSchema, MulticodecKeyAlgorithm, MulticodecKeyAlgorithmSchema, SignatureAlgorithm, SignatureAlgorithmSchema, file_reallyme_crypto_v1_crypto, } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
9
|
+
import { AeadAlgorithm, HashAlgorithm, HpkeAeadId, HpkeKdfId, HpkeKemId, KdfAlgorithm, KemAlgorithm, KeyAgreementAlgorithm, KeyWrapAlgorithm, MacAlgorithm, MulticodecKeyAlgorithm, SignatureAlgorithm, CryptoAlgorithmIdentifierSchema, CryptoAlgorithmFamily, CryptoBackendErrorSchema, CryptoErrorReason, CryptoErrorSchema, CryptoHpkeSealedMessageSchema, HpkeSuiteIdentifierSchema, CryptoKemEncapsulationSchema, CryptoKeyPairSchema, CryptoPrimitiveErrorSchema, CryptoProviderCapabilitySchema, CryptoProviderCapabilitySetSchema, CryptoProviderErrorSchema, CryptoProviderSupportStatus, CryptoVerificationResultSchema, CryptoVerificationStatus, JsonWebKeySchema, JsonWebKeySetSchema, } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
8
10
|
export const signatureAlgorithmFromProto = (value) => {
|
|
9
11
|
switch (value) {
|
|
10
12
|
case SignatureAlgorithm.ED25519:
|
|
@@ -169,8 +171,6 @@ export const kemAlgorithmFromProto = (value) => {
|
|
|
169
171
|
return "ML-KEM-1024";
|
|
170
172
|
case KemAlgorithm.X_WING_768:
|
|
171
173
|
return "X-Wing-768";
|
|
172
|
-
case KemAlgorithm.X_WING_1024:
|
|
173
|
-
return "X-Wing-1024";
|
|
174
174
|
default:
|
|
175
175
|
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
176
176
|
}
|
|
@@ -185,8 +185,6 @@ export const kemAlgorithmToProto = (value) => {
|
|
|
185
185
|
return KemAlgorithm.ML_KEM_1024;
|
|
186
186
|
case "X-Wing-768":
|
|
187
187
|
return KemAlgorithm.X_WING_768;
|
|
188
|
-
case "X-Wing-1024":
|
|
189
|
-
return KemAlgorithm.X_WING_1024;
|
|
190
188
|
}
|
|
191
189
|
};
|
|
192
190
|
export const keyAgreementAlgorithmFromProto = (value) => {
|
|
@@ -219,6 +217,8 @@ export const macAlgorithmFromProto = (value) => {
|
|
|
219
217
|
switch (value) {
|
|
220
218
|
case MacAlgorithm.HMAC_SHA256:
|
|
221
219
|
return "HMAC-SHA-256";
|
|
220
|
+
case MacAlgorithm.HMAC_SHA384:
|
|
221
|
+
return "HMAC-SHA-384";
|
|
222
222
|
case MacAlgorithm.HMAC_SHA512:
|
|
223
223
|
return "HMAC-SHA-512";
|
|
224
224
|
default:
|
|
@@ -229,6 +229,8 @@ export const macAlgorithmToProto = (value) => {
|
|
|
229
229
|
switch (value) {
|
|
230
230
|
case "HMAC-SHA-256":
|
|
231
231
|
return MacAlgorithm.HMAC_SHA256;
|
|
232
|
+
case "HMAC-SHA-384":
|
|
233
|
+
return MacAlgorithm.HMAC_SHA384;
|
|
232
234
|
case "HMAC-SHA-512":
|
|
233
235
|
return MacAlgorithm.HMAC_SHA512;
|
|
234
236
|
}
|
|
@@ -237,6 +239,10 @@ export const kdfAlgorithmFromProto = (value) => {
|
|
|
237
239
|
switch (value) {
|
|
238
240
|
case KdfAlgorithm.HKDF_SHA256:
|
|
239
241
|
return "HKDF-SHA256";
|
|
242
|
+
case KdfAlgorithm.HKDF_SHA384:
|
|
243
|
+
return "HKDF-SHA384";
|
|
244
|
+
case KdfAlgorithm.KMAC_256:
|
|
245
|
+
return "KMAC256";
|
|
240
246
|
case KdfAlgorithm.ARGON2ID:
|
|
241
247
|
return "Argon2id";
|
|
242
248
|
case KdfAlgorithm.PBKDF2_HMAC_SHA256:
|
|
@@ -253,6 +259,10 @@ export const kdfAlgorithmToProto = (value) => {
|
|
|
253
259
|
switch (value) {
|
|
254
260
|
case "HKDF-SHA256":
|
|
255
261
|
return KdfAlgorithm.HKDF_SHA256;
|
|
262
|
+
case "HKDF-SHA384":
|
|
263
|
+
return KdfAlgorithm.HKDF_SHA384;
|
|
264
|
+
case "KMAC256":
|
|
265
|
+
return KdfAlgorithm.KMAC_256;
|
|
256
266
|
case "Argon2id":
|
|
257
267
|
return KdfAlgorithm.ARGON2ID;
|
|
258
268
|
case "PBKDF2-HMAC-SHA-256":
|
|
@@ -265,6 +275,10 @@ export const kdfAlgorithmToProto = (value) => {
|
|
|
265
275
|
};
|
|
266
276
|
export const keyWrapAlgorithmFromProto = (value) => {
|
|
267
277
|
switch (value) {
|
|
278
|
+
case KeyWrapAlgorithm.AES_128_KW:
|
|
279
|
+
return "AES-128-KW";
|
|
280
|
+
case KeyWrapAlgorithm.AES_192_KW:
|
|
281
|
+
return "AES-192-KW";
|
|
268
282
|
case KeyWrapAlgorithm.AES_256_KW:
|
|
269
283
|
return "AES-256-KW";
|
|
270
284
|
default:
|
|
@@ -273,28 +287,79 @@ export const keyWrapAlgorithmFromProto = (value) => {
|
|
|
273
287
|
};
|
|
274
288
|
export const keyWrapAlgorithmToProto = (value) => {
|
|
275
289
|
switch (value) {
|
|
290
|
+
case "AES-128-KW":
|
|
291
|
+
return KeyWrapAlgorithm.AES_128_KW;
|
|
292
|
+
case "AES-192-KW":
|
|
293
|
+
return KeyWrapAlgorithm.AES_192_KW;
|
|
276
294
|
case "AES-256-KW":
|
|
277
295
|
return KeyWrapAlgorithm.AES_256_KW;
|
|
278
296
|
}
|
|
279
297
|
};
|
|
280
298
|
export const hpkeSuiteFromProto = (value) => {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
return "DHKEM-X25519-HKDF-SHA256-HKDF-SHA256-CHACHA20-POLY1305";
|
|
286
|
-
default:
|
|
287
|
-
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
299
|
+
if (value.kem === HpkeKemId.DHKEM_P256_HKDF_SHA256 &&
|
|
300
|
+
value.kdf === HpkeKdfId.HKDF_SHA256 &&
|
|
301
|
+
value.aead === HpkeAeadId.AES_256_GCM) {
|
|
302
|
+
return "DHKEM-P256-HKDF-SHA256-HKDF-SHA256-AES-256-GCM";
|
|
288
303
|
}
|
|
304
|
+
if (value.kem === HpkeKemId.DHKEM_X25519_HKDF_SHA256 &&
|
|
305
|
+
value.kdf === HpkeKdfId.HKDF_SHA256 &&
|
|
306
|
+
value.aead === HpkeAeadId.CHACHA20_POLY1305) {
|
|
307
|
+
return "DHKEM-X25519-HKDF-SHA256-HKDF-SHA256-CHACHA20-POLY1305";
|
|
308
|
+
}
|
|
309
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
289
310
|
};
|
|
290
311
|
export const hpkeSuiteToProto = (value) => {
|
|
291
312
|
switch (value) {
|
|
292
313
|
case "DHKEM-P256-HKDF-SHA256-HKDF-SHA256-AES-256-GCM":
|
|
293
|
-
return
|
|
314
|
+
return create(HpkeSuiteIdentifierSchema, {
|
|
315
|
+
kem: HpkeKemId.DHKEM_P256_HKDF_SHA256,
|
|
316
|
+
kdf: HpkeKdfId.HKDF_SHA256,
|
|
317
|
+
aead: HpkeAeadId.AES_256_GCM,
|
|
318
|
+
});
|
|
294
319
|
case "DHKEM-X25519-HKDF-SHA256-HKDF-SHA256-CHACHA20-POLY1305":
|
|
295
|
-
return
|
|
320
|
+
return create(HpkeSuiteIdentifierSchema, {
|
|
321
|
+
kem: HpkeKemId.DHKEM_X25519_HKDF_SHA256,
|
|
322
|
+
kdf: HpkeKdfId.HKDF_SHA256,
|
|
323
|
+
aead: HpkeAeadId.CHACHA20_POLY1305,
|
|
324
|
+
});
|
|
296
325
|
}
|
|
297
326
|
};
|
|
327
|
+
const signatureAlgorithmIdentifierToProto = (value) => create(CryptoAlgorithmIdentifierSchema, {
|
|
328
|
+
algorithm: { case: "signature", value: signatureAlgorithmToProto(value) },
|
|
329
|
+
});
|
|
330
|
+
const keyAgreementAlgorithmIdentifierToProto = (value) => create(CryptoAlgorithmIdentifierSchema, {
|
|
331
|
+
algorithm: { case: "keyAgreement", value: keyAgreementAlgorithmToProto(value) },
|
|
332
|
+
});
|
|
333
|
+
const kemAlgorithmIdentifierToProto = (value) => create(CryptoAlgorithmIdentifierSchema, {
|
|
334
|
+
algorithm: { case: "kem", value: kemAlgorithmToProto(value) },
|
|
335
|
+
});
|
|
336
|
+
const hpkeSuiteIdentifierToProto = (value) => create(CryptoAlgorithmIdentifierSchema, {
|
|
337
|
+
algorithm: { case: "hpkeSuite", value: hpkeSuiteToProto(value) },
|
|
338
|
+
});
|
|
339
|
+
const signatureAlgorithmFromIdentifier = (value) => {
|
|
340
|
+
if (value?.algorithm.case !== "signature") {
|
|
341
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
342
|
+
}
|
|
343
|
+
return signatureAlgorithmFromProto(value.algorithm.value);
|
|
344
|
+
};
|
|
345
|
+
const keyAgreementAlgorithmFromIdentifier = (value) => {
|
|
346
|
+
if (value?.algorithm.case !== "keyAgreement") {
|
|
347
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
348
|
+
}
|
|
349
|
+
return keyAgreementAlgorithmFromProto(value.algorithm.value);
|
|
350
|
+
};
|
|
351
|
+
const kemAlgorithmFromIdentifier = (value) => {
|
|
352
|
+
if (value?.algorithm.case !== "kem") {
|
|
353
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
354
|
+
}
|
|
355
|
+
return kemAlgorithmFromProto(value.algorithm.value);
|
|
356
|
+
};
|
|
357
|
+
const hpkeSuiteFromIdentifier = (value) => {
|
|
358
|
+
if (value?.algorithm.case !== "hpkeSuite") {
|
|
359
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
360
|
+
}
|
|
361
|
+
return hpkeSuiteFromProto(value.algorithm.value);
|
|
362
|
+
};
|
|
298
363
|
export const multicodecKeyAlgorithmFromProto = (value) => {
|
|
299
364
|
switch (value) {
|
|
300
365
|
case MulticodecKeyAlgorithm.ED25519_PUB:
|
|
@@ -361,3 +426,663 @@ export const multicodecKeyAlgorithmToProto = (value) => {
|
|
|
361
426
|
return MulticodecKeyAlgorithm.ML_DSA_87_PUB;
|
|
362
427
|
}
|
|
363
428
|
};
|
|
429
|
+
// The largest supported canonical JWK is below 4 KiB. Keeping a full factor of
|
|
430
|
+
// two for future public-key encodings prevents attacker-controlled allocations
|
|
431
|
+
// and guarantees conversion never depends on an engine's argument-count limit.
|
|
432
|
+
const MAX_JWK_CANONICAL_JCS_LENGTH = 8_192;
|
|
433
|
+
const asciiToBytes = (value) => {
|
|
434
|
+
if (value.length > MAX_JWK_CANONICAL_JCS_LENGTH) {
|
|
435
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
436
|
+
}
|
|
437
|
+
const bytes = new Uint8Array(value.length);
|
|
438
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
439
|
+
const codeUnit = value.charCodeAt(index);
|
|
440
|
+
if (codeUnit > 0x7f) {
|
|
441
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
442
|
+
}
|
|
443
|
+
bytes[index] = codeUnit;
|
|
444
|
+
}
|
|
445
|
+
return bytes;
|
|
446
|
+
};
|
|
447
|
+
const asciiFromBytes = (value) => {
|
|
448
|
+
ensureByteArrayAtMost(value, MAX_JWK_CANONICAL_JCS_LENGTH);
|
|
449
|
+
const characters = [];
|
|
450
|
+
for (const byte of value) {
|
|
451
|
+
if (byte > 0x7f) {
|
|
452
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
453
|
+
}
|
|
454
|
+
characters.push(String.fromCharCode(byte));
|
|
455
|
+
}
|
|
456
|
+
return characters.join("");
|
|
457
|
+
};
|
|
458
|
+
const withJwkProtoBoundaryErrors = (operation) => {
|
|
459
|
+
try {
|
|
460
|
+
return operation();
|
|
461
|
+
}
|
|
462
|
+
catch (error) {
|
|
463
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
464
|
+
throw error;
|
|
465
|
+
}
|
|
466
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
const cryptoErrorReasonToFacadeError = (reason) => {
|
|
470
|
+
switch (reason) {
|
|
471
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_SIGNATURE:
|
|
472
|
+
case CryptoErrorReason.PRIMITIVE_VERIFICATION_FAILED:
|
|
473
|
+
return new ReallyMeCryptoError("invalid-signature");
|
|
474
|
+
case CryptoErrorReason.PROVIDER_UNSUPPORTED_ALGORITHM:
|
|
475
|
+
case CryptoErrorReason.PROVIDER_UNSUPPORTED_BACKEND:
|
|
476
|
+
return new ReallyMeCryptoError("unsupported-algorithm");
|
|
477
|
+
case CryptoErrorReason.PROVIDER_UNAVAILABLE:
|
|
478
|
+
case CryptoErrorReason.PROVIDER_RANDOMNESS_UNAVAILABLE:
|
|
479
|
+
case CryptoErrorReason.PROVIDER_KEY_EXISTS:
|
|
480
|
+
case CryptoErrorReason.PROVIDER_KEY_NOT_FOUND:
|
|
481
|
+
case CryptoErrorReason.PROVIDER_ACCESS_DENIED:
|
|
482
|
+
case CryptoErrorReason.PROVIDER_USER_AUTHENTICATION_REQUIRED:
|
|
483
|
+
case CryptoErrorReason.PROVIDER_USER_CANCELED:
|
|
484
|
+
case CryptoErrorReason.PROVIDER_HARDWARE_UNAVAILABLE:
|
|
485
|
+
case CryptoErrorReason.PROVIDER_HARDWARE_REJECTED_KEY:
|
|
486
|
+
case CryptoErrorReason.BACKEND_INVALID_STATE:
|
|
487
|
+
case CryptoErrorReason.BACKEND_INTERNAL:
|
|
488
|
+
return new ReallyMeCryptoError("provider-failure");
|
|
489
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_PARAMETER:
|
|
490
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_LENGTH:
|
|
491
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_KEY:
|
|
492
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_PUBLIC_KEY:
|
|
493
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_PRIVATE_KEY:
|
|
494
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_NONCE:
|
|
495
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_SALT:
|
|
496
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_PASSWORD:
|
|
497
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_ENCODING:
|
|
498
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_SHARED_SECRET:
|
|
499
|
+
case CryptoErrorReason.PRIMITIVE_MALFORMED_CIPHERTEXT:
|
|
500
|
+
case CryptoErrorReason.PRIMITIVE_INVALID_TAG:
|
|
501
|
+
case CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF:
|
|
502
|
+
case CryptoErrorReason.PRIMITIVE_MALFORMED_JSON:
|
|
503
|
+
case CryptoErrorReason.PRIMITIVE_RESOURCE_LIMIT_EXCEEDED:
|
|
504
|
+
case CryptoErrorReason.PRIMITIVE_MISSING_OPERATION:
|
|
505
|
+
return new ReallyMeCryptoError("invalid-input");
|
|
506
|
+
case CryptoErrorReason.PRIMITIVE_AUTHENTICATION_FAILED:
|
|
507
|
+
return new ReallyMeCryptoError("authentication-failed");
|
|
508
|
+
default:
|
|
509
|
+
return new ReallyMeCryptoError("invalid-input");
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
const invalidInputReasons = new Set([
|
|
513
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PARAMETER,
|
|
514
|
+
CryptoErrorReason.PRIMITIVE_INVALID_LENGTH,
|
|
515
|
+
CryptoErrorReason.PRIMITIVE_INVALID_KEY,
|
|
516
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PUBLIC_KEY,
|
|
517
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PRIVATE_KEY,
|
|
518
|
+
CryptoErrorReason.PRIMITIVE_INVALID_NONCE,
|
|
519
|
+
CryptoErrorReason.PRIMITIVE_INVALID_SALT,
|
|
520
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PASSWORD,
|
|
521
|
+
CryptoErrorReason.PRIMITIVE_INVALID_ENCODING,
|
|
522
|
+
CryptoErrorReason.PRIMITIVE_INVALID_SHARED_SECRET,
|
|
523
|
+
CryptoErrorReason.PRIMITIVE_MALFORMED_CIPHERTEXT,
|
|
524
|
+
CryptoErrorReason.PRIMITIVE_INVALID_TAG,
|
|
525
|
+
CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF,
|
|
526
|
+
CryptoErrorReason.PRIMITIVE_MALFORMED_JSON,
|
|
527
|
+
CryptoErrorReason.PRIMITIVE_RESOURCE_LIMIT_EXCEEDED,
|
|
528
|
+
CryptoErrorReason.PRIMITIVE_MISSING_OPERATION,
|
|
529
|
+
]);
|
|
530
|
+
export const cryptoWireErrorToProto = (error) => {
|
|
531
|
+
switch (error.branch) {
|
|
532
|
+
case "primitive":
|
|
533
|
+
return create(CryptoErrorSchema, {
|
|
534
|
+
error: {
|
|
535
|
+
case: "primitive",
|
|
536
|
+
value: create(CryptoPrimitiveErrorSchema, {
|
|
537
|
+
reason: error.reason,
|
|
538
|
+
}),
|
|
539
|
+
},
|
|
540
|
+
});
|
|
541
|
+
case "provider":
|
|
542
|
+
return create(CryptoErrorSchema, {
|
|
543
|
+
error: {
|
|
544
|
+
case: "provider",
|
|
545
|
+
value: create(CryptoProviderErrorSchema, {
|
|
546
|
+
reason: error.reason,
|
|
547
|
+
}),
|
|
548
|
+
},
|
|
549
|
+
});
|
|
550
|
+
case "backend":
|
|
551
|
+
return create(CryptoErrorSchema, {
|
|
552
|
+
error: {
|
|
553
|
+
case: "backend",
|
|
554
|
+
value: create(CryptoBackendErrorSchema, {
|
|
555
|
+
reason: error.reason,
|
|
556
|
+
}),
|
|
557
|
+
},
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
export const cryptoWireErrorFromProto = (value) => {
|
|
562
|
+
switch (value.error.case) {
|
|
563
|
+
case "primitive":
|
|
564
|
+
return strictCryptoWireError("primitive", value.error.value.reason);
|
|
565
|
+
case "provider":
|
|
566
|
+
return strictCryptoWireError("provider", value.error.value.reason);
|
|
567
|
+
case "backend":
|
|
568
|
+
return strictCryptoWireError("backend", value.error.value.reason);
|
|
569
|
+
default:
|
|
570
|
+
return malformedCryptoErrorEnvelope();
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
export const cryptoWireErrorToProtoBytes = (error) => toBinary(CryptoErrorSchema, cryptoWireErrorToProto(error));
|
|
574
|
+
export const cryptoWireErrorFromProtoBytes = (bytes) => {
|
|
575
|
+
try {
|
|
576
|
+
return cryptoWireErrorFromProto(fromBinary(CryptoErrorSchema, bytes));
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
return malformedCryptoErrorEnvelope();
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
const strictCryptoWireError = (branch, reason) => {
|
|
583
|
+
const result = cryptoWireErrorTryNew(branch, reason);
|
|
584
|
+
return result.ok ? result.value : malformedCryptoErrorEnvelope();
|
|
585
|
+
};
|
|
586
|
+
export const cryptoWireErrorTryNew = (branch, reason) => {
|
|
587
|
+
if (reason === CryptoErrorReason.UNSPECIFIED) {
|
|
588
|
+
return { ok: false, error: "unspecified-reason" };
|
|
589
|
+
}
|
|
590
|
+
if (knownCryptoErrorReasons.has(reason) && !cryptoErrorReasonMatchesBranch(branch, reason)) {
|
|
591
|
+
return { ok: false, error: "branch-reason-mismatch" };
|
|
592
|
+
}
|
|
593
|
+
if (!cryptoErrorReasonCodeMatchesBranch(branch, reason)) {
|
|
594
|
+
return { ok: false, error: "reason-code-out-of-range" };
|
|
595
|
+
}
|
|
596
|
+
return { ok: true, value: { branch, reason, reasonCode: reason } };
|
|
597
|
+
};
|
|
598
|
+
const malformedCryptoErrorEnvelope = () => ({
|
|
599
|
+
branch: "primitive",
|
|
600
|
+
reason: CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF,
|
|
601
|
+
reasonCode: CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF,
|
|
602
|
+
});
|
|
603
|
+
const cryptoErrorReasonCodeMatchesBranch = (branch, reasonCode) => {
|
|
604
|
+
switch (branch) {
|
|
605
|
+
case "primitive":
|
|
606
|
+
return reasonCode >= 100 && reasonCode <= 199;
|
|
607
|
+
case "provider":
|
|
608
|
+
return reasonCode >= 200 && reasonCode <= 299;
|
|
609
|
+
case "backend":
|
|
610
|
+
return reasonCode >= 300 && reasonCode <= 399;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
const cryptoErrorReasonMatchesBranch = (branch, reason) => {
|
|
614
|
+
switch (branch) {
|
|
615
|
+
case "primitive":
|
|
616
|
+
return primitiveCryptoErrorReasons.has(reason);
|
|
617
|
+
case "provider":
|
|
618
|
+
return providerCryptoErrorReasons.has(reason);
|
|
619
|
+
case "backend":
|
|
620
|
+
return backendCryptoErrorReasons.has(reason);
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
const primitiveCryptoErrorReasons = new Set([
|
|
624
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PARAMETER,
|
|
625
|
+
CryptoErrorReason.PRIMITIVE_INVALID_LENGTH,
|
|
626
|
+
CryptoErrorReason.PRIMITIVE_INVALID_KEY,
|
|
627
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PUBLIC_KEY,
|
|
628
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PRIVATE_KEY,
|
|
629
|
+
CryptoErrorReason.PRIMITIVE_INVALID_NONCE,
|
|
630
|
+
CryptoErrorReason.PRIMITIVE_INVALID_SALT,
|
|
631
|
+
CryptoErrorReason.PRIMITIVE_INVALID_PASSWORD,
|
|
632
|
+
CryptoErrorReason.PRIMITIVE_INVALID_ENCODING,
|
|
633
|
+
CryptoErrorReason.PRIMITIVE_INVALID_SIGNATURE,
|
|
634
|
+
CryptoErrorReason.PRIMITIVE_VERIFICATION_FAILED,
|
|
635
|
+
CryptoErrorReason.PRIMITIVE_AUTHENTICATION_FAILED,
|
|
636
|
+
CryptoErrorReason.PRIMITIVE_MALFORMED_CIPHERTEXT,
|
|
637
|
+
CryptoErrorReason.PRIMITIVE_INVALID_TAG,
|
|
638
|
+
CryptoErrorReason.PRIMITIVE_INVALID_SHARED_SECRET,
|
|
639
|
+
CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF,
|
|
640
|
+
CryptoErrorReason.PRIMITIVE_MALFORMED_JSON,
|
|
641
|
+
CryptoErrorReason.PRIMITIVE_RESOURCE_LIMIT_EXCEEDED,
|
|
642
|
+
CryptoErrorReason.PRIMITIVE_MISSING_OPERATION,
|
|
643
|
+
]);
|
|
644
|
+
const providerCryptoErrorReasons = new Set([
|
|
645
|
+
CryptoErrorReason.PROVIDER_UNSUPPORTED_ALGORITHM,
|
|
646
|
+
CryptoErrorReason.PROVIDER_UNSUPPORTED_BACKEND,
|
|
647
|
+
CryptoErrorReason.PROVIDER_UNAVAILABLE,
|
|
648
|
+
CryptoErrorReason.PROVIDER_RANDOMNESS_UNAVAILABLE,
|
|
649
|
+
CryptoErrorReason.PROVIDER_KEY_EXISTS,
|
|
650
|
+
CryptoErrorReason.PROVIDER_KEY_NOT_FOUND,
|
|
651
|
+
CryptoErrorReason.PROVIDER_ACCESS_DENIED,
|
|
652
|
+
CryptoErrorReason.PROVIDER_USER_AUTHENTICATION_REQUIRED,
|
|
653
|
+
CryptoErrorReason.PROVIDER_USER_CANCELED,
|
|
654
|
+
CryptoErrorReason.PROVIDER_HARDWARE_UNAVAILABLE,
|
|
655
|
+
CryptoErrorReason.PROVIDER_HARDWARE_REJECTED_KEY,
|
|
656
|
+
]);
|
|
657
|
+
const backendCryptoErrorReasons = new Set([
|
|
658
|
+
CryptoErrorReason.BACKEND_INVALID_STATE,
|
|
659
|
+
CryptoErrorReason.BACKEND_INTERNAL,
|
|
660
|
+
]);
|
|
661
|
+
const knownCryptoErrorReasons = new Set([
|
|
662
|
+
...primitiveCryptoErrorReasons,
|
|
663
|
+
...providerCryptoErrorReasons,
|
|
664
|
+
...backendCryptoErrorReasons,
|
|
665
|
+
]);
|
|
666
|
+
export const cryptoWireErrorToFacadeError = (error) => {
|
|
667
|
+
if (!knownCryptoErrorReasons.has(error.reason)) {
|
|
668
|
+
return new ReallyMeCryptoError("provider-failure");
|
|
669
|
+
}
|
|
670
|
+
const facadeError = cryptoErrorReasonToFacadeError(error.reason);
|
|
671
|
+
if (facadeError.code !== "invalid-input" || invalidInputReasons.has(error.reason)) {
|
|
672
|
+
return facadeError;
|
|
673
|
+
}
|
|
674
|
+
switch (error.branch) {
|
|
675
|
+
case "primitive":
|
|
676
|
+
return facadeError;
|
|
677
|
+
case "provider":
|
|
678
|
+
case "backend":
|
|
679
|
+
return new ReallyMeCryptoError("provider-failure");
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
export const cryptoErrorToProto = (error) => {
|
|
683
|
+
switch (error.code) {
|
|
684
|
+
case "invalid-input":
|
|
685
|
+
return create(CryptoErrorSchema, {
|
|
686
|
+
error: {
|
|
687
|
+
case: "primitive",
|
|
688
|
+
value: create(CryptoPrimitiveErrorSchema, {
|
|
689
|
+
reason: CryptoErrorReason.PRIMITIVE_INVALID_PARAMETER,
|
|
690
|
+
}),
|
|
691
|
+
},
|
|
692
|
+
});
|
|
693
|
+
case "invalid-signature":
|
|
694
|
+
return create(CryptoErrorSchema, {
|
|
695
|
+
error: {
|
|
696
|
+
case: "primitive",
|
|
697
|
+
value: create(CryptoPrimitiveErrorSchema, {
|
|
698
|
+
reason: CryptoErrorReason.PRIMITIVE_INVALID_SIGNATURE,
|
|
699
|
+
}),
|
|
700
|
+
},
|
|
701
|
+
});
|
|
702
|
+
case "authentication-failed":
|
|
703
|
+
return create(CryptoErrorSchema, {
|
|
704
|
+
error: {
|
|
705
|
+
case: "primitive",
|
|
706
|
+
value: create(CryptoPrimitiveErrorSchema, {
|
|
707
|
+
reason: CryptoErrorReason.PRIMITIVE_AUTHENTICATION_FAILED,
|
|
708
|
+
}),
|
|
709
|
+
},
|
|
710
|
+
});
|
|
711
|
+
case "provider-failure":
|
|
712
|
+
return create(CryptoErrorSchema, {
|
|
713
|
+
error: {
|
|
714
|
+
case: "backend",
|
|
715
|
+
value: create(CryptoBackendErrorSchema, {
|
|
716
|
+
reason: CryptoErrorReason.BACKEND_INTERNAL,
|
|
717
|
+
}),
|
|
718
|
+
},
|
|
719
|
+
});
|
|
720
|
+
case "unsupported-algorithm":
|
|
721
|
+
return create(CryptoErrorSchema, {
|
|
722
|
+
error: {
|
|
723
|
+
case: "provider",
|
|
724
|
+
value: create(CryptoProviderErrorSchema, {
|
|
725
|
+
reason: CryptoErrorReason.PROVIDER_UNSUPPORTED_ALGORITHM,
|
|
726
|
+
}),
|
|
727
|
+
},
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
export const cryptoErrorToProtoBytes = (error) => toBinary(CryptoErrorSchema, cryptoErrorToProto(error));
|
|
732
|
+
export const cryptoErrorFromProto = (value) => {
|
|
733
|
+
return cryptoWireErrorToFacadeError(cryptoWireErrorFromProto(value));
|
|
734
|
+
};
|
|
735
|
+
export const cryptoErrorFromProtoBytes = (bytes) => {
|
|
736
|
+
return cryptoWireErrorToFacadeError(cryptoWireErrorFromProtoBytes(bytes));
|
|
737
|
+
};
|
|
738
|
+
const signatureJwkAlgorithmToProto = (value) => {
|
|
739
|
+
switch (value) {
|
|
740
|
+
case "Ed25519":
|
|
741
|
+
return SignatureAlgorithm.ED25519;
|
|
742
|
+
case "P-256":
|
|
743
|
+
return SignatureAlgorithm.ECDSA_P256_SHA256;
|
|
744
|
+
case "secp256k1":
|
|
745
|
+
return SignatureAlgorithm.ECDSA_SECP256K1_SHA256;
|
|
746
|
+
case "ML-DSA-44":
|
|
747
|
+
return SignatureAlgorithm.ML_DSA_44;
|
|
748
|
+
case "ML-DSA-65":
|
|
749
|
+
return SignatureAlgorithm.ML_DSA_65;
|
|
750
|
+
case "ML-DSA-87":
|
|
751
|
+
return SignatureAlgorithm.ML_DSA_87;
|
|
752
|
+
case "SLH-DSA-SHA2-128s":
|
|
753
|
+
return SignatureAlgorithm.SLH_DSA_SHA2_128S;
|
|
754
|
+
default:
|
|
755
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
756
|
+
}
|
|
757
|
+
};
|
|
758
|
+
const jwkAlgorithmToProto = (value) => {
|
|
759
|
+
switch (value) {
|
|
760
|
+
case "X25519":
|
|
761
|
+
return create(CryptoAlgorithmIdentifierSchema, {
|
|
762
|
+
algorithm: {
|
|
763
|
+
case: "keyAgreement",
|
|
764
|
+
value: KeyAgreementAlgorithm.X25519,
|
|
765
|
+
},
|
|
766
|
+
});
|
|
767
|
+
case "ML-KEM-512":
|
|
768
|
+
return create(CryptoAlgorithmIdentifierSchema, {
|
|
769
|
+
algorithm: {
|
|
770
|
+
case: "kem",
|
|
771
|
+
value: KemAlgorithm.ML_KEM_512,
|
|
772
|
+
},
|
|
773
|
+
});
|
|
774
|
+
case "ML-KEM-768":
|
|
775
|
+
return create(CryptoAlgorithmIdentifierSchema, {
|
|
776
|
+
algorithm: {
|
|
777
|
+
case: "kem",
|
|
778
|
+
value: KemAlgorithm.ML_KEM_768,
|
|
779
|
+
},
|
|
780
|
+
});
|
|
781
|
+
case "ML-KEM-1024":
|
|
782
|
+
return create(CryptoAlgorithmIdentifierSchema, {
|
|
783
|
+
algorithm: {
|
|
784
|
+
case: "kem",
|
|
785
|
+
value: KemAlgorithm.ML_KEM_1024,
|
|
786
|
+
},
|
|
787
|
+
});
|
|
788
|
+
case "X-Wing-768":
|
|
789
|
+
return create(CryptoAlgorithmIdentifierSchema, {
|
|
790
|
+
algorithm: {
|
|
791
|
+
case: "kem",
|
|
792
|
+
value: KemAlgorithm.X_WING_768,
|
|
793
|
+
},
|
|
794
|
+
});
|
|
795
|
+
default:
|
|
796
|
+
return create(CryptoAlgorithmIdentifierSchema, {
|
|
797
|
+
algorithm: {
|
|
798
|
+
case: "signature",
|
|
799
|
+
value: signatureJwkAlgorithmToProto(value),
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
const signatureJwkAlgorithmFromProto = (value) => {
|
|
805
|
+
switch (value) {
|
|
806
|
+
case SignatureAlgorithm.ED25519:
|
|
807
|
+
return "Ed25519";
|
|
808
|
+
case SignatureAlgorithm.ECDSA_P256_SHA256:
|
|
809
|
+
return "P-256";
|
|
810
|
+
case SignatureAlgorithm.ECDSA_SECP256K1_SHA256:
|
|
811
|
+
return "secp256k1";
|
|
812
|
+
case SignatureAlgorithm.ML_DSA_44:
|
|
813
|
+
return "ML-DSA-44";
|
|
814
|
+
case SignatureAlgorithm.ML_DSA_65:
|
|
815
|
+
return "ML-DSA-65";
|
|
816
|
+
case SignatureAlgorithm.ML_DSA_87:
|
|
817
|
+
return "ML-DSA-87";
|
|
818
|
+
case SignatureAlgorithm.SLH_DSA_SHA2_128S:
|
|
819
|
+
return "SLH-DSA-SHA2-128s";
|
|
820
|
+
default:
|
|
821
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
822
|
+
}
|
|
823
|
+
};
|
|
824
|
+
const jwkAlgorithmFromProto = (value) => {
|
|
825
|
+
switch (value.algorithm.case) {
|
|
826
|
+
case "signature":
|
|
827
|
+
return signatureJwkAlgorithmFromProto(value.algorithm.value);
|
|
828
|
+
case "keyAgreement":
|
|
829
|
+
if (value.algorithm.value === KeyAgreementAlgorithm.X25519) {
|
|
830
|
+
return "X25519";
|
|
831
|
+
}
|
|
832
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
833
|
+
case "kem":
|
|
834
|
+
switch (value.algorithm.value) {
|
|
835
|
+
case KemAlgorithm.ML_KEM_512:
|
|
836
|
+
return "ML-KEM-512";
|
|
837
|
+
case KemAlgorithm.ML_KEM_768:
|
|
838
|
+
return "ML-KEM-768";
|
|
839
|
+
case KemAlgorithm.ML_KEM_1024:
|
|
840
|
+
return "ML-KEM-1024";
|
|
841
|
+
case KemAlgorithm.X_WING_768:
|
|
842
|
+
return "X-Wing-768";
|
|
843
|
+
default:
|
|
844
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
845
|
+
}
|
|
846
|
+
default:
|
|
847
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
export const jsonWebKeyToProto = (key) => create(JsonWebKeySchema, {
|
|
851
|
+
algorithm: jwkAlgorithmToProto(key.algorithm),
|
|
852
|
+
publicKey: key.publicKey,
|
|
853
|
+
canonicalJcs: asciiToBytes(ReallyMeJwk.toJcs(key.jwk)),
|
|
854
|
+
});
|
|
855
|
+
export const jsonWebKeyToProtoBytes = (key) => toBinary(JsonWebKeySchema, jsonWebKeyToProto(key));
|
|
856
|
+
export const jsonWebKeyFromProto = (value) => withJwkProtoBoundaryErrors(() => {
|
|
857
|
+
// Read each field once so a hostile message proxy cannot change values
|
|
858
|
+
// between validation and construction.
|
|
859
|
+
const algorithmValue = value.algorithm;
|
|
860
|
+
const publicKey = value.publicKey;
|
|
861
|
+
const canonicalJcs = value.canonicalJcs;
|
|
862
|
+
const algorithm = algorithmValue === undefined
|
|
863
|
+
? undefined
|
|
864
|
+
: jwkAlgorithmFromProto(algorithmValue);
|
|
865
|
+
if (algorithm === undefined) {
|
|
866
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
867
|
+
}
|
|
868
|
+
ensureByteArrayAtMost(publicKey, MAX_CRYPTO_INPUT_LENGTH);
|
|
869
|
+
const jwk = ReallyMeJwk.toJwk(algorithm, publicKey);
|
|
870
|
+
if (canonicalJcs.length > 0) {
|
|
871
|
+
const expected = ReallyMeJwk.toJcs(jwk);
|
|
872
|
+
if (asciiFromBytes(canonicalJcs) !== expected) {
|
|
873
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return { algorithm, publicKey, jwk };
|
|
877
|
+
});
|
|
878
|
+
export const jsonWebKeyFromProtoBytes = (bytes) => withJwkProtoBoundaryErrors(() => {
|
|
879
|
+
ensureByteArrayAtMost(bytes, MAX_CRYPTO_INPUT_LENGTH);
|
|
880
|
+
return jsonWebKeyFromProto(fromBinary(JsonWebKeySchema, bytes));
|
|
881
|
+
});
|
|
882
|
+
export const jsonWebKeySetToProto = (keySet) => create(JsonWebKeySetSchema, {
|
|
883
|
+
keys: keySet.keys.map((key) => jsonWebKeyToProto(key)),
|
|
884
|
+
});
|
|
885
|
+
export const jsonWebKeySetToProtoBytes = (keySet) => toBinary(JsonWebKeySetSchema, jsonWebKeySetToProto(keySet));
|
|
886
|
+
export const jsonWebKeySetFromProto = (value) => withJwkProtoBoundaryErrors(() => {
|
|
887
|
+
const keys = value.keys;
|
|
888
|
+
if (!Array.isArray(keys) || keys.length > MAX_JWKS_KEYS) {
|
|
889
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
890
|
+
}
|
|
891
|
+
return { keys: keys.map((key) => jsonWebKeyFromProto(key)) };
|
|
892
|
+
});
|
|
893
|
+
export const jsonWebKeySetFromProtoBytes = (bytes) => withJwkProtoBoundaryErrors(() => {
|
|
894
|
+
ensureByteArrayAtMost(bytes, MAX_CRYPTO_INPUT_LENGTH);
|
|
895
|
+
return jsonWebKeySetFromProto(fromBinary(JsonWebKeySetSchema, bytes));
|
|
896
|
+
});
|
|
897
|
+
const keyPairToProto = (algorithm, keyPair) => create(CryptoKeyPairSchema, {
|
|
898
|
+
algorithm,
|
|
899
|
+
publicKey: keyPair.publicKey,
|
|
900
|
+
secretKey: keyPair.secretKey,
|
|
901
|
+
});
|
|
902
|
+
export const signatureKeyPairToProto = (algorithm, keyPair) => keyPairToProto(signatureAlgorithmIdentifierToProto(algorithm), keyPair);
|
|
903
|
+
export const signatureKeyPairToProtoBytes = (algorithm, keyPair) => toBinary(CryptoKeyPairSchema, signatureKeyPairToProto(algorithm, keyPair));
|
|
904
|
+
export const signatureKeyPairFromProto = (value) => ({
|
|
905
|
+
algorithm: signatureAlgorithmFromIdentifier(value.algorithm),
|
|
906
|
+
keyPair: {
|
|
907
|
+
publicKey: value.publicKey,
|
|
908
|
+
secretKey: value.secretKey,
|
|
909
|
+
},
|
|
910
|
+
});
|
|
911
|
+
export const signatureKeyPairFromProtoBytes = (bytes) => {
|
|
912
|
+
try {
|
|
913
|
+
return signatureKeyPairFromProto(fromBinary(CryptoKeyPairSchema, bytes));
|
|
914
|
+
}
|
|
915
|
+
catch (error) {
|
|
916
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
917
|
+
throw error;
|
|
918
|
+
}
|
|
919
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
export const keyAgreementKeyPairToProto = (algorithm, keyPair) => keyPairToProto(keyAgreementAlgorithmIdentifierToProto(algorithm), keyPair);
|
|
923
|
+
export const keyAgreementKeyPairToProtoBytes = (algorithm, keyPair) => toBinary(CryptoKeyPairSchema, keyAgreementKeyPairToProto(algorithm, keyPair));
|
|
924
|
+
export const keyAgreementKeyPairFromProto = (value) => ({
|
|
925
|
+
algorithm: keyAgreementAlgorithmFromIdentifier(value.algorithm),
|
|
926
|
+
keyPair: {
|
|
927
|
+
publicKey: value.publicKey,
|
|
928
|
+
secretKey: value.secretKey,
|
|
929
|
+
},
|
|
930
|
+
});
|
|
931
|
+
export const keyAgreementKeyPairFromProtoBytes = (bytes) => {
|
|
932
|
+
try {
|
|
933
|
+
return keyAgreementKeyPairFromProto(fromBinary(CryptoKeyPairSchema, bytes));
|
|
934
|
+
}
|
|
935
|
+
catch (error) {
|
|
936
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
937
|
+
throw error;
|
|
938
|
+
}
|
|
939
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
export const kemKeyPairToProto = (algorithm, keyPair) => keyPairToProto(kemAlgorithmIdentifierToProto(algorithm), keyPair);
|
|
943
|
+
export const kemKeyPairToProtoBytes = (algorithm, keyPair) => toBinary(CryptoKeyPairSchema, kemKeyPairToProto(algorithm, keyPair));
|
|
944
|
+
export const kemKeyPairFromProto = (value) => ({
|
|
945
|
+
algorithm: kemAlgorithmFromIdentifier(value.algorithm),
|
|
946
|
+
keyPair: {
|
|
947
|
+
publicKey: value.publicKey,
|
|
948
|
+
secretKey: value.secretKey,
|
|
949
|
+
},
|
|
950
|
+
});
|
|
951
|
+
export const kemKeyPairFromProtoBytes = (bytes) => {
|
|
952
|
+
try {
|
|
953
|
+
return kemKeyPairFromProto(fromBinary(CryptoKeyPairSchema, bytes));
|
|
954
|
+
}
|
|
955
|
+
catch (error) {
|
|
956
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
957
|
+
throw error;
|
|
958
|
+
}
|
|
959
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
export const kemEncapsulationToProto = (algorithm, encapsulation) => create(CryptoKemEncapsulationSchema, {
|
|
963
|
+
algorithm: kemAlgorithmIdentifierToProto(algorithm),
|
|
964
|
+
ciphertext: encapsulation.ciphertext,
|
|
965
|
+
sharedSecret: encapsulation.sharedSecret,
|
|
966
|
+
});
|
|
967
|
+
export const kemEncapsulationToProtoBytes = (algorithm, encapsulation) => toBinary(CryptoKemEncapsulationSchema, kemEncapsulationToProto(algorithm, encapsulation));
|
|
968
|
+
export const kemEncapsulationFromProto = (value) => ({
|
|
969
|
+
algorithm: kemAlgorithmFromIdentifier(value.algorithm),
|
|
970
|
+
encapsulation: {
|
|
971
|
+
ciphertext: value.ciphertext,
|
|
972
|
+
sharedSecret: value.sharedSecret,
|
|
973
|
+
},
|
|
974
|
+
});
|
|
975
|
+
export const kemEncapsulationFromProtoBytes = (bytes) => {
|
|
976
|
+
try {
|
|
977
|
+
return kemEncapsulationFromProto(fromBinary(CryptoKemEncapsulationSchema, bytes));
|
|
978
|
+
}
|
|
979
|
+
catch (error) {
|
|
980
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
981
|
+
throw error;
|
|
982
|
+
}
|
|
983
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
export const hpkeSealedMessageToProto = (suite, sealedMessage) => create(CryptoHpkeSealedMessageSchema, {
|
|
987
|
+
algorithm: hpkeSuiteIdentifierToProto(suite),
|
|
988
|
+
encapsulatedKey: sealedMessage.encapsulatedKey,
|
|
989
|
+
ciphertext: sealedMessage.ciphertext,
|
|
990
|
+
});
|
|
991
|
+
export const hpkeSealedMessageToProtoBytes = (suite, sealedMessage) => toBinary(CryptoHpkeSealedMessageSchema, hpkeSealedMessageToProto(suite, sealedMessage));
|
|
992
|
+
export const hpkeSealedMessageFromProto = (value) => ({
|
|
993
|
+
suite: hpkeSuiteFromIdentifier(value.algorithm),
|
|
994
|
+
sealedMessage: {
|
|
995
|
+
encapsulatedKey: value.encapsulatedKey,
|
|
996
|
+
ciphertext: value.ciphertext,
|
|
997
|
+
},
|
|
998
|
+
});
|
|
999
|
+
export const hpkeSealedMessageFromProtoBytes = (bytes) => {
|
|
1000
|
+
try {
|
|
1001
|
+
return hpkeSealedMessageFromProto(fromBinary(CryptoHpkeSealedMessageSchema, bytes));
|
|
1002
|
+
}
|
|
1003
|
+
catch (error) {
|
|
1004
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
1005
|
+
throw error;
|
|
1006
|
+
}
|
|
1007
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
export const verificationResultToProto = (algorithm, valid) => create(CryptoVerificationResultSchema, {
|
|
1011
|
+
algorithm,
|
|
1012
|
+
status: valid ? CryptoVerificationStatus.VALID : CryptoVerificationStatus.INVALID,
|
|
1013
|
+
});
|
|
1014
|
+
export const verificationErrorToProto = (algorithm, error) => create(CryptoVerificationResultSchema, {
|
|
1015
|
+
algorithm,
|
|
1016
|
+
status: CryptoVerificationStatus.ERROR,
|
|
1017
|
+
error: cryptoErrorToProto(error),
|
|
1018
|
+
});
|
|
1019
|
+
export const verificationResultToProtoBytes = (value) => toBinary(CryptoVerificationResultSchema, value);
|
|
1020
|
+
export const verificationResultFromProtoBytes = (bytes) => {
|
|
1021
|
+
try {
|
|
1022
|
+
return fromBinary(CryptoVerificationResultSchema, bytes);
|
|
1023
|
+
}
|
|
1024
|
+
catch {
|
|
1025
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
const providerSupportStatusToProto = (value) => {
|
|
1029
|
+
switch (value) {
|
|
1030
|
+
case "partial":
|
|
1031
|
+
return CryptoProviderSupportStatus.PARTIAL;
|
|
1032
|
+
case "provider-aware":
|
|
1033
|
+
return CryptoProviderSupportStatus.PROVIDER_AWARE;
|
|
1034
|
+
case "supported":
|
|
1035
|
+
return CryptoProviderSupportStatus.SUPPORTED;
|
|
1036
|
+
case "unsupported":
|
|
1037
|
+
return CryptoProviderSupportStatus.UNSUPPORTED;
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
const providerSupportStatusFromProto = (value) => {
|
|
1041
|
+
switch (value) {
|
|
1042
|
+
case CryptoProviderSupportStatus.PARTIAL:
|
|
1043
|
+
return "partial";
|
|
1044
|
+
case CryptoProviderSupportStatus.PROVIDER_AWARE:
|
|
1045
|
+
return "provider-aware";
|
|
1046
|
+
case CryptoProviderSupportStatus.SUPPORTED:
|
|
1047
|
+
return "supported";
|
|
1048
|
+
case CryptoProviderSupportStatus.UNSUPPORTED:
|
|
1049
|
+
return "unsupported";
|
|
1050
|
+
default:
|
|
1051
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
export const providerCapabilityToProto = (value) => create(CryptoProviderCapabilitySchema, {
|
|
1055
|
+
algorithm: value.algorithm,
|
|
1056
|
+
family: value.family,
|
|
1057
|
+
providerNames: [...value.providerNames],
|
|
1058
|
+
status: providerSupportStatusToProto(value.status),
|
|
1059
|
+
usesRust: value.usesRust,
|
|
1060
|
+
});
|
|
1061
|
+
export const providerCapabilityFromProto = (value) => {
|
|
1062
|
+
if (value.algorithm === undefined || value.family === CryptoAlgorithmFamily.UNSPECIFIED) {
|
|
1063
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
1064
|
+
}
|
|
1065
|
+
return {
|
|
1066
|
+
algorithm: value.algorithm,
|
|
1067
|
+
family: value.family,
|
|
1068
|
+
providerNames: [...value.providerNames],
|
|
1069
|
+
status: providerSupportStatusFromProto(value.status),
|
|
1070
|
+
usesRust: value.usesRust,
|
|
1071
|
+
};
|
|
1072
|
+
};
|
|
1073
|
+
export const providerCapabilitySetToProto = (values) => create(CryptoProviderCapabilitySetSchema, {
|
|
1074
|
+
capabilities: values.map((value) => providerCapabilityToProto(value)),
|
|
1075
|
+
});
|
|
1076
|
+
export const providerCapabilitySetToProtoBytes = (values) => toBinary(CryptoProviderCapabilitySetSchema, providerCapabilitySetToProto(values));
|
|
1077
|
+
export const providerCapabilitySetFromProto = (value) => value.capabilities.map((capability) => providerCapabilityFromProto(capability));
|
|
1078
|
+
export const providerCapabilitySetFromProtoBytes = (bytes) => {
|
|
1079
|
+
try {
|
|
1080
|
+
return providerCapabilitySetFromProto(fromBinary(CryptoProviderCapabilitySetSchema, bytes));
|
|
1081
|
+
}
|
|
1082
|
+
catch (error) {
|
|
1083
|
+
if (error instanceof ReallyMeCryptoError) {
|
|
1084
|
+
throw error;
|
|
1085
|
+
}
|
|
1086
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
1087
|
+
}
|
|
1088
|
+
};
|