mirror of
https://github.com/containers/skopeo.git
synced 2025-04-27 11:01:18 +00:00
fix(deps): update module github.com/containers/image/v5 to v5.34.1
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
parent
2d79fec20c
commit
8a44fe6c8b
2
go.mod
2
go.mod
@ -8,7 +8,7 @@ go 1.22.8
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.3.1
|
||||
github.com/containers/common v0.62.0
|
||||
github.com/containers/image/v5 v5.34.0
|
||||
github.com/containers/image/v5 v5.34.1
|
||||
github.com/containers/ocicrypt v1.2.1
|
||||
github.com/containers/storage v1.57.1
|
||||
github.com/docker/distribution v2.8.3+incompatible
|
||||
|
4
go.sum
4
go.sum
@ -43,8 +43,8 @@ github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++
|
||||
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||
github.com/containers/common v0.62.0 h1:Sl9WE5h7Y/F3bejrMAA4teP1EcY9ygqJmW4iwSloZ10=
|
||||
github.com/containers/common v0.62.0/go.mod h1:Yec+z8mrSq4rydHofrnDCBqAcNA/BGrSg1kfFUL6F6s=
|
||||
github.com/containers/image/v5 v5.34.0 h1:HPqQaDUsox/3mC1pbOyLAIQEp0JhQqiUZ+6JiFIZLDI=
|
||||
github.com/containers/image/v5 v5.34.0/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo=
|
||||
github.com/containers/image/v5 v5.34.1 h1:/m2bkFnuedTyNkzma8s7cFLjeefPIb4trjyafWhIlwM=
|
||||
github.com/containers/image/v5 v5.34.1/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
|
||||
github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
|
||||
|
28
vendor/github.com/containers/image/v5/signature/fulcio_cert.go
generated
vendored
28
vendor/github.com/containers/image/v5/signature/fulcio_cert.go
generated
vendored
@ -108,19 +108,10 @@ func (f *fulcioTrustRoot) verifyFulcioCertificateAtTime(relevantTime time.Time,
|
||||
}
|
||||
}
|
||||
|
||||
untrustedLeafCerts, err := cryptoutils.UnmarshalCertificatesFromPEM(untrustedCertificateBytes)
|
||||
untrustedCertificate, err := parseLeafCertFromPEM(untrustedCertificateBytes)
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("parsing leaf certificate: %v", err))
|
||||
return nil, err
|
||||
}
|
||||
switch len(untrustedLeafCerts) {
|
||||
case 0:
|
||||
return nil, internal.NewInvalidSignatureError("no certificate found in signature certificate data")
|
||||
case 1:
|
||||
break // OK
|
||||
default:
|
||||
return nil, internal.NewInvalidSignatureError("unexpected multiple certificates present in signature certificate data")
|
||||
}
|
||||
untrustedCertificate := untrustedLeafCerts[0]
|
||||
|
||||
// Go rejects Subject Alternative Name that has no DNSNames, EmailAddresses, IPAddresses and URIs;
|
||||
// we match SAN ourselves, so override that.
|
||||
@ -195,6 +186,21 @@ func (f *fulcioTrustRoot) verifyFulcioCertificateAtTime(relevantTime time.Time,
|
||||
return untrustedCertificate.PublicKey, nil
|
||||
}
|
||||
|
||||
func parseLeafCertFromPEM(untrustedCertificateBytes []byte) (*x509.Certificate, error) {
|
||||
untrustedLeafCerts, err := cryptoutils.UnmarshalCertificatesFromPEM(untrustedCertificateBytes)
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("parsing leaf certificate: %v", err))
|
||||
}
|
||||
switch len(untrustedLeafCerts) {
|
||||
case 0:
|
||||
return nil, internal.NewInvalidSignatureError("no certificate found in signature certificate data")
|
||||
case 1: // OK
|
||||
return untrustedLeafCerts[0], nil
|
||||
default:
|
||||
return nil, internal.NewInvalidSignatureError("unexpected multiple certificates present in signature certificate data")
|
||||
}
|
||||
}
|
||||
|
||||
func verifyRekorFulcio(rekorPublicKeys []*ecdsa.PublicKey, fulcioTrustRoot *fulcioTrustRoot, untrustedRekorSET []byte,
|
||||
untrustedCertificateBytes []byte, untrustedIntermediateChainBytes []byte, untrustedBase64Signature string,
|
||||
untrustedPayloadBytes []byte) (crypto.PublicKey, error) {
|
||||
|
74
vendor/github.com/containers/image/v5/signature/pki_cert.go
generated
vendored
Normal file
74
vendor/github.com/containers/image/v5/signature/pki_cert.go
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
package signature
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"github.com/containers/image/v5/signature/internal"
|
||||
"github.com/sigstore/sigstore/pkg/cryptoutils"
|
||||
)
|
||||
|
||||
type pkiTrustRoot struct {
|
||||
caRootsCertificates *x509.CertPool
|
||||
caIntermediateCertificates *x509.CertPool
|
||||
subjectEmail string
|
||||
subjectHostname string
|
||||
}
|
||||
|
||||
func (p *pkiTrustRoot) validate() error {
|
||||
if p.subjectEmail == "" && p.subjectHostname == "" {
|
||||
return errors.New("Internal inconsistency: PKI use set up without subject email or subject hostname")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyPKI(pkiTrustRoot *pkiTrustRoot, untrustedCertificateBytes []byte, untrustedIntermediateChainBytes []byte) (crypto.PublicKey, error) {
|
||||
var untrustedIntermediatePool *x509.CertPool
|
||||
if pkiTrustRoot.caIntermediateCertificates != nil {
|
||||
untrustedIntermediatePool = pkiTrustRoot.caIntermediateCertificates.Clone()
|
||||
} else {
|
||||
untrustedIntermediatePool = x509.NewCertPool()
|
||||
}
|
||||
if len(untrustedIntermediateChainBytes) > 0 {
|
||||
untrustedIntermediateChain, err := cryptoutils.UnmarshalCertificatesFromPEM(untrustedIntermediateChainBytes)
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("loading certificate chain: %v", err))
|
||||
}
|
||||
if len(untrustedIntermediateChain) > 1 {
|
||||
for _, untrustedIntermediateCert := range untrustedIntermediateChain[:len(untrustedIntermediateChain)-1] {
|
||||
untrustedIntermediatePool.AddCert(untrustedIntermediateCert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
untrustedCertificate, err := parseLeafCertFromPEM(untrustedCertificateBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := untrustedCertificate.Verify(x509.VerifyOptions{
|
||||
Intermediates: untrustedIntermediatePool,
|
||||
Roots: pkiTrustRoot.caRootsCertificates,
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
|
||||
}); err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("veryfing leaf certificate failed: %v", err))
|
||||
}
|
||||
|
||||
if pkiTrustRoot.subjectEmail != "" {
|
||||
if !slices.Contains(untrustedCertificate.EmailAddresses, pkiTrustRoot.subjectEmail) {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("Required email %q not found (got %q)",
|
||||
pkiTrustRoot.subjectEmail,
|
||||
untrustedCertificate.EmailAddresses))
|
||||
}
|
||||
}
|
||||
if pkiTrustRoot.subjectHostname != "" {
|
||||
if err = untrustedCertificate.VerifyHostname(pkiTrustRoot.subjectHostname); err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("Unexpected subject hostname: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
return untrustedCertificate.PublicKey, nil
|
||||
}
|
192
vendor/github.com/containers/image/v5/signature/policy_config_sigstore.go
generated
vendored
192
vendor/github.com/containers/image/v5/signature/policy_config_sigstore.go
generated
vendored
@ -71,6 +71,17 @@ func PRSigstoreSignedWithFulcio(fulcio PRSigstoreSignedFulcio) PRSigstoreSignedO
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedWithPKI specifies a value for the "pki" field when calling NewPRSigstoreSigned.
|
||||
func PRSigstoreSignedWithPKI(p PRSigstoreSignedPKI) PRSigstoreSignedOption {
|
||||
return func(pr *prSigstoreSigned) error {
|
||||
if pr.PKI != nil {
|
||||
return InvalidPolicyFormatError(`"pki" already specified`)
|
||||
}
|
||||
pr.PKI = p
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedWithRekorPublicKeyPath specifies a value for the "rekorPublicKeyPath" field when calling NewPRSigstoreSigned.
|
||||
func PRSigstoreSignedWithRekorPublicKeyPath(rekorPublicKeyPath string) PRSigstoreSignedOption {
|
||||
return func(pr *prSigstoreSigned) error {
|
||||
@ -159,8 +170,11 @@ func newPRSigstoreSigned(options ...PRSigstoreSignedOption) (*prSigstoreSigned,
|
||||
if res.Fulcio != nil {
|
||||
keySources++
|
||||
}
|
||||
if res.PKI != nil {
|
||||
keySources++
|
||||
}
|
||||
if keySources != 1 {
|
||||
return nil, InvalidPolicyFormatError("exactly one of keyPath, keyPaths, keyData, keyDatas and fulcio must be specified")
|
||||
return nil, InvalidPolicyFormatError("exactly one of keyPath, keyPaths, keyData, keyDatas, fulcio, and pki must be specified")
|
||||
}
|
||||
|
||||
rekorSources := 0
|
||||
@ -182,6 +196,9 @@ func newPRSigstoreSigned(options ...PRSigstoreSignedOption) (*prSigstoreSigned,
|
||||
if res.Fulcio != nil && rekorSources == 0 {
|
||||
return nil, InvalidPolicyFormatError("At least one of rekorPublickeyPath, rekorPublicKeyPaths, rekorPublickeyData and rekorPublicKeyDatas must be specified if fulcio is used")
|
||||
}
|
||||
if res.PKI != nil && rekorSources > 0 {
|
||||
return nil, InvalidPolicyFormatError("rekorPublickeyPath, rekorPublicKeyPaths, rekorPublickeyData and rekorPublicKeyDatas are not supported for pki")
|
||||
}
|
||||
|
||||
if res.SignedIdentity == nil {
|
||||
return nil, InvalidPolicyFormatError("signedIdentity not specified")
|
||||
@ -218,9 +235,10 @@ var _ json.Unmarshaler = (*prSigstoreSigned)(nil)
|
||||
func (pr *prSigstoreSigned) UnmarshalJSON(data []byte) error {
|
||||
*pr = prSigstoreSigned{}
|
||||
var tmp prSigstoreSigned
|
||||
var gotKeyPath, gotKeyPaths, gotKeyData, gotKeyDatas, gotFulcio bool
|
||||
var gotKeyPath, gotKeyPaths, gotKeyData, gotKeyDatas, gotFulcio, gotPKI bool
|
||||
var gotRekorPublicKeyPath, gotRekorPublicKeyPaths, gotRekorPublicKeyData, gotRekorPublicKeyDatas bool
|
||||
var fulcio prSigstoreSignedFulcio
|
||||
var pki prSigstoreSignedPKI
|
||||
var signedIdentity json.RawMessage
|
||||
if err := internal.ParanoidUnmarshalJSONObject(data, func(key string) any {
|
||||
switch key {
|
||||
@ -253,6 +271,9 @@ func (pr *prSigstoreSigned) UnmarshalJSON(data []byte) error {
|
||||
case "rekorPublicKeyDatas":
|
||||
gotRekorPublicKeyDatas = true
|
||||
return &tmp.RekorPublicKeyDatas
|
||||
case "pki":
|
||||
gotPKI = true
|
||||
return &pki
|
||||
case "signedIdentity":
|
||||
return &signedIdentity
|
||||
default:
|
||||
@ -303,6 +324,9 @@ func (pr *prSigstoreSigned) UnmarshalJSON(data []byte) error {
|
||||
if gotRekorPublicKeyDatas {
|
||||
opts = append(opts, PRSigstoreSignedWithRekorPublicKeyDatas(tmp.RekorPublicKeyDatas))
|
||||
}
|
||||
if gotPKI {
|
||||
opts = append(opts, PRSigstoreSignedWithPKI(&pki))
|
||||
}
|
||||
opts = append(opts, PRSigstoreSignedWithSignedIdentity(tmp.SignedIdentity))
|
||||
|
||||
res, err := newPRSigstoreSigned(opts...)
|
||||
@ -440,3 +464,167 @@ func (f *prSigstoreSignedFulcio) UnmarshalJSON(data []byte) error {
|
||||
*f = *res
|
||||
return nil
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIOption is a way to pass values to NewPRSigstoreSignedPKI
|
||||
type PRSigstoreSignedPKIOption func(*prSigstoreSignedPKI) error
|
||||
|
||||
// PRSigstoreSignedPKIWithCARootsPath specifies a value for the "caRootsPath" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCARootsPath(caRootsPath string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CARootsPath != "" {
|
||||
return InvalidPolicyFormatError(`"caRootsPath" already specified`)
|
||||
}
|
||||
p.CARootsPath = caRootsPath
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithCARootsData specifies a value for the "caRootsData" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCARootsData(caRootsData []byte) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CARootsData != nil {
|
||||
return InvalidPolicyFormatError(`"caRootsData" already specified`)
|
||||
}
|
||||
p.CARootsData = caRootsData
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithCAIntermediatesPath specifies a value for the "caIntermediatesPath" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCAIntermediatesPath(caIntermediatesPath string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CAIntermediatesPath != "" {
|
||||
return InvalidPolicyFormatError(`"caIntermediatesPath" already specified`)
|
||||
}
|
||||
p.CAIntermediatesPath = caIntermediatesPath
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithCAIntermediatesData specifies a value for the "caIntermediatesData" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithCAIntermediatesData(caIntermediatesData []byte) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.CAIntermediatesData != nil {
|
||||
return InvalidPolicyFormatError(`"caIntermediatesData" already specified`)
|
||||
}
|
||||
p.CAIntermediatesData = caIntermediatesData
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithSubjectEmail specifies a value for the "subjectEmail" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithSubjectEmail(subjectEmail string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.SubjectEmail != "" {
|
||||
return InvalidPolicyFormatError(`"subjectEmail" already specified`)
|
||||
}
|
||||
p.SubjectEmail = subjectEmail
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKIWithSubjectHostname specifies a value for the "subjectHostname" field when calling NewPRSigstoreSignedPKI
|
||||
func PRSigstoreSignedPKIWithSubjectHostname(subjectHostname string) PRSigstoreSignedPKIOption {
|
||||
return func(p *prSigstoreSignedPKI) error {
|
||||
if p.SubjectHostname != "" {
|
||||
return InvalidPolicyFormatError(`"subjectHostname" already specified`)
|
||||
}
|
||||
p.SubjectHostname = subjectHostname
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// newPRSigstoreSignedPKI is NewPRSigstoreSignedPKI, except it returns the private type
|
||||
func newPRSigstoreSignedPKI(options ...PRSigstoreSignedPKIOption) (*prSigstoreSignedPKI, error) {
|
||||
res := prSigstoreSignedPKI{}
|
||||
for _, o := range options {
|
||||
if err := o(&res); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if res.CARootsPath != "" && res.CARootsData != nil {
|
||||
return nil, InvalidPolicyFormatError("caRootsPath and caRootsData cannot be used simultaneously")
|
||||
}
|
||||
if res.CARootsPath == "" && res.CARootsData == nil {
|
||||
return nil, InvalidPolicyFormatError("At least one of caRootsPath and caRootsData must be specified")
|
||||
}
|
||||
|
||||
if res.CAIntermediatesPath != "" && res.CAIntermediatesData != nil {
|
||||
return nil, InvalidPolicyFormatError("caIntermediatesPath and caIntermediatesData cannot be used simultaneously")
|
||||
}
|
||||
|
||||
if res.SubjectEmail == "" && res.SubjectHostname == "" {
|
||||
return nil, InvalidPolicyFormatError("At least one of subjectEmail, subjectHostname must be specified")
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// NewPRSigstoreSignedPKI returns a PRSigstoreSignedPKI based on options.
|
||||
func NewPRSigstoreSignedPKI(options ...PRSigstoreSignedPKIOption) (PRSigstoreSignedPKI, error) {
|
||||
return newPRSigstoreSignedPKI(options...)
|
||||
}
|
||||
|
||||
// Compile-time check that prSigstoreSignedPKI implements json.Unmarshaler.
|
||||
var _ json.Unmarshaler = (*prSigstoreSignedPKI)(nil)
|
||||
|
||||
func (p *prSigstoreSignedPKI) UnmarshalJSON(data []byte) error {
|
||||
*p = prSigstoreSignedPKI{}
|
||||
var tmp prSigstoreSignedPKI
|
||||
var gotCARootsPath, gotCARootsData, gotCAIntermediatesPath, gotCAIntermediatesData, gotSubjectEmail, gotSubjectHostname bool
|
||||
if err := internal.ParanoidUnmarshalJSONObject(data, func(key string) any {
|
||||
switch key {
|
||||
case "caRootsPath":
|
||||
gotCARootsPath = true
|
||||
return &tmp.CARootsPath
|
||||
case "caRootsData":
|
||||
gotCARootsData = true
|
||||
return &tmp.CARootsData
|
||||
case "caIntermediatesPath":
|
||||
gotCAIntermediatesPath = true
|
||||
return &tmp.CAIntermediatesPath
|
||||
case "caIntermediatesData":
|
||||
gotCAIntermediatesData = true
|
||||
return &tmp.CAIntermediatesData
|
||||
case "subjectEmail":
|
||||
gotSubjectEmail = true
|
||||
return &tmp.SubjectEmail
|
||||
case "subjectHostname":
|
||||
gotSubjectHostname = true
|
||||
return &tmp.SubjectHostname
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var opts []PRSigstoreSignedPKIOption
|
||||
if gotCARootsPath {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCARootsPath(tmp.CARootsPath))
|
||||
}
|
||||
if gotCARootsData {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCARootsData(tmp.CARootsData))
|
||||
}
|
||||
if gotCAIntermediatesPath {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCAIntermediatesPath(tmp.CAIntermediatesPath))
|
||||
}
|
||||
if gotCAIntermediatesData {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithCAIntermediatesData(tmp.CAIntermediatesData))
|
||||
}
|
||||
if gotSubjectEmail {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithSubjectEmail(tmp.SubjectEmail))
|
||||
}
|
||||
if gotSubjectHostname {
|
||||
opts = append(opts, PRSigstoreSignedPKIWithSubjectHostname(tmp.SubjectHostname))
|
||||
}
|
||||
|
||||
res, err := newPRSigstoreSignedPKI(opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*p = *res
|
||||
return nil
|
||||
}
|
||||
|
99
vendor/github.com/containers/image/v5/signature/policy_eval_sigstore.go
generated
vendored
99
vendor/github.com/containers/image/v5/signature/policy_eval_sigstore.go
generated
vendored
@ -97,11 +97,64 @@ func (f *prSigstoreSignedFulcio) prepareTrustRoot() (*fulcioTrustRoot, error) {
|
||||
return &fulcio, nil
|
||||
}
|
||||
|
||||
// prepareTrustRoot creates a pkiTrustRoot from the input data.
|
||||
// (This also prevents external implementations of this interface, ensuring that prSigstoreSignedPKI is the only one.)
|
||||
func (p *prSigstoreSignedPKI) prepareTrustRoot() (*pkiTrustRoot, error) {
|
||||
caRootsCertPEMs, err := loadBytesFromConfigSources(configBytesSources{
|
||||
inconsistencyErrorMessage: `Internal inconsistency: both "caRootsPath" and "caRootsData" specified`,
|
||||
path: p.CARootsPath,
|
||||
data: p.CARootsData,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(caRootsCertPEMs) != 1 {
|
||||
return nil, errors.New(`Internal inconsistency: PKI specified with not exactly one of "caRootsPath" nor "caRootsData"`)
|
||||
}
|
||||
rootsCerts := x509.NewCertPool()
|
||||
if ok := rootsCerts.AppendCertsFromPEM(caRootsCertPEMs[0]); !ok {
|
||||
return nil, errors.New("error loading PKI CA Roots certificates")
|
||||
}
|
||||
pki := pkiTrustRoot{
|
||||
caRootsCertificates: rootsCerts,
|
||||
subjectEmail: p.SubjectEmail,
|
||||
subjectHostname: p.SubjectHostname,
|
||||
}
|
||||
caIntermediateCertPEMs, err := loadBytesFromConfigSources(configBytesSources{
|
||||
inconsistencyErrorMessage: `Internal inconsistency: both "caIntermediatesPath" and "caIntermediatesData" specified`,
|
||||
path: p.CAIntermediatesPath,
|
||||
data: p.CAIntermediatesData,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if caIntermediateCertPEMs != nil {
|
||||
if len(caIntermediateCertPEMs) != 1 {
|
||||
return nil, errors.New(`Internal inconsistency: PKI specified with invalid value from "caIntermediatesPath" or "caIntermediatesData"`)
|
||||
}
|
||||
intermediatePool := x509.NewCertPool()
|
||||
trustedIntermediates, err := cryptoutils.UnmarshalCertificatesFromPEM(caIntermediateCertPEMs[0])
|
||||
if err != nil {
|
||||
return nil, internal.NewInvalidSignatureError(fmt.Sprintf("loading trusted intermediate certificates: %v", err))
|
||||
}
|
||||
for _, trustedIntermediateCert := range trustedIntermediates {
|
||||
intermediatePool.AddCert(trustedIntermediateCert)
|
||||
}
|
||||
pki.caIntermediateCertificates = intermediatePool
|
||||
}
|
||||
|
||||
if err := pki.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &pki, nil
|
||||
}
|
||||
|
||||
// sigstoreSignedTrustRoot contains an already parsed version of the prSigstoreSigned policy
|
||||
type sigstoreSignedTrustRoot struct {
|
||||
publicKeys []crypto.PublicKey
|
||||
fulcio *fulcioTrustRoot
|
||||
rekorPublicKeys []*ecdsa.PublicKey
|
||||
pki *pkiTrustRoot
|
||||
}
|
||||
|
||||
func (pr *prSigstoreSigned) prepareTrustRoot() (*sigstoreSignedTrustRoot, error) {
|
||||
@ -166,6 +219,14 @@ func (pr *prSigstoreSigned) prepareTrustRoot() (*sigstoreSignedTrustRoot, error)
|
||||
}
|
||||
}
|
||||
|
||||
if pr.PKI != nil {
|
||||
p, err := pr.PKI.prepareTrustRoot()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.pki = p
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
@ -189,13 +250,23 @@ func (pr *prSigstoreSigned) isSignatureAccepted(ctx context.Context, image priva
|
||||
}
|
||||
untrustedPayload := sig.UntrustedPayload()
|
||||
|
||||
keySources := 0
|
||||
if trustRoot.publicKeys != nil {
|
||||
keySources++
|
||||
}
|
||||
if trustRoot.fulcio != nil {
|
||||
keySources++
|
||||
}
|
||||
if trustRoot.pki != nil {
|
||||
keySources++
|
||||
}
|
||||
|
||||
var publicKeys []crypto.PublicKey
|
||||
switch {
|
||||
case trustRoot.publicKeys != nil && trustRoot.fulcio != nil: // newPRSigstoreSigned rejects such combinations.
|
||||
return sarRejected, errors.New("Internal inconsistency: Both a public key and Fulcio CA specified")
|
||||
case trustRoot.publicKeys == nil && trustRoot.fulcio == nil: // newPRSigstoreSigned rejects such combinations.
|
||||
return sarRejected, errors.New("Internal inconsistency: Neither a public key nor a Fulcio CA specified")
|
||||
|
||||
case keySources > 1: // newPRSigstoreSigned rejects more than one key sources.
|
||||
return sarRejected, errors.New("Internal inconsistency: More than one of public key, Fulcio, or PKI specified")
|
||||
case keySources == 0: // newPRSigstoreSigned rejects empty key sources.
|
||||
return sarRejected, errors.New("Internal inconsistency: A public key, Fulcio, or PKI must be specified.")
|
||||
case trustRoot.publicKeys != nil:
|
||||
if trustRoot.rekorPublicKeys != nil {
|
||||
untrustedSET, ok := untrustedAnnotations[signature.SigstoreSETAnnotationKey]
|
||||
@ -254,6 +325,24 @@ func (pr *prSigstoreSigned) isSignatureAccepted(ctx context.Context, image priva
|
||||
return sarRejected, err
|
||||
}
|
||||
publicKeys = []crypto.PublicKey{pk}
|
||||
|
||||
case trustRoot.pki != nil:
|
||||
if trustRoot.rekorPublicKeys != nil { // newPRSigstoreSigned rejects such combinations.
|
||||
return sarRejected, errors.New("Internal inconsistency: PKI specified with a Rekor public key")
|
||||
}
|
||||
untrustedCert, ok := untrustedAnnotations[signature.SigstoreCertificateAnnotationKey]
|
||||
if !ok {
|
||||
return sarRejected, fmt.Errorf("missing %s annotation", signature.SigstoreCertificateAnnotationKey)
|
||||
}
|
||||
var untrustedIntermediateChainBytes []byte
|
||||
if untrustedIntermediateChain, ok := untrustedAnnotations[signature.SigstoreIntermediateCertificateChainAnnotationKey]; ok {
|
||||
untrustedIntermediateChainBytes = []byte(untrustedIntermediateChain)
|
||||
}
|
||||
pk, err := verifyPKI(trustRoot.pki, []byte(untrustedCert), untrustedIntermediateChainBytes)
|
||||
if err != nil {
|
||||
return sarRejected, err
|
||||
}
|
||||
publicKeys = []crypto.PublicKey{pk}
|
||||
}
|
||||
|
||||
if len(publicKeys) == 0 {
|
||||
|
37
vendor/github.com/containers/image/v5/signature/policy_types.go
generated
vendored
37
vendor/github.com/containers/image/v5/signature/policy_types.go
generated
vendored
@ -111,16 +111,16 @@ type prSignedBaseLayer struct {
|
||||
type prSigstoreSigned struct {
|
||||
prCommon
|
||||
|
||||
// KeyPath is a pathname to a local file containing the trusted key. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyPath is a pathname to a local file containing the trusted key. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyPath string `json:"keyPath,omitempty"`
|
||||
// KeyPaths is a set of pathnames to local files containing the trusted key(s). Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyPaths is a set of pathnames to local files containing the trusted key(s). Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyPaths []string `json:"keyPaths,omitempty"`
|
||||
// KeyData contains the trusted key, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyData contains the trusted key, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyData []byte `json:"keyData,omitempty"`
|
||||
// KeyDatas is a set of trusted keys, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// KeyDatas is a set of trusted keys, base64-encoded. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
KeyDatas [][]byte `json:"keyDatas,omitempty"`
|
||||
|
||||
// Fulcio specifies which Fulcio-generated certificates are accepted. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas and Fulcio must be specified.
|
||||
// Fulcio specifies which Fulcio-generated certificates are accepted. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
// If Fulcio is specified, one of RekorPublicKeyPath or RekorPublicKeyData must be specified as well.
|
||||
Fulcio PRSigstoreSignedFulcio `json:"fulcio,omitempty"`
|
||||
|
||||
@ -141,6 +141,9 @@ type prSigstoreSigned struct {
|
||||
// otherwise it is optional (and Rekor inclusion is not required if a Rekor public key is not specified).
|
||||
RekorPublicKeyDatas [][]byte `json:"rekorPublicKeyDatas,omitempty"`
|
||||
|
||||
// PKI specifies which PKI-generated certificates are accepted. Exactly one of KeyPath, KeyPaths, KeyData, KeyDatas, Fulcio, and PKI must be specified.
|
||||
PKI PRSigstoreSignedPKI `json:"pki,omitempty"`
|
||||
|
||||
// SignedIdentity specifies what image identity the signature must be claiming about the image.
|
||||
// Defaults to "matchRepoDigestOrExact" if not specified.
|
||||
// Note that /usr/bin/cosign interoperability might require using repo-only matching.
|
||||
@ -167,6 +170,30 @@ type prSigstoreSignedFulcio struct {
|
||||
SubjectEmail string `json:"subjectEmail,omitempty"`
|
||||
}
|
||||
|
||||
// PRSigstoreSignedPKI contains PKI configuration options for a "sigstoreSigned" PolicyRequirement.
|
||||
type PRSigstoreSignedPKI interface {
|
||||
// prepareTrustRoot creates a pkiTrustRoot from the input data.
|
||||
// (This also prevents external implementations of this interface, ensuring that prSigstoreSignedPKI is the only one.)
|
||||
prepareTrustRoot() (*pkiTrustRoot, error)
|
||||
}
|
||||
|
||||
// prSigstoreSignedPKI contains non-fulcio certificate PKI configuration options for prSigstoreSigned
|
||||
type prSigstoreSignedPKI struct {
|
||||
// CARootsPath a path to a file containing accepted CA root certificates, in PEM format. Exactly one of CARootsPath and CARootsData must be specified.
|
||||
CARootsPath string `json:"caRootsPath"`
|
||||
// CARootsData contains accepted CA root certificates in PEM format, all of that base64-encoded. Exactly one of CARootsPath and CARootsData must be specified.
|
||||
CARootsData []byte `json:"caRootsData"`
|
||||
// CAIntermediatesPath a path to a file containing accepted CA intermediate certificates, in PEM format. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both.
|
||||
CAIntermediatesPath string `json:"caIntermediatesPath"`
|
||||
// CAIntermediatesData contains accepted CA intermediate certificates in PEM format, all of that base64-encoded. Only one of CAIntermediatesPath or CAIntermediatesData can be specified, not both.
|
||||
CAIntermediatesData []byte `json:"caIntermediatesData"`
|
||||
|
||||
// SubjectEmail specifies the expected email address imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified.
|
||||
SubjectEmail string `json:"subjectEmail"`
|
||||
// SubjectHostname specifies the expected hostname imposed on the subject to which the certificate was issued. At least one of SubjectEmail and SubjectHostname must be specified.
|
||||
SubjectHostname string `json:"subjectHostname"`
|
||||
}
|
||||
|
||||
// PolicyReferenceMatch specifies a set of image identities accepted in PolicyRequirement.
|
||||
// The type is public, but its implementation is private.
|
||||
|
||||
|
2
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
2
vendor/github.com/containers/image/v5/version/version.go
generated
vendored
@ -8,7 +8,7 @@ const (
|
||||
// VersionMinor is for functionality in a backwards-compatible manner
|
||||
VersionMinor = 34
|
||||
// VersionPatch is for backwards-compatible bug fixes
|
||||
VersionPatch = 0
|
||||
VersionPatch = 1
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = ""
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -81,7 +81,7 @@ github.com/containers/common/pkg/password
|
||||
github.com/containers/common/pkg/report
|
||||
github.com/containers/common/pkg/report/camelcase
|
||||
github.com/containers/common/pkg/retry
|
||||
# github.com/containers/image/v5 v5.34.0
|
||||
# github.com/containers/image/v5 v5.34.1
|
||||
## explicit; go 1.22.8
|
||||
github.com/containers/image/v5/copy
|
||||
github.com/containers/image/v5/directory
|
||||
|
Loading…
Reference in New Issue
Block a user