@freedomofpress/sigstore-browser 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -16
- package/dist/bundle.d.ts +3 -2
- package/dist/bundle.js +66 -1
- package/dist/bundle.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js.map +1 -1
- package/dist/dsse.d.ts +0 -1
- package/dist/dsse.js.map +1 -1
- package/dist/errors.d.ts +0 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +9 -10
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +18 -4
- package/dist/interfaces.js +15 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/oid.d.ts +0 -1
- package/dist/oid.js.map +1 -1
- package/dist/policy.d.ts +3 -4
- package/dist/policy.js +5 -5
- package/dist/policy.js.map +1 -1
- package/dist/rfc3161/error.d.ts +0 -1
- package/dist/rfc3161/error.js.map +1 -1
- package/dist/rfc3161/index.d.ts +0 -1
- package/dist/rfc3161/index.js.map +1 -1
- package/dist/rfc3161/timestamp.d.ts +0 -1
- package/dist/rfc3161/timestamp.js.map +1 -1
- package/dist/rfc3161/tstinfo.d.ts +0 -1
- package/dist/rfc3161/tstinfo.js.map +1 -1
- package/dist/sigstore.d.ts +10 -20
- package/dist/sigstore.js +167 -400
- package/dist/sigstore.js.map +1 -1
- package/dist/timestamp/tsa.d.ts +6 -3
- package/dist/timestamp/tsa.js +16 -19
- package/dist/timestamp/tsa.js.map +1 -1
- package/dist/tlog/body.d.ts +3 -2
- package/dist/tlog/body.js +19 -6
- package/dist/tlog/body.js.map +1 -1
- package/dist/tlog/checkpoint.d.ts +2 -3
- package/dist/tlog/checkpoint.js +17 -95
- package/dist/tlog/checkpoint.js.map +1 -1
- package/dist/tlog/dsse.d.ts +3 -3
- package/dist/tlog/dsse.js +11 -5
- package/dist/tlog/dsse.js.map +1 -1
- package/dist/tlog/hashedrekord.d.ts +3 -3
- package/dist/tlog/hashedrekord.js +8 -5
- package/dist/tlog/hashedrekord.js.map +1 -1
- package/dist/tlog/intoto.d.ts +3 -3
- package/dist/tlog/intoto.js +3 -1
- package/dist/tlog/intoto.js.map +1 -1
- package/dist/tlog/merkle.d.ts +0 -1
- package/dist/tlog/merkle.js.map +1 -1
- package/dist/trust/tuf-root.d.ts +0 -1
- package/dist/trust/tuf-root.js.map +1 -1
- package/dist/trust/tuf.d.ts +0 -1
- package/dist/trust/tuf.js.map +1 -1
- package/dist/x509/cert.d.ts +0 -1
- package/dist/x509/cert.js +1 -1
- package/dist/x509/cert.js.map +1 -1
- package/dist/x509/chain.d.ts +0 -1
- package/dist/x509/chain.js +2 -2
- package/dist/x509/chain.js.map +1 -1
- package/dist/x509/ext.d.ts +0 -1
- package/dist/x509/ext.js.map +1 -1
- package/dist/x509/index.d.ts +1 -2
- package/dist/x509/index.js +1 -1
- package/dist/x509/index.js.map +1 -1
- package/dist/x509/sct.d.ts +0 -1
- package/dist/x509/sct.js.map +1 -1
- package/package.json +15 -8
- package/.github/workflows/conformance.yml +0 -29
- package/.github/workflows/publish.yml +0 -47
- package/dist/bundle.d.ts.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/dsse.d.ts.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interfaces.d.ts.map +0 -1
- package/dist/oid.d.ts.map +0 -1
- package/dist/policy.d.ts.map +0 -1
- package/dist/rfc3161/error.d.ts.map +0 -1
- package/dist/rfc3161/index.d.ts.map +0 -1
- package/dist/rfc3161/timestamp.d.ts.map +0 -1
- package/dist/rfc3161/tstinfo.d.ts.map +0 -1
- package/dist/sigstore.d.ts.map +0 -1
- package/dist/timestamp/tsa.d.ts.map +0 -1
- package/dist/tlog/body.d.ts.map +0 -1
- package/dist/tlog/checkpoint.d.ts.map +0 -1
- package/dist/tlog/dsse.d.ts.map +0 -1
- package/dist/tlog/hashedrekord.d.ts.map +0 -1
- package/dist/tlog/intoto.d.ts.map +0 -1
- package/dist/tlog/merkle.d.ts.map +0 -1
- package/dist/trust/tuf-root.d.ts.map +0 -1
- package/dist/trust/tuf.d.ts.map +0 -1
- package/dist/x509/cert.d.ts.map +0 -1
- package/dist/x509/chain.d.ts.map +0 -1
- package/dist/x509/ext.d.ts.map +0 -1
- package/dist/x509/index.d.ts.map +0 -1
- package/dist/x509/sct.d.ts.map +0 -1
- package/eslint.config.mjs +0 -31
- package/src/bundle.ts +0 -99
- package/src/cli.ts +0 -290
- package/src/dsse.ts +0 -49
- package/src/errors.ts +0 -82
- package/src/index.browser.test.ts +0 -290
- package/src/index.ts +0 -93
- package/src/interfaces.ts +0 -123
- package/src/oid.ts +0 -34
- package/src/policy.ts +0 -476
- package/src/rfc3161/error.ts +0 -16
- package/src/rfc3161/index.ts +0 -17
- package/src/rfc3161/timestamp.ts +0 -268
- package/src/rfc3161/tstinfo.ts +0 -78
- package/src/sigstore.ts +0 -948
- package/src/timestamp/tsa.ts +0 -211
- package/src/tlog/body.ts +0 -65
- package/src/tlog/checkpoint.ts +0 -254
- package/src/tlog/dsse.ts +0 -147
- package/src/tlog/hashedrekord.ts +0 -130
- package/src/tlog/intoto.ts +0 -106
- package/src/tlog/merkle.ts +0 -152
- package/src/trust/README.md +0 -38
- package/src/trust/tuf-root.ts +0 -3
- package/src/trust/tuf.ts +0 -233
- package/src/x509/cert.ts +0 -569
- package/src/x509/chain.ts +0 -212
- package/src/x509/ext.ts +0 -356
- package/src/x509/index.ts +0 -19
- package/src/x509/sct.ts +0 -156
- package/tsconfig.json +0 -18
- package/vite.config.playwright.ts +0 -14
- package/vite.config.ts +0 -18
package/src/x509/chain.ts
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2023 The Sigstore Authors.
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/*
|
|
18
|
-
* Certificate chain verification for browser environments
|
|
19
|
-
*
|
|
20
|
-
* Ported from sigstore-js:
|
|
21
|
-
* https://github.com/sigstore/sigstore-js/blob/main/packages/verify/src/key/certificate.ts
|
|
22
|
-
*
|
|
23
|
-
* Key differences from sigstore-js:
|
|
24
|
-
* - Browser-compatible: async verify() method for Web Crypto API
|
|
25
|
-
* - Uses Uint8Array instead of Buffer for binary data
|
|
26
|
-
* - Uses uint8ArrayEqual for Uint8Array comparisons
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import { uint8ArrayEqual } from "@freedomofpress/crypto-browser";
|
|
30
|
-
import { X509Certificate } from "./cert.js";
|
|
31
|
-
|
|
32
|
-
interface CertificateChainVerifierOptions {
|
|
33
|
-
trustedCerts: X509Certificate[];
|
|
34
|
-
untrustedCert: X509Certificate;
|
|
35
|
-
timestamp: Date;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class CertificateChainVerifier {
|
|
39
|
-
private untrustedCert: X509Certificate;
|
|
40
|
-
private trustedCerts: X509Certificate[];
|
|
41
|
-
private localCerts: X509Certificate[];
|
|
42
|
-
private timestamp: Date;
|
|
43
|
-
|
|
44
|
-
constructor(opts: CertificateChainVerifierOptions) {
|
|
45
|
-
this.untrustedCert = opts.untrustedCert;
|
|
46
|
-
this.trustedCerts = opts.trustedCerts;
|
|
47
|
-
this.localCerts = dedupeCertificates([
|
|
48
|
-
...opts.trustedCerts,
|
|
49
|
-
opts.untrustedCert,
|
|
50
|
-
]);
|
|
51
|
-
this.timestamp = opts.timestamp;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
public async verify(): Promise<X509Certificate[]> {
|
|
55
|
-
const certificatePath = await this.sort();
|
|
56
|
-
|
|
57
|
-
this.checkPath(certificatePath);
|
|
58
|
-
|
|
59
|
-
const validForDate = certificatePath.every((cert) =>
|
|
60
|
-
cert.validForDate(this.timestamp)
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
if (!validForDate) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
"certificate is not valid or expired at the specified date"
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return certificatePath;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
private async sort(): Promise<X509Certificate[]> {
|
|
73
|
-
const leafCert = this.untrustedCert;
|
|
74
|
-
|
|
75
|
-
let paths = await this.buildPaths(leafCert);
|
|
76
|
-
|
|
77
|
-
paths = paths.filter((path) =>
|
|
78
|
-
path.some((cert) => this.trustedCerts.includes(cert))
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
if (paths.length === 0) {
|
|
82
|
-
throw new Error("no trusted certificate path found");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const path = paths.reduce((prev, curr) =>
|
|
86
|
-
prev.length < curr.length ? prev : curr
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
return [leafCert, ...path].slice(0, -1);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private async buildPaths(
|
|
93
|
-
certificate: X509Certificate
|
|
94
|
-
): Promise<X509Certificate[][]> {
|
|
95
|
-
const paths = [];
|
|
96
|
-
const issuers = await this.findIssuer(certificate);
|
|
97
|
-
|
|
98
|
-
if (issuers.length === 0) {
|
|
99
|
-
throw new Error("no valid certificate path found");
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for (let i = 0; i < issuers.length; i++) {
|
|
103
|
-
const issuer = issuers[i];
|
|
104
|
-
|
|
105
|
-
if (issuer.equals(certificate)) {
|
|
106
|
-
paths.push([certificate]);
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const subPaths = await this.buildPaths(issuer);
|
|
111
|
-
|
|
112
|
-
for (let j = 0; j < subPaths.length; j++) {
|
|
113
|
-
paths.push([issuer, ...subPaths[j]]);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return paths;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private async findIssuer(
|
|
121
|
-
certificate: X509Certificate
|
|
122
|
-
): Promise<X509Certificate[]> {
|
|
123
|
-
let issuers: X509Certificate[] = [];
|
|
124
|
-
let keyIdentifier: Uint8Array | undefined;
|
|
125
|
-
|
|
126
|
-
if (uint8ArrayEqual(certificate.subject, certificate.issuer)) {
|
|
127
|
-
if (await certificate.verify()) {
|
|
128
|
-
return [certificate];
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (certificate.extAuthorityKeyID) {
|
|
133
|
-
keyIdentifier = certificate.extAuthorityKeyID.keyIdentifier;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
this.localCerts.forEach((possibleIssuer) => {
|
|
137
|
-
if (keyIdentifier) {
|
|
138
|
-
if (possibleIssuer.extSubjectKeyID) {
|
|
139
|
-
if (
|
|
140
|
-
uint8ArrayEqual(
|
|
141
|
-
possibleIssuer.extSubjectKeyID.keyIdentifier,
|
|
142
|
-
keyIdentifier
|
|
143
|
-
)
|
|
144
|
-
) {
|
|
145
|
-
issuers.push(possibleIssuer);
|
|
146
|
-
}
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (uint8ArrayEqual(possibleIssuer.subject, certificate.issuer)) {
|
|
152
|
-
issuers.push(possibleIssuer);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
const verifiedIssuers: X509Certificate[] = [];
|
|
157
|
-
for (const issuer of issuers) {
|
|
158
|
-
try {
|
|
159
|
-
if (await certificate.verify(issuer)) {
|
|
160
|
-
verifiedIssuers.push(issuer);
|
|
161
|
-
}
|
|
162
|
-
} catch (ex) {
|
|
163
|
-
// Ignore verification failures
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return verifiedIssuers;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
private checkPath(path: X509Certificate[]): void {
|
|
171
|
-
if (path.length < 1) {
|
|
172
|
-
throw new Error(
|
|
173
|
-
"certificate chain must contain at least one certificate"
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const validCAs = path.slice(1).every((cert) => cert.isCA);
|
|
178
|
-
if (!validCAs) {
|
|
179
|
-
throw new Error("intermediate certificate is not a CA");
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
for (let i = path.length - 2; i >= 0; i--) {
|
|
183
|
-
if (!uint8ArrayEqual(path[i].issuer, path[i + 1].subject)) {
|
|
184
|
-
throw new Error("incorrect certificate name chaining");
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
for (let i = 0; i < path.length; i++) {
|
|
189
|
-
const cert = path[i];
|
|
190
|
-
|
|
191
|
-
if (cert.extBasicConstraints?.isCA) {
|
|
192
|
-
const pathLength = cert.extBasicConstraints.pathLenConstraint;
|
|
193
|
-
|
|
194
|
-
if (pathLength !== undefined && pathLength < BigInt(i - 1)) {
|
|
195
|
-
throw new Error("path length constraint exceeded");
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function dedupeCertificates(certs: X509Certificate[]): X509Certificate[] {
|
|
203
|
-
for (let i = 0; i < certs.length; i++) {
|
|
204
|
-
for (let j = i + 1; j < certs.length; j++) {
|
|
205
|
-
if (certs[i].equals(certs[j])) {
|
|
206
|
-
certs.splice(j, 1);
|
|
207
|
-
j--;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return certs;
|
|
212
|
-
}
|
package/src/x509/ext.ts
DELETED
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2023 The Sigstore Authors.
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
import { ASN1Obj, ByteStream, Uint8ArrayToString } from "@freedomofpress/crypto-browser";
|
|
17
|
-
import { SignedCertificateTimestamp } from "./sct.js";
|
|
18
|
-
|
|
19
|
-
// https://www.rfc-editor.org/rfc/rfc5280#section-4.1
|
|
20
|
-
export class X509Extension {
|
|
21
|
-
protected root: ASN1Obj;
|
|
22
|
-
|
|
23
|
-
constructor(asn1: ASN1Obj) {
|
|
24
|
-
this.root = asn1;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
get oid(): string {
|
|
28
|
-
return this.root.subs[0].toOID();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get critical(): boolean {
|
|
32
|
-
// The critical field is optional and will be the second element of the
|
|
33
|
-
// extension sequence if present. Default to false if not present.
|
|
34
|
-
return this.root.subs.length === 3 ? this.root.subs[1].toBoolean() : false;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
get value(): Uint8Array {
|
|
38
|
-
return this.extnValueObj.value;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get valueObj(): ASN1Obj {
|
|
42
|
-
return this.extnValueObj;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
protected get extnValueObj(): ASN1Obj {
|
|
46
|
-
// The extnValue field will be the last element of the extension sequence
|
|
47
|
-
return this.root.subs[this.root.subs.length - 1];
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.9
|
|
52
|
-
export class X509BasicConstraintsExtension extends X509Extension {
|
|
53
|
-
get isCA(): boolean {
|
|
54
|
-
return this.sequence.subs[0]?.toBoolean() ?? false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
get pathLenConstraint(): bigint | undefined {
|
|
58
|
-
return this.sequence.subs.length > 1
|
|
59
|
-
? this.sequence.subs[1].toInteger()
|
|
60
|
-
: undefined;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// The extnValue field contains a single sequence wrapping the isCA and
|
|
64
|
-
// pathLenConstraint.
|
|
65
|
-
private get sequence(): ASN1Obj {
|
|
66
|
-
return this.extnValueObj.subs[0];
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.3
|
|
71
|
-
export class X509KeyUsageExtension extends X509Extension {
|
|
72
|
-
get digitalSignature(): boolean {
|
|
73
|
-
return this.bitString[0] === 1;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
get keyCertSign(): boolean {
|
|
77
|
-
return this.bitString[5] === 1;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
get crlSign(): boolean {
|
|
81
|
-
return this.bitString[6] === 1;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// The extnValue field contains a single bit string which is a bit mask
|
|
85
|
-
// indicating which key usages are enabled.
|
|
86
|
-
private get bitString(): number[] {
|
|
87
|
-
return this.extnValueObj.subs[0].toBitString();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.6
|
|
92
|
-
export class X509SubjectAlternativeNameExtension extends X509Extension {
|
|
93
|
-
get rfc822Name(): string | undefined {
|
|
94
|
-
const rfc822Name = this.findGeneralName(0x01)?.value;
|
|
95
|
-
if (rfc822Name === undefined) {
|
|
96
|
-
return undefined;
|
|
97
|
-
} else {
|
|
98
|
-
return Uint8ArrayToString(rfc822Name);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
get uri(): string | undefined {
|
|
103
|
-
const uri = this.findGeneralName(0x06)?.value;
|
|
104
|
-
if (uri === undefined) {
|
|
105
|
-
return undefined;
|
|
106
|
-
} else {
|
|
107
|
-
return Uint8ArrayToString(uri);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Retrieve the value of an otherName with the given OID.
|
|
112
|
-
public otherName(oid: string): string | undefined {
|
|
113
|
-
const otherName = this.findGeneralName(0x00);
|
|
114
|
-
|
|
115
|
-
if (otherName === undefined) {
|
|
116
|
-
return undefined;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// The otherName is a sequence containing an OID and a value.
|
|
120
|
-
// Need to check that the OID matches the one we're looking for.
|
|
121
|
-
const otherNameOID = otherName.subs[0].toOID();
|
|
122
|
-
if (otherNameOID !== oid) {
|
|
123
|
-
return undefined;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// The otherNameValue is a sequence containing the actual value.
|
|
127
|
-
const otherNameValue = otherName.subs[1];
|
|
128
|
-
return Uint8ArrayToString(otherNameValue.subs[0].value);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
private findGeneralName(tag: number): ASN1Obj | undefined {
|
|
132
|
-
return this.generalNames.find((gn) => gn.tag.isContextSpecific(tag));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// The extnValue field contains a sequence of GeneralNames.
|
|
136
|
-
private get generalNames(): ASN1Obj[] {
|
|
137
|
-
return this.extnValueObj.subs[0].subs;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.1
|
|
142
|
-
export class X509AuthorityKeyIDExtension extends X509Extension {
|
|
143
|
-
get keyIdentifier(): Uint8Array | undefined {
|
|
144
|
-
return this.findSequenceMember(0x00)?.value;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private findSequenceMember(tag: number): ASN1Obj | undefined {
|
|
148
|
-
return this.sequence.subs.find((el) => el.tag.isContextSpecific(tag));
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// The extnValue field contains a single sequence wrapping the keyIdentifier
|
|
152
|
-
private get sequence(): ASN1Obj {
|
|
153
|
-
return this.extnValueObj.subs[0];
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.2
|
|
158
|
-
export class X509SubjectKeyIDExtension extends X509Extension {
|
|
159
|
-
get keyIdentifier(): Uint8Array {
|
|
160
|
-
return this.extnValueObj.subs[0].value;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Base class for Fulcio extensions with V1 format (raw OCTET STRING value)
|
|
165
|
-
// https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md
|
|
166
|
-
class X509FulcioExtensionV1 extends X509Extension {
|
|
167
|
-
get stringValue(): string {
|
|
168
|
-
return Uint8ArrayToString(this.extnValueObj.value);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Base class for Fulcio extensions with V2 format (DER-encoded UTF8String)
|
|
173
|
-
class X509FulcioExtensionV2 extends X509Extension {
|
|
174
|
-
get stringValue(): string {
|
|
175
|
-
return Uint8ArrayToString(this.extnValueObj.subs[0].value);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// OID 1.3.6.1.4.1.57264.1.1 - OIDC Issuer (V1)
|
|
180
|
-
export class X509FulcioIssuerV1 extends X509FulcioExtensionV1 {
|
|
181
|
-
get issuer(): string {
|
|
182
|
-
return this.stringValue;
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// OID 1.3.6.1.4.1.57264.1.2 - GitHub Workflow Trigger (V1)
|
|
187
|
-
export class X509GitHubWorkflowTriggerExtension extends X509FulcioExtensionV1 {
|
|
188
|
-
get workflowTrigger(): string {
|
|
189
|
-
return this.stringValue;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// OID 1.3.6.1.4.1.57264.1.3 - GitHub Workflow SHA (V1)
|
|
194
|
-
export class X509GitHubWorkflowSHAExtension extends X509FulcioExtensionV1 {
|
|
195
|
-
get workflowSHA(): string {
|
|
196
|
-
return this.stringValue;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// OID 1.3.6.1.4.1.57264.1.4 - GitHub Workflow Name (V1)
|
|
201
|
-
export class X509GitHubWorkflowNameExtension extends X509FulcioExtensionV1 {
|
|
202
|
-
get workflowName(): string {
|
|
203
|
-
return this.stringValue;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// OID 1.3.6.1.4.1.57264.1.5 - GitHub Workflow Repository (V1)
|
|
208
|
-
export class X509GitHubWorkflowRepositoryExtension extends X509FulcioExtensionV1 {
|
|
209
|
-
get workflowRepository(): string {
|
|
210
|
-
return this.stringValue;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// OID 1.3.6.1.4.1.57264.1.6 - GitHub Workflow Ref (V1)
|
|
215
|
-
export class X509GitHubWorkflowRefExtension extends X509FulcioExtensionV1 {
|
|
216
|
-
get workflowRef(): string {
|
|
217
|
-
return this.stringValue;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// OID 1.3.6.1.4.1.57264.1.8 - OIDC Issuer (V2)
|
|
222
|
-
export class X509FulcioIssuerV2 extends X509FulcioExtensionV2 {
|
|
223
|
-
get issuer(): string {
|
|
224
|
-
return this.stringValue;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// OID 1.3.6.1.4.1.57264.1.9 - Build Signer URI (V2)
|
|
229
|
-
export class X509BuildSignerURIExtension extends X509FulcioExtensionV2 {
|
|
230
|
-
get buildSignerURI(): string {
|
|
231
|
-
return this.stringValue;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// OID 1.3.6.1.4.1.57264.1.10 - Build Signer Digest (V2)
|
|
236
|
-
export class X509BuildSignerDigestExtension extends X509FulcioExtensionV2 {
|
|
237
|
-
get buildSignerDigest(): string {
|
|
238
|
-
return this.stringValue;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
// OID 1.3.6.1.4.1.57264.1.11 - Runner Environment (V2)
|
|
243
|
-
export class X509RunnerEnvironmentExtension extends X509FulcioExtensionV2 {
|
|
244
|
-
get runnerEnvironment(): string {
|
|
245
|
-
return this.stringValue;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// OID 1.3.6.1.4.1.57264.1.12 - Source Repository URI (V2)
|
|
250
|
-
export class X509SourceRepositoryURIExtension extends X509FulcioExtensionV2 {
|
|
251
|
-
get sourceRepositoryURI(): string {
|
|
252
|
-
return this.stringValue;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// OID 1.3.6.1.4.1.57264.1.13 - Source Repository Digest (V2)
|
|
257
|
-
export class X509SourceRepositoryDigestExtension extends X509FulcioExtensionV2 {
|
|
258
|
-
get sourceRepositoryDigest(): string {
|
|
259
|
-
return this.stringValue;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// OID 1.3.6.1.4.1.57264.1.14 - Source Repository Ref (V2)
|
|
264
|
-
export class X509SourceRepositoryRefExtension extends X509FulcioExtensionV2 {
|
|
265
|
-
get sourceRepositoryRef(): string {
|
|
266
|
-
return this.stringValue;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// OID 1.3.6.1.4.1.57264.1.15 - Source Repository Identifier (V2)
|
|
271
|
-
export class X509SourceRepositoryIdentifierExtension extends X509FulcioExtensionV2 {
|
|
272
|
-
get sourceRepositoryIdentifier(): string {
|
|
273
|
-
return this.stringValue;
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// OID 1.3.6.1.4.1.57264.1.16 - Source Repository Owner URI (V2)
|
|
278
|
-
export class X509SourceRepositoryOwnerURIExtension extends X509FulcioExtensionV2 {
|
|
279
|
-
get sourceRepositoryOwnerURI(): string {
|
|
280
|
-
return this.stringValue;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// OID 1.3.6.1.4.1.57264.1.17 - Source Repository Owner Identifier (V2)
|
|
285
|
-
export class X509SourceRepositoryOwnerIdentifierExtension extends X509FulcioExtensionV2 {
|
|
286
|
-
get sourceRepositoryOwnerIdentifier(): string {
|
|
287
|
-
return this.stringValue;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// OID 1.3.6.1.4.1.57264.1.18 - Build Config URI (V2)
|
|
292
|
-
export class X509BuildConfigURIExtension extends X509FulcioExtensionV2 {
|
|
293
|
-
get buildConfigURI(): string {
|
|
294
|
-
return this.stringValue;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// OID 1.3.6.1.4.1.57264.1.19 - Build Config Digest (V2)
|
|
299
|
-
export class X509BuildConfigDigestExtension extends X509FulcioExtensionV2 {
|
|
300
|
-
get buildConfigDigest(): string {
|
|
301
|
-
return this.stringValue;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// OID 1.3.6.1.4.1.57264.1.20 - Build Trigger (V2)
|
|
306
|
-
export class X509BuildTriggerExtension extends X509FulcioExtensionV2 {
|
|
307
|
-
get buildTrigger(): string {
|
|
308
|
-
return this.stringValue;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// OID 1.3.6.1.4.1.57264.1.21 - Run Invocation URI (V2)
|
|
313
|
-
export class X509RunInvocationURIExtension extends X509FulcioExtensionV2 {
|
|
314
|
-
get runInvocationURI(): string {
|
|
315
|
-
return this.stringValue;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// OID 1.3.6.1.4.1.57264.1.22 - Source Repository Visibility (V2)
|
|
320
|
-
export class X509SourceRepositoryVisibilityExtension extends X509FulcioExtensionV2 {
|
|
321
|
-
get sourceRepositoryVisibility(): string {
|
|
322
|
-
return this.stringValue;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// https://www.rfc-editor.org/rfc/rfc6962#section-3.3
|
|
327
|
-
export class X509SCTExtension extends X509Extension {
|
|
328
|
-
constructor(asn1: ASN1Obj) {
|
|
329
|
-
super(asn1);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
get signedCertificateTimestamps(): SignedCertificateTimestamp[] {
|
|
333
|
-
const buf = this.extnValueObj.subs[0].value;
|
|
334
|
-
const stream = new ByteStream(buf);
|
|
335
|
-
|
|
336
|
-
// The overall list length is encoded in the first two bytes -- note this
|
|
337
|
-
// is the length of the list in bytes, NOT the number of SCTs in the list
|
|
338
|
-
const end = stream.getUint16() + 2;
|
|
339
|
-
|
|
340
|
-
const sctList: SignedCertificateTimestamp[] = [];
|
|
341
|
-
while (stream.position < end) {
|
|
342
|
-
// Read the length of the next SCT
|
|
343
|
-
const sctLength = stream.getUint16();
|
|
344
|
-
|
|
345
|
-
// Slice out the bytes for the next SCT and parse it
|
|
346
|
-
const sct = stream.getBlock(sctLength);
|
|
347
|
-
sctList.push(SignedCertificateTimestamp.parse(sct));
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
if (stream.position !== end) {
|
|
351
|
-
throw new Error("SCT list length does not match actual length");
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
return sctList;
|
|
355
|
-
}
|
|
356
|
-
}
|
package/src/x509/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2023 The Sigstore Authors.
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export { EXTENSION_OID_SCT, X509Certificate } from "./cert.js";
|
|
18
|
-
export { X509SCTExtension } from "./ext.js";
|
|
19
|
-
export { CertificateChainVerifier } from "./chain.js";
|