Skip to content

Commit

Permalink
add support for ignoring certificates with pkcs11 (#3334)
Browse files Browse the repository at this point in the history
This commit adds a new environment variable,
COSIGN_PKCS11_IGNORE_CERTIFICATE, which will skip loading certificates
into a PKCS11 key when set to "1". This is desirable when you want to
sign with a private key that has a certificate associated with it, but
do not want that certificate to be included with the signature for
verification. Certificates are already optional for keys from non-PKCS11
sources via the --certificate command line flag.

Signed-off-by: dylrich <dylan.richardson@mongodb.com>
  • Loading branch information
dylrich authored Nov 6, 2023
1 parent 23920de commit 8b366c4
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 11 deletions.
18 changes: 12 additions & 6 deletions pkg/cosign/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ func (v Variable) String() string {

const (
// Cosign environment variables
VariableExperimental Variable = "COSIGN_EXPERIMENTAL"
VariableDockerMediaTypes Variable = "COSIGN_DOCKER_MEDIA_TYPES"
VariablePassword Variable = "COSIGN_PASSWORD"
VariablePKCS11Pin Variable = "COSIGN_PKCS11_PIN"
VariablePKCS11ModulePath Variable = "COSIGN_PKCS11_MODULE_PATH"
VariableRepository Variable = "COSIGN_REPOSITORY"
VariableExperimental Variable = "COSIGN_EXPERIMENTAL"
VariableDockerMediaTypes Variable = "COSIGN_DOCKER_MEDIA_TYPES"
VariablePassword Variable = "COSIGN_PASSWORD"
VariablePKCS11Pin Variable = "COSIGN_PKCS11_PIN"
VariablePKCS11ModulePath Variable = "COSIGN_PKCS11_MODULE_PATH"
VariablePKCS11IgnoreCertificate Variable = "COSIGN_PKCS11_IGNORE_CERTIFICATE"
VariableRepository Variable = "COSIGN_REPOSITORY"

// Sigstore environment variables
VariableSigstoreCTLogPublicKeyFile Variable = "SIGSTORE_CT_LOG_PUBLIC_KEY_FILE"
Expand Down Expand Up @@ -102,6 +103,11 @@ var (
Expects: "string with a module-path",
Sensitive: false,
},
VariablePKCS11IgnoreCertificate: {
Description: "disables loading certificates with PKCS11",
Expects: "1 if loading certificates should be disabled (0 by default)",
Sensitive: false,
},
VariableRepository: {
Description: "can be used to store signatures in an alternate location",
Expects: "string with a repository",
Expand Down
13 changes: 9 additions & 4 deletions pkg/cosign/pkcs11key/pkcs11key.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,15 @@ func GetKeyWithURIConfig(config *Pkcs11UriConfig, askForPinIfNeeded bool) (*Key,
// Key's corresponding cert might not exist,
// therefore, we do not fail if it is the case.
var cert *x509.Certificate
if len(config.KeyID) != 0 {
cert, _ = ctx.FindCertificate(config.KeyID, nil, nil)
} else if len(config.KeyLabel) != 0 {
cert, _ = ctx.FindCertificate(nil, config.KeyLabel, nil)

ignoreCert := env.Getenv(env.VariablePKCS11IgnoreCertificate) == "1"

if !ignoreCert {
if len(config.KeyID) != 0 {
cert, _ = ctx.FindCertificate(config.KeyID, nil, nil)
} else if len(config.KeyLabel) != 0 {
cert, _ = ctx.FindCertificate(nil, config.KeyLabel, nil)
}
}

return &Key{ctx: ctx, signer: signer, cert: cert}, nil
Expand Down
61 changes: 60 additions & 1 deletion test/pkcs11_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (
"encoding/hex"
"encoding/pem"
"fmt"
"io"
"math/big"
"os"
"strings"
Expand Down Expand Up @@ -214,6 +215,64 @@ func TestListKeysUrisCmd(t *testing.T) {
}
}

func TestCertificateIgnored(t *testing.T) {
ctx := context.Background()

tokens, err := GetTokens(ctx, modulePath)
if err != nil {
t.Fatal(err)
}

bTokenFound := false
var slotID uint
for _, token := range tokens {
if token.TokenInfo.Label == tokenLabel {
bTokenFound = true
slotID = token.Slot
break
}
}
if !bTokenFound {
t.Fatalf("token with label '%s' not found", tokenLabel)
}

err = importKey(slotID)
if err != nil {
t.Fatal(err)
}
defer deleteKey(slotID)

pkcs11UriConfig := pkcs11key.NewPkcs11UriConfig()
err = pkcs11UriConfig.Parse(uri)
if err != nil {
t.Fatal(err)
}

const envvar = "COSIGN_PKCS11_IGNORE_CERTIFICATE"

if err := os.Setenv(envvar, "1"); err != nil {
t.Fatal(err)
}

defer os.Setenv(envvar, "")

sk, err := pkcs11key.GetKeyWithURIConfig(pkcs11UriConfig, true)
if err != nil {
t.Fatal(err)
}

defer sk.Close()

cert, err := sk.Certificate()
if err != nil {
t.Fatal(err)
}

if cert != nil {
t.Fatalf("expected certificate to be ignored while loading")
}
}

func TestSignAndVerify(t *testing.T) {
ctx := context.Background()

Expand Down Expand Up @@ -350,7 +409,7 @@ func importKey(slotID uint) error {
keyLabelBytes := []byte(keyLabel)

r := strings.NewReader(rsaPrivKey)
pemBytes, err = os.ReadAll(r)
pemBytes, err = io.ReadAll(r)
if err != nil {
return fmt.Errorf("unable to read pem")
}
Expand Down

0 comments on commit 8b366c4

Please sign in to comment.