Check JKS/PKCS12 truststores only if issuer provides the CA

The current policy check for keystores in Secrets creates a loop because
the truststore.jks or truststore.p12 will never exist when the issuer didn't
provide the CA certificate. This behaviour was introduced by #5597

The JKS and PKCS12 truststores are only added to the Secret
if the CA is provided by the issuer. The CertificateRequest API
reference states:

> The PEM encoded x509 certificate of the signer, also known
> as the CA (Certificate Authority). This is set on a best-effort basis by
> different issuers. If not set, the CA is assumed to be unknown/not available.

This change will only check the PKCS12/JKS truststores if the CA cert from the
issuer exists in the secret.

Fixes #5755

Signed-off-by: Thomas Müller <thomas@chaschperli.ch>
This commit is contained in:
Thomas Müller 2023-04-20 16:58:00 +02:00
parent 19104fcb4a
commit 12483d3d54
3 changed files with 17 additions and 12 deletions

View File

@ -134,7 +134,7 @@ spec:
- passwordSecretRef
properties:
create:
description: Create enables JKS keystore creation for the Certificate. If true, a file named `keystore.jks` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will be updated immediately. A file named `truststore.jks` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority
description: Create enables JKS keystore creation for the Certificate. If true, a file named `keystore.jks` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will be updated immediately. If the issuer provided a CA certificate, a file named `truststore.jks` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority
type: boolean
passwordSecretRef:
description: PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the JKS keystore.
@ -156,7 +156,7 @@ spec:
- passwordSecretRef
properties:
create:
description: Create enables PKCS12 keystore creation for the Certificate. If true, a file named `keystore.p12` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will be updated immediately. A file named `truststore.p12` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority
description: Create enables PKCS12 keystore creation for the Certificate. If true, a file named `keystore.p12` will be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef`. The keystore file will be updated immediately. If the issuer provided a CA certificate, a file named `truststore.p12` will also be created in the target Secret resource, encrypted using the password stored in `passwordSecretRef` containing the issuing Certificate Authority
type: boolean
passwordSecretRef:
description: PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the PKCS12 keystore.

View File

@ -33,6 +33,7 @@ import (
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
"sigs.k8s.io/structured-merge-diff/v4/value"
cmmeta "github.com/cert-manager/cert-manager/internal/apis/meta"
internalcertificates "github.com/cert-manager/cert-manager/internal/controller/certificates"
cmapi "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/cert-manager/cert-manager/pkg/util/pki"
@ -100,6 +101,8 @@ func SecretPrivateKeyMatchesSpec(input Input) (string, string, bool) {
// If the private key rotation is set to "Never", the key store related values are re-encoded
// as per the certificate specification
func SecretKeystoreFormatMatchesSpec(input Input) (string, string, bool) {
_, issuerProvidesCA := input.Secret.Data[cmmeta.TLSCAKey]
if input.Certificate.Spec.Keystores == nil {
if len(input.Secret.Data[cmapi.PKCS12SecretKey]) != 0 ||
len(input.Secret.Data[cmapi.PKCS12TruststoreKey]) != 0 ||
@ -113,8 +116,8 @@ func SecretKeystoreFormatMatchesSpec(input Input) (string, string, bool) {
if input.Certificate.Spec.Keystores.JKS != nil {
if input.Certificate.Spec.Keystores.JKS.Create {
if len(input.Secret.Data[cmapi.JKSSecretKey]) == 0 ||
len(input.Secret.Data[cmapi.JKSTruststoreKey]) == 0 {
return SecretMismatch, "JKS Keystore keys does not contain data", true
(len(input.Secret.Data[cmapi.JKSTruststoreKey]) == 0 && issuerProvidesCA) {
return SecretMismatch, "JKS Keystore key does not contain data", true
}
} else {
if len(input.Secret.Data[cmapi.JKSSecretKey]) != 0 ||
@ -132,8 +135,8 @@ func SecretKeystoreFormatMatchesSpec(input Input) (string, string, bool) {
if input.Certificate.Spec.Keystores.PKCS12 != nil {
if input.Certificate.Spec.Keystores.PKCS12.Create {
if len(input.Secret.Data[cmapi.PKCS12SecretKey]) == 0 ||
len(input.Secret.Data[cmapi.PKCS12TruststoreKey]) == 0 {
return SecretMismatch, "PKCS12 Keystore keys does not contain data", true
(len(input.Secret.Data[cmapi.PKCS12TruststoreKey]) == 0 && issuerProvidesCA) {
return SecretMismatch, "PKCS12 Keystore key does not contain data", true
}
} else {
if len(input.Secret.Data[cmapi.PKCS12SecretKey]) != 0 ||

View File

@ -357,9 +357,10 @@ type JKSKeystore struct {
// Secret resource, encrypted using the password stored in
// `passwordSecretRef`.
// The keystore file will be updated immediately.
// A file named `truststore.jks` will also be created in the target
// Secret resource, encrypted using the password stored in
// `passwordSecretRef` containing the issuing Certificate Authority
// If the issuer provided a CA certificate, a file named `truststore.jks`
// will also be created in the target Secret resource, encrypted using the
// password stored in `passwordSecretRef`
// containing the issuing Certificate Authority
Create bool `json:"create"`
// PasswordSecretRef is a reference to a key in a Secret resource
@ -375,9 +376,10 @@ type PKCS12Keystore struct {
// Secret resource, encrypted using the password stored in
// `passwordSecretRef`.
// The keystore file will be updated immediately.
// A file named `truststore.p12` will also be created in the target
// Secret resource, encrypted using the password stored in
// `passwordSecretRef` containing the issuing Certificate Authority
// If the issuer provided a CA certificate, a file named `truststore.p12` will
// also be created in the target Secret resource, encrypted using the
// password stored in `passwordSecretRef` containing the issuing Certificate
// Authority
Create bool `json:"create"`
// PasswordSecretRef is a reference to a key in a Secret resource