-
Notifications
You must be signed in to change notification settings - Fork 547
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Swap the use of the go-tuf v0.7.0 client from sigstore/sigstore to the v2.0.0 client from sigstore/sigstore-go. This change strictly adds logic to attempt to use the sigstore-go TUF client if possible, and falls back to the old TUF client. The new client can only fetch targets by name, not by custom metadata. This means that, on its own, the new client cannot support renaming/rotating keys, so the old client must be used to support that case. A future change will add support for fetching or reading a trusted_root.json file, which has better support for rotating keys. Once this later change is introduced, using the old client can be deprecated. The logic in this change works as follows: - if a path fo a key is provided by a SIGSTORE_ environment variable, read that file and use it (same as previously) - if new environment variables TUF_MIRROR and TUF_ROOT_JSON are set, use those to instantiate a TUF client that fetches keys from the given mirror - else, try reading the mirror URL from remote.json, which set set by `cosign initialize`, and try reading the root.json from the mirror's cache directory which may have been created by a previous TUF v2 run - if fetching keys using the new client with the given mirror did not work, fallback to the v1 client Also not that the use of the "status" field in the custom TUF metadata is removed, as it was only used for human-readable feedback. TODO: - e2e tests Signed-off-by: Colleen Murphy <colleenmurphy@google.com>
- Loading branch information
Showing
15 changed files
with
456 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright 2024 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. | ||
|
||
package cosign | ||
|
||
import ( | ||
"bytes" | ||
"crypto/x509" | ||
"fmt" | ||
"os" | ||
|
||
"github.com/sigstore/cosign/v2/pkg/cosign/env" | ||
"github.com/sigstore/sigstore-go/pkg/tuf" | ||
"github.com/sigstore/sigstore/pkg/cryptoutils" | ||
"github.com/sigstore/sigstore/pkg/fulcioroots" | ||
) | ||
|
||
const ( | ||
// This is the root in the fulcio project. | ||
fulcioTargetStr = `fulcio.crt.pem` | ||
// This is the v1 migrated root. | ||
fulcioV1TargetStr = `fulcio_v1.crt.pem` | ||
// This is the untrusted v1 intermediate CA certificate, used or chain building. | ||
fulcioV1IntermediateTargetStr = `fulcio_intermediate_v1.crt.pem` | ||
) | ||
|
||
func GetFulcioCerts() (*x509.CertPool, *x509.CertPool, error) { | ||
rootEnv := env.Getenv(env.VariableSigstoreRootFile) | ||
if rootEnv != "" { | ||
return getFulcioCertsFromFile(rootEnv) | ||
} | ||
|
||
opts, err := setTUFOpts() | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
roots, intermediates, _ := getFulcioCertsFromTUF(opts) | ||
if roots == nil { | ||
roots, intermediates, err = legacyGetFulcioCertsFromTUF() | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error getting fulcio certs: %w", err) | ||
} | ||
} | ||
return roots, intermediates, nil | ||
} | ||
|
||
func getFulcioCertsFromFile(path string) (*x509.CertPool, *x509.CertPool, error) { | ||
rootPool := x509.NewCertPool() | ||
// intermediatePool should be nil if no intermediates are found | ||
var intermediatePool *x509.CertPool | ||
raw, err := os.ReadFile(path) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error reading root PEM file: %w", err) | ||
} | ||
certs, err := cryptoutils.UnmarshalCertificatesFromPEM(raw) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error unmarshalling certificates: %w", err) | ||
} | ||
for _, cert := range certs { | ||
// root certificates are self-signed | ||
if bytes.Equal(cert.RawSubject, cert.RawIssuer) { | ||
rootPool.AddCert(cert) | ||
} else { | ||
if intermediatePool == nil { | ||
intermediatePool = x509.NewCertPool() | ||
} | ||
intermediatePool.AddCert(cert) | ||
} | ||
} | ||
return rootPool, intermediatePool, nil | ||
} | ||
|
||
func getFulcioCertsFromTUF(opts *tuf.Options) (*x509.CertPool, *x509.CertPool, error) { | ||
tufClient, err := tuf.New(opts) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error creating TUF client: %w", err) | ||
} | ||
rootPool := x509.NewCertPool() | ||
fulcioCertBytes, _ := tufClient.GetTarget(fulcioTargetStr) | ||
fulcioV1CertBytes, _ := tufClient.GetTarget(fulcioV1TargetStr) | ||
if len(fulcioCertBytes) > 0 { | ||
fulcioCert, err := cryptoutils.UnmarshalCertificatesFromPEM(fulcioCertBytes) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error unmarshalling fulcio cert: %w", err) | ||
} | ||
for _, c := range fulcioCert { | ||
rootPool.AddCert(c) | ||
} | ||
} | ||
if len(fulcioV1CertBytes) > 0 { | ||
fulcioV1Cert, err := cryptoutils.UnmarshalCertificatesFromPEM(fulcioV1CertBytes) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error unmarshalling fulcio v1 cert: %w", err) | ||
} | ||
for _, c := range fulcioV1Cert { | ||
rootPool.AddCert(c) | ||
} | ||
} | ||
|
||
var intermediatePool *x509.CertPool | ||
fulcioIntermediateBytes, _ := tufClient.GetTarget(fulcioV1IntermediateTargetStr) | ||
if len(fulcioIntermediateBytes) == 0 { | ||
fulcioIntermediate, err := cryptoutils.UnmarshalCertificatesFromPEM(fulcioIntermediateBytes) | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error unmarshalling fulcio intermediate cert: %w", err) | ||
} | ||
intermediatePool = x509.NewCertPool() | ||
for _, c := range fulcioIntermediate { | ||
intermediatePool.AddCert(c) | ||
} | ||
} | ||
return rootPool, intermediatePool, nil | ||
} | ||
|
||
func legacyGetFulcioCertsFromTUF() (*x509.CertPool, *x509.CertPool, error) { | ||
roots, err := fulcioroots.Get() | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error getting fulcio roots: %w", err) | ||
} | ||
intermediates, err := fulcioroots.GetIntermediates() | ||
if err != nil { | ||
return nil, nil, fmt.Errorf("error getting fulcio intermediates: %w", err) | ||
} | ||
return roots, intermediates, err | ||
} |
Oops, something went wrong.