@sebastienrousseau/crypto-server 0.0.8 → 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 +20 -17
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const route_helpers_1 = require("../../utils/route-helpers");
37
37
  const HMAC_ALGORITHMS = ["sha256", "sha384", "sha512", "sha3-256", "sha3-512"];
38
- exports.default = (app) => {
38
+ function registerHmac(app) {
39
39
  app.post("/v2/hmac", {
40
40
  schema: {
41
41
  tags: ["MAC"],
@@ -53,7 +53,7 @@ exports.default = (app) => {
53
53
  },
54
54
  }, async (request, reply) => {
55
55
  try {
56
- const { computeHmac } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/mac")));
56
+ const { computeHmac } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
57
57
  const body = request.body;
58
58
  const result = computeHmac({
59
59
  algorithm: body.algorithm,
@@ -66,6 +66,8 @@ exports.default = (app) => {
66
66
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "HMAC computation");
67
67
  }
68
68
  });
69
+ }
70
+ function registerHmacVerify(app) {
69
71
  app.post("/v2/hmac/verify", {
70
72
  schema: {
71
73
  tags: ["MAC"],
@@ -84,7 +86,7 @@ exports.default = (app) => {
84
86
  },
85
87
  }, async (request, reply) => {
86
88
  try {
87
- const { verifyHmac } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/mac")));
89
+ const { verifyHmac } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
88
90
  const body = request.body;
89
91
  const result = verifyHmac({
90
92
  algorithm: body.algorithm,
@@ -98,5 +100,9 @@ exports.default = (app) => {
98
100
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "HMAC verification");
99
101
  }
100
102
  });
103
+ }
104
+ exports.default = (app) => {
105
+ registerHmac(app);
106
+ registerHmacVerify(app);
101
107
  };
102
108
  //# sourceMappingURL=mac.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"multi-recipient.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/multi-recipient.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAgEE"}
1
+ {"version":3,"file":"multi-recipient.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/multi-recipient.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAuB/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiDE"}
@@ -34,6 +34,16 @@ 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
+ function toLibRecipient(r) {
38
+ if (r.type === "classical") {
39
+ return { type: "x25519", publicKey: r.publicKey };
40
+ }
41
+ return {
42
+ type: "x25519-ml-kem-768",
43
+ x25519PublicKey: r.publicKey,
44
+ mlKemPublicKey: r.mlKemPublicKey,
45
+ };
46
+ }
37
47
  exports.default = (app) => {
38
48
  app.post("/v2/multi-recipient/encrypt", {
39
49
  schema: {
@@ -66,18 +76,9 @@ exports.default = (app) => {
66
76
  },
67
77
  }, async (request, reply) => {
68
78
  try {
69
- const { multiEncrypt } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/high-level/multi-recipient")));
79
+ const { multiEncrypt } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/high-level")));
70
80
  const { plaintext, recipients } = request.body;
71
- const libRecipients = recipients.map((r) => {
72
- if (r.type === "classical") {
73
- return { type: "x25519", publicKey: r.publicKey };
74
- }
75
- return {
76
- type: "x25519-ml-kem-768",
77
- x25519PublicKey: r.publicKey,
78
- mlKemPublicKey: r.mlKemPublicKey,
79
- };
80
- });
81
+ const libRecipients = recipients.map(toLibRecipient);
81
82
  return reply.send({ data: multiEncrypt(libRecipients, plaintext) });
82
83
  }
83
84
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"password-encrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/password-encrypt.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAsEE"}
1
+ {"version":3,"file":"password-encrypt.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/password-encrypt.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAoF/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAGE"}
@@ -1,44 +1,12 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  const route_helpers_1 = require("../../utils/route-helpers");
37
- exports.default = (app) => {
4
+ function registerEncrypt(app) {
38
5
  app.post("/v2/password/encrypt", {
39
6
  schema: {
40
7
  tags: ["Password Encryption"],
41
8
  summary: "Encrypt with password (Argon2id + XChaCha20-Poly1305)",
9
+ description: "Derives the key with Argon2id (t = 3, m = 64 MiB, p = 4) on a worker thread.",
42
10
  body: {
43
11
  type: "object",
44
12
  required: ["password", "plaintext"],
@@ -50,21 +18,17 @@ exports.default = (app) => {
50
18
  },
51
19
  },
52
20
  }, async (request, reply) => {
53
- try {
54
- const { passwordEncrypt } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/high-level/password-encrypt")));
55
- const { password, plaintext } = request.body;
56
- return reply.send({
57
- data: passwordEncrypt({ password, plaintext }),
58
- });
59
- }
60
- catch (error) {
61
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Encryption");
62
- }
21
+ const { password, plaintext } = request.body;
22
+ const result = await request.server.kdf.run("highLevel", "passwordEncrypt", { password, plaintext });
23
+ return reply.send({ data: result });
63
24
  });
25
+ }
26
+ function registerDecrypt(app) {
64
27
  app.post("/v2/password/decrypt", {
65
28
  schema: {
66
29
  tags: ["Password Encryption"],
67
30
  summary: "Decrypt with password (Argon2id + XChaCha20-Poly1305)",
31
+ description: "Derives the key with the Argon2id parameters stored in the ciphertext, on a worker thread.",
68
32
  body: {
69
33
  type: "object",
70
34
  required: ["password", "ciphertext"],
@@ -77,9 +41,8 @@ exports.default = (app) => {
77
41
  },
78
42
  }, async (request, reply) => {
79
43
  try {
80
- const { passwordDecrypt } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/high-level/password-encrypt")));
81
44
  const { password, ciphertext } = request.body;
82
- const plaintext = passwordDecrypt(password, ciphertext);
45
+ const plaintext = await request.server.kdf.run("highLevel", "passwordDecrypt", password, ciphertext);
83
46
  return reply.send({
84
47
  data: Buffer.from(plaintext).toString("utf8"),
85
48
  });
@@ -88,5 +51,9 @@ exports.default = (app) => {
88
51
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Decryption");
89
52
  }
90
53
  });
54
+ }
55
+ exports.default = (app) => {
56
+ registerEncrypt(app);
57
+ registerDecrypt(app);
91
58
  };
92
59
  //# sourceMappingURL=password-encrypt.js.map
@@ -1,4 +1,8 @@
1
1
  import type { FastifyInstance } from "fastify";
2
+ export declare const ARGON2_FLOORS: Readonly<{
3
+ memoryCostKiB: 19456;
4
+ timeCost: 2;
5
+ }>;
2
6
  declare const _default: (app: FastifyInstance) => void;
3
7
  export default _default;
4
8
  //# sourceMappingURL=password.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/password.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiGE"}
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/password.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAY/C,eAAO,MAAM,aAAa;;;EAGxB,CAAC;yBA2Ga,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAGE"}
@@ -1,78 +1,51 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ARGON2_FLOORS = void 0;
36
4
  const route_helpers_1 = require("../../utils/route-helpers");
37
- exports.default = (app) => {
5
+ exports.ARGON2_FLOORS = Object.freeze({
6
+ memoryCostKiB: 19456,
7
+ timeCost: 2,
8
+ });
9
+ function registerHash(app) {
38
10
  app.post("/v2/password/hash", {
39
11
  config: { rateLimit: { max: 5, timeWindow: "1 minute" } },
40
12
  schema: {
41
13
  tags: ["Password"],
42
14
  summary: "Hash a password with Argon2id",
15
+ description: "Argon2id with at least 19 MiB of memory and two passes (OWASP); defaults are t = 3, m = 64 MiB, p = 4. Runs on a worker thread.",
43
16
  body: {
44
17
  type: "object",
45
18
  required: ["password"],
46
19
  additionalProperties: false,
47
20
  properties: {
48
21
  password: { type: "string", minLength: 1, maxLength: 1024 },
49
- timeCost: { type: "integer", minimum: 1, maximum: 10 },
50
- memoryCost: { type: "integer", minimum: 1024, maximum: 262144 },
22
+ timeCost: {
23
+ type: "integer",
24
+ minimum: exports.ARGON2_FLOORS.timeCost,
25
+ maximum: 10,
26
+ },
27
+ memoryCost: {
28
+ type: "integer",
29
+ minimum: exports.ARGON2_FLOORS.memoryCostKiB,
30
+ maximum: 262144,
31
+ },
51
32
  parallelism: { type: "integer", minimum: 1, maximum: 8 },
52
33
  },
53
34
  },
54
35
  },
55
36
  }, async (request, reply) => {
56
- try {
57
- const { hashPassword } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/password")));
58
- const body = request.body;
59
- const result = hashPassword({
60
- password: body.password,
61
- ...(body.timeCost ? { timeCost: body.timeCost } : {}),
62
- ...(body.memoryCost ? { memoryCost: body.memoryCost } : {}),
63
- ...(body.parallelism ? { parallelism: body.parallelism } : {}),
64
- });
65
- return reply.send({ data: result });
66
- }
67
- catch (error) {
68
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Password hashing");
69
- }
37
+ const body = request.body;
38
+ const result = await request.server.kdf.run("modern", "hashPassword", body);
39
+ return reply.send({ data: result });
70
40
  });
41
+ }
42
+ function registerVerify(app) {
71
43
  app.post("/v2/password/verify", {
72
44
  config: { rateLimit: { max: 5, timeWindow: "1 minute" } },
73
45
  schema: {
74
46
  tags: ["Password"],
75
47
  summary: "Verify a password against an Argon2id hash",
48
+ description: "Accepts the parameters of existing hashes, including ones below the floor for new hashes. Runs on a worker thread.",
76
49
  body: {
77
50
  type: "object",
78
51
  required: ["password", "hash", "salt", "params"],
@@ -96,14 +69,16 @@ exports.default = (app) => {
96
69
  },
97
70
  }, async (request, reply) => {
98
71
  try {
99
- const { verifyPassword } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/password")));
100
- const body = request.body;
101
- const result = verifyPassword(body);
72
+ const result = await request.server.kdf.run("modern", "verifyPassword", request.body);
102
73
  return reply.send({ data: result });
103
74
  }
104
75
  catch (error) {
105
76
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Password verification");
106
77
  }
107
78
  });
79
+ }
80
+ exports.default = (app) => {
81
+ registerHash(app);
82
+ registerVerify(app);
108
83
  };
109
84
  //# sourceMappingURL=password.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pq-hash-sign.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/pq-hash-sign.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAqB/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAiHE"}
1
+ {"version":3,"file":"pq-hash-sign.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/pq-hash-sign.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAmJ/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAKE"}
@@ -34,6 +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
+ const keys_1 = require("../../utils/keys");
37
38
  const SLH_DSA_VARIANTS = [
38
39
  "sha2-128f",
39
40
  "sha2-128s",
@@ -48,11 +49,13 @@ const SLH_DSA_VARIANTS = [
48
49
  "shake-256f",
49
50
  "shake-256s",
50
51
  ];
51
- exports.default = (app) => {
52
+ const SLH_DSA_ALGORITHMS = SLH_DSA_VARIANTS.map((v) => `slh-dsa-${v}`);
53
+ function registerKeygen(app) {
52
54
  app.post("/v2/pq/slh-dsa/keygen", {
53
55
  schema: {
54
56
  tags: ["Post-Quantum Hash-Based Signatures"],
55
- summary: "Generate SLH-DSA key pair (FIPS 205)",
57
+ summary: "Generate a server-held SLH-DSA key pair (FIPS 205)",
58
+ description: "Generates an SLH-DSA key pair, keeps the secret key on the server and returns its keyId with the public key.",
56
59
  body: {
57
60
  type: "object",
58
61
  required: ["variant"],
@@ -63,42 +66,40 @@ exports.default = (app) => {
63
66
  },
64
67
  },
65
68
  }, async (request, reply) => {
66
- try {
67
- const { slhDsaKeygen } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/pq-hash-sign")));
68
- const { variant } = request.body;
69
- return reply.send({ data: slhDsaKeygen(variant) });
70
- }
71
- catch (error) {
72
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Key generation");
73
- }
69
+ const { slhDsaKeygen } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
70
+ const { variant } = request.body;
71
+ const { publicKey, secretKey, algorithm } = slhDsaKeygen(variant);
72
+ const stored = await (0, keys_1.storeKey)(request, algorithm, { publicKey }, { secretKey });
73
+ return reply.send({ data: (0, keys_1.publicView)(stored) });
74
74
  });
75
+ }
76
+ function registerSign(app) {
75
77
  app.post("/v2/pq/slh-dsa/sign", {
76
78
  schema: {
77
79
  tags: ["Post-Quantum Hash-Based Signatures"],
78
80
  summary: "Sign with SLH-DSA (FIPS 205)",
81
+ description: "Signs with a server-held SLH-DSA key (keyId from POST /v2/pq/slh-dsa/keygen); the variant comes from the key.",
79
82
  body: {
80
83
  type: "object",
81
- required: ["variant", "secretKey", "message"],
84
+ required: ["keyId", "message"],
82
85
  additionalProperties: false,
83
86
  properties: {
84
- variant: { type: "string", enum: SLH_DSA_VARIANTS },
85
- secretKey: { type: "string", minLength: 1 },
87
+ keyId: keys_1.KEY_ID_SCHEMA,
86
88
  message: { type: "string", minLength: 1 },
87
89
  },
88
90
  },
89
91
  },
90
92
  }, async (request, reply) => {
91
- try {
92
- const { slhDsaSign } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/pq-hash-sign")));
93
- const body = request.body;
94
- return reply.send({
95
- data: slhDsaSign(body.variant, body.secretKey, body.message),
96
- });
97
- }
98
- catch (error) {
99
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Signing");
100
- }
93
+ const { slhDsaSign } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
94
+ const body = request.body;
95
+ const key = await (0, keys_1.resolveKey)(request, body.keyId, SLH_DSA_ALGORITHMS);
96
+ const variant = key.algorithm.slice("slh-dsa-".length);
97
+ return reply.send({
98
+ data: slhDsaSign(variant, key.privateParts["secretKey"], body.message),
99
+ });
101
100
  });
101
+ }
102
+ function registerVerify(app) {
102
103
  app.post("/v2/pq/slh-dsa/verify", {
103
104
  schema: {
104
105
  tags: ["Post-Quantum Hash-Based Signatures"],
@@ -117,7 +118,7 @@ exports.default = (app) => {
117
118
  },
118
119
  }, async (request, reply) => {
119
120
  try {
120
- const { slhDsaVerify } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/pq-hash-sign")));
121
+ const { slhDsaVerify } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
121
122
  const body = request.body;
122
123
  return reply.send({
123
124
  data: slhDsaVerify(body.variant, body.publicKey, body.message, body.signature),
@@ -127,5 +128,10 @@ exports.default = (app) => {
127
128
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Verification");
128
129
  }
129
130
  });
131
+ }
132
+ exports.default = (app) => {
133
+ registerKeygen(app);
134
+ registerSign(app);
135
+ registerVerify(app);
130
136
  };
131
137
  //# sourceMappingURL=pq-hash-sign.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pq-sign.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/pq-sign.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA6GE"}
1
+ {"version":3,"file":"pq-sign.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/pq-sign.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAmI/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAKE"}
@@ -34,11 +34,14 @@ 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
+ const keys_1 = require("../../utils/keys");
38
+ const ML_DSA_ALGORITHMS = ["ml-dsa-44", "ml-dsa-65", "ml-dsa-87"];
39
+ function registerKeygen(app) {
38
40
  app.post("/v2/pq/dsa/keygen", {
39
41
  schema: {
40
42
  tags: ["Post-Quantum Signatures"],
41
- summary: "Generate ML-DSA key pair (FIPS 204)",
43
+ summary: "Generate a server-held ML-DSA key pair (FIPS 204)",
44
+ description: "Generates an ML-DSA key pair, keeps the secret key on the server and returns its keyId with the public key.",
42
45
  body: {
43
46
  type: "object",
44
47
  required: ["level"],
@@ -49,42 +52,40 @@ exports.default = (app) => {
49
52
  },
50
53
  },
51
54
  }, async (request, reply) => {
52
- try {
53
- const { mlDsaKeygen } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/pq-sign")));
54
- const { level } = request.body;
55
- return reply.send({ data: mlDsaKeygen(level) });
56
- }
57
- catch (error) {
58
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Key generation");
59
- }
55
+ const { mlDsaKeygen } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
56
+ const { level } = request.body;
57
+ const { publicKey, secretKey, algorithm } = mlDsaKeygen(level);
58
+ const stored = await (0, keys_1.storeKey)(request, algorithm, { publicKey }, { secretKey });
59
+ return reply.send({ data: (0, keys_1.publicView)(stored) });
60
60
  });
61
+ }
62
+ function registerSign(app) {
61
63
  app.post("/v2/pq/dsa/sign", {
62
64
  schema: {
63
65
  tags: ["Post-Quantum Signatures"],
64
66
  summary: "Sign with ML-DSA (FIPS 204)",
67
+ description: "Signs with a server-held ML-DSA key (keyId from POST /v2/pq/dsa/keygen or POST /v2/keys/generate); the level comes from the key.",
65
68
  body: {
66
69
  type: "object",
67
- required: ["level", "secretKey", "message"],
70
+ required: ["keyId", "message"],
68
71
  additionalProperties: false,
69
72
  properties: {
70
- level: { type: "number", enum: [44, 65, 87] },
71
- secretKey: { type: "string", minLength: 1 },
73
+ keyId: keys_1.KEY_ID_SCHEMA,
72
74
  message: { type: "string", minLength: 1 },
73
75
  },
74
76
  },
75
77
  },
76
78
  }, async (request, reply) => {
77
- try {
78
- const { mlDsaSign } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/pq-sign")));
79
- const body = request.body;
80
- return reply.send({
81
- data: mlDsaSign(body.level, body.secretKey, body.message),
82
- });
83
- }
84
- catch (error) {
85
- return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Signing");
86
- }
79
+ const { mlDsaSign } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
80
+ const body = request.body;
81
+ const key = await (0, keys_1.resolveKey)(request, body.keyId, ML_DSA_ALGORITHMS);
82
+ const level = Number(key.algorithm.slice("ml-dsa-".length));
83
+ return reply.send({
84
+ data: mlDsaSign(level, key.privateParts["secretKey"], body.message),
85
+ });
87
86
  });
87
+ }
88
+ function registerVerify(app) {
88
89
  app.post("/v2/pq/dsa/verify", {
89
90
  schema: {
90
91
  tags: ["Post-Quantum Signatures"],
@@ -103,7 +104,7 @@ exports.default = (app) => {
103
104
  },
104
105
  }, async (request, reply) => {
105
106
  try {
106
- const { mlDsaVerify } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/dist/modern/pq-sign")));
107
+ const { mlDsaVerify } = await Promise.resolve().then(() => __importStar(require("@sebastienrousseau/crypto-lib/modern")));
107
108
  const body = request.body;
108
109
  return reply.send({
109
110
  data: mlDsaVerify(body.level, body.publicKey, body.message, body.signature),
@@ -113,5 +114,10 @@ exports.default = (app) => {
113
114
  return (0, route_helpers_1.classifyCryptoError)(error, request, reply, "Verification");
114
115
  }
115
116
  });
117
+ }
118
+ exports.default = (app) => {
119
+ registerKeygen(app);
120
+ registerSign(app);
121
+ registerVerify(app);
116
122
  };
117
123
  //# sourceMappingURL=pq-sign.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pq.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/pq.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBAY/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBA4ME"}
1
+ {"version":3,"file":"pq.d.ts","sourceRoot":"","sources":["../../../src/routes/v2/pq.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;yBA0P/B,KAAK,eAAe,KAAG,IAAI;AAA3C,wBAUE"}