euclid-ndk 0.2.0

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 (127) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +603 -0
  3. package/dist/auth/index.d.ts +18 -0
  4. package/dist/auth/index.d.ts.map +1 -0
  5. package/dist/auth/index.js +17 -0
  6. package/dist/auth/index.js.map +1 -0
  7. package/dist/auth/rfc9421.d.ts +112 -0
  8. package/dist/auth/rfc9421.d.ts.map +1 -0
  9. package/dist/auth/rfc9421.js +452 -0
  10. package/dist/auth/rfc9421.js.map +1 -0
  11. package/dist/auth/scheme.d.ts +46 -0
  12. package/dist/auth/scheme.d.ts.map +1 -0
  13. package/dist/auth/scheme.js +44 -0
  14. package/dist/auth/scheme.js.map +1 -0
  15. package/dist/auth/signable.d.ts +37 -0
  16. package/dist/auth/signable.d.ts.map +1 -0
  17. package/dist/auth/signable.js +70 -0
  18. package/dist/auth/signable.js.map +1 -0
  19. package/dist/auth/sigv4.d.ts +72 -0
  20. package/dist/auth/sigv4.d.ts.map +1 -0
  21. package/dist/auth/sigv4.js +227 -0
  22. package/dist/auth/sigv4.js.map +1 -0
  23. package/dist/credentials.d.ts +56 -0
  24. package/dist/credentials.d.ts.map +1 -0
  25. package/dist/credentials.js +135 -0
  26. package/dist/credentials.js.map +1 -0
  27. package/dist/dto/com.d.ts +101 -0
  28. package/dist/dto/com.d.ts.map +1 -0
  29. package/dist/dto/com.js +132 -0
  30. package/dist/dto/com.js.map +1 -0
  31. package/dist/dto/eag.d.ts +104 -0
  32. package/dist/dto/eag.d.ts.map +1 -0
  33. package/dist/dto/eag.js +70 -0
  34. package/dist/dto/eag.js.map +1 -0
  35. package/dist/dto/eam.d.ts +105 -0
  36. package/dist/dto/eam.d.ts.map +1 -0
  37. package/dist/dto/eam.js +98 -0
  38. package/dist/dto/eam.js.map +1 -0
  39. package/dist/dto/eap.d.ts +88 -0
  40. package/dist/dto/eap.d.ts.map +1 -0
  41. package/dist/dto/eap.js +54 -0
  42. package/dist/dto/eap.js.map +1 -0
  43. package/dist/dto/ekm.d.ts +109 -0
  44. package/dist/dto/ekm.d.ts.map +1 -0
  45. package/dist/dto/ekm.js +78 -0
  46. package/dist/dto/ekm.js.map +1 -0
  47. package/dist/dto/ekv.d.ts +73 -0
  48. package/dist/dto/ekv.d.ts.map +1 -0
  49. package/dist/dto/ekv.js +45 -0
  50. package/dist/dto/ekv.js.map +1 -0
  51. package/dist/dto/ens.d.ts +84 -0
  52. package/dist/dto/ens.d.ts.map +1 -0
  53. package/dist/dto/ens.js +72 -0
  54. package/dist/dto/ens.js.map +1 -0
  55. package/dist/dto/eqs.d.ts +160 -0
  56. package/dist/dto/eqs.d.ts.map +1 -0
  57. package/dist/dto/eqs.js +120 -0
  58. package/dist/dto/eqs.js.map +1 -0
  59. package/dist/dto/esm.d.ts +192 -0
  60. package/dist/dto/esm.d.ts.map +1 -0
  61. package/dist/dto/esm.js +147 -0
  62. package/dist/dto/esm.js.map +1 -0
  63. package/dist/dto/ess.d.ts +49 -0
  64. package/dist/dto/ess.d.ts.map +1 -0
  65. package/dist/dto/ess.js +30 -0
  66. package/dist/dto/ess.js.map +1 -0
  67. package/dist/dto/json.d.ts +24 -0
  68. package/dist/dto/json.d.ts.map +1 -0
  69. package/dist/dto/json.js +47 -0
  70. package/dist/dto/json.js.map +1 -0
  71. package/dist/errors.d.ts +40 -0
  72. package/dist/errors.d.ts.map +1 -0
  73. package/dist/errors.js +73 -0
  74. package/dist/errors.js.map +1 -0
  75. package/dist/http/client.d.ts +96 -0
  76. package/dist/http/client.d.ts.map +1 -0
  77. package/dist/http/client.js +258 -0
  78. package/dist/http/client.js.map +1 -0
  79. package/dist/index.d.ts +93 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +110 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/modules/base.d.ts +121 -0
  84. package/dist/modules/base.d.ts.map +1 -0
  85. package/dist/modules/base.js +142 -0
  86. package/dist/modules/base.js.map +1 -0
  87. package/dist/modules/eag.d.ts +166 -0
  88. package/dist/modules/eag.d.ts.map +1 -0
  89. package/dist/modules/eag.js +189 -0
  90. package/dist/modules/eag.js.map +1 -0
  91. package/dist/modules/eam.d.ts +314 -0
  92. package/dist/modules/eam.d.ts.map +1 -0
  93. package/dist/modules/eam.js +641 -0
  94. package/dist/modules/eam.js.map +1 -0
  95. package/dist/modules/eap.d.ts +204 -0
  96. package/dist/modules/eap.d.ts.map +1 -0
  97. package/dist/modules/eap.js +218 -0
  98. package/dist/modules/eap.js.map +1 -0
  99. package/dist/modules/ekm.d.ts +182 -0
  100. package/dist/modules/ekm.d.ts.map +1 -0
  101. package/dist/modules/ekm.js +228 -0
  102. package/dist/modules/ekm.js.map +1 -0
  103. package/dist/modules/ekv.d.ts +189 -0
  104. package/dist/modules/ekv.d.ts.map +1 -0
  105. package/dist/modules/ekv.js +212 -0
  106. package/dist/modules/ekv.js.map +1 -0
  107. package/dist/modules/ens.d.ts +122 -0
  108. package/dist/modules/ens.d.ts.map +1 -0
  109. package/dist/modules/ens.js +167 -0
  110. package/dist/modules/ens.js.map +1 -0
  111. package/dist/modules/eqs.d.ts +283 -0
  112. package/dist/modules/eqs.d.ts.map +1 -0
  113. package/dist/modules/eqs.js +355 -0
  114. package/dist/modules/eqs.js.map +1 -0
  115. package/dist/modules/esm.d.ts +358 -0
  116. package/dist/modules/esm.d.ts.map +1 -0
  117. package/dist/modules/esm.js +660 -0
  118. package/dist/modules/esm.js.map +1 -0
  119. package/dist/modules/ess.d.ts +96 -0
  120. package/dist/modules/ess.d.ts.map +1 -0
  121. package/dist/modules/ess.js +110 -0
  122. package/dist/modules/ess.js.map +1 -0
  123. package/dist/url.d.ts +31 -0
  124. package/dist/url.d.ts.map +1 -0
  125. package/dist/url.js +47 -0
  126. package/dist/url.js.map +1 -0
  127. package/package.json +47 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * RFC 9421 HTTP Message Signatures, the scheme meant to take over from SigV4.
3
+ *
4
+ * Same credentials, same threat model, standard wire format: the caller still presents an access
5
+ * key ID and its secret, and the signature is still an HMAC-SHA256 over a canonical rendering of
6
+ * the request, but what gets rendered and how it travels is the IETF's rather than AWS's. The
7
+ * signature goes in `Signature` and `Signature-Input` instead of `Authorization`, which is what
8
+ * lets the two schemes coexist during a migration - SigV4 owns `Authorization`, this owns its own
9
+ * headers, and a server can accept either without guessing which one a request meant.
10
+ *
11
+ * **Algorithm.** Only `hmac-sha256`, because that is the algorithm that takes euclid's existing
12
+ * access-key/secret pairs unchanged: the HMAC key is the secret's UTF-8 bytes directly (RFC 9421
13
+ * §3.3.3), with none of SigV4's key-derivation chain to reproduce.
14
+ *
15
+ * **Covered components.** RFC 9421 lets a signer choose what its signature covers and declare it
16
+ * in `Signature-Input`. Taken literally that would let a request decide how little of itself to
17
+ * authenticate, so it is not taken literally here: the set is fixed, {@link verify} rejects a
18
+ * signature covering anything else in any other order, and {@link sign} refuses to sign a request
19
+ * that cannot supply all of it. The list is a wire format shared with euclid's
20
+ * `Core::HttpSignature::CoveredComponents()` and the two only ever change together.
21
+ *
22
+ * See RFC 9421 and RFC 9530 (Content-Digest).
23
+ */
24
+ import type { SignableRequest } from "./signable.js";
25
+ export declare const ALGORITHM = "hmac-sha256";
26
+ export declare const TAG = "euclid";
27
+ export declare const SIGNATURE_HEADER_NAMES: readonly ["Content-Digest", "Signature-Input", "Signature"];
28
+ /**
29
+ * The parameters of one signature, as carried in `Signature-Input`.
30
+ *
31
+ * `raw` is the parameter string exactly as received. It is kept because that is what the signature
32
+ * was computed over: re-serialising the parsed fields would not reliably reproduce another
33
+ * implementation's byte-for-byte choices, and a base rebuilt from a re-serialisation would fail to
34
+ * verify a perfectly good signature.
35
+ */
36
+ export interface SignatureParams {
37
+ components: string[];
38
+ created: number | null;
39
+ expires: number | null;
40
+ keyId: string;
41
+ algorithm: string | null;
42
+ nonce: string | null;
43
+ tag: string | null;
44
+ raw: string;
45
+ }
46
+ /** A signature and its parameters, paired by the dictionary label they share. */
47
+ export interface ParsedSignature {
48
+ label: string;
49
+ params: SignatureParams;
50
+ signature: Buffer;
51
+ }
52
+ /** The components every euclid signature covers, in signing order. */
53
+ export declare function requiredComponents(): readonly string[];
54
+ /**
55
+ * The components a signature over this request must cover.
56
+ *
57
+ * Takes the request because RFC 9421 allows a signer to cover a field only when the message carries
58
+ * one, and a future version of euclid may want that back. It does not vary today.
59
+ */
60
+ export declare function coveredComponents(_req: SignableRequest): readonly string[];
61
+ /** The headers {@link sign} writes, in the case they should be sent in. */
62
+ export declare function signatureHeaderNames(): readonly string[];
63
+ /** The RFC 9530 `Content-Digest` value binding a body to its signature. */
64
+ export declare function contentDigest(body: Buffer | string): string;
65
+ /** Serialises the `Signature-Input` value for a set of covered components, without a label. */
66
+ export declare function serializeSignatureParams(components: readonly string[], created: number, keyId: string, nonce: string): string;
67
+ /**
68
+ * Builds the §2.5 signature base: one line per component, then `@signature-params`.
69
+ *
70
+ * The last line carries no trailing newline. Answers null if any covered component is absent from
71
+ * the request - §2.1 forbids signing over a field that is not there, and producing a base with a
72
+ * blank in its place would sign something the verifier will never reconstruct.
73
+ */
74
+ export declare function signatureBase(req: SignableRequest, components: readonly string[], params: string): string | null;
75
+ /**
76
+ * Signs a request in place: sets Content-Digest, Signature-Input and Signature.
77
+ *
78
+ * Call it once every header the signature covers and the body are already set. Unlike SigV4 this
79
+ * leaves Authorization alone, so a request can carry a bearer token and a signature at once if a
80
+ * deployment wants both during a migration.
81
+ *
82
+ * Throws when a component that must be covered is missing, which for a client means it was
83
+ * configured without a region, an account id or a user id and so has nothing to sign with.
84
+ */
85
+ export declare function sign(req: SignableRequest, accessKeyId: string, secretAccessKey: string): void;
86
+ /**
87
+ * Verifies an RFC 9421-signed request, answering the key ID it was signed with.
88
+ *
89
+ * Rebuilds the base from the request exactly as received - including the parameters verbatim - and
90
+ * compares the HMAC in constant time. Answers null on every failure without saying which, as
91
+ * {@link import("./sigv4.js").verify} does.
92
+ *
93
+ * The checks mirror euclid's `Core::HttpSignature::Verify`: the covered set must be exactly
94
+ * {@link requiredComponents}, in that order; `alg` must be `hmac-sha256`; `created` must be within
95
+ * the skew window; and `Content-Digest` must match the body actually received, since that header is
96
+ * the only thing the signature covers the body through.
97
+ *
98
+ * `tag` is checked only when present, and euclid's own signer emits none. Requiring it would reject
99
+ * signatures made by the server itself.
100
+ */
101
+ export declare function verify(req: SignableRequest, lookupSecret: (keyId: string) => string | null | undefined, maxSkewSeconds?: number): string | null;
102
+ /**
103
+ * Parses a matching pair of `Signature-Input` and `Signature` values.
104
+ *
105
+ * Both must hold exactly one signature under the same label. RFC 9421 allows several - a proxy
106
+ * adding its own alongside the client's - but euclid has no use for more than one, and refusing to
107
+ * choose among them means never verifying the wrong one.
108
+ */
109
+ export declare function parseSignature(signatureInputHeader: string, signatureHeader: string): ParsedSignature | null;
110
+ /** Parses a `Signature-Input` value: an inner list of components, then the parameters. */
111
+ export declare function parseSignatureParams(value: string): SignatureParams | null;
112
+ //# sourceMappingURL=rfc9421.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rfc9421.d.ts","sourceRoot":"","sources":["../../src/auth/rfc9421.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,eAAO,MAAM,SAAS,gBAAgB,CAAC;AACvC,eAAO,MAAM,GAAG,WAAW,CAAC;AA2B5B,eAAO,MAAM,sBAAsB,6DAA8D,CAAC;AAElG;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,IAAI,SAAS,MAAM,EAAE,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,MAAM,EAAE,CAE1E;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,IAAI,SAAS,MAAM,EAAE,CAExD;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAG3D;AAED,+FAA+F;AAC/F,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAShH;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAiB7F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CACpB,GAAG,EAAE,eAAe,EACpB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,EAC1D,cAAc,GAAE,MAAiC,GAChD,MAAM,GAAG,IAAI,CA+Bf;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,oBAAoB,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAS5G;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA+C1E"}
@@ -0,0 +1,452 @@
1
+ /**
2
+ * RFC 9421 HTTP Message Signatures, the scheme meant to take over from SigV4.
3
+ *
4
+ * Same credentials, same threat model, standard wire format: the caller still presents an access
5
+ * key ID and its secret, and the signature is still an HMAC-SHA256 over a canonical rendering of
6
+ * the request, but what gets rendered and how it travels is the IETF's rather than AWS's. The
7
+ * signature goes in `Signature` and `Signature-Input` instead of `Authorization`, which is what
8
+ * lets the two schemes coexist during a migration - SigV4 owns `Authorization`, this owns its own
9
+ * headers, and a server can accept either without guessing which one a request meant.
10
+ *
11
+ * **Algorithm.** Only `hmac-sha256`, because that is the algorithm that takes euclid's existing
12
+ * access-key/secret pairs unchanged: the HMAC key is the secret's UTF-8 bytes directly (RFC 9421
13
+ * §3.3.3), with none of SigV4's key-derivation chain to reproduce.
14
+ *
15
+ * **Covered components.** RFC 9421 lets a signer choose what its signature covers and declare it
16
+ * in `Signature-Input`. Taken literally that would let a request decide how little of itself to
17
+ * authenticate, so it is not taken literally here: the set is fixed, {@link verify} rejects a
18
+ * signature covering anything else in any other order, and {@link sign} refuses to sign a request
19
+ * that cannot supply all of it. The list is a wire format shared with euclid's
20
+ * `Core::HttpSignature::CoveredComponents()` and the two only ever change together.
21
+ *
22
+ * See RFC 9421 and RFC 9530 (Content-Digest).
23
+ */
24
+ import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
25
+ export const ALGORITHM = "hmac-sha256";
26
+ export const TAG = "euclid";
27
+ const LABEL = "sig1";
28
+ const DEFAULT_MAX_SKEW_SECONDS = 15 * 60;
29
+ /**
30
+ * The derived components pin the request line and host, content-digest pins the body, and the
31
+ * x-euclid-* headers pin what the request asks for and on whose behalf - which for euclid lives in
32
+ * headers rather than in the URI.
33
+ *
34
+ * Two absences are deliberate. "@query" is not covered because euclid POSTs everything to "/" and
35
+ * carries its arguments in the body, so there is no query string to protect. "x-euclid-namespace"
36
+ * is not covered either, and that one is a real gap rather than a simplification: the namespace
37
+ * scopes what a request may touch and it currently travels unsigned. Closing it means adding the
38
+ * component to euclid's server and to this list in the same release.
39
+ */
40
+ const REQUIRED_COMPONENTS = [
41
+ "@method",
42
+ "@path",
43
+ "@authority",
44
+ "content-digest",
45
+ "x-euclid-account-id",
46
+ "x-euclid-action",
47
+ "x-euclid-region",
48
+ "x-euclid-target",
49
+ "x-euclid-user-id",
50
+ ];
51
+ export const SIGNATURE_HEADER_NAMES = ["Content-Digest", "Signature-Input", "Signature"];
52
+ /** The components every euclid signature covers, in signing order. */
53
+ export function requiredComponents() {
54
+ return REQUIRED_COMPONENTS;
55
+ }
56
+ /**
57
+ * The components a signature over this request must cover.
58
+ *
59
+ * Takes the request because RFC 9421 allows a signer to cover a field only when the message carries
60
+ * one, and a future version of euclid may want that back. It does not vary today.
61
+ */
62
+ export function coveredComponents(_req) {
63
+ return REQUIRED_COMPONENTS;
64
+ }
65
+ /** The headers {@link sign} writes, in the case they should be sent in. */
66
+ export function signatureHeaderNames() {
67
+ return SIGNATURE_HEADER_NAMES;
68
+ }
69
+ /** The RFC 9530 `Content-Digest` value binding a body to its signature. */
70
+ export function contentDigest(body) {
71
+ const raw = typeof body === "string" ? Buffer.from(body, "utf8") : body;
72
+ return `sha-256=:${createHash("sha256").update(raw).digest("base64")}:`;
73
+ }
74
+ /** Serialises the `Signature-Input` value for a set of covered components, without a label. */
75
+ export function serializeSignatureParams(components, created, keyId, nonce) {
76
+ const inner = components.map(quote).join(" ");
77
+ return `(${inner});created=${created};keyid=${quote(keyId)};alg=${quote(ALGORITHM)};nonce=${quote(nonce)};tag=${quote(TAG)}`;
78
+ }
79
+ /**
80
+ * Builds the §2.5 signature base: one line per component, then `@signature-params`.
81
+ *
82
+ * The last line carries no trailing newline. Answers null if any covered component is absent from
83
+ * the request - §2.1 forbids signing over a field that is not there, and producing a base with a
84
+ * blank in its place would sign something the verifier will never reconstruct.
85
+ */
86
+ export function signatureBase(req, components, params) {
87
+ const lines = [];
88
+ for (const component of components) {
89
+ const value = componentValue(req, component);
90
+ if (value === null)
91
+ return null;
92
+ lines.push(`"${component}": ${value}`);
93
+ }
94
+ lines.push(`"@signature-params": ${params}`);
95
+ return lines.join("\n");
96
+ }
97
+ /**
98
+ * Signs a request in place: sets Content-Digest, Signature-Input and Signature.
99
+ *
100
+ * Call it once every header the signature covers and the body are already set. Unlike SigV4 this
101
+ * leaves Authorization alone, so a request can carry a bearer token and a signature at once if a
102
+ * deployment wants both during a migration.
103
+ *
104
+ * Throws when a component that must be covered is missing, which for a client means it was
105
+ * configured without a region, an account id or a user id and so has nothing to sign with.
106
+ */
107
+ export function sign(req, accessKeyId, secretAccessKey) {
108
+ req.header("Content-Digest", contentDigest(req.body));
109
+ const components = coveredComponents(req);
110
+ const params = serializeSignatureParams(components, Math.floor(Date.now() / 1000), accessKeyId, newNonce());
111
+ const base = signatureBase(req, components, params);
112
+ if (base === null) {
113
+ const missing = components.filter((component) => componentValue(req, component) === null);
114
+ throw new Error(`request cannot be signed, it is missing ${JSON.stringify(missing)} - euclid signs a fixed set of ` +
115
+ "components, so a client configured without a region, account id or user id has nothing to sign with");
116
+ }
117
+ const signature = createHmac("sha256", Buffer.from(secretAccessKey, "utf8")).update(base, "utf8").digest();
118
+ req.header("Signature-Input", `${LABEL}=${params}`);
119
+ req.header("Signature", `${LABEL}=:${signature.toString("base64")}:`);
120
+ }
121
+ /**
122
+ * Verifies an RFC 9421-signed request, answering the key ID it was signed with.
123
+ *
124
+ * Rebuilds the base from the request exactly as received - including the parameters verbatim - and
125
+ * compares the HMAC in constant time. Answers null on every failure without saying which, as
126
+ * {@link import("./sigv4.js").verify} does.
127
+ *
128
+ * The checks mirror euclid's `Core::HttpSignature::Verify`: the covered set must be exactly
129
+ * {@link requiredComponents}, in that order; `alg` must be `hmac-sha256`; `created` must be within
130
+ * the skew window; and `Content-Digest` must match the body actually received, since that header is
131
+ * the only thing the signature covers the body through.
132
+ *
133
+ * `tag` is checked only when present, and euclid's own signer emits none. Requiring it would reject
134
+ * signatures made by the server itself.
135
+ */
136
+ export function verify(req, lookupSecret, maxSkewSeconds = DEFAULT_MAX_SKEW_SECONDS) {
137
+ const parsed = parseSignature(req.get("signature-input"), req.get("signature"));
138
+ if (parsed === null)
139
+ return null;
140
+ const params = parsed.params;
141
+ // Only one algorithm exists here, so an unexpected alg is a rejection rather than a branch -
142
+ // which is also what stops a signature being reinterpreted under a weaker one.
143
+ if (params.algorithm !== ALGORITHM)
144
+ return null;
145
+ if (params.tag !== null && params.tag !== TAG)
146
+ return null;
147
+ // Fixed policy, not client-negotiated, and order-sensitive because the server is.
148
+ const required = coveredComponents(req);
149
+ if (params.components.length !== required.length)
150
+ return null;
151
+ if (params.components.some((component, index) => component !== required[index]))
152
+ return null;
153
+ const now = Math.floor(Date.now() / 1000);
154
+ if (params.created === null || Math.abs(now - params.created) > maxSkewSeconds)
155
+ return null;
156
+ if (params.expires !== null && params.expires < now)
157
+ return null;
158
+ if (!req.has("content-digest") || !equal(req.get("content-digest"), contentDigest(req.body)))
159
+ return null;
160
+ const secret = lookupSecret(params.keyId);
161
+ if (secret == null)
162
+ return null;
163
+ const base = signatureBase(req, params.components, params.raw);
164
+ if (base === null)
165
+ return null;
166
+ const expected = createHmac("sha256", Buffer.from(secret, "utf8")).update(base, "utf8").digest();
167
+ if (expected.length !== parsed.signature.length || !timingSafeEqual(expected, parsed.signature))
168
+ return null;
169
+ return params.keyId;
170
+ }
171
+ /**
172
+ * Parses a matching pair of `Signature-Input` and `Signature` values.
173
+ *
174
+ * Both must hold exactly one signature under the same label. RFC 9421 allows several - a proxy
175
+ * adding its own alongside the client's - but euclid has no use for more than one, and refusing to
176
+ * choose among them means never verifying the wrong one.
177
+ */
178
+ export function parseSignature(signatureInputHeader, signatureHeader) {
179
+ const inputMember = singleDictionaryMember(signatureInputHeader);
180
+ const signatureMember = singleDictionaryMember(signatureHeader);
181
+ if (inputMember === null || signatureMember === null || inputMember[0] !== signatureMember[0])
182
+ return null;
183
+ const params = parseSignatureParams(inputMember[1]);
184
+ const signature = parseByteSequence(signatureMember[1]);
185
+ if (params === null || signature === null)
186
+ return null;
187
+ return { label: inputMember[0], params, signature };
188
+ }
189
+ /** Parses a `Signature-Input` value: an inner list of components, then the parameters. */
190
+ export function parseSignatureParams(value) {
191
+ if (!value || value[0] !== "(")
192
+ return null;
193
+ const components = [];
194
+ let pos = 1;
195
+ for (;;) {
196
+ if (pos >= value.length)
197
+ return null;
198
+ const char = value[pos];
199
+ if (char === ")") {
200
+ pos += 1;
201
+ break;
202
+ }
203
+ if (char === " ") {
204
+ pos += 1;
205
+ continue;
206
+ }
207
+ if (char !== '"')
208
+ return null;
209
+ const end = endOfQuotedString(value, pos);
210
+ if (end < 0)
211
+ return null;
212
+ // A component carrying parameters of its own ("x";req and friends) means something this module
213
+ // does not implement, so it is rejected rather than quietly read as plain.
214
+ if (end + 1 < value.length && value[end + 1] !== " " && value[end + 1] !== ")")
215
+ return null;
216
+ components.push(unquote(value.slice(pos, end + 1)));
217
+ pos = end + 1;
218
+ }
219
+ if (components.length === 0)
220
+ return null;
221
+ const parameters = parseParameters(value.slice(pos));
222
+ if (parameters === null)
223
+ return null;
224
+ const keyId = parameters["keyid"];
225
+ if (typeof keyId !== "string")
226
+ return null;
227
+ const created = timestampOf(parameters, "created");
228
+ const expires = timestampOf(parameters, "expires");
229
+ if (created === INVALID || expires === INVALID)
230
+ return null;
231
+ return {
232
+ components,
233
+ created,
234
+ expires,
235
+ keyId,
236
+ algorithm: stringOrNull(parameters["alg"]),
237
+ nonce: stringOrNull(parameters["nonce"]),
238
+ tag: stringOrNull(parameters["tag"]),
239
+ raw: value,
240
+ };
241
+ }
242
+ // -- internals -------------------------------------------------------------------------------
243
+ /** One covered component's value for the base: §2.2's derived values, or the header. */
244
+ function componentValue(req, component) {
245
+ if (!component.startsWith("@"))
246
+ return req.has(component) ? req.get(component) : null;
247
+ const question = req.target.indexOf("?");
248
+ const path = question < 0 ? req.target : req.target.slice(0, question);
249
+ const query = question < 0 ? null : req.target.slice(question + 1);
250
+ switch (component) {
251
+ case "@method":
252
+ return req.method.toUpperCase();
253
+ case "@authority":
254
+ return authorityOf(req);
255
+ case "@scheme":
256
+ return req.scheme;
257
+ case "@path":
258
+ // §2.2.6: the path is "/" when empty.
259
+ return path === "" ? "/" : path;
260
+ case "@query":
261
+ // §2.2.7: the query keeps its leading "?", and is that character alone when there is none.
262
+ return query === null ? "?" : `?${query}`;
263
+ case "@request-target":
264
+ return req.target;
265
+ case "@target-uri": {
266
+ const authority = authorityOf(req);
267
+ return authority === null ? null : `${req.scheme}://${authority}${req.target}`;
268
+ }
269
+ default:
270
+ return null;
271
+ }
272
+ }
273
+ /** §2.2.3: the host header lowercased, minus the port when it is the scheme's default. */
274
+ function authorityOf(req) {
275
+ const host = req.get("host").toLowerCase();
276
+ if (!host)
277
+ return null;
278
+ const defaultPort = req.scheme === "https" ? ":443" : req.scheme === "http" ? ":80" : "";
279
+ return defaultPort && host.endsWith(defaultPort) ? host.slice(0, -defaultPort.length) : host;
280
+ }
281
+ /**
282
+ * Splits a structured-field dictionary that must hold exactly one member into label and value.
283
+ *
284
+ * Respects quoting and nesting, so a comma inside a component name or a base64 signature cannot be
285
+ * mistaken for a member separator.
286
+ */
287
+ function singleDictionaryMember(value) {
288
+ if (!value)
289
+ return null;
290
+ const members = splitTopLevel(value, ",");
291
+ if (members.length !== 1)
292
+ return null;
293
+ const member = members[0].trim();
294
+ const equals = indexOfTopLevel(member, "=");
295
+ if (equals <= 0 || equals === member.length - 1)
296
+ return null;
297
+ return [member.slice(0, equals).trim(), member.slice(equals + 1).trim()];
298
+ }
299
+ function splitTopLevel(value, delimiter) {
300
+ const parts = [];
301
+ let depth = 0;
302
+ let inQuotes = false;
303
+ let start = 0;
304
+ let i = 0;
305
+ while (i < value.length) {
306
+ const char = value[i];
307
+ if (inQuotes) {
308
+ if (char === "\\") {
309
+ i += 2;
310
+ continue;
311
+ }
312
+ if (char === '"')
313
+ inQuotes = false;
314
+ }
315
+ else if (char === '"')
316
+ inQuotes = true;
317
+ else if (char === "(")
318
+ depth += 1;
319
+ else if (char === ")")
320
+ depth -= 1;
321
+ else if (char === delimiter && depth === 0) {
322
+ parts.push(value.slice(start, i));
323
+ start = i + 1;
324
+ }
325
+ i += 1;
326
+ }
327
+ parts.push(value.slice(start));
328
+ return parts;
329
+ }
330
+ function indexOfTopLevel(value, charToFind) {
331
+ let inQuotes = false;
332
+ let i = 0;
333
+ while (i < value.length) {
334
+ const char = value[i];
335
+ if (inQuotes) {
336
+ if (char === "\\") {
337
+ i += 2;
338
+ continue;
339
+ }
340
+ if (char === '"')
341
+ inQuotes = false;
342
+ }
343
+ else if (char === '"')
344
+ inQuotes = true;
345
+ else if (char === charToFind)
346
+ return i;
347
+ i += 1;
348
+ }
349
+ return -1;
350
+ }
351
+ /** The index of the closing quote of the string opening at `start`, or -1 if unterminated. */
352
+ function endOfQuotedString(value, start) {
353
+ let i = start + 1;
354
+ while (i < value.length) {
355
+ if (value[i] === "\\") {
356
+ i += 2;
357
+ continue;
358
+ }
359
+ if (value[i] === '"')
360
+ return i;
361
+ i += 1;
362
+ }
363
+ return -1;
364
+ }
365
+ /** Parses `;name=value;name2=value2` into a mapping, or null if it is not well-formed. */
366
+ function parseParameters(rest) {
367
+ const parameters = {};
368
+ let pos = 0;
369
+ while (pos < rest.length) {
370
+ if (rest[pos] !== ";")
371
+ return null;
372
+ pos += 1;
373
+ while (pos < rest.length && rest[pos] === " ")
374
+ pos += 1;
375
+ const nameStart = pos;
376
+ while (pos < rest.length && rest[pos] !== "=" && rest[pos] !== ";")
377
+ pos += 1;
378
+ const name = rest.slice(nameStart, pos).trim();
379
+ if (!name)
380
+ return null;
381
+ if (pos >= rest.length || rest[pos] === ";") {
382
+ // A bare parameter is a boolean true in structured fields.
383
+ parameters[name] = true;
384
+ continue;
385
+ }
386
+ pos += 1; // the '='
387
+ if (pos < rest.length && rest[pos] === '"') {
388
+ const end = endOfQuotedString(rest, pos);
389
+ if (end < 0)
390
+ return null;
391
+ parameters[name] = unquote(rest.slice(pos, end + 1));
392
+ pos = end + 1;
393
+ }
394
+ else if (pos < rest.length && rest[pos] === ":") {
395
+ const end = rest.indexOf(":", pos + 1);
396
+ if (end < 0)
397
+ return null;
398
+ parameters[name] = decodeBase64(rest.slice(pos + 1, end));
399
+ pos = end + 1;
400
+ }
401
+ else {
402
+ const valueStart = pos;
403
+ while (pos < rest.length && rest[pos] !== ";")
404
+ pos += 1;
405
+ parameters[name] = asIntegerOrToken(rest.slice(valueStart, pos).trim());
406
+ }
407
+ }
408
+ return parameters;
409
+ }
410
+ /** Parses a structured-field byte sequence, `:<base64>:`. */
411
+ function parseByteSequence(value) {
412
+ const trimmed = value.trim();
413
+ if (trimmed.length < 2 || trimmed[0] !== ":" || trimmed[trimmed.length - 1] !== ":")
414
+ return null;
415
+ return decodeBase64(trimmed.slice(1, -1));
416
+ }
417
+ function decodeBase64(value) {
418
+ // Node's base64 decoder ignores what it cannot read rather than refusing it, so a round trip is
419
+ // what says the input really was base64 - the strictness the verifier depends on.
420
+ const decoded = Buffer.from(value, "base64");
421
+ return decoded.toString("base64").replace(/=+$/, "") === value.replace(/=+$/, "") ? decoded : null;
422
+ }
423
+ function asIntegerOrToken(raw) {
424
+ return /^-?\d+$/.test(raw) ? Number(raw) : raw;
425
+ }
426
+ const INVALID = Symbol("invalid");
427
+ /** The parameter as a Unix timestamp; null when absent, INVALID when present but not an integer. */
428
+ function timestampOf(parameters, name) {
429
+ if (!(name in parameters))
430
+ return null;
431
+ const value = parameters[name];
432
+ return typeof value === "number" && Number.isInteger(value) ? value : INVALID;
433
+ }
434
+ function stringOrNull(value) {
435
+ return typeof value === "string" ? value : null;
436
+ }
437
+ function quote(value) {
438
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
439
+ }
440
+ function unquote(quoted) {
441
+ return quoted.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, "\\");
442
+ }
443
+ function newNonce() {
444
+ return randomBytes(16).toString("base64url");
445
+ }
446
+ /** Constant-time string comparison, which is what a digest check has to be. */
447
+ function equal(left, right) {
448
+ const a = Buffer.from(left, "utf8");
449
+ const b = Buffer.from(right, "utf8");
450
+ return a.length === b.length && timingSafeEqual(a, b);
451
+ }
452
+ //# sourceMappingURL=rfc9421.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rfc9421.js","sourceRoot":"","sources":["../../src/auth/rfc9421.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /** Which request-signing scheme a client uses when it authenticates with an access key. */
2
+ import type { SignableRequest } from "./signable.js";
3
+ /**
4
+ * SigV4 or RFC 9421.
5
+ *
6
+ * Two schemes exist because euclid is moving from one to the other, not because both are wanted in
7
+ * the end. {@link SIGV4} is what euclid has always spoken and stays the default, so no existing
8
+ * caller changes behaviour; {@link RFC9421} is the standard scheme meant to replace it. Choosing
9
+ * one is a per-client decision, so a deployment can move one service at a time and roll back by
10
+ * changing a line rather than a release.
11
+ *
12
+ * Neither is consulted when a client authenticates with a bearer token: with no access key there is
13
+ * nothing to sign with, and the token goes in Authorization as before.
14
+ *
15
+ * The two do not collide on the wire - SigV4 puts its signature in Authorization, RFC 9421 in
16
+ * Signature/Signature-Input - so a server can accept both at once and tell which a request used.
17
+ * {@link signingSchemeOf} is that test.
18
+ */
19
+ export interface SigningScheme {
20
+ readonly name: "sigv4" | "rfc9421";
21
+ /**
22
+ * Signs a request in place.
23
+ *
24
+ * `region` and `service` are ignored by {@link RFC9421}: SigV4 needs them to derive its signing
25
+ * key, whereas RFC 9421 signs the `x-euclid-region` and `x-euclid-target` headers that carry the
26
+ * same facts, and binding them twice would add a way for the two copies to disagree.
27
+ */
28
+ sign(req: SignableRequest, accessKeyId: string, secretAccessKey: string, region: string, service: string): void;
29
+ /** Verifies a request signed with this scheme, answering the access key ID or null. */
30
+ verify(req: SignableRequest, lookupSecret: (keyId: string) => string | null | undefined): string | null;
31
+ /** The headers {@link SigningScheme.sign} writes, for callers that copy them onto another request. */
32
+ signatureHeaderNames(): readonly string[];
33
+ }
34
+ /** What euclid has always spoken, and the default. */
35
+ export declare const SIGV4: SigningScheme;
36
+ /** The standard scheme meant to replace SigV4. */
37
+ export declare const RFC9421: SigningScheme;
38
+ /**
39
+ * Which scheme, if either, a received request presents a signature for.
40
+ *
41
+ * A routing decision, not a verification: it says which {@link SigningScheme.verify} to call and
42
+ * nothing about whether that call will succeed. Null means the request presents no signature at
43
+ * all - a bearer-token request, or an unsigned one.
44
+ */
45
+ export declare function signingSchemeOf(req: SignableRequest): SigningScheme | null;
46
+ //# sourceMappingURL=scheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheme.d.ts","sourceRoot":"","sources":["../../src/auth/scheme.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAG3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAEnC;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhH,uFAAuF;IACvF,MAAM,CAAC,GAAG,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IAExG,sGAAsG;IACtG,oBAAoB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,sDAAsD;AACtD,eAAO,MAAM,KAAK,EAAE,aAWlB,CAAC;AAEH,kDAAkD;AAClD,eAAO,MAAM,OAAO,EAAE,aAWpB,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,GAAG,IAAI,CAI1E"}