Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load in intermediate cert pool from TUF #1804

Merged
merged 1 commit into from Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 17 additions & 2 deletions cmd/cosign/cli/fulcio/fulcioroots/fulcioroots.go
Expand Up @@ -83,8 +83,8 @@ func GetIntermediates() *x509.CertPool {
}

func initRoots() (*x509.CertPool, *x509.CertPool, error) {
rootPool := x509.NewCertPool()
intermediatePool := x509.NewCertPool()
var rootPool *x509.CertPool
var intermediatePool *x509.CertPool

rootEnv := os.Getenv(altRoot)
if rootEnv != "" {
Expand All @@ -99,8 +99,14 @@ func initRoots() (*x509.CertPool, *x509.CertPool, error) {
for _, cert := range certs {
// root certificates are self-signed
if bytes.Equal(cert.RawSubject, cert.RawIssuer) {
if rootPool == nil {
rootPool = x509.NewCertPool()
}
rootPool.AddCert(cert)
} else {
if intermediatePool == nil {
intermediatePool = x509.NewCertPool()
}
intermediatePool.AddCert(cert)
}
}
Expand All @@ -127,12 +133,21 @@ func initRoots() (*x509.CertPool, *x509.CertPool, error) {
for _, cert := range certs {
// root certificates are self-signed
if bytes.Equal(cert.RawSubject, cert.RawIssuer) {
if rootPool == nil {
rootPool = x509.NewCertPool()
}
rootPool.AddCert(cert)
} else {
if intermediatePool == nil {
intermediatePool = x509.NewCertPool()
}
intermediatePool.AddCert(cert)
}
}
}
if intermediatePool == nil {
intermediatePool = x509.NewCertPool()
}
intermediatePool.AppendCertsFromPEM([]byte(fulcioIntermediateV1))
}
return rootPool, intermediatePool, nil
Expand Down
1 change: 1 addition & 0 deletions cmd/cosign/cli/verify/verify.go
Expand Up @@ -111,6 +111,7 @@ func (c *VerifyCommand) Exec(ctx context.Context, images []string) (err error) {
co.RekorClient = rekorClient
}
co.RootCerts = fulcio.GetRoots()
co.IntermediateCerts = fulcio.GetIntermediates()
}
keyRef := c.KeyRef
certRef := c.CertRef
Expand Down
1 change: 1 addition & 0 deletions cmd/cosign/cli/verify/verify_attestation.go
Expand Up @@ -92,6 +92,7 @@ func (c *VerifyAttestationCommand) Exec(ctx context.Context, images []string) (e
co.RekorClient = rekorClient
}
co.RootCerts = fulcio.GetRoots()
co.IntermediateCerts = fulcio.GetIntermediates()
}
keyRef := c.KeyRef

Expand Down
6 changes: 4 additions & 2 deletions pkg/cosign/verify.go
Expand Up @@ -475,7 +475,8 @@ func VerifyImageSignature(ctx context.Context, sig oci.Signature, h v1.Hash, co
// If the chain annotation is not present or there is only a root
if chain == nil || len(chain) <= 1 {
co.IntermediateCerts = nil
} else {
} else if co.IntermediateCerts == nil {
// If the intermediate certs have not been loaded in by TUF
pool := x509.NewCertPool()
for _, cert := range chain[:len(chain)-1] {
pool.AddCert(cert)
Expand Down Expand Up @@ -653,7 +654,8 @@ func verifyImageAttestations(ctx context.Context, atts oci.Signatures, h v1.Hash
// If the chain annotation is not present or there is only a root
if chain == nil || len(chain) <= 1 {
co.IntermediateCerts = nil
} else {
} else if co.IntermediateCerts == nil {
// If the intermediate certs have not been loaded in by TUF
pool := x509.NewCertPool()
for _, cert := range chain[:len(chain)-1] {
pool.AddCert(cert)
Expand Down
36 changes: 36 additions & 0 deletions pkg/cosign/verify_test.go
Expand Up @@ -309,6 +309,42 @@ func TestVerifyImageSignatureWithMissingSub(t *testing.T) {
}
}

func TestVerifyImageSignatureWithExistingSub(t *testing.T) {
rootCert, rootKey, _ := test.GenerateRootCa()
subCert, subKey, _ := test.GenerateSubordinateCa(rootCert, rootKey)
leafCert, privKey, _ := test.GenerateLeafCert("subject", "oidc-issuer", subCert, subKey)
pemRoot := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Raw})
pemSub := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: subCert.Raw})
pemLeaf := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: leafCert.Raw})

otherSubCert, _, _ := test.GenerateSubordinateCa(rootCert, rootKey)

rootPool := x509.NewCertPool()
rootPool.AddCert(rootCert)
subPool := x509.NewCertPool()
// Load in different sub cert so the chain doesn't verify
rootPool.AddCert(otherSubCert)

payload := []byte{1, 2, 3, 4}
h := sha256.Sum256(payload)
signature, _ := privKey.Sign(rand.Reader, h[:], crypto.SHA256)

ociSig, _ := static.NewSignature(payload,
base64.StdEncoding.EncodeToString(signature),
static.WithCertChain(pemLeaf, appendSlices([][]byte{pemSub, pemRoot})))
verified, err := VerifyImageSignature(context.TODO(), ociSig, v1.Hash{}, &CheckOpts{RootCerts: rootPool, IntermediateCerts: subPool})
if err == nil {
t.Fatal("expected error while verifying signature")
}
if !strings.Contains(err.Error(), "certificate signed by unknown authority") {
t.Fatal("expected error while verifying signature")
}
// TODO: Create fake bundle and test verification
if verified == true {
t.Fatalf("expected verified=false, got verified=true")
}
}

func TestValidateAndUnpackCertSuccess(t *testing.T) {
subject := "email@email"
oidcIssuer := "https://accounts.google.com"
Expand Down
1 change: 1 addition & 0 deletions pkg/sget/sget.go
Expand Up @@ -91,6 +91,7 @@ func (sg *SecureGet) Do(ctx context.Context) error {
fulcioVerified := (co.SigVerifier == nil)

co.RootCerts = fulcio.GetRoots()
co.IntermediateCerts = fulcio.GetIntermediates()

sp, bundleVerified, err := cosign.VerifyImageSignatures(ctx, ref, co)
if err != nil {
Expand Down