Last commit july 5th

This commit is contained in:
2024-07-05 13:46:23 +02:00
parent dad0d86e8c
commit b0e4dfbb76
24982 changed files with 2621219 additions and 413 deletions

202
spa/node_modules/sigstore/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 The Sigstore Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

282
spa/node_modules/sigstore/README.md generated vendored Normal file
View File

@@ -0,0 +1,282 @@
# sigstore · [![npm version](https://img.shields.io/npm/v/sigstore.svg?style=flat)](https://www.npmjs.com/package/sigstore) [![CI Status](https://github.com/sigstore/sigstore-js/workflows/CI/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/ci.yml) [![Smoke Test Status](https://github.com/sigstore/sigstore-js/workflows/smoke-test/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/smoke-test.yml)
A JavaScript library for generating and verifying Sigstore signatures. One of
the intended uses is to sign and verify npm packages but it can be used to sign
and verify any file.
## Features
* Support for signing using an OpenID Connect identity
* Support for publishing signatures to a [Rekor][1] instance
* Support for verifying Sigstore bundles
## Prerequisites
- Node.js version >= 14.17.0
## Installation
```
npm install sigstore
```
## Compatibility
The following table documents which combinations of Sigstore bundle versions
and Rekor types can be verified by different versions of the `sigstore`
library. It also lists which `sigstore` versions were shipped with different
`npm` CLI versions.
<table>
<thead>
<tr>
<th colspan=2><code>sigstore</code></th>
<th>1.0</th>
<th>1.1</th>
<th>1.2</th>
<th>1.3</th>
<th>1.4</th>
<th>1.5</th>
<th>1.6</th>
<th>1.7</th>
<th>1.8</th>
</tr>
<tr>
<th colspan=2><code>npm</code></th>
<th>9.5.0</th>
<th>9.6.2</th>
<th>9.6.3</th>
<th>9.6.5</th>
<th>9.6.6</th>
<th>9.6.7</th>
<th>9.7.2</th>
<th>9.8.0</th>
<th></th>
</tr>
<tr>
<th>Bundle Version</th>
<th>Rekor Type</th>
<th colspan=9></th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan=3>0.1</td>
<td>hashedrekord</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
</tr>
<tr>
<td>intoto</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
</tr>
<tr>
<td>dsse</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
</tr>
<tr>
<td rowspan=3>0.2</td>
<td>hashedrekord</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
</tr>
<tr>
<td>intoto</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
</tr>
<tr>
<td>dsse</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:x:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
<td>:white_check_mark:</td>
</tr>
</tbody>
</table>
## Usage
```javascript
const { sigstore } = require('sigstore')
```
```javascript
import { sigstore } from 'sigstore'
```
### sign(payload[, options])
Generates a Sigstore signature for the supplied payload. Returns a
[Sigstore bundle][2] containing the signature and the verification material
necessary to verify the signature.
* `payload` `<Buffer>`: The bytes of the artifact to be signed.
* `options` `<Object>`
* `fulcioURL` `<string>`: The base URL of the Fulcio instance to use for retrieving the signing certificate. Defaults to `'https://fulcio.sigstore.dev'`.
* `rekorURL` `<string>`: The base URL of the Rekor instance to use when adding the signature to the transparency log. Defaults to `'https://rekor.sigstore.dev'`.
* `tsaServerURL` `<string>`: The base URL of the Timestamp Authority instance to use when requesting a signed timestamp. If omitted, no timestamp will be requested.
* `tlogUpload` `<boolean>`: Flag indicating whether or not the signature should be recorded on the Rekor transparency log. Defaults to `true`.
* `identityToken` `<string>`: The OIDC token identifying the signer. If no explicit token is supplied, an attempt will be made to retrieve one from the environment. This config cannot be used with `identityProvider`.
* `identityProvider` `<IdentityProvider>`: Object which implements `getToken: () => Promise<string>`. The supplied provider will be used to retrieve an OIDC token. If no provider is supplied, an attempt will be made to retrieve an OIDC token from the environment. This config cannot be used with `identityToken`.
### attest(payload, payloadType[, options])
Generates a Sigstore signature for the supplied in-toto statement. Returns a
[Sigstore bundle][2] containing the [DSSE][3]-wrapped statement and signature
as well as the verification material necessary to verify the signature.
* `payload` `<Buffer>`: The bytes of the statement to be signed.
* `payloadType` `<string>`: MIME or content type describing the statement to be signed.
* `options` `<Object>`
* `fulcioURL` `<string>`: The base URL of the Fulcio instance to use for retrieving the signing certificate. Defaults to `'https://fulcio.sigstore.dev'`.
* `rekorURL` `<string>`: The base URL of the Rekor instance to use when adding the signature to the transparency log. Defaults to `'https://rekor.sigstore.dev'`.
* `tsaServerURL` `<string>`: The base URL of the Timestamp Authority instance to use when requesting a signed timestamp. If omitted, no timestamp will be requested.
* `tlogUpload` `<boolean>`: Flag indicating whether or not the signed statement should be recorded on the Rekor transparency log. Defaults to `true`.
* `identityToken` `<string>`: The OIDC token identifying the signer. If no explicit token is supplied, an attempt will be made to retrieve one from the environment. This config cannot be used with `identityProvider`.
* `identityProvider` `<IdentityProvider>`: Object which implements `getToken: () => Promise<string>`. The supplied provider will be used to retrieve an OIDC token. If no provider is supplied, an attempt will be made to retrieve an OIDC token from the environment. This config cannot be used with `identityToken`.
### verify(bundle[, payload][, options])
Verifies the signature in the supplied bundle.
* `bundle` `<Bundle>`: The Sigstore bundle containing the signature to be verified and the verification material necessary to verify the signature.
* `payload` `<Buffer>`: The bytes of the artifact over which the signature was created. Only necessary when the `sign` function was used to generate the signature since the Bundle does not contain any information about the artifact which was signed. Not required when the `attest` function was used to generate the Bundle.
* `options` `<Object>`
* `ctLogThreshold` `<number>`: The number of certificate transparency logs on which the signing certificate must appear. Defaults to `1`.
* `tlogThreshold` `<number>`: The number of transparency logs on which the signature must appear. Defaults to `1`.
* `certificateIssuer` `<string>`: Value that must appear in the signing certificate's issuer extension (OID 1.3.6.1.4.1.57264.1.1). Not verified if no value is supplied.
* `certificateIdentityEmail` `<string>`: Email address which must appear in the signing certificate's Subject Alternative Name (SAN) extension. Must be specified in conjunction with the `certificateIssuer` option. Takes precedence over the `certificateIdentityURI` option. Not verified if no value is supplied.
* `certificateIdentityURI` `<string>`: URI which must appear in the signing certificate's Subject Alternative Name (SAN) extension. Must be specified in conjunction with the `certificateIssuer` option. Ignored if the `certificateIdentityEmail` option is set. Not verified if no value is supplied.
* `certificateOIDs` `<Object>`: A collection of OID/value pairs which must be present in the certificate's extension list. Not verified if no value is supplied.
* `keySelector` `<Function>`: Callback invoked to retrieve the public key (as either `string` or `Buffer`) necessary to verify the bundle signature. Not used when the signature was generated from a Fulcio-issued signing certificate.
* `hint` `<String>`: The hint from the bundle used to identify the the signing key.
### tuf
The `tuf` object contains utility function for working with the Sigstore TUF repository.
#### client([options])
Returns a TUF client which can be used to retrieve targets from the Sigstore TUF repository.
* `options` `<Object>`
* `tufMirrorURL` `<string>`: Base URL for the Sigstore TUF repository. Defaults to `'https://tuf-repo-cdn.sigstore.dev'`
* `tufRootPath` `<string>`: Path to the initial trusted root for the TUF repository. Defaults to the embedded root.
* `tufCachePath` `<string>`: Absolute path to the directory to be used for caching downloaded TUF metadata and targets. Defaults to a directory named "sigstore-js" within the platform-specific application data directory.
The returned object exposes a `getTarget(path)` function which returns the
contents of the target at the specified path in the Sigstore TUF repository.
#### getTarget(path[, options]) (deprecated)
Returns the contents of the target at the specified path in the Sigstore TUF repository.
This method has been deprecated and will be removed in the next major version.
You should use the TUF `client` function to retrieve a stateful TUF client and
then call `getTarget` against that object. This will avoid re-initializing the
internal TUF state between requests.
* `path` `<string>`: The [path-relative-url string](https://url.spec.whatwg.org/#path-relative-url-string) that uniquely identifies the target within the Sigstore TUF repository.
* `options` `<Object>`
* `tufMirrorURL` `<string>`: Base URL for the Sigstore TUF repository. Defaults to `'https://tuf-repo-cdn.sigstore.dev'`
* `tufRootPath` `<string>`: Path to the initial trusted root for the TUF repository. Defaults to the embedded root.
* `tufCachePath` `<string>`: Absolute path to the directory to be used for caching downloaded TUF metadata and targets. Defaults to a directory named "sigstore-js" within the platform-specific application data directory.
### utils
The `utils` object contains a few internal utility functions. These are exposed
to support the needs of specific `sigstore-js` consumers but should **NOT** be
considered part of the stable public interface.
## CLI
The `sigstore-js` library comes packaged with a basic command line interface
for testing and demo purposes. However, the CLI should **NOT** be considered
part of the stable interface of the library. If you require a production-ready
Sigstore CLI, we recommend you use [`cosign`][4].
```shell
$ npx sigstore help
sigstore <command> <artifact>
Usage:
sigstore sign sign an artifact
sigstore attest sign an artifact using dsse (Dead Simple Signing Envelope)
sigstore verify verify an artifact
sigstore version print version information
sigstore help print help information
```
## Credential Sources
### GitHub Actions
If sigstore-js detects that it is being executed on GitHub Actions, it will use `ACTIONS_ID_TOKEN_REQUEST_URL`
and `ACTIONS_ID_TOKEN_REQUEST_TOKEN` environment variables to request an OIDC token with the correct scope.
Note: the `id_token: write` permission must be granted to the GitHub Action Job.
See https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
for more details.
### Environment Variables
If the `SIGSTORE_ID_TOKEN` environment variable is set, it will use this to authenticate to Fulcio.
It is the callers responsibility to make sure that this token has the correct scopes.
### Interactive Flow
If sigstore-js cannot detect ambient credentials, then it will prompt the user to go through the
interactive flow.
[1]: https://github.com/sigstore/rekor
[2]: https://github.com/sigstore/protobuf-specs/blob/9b722b68a717778ba4f11543afa4ef93205ab502/protos/sigstore_bundle.proto#L63-L84
[3]: https://github.com/secure-systems-lab/dsse
[4]: https://github.com/sigstore/cosign

17
spa/node_modules/sigstore/bin/sigstore.js generated vendored Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env node
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
require('../dist/cli').processArgv();

4
spa/node_modules/sigstore/dist/ca/verify/chain.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
import * as sigstore from '../../types/sigstore';
import { x509Certificate } from '../../x509/cert';
import type { X509Certificate } from '@sigstore/bundle';
export declare function verifyChain(certificate: X509Certificate, certificateAuthorities: sigstore.CertificateAuthority[]): x509Certificate[];

63
spa/node_modules/sigstore/dist/ca/verify/chain.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyChain = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../../error");
const cert_1 = require("../../x509/cert");
const verify_1 = require("../../x509/verify");
function verifyChain(certificate, certificateAuthorities) {
const untrustedCert = cert_1.x509Certificate.parse(certificate.rawBytes);
// Filter the list of certificate authorities to those which are valid for the
// signing certificate's notBefore date.
const validCAs = filterCertificateAuthorities(certificateAuthorities, untrustedCert.notBefore);
if (validCAs.length === 0) {
throw new error_1.VerificationError('No valid certificate authorities');
}
let trustedChain = [];
// Loop through all valid CAs and attempt to verify the certificate chain
const verified = validCAs.find((ca) => {
const trustedCerts = parseCerts(ca.certChain?.certificates || []);
try {
trustedChain = (0, verify_1.verifyCertificateChain)({
untrustedCert,
trustedCerts,
validAt: untrustedCert.notBefore,
});
return true;
}
catch (e) {
return false;
}
});
if (!verified) {
throw new error_1.VerificationError('No valid certificate chain');
}
return trustedChain;
}
exports.verifyChain = verifyChain;
// Filter the list of certificate authorities to those which are valid for the
// given date.
function filterCertificateAuthorities(certificateAuthorities, validAt) {
return certificateAuthorities.filter((ca) => ca.validFor &&
ca.validFor.start &&
ca.validFor.start <= validAt &&
(!ca.validFor.end || validAt <= ca.validFor.end));
}
// Parse the raw bytes of a certificate into an x509Certificate object.
function parseCerts(certs) {
return certs.map((cert) => cert_1.x509Certificate.parse(cert.rawBytes));
}

3
spa/node_modules/sigstore/dist/ca/verify/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import * as sigstore from '../../types/sigstore';
import type { BundleWithCertificateChain } from '@sigstore/bundle';
export declare function verifySigningCertificate(bundle: BundleWithCertificateChain, trustedRoot: sigstore.TrustedRoot, options: sigstore.CAArtifactVerificationOptions): void;

22
spa/node_modules/sigstore/dist/ca/verify/index.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifySigningCertificate = void 0;
const chain_1 = require("./chain");
const sct_1 = require("./sct");
const signer_1 = require("./signer");
function verifySigningCertificate(bundle, trustedRoot, options) {
// Check that a trusted certificate chain can be found for the signing
// certificate in the bundle. Only the first certificate in the bundle's
// chain is used -- everything else must come from the trusted root.
const trustedChain = (0, chain_1.verifyChain)(bundle.verificationMaterial.content.x509CertificateChain.certificates[0], trustedRoot.certificateAuthorities);
// Unless disabled, verify the SCTs in the signing certificate
if (options.ctlogOptions.disable === false) {
(0, sct_1.verifySCTs)(trustedChain, trustedRoot.ctlogs, options.ctlogOptions);
}
// Verify the signing certificate against the provided identities
// if provided
if (options.signers) {
(0, signer_1.verifySignerIdentity)(trustedChain[0], options.signers.certificateIdentities);
}
}
exports.verifySigningCertificate = verifySigningCertificate;

3
spa/node_modules/sigstore/dist/ca/verify/sct.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import * as sigstore from '../../types/sigstore';
import { x509Certificate } from '../../x509/cert';
export declare function verifySCTs(certificateChain: x509Certificate[], ctLogs: sigstore.TransparencyLogInstance[], options: sigstore.ArtifactVerificationOptions_CtlogOptions): void;

30
spa/node_modules/sigstore/dist/ca/verify/sct.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifySCTs = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../../error");
function verifySCTs(certificateChain, ctLogs, options) {
const signingCert = certificateChain[0];
const issuerCert = certificateChain[1];
const sctResults = signingCert.verifySCTs(issuerCert, ctLogs);
// Count the number of verified SCTs which were found
const verifiedSCTCount = sctResults.filter((sct) => sct.verified).length;
if (verifiedSCTCount < options.threshold) {
throw new error_1.VerificationError(`Not enough SCTs verified (found ${verifiedSCTCount}, need ${options.threshold})`);
}
}
exports.verifySCTs = verifySCTs;

3
spa/node_modules/sigstore/dist/ca/verify/signer.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import * as sigstore from '../../types/sigstore';
import { x509Certificate } from '../../x509/cert';
export declare function verifySignerIdentity(signingCert: x509Certificate, identities: sigstore.CertificateIdentities): void;

143
spa/node_modules/sigstore/dist/ca/verify/signer.js generated vendored Normal file
View File

@@ -0,0 +1,143 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifySignerIdentity = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../../error");
const sigstore = __importStar(require("../../types/sigstore"));
// https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#1361415726411--issuer
const OID_FULCIO_ISSUER = '1.3.6.1.4.1.57264.1.1';
// https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#1361415726417--othername-san
const OID_FULCIO_USERNAME_SUBJECT = '1.3.6.1.4.1.57264.1.7';
// Verifies the identity embedded in a Fulcio-issued signing certificate against
// the list of trusted identities. Returns without error if at least one of the
// identities matches the signing certificate; otherwise, throws a
// VerificationError.
function verifySignerIdentity(signingCert, identities) {
// Check that the signing certificate was issued to at least one of the
// specified identities
const signerVerified = identities.identities.some((identity) => verifyIdentity(signingCert, identity));
if (!signerVerified) {
throw new error_1.PolicyError('Certificate issued to untrusted signer');
}
}
exports.verifySignerIdentity = verifySignerIdentity;
// Checks that the specified certificate was issued to the specified identity.
// The certificate must match the issuer, subject alternative name, and an
// optional list of certificate extensions. Returns true if the certificate was
// issued to the identity; otherwise, returns false.
function verifyIdentity(cert, identity) {
return (verifyIssuer(cert, identity.issuer) &&
verifySAN(cert, identity.san) &&
verifyOIDs(cert, identity.oids));
}
// Checks the Fulcio issuer extension against the expected issuer. Returns true
// if the issuer matches; otherwise, returns false.
function verifyIssuer(cert, issuer) {
const issuerExtension = cert.extension(OID_FULCIO_ISSUER);
return issuerExtension?.value.toString('ascii') === issuer;
}
// Checks the certificate against the expected subject alternative name. Returns
// true if the SAN matches; otherwise, returns false.
function verifySAN(cert, expectedSAN) {
// Fail if the SAN is not specified or is not a supported type
if (expectedSAN === undefined ||
expectedSAN.identity === undefined ||
expectedSAN.type ===
sigstore.SubjectAlternativeNameType
.SUBJECT_ALTERNATIVE_NAME_TYPE_UNSPECIFIED) {
return false;
}
const sanExtension = cert.extSubjectAltName;
// Fail if the certificate does not have a SAN extension
if (!sanExtension) {
return false;
}
let sanValue;
switch (expectedSAN.type) {
case sigstore.SubjectAlternativeNameType.EMAIL:
sanValue = sanExtension.rfc822Name;
break;
case sigstore.SubjectAlternativeNameType.URI:
sanValue = sanExtension.uri;
break;
case sigstore.SubjectAlternativeNameType.OTHER_NAME:
sanValue = sanExtension.otherName(OID_FULCIO_USERNAME_SUBJECT);
break;
}
// Missing SAN value is an automatic failure
if (sanValue === undefined) {
return false;
}
let match;
switch (expectedSAN.identity.$case) {
case 'value':
match = expectedSAN.identity.value;
break;
case 'regexp':
// TODO support regex
break;
}
return sanValue === match;
}
// Checks that the certificate contains the specified extensions. Returns true
// if all extensions are present and match the expected values; otherwise,
// returns false.
function verifyOIDs(cert, oids) {
return oids.every((expectedExtension) => {
if (!expectedExtension.oid) {
return false;
}
const oid = expectedExtension.oid.id.join('.');
const extension = cert.extension(oid);
// If the extension is not present, or there is no value, return false
const valueObj = extension?.valueObj;
if (!valueObj) {
return false;
}
// Check to see if this is a newer style extension with an embedded
// UTF8String, or an older style extension with a raw string
if (valueObj.subs.length > 0) {
return valueObj.subs[0].value.equals(expectedExtension.value);
}
else {
return valueObj.value.equals(expectedExtension.value);
}
});
}

1
spa/node_modules/sigstore/dist/cli/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare function processArgv(): Promise<void>;

125
spa/node_modules/sigstore/dist/cli/index.js generated vendored Normal file
View File

@@ -0,0 +1,125 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.processArgv = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const fs_1 = __importDefault(require("fs"));
const index_1 = require("../index");
const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json';
async function cli(args) {
switch (args[0]) {
case 'sign':
await sign(args[1]);
break;
case 'attest':
await attest(args[1], args[2]);
break;
case 'verify':
await verify(args[1], args[2]);
break;
case 'version':
case '-version':
case '--version':
case '-v':
// eslint-disable-next-line @typescript-eslint/no-var-requires
console.log(require('../../package.json').version);
break;
case 'help':
case '--help':
case '-h':
case '-?':
printUsage();
break;
default:
throw 'Unknown command';
}
}
function printUsage() {
console.log(`sigstore <command> <artifact>
Usage:
sigstore sign sign an artifact
sigstore attest sign an artifact using dsse (Dead Simple Signing Envelope)
sigstore verify verify an artifact
sigstore version print version information
sigstore help print help information
`);
}
function printRekorEntry(bundle, options) {
let url;
if (options.rekorURL === index_1.sigstore.DEFAULT_REKOR_URL) {
url = `https://search.sigstore.dev`;
}
else {
url = `${options.rekorURL}/api/v1/log/entries`;
}
const logIndex = bundle.verificationMaterial?.tlogEntries[0].logIndex;
console.error(`Created entry at index ${logIndex}, available at`);
console.error(`${url}?logIndex=${logIndex}`);
}
// TODO: Allow customing these options
const signOptions = {
oidcClientID: 'sigstore',
oidcIssuer: 'https://oauth2.sigstore.dev/auth',
oidcRedirectURL: process.env.OIDC_REDIRECT_URL,
rekorURL: index_1.sigstore.DEFAULT_REKOR_URL,
};
async function sign(artifactPath) {
const buffer = fs_1.default.readFileSync(artifactPath);
const bundle = await index_1.sigstore.sign(buffer, signOptions);
printRekorEntry(bundle, signOptions);
console.log(JSON.stringify(bundle));
}
async function attest(artifactPath, payloadType = INTOTO_PAYLOAD_TYPE) {
const buffer = fs_1.default.readFileSync(artifactPath);
const bundle = await index_1.sigstore.attest(buffer, payloadType, signOptions);
printRekorEntry(bundle, signOptions);
console.log(JSON.stringify(bundle));
}
async function verify(bundlePath, artifactPath) {
let payload = undefined;
if (artifactPath) {
payload = fs_1.default.readFileSync(artifactPath);
}
const bundleFile = fs_1.default.readFileSync(bundlePath);
const bundle = JSON.parse(bundleFile.toString('utf-8'));
try {
await index_1.sigstore.verify(bundle, payload, {});
console.error('Verified OK');
}
catch (e) {
console.error('Verification failed');
if (e instanceof Error) {
console.error('Error: ' + e.message);
}
process.exit(1);
}
}
async function processArgv() {
try {
await cli(process.argv.slice(2));
process.exit(0);
}
catch (e) {
console.error(e);
process.exit(1);
}
}
exports.processArgv = processArgv;

44
spa/node_modules/sigstore/dist/config.d.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import { DSSEBundleBuilder, IdentityProvider, MessageSignatureBundleBuilder } from '@sigstore/sign';
import { SignerFunc } from './types/signature';
import * as sigstore from './types/sigstore';
import type { FetchOptions, Retry } from './types/fetch';
import type { KeySelector } from './verify';
export type TUFOptions = {
tufMirrorURL?: string;
tufRootPath?: string;
tufCachePath?: string;
} & FetchOptions;
export type SignOptions = {
fulcioURL?: string;
identityProvider?: IdentityProvider;
identityToken?: string;
oidcIssuer?: string;
oidcClientID?: string;
oidcClientSecret?: string;
oidcRedirectURL?: string;
rekorURL?: string;
signer?: SignerFunc;
tlogUpload?: boolean;
tsaServerURL?: string;
} & FetchOptions;
export type VerifyOptions = {
ctLogThreshold?: number;
tlogThreshold?: number;
certificateIssuer?: string;
certificateIdentityEmail?: string;
certificateIdentityURI?: string;
certificateOIDs?: Record<string, string>;
keySelector?: KeySelector;
rekorURL?: string;
} & TUFOptions;
export type CreateVerifierOptions = {
keySelector?: KeySelector;
} & TUFOptions;
export declare const DEFAULT_FULCIO_URL = "https://fulcio.sigstore.dev";
export declare const DEFAULT_REKOR_URL = "https://rekor.sigstore.dev";
export declare const DEFAULT_RETRY: Retry;
export declare const DEFAULT_TIMEOUT = 5000;
export type BundleType = 'messageSignature' | 'dsseEnvelope';
export declare function createBundleBuilder(bundleType: 'messageSignature', options: SignOptions): MessageSignatureBundleBuilder;
export declare function createBundleBuilder(bundleType: 'dsseEnvelope', options: SignOptions): DSSEBundleBuilder;
export declare function artifactVerificationOptions(options: VerifyOptions): sigstore.RequiredArtifactVerificationOptions;

192
spa/node_modules/sigstore/dist/config.js generated vendored Normal file
View File

@@ -0,0 +1,192 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.artifactVerificationOptions = exports.createBundleBuilder = exports.DEFAULT_TIMEOUT = exports.DEFAULT_RETRY = exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const sign_1 = require("@sigstore/sign");
const identity_1 = __importDefault(require("./identity"));
const signature_1 = require("./types/signature");
const sigstore = __importStar(require("./types/sigstore"));
exports.DEFAULT_FULCIO_URL = 'https://fulcio.sigstore.dev';
exports.DEFAULT_REKOR_URL = 'https://rekor.sigstore.dev';
exports.DEFAULT_RETRY = { retries: 2 };
exports.DEFAULT_TIMEOUT = 5000;
function createBundleBuilder(bundleType, options) {
const bundlerOptions = {
signer: initSigner(options),
witnesses: initWitnesses(options),
};
switch (bundleType) {
case 'messageSignature':
return new sign_1.MessageSignatureBundleBuilder(bundlerOptions);
case 'dsseEnvelope':
return new sign_1.DSSEBundleBuilder(bundlerOptions);
}
}
exports.createBundleBuilder = createBundleBuilder;
// Instantiate a signer based on the supplied options. If a signer function is
// provided, use that. Otherwise, if a Fulcio URL is provided, use the Fulcio
// signer. Otherwise, throw an error.
function initSigner(options) {
if (isCallbackSignerEnabled(options)) {
return new signature_1.CallbackSigner(options);
}
else {
return new sign_1.FulcioSigner({
fulcioBaseURL: options.fulcioURL || exports.DEFAULT_FULCIO_URL,
identityProvider: options.identityProvider || initIdentityProvider(options),
retry: options.retry ?? exports.DEFAULT_RETRY,
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
});
}
}
// Instantiate an identity provider based on the supplied options. If an
// explicit identity token is provided, use that. Otherwise, if an OIDC issuer
// and client ID are provided, use the OIDC provider. Otherwise, use the CI
// context provider.
function initIdentityProvider(options) {
const token = options.identityToken;
if (token) {
return { getToken: () => Promise.resolve(token) };
}
else if (options.oidcIssuer && options.oidcClientID) {
return identity_1.default.oauthProvider({
issuer: options.oidcIssuer,
clientID: options.oidcClientID,
clientSecret: options.oidcClientSecret,
redirectURL: options.oidcRedirectURL,
});
}
else {
return new sign_1.CIContextProvider('sigstore');
}
}
// Instantiate a collection of witnesses based on the supplied options.
function initWitnesses(options) {
const witnesses = [];
if (isRekorEnabled(options)) {
witnesses.push(new sign_1.RekorWitness({
rekorBaseURL: options.rekorURL || exports.DEFAULT_REKOR_URL,
fetchOnConflict: false,
retry: options.retry ?? exports.DEFAULT_RETRY,
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
}));
}
if (isTSAEnabled(options)) {
witnesses.push(new sign_1.TSAWitness({
tsaBaseURL: options.tsaServerURL,
retry: options.retry ?? exports.DEFAULT_RETRY,
timeout: options.timeout ?? exports.DEFAULT_TIMEOUT,
}));
}
return witnesses;
}
// Type assertion to ensure that the signer is enabled
function isCallbackSignerEnabled(options) {
return options.signer !== undefined;
}
// Type assertion to ensure that Rekor is enabled
function isRekorEnabled(options) {
return options.tlogUpload !== false;
}
// Type assertion to ensure that TSA is enabled
function isTSAEnabled(options) {
return options.tsaServerURL !== undefined;
}
// Assembles the AtifactVerificationOptions from the supplied VerifyOptions.
function artifactVerificationOptions(options) {
// The trusted signers are only used if the options contain a certificate
// issuer
let signers;
if (options.certificateIssuer) {
let san = undefined;
if (options.certificateIdentityEmail) {
san = {
type: sigstore.SubjectAlternativeNameType.EMAIL,
identity: {
$case: 'value',
value: options.certificateIdentityEmail,
},
};
}
else if (options.certificateIdentityURI) {
san = {
type: sigstore.SubjectAlternativeNameType.URI,
identity: {
$case: 'value',
value: options.certificateIdentityURI,
},
};
}
const oids = Object.entries(options.certificateOIDs || /* istanbul ignore next */ {}).map(([oid, value]) => ({
oid: { id: oid.split('.').map((s) => parseInt(s, 10)) },
value: Buffer.from(value),
}));
signers = {
$case: 'certificateIdentities',
certificateIdentities: {
identities: [
{
issuer: options.certificateIssuer,
san: san,
oids: oids,
},
],
},
};
}
// Construct the artifact verification options w/ defaults
return {
ctlogOptions: {
disable: options.ctLogThreshold === 0,
threshold: options.ctLogThreshold ?? 1,
detachedSct: false,
},
tlogOptions: {
disable: options.tlogThreshold === 0,
threshold: options.tlogThreshold ?? 1,
performOnlineVerification: false,
},
signers,
};
}
exports.artifactVerificationOptions = artifactVerificationOptions;

23
spa/node_modules/sigstore/dist/error.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
declare class BaseError extends Error {
cause: any | undefined;
constructor(message: string, cause?: any);
}
declare class ErrorWithCode<T extends string> extends BaseError {
code: T;
constructor({ code, message, cause, }: {
code: T;
message: string;
cause?: any;
});
}
export declare class VerificationError extends BaseError {
}
export declare class PolicyError extends BaseError {
}
type InternalErrorCode = 'TUF_FIND_TARGET_ERROR' | 'TUF_REFRESH_METADATA_ERROR' | 'TUF_DOWNLOAD_TARGET_ERROR' | 'TUF_READ_TARGET_ERROR';
export declare class InternalError extends ErrorWithCode<InternalErrorCode> {
}
type SignatureErrorCode = 'MISSING_SIGNATURE_ERROR' | 'MISSING_PUBLIC_KEY_ERROR';
export declare class SignatureError extends ErrorWithCode<SignatureErrorCode> {
}
export {};

45
spa/node_modules/sigstore/dist/error.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignatureError = exports.InternalError = exports.PolicyError = exports.VerificationError = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
class BaseError extends Error {
constructor(message, cause) {
super(message);
this.name = this.constructor.name;
this.cause = cause;
}
}
class ErrorWithCode extends BaseError {
constructor({ code, message, cause, }) {
super(message, cause);
this.code = code;
this.name = this.constructor.name;
}
}
class VerificationError extends BaseError {
}
exports.VerificationError = VerificationError;
class PolicyError extends BaseError {
}
exports.PolicyError = PolicyError;
class InternalError extends ErrorWithCode {
}
exports.InternalError = InternalError;
class SignatureError extends ErrorWithCode {
}
exports.SignatureError = SignatureError;

20
spa/node_modules/sigstore/dist/identity/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
import { IdentityProvider } from '@sigstore/sign';
/**
* oauthProvider returns a new Provider instance which attempts to retrieve
* an identity token from the configured OAuth2 issuer.
*
* @param issuer Base URL of the issuer
* @param clientID Client ID for the issuer
* @param clientSecret Client secret for the issuer (optional)
* @returns {IdentityProvider}
*/
declare function oauthProvider(options: {
issuer: string;
clientID: string;
clientSecret?: string;
redirectURL?: string;
}): IdentityProvider;
declare const _default: {
oauthProvider: typeof oauthProvider;
};
export default _default;

24
spa/node_modules/sigstore/dist/identity/index.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const issuer_1 = require("./issuer");
const oauth_1 = require("./oauth");
/**
* oauthProvider returns a new Provider instance which attempts to retrieve
* an identity token from the configured OAuth2 issuer.
*
* @param issuer Base URL of the issuer
* @param clientID Client ID for the issuer
* @param clientSecret Client secret for the issuer (optional)
* @returns {IdentityProvider}
*/
function oauthProvider(options) {
return new oauth_1.OAuthProvider({
issuer: new issuer_1.Issuer(options.issuer),
clientID: options.clientID,
clientSecret: options.clientSecret,
redirectURL: options.redirectURL,
});
}
exports.default = {
oauthProvider,
};

15
spa/node_modules/sigstore/dist/identity/issuer.d.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
/**
* The Issuer reperesents a single OAuth2 provider.
*
* The Issuer is configured with a provider's base OAuth2 endpoint which is
* used to retrieve the associated configuration information.
*/
export declare class Issuer {
private baseURL;
private fetch;
private config?;
constructor(baseURL: string);
authEndpoint(): Promise<string>;
tokenEndpoint(): Promise<string>;
private loadOpenIDConfig;
}

53
spa/node_modules/sigstore/dist/identity/issuer.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Issuer = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
// Standard endpoint for retrieving OpenID configuration information
const OPENID_CONFIG_PATH = '/.well-known/openid-configuration';
/**
* The Issuer reperesents a single OAuth2 provider.
*
* The Issuer is configured with a provider's base OAuth2 endpoint which is
* used to retrieve the associated configuration information.
*/
class Issuer {
constructor(baseURL) {
this.baseURL = baseURL;
this.fetch = make_fetch_happen_1.default.defaults({ retry: 2 });
}
async authEndpoint() {
if (!this.config) {
this.config = await this.loadOpenIDConfig();
}
return this.config.authorization_endpoint;
}
async tokenEndpoint() {
if (!this.config) {
this.config = await this.loadOpenIDConfig();
}
return this.config.token_endpoint;
}
async loadOpenIDConfig() {
const url = `${this.baseURL}${OPENID_CONFIG_PATH}`;
return this.fetch(url).then((res) => res.json());
}
}
exports.Issuer = Issuer;

26
spa/node_modules/sigstore/dist/identity/oauth.d.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import { Issuer } from './issuer';
import type { IdentityProvider } from '@sigstore/sign';
interface OAuthProviderOptions {
issuer: Issuer;
clientID: string;
clientSecret?: string;
redirectURL?: string;
}
export declare class OAuthProvider implements IdentityProvider {
private clientID;
private clientSecret;
private issuer;
private codeVerifier;
private state;
private redirectURI?;
constructor(options: OAuthProviderOptions);
getToken(): Promise<string>;
private initiateAuthRequest;
private getIDToken;
private getBasicAuthHeaderValue;
private getAuthRequestURL;
private getAuthRequestParams;
private getCodeChallenge;
private openURL;
}
export {};

197
spa/node_modules/sigstore/dist/identity/oauth.js generated vendored Normal file
View File

@@ -0,0 +1,197 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.OAuthProvider = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const assert_1 = __importDefault(require("assert"));
const child_process_1 = __importDefault(require("child_process"));
const http_1 = __importDefault(require("http"));
const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
const url_1 = require("url");
const util_1 = require("../util");
class OAuthProvider {
constructor(options) {
this.clientID = options.clientID;
this.clientSecret = options.clientSecret || '';
this.issuer = options.issuer;
this.redirectURI = options.redirectURL;
this.codeVerifier = generateRandomString(32);
this.state = generateRandomString(16);
}
async getToken() {
const authCode = await this.initiateAuthRequest();
return this.getIDToken(authCode);
}
// Initates the authorization request. This will start an HTTP server to
// receive the post-auth redirect and then open the user's default browser to
// the provider's authorization page.
async initiateAuthRequest() {
const server = http_1.default.createServer();
const sockets = new Set();
// Start server and wait till it is listening. If a redirect URL was
// provided, use that. Otherwise, use a random port and construct the
// redirect URL.
await new Promise((resolve) => {
if (this.redirectURI) {
const url = new url_1.URL(this.redirectURI);
server.listen(Number(url.port), url.hostname, resolve);
}
else {
server.listen(0, resolve);
// Get port the server is listening on and construct the server URL
const port = server.address().port;
this.redirectURI = `http://localhost:${port}`;
}
});
// Keep track of connections to the server so we can force a shutdown
server.on('connection', (socket) => {
sockets.add(socket);
socket.once('close', () => {
sockets.delete(socket);
});
});
const result = new Promise((resolve, reject) => {
// Set-up handler for post-auth redirect
server.on('request', (req, res) => {
if (!req.url) {
reject('invalid server request');
return;
}
res.writeHead(200);
res.end('Auth Successful');
// Parse incoming request URL
const query = new url_1.URL(req.url, this.redirectURI).searchParams;
// Check to see if the state matches
if (query.get('state') !== this.state) {
reject('invalid state value');
return;
}
const authCode = query.get('code');
// Force-close any open connections to the server so we can get a
// clean shutdown
for (const socket of sockets) {
socket.destroy();
sockets.delete(socket);
}
// Return auth code once we've shutdown server
server.close(() => {
if (!authCode) {
reject('authorization code not found');
}
else {
resolve(authCode);
}
});
});
});
try {
// Open browser to start authorization request
const authBaseURL = await this.issuer.authEndpoint();
const authURL = this.getAuthRequestURL(authBaseURL);
await this.openURL(authURL);
}
catch (err) {
// Prevent leaked server handler on error
server.close();
throw err;
}
return result;
}
// Uses the provided authorization code, to retrieve the ID token from the
// provider
async getIDToken(authCode) {
(0, assert_1.default)(this.redirectURI);
const tokenEndpointURL = await this.issuer.tokenEndpoint();
const params = new url_1.URLSearchParams();
params.append('grant_type', 'authorization_code');
params.append('code', authCode);
params.append('redirect_uri', this.redirectURI);
params.append('code_verifier', this.codeVerifier);
const response = await (0, make_fetch_happen_1.default)(tokenEndpointURL, {
method: 'POST',
headers: { Authorization: `Basic ${this.getBasicAuthHeaderValue()}` },
body: params,
}).then((r) => r.json());
return response.id_token;
}
// Construct the basic auth header value from the client ID and secret
getBasicAuthHeaderValue() {
return util_1.encoding.base64Encode(`${this.clientID}:${this.clientSecret}`);
}
// Generate starting URL for authorization request
getAuthRequestURL(baseURL) {
const params = this.getAuthRequestParams();
return `${baseURL}?${params.toString()}`;
}
// Collect parameters for authorization request
getAuthRequestParams() {
(0, assert_1.default)(this.redirectURI);
const codeChallenge = this.getCodeChallenge();
return new url_1.URLSearchParams({
response_type: 'code',
client_id: this.clientID,
client_secret: this.clientSecret,
scope: 'openid email',
redirect_uri: this.redirectURI,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
state: this.state,
nonce: generateRandomString(16),
});
}
// Generate code challenge for authorization request
getCodeChallenge() {
return util_1.encoding.base64URLEscape(util_1.crypto.hash(this.codeVerifier).toString('base64'));
}
// Open the supplied URL in the user's default browser
async openURL(url) {
return new Promise((resolve, reject) => {
let open = null;
let command = `"${url}"`;
switch (process.platform) {
case 'darwin':
open = 'open';
break;
case 'linux' || 'freebsd' || 'netbsd' || 'openbsd':
open = 'xdg-open';
break;
case 'win32':
open = 'start';
command = `"" ${command}`;
break;
default:
return reject(`OAuth: unsupported platform: ${process.platform}`);
}
console.error(`Your browser will now be opened to: ${url}`);
child_process_1.default.exec(`${open} ${command}`, undefined, (err) => {
if (err) {
reject(err);
}
else {
resolve();
}
});
});
}
}
exports.OAuthProvider = OAuthProvider;
// Generate random code verifier value
function generateRandomString(len) {
return util_1.encoding.base64URLEscape(util_1.crypto.randomBytes(len).toString('base64'));
}

2
spa/node_modules/sigstore/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export type { IdentityProvider } from '@sigstore/sign';
export * as sigstore from './sigstore';

27
spa/node_modules/sigstore/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sigstore = void 0;
exports.sigstore = __importStar(require("./sigstore"));

8
spa/node_modules/sigstore/dist/sigstore-utils.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/// <reference types="node" />
import { SerializedBundle, SerializedEnvelope } from '@sigstore/bundle';
import { SignOptions } from './config';
import { SignerFunc } from './types/signature';
export declare function createDSSEEnvelope(payload: Buffer, payloadType: string, options: {
signer: SignerFunc;
}): Promise<SerializedEnvelope>;
export declare function createRekorEntry(dsseEnvelope: SerializedEnvelope, publicKey: string, options?: SignOptions): Promise<SerializedBundle>;

55
spa/node_modules/sigstore/dist/sigstore-utils.js generated vendored Normal file
View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRekorEntry = exports.createDSSEEnvelope = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const bundle_1 = require("@sigstore/bundle");
const sign_1 = require("@sigstore/sign");
const config_1 = require("./config");
async function createDSSEEnvelope(payload, payloadType, options) {
const bundler = (0, config_1.createBundleBuilder)('dsseEnvelope', {
signer: options.signer,
tlogUpload: false,
});
const bundle = await bundler.create({ data: payload, type: payloadType });
return (0, bundle_1.envelopeToJSON)(bundle.content.dsseEnvelope);
}
exports.createDSSEEnvelope = createDSSEEnvelope;
// Accepts a signed DSSE envelope and a PEM-encoded public key to be added to the
// transparency log. Returns a Sigstore bundle suitable for offline verification.
async function createRekorEntry(dsseEnvelope, publicKey,
/* istanbul ignore next */
options = {}) {
const envelope = (0, bundle_1.envelopeFromJSON)(dsseEnvelope);
const bundle = (0, bundle_1.toDSSEBundle)({
artifact: envelope.payload,
artifactType: envelope.payloadType,
signature: envelope.signatures[0].sig,
keyHint: envelope.signatures[0].keyid,
});
const tlog = new sign_1.RekorWitness({
rekorBaseURL: options.rekorURL || /* istanbul ignore next */ config_1.DEFAULT_REKOR_URL,
fetchOnConflict: true,
retry: options.retry ?? config_1.DEFAULT_RETRY,
timeout: options.timeout ?? config_1.DEFAULT_TIMEOUT,
});
// Add entry to transparency log
const vm = await tlog.testify(bundle.content, publicKey);
// Add transparency log entries to bundle
bundle.verificationMaterial.tlogEntries = [...vm.tlogEntries];
return (0, bundle_1.bundleToJSON)(bundle);
}
exports.createRekorEntry = createRekorEntry;

24
spa/node_modules/sigstore/dist/sigstore.d.ts generated vendored Normal file
View File

@@ -0,0 +1,24 @@
/// <reference types="node" />
import { SerializedBundle } from '@sigstore/bundle';
import * as tuf from '@sigstore/tuf';
import * as config from './config';
export declare function sign(payload: Buffer, options?: config.SignOptions): Promise<SerializedBundle>;
export declare function attest(payload: Buffer, payloadType: string, options?: config.SignOptions): Promise<SerializedBundle>;
export declare function verify(bundle: SerializedBundle, payload?: Buffer, options?: config.VerifyOptions): Promise<void>;
export interface BundleVerifier {
verify(bundle: SerializedBundle): void;
}
export declare function createVerifier(options: config.CreateVerifierOptions): Promise<BundleVerifier>;
declare const tufUtils: {
client: (options?: config.TUFOptions) => Promise<tuf.TUF>;
getTarget: (path: string, options?: config.TUFOptions) => Promise<string>;
};
export { ValidationError } from '@sigstore/bundle';
export type { SerializedBundle as Bundle, SerializedEnvelope as Envelope, } from '@sigstore/bundle';
export type { TUF } from '@sigstore/tuf';
export type { SignOptions, VerifyOptions } from './config';
export { InternalError, PolicyError, VerificationError } from './error';
export * as utils from './sigstore-utils';
export { tufUtils as tuf };
export declare const DEFAULT_FULCIO_URL = "https://fulcio.sigstore.dev";
export declare const DEFAULT_REKOR_URL = "https://rekor.sigstore.dev";

124
spa/node_modules/sigstore/dist/sigstore.js generated vendored Normal file
View File

@@ -0,0 +1,124 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DEFAULT_REKOR_URL = exports.DEFAULT_FULCIO_URL = exports.tuf = exports.utils = exports.VerificationError = exports.PolicyError = exports.InternalError = exports.ValidationError = exports.createVerifier = exports.verify = exports.attest = exports.sign = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const bundle_1 = require("@sigstore/bundle");
const tuf = __importStar(require("@sigstore/tuf"));
const config = __importStar(require("./config"));
const verify_1 = require("./verify");
async function sign(payload, options = {}) {
const bundler = config.createBundleBuilder('messageSignature', options);
const bundle = await bundler.create({ data: payload });
return (0, bundle_1.bundleToJSON)(bundle);
}
exports.sign = sign;
async function attest(payload, payloadType, options = {}) {
const bundler = config.createBundleBuilder('dsseEnvelope', options);
const bundle = await bundler.create({ data: payload, type: payloadType });
return (0, bundle_1.bundleToJSON)(bundle);
}
exports.attest = attest;
async function verify(bundle, payload, options = {}) {
const trustedRoot = await tuf.getTrustedRoot({
mirrorURL: options.tufMirrorURL,
rootPath: options.tufRootPath,
cachePath: options.tufCachePath,
retry: options.retry ?? config.DEFAULT_RETRY,
timeout: options.timeout ?? config.DEFAULT_TIMEOUT,
});
const verifier = new verify_1.Verifier(trustedRoot, options.keySelector);
const deserializedBundle = (0, bundle_1.bundleFromJSON)(bundle);
const opts = config.artifactVerificationOptions(options);
return verifier.verify(deserializedBundle, opts, payload);
}
exports.verify = verify;
async function createVerifier(options) {
const trustedRoot = await tuf.getTrustedRoot({
mirrorURL: options.tufMirrorURL,
rootPath: options.tufRootPath,
cachePath: options.tufCachePath,
retry: options.retry ?? config.DEFAULT_RETRY,
timeout: options.timeout ?? config.DEFAULT_TIMEOUT,
});
const verifier = new verify_1.Verifier(trustedRoot, options.keySelector);
const verifyOpts = config.artifactVerificationOptions(options);
return {
verify: (bundle) => {
const deserializedBundle = (0, bundle_1.bundleFromJSON)(bundle);
return verifier.verify(deserializedBundle, verifyOpts);
},
};
}
exports.createVerifier = createVerifier;
const tufUtils = {
client: (options = {}) => {
return tuf.initTUF({
mirrorURL: options.tufMirrorURL,
rootPath: options.tufRootPath,
cachePath: options.tufCachePath,
retry: options.retry,
timeout: options.timeout,
});
},
/*
* @deprecated Use tufUtils.client instead.
*/
getTarget: (path, options = {}) => {
return tuf
.initTUF({
mirrorURL: options.tufMirrorURL,
rootPath: options.tufRootPath,
cachePath: options.tufCachePath,
retry: options.retry,
timeout: options.timeout,
})
.then((t) => t.getTarget(path));
},
};
exports.tuf = tufUtils;
var bundle_2 = require("@sigstore/bundle");
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return bundle_2.ValidationError; } });
var error_1 = require("./error");
Object.defineProperty(exports, "InternalError", { enumerable: true, get: function () { return error_1.InternalError; } });
Object.defineProperty(exports, "PolicyError", { enumerable: true, get: function () { return error_1.PolicyError; } });
Object.defineProperty(exports, "VerificationError", { enumerable: true, get: function () { return error_1.VerificationError; } });
exports.utils = __importStar(require("./sigstore-utils"));
exports.DEFAULT_FULCIO_URL = config.DEFAULT_FULCIO_URL;
exports.DEFAULT_REKOR_URL = config.DEFAULT_REKOR_URL;

2
spa/node_modules/sigstore/dist/tlog/verify/body.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import type { Bundle, TransparencyLogEntry } from '@sigstore/bundle';
export declare function verifyTLogBody(entry: TransparencyLogEntry, bundleContent: Bundle['content']): boolean;

152
spa/node_modules/sigstore/dist/tlog/verify/body.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyTLogBody = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../../error");
const util_1 = require("../../util");
const TLOG_MISMATCH_ERROR_MSG = 'bundle content and tlog entry do not match';
// Compare the given tlog entry to the given bundle
function verifyTLogBody(entry, bundleContent) {
const { kind, version } = entry.kindVersion;
const body = JSON.parse(entry.canonicalizedBody.toString('utf8'));
try {
if (kind !== body.kind || version !== body.apiVersion) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
switch (body.kind) {
case 'dsse':
verifyDSSETLogBody(body, bundleContent);
break;
case 'intoto':
verifyIntotoTLogBody(body, bundleContent);
break;
case 'hashedrekord':
verifyHashedRekordTLogBody(body, bundleContent);
break;
default:
throw new error_1.VerificationError(`unsupported kind in tlog entry: ${kind}`);
}
return true;
}
catch (e) {
return false;
}
}
exports.verifyTLogBody = verifyTLogBody;
// Compare the given intoto tlog entry to the given bundle
function verifyDSSETLogBody(tlogEntry, content) {
if (content?.$case !== 'dsseEnvelope') {
throw new error_1.VerificationError(`unsupported bundle content: ${content?.$case || 'unknown'}`);
}
const dsse = content.dsseEnvelope;
switch (tlogEntry.apiVersion) {
case '0.0.1':
verifyDSSE001TLogBody(tlogEntry, dsse);
break;
default:
throw new error_1.VerificationError(`unsupported dsse version: ${tlogEntry.apiVersion}`);
}
}
// Compare the given intoto tlog entry to the given bundle
function verifyIntotoTLogBody(tlogEntry, content) {
if (content?.$case !== 'dsseEnvelope') {
throw new error_1.VerificationError(`unsupported bundle content: ${content?.$case || 'unknown'}`);
}
const dsse = content.dsseEnvelope;
switch (tlogEntry.apiVersion) {
case '0.0.2':
verifyIntoto002TLogBody(tlogEntry, dsse);
break;
default:
throw new error_1.VerificationError(`unsupported intoto version: ${tlogEntry.apiVersion}`);
}
}
// Compare the given hashedrekord tlog entry to the given bundle
function verifyHashedRekordTLogBody(tlogEntry, content) {
if (content?.$case !== 'messageSignature') {
throw new error_1.VerificationError(`unsupported bundle content: ${content?.$case || 'unknown'}`);
}
const messageSignature = content.messageSignature;
switch (tlogEntry.apiVersion) {
case '0.0.1':
verifyHashedrekor001TLogBody(tlogEntry, messageSignature);
break;
default:
throw new error_1.VerificationError(`unsupported hashedrekord version: ${tlogEntry.apiVersion}`);
}
}
// Compare the given dsse v0.0.1 tlog entry to the given DSSE envelope.
function verifyDSSE001TLogBody(tlogEntry, dsse) {
// Collect all of the signatures from the DSSE envelope
// Turns them into base64-encoded strings for comparison
const dsseSigs = dsse.signatures.map((signature) => signature.sig.toString('base64'));
// Collect all of the signatures from the tlog entry
const tlogSigs = tlogEntry.spec.signatures?.map((signature) => signature.signature);
// Ensure the bundle's DSSE and the tlog entry contain the same number of signatures
if (dsseSigs.length !== tlogSigs?.length) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
// Ensure that every signature in the bundle's DSSE is present in the tlog entry
if (!dsseSigs.every((dsseSig) => tlogSigs.includes(dsseSig))) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
// Ensure the digest of the bundle's DSSE payload matches the digest in the
// tlog entry
const dssePayloadHash = util_1.crypto.hash(dsse.payload).toString('hex');
if (dssePayloadHash !== tlogEntry.spec.payloadHash?.value) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
}
// Compare the given intoto v0.0.2 tlog entry to the given DSSE envelope.
function verifyIntoto002TLogBody(tlogEntry, dsse) {
// Collect all of the signatures from the DSSE envelope
// Turns them into base64-encoded strings for comparison
const dsseSigs = dsse.signatures.map((signature) => signature.sig.toString('base64'));
// Collect all of the signatures from the tlog entry
// Remember that tlog signastures are double base64-encoded
const tlogSigs = tlogEntry.spec.content.envelope?.signatures.map((signature) => (signature.sig ? util_1.encoding.base64Decode(signature.sig) : ''));
// Ensure the bundle's DSSE and the tlog entry contain the same number of signatures
if (dsseSigs.length !== tlogSigs?.length) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
// Ensure that every signature in the bundle's DSSE is present in the tlog entry
if (!dsseSigs.every((dsseSig) => tlogSigs.includes(dsseSig))) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
// Ensure the digest of the bundle's DSSE payload matches the digest in the
// tlog entry
const dssePayloadHash = util_1.crypto.hash(dsse.payload).toString('hex');
if (dssePayloadHash !== tlogEntry.spec.content.payloadHash?.value) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
}
// Compare the given hashedrekord v0.0.1 tlog entry to the given message
// signature
function verifyHashedrekor001TLogBody(tlogEntry, messageSignature) {
// Ensure that the bundles message signature matches the tlog entry
const msgSig = messageSignature.signature.toString('base64');
const tlogSig = tlogEntry.spec.signature.content;
if (msgSig !== tlogSig) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
// Ensure that the bundle's message digest matches the tlog entry
const msgDigest = messageSignature.messageDigest?.digest.toString('hex');
const tlogDigest = tlogEntry.spec.data.hash?.value;
if (msgDigest !== tlogDigest) {
throw new error_1.VerificationError(TLOG_MISMATCH_ERROR_MSG);
}
}

View File

@@ -0,0 +1,3 @@
import type { TLogEntryWithInclusionProof } from '@sigstore/bundle';
import * as sigstore from '../../types/sigstore';
export declare function verifyCheckpoint(entry: TLogEntryWithInclusionProof, tlogs: sigstore.TransparencyLogInstance[]): boolean;

View File

@@ -0,0 +1,148 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyCheckpoint = void 0;
const error_1 = require("../../error");
const util_1 = require("../../util");
// Separator between the note and the signatures in a checkpoint
const CHECKPOINT_SEPARATOR = '\n\n';
// Checkpoint signatures are of the following form:
// " <identity> <key_hint+signature_bytes>\n"
// where:
// - the prefix is an emdash (U+2014).
// - <identity> gives a human-readable representation of the signing ID.
// - <key_hint+signature_bytes> is the first 4 bytes of the SHA256 hash of the
// associated public key followed by the signature bytes.
const SIGNATURE_REGEX = /\u2014 (\S+) (\S+)\n/g;
// Verifies the checkpoint value in the given tlog entry. There are two steps
// to the verification:
// 1. Verify that all signatures in the checkpoint can be verified against a
// trusted public key
// 2. Verify that the root hash in the checkpoint matches the root hash in the
// inclusion proof
// See: https://github.com/transparency-dev/formats/blob/main/log/README.md
function verifyCheckpoint(entry, tlogs) {
// Filter tlog instances to just those which were valid at the time of the
// entry
const validTLogs = filterTLogInstances(tlogs, entry.integratedTime);
const inclusionProof = entry.inclusionProof;
const signedNote = SignedNote.fromString(inclusionProof.checkpoint.envelope);
const checkpoint = LogCheckpoint.fromString(signedNote.note);
// Verify that the signatures in the checkpoint are all valid, also check
// that the root hash from the checkpoint matches the root hash in the
// inclusion proof
return (signedNote.verify(validTLogs) &&
util_1.crypto.bufferEqual(checkpoint.logHash, inclusionProof.rootHash));
}
exports.verifyCheckpoint = verifyCheckpoint;
// SignedNote represents a signed note from a transparency log checkpoint. Consists
// of a body (or note) and one more signatures calculated over the body. See
// https://github.com/transparency-dev/formats/blob/main/log/README.md#signed-envelope
class SignedNote {
constructor(note, signatures) {
this.note = note;
this.signatures = signatures;
}
// Deserialize a SignedNote from a string
static fromString(envelope) {
if (!envelope.includes(CHECKPOINT_SEPARATOR)) {
throw new error_1.VerificationError('malformed checkpoint: no separator');
}
// Split the note into the header and the data portions at the separator
const split = envelope.indexOf(CHECKPOINT_SEPARATOR);
const header = envelope.slice(0, split + 1);
const data = envelope.slice(split + CHECKPOINT_SEPARATOR.length);
// Find all the signature lines in the data portion
const matches = data.matchAll(SIGNATURE_REGEX);
// Parse each of the matched signature lines into the name and signature.
// The first four bytes of the signature are the key hint (should match the
// first four bytes of the log ID), and the rest is the signature itself.
const signatures = Array.from(matches, (match) => {
const [, name, signature] = match;
const sigBytes = Buffer.from(signature, 'base64');
if (sigBytes.length < 5) {
throw new error_1.VerificationError('malformed checkpoint: invalid signature');
}
return {
name,
keyHint: sigBytes.subarray(0, 4),
signature: sigBytes.subarray(4),
};
});
if (signatures.length === 0) {
throw new error_1.VerificationError('malformed checkpoint: no signatures');
}
return new SignedNote(header, signatures);
}
// Verifies the signatures in the SignedNote. For each signature, the
// corresponding transparency log is looked up by the key hint and the
// signature is verified against the public key in the transparency log.
// Throws an error if any of the signatures are invalid.
verify(tlogs) {
const data = Buffer.from(this.note, 'utf-8');
return this.signatures.every((signature) => {
// Find the transparency log instance with the matching key hint
const tlog = tlogs.find((tlog) => util_1.crypto.bufferEqual(tlog.logId.keyId.subarray(0, 4), signature.keyHint));
if (!tlog) {
return false;
}
const publicKey = util_1.crypto.createPublicKey(tlog.publicKey.rawBytes);
return util_1.crypto.verifyBlob(data, publicKey, signature.signature);
});
}
}
// LogCheckpoint represents a transparency log checkpoint. Consists of the
// following:
// - origin: the name of the transparency log
// - logSize: the size of the log at the time of the checkpoint
// - logHash: the root hash of the log at the time of the checkpoint
// - rest: the rest of the checkpoint body, which is a list of log entries
// See:
// https://github.com/transparency-dev/formats/blob/main/log/README.md#checkpoint-body
class LogCheckpoint {
constructor(origin, logSize, logHash, rest) {
this.origin = origin;
this.logSize = logSize;
this.logHash = logHash;
this.rest = rest;
}
static fromString(note) {
const lines = note.trim().split('\n');
if (lines.length < 4) {
throw new error_1.VerificationError('malformed checkpoint: too few lines in header');
}
const origin = lines[0];
const logSize = BigInt(lines[1]);
const rootHash = Buffer.from(lines[2], 'base64');
const rest = lines.slice(3);
return new LogCheckpoint(origin, logSize, rootHash, rest);
}
}
// Filter the list of tlog instances to only those which have usable public
// keys and were valid at the given time.
function filterTLogInstances(tlogInstances, integratedTime) {
const targetDate = new Date(Number(integratedTime) * 1000);
return tlogInstances.filter((tlog) => {
// Must have a log ID
if (!tlog.logId) {
return false;
}
// If the tlog doesn't have a public key, we can't use it
const publicKey = tlog.publicKey;
if (publicKey === undefined) {
return false;
}
// If the tlog doesn't have a rawBytes field, we can't use it
if (publicKey.rawBytes === undefined) {
return false;
}
// If the tlog doesn't have a validFor field, we don't need to check it
const validFor = publicKey.validFor;
if (validFor === undefined) {
return true;
}
// Check that the integrated time is within the validFor range
return (validFor.start !== undefined &&
validFor.start <= targetDate &&
(validFor.end === undefined || targetDate <= validFor.end));
});
}

View File

@@ -0,0 +1,3 @@
import { Bundle } from '@sigstore/bundle';
import * as sigstore from '../../types/sigstore';
export declare function verifyTLogEntries(bundle: Bundle, trustedRoot: sigstore.TrustedRoot, options: sigstore.ArtifactVerificationOptions_TlogOptions): void;

92
spa/node_modules/sigstore/dist/tlog/verify/index.js generated vendored Normal file
View File

@@ -0,0 +1,92 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyTLogEntries = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const bundle_1 = require("@sigstore/bundle");
const error_1 = require("../../error");
const cert_1 = require("../../x509/cert");
const body_1 = require("./body");
const checkpoint_1 = require("./checkpoint");
const merkle_1 = require("./merkle");
const set_1 = require("./set");
// Verifies that the number of tlog entries that pass offline verification
// is greater than or equal to the threshold specified in the options.
function verifyTLogEntries(bundle, trustedRoot, options) {
if (bundle.mediaType === bundle_1.BUNDLE_V01_MEDIA_TYPE) {
(0, bundle_1.assertBundleV01)(bundle);
verifyTLogEntriesForBundleV01(bundle, trustedRoot, options);
}
else {
(0, bundle_1.assertBundleLatest)(bundle);
verifyTLogEntriesForBundleLatest(bundle, trustedRoot, options);
}
}
exports.verifyTLogEntries = verifyTLogEntries;
function verifyTLogEntriesForBundleV01(bundle, trustedRoot, options) {
if (options.performOnlineVerification) {
throw new error_1.VerificationError('Online verification not implemented');
}
// Extract the signing cert, if available
const signingCert = signingCertificate(bundle);
// Iterate over the tlog entries and verify each one
const verifiedEntries = bundle.verificationMaterial.tlogEntries.filter((entry) => verifyTLogEntryWithInclusionPromise(entry, bundle.content, trustedRoot.tlogs, signingCert));
if (verifiedEntries.length < options.threshold) {
throw new error_1.VerificationError('tlog verification failed');
}
}
function verifyTLogEntriesForBundleLatest(bundle, trustedRoot, options) {
if (options.performOnlineVerification) {
throw new error_1.VerificationError('Online verification not implemented');
}
// Extract the signing cert, if available
const signingCert = signingCertificate(bundle);
// Iterate over the tlog entries and verify each one
const verifiedEntries = bundle.verificationMaterial.tlogEntries.filter((entry) => verifyTLogEntryWithInclusionProof(entry, bundle.content, trustedRoot.tlogs, signingCert));
if (verifiedEntries.length < options.threshold) {
throw new error_1.VerificationError('tlog verification failed');
}
}
function verifyTLogEntryWithInclusionPromise(entry, bundleContent, tlogs, signingCert) {
// If there is a signing certificate availble, check that the tlog integrated
// time is within the certificate's validity period; otherwise, skip this
// check.
const verifyTLogIntegrationTime = signingCert
? () => signingCert.validForDate(new Date(Number(entry.integratedTime) * 1000))
: () => true;
return ((0, body_1.verifyTLogBody)(entry, bundleContent) &&
(0, set_1.verifyTLogSET)(entry, tlogs) &&
verifyTLogIntegrationTime());
}
function verifyTLogEntryWithInclusionProof(entry, bundleContent, tlogs, signingCert) {
// If there is a signing certificate availble, check that the tlog integrated
// time is within the certificate's validity period; otherwise, skip this
// check.
const verifyTLogIntegrationTime = signingCert
? () => signingCert.validForDate(new Date(Number(entry.integratedTime) * 1000))
: () => true;
return ((0, body_1.verifyTLogBody)(entry, bundleContent) &&
(0, merkle_1.verifyMerkleInclusion)(entry) &&
(0, checkpoint_1.verifyCheckpoint)(entry, tlogs) &&
verifyTLogIntegrationTime());
}
function signingCertificate(bundle) {
if (!(0, bundle_1.isBundleWithCertificateChain)(bundle)) {
return undefined;
}
const signingCert = bundle.verificationMaterial.content.x509CertificateChain.certificates[0];
return cert_1.x509Certificate.parse(signingCert.rawBytes);
}

View File

@@ -0,0 +1,2 @@
import type { TLogEntryWithInclusionProof } from '@sigstore/bundle';
export declare function verifyMerkleInclusion(entry: TLogEntryWithInclusionProof): boolean;

113
spa/node_modules/sigstore/dist/tlog/verify/merkle.js generated vendored Normal file
View File

@@ -0,0 +1,113 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyMerkleInclusion = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const crypto_1 = __importDefault(require("crypto"));
const error_1 = require("../../error");
const RFC6962_LEAF_HASH_PREFIX = Buffer.from([0x00]);
const RFC6962_NODE_HASH_PREFIX = Buffer.from([0x01]);
function verifyMerkleInclusion(entry) {
const inclusionProof = entry.inclusionProof;
const logIndex = BigInt(inclusionProof.logIndex);
const treeSize = BigInt(inclusionProof.treeSize);
if (logIndex < 0n || logIndex >= treeSize) {
throw new error_1.VerificationError('invalid inclusion proof index');
}
// Figure out which subset of hashes corresponds to the inner and border
// nodes
const { inner, border } = decompInclProof(logIndex, treeSize);
if (inclusionProof.hashes.length !== inner + border) {
throw new error_1.VerificationError('invalid inclusion proof length');
}
const innerHashes = inclusionProof.hashes.slice(0, inner);
const borderHashes = inclusionProof.hashes.slice(inner);
// The entry's hash is the leaf hash
const leafHash = hashLeaf(entry.canonicalizedBody);
// Chain the hashes belonging to the inner and border portions
const calculatedHash = chainBorderRight(chainInner(leafHash, innerHashes, logIndex), borderHashes);
// Calculated hash should match the root hash in the inclusion proof
return bufferEqual(calculatedHash, inclusionProof.rootHash);
}
exports.verifyMerkleInclusion = verifyMerkleInclusion;
// Breaks down inclusion proof for a leaf at the specified index in a tree of
// the specified size. The split point is where paths to the index leaf and
// the (size - 1) leaf diverge. Returns lengths of the bottom and upper proof
// parts.
function decompInclProof(index, size) {
const inner = innerProofSize(index, size);
const border = onesCount(index >> BigInt(inner));
return { inner, border };
}
// Computes a subtree hash for a node on or below the tree's right border.
// Assumes the provided proof hashes are ordered from lower to higher levels
// and seed is the initial hash of the node specified by the index.
function chainInner(seed, hashes, index) {
return hashes.reduce((acc, h, i) => {
if ((index >> BigInt(i)) & BigInt(1)) {
return hashChildren(h, acc);
}
else {
return hashChildren(acc, h);
}
}, seed);
}
// Computes a subtree hash for nodes along the tree's right border.
function chainBorderRight(seed, hashes) {
return hashes.reduce((acc, h) => hashChildren(h, acc), seed);
}
function innerProofSize(index, size) {
return bitLength(index ^ (size - BigInt(1)));
}
// Counts the number of ones in the binary representation of the given number.
// https://en.wikipedia.org/wiki/Hamming_weight
function onesCount(x) {
return x.toString(2).split('1').length - 1;
}
// Returns the number of bits necessary to represent an integer in binary.
function bitLength(n) {
if (n === 0n) {
return 0;
}
return n.toString(2).length;
}
// Hashing logic according to RFC6962.
// https://datatracker.ietf.org/doc/html/rfc6962#section-2
function hashChildren(left, right) {
const hasher = crypto_1.default.createHash('sha256');
hasher.update(RFC6962_NODE_HASH_PREFIX);
hasher.update(left);
hasher.update(right);
return hasher.digest();
}
function hashLeaf(leaf) {
const hasher = crypto_1.default.createHash('sha256');
hasher.update(RFC6962_LEAF_HASH_PREFIX);
hasher.update(leaf);
return hasher.digest();
}
function bufferEqual(a, b) {
try {
return crypto_1.default.timingSafeEqual(a, b);
}
catch {
/* istanbul ignore next */
return false;
}
}

3
spa/node_modules/sigstore/dist/tlog/verify/set.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import * as sigstore from '../../types/sigstore';
import type { TLogEntryWithInclusionPromise } from '@sigstore/bundle';
export declare function verifyTLogSET(entry: TLogEntryWithInclusionPromise, tlogs: sigstore.TransparencyLogInstance[]): boolean;

64
spa/node_modules/sigstore/dist/tlog/verify/set.js generated vendored Normal file
View File

@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyTLogSET = void 0;
const util_1 = require("../../util");
// Verifies the SET for the given entry against the list of trusted
// transparency logs. Returns true if the SET can be verified against at least
// one of the trusted logs; otherwise, returns false.
function verifyTLogSET(entry, tlogs) {
// Filter the list of tlog instances to only those which might be able to
// verify the SET
const validTLogs = filterTLogInstances(tlogs, entry.logId.keyId, entry.integratedTime);
// Check to see if we can verify the SET against any of the valid tlogs
return validTLogs.some((tlog) => {
const publicKey = util_1.crypto.createPublicKey(tlog.publicKey.rawBytes);
// Re-create the original Rekor verification payload
const payload = toVerificationPayload(entry);
// Canonicalize the payload and turn into a buffer for verification
const data = Buffer.from(util_1.json.canonicalize(payload), 'utf8');
// Extract the SET from the tlog entry
const signature = entry.inclusionPromise.signedEntryTimestamp;
return util_1.crypto.verifyBlob(data, publicKey, signature);
});
}
exports.verifyTLogSET = verifyTLogSET;
// Returns a properly formatted "VerificationPayload" for one of the
// transaction log entires in the given bundle which can be used for SET
// verification.
function toVerificationPayload(entry) {
const { integratedTime, logIndex, logId, canonicalizedBody } = entry;
return {
body: canonicalizedBody.toString('base64'),
integratedTime: Number(integratedTime),
logIndex: Number(logIndex),
logID: logId.keyId.toString('hex'),
};
}
// Filter the list of tlog instances to only those which match the given log
// ID and have public keys which are valid for the given integrated time.
function filterTLogInstances(tlogInstances, logID, integratedTime) {
const targetDate = new Date(Number(integratedTime) * 1000);
return tlogInstances.filter((tlog) => {
// If the log IDs don't match, we can't use this tlog
if (!tlog.logId?.keyId.equals(logID)) {
return false;
}
// If the tlog doesn't have a public key, we can't use it
const publicKey = tlog.publicKey;
if (publicKey === undefined) {
return false;
}
// If the tlog doesn't have a rawBytes field, we can't use it
if (publicKey.rawBytes === undefined) {
return false;
}
// If the tlog doesn't have a validFor field, we don't need to check it
if (publicKey.validFor === undefined) {
return true;
}
// Check that the integrated time is within the validFor range
return (publicKey.validFor.start !== undefined &&
publicKey.validFor.start <= targetDate &&
(!publicKey.validFor.end || targetDate <= publicKey.validFor.end));
});
}

6
spa/node_modules/sigstore/dist/types/fetch.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import type { MakeFetchHappenOptions } from 'make-fetch-happen';
export type Retry = MakeFetchHappenOptions['retry'];
export type FetchOptions = {
retry?: Retry;
timeout?: number | undefined;
};

2
spa/node_modules/sigstore/dist/types/fetch.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

23
spa/node_modules/sigstore/dist/types/signature.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/// <reference types="node" />
import { Signature, Signer } from '@sigstore/sign';
import { OneOf } from './utility';
interface VerificationMaterial {
certificates: string[];
key: {
id?: string;
value: string;
};
}
export type SignatureMaterial = {
signature: Buffer;
} & OneOf<VerificationMaterial>;
export type SignerFunc = (payload: Buffer) => Promise<SignatureMaterial>;
type CallbackSignerOptions = {
signer: SignerFunc;
};
export declare class CallbackSigner implements Signer {
private signer;
constructor(options: CallbackSignerOptions);
sign(data: Buffer): Promise<Signature>;
}
export {};

37
spa/node_modules/sigstore/dist/types/signature.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CallbackSigner = void 0;
const error_1 = require("../error");
// Adapter to allow the legacy SignerFunc callback to be used as a new Signer
// interface.
class CallbackSigner {
constructor(options) {
this.signer = options.signer;
}
async sign(data) {
const sigMaterial = await this.signer(data);
// Since we're getting data from an external source, we need to validate
// that it's well-formed and complete.
if (!sigMaterial.signature) {
throw new error_1.SignatureError({
code: 'MISSING_SIGNATURE_ERROR',
message: 'no signature returned from signer',
});
}
if (!sigMaterial.key?.value) {
throw new error_1.SignatureError({
code: 'MISSING_PUBLIC_KEY_ERROR',
message: 'no key returned from signer',
});
}
return {
signature: sigMaterial.signature,
key: {
$case: 'publicKey',
hint: sigMaterial.key.id,
publicKey: sigMaterial.key.value,
},
};
}
}
exports.CallbackSigner = CallbackSigner;

15
spa/node_modules/sigstore/dist/types/sigstore.d.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import type { ArtifactVerificationOptions, PublicKey, TransparencyLogInstance } from '@sigstore/protobuf-specs';
import type { WithRequired } from './utility';
export { SubjectAlternativeNameType } from '@sigstore/protobuf-specs';
export type { ArtifactVerificationOptions, ArtifactVerificationOptions_CtlogOptions, ArtifactVerificationOptions_TlogOptions, CertificateAuthority, CertificateIdentities, CertificateIdentity, Envelope, ObjectIdentifierValuePair, PublicKey, SubjectAlternativeName, TransparencyLogInstance, TrustedRoot, } from '@sigstore/protobuf-specs';
export type RequiredArtifactVerificationOptions = WithRequired<ArtifactVerificationOptions, 'ctlogOptions' | 'tlogOptions'>;
export type CAArtifactVerificationOptions = WithRequired<ArtifactVerificationOptions, 'ctlogOptions'> & {
signers?: Extract<ArtifactVerificationOptions['signers'], {
$case: 'certificateIdentities';
}>;
};
export declare function isCAVerificationOptions(options: ArtifactVerificationOptions): options is CAArtifactVerificationOptions;
export type ViableTransparencyLogInstance = TransparencyLogInstance & {
logId: NonNullable<TransparencyLogInstance['logId']>;
publicKey: WithRequired<PublicKey, 'rawBytes'>;
};

27
spa/node_modules/sigstore/dist/types/sigstore.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
"use strict";
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isCAVerificationOptions = exports.SubjectAlternativeNameType = void 0;
// Enums from protobuf-specs
var protobuf_specs_1 = require("@sigstore/protobuf-specs");
Object.defineProperty(exports, "SubjectAlternativeNameType", { enumerable: true, get: function () { return protobuf_specs_1.SubjectAlternativeNameType; } });
function isCAVerificationOptions(options) {
return (options.ctlogOptions !== undefined &&
(options.signers === undefined ||
options.signers.$case === 'certificateIdentities'));
}
exports.isCAVerificationOptions = isCAVerificationOptions;

14
spa/node_modules/sigstore/dist/types/utility.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
type ValueOf<Obj> = Obj[keyof Obj];
type OneOnly<Obj, K extends keyof Obj> = {
[key in Exclude<keyof Obj, K>]: undefined;
} & {
[key in K]: Obj[K];
};
type OneOfByKey<Obj> = {
[key in keyof Obj]: OneOnly<Obj, key>;
};
export type OneOf<T> = ValueOf<OneOfByKey<T>>;
export type WithRequired<T, K extends keyof T> = T & {
[P in K]-?: NonNullable<T[P]>;
};
export {};

18
spa/node_modules/sigstore/dist/types/utility.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
"use strict";
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// https://dev.to/maxime1992/implement-a-generic-oneof-type-with-typescript-22em
Object.defineProperty(exports, "__esModule", { value: true });

2
spa/node_modules/sigstore/dist/util/asn1/dump.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
import { ASN1Obj } from './obj';
export declare function dump(obj: ASN1Obj, indent?: number): void;

97
spa/node_modules/sigstore/dist/util/asn1/dump.js generated vendored Normal file
View File

@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.dump = void 0;
const tag_1 = require("./tag");
// Utility function to dump the contents of an ASN1Obj to the console.
function dump(obj, indent = 0) {
let str = ' '.repeat(indent);
str += tagToString(obj.tag) + ' ';
if (obj.tag.isUniversal()) {
switch (obj.tag.number) {
case tag_1.UNIVERSAL_TAG.BOOLEAN:
str += obj.toBoolean();
break;
case tag_1.UNIVERSAL_TAG.INTEGER:
str += `(${obj.value.length} byte) `;
str += obj.toInteger();
break;
case tag_1.UNIVERSAL_TAG.BIT_STRING: {
const bits = obj.toBitString();
str += `(${bits.length} bit) `;
str += truncate(bits.map((bit) => bit.toString()).join(''));
break;
}
case tag_1.UNIVERSAL_TAG.OBJECT_IDENTIFIER:
str += obj.toOID();
break;
case tag_1.UNIVERSAL_TAG.SEQUENCE:
case tag_1.UNIVERSAL_TAG.SET:
str += `(${obj.subs.length} elem) `;
break;
case tag_1.UNIVERSAL_TAG.PRINTABLE_STRING:
str += obj.value.toString('ascii');
break;
case tag_1.UNIVERSAL_TAG.UTC_TIME:
case tag_1.UNIVERSAL_TAG.GENERALIZED_TIME:
str += obj.toDate().toUTCString();
break;
default:
str += `(${obj.value.length} byte) `;
str += isASCII(obj.value)
? obj.value.toString('ascii')
: truncate(obj.value.toString('hex').toUpperCase());
}
}
else {
if (obj.tag.constructed) {
str += `(${obj.subs.length} elem) `;
}
else {
str += `(${obj.value.length} byte) `;
str += isASCII(obj.value)
? obj.value.toString('ascii')
: obj.value.toString('hex').toUpperCase();
}
}
console.log(str);
// Recursive call for children
obj.subs.forEach((sub) => dump(sub, indent + 2));
}
exports.dump = dump;
function tagToString(tag) {
if (tag.isContextSpecific()) {
return `[${tag.number.toString(16)}]`;
}
else {
switch (tag.number) {
case tag_1.UNIVERSAL_TAG.BOOLEAN:
return 'BOOLEAN';
case tag_1.UNIVERSAL_TAG.INTEGER:
return 'INTEGER';
case tag_1.UNIVERSAL_TAG.BIT_STRING:
return 'BIT STRING';
case tag_1.UNIVERSAL_TAG.OCTET_STRING:
return 'OCTET STRING';
case tag_1.UNIVERSAL_TAG.OBJECT_IDENTIFIER:
return 'OBJECT IDENTIFIER';
case tag_1.UNIVERSAL_TAG.SEQUENCE:
return 'SEQUENCE';
case tag_1.UNIVERSAL_TAG.SET:
return 'SET';
case tag_1.UNIVERSAL_TAG.PRINTABLE_STRING:
return 'PrintableString';
case tag_1.UNIVERSAL_TAG.UTC_TIME:
return 'UTCTime';
case tag_1.UNIVERSAL_TAG.GENERALIZED_TIME:
return 'GeneralizedTime';
default:
return tag.number.toString(16);
}
}
}
function isASCII(buf) {
return buf.every((b) => b >= 32 && b <= 126);
}
function truncate(str) {
return str.length > 70 ? str.substring(0, 69) + '...' : str;
}

4
spa/node_modules/sigstore/dist/util/asn1/error.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
export declare class ASN1ParseError extends Error {
}
export declare class ASN1TypeError extends Error {
}

24
spa/node_modules/sigstore/dist/util/asn1/error.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASN1TypeError = exports.ASN1ParseError = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
class ASN1ParseError extends Error {
}
exports.ASN1ParseError = ASN1ParseError;
class ASN1TypeError extends Error {
}
exports.ASN1TypeError = ASN1TypeError;

1
spa/node_modules/sigstore/dist/util/asn1/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export { ASN1Obj } from './obj';

20
spa/node_modules/sigstore/dist/util/asn1/index.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASN1Obj = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var obj_1 = require("./obj");
Object.defineProperty(exports, "ASN1Obj", { enumerable: true, get: function () { return obj_1.ASN1Obj; } });

4
spa/node_modules/sigstore/dist/util/asn1/length.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
/// <reference types="node" />
import { ByteStream } from '../stream';
export declare function decodeLength(stream: ByteStream): number;
export declare function encodeLength(len: number): Buffer;

63
spa/node_modules/sigstore/dist/util/asn1/length.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
"use strict";
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeLength = exports.decodeLength = void 0;
const error_1 = require("./error");
// Decodes the length of a DER-encoded ANS.1 element from the supplied stream.
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-length-and-value-bytes
function decodeLength(stream) {
const buf = stream.getUint8();
// If the most significant bit is UNSET the length is just the value of the
// byte.
if ((buf & 0x80) === 0x00) {
return buf;
}
// Otherwise, the lower 7 bits of the first byte indicate the number of bytes
// that follow to encode the length.
const byteCount = buf & 0x7f;
// Ensure the encoded length can safely fit in a JS number.
if (byteCount > 6) {
throw new error_1.ASN1ParseError('length exceeds 6 byte limit');
}
// Iterate over the bytes that encode the length.
let len = 0;
for (let i = 0; i < byteCount; i++) {
len = len * 256 + stream.getUint8();
}
// This is a valid ASN.1 length encoding, but we don't support it.
if (len === 0) {
throw new error_1.ASN1ParseError('indefinite length encoding not supported');
}
return len;
}
exports.decodeLength = decodeLength;
// Translates the supplied value to a DER-encoded length.
function encodeLength(len) {
if (len < 128) {
return Buffer.from([len]);
}
// Bitwise operations on large numbers are not supported in JS, so we need to
// use BigInts.
let val = BigInt(len);
const bytes = [];
while (val > 0n) {
bytes.unshift(Number(val & 255n));
val = val >> 8n;
}
return Buffer.from([0x80 | bytes.length, ...bytes]);
}
exports.encodeLength = encodeLength;

15
spa/node_modules/sigstore/dist/util/asn1/obj.d.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
/// <reference types="node" />
import { ASN1Tag } from './tag';
export declare class ASN1Obj {
readonly tag: ASN1Tag;
readonly subs: ASN1Obj[];
readonly value: Buffer;
constructor(tag: ASN1Tag, value: Buffer, subs: ASN1Obj[]);
static parseBuffer(buf: Buffer): ASN1Obj;
toDER(): Buffer;
toBoolean(): boolean;
toInteger(): bigint;
toOID(): string;
toDate(): Date;
toBitString(): number[];
}

152
spa/node_modules/sigstore/dist/util/asn1/obj.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASN1Obj = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const stream_1 = require("../stream");
const error_1 = require("./error");
const length_1 = require("./length");
const parse_1 = require("./parse");
const tag_1 = require("./tag");
class ASN1Obj {
constructor(tag, value, subs) {
this.tag = tag;
this.value = value;
this.subs = subs;
}
// Constructs an ASN.1 object from a Buffer of DER-encoded bytes.
static parseBuffer(buf) {
return parseStream(new stream_1.ByteStream(buf));
}
toDER() {
const valueStream = new stream_1.ByteStream();
if (this.subs.length > 0) {
for (const sub of this.subs) {
valueStream.appendView(sub.toDER());
}
}
else {
valueStream.appendView(this.value);
}
const value = valueStream.buffer;
// Concat tag/length/value
const obj = new stream_1.ByteStream();
obj.appendChar(this.tag.toDER());
obj.appendView((0, length_1.encodeLength)(value.length));
obj.appendView(value);
return obj.buffer;
}
/////////////////////////////////////////////////////////////////////////////
// Convenience methods for parsing ASN.1 primitives into JS types
// Returns the ASN.1 object's value as a boolean. Throws an error if the
// object is not a boolean.
toBoolean() {
if (!this.tag.isBoolean()) {
throw new error_1.ASN1TypeError('not a boolean');
}
return (0, parse_1.parseBoolean)(this.value);
}
// Returns the ASN.1 object's value as a BigInt. Throws an error if the
// object is not an integer.
toInteger() {
if (!this.tag.isInteger()) {
throw new error_1.ASN1TypeError('not an integer');
}
return (0, parse_1.parseInteger)(this.value);
}
// Returns the ASN.1 object's value as an OID string. Throws an error if the
// object is not an OID.
toOID() {
if (!this.tag.isOID()) {
throw new error_1.ASN1TypeError('not an OID');
}
return (0, parse_1.parseOID)(this.value);
}
// Returns the ASN.1 object's value as a Date. Throws an error if the object
// is not either a UTCTime or a GeneralizedTime.
toDate() {
switch (true) {
case this.tag.isUTCTime():
return (0, parse_1.parseTime)(this.value, true);
case this.tag.isGeneralizedTime():
return (0, parse_1.parseTime)(this.value, false);
default:
throw new error_1.ASN1TypeError('not a date');
}
}
// Returns the ASN.1 object's value as a number[] where each number is the
// value of a bit in the bit string. Throws an error if the object is not a
// bit string.
toBitString() {
if (!this.tag.isBitString()) {
throw new error_1.ASN1TypeError('not a bit string');
}
return (0, parse_1.parseBitString)(this.value);
}
}
exports.ASN1Obj = ASN1Obj;
/////////////////////////////////////////////////////////////////////////////
// Internal stream parsing functions
function parseStream(stream) {
// Parse tag, length, and value from stream
const tag = new tag_1.ASN1Tag(stream.getUint8());
const len = (0, length_1.decodeLength)(stream);
const value = stream.slice(stream.position, len);
const start = stream.position;
let subs = [];
// If the object is constructed, parse its children. Sometimes, children
// are embedded in OCTESTRING objects, so we need to check those
// for children as well.
if (tag.constructed) {
subs = collectSubs(stream, len);
}
else if (tag.isOctetString()) {
// Attempt to parse children of OCTETSTRING objects. If anything fails,
// assume the object is not constructed and treat as primitive.
try {
subs = collectSubs(stream, len);
}
catch (e) {
// Fail silently and treat as primitive
}
}
// If there are no children, move stream cursor to the end of the object
if (subs.length === 0) {
stream.seek(start + len);
}
return new ASN1Obj(tag, value, subs);
}
function collectSubs(stream, len) {
// Calculate end of object content
const end = stream.position + len;
// Make sure there are enough bytes left in the stream. This should never
// happen, cause it'll get caught when the stream is sliced in parseStream.
// Leaving as an extra check just in case.
/* istanbul ignore if */
if (end > stream.length) {
throw new error_1.ASN1ParseError('invalid length');
}
// Parse all children
const subs = [];
while (stream.position < end) {
subs.push(parseStream(stream));
}
// When we're done parsing children, we should be at the end of the object
if (stream.position !== end) {
throw new error_1.ASN1ParseError('invalid length');
}
return subs;
}

7
spa/node_modules/sigstore/dist/util/asn1/parse.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/// <reference types="node" />
export declare function parseInteger(buf: Buffer): bigint;
export declare function parseStringASCII(buf: Buffer): string;
export declare function parseTime(buf: Buffer, shortYear: boolean): Date;
export declare function parseOID(buf: Buffer): string;
export declare function parseBoolean(buf: Buffer): boolean;
export declare function parseBitString(buf: Buffer): number[];

125
spa/node_modules/sigstore/dist/util/asn1/parse.js generated vendored Normal file
View File

@@ -0,0 +1,125 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseBitString = exports.parseBoolean = exports.parseOID = exports.parseTime = exports.parseStringASCII = exports.parseInteger = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const RE_TIME_SHORT_YEAR = /^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/;
const RE_TIME_LONG_YEAR = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/;
// Parse a BigInt from the DER-encoded buffer
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-integer
function parseInteger(buf) {
let pos = 0;
const end = buf.length;
let val = buf[pos];
const neg = val > 0x7f;
// Consume any padding bytes
const pad = neg ? 0xff : 0x00;
while (val == pad && ++pos < end) {
val = buf[pos];
}
// Calculate remaining bytes to read
const len = end - pos;
if (len === 0)
return BigInt(neg ? -1 : 0);
// Handle two's complement for negative numbers
val = neg ? val - 256 : val;
// Parse remaining bytes
let n = BigInt(val);
for (let i = pos + 1; i < end; ++i) {
n = n * BigInt(256) + BigInt(buf[i]);
}
return n;
}
exports.parseInteger = parseInteger;
// Parse an ASCII string from the DER-encoded buffer
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-basic-types#boolean
function parseStringASCII(buf) {
return buf.toString('ascii');
}
exports.parseStringASCII = parseStringASCII;
// Parse a Date from the DER-encoded buffer
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5.1
function parseTime(buf, shortYear) {
const timeStr = parseStringASCII(buf);
// Parse the time string into matches - captured groups start at index 1
const m = shortYear
? RE_TIME_SHORT_YEAR.exec(timeStr)
: RE_TIME_LONG_YEAR.exec(timeStr);
if (!m) {
throw new Error('invalid time');
}
// Translate dates with a 2-digit year to 4 digits per the spec
if (shortYear) {
let year = Number(m[1]);
year += year >= 50 ? 1900 : 2000;
m[1] = year.toString();
}
// Translate to ISO8601 format and parse
return new Date(`${m[1]}-${m[2]}-${m[3]}T${m[4]}:${m[5]}:${m[6]}Z`);
}
exports.parseTime = parseTime;
// Parse an OID from the DER-encoded buffer
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier
function parseOID(buf) {
let pos = 0;
const end = buf.length;
// Consume first byte which encodes the first two OID components
let n = buf[pos++];
const first = Math.floor(n / 40);
const second = n % 40;
let oid = `${first}.${second}`;
// Consume remaining bytes
let val = 0;
for (; pos < end; ++pos) {
n = buf[pos];
val = (val << 7) + (n & 0x7f);
// If the left-most bit is NOT set, then this is the last byte in the
// sequence and we can add the value to the OID and reset the accumulator
if ((n & 0x80) === 0) {
oid += `.${val}`;
val = 0;
}
}
return oid;
}
exports.parseOID = parseOID;
// Parse a boolean from the DER-encoded buffer
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-basic-types#boolean
function parseBoolean(buf) {
return buf[0] !== 0;
}
exports.parseBoolean = parseBoolean;
// Parse a bit string from the DER-encoded buffer
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-bit-string
function parseBitString(buf) {
// First byte tell us how many unused bits are in the last byte
const unused = buf[0];
const start = 1;
const end = buf.length;
const bits = [];
for (let i = start; i < end; ++i) {
const byte = buf[i];
// The skip value is only used for the last byte
const skip = i === end - 1 ? unused : 0;
// Iterate over each bit in the byte (most significant first)
for (let j = 7; j >= skip; --j) {
// Read the bit and add it to the bit string
bits.push((byte >> j) & 0x01);
}
}
return bits;
}
exports.parseBitString = parseBitString;

28
spa/node_modules/sigstore/dist/util/asn1/tag.d.ts generated vendored Normal file
View File

@@ -0,0 +1,28 @@
export declare const UNIVERSAL_TAG: {
BOOLEAN: number;
INTEGER: number;
BIT_STRING: number;
OCTET_STRING: number;
OBJECT_IDENTIFIER: number;
SEQUENCE: number;
SET: number;
PRINTABLE_STRING: number;
UTC_TIME: number;
GENERALIZED_TIME: number;
};
export declare class ASN1Tag {
readonly number: number;
readonly constructed: boolean;
readonly class: number;
constructor(enc: number);
isUniversal(): boolean;
isContextSpecific(num?: number): boolean;
isBoolean(): boolean;
isInteger(): boolean;
isBitString(): boolean;
isOctetString(): boolean;
isOID(): boolean;
isUTCTime(): boolean;
isGeneralizedTime(): boolean;
toDER(): number;
}

86
spa/node_modules/sigstore/dist/util/asn1/tag.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ASN1Tag = exports.UNIVERSAL_TAG = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("./error");
exports.UNIVERSAL_TAG = {
BOOLEAN: 0x01,
INTEGER: 0x02,
BIT_STRING: 0x03,
OCTET_STRING: 0x04,
OBJECT_IDENTIFIER: 0x06,
SEQUENCE: 0x10,
SET: 0x11,
PRINTABLE_STRING: 0x13,
UTC_TIME: 0x17,
GENERALIZED_TIME: 0x18,
};
const TAG_CLASS = {
UNIVERSAL: 0x00,
APPLICATION: 0x01,
CONTEXT_SPECIFIC: 0x02,
PRIVATE: 0x03,
};
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-encoded-tag-bytes
class ASN1Tag {
constructor(enc) {
// Bits 0 through 4 are the tag number
this.number = enc & 0x1f;
// Bit 5 is the constructed bit
this.constructed = (enc & 0x20) === 0x20;
// Bit 6 & 7 are the class
this.class = enc >> 6;
if (this.number === 0x1f) {
throw new error_1.ASN1ParseError('long form tags not supported');
}
if (this.class === TAG_CLASS.UNIVERSAL && this.number === 0x00) {
throw new error_1.ASN1ParseError('unsupported tag 0x00');
}
}
isUniversal() {
return this.class === TAG_CLASS.UNIVERSAL;
}
isContextSpecific(num) {
const res = this.class === TAG_CLASS.CONTEXT_SPECIFIC;
return num !== undefined ? res && this.number === num : res;
}
isBoolean() {
return this.isUniversal() && this.number === exports.UNIVERSAL_TAG.BOOLEAN;
}
isInteger() {
return this.isUniversal() && this.number === exports.UNIVERSAL_TAG.INTEGER;
}
isBitString() {
return this.isUniversal() && this.number === exports.UNIVERSAL_TAG.BIT_STRING;
}
isOctetString() {
return this.isUniversal() && this.number === exports.UNIVERSAL_TAG.OCTET_STRING;
}
isOID() {
return (this.isUniversal() && this.number === exports.UNIVERSAL_TAG.OBJECT_IDENTIFIER);
}
isUTCTime() {
return this.isUniversal() && this.number === exports.UNIVERSAL_TAG.UTC_TIME;
}
isGeneralizedTime() {
return this.isUniversal() && this.number === exports.UNIVERSAL_TAG.GENERALIZED_TIME;
}
toDER() {
return this.number | (this.constructed ? 0x20 : 0x00) | (this.class << 6);
}
}
exports.ASN1Tag = ASN1Tag;

8
spa/node_modules/sigstore/dist/util/crypto.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/// <reference types="node" />
/// <reference types="node" />
import { BinaryLike, KeyLike } from 'crypto';
export declare function createPublicKey(key: string | Buffer): KeyLike;
export declare function verifyBlob(data: Buffer, key: KeyLike, signature: Buffer, algorithm?: string): boolean;
export declare function hash(data: BinaryLike): Buffer;
export declare function randomBytes(count: number): Buffer;
export declare function bufferEqual(a: Buffer, b: Buffer): boolean;

63
spa/node_modules/sigstore/dist/util/crypto.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.bufferEqual = exports.randomBytes = exports.hash = exports.verifyBlob = exports.createPublicKey = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const crypto_1 = __importDefault(require("crypto"));
const SHA256_ALGORITHM = 'sha256';
function createPublicKey(key) {
if (typeof key === 'string') {
return crypto_1.default.createPublicKey(key);
}
else {
return crypto_1.default.createPublicKey({ key, format: 'der', type: 'spki' });
}
}
exports.createPublicKey = createPublicKey;
function verifyBlob(data, key, signature, algorithm) {
// The try/catch is to work around an issue in Node 14.x where verify throws
// an error in some scenarios if the signature is invalid.
try {
return crypto_1.default.verify(algorithm, data, key, signature);
}
catch (e) {
/* istanbul ignore next */
return false;
}
}
exports.verifyBlob = verifyBlob;
function hash(data) {
const hash = crypto_1.default.createHash(SHA256_ALGORITHM);
return hash.update(data).digest();
}
exports.hash = hash;
function randomBytes(count) {
return crypto_1.default.randomBytes(count);
}
exports.randomBytes = randomBytes;
function bufferEqual(a, b) {
try {
return crypto_1.default.timingSafeEqual(a, b);
}
catch {
/* istanbul ignore next */
return false;
}
}
exports.bufferEqual = bufferEqual;

2
spa/node_modules/sigstore/dist/util/dsse.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
/// <reference types="node" />
export declare function preAuthEncoding(payloadType: string, payload: Buffer): Buffer;

25
spa/node_modules/sigstore/dist/util/dsse.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.preAuthEncoding = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PAE_PREFIX = 'DSSEv1';
// DSSE Pre-Authentication Encoding
function preAuthEncoding(payloadType, payload) {
const prefix = Buffer.from(`${PAE_PREFIX} ${payloadType.length} ${payloadType} ${payload.length} `, 'ascii');
return Buffer.concat([prefix, payload]);
}
exports.preAuthEncoding = preAuthEncoding;

6
spa/node_modules/sigstore/dist/util/encoding.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
export declare function base64Encode(str: string): string;
export declare function base64Decode(str: string): string;
export declare function base64URLEncode(str: string): string;
export declare function base64URLDecode(str: string): string;
export declare function base64URLEscape(str: string): string;
export declare function base64URLUnescape(str: string): string;

46
spa/node_modules/sigstore/dist/util/encoding.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.base64URLUnescape = exports.base64URLEscape = exports.base64URLDecode = exports.base64URLEncode = exports.base64Decode = exports.base64Encode = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const BASE64_ENCODING = 'base64';
const UTF8_ENCODING = 'utf-8';
function base64Encode(str) {
return Buffer.from(str, UTF8_ENCODING).toString(BASE64_ENCODING);
}
exports.base64Encode = base64Encode;
function base64Decode(str) {
return Buffer.from(str, BASE64_ENCODING).toString(UTF8_ENCODING);
}
exports.base64Decode = base64Decode;
function base64URLEncode(str) {
return base64URLEscape(base64Encode(str));
}
exports.base64URLEncode = base64URLEncode;
function base64URLDecode(str) {
return base64Decode(base64URLUnescape(str));
}
exports.base64URLDecode = base64URLDecode;
function base64URLEscape(str) {
return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
exports.base64URLEscape = base64URLEscape;
function base64URLUnescape(str) {
// Repad the base64 string if necessary
str += '='.repeat((4 - (str.length % 4)) % 4);
return str.replace(/-/g, '+').replace(/_/g, '/');
}
exports.base64URLUnescape = base64URLUnescape;

6
spa/node_modules/sigstore/dist/util/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
export * as asn1 from './asn1';
export * as crypto from './crypto';
export * as dsse from './dsse';
export * as encoding from './encoding';
export * as json from './json';
export * as pem from './pem';

47
spa/node_modules/sigstore/dist/util/index.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pem = exports.json = exports.encoding = exports.dsse = exports.crypto = exports.asn1 = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
exports.asn1 = __importStar(require("./asn1"));
exports.crypto = __importStar(require("./crypto"));
exports.dsse = __importStar(require("./dsse"));
exports.encoding = __importStar(require("./encoding"));
exports.json = __importStar(require("./json"));
exports.pem = __importStar(require("./pem"));

1
spa/node_modules/sigstore/dist/util/json.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare function canonicalize(object: any): string;

61
spa/node_modules/sigstore/dist/util/json.js generated vendored Normal file
View File

@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.canonicalize = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// JSON canonicalization per https://github.com/cyberphone/json-canonicalization
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function canonicalize(object) {
let buffer = '';
if (object === null || typeof object !== 'object' || object.toJSON != null) {
// Primitives or toJSONable objects
buffer += JSON.stringify(object);
}
else if (Array.isArray(object)) {
// Array - maintain element order
buffer += '[';
let first = true;
object.forEach((element) => {
if (!first) {
buffer += ',';
}
first = false;
// recursive call
buffer += canonicalize(element);
});
buffer += ']';
}
else {
// Object - Sort properties before serializing
buffer += '{';
let first = true;
Object.keys(object)
.sort()
.forEach((property) => {
if (!first) {
buffer += ',';
}
first = false;
buffer += JSON.stringify(property);
buffer += ':';
// recursive call
buffer += canonicalize(object[property]);
});
buffer += '}';
}
return buffer;
}
exports.canonicalize = canonicalize;

3
spa/node_modules/sigstore/dist/util/pem.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
/// <reference types="node" />
export declare function toDER(certificate: string): Buffer;
export declare function fromDER(certificate: Buffer, type?: string): string;

44
spa/node_modules/sigstore/dist/util/pem.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fromDER = exports.toDER = void 0;
/*
Copyright 2022 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const PEM_HEADER = /-----BEGIN (.*)-----/;
const PEM_FOOTER = /-----END (.*)-----/;
function toDER(certificate) {
let der = '';
certificate.split('\n').forEach((line) => {
if (line.match(PEM_HEADER) || line.match(PEM_FOOTER)) {
return;
}
der += line;
});
return Buffer.from(der, 'base64');
}
exports.toDER = toDER;
// Translates a DER-encoded buffer into a PEM-encoded string. Standard PEM
// encoding dictates that each certificate should have a trailing newline after
// the footer.
function fromDER(certificate, type = 'CERTIFICATE') {
// Base64-encode the certificate.
const der = certificate.toString('base64');
// Split the certificate into lines of 64 characters.
const lines = der.match(/.{1,64}/g) || '';
return [`-----BEGIN ${type}-----`, ...lines, `-----END ${type}-----`]
.join('\n')
.concat('\n');
}
exports.fromDER = fromDER;

24
spa/node_modules/sigstore/dist/util/stream.d.ts generated vendored Normal file
View File

@@ -0,0 +1,24 @@
/// <reference types="node" />
export declare class StreamError extends Error {
}
export declare class ByteStream {
private static BLOCK_SIZE;
private buf;
private view;
private start;
constructor(buffer?: ArrayBuffer);
get buffer(): Buffer;
get length(): number;
get position(): number;
seek(position: number): void;
slice(start: number, len: number): Buffer;
appendChar(char: number): void;
appendUint16(num: number): void;
appendUint24(num: number): void;
appendView(view: Uint8Array): void;
getBlock(size: number): Buffer;
getUint8(): number;
getUint16(): number;
private ensureCapacity;
private realloc;
}

116
spa/node_modules/sigstore/dist/util/stream.js generated vendored Normal file
View File

@@ -0,0 +1,116 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ByteStream = exports.StreamError = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
class StreamError extends Error {
}
exports.StreamError = StreamError;
class ByteStream {
constructor(buffer) {
this.start = 0;
if (buffer) {
this.buf = buffer;
this.view = Buffer.from(buffer);
}
else {
this.buf = new ArrayBuffer(0);
this.view = Buffer.from(this.buf);
}
}
get buffer() {
return this.view.subarray(0, this.start);
}
get length() {
return this.view.byteLength;
}
get position() {
return this.start;
}
seek(position) {
this.start = position;
}
// Returns a Buffer containing the specified number of bytes starting at the
// given start position.
slice(start, len) {
const end = start + len;
if (end > this.length) {
throw new StreamError('request past end of buffer');
}
return this.view.subarray(start, end);
}
appendChar(char) {
this.ensureCapacity(1);
this.view[this.start] = char;
this.start += 1;
}
appendUint16(num) {
this.ensureCapacity(2);
const value = new Uint16Array([num]);
const view = new Uint8Array(value.buffer);
this.view[this.start] = view[1];
this.view[this.start + 1] = view[0];
this.start += 2;
}
appendUint24(num) {
this.ensureCapacity(3);
const value = new Uint32Array([num]);
const view = new Uint8Array(value.buffer);
this.view[this.start] = view[2];
this.view[this.start + 1] = view[1];
this.view[this.start + 2] = view[0];
this.start += 3;
}
appendView(view) {
this.ensureCapacity(view.length);
this.view.set(view, this.start);
this.start += view.length;
}
getBlock(size) {
if (size <= 0) {
return Buffer.alloc(0);
}
if (this.start + size > this.view.length) {
throw new Error('request past end of buffer');
}
const result = this.view.subarray(this.start, this.start + size);
this.start += size;
return result;
}
getUint8() {
return this.getBlock(1)[0];
}
getUint16() {
const block = this.getBlock(2);
return (block[0] << 8) | block[1];
}
ensureCapacity(size) {
if (this.start + size > this.view.byteLength) {
const blockSize = ByteStream.BLOCK_SIZE + (size > ByteStream.BLOCK_SIZE ? size : 0);
this.realloc(this.view.byteLength + blockSize);
}
}
realloc(size) {
const newArray = new ArrayBuffer(size);
const newView = Buffer.from(newArray);
// Copy the old buffer into the new one
newView.set(this.view);
this.buf = newArray;
this.view = newView;
}
}
exports.ByteStream = ByteStream;
ByteStream.BLOCK_SIZE = 1024;

14
spa/node_modules/sigstore/dist/verify.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/// <reference types="node" />
import { Bundle } from '@sigstore/bundle';
import * as sigstore from './types/sigstore';
export type KeySelector = (hint: string) => string | Buffer | undefined;
export declare class Verifier {
private trustedRoot;
private keySelector;
constructor(trustedRoot: sigstore.TrustedRoot, keySelector?: KeySelector);
verify(bundle: Bundle, options: sigstore.RequiredArtifactVerificationOptions, data?: Buffer): void;
private verifyArtifactSignature;
private verifySigningCertificate;
private verifyTLogEntries;
private getPublicKey;
}

160
spa/node_modules/sigstore/dist/verify.js generated vendored Normal file
View File

@@ -0,0 +1,160 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Verifier = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const bundle_1 = require("@sigstore/bundle");
const ca = __importStar(require("./ca/verify"));
const error_1 = require("./error");
const tlog = __importStar(require("./tlog/verify"));
const sigstore = __importStar(require("./types/sigstore"));
const util_1 = require("./util");
class Verifier {
constructor(trustedRoot, keySelector) {
this.trustedRoot = trustedRoot;
this.keySelector = keySelector || (() => undefined);
}
// Verifies the bundle signature, the bundle's certificate chain (if present)
// and the bundle's transparency log entries.
verify(bundle, options, data) {
this.verifyArtifactSignature(bundle, data);
if ((0, bundle_1.isBundleWithCertificateChain)(bundle)) {
this.verifySigningCertificate(bundle, options);
}
if (options.tlogOptions.disable === false) {
this.verifyTLogEntries(bundle, options);
}
}
// Performs bundle signature verification. Determines the type of the bundle
// content and delegates to the appropriate signature verification function.
verifyArtifactSignature(bundle, data) {
const publicKey = this.getPublicKey(bundle);
switch (bundle.content?.$case) {
case 'messageSignature':
if (!data) {
throw new error_1.VerificationError('no data provided for message signature verification');
}
verifyMessageSignature(data, bundle.content.messageSignature, publicKey);
break;
case 'dsseEnvelope':
verifyDSSESignature(bundle.content.dsseEnvelope, publicKey);
break;
}
}
// Performs verification of the bundle's certificate chain. The bundle must
// contain a certificate chain and the options must contain the required
// options for CA verification.
// TODO: We've temporarily removed the requirement that the options contain
// the list of trusted signer identities. This will be added back in a future
// release.
verifySigningCertificate(bundle, options) {
if (!sigstore.isCAVerificationOptions(options)) {
throw new error_1.VerificationError('no trusted certificates provided for verification');
}
ca.verifySigningCertificate(bundle, this.trustedRoot, options);
}
// Performs verification of the bundle's transparency log entries. The bundle
// must contain a list of transparency log entries.
verifyTLogEntries(bundle, options) {
tlog.verifyTLogEntries(bundle, this.trustedRoot, options.tlogOptions);
}
// Returns the public key which will be used to verify the bundle signature.
// The public key is selected based on the verification material in the bundle
// and the options provided.
getPublicKey(bundle) {
// Select the key which will be used to verify the signature
switch (bundle.verificationMaterial?.content?.$case) {
// If the bundle contains a certificate chain, the public key is the
// first certificate in the chain (the signing certificate)
case 'x509CertificateChain':
return getPublicKeyFromCertificateChain(bundle.verificationMaterial.content.x509CertificateChain);
// If the bundle contains a public key hint, the public key is selected
// from the list of trusted keys in the options
case 'publicKey':
return getPublicKeyFromHint(bundle.verificationMaterial.content.publicKey, this.keySelector);
}
}
}
exports.Verifier = Verifier;
// Retrieves the public key from the first certificate in the certificate chain
function getPublicKeyFromCertificateChain(certificateChain) {
const cert = util_1.pem.fromDER(certificateChain.certificates[0].rawBytes);
return util_1.crypto.createPublicKey(cert);
}
// Retrieves the public key through the key selector callback, passing the
// public key hint from the bundle
function getPublicKeyFromHint(publicKeyID, keySelector) {
const key = keySelector(publicKeyID.hint);
if (!key) {
throw new error_1.VerificationError('no public key found for signature verification');
}
try {
return util_1.crypto.createPublicKey(key);
}
catch (e) {
throw new error_1.VerificationError('invalid public key');
}
}
// Performs signature verification for bundle containing a message signature.
// Verifies that the digest and signature found in the bundle match the
// provided data.
function verifyMessageSignature(data, messageSignature, publicKey) {
// Extract signature for message
const { signature, messageDigest } = messageSignature;
const calculatedDigest = util_1.crypto.hash(data);
if (!calculatedDigest.equals(messageDigest.digest)) {
throw new error_1.VerificationError('message digest verification failed');
}
if (!util_1.crypto.verifyBlob(data, publicKey, signature)) {
throw new error_1.VerificationError('artifact signature verification failed');
}
}
// Performs signature verification for bundle containing a DSSE envelope.
// Calculates the PAE for the DSSE envelope and verifies it against the
// signature in the envelope.
function verifyDSSESignature(envelope, publicKey) {
// Construct payload over which the signature was originally created
const { payloadType, payload } = envelope;
const data = util_1.dsse.preAuthEncoding(payloadType, payload);
// Only support a single signature in DSSE
const signature = envelope.signatures[0].sig;
if (!util_1.crypto.verifyBlob(data, publicKey, signature)) {
throw new error_1.VerificationError('artifact signature verification failed');
}
}

48
spa/node_modules/sigstore/dist/x509/cert.d.ts generated vendored Normal file
View File

@@ -0,0 +1,48 @@
/// <reference types="node" />
import * as sigstore from '../types/sigstore';
import { ASN1Obj } from '../util/asn1';
import { x509AuthorityKeyIDExtension, x509BasicConstraintsExtension, x509Extension, x509KeyUsageExtension, x509SCTExtension, x509SubjectAlternativeNameExtension, x509SubjectKeyIDExtension } from './ext';
interface SCTVerificationResult {
verified: boolean;
logID: Buffer;
}
export declare class x509Certificate {
root: ASN1Obj;
constructor(asn1: ASN1Obj);
static parse(cert: Buffer | string): x509Certificate;
get tbsCertificate(): ASN1Obj;
get version(): string;
get notBefore(): Date;
get notAfter(): Date;
get issuer(): Buffer;
get subject(): Buffer;
get publicKey(): Buffer;
get signatureAlgorithm(): string;
get signatureValue(): Buffer;
get extensions(): ASN1Obj[];
get extKeyUsage(): x509KeyUsageExtension | undefined;
get extBasicConstraints(): x509BasicConstraintsExtension | undefined;
get extSubjectAltName(): x509SubjectAlternativeNameExtension | undefined;
get extAuthorityKeyID(): x509AuthorityKeyIDExtension | undefined;
get extSubjectKeyID(): x509SubjectKeyIDExtension | undefined;
get extSCT(): x509SCTExtension | undefined;
get isCA(): boolean;
extension(oid: string): x509Extension | undefined;
verify(issuerCertificate?: x509Certificate): boolean;
validForDate(date: Date): boolean;
equals(other: x509Certificate): boolean;
verifySCTs(issuer: x509Certificate, logs: sigstore.TransparencyLogInstance[]): SCTVerificationResult[];
private clone;
private findExtension;
private checkRecognizedExtensions;
private get tbsCertificateObj();
private get signatureAlgorithmObj();
private get signatureValueObj();
private get versionObj();
private get issuerObj();
private get validityObj();
private get subjectObj();
private get subjectPublicKeyInfoObj();
private get extensionsObj();
}
export {};

242
spa/node_modules/sigstore/dist/x509/cert.js generated vendored Normal file
View File

@@ -0,0 +1,242 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x509Certificate = void 0;
const util_1 = require("../util");
const asn1_1 = require("../util/asn1");
const stream_1 = require("../util/stream");
const ext_1 = require("./ext");
const EXTENSION_OID_SUBJECT_KEY_ID = '2.5.29.14';
const EXTENSION_OID_KEY_USAGE = '2.5.29.15';
const EXTENSION_OID_SUBJECT_ALT_NAME = '2.5.29.17';
const EXTENSION_OID_BASIC_CONSTRAINTS = '2.5.29.19';
const EXTENSION_OID_AUTHORITY_KEY_ID = '2.5.29.35';
const EXTENSION_OID_SCT = '1.3.6.1.4.1.11129.2.4.2';
// List of recognized critical extensions
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2
const RECOGNIZED_EXTENSIONS = [
EXTENSION_OID_KEY_USAGE,
EXTENSION_OID_BASIC_CONSTRAINTS,
EXTENSION_OID_SUBJECT_ALT_NAME,
];
const ECDSA_SIGNATURE_ALGOS = {
'1.2.840.10045.4.3.1': 'sha224',
'1.2.840.10045.4.3.2': 'sha256',
'1.2.840.10045.4.3.3': 'sha384',
'1.2.840.10045.4.3.4': 'sha512',
};
class x509Certificate {
constructor(asn1) {
this.root = asn1;
if (!this.checkRecognizedExtensions()) {
throw new Error('Certificate contains unrecognized critical extensions');
}
}
static parse(cert) {
const der = typeof cert === 'string' ? util_1.pem.toDER(cert) : cert;
const asn1 = asn1_1.ASN1Obj.parseBuffer(der);
return new x509Certificate(asn1);
}
get tbsCertificate() {
return this.tbsCertificateObj;
}
get version() {
// version number is the first element of the version context specific tag
const ver = this.versionObj.subs[0].toInteger();
return `v${(ver + BigInt(1)).toString()}`;
}
get notBefore() {
// notBefore is the first element of the validity sequence
return this.validityObj.subs[0].toDate();
}
get notAfter() {
// notAfter is the second element of the validity sequence
return this.validityObj.subs[1].toDate();
}
get issuer() {
return this.issuerObj.value;
}
get subject() {
return this.subjectObj.value;
}
get publicKey() {
return this.subjectPublicKeyInfoObj.toDER();
}
get signatureAlgorithm() {
const oid = this.signatureAlgorithmObj.subs[0].toOID();
return ECDSA_SIGNATURE_ALGOS[oid];
}
get signatureValue() {
// Signature value is a bit string, so we need to skip the first byte
return this.signatureValueObj.value.subarray(1);
}
get extensions() {
// The extension list is the first (and only) element of the extensions
// context specific tag
const extSeq = this.extensionsObj?.subs[0];
return extSeq?.subs || [];
}
get extKeyUsage() {
const ext = this.findExtension(EXTENSION_OID_KEY_USAGE);
return ext ? new ext_1.x509KeyUsageExtension(ext) : undefined;
}
get extBasicConstraints() {
const ext = this.findExtension(EXTENSION_OID_BASIC_CONSTRAINTS);
return ext ? new ext_1.x509BasicConstraintsExtension(ext) : undefined;
}
get extSubjectAltName() {
const ext = this.findExtension(EXTENSION_OID_SUBJECT_ALT_NAME);
return ext ? new ext_1.x509SubjectAlternativeNameExtension(ext) : undefined;
}
get extAuthorityKeyID() {
const ext = this.findExtension(EXTENSION_OID_AUTHORITY_KEY_ID);
return ext ? new ext_1.x509AuthorityKeyIDExtension(ext) : undefined;
}
get extSubjectKeyID() {
const ext = this.findExtension(EXTENSION_OID_SUBJECT_KEY_ID);
return ext ? new ext_1.x509SubjectKeyIDExtension(ext) : undefined;
}
get extSCT() {
const ext = this.findExtension(EXTENSION_OID_SCT);
return ext ? new ext_1.x509SCTExtension(ext) : undefined;
}
get isCA() {
const ca = this.extBasicConstraints?.isCA || false;
// If the KeyUsage extension is present, keyCertSign must be set
if (this.extKeyUsage) {
ca && this.extKeyUsage.keyCertSign;
}
return ca;
}
extension(oid) {
const ext = this.findExtension(oid);
return ext ? new ext_1.x509Extension(ext) : undefined;
}
verify(issuerCertificate) {
// Use the issuer's public key if provided, otherwise use the subject's
const publicKey = issuerCertificate?.publicKey || this.publicKey;
const key = util_1.crypto.createPublicKey(publicKey);
return util_1.crypto.verifyBlob(this.tbsCertificate.toDER(), key, this.signatureValue, this.signatureAlgorithm);
}
validForDate(date) {
return this.notBefore <= date && date <= this.notAfter;
}
equals(other) {
return this.root.toDER().equals(other.root.toDER());
}
verifySCTs(issuer, logs) {
let extSCT;
// Verifying the SCT requires that we remove the SCT extension and
// re-encode the TBS structure to DER -- this value is part of the data
// over which the signature is calculated. Since this is a destructive action
// we create a copy of the certificate so we can remove the SCT extension
// without affecting the original certificate.
const clone = this.clone();
// Intentionally not using the findExtension method here because we want to
// remove the the SCT extension from the certificate before calculating the
// PreCert structure
for (let i = 0; i < clone.extensions.length; i++) {
const ext = clone.extensions[i];
if (ext.subs[0].toOID() === EXTENSION_OID_SCT) {
extSCT = new ext_1.x509SCTExtension(ext);
// Remove the extension from the certificate
clone.extensions.splice(i, 1);
break;
}
}
if (!extSCT) {
throw new Error('Certificate does not contain SCT extension');
}
if (extSCT?.signedCertificateTimestamps?.length === 0) {
throw new Error('Certificate does not contain any SCTs');
}
// Construct the PreCert structure
// https://www.rfc-editor.org/rfc/rfc6962#section-3.2
const preCert = new stream_1.ByteStream();
// Calculate hash of the issuer's public key
const issuerId = util_1.crypto.hash(issuer.publicKey);
preCert.appendView(issuerId);
// Re-encodes the certificate to DER after removing the SCT extension
const tbs = clone.tbsCertificate.toDER();
preCert.appendUint24(tbs.length);
preCert.appendView(tbs);
// Calculate and return the verification results for each SCT
return extSCT.signedCertificateTimestamps.map((sct) => ({
logID: sct.logID,
verified: sct.verify(preCert.buffer, logs),
}));
}
// Creates a copy of the certificate with a new buffer
clone() {
const der = this.root.toDER();
const clone = Buffer.alloc(der.length);
der.copy(clone);
return x509Certificate.parse(clone);
}
findExtension(oid) {
// Find the extension with the given OID. The OID will always be the first
// element of the extension sequence
return this.extensions.find((ext) => ext.subs[0].toOID() === oid);
}
// A certificate should be considered invalid if it contains critical
// extensions that are not recognized
checkRecognizedExtensions() {
// The extension list is the first (and only) element of the extensions
// context specific tag
const extSeq = this.extensionsObj?.subs[0];
const exts = extSeq?.subs.map((ext) => new ext_1.x509Extension(ext));
// Check for unrecognized critical extensions
return (!exts ||
exts.every((ext) => !ext.critical || RECOGNIZED_EXTENSIONS.includes(ext.oid)));
}
/////////////////////////////////////////////////////////////////////////////
// The following properties use the documented x509 structure to locate the
// desired ASN.1 object
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.1
get tbsCertificateObj() {
// tbsCertificate is the first element of the certificate sequence
return this.root.subs[0];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.2
get signatureAlgorithmObj() {
// signatureAlgorithm is the second element of the certificate sequence
return this.root.subs[1];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.1.3
get signatureValueObj() {
// signatureValue is the third element of the certificate sequence
return this.root.subs[2];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.1
get versionObj() {
// version is the first element of the tbsCertificate sequence
return this.tbsCertificateObj.subs[0];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.4
get issuerObj() {
// issuer is the fourth element of the tbsCertificate sequence
return this.tbsCertificateObj.subs[3];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.5
get validityObj() {
// version is the fifth element of the tbsCertificate sequence
return this.tbsCertificateObj.subs[4];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.6
get subjectObj() {
// subject is the sixth element of the tbsCertificate sequence
return this.tbsCertificateObj.subs[5];
}
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.7
get subjectPublicKeyInfoObj() {
// subjectPublicKeyInfo is the seventh element of the tbsCertificate sequence
return this.tbsCertificateObj.subs[6];
}
// Extensions can't be located by index because their position varies. Instead,
// we need to find the extensions context specific tag
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1.2.9
get extensionsObj() {
return this.tbsCertificateObj.subs.find((sub) => sub.tag.isContextSpecific(0x03));
}
}
exports.x509Certificate = x509Certificate;

42
spa/node_modules/sigstore/dist/x509/ext.d.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
/// <reference types="node" />
import { ASN1Obj } from '../util/asn1';
import { SignedCertificateTimestamp } from './sct';
export declare class x509Extension {
protected root: ASN1Obj;
constructor(asn1: ASN1Obj);
get oid(): string;
get critical(): boolean;
get value(): Buffer;
get valueObj(): ASN1Obj;
protected get extnValueObj(): ASN1Obj;
}
export declare class x509BasicConstraintsExtension extends x509Extension {
get isCA(): boolean;
get pathLenConstraint(): bigint | undefined;
private get sequence();
}
export declare class x509KeyUsageExtension extends x509Extension {
get digitalSignature(): boolean;
get keyCertSign(): boolean;
get crlSign(): boolean;
private get bitString();
}
export declare class x509SubjectAlternativeNameExtension extends x509Extension {
get rfc822Name(): string | undefined;
get uri(): string | undefined;
otherName(oid: string): string | undefined;
private findGeneralName;
private get generalNames();
}
export declare class x509AuthorityKeyIDExtension extends x509Extension {
get keyIdentifier(): Buffer | undefined;
private findSequenceMember;
private get sequence();
}
export declare class x509SubjectKeyIDExtension extends x509Extension {
get keyIdentifier(): Buffer;
}
export declare class x509SCTExtension extends x509Extension {
constructor(asn1: ASN1Obj);
get signedCertificateTimestamps(): SignedCertificateTimestamp[];
}

145
spa/node_modules/sigstore/dist/x509/ext.js generated vendored Normal file
View File

@@ -0,0 +1,145 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.x509SCTExtension = exports.x509SubjectKeyIDExtension = exports.x509AuthorityKeyIDExtension = exports.x509SubjectAlternativeNameExtension = exports.x509KeyUsageExtension = exports.x509BasicConstraintsExtension = exports.x509Extension = void 0;
const stream_1 = require("../util/stream");
const sct_1 = require("./sct");
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1
class x509Extension {
constructor(asn1) {
this.root = asn1;
}
get oid() {
return this.root.subs[0].toOID();
}
get critical() {
// The critical field is optional and will be the second element of the
// extension sequence if present. Default to false if not present.
return this.root.subs.length === 3 ? this.root.subs[1].toBoolean() : false;
}
get value() {
return this.extnValueObj.value;
}
get valueObj() {
return this.extnValueObj;
}
get extnValueObj() {
// The extnValue field will be the last element of the extension sequence
return this.root.subs[this.root.subs.length - 1];
}
}
exports.x509Extension = x509Extension;
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9
class x509BasicConstraintsExtension extends x509Extension {
get isCA() {
return this.sequence.subs[0].toBoolean();
}
get pathLenConstraint() {
return this.sequence.subs.length > 1
? this.sequence.subs[1].toInteger()
: undefined;
}
// The extnValue field contains a single sequence wrapping the isCA and
// pathLenConstraint.
get sequence() {
return this.extnValueObj.subs[0];
}
}
exports.x509BasicConstraintsExtension = x509BasicConstraintsExtension;
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.3
class x509KeyUsageExtension extends x509Extension {
get digitalSignature() {
return this.bitString[0] === 1;
}
get keyCertSign() {
return this.bitString[5] === 1;
}
get crlSign() {
return this.bitString[6] === 1;
}
// The extnValue field contains a single bit string which is a bit mask
// indicating which key usages are enabled.
get bitString() {
return this.extnValueObj.subs[0].toBitString();
}
}
exports.x509KeyUsageExtension = x509KeyUsageExtension;
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.6
class x509SubjectAlternativeNameExtension extends x509Extension {
get rfc822Name() {
return this.findGeneralName(0x01)?.value.toString('ascii');
}
get uri() {
return this.findGeneralName(0x06)?.value.toString('ascii');
}
// Retrieve the value of an otherName with the given OID.
otherName(oid) {
const otherName = this.findGeneralName(0x00);
if (otherName === undefined) {
return undefined;
}
// The otherName is a sequence containing an OID and a value.
// Need to check that the OID matches the one we're looking for.
const otherNameOID = otherName.subs[0].toOID();
if (otherNameOID !== oid) {
return undefined;
}
// The otherNameValue is a sequence containing the actual value.
const otherNameValue = otherName.subs[1];
return otherNameValue.subs[0].value.toString('ascii');
}
findGeneralName(tag) {
return this.generalNames.find((gn) => gn.tag.isContextSpecific(tag));
}
// The extnValue field contains a sequence of GeneralNames.
get generalNames() {
return this.extnValueObj.subs[0].subs;
}
}
exports.x509SubjectAlternativeNameExtension = x509SubjectAlternativeNameExtension;
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.1
class x509AuthorityKeyIDExtension extends x509Extension {
get keyIdentifier() {
return this.findSequenceMember(0x00)?.value;
}
findSequenceMember(tag) {
return this.sequence.subs.find((el) => el.tag.isContextSpecific(tag));
}
// The extnValue field contains a single sequence wrapping the keyIdentifier
get sequence() {
return this.extnValueObj.subs[0];
}
}
exports.x509AuthorityKeyIDExtension = x509AuthorityKeyIDExtension;
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.2
class x509SubjectKeyIDExtension extends x509Extension {
get keyIdentifier() {
return this.extnValueObj.subs[0].value;
}
}
exports.x509SubjectKeyIDExtension = x509SubjectKeyIDExtension;
// https://www.rfc-editor.org/rfc/rfc6962#section-3.3
class x509SCTExtension extends x509Extension {
constructor(asn1) {
super(asn1);
}
get signedCertificateTimestamps() {
const buf = this.extnValueObj.subs[0].value;
const stream = new stream_1.ByteStream(buf);
// The overall list length is encoded in the first two bytes -- note this
// is the length of the list in bytes, NOT the number of SCTs in the list
const end = stream.getUint16() + 2;
const sctList = [];
while (stream.position < end) {
// Read the length of the next SCT
const sctLength = stream.getUint16();
// Slice out the bytes for the next SCT and parse it
const sct = stream.getBlock(sctLength);
sctList.push(sct_1.SignedCertificateTimestamp.parse(sct));
}
if (stream.position !== end) {
throw new Error('SCT list length does not match actual length');
}
return sctList;
}
}
exports.x509SCTExtension = x509SCTExtension;

26
spa/node_modules/sigstore/dist/x509/sct.d.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
/// <reference types="node" />
import * as sigstore from '../types/sigstore';
interface SCTOptions {
version: number;
logID: Buffer;
timestamp: Buffer;
extensions: Buffer;
hashAlgorithm: number;
signatureAlgorithm: number;
signature: Buffer;
}
export declare class SignedCertificateTimestamp {
readonly version: number;
readonly logID: Buffer;
readonly timestamp: Buffer;
readonly extensions: Buffer;
readonly hashAlgorithm: number;
readonly signatureAlgorithm: number;
readonly signature: Buffer;
constructor(options: SCTOptions);
get datetime(): Date;
get algorithm(): string;
verify(preCert: Buffer, logs: sigstore.TransparencyLogInstance[]): boolean;
static parse(buf: Buffer): SignedCertificateTimestamp;
}
export {};

101
spa/node_modules/sigstore/dist/x509/sct.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignedCertificateTimestamp = void 0;
const util_1 = require("../util");
const stream_1 = require("../util/stream");
class SignedCertificateTimestamp {
constructor(options) {
this.version = options.version;
this.logID = options.logID;
this.timestamp = options.timestamp;
this.extensions = options.extensions;
this.hashAlgorithm = options.hashAlgorithm;
this.signatureAlgorithm = options.signatureAlgorithm;
this.signature = options.signature;
}
get datetime() {
return new Date(Number(this.timestamp.readBigInt64BE()));
}
// Returns the hash algorithm used to generate the SCT's signature.
// https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1
get algorithm() {
switch (this.hashAlgorithm) {
case 0:
return 'none';
case 1:
return 'md5';
case 2:
return 'sha1';
case 3:
return 'sha224';
case 4:
return 'sha256';
case 5:
return 'sha384';
case 6:
return 'sha512';
default:
return 'unknown';
}
}
verify(preCert, logs) {
// Find key for the log reponsible for this signature
const log = logs.find((log) => log.logId?.keyId.equals(this.logID));
if (!log?.publicKey?.rawBytes) {
throw new Error(`No key found for log: ${this.logID.toString('base64')}`);
}
const publicKey = util_1.crypto.createPublicKey(log.publicKey.rawBytes);
// Assemble the digitally-signed struct (the data over which the signature
// was generated).
// https://www.rfc-editor.org/rfc/rfc6962#section-3.2
const stream = new stream_1.ByteStream();
stream.appendChar(this.version);
stream.appendChar(0x00); // SignatureType = certificate_timestamp(0)
stream.appendView(this.timestamp);
stream.appendUint16(0x01); // LogEntryType = precert_entry(1)
stream.appendView(preCert);
stream.appendUint16(this.extensions.byteLength);
if (this.extensions.byteLength > 0) {
stream.appendView(this.extensions);
}
return util_1.crypto.verifyBlob(stream.buffer, publicKey, this.signature, this.algorithm);
}
// Parses a SignedCertificateTimestamp from a buffer. SCTs are encoded using
// TLS encoding which means the fields and lengths of most fields are
// specified as part of the SCT and TLS specs.
// https://www.rfc-editor.org/rfc/rfc6962#section-3.2
// https://www.rfc-editor.org/rfc/rfc5246#section-7.4.1.4.1
static parse(buf) {
const stream = new stream_1.ByteStream(buf);
// Version - enum { v1(0), (255) }
const version = stream.getUint8();
// Log ID - struct { opaque key_id[32]; }
const logID = stream.getBlock(32);
// Timestamp - uint64
const timestamp = stream.getBlock(8);
// Extensions - opaque extensions<0..2^16-1>;
const extenstionLength = stream.getUint16();
const extensions = stream.getBlock(extenstionLength);
// Hash algo - enum { sha256(4), . . . (255) }
const hashAlgorithm = stream.getUint8();
// Signature algo - enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
const signatureAlgorithm = stream.getUint8();
// Signature - opaque signature<0..2^16-1>;
const sigLength = stream.getUint16();
const signature = stream.getBlock(sigLength);
// Check that we read the entire buffer
if (stream.position !== buf.length) {
throw new Error('SCT buffer length mismatch');
}
return new SignedCertificateTimestamp({
version,
logID,
timestamp,
extensions,
hashAlgorithm,
signatureAlgorithm,
signature,
});
}
}
exports.SignedCertificateTimestamp = SignedCertificateTimestamp;

8
spa/node_modules/sigstore/dist/x509/verify.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import { x509Certificate } from './cert';
interface VerifyCertificateChainOptions {
trustedCerts: x509Certificate[];
untrustedCert: x509Certificate;
validAt?: Date;
}
export declare function verifyCertificateChain(opts: VerifyCertificateChainOptions): x509Certificate[];
export {};

177
spa/node_modules/sigstore/dist/x509/verify.js generated vendored Normal file
View File

@@ -0,0 +1,177 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyCertificateChain = void 0;
/*
Copyright 2023 The Sigstore Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
const error_1 = require("../error");
function verifyCertificateChain(opts) {
const verifier = new CertificateChainVerifier(opts);
return verifier.verify();
}
exports.verifyCertificateChain = verifyCertificateChain;
class CertificateChainVerifier {
constructor(opts) {
this.untrustedCert = opts.untrustedCert;
this.trustedCerts = opts.trustedCerts;
this.localCerts = dedupeCertificates([
...opts.trustedCerts,
opts.untrustedCert,
]);
this.validAt = opts.validAt || new Date();
}
verify() {
// Construct certificate path from leaf to root
const certificatePath = this.sort();
// Perform validation checks on each certificate in the path
this.checkPath(certificatePath);
// Return verified certificate path
return certificatePath;
}
sort() {
const leafCert = this.untrustedCert;
// Construct all possible paths from the leaf
let paths = this.buildPaths(leafCert);
// Filter for paths which contain a trusted certificate
paths = paths.filter((path) => path.some((cert) => this.trustedCerts.includes(cert)));
if (paths.length === 0) {
throw new error_1.VerificationError('No trusted certificate path found');
}
// Find the shortest of possible paths
const path = paths.reduce((prev, curr) => prev.length < curr.length ? prev : curr);
// Construct chain from shortest path
// Removes the last certificate in the path, which will be a second copy
// of the root certificate given that the root is self-signed.
return [leafCert, ...path].slice(0, -1);
}
// Recursively build all possible paths from the leaf to the root
buildPaths(certificate) {
const paths = [];
const issuers = this.findIssuer(certificate);
if (issuers.length === 0) {
throw new error_1.VerificationError('No valid certificate path found');
}
for (let i = 0; i < issuers.length; i++) {
const issuer = issuers[i];
// Base case - issuer is self
if (issuer.equals(certificate)) {
paths.push([certificate]);
continue;
}
// Recursively build path for the issuer
const subPaths = this.buildPaths(issuer);
// Construct paths by appending the issuer to each subpath
for (let j = 0; j < subPaths.length; j++) {
paths.push([issuer, ...subPaths[j]]);
}
}
return paths;
}
// Return all possible issuers for the given certificate
findIssuer(certificate) {
let issuers = [];
let keyIdentifier;
// Exit early if the certificate is self-signed
if (certificate.subject.equals(certificate.issuer)) {
if (certificate.verify()) {
return [certificate];
}
}
// If the certificate has an authority key identifier, use that
// to find the issuer
if (certificate.extAuthorityKeyID) {
keyIdentifier = certificate.extAuthorityKeyID.keyIdentifier;
// TODO: Add support for authorityCertIssuer/authorityCertSerialNumber
// though Fulcio doesn't appear to use these
}
// Find possible issuers by comparing the authorityKeyID/subjectKeyID
// or issuer/subject. Potential issuers are added to the result array.
this.localCerts.forEach((possibleIssuer) => {
if (keyIdentifier) {
if (possibleIssuer.extSubjectKeyID) {
if (possibleIssuer.extSubjectKeyID.keyIdentifier.equals(keyIdentifier)) {
issuers.push(possibleIssuer);
}
return;
}
}
// Fallback to comparing certificate issuer and subject if
// subjectKey/authorityKey extensions are not present
if (possibleIssuer.subject.equals(certificate.issuer)) {
issuers.push(possibleIssuer);
}
});
// Remove any issuers which fail to verify the certificate
issuers = issuers.filter((issuer) => {
try {
return certificate.verify(issuer);
}
catch (ex) {
return false;
}
});
return issuers;
}
checkPath(path) {
if (path.length < 1) {
throw new error_1.VerificationError('Certificate chain must contain at least one certificate');
}
// Check that all certificates are valid at the check date
const validForDate = path.every((cert) => cert.validForDate(this.validAt));
if (!validForDate) {
throw new error_1.VerificationError('Certificate is not valid or expired at the specified date');
}
// Ensure that all certificates beyond the leaf are CAs
const validCAs = path.slice(1).every((cert) => cert.isCA);
if (!validCAs) {
throw new error_1.VerificationError('Intermediate certificate is not a CA');
}
// Certificate's issuer must match the subject of the next certificate
// in the chain
for (let i = path.length - 2; i >= 0; i--) {
if (!path[i].issuer.equals(path[i + 1].subject)) {
throw new error_1.VerificationError('Incorrect certificate name chaining');
}
}
// Check pathlength constraints
for (let i = 0; i < path.length; i++) {
const cert = path[i];
// If the certificate is a CA, check the path length
if (cert.extBasicConstraints?.isCA) {
const pathLength = cert.extBasicConstraints.pathLenConstraint;
// The path length, if set, indicates how many intermediate
// certificates (NOT including the leaf) are allowed to follow. The
// pathLength constraint of any intermediate CA certificate MUST be
// greater than or equal to it's own depth in the chain (with an
// adjustment for the leaf certificate)
if (pathLength !== undefined && pathLength < i - 1) {
throw new error_1.VerificationError('Path length constraint exceeded');
}
}
}
}
}
// Remove duplicate certificates from the array
function dedupeCertificates(certs) {
for (let i = 0; i < certs.length; i++) {
for (let j = i + 1; j < certs.length; j++) {
if (certs[i].equals(certs[j])) {
certs.splice(j, 1);
j--;
}
}
}
return certs;
}

1
spa/node_modules/sigstore/node_modules/.bin/glob generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../glob/dist/esm/bin.mjs

1
spa/node_modules/sigstore/node_modules/.bin/semver generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../semver/bin/semver.js

View File

@@ -0,0 +1,20 @@
<!-- This file is automatically added by @npmcli/template-oss. Do not edit. -->
ISC License
Copyright npm, Inc.
Permission to use, copy, modify, and/or distribute this
software for any purpose with or without fee is hereby
granted, provided that the above copyright notice and this
permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,97 @@
# @npmcli/fs
polyfills, and extensions, of the core `fs` module.
## Features
- `fs.cp` polyfill for node < 16.7.0
- `fs.withTempDir` added
- `fs.readdirScoped` added
- `fs.moveFile` added
## `fs.withTempDir(root, fn, options) -> Promise`
### Parameters
- `root`: the directory in which to create the temporary directory
- `fn`: a function that will be called with the path to the temporary directory
- `options`
- `tmpPrefix`: a prefix to be used in the generated directory name
### Usage
The `withTempDir` function creates a temporary directory, runs the provided
function (`fn`), then removes the temporary directory and resolves or rejects
based on the result of `fn`.
```js
const fs = require('@npmcli/fs')
const os = require('os')
// this function will be called with the full path to the temporary directory
// it is called with `await` behind the scenes, so can be async if desired.
const myFunction = async (tempPath) => {
return 'done!'
}
const main = async () => {
const result = await fs.withTempDir(os.tmpdir(), myFunction)
// result === 'done!'
}
main()
```
## `fs.readdirScoped(root) -> Promise`
### Parameters
- `root`: the directory to read
### Usage
Like `fs.readdir` but handling `@org/module` dirs as if they were
a single entry.
```javascript
const { readdirScoped } = require('@npmcli/fs')
const entries = await readdirScoped('node_modules')
// entries will be something like: ['a', '@org/foo', '@org/bar']
```
## `fs.moveFile(source, dest, options) -> Promise`
A fork of [move-file](https://github.com/sindresorhus/move-file) with
support for Common JS.
### Highlights
- Promise API.
- Supports moving a file across partitions and devices.
- Optionally prevent overwriting an existing file.
- Creates non-existent destination directories for you.
- Automatically recurses when source is a directory.
### Parameters
- `source`: File, or directory, you want to move.
- `dest`: Where you want the file or directory moved.
- `options`
- `overwrite` (`boolean`, default: `true`): Overwrite existing destination file(s).
### Usage
The built-in
[`fs.rename()`](https://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback)
is just a JavaScript wrapper for the C `rename(2)` function, which doesn't
support moving files across partitions or devices. This module is what you
would have expected `fs.rename()` to be.
```js
const { moveFile } = require('@npmcli/fs');
(async () => {
await moveFile('source/unicorn.png', 'destination/unicorn.png');
console.log('The file has been moved');
})();
```

View File

@@ -0,0 +1,20 @@
// given an input that may or may not be an object, return an object that has
// a copy of every defined property listed in 'copy'. if the input is not an
// object, assign it to the property named by 'wrap'
const getOptions = (input, { copy, wrap }) => {
const result = {}
if (input && typeof input === 'object') {
for (const prop of copy) {
if (input[prop] !== undefined) {
result[prop] = input[prop]
}
}
} else {
result[wrap] = input
}
return result
}
module.exports = getOptions

View File

@@ -0,0 +1,9 @@
const semver = require('semver')
const satisfies = (range) => {
return semver.satisfies(process.version, range, { includePrerelease: true })
}
module.exports = {
satisfies,
}

View File

@@ -0,0 +1,15 @@
(The MIT License)
Copyright (c) 2011-2017 JP Richardson
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,129 @@
'use strict'
const { inspect } = require('util')
// adapted from node's internal/errors
// https://github.com/nodejs/node/blob/c8a04049/lib/internal/errors.js
// close copy of node's internal SystemError class.
class SystemError {
constructor (code, prefix, context) {
// XXX context.code is undefined in all constructors used in cp/polyfill
// that may be a bug copied from node, maybe the constructor should use
// `code` not `errno`? nodejs/node#41104
let message = `${prefix}: ${context.syscall} returned ` +
`${context.code} (${context.message})`
if (context.path !== undefined) {
message += ` ${context.path}`
}
if (context.dest !== undefined) {
message += ` => ${context.dest}`
}
this.code = code
Object.defineProperties(this, {
name: {
value: 'SystemError',
enumerable: false,
writable: true,
configurable: true,
},
message: {
value: message,
enumerable: false,
writable: true,
configurable: true,
},
info: {
value: context,
enumerable: true,
configurable: true,
writable: false,
},
errno: {
get () {
return context.errno
},
set (value) {
context.errno = value
},
enumerable: true,
configurable: true,
},
syscall: {
get () {
return context.syscall
},
set (value) {
context.syscall = value
},
enumerable: true,
configurable: true,
},
})
if (context.path !== undefined) {
Object.defineProperty(this, 'path', {
get () {
return context.path
},
set (value) {
context.path = value
},
enumerable: true,
configurable: true,
})
}
if (context.dest !== undefined) {
Object.defineProperty(this, 'dest', {
get () {
return context.dest
},
set (value) {
context.dest = value
},
enumerable: true,
configurable: true,
})
}
}
toString () {
return `${this.name} [${this.code}]: ${this.message}`
}
[Symbol.for('nodejs.util.inspect.custom')] (_recurseTimes, ctx) {
return inspect(this, {
...ctx,
getters: true,
customInspect: false,
})
}
}
function E (code, message) {
module.exports[code] = class NodeError extends SystemError {
constructor (ctx) {
super(code, message, ctx)
}
}
}
E('ERR_FS_CP_DIR_TO_NON_DIR', 'Cannot overwrite directory with non-directory')
E('ERR_FS_CP_EEXIST', 'Target already exists')
E('ERR_FS_CP_EINVAL', 'Invalid src or dest')
E('ERR_FS_CP_FIFO_PIPE', 'Cannot copy a FIFO pipe')
E('ERR_FS_CP_NON_DIR_TO_DIR', 'Cannot overwrite non-directory with directory')
E('ERR_FS_CP_SOCKET', 'Cannot copy a socket file')
E('ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY', 'Cannot overwrite symlink in subdirectory of self')
E('ERR_FS_CP_UNKNOWN', 'Cannot copy an unknown file type')
E('ERR_FS_EISDIR', 'Path is a directory')
module.exports.ERR_INVALID_ARG_TYPE = class ERR_INVALID_ARG_TYPE extends Error {
constructor (name, expected, actual) {
super()
this.code = 'ERR_INVALID_ARG_TYPE'
this.message = `The ${name} argument must be ${expected}. Received ${typeof actual}`
}
}

View File

@@ -0,0 +1,22 @@
const fs = require('fs/promises')
const getOptions = require('../common/get-options.js')
const node = require('../common/node.js')
const polyfill = require('./polyfill.js')
// node 16.7.0 added fs.cp
const useNative = node.satisfies('>=16.7.0')
const cp = async (src, dest, opts) => {
const options = getOptions(opts, {
copy: ['dereference', 'errorOnExist', 'filter', 'force', 'preserveTimestamps', 'recursive'],
})
// the polyfill is tested separately from this module, no need to hack
// process.version to try to trigger it just for coverage
// istanbul ignore next
return useNative
? fs.cp(src, dest, options)
: polyfill(src, dest, options)
}
module.exports = cp

View File

@@ -0,0 +1,428 @@
// this file is a modified version of the code in node 17.2.0
// which is, in turn, a modified version of the fs-extra module on npm
// node core changes:
// - Use of the assert module has been replaced with core's error system.
// - All code related to the glob dependency has been removed.
// - Bring your own custom fs module is not currently supported.
// - Some basic code cleanup.
// changes here:
// - remove all callback related code
// - drop sync support
// - change assertions back to non-internal methods (see options.js)
// - throws ENOTDIR when rmdir gets an ENOENT for a path that exists in Windows
'use strict'
const {
ERR_FS_CP_DIR_TO_NON_DIR,
ERR_FS_CP_EEXIST,
ERR_FS_CP_EINVAL,
ERR_FS_CP_FIFO_PIPE,
ERR_FS_CP_NON_DIR_TO_DIR,
ERR_FS_CP_SOCKET,
ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY,
ERR_FS_CP_UNKNOWN,
ERR_FS_EISDIR,
ERR_INVALID_ARG_TYPE,
} = require('./errors.js')
const {
constants: {
errno: {
EEXIST,
EISDIR,
EINVAL,
ENOTDIR,
},
},
} = require('os')
const {
chmod,
copyFile,
lstat,
mkdir,
readdir,
readlink,
stat,
symlink,
unlink,
utimes,
} = require('fs/promises')
const {
dirname,
isAbsolute,
join,
parse,
resolve,
sep,
toNamespacedPath,
} = require('path')
const { fileURLToPath } = require('url')
const defaultOptions = {
dereference: false,
errorOnExist: false,
filter: undefined,
force: true,
preserveTimestamps: false,
recursive: false,
}
async function cp (src, dest, opts) {
if (opts != null && typeof opts !== 'object') {
throw new ERR_INVALID_ARG_TYPE('options', ['Object'], opts)
}
return cpFn(
toNamespacedPath(getValidatedPath(src)),
toNamespacedPath(getValidatedPath(dest)),
{ ...defaultOptions, ...opts })
}
function getValidatedPath (fileURLOrPath) {
const path = fileURLOrPath != null && fileURLOrPath.href
&& fileURLOrPath.origin
? fileURLToPath(fileURLOrPath)
: fileURLOrPath
return path
}
async function cpFn (src, dest, opts) {
// Warn about using preserveTimestamps on 32-bit node
// istanbul ignore next
if (opts.preserveTimestamps && process.arch === 'ia32') {
const warning = 'Using the preserveTimestamps option in 32-bit ' +
'node is not recommended'
process.emitWarning(warning, 'TimestampPrecisionWarning')
}
const stats = await checkPaths(src, dest, opts)
const { srcStat, destStat } = stats
await checkParentPaths(src, srcStat, dest)
if (opts.filter) {
return handleFilter(checkParentDir, destStat, src, dest, opts)
}
return checkParentDir(destStat, src, dest, opts)
}
async function checkPaths (src, dest, opts) {
const { 0: srcStat, 1: destStat } = await getStats(src, dest, opts)
if (destStat) {
if (areIdentical(srcStat, destStat)) {
throw new ERR_FS_CP_EINVAL({
message: 'src and dest cannot be the same',
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
if (srcStat.isDirectory() && !destStat.isDirectory()) {
throw new ERR_FS_CP_DIR_TO_NON_DIR({
message: `cannot overwrite directory ${src} ` +
`with non-directory ${dest}`,
path: dest,
syscall: 'cp',
errno: EISDIR,
})
}
if (!srcStat.isDirectory() && destStat.isDirectory()) {
throw new ERR_FS_CP_NON_DIR_TO_DIR({
message: `cannot overwrite non-directory ${src} ` +
`with directory ${dest}`,
path: dest,
syscall: 'cp',
errno: ENOTDIR,
})
}
}
if (srcStat.isDirectory() && isSrcSubdir(src, dest)) {
throw new ERR_FS_CP_EINVAL({
message: `cannot copy ${src} to a subdirectory of self ${dest}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
return { srcStat, destStat }
}
function areIdentical (srcStat, destStat) {
return destStat.ino && destStat.dev && destStat.ino === srcStat.ino &&
destStat.dev === srcStat.dev
}
function getStats (src, dest, opts) {
const statFunc = opts.dereference ?
(file) => stat(file, { bigint: true }) :
(file) => lstat(file, { bigint: true })
return Promise.all([
statFunc(src),
statFunc(dest).catch((err) => {
// istanbul ignore next: unsure how to cover.
if (err.code === 'ENOENT') {
return null
}
// istanbul ignore next: unsure how to cover.
throw err
}),
])
}
async function checkParentDir (destStat, src, dest, opts) {
const destParent = dirname(dest)
const dirExists = await pathExists(destParent)
if (dirExists) {
return getStatsForCopy(destStat, src, dest, opts)
}
await mkdir(destParent, { recursive: true })
return getStatsForCopy(destStat, src, dest, opts)
}
function pathExists (dest) {
return stat(dest).then(
() => true,
// istanbul ignore next: not sure when this would occur
(err) => (err.code === 'ENOENT' ? false : Promise.reject(err)))
}
// Recursively check if dest parent is a subdirectory of src.
// It works for all file types including symlinks since it
// checks the src and dest inodes. It starts from the deepest
// parent and stops once it reaches the src parent or the root path.
async function checkParentPaths (src, srcStat, dest) {
const srcParent = resolve(dirname(src))
const destParent = resolve(dirname(dest))
if (destParent === srcParent || destParent === parse(destParent).root) {
return
}
let destStat
try {
destStat = await stat(destParent, { bigint: true })
} catch (err) {
// istanbul ignore else: not sure when this would occur
if (err.code === 'ENOENT') {
return
}
// istanbul ignore next: not sure when this would occur
throw err
}
if (areIdentical(srcStat, destStat)) {
throw new ERR_FS_CP_EINVAL({
message: `cannot copy ${src} to a subdirectory of self ${dest}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
return checkParentPaths(src, srcStat, destParent)
}
const normalizePathToArray = (path) =>
resolve(path).split(sep).filter(Boolean)
// Return true if dest is a subdir of src, otherwise false.
// It only checks the path strings.
function isSrcSubdir (src, dest) {
const srcArr = normalizePathToArray(src)
const destArr = normalizePathToArray(dest)
return srcArr.every((cur, i) => destArr[i] === cur)
}
async function handleFilter (onInclude, destStat, src, dest, opts, cb) {
const include = await opts.filter(src, dest)
if (include) {
return onInclude(destStat, src, dest, opts, cb)
}
}
function startCopy (destStat, src, dest, opts) {
if (opts.filter) {
return handleFilter(getStatsForCopy, destStat, src, dest, opts)
}
return getStatsForCopy(destStat, src, dest, opts)
}
async function getStatsForCopy (destStat, src, dest, opts) {
const statFn = opts.dereference ? stat : lstat
const srcStat = await statFn(src)
// istanbul ignore else: can't portably test FIFO
if (srcStat.isDirectory() && opts.recursive) {
return onDir(srcStat, destStat, src, dest, opts)
} else if (srcStat.isDirectory()) {
throw new ERR_FS_EISDIR({
message: `${src} is a directory (not copied)`,
path: src,
syscall: 'cp',
errno: EINVAL,
})
} else if (srcStat.isFile() ||
srcStat.isCharacterDevice() ||
srcStat.isBlockDevice()) {
return onFile(srcStat, destStat, src, dest, opts)
} else if (srcStat.isSymbolicLink()) {
return onLink(destStat, src, dest)
} else if (srcStat.isSocket()) {
throw new ERR_FS_CP_SOCKET({
message: `cannot copy a socket file: ${dest}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
} else if (srcStat.isFIFO()) {
throw new ERR_FS_CP_FIFO_PIPE({
message: `cannot copy a FIFO pipe: ${dest}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
// istanbul ignore next: should be unreachable
throw new ERR_FS_CP_UNKNOWN({
message: `cannot copy an unknown file type: ${dest}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
function onFile (srcStat, destStat, src, dest, opts) {
if (!destStat) {
return _copyFile(srcStat, src, dest, opts)
}
return mayCopyFile(srcStat, src, dest, opts)
}
async function mayCopyFile (srcStat, src, dest, opts) {
if (opts.force) {
await unlink(dest)
return _copyFile(srcStat, src, dest, opts)
} else if (opts.errorOnExist) {
throw new ERR_FS_CP_EEXIST({
message: `${dest} already exists`,
path: dest,
syscall: 'cp',
errno: EEXIST,
})
}
}
async function _copyFile (srcStat, src, dest, opts) {
await copyFile(src, dest)
if (opts.preserveTimestamps) {
return handleTimestampsAndMode(srcStat.mode, src, dest)
}
return setDestMode(dest, srcStat.mode)
}
async function handleTimestampsAndMode (srcMode, src, dest) {
// Make sure the file is writable before setting the timestamp
// otherwise open fails with EPERM when invoked with 'r+'
// (through utimes call)
if (fileIsNotWritable(srcMode)) {
await makeFileWritable(dest, srcMode)
return setDestTimestampsAndMode(srcMode, src, dest)
}
return setDestTimestampsAndMode(srcMode, src, dest)
}
function fileIsNotWritable (srcMode) {
return (srcMode & 0o200) === 0
}
function makeFileWritable (dest, srcMode) {
return setDestMode(dest, srcMode | 0o200)
}
async function setDestTimestampsAndMode (srcMode, src, dest) {
await setDestTimestamps(src, dest)
return setDestMode(dest, srcMode)
}
function setDestMode (dest, srcMode) {
return chmod(dest, srcMode)
}
async function setDestTimestamps (src, dest) {
// The initial srcStat.atime cannot be trusted
// because it is modified by the read(2) system call
// (See https://nodejs.org/api/fs.html#fs_stat_time_values)
const updatedSrcStat = await stat(src)
return utimes(dest, updatedSrcStat.atime, updatedSrcStat.mtime)
}
function onDir (srcStat, destStat, src, dest, opts) {
if (!destStat) {
return mkDirAndCopy(srcStat.mode, src, dest, opts)
}
return copyDir(src, dest, opts)
}
async function mkDirAndCopy (srcMode, src, dest, opts) {
await mkdir(dest)
await copyDir(src, dest, opts)
return setDestMode(dest, srcMode)
}
async function copyDir (src, dest, opts) {
const dir = await readdir(src)
for (let i = 0; i < dir.length; i++) {
const item = dir[i]
const srcItem = join(src, item)
const destItem = join(dest, item)
const { destStat } = await checkPaths(srcItem, destItem, opts)
await startCopy(destStat, srcItem, destItem, opts)
}
}
async function onLink (destStat, src, dest) {
let resolvedSrc = await readlink(src)
if (!isAbsolute(resolvedSrc)) {
resolvedSrc = resolve(dirname(src), resolvedSrc)
}
if (!destStat) {
return symlink(resolvedSrc, dest)
}
let resolvedDest
try {
resolvedDest = await readlink(dest)
} catch (err) {
// Dest exists and is a regular file or directory,
// Windows may throw UNKNOWN error. If dest already exists,
// fs throws error anyway, so no need to guard against it here.
// istanbul ignore next: can only test on windows
if (err.code === 'EINVAL' || err.code === 'UNKNOWN') {
return symlink(resolvedSrc, dest)
}
// istanbul ignore next: should not be possible
throw err
}
if (!isAbsolute(resolvedDest)) {
resolvedDest = resolve(dirname(dest), resolvedDest)
}
if (isSrcSubdir(resolvedSrc, resolvedDest)) {
throw new ERR_FS_CP_EINVAL({
message: `cannot copy ${resolvedSrc} to a subdirectory of self ` +
`${resolvedDest}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
// Do not copy if src is a subdir of dest since unlinking
// dest in this case would result in removing src contents
// and therefore a broken symlink would be created.
const srcStat = await stat(src)
if (srcStat.isDirectory() && isSrcSubdir(resolvedDest, resolvedSrc)) {
throw new ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY({
message: `cannot overwrite ${resolvedDest} with ${resolvedSrc}`,
path: dest,
syscall: 'cp',
errno: EINVAL,
})
}
return copyLink(resolvedSrc, dest)
}
async function copyLink (resolvedSrc, dest) {
await unlink(dest)
return symlink(resolvedSrc, dest)
}
module.exports = cp

View File

@@ -0,0 +1,13 @@
'use strict'
const cp = require('./cp/index.js')
const withTempDir = require('./with-temp-dir.js')
const readdirScoped = require('./readdir-scoped.js')
const moveFile = require('./move-file.js')
module.exports = {
cp,
withTempDir,
readdirScoped,
moveFile,
}

View File

@@ -0,0 +1,78 @@
const { dirname, join, resolve, relative, isAbsolute } = require('path')
const fs = require('fs/promises')
const pathExists = async path => {
try {
await fs.access(path)
return true
} catch (er) {
return er.code !== 'ENOENT'
}
}
const moveFile = async (source, destination, options = {}, root = true, symlinks = []) => {
if (!source || !destination) {
throw new TypeError('`source` and `destination` file required')
}
options = {
overwrite: true,
...options,
}
if (!options.overwrite && await pathExists(destination)) {
throw new Error(`The destination file exists: ${destination}`)
}
await fs.mkdir(dirname(destination), { recursive: true })
try {
await fs.rename(source, destination)
} catch (error) {
if (error.code === 'EXDEV' || error.code === 'EPERM') {
const sourceStat = await fs.lstat(source)
if (sourceStat.isDirectory()) {
const files = await fs.readdir(source)
await Promise.all(files.map((file) =>
moveFile(join(source, file), join(destination, file), options, false, symlinks)
))
} else if (sourceStat.isSymbolicLink()) {
symlinks.push({ source, destination })
} else {
await fs.copyFile(source, destination)
}
} else {
throw error
}
}
if (root) {
await Promise.all(symlinks.map(async ({ source: symSource, destination: symDestination }) => {
let target = await fs.readlink(symSource)
// junction symlinks in windows will be absolute paths, so we need to
// make sure they point to the symlink destination
if (isAbsolute(target)) {
target = resolve(symDestination, relative(symSource, target))
}
// try to determine what the actual file is so we can create the correct
// type of symlink in windows
let targetStat = 'file'
try {
targetStat = await fs.stat(resolve(dirname(symSource), target))
if (targetStat.isDirectory()) {
targetStat = 'junction'
}
} catch {
// targetStat remains 'file'
}
await fs.symlink(
target,
symDestination,
targetStat
)
}))
await fs.rm(source, { recursive: true, force: true })
}
}
module.exports = moveFile

View File

@@ -0,0 +1,20 @@
const { readdir } = require('fs/promises')
const { join } = require('path')
const readdirScoped = async (dir) => {
const results = []
for (const item of await readdir(dir)) {
if (item.startsWith('@')) {
for (const scopedItem of await readdir(join(dir, item))) {
results.push(join(item, scopedItem))
}
} else {
results.push(item)
}
}
return results
}
module.exports = readdirScoped

View File

@@ -0,0 +1,39 @@
const { join, sep } = require('path')
const getOptions = require('./common/get-options.js')
const { mkdir, mkdtemp, rm } = require('fs/promises')
// create a temp directory, ensure its permissions match its parent, then call
// the supplied function passing it the path to the directory. clean up after
// the function finishes, whether it throws or not
const withTempDir = async (root, fn, opts) => {
const options = getOptions(opts, {
copy: ['tmpPrefix'],
})
// create the directory
await mkdir(root, { recursive: true })
const target = await mkdtemp(join(`${root}${sep}`, options.tmpPrefix || ''))
let err
let result
try {
result = await fn(target)
} catch (_err) {
err = _err
}
try {
await rm(target, { force: true, recursive: true })
} catch {
// ignore errors
}
if (err) {
throw err
}
return result
}
module.exports = withTempDir

View File

@@ -0,0 +1,52 @@
{
"name": "@npmcli/fs",
"version": "3.1.1",
"description": "filesystem utilities for the npm cli",
"main": "lib/index.js",
"files": [
"bin/",
"lib/"
],
"scripts": {
"snap": "tap",
"test": "tap",
"npmclilint": "npmcli-lint",
"lint": "eslint \"**/*.{js,cjs,ts,mjs,jsx,tsx}\"",
"lintfix": "npm run lint -- --fix",
"posttest": "npm run lint",
"postsnap": "npm run lintfix --",
"postlint": "template-oss-check",
"template-oss-apply": "template-oss-apply --force"
},
"repository": {
"type": "git",
"url": "git+https://github.com/npm/fs.git"
},
"keywords": [
"npm",
"oss"
],
"author": "GitHub Inc.",
"license": "ISC",
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.22.0",
"tap": "^16.0.1"
},
"dependencies": {
"semver": "^7.3.5"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
},
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
"version": "4.22.0"
},
"tap": {
"nyc-arg": [
"--exclude",
"tap-snapshots/**"
]
}
}

Some files were not shown because too many files have changed in this diff Show More