@@ -216,86 +216,15 @@ func verifyOCISignature(ctx context.Context, verifier signature.Verifier, sig pa
216
216
return verifier .VerifySignature (bytes .NewReader (signature ), bytes .NewReader (payload ), options .WithContext (ctx ))
217
217
}
218
218
219
- // ValidateAndUnpackCert creates a Verifier from a certificate. Veries that the certificate
220
- // chains up to a trusted root. Optionally verifies the subject and issuer of the certificate.
219
+ // ValidateAndUnpackCert calls ValidateAndUnpackCertWithIntermediates() by passing intermediate
220
+ // certs from checkOpts as seperate argument
221
221
func ValidateAndUnpackCert (cert * x509.Certificate , co * CheckOpts ) (signature.Verifier , error ) {
222
- verifier , err := signature .LoadVerifier (cert .PublicKey , crypto .SHA256 )
223
- if err != nil {
224
- return nil , fmt .Errorf ("invalid certificate found on signature: %w" , err )
225
- }
226
-
227
- // Handle certificates where the Subject Alternative Name is not set to a supported
228
- // GeneralName (RFC 5280 4.2.1.6). Go only supports DNS, IP addresses, email addresses,
229
- // or URIs as SANs. Fulcio can issue a certificate with an OtherName GeneralName, so
230
- // remove the unhandled critical SAN extension before verifying.
231
- if len (cert .UnhandledCriticalExtensions ) > 0 {
232
- var unhandledExts []asn1.ObjectIdentifier
233
- for _ , oid := range cert .UnhandledCriticalExtensions {
234
- if ! oid .Equal (cryptoutils .SANOID ) {
235
- unhandledExts = append (unhandledExts , oid )
236
- }
237
- }
238
- cert .UnhandledCriticalExtensions = unhandledExts
239
- }
240
-
241
- // Now verify the cert, then the signature.
242
- chains , err := TrustedCert (cert , co .RootCerts , co .IntermediateCerts )
243
- if err != nil {
244
- return nil , err
245
- }
246
-
247
- err = CheckCertificatePolicy (cert , co )
248
- if err != nil {
249
- return nil , err
250
- }
251
-
252
- // If IgnoreSCT is set, skip the SCT check
253
- if co .IgnoreSCT {
254
- return verifier , nil
255
- }
256
- contains , err := ContainsSCT (cert .Raw )
257
- if err != nil {
258
- return nil , err
259
- }
260
- if ! contains && len (co .SCT ) == 0 {
261
- return nil , & VerificationFailure {
262
- fmt .Errorf ("certificate does not include required embedded SCT and no detached SCT was set" ),
263
- }
264
- }
265
- // handle if chains has more than one chain - grab first and print message
266
- if len (chains ) > 1 {
267
- fmt .Fprintf (os .Stderr , "**Info** Multiple valid certificate chains found. Selecting the first to verify the SCT.\n " )
268
- }
269
- if contains {
270
- if err := VerifyEmbeddedSCT (context .Background (), chains [0 ], co .CTLogPubKeys ); err != nil {
271
- return nil , err
272
- }
273
- } else {
274
- chain := chains [0 ]
275
- if len (chain ) < 2 {
276
- return nil , errors .New ("certificate chain must contain at least a certificate and its issuer" )
277
- }
278
- certPEM , err := cryptoutils .MarshalCertificateToPEM (chain [0 ])
279
- if err != nil {
280
- return nil , err
281
- }
282
- chainPEM , err := cryptoutils .MarshalCertificatesToPEM (chain [1 :])
283
- if err != nil {
284
- return nil , err
285
- }
286
- if err := VerifySCT (context .Background (), certPEM , chainPEM , co .SCT , co .CTLogPubKeys ); err != nil {
287
- return nil , err
288
- }
289
- }
290
-
291
- return verifier , nil
222
+ return ValidateAndUnpackCertWithIntermediates (cert , co , co .IntermediateCerts )
292
223
}
293
224
294
- // ValidateAndUnpackCertWithIntermediates function has same logic as ValidateAndUnpackCert.
295
- // Main diffrence is that we can not use ValidateAndUnpackCert in multi thread invocation
296
- // as it uses a common reference of CheckOpts so in multi thread invocation co.intermediateCert object
297
- // can get overwritten my multiple threads. So to solve this ValidateAndUnpackCertWithIntermediates
298
- // is created which has a separate argument for Intermediate certs.
225
+ // ValidateAndUnpackCertWithIntermediates creates a Verifier from a certificate. Verifies that the
226
+ // certificate chains up to a trusted root using intermediate cert passed as seperate argument.
227
+ // Optionally verifies the subject and issuer of the certificate.
299
228
func ValidateAndUnpackCertWithIntermediates (cert * x509.Certificate , co * CheckOpts , intermediateCerts * x509.CertPool ) (signature.Verifier , error ) {
300
229
verifier , err := signature .LoadVerifier (cert .PublicKey , crypto .SHA256 )
301
230
if err != nil {
@@ -317,9 +246,6 @@ func ValidateAndUnpackCertWithIntermediates(cert *x509.Certificate, co *CheckOpt
317
246
}
318
247
319
248
// Now verify the cert, then the signature.
320
- if intermediateCerts == nil {
321
- intermediateCerts = co .IntermediateCerts
322
- }
323
249
chains , err := TrustedCert (cert , co .RootCerts , intermediateCerts )
324
250
325
251
if err != nil {
@@ -803,11 +729,9 @@ func verifyInternal(ctx context.Context, sig oci.Signature, h v1.Hash,
803
729
return false , err
804
730
}
805
731
// If there is no chain annotation present, we preserve the pools set in the CheckOpts.
806
- var pool = (* x509 .CertPool )(nil )
807
- if len (chain ) > 0 {
808
- if len (chain ) == 1 {
809
- co .IntermediateCerts = nil
810
- } else if co .IntermediateCerts == nil {
732
+ var pool * x509.CertPool
733
+ if len (chain ) > 1 {
734
+ if co .IntermediateCerts == nil {
811
735
// If the intermediate certs have not been loaded in by TUF
812
736
pool = x509 .NewCertPool ()
813
737
for _ , cert := range chain [:len (chain )- 1 ] {
0 commit comments