KeyStoreLoader.java
/*
* Copyright (c) 2019 the Eclipse Milo Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package de.dlr.bt.stc.source.opcua;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder;
import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;
import de.dlr.bt.stc.exceptions.SourceConfigurationException;
import lombok.extern.slf4j.Slf4j;
@Slf4j
class KeyStoreLoader {
// private static final Pattern IP_ADDR_PATTERN = Pattern
// .compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
private static final String CLIENT_ALIAS = "client-ai";
private static final char[] PASSWORD = "password".toCharArray();
private X509Certificate clientCertificate;
private KeyPair clientKeyPair;
KeyStoreLoader load(File keyStoreFile, boolean createIfNotExisting) throws SourceConfigurationException {
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
log.info("Loading KeyStore at {}", keyStoreFile);
if (!keyStoreFile.exists()) {
if (!createIfNotExisting)
throw new SourceConfigurationException(
"Keystore " + keyStoreFile + " not found and automatic creation is disabled!");
keyStore.load(null, PASSWORD);
KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048);
SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair)
.setCommonName("Shepard Timeseries Connector").setOrganization("DLR e.V.")
.setOrganizationalUnit("BT").setLocalityName("Augsburg").setStateName("BY").setCountryCode("DE")
.setApplicationUri("urn:idms:stc").addDnsName("localhost").addIpAddress("127.0.0.1");
// Get as many hostnames and IP addresses as we can listed in the certificate.
// for (String hostname : HostnameUtil.getHostnames("0.0.0.0")) {
// if (IP_ADDR_PATTERN.matcher(hostname)
// .matches()) {
// builder.addIpAddress(hostname);
// } else {
// builder.addDnsName(hostname);
// }
// }
X509Certificate certificate = builder.build();
keyStore.setKeyEntry(CLIENT_ALIAS, keyPair.getPrivate(), PASSWORD,
new X509Certificate[] { certificate });
try (OutputStream out = Files.newOutputStream(keyStoreFile.toPath())) {
keyStore.store(out, PASSWORD);
}
} else {
try (InputStream in = Files.newInputStream(keyStoreFile.toPath())) {
keyStore.load(in, PASSWORD);
}
}
Key serverPrivateKey = keyStore.getKey(CLIENT_ALIAS, PASSWORD);
if (serverPrivateKey instanceof PrivateKey) {
clientCertificate = (X509Certificate) keyStore.getCertificate(CLIENT_ALIAS);
PublicKey serverPublicKey = clientCertificate.getPublicKey();
clientKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey);
}
return this;
} catch (Exception ex) {
// This is ugly, but builder throws a generic Exception ...
throw new SourceConfigurationException("Keystore operation failed", ex);
}
}
X509Certificate getClientCertificate() {
return clientCertificate;
}
KeyPair getClientKeyPair() {
return clientKeyPair;
}
}