1
2
3
4
5
6
7
8
9
10
11 package de.dlr.bt.stc.opcuaserver;
12
13 import java.io.File;
14 import java.io.FileInputStream;
15 import java.io.FileOutputStream;
16 import java.nio.file.Path;
17 import java.security.Key;
18 import java.security.KeyPair;
19 import java.security.KeyStore;
20 import java.security.PrivateKey;
21 import java.security.PublicKey;
22 import java.security.cert.X509Certificate;
23 import java.util.Arrays;
24 import java.util.Set;
25 import java.util.UUID;
26 import java.util.regex.Pattern;
27
28 import org.eclipse.milo.opcua.sdk.server.util.HostnameUtil;
29 import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateBuilder;
30 import org.eclipse.milo.opcua.stack.core.util.SelfSignedCertificateGenerator;
31
32 import com.google.common.collect.Sets;
33
34 import lombok.extern.slf4j.Slf4j;
35
36 @Slf4j
37 class KeyStoreLoader {
38
39 private static final Pattern IP_ADDR_PATTERN = Pattern
40 .compile("^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
41
42 private static final String SERVER_ALIAS = "server-ai";
43 private static final char[] PASSWORD = "password".toCharArray();
44
45 private X509Certificate[] serverCertificateChain;
46 private X509Certificate serverCertificate;
47 private KeyPair serverKeyPair;
48
49 KeyStoreLoader load(Path baseDir) throws Exception {
50 KeyStore keyStore = KeyStore.getInstance("PKCS12");
51
52 File serverKeyStore = baseDir.resolve("example-server.pfx").toFile();
53
54 log.info("Loading KeyStore at {}", serverKeyStore);
55
56 if (!serverKeyStore.exists()) {
57 keyStore.load(null, PASSWORD);
58
59 KeyPair keyPair = SelfSignedCertificateGenerator.generateRsaKeyPair(2048);
60
61 String applicationUri = "urn:dlr:stc:server:" + UUID.randomUUID();
62
63 SelfSignedCertificateBuilder builder = new SelfSignedCertificateBuilder(keyPair)
64 .setCommonName("Shepard Timeseries Collector").setOrganization("DLR e.V.")
65 .setOrganizationalUnit("BT").setLocalityName("Augsburg").setStateName("BY").setCountryCode("DE")
66 .setApplicationUri(applicationUri);
67
68
69 Set<String> hostnames = Sets.union(Sets.newHashSet(HostnameUtil.getHostname()),
70 HostnameUtil.getHostnames("0.0.0.0", false));
71
72 for (String hostname : hostnames) {
73 if (IP_ADDR_PATTERN.matcher(hostname).matches()) {
74 builder.addIpAddress(hostname);
75 } else {
76 builder.addDnsName(hostname);
77 }
78 }
79
80 X509Certificate certificate = builder.build();
81
82 keyStore.setKeyEntry(SERVER_ALIAS, keyPair.getPrivate(), PASSWORD, new X509Certificate[] { certificate });
83 keyStore.store(new FileOutputStream(serverKeyStore), PASSWORD);
84 } else {
85 keyStore.load(new FileInputStream(serverKeyStore), PASSWORD);
86 }
87
88 Key serverPrivateKey = keyStore.getKey(SERVER_ALIAS, PASSWORD);
89 if (serverPrivateKey instanceof PrivateKey) {
90 serverCertificate = (X509Certificate) keyStore.getCertificate(SERVER_ALIAS);
91
92 serverCertificateChain = Arrays.stream(keyStore.getCertificateChain(SERVER_ALIAS))
93 .map(X509Certificate.class::cast).toArray(X509Certificate[]::new);
94
95 PublicKey serverPublicKey = serverCertificate.getPublicKey();
96 serverKeyPair = new KeyPair(serverPublicKey, (PrivateKey) serverPrivateKey);
97 }
98
99 return this;
100 }
101
102 X509Certificate getServerCertificate() {
103 return serverCertificate;
104 }
105
106 public X509Certificate[] getServerCertificateChain() {
107 return serverCertificateChain;
108 }
109
110 KeyPair getServerKeyPair() {
111 return serverKeyPair;
112 }
113
114 }