codekingpro/portable-devtools
114k
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.assertBundle = assertBundle;
4exports.assertBundleV01 = assertBundleV01;
5exports.isBundleV01 = isBundleV01;
6exports.assertBundleV02 = assertBundleV02;
7exports.assertBundleLatest = assertBundleLatest;
8/*
9Copyright 2023 The Sigstore Authors.
10
11Licensed under the Apache License, Version 2.0 (the "License");
12you may not use this file except in compliance with the License.
13You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17Unless required by applicable law or agreed to in writing, software
18distributed under the License is distributed on an "AS IS" BASIS,
19WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20See the License for the specific language governing permissions and
21limitations under the License.
22*/
23const error_1 = require("./error");
24// Performs basic validation of a Sigstore bundle to ensure that all required
25// fields are populated. This is not a complete validation of the bundle, but
26// rather a check that the bundle is in a valid state to be processed by the
27// rest of the code.
28function assertBundle(b) {
29 const invalidValues = validateBundleBase(b);
30 if (invalidValues.length > 0) {
31 throw new error_1.ValidationError('invalid bundle', invalidValues);
32 }
33}
34// Asserts that the given bundle conforms to the v0.1 bundle format.
35function assertBundleV01(b) {
36 const invalidValues = [];
37 invalidValues.push(...validateBundleBase(b));
38 invalidValues.push(...validateInclusionPromise(b));
39 if (invalidValues.length > 0) {
40 throw new error_1.ValidationError('invalid v0.1 bundle', invalidValues);
41 }
42}
43// Type guard to determine if Bundle is a v0.1 bundle.
44function isBundleV01(b) {
45 try {
46 assertBundleV01(b);
47 return true;
48 }
49 catch (e) {
50 return false;
51 }
52}
53// Asserts that the given bundle conforms to the v0.2 bundle format.
54function assertBundleV02(b) {
55 const invalidValues = [];
56 invalidValues.push(...validateBundleBase(b));
57 invalidValues.push(...validateInclusionProof(b));
58 if (invalidValues.length > 0) {
59 throw new error_1.ValidationError('invalid v0.2 bundle', invalidValues);
60 }
61}
62// Asserts that the given bundle conforms to the newest (0.3) bundle format.
63function assertBundleLatest(b) {
64 const invalidValues = [];
65 invalidValues.push(...validateBundleBase(b));
66 invalidValues.push(...validateInclusionProof(b));
67 invalidValues.push(...validateNoCertificateChain(b));
68 if (invalidValues.length > 0) {
69 throw new error_1.ValidationError('invalid bundle', invalidValues);
70 }
71}
72function validateBundleBase(b) {
73 const invalidValues = [];
74 // Media type validation
75 if (b.mediaType === undefined ||
76 (!b.mediaType.match(/^application\/vnd\.dev\.sigstore\.bundle\+json;version=\d\.\d/) &&
77 !b.mediaType.match(/^application\/vnd\.dev\.sigstore\.bundle\.v\d\.\d\+json/))) {
78 invalidValues.push('mediaType');
79 }
80 // Content-related validation
81 if (b.content === undefined) {
82 invalidValues.push('content');
83 }
84 else {
85 switch (b.content.$case) {
86 case 'messageSignature':
87 if (b.content.messageSignature.messageDigest === undefined) {
88 invalidValues.push('content.messageSignature.messageDigest');
89 }
90 else {
91 if (b.content.messageSignature.messageDigest.digest.length === 0) {
92 invalidValues.push('content.messageSignature.messageDigest.digest');
93 }
94 }
95 if (b.content.messageSignature.signature.length === 0) {
96 invalidValues.push('content.messageSignature.signature');
97 }
98 break;
99 case 'dsseEnvelope':
100 if (b.content.dsseEnvelope.payload.length === 0) {
101 invalidValues.push('content.dsseEnvelope.payload');
102 }
103 if (b.content.dsseEnvelope.signatures.length !== 1) {
104 invalidValues.push('content.dsseEnvelope.signatures');
105 }
106 else {
107 if (b.content.dsseEnvelope.signatures[0].sig.length === 0) {
108 invalidValues.push('content.dsseEnvelope.signatures[0].sig');
109 }
110 }
111 break;
112 }
113 }
114 // Verification material-related validation
115 if (b.verificationMaterial === undefined) {
116 invalidValues.push('verificationMaterial');
117 }
118 else {
119 if (b.verificationMaterial.content === undefined) {
120 invalidValues.push('verificationMaterial.content');
121 }
122 else {
123 switch (b.verificationMaterial.content.$case) {
124 case 'x509CertificateChain':
125 if (b.verificationMaterial.content.x509CertificateChain.certificates
126 .length === 0) {
127 invalidValues.push('verificationMaterial.content.x509CertificateChain.certificates');
128 }
129 b.verificationMaterial.content.x509CertificateChain.certificates.forEach((cert, i) => {
130 if (cert.rawBytes.length === 0) {
131 invalidValues.push(`verificationMaterial.content.x509CertificateChain.certificates[${i}].rawBytes`);
132 }
133 });
134 break;
135 case 'certificate':
136 if (b.verificationMaterial.content.certificate.rawBytes.length === 0) {
137 invalidValues.push('verificationMaterial.content.certificate.rawBytes');
138 }
139 break;
140 }
141 }
142 if (b.verificationMaterial.tlogEntries === undefined) {
143 invalidValues.push('verificationMaterial.tlogEntries');
144 }
145 else {
146 if (b.verificationMaterial.tlogEntries.length > 0) {
147 b.verificationMaterial.tlogEntries.forEach((entry, i) => {
148 if (entry.logId === undefined) {
149 invalidValues.push(`verificationMaterial.tlogEntries[${i}].logId`);
150 }
151 if (entry.kindVersion === undefined) {
152 invalidValues.push(`verificationMaterial.tlogEntries[${i}].kindVersion`);
153 }
154 });
155 }
156 }
157 }
158 return invalidValues;
159}
160// Necessary for V01 bundles
161function validateInclusionPromise(b) {
162 const invalidValues = [];
163 if (b.verificationMaterial &&
164 b.verificationMaterial.tlogEntries?.length > 0) {
165 b.verificationMaterial.tlogEntries.forEach((entry, i) => {
166 if (entry.inclusionPromise === undefined) {
167 invalidValues.push(`verificationMaterial.tlogEntries[${i}].inclusionPromise`);
168 }
169 });
170 }
171 return invalidValues;
172}
173// Necessary for V02 and later bundles
174function validateInclusionProof(b) {
175 const invalidValues = [];
176 if (b.verificationMaterial &&
177 b.verificationMaterial.tlogEntries?.length > 0) {
178 b.verificationMaterial.tlogEntries.forEach((entry, i) => {
179 if (entry.inclusionProof === undefined) {
180 invalidValues.push(`verificationMaterial.tlogEntries[${i}].inclusionProof`);
181 }
182 else {
183 if (entry.inclusionProof.checkpoint === undefined) {
184 invalidValues.push(`verificationMaterial.tlogEntries[${i}].inclusionProof.checkpoint`);
185 }
186 }
187 });
188 }
189 return invalidValues;
190}
191// Necessary for V03 and later bundles
192function validateNoCertificateChain(b) {
193 const invalidValues = [];
194 /* istanbul ignore next */
195 if (b.verificationMaterial?.content?.$case === 'x509CertificateChain') {
196 invalidValues.push('verificationMaterial.content.$case');
197 }
198 return invalidValues;
199}
200 