Add optional flag to specify jks keystore alias.

Previously the JKS keystore alias was hardcoded to "certificate".
This change adds an optional configuration point to allow users
to specify a custom keystore alias. If the flag is omitted we
will default to the previous behavior.

Signed-off-by: Bill Waldrep <bwaldrep@palantir.com>
This commit is contained in:
Bill Waldrep 2024-02-29 11:24:41 -05:00
parent fd551160b1
commit d4911ebfaa
No known key found for this signature in database
GPG Key ID: DF6FE04D604AB5F7
18 changed files with 87 additions and 15 deletions

View File

@ -202,6 +202,11 @@ spec:
- create
- passwordSecretRef
properties:
alias:
description: |-
Alias specifies the alias of the key in the keystore, required by the JKS format.
If not provided, the default alias `certificate` will be used.
type: string
create:
description: |-
Create enables JKS keystore creation for the Certificate.

View File

@ -410,6 +410,11 @@ type JKSKeystore struct {
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the JKS keystore.
PasswordSecretRef cmmeta.SecretKeySelector
// Alias specifies the alias of the key in the keystore, required by the JKS format.
// If not provided, the default alias `certificate` will be used.
// +optional
Alias *string `json:"alias,omitempty"`
}
// PKCS12 configures options for storing a PKCS12 keystore in the

View File

@ -1266,6 +1266,7 @@ func autoConvert_v1_JKSKeystore_To_certmanager_JKSKeystore(in *v1.JKSKeystore, o
if err := internalapismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}
@ -1279,6 +1280,7 @@ func autoConvert_certmanager_JKSKeystore_To_v1_JKSKeystore(in *certmanager.JKSKe
if err := internalapismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}

View File

@ -335,6 +335,11 @@ type JKSKeystore struct {
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the JKS keystore.
PasswordSecretRef cmmeta.SecretKeySelector `json:"passwordSecretRef"`
// Alias specifies the alias of the key in the keystore, required by the JKS format.
// If not provided, the default alias `certificate` will be used.
// +optional
Alias *string `json:"alias,omitempty"`
}
// PKCS12 configures options for storing a PKCS12 keystore in the

View File

@ -1272,6 +1272,7 @@ func autoConvert_v1alpha2_JKSKeystore_To_certmanager_JKSKeystore(in *JKSKeystore
if err := apismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}
@ -1285,6 +1286,7 @@ func autoConvert_certmanager_JKSKeystore_To_v1alpha2_JKSKeystore(in *certmanager
if err := apismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}

View File

@ -129,7 +129,7 @@ func (in *CertificateKeystores) DeepCopyInto(out *CertificateKeystores) {
if in.JKS != nil {
in, out := &in.JKS, &out.JKS
*out = new(JKSKeystore)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.PKCS12 != nil {
in, out := &in.PKCS12, &out.PKCS12
@ -786,6 +786,11 @@ func (in *IssuerStatus) DeepCopy() *IssuerStatus {
func (in *JKSKeystore) DeepCopyInto(out *JKSKeystore) {
*out = *in
out.PasswordSecretRef = in.PasswordSecretRef
if in.Alias != nil {
in, out := &in.Alias, &out.Alias
*out = new(string)
**out = **in
}
return
}

View File

@ -339,6 +339,11 @@ type JKSKeystore struct {
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the JKS keystore.
PasswordSecretRef cmmeta.SecretKeySelector `json:"passwordSecretRef"`
// Alias specifies the alias of the key in the keystore, required by the JKS format.
// If not provided, the default alias `certificate` will be used.
// +optional
Alias *string `json:"alias,omitempty"`
}
// PKCS12 configures options for storing a PKCS12 keystore in the

View File

@ -1271,6 +1271,7 @@ func autoConvert_v1alpha3_JKSKeystore_To_certmanager_JKSKeystore(in *JKSKeystore
if err := apismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}
@ -1284,6 +1285,7 @@ func autoConvert_certmanager_JKSKeystore_To_v1alpha3_JKSKeystore(in *certmanager
if err := apismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}

View File

@ -129,7 +129,7 @@ func (in *CertificateKeystores) DeepCopyInto(out *CertificateKeystores) {
if in.JKS != nil {
in, out := &in.JKS, &out.JKS
*out = new(JKSKeystore)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.PKCS12 != nil {
in, out := &in.PKCS12, &out.PKCS12
@ -781,6 +781,11 @@ func (in *IssuerStatus) DeepCopy() *IssuerStatus {
func (in *JKSKeystore) DeepCopyInto(out *JKSKeystore) {
*out = *in
out.PasswordSecretRef = in.PasswordSecretRef
if in.Alias != nil {
in, out := &in.Alias, &out.Alias
*out = new(string)
**out = **in
}
return
}

View File

@ -340,6 +340,11 @@ type JKSKeystore struct {
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the JKS keystore.
PasswordSecretRef cmmeta.SecretKeySelector `json:"passwordSecretRef"`
// Alias specifies the alias of the key in the keystore, required by the JKS format.
// If not provided, the default alias `certificate` will be used.
// +optional
Alias *string `json:"alias,omitempty"`
}
// PKCS12 configures options for storing a PKCS12 keystore in the

View File

@ -1254,6 +1254,7 @@ func autoConvert_v1beta1_JKSKeystore_To_certmanager_JKSKeystore(in *JKSKeystore,
if err := apismetav1.Convert_v1_SecretKeySelector_To_meta_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}
@ -1267,6 +1268,7 @@ func autoConvert_certmanager_JKSKeystore_To_v1beta1_JKSKeystore(in *certmanager.
if err := apismetav1.Convert_meta_SecretKeySelector_To_v1_SecretKeySelector(&in.PasswordSecretRef, &out.PasswordSecretRef, s); err != nil {
return err
}
out.Alias = (*string)(unsafe.Pointer(in.Alias))
return nil
}

View File

@ -129,7 +129,7 @@ func (in *CertificateKeystores) DeepCopyInto(out *CertificateKeystores) {
if in.JKS != nil {
in, out := &in.JKS, &out.JKS
*out = new(JKSKeystore)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.PKCS12 != nil {
in, out := &in.PKCS12, &out.PKCS12
@ -781,6 +781,11 @@ func (in *IssuerStatus) DeepCopy() *IssuerStatus {
func (in *JKSKeystore) DeepCopyInto(out *JKSKeystore) {
*out = *in
out.PasswordSecretRef = in.PasswordSecretRef
if in.Alias != nil {
in, out := &in.Alias, &out.Alias
*out = new(string)
**out = **in
}
return
}

View File

@ -129,7 +129,7 @@ func (in *CertificateKeystores) DeepCopyInto(out *CertificateKeystores) {
if in.JKS != nil {
in, out := &in.JKS, &out.JKS
*out = new(JKSKeystore)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.PKCS12 != nil {
in, out := &in.PKCS12, &out.PKCS12
@ -781,6 +781,11 @@ func (in *IssuerStatus) DeepCopy() *IssuerStatus {
func (in *JKSKeystore) DeepCopyInto(out *JKSKeystore) {
*out = *in
out.PasswordSecretRef = in.PasswordSecretRef
if in.Alias != nil {
in, out := &in.Alias, &out.Alias
*out = new(string)
**out = **in
}
return
}

View File

@ -460,6 +460,11 @@ type JKSKeystore struct {
// PasswordSecretRef is a reference to a key in a Secret resource
// containing the password used to encrypt the JKS keystore.
PasswordSecretRef cmmeta.SecretKeySelector `json:"passwordSecretRef"`
// Alias specifies the alias of the key in the keystore, required by the JKS format.
// If not provided, the default alias `certificate` will be used.
// +optional
Alias *string `json:"alias,omitempty"`
}
// PKCS12 configures options for storing a PKCS12 keystore in the

View File

@ -129,7 +129,7 @@ func (in *CertificateKeystores) DeepCopyInto(out *CertificateKeystores) {
if in.JKS != nil {
in, out := &in.JKS, &out.JKS
*out = new(JKSKeystore)
**out = **in
(*in).DeepCopyInto(*out)
}
if in.PKCS12 != nil {
in, out := &in.PKCS12, &out.PKCS12
@ -781,6 +781,11 @@ func (in *IssuerStatus) DeepCopy() *IssuerStatus {
func (in *JKSKeystore) DeepCopyInto(out *JKSKeystore) {
*out = *in
out.PasswordSecretRef = in.PasswordSecretRef
if in.Alias != nil {
in, out := &in.Alias, &out.Alias
*out = new(string)
**out = **in
}
return
}

View File

@ -92,7 +92,7 @@ func encodePKCS12Truststore(profile cmapi.PKCS12Profile, password string, caPem
}
}
func encodeJKSKeystore(password []byte, rawKey []byte, certPem []byte, caPem []byte) ([]byte, error) {
func encodeJKSKeystore(password []byte, keyAlias string, rawKey []byte, certPem []byte, caPem []byte) ([]byte, error) {
// encode the private key to PKCS8
key, err := pki.DecodePrivateKeyBytes(rawKey)
if err != nil {
@ -117,7 +117,7 @@ func encodeJKSKeystore(password []byte, rawKey []byte, certPem []byte, caPem []b
}
ks := jks.New()
if err = ks.SetPrivateKeyEntry("certificate", jks.PrivateKeyEntry{
if err = ks.SetPrivateKeyEntry(keyAlias, jks.PrivateKeyEntry{
CreationTime: time.Now(),
PrivateKey: keyDER,
CertificateChain: certs,

View File

@ -157,11 +157,13 @@ func mustLeafWithChain(t *testing.T) leafWithChain {
func TestEncodeJKSKeystore(t *testing.T) {
tests := map[string]struct {
password string
alias string
rawKey, certPEM, caPEM []byte
verify func(t *testing.T, out []byte, err error)
}{
"encode a JKS bundle for a PKCS1 key and certificate only": {
password: "password",
alias: "alias",
rawKey: mustGeneratePrivateKey(t, cmapi.PKCS1),
certPEM: mustSelfSignCertificate(t, nil),
verify: func(t *testing.T, out []byte, err error) {
@ -177,7 +179,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
return
}
if !ks.IsPrivateKeyEntry("certificate") {
if !ks.IsPrivateKeyEntry("alias") {
t.Errorf("no certificate data found in keystore")
}
@ -188,6 +190,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
},
"encode a JKS bundle for a PKCS8 key and certificate only": {
password: "password",
alias: "alias",
rawKey: mustGeneratePrivateKey(t, cmapi.PKCS8),
certPEM: mustSelfSignCertificate(t, nil),
verify: func(t *testing.T, out []byte, err error) {
@ -201,7 +204,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
t.Errorf("error decoding keystore: %v", err)
return
}
if !ks.IsPrivateKeyEntry("certificate") {
if !ks.IsPrivateKeyEntry("alias") {
t.Errorf("no certificate data found in keystore")
}
@ -212,6 +215,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
},
"encode a JKS bundle for a key, certificate and ca": {
password: "password",
alias: "alias",
rawKey: mustGeneratePrivateKey(t, cmapi.PKCS8),
certPEM: mustSelfSignCertificate(t, nil),
caPEM: mustSelfSignCertificate(t, nil),
@ -226,7 +230,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
t.Errorf("error decoding keystore: %v", err)
return
}
if !ks.IsPrivateKeyEntry("certificate") {
if !ks.IsPrivateKeyEntry("alias") {
t.Errorf("no certificate data found in keystore")
}
if !ks.IsTrustedCertificateEntry("ca") {
@ -236,6 +240,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
},
"encode a JKS bundle for a key, certificate and multiple cas": {
password: "password",
alias: "alias",
rawKey: mustGeneratePrivateKey(t, cmapi.PKCS8),
certPEM: mustSelfSignCertificate(t, nil),
caPEM: mustSelfSignCertificates(t, 3),
@ -250,7 +255,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
t.Errorf("error decoding keystore: %v", err)
return
}
if !ks.IsPrivateKeyEntry("certificate") {
if !ks.IsPrivateKeyEntry("alias") {
t.Errorf("no certificate data found in keystore")
}
if !ks.IsTrustedCertificateEntry("ca") {
@ -270,7 +275,7 @@ func TestEncodeJKSKeystore(t *testing.T) {
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
out, err := encodeJKSKeystore([]byte(test.password), test.rawKey, test.certPEM, test.caPEM)
out, err := encodeJKSKeystore([]byte(test.password), test.alias, test.rawKey, test.certPEM, test.caPEM)
test.verify(t, out, err)
})
}
@ -559,7 +564,7 @@ func TestManyPasswordLengths(t *testing.T) {
}
g.Go(func() error {
defer s.Release(1)
keystore, err := encodeJKSKeystore([]byte(passwords[testi]), rawKey, certPEM, caPEM)
keystore, err := encodeJKSKeystore([]byte(passwords[testi]), "alias", rawKey, certPEM, caPEM)
if err != nil {
t.Errorf("couldn't encode JKS Keystore with password %s (length %d): %s", passwords[testi], len(passwords[testi]), err.Error())
return err
@ -572,7 +577,7 @@ func TestManyPasswordLengths(t *testing.T) {
t.Errorf("error decoding keystore with password %s (length %d): %v", passwords[testi], len(passwords[testi]), err)
return err
}
if !ks.IsPrivateKeyEntry("certificate") {
if !ks.IsPrivateKeyEntry("alias") {
t.Errorf("no certificate data found in keystore")
}
if !ks.IsTrustedCertificateEntry("ca") {

View File

@ -287,7 +287,11 @@ func (s *SecretsManager) setKeystores(crt *cmapi.Certificate, secret *corev1.Sec
return fmt.Errorf("JKS keystore password Secret contains no data for key %q", ref.Key)
}
pw := pwSecret.Data[ref.Key]
keystoreData, err := encodeJKSKeystore(pw, data.PrivateKey, data.Certificate, data.CA)
alias := "certificate"
if crt.Spec.Keystores.JKS.Alias != nil {
alias = *crt.Spec.Keystores.JKS.Alias
}
keystoreData, err := encodeJKSKeystore(pw, alias, data.PrivateKey, data.Certificate, data.CA)
if err != nil {
return fmt.Errorf("error encoding JKS bundle: %w", err)
}