@sebastienrousseau/crypto-server 0.0.7 → 0.0.9

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.
Files changed (80) hide show
  1. package/README.md +159 -56
  2. package/dist/@types/types.d.ts +1 -2
  3. package/dist/@types/types.d.ts.map +1 -1
  4. package/dist/config/auth-policy.d.ts +18 -0
  5. package/dist/config/auth-policy.d.ts.map +1 -1
  6. package/dist/config/auth-policy.js +109 -0
  7. package/dist/enterprise/metering.d.ts.map +1 -1
  8. package/dist/enterprise/metering.js +2 -4
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.js +1 -0
  11. package/dist/lib/auth.d.ts +4 -1
  12. package/dist/lib/auth.d.ts.map +1 -1
  13. package/dist/lib/auth.js +87 -40
  14. package/dist/lib/kdf-runner.d.ts +18 -0
  15. package/dist/lib/kdf-runner.d.ts.map +1 -0
  16. package/dist/lib/kdf-runner.js +27 -0
  17. package/dist/lib/key-store.d.ts +30 -0
  18. package/dist/lib/key-store.d.ts.map +1 -0
  19. package/dist/lib/key-store.js +126 -0
  20. package/dist/lib/problem.d.ts +66 -0
  21. package/dist/lib/problem.d.ts.map +1 -0
  22. package/dist/lib/problem.js +152 -0
  23. package/dist/routes/v1/decrypt.d.ts.map +1 -1
  24. package/dist/routes/v1/decrypt.js +20 -15
  25. package/dist/routes/v1/encrypt.d.ts.map +1 -1
  26. package/dist/routes/v1/encrypt.js +12 -13
  27. package/dist/routes/v1/generate.d.ts.map +1 -1
  28. package/dist/routes/v1/generate.js +22 -25
  29. package/dist/routes/v1/revoke.d.ts.map +1 -1
  30. package/dist/routes/v1/revoke.js +6 -11
  31. package/dist/routes/v1/verify.d.ts.map +1 -1
  32. package/dist/routes/v1/verify.js +6 -11
  33. package/dist/routes/v2/algorithms.js +1 -1
  34. package/dist/routes/v2/compliance.js +1 -1
  35. package/dist/routes/v2/encrypt.d.ts.map +1 -1
  36. package/dist/routes/v2/encrypt.js +1 -1
  37. package/dist/routes/v2/hash.d.ts.map +1 -1
  38. package/dist/routes/v2/hash.js +1 -1
  39. package/dist/routes/v2/kdf.d.ts +5 -0
  40. package/dist/routes/v2/kdf.d.ts.map +1 -1
  41. package/dist/routes/v2/kdf.js +27 -12
  42. package/dist/routes/v2/key-wrap.d.ts.map +1 -1
  43. package/dist/routes/v2/key-wrap.js +9 -3
  44. package/dist/routes/v2/keys.d.ts.map +1 -1
  45. package/dist/routes/v2/keys.js +39 -26
  46. package/dist/routes/v2/mac.d.ts.map +1 -1
  47. package/dist/routes/v2/mac.js +9 -3
  48. package/dist/routes/v2/multi-recipient.d.ts.map +1 -1
  49. package/dist/routes/v2/multi-recipient.js +12 -11
  50. package/dist/routes/v2/password-encrypt.d.ts.map +1 -1
  51. package/dist/routes/v2/password-encrypt.js +13 -46
  52. package/dist/routes/v2/password.d.ts +4 -0
  53. package/dist/routes/v2/password.d.ts.map +1 -1
  54. package/dist/routes/v2/password.js +28 -53
  55. package/dist/routes/v2/pq-hash-sign.d.ts.map +1 -1
  56. package/dist/routes/v2/pq-hash-sign.js +30 -24
  57. package/dist/routes/v2/pq-sign.d.ts.map +1 -1
  58. package/dist/routes/v2/pq-sign.js +30 -24
  59. package/dist/routes/v2/pq.d.ts.map +1 -1
  60. package/dist/routes/v2/pq.js +57 -38
  61. package/dist/routes/v2/sealedbox.d.ts.map +1 -1
  62. package/dist/routes/v2/sealedbox.js +32 -14
  63. package/dist/routes/v2/secretbox.d.ts.map +1 -1
  64. package/dist/routes/v2/secretbox.js +10 -3
  65. package/dist/routes/v2/signing.d.ts.map +1 -1
  66. package/dist/routes/v2/signing.js +16 -13
  67. package/dist/routes/v2/stream.d.ts.map +1 -1
  68. package/dist/routes/v2/stream.js +29 -24
  69. package/dist/server.d.ts.map +1 -1
  70. package/dist/server.js +15 -5
  71. package/dist/utils/keys.d.ts +17 -0
  72. package/dist/utils/keys.d.ts.map +1 -0
  73. package/dist/utils/keys.js +36 -0
  74. package/dist/utils/route-helpers.d.ts +1 -5
  75. package/dist/utils/route-helpers.d.ts.map +1 -1
  76. package/dist/utils/route-helpers.js +16 -10
  77. package/dist/utils/validation.d.ts +1 -0
  78. package/dist/utils/validation.d.ts.map +1 -1
  79. package/dist/utils/validation.js +17 -9
  80. package/package.json +23 -20
@@ -1,32 +1,38 @@
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 decrypt_1 = __importDefault(require("@sebastienrousseau/crypto-lib/dist/lib/decrypt"));
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-encrypted message using private/public key pair and passphrase.",
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: { type: "object", properties: { data: { type: "string" } } },
15
- 400: {
13
+ 200: {
16
14
  type: "object",
17
- properties: { error: { type: "string" }, details: { type: "array" } },
15
+ properties: {
16
+ data: {
17
+ type: "object",
18
+ properties: {
19
+ data: { type: "string" },
20
+ signatureValid: { type: "boolean" },
21
+ },
22
+ },
23
+ },
18
24
  },
19
- 401: { type: "object", properties: { error: { type: "string" } } },
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", "privateKey"],
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
  };
@@ -38,21 +44,20 @@ exports.default = (app) => {
38
44
  passphrase: (0, validation_1.validateRequiredString)(body.passphrase, "passphrase"),
39
45
  message: (0, validation_1.validateBase64)(body.message, "message"),
40
46
  publicKey: (0, validation_1.validateBase64)(body.publicKey, "publicKey"),
41
- privateKey: (0, validation_1.validateBase64)(body.privateKey, "privateKey"),
42
47
  }, reply);
43
48
  if (!v)
44
49
  return;
45
- const decryptedData = await (0, decrypt_1.default)({
50
+ const decryptedData = await (0, pgp_1.decrypt)({
46
51
  passphrase: v.passphrase,
47
52
  message: v.message,
48
53
  publicKey: v.publicKey,
49
- privateKey: v.privateKey,
54
+ privateKey: await (0, keys_1.serverPgpPrivateKey)(),
50
55
  });
51
56
  return reply.send({ data: decryptedData });
52
57
  }
53
58
  catch (error) {
54
59
  request.log.error(error, "Decryption operation failed");
55
- return reply.status(500).send({ error: "Decryption failed" });
60
+ return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Decryption failed");
56
61
  }
57
62
  });
58
63
  };
@@ -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;yBAkC/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA+BE"}
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 encrypt_1 = __importDefault(require("@sebastienrousseau/crypto-lib/dist/lib/encrypt"));
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
- type: "object",
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
- privateKey: { type: "string", minLength: 1, maxLength: 64 * 1024 },
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, encrypt_1.default)({
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.privateKey ? { privateKey: body.privateKey } : {}),
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 reply.status(500).send({ error: "Encryption failed" });
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,EAAE,MAAM,SAAS,CAAC;yBA+D/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAkEE"}
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 generate_1 = __importDefault(require("@sebastienrousseau/crypto-lib/dist/lib/generate"));
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
- type: "object",
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 body = request.body;
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, generate_1.default)({
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 reply.status(500).send({ error: "Key pair generation failed" });
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;yBA8C/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAgCE"}
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"}
@@ -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 revoke_1 = __importDefault(require("@sebastienrousseau/crypto-lib/dist/lib/revoke"));
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
- type: "object",
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, revoke_1.default)({
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 reply.status(500).send({ error: "Revocation failed" });
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;yBAyC/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiCE"}
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,wBAiCE"}
@@ -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 verify_1 = __importDefault(require("@sebastienrousseau/crypto-lib/dist/lib/verify"));
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
- type: "object",
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",
@@ -44,7 +39,7 @@ exports.default = (app) => {
44
39
  }, reply);
45
40
  if (!v)
46
41
  return;
47
- const verifyData = await (0, verify_1.default)({
42
+ const verifyData = await (0, pgp_1.verify)({
48
43
  date: v.date,
49
44
  message: v.message,
50
45
  verificationKeys: v.verificationKeys,
@@ -53,7 +48,7 @@ exports.default = (app) => {
53
48
  }
54
49
  catch (error) {
55
50
  request.log.error(error, "Verification operation failed");
56
- return reply.status(500).send({ error: "Verification failed" });
51
+ return (0, problem_1.sendProblem)(reply, 500, "internal-error", "Verification failed");
57
52
  }
58
53
  });
59
54
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const modern_1 = require("@sebastienrousseau/crypto-lib/dist/modern");
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/dist/modern");
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;yBA+C/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA4BE"}
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/dist/modern");
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;yBAwB/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiBE"}
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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const modern_1 = require("@sebastienrousseau/crypto-lib/dist/modern");
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"],
@@ -1,4 +1,9 @@
1
1
  import type { FastifyInstance } from "fastify";
2
+ export declare const KDF_FLOORS: Readonly<{
3
+ scryptN: 131072;
4
+ scryptR: 8;
5
+ pbkdf2Iterations: 600000;
6
+ }>;
2
7
  declare const _default: (app: FastifyInstance) => void;
3
8
  export default _default;
4
9
  //# sourceMappingURL=kdf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"kdf.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/kdf.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAuC/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAgCE"}
1
+ {"version":3,"file":"kdf.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/kdf.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAc/C,eAAO,MAAM,UAAU;;;;EAIrB,CAAC;yBA+Ca,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAqBE"}
@@ -1,11 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const modern_1 = require("@sebastienrousseau/crypto-lib/dist/modern");
3
+ exports.KDF_FLOORS = void 0;
4
+ const modern_1 = require("@sebastienrousseau/crypto-lib/modern");
4
5
  const route_helpers_1 = require("../../utils/route-helpers");
6
+ exports.KDF_FLOORS = Object.freeze({
7
+ scryptN: 131072,
8
+ scryptR: 8,
9
+ pbkdf2Iterations: 600_000,
10
+ });
5
11
  const kdfSchema = {
6
12
  tags: ["Key Derivation"],
7
13
  summary: "Derive a key from a password",
8
- description: "Key derivation using scrypt, HKDF-SHA256, or PBKDF2-SHA256.",
14
+ description: "Key derivation using scrypt (N = 2^17, r = 8), HKDF-SHA256, or PBKDF2-SHA256 (>= 600,000 iterations). Runs on a worker thread.",
9
15
  body: {
10
16
  type: "object",
11
17
  required: ["algorithm", "password"],
@@ -19,10 +25,22 @@ const kdfSchema = {
19
25
  type: "object",
20
26
  additionalProperties: false,
21
27
  properties: {
22
- N: { type: "integer", minimum: 2, maximum: 131072 },
23
- r: { type: "integer", minimum: 1, maximum: 8 },
28
+ N: {
29
+ type: "integer",
30
+ minimum: exports.KDF_FLOORS.scryptN,
31
+ maximum: exports.KDF_FLOORS.scryptN,
32
+ },
33
+ r: {
34
+ type: "integer",
35
+ minimum: exports.KDF_FLOORS.scryptR,
36
+ maximum: exports.KDF_FLOORS.scryptR,
37
+ },
24
38
  p: { type: "integer", minimum: 1, maximum: 4 },
25
- iterations: { type: "integer", minimum: 1, maximum: 1000000 },
39
+ iterations: {
40
+ type: "integer",
41
+ minimum: exports.KDF_FLOORS.pbkdf2Iterations,
42
+ maximum: 1000000,
43
+ },
26
44
  info: { type: "string", maxLength: 1024 },
27
45
  },
28
46
  },
@@ -33,17 +51,14 @@ exports.default = (app) => {
33
51
  app.post("/v2/kdf", { schema: kdfSchema }, async (request, reply) => {
34
52
  try {
35
53
  const body = request.body;
36
- const result = (0, modern_1.kdfDerive)({
54
+ const options = {
37
55
  algorithm: body.algorithm,
38
56
  password: body.password,
39
57
  ...(body.salt ? { salt: body.salt } : {}),
40
58
  ...(body.keyLength ? { keyLength: body.keyLength } : {}),
41
- ...(body.params
42
- ? {
43
- params: body.params,
44
- }
45
- : {}),
46
- });
59
+ ...(body.params ? { params: body.params } : {}),
60
+ };
61
+ const result = await request.server.kdf.run("modern", "kdfDerive", options);
47
62
  return reply.send({ data: result });
48
63
  }
49
64
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"key-wrap.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/key-wrap.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA8EE"}
1
+ {"version":3,"file":"key-wrap.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/key-wrap.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAwF/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAGE"}
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const route_helpers_1 = require("../../utils/route-helpers");
37
- exports.default = (app) => {
37
+ function registerKeysWrap(app) {
38
38
  app.post("/v2/keys/wrap", {
39
39
  schema: {
40
40
  tags: ["Key Wrapping"],
@@ -52,7 +52,7 @@ exports.default = (app) => {
52
52
  },
53
53
  }, async (request, reply) => {
54
54
  try {
55
- const { aesKwWrap, aesKwpWrap } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/high-level/key-wrap")));
55
+ const { aesKwWrap, aesKwpWrap } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/high-level")));
56
56
  const { kek, keyToWrap, algorithm } = request.body;
57
57
  const result = algorithm === "aes-kwp"
58
58
  ? aesKwpWrap(kek, keyToWrap)
@@ -63,6 +63,8 @@ exports.default = (app) => {
63
63
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Key wrapping");
64
64
  }
65
65
  });
66
+ }
67
+ function registerKeysUnwrap(app) {
66
68
  app.post("/v2/keys/unwrap", {
67
69
  schema: {
68
70
  tags: ["Key Wrapping"],
@@ -80,7 +82,7 @@ exports.default = (app) => {
80
82
  },
81
83
  }, async (request, reply) => {
82
84
  try {
83
- const { aesKwUnwrap, aesKwpUnwrap } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/high-level/key-wrap")));
85
+ const { aesKwUnwrap, aesKwpUnwrap } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/high-level")));
84
86
  const { kek, wrappedKey, algorithm } = request.body;
85
87
  const result = algorithm === "aes-kwp"
86
88
  ? aesKwpUnwrap(kek, wrappedKey)
@@ -93,5 +95,9 @@ exports.default = (app) => {
93
95
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Key unwrapping");
94
96
  }
95
97
  });
98
+ }
99
+ exports.default = (app) => {
100
+ registerKeysWrap(app);
101
+ registerKeysUnwrap(app);
96
102
  };
97
103
  //# sourceMappingURL=key-wrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/keys.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA0DE"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/keys.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAiG/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAGE"}
@@ -33,12 +33,14 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- const route_helpers_1 = require("../../utils/route-helpers");
37
- exports.default = (app) => {
36
+ const keys_1 = require("@sebastienrousseau/crypto-lib/keys");
37
+ const keys_2 = require("../../utils/keys");
38
+ function registerGenerate(app) {
38
39
  app.post("/v2/keys/generate", {
39
40
  schema: {
40
41
  tags: ["Key Management"],
41
- summary: "Generate a key pair for any supported algorithm",
42
+ summary: "Generate a server-held key pair for any supported algorithm",
43
+ description: "Generates a key pair, keeps the private key on the server and returns its keyId with the public key. Use the keyId with the signing, decryption and decapsulation routes.",
42
44
  body: {
43
45
  type: "object",
44
46
  additionalProperties: false,
@@ -46,20 +48,7 @@ exports.default = (app) => {
46
48
  algorithm: {
47
49
  default: "ed25519",
48
50
  type: "string",
49
- enum: [
50
- "ed25519",
51
- "x25519",
52
- "ed448",
53
- "x448",
54
- "p256",
55
- "p384",
56
- "ml-kem-512",
57
- "ml-kem-768",
58
- "ml-kem-1024",
59
- "ml-dsa-44",
60
- "ml-dsa-65",
61
- "ml-dsa-87",
62
- ],
51
+ enum: [...keys_1.KEY_ALGORITHMS],
63
52
  },
64
53
  metadata: {
65
54
  type: "object",
@@ -74,15 +63,39 @@ exports.default = (app) => {
74
63
  },
75
64
  },
76
65
  }, async (request, reply) => {
77
- try {
78
- const { generateKeyPair } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/keys/keygen")));
79
- const { algorithm, metadata } = request.body;
80
- const result = generateKeyPair(algorithm, metadata);
81
- return reply.send({ data: result });
82
- }
83
- catch (error) {
84
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Key generation");
85
- }
66
+ const { generateKeyPair } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/keys")));
67
+ const { algorithm, metadata } = request.body;
68
+ const pair = generateKeyPair(algorithm, metadata);
69
+ const stored = await (0, keys_2.storeKey)(request, pair.algorithm, { publicKey: pair.publicKey }, { privateKey: pair.privateKey });
70
+ return reply.send({
71
+ data: { ...(0, keys_2.publicView)(stored), kid: pair.kid, metadata: pair.metadata },
72
+ });
86
73
  });
74
+ }
75
+ function registerExport(app) {
76
+ app.post("/v2/keys/export", {
77
+ schema: {
78
+ tags: ["Key Management"],
79
+ summary: "Export a server-held private key",
80
+ description: "Returns the private key of a key pair this principal generated. Requires the crypto:keys:export scope, granted explicitly (crypto:admin does not include it).",
81
+ body: {
82
+ type: "object",
83
+ required: ["keyId"],
84
+ additionalProperties: false,
85
+ properties: { keyId: keys_2.KEY_ID_SCHEMA },
86
+ },
87
+ },
88
+ }, async (request, reply) => {
89
+ const { keyId } = request.body;
90
+ const key = await (0, keys_2.resolveKey)(request, keyId);
91
+ request.log.warn({ keyId }, "Private key exported");
92
+ return reply.send({
93
+ data: { ...(0, keys_2.publicView)(key), ...key.privateParts },
94
+ });
95
+ });
96
+ }
97
+ exports.default = (app) => {
98
+ registerGenerate(app);
99
+ registerExport(app);
87
100
  };
88
101
  //# sourceMappingURL=keys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mac.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/mac.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAQ/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiFE"}
1
+ {"version":3,"file":"mac.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/mac.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBA+F/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAGE"}