hbsig 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/bin_to_str.js +44 -0
- package/cjs/collect-body-keys.js +470 -0
- package/cjs/encode-array-item.js +110 -0
- package/cjs/encode-utils.js +236 -0
- package/cjs/encode.js +1318 -0
- package/cjs/erl_json.js +317 -0
- package/cjs/erl_str.js +1037 -0
- package/cjs/flat.js +222 -0
- package/cjs/http-message-signatures/httpbis.js +489 -0
- package/cjs/http-message-signatures/index.js +25 -0
- package/cjs/http-message-signatures/structured-header.js +129 -0
- package/cjs/httpsig.js +716 -0
- package/cjs/httpsig2.js +1160 -0
- package/cjs/id.js +470 -0
- package/cjs/index.js +63 -0
- package/cjs/send.js +194 -0
- package/cjs/signer-utils.js +617 -0
- package/cjs/signer.js +606 -0
- package/cjs/structured.js +296 -0
- package/cjs/test.js +27 -0
- package/cjs/utils.js +42 -0
- package/esm/bin_to_str.js +46 -0
- package/esm/collect-body-keys.js +436 -0
- package/esm/encode-array-item.js +112 -0
- package/esm/encode-utils.js +185 -0
- package/esm/encode.js +1219 -0
- package/esm/erl_json.js +289 -0
- package/esm/erl_str.js +1139 -0
- package/esm/flat.js +196 -0
- package/esm/http-message-signatures/httpbis.js +438 -0
- package/esm/http-message-signatures/index.js +4 -0
- package/esm/http-message-signatures/structured-header.js +105 -0
- package/esm/httpsig.js +658 -0
- package/esm/httpsig2.js +1097 -0
- package/esm/id.js +459 -0
- package/esm/index.js +4 -0
- package/esm/package.json +3 -0
- package/esm/send.js +124 -0
- package/esm/signer-utils.js +494 -0
- package/esm/signer.js +452 -0
- package/esm/structured.js +269 -0
- package/esm/test.js +6 -0
- package/esm/utils.js +28 -0
- package/package.json +28 -0
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.decodeSigInput = decodeSigInput;
|
|
8
|
+
exports.extractPublicKeyFromHeaders = extractPublicKeyFromHeaders;
|
|
9
|
+
exports.send = send;
|
|
10
|
+
exports.toHttpSigner = void 0;
|
|
11
|
+
exports.verify = verify;
|
|
12
|
+
var _base64url = _interopRequireDefault(require("base64url"));
|
|
13
|
+
var _crypto = _interopRequireDefault(require("crypto"));
|
|
14
|
+
var _index = require("./http-message-signatures/index.js");
|
|
15
|
+
var _structuredHeaders = require("structured-headers");
|
|
16
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
17
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
18
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
19
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
20
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
21
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
22
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
23
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
24
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
25
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
26
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
27
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
28
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
29
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
30
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
31
|
+
function _toArray(r) { return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest(); }
|
|
32
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
33
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
34
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
35
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
36
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
37
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
38
|
+
var augmentHeaders = _index.httpbis.augmentHeaders,
|
|
39
|
+
createSignatureBase = _index.httpbis.createSignatureBase,
|
|
40
|
+
createSigningParameters = _index.httpbis.createSigningParameters,
|
|
41
|
+
formatSignatureBase = _index.httpbis.formatSignatureBase;
|
|
42
|
+
var verifyMessage = _index.httpbis.verifyMessage;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Decode signature-input header to extract all components
|
|
46
|
+
* Handles format: signature-name=(components);params
|
|
47
|
+
*
|
|
48
|
+
* @param {string} signatureInput - The signature-input header value
|
|
49
|
+
* @param {string} [signatureName] - Optional specific signature name to decode
|
|
50
|
+
* @returns {Object} Decoded signature input with components and parameters
|
|
51
|
+
*/
|
|
52
|
+
function decodeSigInput(signatureInput) {
|
|
53
|
+
var signatureName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
54
|
+
if (!signatureInput) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
// If signature name is provided, extract just that section
|
|
59
|
+
var inputToDecode = signatureInput;
|
|
60
|
+
if (signatureName) {
|
|
61
|
+
// Find the section for this specific signature
|
|
62
|
+
var startIndex = signatureInput.indexOf(signatureName);
|
|
63
|
+
if (startIndex === -1) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Extract from signature name to the next signature (if any) or end
|
|
68
|
+
var nextSigMatch = signatureInput.substring(startIndex + signatureName.length).match(/,\s*[a-zA-Z0-9-]+=/);
|
|
69
|
+
var endIndex = nextSigMatch ? startIndex + signatureName.length + nextSigMatch.index : signatureInput.length;
|
|
70
|
+
inputToDecode = signatureInput.substring(startIndex, endIndex).trim();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Parse each signature entry
|
|
74
|
+
var signatures = {};
|
|
75
|
+
|
|
76
|
+
// Split by signature entries (handle multiple signatures)
|
|
77
|
+
var entries = inputToDecode.split(/,(?=\s*[a-zA-Z0-9-]+=)/);
|
|
78
|
+
var _iterator = _createForOfIteratorHelper(entries),
|
|
79
|
+
_step;
|
|
80
|
+
try {
|
|
81
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
82
|
+
var entry = _step.value;
|
|
83
|
+
var trimmedEntry = entry.trim();
|
|
84
|
+
|
|
85
|
+
// Match signature-name=(components);params format
|
|
86
|
+
var match = trimmedEntry.match(/^([a-zA-Z0-9-]+)=\(([^)]*)\)(.*)$/);
|
|
87
|
+
if (!match) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
var sigName = match[1];
|
|
91
|
+
var componentsStr = match[2];
|
|
92
|
+
var paramsStr = match[3];
|
|
93
|
+
|
|
94
|
+
// Parse components (space-separated, may be quoted)
|
|
95
|
+
var components = [];
|
|
96
|
+
var componentRegex = /"[^"]+"|[^\s]+/g;
|
|
97
|
+
var componentMatch = void 0;
|
|
98
|
+
while ((componentMatch = componentRegex.exec(componentsStr)) !== null) {
|
|
99
|
+
components.push(componentMatch[0].replace(/"/g, ""));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Parse parameters (semicolon-separated key="value" pairs)
|
|
103
|
+
var params = {};
|
|
104
|
+
if (paramsStr) {
|
|
105
|
+
var paramPairs = paramsStr.split(";").filter(function (p) {
|
|
106
|
+
return p.trim();
|
|
107
|
+
});
|
|
108
|
+
var _iterator2 = _createForOfIteratorHelper(paramPairs),
|
|
109
|
+
_step2;
|
|
110
|
+
try {
|
|
111
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
112
|
+
var pair = _step2.value;
|
|
113
|
+
var _pair$split = pair.split("="),
|
|
114
|
+
_pair$split2 = _toArray(_pair$split),
|
|
115
|
+
key = _pair$split2[0],
|
|
116
|
+
valueParts = _pair$split2.slice(1);
|
|
117
|
+
if (key && valueParts.length > 0) {
|
|
118
|
+
var value = valueParts.join("=").replace(/^"|"$/g, "");
|
|
119
|
+
params[key.trim()] = value;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch (err) {
|
|
123
|
+
_iterator2.e(err);
|
|
124
|
+
} finally {
|
|
125
|
+
_iterator2.f();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
signatures[sigName] = {
|
|
129
|
+
components: components,
|
|
130
|
+
params: params,
|
|
131
|
+
raw: trimmedEntry
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// If specific signature was requested, return just that one
|
|
136
|
+
} catch (err) {
|
|
137
|
+
_iterator.e(err);
|
|
138
|
+
} finally {
|
|
139
|
+
_iterator.f();
|
|
140
|
+
}
|
|
141
|
+
if (signatureName && signatures[signatureName]) {
|
|
142
|
+
return signatures[signatureName];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Return all signatures or the first one if no specific name was given
|
|
146
|
+
return signatureName ? null : signatures;
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error("Error decoding signature-input:", error);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Convert JWK modulus (n) to PEM format public key
|
|
155
|
+
* @param {Buffer} nBuffer - The modulus buffer
|
|
156
|
+
* @returns {string} PEM formatted public key
|
|
157
|
+
*/
|
|
158
|
+
function jwkModulusToPem(nBuffer) {
|
|
159
|
+
// RSA public key with standard exponent
|
|
160
|
+
var rsaPublicKey = _crypto["default"].createPublicKey({
|
|
161
|
+
key: {
|
|
162
|
+
kty: "RSA",
|
|
163
|
+
n: _base64url["default"].encode(nBuffer),
|
|
164
|
+
e: "AQAB" // Standard exponent 65537
|
|
165
|
+
},
|
|
166
|
+
format: "jwk"
|
|
167
|
+
});
|
|
168
|
+
return rsaPublicKey["export"]({
|
|
169
|
+
type: "spki",
|
|
170
|
+
format: "pem"
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Extract signature name from headers
|
|
176
|
+
* @param {Object} headers - Request headers
|
|
177
|
+
* @returns {string|null} Signature name or null
|
|
178
|
+
*/
|
|
179
|
+
function extractSignatureName(headers) {
|
|
180
|
+
var signatureHeader = headers["signature"] || headers["Signature"];
|
|
181
|
+
if (!signatureHeader) return null;
|
|
182
|
+
|
|
183
|
+
// Extract signature name (e.g., "http-sig-xxxxxxxx")
|
|
184
|
+
// Handle both "name:" and "name=" formats
|
|
185
|
+
var match = signatureHeader.match(/^([^:=]+)[:=]/);
|
|
186
|
+
return match ? match[1] : null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Verify an HTTP signed message using http-message-signatures
|
|
191
|
+
*
|
|
192
|
+
* @param {Object} signedMessage - The signed message to verify
|
|
193
|
+
* @param {string} signedMessage.url - Request URL
|
|
194
|
+
* @param {string} signedMessage.method - HTTP method
|
|
195
|
+
* @param {Object} signedMessage.headers - Headers including signature
|
|
196
|
+
* @param {string} [signedMessage.body] - Request body
|
|
197
|
+
* @param {string|Buffer} [publicKey] - Optional public key (if not provided, extracts from keyid)
|
|
198
|
+
* @returns {Object} Verification result
|
|
199
|
+
*/
|
|
200
|
+
function verify(_x, _x2) {
|
|
201
|
+
return _verify.apply(this, arguments);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Extract public key from signature-input header
|
|
205
|
+
* @param {Object} headers - Request headers
|
|
206
|
+
* @param {string} [signatureName] - Optional signature name to look for
|
|
207
|
+
* @returns {Buffer|null} Public key buffer or null
|
|
208
|
+
*/
|
|
209
|
+
function _verify() {
|
|
210
|
+
_verify = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6(signedMessage, publicKey) {
|
|
211
|
+
var _decodedSigInput$para, url, method, headers, body, keyLookup, pem, _signatureName, extractedKey, _pem, _request, signatureName, extractedPublicKey, signatureInputHeader, decodedSigInput, algorithm, verified, verificationError, verificationResult, _t2, _t3;
|
|
212
|
+
return _regenerator().w(function (_context6) {
|
|
213
|
+
while (1) switch (_context6.p = _context6.n) {
|
|
214
|
+
case 0:
|
|
215
|
+
_context6.p = 0;
|
|
216
|
+
url = signedMessage.url, method = signedMessage.method, headers = signedMessage.headers, body = signedMessage.body; // Determine which public key to use
|
|
217
|
+
if (!publicKey) {
|
|
218
|
+
_context6.n = 1;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
// Use provided public key
|
|
222
|
+
pem = typeof publicKey === "string" ? publicKey : jwkModulusToPem(publicKey);
|
|
223
|
+
keyLookup = /*#__PURE__*/function () {
|
|
224
|
+
var _ref5 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(keyId) {
|
|
225
|
+
return _regenerator().w(function (_context3) {
|
|
226
|
+
while (1) switch (_context3.n) {
|
|
227
|
+
case 0:
|
|
228
|
+
return _context3.a(2, {
|
|
229
|
+
id: keyId,
|
|
230
|
+
algs: ["rsa-pss-sha512", "rsa-pss-sha256", "rsa-v1_5-sha256"],
|
|
231
|
+
verify: function () {
|
|
232
|
+
var _verify2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(data, signature, parameters) {
|
|
233
|
+
var verifier;
|
|
234
|
+
return _regenerator().w(function (_context2) {
|
|
235
|
+
while (1) switch (_context2.n) {
|
|
236
|
+
case 0:
|
|
237
|
+
verifier = _crypto["default"].createVerify("RSA-SHA".concat(parameters.alg.includes("512") ? "512" : "256"));
|
|
238
|
+
verifier.update(data);
|
|
239
|
+
if (!parameters.alg.startsWith("rsa-pss")) {
|
|
240
|
+
_context2.n = 1;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
return _context2.a(2, verifier.verify({
|
|
244
|
+
key: pem,
|
|
245
|
+
padding: _crypto["default"].constants.RSA_PKCS1_PSS_PADDING,
|
|
246
|
+
saltLength: _crypto["default"].constants.RSA_PSS_SALTLEN_DIGEST
|
|
247
|
+
}, signature));
|
|
248
|
+
case 1:
|
|
249
|
+
return _context2.a(2, verifier.verify(pem, signature));
|
|
250
|
+
case 2:
|
|
251
|
+
return _context2.a(2);
|
|
252
|
+
}
|
|
253
|
+
}, _callee2);
|
|
254
|
+
}));
|
|
255
|
+
function verify(_x7, _x8, _x9) {
|
|
256
|
+
return _verify2.apply(this, arguments);
|
|
257
|
+
}
|
|
258
|
+
return verify;
|
|
259
|
+
}()
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}, _callee3);
|
|
263
|
+
}));
|
|
264
|
+
return function keyLookup(_x6) {
|
|
265
|
+
return _ref5.apply(this, arguments);
|
|
266
|
+
};
|
|
267
|
+
}();
|
|
268
|
+
_context6.n = 3;
|
|
269
|
+
break;
|
|
270
|
+
case 1:
|
|
271
|
+
// Extract public key from keyid
|
|
272
|
+
_signatureName = extractSignatureName(headers);
|
|
273
|
+
extractedKey = extractPublicKeyFromHeaders(headers, _signatureName);
|
|
274
|
+
if (extractedKey) {
|
|
275
|
+
_context6.n = 2;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
return _context6.a(2, {
|
|
279
|
+
valid: false,
|
|
280
|
+
error: "No public key provided and none found in signature"
|
|
281
|
+
});
|
|
282
|
+
case 2:
|
|
283
|
+
_pem = jwkModulusToPem(extractedKey);
|
|
284
|
+
keyLookup = /*#__PURE__*/function () {
|
|
285
|
+
var _ref6 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(keyId) {
|
|
286
|
+
return _regenerator().w(function (_context5) {
|
|
287
|
+
while (1) switch (_context5.n) {
|
|
288
|
+
case 0:
|
|
289
|
+
return _context5.a(2, {
|
|
290
|
+
id: keyId,
|
|
291
|
+
algs: ["rsa-pss-sha512", "rsa-pss-sha256", "rsa-v1_5-sha256"],
|
|
292
|
+
verify: function () {
|
|
293
|
+
var _verify3 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(data, signature, parameters) {
|
|
294
|
+
var verifier, _verified, _t;
|
|
295
|
+
return _regenerator().w(function (_context4) {
|
|
296
|
+
while (1) switch (_context4.p = _context4.n) {
|
|
297
|
+
case 0:
|
|
298
|
+
_context4.p = 0;
|
|
299
|
+
verifier = _crypto["default"].createVerify("RSA-SHA".concat(parameters.alg.includes("512") ? "512" : "256"));
|
|
300
|
+
verifier.update(data);
|
|
301
|
+
if (parameters.alg.startsWith("rsa-pss")) {
|
|
302
|
+
_verified = verifier.verify({
|
|
303
|
+
key: _pem,
|
|
304
|
+
padding: _crypto["default"].constants.RSA_PKCS1_PSS_PADDING,
|
|
305
|
+
saltLength: _crypto["default"].constants.RSA_PSS_SALTLEN_DIGEST
|
|
306
|
+
}, signature);
|
|
307
|
+
} else {
|
|
308
|
+
_verified = verifier.verify(_pem, signature);
|
|
309
|
+
}
|
|
310
|
+
return _context4.a(2, _verified);
|
|
311
|
+
case 1:
|
|
312
|
+
_context4.p = 1;
|
|
313
|
+
_t = _context4.v;
|
|
314
|
+
console.error("Verification error:", _t);
|
|
315
|
+
return _context4.a(2, false);
|
|
316
|
+
}
|
|
317
|
+
}, _callee4, null, [[0, 1]]);
|
|
318
|
+
}));
|
|
319
|
+
function verify(_x1, _x10, _x11) {
|
|
320
|
+
return _verify3.apply(this, arguments);
|
|
321
|
+
}
|
|
322
|
+
return verify;
|
|
323
|
+
}()
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
}, _callee5);
|
|
327
|
+
}));
|
|
328
|
+
return function keyLookup(_x0) {
|
|
329
|
+
return _ref6.apply(this, arguments);
|
|
330
|
+
};
|
|
331
|
+
}();
|
|
332
|
+
case 3:
|
|
333
|
+
// Create request object for verification
|
|
334
|
+
_request = {
|
|
335
|
+
method: method,
|
|
336
|
+
url: url,
|
|
337
|
+
headers: _objectSpread({}, headers)
|
|
338
|
+
}; // Extract additional info from headers
|
|
339
|
+
signatureName = extractSignatureName(headers);
|
|
340
|
+
extractedPublicKey = extractPublicKeyFromHeaders(headers, signatureName); // Extract algorithm from signature-input
|
|
341
|
+
signatureInputHeader = headers["signature-input"] || headers["Signature-Input"];
|
|
342
|
+
decodedSigInput = decodeSigInput(signatureInputHeader, signatureName);
|
|
343
|
+
algorithm = decodedSigInput === null || decodedSigInput === void 0 || (_decodedSigInput$para = decodedSigInput.params) === null || _decodedSigInput$para === void 0 ? void 0 : _decodedSigInput$para.alg; // Verify using the library
|
|
344
|
+
verified = false;
|
|
345
|
+
verificationError = null;
|
|
346
|
+
_context6.p = 4;
|
|
347
|
+
_context6.n = 5;
|
|
348
|
+
return verifyMessage({
|
|
349
|
+
keyLookup: keyLookup,
|
|
350
|
+
requiredFields: [] // Don't require specific fields
|
|
351
|
+
}, _request);
|
|
352
|
+
case 5:
|
|
353
|
+
verificationResult = _context6.v;
|
|
354
|
+
// If we get here without throwing, verification succeeded
|
|
355
|
+
verified = true;
|
|
356
|
+
_context6.n = 7;
|
|
357
|
+
break;
|
|
358
|
+
case 6:
|
|
359
|
+
_context6.p = 6;
|
|
360
|
+
_t2 = _context6.v;
|
|
361
|
+
// Verification failed
|
|
362
|
+
verificationError = _t2.message;
|
|
363
|
+
verified = false;
|
|
364
|
+
case 7:
|
|
365
|
+
return _context6.a(2, _objectSpread({
|
|
366
|
+
valid: true,
|
|
367
|
+
// The signature format is valid
|
|
368
|
+
verified: verified,
|
|
369
|
+
// Whether the cryptographic verification passed
|
|
370
|
+
signatureName: signatureName,
|
|
371
|
+
keyId: extractedPublicKey ? _base64url["default"].encode(extractedPublicKey) : undefined,
|
|
372
|
+
algorithm: algorithm,
|
|
373
|
+
publicKeyFromHeader: extractedPublicKey,
|
|
374
|
+
decodedSignatureInput: decodedSigInput
|
|
375
|
+
}, verificationError && {
|
|
376
|
+
error: verificationError
|
|
377
|
+
}));
|
|
378
|
+
case 8:
|
|
379
|
+
_context6.p = 8;
|
|
380
|
+
_t3 = _context6.v;
|
|
381
|
+
return _context6.a(2, {
|
|
382
|
+
valid: false,
|
|
383
|
+
error: _t3.message
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}, _callee6, null, [[4, 6], [0, 8]]);
|
|
387
|
+
}));
|
|
388
|
+
return _verify.apply(this, arguments);
|
|
389
|
+
}
|
|
390
|
+
function extractPublicKeyFromHeaders(headers, signatureName) {
|
|
391
|
+
var _Object$values$;
|
|
392
|
+
var signatureInput = headers["signature-input"] || headers["Signature-Input"];
|
|
393
|
+
if (!signatureInput) return null;
|
|
394
|
+
|
|
395
|
+
// Use the decoder to properly parse the signature-input
|
|
396
|
+
var decoded = decodeSigInput(signatureInput, signatureName);
|
|
397
|
+
if (!decoded) return null;
|
|
398
|
+
|
|
399
|
+
// If we decoded a specific signature, use its keyid
|
|
400
|
+
var keyid = signatureName && decoded.params ? decoded.params.keyid : (_Object$values$ = Object.values(decoded)[0]) === null || _Object$values$ === void 0 || (_Object$values$ = _Object$values$.params) === null || _Object$values$ === void 0 ? void 0 : _Object$values$.keyid;
|
|
401
|
+
if (!keyid) return null;
|
|
402
|
+
try {
|
|
403
|
+
return _base64url["default"].toBuffer(keyid);
|
|
404
|
+
} catch (error) {
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Extract public key from a signed message
|
|
411
|
+
*
|
|
412
|
+
* @param {Object} signedMessage - The signed message
|
|
413
|
+
* @returns {Buffer|null} The public key buffer or null
|
|
414
|
+
*/
|
|
415
|
+
function extractPublicKeyFromMessage(signedMessage) {
|
|
416
|
+
var signatureName = extractSignatureName(signedMessage.headers);
|
|
417
|
+
return extractPublicKeyFromHeaders(signedMessage.headers, signatureName);
|
|
418
|
+
}
|
|
419
|
+
function send(_x3) {
|
|
420
|
+
return _send.apply(this, arguments);
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Convert value to Buffer
|
|
424
|
+
*/
|
|
425
|
+
function _send() {
|
|
426
|
+
_send = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(signedMsg) {
|
|
427
|
+
var fetchImpl,
|
|
428
|
+
fetchOptions,
|
|
429
|
+
response,
|
|
430
|
+
_args7 = arguments,
|
|
431
|
+
_t4,
|
|
432
|
+
_t5,
|
|
433
|
+
_t6,
|
|
434
|
+
_t7,
|
|
435
|
+
_t8,
|
|
436
|
+
_t9,
|
|
437
|
+
_t0;
|
|
438
|
+
return _regenerator().w(function (_context7) {
|
|
439
|
+
while (1) switch (_context7.n) {
|
|
440
|
+
case 0:
|
|
441
|
+
fetchImpl = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : fetch;
|
|
442
|
+
fetchOptions = {
|
|
443
|
+
method: signedMsg.method,
|
|
444
|
+
headers: signedMsg.headers,
|
|
445
|
+
redirect: "follow"
|
|
446
|
+
}; // Only add body if it exists and method supports it
|
|
447
|
+
if (signedMsg.body !== undefined && signedMsg.method !== "GET" && signedMsg.method !== "HEAD") {
|
|
448
|
+
fetchOptions.body = signedMsg.body;
|
|
449
|
+
}
|
|
450
|
+
_context7.n = 1;
|
|
451
|
+
return fetchImpl(signedMsg.url, fetchOptions);
|
|
452
|
+
case 1:
|
|
453
|
+
response = _context7.v;
|
|
454
|
+
if (!(response.status >= 400)) {
|
|
455
|
+
_context7.n = 3;
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
458
|
+
_t4 = Error;
|
|
459
|
+
_t5 = "".concat(response.status, ": ");
|
|
460
|
+
_context7.n = 2;
|
|
461
|
+
return response.text();
|
|
462
|
+
case 2:
|
|
463
|
+
_t6 = _context7.v;
|
|
464
|
+
_t7 = _t5.concat.call(_t5, _t6);
|
|
465
|
+
throw new _t4(_t7);
|
|
466
|
+
case 3:
|
|
467
|
+
_t8 = response.headers;
|
|
468
|
+
_context7.n = 4;
|
|
469
|
+
return response.text();
|
|
470
|
+
case 4:
|
|
471
|
+
_t9 = _context7.v;
|
|
472
|
+
_t0 = response.status;
|
|
473
|
+
return _context7.a(2, {
|
|
474
|
+
headers: _t8,
|
|
475
|
+
body: _t9,
|
|
476
|
+
status: _t0
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}, _callee7);
|
|
480
|
+
}));
|
|
481
|
+
return _send.apply(this, arguments);
|
|
482
|
+
}
|
|
483
|
+
var toView = function toView(value) {
|
|
484
|
+
if (ArrayBuffer.isView(value)) {
|
|
485
|
+
return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
|
|
486
|
+
} else if (typeof value === "string") {
|
|
487
|
+
return _base64url["default"].toBuffer(value);
|
|
488
|
+
}
|
|
489
|
+
throw new Error("Value must be Uint8Array, ArrayBuffer, or base64url-encoded string");
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Generate HTTP signature name from address
|
|
494
|
+
*/
|
|
495
|
+
var httpSigName = function httpSigName(address) {
|
|
496
|
+
var decoded = _base64url["default"].toBuffer(address);
|
|
497
|
+
var hexString = _toConsumableArray(decoded.subarray(1, 9)).map(function (_byte) {
|
|
498
|
+
return _byte.toString(16).padStart(2, "0");
|
|
499
|
+
}).join("");
|
|
500
|
+
return "http-sig-".concat(hexString);
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Create HTTP signer wrapper
|
|
505
|
+
*/
|
|
506
|
+
var toHttpSigner = exports.toHttpSigner = function toHttpSigner(signer) {
|
|
507
|
+
var params = ["alg", "keyid"].sort();
|
|
508
|
+
return /*#__PURE__*/function () {
|
|
509
|
+
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(_ref) {
|
|
510
|
+
var request, fields, signatureBase, signatureInput, createCalled, create, result, signatureBuffer, signedHeaders, finalHeaders, _i, _Object$entries, _Object$entries$_i, key, value;
|
|
511
|
+
return _regenerator().w(function (_context) {
|
|
512
|
+
while (1) switch (_context.n) {
|
|
513
|
+
case 0:
|
|
514
|
+
request = _ref.request, fields = _ref.fields;
|
|
515
|
+
createCalled = false;
|
|
516
|
+
create = function create(injected) {
|
|
517
|
+
createCalled = true;
|
|
518
|
+
var publicKey = injected.publicKey,
|
|
519
|
+
_injected$alg = injected.alg,
|
|
520
|
+
alg = _injected$alg === void 0 ? "rsa-pss-sha512" : _injected$alg;
|
|
521
|
+
var publicKeyBuffer = toView(publicKey);
|
|
522
|
+
var signingParameters = createSigningParameters({
|
|
523
|
+
params: params,
|
|
524
|
+
paramValues: {
|
|
525
|
+
keyid: _base64url["default"].encode(publicKeyBuffer),
|
|
526
|
+
alg: alg
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
var signatureBaseArray = createSignatureBase({
|
|
530
|
+
fields: fields
|
|
531
|
+
}, request);
|
|
532
|
+
signatureInput = (0, _structuredHeaders.serializeList)([[signatureBaseArray.map(function (_ref3) {
|
|
533
|
+
var _ref4 = _slicedToArray(_ref3, 1),
|
|
534
|
+
item = _ref4[0];
|
|
535
|
+
return (0, _structuredHeaders.parseItem)(item);
|
|
536
|
+
}), signingParameters]]);
|
|
537
|
+
signatureBaseArray.push(['"@signature-params"', [signatureInput]]);
|
|
538
|
+
signatureBase = formatSignatureBase(signatureBaseArray);
|
|
539
|
+
return new TextEncoder().encode(signatureBase);
|
|
540
|
+
};
|
|
541
|
+
_context.n = 1;
|
|
542
|
+
return signer(create, "httpsig");
|
|
543
|
+
case 1:
|
|
544
|
+
result = _context.v;
|
|
545
|
+
if (createCalled) {
|
|
546
|
+
_context.n = 2;
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
throw new Error("create() must be invoked in order to construct the data to sign");
|
|
550
|
+
case 2:
|
|
551
|
+
if (!(!result.signature || !result.address)) {
|
|
552
|
+
_context.n = 3;
|
|
553
|
+
break;
|
|
554
|
+
}
|
|
555
|
+
throw new Error("Signer must return signature and address");
|
|
556
|
+
case 3:
|
|
557
|
+
signatureBuffer = toView(result.signature);
|
|
558
|
+
signedHeaders = augmentHeaders(request.headers, signatureBuffer, signatureInput, httpSigName(result.address)); // Only lowercase the signature headers
|
|
559
|
+
finalHeaders = {};
|
|
560
|
+
for (_i = 0, _Object$entries = Object.entries(signedHeaders); _i < _Object$entries.length; _i++) {
|
|
561
|
+
_Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), key = _Object$entries$_i[0], value = _Object$entries$_i[1];
|
|
562
|
+
if (key === "Signature" || key === "Signature-Input") {
|
|
563
|
+
finalHeaders[key.toLowerCase()] = value;
|
|
564
|
+
} else {
|
|
565
|
+
finalHeaders[key] = value;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return _context.a(2, _objectSpread(_objectSpread({}, request), {}, {
|
|
569
|
+
headers: finalHeaders
|
|
570
|
+
}));
|
|
571
|
+
}
|
|
572
|
+
}, _callee);
|
|
573
|
+
}));
|
|
574
|
+
return function (_x4) {
|
|
575
|
+
return _ref2.apply(this, arguments);
|
|
576
|
+
};
|
|
577
|
+
}();
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Utility function to extract the message ID from a signed message
|
|
582
|
+
* Based on the original code's hash calculation
|
|
583
|
+
*/
|
|
584
|
+
function getMessageId(_x5) {
|
|
585
|
+
return _getMessageId.apply(this, arguments);
|
|
586
|
+
}
|
|
587
|
+
function _getMessageId() {
|
|
588
|
+
_getMessageId = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8(signedMessage) {
|
|
589
|
+
var signatureHeader, match, signature, encoder, data, hashBuffer, hashArray, hashBase64;
|
|
590
|
+
return _regenerator().w(function (_context8) {
|
|
591
|
+
while (1) switch (_context8.n) {
|
|
592
|
+
case 0:
|
|
593
|
+
// Extract signature from the Signature header
|
|
594
|
+
signatureHeader = signedMessage.headers.Signature || signedMessage.headers.signature;
|
|
595
|
+
match = signatureHeader.match(/Signature:\s*'http-sig-[^:]+:([^']+)'/);
|
|
596
|
+
signature = match ? match[1] : null;
|
|
597
|
+
if (signature) {
|
|
598
|
+
_context8.n = 1;
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
throw new Error("Could not extract signature from headers");
|
|
602
|
+
case 1:
|
|
603
|
+
// Hash the signature to get message ID
|
|
604
|
+
encoder = new TextEncoder();
|
|
605
|
+
data = encoder.encode(signature);
|
|
606
|
+
_context8.n = 2;
|
|
607
|
+
return _crypto["default"].subtle.digest("SHA-256", data);
|
|
608
|
+
case 2:
|
|
609
|
+
hashBuffer = _context8.v;
|
|
610
|
+
hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
611
|
+
hashBase64 = btoa(String.fromCharCode.apply(String, hashArray));
|
|
612
|
+
return _context8.a(2, hashBase64);
|
|
613
|
+
}
|
|
614
|
+
}, _callee8);
|
|
615
|
+
}));
|
|
616
|
+
return _getMessageId.apply(this, arguments);
|
|
617
|
+
}
|