From 06869216f546b71ff71f984a6af55b2264b01b12 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov <19779+xnox@users.noreply.github.com> Date: Fri, 13 Dec 2024 23:11:41 +0000 Subject: [PATCH] pkg/apk: switch to SHA2-256 based signatures by default (#1440) Remove commented out support for dual-signing, as it is not correctly supported by anything (non-deterministic validation, leading to trusting weakest signature, rather than strongest one). Switch default signing type to RSA256 (RSA signature over SHA2-256 message digest). Provide environment variable opt-out to switch back to RSA (RSA signature over SHA1 message digest). This allows to roll this out, with a runtime escape hatch. If successful, runtime escape hatch can be reverted. All tests pass, as support for validating RSA/RSA256/dual signatures was already landed previously. This api is used by melange and has been cross-tested with melange (using replace go.mod directive pointing at this proposed apko code). --- pkg/apk/signature/sign.go | 58 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/pkg/apk/signature/sign.go b/pkg/apk/signature/sign.go index a30643810..a107d97b2 100644 --- a/pkg/apk/signature/sign.go +++ b/pkg/apk/signature/sign.go @@ -55,24 +55,24 @@ func SignIndex(ctx context.Context, signingKey string, indexFile string) error { // // Done: // Step 0) apk-tools supports RSA256 since 2017 - // This PR: // Step 1) Upgrade all deployments of melange/go-apk with verification support for RSA256 - // Follow-up: - // Step 2) Turn off RSA signatures & turn on RSA256 signatures - // - // Enable both (incorrectly ordered dual-signed) only for local testing - sigs := []struct { - filename string - digestType crypto.Hash - }{ - { - "RSA", - crypto.SHA1, - }, - // { - // "RSA256", - // crypto.SHA256, - // }, + // This PR: + // Step 2) Turn on RSA256 signatures, with RSA escape hatch + // Next: + // Step 3) Remove RSA escape hatch + + filename := "RSA256" + digestType := crypto.SHA256 + + if digest, ok := os.LookupEnv("SIGNING_DIGEST"); ok { + switch digest { + case "SHA256": + case "SHA1": + filename = "RSA" + digestType = crypto.SHA1 + default: + return fmt.Errorf("unsupported SIGNING_DIGEST") + } } indexData, err := os.ReadFile(indexFile) @@ -81,22 +81,20 @@ func SignIndex(ctx context.Context, signingKey string, indexFile string) error { } sigFS := memfs.New() - for _, sig := range sigs { - indexDigest, err := HashData(indexData, sig.digestType) - if err != nil { - return err - } + indexDigest, err := HashData(indexData, digestType) + if err != nil { + return err + } - sigData, err := RSASignDigest(indexDigest, sig.digestType, signingKey, "") - if err != nil { - return fmt.Errorf("unable to sign index: %w", err) - } + sigData, err := RSASignDigest(indexDigest, digestType, signingKey, "") + if err != nil { + return fmt.Errorf("unable to sign index: %w", err) + } - log.Infof("appending signature %s to index %s", sig.filename, indexFile) + log.Infof("appending signature %s to index %s", filename, indexFile) - if err := sigFS.WriteFile(fmt.Sprintf(".SIGN.%s.%s.pub", sig.filename, filepath.Base(signingKey)), sigData, 0644); err != nil { - return fmt.Errorf("unable to append signature: %w", err) - } + if err := sigFS.WriteFile(fmt.Sprintf(".SIGN.%s.%s.pub", filename, filepath.Base(signingKey)), sigData, 0644); err != nil { + return fmt.Errorf("unable to append signature: %w", err) } // prepare control.tar.gz