@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,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROBLEM_SCHEMA = exports.PROBLEM_TITLES = exports.PROBLEM_TYPE_PREFIX = exports.PROBLEM_CONTENT_TYPE = void 0;
|
|
4
|
+
exports.problem = problem;
|
|
5
|
+
exports.sendProblem = sendProblem;
|
|
6
|
+
exports.cryptoErrorStatus = cryptoErrorStatus;
|
|
7
|
+
exports.isCryptoError = isCryptoError;
|
|
8
|
+
exports.classifyThrown = classifyThrown;
|
|
9
|
+
exports.registerProblemHandlers = registerProblemHandlers;
|
|
10
|
+
const http_1 = require("http");
|
|
11
|
+
const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
|
|
12
|
+
const key_store_1 = require("./key-store");
|
|
13
|
+
exports.PROBLEM_CONTENT_TYPE = "application/problem+json";
|
|
14
|
+
exports.PROBLEM_TYPE_PREFIX = "urn:crypto-service:problem:";
|
|
15
|
+
exports.PROBLEM_TITLES = Object.freeze({
|
|
16
|
+
"validation-failed": "Validation failed",
|
|
17
|
+
"invalid-input": "Invalid input",
|
|
18
|
+
unauthorized: "Unauthorized",
|
|
19
|
+
forbidden: "Forbidden",
|
|
20
|
+
"not-found": "Not Found",
|
|
21
|
+
"key-not-found": "Key not found",
|
|
22
|
+
"key-algorithm-mismatch": "Key algorithm mismatch",
|
|
23
|
+
"key-store-full": "Key store full",
|
|
24
|
+
"payload-too-large": "Payload Too Large",
|
|
25
|
+
"rate-limited": "Too Many Requests",
|
|
26
|
+
"request-error": "Bad Request",
|
|
27
|
+
"internal-error": "Internal Server Error",
|
|
28
|
+
conflict: "Conflict",
|
|
29
|
+
});
|
|
30
|
+
exports.PROBLEM_SCHEMA = {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
type: { type: "string" },
|
|
34
|
+
title: { type: "string" },
|
|
35
|
+
status: { type: "integer" },
|
|
36
|
+
detail: { type: "string" },
|
|
37
|
+
instance: { type: "string" },
|
|
38
|
+
code: { type: "string" },
|
|
39
|
+
errors: { type: "array" },
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
function problem(status, slug, detail, extensions = {}, instance) {
|
|
43
|
+
return {
|
|
44
|
+
type: `${exports.PROBLEM_TYPE_PREFIX}${slug}`,
|
|
45
|
+
title: exports.PROBLEM_TITLES[slug],
|
|
46
|
+
status,
|
|
47
|
+
detail,
|
|
48
|
+
...(instance === undefined ? {} : { instance }),
|
|
49
|
+
...extensions,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const pathOf = (request) => request?.url.split("?")[0];
|
|
53
|
+
function sendProblem(reply, status, slug, detail, extensions) {
|
|
54
|
+
const body = problem(status, slug, detail, extensions, pathOf(reply.request));
|
|
55
|
+
return reply.status(status).type(exports.PROBLEM_CONTENT_TYPE).send(body);
|
|
56
|
+
}
|
|
57
|
+
const CRYPTO_INPUT_CODES = new Set([
|
|
58
|
+
"INVALID_KEY",
|
|
59
|
+
"UNSUPPORTED_ALGORITHM",
|
|
60
|
+
"INVALID_HEX",
|
|
61
|
+
"INVALID_CIPHERTEXT",
|
|
62
|
+
"AUTH_FAILED",
|
|
63
|
+
"INVALID_INPUT",
|
|
64
|
+
"OPAQUE_ENVELOPE_RECOVERY",
|
|
65
|
+
"OPAQUE_SERVER_AUTHENTICATION",
|
|
66
|
+
"OPAQUE_CLIENT_AUTHENTICATION",
|
|
67
|
+
"OPAQUE_DESERIALIZE",
|
|
68
|
+
"OPAQUE_INVALID_INPUT",
|
|
69
|
+
]);
|
|
70
|
+
function cryptoErrorStatus(code) {
|
|
71
|
+
return CRYPTO_INPUT_CODES.has(code) ? 400 : 500;
|
|
72
|
+
}
|
|
73
|
+
function isCryptoError(error) {
|
|
74
|
+
return error instanceof crypto_lib_1.CryptoError;
|
|
75
|
+
}
|
|
76
|
+
const KEY_STORE_SLUGS = {
|
|
77
|
+
KEY_NOT_FOUND: "key-not-found",
|
|
78
|
+
KEY_ALGORITHM_MISMATCH: "key-algorithm-mismatch",
|
|
79
|
+
KEY_STORE_FULL: "key-store-full",
|
|
80
|
+
STORAGE_KEY_REQUIRED: "internal-error",
|
|
81
|
+
KEY_INTEGRITY_FAILED: "internal-error",
|
|
82
|
+
KEY_CORRUPTED: "internal-error",
|
|
83
|
+
UNSUPPORTED_STORAGE_ALGORITHM: "internal-error",
|
|
84
|
+
};
|
|
85
|
+
function fieldOf(issue) {
|
|
86
|
+
const missing = issue.params.missingProperty;
|
|
87
|
+
return missing ? `${issue.instancePath}/${missing}` : issue.instancePath;
|
|
88
|
+
}
|
|
89
|
+
const internal = (extensions = {}) => ({
|
|
90
|
+
status: 500,
|
|
91
|
+
slug: "internal-error",
|
|
92
|
+
detail: "An unexpected error occurred",
|
|
93
|
+
extensions,
|
|
94
|
+
});
|
|
95
|
+
function validationProblem(error) {
|
|
96
|
+
const errors = error.validation.map((issue) => ({
|
|
97
|
+
field: fieldOf(issue),
|
|
98
|
+
message: issue.message ?? "is invalid",
|
|
99
|
+
}));
|
|
100
|
+
return {
|
|
101
|
+
status: 400,
|
|
102
|
+
slug: "validation-failed",
|
|
103
|
+
detail: error.message,
|
|
104
|
+
extensions: { errors },
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function cryptoProblem(error) {
|
|
108
|
+
if (cryptoErrorStatus(error.code) === 500) {
|
|
109
|
+
return internal({ code: error.code });
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
status: 400,
|
|
113
|
+
slug: "invalid-input",
|
|
114
|
+
detail: "Invalid input",
|
|
115
|
+
extensions: { code: error.code },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function keyStoreProblem(error) {
|
|
119
|
+
return {
|
|
120
|
+
status: error.statusCode,
|
|
121
|
+
slug: KEY_STORE_SLUGS[error.code] ?? "request-error",
|
|
122
|
+
detail: error.message,
|
|
123
|
+
extensions: { code: error.code },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function clientProblem(status, error) {
|
|
127
|
+
const slug = status === 429
|
|
128
|
+
? "rate-limited"
|
|
129
|
+
: status === 413
|
|
130
|
+
? "payload-too-large"
|
|
131
|
+
: "request-error";
|
|
132
|
+
return {
|
|
133
|
+
status,
|
|
134
|
+
slug,
|
|
135
|
+
detail: error.message ?? String(http_1.STATUS_CODES[status]),
|
|
136
|
+
extensions: {},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function classifyThrown(error) {
|
|
140
|
+
if (isCryptoError(error))
|
|
141
|
+
return cryptoProblem(error);
|
|
142
|
+
if (error instanceof key_store_1.KeyStoreError)
|
|
143
|
+
return keyStoreProblem(error);
|
|
144
|
+
const thrown = (error ?? {});
|
|
145
|
+
if (thrown.validation) {
|
|
146
|
+
return validationProblem(thrown);
|
|
147
|
+
}
|
|
148
|
+
const status = thrown.statusCode ?? 500;
|
|
149
|
+
if (status >= 400 && status < 500)
|
|
150
|
+
return clientProblem(status, thrown);
|
|
151
|
+
return internal();
|
|
152
|
+
}
|
|
153
|
+
function registerProblemHandlers(app) {
|
|
154
|
+
app.setErrorHandler((error, request, reply) => {
|
|
155
|
+
const spec = classifyThrown(error);
|
|
156
|
+
if (spec.status >= 500)
|
|
157
|
+
request.log.error(error, "Request failed");
|
|
158
|
+
return sendProblem(reply, spec.status, spec.slug, spec.detail, spec.extensions);
|
|
159
|
+
});
|
|
160
|
+
app.setNotFoundHandler((request, reply) => sendProblem(reply, 404, "not-found", `Route ${request.method} ${pathOf(request)} not found`));
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=problem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/decrypt.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"decrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/decrypt.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBA2C/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAkCE"}
|
|
@@ -1,58 +1,66 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
3
|
+
const pgp_1 = require("@sebastienrousseau/crypto-lib/pgp");
|
|
7
4
|
const validation_1 = require("../../utils/validation");
|
|
8
5
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
6
|
+
const problem_1 = require("../../lib/problem");
|
|
7
|
+
const keys_1 = require("../../utils/keys");
|
|
9
8
|
const decryptSchema = {
|
|
10
9
|
tags: ["Encryption"],
|
|
11
10
|
summary: "Decrypt a message",
|
|
12
|
-
description: "Decrypts a PGP
|
|
11
|
+
description: "Decrypts a PGP message encrypted to the server's key pair (CRYPTO_KEY_DIR), unlocked with the passphrase. The API never takes a private key.",
|
|
13
12
|
response: {
|
|
14
|
-
200: {
|
|
15
|
-
400: {
|
|
13
|
+
200: {
|
|
16
14
|
type: "object",
|
|
17
|
-
properties: {
|
|
15
|
+
properties: {
|
|
16
|
+
data: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
data: { type: "string" },
|
|
20
|
+
signatureValid: { type: "boolean" },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
18
24
|
},
|
|
19
|
-
|
|
25
|
+
400: problem_1.PROBLEM_SCHEMA,
|
|
26
|
+
401: problem_1.PROBLEM_SCHEMA,
|
|
20
27
|
},
|
|
21
28
|
body: {
|
|
22
29
|
type: "object",
|
|
23
|
-
required: ["passphrase", "message", "publicKey"
|
|
30
|
+
required: ["passphrase", "message", "publicKey"],
|
|
24
31
|
additionalProperties: false,
|
|
25
32
|
properties: {
|
|
26
33
|
passphrase: { type: "string", minLength: 1, maxLength: 1024 },
|
|
27
34
|
message: { type: "string", minLength: 1, maxLength: 1024 * 1024 },
|
|
28
35
|
publicKey: { type: "string", minLength: 1, maxLength: 64 * 1024 },
|
|
29
|
-
privateKey: { type: "string", minLength: 1, maxLength: 64 * 1024 },
|
|
30
36
|
},
|
|
31
37
|
},
|
|
32
38
|
};
|
|
33
39
|
exports.default = (app) => {
|
|
34
|
-
app.post("/v1/decrypt", {
|
|
40
|
+
app.post("/v1/decrypt", {
|
|
41
|
+
schema: decryptSchema,
|
|
42
|
+
config: { rateLimit: { max: 100, timeWindow: "1 minute" } },
|
|
43
|
+
}, async (request, reply) => {
|
|
35
44
|
try {
|
|
36
45
|
const body = request.body;
|
|
37
46
|
const v = (0, route_helpers_1.collectValidation)({
|
|
38
47
|
passphrase: (0, validation_1.validateRequiredString)(body.passphrase, "passphrase"),
|
|
39
48
|
message: (0, validation_1.validateBase64)(body.message, "message"),
|
|
40
49
|
publicKey: (0, validation_1.validateBase64)(body.publicKey, "publicKey"),
|
|
41
|
-
privateKey: (0, validation_1.validateBase64)(body.privateKey, "privateKey"),
|
|
42
50
|
}, reply);
|
|
43
51
|
if (!v)
|
|
44
52
|
return;
|
|
45
|
-
const decryptedData = await (0,
|
|
53
|
+
const decryptedData = await (0, pgp_1.decrypt)({
|
|
46
54
|
passphrase: v.passphrase,
|
|
47
55
|
message: v.message,
|
|
48
56
|
publicKey: v.publicKey,
|
|
49
|
-
privateKey:
|
|
57
|
+
privateKey: await (0, keys_1.serverPgpPrivateKey)(),
|
|
50
58
|
});
|
|
51
59
|
return reply.send({ data: decryptedData });
|
|
52
60
|
}
|
|
53
61
|
catch (error) {
|
|
54
62
|
request.log.error(error, "Decryption operation failed");
|
|
55
|
-
return
|
|
63
|
+
return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Decryption failed");
|
|
56
64
|
}
|
|
57
65
|
});
|
|
58
66
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/encrypt.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/encrypt.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAqC/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA+BE"}
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
3
|
+
const pgp_1 = require("@sebastienrousseau/crypto-lib/pgp");
|
|
7
4
|
const validation_1 = require("../../utils/validation");
|
|
8
5
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
6
|
+
const problem_1 = require("../../lib/problem");
|
|
7
|
+
const keys_1 = require("../../utils/keys");
|
|
9
8
|
const encryptSchema = {
|
|
10
9
|
tags: ["Encryption"],
|
|
11
10
|
summary: "Encrypt a message",
|
|
12
11
|
description: "Encrypts a plaintext message using the supplied PGP public key and passphrase.",
|
|
13
12
|
response: {
|
|
14
13
|
200: { type: "object", properties: { data: { type: "string" } } },
|
|
15
|
-
400:
|
|
16
|
-
|
|
17
|
-
properties: { error: { type: "string" }, details: { type: "array" } },
|
|
18
|
-
},
|
|
19
|
-
401: { type: "object", properties: { error: { type: "string" } } },
|
|
14
|
+
400: problem_1.PROBLEM_SCHEMA,
|
|
15
|
+
401: problem_1.PROBLEM_SCHEMA,
|
|
20
16
|
},
|
|
21
17
|
body: {
|
|
22
18
|
type: "object",
|
|
@@ -26,7 +22,10 @@ const encryptSchema = {
|
|
|
26
22
|
passphrase: { type: "string", minLength: 1, maxLength: 1024 },
|
|
27
23
|
message: { type: "string", minLength: 1, maxLength: 1024 * 1024 },
|
|
28
24
|
publicKey: { type: "string", minLength: 1, maxLength: 64 * 1024 },
|
|
29
|
-
|
|
25
|
+
sign: {
|
|
26
|
+
type: "boolean",
|
|
27
|
+
description: "Also sign with the server's key pair (CRYPTO_KEY_DIR), unlocked with the passphrase.",
|
|
28
|
+
},
|
|
30
29
|
},
|
|
31
30
|
},
|
|
32
31
|
};
|
|
@@ -41,17 +40,17 @@ exports.default = (app) => {
|
|
|
41
40
|
}, reply);
|
|
42
41
|
if (!v)
|
|
43
42
|
return;
|
|
44
|
-
const encryptedData = await (0,
|
|
43
|
+
const encryptedData = await (0, pgp_1.encrypt)({
|
|
45
44
|
passphrase: v.passphrase,
|
|
46
45
|
message: v.message,
|
|
47
46
|
publicKey: v.publicKey,
|
|
48
|
-
...(body.
|
|
47
|
+
...(body.sign ? { privateKey: await (0, keys_1.serverPgpPrivateKey)() } : {}),
|
|
49
48
|
});
|
|
50
49
|
return reply.send({ data: encryptedData });
|
|
51
50
|
}
|
|
52
51
|
catch (error) {
|
|
53
52
|
request.log.error(error, "Encryption operation failed");
|
|
54
|
-
return
|
|
53
|
+
return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Encryption failed");
|
|
55
54
|
}
|
|
56
55
|
});
|
|
57
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/generate.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/generate.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;yBAsF7C,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA8CE"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
3
|
+
const pgp_1 = require("@sebastienrousseau/crypto-lib/pgp");
|
|
7
4
|
const types_1 = require("../../@types/types");
|
|
8
5
|
const validation_1 = require("../../utils/validation");
|
|
9
6
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
7
|
+
const problem_1 = require("../../lib/problem");
|
|
10
8
|
const generateSchema = {
|
|
11
9
|
tags: ["Key Management"],
|
|
12
10
|
summary: "Generate a key pair",
|
|
@@ -25,11 +23,8 @@ const generateSchema = {
|
|
|
25
23
|
warning: { type: "string" },
|
|
26
24
|
},
|
|
27
25
|
},
|
|
28
|
-
400:
|
|
29
|
-
|
|
30
|
-
properties: { error: { type: "string" }, details: { type: "array" } },
|
|
31
|
-
},
|
|
32
|
-
401: { type: "object", properties: { error: { type: "string" } } },
|
|
26
|
+
400: problem_1.PROBLEM_SCHEMA,
|
|
27
|
+
401: problem_1.PROBLEM_SCHEMA,
|
|
33
28
|
},
|
|
34
29
|
body: {
|
|
35
30
|
type: "object",
|
|
@@ -47,26 +42,28 @@ const generateSchema = {
|
|
|
47
42
|
},
|
|
48
43
|
},
|
|
49
44
|
};
|
|
45
|
+
function validateGenerateBody(body, reply) {
|
|
46
|
+
return (0, route_helpers_1.collectValidation)({
|
|
47
|
+
name: (0, validation_1.validateRequiredString)(body.name, "name"),
|
|
48
|
+
email: (0, validation_1.validateEmail)(body.email, "email"),
|
|
49
|
+
type: (0, validation_1.validateEnum)(body.type, "type", types_1.KEY_TYPES),
|
|
50
|
+
passphrase: (0, validation_1.validateRequiredString)(body.passphrase, "passphrase"),
|
|
51
|
+
curve: (0, validation_1.validateEnum)(body.curve, "curve", types_1.CURVE_TYPES),
|
|
52
|
+
format: (0, validation_1.validateEnum)(body.format, "format", types_1.FORMAT_TYPES),
|
|
53
|
+
rsaBits: (0, validation_1.validateOptionalNumber)(body.rsaBits, 2048, "rsaBits", {
|
|
54
|
+
min: 2048,
|
|
55
|
+
max: 4096,
|
|
56
|
+
}),
|
|
57
|
+
keyExpirationTime: (0, validation_1.validateOptionalNumber)(body.keyExpirationTime, 0, "keyExpirationTime", { min: 0 }),
|
|
58
|
+
}, reply);
|
|
59
|
+
}
|
|
50
60
|
exports.default = (app) => {
|
|
51
61
|
app.post("/v1/generate", { schema: generateSchema }, async (request, reply) => {
|
|
52
62
|
try {
|
|
53
|
-
const
|
|
54
|
-
const v = (0, route_helpers_1.collectValidation)({
|
|
55
|
-
name: (0, validation_1.validateRequiredString)(body.name, "name"),
|
|
56
|
-
email: (0, validation_1.validateEmail)(body.email, "email"),
|
|
57
|
-
type: (0, validation_1.validateEnum)(body.type, "type", types_1.KEY_TYPES),
|
|
58
|
-
passphrase: (0, validation_1.validateRequiredString)(body.passphrase, "passphrase"),
|
|
59
|
-
curve: (0, validation_1.validateEnum)(body.curve, "curve", types_1.CURVE_TYPES),
|
|
60
|
-
format: (0, validation_1.validateEnum)(body.format, "format", types_1.FORMAT_TYPES),
|
|
61
|
-
rsaBits: (0, validation_1.validateOptionalNumber)(body.rsaBits, 2048, "rsaBits", {
|
|
62
|
-
min: 2048,
|
|
63
|
-
max: 4096,
|
|
64
|
-
}),
|
|
65
|
-
keyExpirationTime: (0, validation_1.validateOptionalNumber)(body.keyExpirationTime, 0, "keyExpirationTime", { min: 0 }),
|
|
66
|
-
}, reply);
|
|
63
|
+
const v = validateGenerateBody(request.body, reply);
|
|
67
64
|
if (!v)
|
|
68
65
|
return;
|
|
69
|
-
const generated = (await (0,
|
|
66
|
+
const generated = (await (0, pgp_1.generate)({
|
|
70
67
|
date: new Date(),
|
|
71
68
|
name: v.name,
|
|
72
69
|
email: v.email,
|
|
@@ -88,7 +85,7 @@ exports.default = (app) => {
|
|
|
88
85
|
}
|
|
89
86
|
catch (error) {
|
|
90
87
|
request.log.error(error, "Key pair generation failed");
|
|
91
|
-
return
|
|
88
|
+
return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Key pair generation failed");
|
|
92
89
|
}
|
|
93
90
|
});
|
|
94
91
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/revoke.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"revoke.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/revoke.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBA4C/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAgCE"}
|
package/dist/routes/v1/revoke.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
3
|
+
const pgp_1 = require("@sebastienrousseau/crypto-lib/pgp");
|
|
7
4
|
const types_1 = require("../../@types/types");
|
|
8
5
|
const validation_1 = require("../../utils/validation");
|
|
9
6
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
7
|
+
const problem_1 = require("../../lib/problem");
|
|
10
8
|
const revokeSchema = {
|
|
11
9
|
tags: ["Key Management"],
|
|
12
10
|
summary: "Revoke a key pair",
|
|
@@ -23,11 +21,8 @@ const revokeSchema = {
|
|
|
23
21
|
},
|
|
24
22
|
},
|
|
25
23
|
},
|
|
26
|
-
400:
|
|
27
|
-
|
|
28
|
-
properties: { error: { type: "string" }, details: { type: "array" } },
|
|
29
|
-
},
|
|
30
|
-
401: { type: "object", properties: { error: { type: "string" } } },
|
|
24
|
+
400: problem_1.PROBLEM_SCHEMA,
|
|
25
|
+
401: problem_1.PROBLEM_SCHEMA,
|
|
31
26
|
},
|
|
32
27
|
body: {
|
|
33
28
|
type: "object",
|
|
@@ -51,7 +46,7 @@ exports.default = (app) => {
|
|
|
51
46
|
}, reply);
|
|
52
47
|
if (!v)
|
|
53
48
|
return;
|
|
54
|
-
const revocationData = await (0,
|
|
49
|
+
const revocationData = await (0, pgp_1.revoke)({
|
|
55
50
|
passphrase: v.passphrase,
|
|
56
51
|
flag: v.flag,
|
|
57
52
|
reason: v.reason,
|
|
@@ -60,7 +55,7 @@ exports.default = (app) => {
|
|
|
60
55
|
}
|
|
61
56
|
catch (error) {
|
|
62
57
|
request.log.error(error, "Revocation operation failed");
|
|
63
|
-
return
|
|
58
|
+
return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Revocation failed");
|
|
64
59
|
}
|
|
65
60
|
});
|
|
66
61
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/verify.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/routes/v1/verify.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAuC/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAoCE"}
|
package/dist/routes/v1/verify.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
3
|
+
const pgp_1 = require("@sebastienrousseau/crypto-lib/pgp");
|
|
7
4
|
const validation_1 = require("../../utils/validation");
|
|
8
5
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
6
|
+
const problem_1 = require("../../lib/problem");
|
|
9
7
|
const verifySchema = {
|
|
10
8
|
tags: ["Signing"],
|
|
11
9
|
summary: "Verify a signed message",
|
|
@@ -16,11 +14,8 @@ const verifySchema = {
|
|
|
16
14
|
additionalProperties: true,
|
|
17
15
|
properties: { data: {} },
|
|
18
16
|
},
|
|
19
|
-
400:
|
|
20
|
-
|
|
21
|
-
properties: { error: { type: "string" }, details: { type: "array" } },
|
|
22
|
-
},
|
|
23
|
-
401: { type: "object", properties: { error: { type: "string" } } },
|
|
17
|
+
400: problem_1.PROBLEM_SCHEMA,
|
|
18
|
+
401: problem_1.PROBLEM_SCHEMA,
|
|
24
19
|
},
|
|
25
20
|
body: {
|
|
26
21
|
type: "object",
|
|
@@ -34,7 +29,10 @@ const verifySchema = {
|
|
|
34
29
|
},
|
|
35
30
|
};
|
|
36
31
|
exports.default = (app) => {
|
|
37
|
-
app.post("/v1/verify", {
|
|
32
|
+
app.post("/v1/verify", {
|
|
33
|
+
schema: verifySchema,
|
|
34
|
+
config: { rateLimit: { max: 100, timeWindow: "1 minute" } },
|
|
35
|
+
}, async (request, reply) => {
|
|
38
36
|
try {
|
|
39
37
|
const body = request.body;
|
|
40
38
|
const v = (0, route_helpers_1.collectValidation)({
|
|
@@ -44,7 +42,7 @@ exports.default = (app) => {
|
|
|
44
42
|
}, reply);
|
|
45
43
|
if (!v)
|
|
46
44
|
return;
|
|
47
|
-
const verifyData = await (0,
|
|
45
|
+
const verifyData = await (0, pgp_1.verify)({
|
|
48
46
|
date: v.date,
|
|
49
47
|
message: v.message,
|
|
50
48
|
verificationKeys: v.verificationKeys,
|
|
@@ -53,7 +51,7 @@ exports.default = (app) => {
|
|
|
53
51
|
}
|
|
54
52
|
catch (error) {
|
|
55
53
|
request.log.error(error, "Verification operation failed");
|
|
56
|
-
return
|
|
54
|
+
return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Verification failed");
|
|
57
55
|
}
|
|
58
56
|
});
|
|
59
57
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const modern_1 = require("@sebastienrousseau/crypto-lib/
|
|
3
|
+
const modern_1 = require("@sebastienrousseau/crypto-lib/modern");
|
|
4
4
|
exports.default = (app) => {
|
|
5
5
|
app.get("/v2/algorithms", {
|
|
6
6
|
schema: {
|
|
@@ -9,7 +9,7 @@ exports.buildCbom = buildCbom;
|
|
|
9
9
|
const node_crypto_1 = require("node:crypto");
|
|
10
10
|
const node_fs_1 = require("node:fs");
|
|
11
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
-
const modern_1 = require("@sebastienrousseau/crypto-lib/
|
|
12
|
+
const modern_1 = require("@sebastienrousseau/crypto-lib/modern");
|
|
13
13
|
const PACKAGES_ROOT = node_path_1.default.resolve(__dirname, "..", "..", "..", "..");
|
|
14
14
|
function readPackageVersion(dir) {
|
|
15
15
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/encrypt.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/encrypt.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBA4C/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA4BE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const modern_1 = require("@sebastienrousseau/crypto-lib/
|
|
3
|
+
const modern_1 = require("@sebastienrousseau/crypto-lib/modern");
|
|
4
4
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
5
5
|
const encryptSchema = {
|
|
6
6
|
tags: ["Modern Encryption"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/hash.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/hash.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAqB/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiBE"}
|
package/dist/routes/v2/hash.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const modern_1 = require("@sebastienrousseau/crypto-lib/
|
|
3
|
+
const modern_1 = require("@sebastienrousseau/crypto-lib/modern");
|
|
4
4
|
const route_helpers_1 = require("../../utils/route-helpers");
|
|
5
5
|
const hashSchema = {
|
|
6
6
|
tags: ["Hashing"],
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hpke.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/hpke.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA0L/C,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAI5D"}
|