| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| package org.apache.plc4x.java.opcua.config; |
| |
| |
| import org.apache.plc4x.java.api.exceptions.PlcConnectionException; |
| import org.apache.plc4x.java.opcua.context.CertificateGenerator; |
| import org.apache.plc4x.java.opcua.context.CertificateKeyPair; |
| import org.apache.plc4x.java.opcua.protocol.OpcuaProtocolLogic; |
| import org.apache.plc4x.java.opcua.readwrite.PascalByteString; |
| import org.apache.plc4x.java.spi.configuration.Configuration; |
| import org.apache.plc4x.java.spi.configuration.annotations.ConfigurationParameter; |
| import org.apache.plc4x.java.spi.configuration.annotations.defaults.BooleanDefaultValue; |
| import org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultValue; |
| import org.apache.plc4x.java.spi.configuration.annotations.defaults.StringDefaultValue; |
| import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration; |
| import org.bouncycastle.jce.provider.BouncyCastleProvider; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.nio.file.FileSystems; |
| import java.nio.file.Path; |
| import java.security.*; |
| import java.security.cert.CertificateException; |
| import java.security.cert.X509Certificate; |
| |
| public class OpcuaConfiguration implements Configuration, TcpTransportConfiguration { |
| |
| static { |
| // Required for SecurityPolicy.Aes256_Sha256_RsaPss |
| Security.addProvider(new BouncyCastleProvider()); |
| } |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(OpcuaConfiguration.class); |
| |
| private String code; |
| private String host; |
| private String port; |
| private String endpoint; |
| private String params; |
| private Boolean isEncrypted = false; |
| private PascalByteString thumbprint; |
| private byte[] senderCertificate; |
| |
| @ConfigurationParameter("discovery") |
| @BooleanDefaultValue(true) |
| private boolean discovery; |
| |
| @ConfigurationParameter("username") |
| private String username; |
| |
| @ConfigurationParameter("password") |
| private String password; |
| |
| @ConfigurationParameter("securityPolicy") |
| @StringDefaultValue("None") |
| private String securityPolicy; |
| |
| @ConfigurationParameter("keyStoreFile") |
| private String keyStoreFile; |
| |
| @ConfigurationParameter("certDirectory") |
| private String certDirectory; |
| |
| @ConfigurationParameter("keyStorePassword") |
| private String keyStorePassword; |
| |
| private CertificateKeyPair ckp; |
| |
| public boolean isDiscovery() { |
| return discovery; |
| } |
| |
| public String getUsername() { |
| return username; |
| } |
| |
| public String getPassword() { |
| return password; |
| } |
| |
| public String getCertDirectory() { |
| return certDirectory; |
| } |
| |
| public String getSecurityPolicy() { |
| return securityPolicy; |
| } |
| |
| public String getKeyStoreFile() { |
| return keyStoreFile; |
| } |
| |
| public String getKeyStorePassword() { |
| return keyStorePassword; |
| } |
| |
| public PascalByteString getThumbprint() { |
| return thumbprint; |
| } |
| |
| public CertificateKeyPair getCertificateKeyPair() { |
| return ckp; |
| } |
| |
| public boolean isEncrypted() { return isEncrypted; } |
| |
| public void setDiscovery(boolean discovery) { |
| this.discovery = discovery; |
| } |
| |
| public void setUsername(String username) { |
| this.username = username; |
| } |
| |
| public void setPassword(String password) { |
| this.password = password; |
| } |
| |
| public void setCertDirectory(String certDirectory) { |
| this.certDirectory = certDirectory; |
| } |
| |
| public void setSecurityPolicy(String securityPolicy) { |
| this.securityPolicy = securityPolicy; |
| } |
| |
| public void setKeyStoreFile(String keyStoreFile) { |
| this.keyStoreFile = keyStoreFile; |
| } |
| |
| public void setKeyStorePassword(String keyStorePassword) { |
| this.keyStorePassword = keyStorePassword; |
| } |
| |
| public void setThumbprint(PascalByteString thumbprint) { this.thumbprint = thumbprint; } |
| |
| public String getTransportCode() { |
| return code; |
| } |
| |
| public String getHost() { |
| return host; |
| } |
| |
| public String getPort() { |
| return port; |
| } |
| |
| public String getEndpoint() { |
| return endpoint; |
| } |
| |
| public byte[] getSenderCertificate() { |
| return this.senderCertificate; |
| } |
| |
| public void setTransportCode(String code) { |
| this.code = code; |
| } |
| |
| public void setHost(String host) { |
| this.host = host; |
| } |
| |
| public void setPort(String port) { |
| this.port = port; |
| } |
| |
| public void setEndpoint(String endpoint) { |
| this.endpoint = endpoint; |
| } |
| |
| public void openKeyStore() throws Exception { |
| this.isEncrypted = true; |
| File securityTempDir = new File(certDirectory, "security"); |
| if (!securityTempDir.exists() && !securityTempDir.mkdirs()) { |
| throw new PlcConnectionException("Unable to create directory please confirm folder permissions on " + certDirectory); |
| } |
| KeyStore keyStore = KeyStore.getInstance("PKCS12"); |
| File serverKeyStore = securityTempDir.toPath().resolve(keyStoreFile).toFile(); |
| |
| File pkiDir = FileSystems.getDefault().getPath(certDirectory).resolve("pki").toFile(); |
| if (!serverKeyStore.exists()) { |
| ckp = CertificateGenerator.generateCertificate(); |
| LOGGER.info("Creating new KeyStore at {}", serverKeyStore); |
| keyStore.load(null, keyStorePassword.toCharArray()); |
| keyStore.setKeyEntry("plc4x-certificate-alias", ckp.getKeyPair().getPrivate(), keyStorePassword.toCharArray(), new X509Certificate[] { ckp.getCertificate() }); |
| keyStore.store(new FileOutputStream(serverKeyStore), keyStorePassword.toCharArray()); |
| } else { |
| LOGGER.info("Loading KeyStore at {}", serverKeyStore); |
| keyStore.load(new FileInputStream(serverKeyStore), keyStorePassword.toCharArray()); |
| String alias = keyStore.aliases().nextElement(); |
| KeyPair kp = new KeyPair(keyStore.getCertificate(alias).getPublicKey(), |
| (PrivateKey) keyStore.getKey(alias, keyStorePassword.toCharArray())); |
| ckp = new CertificateKeyPair(kp,(X509Certificate) keyStore.getCertificate(alias)); |
| } |
| } |
| |
| @Override |
| public String toString() { |
| return "Configuration{" + |
| '}'; |
| } |
| |
| public void setSenderCertificate(byte[] certificate) { this.senderCertificate = certificate; } |
| |
| } |
| |