@sebastienrousseau/crypto-server 0.0.8 → 0.0.24
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 +159 -56
- package/dist/@types/types.d.ts +1 -2
- package/dist/@types/types.d.ts.map +1 -1
- package/dist/config/auth-policy.d.ts +18 -0
- package/dist/config/auth-policy.d.ts.map +1 -1
- package/dist/config/auth-policy.js +126 -0
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +7 -1
- package/dist/enterprise/metering.d.ts.map +1 -1
- package/dist/enterprise/metering.js +2 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/auth.d.ts +4 -1
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +87 -40
- package/dist/lib/kdf-runner.d.ts +18 -0
- package/dist/lib/kdf-runner.d.ts.map +1 -0
- package/dist/lib/kdf-runner.js +27 -0
- package/dist/lib/key-store.d.ts +37 -0
- package/dist/lib/key-store.d.ts.map +1 -0
- package/dist/lib/key-store.js +223 -0
- package/dist/lib/opaque-store.d.ts +34 -0
- package/dist/lib/opaque-store.d.ts.map +1 -0
- package/dist/lib/opaque-store.js +72 -0
- package/dist/lib/problem.d.ts +67 -0
- package/dist/lib/problem.d.ts.map +1 -0
- package/dist/lib/problem.js +162 -0
- package/dist/routes/v1/decrypt.d.ts.map +1 -1
- package/dist/routes/v1/decrypt.js +24 -16
- package/dist/routes/v1/encrypt.d.ts.map +1 -1
- package/dist/routes/v1/encrypt.js +12 -13
- package/dist/routes/v1/generate.d.ts.map +1 -1
- package/dist/routes/v1/generate.js +22 -25
- package/dist/routes/v1/revoke.d.ts.map +1 -1
- package/dist/routes/v1/revoke.js +6 -11
- package/dist/routes/v1/verify.d.ts.map +1 -1
- package/dist/routes/v1/verify.js +10 -12
- package/dist/routes/v2/algorithms.js +1 -1
- package/dist/routes/v2/compliance.js +1 -1
- package/dist/routes/v2/encrypt.d.ts.map +1 -1
- package/dist/routes/v2/encrypt.js +1 -1
- package/dist/routes/v2/hash.d.ts.map +1 -1
- package/dist/routes/v2/hash.js +1 -1
- package/dist/routes/v2/hpke.d.ts +3 -0
- package/dist/routes/v2/hpke.d.ts.map +1 -0
- package/dist/routes/v2/hpke.js +168 -0
- package/dist/routes/v2/index.d.ts.map +1 -1
- package/dist/routes/v2/index.js +6 -0
- package/dist/routes/v2/kdf.d.ts +5 -0
- package/dist/routes/v2/kdf.d.ts.map +1 -1
- package/dist/routes/v2/kdf.js +27 -12
- package/dist/routes/v2/key-wrap.d.ts.map +1 -1
- package/dist/routes/v2/key-wrap.js +9 -3
- package/dist/routes/v2/keys.d.ts.map +1 -1
- package/dist/routes/v2/keys.js +39 -26
- package/dist/routes/v2/kms.d.ts +7 -0
- package/dist/routes/v2/kms.d.ts.map +1 -0
- package/dist/routes/v2/kms.js +310 -0
- package/dist/routes/v2/mac.d.ts.map +1 -1
- package/dist/routes/v2/mac.js +10 -3
- package/dist/routes/v2/multi-recipient.d.ts.map +1 -1
- package/dist/routes/v2/multi-recipient.js +12 -11
- package/dist/routes/v2/opaque.d.ts +4 -0
- package/dist/routes/v2/opaque.d.ts.map +1 -0
- package/dist/routes/v2/opaque.js +174 -0
- package/dist/routes/v2/password-encrypt.d.ts.map +1 -1
- package/dist/routes/v2/password-encrypt.js +13 -46
- package/dist/routes/v2/password.d.ts +4 -0
- package/dist/routes/v2/password.d.ts.map +1 -1
- package/dist/routes/v2/password.js +28 -53
- package/dist/routes/v2/pq-hash-sign.d.ts.map +1 -1
- package/dist/routes/v2/pq-hash-sign.js +33 -24
- package/dist/routes/v2/pq-sign.d.ts.map +1 -1
- package/dist/routes/v2/pq-sign.js +31 -24
- package/dist/routes/v2/pq.d.ts.map +1 -1
- package/dist/routes/v2/pq.js +57 -38
- package/dist/routes/v2/sealedbox.d.ts.map +1 -1
- package/dist/routes/v2/sealedbox.js +32 -14
- package/dist/routes/v2/secretbox.d.ts.map +1 -1
- package/dist/routes/v2/secretbox.js +10 -3
- package/dist/routes/v2/signing.d.ts.map +1 -1
- package/dist/routes/v2/signing.js +17 -13
- package/dist/routes/v2/stream-schemas.d.ts +296 -0
- package/dist/routes/v2/stream-schemas.d.ts.map +1 -0
- package/dist/routes/v2/stream-schemas.js +207 -0
- package/dist/routes/v2/stream.d.ts.map +1 -1
- package/dist/routes/v2/stream.js +144 -151
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +19 -5
- package/dist/utils/keys.d.ts +17 -0
- package/dist/utils/keys.d.ts.map +1 -0
- package/dist/utils/keys.js +36 -0
- package/dist/utils/route-helpers.d.ts +1 -5
- package/dist/utils/route-helpers.d.ts.map +1 -1
- package/dist/utils/route-helpers.js +16 -10
- package/dist/utils/trace.d.ts +12 -0
- package/dist/utils/trace.d.ts.map +1 -0
- package/dist/utils/trace.js +62 -0
- package/dist/utils/validation.d.ts +1 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +17 -9
- package/package.json +22 -18
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STREAM_MULTI_PQ_DECRYPT_SCHEMA = exports.STREAM_MULTI_PQ_ENCRYPT_SCHEMA = exports.STREAM_PQ_DECRYPT_SCHEMA = exports.STREAM_PQ_ENCRYPT_SCHEMA = exports.ISO20022_SCHEMA = exports.VERIFY_SCHEMA = exports.SIGN_SCHEMA = void 0;
|
|
4
|
+
const keys_1 = require("../../utils/keys");
|
|
5
|
+
exports.SIGN_SCHEMA = {
|
|
6
|
+
tags: ["Streaming"],
|
|
7
|
+
summary: "Batch sign messages with sub-millisecond throughput",
|
|
8
|
+
description: "Process high-throughput batch digital signing operations over multiple payloads.",
|
|
9
|
+
body: {
|
|
10
|
+
type: "object",
|
|
11
|
+
required: ["items"],
|
|
12
|
+
additionalProperties: false,
|
|
13
|
+
properties: {
|
|
14
|
+
items: {
|
|
15
|
+
type: "array",
|
|
16
|
+
minItems: 1,
|
|
17
|
+
maxItems: 1000,
|
|
18
|
+
items: {
|
|
19
|
+
type: "object",
|
|
20
|
+
required: ["id", "message", "keyId"],
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
properties: {
|
|
23
|
+
id: { type: "string" },
|
|
24
|
+
message: { type: "string", minLength: 1 },
|
|
25
|
+
keyId: keys_1.KEY_ID_SCHEMA,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
exports.VERIFY_SCHEMA = {
|
|
33
|
+
tags: ["Streaming"],
|
|
34
|
+
summary: "Batch verify digital signatures",
|
|
35
|
+
description: "Batch verification pipeline for high-concurrency payment and transaction verification.",
|
|
36
|
+
body: {
|
|
37
|
+
type: "object",
|
|
38
|
+
required: ["items"],
|
|
39
|
+
additionalProperties: false,
|
|
40
|
+
properties: {
|
|
41
|
+
items: {
|
|
42
|
+
type: "array",
|
|
43
|
+
minItems: 1,
|
|
44
|
+
maxItems: 1000,
|
|
45
|
+
items: {
|
|
46
|
+
type: "object",
|
|
47
|
+
required: ["id", "message", "signature", "publicKey"],
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
properties: {
|
|
50
|
+
id: { type: "string" },
|
|
51
|
+
message: { type: "string", minLength: 1 },
|
|
52
|
+
signature: { type: "string", minLength: 1 },
|
|
53
|
+
publicKey: { type: "string", minLength: 64, maxLength: 64 },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
exports.ISO20022_SCHEMA = {
|
|
61
|
+
tags: ["Wholesale Payments"],
|
|
62
|
+
summary: "Verify ISO 20022 post-quantum dual-signature envelope",
|
|
63
|
+
description: "Validates the payload digest and both the Ed25519 and ML-DSA signatures of a pacs.008, pain.001 or camt.053 envelope. Signatures are checked against trustedKeys, the signer's public keys from the caller's own registry; the public keys inside the envelope are ignored.",
|
|
64
|
+
body: {
|
|
65
|
+
type: "object",
|
|
66
|
+
required: ["envelope", "payload", "trustedKeys"],
|
|
67
|
+
additionalProperties: false,
|
|
68
|
+
properties: {
|
|
69
|
+
trustedKeys: {
|
|
70
|
+
type: "object",
|
|
71
|
+
required: ["classicalPublicKey", "postQuantumPublicKey"],
|
|
72
|
+
additionalProperties: false,
|
|
73
|
+
properties: {
|
|
74
|
+
classicalPublicKey: { type: "string", minLength: 1 },
|
|
75
|
+
postQuantumPublicKey: { type: "string", minLength: 1 },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
envelope: {
|
|
79
|
+
type: "object",
|
|
80
|
+
required: [
|
|
81
|
+
"messageId",
|
|
82
|
+
"messageType",
|
|
83
|
+
"payloadDigest",
|
|
84
|
+
"digestAlgorithm",
|
|
85
|
+
"timestamp",
|
|
86
|
+
"classical",
|
|
87
|
+
"postQuantum",
|
|
88
|
+
],
|
|
89
|
+
additionalProperties: false,
|
|
90
|
+
properties: {
|
|
91
|
+
messageId: { type: "string" },
|
|
92
|
+
messageType: {
|
|
93
|
+
type: "string",
|
|
94
|
+
enum: ["pacs.008", "pain.001", "camt.053", "generic"],
|
|
95
|
+
},
|
|
96
|
+
payloadDigest: { type: "string" },
|
|
97
|
+
digestAlgorithm: {
|
|
98
|
+
type: "string",
|
|
99
|
+
enum: ["sha256", "sha384", "sha512"],
|
|
100
|
+
},
|
|
101
|
+
timestamp: { type: "string" },
|
|
102
|
+
classical: {
|
|
103
|
+
type: "object",
|
|
104
|
+
required: ["algorithm", "signature", "publicKey"],
|
|
105
|
+
additionalProperties: false,
|
|
106
|
+
properties: {
|
|
107
|
+
algorithm: { type: "string" },
|
|
108
|
+
signature: { type: "string" },
|
|
109
|
+
publicKey: { type: "string" },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
postQuantum: {
|
|
113
|
+
type: "object",
|
|
114
|
+
required: ["algorithm", "signature", "publicKey"],
|
|
115
|
+
additionalProperties: false,
|
|
116
|
+
properties: {
|
|
117
|
+
algorithm: {
|
|
118
|
+
type: "string",
|
|
119
|
+
enum: ["ml-dsa-44", "ml-dsa-65", "ml-dsa-87"],
|
|
120
|
+
},
|
|
121
|
+
signature: { type: "string" },
|
|
122
|
+
publicKey: { type: "string" },
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
payload: {},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
exports.STREAM_PQ_ENCRYPT_SCHEMA = {
|
|
132
|
+
tags: ["Streaming"],
|
|
133
|
+
summary: "Encrypt stream with hybrid post-quantum AEAD",
|
|
134
|
+
description: "Encrypts plaintext using chunked hybrid post-quantum STREAM (X25519 + ML-KEM-768 + XChaCha20-Poly1305).",
|
|
135
|
+
body: {
|
|
136
|
+
type: "object",
|
|
137
|
+
required: ["x25519PublicKey", "mlKemPublicKey", "plaintext"],
|
|
138
|
+
additionalProperties: false,
|
|
139
|
+
properties: {
|
|
140
|
+
x25519PublicKey: { type: "string", minLength: 64, maxLength: 64 },
|
|
141
|
+
mlKemPublicKey: { type: "string", minLength: 1 },
|
|
142
|
+
plaintext: { type: "string", minLength: 1 },
|
|
143
|
+
chunkSize: { type: "integer", minimum: 64, maximum: 1048576 },
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
exports.STREAM_PQ_DECRYPT_SCHEMA = {
|
|
148
|
+
tags: ["Streaming"],
|
|
149
|
+
summary: "Decrypt stream with server-held hybrid post-quantum key",
|
|
150
|
+
description: "Decrypts hybrid post-quantum STREAM ciphertext using a server-held x25519-ml-kem-768 key.",
|
|
151
|
+
body: {
|
|
152
|
+
type: "object",
|
|
153
|
+
required: ["keyId", "ciphertext"],
|
|
154
|
+
additionalProperties: false,
|
|
155
|
+
properties: {
|
|
156
|
+
keyId: keys_1.KEY_ID_SCHEMA,
|
|
157
|
+
ciphertext: { type: "string", minLength: 1 },
|
|
158
|
+
chunkSize: { type: "integer", minimum: 64, maximum: 1048576 },
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
exports.STREAM_MULTI_PQ_ENCRYPT_SCHEMA = {
|
|
163
|
+
tags: ["Streaming"],
|
|
164
|
+
summary: "Encrypt stream for multiple recipients with hybrid post-quantum AEAD",
|
|
165
|
+
description: "Encrypts plaintext for multiple recipients using hybrid post-quantum key encapsulation and chunked AEAD.",
|
|
166
|
+
body: {
|
|
167
|
+
type: "object",
|
|
168
|
+
required: ["recipients", "plaintext"],
|
|
169
|
+
additionalProperties: false,
|
|
170
|
+
properties: {
|
|
171
|
+
recipients: {
|
|
172
|
+
type: "array",
|
|
173
|
+
minItems: 1,
|
|
174
|
+
maxItems: 100,
|
|
175
|
+
items: {
|
|
176
|
+
type: "object",
|
|
177
|
+
required: ["recipientId", "x25519PublicKey", "mlKemPublicKey"],
|
|
178
|
+
additionalProperties: false,
|
|
179
|
+
properties: {
|
|
180
|
+
recipientId: { type: "string", minLength: 1, maxLength: 255 },
|
|
181
|
+
x25519PublicKey: { type: "string", minLength: 64, maxLength: 64 },
|
|
182
|
+
mlKemPublicKey: { type: "string", minLength: 1 },
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
plaintext: { type: "string", minLength: 1 },
|
|
187
|
+
chunkSize: { type: "integer", minimum: 1024, maximum: 16777216 },
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
exports.STREAM_MULTI_PQ_DECRYPT_SCHEMA = {
|
|
192
|
+
tags: ["Streaming"],
|
|
193
|
+
summary: "Decrypt multi-recipient stream with server-held hybrid post-quantum key",
|
|
194
|
+
description: "Decrypts multi-recipient hybrid post-quantum STREAM ciphertext using a server-held x25519-ml-kem-768 key.",
|
|
195
|
+
body: {
|
|
196
|
+
type: "object",
|
|
197
|
+
required: ["keyId", "ciphertext"],
|
|
198
|
+
additionalProperties: false,
|
|
199
|
+
properties: {
|
|
200
|
+
keyId: keys_1.KEY_ID_SCHEMA,
|
|
201
|
+
recipientId: { type: "string", minLength: 1, maxLength: 255 },
|
|
202
|
+
ciphertext: { type: "string", minLength: 1 },
|
|
203
|
+
chunkSize: { type: "integer", minimum: 1024, maximum: 16777216 },
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=stream-schemas.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/stream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/stream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;yBA6U/C,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAQE"}
|
package/dist/routes/v2/stream.js
CHANGED
|
@@ -1,160 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
|
|
4
|
-
const
|
|
4
|
+
const streaming_1 = require("@sebastienrousseau/crypto-lib/streaming");
|
|
5
|
+
const protocols_1 = require("@sebastienrousseau/crypto-lib/protocols");
|
|
5
6
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
items: {
|
|
16
|
-
type: "array",
|
|
17
|
-
minItems: 1,
|
|
18
|
-
maxItems: 1000,
|
|
19
|
-
items: {
|
|
20
|
-
type: "object",
|
|
21
|
-
required: ["id", "message", "privateKey"],
|
|
22
|
-
additionalProperties: false,
|
|
23
|
-
properties: {
|
|
24
|
-
id: { type: "string" },
|
|
25
|
-
message: { type: "string", minLength: 1 },
|
|
26
|
-
privateKey: { type: "string", minLength: 64, maxLength: 64 },
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
const VERIFY_SCHEMA = {
|
|
34
|
-
tags: ["Streaming"],
|
|
35
|
-
summary: "Batch verify digital signatures",
|
|
36
|
-
description: "Batch verification pipeline for high-concurrency payment and transaction verification.",
|
|
37
|
-
body: {
|
|
38
|
-
type: "object",
|
|
39
|
-
required: ["items"],
|
|
40
|
-
additionalProperties: false,
|
|
41
|
-
properties: {
|
|
42
|
-
items: {
|
|
43
|
-
type: "array",
|
|
44
|
-
minItems: 1,
|
|
45
|
-
maxItems: 1000,
|
|
46
|
-
items: {
|
|
47
|
-
type: "object",
|
|
48
|
-
required: ["id", "message", "signature", "publicKey"],
|
|
49
|
-
additionalProperties: false,
|
|
50
|
-
properties: {
|
|
51
|
-
id: { type: "string" },
|
|
52
|
-
message: { type: "string", minLength: 1 },
|
|
53
|
-
signature: { type: "string", minLength: 1 },
|
|
54
|
-
publicKey: { type: "string", minLength: 64, maxLength: 64 },
|
|
55
|
-
},
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
const ISO20022_SCHEMA = {
|
|
62
|
-
tags: ["Wholesale Payments"],
|
|
63
|
-
summary: "Verify ISO 20022 post-quantum dual-signature envelope",
|
|
64
|
-
description: "Validates the payload digest and both the Ed25519 and ML-DSA signatures of a pacs.008, pain.001 or camt.053 envelope. Signatures are checked against trustedKeys, the signer's public keys from the caller's own registry; the public keys inside the envelope are ignored.",
|
|
65
|
-
body: {
|
|
66
|
-
type: "object",
|
|
67
|
-
required: ["envelope", "payload", "trustedKeys"],
|
|
68
|
-
additionalProperties: false,
|
|
69
|
-
properties: {
|
|
70
|
-
trustedKeys: {
|
|
71
|
-
type: "object",
|
|
72
|
-
required: ["classicalPublicKey", "postQuantumPublicKey"],
|
|
73
|
-
additionalProperties: false,
|
|
74
|
-
properties: {
|
|
75
|
-
classicalPublicKey: { type: "string", minLength: 1 },
|
|
76
|
-
postQuantumPublicKey: { type: "string", minLength: 1 },
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
envelope: {
|
|
80
|
-
type: "object",
|
|
81
|
-
required: [
|
|
82
|
-
"messageId",
|
|
83
|
-
"messageType",
|
|
84
|
-
"payloadDigest",
|
|
85
|
-
"digestAlgorithm",
|
|
86
|
-
"timestamp",
|
|
87
|
-
"classical",
|
|
88
|
-
"postQuantum",
|
|
89
|
-
],
|
|
90
|
-
additionalProperties: false,
|
|
91
|
-
properties: {
|
|
92
|
-
messageId: { type: "string" },
|
|
93
|
-
messageType: {
|
|
94
|
-
type: "string",
|
|
95
|
-
enum: ["pacs.008", "pain.001", "camt.053", "generic"],
|
|
96
|
-
},
|
|
97
|
-
payloadDigest: { type: "string" },
|
|
98
|
-
digestAlgorithm: {
|
|
99
|
-
type: "string",
|
|
100
|
-
enum: ["sha256", "sha384", "sha512"],
|
|
101
|
-
},
|
|
102
|
-
timestamp: { type: "string" },
|
|
103
|
-
classical: {
|
|
104
|
-
type: "object",
|
|
105
|
-
required: ["algorithm", "signature", "publicKey"],
|
|
106
|
-
additionalProperties: false,
|
|
107
|
-
properties: {
|
|
108
|
-
algorithm: { type: "string" },
|
|
109
|
-
signature: { type: "string" },
|
|
110
|
-
publicKey: { type: "string" },
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
postQuantum: {
|
|
114
|
-
type: "object",
|
|
115
|
-
required: ["algorithm", "signature", "publicKey"],
|
|
116
|
-
additionalProperties: false,
|
|
117
|
-
properties: {
|
|
118
|
-
algorithm: {
|
|
119
|
-
type: "string",
|
|
120
|
-
enum: ["ml-dsa-44", "ml-dsa-65", "ml-dsa-87"],
|
|
121
|
-
},
|
|
122
|
-
signature: { type: "string" },
|
|
123
|
-
publicKey: { type: "string" },
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
payload: {},
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
};
|
|
7
|
+
const keys_1 = require("../../utils/keys");
|
|
8
|
+
const stream_schemas_1 = require("./stream-schemas");
|
|
9
|
+
async function resolveBatchKeys(request, items) {
|
|
10
|
+
const keys = new Map();
|
|
11
|
+
for (const keyId of new Set(items.map((i) => i.keyId))) {
|
|
12
|
+
keys.set(keyId, await (0, keys_1.resolveKey)(request, keyId, ["ed25519"]));
|
|
13
|
+
}
|
|
14
|
+
return keys;
|
|
15
|
+
}
|
|
132
16
|
function registerBatchSign(app) {
|
|
133
|
-
app.post("/v2/stream/sign", { schema: SIGN_SCHEMA }, async (request, reply) => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Batch signing");
|
|
153
|
-
}
|
|
17
|
+
app.post("/v2/stream/sign", { schema: stream_schemas_1.SIGN_SCHEMA }, async (request, reply) => {
|
|
18
|
+
const { items } = request.body;
|
|
19
|
+
const keys = await resolveBatchKeys(request, items);
|
|
20
|
+
const signatures = items.map((item) => {
|
|
21
|
+
const key = keys.get(item.keyId);
|
|
22
|
+
const res = (0, crypto_lib_1.ed25519Sign)(key.privateParts["privateKey"], item.message);
|
|
23
|
+
return {
|
|
24
|
+
id: item.id,
|
|
25
|
+
signature: res.signature,
|
|
26
|
+
algorithm: "ed25519",
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
return reply.send({
|
|
30
|
+
data: {
|
|
31
|
+
count: signatures.length,
|
|
32
|
+
signatures,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
154
35
|
});
|
|
155
36
|
}
|
|
156
37
|
function registerBatchVerify(app) {
|
|
157
|
-
app.post("/v2/stream/verify", {
|
|
38
|
+
app.post("/v2/stream/verify", {
|
|
39
|
+
schema: stream_schemas_1.VERIFY_SCHEMA,
|
|
40
|
+
config: { rateLimit: { max: 100, timeWindow: "1 minute" } },
|
|
41
|
+
}, async (request, reply) => {
|
|
158
42
|
try {
|
|
159
43
|
const { items } = request.body;
|
|
160
44
|
let validCount = 0;
|
|
@@ -184,10 +68,13 @@ function registerBatchVerify(app) {
|
|
|
184
68
|
});
|
|
185
69
|
}
|
|
186
70
|
function registerIso20022Verify(app) {
|
|
187
|
-
app.post("/v2/stream/iso20022", {
|
|
71
|
+
app.post("/v2/stream/iso20022", {
|
|
72
|
+
schema: stream_schemas_1.ISO20022_SCHEMA,
|
|
73
|
+
config: { rateLimit: { max: 100, timeWindow: "1 minute" } },
|
|
74
|
+
}, async (request, reply) => {
|
|
188
75
|
try {
|
|
189
76
|
const { envelope, payload, trustedKeys } = request.body;
|
|
190
|
-
const result = (0,
|
|
77
|
+
const result = (0, protocols_1.verifyIso20022Payment)(envelope, payload, {
|
|
191
78
|
classicalPublicKeyHex: trustedKeys.classicalPublicKey,
|
|
192
79
|
postQuantumPublicKeyHex: trustedKeys.postQuantumPublicKey,
|
|
193
80
|
});
|
|
@@ -198,9 +85,115 @@ function registerIso20022Verify(app) {
|
|
|
198
85
|
}
|
|
199
86
|
});
|
|
200
87
|
}
|
|
88
|
+
function registerStreamPqEncrypt(app) {
|
|
89
|
+
app.post("/v2/stream/pq-encrypt", { schema: stream_schemas_1.STREAM_PQ_ENCRYPT_SCHEMA }, async (request, reply) => {
|
|
90
|
+
try {
|
|
91
|
+
const { x25519PublicKey, mlKemPublicKey, plaintext, chunkSize } = request.body;
|
|
92
|
+
const ptBytes = Buffer.from(plaintext, "utf8");
|
|
93
|
+
const res = (0, streaming_1.streamPqEncrypt)({
|
|
94
|
+
recipientX25519Public: x25519PublicKey,
|
|
95
|
+
recipientMlKemPublic: mlKemPublicKey,
|
|
96
|
+
plaintext: ptBytes,
|
|
97
|
+
...(chunkSize !== undefined ? { chunkSize } : {}),
|
|
98
|
+
});
|
|
99
|
+
return reply.send({
|
|
100
|
+
data: {
|
|
101
|
+
ciphertext: Buffer.from(res.ciphertext).toString("base64"),
|
|
102
|
+
algorithm: res.algorithm,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "PQ stream encryption");
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function registerStreamPqDecrypt(app) {
|
|
112
|
+
app.post("/v2/stream/pq-decrypt", { schema: stream_schemas_1.STREAM_PQ_DECRYPT_SCHEMA }, async (request, reply) => {
|
|
113
|
+
const { keyId, ciphertext, chunkSize } = request.body;
|
|
114
|
+
const key = await (0, keys_1.resolveKey)(request, keyId, ["x25519-ml-kem-768"]);
|
|
115
|
+
try {
|
|
116
|
+
const ctBytes = Buffer.from(ciphertext, "base64");
|
|
117
|
+
const decrypted = (0, streaming_1.streamPqDecrypt)({
|
|
118
|
+
recipientX25519Secret: key.privateParts["x25519PrivateKey"],
|
|
119
|
+
recipientMlKemSecret: key.privateParts["mlKemSecretKey"],
|
|
120
|
+
ciphertext: ctBytes,
|
|
121
|
+
...(chunkSize !== undefined ? { chunkSize } : {}),
|
|
122
|
+
});
|
|
123
|
+
const plaintext = Buffer.from(decrypted).toString("utf8");
|
|
124
|
+
(0, crypto_lib_1.wipeMemory)(decrypted);
|
|
125
|
+
return reply.send({ data: { plaintext } });
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "PQ stream decryption");
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
function registerStreamMultiPqEncrypt(app) {
|
|
133
|
+
app.post("/v2/stream/multi-pq-encrypt", { schema: stream_schemas_1.STREAM_MULTI_PQ_ENCRYPT_SCHEMA }, async (request, reply) => {
|
|
134
|
+
try {
|
|
135
|
+
const { recipients, plaintext, chunkSize } = request.body;
|
|
136
|
+
const ptBytes = Buffer.from(plaintext, "utf8");
|
|
137
|
+
const res = (0, streaming_1.streamMultiPqEncrypt)({
|
|
138
|
+
recipients: recipients.map((r) => ({
|
|
139
|
+
recipientId: r.recipientId,
|
|
140
|
+
recipientX25519Public: r.x25519PublicKey,
|
|
141
|
+
recipientMlKemPublic: r.mlKemPublicKey,
|
|
142
|
+
})),
|
|
143
|
+
plaintext: ptBytes,
|
|
144
|
+
...(chunkSize !== undefined ? { chunkSize } : {}),
|
|
145
|
+
});
|
|
146
|
+
(0, crypto_lib_1.wipeMemory)(ptBytes);
|
|
147
|
+
return reply.send({
|
|
148
|
+
data: {
|
|
149
|
+
ciphertext: Buffer.from(res.ciphertext).toString("base64"),
|
|
150
|
+
algorithm: res.algorithm,
|
|
151
|
+
recipientCount: res.recipientCount,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Multi-PQ stream encryption");
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function registerStreamMultiPqDecrypt(app) {
|
|
161
|
+
app.post("/v2/stream/multi-pq-decrypt", {
|
|
162
|
+
schema: stream_schemas_1.STREAM_MULTI_PQ_DECRYPT_SCHEMA,
|
|
163
|
+
config: { rateLimit: { max: 100, timeWindow: "1 minute" } },
|
|
164
|
+
}, async (request, reply) => {
|
|
165
|
+
const { keyId, recipientId, ciphertext, chunkSize } = request.body;
|
|
166
|
+
const key = await (0, keys_1.resolveKey)(request, keyId, ["x25519-ml-kem-768"]);
|
|
167
|
+
try {
|
|
168
|
+
const ctBytes = Buffer.from(ciphertext, "base64");
|
|
169
|
+
const decrypted = (0, streaming_1.streamMultiPqDecrypt)({
|
|
170
|
+
...(recipientId !== undefined ? { recipientId } : {}),
|
|
171
|
+
recipientX25519Secret: key.privateParts["x25519PrivateKey"],
|
|
172
|
+
recipientMlKemSecret: key.privateParts["mlKemSecretKey"],
|
|
173
|
+
ciphertext: ctBytes,
|
|
174
|
+
...(chunkSize !== undefined ? { chunkSize } : {}),
|
|
175
|
+
});
|
|
176
|
+
const plaintext = Buffer.from(decrypted.plaintext).toString("utf8");
|
|
177
|
+
(0, crypto_lib_1.wipeMemory)(decrypted.plaintext);
|
|
178
|
+
return reply.send({
|
|
179
|
+
data: {
|
|
180
|
+
plaintext,
|
|
181
|
+
recipientId: decrypted.recipientId,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Multi-PQ stream decryption");
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
201
190
|
exports.default = (app) => {
|
|
202
191
|
registerBatchSign(app);
|
|
203
192
|
registerBatchVerify(app);
|
|
204
193
|
registerIso20022Verify(app);
|
|
194
|
+
registerStreamPqEncrypt(app);
|
|
195
|
+
registerStreamPqDecrypt(app);
|
|
196
|
+
registerStreamMultiPqEncrypt(app);
|
|
197
|
+
registerStreamMultiPqDecrypt(app);
|
|
205
198
|
};
|
|
206
199
|
//# sourceMappingURL=stream.js.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAuCnC,iBAAe,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAgFtD;AAED,OAAO,EAAE,IAAI,EAAE,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -50,12 +50,15 @@ const swagger_ui_1 = __importDefault(require("@fastify/swagger-ui"));
|
|
|
50
50
|
const crypto_1 = require("crypto");
|
|
51
51
|
const logger_1 = __importDefault(require("./lib/logger"));
|
|
52
52
|
const auth_1 = require("./lib/auth");
|
|
53
|
+
const auth_policy_1 = require("./config/auth-policy");
|
|
53
54
|
const metering_1 = require("./enterprise/metering");
|
|
55
|
+
const key_store_1 = require("./lib/key-store");
|
|
56
|
+
const kdf_runner_1 = require("./lib/kdf-runner");
|
|
57
|
+
const problem_1 = require("./lib/problem");
|
|
58
|
+
const trace_1 = require("./utils/trace");
|
|
59
|
+
const opaque_store_1 = require("./lib/opaque-store");
|
|
54
60
|
const routes_1 = __importDefault(require("./routes"));
|
|
55
61
|
const fastify = __importStar(require("fastify"));
|
|
56
|
-
function isPublicPath(url) {
|
|
57
|
-
return (0, constants_1.isProbePath)(url) || url.startsWith("/docs");
|
|
58
|
-
}
|
|
59
62
|
async function registerDocs(app) {
|
|
60
63
|
await app.register(swagger_1.default, {
|
|
61
64
|
openapi: {
|
|
@@ -82,10 +85,16 @@ async function registerDocs(app) {
|
|
|
82
85
|
}
|
|
83
86
|
async function init() {
|
|
84
87
|
const app = fastify.fastify(constants_1.fastifyOptions);
|
|
88
|
+
const registered = [];
|
|
89
|
+
app.addHook("onRoute", (route) => {
|
|
90
|
+
registered.push({ method: route.method, url: route.url });
|
|
91
|
+
});
|
|
85
92
|
logger_1.default.info("\n\nEnvironment details: " + constants_1.consoleOutput);
|
|
93
|
+
(0, problem_1.registerProblemHandlers)(app);
|
|
86
94
|
app.addHook("onRequest", async (request, reply) => {
|
|
87
95
|
const reqId = request.headers["x-request-id"] ?? (0, crypto_1.randomUUID)();
|
|
88
96
|
reply.header("x-request-id", reqId);
|
|
97
|
+
(0, trace_1.propagateTraceContext)(request, reply);
|
|
89
98
|
});
|
|
90
99
|
app.addHook("onSend", async (request, reply) => {
|
|
91
100
|
if (request.url.startsWith("/v2/")) {
|
|
@@ -107,18 +116,23 @@ async function init() {
|
|
|
107
116
|
});
|
|
108
117
|
await (0, auth_1.registerAuth)(app);
|
|
109
118
|
app.addHook("onRequest", async (request, reply) => {
|
|
110
|
-
if (
|
|
119
|
+
if ((0, auth_policy_1.isPublicRoute)(request.url))
|
|
111
120
|
return;
|
|
112
121
|
const auth = await (0, auth_1.authenticate)(request, reply);
|
|
113
|
-
if (!auth)
|
|
122
|
+
if (!auth || !(0, auth_1.authorizeRoute)(request, reply, auth))
|
|
114
123
|
return reply;
|
|
115
124
|
request.auth = auth;
|
|
116
125
|
});
|
|
126
|
+
app.decorate("keyStore", (0, key_store_1.keyStoreFromEnv)());
|
|
127
|
+
app.decorate("kdf", new kdf_runner_1.KdfRunner());
|
|
128
|
+
app.decorate("opaqueStore", new opaque_store_1.OpaqueStore());
|
|
129
|
+
app.addHook("onClose", () => app.kdf.close());
|
|
117
130
|
(0, metering_1.registerMetering)(app);
|
|
118
131
|
await app.register(async (scope) => {
|
|
119
132
|
(0, routes_1.default)(scope);
|
|
120
133
|
});
|
|
121
134
|
await app.ready();
|
|
135
|
+
(0, auth_policy_1.assertRoutesCovered)(registered);
|
|
122
136
|
return app;
|
|
123
137
|
}
|
|
124
138
|
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FastifyRequest } from "fastify";
|
|
2
|
+
import { type KeyParts, type KeyStore, type StoredKey } from "../lib/key-store";
|
|
3
|
+
declare module "fastify" {
|
|
4
|
+
interface FastifyInstance {
|
|
5
|
+
keyStore: KeyStore;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export declare const KEY_ID_SCHEMA: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly pattern: "^k_[A-Za-z0-9_-]{22}$";
|
|
11
|
+
readonly description: "Identifier of a server-held key, returned by a key-generation route.";
|
|
12
|
+
};
|
|
13
|
+
export declare function resolveKey(request: FastifyRequest, keyId: string, algorithms?: readonly string[]): Promise<StoredKey>;
|
|
14
|
+
export declare function storeKey(request: FastifyRequest, algorithm: string, publicParts: KeyParts, privateParts: KeyParts): Promise<StoredKey>;
|
|
15
|
+
export declare function serverPgpPrivateKey(): Promise<string>;
|
|
16
|
+
export declare function publicView(key: StoredKey): Record<string, string>;
|
|
17
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/utils/keys.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QAEvB,QAAQ,EAAE,QAAQ,CAAC;KACpB;CACF;AAGD,eAAO,MAAM,aAAa;;;;CAKhB,CAAC;AAeX,wBAAgB,UAAU,CACxB,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,SAAS,CAAC,CAEpB;AAGD,wBAAgB,QAAQ,CACtB,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,QAAQ,EACrB,YAAY,EAAE,QAAQ,GACrB,OAAO,CAAC,SAAS,CAAC,CAOpB;AAOD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAG3D;AAGD,wBAAgB,UAAU,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEjE"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KEY_ID_SCHEMA = void 0;
|
|
4
|
+
exports.resolveKey = resolveKey;
|
|
5
|
+
exports.storeKey = storeKey;
|
|
6
|
+
exports.serverPgpPrivateKey = serverPgpPrivateKey;
|
|
7
|
+
exports.publicView = publicView;
|
|
8
|
+
const pgp_1 = require("@sebastienrousseau/crypto-lib/pgp");
|
|
9
|
+
const key_store_1 = require("../lib/key-store");
|
|
10
|
+
exports.KEY_ID_SCHEMA = {
|
|
11
|
+
type: "string",
|
|
12
|
+
pattern: key_store_1.KEY_ID_PATTERN,
|
|
13
|
+
description: "Identifier of a server-held key, returned by a key-generation route.",
|
|
14
|
+
};
|
|
15
|
+
function principalOf(request) {
|
|
16
|
+
return request.auth.sub;
|
|
17
|
+
}
|
|
18
|
+
function resolveKey(request, keyId, algorithms) {
|
|
19
|
+
return request.server.keyStore.get(keyId, principalOf(request), algorithms);
|
|
20
|
+
}
|
|
21
|
+
function storeKey(request, algorithm, publicParts, privateParts) {
|
|
22
|
+
return request.server.keyStore.put({
|
|
23
|
+
algorithm,
|
|
24
|
+
owner: principalOf(request),
|
|
25
|
+
publicParts,
|
|
26
|
+
privateParts,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
async function serverPgpPrivateKey() {
|
|
30
|
+
const { privateKeyArmored } = await (0, pgp_1.loadKeystore)();
|
|
31
|
+
return Buffer.from(privateKeyArmored, "latin1").toString("base64");
|
|
32
|
+
}
|
|
33
|
+
function publicView(key) {
|
|
34
|
+
return { keyId: key.keyId, algorithm: key.algorithm, ...key.publicParts };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -7,9 +7,5 @@ export declare function classifyCryptoError(error: unknown, request: {
|
|
|
7
7
|
log: {
|
|
8
8
|
error: (err: unknown, msg: string) => void;
|
|
9
9
|
};
|
|
10
|
-
}, reply:
|
|
11
|
-
status: (code: number) => {
|
|
12
|
-
send: (body: unknown) => unknown;
|
|
13
|
-
};
|
|
14
|
-
}, operation: string): unknown;
|
|
10
|
+
}, reply: FastifyReply, operation: string): FastifyReply;
|
|
15
11
|
//# sourceMappingURL=route-helpers.d.ts.map
|