@h-ai/crypto 0.1.0-alpha.67 → 0.1.0-alpha.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -35,7 +35,15 @@ var en_US_default = {
35
35
  crypto_hashFormatInvalid: "Invalid hash format",
36
36
  crypto_passwordVerifyFailed: "Password verification failed",
37
37
  crypto_transportClientKeyGenerateFailed: "Failed to generate transport client key pair",
38
- crypto_transportServerKeyGenerateFailed: "Failed to generate transport server key pair",
38
+ crypto_transportServerKeyRingInvalid: "The server transport key ring is missing or invalid. Check that private HAI_CRYPTO_TRANSPORT_SERVERKEYRING contains complete valid JSON and distribute the same ring to every node.",
39
+ crypto_transportServerKeyUnknown: "Transport server key version is unknown or revoked",
40
+ crypto_transportKeyStoreRequired: "Transport encryption requires an explicit client public key store",
41
+ crypto_transportKeyStoreTtlInvalid: "Public-key store TTL must be an integer between 1 and 2147483647 seconds",
42
+ crypto_transportKeyStoreCapacityInvalid: "Public-key store capacity must be a positive safe integer",
43
+ crypto_transportKeyStoreCapacityMismatch: "Public-key store shared capacity settings do not match",
44
+ crypto_transportKeyStoreCapacityReached: "Public-key store capacity has been reached",
45
+ crypto_transportKeyStoreOperationFailed: "Public-key store operation failed",
46
+ crypto_transportAuthenticationFailed: "Transport authentication, request binding or replay validation failed",
39
47
  crypto_transportKeyExchangeRequestFailed: "Transport key exchange request failed",
40
48
  crypto_transportKeyExchangeHttpFailed: "Transport key exchange returned HTTP {status}",
41
49
  crypto_transportKeyExchangeInvalidJson: "Transport key exchange response is not valid JSON",
@@ -47,7 +55,68 @@ var en_US_default = {
47
55
  crypto_transportResponseEncryptFailed: "Failed to encrypt transport response body",
48
56
  crypto_transportResponseDecryptFailed: "Failed to decrypt transport response body",
49
57
  crypto_transportSessionKeyEncryptFailed: "Failed to encrypt transport session key",
50
- crypto_transportSessionKeyDecryptFailed: "Failed to decrypt transport session key"
58
+ crypto_transportSessionKeyDecryptFailed: "Failed to decrypt transport session key",
59
+ crypto_transportBodyLimitInvalid: "Transport plaintext limit must be an integer between 1024 and 67108864 bytes",
60
+ crypto_transportBodyTooLarge: "Encrypted transport payload exceeds the configured byte limit",
61
+ crypto_transportTimeInvalid: "Your device and server clocks may be out of sync, or the request has expired. Enable automatic time synchronization and refresh to retry. If this continues, ask an administrator to check the server clock."
62
+ };
63
+
64
+ // messages/ja-JP.json
65
+ var ja_JP_default = {
66
+ $schema: "https://inlang.com/schema/inlang-message-format",
67
+ crypto_notInitialized: "\u6697\u53F7\u30E2\u30B8\u30E5\u30FC\u30EB\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\u5148\u306Bcrypto.init()\u3092\u547C\u3073\u51FA\u3057\u3066\u304F\u3060\u3055\u3044",
68
+ crypto_initFailed: "\u6697\u53F7\u30E2\u30B8\u30E5\u30FC\u30EB\u306E\u521D\u671F\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
69
+ crypto_sm2PublicKeyInvalid: "SM2\u516C\u958B\u9375\u306E\u5F62\u5F0F\u304C\u7121\u52B9\u3067\u3059",
70
+ crypto_sm2PrivateKeyInvalid: "SM2\u79D8\u5BC6\u9375\u306E\u5F62\u5F0F\u304C\u7121\u52B9\u3067\u3059",
71
+ crypto_sm2EncryptEmpty: "SM2\u6697\u53F7\u5316\u306E\u7D50\u679C\u304C\u7A7A\u3067\u3059",
72
+ crypto_sm2DecryptFailed: "SM2\u5FA9\u53F7\u306B\u5931\u6557\u3057\u305F\u304B\u3001\u7D50\u679C\u304C\u7121\u52B9\u3067\u3059",
73
+ crypto_sm2SignEmpty: "SM2\u7F72\u540D\u306E\u7D50\u679C\u304C\u7A7A\u3067\u3059",
74
+ crypto_sm2KeyPairGenerateFailed: "SM2\u9375\u30DA\u30A2\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
75
+ crypto_sm2EncryptFailed: "SM2\u6697\u53F7\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
76
+ crypto_sm2DecryptFailedWithError: "SM2\u5FA9\u53F7\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
77
+ crypto_sm2SignFailed: "SM2\u7F72\u540D\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
78
+ crypto_sm2VerifyFailed: "SM2\u7F72\u540D\u306E\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
79
+ crypto_sm3HashEmpty: "SM3\u30CF\u30C3\u30B7\u30E5\u306E\u7D50\u679C\u304C\u7A7A\u3067\u3059",
80
+ crypto_sm3HashFailed: "SM3\u30CF\u30C3\u30B7\u30E5\u306E\u8A08\u7B97\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
81
+ crypto_sm3HmacFailed: "HMAC-SM3\u306E\u8A08\u7B97\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
82
+ crypto_sm3VerifyFailed: "SM3\u30CF\u30C3\u30B7\u30E5\u306E\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
83
+ crypto_sm4KeyInvalid: "SM4\u9375\u306F16\u30D0\u30A4\u30C8\uFF0816\u9032\u657032\u6587\u5B57\uFF09\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059",
84
+ crypto_sm4CbcNeedIv: "CBC\u30E2\u30FC\u30C9\u306B\u306FIV\u304C\u5FC5\u8981\u3067\u3059",
85
+ crypto_sm4IvInvalid: "SM4\u306EIV\u306F16\u30D0\u30A4\u30C8\uFF0816\u9032\u657032\u6587\u5B57\uFF09\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059",
86
+ crypto_sm4EncryptEmpty: "SM4\u6697\u53F7\u5316\u306E\u7D50\u679C\u304C\u7A7A\u3067\u3059",
87
+ crypto_sm4DecryptFailed: "SM4\u5FA9\u53F7\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
88
+ crypto_sm4EncryptFailed: "SM4\u6697\u53F7\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
89
+ crypto_sm4DecryptFailedWithError: "SM4\u5FA9\u53F7\u306B\u5931\u6557\u3057\u307E\u3057\u305F: {error}",
90
+ crypto_passwordEmpty: "\u30D1\u30B9\u30EF\u30FC\u30C9\u3092\u7A7A\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093",
91
+ crypto_passwordHashEmpty: "\u30D1\u30B9\u30EF\u30FC\u30C9\u3068\u30CF\u30C3\u30B7\u30E5\u3092\u7A7A\u306B\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093",
92
+ crypto_passwordHashFailed: "\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u30CF\u30C3\u30B7\u30E5\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
93
+ crypto_hashFormatInvalid: "\u30CF\u30C3\u30B7\u30E5\u306E\u5F62\u5F0F\u304C\u7121\u52B9\u3067\u3059",
94
+ crypto_passwordVerifyFailed: "\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
95
+ crypto_transportClientKeyGenerateFailed: "\u901A\u4FE1\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u306E\u9375\u30DA\u30A2\u306E\u751F\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
96
+ crypto_transportServerKeyRingInvalid: "\u30B5\u30FC\u30D0\u30FC\u306E\u8EE2\u9001\u9375\u30EA\u30F3\u30B0\u304C\u4E0D\u8DB3\u307E\u305F\u306F\u4E0D\u6B63\u3067\u3059\u3002\u975E\u516C\u958B\u306E HAI_CRYPTO_TRANSPORT_SERVERKEYRING \u304C\u5B8C\u5168\u3067\u6709\u52B9\u306A JSON \u3067\u3042\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3057\u3001\u5168\u30CE\u30FC\u30C9\u306B\u540C\u3058\u30EA\u30F3\u30B0\u3092\u914D\u5E03\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
97
+ crypto_transportServerKeyUnknown: "\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u306E\u30B5\u30FC\u30D0\u30FC\u30AD\u30FC\u30D0\u30FC\u30B8\u30E7\u30F3\u304C\u4E0D\u660E\u3001\u307E\u305F\u306F\u5931\u52B9\u3057\u3066\u3044\u307E\u3059",
98
+ crypto_transportKeyStoreRequired: "\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u6697\u53F7\u5316\u306B\u306F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u516C\u958B\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u660E\u793A\u7684\u306A\u6307\u5B9A\u304C\u5FC5\u8981\u3067\u3059",
99
+ crypto_transportKeyStoreTtlInvalid: "\u516C\u958B\u30AD\u30FC\u30B9\u30C8\u30A2\u306E TTL \u306F1\u301C2147483647\u79D2\u306E\u6574\u6570\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
100
+ crypto_transportKeyStoreCapacityInvalid: "\u516C\u958B\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5BB9\u91CF\u306F\u6B63\u306E\u5B89\u5168\u306A\u6574\u6570\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
101
+ crypto_transportKeyStoreCapacityMismatch: "\u516C\u958B\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5171\u6709\u5BB9\u91CF\u8A2D\u5B9A\u304C\u4E00\u81F4\u3057\u307E\u305B\u3093",
102
+ crypto_transportKeyStoreCapacityReached: "\u516C\u958B\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u5BB9\u91CF\u4E0A\u9650\u306B\u9054\u3057\u307E\u3057\u305F",
103
+ crypto_transportKeyStoreOperationFailed: "\u516C\u958B\u30AD\u30FC\u30B9\u30C8\u30A2\u306E\u64CD\u4F5C\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
104
+ crypto_transportAuthenticationFailed: "\u30C8\u30E9\u30F3\u30B9\u30DD\u30FC\u30C8\u8A8D\u8A3C\u3001\u30EA\u30AF\u30A8\u30B9\u30C8\u3068\u306E\u7D10\u4ED8\u3051\u3001\u307E\u305F\u306F\u30EA\u30D7\u30EC\u30A4\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
105
+ crypto_transportKeyExchangeRequestFailed: "\u901A\u4FE1\u306E\u9375\u4EA4\u63DB\u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
106
+ crypto_transportKeyExchangeHttpFailed: "\u901A\u4FE1\u306E\u9375\u4EA4\u63DB\u3067HTTP {status}\u304C\u8FD4\u3055\u308C\u307E\u3057\u305F",
107
+ crypto_transportKeyExchangeInvalidJson: "\u901A\u4FE1\u306E\u9375\u4EA4\u63DB\u30EC\u30B9\u30DD\u30F3\u30B9\u304C\u6709\u52B9\u306AJSON\u3067\u306F\u3042\u308A\u307E\u305B\u3093",
108
+ crypto_transportKeyExchangeMissingFields: "\u901A\u4FE1\u306E\u9375\u4EA4\u63DB\u30EC\u30B9\u30DD\u30F3\u30B9\u306B\u5FC5\u9808\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u3042\u308A\u307E\u305B\u3093",
109
+ crypto_transportClientNotInitialized: "\u901A\u4FE1\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u306E\u9375\u4EA4\u63DB\u304C\u5B8C\u4E86\u3057\u3066\u3044\u307E\u305B\u3093",
110
+ crypto_transportClientNotRegistered: "\u901A\u4FE1\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u304C\u767B\u9332\u3055\u308C\u3066\u3044\u306A\u3044\u304B\u3001\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059",
111
+ crypto_transportRequestEncryptFailed: "\u901A\u4FE1\u30EA\u30AF\u30A8\u30B9\u30C8\u672C\u6587\u306E\u6697\u53F7\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
112
+ crypto_transportRequestDecryptFailed: "\u901A\u4FE1\u30EA\u30AF\u30A8\u30B9\u30C8\u672C\u6587\u306E\u5FA9\u53F7\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
113
+ crypto_transportResponseEncryptFailed: "\u901A\u4FE1\u30EC\u30B9\u30DD\u30F3\u30B9\u672C\u6587\u306E\u6697\u53F7\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
114
+ crypto_transportResponseDecryptFailed: "\u901A\u4FE1\u30EC\u30B9\u30DD\u30F3\u30B9\u672C\u6587\u306E\u5FA9\u53F7\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
115
+ crypto_transportSessionKeyEncryptFailed: "\u901A\u4FE1\u30BB\u30C3\u30B7\u30E7\u30F3\u9375\u306E\u6697\u53F7\u5316\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
116
+ crypto_transportSessionKeyDecryptFailed: "\u901A\u4FE1\u30BB\u30C3\u30B7\u30E7\u30F3\u9375\u306E\u5FA9\u53F7\u306B\u5931\u6557\u3057\u307E\u3057\u305F",
117
+ crypto_transportBodyLimitInvalid: "\u901A\u4FE1\u5E73\u6587\u306E\u4E0A\u9650\u306F 1024 \u304B\u3089 67108864 \u30D0\u30A4\u30C8\u306E\u6574\u6570\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044",
118
+ crypto_transportBodyTooLarge: "\u6697\u53F7\u5316\u901A\u4FE1\u306E\u30C7\u30FC\u30BF\u304C\u8A2D\u5B9A\u3055\u308C\u305F\u30D0\u30A4\u30C8\u4E0A\u9650\u3092\u8D85\u3048\u3066\u3044\u307E\u3059",
119
+ crypto_transportTimeInvalid: "\u7AEF\u672B\u3068\u30B5\u30FC\u30D0\u30FC\u306E\u6642\u523B\u304C\u540C\u671F\u3057\u3066\u3044\u306A\u3044\u304B\u3001\u8981\u6C42\u306E\u6709\u52B9\u671F\u9650\u304C\u5207\u308C\u3066\u3044\u307E\u3059\u3002\u81EA\u52D5\u6642\u523B\u540C\u671F\u3092\u6709\u52B9\u306B\u3057\u3066\u30DA\u30FC\u30B8\u3092\u518D\u8AAD\u307F\u8FBC\u307F\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u89E3\u6D88\u3057\u306A\u3044\u5834\u5408\u306F\u7BA1\u7406\u8005\u306B\u30B5\u30FC\u30D0\u30FC\u306E\u6642\u523B\u78BA\u8A8D\u3092\u4F9D\u983C\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
51
120
  };
52
121
 
53
122
  // messages/zh-CN.json
@@ -82,7 +151,15 @@ var zh_CN_default = {
82
151
  crypto_hashFormatInvalid: "\u65E0\u6548\u7684\u54C8\u5E0C\u683C\u5F0F",
83
152
  crypto_passwordVerifyFailed: "\u5BC6\u7801\u9A8C\u8BC1\u5931\u8D25",
84
153
  crypto_transportClientKeyGenerateFailed: "\u4F20\u8F93\u52A0\u5BC6\u5BA2\u6237\u7AEF\u5BC6\u94A5\u751F\u6210\u5931\u8D25",
85
- crypto_transportServerKeyGenerateFailed: "\u4F20\u8F93\u52A0\u5BC6\u670D\u52A1\u7AEF\u5BC6\u94A5\u751F\u6210\u5931\u8D25",
154
+ crypto_transportServerKeyRingInvalid: "\u670D\u52A1\u7AEF\u4F20\u8F93\u5BC6\u94A5\u73AF\u7F3A\u5931\u6216\u65E0\u6548\u3002\u8BF7\u68C0\u67E5\u79C1\u6709\u73AF\u5883\u53D8\u91CF HAI_CRYPTO_TRANSPORT_SERVERKEYRING \u662F\u5426\u4E3A\u5B8C\u6574\u6709\u6548\u7684 JSON\uFF0C\u5E76\u5411\u6240\u6709\u8282\u70B9\u5206\u53D1\u540C\u4E00\u5BC6\u94A5\u73AF\u3002",
155
+ crypto_transportServerKeyUnknown: "\u670D\u52A1\u7AEF\u4F20\u8F93\u5BC6\u94A5\u7248\u672C\u672A\u77E5\u6216\u5DF2\u64A4\u9500",
156
+ crypto_transportKeyStoreRequired: "\u4F20\u8F93\u52A0\u5BC6\u5FC5\u987B\u663E\u5F0F\u63D0\u4F9B\u5BA2\u6237\u7AEF\u516C\u94A5\u5B58\u50A8",
157
+ crypto_transportKeyStoreTtlInvalid: "\u516C\u94A5\u5B58\u50A8 TTL \u5FC5\u987B\u4E3A 1 \u5230 2147483647 \u4E4B\u95F4\u7684\u6574\u6570\u79D2",
158
+ crypto_transportKeyStoreCapacityInvalid: "\u516C\u94A5\u5B58\u50A8\u5BB9\u91CF\u5FC5\u987B\u4E3A\u6B63\u5B89\u5168\u6574\u6570",
159
+ crypto_transportKeyStoreCapacityMismatch: "\u516C\u94A5\u5B58\u50A8\u7684\u5171\u4EAB\u5BB9\u91CF\u914D\u7F6E\u4E0D\u4E00\u81F4",
160
+ crypto_transportKeyStoreCapacityReached: "\u516C\u94A5\u5B58\u50A8\u5BB9\u91CF\u5DF2\u6EE1",
161
+ crypto_transportKeyStoreOperationFailed: "\u516C\u94A5\u5B58\u50A8\u64CD\u4F5C\u5931\u8D25",
162
+ crypto_transportAuthenticationFailed: "\u4F20\u8F93\u6D88\u606F\u8BA4\u8BC1\u3001\u8BF7\u6C42\u7ED1\u5B9A\u6216\u9632\u91CD\u653E\u6821\u9A8C\u5931\u8D25",
86
163
  crypto_transportKeyExchangeRequestFailed: "\u4F20\u8F93\u52A0\u5BC6\u5BC6\u94A5\u534F\u5546\u8BF7\u6C42\u5931\u8D25",
87
164
  crypto_transportKeyExchangeHttpFailed: "\u4F20\u8F93\u52A0\u5BC6\u5BC6\u94A5\u534F\u5546\u8FD4\u56DE HTTP {status}",
88
165
  crypto_transportKeyExchangeInvalidJson: "\u4F20\u8F93\u52A0\u5BC6\u5BC6\u94A5\u534F\u5546\u54CD\u5E94\u4E0D\u662F\u6709\u6548 JSON",
@@ -94,13 +171,17 @@ var zh_CN_default = {
94
171
  crypto_transportResponseEncryptFailed: "\u4F20\u8F93\u52A0\u5BC6\u54CD\u5E94\u4F53\u52A0\u5BC6\u5931\u8D25",
95
172
  crypto_transportResponseDecryptFailed: "\u4F20\u8F93\u52A0\u5BC6\u54CD\u5E94\u4F53\u89E3\u5BC6\u5931\u8D25",
96
173
  crypto_transportSessionKeyEncryptFailed: "\u4F20\u8F93\u52A0\u5BC6\u4F1A\u8BDD\u5BC6\u94A5\u52A0\u5BC6\u5931\u8D25",
97
- crypto_transportSessionKeyDecryptFailed: "\u4F20\u8F93\u52A0\u5BC6\u4F1A\u8BDD\u5BC6\u94A5\u89E3\u5BC6\u5931\u8D25"
174
+ crypto_transportSessionKeyDecryptFailed: "\u4F20\u8F93\u52A0\u5BC6\u4F1A\u8BDD\u5BC6\u94A5\u89E3\u5BC6\u5931\u8D25",
175
+ crypto_transportBodyLimitInvalid: "\u4F20\u8F93\u660E\u6587\u5BB9\u91CF\u5FC5\u987B\u662F 1024 \u5230 67108864 \u5B57\u8282\u4E4B\u95F4\u7684\u6574\u6570",
176
+ crypto_transportBodyTooLarge: "\u52A0\u5BC6\u4F20\u8F93\u62A5\u6587\u8D85\u8FC7\u914D\u7F6E\u7684\u5B57\u8282\u4E0A\u9650",
177
+ crypto_transportTimeInvalid: "\u8BBE\u5907\u4E0E\u670D\u52A1\u5668\u65F6\u95F4\u53EF\u80FD\u4E0D\u540C\u6B65\uFF0C\u6216\u8BF7\u6C42\u5DF2\u8FC7\u671F\u3002\u8BF7\u5F00\u542F\u81EA\u52A8\u6821\u65F6\u5E76\u5237\u65B0\u91CD\u8BD5\uFF1B\u82E5\u4ECD\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u68C0\u67E5\u670D\u52A1\u5668\u65F6\u95F4\u3002"
98
178
  };
99
179
 
100
180
  // src/crypto-i18n.ts
101
181
  var cryptoM = core.i18n.createMessageGetter({
102
182
  "zh-CN": zh_CN_default,
103
- "en-US": en_US_default
183
+ "en-US": en_US_default,
184
+ "ja-JP": ja_JP_default
104
185
  });
105
186
  var CryptoErrorInfo = {
106
187
  INVALID_INPUT: "002:400",
@@ -114,7 +195,9 @@ var CryptoErrorInfo = {
114
195
  VERIFY_FAILED: "024:500",
115
196
  HASH_FAILED: "040:500",
116
197
  HMAC_FAILED: "041:500",
117
- INVALID_IV: "060:400"
198
+ INVALID_IV: "060:400",
199
+ TRANSPORT_PAYLOAD_TOO_LARGE: "070:413",
200
+ TRANSPORT_TIME_INVALID: "071:400"
118
201
  };
119
202
  var HaiCryptoError = core.error.buildHaiErrorsDef("crypto", CryptoErrorInfo);
120
203
 
@@ -241,6 +324,13 @@ function createPasswordFunctions(deps) {
241
324
  }
242
325
  };
243
326
  }
327
+ var SM2_PUBLIC_KEY_REGEX = /^(?:04)?[0-9a-f]{128}$/i;
328
+ function isValidSM2PublicKey(publicKey) {
329
+ if (typeof publicKey !== "string" || publicKey.length !== 128 && publicKey.length !== 130 || !SM2_PUBLIC_KEY_REGEX.test(publicKey))
330
+ return false;
331
+ const encoded = publicKey.length === 128 ? `04${publicKey}` : publicKey;
332
+ return smCrypto.sm2.verifyPublicKey(encoded) === true;
333
+ }
244
334
 
245
335
  // src/crypto-utils.ts
246
336
  function isBase64(str) {
@@ -264,7 +354,6 @@ function base64ToHex(base64) {
264
354
 
265
355
  // src/crypto-sm2.ts
266
356
  var { sm2 } = smCrypto;
267
- var SM2_PUBLIC_KEY_REGEX = /^[0-9a-f]{128}$/i;
268
357
  var SM2_PRIVATE_KEY_REGEX = /^[0-9a-f]{64}$/i;
269
358
  function createSM2() {
270
359
  return {
@@ -307,7 +396,7 @@ function createSM2() {
307
396
  );
308
397
  }
309
398
  try {
310
- const key = publicKey.startsWith("04") ? publicKey : `04${publicKey}`;
399
+ const key = publicKey.length === 130 ? publicKey : `04${publicKey}`;
311
400
  const encrypted = sm2.doEncrypt(data, key, cipherMode);
312
401
  if (!encrypted) {
313
402
  return err(
@@ -421,7 +510,7 @@ function createSM2() {
421
510
  );
422
511
  }
423
512
  try {
424
- const key = publicKey.startsWith("04") ? publicKey : `04${publicKey}`;
513
+ const key = publicKey.length === 130 ? publicKey : `04${publicKey}`;
425
514
  const isValid = sm2.doVerifySignature(data, signature, key, { hash, userId });
426
515
  return ok(!!isValid);
427
516
  } catch (error) {
@@ -433,18 +522,16 @@ function createSM2() {
433
522
  }
434
523
  },
435
524
  /**
436
- * 校验公钥格式是否合法
525
+ * 校验公钥编码及曲线点是否合法
437
526
  *
438
527
  * 合法格式:128 字符十六进制(无前缀)或 130 字符(含 04 前缀)。
439
528
  *
440
529
  * @param key - 待校验公钥
441
- * @returns 格式合法返回 true
530
+ * @returns 编码有效且为 SM2 曲线上的非无穷远点时返回 true
531
+ * @example `crypto.asymmetric.isValidPublicKey(clientPublicKey)`
442
532
  */
443
533
  isValidPublicKey(key) {
444
- if (!key || typeof key !== "string")
445
- return false;
446
- const cleanKey = key.startsWith("04") ? key.slice(2) : key;
447
- return SM2_PUBLIC_KEY_REGEX.test(cleanKey);
534
+ return isValidSM2PublicKey(key);
448
535
  },
449
536
  /**
450
537
  * 校验私钥格式是否合法
@@ -573,7 +660,7 @@ function stringToBytes(str) {
573
660
  const encoder = new TextEncoder();
574
661
  return Array.from(encoder.encode(str));
575
662
  }
576
- var { sm3: sm32, sm4 } = smCrypto;
663
+ var { sm4 } = smCrypto;
577
664
  var SM4_HEX_32_REGEX = /^[0-9a-f]{32}$/i;
578
665
  function createSM4() {
579
666
  return {
@@ -591,7 +678,7 @@ function createSM4() {
591
678
  * 默认使用 CBC 并自动生成随机 IV,返回结构化字段。
592
679
  *
593
680
  * ⚠️ 安全警告:ECB 模式会让相同明文块产生相同密文块,泄漏结构信息。
594
- * 生产场景请使用默认 CBC,或显式传入 `{ mode: 'cbc', iv }`。
681
+ * 新数据使用默认 CBC,或每次显式传入新的随机 IV;CBC 仍需独立完整性认证,HTTP 使用 transport。
595
682
  *
596
683
  * @param data - 待加密明文
597
684
  * @param key - 密钥(32 字符十六进制)
@@ -701,7 +788,7 @@ function createSM4() {
701
788
  *
702
789
  * @param data - 待加密明文
703
790
  * @param key - 密钥(32 字符十六进制)
704
- * @returns 成功时返回 { ciphertext, iv };失败时同 encrypt
791
+ * @returns 成功时返回完整 { mode, ciphertext, iv, encoding };失败时同 encrypt
705
792
  */
706
793
  encryptWithIV(data, key) {
707
794
  const iv = this.generateIV();
@@ -719,6 +806,8 @@ function createSM4() {
719
806
  /**
720
807
  * 带 IV 解密(CBC 模式)
721
808
  *
809
+ * 这是不含认证的底层 primitive;传输数据必须经 transport 验签及 MAC 后再调用,禁止直接用于 HTTP 解密。
810
+ *
722
811
  * @param ciphertext - 密文
723
812
  * @param key - 密钥
724
813
  * @param iv - 加密时使用的 IV
@@ -727,26 +816,6 @@ function createSM4() {
727
816
  decryptWithIV(ciphertext, key, iv) {
728
817
  return this.decrypt({ mode: "cbc", ciphertext, iv, encoding: "hex" }, key);
729
818
  },
730
- /**
731
- * 从密码和盐值派生密钥
732
- *
733
- * 内部仅执行单次 SM3 哈希(password + salt),取前 32 字符作为密钥。
734
- *
735
- * ⚠️ 安全警告:**此实现不是标准 KDF**,不具备密码爆破抗性(无迭代、无内存硬化)。
736
- * - **禁止用于密码存储**:密码散列请用 `crypto.password.hash()`。
737
- * - **禁止用于高价值密钥派生**:如需从密码派生加密密钥,请在应用层自行实现 PBKDF2 / scrypt / Argon2。
738
- * - 仅适用于测试、迭代兼容或不敏感的场景。
739
- *
740
- * @deprecated 未来版本可能移除。密码散列请用 `crypto.password.hash`;密钥派生请使用标准 KDF。
741
- * @param password - 密码
742
- * @param salt - 盐值
743
- * @returns 32 字符十六进制密钥
744
- */
745
- deriveKey(password, salt) {
746
- const combined = password + salt;
747
- const hash = sm32(combined);
748
- return hash.slice(0, 32);
749
- },
750
819
  /** 校验密钥格式是否合法(32 字符十六进制) */
751
820
  isValidKey(key) {
752
821
  return SM4_HEX_32_REGEX.test(key);
@@ -769,10 +838,102 @@ function decodeCiphertext(payload) {
769
838
  return payload.encoding === "base64" ? base64ToHex(payload.ciphertext) : payload.ciphertext;
770
839
  }
771
840
 
841
+ // src/transport/crypto-transport-body.ts
842
+ var TRANSPORT_PLAINTEXT_RANGE = Object.freeze({ min: 1024, max: 64 * 1024 * 1024 });
843
+ var TRANSPORT_BODY_LIMITS = Object.freeze({
844
+ /** 密钥协商 JSON 的 UTF-8 总字节数。 */
845
+ keyExchangeBytes: 16384,
846
+ /** GET/HEAD 请求及无正文响应的认证头封装 UTF-8 上限。 */
847
+ envelopeHeaderBytes: 16384,
848
+ /** 单个协商公钥的 UTF-8 字节数。 */
849
+ publicKeyBytes: 4096,
850
+ /** 解密后的请求/加密前的响应明文字节数。 */
851
+ plaintextBytes: 1048576,
852
+ /** 密文 JSON 的 UTF-8 总字节数(2 MiB + 32 KiB,含 CBC 填充与全部认证字段)。 */
853
+ encryptedPayloadBytes: 2129920
854
+ });
855
+ function resolveTransportBodyLimits(maxPlaintextBytes = TRANSPORT_BODY_LIMITS.plaintextBytes) {
856
+ if (!Number.isSafeInteger(maxPlaintextBytes) || maxPlaintextBytes < TRANSPORT_PLAINTEXT_RANGE.min || maxPlaintextBytes > TRANSPORT_PLAINTEXT_RANGE.max)
857
+ throw new RangeError(cryptoM("crypto_transportBodyLimitInvalid"));
858
+ return Object.freeze({ ...TRANSPORT_BODY_LIMITS, plaintextBytes: maxPlaintextBytes, encryptedPayloadBytes: 2 * maxPlaintextBytes + 32768 });
859
+ }
860
+ var TransportBodyTooLargeError = class extends RangeError {
861
+ code = HaiCryptoError.TRANSPORT_PAYLOAD_TOO_LARGE.code;
862
+ direction;
863
+ stage;
864
+ limitBytes;
865
+ actualBytes;
866
+ constructor(limitBytes, actualBytes, options = {}) {
867
+ super(cryptoM("crypto_transportBodyTooLarge"));
868
+ this.name = "TransportBodyTooLargeError";
869
+ this.limitBytes = limitBytes;
870
+ this.actualBytes = actualBytes;
871
+ this.direction = options.direction ?? "request";
872
+ this.stage = options.stage ?? "plaintext";
873
+ }
874
+ };
875
+ async function readTransportBody(stream, options) {
876
+ if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes < 0)
877
+ throw new RangeError("Invalid transport body byte limit");
878
+ if (!stream) {
879
+ options.signal?.throwIfAborted();
880
+ return "";
881
+ }
882
+ const reader = stream.getReader();
883
+ const signal = options.signal;
884
+ const decoder = new TextDecoder("utf-8", { fatal: true });
885
+ let completed = false;
886
+ let failure;
887
+ let onAbort;
888
+ try {
889
+ signal?.throwIfAborted();
890
+ const aborted = signal ? new Promise((_resolve, reject) => {
891
+ onAbort = () => reject(signal.reason);
892
+ signal.addEventListener("abort", onAbort, { once: true });
893
+ }) : void 0;
894
+ let bytes = 0;
895
+ let text = "";
896
+ while (true) {
897
+ const next = reader.read();
898
+ const chunk = await (aborted ? Promise.race([next, aborted]) : next);
899
+ if (chunk.done) {
900
+ completed = true;
901
+ return text + decoder.decode();
902
+ }
903
+ bytes += chunk.value.byteLength;
904
+ if (bytes > options.maxBytes)
905
+ throw new TransportBodyTooLargeError(options.maxBytes, bytes, options);
906
+ text += decoder.decode(chunk.value, { stream: true });
907
+ }
908
+ } catch (error) {
909
+ failure = error;
910
+ throw error;
911
+ } finally {
912
+ if (onAbort)
913
+ signal?.removeEventListener("abort", onAbort);
914
+ if (!completed) {
915
+ try {
916
+ void reader.cancel(failure).catch(() => {
917
+ });
918
+ } catch {
919
+ }
920
+ }
921
+ reader.releaseLock();
922
+ }
923
+ }
924
+
772
925
  // src/transport/crypto-transport-types.ts
773
926
  var TRANSPORT_PROTOCOL = {
774
927
  /** 客户端 ID 请求头名。 */
775
928
  CLIENT_ID_HEADER: "X-Client-Id",
929
+ /** GET/HEAD 等无正文请求的认证封装;禁止与正文封装同时出现。 */
930
+ ENVELOPE_HEADER: "X-Hai-Transport",
931
+ /** 唯一支持的认证协议版本;旧未认证格式拒绝。 */
932
+ VERSION: 2,
933
+ /** 请求允许的过去时间窗口(毫秒)。 */
934
+ REQUEST_WINDOW_MS: 3e5,
935
+ /** 节点时钟允许的最大未来偏差(毫秒)。 */
936
+ CLOCK_SKEW_MS: 3e4,
776
937
  /** 标识响应体已加密的响应头名。 */
777
938
  ENCRYPTED_HEADER: "X-Encrypted",
778
939
  /** `X-Encrypted` 响应头的开启值。 */
@@ -781,11 +942,138 @@ var TRANSPORT_PROTOCOL = {
781
942
  DEFAULT_KEY_EXCHANGE_PATH: "/_hai/key-exchange"
782
943
  };
783
944
 
945
+ // src/transport/crypto-transport-codec.ts
946
+ function authenticatedText(payload) {
947
+ const c = payload.context;
948
+ return JSON.stringify([
949
+ "hai-transport",
950
+ c.version,
951
+ payload.direction,
952
+ c.serverKeyId,
953
+ c.clientId,
954
+ c.requestId,
955
+ c.issuedAt,
956
+ c.method,
957
+ c.pathHash,
958
+ payload.status,
959
+ payload.encryptedKey,
960
+ payload.ciphertext,
961
+ payload.iv
962
+ ]);
963
+ }
964
+ function transportAuthenticationFailure() {
965
+ return err(HaiCryptoError.INVALID_INPUT, cryptoM("crypto_transportAuthenticationFailed"));
966
+ }
967
+ function hashTransportPath(service, path) {
968
+ try {
969
+ if (!path.startsWith("/") || new TextEncoder().encode(path).byteLength > 8192)
970
+ return transportAuthenticationFailure();
971
+ const digest = service.hash.hash(path);
972
+ return digest.success && /^[a-f0-9]{64}$/.test(digest.data) ? digest : transportAuthenticationFailure();
973
+ } catch {
974
+ return transportAuthenticationFailure();
975
+ }
976
+ }
977
+ function sealTransportPayload(service, plaintext, context, direction, status, recipientPublicKey, senderPrivateKey, limits = TRANSPORT_BODY_LIMITS) {
978
+ try {
979
+ const bytes = new TextEncoder().encode(plaintext).byteLength;
980
+ if (bytes > limits.plaintextBytes)
981
+ return err(HaiCryptoError.TRANSPORT_PAYLOAD_TOO_LARGE, cryptoM("crypto_transportBodyTooLarge"), new TransportBodyTooLargeError(limits.plaintextBytes, bytes, { direction }));
982
+ const encryptionKey = service.symmetric.generateKey();
983
+ const authenticationKey = service.symmetric.generateKey() + service.symmetric.generateKey();
984
+ const encrypted = service.symmetric.encryptWithIV(plaintext, encryptionKey);
985
+ const wrapped = service.asymmetric.encrypt(JSON.stringify([encryptionKey, authenticationKey]), recipientPublicKey);
986
+ if (!encrypted.success || !wrapped.success)
987
+ return transportAuthenticationFailure();
988
+ const payload = { context: { ...context }, direction, status, encryptedKey: wrapped.data, ciphertext: encrypted.data.ciphertext, iv: encrypted.data.iv };
989
+ const text = authenticatedText(payload);
990
+ const tag = service.hash.hmac(text, authenticationKey);
991
+ if (!tag.success)
992
+ return transportAuthenticationFailure();
993
+ const signature = service.asymmetric.sign(JSON.stringify([text, tag.data]), senderPrivateKey);
994
+ if (!signature.success)
995
+ return transportAuthenticationFailure();
996
+ const authenticated = { ...payload, tag: tag.data, signature: signature.data };
997
+ return isValidEncryptedPayload(authenticated, limits) ? ok(authenticated) : transportAuthenticationFailure();
998
+ } catch {
999
+ return transportAuthenticationFailure();
1000
+ }
1001
+ }
1002
+ function openTransportPayload(service, payload, recipientPrivateKey, senderPublicKey, limits = TRANSPORT_BODY_LIMITS) {
1003
+ try {
1004
+ if (!isValidEncryptedPayload(payload, limits))
1005
+ return transportAuthenticationFailure();
1006
+ const text = authenticatedText(payload);
1007
+ const verified = service.asymmetric.verify(JSON.stringify([text, payload.tag]), payload.signature, senderPublicKey);
1008
+ if (!verified.success || !verified.data)
1009
+ return transportAuthenticationFailure();
1010
+ const unwrapped = service.asymmetric.decrypt(payload.encryptedKey, recipientPrivateKey);
1011
+ if (!unwrapped.success)
1012
+ return transportAuthenticationFailure();
1013
+ const keys = JSON.parse(unwrapped.data);
1014
+ if (!Array.isArray(keys) || keys.length !== 2 || typeof keys[0] !== "string" || !/^[a-f0-9]{32}$/.test(keys[0]) || typeof keys[1] !== "string" || !/^[a-f0-9]{64}$/.test(keys[1])) {
1015
+ return transportAuthenticationFailure();
1016
+ }
1017
+ const tag = service.hash.hmac(text, keys[1]);
1018
+ if (!tag.success || !core.string.constantTimeEqual(tag.data, payload.tag))
1019
+ return transportAuthenticationFailure();
1020
+ const plaintext = service.symmetric.decryptWithIV(payload.ciphertext, keys[0], payload.iv);
1021
+ if (!plaintext.success)
1022
+ return transportAuthenticationFailure();
1023
+ const bytes = new TextEncoder().encode(plaintext.data).byteLength;
1024
+ if (bytes > limits.plaintextBytes)
1025
+ return err(HaiCryptoError.TRANSPORT_PAYLOAD_TOO_LARGE, cryptoM("crypto_transportBodyTooLarge"), new TransportBodyTooLargeError(limits.plaintextBytes, bytes, { direction: payload.direction }));
1026
+ return plaintext;
1027
+ } catch {
1028
+ return transportAuthenticationFailure();
1029
+ }
1030
+ }
1031
+ function isValidEncryptedPayload(value, limits = TRANSPORT_BODY_LIMITS) {
1032
+ if (!value || typeof value !== "object")
1033
+ return false;
1034
+ const p = value;
1035
+ const c = p.context;
1036
+ return Object.keys(p).length === 8 && !!c && typeof c === "object" && Object.keys(c).length === 7 && c.version === TRANSPORT_PROTOCOL.VERSION && typeof c.serverKeyId === "string" && /^[\w-]{1,64}$/.test(c.serverKeyId) && typeof c.clientId === "string" && /^[\w-]{1,128}$/.test(c.clientId) && typeof c.requestId === "string" && /^[a-f0-9]{32}$/.test(c.requestId) && Number.isSafeInteger(c.issuedAt) && c.issuedAt > 0 && typeof c.method === "string" && /^[A-Z]{1,16}$/.test(c.method) && typeof c.pathHash === "string" && /^[a-f0-9]{64}$/.test(c.pathHash) && (p.direction === "request" || p.direction === "response") && Number.isInteger(p.status) && (p.direction === "request" ? p.status === 0 : Number(p.status) >= 100 && Number(p.status) <= 599) && typeof p.encryptedKey === "string" && /^[a-f0-9]{1,8192}$/i.test(p.encryptedKey) && typeof p.ciphertext === "string" && p.ciphertext.length <= limits.encryptedPayloadBytes && p.ciphertext.length > 0 && p.ciphertext.length % 32 === 0 && /^[a-f0-9]+$/i.test(p.ciphertext) && typeof p.iv === "string" && /^[a-f0-9]{32}$/i.test(p.iv) && typeof p.tag === "string" && /^[a-f0-9]{64}$/.test(p.tag) && typeof p.signature === "string" && /^[a-f0-9]{128}$/i.test(p.signature);
1037
+ }
1038
+ function sameTransportContext(a, b) {
1039
+ return a.version === b.version && a.serverKeyId === b.serverKeyId && a.clientId === b.clientId && a.requestId === b.requestId && a.issuedAt === b.issuedAt && a.method === b.method && a.pathHash === b.pathHash;
1040
+ }
1041
+
1042
+ // src/transport/crypto-transport-error.ts
1043
+ var TransportTimeError = class extends Error {
1044
+ constructor(context) {
1045
+ super(cryptoM("crypto_transportTimeInvalid"));
1046
+ this.context = context;
1047
+ this.name = "TransportTimeError";
1048
+ }
1049
+ context;
1050
+ code = HaiCryptoError.TRANSPORT_TIME_INVALID.code;
1051
+ };
1052
+ async function createTransportErrorResponse(error, authenticated) {
1053
+ const status = error instanceof TransportTimeError ? 400 : error.direction === "request" ? 413 : 500;
1054
+ const body = JSON.stringify({ success: false, error: { code: error.code, message: error.message, httpStatus: status, details: error instanceof TransportTimeError ? void 0 : {
1055
+ direction: error.direction,
1056
+ stage: error.stage,
1057
+ limitBytes: error.limitBytes,
1058
+ actualBytes: error.actualBytes
1059
+ } } });
1060
+ if (authenticated) {
1061
+ const encrypted = await authenticated.manager.encryptResponse(authenticated.context, body, status);
1062
+ if (encrypted.success) {
1063
+ return Response.json(encrypted.data, { status, headers: { [TRANSPORT_PROTOCOL.ENCRYPTED_HEADER]: TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE } });
1064
+ }
1065
+ }
1066
+ return new Response(body, { status, headers: { "Content-Type": "application/json; charset=utf-8" } });
1067
+ }
1068
+
784
1069
  // src/transport/crypto-transport-client.ts
785
1070
  function createTransportClient(options) {
786
1071
  const baseFetch = options.fetch ?? fetch;
1072
+ const localLimits = options.maxPlaintextBytes === void 0 ? void 0 : resolveTransportBodyLimits(options.maxPlaintextBytes);
1073
+ let bodyLimits = localLimits ?? resolveTransportBodyLimits();
787
1074
  let keyPair = null;
788
1075
  let serverPublicKey = null;
1076
+ let serverKeyId = null;
789
1077
  let clientId = null;
790
1078
  let initPromise = null;
791
1079
  async function doInit() {
@@ -793,30 +1081,53 @@ function createTransportClient(options) {
793
1081
  if (!kpResult.success)
794
1082
  return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportClientKeyGenerateFailed"), kpResult.error);
795
1083
  const localKeyPair = kpResult.data;
796
- let response;
797
- try {
798
- response = await baseFetch(options.keyExchangeUrl, {
799
- method: "POST",
800
- headers: { "Content-Type": "application/json" },
801
- body: JSON.stringify({ clientPublicKey: localKeyPair.publicKey })
802
- });
803
- } catch (cause) {
804
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeRequestFailed"), cause);
805
- }
806
- if (!response.ok)
807
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeHttpFailed", { params: { status: response.status } }));
808
- let body;
1084
+ if (new TextEncoder().encode(localKeyPair.publicKey).byteLength > TRANSPORT_BODY_LIMITS.publicKeyBytes)
1085
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportClientKeyGenerateFailed"));
1086
+ const controller = new AbortController();
1087
+ const timeout = setTimeout(() => controller.abort(new DOMException("Key exchange timed out", "TimeoutError")), 3e4);
809
1088
  try {
810
- body = await response.json();
811
- } catch (cause) {
812
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeInvalidJson"), cause);
1089
+ let response;
1090
+ try {
1091
+ response = await baseFetch(options.keyExchangeUrl, {
1092
+ method: "POST",
1093
+ headers: { "Content-Type": "application/json" },
1094
+ body: JSON.stringify({ clientPublicKey: localKeyPair.publicKey }),
1095
+ signal: controller.signal
1096
+ });
1097
+ } catch (cause) {
1098
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeRequestFailed"), cause);
1099
+ }
1100
+ if (!response.ok) {
1101
+ void response.body?.cancel().catch(() => {
1102
+ });
1103
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeHttpFailed", { params: { status: response.status } }));
1104
+ }
1105
+ let body;
1106
+ try {
1107
+ body = JSON.parse(await readTransportBody(response.body, {
1108
+ maxBytes: TRANSPORT_BODY_LIMITS.keyExchangeBytes,
1109
+ signal: controller.signal
1110
+ }));
1111
+ } catch {
1112
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeInvalidJson"));
1113
+ }
1114
+ if (!isKeyExchangeResponse(body)) {
1115
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeMissingFields"));
1116
+ }
1117
+ try {
1118
+ const serverLimits = resolveTransportBodyLimits(body.maxPlaintextBytes);
1119
+ bodyLimits = resolveTransportBodyLimits(Math.min(localLimits?.plaintextBytes ?? serverLimits.plaintextBytes, serverLimits.plaintextBytes));
1120
+ } catch {
1121
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportBodyLimitInvalid"));
1122
+ }
1123
+ keyPair = localKeyPair;
1124
+ serverPublicKey = body.serverPublicKey;
1125
+ serverKeyId = body.serverKeyId;
1126
+ clientId = body.clientId;
1127
+ return ok(void 0);
1128
+ } finally {
1129
+ clearTimeout(timeout);
813
1130
  }
814
- if (!body.serverPublicKey || !body.clientId)
815
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportKeyExchangeMissingFields"));
816
- keyPair = localKeyPair;
817
- serverPublicKey = body.serverPublicKey;
818
- clientId = body.clientId;
819
- return ok(void 0);
820
1131
  }
821
1132
  async function ensureReady() {
822
1133
  if (clientId && serverPublicKey)
@@ -830,66 +1141,91 @@ function createTransportClient(options) {
830
1141
  }
831
1142
  return initPromise;
832
1143
  }
833
- function encryptBody(plaintext) {
834
- if (!serverPublicKey)
1144
+ function encryptBody(plaintext, context) {
1145
+ if (!serverPublicKey || !serverKeyId || !keyPair)
835
1146
  return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportClientNotInitialized"));
836
- const symKey = options.crypto.symmetric.generateKey();
837
- const encResult = options.crypto.symmetric.encryptWithIV(plaintext, symKey);
838
- if (!encResult.success)
839
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportRequestEncryptFailed"), encResult.error);
840
- const keyEncResult = options.crypto.asymmetric.encrypt(symKey, serverPublicKey);
841
- if (!keyEncResult.success)
842
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportSessionKeyEncryptFailed"), keyEncResult.error);
843
- return ok({
844
- encryptedKey: keyEncResult.data,
845
- ciphertext: encResult.data.ciphertext,
846
- iv: encResult.data.iv
847
- });
1147
+ return sealTransportPayload(options.crypto, plaintext, context, "request", 0, serverPublicKey, keyPair.privateKey, bodyLimits);
848
1148
  }
849
1149
  function decryptPayload(payload) {
850
- if (!keyPair)
1150
+ if (!keyPair || !serverPublicKey)
851
1151
  return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportClientNotInitialized"));
852
- const keyDec = options.crypto.asymmetric.decrypt(payload.encryptedKey, keyPair.privateKey);
853
- if (!keyDec.success)
854
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportSessionKeyDecryptFailed"), keyDec.error);
855
- const dec = options.crypto.symmetric.decryptWithIV(payload.ciphertext, keyDec.data, payload.iv);
856
- if (!dec.success)
857
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportResponseDecryptFailed"), dec.error);
858
- return ok(dec.data);
1152
+ return openTransportPayload(options.crypto, payload, keyPair.privateKey, serverPublicKey, bodyLimits);
859
1153
  }
860
1154
  const encryptedFetch = async (input, init) => {
861
1155
  const requestInput = isRequestLike(input) ? input : void 0;
1156
+ const signal = init?.signal ?? requestInput?.signal ?? void 0;
1157
+ signal?.throwIfAborted();
862
1158
  const targetUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : requestInput?.url ?? String(input);
863
1159
  if (targetUrl === options.keyExchangeUrl)
864
1160
  return baseFetch(input, init);
865
- const ready = await ensureReady();
1161
+ let onAbort;
1162
+ let ready;
1163
+ try {
1164
+ ready = await (signal ? Promise.race([
1165
+ ensureReady(),
1166
+ new Promise((_resolve, reject) => {
1167
+ onAbort = () => reject(signal.reason);
1168
+ signal.addEventListener("abort", onAbort, { once: true });
1169
+ if (signal.aborted)
1170
+ onAbort();
1171
+ })
1172
+ ]) : ensureReady());
1173
+ } finally {
1174
+ if (onAbort)
1175
+ signal?.removeEventListener("abort", onAbort);
1176
+ }
866
1177
  if (!ready.success)
867
1178
  throw new Error(ready.error.message);
868
1179
  const headers = new Headers(init?.headers ?? requestInput?.headers);
869
1180
  headers.set(TRANSPORT_PROTOCOL.CLIENT_ID_HEADER, clientId);
870
1181
  let rawBody = init?.body;
871
1182
  if (rawBody == null && requestInput) {
872
- const method = (init?.method ?? requestInput.method).toUpperCase();
873
- if (method !== "GET" && method !== "HEAD") {
874
- const text = await requestInput.clone().text();
1183
+ const method2 = (init?.method ?? requestInput.method).toUpperCase();
1184
+ if (method2 !== "GET" && method2 !== "HEAD") {
1185
+ const text = await readTransportBody(requestInput.body, { maxBytes: bodyLimits.plaintextBytes, signal });
875
1186
  if (text)
876
1187
  rawBody = text;
877
1188
  }
878
1189
  }
879
- let nextBody = rawBody;
880
- if (rawBody != null) {
881
- const plaintext = await bodyToText(rawBody);
882
- const encResult = encryptBody(plaintext);
883
- if (!encResult.success)
884
- throw new Error(encResult.error.message);
885
- nextBody = JSON.stringify(encResult.data);
1190
+ const method = (init?.method ?? requestInput?.method ?? "GET").toUpperCase();
1191
+ const base = new URL(options.keyExchangeUrl, globalThis.location?.href ?? "http://localhost");
1192
+ const url = new URL(targetUrl, base);
1193
+ const pathHash = hashTransportPath(options.crypto, url.pathname + url.search);
1194
+ if (!pathHash.success)
1195
+ throw new Error(pathHash.error.message);
1196
+ const context = {
1197
+ version: TRANSPORT_PROTOCOL.VERSION,
1198
+ serverKeyId,
1199
+ clientId,
1200
+ requestId: options.crypto.symmetric.generateKey(),
1201
+ issuedAt: Date.now(),
1202
+ method,
1203
+ pathHash: pathHash.data
1204
+ };
1205
+ const plaintext = rawBody == null ? "" : await readTransportBody(new Response(rawBody).body, { maxBytes: bodyLimits.plaintextBytes, signal });
1206
+ const encResult = encryptBody(plaintext, context);
1207
+ if (!encResult.success)
1208
+ throw new Error(encResult.error.message);
1209
+ const serialized = JSON.stringify(encResult.data);
1210
+ if (new TextEncoder().encode(serialized).byteLength > bodyLimits.encryptedPayloadBytes)
1211
+ throw new TransportBodyTooLargeError(bodyLimits.encryptedPayloadBytes, new TextEncoder().encode(serialized).byteLength, { stage: "encrypted" });
1212
+ let nextBody;
1213
+ headers.delete(TRANSPORT_PROTOCOL.ENVELOPE_HEADER);
1214
+ headers.set(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER, TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE);
1215
+ headers.delete("Content-Length");
1216
+ headers.delete("Content-Encoding");
1217
+ if (method === "GET" || method === "HEAD") {
1218
+ if (new TextEncoder().encode(serialized).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)
1219
+ throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(serialized).byteLength, { stage: "header" });
1220
+ headers.set(TRANSPORT_PROTOCOL.ENVELOPE_HEADER, serialized);
1221
+ } else {
1222
+ nextBody = serialized;
886
1223
  headers.set("Content-Type", "application/json");
887
- headers.set(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER, TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE);
888
1224
  }
889
1225
  const finalInput = requestInput ? requestInput.url : input;
890
1226
  const finalInit = {
891
1227
  ...init,
892
- method: init?.method ?? requestInput?.method,
1228
+ method,
893
1229
  headers,
894
1230
  body: nextBody,
895
1231
  cache: init?.cache ?? requestInput?.cache,
@@ -903,24 +1239,66 @@ function createTransportClient(options) {
903
1239
  signal: init?.signal ?? requestInput?.signal
904
1240
  };
905
1241
  const response = await baseFetch(finalInput, finalInit);
906
- if (response.headers.get(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER) !== TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE)
907
- return response;
908
- const cloned = response.clone();
1242
+ if (response.headers.get(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER) !== TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE) {
1243
+ void response.body?.cancel().catch(() => {
1244
+ });
1245
+ if (response.status === 413)
1246
+ throw new TransportBodyTooLargeError(bodyLimits.encryptedPayloadBytes, void 0, { stage: "encrypted" });
1247
+ throw new Error(cryptoM("crypto_transportResponseDecryptFailed"));
1248
+ }
909
1249
  let payload;
910
1250
  try {
911
- payload = await cloned.json();
912
- } catch {
913
- return response;
1251
+ const envelope = response.headers.get(TRANSPORT_PROTOCOL.ENVELOPE_HEADER);
1252
+ if (envelope && response.body !== null) {
1253
+ void response.body.cancel().catch(() => {
1254
+ });
1255
+ throw new Error(cryptoM("crypto_transportResponseDecryptFailed"));
1256
+ }
1257
+ if (envelope && new TextEncoder().encode(envelope).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)
1258
+ throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(envelope).byteLength, { direction: "response", stage: "header" });
1259
+ payload = JSON.parse(envelope ?? await readTransportBody(response.body, { maxBytes: bodyLimits.encryptedPayloadBytes, direction: "response", stage: "encrypted", signal }));
1260
+ } catch (error) {
1261
+ if (error instanceof TransportBodyTooLargeError)
1262
+ throw error;
1263
+ throw new Error(cryptoM("crypto_transportResponseDecryptFailed"), signal?.aborted ? { cause: signal.reason } : void 0);
1264
+ }
1265
+ if (!isValidEncryptedPayload(payload, bodyLimits) || payload.direction !== "response" || payload.status !== response.status || !sameTransportContext(payload.context, context)) {
1266
+ throw new Error(cryptoM("crypto_transportResponseDecryptFailed"));
914
1267
  }
915
- if (!isEncryptedPayload(payload))
916
- return response;
917
1268
  const decResult = decryptPayload(payload);
918
- if (!decResult.success)
1269
+ if (!decResult.success) {
1270
+ if (decResult.error.cause instanceof TransportBodyTooLargeError)
1271
+ throw decResult.error.cause;
919
1272
  throw new Error(decResult.error.message);
1273
+ }
1274
+ if (new TextEncoder().encode(decResult.data).byteLength > bodyLimits.plaintextBytes)
1275
+ throw new TransportBodyTooLargeError(bodyLimits.plaintextBytes, new TextEncoder().encode(decResult.data).byteLength, { direction: "response" });
1276
+ if (response.status === 400) {
1277
+ let failure;
1278
+ try {
1279
+ failure = JSON.parse(decResult.data);
1280
+ } catch {
1281
+ }
1282
+ if (failure?.success === false && failure.error?.code === HaiCryptoError.TRANSPORT_TIME_INVALID.code)
1283
+ throw new TransportTimeError();
1284
+ }
1285
+ if (response.status === 500) {
1286
+ let failure;
1287
+ try {
1288
+ failure = JSON.parse(decResult.data);
1289
+ } catch {
1290
+ }
1291
+ const details = failure?.error?.details;
1292
+ if (failure?.success === false && failure.error?.code === "hai:crypto:070" && details?.direction === "response" && (details.stage === "plaintext" || details.stage === "encrypted" || details.stage === "header") && typeof details.limitBytes === "number" && Number.isSafeInteger(details.limitBytes) && details.limitBytes >= 0) {
1293
+ throw new TransportBodyTooLargeError(details.limitBytes, typeof details.actualBytes === "number" ? details.actualBytes : void 0, { direction: "response", stage: details.stage });
1294
+ }
1295
+ }
920
1296
  const respHeaders = new Headers(response.headers);
921
1297
  respHeaders.delete(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER);
1298
+ respHeaders.delete(TRANSPORT_PROTOCOL.ENVELOPE_HEADER);
922
1299
  respHeaders.delete("Content-Length");
923
- return new Response(decResult.data, {
1300
+ respHeaders.delete("Content-Encoding");
1301
+ return new Response(method === "HEAD" || [204, 304].includes(response.status) ? null : decResult.data, {
924
1302
  status: response.status,
925
1303
  statusText: response.statusText,
926
1304
  headers: respHeaders
@@ -933,24 +1311,12 @@ function createTransportClient(options) {
933
1311
  destroy() {
934
1312
  keyPair = null;
935
1313
  serverPublicKey = null;
1314
+ serverKeyId = null;
936
1315
  clientId = null;
937
1316
  initPromise = null;
938
1317
  }
939
1318
  };
940
1319
  }
941
- async function bodyToText(body) {
942
- if (typeof body === "string")
943
- return body;
944
- if (body instanceof URLSearchParams)
945
- return body.toString();
946
- if (body instanceof Blob)
947
- return body.text();
948
- if (body instanceof ArrayBuffer)
949
- return new TextDecoder().decode(body);
950
- if (ArrayBuffer.isView(body))
951
- return new TextDecoder().decode(body.buffer);
952
- return new Response(body).text();
953
- }
954
1320
  function isRequestLike(input) {
955
1321
  if (typeof input !== "object" || input === null)
956
1322
  return false;
@@ -958,95 +1324,130 @@ function isRequestLike(input) {
958
1324
  const headers = candidate.headers;
959
1325
  return typeof candidate.url === "string" && typeof headers?.get === "function" && typeof candidate.method === "string" && typeof candidate.clone === "function";
960
1326
  }
961
- function isEncryptedPayload(payload) {
962
- if (!payload || typeof payload !== "object")
1327
+ function isKeyExchangeResponse(body) {
1328
+ if (!body || typeof body !== "object")
963
1329
  return false;
964
- const p = payload;
965
- return typeof p.encryptedKey === "string" && typeof p.ciphertext === "string" && typeof p.iv === "string";
966
- }
967
-
968
- // src/transport/store-provider/crypto-transport-store-memory.ts
969
- var DEFAULT_MAX_CLIENTS = 1e4;
970
- function normalizeMaxClients(maxClients) {
971
- if (!Number.isFinite(maxClients))
972
- return DEFAULT_MAX_CLIENTS;
973
- return Math.max(1, Math.floor(maxClients));
1330
+ const fields = body;
1331
+ return typeof fields.serverPublicKey === "string" && fields.serverPublicKey.length > 0 && new TextEncoder().encode(fields.serverPublicKey).byteLength <= TRANSPORT_BODY_LIMITS.publicKeyBytes && typeof fields.clientId === "string" && fields.clientId.length > 0 && typeof fields.serverKeyId === "string" && /^[\w-]{1,64}$/.test(fields.serverKeyId);
974
1332
  }
975
- function createClientId(counter) {
976
- const entropy = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID().replace(/-/g, "") : Math.random().toString(36).slice(2, 12);
977
- return `c_${counter}_${Date.now()}_${entropy}`;
1333
+ function parseTransportServerKeyRing(serialized) {
1334
+ try {
1335
+ const value = typeof serialized === "string" ? JSON.parse(serialized) : serialized;
1336
+ if (isTransportServerKeyRing(value))
1337
+ return ok(value);
1338
+ } catch {
1339
+ }
1340
+ return err(HaiCryptoError.INVALID_KEY, cryptoM("crypto_transportServerKeyRingInvalid"));
978
1341
  }
979
- function createInMemoryKeyStore(maxClients = DEFAULT_MAX_CLIENTS) {
980
- const clientKeys = /* @__PURE__ */ new Map();
981
- const capacity = normalizeMaxClients(maxClients);
982
- let counter = 0;
983
- return {
984
- async register(publicKey) {
985
- counter++;
986
- const clientId = createClientId(counter);
987
- if (clientKeys.size >= capacity) {
988
- const oldest = clientKeys.keys().next().value;
989
- if (oldest !== void 0)
990
- clientKeys.delete(oldest);
991
- }
992
- clientKeys.set(clientId, publicKey);
993
- return clientId;
994
- },
995
- async get(clientId) {
996
- return clientKeys.get(clientId);
997
- },
998
- async delete(clientId) {
999
- clientKeys.delete(clientId);
1000
- },
1001
- async close() {
1002
- clientKeys.clear();
1003
- }
1004
- };
1342
+ function isTransportServerKeyRing(value) {
1343
+ if (!value || typeof value !== "object")
1344
+ return false;
1345
+ const ring = value;
1346
+ if (typeof ring.activeKeyId !== "string" || !/^[\w-]{1,64}$/.test(ring.activeKeyId) || !ring.keys || typeof ring.keys !== "object" || Array.isArray(ring.keys)) {
1347
+ return false;
1348
+ }
1349
+ if (!Object.hasOwn(ring.keys, ring.activeKeyId))
1350
+ return false;
1351
+ return Object.entries(ring.keys).every(([id, pair]) => {
1352
+ if (!/^[\w-]{1,64}$/.test(id) || !pair || typeof pair !== "object")
1353
+ return false;
1354
+ const fields = pair;
1355
+ return typeof fields.publicKey === "string" && fields.publicKey.length > 0 && new TextEncoder().encode(fields.publicKey).byteLength <= TRANSPORT_BODY_LIMITS.publicKeyBytes && typeof fields.privateKey === "string" && fields.privateKey.length > 0 && fields.privateKey.length <= TRANSPORT_BODY_LIMITS.publicKeyBytes;
1356
+ });
1005
1357
  }
1006
1358
 
1007
1359
  // src/transport/crypto-transport-server.ts
1008
- function createTransportEncryption(cryptoService, options = {}) {
1009
- const keyPairResult = cryptoService.asymmetric.generateKeyPair();
1010
- if (!keyPairResult.success)
1011
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportServerKeyGenerateFailed"), keyPairResult.error);
1012
- const serverKeyPair = keyPairResult.data;
1013
- const keyStore = options.keyStore ?? createInMemoryKeyStore(options.maxClients);
1360
+ function createTransportEncryption(cryptoService, options) {
1361
+ let bodyLimits;
1362
+ try {
1363
+ bodyLimits = resolveTransportBodyLimits(options?.maxPlaintextBytes);
1364
+ } catch {
1365
+ return err(HaiCryptoError.INVALID_INPUT, cryptoM("crypto_transportBodyLimitInvalid"));
1366
+ }
1367
+ const ring = parseTransportServerKeyRing(options?.serverKeyRing);
1368
+ if (!ring.success)
1369
+ return ring;
1370
+ if (!options.keyStore || typeof options.keyStore.register !== "function" || typeof options.keyStore.get !== "function" || typeof options.keyStore.claimRequest !== "function") {
1371
+ return err(HaiCryptoError.INVALID_INPUT, cryptoM("crypto_transportKeyStoreRequired"));
1372
+ }
1373
+ if (core.module.requiresSharedState(globalThis.process?.env ?? {}) && options.keyStore.stateScope !== "shared")
1374
+ return err(HaiCryptoError.INVALID_INPUT, cryptoM("crypto_transportKeyStoreRequired"));
1375
+ const serverKeys = /* @__PURE__ */ new Map();
1376
+ for (const [id, key] of Object.entries(ring.data.keys)) {
1377
+ const probe = cryptoService.asymmetric.encrypt("hai-transport-key-check", key.publicKey);
1378
+ if (!probe.success)
1379
+ return err(HaiCryptoError.INVALID_KEY, cryptoM("crypto_transportServerKeyRingInvalid"));
1380
+ const checked = cryptoService.asymmetric.decrypt(probe.data, key.privateKey);
1381
+ if (!checked.success || checked.data !== "hai-transport-key-check")
1382
+ return err(HaiCryptoError.INVALID_KEY, cryptoM("crypto_transportServerKeyRingInvalid"));
1383
+ serverKeys.set(id, { publicKey: key.publicKey, privateKey: key.privateKey });
1384
+ }
1385
+ const activeKeyId = ring.data.activeKeyId;
1386
+ const serverKeyPair = serverKeys.get(activeKeyId);
1387
+ const keyStore = options.keyStore;
1014
1388
  const manager = {
1389
+ bodyLimits,
1390
+ getServerKeyId() {
1391
+ return activeKeyId;
1392
+ },
1015
1393
  getServerPublicKey() {
1016
1394
  return serverKeyPair.publicKey;
1017
1395
  },
1018
1396
  async registerClientKey(clientPublicKey) {
1397
+ if (!isValidSM2PublicKey(clientPublicKey))
1398
+ throw new TypeError(cryptoM("crypto_sm2PublicKeyInvalid"));
1019
1399
  return keyStore.register(clientPublicKey);
1020
1400
  },
1021
1401
  async getClientPublicKey(clientId) {
1022
1402
  return keyStore.get(clientId);
1023
1403
  },
1024
- async encryptResponse(clientId, data) {
1025
- const clientPublicKey = await keyStore.get(clientId);
1026
- if (!clientPublicKey)
1027
- return err(HaiCommonError.NOT_FOUND, cryptoM("crypto_transportClientNotRegistered"));
1028
- const symmetricKey = cryptoService.symmetric.generateKey();
1029
- const encResult = cryptoService.symmetric.encryptWithIV(data, symmetricKey);
1030
- if (!encResult.success)
1031
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportResponseEncryptFailed"), encResult.error);
1032
- const keyEncResult = cryptoService.asymmetric.encrypt(symmetricKey, clientPublicKey);
1033
- if (!keyEncResult.success)
1034
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportSessionKeyEncryptFailed"), keyEncResult.error);
1035
- const payload = {
1036
- encryptedKey: keyEncResult.data,
1037
- ciphertext: encResult.data.ciphertext,
1038
- iv: encResult.data.iv
1039
- };
1040
- return ok(payload);
1404
+ async encryptResponse(request, data, status) {
1405
+ try {
1406
+ const context = { ...request };
1407
+ const clientPublicKey = await keyStore.get(context.clientId);
1408
+ if (!clientPublicKey)
1409
+ return err(HaiCommonError.NOT_FOUND, cryptoM("crypto_transportClientNotRegistered"));
1410
+ const key = serverKeys.get(context.serverKeyId);
1411
+ if (!key)
1412
+ return transportAuthenticationFailure();
1413
+ return sealTransportPayload(cryptoService, data, context, "response", status, clientPublicKey, key.privateKey, bodyLimits);
1414
+ } catch {
1415
+ return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportResponseEncryptFailed"));
1416
+ }
1041
1417
  },
1042
- decryptRequest(payload) {
1043
- const keyDecResult = cryptoService.asymmetric.decrypt(payload.encryptedKey, serverKeyPair.privateKey);
1044
- if (!keyDecResult.success)
1045
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportSessionKeyDecryptFailed"), keyDecResult.error);
1046
- const decResult = cryptoService.symmetric.decryptWithIV(payload.ciphertext, keyDecResult.data, payload.iv);
1047
- if (!decResult.success)
1048
- return err(HaiCommonError.INTERNAL_ERROR, cryptoM("crypto_transportRequestDecryptFailed"), decResult.error);
1049
- return ok(decResult.data);
1418
+ async decryptRequest(payload, expected) {
1419
+ try {
1420
+ if (!isValidEncryptedPayload(payload, bodyLimits) || payload.direction !== "request" || payload.status !== 0)
1421
+ return transportAuthenticationFailure();
1422
+ const authenticated = { ...payload, context: { ...payload.context } };
1423
+ const c = authenticated.context;
1424
+ const pathHash = hashTransportPath(cryptoService, expected.path);
1425
+ if (!pathHash.success || c.clientId !== expected.clientId || c.method !== expected.method || c.pathHash !== pathHash.data) {
1426
+ return transportAuthenticationFailure();
1427
+ }
1428
+ const key = serverKeys.get(c.serverKeyId);
1429
+ const clientPublicKey = await keyStore.get(c.clientId);
1430
+ if (!key || !clientPublicKey)
1431
+ return transportAuthenticationFailure();
1432
+ const plaintext = openTransportPayload(cryptoService, authenticated, key.privateKey, clientPublicKey, bodyLimits);
1433
+ if (!plaintext.success)
1434
+ return plaintext;
1435
+ const timeFailure = () => {
1436
+ const error = new TransportTimeError(c);
1437
+ return err(HaiCryptoError.TRANSPORT_TIME_INVALID, error.message, error);
1438
+ };
1439
+ const now = Date.now();
1440
+ if (c.issuedAt > now + TRANSPORT_PROTOCOL.CLOCK_SKEW_MS || now >= c.issuedAt + TRANSPORT_PROTOCOL.REQUEST_WINDOW_MS)
1441
+ return timeFailure();
1442
+ if (!await keyStore.claimRequest(c.clientId, c.requestId, c.issuedAt + TRANSPORT_PROTOCOL.REQUEST_WINDOW_MS + 2 * TRANSPORT_PROTOCOL.CLOCK_SKEW_MS)) {
1443
+ return transportAuthenticationFailure();
1444
+ }
1445
+ if (Date.now() >= c.issuedAt + TRANSPORT_PROTOCOL.REQUEST_WINDOW_MS)
1446
+ return timeFailure();
1447
+ return plaintext;
1448
+ } catch {
1449
+ return transportAuthenticationFailure();
1450
+ }
1050
1451
  },
1051
1452
  async close() {
1052
1453
  await keyStore.close?.();
@@ -1075,7 +1476,7 @@ function getCrypto() {
1075
1476
  return crypto2;
1076
1477
  }
1077
1478
  var transportOperations = {
1078
- createServer: (options) => createTransportEncryption(getCrypto(), options),
1479
+ createServer: (options) => getCrypto().isInitialized ? createTransportEncryption(getCrypto(), options) : notInitialized.result(),
1079
1480
  createClient: (options) => createTransportClient({ crypto: getCrypto(), ...options }),
1080
1481
  protocol: TRANSPORT_PROTOCOL
1081
1482
  };
@@ -1148,8 +1549,7 @@ var crypto2 = {
1148
1549
  /**
1149
1550
  * 传输加密操作(端到端混合加密)
1150
1551
  *
1151
- * createServer 内部直接复用 asymmetric/symmetric,因此未初始化时
1152
- * 自动通过 asymmetric proxy 返回 NOT_INITIALIZED 错误。
1552
+ * createServer 检查初始化后复用 asymmetric/symmetric;未初始化返回 NOT_INITIALIZED。
1153
1553
  */
1154
1554
  transport: transportOperations,
1155
1555
  /** 是否已初始化 */
@@ -1175,13 +1575,120 @@ var crypto2 = {
1175
1575
  logger.info("Crypto module closed");
1176
1576
  }
1177
1577
  };
1578
+ async function authenticateTransportRequest(manager, request) {
1579
+ const reject = () => {
1580
+ void request.body?.cancel().catch(() => {
1581
+ });
1582
+ return transportAuthenticationFailure();
1583
+ };
1584
+ if (request.headers.get(TRANSPORT_PROTOCOL.ENCRYPTED_HEADER) !== TRANSPORT_PROTOCOL.ENCRYPTED_HEADER_VALUE)
1585
+ return reject();
1586
+ const clientId = request.headers.get(TRANSPORT_PROTOCOL.CLIENT_ID_HEADER);
1587
+ if (!clientId)
1588
+ return reject();
1589
+ const envelope = request.headers.get(TRANSPORT_PROTOCOL.ENVELOPE_HEADER);
1590
+ const bodyless = request.method === "GET" || request.method === "HEAD";
1591
+ if (bodyless && (!envelope || request.body !== null) || !bodyless && envelope !== null)
1592
+ return reject();
1593
+ if (envelope && new TextEncoder().encode(envelope).byteLength > TRANSPORT_BODY_LIMITS.envelopeHeaderBytes)
1594
+ throw new TransportBodyTooLargeError(TRANSPORT_BODY_LIMITS.envelopeHeaderBytes, new TextEncoder().encode(envelope).byteLength, { stage: "header" });
1595
+ const text = envelope ?? await readTransportBody(request.body, {
1596
+ maxBytes: manager.bodyLimits.encryptedPayloadBytes,
1597
+ stage: "encrypted",
1598
+ signal: request.signal
1599
+ });
1600
+ let payload;
1601
+ try {
1602
+ payload = JSON.parse(text);
1603
+ } catch {
1604
+ return transportAuthenticationFailure();
1605
+ }
1606
+ if (!isValidEncryptedPayload(payload, manager.bodyLimits) || payload.direction !== "request" || payload.status !== 0)
1607
+ return transportAuthenticationFailure();
1608
+ const url = new URL(request.url);
1609
+ const decrypted = await manager.decryptRequest(payload, {
1610
+ clientId,
1611
+ method: request.method,
1612
+ path: url.pathname + url.search
1613
+ });
1614
+ if (!decrypted.success) {
1615
+ if (decrypted.error.cause instanceof TransportBodyTooLargeError)
1616
+ throw decrypted.error.cause;
1617
+ return decrypted;
1618
+ }
1619
+ if (new TextEncoder().encode(decrypted.data).byteLength > manager.bodyLimits.plaintextBytes)
1620
+ throw new TransportBodyTooLargeError(manager.bodyLimits.plaintextBytes, new TextEncoder().encode(decrypted.data).byteLength);
1621
+ if (bodyless && decrypted.data !== "")
1622
+ return transportAuthenticationFailure();
1623
+ return ok({ plaintext: decrypted.data, context: payload.context });
1624
+ }
1625
+
1626
+ // src/transport/store-provider/crypto-transport-store-memory.ts
1627
+ var DEFAULT_MAX_CLIENTS = 1e4;
1628
+ function normalizeMaxClients(maxClients) {
1629
+ if (!Number.isFinite(maxClients))
1630
+ return DEFAULT_MAX_CLIENTS;
1631
+ return Math.max(1, Math.floor(maxClients));
1632
+ }
1633
+ function createClientId(counter) {
1634
+ const entropy = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID().replace(/-/g, "") : Math.random().toString(36).slice(2, 12);
1635
+ return `c_${counter}_${Date.now()}_${entropy}`;
1636
+ }
1637
+ function createInMemoryKeyStore(maxClients = DEFAULT_MAX_CLIENTS) {
1638
+ const clientKeys = /* @__PURE__ */ new Map();
1639
+ const requests = /* @__PURE__ */ new Map();
1640
+ const capacity = normalizeMaxClients(maxClients);
1641
+ let counter = 0;
1642
+ return {
1643
+ get stateScope() {
1644
+ return "local";
1645
+ },
1646
+ async register(publicKey) {
1647
+ if (!isValidSM2PublicKey(publicKey))
1648
+ throw new TypeError(cryptoM("crypto_sm2PublicKeyInvalid"));
1649
+ counter++;
1650
+ const clientId = createClientId(counter);
1651
+ if (clientKeys.size >= capacity) {
1652
+ const oldest = clientKeys.keys().next().value;
1653
+ if (oldest !== void 0)
1654
+ clientKeys.delete(oldest);
1655
+ }
1656
+ clientKeys.set(clientId, publicKey);
1657
+ return clientId;
1658
+ },
1659
+ async get(clientId) {
1660
+ return clientKeys.get(clientId);
1661
+ },
1662
+ async claimRequest(clientId, requestId, expiresAt) {
1663
+ const now = Date.now();
1664
+ for (const [id2, expiry] of requests) {
1665
+ if (expiry <= now)
1666
+ requests.delete(id2);
1667
+ }
1668
+ const id = JSON.stringify([clientId, requestId]);
1669
+ if (requests.has(id) || expiresAt <= now)
1670
+ return false;
1671
+ requests.set(id, expiresAt);
1672
+ return true;
1673
+ },
1674
+ async delete(clientId) {
1675
+ clientKeys.delete(clientId);
1676
+ },
1677
+ async close() {
1678
+ clientKeys.clear();
1679
+ requests.clear();
1680
+ }
1681
+ };
1682
+ }
1178
1683
 
1179
1684
  // src/transport/store-provider/crypto-transport-store-redis.ts
1180
1685
  var TRANSPORT_KEY_CACHE_PREFIX = "hai:crypto:transport:client";
1181
1686
  function normalizeTtlSeconds(ttlSeconds) {
1182
- if (ttlSeconds === void 0 || !Number.isFinite(ttlSeconds) || ttlSeconds <= 0)
1687
+ if (ttlSeconds === void 0)
1183
1688
  return void 0;
1184
- return Math.floor(ttlSeconds);
1689
+ if (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0 || ttlSeconds > 2147483647)
1690
+ throw new TypeError(cryptoM("crypto_transportKeyStoreTtlInvalid"));
1691
+ return ttlSeconds;
1185
1692
  }
1186
1693
  function createClientId2() {
1187
1694
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
@@ -1204,9 +1711,14 @@ function createRedisTransportKeyStore(options) {
1204
1711
  return `${TRANSPORT_KEY_CACHE_PREFIX}:${clientId}`;
1205
1712
  }
1206
1713
  return {
1714
+ get stateScope() {
1715
+ return options.cache.config?.type === "redis" ? "shared" : "local";
1716
+ },
1207
1717
  async register(publicKey) {
1718
+ if (!isValidSM2PublicKey(publicKey))
1719
+ throw new TypeError(cryptoM("crypto_sm2PublicKeyInvalid"));
1208
1720
  const clientId = createClientId2();
1209
- unwrapResult(
1721
+ const applied = unwrapResult(
1210
1722
  "cache.kv.set",
1211
1723
  await options.cache.kv.set(
1212
1724
  buildCacheKey(clientId),
@@ -1214,6 +1726,8 @@ function createRedisTransportKeyStore(options) {
1214
1726
  ttlSeconds === void 0 ? void 0 : { ex: ttlSeconds }
1215
1727
  )
1216
1728
  );
1729
+ if (!applied)
1730
+ throw new Error(cryptoM("crypto_transportClientNotRegistered"));
1217
1731
  return clientId;
1218
1732
  },
1219
1733
  async get(clientId) {
@@ -1223,6 +1737,17 @@ function createRedisTransportKeyStore(options) {
1223
1737
  );
1224
1738
  return publicKey ?? void 0;
1225
1739
  },
1740
+ async claimRequest(clientId, requestId, expiresAt) {
1741
+ const ttl = expiresAt - Date.now();
1742
+ if (ttl <= 0)
1743
+ return false;
1744
+ return unwrapResult("cache.kv.compareAndSwap", await options.cache.kv.compareAndSwap(
1745
+ `hai:crypto:transport:request:${clientId}:${requestId}`,
1746
+ void 0,
1747
+ true,
1748
+ { px: ttl }
1749
+ ));
1750
+ },
1226
1751
  async delete(clientId) {
1227
1752
  unwrapResult("cache.kv.del", await options.cache.kv.del(buildCacheKey(clientId)));
1228
1753
  }
@@ -1231,20 +1756,11 @@ function createRedisTransportKeyStore(options) {
1231
1756
 
1232
1757
  // src/transport/store-provider/crypto-transport-store-reldb.ts
1233
1758
  var TRANSPORT_KEY_TABLE = "hai_crypto_transport_client_keys";
1234
- function normalizeTtlSeconds2(ttlSeconds) {
1235
- if (ttlSeconds === void 0 || !Number.isFinite(ttlSeconds) || ttlSeconds <= 0)
1236
- return void 0;
1237
- return Math.floor(ttlSeconds);
1238
- }
1239
- function createClientId3() {
1240
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function")
1241
- return `c_${crypto.randomUUID()}`;
1242
- return `c_${Date.now()}_${Math.random().toString(36).slice(2, 12)}`;
1243
- }
1759
+ var TRANSPORT_REQUEST_TABLE = "hai_crypto_transport_requests";
1760
+ var TRANSPORT_CAPACITY_TABLE = "hai_crypto_transport_capacity";
1761
+ var PRUNE_BATCH_SIZE = 100;
1244
1762
  function toOperationError2(operation, error) {
1245
- const wrapped = new Error(`${operation} failed: ${error.message}`, { cause: error });
1246
- wrapped.code = error.code;
1247
- return wrapped;
1763
+ return Object.assign(new Error(cryptoM("crypto_transportKeyStoreOperationFailed")), { operation, code: error.code });
1248
1764
  }
1249
1765
  function unwrapResult2(operation, result) {
1250
1766
  if (result.success)
@@ -1252,21 +1768,66 @@ function unwrapResult2(operation, result) {
1252
1768
  throw toOperationError2(operation, result.error);
1253
1769
  }
1254
1770
  function createReldbTransportKeyStore(options) {
1255
- const ttlSeconds = normalizeTtlSeconds2(options.ttlSeconds);
1771
+ const { ttlSeconds } = options;
1772
+ if (ttlSeconds !== void 0 && (!Number.isSafeInteger(ttlSeconds) || ttlSeconds <= 0 || ttlSeconds > 2147483647))
1773
+ throw new TypeError(cryptoM("crypto_transportKeyStoreTtlInvalid"));
1774
+ const maxClients = options.maxClients ?? 1e4;
1775
+ if (!Number.isSafeInteger(maxClients) || maxClients <= 0)
1776
+ throw new TypeError(cryptoM("crypto_transportKeyStoreCapacityInvalid"));
1256
1777
  let ensureTablePromise = null;
1778
+ function nowSql() {
1779
+ switch (options.reldb.config?.type) {
1780
+ case "postgresql":
1781
+ return "CAST(FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) AS BIGINT)";
1782
+ case "mysql":
1783
+ return "CAST(FLOOR(UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000) AS SIGNED)";
1784
+ default:
1785
+ return "(CAST(strftime('%s', 'now') AS INTEGER) * 1000 + CAST(substr(strftime('%f', 'now'), 4, 3) AS INTEGER))";
1786
+ }
1787
+ }
1788
+ function insertIfAbsent(table, columns, placeholders, key) {
1789
+ return options.reldb.config?.type === "mysql" ? `INSERT IGNORE INTO ${table} (${columns}) VALUES (${placeholders})` : `INSERT INTO ${table} (${columns}) VALUES (${placeholders}) ON CONFLICT (${key}) DO NOTHING`;
1790
+ }
1257
1791
  async function ensureTable() {
1258
1792
  if (!ensureTablePromise) {
1259
- ensureTablePromise = (async () => {
1793
+ const initialization = (async () => {
1260
1794
  unwrapResult2(
1261
1795
  "reldb.ddl.createTable",
1262
1796
  await options.reldb.ddl.createTable(TRANSPORT_KEY_TABLE, {
1263
1797
  client_id: { type: "TEXT", primaryKey: true },
1264
1798
  public_key: { type: "TEXT", notNull: true },
1265
- created_at: { type: "TIMESTAMP", notNull: true },
1266
- expires_at: { type: "TIMESTAMP" }
1799
+ created_at_ms: { type: "BIGINT", notNull: true },
1800
+ expires_at_ms: { type: "BIGINT" }
1267
1801
  }, true)
1268
1802
  );
1803
+ unwrapResult2("reldb.ddl.createTable", await options.reldb.ddl.createTable(TRANSPORT_REQUEST_TABLE, {
1804
+ request_key: { type: "TEXT", primaryKey: true },
1805
+ expires_at: { type: "BIGINT", notNull: true }
1806
+ }, true));
1807
+ unwrapResult2("reldb.ddl.createTable", await options.reldb.ddl.createTable(TRANSPORT_CAPACITY_TABLE, {
1808
+ id: { type: "INTEGER", primaryKey: true },
1809
+ max_clients: { type: "BIGINT", notNull: true },
1810
+ revision: { type: "BIGINT", notNull: true }
1811
+ }, true));
1812
+ unwrapResult2("reldb.sql.execute", await options.reldb.sql.execute(
1813
+ insertIfAbsent(TRANSPORT_CAPACITY_TABLE, "id, max_clients, revision", "?, ?, ?", "id"),
1814
+ [1, maxClients, 0]
1815
+ ));
1816
+ const capacity = unwrapResult2("reldb.sql.get", await options.reldb.sql.get(
1817
+ `SELECT max_clients FROM ${TRANSPORT_CAPACITY_TABLE} WHERE id = ?`,
1818
+ [1]
1819
+ ));
1820
+ if (!capacity || Number(capacity.max_clients) !== maxClients)
1821
+ throw new Error(cryptoM("crypto_transportKeyStoreCapacityMismatch"));
1269
1822
  })();
1823
+ ensureTablePromise = initialization;
1824
+ try {
1825
+ await initialization;
1826
+ } catch (error) {
1827
+ if (ensureTablePromise === initialization)
1828
+ ensureTablePromise = null;
1829
+ throw error;
1830
+ }
1270
1831
  }
1271
1832
  return ensureTablePromise;
1272
1833
  }
@@ -1279,45 +1840,88 @@ function createReldbTransportKeyStore(options) {
1279
1840
  )
1280
1841
  );
1281
1842
  }
1843
+ async function withCapacityLock(operation) {
1844
+ await ensureTable();
1845
+ const result = await options.reldb.tx.wrap(async (tx) => {
1846
+ const locked = unwrapResult2("tx.execute", await tx.execute(
1847
+ `UPDATE ${TRANSPORT_CAPACITY_TABLE} SET revision = revision + 1 WHERE id = ? AND max_clients = ?`,
1848
+ [1, maxClients]
1849
+ ));
1850
+ if (locked.changes !== 1)
1851
+ throw new Error(cryptoM("crypto_transportKeyStoreCapacityMismatch"));
1852
+ return operation(tx);
1853
+ });
1854
+ return unwrapResult2("reldb.tx.wrap", result);
1855
+ }
1856
+ async function pruneRows(tx) {
1857
+ let removed = 0;
1858
+ for (const [table, id, expiry] of [[TRANSPORT_KEY_TABLE, "client_id", "expires_at_ms"], [TRANSPORT_REQUEST_TABLE, "request_key", "expires_at"]]) {
1859
+ removed += unwrapResult2("tx.execute", await tx.execute(
1860
+ `DELETE FROM ${table} WHERE ${expiry} <= ${nowSql()} AND ${id} IN (SELECT ${id} FROM (SELECT ${id} FROM ${table} WHERE ${expiry} <= ${nowSql()} LIMIT ${PRUNE_BATCH_SIZE}) AS expired)`
1861
+ )).changes;
1862
+ }
1863
+ return removed;
1864
+ }
1865
+ async function pruneExpired() {
1866
+ return withCapacityLock(pruneRows);
1867
+ }
1282
1868
  return {
1869
+ get stateScope() {
1870
+ return options.reldb.config?.type && options.reldb.config.type !== "sqlite" ? "shared" : "local";
1871
+ },
1283
1872
  async register(publicKey) {
1284
- await ensureTable();
1285
- const clientId = createClientId3();
1286
- const createdAt = (/* @__PURE__ */ new Date()).toISOString();
1287
- const expiresAt = ttlSeconds === void 0 ? null : new Date(Date.now() + ttlSeconds * 1e3).toISOString();
1288
- unwrapResult2(
1289
- "reldb.sql.execute",
1290
- await options.reldb.sql.execute(
1291
- `INSERT INTO ${TRANSPORT_KEY_TABLE} (client_id, public_key, created_at, expires_at) VALUES (?, ?, ?, ?)`,
1292
- [clientId, publicKey, createdAt, expiresAt]
1293
- )
1294
- );
1295
- return clientId;
1873
+ if (!isValidSM2PublicKey(publicKey))
1874
+ throw new TypeError(cryptoM("crypto_sm2PublicKeyInvalid"));
1875
+ const clientId = `c_${globalThis.crypto.randomUUID()}`;
1876
+ return withCapacityLock(async (tx) => {
1877
+ await pruneRows(tx);
1878
+ const count = unwrapResult2("tx.get", await tx.get(
1879
+ `SELECT COUNT(*) AS total FROM ${TRANSPORT_KEY_TABLE} WHERE expires_at_ms IS NULL OR expires_at_ms > ${nowSql()}`
1880
+ ));
1881
+ const total = Number(count?.total);
1882
+ if (!Number.isSafeInteger(total) || total < 0)
1883
+ throw new Error(cryptoM("crypto_transportKeyStoreOperationFailed"));
1884
+ if (total >= maxClients)
1885
+ throw new Error(cryptoM("crypto_transportKeyStoreCapacityReached"));
1886
+ const inserted = unwrapResult2("tx.execute", await tx.execute(
1887
+ `INSERT INTO ${TRANSPORT_KEY_TABLE} (client_id, public_key, created_at_ms, expires_at_ms) VALUES (?, ?, ${nowSql()}, ${ttlSeconds === void 0 ? "NULL" : `${nowSql()} + ?`})`,
1888
+ ttlSeconds === void 0 ? [clientId, publicKey] : [clientId, publicKey, ttlSeconds * 1e3]
1889
+ ));
1890
+ if (inserted.changes !== 1)
1891
+ throw new Error(cryptoM("crypto_transportClientNotRegistered"));
1892
+ return clientId;
1893
+ });
1296
1894
  },
1297
1895
  async get(clientId) {
1298
1896
  await ensureTable();
1299
1897
  const row = unwrapResult2(
1300
1898
  "reldb.sql.get",
1301
1899
  await options.reldb.sql.get(
1302
- `SELECT public_key, expires_at FROM ${TRANSPORT_KEY_TABLE} WHERE client_id = ?`,
1900
+ `SELECT public_key FROM ${TRANSPORT_KEY_TABLE} WHERE client_id = ? AND (expires_at_ms IS NULL OR expires_at_ms > ${nowSql()})`,
1303
1901
  [clientId]
1304
1902
  )
1305
1903
  );
1306
- if (!row)
1307
- return void 0;
1308
- if (row.expires_at && Date.parse(row.expires_at) <= Date.now()) {
1309
- await deleteClientKey(clientId);
1310
- return void 0;
1311
- }
1312
- return row.public_key;
1904
+ return row?.public_key;
1905
+ },
1906
+ async claimRequest(clientId, requestId, expiresAt) {
1907
+ await ensureTable();
1908
+ if (!Number.isSafeInteger(expiresAt) || expiresAt <= Date.now())
1909
+ return false;
1910
+ const insertSql = options.reldb.config?.type === "mysql" ? `INSERT IGNORE INTO ${TRANSPORT_REQUEST_TABLE} (request_key, expires_at) VALUES (?, ?)` : `INSERT INTO ${TRANSPORT_REQUEST_TABLE} (request_key, expires_at) VALUES (?, ?) ON CONFLICT (request_key) DO NOTHING`;
1911
+ const inserted = unwrapResult2("reldb.sql.execute", await options.reldb.sql.execute(
1912
+ insertSql,
1913
+ [JSON.stringify([clientId, requestId]), expiresAt]
1914
+ ));
1915
+ return inserted.changes === 1;
1313
1916
  },
1314
1917
  async delete(clientId) {
1315
1918
  await ensureTable();
1316
1919
  await deleteClientKey(clientId);
1317
- }
1920
+ },
1921
+ pruneExpired
1318
1922
  };
1319
1923
  }
1320
1924
 
1321
- export { HaiCryptoError, TRANSPORT_PROTOCOL, createInMemoryKeyStore, createRedisTransportKeyStore, createReldbTransportKeyStore, crypto2 as crypto };
1925
+ export { HaiCryptoError, TRANSPORT_BODY_LIMITS, TRANSPORT_PLAINTEXT_RANGE, TRANSPORT_PROTOCOL, TransportBodyTooLargeError, TransportTimeError, authenticateTransportRequest, createInMemoryKeyStore, createRedisTransportKeyStore, createReldbTransportKeyStore, createTransportErrorResponse, crypto2 as crypto, isValidSM2PublicKey, parseTransportServerKeyRing, readTransportBody, resolveTransportBodyLimits };
1322
1926
  //# sourceMappingURL=index.js.map
1323
1927
  //# sourceMappingURL=index.js.map