From 72434a036e031405ec078c264b2f8abbe83729f9 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Mon, 22 Nov 2021 14:52:30 -0300 Subject: [PATCH] fix: ensure certificate is always within dist (#2680) * fix: ensure certificate is always within dist * fix: improve impl * fix: uneeded err check --- internal/pipe/sign/sign.go | 16 ++++++---------- internal/pipe/sign/sign_test.go | 5 +++-- www/docs/customization/docker_sign.md | 15 --------------- www/docs/customization/sign.md | 3 --- 4 files changed, 9 insertions(+), 30 deletions(-) diff --git a/internal/pipe/sign/sign.go b/internal/pipe/sign/sign.go index 9a5e04ea3..1691e9d1e 100644 --- a/internal/pipe/sign/sign.go +++ b/internal/pipe/sign/sign.go @@ -6,7 +6,6 @@ import ( "io" "os" "os/exec" - "path/filepath" "strings" "github.com/apex/log" @@ -114,7 +113,7 @@ func sign(ctx *context.Context, cfg config.Sign, artifacts []*artifact.Artifact) func signone(ctx *context.Context, cfg config.Sign, art *artifact.Artifact) ([]*artifact.Artifact, error) { env := ctx.Env.Copy() - env["artifactName"] = art.Name + env["artifactName"] = art.Name // shouldn't be used env["artifact"] = art.Path env["artifactID"] = art.ID() @@ -190,19 +189,16 @@ func signone(ctx *context.Context, cfg config.Sign, art *artifact.Artifact) ([]* return nil, nil } + // re-execute template results, using artifact name as artifact so they eval to the actual needed file name. env["artifact"] = art.Name - name, err = tmpl.New(ctx).WithEnv(env).Apply(expand(cfg.Signature, env)) - if err != nil { - return nil, fmt.Errorf("sign failed: %s: invalid template: %w", art.Name, err) - } + name, _ = tmpl.New(ctx).WithEnv(env).Apply(expand(cfg.Signature, env)) // could never error as it passed the previous check + cert, _ = tmpl.New(ctx).WithEnv(env).Apply(expand(cfg.Certificate, env)) // could never error as it passed the previous check - artifactPathBase, _ := filepath.Split(art.Path) - sigFilename := filepath.Base(env["signature"]) result := []*artifact.Artifact{ { Type: artifact.Signature, Name: name, - Path: filepath.Join(artifactPathBase, sigFilename), + Path: env["signature"], Extra: map[string]interface{}{ artifact.ExtraID: cfg.ID, }, @@ -213,7 +209,7 @@ func signone(ctx *context.Context, cfg config.Sign, art *artifact.Artifact) ([]* result = append(result, &artifact.Artifact{ Type: artifact.Certificate, Name: cert, - Path: filepath.Join(artifactPathBase, cert), + Path: env["certificate"], Extra: map[string]interface{}{ artifact.ExtraID: cfg.ID, }, diff --git a/internal/pipe/sign/sign_test.go b/internal/pipe/sign/sign_test.go index a5ab57398..91e19570a 100644 --- a/internal/pipe/sign/sign_test.go +++ b/internal/pipe/sign/sign_test.go @@ -522,7 +522,7 @@ func TestSignArtifacts(t *testing.T) { config.Project{ Signs: []config.Sign{ { - Certificate: "${artifactName}.pem", + Certificate: "${artifact}.pem", Artifacts: "checksum", }, }, @@ -539,7 +539,7 @@ func TestSignArtifacts(t *testing.T) { Signs: []config.Sign{ { Env: []string{"NOT_HONK=honk", "HONK={{ .Env.NOT_HONK }}"}, - Certificate: `{{ trimsuffix (trimsuffix .Env.artifactName ".tar.gz") ".deb" }}_${HONK}.pem`, + Certificate: `{{ trimsuffix (trimsuffix .Env.artifact ".tar.gz") ".deb" }}_${HONK}.pem`, Artifacts: "all", }, }, @@ -669,6 +669,7 @@ func testSign(tb testing.TB, ctx *context.Context, certificateNames, signaturePa certNames := []string{} for _, cert := range certificates { certNames = append(certNames, cert.Name) + require.True(tb, strings.HasPrefix(cert.Path, ctx.Config.Dist)) } sort.Strings(certificateNames) sort.Strings(certNames) diff --git a/www/docs/customization/docker_sign.md b/www/docs/customization/docker_sign.md index 18d9817a9..1e6ce034a 100644 --- a/www/docs/customization/docker_sign.md +++ b/www/docs/customization/docker_sign.md @@ -19,12 +19,6 @@ docker_signs: # Defaults to "default". id: foo - # Name/template of the signature file. - # Note that with cosign you don't need to use this. - # - # Defaults to empty. - signature: "${artifact}_sig" - # Path to the signature command # # Defaults to `cosign` @@ -61,14 +55,6 @@ docker_signs: # Defaults to empty stdin_file: ./.password - # Sets a certificate name that your signing command should write to. - # You can later use `${certificate}` or `.Env.certificate` in the `args` section. - # This is particularly useful for keyless signing (for instance, with cosign). - # Note that this should be a name, not a path. - # - # Defaults to empty. - certificate: '{{ trimsuffix .Env.artifactName ".tar.gz" }}.pem' - # List of environment variables that will be passed to the signing command as well as the templates. # # Defaults to empty @@ -84,7 +70,6 @@ These environment variables might be available in the fields that are templateab - `${artifact}`: the path to the artifact that will be signed [^1] - `${artifactID}`: the ID of the artifact that will be signed - `${certificate}`: the certificate filename, if provided -- `${artifactName}`: the name of the artifact [^1] [^1]: notice that the this might contain `/` characters, which depending on how you use it migth evaluate to actual paths within the filesystem. Use with care. diff --git a/www/docs/customization/sign.md b/www/docs/customization/sign.md index 0bac1bbc2..5aa938f21 100644 --- a/www/docs/customization/sign.md +++ b/www/docs/customization/sign.md @@ -107,9 +107,6 @@ These environment variables might be available in the fields that are templateab - `${artifactID}`: the ID of the artifact that will be signed - `${certificate}`: the certificate filename, if provided - `${signature}`: the signature filename -- `${artifactName}`: the name of the artifact [^1] - -[^1]: notice that the name won't have the `dist` prefix, so if you are using it to build filepaths, be sure to prefix them properly. Prefer using `${artifact}` instead. ## Signing with cosign