Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion pkg/generator/certificate_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package generator

import (
"context"
"crypto/fips140"
"fmt"

sgv1alpha1 "carvel.dev/secretgen-controller/pkg/apis/secretgen/v1alpha1"
Expand Down Expand Up @@ -185,7 +186,15 @@ func (r *CertificateReconciler) generate(ctx context.Context, params certParams,

gen := cfgtypes.NewCertificateGenerator(singleCertLoader{caCertSecret})

certVal, err := gen.Generate(params)
// cfgtypes.CertificateGenerator.Generate uses crypto/sha1 to derive the certificate's
// SubjectKeyId (RFC 5280 4.2.1.2, method (1)): a non-cryptographic key identifier used
// for chain-building/lookup, not for signing or trust decisions. WithoutEnforcement
// scopes the FIPS 140-3 "only" exemption to just this call, so it has no effect when
// strict enforcement isn't active.
var certVal interface{}
fips140.WithoutEnforcement(func() {
certVal, err = gen.Generate(params)
})
if err != nil {
return cfgtypes.CertResponse{}, err
}
Expand Down
57 changes: 57 additions & 0 deletions pkg/generator/fips140_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2024 The Carvel Authors.
// SPDX-License-Identifier: Apache-2.0

package generator

import (
"context"
"crypto/fips140"
"testing"

sgv1alpha1 "carvel.dev/secretgen-controller/pkg/apis/secretgen/v1alpha1"
)

// These tests only exercise anything meaningful when run with
// GOFIPS140=v1.0.0 GODEBUG=fips140=only, which enables strict FIPS 140-3
// enforcement (crypto/fips140.Enforced() reports it at runtime). Without
// that, they degrade to a skip so they don't add noise to a normal `go test
// ./...` run.

func TestSSHKeyReconciler_GenerateUnderFIPS140Only(t *testing.T) {
if !fips140.Enforced() {
t.Skip("run with GOFIPS140=v1.0.0 GODEBUG=fips140=only to exercise strict FIPS 140-3 enforcement")
}

r := &SSHKeyReconciler{}

sshKey, err := r.generate(&sgv1alpha1.SSHKey{})
if err != nil {
t.Fatalf("generate: %v", err)
}
if sshKey.PrivateKey == "" || sshKey.PublicKey == "" || sshKey.PublicKeyFingerprint == "" {
t.Fatalf("generate returned incomplete SSHKey: %+v", sshKey)
}
}

func TestCertificateReconciler_GenerateUnderFIPS140Only(t *testing.T) {
if !fips140.Enforced() {
t.Skip("run with GOFIPS140=v1.0.0 GODEBUG=fips140=only to exercise strict FIPS 140-3 enforcement")
}

r := &CertificateReconciler{}
cert := &sgv1alpha1.Certificate{
Spec: sgv1alpha1.CertificateSpec{
CommonName: "test-ca",
IsCA: true,
},
}
params := newCertParams(cert)

certResp, err := r.generate(context.Background(), params, cert)
if err != nil {
t.Fatalf("generate: %v", err)
}
if certResp.Certificate == "" || certResp.PrivateKey == "" {
t.Fatalf("generate returned incomplete CertResponse: %+v", certResp)
}
}
11 changes: 10 additions & 1 deletion pkg/generator/ssh_key_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package generator

import (
"context"
"crypto/fips140"
"fmt"

sgv1alpha1 "carvel.dev/secretgen-controller/pkg/apis/secretgen/v1alpha1"
Expand Down Expand Up @@ -122,7 +123,15 @@ func (r *SSHKeyReconciler) generate(sshKey *sgv1alpha1.SSHKey) (cfgtypes.SSHKey,
gen := cfgtypes.NewSSHKeyGenerator()

// TODO allow type and number of bits?
sshKeyVal, err := gen.Generate(nil)
// cfgtypes.SSHKeyGenerator.Generate uses crypto/md5 to compute PublicKeyFingerprint,
// a display-only identifier (same convention as `ssh-keygen -l -E md5`), not a
// cryptographic operation. WithoutEnforcement scopes the FIPS 140-3 "only" exemption
// to just this call, so it has no effect when strict enforcement isn't active.
var sshKeyVal interface{}
var err error
fips140.WithoutEnforcement(func() {
sshKeyVal, err = gen.Generate(nil)
})
if err != nil {
return cfgtypes.SSHKey{}, err
}
Expand Down
Loading