@reallyme/crypto 0.2.0 → 0.3.1
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/README.md +107 -17
- package/dist/aead.js +15 -8
- package/dist/aesKw.d.ts +7 -4
- package/dist/aesKw.js +69 -22
- package/dist/algorithms.d.ts +12 -4
- package/dist/algorithms.js +8 -2
- package/dist/argon2id.d.ts +1 -0
- package/dist/argon2id.js +13 -4
- package/dist/cryptoFacade.d.ts +33 -8
- package/dist/cryptoFacade.js +42 -29
- 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 +1 -2
- package/dist/hpke.js +33 -22
- package/dist/index.d.ts +9 -7
- package/dist/index.js +8 -6
- package/dist/jwk.d.ts +2 -1
- package/dist/jwk.js +104 -63
- package/dist/kmac.d.ts +11 -0
- package/dist/kmac.js +49 -0
- package/dist/mlDsa.js +22 -11
- package/dist/mlKem.d.ts +0 -3
- package/dist/mlKem.js +19 -37
- package/dist/operationResponse.d.ts +16 -0
- package/dist/operationResponse.js +46 -0
- package/dist/pbkdf2.d.ts +6 -8
- package/dist/pbkdf2.js +12 -12
- package/dist/proto/generated/reallyme/crypto/v1/crypto_pb.d.ts +1741 -328
- package/dist/proto/generated/reallyme/crypto/v1/crypto_pb.js +731 -344
- package/dist/proto.d.ts +6 -22
- package/dist/proto.js +124 -102
- package/dist/rsa.d.ts +2 -1
- package/dist/rsa.js +5 -1
- package/dist/slhDsa.js +21 -11
- package/dist/validateBytes.d.ts +6 -1
- package/dist/validateBytes.js +57 -3
- package/dist/wasm/reallyme_crypto_wasm.js +91 -134
- package/dist/wasm/reallyme_crypto_wasm_bg.wasm +0 -0
- package/dist/wasmModuleTypes.d.ts +7 -10
- package/dist/wasmProvider.d.ts +11 -13
- package/dist/wasmProvider.js +16 -19
- package/dist/xWing.d.ts +0 -5
- package/dist/xWing.js +20 -52
- package/package.json +15 -2
package/dist/proto.d.ts
CHANGED
|
@@ -2,10 +2,10 @@ import type { ReallyMeAeadAlgorithm, ReallyMeHashAlgorithm, ReallyMeHpkeSuite, R
|
|
|
2
2
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
3
3
|
import type { ReallyMeHpkeSealedMessage, ReallyMeKemEncapsulation, ReallyMeKemKeyPair, ReallyMeKeyAgreementKeyPair, ReallyMeSignatureKeyPair } from "./cryptoFacade.js";
|
|
4
4
|
import type { ReallyMeJwkKey, ReallyMeJwksKeySet } from "./jwk.js";
|
|
5
|
-
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, CryptoKemGenerateKeyPairRequestSchema, CryptoKeyAgreementDeriveKeyPairRequestSchema, CryptoKeyAgreementDeriveSharedSecretRequestSchema, CryptoKeyAgreementDeriveSharedSecretResultSchema, CryptoKeyPairSchema, CryptoKeyUnwrapRequestSchema, CryptoKeyUnwrapResultSchema, CryptoKeyWrapRequestSchema, CryptoKeyWrapResultSchema, CryptoMacAuthenticateRequestSchema, CryptoMacAuthenticateResultSchema, CryptoMacVerifyRequestSchema, CryptoPrimitiveErrorSchema, CryptoProviderErrorSchema, CryptoProviderCapabilitySchema, CryptoProviderCapabilitySetSchema, CryptoProviderSupportStatus, CryptoProviderSupportStatusSchema, CryptoRsaVerifyRequestSchema, CryptoSignatureDeriveKeyPairRequestSchema, CryptoSignatureGenerateKeyPairRequestSchema, CryptoSignatureSignRequestSchema, CryptoSignatureSignResultSchema, CryptoSignatureVerifyRequestSchema, CryptoVerificationResultSchema, CryptoVerificationStatus, CryptoVerificationStatusSchema, HashAlgorithm, HashAlgorithmSchema,
|
|
6
|
-
export type { CryptoAlgorithmIdentifier, CryptoAeadOpenRequest, CryptoAeadOpenResult, CryptoAeadSealRequest, CryptoAeadSealResult, CryptoBackendError, CryptoBip340SchnorrSignRequest, CryptoError, CryptoHashRequest, CryptoHashResult, CryptoHkdfDeriveRequest, CryptoHkdfDeriveResult, CryptoHpkeOpenRequest, CryptoHpkeOpenResult, CryptoHpkeSealRequest, CryptoHpkeSealedMessage, CryptoJwaConcatKdfSha256DeriveRequest, CryptoJwaConcatKdfSha256DeriveResult, CryptoKdfDeriveKeyRequest, CryptoKdfDeriveKeyResult, CryptoKemEncapsulation, CryptoKemDecapsulateRequest, CryptoKemDecapsulateResult, CryptoKemEncapsulateRequest, CryptoKemGenerateKeyPairRequest, CryptoKeyAgreementDeriveKeyPairRequest, CryptoKeyAgreementDeriveSharedSecretRequest, CryptoKeyAgreementDeriveSharedSecretResult, CryptoKeyPair, CryptoKeyUnwrapRequest, CryptoKeyUnwrapResult, CryptoKeyWrapRequest, CryptoKeyWrapResult, CryptoMacAuthenticateRequest, CryptoMacAuthenticateResult, CryptoMacVerifyRequest, CryptoPrimitiveError, CryptoProviderCapability, CryptoProviderCapabilitySet, CryptoProviderError, CryptoRsaVerifyRequest, CryptoSignatureDeriveKeyPairRequest, CryptoSignatureGenerateKeyPairRequest, CryptoSignatureSignRequest, CryptoSignatureSignResult, CryptoSignatureVerifyRequest, CryptoVerificationResult, JsonWebKey, JsonWebKeySet, } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
7
|
-
import { AeadAlgorithm, HashAlgorithm,
|
|
8
|
-
import type { CryptoAlgorithmIdentifier, CryptoError, CryptoHpkeSealedMessage, CryptoKemEncapsulation, CryptoKeyPair, CryptoProviderCapability, CryptoProviderCapabilitySet, CryptoVerificationResult, JsonWebKey, JsonWebKeySet } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
5
|
+
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";
|
|
6
|
+
export type { CryptoAlgorithmIdentifier, CryptoAeadOpenRequest, CryptoAeadOpenResult, CryptoAeadSealRequest, CryptoAeadSealResult, CryptoBackendError, CryptoBip340SchnorrSignRequest, CryptoError, CryptoHashRequest, CryptoHashResult, CryptoHkdfDeriveRequest, CryptoHkdfDeriveResult, CryptoHpkeOpenRequest, CryptoHpkeOpenResult, CryptoHpkeSealRequest, CryptoHpkeSealedMessage, CryptoJwaConcatKdfSha256DeriveRequest, CryptoJwaConcatKdfSha256DeriveResult, CryptoKdfDeriveKeyRequest, CryptoKdfDeriveKeyResult, CryptoKemEncapsulation, CryptoKemDecapsulateRequest, CryptoKemDecapsulateResult, CryptoKemEncapsulateRequest, CryptoKemDeriveKeyPairRequest, CryptoKemGenerateKeyPairRequest, CryptoKeyAgreementDeriveKeyPairRequest, CryptoKeyAgreementDeriveSharedSecretRequest, CryptoKeyAgreementDeriveSharedSecretResult, CryptoKeyPair, CryptoKeyUnwrapRequest, CryptoKeyUnwrapResult, CryptoKeyWrapRequest, CryptoKeyWrapResult, CryptoMacAuthenticateRequest, CryptoMacAuthenticateResult, CryptoMacVerifyRequest, CryptoOperationRequest, CryptoOperationResponse, CryptoOperationResult, CryptoPrimitiveError, CryptoProviderCapability, CryptoProviderCapabilitySet, CryptoProviderError, CryptoRsaVerifyRequest, CryptoSignatureDeriveKeyPairRequest, CryptoSignatureGenerateKeyPairRequest, CryptoSignatureSignRequest, CryptoSignatureSignResult, CryptoSignatureVerifyRequest, CryptoVerificationResult, HpkeSuiteIdentifier, JsonWebKey, JsonWebKeySet, } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
7
|
+
import { AeadAlgorithm, HashAlgorithm, KdfAlgorithm, KemAlgorithm, KeyAgreementAlgorithm, KeyWrapAlgorithm, MacAlgorithm, MulticodecKeyAlgorithm, SignatureAlgorithm, CryptoAlgorithmFamily, CryptoErrorReason } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
8
|
+
import type { CryptoAlgorithmIdentifier, CryptoError, CryptoHpkeSealedMessage, CryptoKemEncapsulation, CryptoKeyPair, CryptoProviderCapability, CryptoProviderCapabilitySet, CryptoVerificationResult, HpkeSuiteIdentifier, JsonWebKey, JsonWebKeySet } from "./proto/generated/reallyme/crypto/v1/crypto_pb.js";
|
|
9
9
|
export type ReallyMeCryptoWireErrorBranch = "primitive" | "provider" | "backend";
|
|
10
10
|
export type ReallyMeCryptoWireError = Readonly<{
|
|
11
11
|
branch: ReallyMeCryptoWireErrorBranch;
|
|
@@ -20,20 +20,6 @@ export type ReallyMeCryptoWireErrorValidationResult = Readonly<{
|
|
|
20
20
|
ok: false;
|
|
21
21
|
error: ReallyMeCryptoWireErrorValidationCode;
|
|
22
22
|
}>;
|
|
23
|
-
export type ReallyMeCryptoProtoStatus = "result" | "crypto-error";
|
|
24
|
-
export declare class ReallyMeCryptoProtoResult {
|
|
25
|
-
#private;
|
|
26
|
-
readonly status: ReallyMeCryptoProtoStatus;
|
|
27
|
-
constructor(status: ReallyMeCryptoProtoStatus, bytes: Uint8Array);
|
|
28
|
-
get bytes(): Uint8Array;
|
|
29
|
-
get isCryptoError(): boolean;
|
|
30
|
-
bestEffortClear(): void;
|
|
31
|
-
toString(): string;
|
|
32
|
-
toJSON(): Readonly<{
|
|
33
|
-
status: ReallyMeCryptoProtoStatus;
|
|
34
|
-
bytes: "<redacted>";
|
|
35
|
-
}>;
|
|
36
|
-
}
|
|
37
23
|
export type ReallyMeMulticodecKeyAlgorithm = "ed25519-pub" | "x25519-pub" | "secp256k1-pub" | "p256-pub" | "p384-pub" | "p521-pub" | "ed448-pub" | "rsa-pub" | "mlkem-512-pub" | "mlkem-768-pub" | "mlkem-1024-pub" | "mldsa-44-pub" | "mldsa-65-pub" | "mldsa-87-pub";
|
|
38
24
|
export type ReallyMeProviderSupportStatus = "partial" | "provider-aware" | "supported" | "unsupported";
|
|
39
25
|
export type ReallyMeProviderCapability = Readonly<{
|
|
@@ -79,8 +65,8 @@ export declare const kdfAlgorithmFromProto: (value: KdfAlgorithm) => ReallyMeKdf
|
|
|
79
65
|
export declare const kdfAlgorithmToProto: (value: ReallyMeKdfAlgorithm) => KdfAlgorithm;
|
|
80
66
|
export declare const keyWrapAlgorithmFromProto: (value: KeyWrapAlgorithm) => ReallyMeKeyWrapAlgorithm;
|
|
81
67
|
export declare const keyWrapAlgorithmToProto: (value: ReallyMeKeyWrapAlgorithm) => KeyWrapAlgorithm;
|
|
82
|
-
export declare const hpkeSuiteFromProto: (value:
|
|
83
|
-
export declare const hpkeSuiteToProto: (value: ReallyMeHpkeSuite) =>
|
|
68
|
+
export declare const hpkeSuiteFromProto: (value: HpkeSuiteIdentifier) => ReallyMeHpkeSuite;
|
|
69
|
+
export declare const hpkeSuiteToProto: (value: ReallyMeHpkeSuite) => HpkeSuiteIdentifier;
|
|
84
70
|
export declare const multicodecKeyAlgorithmFromProto: (value: MulticodecKeyAlgorithm) => ReallyMeMulticodecKeyAlgorithm;
|
|
85
71
|
export declare const multicodecKeyAlgorithmToProto: (value: ReallyMeMulticodecKeyAlgorithm) => MulticodecKeyAlgorithm;
|
|
86
72
|
export declare const cryptoWireErrorToProto: (error: ReallyMeCryptoWireError) => CryptoError;
|
|
@@ -89,8 +75,6 @@ export declare const cryptoWireErrorToProtoBytes: (error: ReallyMeCryptoWireErro
|
|
|
89
75
|
export declare const cryptoWireErrorFromProtoBytes: (bytes: Uint8Array) => ReallyMeCryptoWireError;
|
|
90
76
|
export declare const cryptoWireErrorTryNew: (branch: ReallyMeCryptoWireErrorBranch, reason: CryptoErrorReason) => ReallyMeCryptoWireErrorValidationResult;
|
|
91
77
|
export declare const cryptoWireErrorToFacadeError: (error: ReallyMeCryptoWireError) => ReallyMeCryptoError;
|
|
92
|
-
export declare const cryptoProtoResult: (bytes: Uint8Array) => ReallyMeCryptoProtoResult;
|
|
93
|
-
export declare const cryptoProtoErrorResult: (error: CryptoError | ReallyMeCryptoWireError | ReallyMeCryptoError) => ReallyMeCryptoProtoResult;
|
|
94
78
|
export declare const cryptoErrorToProto: (error: ReallyMeCryptoError) => CryptoError;
|
|
95
79
|
export declare const cryptoErrorToProtoBytes: (error: ReallyMeCryptoError) => Uint8Array;
|
|
96
80
|
export declare const cryptoErrorFromProto: (value: CryptoError) => ReallyMeCryptoError;
|
package/dist/proto.js
CHANGED
|
@@ -3,32 +3,10 @@
|
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import { create, fromBinary, toBinary } from "@bufbuild/protobuf";
|
|
5
5
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
6
|
-
import { ReallyMeJwk } from "./jwk.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
#bytes;
|
|
11
|
-
status;
|
|
12
|
-
constructor(status, bytes) {
|
|
13
|
-
this.status = status;
|
|
14
|
-
this.#bytes = bytes.slice();
|
|
15
|
-
}
|
|
16
|
-
get bytes() {
|
|
17
|
-
return this.#bytes.slice();
|
|
18
|
-
}
|
|
19
|
-
get isCryptoError() {
|
|
20
|
-
return this.status === "crypto-error";
|
|
21
|
-
}
|
|
22
|
-
bestEffortClear() {
|
|
23
|
-
this.#bytes.fill(0);
|
|
24
|
-
}
|
|
25
|
-
toString() {
|
|
26
|
-
return `ReallyMeCryptoProtoResult(status=${this.status}, bytes=<redacted>)`;
|
|
27
|
-
}
|
|
28
|
-
toJSON() {
|
|
29
|
-
return { status: this.status, bytes: "<redacted>" };
|
|
30
|
-
}
|
|
31
|
-
}
|
|
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";
|
|
32
10
|
export const signatureAlgorithmFromProto = (value) => {
|
|
33
11
|
switch (value) {
|
|
34
12
|
case SignatureAlgorithm.ED25519:
|
|
@@ -193,8 +171,6 @@ export const kemAlgorithmFromProto = (value) => {
|
|
|
193
171
|
return "ML-KEM-1024";
|
|
194
172
|
case KemAlgorithm.X_WING_768:
|
|
195
173
|
return "X-Wing-768";
|
|
196
|
-
case KemAlgorithm.X_WING_1024:
|
|
197
|
-
return "X-Wing-1024";
|
|
198
174
|
default:
|
|
199
175
|
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
200
176
|
}
|
|
@@ -209,8 +185,6 @@ export const kemAlgorithmToProto = (value) => {
|
|
|
209
185
|
return KemAlgorithm.ML_KEM_1024;
|
|
210
186
|
case "X-Wing-768":
|
|
211
187
|
return KemAlgorithm.X_WING_768;
|
|
212
|
-
case "X-Wing-1024":
|
|
213
|
-
return KemAlgorithm.X_WING_1024;
|
|
214
188
|
}
|
|
215
189
|
};
|
|
216
190
|
export const keyAgreementAlgorithmFromProto = (value) => {
|
|
@@ -243,6 +217,8 @@ export const macAlgorithmFromProto = (value) => {
|
|
|
243
217
|
switch (value) {
|
|
244
218
|
case MacAlgorithm.HMAC_SHA256:
|
|
245
219
|
return "HMAC-SHA-256";
|
|
220
|
+
case MacAlgorithm.HMAC_SHA384:
|
|
221
|
+
return "HMAC-SHA-384";
|
|
246
222
|
case MacAlgorithm.HMAC_SHA512:
|
|
247
223
|
return "HMAC-SHA-512";
|
|
248
224
|
default:
|
|
@@ -253,6 +229,8 @@ export const macAlgorithmToProto = (value) => {
|
|
|
253
229
|
switch (value) {
|
|
254
230
|
case "HMAC-SHA-256":
|
|
255
231
|
return MacAlgorithm.HMAC_SHA256;
|
|
232
|
+
case "HMAC-SHA-384":
|
|
233
|
+
return MacAlgorithm.HMAC_SHA384;
|
|
256
234
|
case "HMAC-SHA-512":
|
|
257
235
|
return MacAlgorithm.HMAC_SHA512;
|
|
258
236
|
}
|
|
@@ -261,6 +239,10 @@ export const kdfAlgorithmFromProto = (value) => {
|
|
|
261
239
|
switch (value) {
|
|
262
240
|
case KdfAlgorithm.HKDF_SHA256:
|
|
263
241
|
return "HKDF-SHA256";
|
|
242
|
+
case KdfAlgorithm.HKDF_SHA384:
|
|
243
|
+
return "HKDF-SHA384";
|
|
244
|
+
case KdfAlgorithm.KMAC_256:
|
|
245
|
+
return "KMAC256";
|
|
264
246
|
case KdfAlgorithm.ARGON2ID:
|
|
265
247
|
return "Argon2id";
|
|
266
248
|
case KdfAlgorithm.PBKDF2_HMAC_SHA256:
|
|
@@ -277,6 +259,10 @@ export const kdfAlgorithmToProto = (value) => {
|
|
|
277
259
|
switch (value) {
|
|
278
260
|
case "HKDF-SHA256":
|
|
279
261
|
return KdfAlgorithm.HKDF_SHA256;
|
|
262
|
+
case "HKDF-SHA384":
|
|
263
|
+
return KdfAlgorithm.HKDF_SHA384;
|
|
264
|
+
case "KMAC256":
|
|
265
|
+
return KdfAlgorithm.KMAC_256;
|
|
280
266
|
case "Argon2id":
|
|
281
267
|
return KdfAlgorithm.ARGON2ID;
|
|
282
268
|
case "PBKDF2-HMAC-SHA-256":
|
|
@@ -289,6 +275,10 @@ export const kdfAlgorithmToProto = (value) => {
|
|
|
289
275
|
};
|
|
290
276
|
export const keyWrapAlgorithmFromProto = (value) => {
|
|
291
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";
|
|
292
282
|
case KeyWrapAlgorithm.AES_256_KW:
|
|
293
283
|
return "AES-256-KW";
|
|
294
284
|
default:
|
|
@@ -297,26 +287,41 @@ export const keyWrapAlgorithmFromProto = (value) => {
|
|
|
297
287
|
};
|
|
298
288
|
export const keyWrapAlgorithmToProto = (value) => {
|
|
299
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;
|
|
300
294
|
case "AES-256-KW":
|
|
301
295
|
return KeyWrapAlgorithm.AES_256_KW;
|
|
302
296
|
}
|
|
303
297
|
};
|
|
304
298
|
export const hpkeSuiteFromProto = (value) => {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
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";
|
|
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";
|
|
312
308
|
}
|
|
309
|
+
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
313
310
|
};
|
|
314
311
|
export const hpkeSuiteToProto = (value) => {
|
|
315
312
|
switch (value) {
|
|
316
313
|
case "DHKEM-P256-HKDF-SHA256-HKDF-SHA256-AES-256-GCM":
|
|
317
|
-
return
|
|
314
|
+
return create(HpkeSuiteIdentifierSchema, {
|
|
315
|
+
kem: HpkeKemId.DHKEM_P256_HKDF_SHA256,
|
|
316
|
+
kdf: HpkeKdfId.HKDF_SHA256,
|
|
317
|
+
aead: HpkeAeadId.AES_256_GCM,
|
|
318
|
+
});
|
|
318
319
|
case "DHKEM-X25519-HKDF-SHA256-HKDF-SHA256-CHACHA20-POLY1305":
|
|
319
|
-
return
|
|
320
|
+
return create(HpkeSuiteIdentifierSchema, {
|
|
321
|
+
kem: HpkeKemId.DHKEM_X25519_HKDF_SHA256,
|
|
322
|
+
kdf: HpkeKdfId.HKDF_SHA256,
|
|
323
|
+
aead: HpkeAeadId.CHACHA20_POLY1305,
|
|
324
|
+
});
|
|
320
325
|
}
|
|
321
326
|
};
|
|
322
327
|
const signatureAlgorithmIdentifierToProto = (value) => create(CryptoAlgorithmIdentifierSchema, {
|
|
@@ -329,7 +334,7 @@ const kemAlgorithmIdentifierToProto = (value) => create(CryptoAlgorithmIdentifie
|
|
|
329
334
|
algorithm: { case: "kem", value: kemAlgorithmToProto(value) },
|
|
330
335
|
});
|
|
331
336
|
const hpkeSuiteIdentifierToProto = (value) => create(CryptoAlgorithmIdentifierSchema, {
|
|
332
|
-
algorithm: { case: "
|
|
337
|
+
algorithm: { case: "hpkeSuite", value: hpkeSuiteToProto(value) },
|
|
333
338
|
});
|
|
334
339
|
const signatureAlgorithmFromIdentifier = (value) => {
|
|
335
340
|
if (value?.algorithm.case !== "signature") {
|
|
@@ -350,7 +355,7 @@ const kemAlgorithmFromIdentifier = (value) => {
|
|
|
350
355
|
return kemAlgorithmFromProto(value.algorithm.value);
|
|
351
356
|
};
|
|
352
357
|
const hpkeSuiteFromIdentifier = (value) => {
|
|
353
|
-
if (value?.algorithm.case !== "
|
|
358
|
+
if (value?.algorithm.case !== "hpkeSuite") {
|
|
354
359
|
throw new ReallyMeCryptoError("invalid-input");
|
|
355
360
|
}
|
|
356
361
|
return hpkeSuiteFromProto(value.algorithm.value);
|
|
@@ -421,7 +426,14 @@ export const multicodecKeyAlgorithmToProto = (value) => {
|
|
|
421
426
|
return MulticodecKeyAlgorithm.ML_DSA_87_PUB;
|
|
422
427
|
}
|
|
423
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;
|
|
424
433
|
const asciiToBytes = (value) => {
|
|
434
|
+
if (value.length > MAX_JWK_CANONICAL_JCS_LENGTH) {
|
|
435
|
+
throw new ReallyMeCryptoError("invalid-input");
|
|
436
|
+
}
|
|
425
437
|
const bytes = new Uint8Array(value.length);
|
|
426
438
|
for (let index = 0; index < value.length; index += 1) {
|
|
427
439
|
const codeUnit = value.charCodeAt(index);
|
|
@@ -433,14 +445,26 @@ const asciiToBytes = (value) => {
|
|
|
433
445
|
return bytes;
|
|
434
446
|
};
|
|
435
447
|
const asciiFromBytes = (value) => {
|
|
436
|
-
|
|
448
|
+
ensureByteArrayAtMost(value, MAX_JWK_CANONICAL_JCS_LENGTH);
|
|
449
|
+
const characters = [];
|
|
437
450
|
for (const byte of value) {
|
|
438
451
|
if (byte > 0x7f) {
|
|
439
452
|
throw new ReallyMeCryptoError("invalid-input");
|
|
440
453
|
}
|
|
441
|
-
|
|
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");
|
|
442
467
|
}
|
|
443
|
-
return String.fromCharCode(...codeUnits);
|
|
444
468
|
};
|
|
445
469
|
const cryptoErrorReasonToFacadeError = (reason) => {
|
|
446
470
|
switch (reason) {
|
|
@@ -452,11 +476,15 @@ const cryptoErrorReasonToFacadeError = (reason) => {
|
|
|
452
476
|
return new ReallyMeCryptoError("unsupported-algorithm");
|
|
453
477
|
case CryptoErrorReason.PROVIDER_UNAVAILABLE:
|
|
454
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:
|
|
455
486
|
case CryptoErrorReason.BACKEND_INVALID_STATE:
|
|
456
487
|
case CryptoErrorReason.BACKEND_INTERNAL:
|
|
457
|
-
case CryptoErrorReason.BACKEND_MALFORMED_PROTOBUF:
|
|
458
|
-
case CryptoErrorReason.BACKEND_MALFORMED_JSON:
|
|
459
|
-
case CryptoErrorReason.BACKEND_RESOURCE_LIMIT_EXCEEDED:
|
|
460
488
|
return new ReallyMeCryptoError("provider-failure");
|
|
461
489
|
case CryptoErrorReason.PRIMITIVE_INVALID_PARAMETER:
|
|
462
490
|
case CryptoErrorReason.PRIMITIVE_INVALID_LENGTH:
|
|
@@ -470,6 +498,10 @@ const cryptoErrorReasonToFacadeError = (reason) => {
|
|
|
470
498
|
case CryptoErrorReason.PRIMITIVE_INVALID_SHARED_SECRET:
|
|
471
499
|
case CryptoErrorReason.PRIMITIVE_MALFORMED_CIPHERTEXT:
|
|
472
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:
|
|
473
505
|
return new ReallyMeCryptoError("invalid-input");
|
|
474
506
|
case CryptoErrorReason.PRIMITIVE_AUTHENTICATION_FAILED:
|
|
475
507
|
return new ReallyMeCryptoError("authentication-failed");
|
|
@@ -490,6 +522,10 @@ const invalidInputReasons = new Set([
|
|
|
490
522
|
CryptoErrorReason.PRIMITIVE_INVALID_SHARED_SECRET,
|
|
491
523
|
CryptoErrorReason.PRIMITIVE_MALFORMED_CIPHERTEXT,
|
|
492
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,
|
|
493
529
|
]);
|
|
494
530
|
export const cryptoWireErrorToProto = (error) => {
|
|
495
531
|
switch (error.branch) {
|
|
@@ -560,9 +596,9 @@ export const cryptoWireErrorTryNew = (branch, reason) => {
|
|
|
560
596
|
return { ok: true, value: { branch, reason, reasonCode: reason } };
|
|
561
597
|
};
|
|
562
598
|
const malformedCryptoErrorEnvelope = () => ({
|
|
563
|
-
branch: "
|
|
564
|
-
reason: CryptoErrorReason.
|
|
565
|
-
reasonCode: CryptoErrorReason.
|
|
599
|
+
branch: "primitive",
|
|
600
|
+
reason: CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF,
|
|
601
|
+
reasonCode: CryptoErrorReason.PRIMITIVE_MALFORMED_PROTOBUF,
|
|
566
602
|
});
|
|
567
603
|
const cryptoErrorReasonCodeMatchesBranch = (branch, reasonCode) => {
|
|
568
604
|
switch (branch) {
|
|
@@ -600,19 +636,27 @@ const primitiveCryptoErrorReasons = new Set([
|
|
|
600
636
|
CryptoErrorReason.PRIMITIVE_MALFORMED_CIPHERTEXT,
|
|
601
637
|
CryptoErrorReason.PRIMITIVE_INVALID_TAG,
|
|
602
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,
|
|
603
643
|
]);
|
|
604
644
|
const providerCryptoErrorReasons = new Set([
|
|
605
645
|
CryptoErrorReason.PROVIDER_UNSUPPORTED_ALGORITHM,
|
|
606
646
|
CryptoErrorReason.PROVIDER_UNSUPPORTED_BACKEND,
|
|
607
647
|
CryptoErrorReason.PROVIDER_UNAVAILABLE,
|
|
608
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,
|
|
609
656
|
]);
|
|
610
657
|
const backendCryptoErrorReasons = new Set([
|
|
611
658
|
CryptoErrorReason.BACKEND_INVALID_STATE,
|
|
612
659
|
CryptoErrorReason.BACKEND_INTERNAL,
|
|
613
|
-
CryptoErrorReason.BACKEND_MALFORMED_PROTOBUF,
|
|
614
|
-
CryptoErrorReason.BACKEND_MALFORMED_JSON,
|
|
615
|
-
CryptoErrorReason.BACKEND_RESOURCE_LIMIT_EXCEEDED,
|
|
616
660
|
]);
|
|
617
661
|
const knownCryptoErrorReasons = new Set([
|
|
618
662
|
...primitiveCryptoErrorReasons,
|
|
@@ -635,15 +679,6 @@ export const cryptoWireErrorToFacadeError = (error) => {
|
|
|
635
679
|
return new ReallyMeCryptoError("provider-failure");
|
|
636
680
|
}
|
|
637
681
|
};
|
|
638
|
-
export const cryptoProtoResult = (bytes) => new ReallyMeCryptoProtoResult("result", bytes);
|
|
639
|
-
export const cryptoProtoErrorResult = (error) => {
|
|
640
|
-
const bytes = error instanceof ReallyMeCryptoError
|
|
641
|
-
? cryptoErrorToProtoBytes(error)
|
|
642
|
-
: "branch" in error
|
|
643
|
-
? cryptoWireErrorToProtoBytes(error)
|
|
644
|
-
: toBinary(CryptoErrorSchema, error);
|
|
645
|
-
return new ReallyMeCryptoProtoResult("crypto-error", bytes);
|
|
646
|
-
};
|
|
647
682
|
export const cryptoErrorToProto = (error) => {
|
|
648
683
|
switch (error.code) {
|
|
649
684
|
case "invalid-input":
|
|
@@ -757,13 +792,6 @@ const jwkAlgorithmToProto = (value) => {
|
|
|
757
792
|
value: KemAlgorithm.X_WING_768,
|
|
758
793
|
},
|
|
759
794
|
});
|
|
760
|
-
case "X-Wing-1024":
|
|
761
|
-
return create(CryptoAlgorithmIdentifierSchema, {
|
|
762
|
-
algorithm: {
|
|
763
|
-
case: "kem",
|
|
764
|
-
value: KemAlgorithm.X_WING_1024,
|
|
765
|
-
},
|
|
766
|
-
});
|
|
767
795
|
default:
|
|
768
796
|
return create(CryptoAlgorithmIdentifierSchema, {
|
|
769
797
|
algorithm: {
|
|
@@ -812,8 +840,6 @@ const jwkAlgorithmFromProto = (value) => {
|
|
|
812
840
|
return "ML-KEM-1024";
|
|
813
841
|
case KemAlgorithm.X_WING_768:
|
|
814
842
|
return "X-Wing-768";
|
|
815
|
-
case KemAlgorithm.X_WING_1024:
|
|
816
|
-
return "X-Wing-1024";
|
|
817
843
|
default:
|
|
818
844
|
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
819
845
|
}
|
|
@@ -827,51 +853,47 @@ export const jsonWebKeyToProto = (key) => create(JsonWebKeySchema, {
|
|
|
827
853
|
canonicalJcs: asciiToBytes(ReallyMeJwk.toJcs(key.jwk)),
|
|
828
854
|
});
|
|
829
855
|
export const jsonWebKeyToProtoBytes = (key) => toBinary(JsonWebKeySchema, jsonWebKeyToProto(key));
|
|
830
|
-
export const jsonWebKeyFromProto = (value) => {
|
|
831
|
-
|
|
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
|
|
832
863
|
? undefined
|
|
833
|
-
: jwkAlgorithmFromProto(
|
|
864
|
+
: jwkAlgorithmFromProto(algorithmValue);
|
|
834
865
|
if (algorithm === undefined) {
|
|
835
866
|
throw new ReallyMeCryptoError("invalid-input");
|
|
836
867
|
}
|
|
837
|
-
|
|
838
|
-
|
|
868
|
+
ensureByteArrayAtMost(publicKey, MAX_CRYPTO_INPUT_LENGTH);
|
|
869
|
+
const jwk = ReallyMeJwk.toJwk(algorithm, publicKey);
|
|
870
|
+
if (canonicalJcs.length > 0) {
|
|
839
871
|
const expected = ReallyMeJwk.toJcs(jwk);
|
|
840
|
-
if (asciiFromBytes(
|
|
872
|
+
if (asciiFromBytes(canonicalJcs) !== expected) {
|
|
841
873
|
throw new ReallyMeCryptoError("invalid-input");
|
|
842
874
|
}
|
|
843
875
|
}
|
|
844
|
-
return { algorithm, publicKey
|
|
845
|
-
};
|
|
846
|
-
export const jsonWebKeyFromProtoBytes = (bytes) => {
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
catch (error) {
|
|
851
|
-
if (error instanceof ReallyMeCryptoError) {
|
|
852
|
-
throw error;
|
|
853
|
-
}
|
|
854
|
-
throw new ReallyMeCryptoError("invalid-input");
|
|
855
|
-
}
|
|
856
|
-
};
|
|
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
|
+
});
|
|
857
882
|
export const jsonWebKeySetToProto = (keySet) => create(JsonWebKeySetSchema, {
|
|
858
883
|
keys: keySet.keys.map((key) => jsonWebKeyToProto(key)),
|
|
859
884
|
});
|
|
860
885
|
export const jsonWebKeySetToProtoBytes = (keySet) => toBinary(JsonWebKeySetSchema, jsonWebKeySetToProto(keySet));
|
|
861
|
-
export const jsonWebKeySetFromProto = (value) => ({
|
|
862
|
-
keys
|
|
863
|
-
|
|
864
|
-
export const jsonWebKeySetFromProtoBytes = (bytes) => {
|
|
865
|
-
try {
|
|
866
|
-
return jsonWebKeySetFromProto(fromBinary(JsonWebKeySetSchema, bytes));
|
|
867
|
-
}
|
|
868
|
-
catch (error) {
|
|
869
|
-
if (error instanceof ReallyMeCryptoError) {
|
|
870
|
-
throw error;
|
|
871
|
-
}
|
|
886
|
+
export const jsonWebKeySetFromProto = (value) => withJwkProtoBoundaryErrors(() => {
|
|
887
|
+
const keys = value.keys;
|
|
888
|
+
if (!Array.isArray(keys) || keys.length > MAX_JWKS_KEYS) {
|
|
872
889
|
throw new ReallyMeCryptoError("invalid-input");
|
|
873
890
|
}
|
|
874
|
-
};
|
|
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
|
+
});
|
|
875
897
|
const keyPairToProto = (algorithm, keyPair) => create(CryptoKeyPairSchema, {
|
|
876
898
|
algorithm,
|
|
877
899
|
publicKey: keyPair.publicKey,
|
package/dist/rsa.d.ts
CHANGED
|
@@ -7,7 +7,8 @@ export declare const RSA_SIGNATURE_MAX_LENGTH = 1024;
|
|
|
7
7
|
* RSA signature verification through the ReallyMe Rust WASM provider.
|
|
8
8
|
*
|
|
9
9
|
* RSA is verification-only in this SDK. It exists for X.509, eMRTD passive
|
|
10
|
-
* authentication, and
|
|
10
|
+
* authentication, and historical document interoperability; no RSA signing
|
|
11
|
+
* API is exposed.
|
|
11
12
|
*/
|
|
12
13
|
export declare const ReallyMeRsa: {
|
|
13
14
|
readonly verify: (algorithm: ReallyMeSignatureAlgorithm, signature: Uint8Array, message: Uint8Array, publicKeyDer: Uint8Array, publicKeyEncoding: ReallyMeRsaPublicKeyDerEncoding) => void;
|
package/dist/rsa.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
|
+
import { ensureByteArray, ensureByteArrayAtMost, MAX_CRYPTO_INPUT_LENGTH, } from "./validateBytes.js";
|
|
5
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
|
6
7
|
export const RSA_PUBLIC_KEY_DER_MAX_LENGTH = 4_096;
|
|
7
8
|
export const RSA_SIGNATURE_MAX_LENGTH = 1_024;
|
|
@@ -12,6 +13,7 @@ const RSA_HASH_SHA512 = 4;
|
|
|
12
13
|
const RSA_PUBLIC_KEY_ENCODING_PKCS1_DER = 1;
|
|
13
14
|
const RSA_PUBLIC_KEY_ENCODING_SPKI_DER = 2;
|
|
14
15
|
const validateBytes = (bytes, maxLength) => {
|
|
16
|
+
ensureByteArray(bytes);
|
|
15
17
|
if (bytes.length === 0 || bytes.length > maxLength) {
|
|
16
18
|
throw new ReallyMeCryptoError("invalid-input");
|
|
17
19
|
}
|
|
@@ -78,6 +80,7 @@ const readVoid = (value) => {
|
|
|
78
80
|
const verifyWithProvider = (provider, algorithm, signature, message, publicKeyDer, publicKeyEncoding) => {
|
|
79
81
|
validateBytes(publicKeyDer, RSA_PUBLIC_KEY_DER_MAX_LENGTH);
|
|
80
82
|
validateBytes(signature, RSA_SIGNATURE_MAX_LENGTH);
|
|
83
|
+
ensureByteArrayAtMost(message, MAX_CRYPTO_INPUT_LENGTH);
|
|
81
84
|
const encoding = encodingId(publicKeyEncoding);
|
|
82
85
|
const pkcs1 = pkcs1v15Suite(algorithm);
|
|
83
86
|
if (pkcs1 !== undefined) {
|
|
@@ -95,7 +98,8 @@ const verifyWithProvider = (provider, algorithm, signature, message, publicKeyDe
|
|
|
95
98
|
* RSA signature verification through the ReallyMe Rust WASM provider.
|
|
96
99
|
*
|
|
97
100
|
* RSA is verification-only in this SDK. It exists for X.509, eMRTD passive
|
|
98
|
-
* authentication, and
|
|
101
|
+
* authentication, and historical document interoperability; no RSA signing
|
|
102
|
+
* API is exposed.
|
|
99
103
|
*/
|
|
100
104
|
export const ReallyMeRsa = {
|
|
101
105
|
verify(algorithm, signature, message, publicKeyDer, publicKeyEncoding) {
|
package/dist/slhDsa.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
//
|
|
3
3
|
// SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
import { ReallyMeCryptoError } from "./errors.js";
|
|
5
|
-
import { ensureBytes,
|
|
5
|
+
import { ensureByteArrayAtMost, ensureBytes, ensureIndependentByteArray, MAX_CRYPTO_INPUT_LENGTH, readIndependentByteArrayProperty, } from "./validateBytes.js";
|
|
6
6
|
import { requireReallyMeWasmProvider } from "./wasmProvider.js";
|
|
7
7
|
export const SLH_DSA_SHA2_128S_PUBLIC_KEY_LENGTH = 32;
|
|
8
8
|
export const SLH_DSA_SHA2_128S_SECRET_KEY_LENGTH = 64;
|
|
@@ -13,15 +13,21 @@ const assertSlhDsa = (algorithm) => {
|
|
|
13
13
|
throw new ReallyMeCryptoError("unsupported-algorithm");
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
|
-
const readKeyPair = (value) =>
|
|
17
|
-
publicKey
|
|
18
|
-
secretKey
|
|
19
|
-
}
|
|
20
|
-
|
|
16
|
+
const readKeyPair = (value, inputs = []) => {
|
|
17
|
+
const publicKey = readIndependentByteArrayProperty(value, "publicKey", SLH_DSA_SHA2_128S_PUBLIC_KEY_LENGTH, inputs);
|
|
18
|
+
const secretKey = readIndependentByteArrayProperty(value, "secretKey", SLH_DSA_SHA2_128S_SECRET_KEY_LENGTH, [...inputs, publicKey]);
|
|
19
|
+
return { publicKey, secretKey };
|
|
20
|
+
};
|
|
21
|
+
const readSignature = (value, inputs) => {
|
|
21
22
|
if (!(value instanceof Uint8Array)) {
|
|
22
23
|
throw new ReallyMeCryptoError("provider-failure");
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
+
// Signature bytes are public, but their shape and ownership are provider
|
|
26
|
+
// postconditions rather than caller validation failures.
|
|
27
|
+
ensureIndependentByteArray(value, inputs);
|
|
28
|
+
if (value.length !== SLH_DSA_SHA2_128S_SIGNATURE_LENGTH) {
|
|
29
|
+
throw new ReallyMeCryptoError("provider-failure");
|
|
30
|
+
}
|
|
25
31
|
return value;
|
|
26
32
|
};
|
|
27
33
|
const readVoid = (value) => {
|
|
@@ -40,22 +46,26 @@ export const ReallyMeSlhDsa = {
|
|
|
40
46
|
},
|
|
41
47
|
sign(algorithm, message, secretKey) {
|
|
42
48
|
assertSlhDsa(algorithm);
|
|
49
|
+
ensureByteArrayAtMost(message, MAX_CRYPTO_INPUT_LENGTH);
|
|
43
50
|
ensureBytes(secretKey, SLH_DSA_SHA2_128S_SECRET_KEY_LENGTH);
|
|
44
|
-
return readSignature(requireReallyMeWasmProvider().slhDsaSha2128sSign(secretKey, message));
|
|
51
|
+
return readSignature(requireReallyMeWasmProvider().slhDsaSha2128sSign(secretKey, message), [secretKey, message]);
|
|
45
52
|
},
|
|
46
53
|
signWithProvider(provider, algorithm, message, secretKey) {
|
|
47
54
|
assertSlhDsa(algorithm);
|
|
55
|
+
ensureByteArrayAtMost(message, MAX_CRYPTO_INPUT_LENGTH);
|
|
48
56
|
ensureBytes(secretKey, SLH_DSA_SHA2_128S_SECRET_KEY_LENGTH);
|
|
49
|
-
return readSignature(provider.slhDsaSha2128sSign(secretKey, message));
|
|
57
|
+
return readSignature(provider.slhDsaSha2128sSign(secretKey, message), [secretKey, message]);
|
|
50
58
|
},
|
|
51
59
|
verify(algorithm, signature, message, publicKey) {
|
|
52
60
|
assertSlhDsa(algorithm);
|
|
61
|
+
ensureByteArrayAtMost(message, MAX_CRYPTO_INPUT_LENGTH);
|
|
53
62
|
ensureBytes(publicKey, SLH_DSA_SHA2_128S_PUBLIC_KEY_LENGTH);
|
|
54
63
|
ensureBytes(signature, SLH_DSA_SHA2_128S_SIGNATURE_LENGTH);
|
|
55
64
|
readVoid(requireReallyMeWasmProvider().slhDsaSha2128sVerify(publicKey, message, signature));
|
|
56
65
|
},
|
|
57
66
|
verifyWithProvider(provider, algorithm, signature, message, publicKey) {
|
|
58
67
|
assertSlhDsa(algorithm);
|
|
68
|
+
ensureByteArrayAtMost(message, MAX_CRYPTO_INPUT_LENGTH);
|
|
59
69
|
ensureBytes(publicKey, SLH_DSA_SHA2_128S_PUBLIC_KEY_LENGTH);
|
|
60
70
|
ensureBytes(signature, SLH_DSA_SHA2_128S_SIGNATURE_LENGTH);
|
|
61
71
|
readVoid(provider.slhDsaSha2128sVerify(publicKey, message, signature));
|
|
@@ -65,11 +75,11 @@ export const deriveSlhDsaSha2128sKeypairForTest = (skSeed, skPrf, pkSeed) => {
|
|
|
65
75
|
ensureBytes(skSeed, SLH_DSA_SHA2_128S_KEYGEN_SEED_LENGTH);
|
|
66
76
|
ensureBytes(skPrf, SLH_DSA_SHA2_128S_KEYGEN_SEED_LENGTH);
|
|
67
77
|
ensureBytes(pkSeed, SLH_DSA_SHA2_128S_KEYGEN_SEED_LENGTH);
|
|
68
|
-
return readKeyPair(requireReallyMeWasmProvider().slhDsaSha2128sDeriveKeypair(skSeed, skPrf, pkSeed));
|
|
78
|
+
return readKeyPair(requireReallyMeWasmProvider().slhDsaSha2128sDeriveKeypair(skSeed, skPrf, pkSeed), [skSeed, skPrf, pkSeed]);
|
|
69
79
|
};
|
|
70
80
|
export const deriveSlhDsaSha2128sKeypairWithProviderForTest = (provider, skSeed, skPrf, pkSeed) => {
|
|
71
81
|
ensureBytes(skSeed, SLH_DSA_SHA2_128S_KEYGEN_SEED_LENGTH);
|
|
72
82
|
ensureBytes(skPrf, SLH_DSA_SHA2_128S_KEYGEN_SEED_LENGTH);
|
|
73
83
|
ensureBytes(pkSeed, SLH_DSA_SHA2_128S_KEYGEN_SEED_LENGTH);
|
|
74
|
-
return readKeyPair(provider.slhDsaSha2128sDeriveKeypair(skSeed, skPrf, pkSeed));
|
|
84
|
+
return readKeyPair(provider.slhDsaSha2128sDeriveKeypair(skSeed, skPrf, pkSeed), [skSeed, skPrf, pkSeed]);
|
|
75
85
|
};
|
package/dist/validateBytes.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
export declare const MAX_CRYPTO_INPUT_LENGTH = 1048576;
|
|
1
2
|
export declare const ensureByteArray: (value: Uint8Array) => void;
|
|
3
|
+
export declare const ensureByteArrayAtMost: (value: Uint8Array, maximumLength: number) => void;
|
|
2
4
|
export declare const ensureBytes: (value: Uint8Array, expectedLength: number) => void;
|
|
3
|
-
export declare const
|
|
5
|
+
export declare const byteArraysOverlap: (left: Uint8Array, right: Uint8Array) => boolean;
|
|
6
|
+
export declare const ensureIndependentByteArray: (value: Uint8Array, disallowedViews: ReadonlyArray<Uint8Array>) => void;
|
|
7
|
+
export declare const readIndependentByteArrayProperty: (value: unknown, propertyName: string, expectedLength: number, disallowedViews: ReadonlyArray<Uint8Array>) => Uint8Array;
|
|
8
|
+
export declare const readIndependentProviderBytes: (value: unknown, expectedLength: number, disallowedViews: ReadonlyArray<Uint8Array>) => Uint8Array;
|