Skip to content

Add tls-pkcs12-trustore format #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion docs/modules/secret-operator/pages/secretclass.adoc
Original file line number Diff line number Diff line change
@@ -206,7 +206,7 @@ metadata:
name: admin-credentials-class
spec:
backend:
k8sSearch:
k8sSearch:
searchNamespace:
pod: {}
---
55 changes: 43 additions & 12 deletions rust/operator-binary/src/format/convert.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ use snafu::{OptionExt, ResultExt, Snafu};
use crate::format::utils::split_pem_certificates;

use super::{
well_known::{CompatibilityOptions, TlsPem, TlsPkcs12},
well_known::{CompatibilityOptions, TlsCaPem, TlsPem, TlsPkcs12, TlsPkcs12Truststore},
SecretFormat, WellKnownSecretData,
};

@@ -29,6 +29,35 @@ pub fn convert(
compat.tls_pkcs12_password.as_deref().unwrap_or_default(),
)?))
}
(WellKnownSecretData::TlsPem(pem), SecretFormat::TlsCaPem) => {
Ok(WellKnownSecretData::TlsCaPem(TlsCaPem {
ca_pem: pem.ca_pem,
}))
}
(WellKnownSecretData::TlsPem(pem), SecretFormat::TlsPkcs12Truststore) => {
let ca_stack = ca_pem_to_ca_stack(&pem.ca_pem)?;

Ok(WellKnownSecretData::TlsPkcs12Truststore(
TlsPkcs12Truststore {
truststore: pkcs12_truststore(
&ca_stack,
compat.tls_pkcs12_password.as_deref().unwrap_or_default(),
)?,
},
))
}
(WellKnownSecretData::TlsCaPem(pem), SecretFormat::TlsPkcs12Truststore) => {
let ca_stack = ca_pem_to_ca_stack(&pem.ca_pem)?;

Ok(WellKnownSecretData::TlsPkcs12Truststore(
TlsPkcs12Truststore {
truststore: pkcs12_truststore(
&ca_stack,
compat.tls_pkcs12_password.as_deref().unwrap_or_default(),
)?,
},
))
}

(from, to) => NoValidConversionSnafu { from, to }.fail(),
}
@@ -49,20 +78,11 @@ pub enum ConvertError {
TlsToPkcs12 { source: TlsToPkcs12Error },
}

pub fn convert_tls_to_pkcs12(
pem: TlsPem,
p12_password: &str,
) -> Result<TlsPkcs12, TlsToPkcs12Error> {
fn convert_tls_to_pkcs12(pem: TlsPem, p12_password: &str) -> Result<TlsPkcs12, TlsToPkcs12Error> {
use tls_to_pkcs12_error::*;
let cert = X509::from_pem(&pem.certificate_pem).context(LoadCertSnafu)?;
let key = PKey::private_key_from_pem(&pem.key_pem).context(LoadKeySnafu)?;

let mut ca_stack = Stack::<X509>::new().context(LoadCaSnafu)?;
for ca in split_pem_certificates(&pem.ca_pem) {
X509::from_pem(ca)
.and_then(|ca| ca_stack.push(ca))
.context(LoadCertSnafu)?;
}
let ca_stack = ca_pem_to_ca_stack(&pem.ca_pem)?;

Ok(TlsPkcs12 {
truststore: pkcs12_truststore(&ca_stack, p12_password)?,
@@ -76,6 +96,17 @@ pub fn convert_tls_to_pkcs12(
})
}

fn ca_pem_to_ca_stack(ca_pem: &[u8]) -> Result<Stack<X509>, TlsToPkcs12Error> {
use tls_to_pkcs12_error::*;
let mut ca_stack = Stack::<X509>::new().context(LoadCaSnafu)?;
for ca in split_pem_certificates(ca_pem) {
X509::from_pem(ca)
.and_then(|ca| ca_stack.push(ca))
.context(LoadCertSnafu)?;
}
Ok(ca_stack)
}

fn bmp_string(s: &str) -> Vec<u8> {
s.encode_utf16()
.chain([0]) // null-termination character
20 changes: 20 additions & 0 deletions rust/operator-binary/src/format/well_known.rs
Original file line number Diff line number Diff line change
@@ -21,12 +21,22 @@ pub struct TlsPem {
pub ca_pem: Vec<u8>,
}

#[derive(Debug)]
pub struct TlsCaPem {
pub ca_pem: Vec<u8>,
}

#[derive(Debug)]
pub struct TlsPkcs12 {
pub keystore: Vec<u8>,
pub truststore: Vec<u8>,
}

#[derive(Debug)]
pub struct TlsPkcs12Truststore {
pub truststore: Vec<u8>,
}

#[derive(Debug)]
pub struct Kerberos {
pub keytab: Vec<u8>,
@@ -41,7 +51,9 @@ pub struct Kerberos {
)]
pub enum WellKnownSecretData {
TlsPem(TlsPem),
TlsCaPem(TlsCaPem),
TlsPkcs12(TlsPkcs12),
TlsPkcs12Truststore(TlsPkcs12Truststore),
Kerberos(Kerberos),
}

@@ -58,6 +70,9 @@ impl WellKnownSecretData {
(FILE_PEM_CERT_CA.to_string(), ca_pem),
]
.into(),
WellKnownSecretData::TlsCaPem(TlsCaPem { ca_pem }) => {
[(FILE_PEM_CERT_CA.to_string(), ca_pem)].into()
}
WellKnownSecretData::TlsPkcs12(TlsPkcs12 {
keystore,
truststore,
@@ -66,6 +81,9 @@ impl WellKnownSecretData {
(FILE_PKCS12_CERT_TRUSTSTORE.to_string(), truststore),
]
.into(),
WellKnownSecretData::TlsPkcs12Truststore(TlsPkcs12Truststore { truststore }) => {
[(FILE_PKCS12_CERT_TRUSTSTORE.to_string(), truststore)].into()
}
WellKnownSecretData::Kerberos(Kerberos { keytab, krb5_conf }) => [
(FILE_KERBEROS_KEYTAB_KEYTAB.to_string(), keytab),
(FILE_KERBEROS_KEYTAB_KRB5_CONF.to_string(), krb5_conf),
@@ -88,6 +106,8 @@ impl WellKnownSecretData {
key_pem: take_file(FILE_PEM_CERT_KEY)?,
ca_pem: take_file(FILE_PEM_CERT_CA)?,
}))
} else if let Ok(ca_pem) = take_file(SecretFormat::TlsCaPem, FILE_PEM_CERT_CA) {
Ok(WellKnownSecretData::TlsCaPem(TlsCaPem { ca_pem }))
} else if let Ok(keystore) = take_file(SecretFormat::TlsPkcs12, FILE_PKCS12_CERT_KEYSTORE) {
Ok(WellKnownSecretData::TlsPkcs12(TlsPkcs12 {
keystore,
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -6,6 +6,6 @@ timeout: 300
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer
name: tls-consumer-pem
status:
succeeded: 1
5 changes: 5 additions & 0 deletions tests/templates/kuttl/auto-tls/10-consumer-pem.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: envsubst '$NAMESPACE' < consumer-pem.yaml | kubectl apply -n $NAMESPACE -f -
11 changes: 11 additions & 0 deletions tests/templates/kuttl/auto-tls/11-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 300
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-pkcs12
status:
succeeded: 1
5 changes: 5 additions & 0 deletions tests/templates/kuttl/auto-tls/11-consumer-pkcs12.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: envsubst '$NAMESPACE' < consumer-pkcs12.yaml | kubectl apply -n $NAMESPACE -f -
11 changes: 11 additions & 0 deletions tests/templates/kuttl/auto-tls/12-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 300
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-pkcs12-truststore
status:
succeeded: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: envsubst '$NAMESPACE' < consumer-pkcs12-truststore.yaml | kubectl apply -n $NAMESPACE -f -
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer
name: tls-consumer-pem
spec:
template:
spec:
48 changes: 48 additions & 0 deletions tests/templates/kuttl/auto-tls/consumer-pkcs12-truststore.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# $NAMESPACE will be replaced with the namespace of the test case.
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-pkcs12-truststore
spec:
template:
spec:
containers:
- name: consumer
image: docker.stackable.tech/stackable/testing-tools:0.2.0-stackable0.0.0-dev
command:
- bash
args:
- -c
- |
set -euo pipefail
ls -la /stackable/tls

if ! test -f /stackable/tls/truststore.p12; then echo "Truststore missing!" && exit 1; fi
if test -f /stackable/tls/keystore.p12; then echo "Keystore is present, but should be absent!" && exit 1; fi
volumeMounts:
- mountPath: /stackable/tls
name: tls
volumes:
- name: tls
ephemeral:
volumeClaimTemplate:
metadata:
annotations:
secrets.stackable.tech/class: tls-$NAMESPACE
secrets.stackable.tech/scope: pod
secrets.stackable.tech/format: tls-pkcs12-truststore
spec:
storageClassName: secrets.stackable.tech
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1"
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
restartPolicy: Never
terminationGracePeriodSeconds: 0
serviceAccount: integration-tests-sa
48 changes: 48 additions & 0 deletions tests/templates/kuttl/auto-tls/consumer-pkcs12.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# $NAMESPACE will be replaced with the namespace of the test case.
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-pkcs12
spec:
template:
spec:
containers:
- name: consumer
image: docker.stackable.tech/stackable/testing-tools:0.2.0-stackable0.0.0-dev
command:
- bash
args:
- -c
- |
set -euo pipefail
ls -la /stackable/tls

if ! test -f /stackable/tls/truststore.p12; then echo "Truststore missing!" && exit 1; fi
if ! test -f /stackable/tls/keystore.p12; then echo "Keystore missing!" && exit 1; fi
volumeMounts:
- mountPath: /stackable/tls
name: tls
volumes:
- name: tls
ephemeral:
volumeClaimTemplate:
metadata:
annotations:
secrets.stackable.tech/class: tls-$NAMESPACE
secrets.stackable.tech/scope: pod
secrets.stackable.tech/format: tls-pkcs12
spec:
storageClassName: secrets.stackable.tech
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1"
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
restartPolicy: Never
terminationGracePeriodSeconds: 0
serviceAccount: integration-tests-sa
File renamed without changes.
5 changes: 0 additions & 5 deletions tests/templates/kuttl/tls/10-consumer.yaml

This file was deleted.

5 changes: 5 additions & 0 deletions tests/templates/kuttl/user-provided-tls/01-secretclass.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: envsubst '$NAMESPACE' < secretclass.yaml | kubectl apply -n "$NAMESPACE" -f -
30 changes: 30 additions & 0 deletions tests/templates/kuttl/user-provided-tls/02-rbac.yaml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: use-integration-tests-scc
rules:
{% if test_scenario['values']['openshift'] == "true" %}
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
resourceNames: ["privileged"]
verbs: ["use"]
{% endif %}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: integration-tests-sa
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: use-integration-tests-scc
subjects:
- kind: ServiceAccount
name: integration-tests-sa
roleRef:
kind: Role
name: use-integration-tests-scc
apiGroup: rbac.authorization.k8s.io

11 changes: 11 additions & 0 deletions tests/templates/kuttl/user-provided-tls/10-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 300
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-ca-pem
status:
succeeded: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: envsubst '$NAMESPACE' < consumer-ca-pem.yaml | kubectl apply -n $NAMESPACE -f -
11 changes: 11 additions & 0 deletions tests/templates/kuttl/user-provided-tls/11-assert.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestAssert
timeout: 300
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-pkcs12-truststore
status:
succeeded: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
apiVersion: kuttl.dev/v1beta1
kind: TestStep
commands:
- script: envsubst '$NAMESPACE' < consumer-pkcs12-truststore.yaml | kubectl apply -n $NAMESPACE -f -
48 changes: 48 additions & 0 deletions tests/templates/kuttl/user-provided-tls/consumer-ca-pem.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# $NAMESPACE will be replaced with the namespace of the test case.
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-ca-pem
spec:
template:
spec:
containers:
- name: consumer
image: docker.stackable.tech/stackable/testing-tools:0.2.0-stackable0.0.0-dev
command:
- bash
args:
- -c
- |
set -euo pipefail
ls -la /stackable/tls
if ! test -f /stackable/tls/ca.crt; then echo "ca.crt missing!" && exit 1; fi
if test -f /stackable/tls/tls.crt; then echo "tls.crt is present, but should be absent!" && exit 1; fi
if test -f /stackable/tls/tls.key; then echo "tls.key is present, but should be absent!" && exit 1; fi
volumeMounts:
- mountPath: /stackable/tls
name: tls
volumes:
- name: tls
ephemeral:
volumeClaimTemplate:
metadata:
annotations:
secrets.stackable.tech/class: custom-ca-$NAMESPACE
secrets.stackable.tech/format: tls-ca-pem
spec:
storageClassName: secrets.stackable.tech
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1"
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
restartPolicy: Never
terminationGracePeriodSeconds: 0
serviceAccount: integration-tests-sa
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# $NAMESPACE will be replaced with the namespace of the test case.
---
apiVersion: batch/v1
kind: Job
metadata:
name: tls-consumer-pkcs12-truststore
spec:
template:
spec:
containers:
- name: consumer
image: docker.stackable.tech/stackable/testing-tools:0.2.0-stackable0.0.0-dev
command:
- bash
args:
- -c
- |
set -euo pipefail
ls -la /stackable/tls
if ! test -f /stackable/tls/truststore.p12; then echo "truststore.p12 missing!" && exit 1; fi
if test -f /stackable/tls/ca.crt; then echo "ca.crt is present, but should be absent!" && exit 1; fi
if test -f /stackable/tls/tls.crt; then echo "tls.crt is present, but should be absent!" && exit 1; fi
if test -f /stackable/tls/tls.key; then echo "tls.key is present, but should be absent!" && exit 1; fi
volumeMounts:
- mountPath: /stackable/tls
name: tls
volumes:
- name: tls
ephemeral:
volumeClaimTemplate:
metadata:
annotations:
secrets.stackable.tech/class: custom-ca-$NAMESPACE
secrets.stackable.tech/format: tls-pkcs12-truststore
spec:
storageClassName: secrets.stackable.tech
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "1"
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
restartPolicy: Never
terminationGracePeriodSeconds: 0
serviceAccount: integration-tests-sa
41 changes: 41 additions & 0 deletions tests/templates/kuttl/user-provided-tls/secretclass.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# $NAMESPACE will be replaced with the namespace of the test case.
---
apiVersion: secrets.stackable.tech/v1alpha1
kind: SecretClass
metadata:
name: custom-ca-$NAMESPACE
spec:
backend:
k8sSearch:
searchNamespace:
pod: {}
---
apiVersion: v1
kind: Secret
metadata:
name: custom-ca
labels:
secrets.stackable.tech/class: custom-ca-$NAMESPACE
stringData:
ca.crt: |
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIQO7eOmc5HFIBOjSAkCI0SODANBgkqhkiG9w0BAQsFADBI
MRQwEgYKCZImiZPyLGQBGRYEdGVzdDEUMBIGCgmSJomT8ixkARkWBHNibGUxGjAY
BgNVBAMTEXNibGUtU0JMRS1BRERTLUNBMB4XDTIzMDMyNzEyMzgwN1oXDTI4MDMy
NzEyNDgwN1owSDEUMBIGCgmSJomT8ixkARkWBHRlc3QxFDASBgoJkiaJk/IsZAEZ
FgRzYmxlMRowGAYDVQQDExFzYmxlLVNCTEUtQUREUy1DQTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAM1sskWrUPrVIQ0Ulwq2XLhcSthHbnCSCeqrlT+z
GPSeMd5QbL9hzo0iP1a1NBxNCbkG1xQ6otDYEGH7I7soV2YjafPJ34qalsejXeQb
HPB56ZQ9ue0QKq5I8STAkewYNdE9NLD9O4wc0r0gU3WqDXQumwMvDSGgMoJ5oCJ8
pZaJyF8HP6v1FRK0h9BHf+pau0ZC9a/2yhPGX/y4tuka4SFE/4RSc5K2xDdCLTEf
EfHovT4zDIx6ErDmVTgLJ0e/UXWoO1v+WJz3gBcrvbwZrKnBs7CUqza26RCApgtd
tlCX0zplT3LjmFENTZO+nN1KOoCCtE3/xOAqgZsLtof4NAUCAwEAAaNRME8wCwYD
VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFC7kiVMA8eKGHp8/
Mozb9c1JYunUMBAGCSsGAQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBCwUAA4IBAQCQ
6oL/8jA6ie39dAyJLMIv8U3+pDokAUCkJplc6COf537kchLrF24evFvZi8+aA3/s
PFntxXJsahcUXi8hBbZLHj+ZdmN2fjq0CE/0sRiHS2C/LRuskLTcVISELLxoiynn
SOR/zeC6mUgFdGhnV1w84cxoeZV8YD3cdrlmFcD0b2kjm3i2t8ifapJENLFllzRW
spnQeRVimyvwH1s4U8qZ/OcR4c3P37kczEuQ165tpjFVfmw7a/OCMFa+olP4bP18
AojYiwU57w90WTveuE76qjK8Q9BGj9C1vjk6xPXM4aS6ga5kwQVmiAYlPmogooyz
EToGeyp1QmS66b5Se18l
-----END CERTIFICATE-----
5 changes: 4 additions & 1 deletion tests/test-definition.yaml
Original file line number Diff line number Diff line change
@@ -13,7 +13,10 @@ tests:
- name: listener
dimensions:
- openshift
- name: tls
- name: auto-tls
dimensions:
- openshift
- name: user-provided-tls
dimensions:
- openshift
suites: