@interop/http-signature-zcap-verify 12.0.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.
- package/LICENSE +27 -0
- package/README.md +125 -0
- package/dist/baseX.d.ts +15 -0
- package/dist/baseX.d.ts.map +1 -0
- package/dist/baseX.js +19 -0
- package/dist/baseX.js.map +1 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +196 -0
- package/dist/index.js.map +1 -0
- package/package.json +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Copyright (c) 2018-2021, Digital Bazaar, Inc.
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
8
|
+
list of conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
11
|
+
this list of conditions and the following disclaimer in the documentation
|
|
12
|
+
and/or other materials provided with the distribution.
|
|
13
|
+
|
|
14
|
+
* Neither the name of http-signature-zcap-verify nor the names of its
|
|
15
|
+
contributors may be used to endorse or promote products derived from
|
|
16
|
+
this software without specific prior written permission.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
22
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
23
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
25
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
26
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# http-signature-zcap-verify _(@interop/http-signature-zcap-verify)_
|
|
2
|
+
|
|
3
|
+
A library for verifying Authorization Capability (ZCAP) invocations via HTTP
|
|
4
|
+
signatures.
|
|
5
|
+
|
|
6
|
+
It is the verifier counterpart to
|
|
7
|
+
[`@interop/http-signature-zcap-invoke`](https://github.com/interop-alliance/http-signature-zcap-invoke),
|
|
8
|
+
which signs the request. On the server, `verifyCapabilityInvocation` parses the
|
|
9
|
+
HTTP signature headers, verifies the signature, dereferences the invoked
|
|
10
|
+
capability, and validates the capability delegation chain.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
- Browsers, Node.js, and React Native are supported.
|
|
15
|
+
- Written in TypeScript; ships ESM with type declarations.
|
|
16
|
+
|
|
17
|
+
To install from NPM:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
pnpm add @interop/http-signature-zcap-verify
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
`verifyCapabilityInvocation` needs two functions you supply:
|
|
26
|
+
|
|
27
|
+
- **`documentLoader`** -- a JSON-LD document loader that can resolve the
|
|
28
|
+
controller document, the invoked root capability, and any contexts in the
|
|
29
|
+
delegation chain.
|
|
30
|
+
- **`getVerifier`** -- an async function that dereferences a key id to a
|
|
31
|
+
signature verifier and its verification method document.
|
|
32
|
+
|
|
33
|
+
### Setting up the document loader and verifier
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { securityLoader } from '@interop/security-document-loader'
|
|
37
|
+
import { Ed25519VerificationKey } from '@interop/ed25519-verification-key'
|
|
38
|
+
|
|
39
|
+
// Preloaded with the zcap, DID, Multikey, ed25519, and data-integrity contexts.
|
|
40
|
+
const documentLoader = securityLoader().build()
|
|
41
|
+
|
|
42
|
+
async function getVerifier({ keyId, documentLoader }) {
|
|
43
|
+
const { document } = await documentLoader(keyId)
|
|
44
|
+
// `fromKeyDocument` rebuilds the key from the dereferenced verification
|
|
45
|
+
// method and throws if the key has been revoked. It accepts a verification
|
|
46
|
+
// method using either the Multikey or the ed25519-2020 suite context.
|
|
47
|
+
const key = await Ed25519VerificationKey.fromKeyDocument({ document })
|
|
48
|
+
return { verifier: key.verifier(), verificationMethod: document }
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> **Note:** the controller document returned by your `documentLoader` should use
|
|
53
|
+
> the DID v1 context (`https://www.w3.org/ns/did/v1`) and list the invoking key
|
|
54
|
+
> under `capabilityInvocation`. Controllers that use a non-DID context force a
|
|
55
|
+
> framing step against the legacy `https://w3id.org/security/v2` context, which
|
|
56
|
+
> the loader above does not bundle.
|
|
57
|
+
|
|
58
|
+
### Verifying an incoming request
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { verifyCapabilityInvocation } from '@interop/http-signature-zcap-verify'
|
|
62
|
+
import { Ed25519Signature2020 } from '@interop/ed25519-signature'
|
|
63
|
+
|
|
64
|
+
// In an HTTP handler, `req.method`, `req.url`, and `req.headers` come from the
|
|
65
|
+
// incoming request. `expectedTarget` is the absolute URL the capability must
|
|
66
|
+
// apply to; `expectedRootCapability` is the root zcap ID you authorized.
|
|
67
|
+
const result = await verifyCapabilityInvocation({
|
|
68
|
+
url: req.url,
|
|
69
|
+
method: req.method,
|
|
70
|
+
headers: req.headers,
|
|
71
|
+
// verify-mode suite for the delegation chain; no signer needed
|
|
72
|
+
suite: new Ed25519Signature2020(),
|
|
73
|
+
getVerifier,
|
|
74
|
+
documentLoader,
|
|
75
|
+
expectedHost: 'api.example.com',
|
|
76
|
+
expectedAction: 'read',
|
|
77
|
+
expectedTarget: 'https://api.example.com/documents/123',
|
|
78
|
+
expectedRootCapability:
|
|
79
|
+
'urn:zcap:root:' +
|
|
80
|
+
encodeURIComponent('https://api.example.com/documents/123')
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
if (!result.verified) {
|
|
84
|
+
// `result.error` describes why verification failed (bad signature,
|
|
85
|
+
// unexpected host, expired capability, unauthorized key, etc.)
|
|
86
|
+
throw result.error
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// On success, `result` also includes the invoked `capability`,
|
|
90
|
+
// `capabilityAction`, the `controller`/`invoker`, the `verificationMethod`,
|
|
91
|
+
// and the `dereferencedChain`.
|
|
92
|
+
console.log('invoked by', result.controller)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Result
|
|
96
|
+
|
|
97
|
+
`verifyCapabilityInvocation` resolves to an object and does not throw for
|
|
98
|
+
verification failures -- check `result.verified`:
|
|
99
|
+
|
|
100
|
+
- On failure: `{ verified: false, error }`.
|
|
101
|
+
- On success: `{ verified: true, capability, capabilityAction, controller,
|
|
102
|
+
invoker, verificationMethod, dereferencedChain }`.
|
|
103
|
+
|
|
104
|
+
(It does throw a `TypeError` for programmer errors, such as omitting
|
|
105
|
+
`getVerifier`.)
|
|
106
|
+
|
|
107
|
+
### Key options
|
|
108
|
+
|
|
109
|
+
| Option | Description |
|
|
110
|
+
| -------------------------- | ------------------------------------------------------------------------- |
|
|
111
|
+
| `url`, `method`, `headers` | The incoming request. |
|
|
112
|
+
| `getVerifier` | Async function returning `{ verifier, verificationMethod }` for a key id. |
|
|
113
|
+
| `documentLoader` | JSON-LD loader for the controller, root capability, and contexts. |
|
|
114
|
+
| `expectedHost` | The expected `Host` header (string or array of allowed hosts). |
|
|
115
|
+
| `expectedAction` | The capability action the request must invoke (e.g. `'read'`). |
|
|
116
|
+
| `expectedTarget` | The absolute URL the capability must apply to. |
|
|
117
|
+
| `expectedRootCapability` | The authorized root capability ID (string or array). |
|
|
118
|
+
| `suite` | The signature suite(s) used to verify the delegation chain. |
|
|
119
|
+
| `allowTargetAttenuation` | Allow hierarchical RESTful target attenuation (default `false`). |
|
|
120
|
+
| `maxClockSkew` | Allowed clock skew in seconds (default `300`). |
|
|
121
|
+
| `now` | A UNIX timestamp (seconds) or `Date` to verify against (default: now). |
|
|
122
|
+
|
|
123
|
+
See the JSDoc on `verifyCapabilityInvocation` for the full list, including
|
|
124
|
+
`additionalHeaders`, `beforeValidatePurpose`, `inspectCapabilityChain`,
|
|
125
|
+
`maxChainLength`, and `maxDelegationTtl`.
|
package/dist/baseX.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard (RFC 4648) base64 with padding. Used to decode the `signature`
|
|
3
|
+
* parameter from the `Authorization` header, which the signer encodes with
|
|
4
|
+
* padding (`Buffer.toString('base64')` in Node, `btoa`/`toBase64()` in the
|
|
5
|
+
* browser).
|
|
6
|
+
*/
|
|
7
|
+
export declare const base64decode: import("@scure/base").BytesCoder;
|
|
8
|
+
/**
|
|
9
|
+
* RFC 4648 url-safe base64 without padding. Used to decode the gzipped
|
|
10
|
+
* capability from the `capability-invocation` header, which the signer encodes
|
|
11
|
+
* unpadded (`Buffer.toString('base64url')` in Node, `toBase64({ omitPadding:
|
|
12
|
+
* true })` in the browser).
|
|
13
|
+
*/
|
|
14
|
+
export declare const base64url: import("@scure/base").BytesCoder;
|
|
15
|
+
//# sourceMappingURL=baseX.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseX.d.ts","sourceRoot":"","sources":["../src/baseX.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,kCAAS,CAAA;AAElC;;;;;GAKG;AACH,eAAO,MAAM,SAAS,kCAAiB,CAAA"}
|
package/dist/baseX.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2021-2026 Digital Bazaar, Inc. and Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { base64, base64urlnopad } from '@scure/base';
|
|
5
|
+
/**
|
|
6
|
+
* Standard (RFC 4648) base64 with padding. Used to decode the `signature`
|
|
7
|
+
* parameter from the `Authorization` header, which the signer encodes with
|
|
8
|
+
* padding (`Buffer.toString('base64')` in Node, `btoa`/`toBase64()` in the
|
|
9
|
+
* browser).
|
|
10
|
+
*/
|
|
11
|
+
export const base64decode = base64;
|
|
12
|
+
/**
|
|
13
|
+
* RFC 4648 url-safe base64 without padding. Used to decode the gzipped
|
|
14
|
+
* capability from the `capability-invocation` header, which the signer encodes
|
|
15
|
+
* unpadded (`Buffer.toString('base64url')` in Node, `toBase64({ omitPadding:
|
|
16
|
+
* true })` in the browser).
|
|
17
|
+
*/
|
|
18
|
+
export const base64url = base64urlnopad;
|
|
19
|
+
//# sourceMappingURL=baseX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseX.js","sourceRoot":"","sources":["../src/baseX.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAA;AAElC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,cAAc,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { InspectCapabilityChain } from '@interop/zcap';
|
|
2
|
+
/**
|
|
3
|
+
* Verifies an HTTP signature using public key material.
|
|
4
|
+
*/
|
|
5
|
+
export interface Verifier {
|
|
6
|
+
verify(payload: {
|
|
7
|
+
data: Uint8Array;
|
|
8
|
+
signature: Uint8Array;
|
|
9
|
+
}): Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A verification method document, typically dereferenced from the key id.
|
|
13
|
+
*/
|
|
14
|
+
export interface VerificationMethod {
|
|
15
|
+
id?: string;
|
|
16
|
+
controller?: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* An async function that dereferences a key id and returns a verifier and the
|
|
21
|
+
* verification method document for that key.
|
|
22
|
+
*/
|
|
23
|
+
export type GetVerifier = (options: {
|
|
24
|
+
keyId: string;
|
|
25
|
+
documentLoader: DocumentLoader;
|
|
26
|
+
}) => Promise<{
|
|
27
|
+
verifier: Verifier;
|
|
28
|
+
verificationMethod: VerificationMethod;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* A JSON-LD document loader.
|
|
32
|
+
*/
|
|
33
|
+
export type DocumentLoader = (url: string) => Promise<{
|
|
34
|
+
contextUrl?: string | null;
|
|
35
|
+
documentUrl?: string;
|
|
36
|
+
document: unknown;
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* @param options {object} - Options to use.
|
|
40
|
+
* @param options.url {string} - The url of the request.
|
|
41
|
+
* @param options.method {string} - The HTTP request method.
|
|
42
|
+
* @param options.headers {object} - The headers from the request.
|
|
43
|
+
* @param options.getVerifier {GetVerifier} - An async function to
|
|
44
|
+
* call to get a verifier and verification method for the key ID.
|
|
45
|
+
* @param options.documentLoader {DocumentLoader} - A jsonld document loader; it
|
|
46
|
+
* must be able to load the root zcap and any contexts used in the zcap
|
|
47
|
+
* delegation chain.
|
|
48
|
+
* @param options.expectedHost {string|string[]} - The expected host of the
|
|
49
|
+
* request.
|
|
50
|
+
* @param options.expectedAction {string} - The expected action of the zcap.
|
|
51
|
+
* @param options.expectedRootCapability {string|string[]} - The expected root
|
|
52
|
+
* capability of the zcap.
|
|
53
|
+
* @param options.expectedTarget {string} - The expected target of the zcap.
|
|
54
|
+
* @param options.suite {object} - The jsigs signature suite(s) for verifying
|
|
55
|
+
* the capability delegation chain.
|
|
56
|
+
* @param [options.allowTargetAttenuation=false] {boolean} - Allow the
|
|
57
|
+
* invocationTarget of a delegation chain to be increasingly restrictive
|
|
58
|
+
* based on a hierarchical RESTful URL structure.
|
|
59
|
+
* @param [options.additionalHeaders=[]] {string[]} - Additional headers
|
|
60
|
+
* to verify.
|
|
61
|
+
* @param [options.beforeValidatePurpose] {Function} - A function that is
|
|
62
|
+
* called prior to validating the proof purpose and is passed the purpose
|
|
63
|
+
* instance, proof meta data, and capability information.
|
|
64
|
+
* @param [options.inspectCapabilityChain] {Function} - A function that can
|
|
65
|
+
* inspect a capability chain.
|
|
66
|
+
* @param [options.maxChainLength] {number} - The maximum length of the
|
|
67
|
+
* capability delegation chain.
|
|
68
|
+
* @param [options.maxDelegationTtl] {number} - The maximum milliseconds to
|
|
69
|
+
* live for a delegated zcap as measured by the time difference between
|
|
70
|
+
* `expires` and `created` on the delegation proof.
|
|
71
|
+
* @param [options.maxClockSkew=300] {number} - A maximum number of seconds
|
|
72
|
+
* that clocks may be skewed when checking capability expiration date-times
|
|
73
|
+
* against `date`, when comparing invocation proof creation time against
|
|
74
|
+
* delegation proof creation time, and when comparing the capability
|
|
75
|
+
* invocation expiration time against `now`.
|
|
76
|
+
* @param [options.now=now] {number|Date} - A unix timestamp or an
|
|
77
|
+
* instance of Date.
|
|
78
|
+
*/
|
|
79
|
+
export interface VerifyCapabilityInvocationOptions {
|
|
80
|
+
url: string;
|
|
81
|
+
method: string;
|
|
82
|
+
headers: Record<string, string>;
|
|
83
|
+
getVerifier: GetVerifier;
|
|
84
|
+
documentLoader: DocumentLoader;
|
|
85
|
+
expectedHost: string | string[];
|
|
86
|
+
expectedAction: string;
|
|
87
|
+
expectedRootCapability: string | string[];
|
|
88
|
+
expectedTarget: string;
|
|
89
|
+
suite: object;
|
|
90
|
+
allowTargetAttenuation?: boolean;
|
|
91
|
+
additionalHeaders?: string[];
|
|
92
|
+
beforeValidatePurpose?: (params: {
|
|
93
|
+
purpose: unknown;
|
|
94
|
+
proof: unknown;
|
|
95
|
+
capability: unknown;
|
|
96
|
+
capabilityAction: unknown;
|
|
97
|
+
}) => Promise<void> | void;
|
|
98
|
+
inspectCapabilityChain?: InspectCapabilityChain;
|
|
99
|
+
maxChainLength?: number;
|
|
100
|
+
maxClockSkew?: number;
|
|
101
|
+
maxDelegationTtl?: number;
|
|
102
|
+
now?: number | Date;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The result of a capability invocation verification.
|
|
106
|
+
*/
|
|
107
|
+
export interface VerifyCapabilityInvocationResult {
|
|
108
|
+
verified: boolean;
|
|
109
|
+
error?: Error;
|
|
110
|
+
capability?: unknown;
|
|
111
|
+
capabilityAction?: unknown;
|
|
112
|
+
controller?: string;
|
|
113
|
+
dereferencedChain?: unknown;
|
|
114
|
+
invoker?: string;
|
|
115
|
+
verificationMethod?: VerificationMethod;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Verifies a zcap invocation in the form of an http-signature header.
|
|
119
|
+
*
|
|
120
|
+
* @param options {VerifyCapabilityInvocationOptions} - Options to use.
|
|
121
|
+
*
|
|
122
|
+
* @returns {Promise<VerifyCapabilityInvocationResult>} The result of the
|
|
123
|
+
* verification.
|
|
124
|
+
*/
|
|
125
|
+
export declare function verifyCapabilityInvocation({ url, method, headers, getVerifier, documentLoader, expectedHost, expectedAction, expectedRootCapability, expectedTarget, suite, additionalHeaders, allowTargetAttenuation, beforeValidatePurpose, inspectCapabilityChain, maxChainLength, maxClockSkew, maxDelegationTtl, now }: VerifyCapabilityInvocationOptions): Promise<VerifyCapabilityInvocationResult>;
|
|
126
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAQ3D;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,OAAO,EAAE;QACd,IAAI,EAAE,UAAU,CAAA;QAChB,SAAS,EAAE,UAAU,CAAA;KACtB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,cAAc,EAAE,cAAc,CAAA;CAC/B,KAAK,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,kBAAkB,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAAA;AAE7E;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,iCAAiC;IAChD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,WAAW,EAAE,WAAW,CAAA;IACxB,cAAc,EAAE,cAAc,CAAA;IAC9B,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAC/B,cAAc,EAAE,MAAM,CAAA;IACtB,sBAAsB,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACzC,cAAc,EAAE,MAAM,CAAA;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,sBAAsB,CAAC,EAAE,OAAO,CAAA;IAChC,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC5B,qBAAqB,CAAC,EAAE,CAAC,MAAM,EAAE;QAC/B,OAAO,EAAE,OAAO,CAAA;QAChB,KAAK,EAAE,OAAO,CAAA;QACd,UAAU,EAAE,OAAO,CAAA;QACnB,gBAAgB,EAAE,OAAO,CAAA;KAC1B,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC1B,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;CACxC;AAUD;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAAC,EAC/C,GAAG,EACH,MAAM,EACN,OAAO,EACP,WAAW,EACX,cAAc,EACd,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,KAAK,EACL,iBAAsB,EACtB,sBAA8B,EAC9B,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,YAAkB,EAClB,gBAAgB,EAChB,GAAmC,EACpC,EAAE,iCAAiC,GAAG,OAAO,CAAC,gCAAgC,CAAC,CA2M/E"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2021-2026 Digital Bazaar, Inc. and Interop Alliance. All rights reserved.
|
|
3
|
+
*/
|
|
4
|
+
import { CapabilityInvocation, constants } from '@interop/zcap';
|
|
5
|
+
import { parseRequest, parseSignatureHeader } from '@interop/http-signature-header';
|
|
6
|
+
import { base64decode, base64url } from './baseX.js';
|
|
7
|
+
import pako from 'pako';
|
|
8
|
+
/**
|
|
9
|
+
* Verifies a zcap invocation in the form of an http-signature header.
|
|
10
|
+
*
|
|
11
|
+
* @param options {VerifyCapabilityInvocationOptions} - Options to use.
|
|
12
|
+
*
|
|
13
|
+
* @returns {Promise<VerifyCapabilityInvocationResult>} The result of the
|
|
14
|
+
* verification.
|
|
15
|
+
*/
|
|
16
|
+
export async function verifyCapabilityInvocation({ url, method, headers, getVerifier, documentLoader, expectedHost, expectedAction, expectedRootCapability, expectedTarget, suite, additionalHeaders = [], allowTargetAttenuation = false, beforeValidatePurpose, inspectCapabilityChain, maxChainLength, maxClockSkew = 300, maxDelegationTtl, now = Math.floor(Date.now() / 1000) }) {
|
|
17
|
+
if (now instanceof Date) {
|
|
18
|
+
now = Math.floor(now.getTime() / 1000);
|
|
19
|
+
}
|
|
20
|
+
if (!getVerifier) {
|
|
21
|
+
throw new TypeError('"getVerifier" must be given to dereference the key for verifying ' +
|
|
22
|
+
'the capability invocation signature.');
|
|
23
|
+
}
|
|
24
|
+
if (beforeValidatePurpose && typeof beforeValidatePurpose !== 'function') {
|
|
25
|
+
throw new TypeError('"beforeValidatePurpose" must be a function.');
|
|
26
|
+
}
|
|
27
|
+
// parse http header for signature
|
|
28
|
+
const expectedHeaders = [
|
|
29
|
+
'(key-id)',
|
|
30
|
+
'(created)',
|
|
31
|
+
'(expires)',
|
|
32
|
+
'(request-target)',
|
|
33
|
+
'host',
|
|
34
|
+
'capability-invocation'
|
|
35
|
+
];
|
|
36
|
+
const reqHeaders = _lowerCaseObjectKeys(headers);
|
|
37
|
+
if (reqHeaders['content-type']) {
|
|
38
|
+
additionalHeaders.push('content-type');
|
|
39
|
+
additionalHeaders.push('digest');
|
|
40
|
+
}
|
|
41
|
+
expectedHeaders.push(...additionalHeaders);
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
// `now` will be used to check against the expiry on the signature using
|
|
45
|
+
// a clock skew of 5 minutes
|
|
46
|
+
parsed = parseRequest({ url, method, headers }, {
|
|
47
|
+
headers: expectedHeaders,
|
|
48
|
+
clockSkew: maxClockSkew,
|
|
49
|
+
now
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return { verified: false, error: error };
|
|
54
|
+
}
|
|
55
|
+
// verify that `host` matches server host
|
|
56
|
+
if (!Array.isArray(expectedHost)) {
|
|
57
|
+
expectedHost = [expectedHost];
|
|
58
|
+
}
|
|
59
|
+
const { host } = reqHeaders;
|
|
60
|
+
if (!expectedHost.includes(host)) {
|
|
61
|
+
const error = new Error('Host header contains an unexpected host name.');
|
|
62
|
+
error.name = 'NotAllowedError';
|
|
63
|
+
error.host = host;
|
|
64
|
+
error.expectedHost = expectedHost;
|
|
65
|
+
return { verified: false, error };
|
|
66
|
+
}
|
|
67
|
+
/* Note: The order in which we run these checks can introduce side channels
|
|
68
|
+
that leak information (e.g., timing). However, we are not presently concerned
|
|
69
|
+
about leaking information about existing capabilities as such leaks do not
|
|
70
|
+
pose any security risk -- and any privacy correlation risk is low if the
|
|
71
|
+
capability identifiers are infeasible to guess. */
|
|
72
|
+
// get parsed parameters from HTTP header and generate signing string
|
|
73
|
+
const { keyId, signingString, params: { created, signature: b64Signature } } = parsed;
|
|
74
|
+
// verify HTTP signature
|
|
75
|
+
const { verifier, verificationMethod } = await getVerifier({
|
|
76
|
+
keyId,
|
|
77
|
+
documentLoader
|
|
78
|
+
});
|
|
79
|
+
const encoder = new TextEncoder();
|
|
80
|
+
const data = encoder.encode(signingString);
|
|
81
|
+
const signature = base64decode.decode(b64Signature);
|
|
82
|
+
const verified = await verifier.verify({ data, signature });
|
|
83
|
+
if (!verified) {
|
|
84
|
+
const error = new Error('Signature not verified.');
|
|
85
|
+
error.name = 'DataError';
|
|
86
|
+
return { verified: false, error };
|
|
87
|
+
}
|
|
88
|
+
// always dereference the invoked capability to ensure that the system can
|
|
89
|
+
// dereference it authoritatively (which may include ensuring that it is
|
|
90
|
+
// saved in an authorized list, etc.)
|
|
91
|
+
const invocationHeader = reqHeaders['capability-invocation'];
|
|
92
|
+
const parsedInvocationHeader = parseSignatureHeader(invocationHeader);
|
|
93
|
+
if (parsedInvocationHeader.scheme !== 'zcap') {
|
|
94
|
+
const error = new Error('Capability invocation scheme must be "zcap".');
|
|
95
|
+
error.name = 'DataError';
|
|
96
|
+
return { verified: false, error };
|
|
97
|
+
}
|
|
98
|
+
let capability = parsedInvocationHeader.params.id;
|
|
99
|
+
if (!capability) {
|
|
100
|
+
capability = parsedInvocationHeader.params.capability;
|
|
101
|
+
if (capability) {
|
|
102
|
+
try {
|
|
103
|
+
capability = JSON.parse(new TextDecoder('utf-8').decode(pako.ungzip(base64url.decode(capability))));
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
const error = new Error('Capability in Capability-Invocation header is improperly encoded.');
|
|
107
|
+
error.name = 'DataError';
|
|
108
|
+
return { verified: false, error };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!capability.parentCapability) {
|
|
112
|
+
const error = new Error('A root capability must be invoked using only its ID.');
|
|
113
|
+
error.name = 'DataError';
|
|
114
|
+
return { verified: false, error };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (!capability) {
|
|
118
|
+
const error = new Error('Capability not present in Capability-Invocation header.');
|
|
119
|
+
error.name = 'DataError';
|
|
120
|
+
return { verified: false, error };
|
|
121
|
+
}
|
|
122
|
+
// check capability invocation
|
|
123
|
+
const purpose = new CapabilityInvocation({
|
|
124
|
+
allowTargetAttenuation,
|
|
125
|
+
// `date` is in milliseconds and `now` is in seconds, so convert
|
|
126
|
+
date: now * 1000,
|
|
127
|
+
expectedAction,
|
|
128
|
+
expectedRootCapability,
|
|
129
|
+
expectedTarget,
|
|
130
|
+
inspectCapabilityChain,
|
|
131
|
+
maxChainLength,
|
|
132
|
+
maxClockSkew,
|
|
133
|
+
maxDelegationTtl,
|
|
134
|
+
suite
|
|
135
|
+
});
|
|
136
|
+
// invocation target must match absolute url
|
|
137
|
+
let invocationTarget;
|
|
138
|
+
// do not simply check for a colon (`:`) to find a relative URL
|
|
139
|
+
// because some applications allow and pass non-conformant
|
|
140
|
+
// relative URLs with unencoded colons (and we accept those
|
|
141
|
+
// because it is common to do so despite non-conformance)
|
|
142
|
+
if (url.startsWith('https://') || url.startsWith('http://')) {
|
|
143
|
+
invocationTarget = url;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// If encountering a relative URL, assume HTTPS
|
|
147
|
+
invocationTarget = `https://${headers.host}${url}`;
|
|
148
|
+
}
|
|
149
|
+
const capabilityAction = parsedInvocationHeader.params.action;
|
|
150
|
+
const proof = {
|
|
151
|
+
'@context': constants.ZCAP_CONTEXT_URL,
|
|
152
|
+
capability,
|
|
153
|
+
capabilityAction,
|
|
154
|
+
// use second precision for created date
|
|
155
|
+
created: new Date(Number(created) * 1000).toISOString().slice(0, -5) + 'Z',
|
|
156
|
+
invocationTarget,
|
|
157
|
+
verificationMethod: keyId
|
|
158
|
+
};
|
|
159
|
+
if (beforeValidatePurpose) {
|
|
160
|
+
await beforeValidatePurpose({
|
|
161
|
+
purpose,
|
|
162
|
+
proof,
|
|
163
|
+
capability,
|
|
164
|
+
capabilityAction
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const result = await purpose.validate(proof, {
|
|
168
|
+
verificationMethod,
|
|
169
|
+
documentLoader
|
|
170
|
+
});
|
|
171
|
+
const { valid, error } = result;
|
|
172
|
+
// `dereferencedChain` is attached internally on success but is not part of
|
|
173
|
+
// the public `ProofValidateResult` type.
|
|
174
|
+
const { dereferencedChain } = result;
|
|
175
|
+
if (!valid) {
|
|
176
|
+
return { verified: false, error };
|
|
177
|
+
}
|
|
178
|
+
const controller = verificationMethod.controller || verificationMethod.id;
|
|
179
|
+
return {
|
|
180
|
+
capability,
|
|
181
|
+
capabilityAction,
|
|
182
|
+
controller,
|
|
183
|
+
dereferencedChain,
|
|
184
|
+
invoker: controller,
|
|
185
|
+
verificationMethod,
|
|
186
|
+
verified: true
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function _lowerCaseObjectKeys(obj) {
|
|
190
|
+
const newObject = {};
|
|
191
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
192
|
+
newObject[key.toLowerCase()] = value;
|
|
193
|
+
}
|
|
194
|
+
return newObject;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@interop/http-signature-zcap-verify",
|
|
3
|
+
"description": "A library for invoking Authorization Capabilities via HTTP signatures",
|
|
4
|
+
"version": "12.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "pnpm run clear && tsc",
|
|
8
|
+
"clear": "rimraf dist/*",
|
|
9
|
+
"dev": "vite",
|
|
10
|
+
"fix": "eslint --fix src test && pnpm run format",
|
|
11
|
+
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
12
|
+
"lint": "eslint src test",
|
|
13
|
+
"prepare": "pnpm run build",
|
|
14
|
+
"rebuild": "pnpm run clear && pnpm run build",
|
|
15
|
+
"test": "pnpm run lint && pnpm run test-node && pnpm run test-browser",
|
|
16
|
+
"test-browser": "playwright test",
|
|
17
|
+
"test-node": "vitest run",
|
|
18
|
+
"test-coverage": "vitest run --coverage"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"react-native": "./dist/index.js",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"module": "dist/index.js",
|
|
33
|
+
"browser": "dist/index.js",
|
|
34
|
+
"types": "dist/index.d.ts",
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@interop/http-signature-header": "^5.0.2",
|
|
38
|
+
"@interop/zcap": "^10.1.0",
|
|
39
|
+
"@scure/base": "^2.2.0",
|
|
40
|
+
"pako": "^2.0.4"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@eslint/js": "^10.0.1",
|
|
44
|
+
"@interop/ed25519-signature": "^7.0.0",
|
|
45
|
+
"@interop/ed25519-verification-key": "^7.0.1",
|
|
46
|
+
"@interop/http-signature-zcap-invoke": "^6.2.0",
|
|
47
|
+
"@interop/security-document-loader": "^9.2.0",
|
|
48
|
+
"@playwright/test": "^1.60.0",
|
|
49
|
+
"@types/node": "^25.9.1",
|
|
50
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
51
|
+
"eslint": "^10.4.0",
|
|
52
|
+
"eslint-config-prettier": "^10.1.8",
|
|
53
|
+
"globals": "^17.6.0",
|
|
54
|
+
"prettier": "^3.8.3",
|
|
55
|
+
"rimraf": "^6.1.3",
|
|
56
|
+
"typescript": "^5.5.0",
|
|
57
|
+
"typescript-eslint": "^8.59.4",
|
|
58
|
+
"vite": "^8.0.14",
|
|
59
|
+
"vitest": "^4.1.7"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
},
|
|
64
|
+
"keywords": [
|
|
65
|
+
"authorization",
|
|
66
|
+
"capability",
|
|
67
|
+
"authorization capability",
|
|
68
|
+
"object capability",
|
|
69
|
+
"ocap-ld",
|
|
70
|
+
"http signature",
|
|
71
|
+
"http signatures",
|
|
72
|
+
"zcap",
|
|
73
|
+
"zcaps"
|
|
74
|
+
],
|
|
75
|
+
"packageManager": "pnpm@11.3.0",
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=24.0"
|
|
78
|
+
},
|
|
79
|
+
"author": {
|
|
80
|
+
"name": "Interop Alliance",
|
|
81
|
+
"url": "https://github.com/interop-alliance/"
|
|
82
|
+
},
|
|
83
|
+
"license": "BSD-3-Clause",
|
|
84
|
+
"repository": {
|
|
85
|
+
"type": "git",
|
|
86
|
+
"url": "git+https://github.com/interop-alliance/http-signature-zcap-verify.git"
|
|
87
|
+
},
|
|
88
|
+
"homepage": "https://github.com/interop-alliance/http-signature-zcap-verify",
|
|
89
|
+
"bugs": "https://github.com/interop-alliance/http-signature-zcap-verify/issues"
|
|
90
|
+
}
|