use of io.strimzi.certs.Subject in project strimzi-kafka-operator by strimzi.
the class CertificateRenewalTest method generateCa.
private CertAndKey generateCa(OpenSslCertManager certManager, CertificateAuthority certificateAuthority, String commonName) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
String clusterCaStorePassword = "123456";
Path clusterCaKeyFile = Files.createTempFile("tls", "cluster-ca-key");
Path clusterCaCertFile = Files.createTempFile("tls", "cluster-ca-cert");
Path clusterCaStoreFile = Files.createTempFile("tls", "cluster-ca-store");
try {
Subject sbj = new Subject.Builder().withOrganizationName("io.strimzi").withCommonName(commonName).build();
certManager.generateSelfSignedCert(clusterCaKeyFile.toFile(), clusterCaCertFile.toFile(), sbj, ModelUtils.getCertificateValidity(certificateAuthority));
certManager.addCertToTrustStore(clusterCaCertFile.toFile(), CA_CRT, clusterCaStoreFile.toFile(), clusterCaStorePassword);
return new CertAndKey(Files.readAllBytes(clusterCaKeyFile), Files.readAllBytes(clusterCaCertFile), Files.readAllBytes(clusterCaStoreFile), null, clusterCaStorePassword);
} finally {
Files.delete(clusterCaKeyFile);
Files.delete(clusterCaCertFile);
Files.delete(clusterCaStoreFile);
}
}
use of io.strimzi.certs.Subject in project strimzi-kafka-operator by strimzi.
the class Ca method generateSignedCert.
/**
* Generates a certificate signed by this CA
*
* @param commonName The CN of the certificate to be generated.
* @param organization The O of the certificate to be generated. May be null.
* @return The CertAndKey
* @throws IOException If the cert could not be generated.
*/
public CertAndKey generateSignedCert(String commonName, String organization) throws IOException {
File csrFile = File.createTempFile("tls", "csr");
File keyFile = File.createTempFile("tls", "key");
File certFile = File.createTempFile("tls", "cert");
File keyStoreFile = File.createTempFile("tls", "p12");
Subject.Builder subject = new Subject.Builder();
if (organization != null) {
subject.withOrganizationName(organization);
}
subject.withCommonName(commonName);
CertAndKey result = generateSignedCert(subject.build(), csrFile, keyFile, certFile, keyStoreFile);
delete(reconciliation, csrFile);
delete(reconciliation, keyFile);
delete(reconciliation, certFile);
delete(reconciliation, keyStoreFile);
return result;
}
use of io.strimzi.certs.Subject in project strimzi-kafka-operator by strimzi.
the class Ca method maybeCopyOrGenerateCerts.
/**
* Copy already existing certificates from provided Secret based on number of effective replicas
* and maybe generate new ones for new replicas (i.e. scale-up).
*/
protected Map<String, CertAndKey> maybeCopyOrGenerateCerts(Reconciliation reconciliation, int replicas, Function<Integer, Subject> subjectFn, Secret secret, Function<Integer, String> podNameFn, boolean isMaintenanceTimeWindowsSatisfied) throws IOException {
int replicasInSecret;
if (secret == null || secret.getData() == null || this.certRenewed()) {
replicasInSecret = 0;
} else {
replicasInSecret = (int) secret.getData().keySet().stream().filter(k -> k.contains(".crt")).count();
}
File brokerCsrFile = File.createTempFile("tls", "broker-csr");
File brokerKeyFile = File.createTempFile("tls", "broker-key");
File brokerCertFile = File.createTempFile("tls", "broker-cert");
File brokerKeyStoreFile = File.createTempFile("tls", "broker-p12");
int replicasInNewSecret = Math.min(replicasInSecret, replicas);
Map<String, CertAndKey> certs = new HashMap<>(replicasInNewSecret);
// scale down -> it will copy just the requested number of replicas
for (int i = 0; i < replicasInNewSecret; i++) {
String podName = podNameFn.apply(i);
LOGGER.debugCr(reconciliation, "Certificate for {} already exists", podName);
Subject subject = subjectFn.apply(i);
CertAndKey certAndKey;
if (secret.getData().get(podName + ".p12") != null && !secret.getData().get(podName + ".p12").isEmpty() && secret.getData().get(podName + ".password") != null && !secret.getData().get(podName + ".password").isEmpty()) {
certAndKey = asCertAndKey(secret, podName + ".key", podName + ".crt", podName + ".p12", podName + ".password");
} else {
// coming from an older operator version, the secret exists but without keystore and password
certAndKey = addKeyAndCertToKeyStore(subject.commonName(), Base64.getDecoder().decode(secret.getData().get(podName + ".key")), Base64.getDecoder().decode(secret.getData().get(podName + ".crt")));
}
List<String> reasons = new ArrayList<>(2);
if (certSubjectChanged(certAndKey, subject, podName)) {
reasons.add("DNS names changed");
}
if (isExpiring(secret, podName + ".crt") && isMaintenanceTimeWindowsSatisfied) {
reasons.add("certificate is expiring");
}
if (renewalType.equals(RenewalType.CREATE)) {
reasons.add("certificate added");
}
if (!reasons.isEmpty()) {
LOGGER.debugCr(reconciliation, "Certificate for pod {} need to be regenerated because: {}", podName, String.join(", ", reasons));
CertAndKey newCertAndKey = generateSignedCert(subject, brokerCsrFile, brokerKeyFile, brokerCertFile, brokerKeyStoreFile);
certs.put(podName, newCertAndKey);
} else {
certs.put(podName, certAndKey);
}
}
// scale down -> does nothing
for (int i = replicasInSecret; i < replicas; i++) {
String podName = podNameFn.apply(i);
LOGGER.debugCr(reconciliation, "Certificate for pod {} to generate", podName);
CertAndKey k = generateSignedCert(subjectFn.apply(i), brokerCsrFile, brokerKeyFile, brokerCertFile, brokerKeyStoreFile);
certs.put(podName, k);
}
delete(reconciliation, brokerCsrFile);
delete(reconciliation, brokerKeyFile);
delete(reconciliation, brokerCertFile);
delete(reconciliation, brokerKeyStoreFile);
return certs;
}
use of io.strimzi.certs.Subject in project strimzi-kafka-operator by strimzi.
the class Ca method getSubjectAltNames.
/**
* Extracts the alternate subject names out of existing certificate
*
* @param certificate Existing X509 certificate as a byte array
* @return
*/
protected List<String> getSubjectAltNames(byte[] certificate) {
List<String> subjectAltNames = null;
try {
X509Certificate cert = x509Certificate(certificate);
Collection<List<?>> altNames = cert.getSubjectAlternativeNames();
subjectAltNames = altNames.stream().filter(name -> name.get(1) instanceof String).map(item -> (String) item.get(1)).collect(Collectors.toList());
} catch (CertificateException | RuntimeException e) {
// TODO: We should mock the certificates properly so that this doesn't fail in tests (not now => long term :-o)
LOGGER.debugCr(reconciliation, "Failed to parse existing certificate", e);
}
return subjectAltNames;
}
Aggregations