Commit b864680b812e86ecc6d1ba032256768fa05ab3fa
Committed by
Andrew Shvayka
1 parent
4c12985a
Lwm2m: back: start DTLS -one server 4 security
Showing
10 changed files
with
358 additions
and
583 deletions
... | ... | @@ -217,23 +217,19 @@ public class LwM2MModelsRepository { |
217 | 217 | switch (mode) { |
218 | 218 | case NO_SEC: |
219 | 219 | bsServ.setHost(contextBootStrap.getBootstrapHost()); |
220 | - bsServ.setPort(contextBootStrap.getBootstrapPortNoSecPsk()); | |
220 | + bsServ.setPort(contextBootStrap.getBootstrapPortNoSec()); | |
221 | 221 | bsServ.setServerPublicKey(""); |
222 | 222 | break; |
223 | 223 | case PSK: |
224 | - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); | |
225 | - bsServ.setPort(contextBootStrap.getBootstrapSecurePortPsk()); | |
224 | + bsServ.setHost(contextBootStrap.getBootstrapHostSecurity()); | |
225 | + bsServ.setPort(contextBootStrap.getBootstrapPortSecurity()); | |
226 | 226 | bsServ.setServerPublicKey(""); |
227 | 227 | break; |
228 | 228 | case RPK: |
229 | - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); | |
230 | - bsServ.setPort(contextBootStrap.getBootstrapSecurePortRpk()); | |
231 | - bsServ.setServerPublicKey(getRPKPublicKey(this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY())); | |
232 | - break; | |
233 | 229 | case X509: |
234 | - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); | |
235 | - bsServ.setPort(contextBootStrap.getBootstrapSecurePortX509()); | |
236 | - bsServ.setServerPublicKey(getServerPublicKeyX509(contextBootStrap.getBootstrapAlias())); | |
230 | + bsServ.setHost(contextBootStrap.getBootstrapHostSecurity()); | |
231 | + bsServ.setPort(contextBootStrap.getBootstrapPortSecurity()); | |
232 | + bsServ.setServerPublicKey(getPublicKey (contextBootStrap.getBootstrapAlias(), this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY())); | |
237 | 233 | break; |
238 | 234 | default: |
239 | 235 | break; |
... | ... | @@ -243,23 +239,19 @@ public class LwM2MModelsRepository { |
243 | 239 | switch (mode) { |
244 | 240 | case NO_SEC: |
245 | 241 | bsServ.setHost(contextServer.getServerHost()); |
246 | - bsServ.setPort(contextServer.getServerPortNoSecPsk()); | |
242 | + bsServ.setPort(contextServer.getServerPortNoSec()); | |
247 | 243 | bsServ.setServerPublicKey(""); |
248 | 244 | break; |
249 | 245 | case PSK: |
250 | - bsServ.setHost(contextServer.getServerSecureHost()); | |
251 | - bsServ.setPort(contextServer.getServerPortPsk()); | |
246 | + bsServ.setHost(contextServer.getServerHostSecurity()); | |
247 | + bsServ.setPort(contextServer.getServerPortSecurity()); | |
252 | 248 | bsServ.setServerPublicKey(""); |
253 | 249 | break; |
254 | 250 | case RPK: |
255 | - bsServ.setHost(contextServer.getServerSecureHost()); | |
256 | - bsServ.setPort(contextServer.getServerPortRpk()); | |
257 | - bsServ.setServerPublicKey(getRPKPublicKey(this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY())); | |
258 | - break; | |
259 | 251 | case X509: |
260 | - bsServ.setHost(contextServer.getServerSecureHost()); | |
261 | - bsServ.setPort(contextServer.getServerPortX509()); | |
262 | - bsServ.setServerPublicKey(getServerPublicKeyX509(contextServer.getServerAlias())); | |
252 | + bsServ.setHost(contextServer.getServerHostSecurity()); | |
253 | + bsServ.setPort(contextServer.getServerPortSecurity()); | |
254 | + bsServ.setServerPublicKey(getPublicKey (contextServer.getServerAlias(), this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY())); | |
263 | 255 | break; |
264 | 256 | default: |
265 | 257 | break; |
... | ... | @@ -268,6 +260,11 @@ public class LwM2MModelsRepository { |
268 | 260 | return bsServ; |
269 | 261 | } |
270 | 262 | |
263 | + private String getPublicKey (String alias, String publicServerX, String publicServerY) { | |
264 | + String publicKey = getServerPublicKeyX509(alias); | |
265 | + return publicKey != null ? publicKey : getRPKPublicKey(publicServerX, publicServerY); | |
266 | + } | |
267 | + | |
271 | 268 | /** |
272 | 269 | * @param alias |
273 | 270 | * @return PublicKey format HexString or null | ... | ... |
... | ... | @@ -584,7 +584,7 @@ transport: |
584 | 584 | update_registered_pool_size: "${LWM2M_UPDATE_REGISTERED_POOL_SIZE:10}" |
585 | 585 | un_registered_pool_size: "${LWM2M_UN_REGISTERED_POOL_SIZE:10}" |
586 | 586 | secure: |
587 | - # Only Certificate_x509: | |
587 | + # Certificate_x509: | |
588 | 588 | # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format |
589 | 589 | # Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh |
590 | 590 | key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}" |
... | ... | @@ -597,18 +597,11 @@ transport: |
597 | 597 | server: |
598 | 598 | id: "${LWM2M_SERVER_ID:123}" |
599 | 599 | bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" |
600 | - bind_port_no_sec_psk: "${LWM2M_BIND_PORT_NO_SEC_PSK:5685}" | |
601 | - bind_port_no_sec_rpk: "${LWM2M_BIND_PORT_NO_SEC_RPK:5687}" | |
602 | - bind_port_no_sec_x509: "${LWM2M_BIND_PORT_NO_SEC_X509:5689}" | |
600 | + bind_port_no_sec: "${LWM2M_BIND_PORT_NO_SEC:5685}" | |
603 | 601 | secure: |
604 | - bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" | |
605 | - start_psk: "${START_SERVER_PSK:true}" | |
606 | - start_rpk: "${START_SERVER_RPK:true}" | |
607 | - start_x509: "${START_SERVER_X509:true}" | |
608 | - bind_port_psk: "${LWM2M_BIND_PORT_SEC_PSK:5686}" | |
609 | - bind_port_rpk: "${LWM2M_BIND_PORT_SEC_RPK:5688}" | |
610 | - bind_port_x509: "${LWM2M_BIND_PORT_SEC_X509:5690}" | |
611 | - # Only RPK: Public & Private Key | |
602 | + bind_address_security: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}" | |
603 | + bind_port_security: "${LWM2M_BIND_PORT_SECURITY:5686}" | |
604 | + # Only for RPK: Public & Private Key. If the keystore file is missing or not working | |
612 | 605 | # create_rpk: "${CREATE_RPK:}" |
613 | 606 | public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" |
614 | 607 | public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" |
... | ... | @@ -619,18 +612,11 @@ transport: |
619 | 612 | enable: "${LWM2M_BOOTSTRAP_ENABLED:true}" |
620 | 613 | id: "${LWM2M_SERVER_ID:111}" |
621 | 614 | bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" |
622 | - bind_port_no_sec_psk: "${LWM2M_BIND_PORT_NO_SEC_BS:5691}" | |
623 | - bind_port_no_sec_rpk: "${LWM2M_BIND_PORT_NO_SEC_BS:5693}" | |
624 | - bind_port_no_sec_x509: "${LWM2M_BIND_PORT_NO_SEC_BS:5695}" | |
615 | + bind_port_no_sec: "${LWM2M_BIND_PORT_NO_SEC_BS:5687}" | |
625 | 616 | secure: |
626 | - bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" | |
627 | - start_psk: "${START_SERVER_PSK_BS:true}" | |
628 | - start_rpk: "${START_SERVER_RPK_BS:true}" | |
629 | - start_x509: "${START_SERVER_X509_BS:true}" | |
630 | - bind_port_psk: "${LWM2M_BIND_PORT_SEC_PSK_BS:5692}" | |
631 | - bind_port_rpk: "${LWM2M_BIND_PORT_SER_RPK_BS:5694}" | |
632 | - bind_port_x509: "${LWM2M_BIND_PORT_SEC_X509_BS:5696}" | |
633 | - # Only RPK: Public & Private Key | |
617 | + bind_address_security: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" | |
618 | + bind_port_security: "${LWM2M_BIND_PORT_SEC_BS:5688}" | |
619 | + # Only for RPK: Public & Private Key. If the keystore file is missing or not working | |
634 | 620 | public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" |
635 | 621 | public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" |
636 | 622 | private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" | ... | ... |
... | ... | @@ -25,20 +25,18 @@ import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuil |
25 | 25 | import org.springframework.beans.factory.annotation.Autowired; |
26 | 26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
27 | 27 | import org.springframework.context.annotation.Bean; |
28 | -import org.springframework.context.annotation.Primary; | |
29 | 28 | import org.springframework.stereotype.Component; |
30 | 29 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore; |
31 | 30 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore; |
32 | 31 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager; |
33 | -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; | |
34 | 32 | import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer; |
35 | 33 | |
36 | 34 | import java.math.BigInteger; |
37 | 35 | import java.security.AlgorithmParameters; |
38 | -import java.security.GeneralSecurityException; | |
39 | 36 | import java.security.KeyFactory; |
40 | 37 | import java.security.KeyStore; |
41 | 38 | import java.security.KeyStoreException; |
39 | +import java.security.NoSuchAlgorithmException; | |
42 | 40 | import java.security.PrivateKey; |
43 | 41 | import java.security.PublicKey; |
44 | 42 | import java.security.cert.CertificateEncodingException; |
... | ... | @@ -49,14 +47,13 @@ import java.security.spec.ECParameterSpec; |
49 | 47 | import java.security.spec.ECPoint; |
50 | 48 | import java.security.spec.ECPrivateKeySpec; |
51 | 49 | import java.security.spec.ECPublicKeySpec; |
50 | +import java.security.spec.InvalidKeySpecException; | |
51 | +import java.security.spec.InvalidParameterSpecException; | |
52 | 52 | import java.security.spec.KeySpec; |
53 | 53 | import java.util.Arrays; |
54 | 54 | |
55 | +import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; | |
55 | 56 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; |
56 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; | |
57 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.PSK; | |
58 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RPK; | |
59 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509; | |
60 | 57 | import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; |
61 | 58 | |
62 | 59 | @Slf4j |
... | ... | @@ -78,61 +75,42 @@ public class LwM2MTransportBootstrapServerConfiguration { |
78 | 75 | @Autowired |
79 | 76 | private LwM2MInMemoryBootstrapConfigStore lwM2MInMemoryBootstrapConfigStore; |
80 | 77 | |
81 | - @Primary | |
82 | - @Bean(name = "leshanBootstrapX509") | |
83 | - @ConditionalOnExpression("('${transport.lwm2m.bootstrap.secure.start_x509:false}'=='true')") | |
84 | - public LeshanBootstrapServer getLeshanBootstrapServerX509() { | |
85 | - log.info("Prepare and start BootstrapServerX509... PostConstruct"); | |
86 | - return getLeshanBootstrapServer(this.contextBs.getCtxBootStrap().getBootstrapPortNoSecX509(), this.contextBs.getCtxBootStrap().getBootstrapSecurePortX509(), X509); | |
87 | - } | |
88 | - | |
89 | - @Bean(name = "leshanBootstrapPsk") | |
90 | - @ConditionalOnExpression("('${transport.lwm2m.bootstrap.secure.start_psk:false}'=='true')") | |
91 | - public LeshanBootstrapServer getLeshanBootstrapServerPsk() { | |
92 | - log.info("Prepare and start BootstrapServerRsk... PostConstruct"); | |
93 | - return getLeshanBootstrapServer(this.contextBs.getCtxBootStrap().getBootstrapPortNoSecPsk(), this.contextBs.getCtxBootStrap().getBootstrapSecurePortPsk(), PSK); | |
94 | - } | |
95 | 78 | |
96 | - @Bean(name = "leshanBootstrapRpk") | |
97 | - @ConditionalOnExpression("('${transport.lwm2m.bootstrap.secure.start_rpk:false}'=='true')") | |
98 | - public LeshanBootstrapServer getLeshanBootstrapServerRpk() { | |
99 | - log.info("Prepare and start BootstrapServerRpk... PostConstruct"); | |
100 | - return getLeshanBootstrapServer(this.contextBs.getCtxBootStrap().getBootstrapPortNoSecRpk(), this.contextBs.getCtxBootStrap().getBootstrapSecurePortRpk(), RPK); | |
79 | + @Bean | |
80 | + public LeshanBootstrapServer getLeshanBootstrapServer() { | |
81 | + log.info("Prepare and start BootstrapServer... PostConstruct"); | |
82 | + return this.getLhBootstrapServer(this.contextBs.getCtxBootStrap().getBootstrapPortNoSec(), this.contextBs.getCtxBootStrap().getBootstrapPortSecurity()); | |
101 | 83 | } |
102 | 84 | |
103 | - public LeshanBootstrapServer getLeshanBootstrapServer(Integer bootstrapPortNoSec, Integer bootstrapSecurePort, LwM2MSecurityMode dtlsMode) { | |
85 | + public LeshanBootstrapServer getLhBootstrapServer(Integer bootstrapPortNoSec, Integer bootstrapSecurePort) { | |
104 | 86 | LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder(); |
105 | 87 | builder.setLocalAddress(this.contextBs.getCtxBootStrap().getBootstrapHost(), bootstrapPortNoSec); |
106 | - builder.setLocalSecureAddress(this.contextBs.getCtxBootStrap().getBootstrapSecureHost(), bootstrapSecurePort); | |
88 | + builder.setLocalSecureAddress(this.contextBs.getCtxBootStrap().getBootstrapHostSecurity(), bootstrapSecurePort); | |
107 | 89 | |
108 | 90 | /** Create CoAP Config */ |
109 | - builder.setCoapConfig(getCoapConfig (bootstrapPortNoSec, bootstrapSecurePort)); | |
91 | + builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort)); | |
92 | + | |
93 | + /** Define model provider (Create Models )*/ | |
94 | + builder.setModel(new StaticModel(contextS.getCtxServer().getModelsValue())); | |
95 | + | |
96 | + /** Create credentials */ | |
97 | + this.setServerWithCredentials(builder); | |
110 | 98 | |
111 | - /** ConfigStore */ | |
99 | + /** Set securityStore with new ConfigStore */ | |
112 | 100 | builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore); |
113 | 101 | |
114 | 102 | /** SecurityStore */ |
115 | 103 | builder.setSecurityStore(lwM2MBootstrapSecurityStore); |
116 | 104 | |
117 | - /** Define model provider (Create Models )*/ | |
118 | - builder.setModel(new StaticModel(contextS.getCtxServer().getModelsValue())); | |
119 | - | |
120 | - /** Create credentials */ | |
121 | - LwM2MSetSecurityStoreBootstrap(builder, dtlsMode); | |
122 | 105 | |
123 | 106 | /** Create and Set DTLS Config */ |
124 | 107 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); |
125 | - if (dtlsMode==PSK) { | |
126 | - dtlsConfig.setRecommendedCipherSuitesOnly(this.contextS.getCtxServer().isRecommendedCiphers()); | |
127 | - dtlsConfig.setRecommendedSupportedGroupsOnly(this.contextS.getCtxServer().isRecommendedSupportedGroups()); | |
128 | - dtlsConfig.setSupportedCipherSuites(TLS_PSK_WITH_AES_128_CBC_SHA256); | |
129 | - } | |
130 | - else { | |
131 | - dtlsConfig.setRecommendedCipherSuitesOnly(this.contextS.getCtxServer().isRecommendedCiphers()); | |
132 | -// dtlsConfig.setRecommendedSupportedGroupsOnly(false); | |
133 | - } | |
134 | - builder.setDtlsConfig(dtlsConfig); | |
108 | + dtlsConfig.setRecommendedSupportedGroupsOnly(!this.contextS.getCtxServer().isRecommendedSupportedGroups()); | |
109 | + dtlsConfig.setRecommendedCipherSuitesOnly(this.contextS.getCtxServer().isRecommendedCiphers()); | |
110 | + dtlsConfig.setSupportedCipherSuites(TLS_PSK_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256); | |
135 | 111 | |
112 | + /** Set DTLS Config */ | |
113 | + builder.setDtlsConfig(dtlsConfig); | |
136 | 114 | |
137 | 115 | BootstrapSessionManager sessionManager = new LwM2mDefaultBootstrapSessionManager(lwM2MBootstrapSecurityStore); |
138 | 116 | builder.setSessionManager(sessionManager); |
... | ... | @@ -141,150 +119,153 @@ public class LwM2MTransportBootstrapServerConfiguration { |
141 | 119 | return builder.build(); |
142 | 120 | } |
143 | 121 | |
144 | - public void LwM2MSetSecurityStoreBootstrap(LeshanBootstrapServerBuilder builder, LwM2MSecurityMode dtlsMode) { | |
145 | - | |
146 | - /** Set securityStore with new registrationStore */ | |
147 | - | |
148 | - switch (dtlsMode) { | |
149 | - /** Use No_Sec only */ | |
150 | - case NO_SEC: | |
151 | - setServerWithX509Cert(builder, NO_SEC.code); | |
152 | - break; | |
153 | - /** Use PSK/RPK */ | |
154 | - case PSK: | |
155 | - break; | |
156 | - case RPK: | |
157 | - setRPK(builder); | |
158 | - break; | |
159 | - case X509: | |
160 | - setServerWithX509Cert(builder, X509.code); | |
161 | - break; | |
162 | - /** Use X509_EST only */ | |
163 | - case X509_EST: | |
164 | - // TODO support sentinel pool and make pool configurable | |
165 | - break; | |
166 | - /** Use ather X509, PSK, No_Sec ?? */ | |
167 | - default: | |
168 | - break; | |
169 | - } | |
170 | - } | |
171 | - | |
172 | - private void setRPK(LeshanBootstrapServerBuilder builder) { | |
173 | - try { | |
174 | - /** Get Elliptic Curve Parameter spec for secp256r1 */ | |
175 | - AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); | |
176 | - algoParameters.init(new ECGenParameterSpec("secp256r1")); | |
177 | - ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); | |
178 | - if (this.contextBs.getCtxBootStrap().getBootstrapPublicX() != null && !this.contextBs.getCtxBootStrap().getBootstrapPublicX().isEmpty() && this.contextBs.getCtxBootStrap().getBootstrapPublicY() != null && !this.contextBs.getCtxBootStrap().getBootstrapPublicY().isEmpty()) { | |
179 | - /** Get point values */ | |
180 | - byte[] publicX = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPublicX().toCharArray()); | |
181 | - byte[] publicY = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPublicY().toCharArray()); | |
182 | - /** Create key specs */ | |
183 | - KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), | |
184 | - parameterSpec); | |
185 | - /** Get keys */ | |
186 | - this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); | |
187 | - } | |
188 | - if (this.contextBs.getCtxBootStrap().getBootstrapPrivateS() != null && !this.contextBs.getCtxBootStrap().getBootstrapPrivateS().isEmpty()) { | |
189 | - /** Get point values */ | |
190 | - byte[] privateS = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPrivateS().toCharArray()); | |
191 | - /** Create key specs */ | |
192 | - KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec); | |
193 | - /** Get keys */ | |
194 | - this.privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec); | |
195 | - } | |
196 | - if (this.publicKey != null && this.publicKey.getEncoded().length > 0 && | |
197 | - this.privateKey != null && this.privateKey.getEncoded().length > 0) { | |
198 | - builder.setPublicKey(this.publicKey); | |
199 | - builder.setPrivateKey(this.privateKey); | |
200 | - this.contextBs.getCtxBootStrap().setBootstrapPublicKey(this.publicKey); | |
201 | - getParamsRPK(); | |
202 | - } | |
203 | - } catch (GeneralSecurityException | IllegalArgumentException e) { | |
204 | - log.error("[{}] Failed generate Server PSK/RPK", e.getMessage()); | |
205 | - throw new RuntimeException(e); | |
206 | - } | |
207 | - } | |
208 | - | |
209 | - private void setServerWithX509Cert(LeshanBootstrapServerBuilder builder, int securityModeCode) { | |
122 | + private void setServerWithCredentials(LeshanBootstrapServerBuilder builder) { | |
210 | 123 | try { |
211 | 124 | if (this.contextS.getCtxServer().getKeyStoreValue() != null) { |
212 | 125 | KeyStore keyStoreServer = this.contextS.getCtxServer().getKeyStoreValue(); |
213 | - setBuilderX509(builder); | |
214 | - X509Certificate rootCAX509Cert = (X509Certificate) keyStoreServer.getCertificate(this.contextS.getCtxServer().getRootAlias()); | |
215 | - if (rootCAX509Cert != null && securityModeCode == X509.code) { | |
216 | - X509Certificate[] trustedCertificates = new X509Certificate[1]; | |
217 | - trustedCertificates[0] = rootCAX509Cert; | |
218 | - builder.setTrustedCertificates(trustedCertificates); | |
126 | + if (this.setBuilderX509(builder)) { | |
127 | + X509Certificate rootCAX509Cert = (X509Certificate) keyStoreServer.getCertificate(this.contextS.getCtxServer().getRootAlias()); | |
128 | + if (rootCAX509Cert != null) { | |
129 | + X509Certificate[] trustedCertificates = new X509Certificate[1]; | |
130 | + trustedCertificates[0] = rootCAX509Cert; | |
131 | + builder.setTrustedCertificates(trustedCertificates); | |
132 | + } else { | |
133 | + /** by default trust all */ | |
134 | + builder.setTrustedCertificates(new X509Certificate[0]); | |
135 | + } | |
136 | + } else if (this.setServerRPK(builder)) { | |
137 | + this.infoParamsServerRPK(); | |
219 | 138 | } else { |
220 | 139 | /** by default trust all */ |
221 | 140 | builder.setTrustedCertificates(new X509Certificate[0]); |
141 | + log.info("Unable to load X509 files for BootStrapServer"); | |
142 | + this.infoParamsServerPSK(); | |
222 | 143 | } |
223 | 144 | } |
224 | - else { | |
225 | - /** by default trust all */ | |
226 | - builder.setTrustedCertificates(new X509Certificate[0]); | |
227 | - log.error("Unable to load X509 files for BootStrapServer"); | |
228 | - } | |
229 | 145 | } catch (KeyStoreException ex) { |
230 | 146 | log.error("[{}] Unable to load X509 files server", ex.getMessage()); |
231 | 147 | } |
232 | - | |
233 | 148 | } |
234 | 149 | |
235 | - private void setBuilderX509(LeshanBootstrapServerBuilder builder) { | |
150 | + private boolean setBuilderX509(LeshanBootstrapServerBuilder builder) { | |
236 | 151 | /** |
237 | 152 | * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE |
238 | 153 | * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks |
239 | 154 | */ |
240 | 155 | try { |
241 | 156 | X509Certificate serverCertificate = (X509Certificate) this.contextS.getCtxServer().getKeyStoreValue().getCertificate(this.contextBs.getCtxBootStrap().getBootstrapAlias()); |
242 | - this.privateKey = (PrivateKey) this.contextS.getCtxServer().getKeyStoreValue().getKey(this.contextBs.getCtxBootStrap().getBootstrapAlias(), this.contextS.getCtxServer().getKeyStorePasswordServer() == null ? null : this.contextS.getCtxServer().getKeyStorePasswordServer().toCharArray()); | |
243 | - if (this.privateKey != null && this.privateKey.getEncoded().length > 0) { | |
244 | - builder.setPrivateKey(this.privateKey); | |
245 | - } | |
246 | - if (serverCertificate != null) { | |
157 | + PrivateKey privateKey = (PrivateKey) this.contextS.getCtxServer().getKeyStoreValue().getKey(this.contextBs.getCtxBootStrap().getBootstrapAlias(), this.contextS.getCtxServer().getKeyStorePasswordServer() == null ? null : this.contextS.getCtxServer().getKeyStorePasswordServer().toCharArray()); | |
158 | + PublicKey publicKey = serverCertificate.getPublicKey(); | |
159 | + if (serverCertificate != null && | |
160 | + privateKey != null && privateKey.getEncoded().length > 0 && | |
161 | + publicKey != null && publicKey.getEncoded().length > 0) { | |
162 | + builder.setPublicKey(serverCertificate.getPublicKey()); | |
163 | + builder.setPrivateKey(privateKey); | |
247 | 164 | builder.setCertificateChain(new X509Certificate[]{serverCertificate}); |
248 | - this.infoParamsX509(serverCertificate); | |
165 | + this.infoParamsServerX509(serverCertificate, publicKey, privateKey); | |
166 | + return true; | |
167 | + } else { | |
168 | + return false; | |
249 | 169 | } |
250 | 170 | } catch (Exception ex) { |
251 | 171 | log.error("[{}] Unable to load KeyStore files server", ex.getMessage()); |
172 | + return false; | |
252 | 173 | } |
253 | 174 | } |
254 | 175 | |
255 | - private void getParamsRPK() { | |
256 | - if (this.publicKey instanceof ECPublicKey) { | |
257 | - /** Get x coordinate */ | |
258 | - byte[] x = ((ECPublicKey) this.publicKey).getW().getAffineX().toByteArray(); | |
259 | - if (x[0] == 0) | |
260 | - x = Arrays.copyOfRange(x, 1, x.length); | |
261 | - | |
262 | - /** Get Y coordinate */ | |
263 | - byte[] y = ((ECPublicKey) this.publicKey).getW().getAffineY().toByteArray(); | |
264 | - if (y[0] == 0) | |
265 | - y = Arrays.copyOfRange(y, 1, y.length); | |
266 | - | |
267 | - /** Get Curves params */ | |
268 | - String params = ((ECPublicKey) this.publicKey).getParams().toString(); | |
269 | - log.info( | |
270 | - " \nBootstrap uses RPK : \n Elliptic Curve parameters : [{}] \n Public x coord : [{}] \n Public y coord : [{}] \n Public Key (Hex): [{}] \n Private Key (Hex): [{}]", | |
271 | - params, Hex.encodeHexString(x), Hex.encodeHexString(y), | |
272 | - Hex.encodeHexString(this.publicKey.getEncoded()), | |
273 | - Hex.encodeHexString(this.privateKey.getEncoded())); | |
274 | - } else { | |
275 | - throw new IllegalStateException("Unsupported Public Key Format (only ECPublicKey supported)."); | |
276 | - } | |
277 | - } | |
278 | - | |
279 | - private void infoParamsX509(X509Certificate certificate) { | |
176 | + private void infoParamsServerX509(X509Certificate certificate, PublicKey publicKey, PrivateKey privateKey) { | |
280 | 177 | try { |
281 | - log.info("BootStrap uses X509 : \n X509 Certificate (Hex): [{}] \n Private Key (Hex): [{}]", | |
178 | + log.info("Bootstrap Server uses X509 : \n X509 Certificate (Hex): [{}] \n Public Key (Hex): [{}] \n Private Key (Hex): [{}]", | |
282 | 179 | Hex.encodeHexString(certificate.getEncoded()), |
283 | - Hex.encodeHexString(this.privateKey.getEncoded())); | |
180 | + Hex.encodeHexString(publicKey.getEncoded()), | |
181 | + Hex.encodeHexString(privateKey.getEncoded())); | |
284 | 182 | } catch (CertificateEncodingException e) { |
285 | 183 | log.error("", e); |
286 | 184 | } |
287 | 185 | } |
288 | 186 | |
187 | + private boolean setServerRPK(LeshanBootstrapServerBuilder builder) { | |
188 | + try { | |
189 | + this.generateKeyForBootstrapRPK(); | |
190 | + if (this.publicKey != null && this.publicKey.getEncoded().length > 0 && | |
191 | + this.privateKey != null && this.privateKey.getEncoded().length > 0) { | |
192 | + builder.setPublicKey(this.publicKey); | |
193 | + builder.setPrivateKey(this.privateKey); | |
194 | + return true; | |
195 | + } | |
196 | + } catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) { | |
197 | + log.error("Fail create Bootstrap Server with RPK", e); | |
198 | + } | |
199 | + return false; | |
200 | + } | |
201 | + | |
202 | + | |
203 | + /** | |
204 | + * From yml^ bootstrap | |
205 | + * public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" | |
206 | + * public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" | |
207 | + * private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" | |
208 | + */ | |
209 | + private void generateKeyForBootstrapRPK() throws NoSuchAlgorithmException, InvalidParameterSpecException, InvalidKeySpecException { | |
210 | + /** Get Elliptic Curve Parameter spec for secp256r1 */ | |
211 | + AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); | |
212 | + algoParameters.init(new ECGenParameterSpec("secp256r1")); | |
213 | + ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); | |
214 | + if (this.contextBs.getCtxBootStrap().getBootstrapPublicX() != null && !this.contextBs.getCtxBootStrap().getBootstrapPublicX().isEmpty() && this.contextBs.getCtxBootStrap().getBootstrapPublicY() != null && !this.contextBs.getCtxBootStrap().getBootstrapPublicY().isEmpty()) { | |
215 | + /** Get point values */ | |
216 | + byte[] publicX = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPublicX().toCharArray()); | |
217 | + byte[] publicY = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPublicY().toCharArray()); | |
218 | + /** Create key specs */ | |
219 | + KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), | |
220 | + parameterSpec); | |
221 | + /** Get keys */ | |
222 | + this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); | |
223 | + } | |
224 | + if (this.contextBs.getCtxBootStrap().getBootstrapPrivateS() != null && !this.contextBs.getCtxBootStrap().getBootstrapPrivateS().isEmpty()) { | |
225 | + /** Get point values */ | |
226 | + byte[] privateS = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPrivateS().toCharArray()); | |
227 | + /** Create key specs */ | |
228 | + KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec); | |
229 | + /** Get keys */ | |
230 | + this.privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec); | |
231 | + } | |
232 | + } | |
233 | + | |
234 | + private void infoParamsServerRPK() { | |
235 | + /** Get x coordinate */ | |
236 | + byte[] x = ((ECPublicKey) this.publicKey).getW().getAffineX().toByteArray(); | |
237 | + if (x[0] == 0) | |
238 | + x = Arrays.copyOfRange(x, 1, x.length); | |
239 | + | |
240 | + /** Get Y coordinate */ | |
241 | + byte[] y = ((ECPublicKey) this.publicKey).getW().getAffineY().toByteArray(); | |
242 | + if (y[0] == 0) | |
243 | + y = Arrays.copyOfRange(y, 1, y.length); | |
244 | + | |
245 | + /** Get Curves params */ | |
246 | + String params = ((ECPublicKey) this.publicKey).getParams().toString(); | |
247 | + String privHex = Hex.encodeHexString(this.privateKey.getEncoded()); | |
248 | + log.info("Server uses RPK -> serverNoSecureURI : [{}], serverSecureURI : [{}], \n" + | |
249 | + "Public Key (Hex): [{}] \n" + | |
250 | + "Private Key (Hex): [{}], \n" + | |
251 | + "- public_x : [{}] \n" + | |
252 | + "- public_y : [{}] \n" + | |
253 | + "- private_s : [{}] \n" + | |
254 | + "- Elliptic Curve parameters : [{}]", | |
255 | + this.contextBs.getCtxBootStrap().getBootstrapHost() + ":" + this.contextBs.getCtxBootStrap().getBootstrapPortNoSec(), | |
256 | + this.contextBs.getCtxBootStrap().getBootstrapHostSecurity() + ":" + this.contextBs.getCtxBootStrap().getBootstrapPortSecurity(), | |
257 | + Hex.encodeHexString(this.publicKey.getEncoded()), | |
258 | + Hex.encodeHexString(this.privateKey.getEncoded()), | |
259 | + Hex.encodeHexString(x), | |
260 | + Hex.encodeHexString(y), | |
261 | + privHex.substring(privHex.length() - 64), | |
262 | + params); | |
263 | + } | |
264 | + | |
265 | + private void infoParamsServerPSK() { | |
266 | + log.info("Server uses PSK -> serverNoSecureURI : [{}], serverSecureURI : [{}]", | |
267 | + this.contextBs.getCtxBootStrap().getBootstrapHost() + ":" + this.contextBs.getCtxBootStrap().getBootstrapPortNoSec(), | |
268 | + this.contextBs.getCtxBootStrap().getBootstrapHostSecurity() + ":" + this.contextBs.getCtxBootStrap().getBootstrapPortSecurity()); | |
269 | + } | |
289 | 270 | |
290 | 271 | } | ... | ... |
... | ... | @@ -18,7 +18,6 @@ package org.thingsboard.server.transport.lwm2m.bootstrap; |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | 19 | import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer; |
20 | 20 | import org.springframework.beans.factory.annotation.Autowired; |
21 | -import org.springframework.beans.factory.annotation.Qualifier; | |
22 | 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
23 | 22 | import org.springframework.stereotype.Service; |
24 | 23 | |
... | ... | @@ -31,39 +30,20 @@ import javax.annotation.PreDestroy; |
31 | 30 | public class LwM2MTransportBootstrapServerInitializer { |
32 | 31 | |
33 | 32 | @Autowired(required = false) |
34 | - @Qualifier("leshanBootstrapX509") | |
35 | - private LeshanBootstrapServer lhBServerCert; | |
36 | - | |
37 | - @Autowired(required = false) | |
38 | - @Qualifier("leshanBootstrapPsk") | |
39 | - private LeshanBootstrapServer lhBServerPsk; | |
40 | - | |
41 | - @Autowired(required = false) | |
42 | - @Qualifier("leshanBootstrapRpk") | |
43 | - private LeshanBootstrapServer lhBServerRpk; | |
33 | + private LeshanBootstrapServer lhBServer; | |
44 | 34 | |
45 | 35 | @Autowired |
46 | 36 | private LwM2MTransportContextBootstrap contextBS; |
47 | 37 | |
48 | 38 | @PostConstruct |
49 | 39 | public void init() { |
50 | - if (this.contextBS.getCtxBootStrap().getBootstrapStartPsk()) { | |
51 | - this.lhBServerPsk.start(); | |
52 | - } | |
53 | - if (this.contextBS.getCtxBootStrap().getBootstrapStartRpk()) { | |
54 | - this.lhBServerRpk.start(); | |
55 | - } | |
56 | - if (this.contextBS.getCtxBootStrap().getBootstrapStartX509()) { | |
57 | - this.lhBServerCert.start(); | |
58 | - } | |
40 | + this.lhBServer.start(); | |
59 | 41 | } |
60 | 42 | |
61 | 43 | @PreDestroy |
62 | 44 | public void shutdown() throws InterruptedException { |
63 | 45 | log.info("Stopping LwM2M transport Bootstrap Server!"); |
64 | - lhBServerPsk.destroy(); | |
65 | - lhBServerRpk.destroy(); | |
66 | - lhBServerCert.destroy(); | |
46 | + lhBServer.destroy(); | |
67 | 47 | log.info("LwM2M transport Bootstrap Server stopped!"); |
68 | 48 | } |
69 | 49 | } | ... | ... |
... | ... | @@ -25,31 +25,20 @@ import org.eclipse.leshan.server.californium.LeshanServer; |
25 | 25 | import org.eclipse.leshan.server.californium.LeshanServerBuilder; |
26 | 26 | import org.eclipse.leshan.server.model.LwM2mModelProvider; |
27 | 27 | import org.eclipse.leshan.server.model.VersionedModelProvider; |
28 | -import org.eclipse.leshan.server.redis.RedisRegistrationStore; | |
29 | -import org.eclipse.leshan.server.redis.RedisSecurityStore; | |
30 | 28 | import org.eclipse.leshan.server.security.DefaultAuthorizer; |
31 | -import org.eclipse.leshan.server.security.EditableSecurityStore; | |
32 | 29 | import org.eclipse.leshan.server.security.SecurityChecker; |
33 | 30 | import org.springframework.beans.factory.annotation.Autowired; |
34 | 31 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
35 | 32 | import org.springframework.context.annotation.Bean; |
36 | -import org.springframework.context.annotation.ComponentScan; | |
37 | -import org.springframework.context.annotation.Configuration; | |
38 | -import org.springframework.context.annotation.Primary; | |
39 | -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; | |
33 | +import org.springframework.stereotype.Component; | |
40 | 34 | import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore; |
41 | 35 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
42 | -import redis.clients.jedis.Jedis; | |
43 | -import redis.clients.jedis.JedisPool; | |
44 | -import redis.clients.jedis.util.Pool; | |
45 | 36 | |
46 | 37 | import java.math.BigInteger; |
47 | -import java.net.URI; | |
48 | -import java.net.URISyntaxException; | |
49 | 38 | import java.security.AlgorithmParameters; |
50 | -import java.security.GeneralSecurityException; | |
51 | 39 | import java.security.KeyFactory; |
52 | 40 | import java.security.KeyStoreException; |
41 | +import java.security.NoSuchAlgorithmException; | |
53 | 42 | import java.security.PrivateKey; |
54 | 43 | import java.security.PublicKey; |
55 | 44 | import java.security.cert.CertificateEncodingException; |
... | ... | @@ -60,20 +49,17 @@ import java.security.spec.ECParameterSpec; |
60 | 49 | import java.security.spec.ECPoint; |
61 | 50 | import java.security.spec.ECPrivateKeySpec; |
62 | 51 | import java.security.spec.ECPublicKeySpec; |
52 | +import java.security.spec.InvalidKeySpecException; | |
53 | +import java.security.spec.InvalidParameterSpecException; | |
63 | 54 | import java.security.spec.KeySpec; |
64 | 55 | import java.util.Arrays; |
65 | 56 | |
57 | +import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; | |
66 | 58 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; |
67 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.PSK; | |
68 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RPK; | |
69 | -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509; | |
70 | 59 | import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; |
71 | 60 | |
72 | - | |
73 | 61 | @Slf4j |
74 | -@ComponentScan("org.thingsboard.server.transport.lwm2m.server") | |
75 | -@ComponentScan("org.thingsboard.server.transport.lwm2m.utils") | |
76 | -@Configuration("LwM2MTransportServerConfiguration") | |
62 | +@Component("LwM2MTransportServerConfiguration") | |
77 | 63 | @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") |
78 | 64 | public class LwM2MTransportServerConfiguration { |
79 | 65 | private PublicKey publicKey; |
... | ... | @@ -85,32 +71,16 @@ public class LwM2MTransportServerConfiguration { |
85 | 71 | @Autowired |
86 | 72 | private LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore; |
87 | 73 | |
88 | - @Primary | |
89 | - @Bean(name = "leshanServerPsk") | |
90 | - @ConditionalOnExpression("('${transport.lwm2m.server.secure.start_psk:false}'=='true')") | |
91 | - public LeshanServer getLeshanServerPsk() { | |
92 | - log.info("Starting LwM2M transport ServerPsk... PostConstruct"); | |
93 | - return getLeshanServer(this.context.getCtxServer().getServerPortNoSecPsk(), this.context.getCtxServer().getServerPortPsk(), PSK); | |
94 | - } | |
95 | - | |
96 | - @Bean(name = "leshanServerRpk") | |
97 | - @ConditionalOnExpression("('${transport.lwm2m.server.secure.start_rpk:false}'=='true')") | |
98 | - public LeshanServer getLeshanServerRpk() { | |
99 | - log.info("Starting LwM2M transport ServerRpk... PostConstruct"); | |
100 | - return getLeshanServer(this.context.getCtxServer().getServerPortNoSecRpk(), this.context.getCtxServer().getServerPortRpk(), RPK); | |
101 | - } | |
102 | - | |
103 | - @Bean(name = "leshanServerX509") | |
104 | - @ConditionalOnExpression("('${transport.lwm2m.server.secure.start_x509:false}'=='true')") | |
105 | - public LeshanServer getLeshanServerX509() { | |
106 | - log.info("Starting LwM2M transport ServerX509... PostConstruct"); | |
107 | - return getLeshanServer(this.context.getCtxServer().getServerPortNoSecX509(), this.context.getCtxServer().getServerPortX509(), X509); | |
74 | + @Bean | |
75 | + public LeshanServer getLeshanServer() { | |
76 | + log.info("Starting LwM2M transport Server... PostConstruct"); | |
77 | + return this.getLhServer(this.context.getCtxServer().getServerPortNoSec(), this.context.getCtxServer().getServerPortSecurity()); | |
108 | 78 | } |
109 | 79 | |
110 | - private LeshanServer getLeshanServer(Integer serverPortNoSec, Integer serverSecurePort, LwM2MSecurityMode dtlsMode) { | |
80 | + private LeshanServer getLhServer(Integer serverPortNoSec, Integer serverSecurePort) { | |
111 | 81 | LeshanServerBuilder builder = new LeshanServerBuilder(); |
112 | 82 | builder.setLocalAddress(this.context.getCtxServer().getServerHost(), serverPortNoSec); |
113 | - builder.setLocalSecureAddress(this.context.getCtxServer().getServerSecureHost(), serverSecurePort); | |
83 | + builder.setLocalSecureAddress(this.context.getCtxServer().getServerHostSecurity(), serverSecurePort); | |
114 | 84 | builder.setEncoder(new DefaultLwM2mNodeEncoder()); |
115 | 85 | LwM2mNodeDecoder decoder = new DefaultLwM2mNodeDecoder(); |
116 | 86 | builder.setDecoder(decoder); |
... | ... | @@ -123,22 +93,19 @@ public class LwM2MTransportServerConfiguration { |
123 | 93 | LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getCtxServer().getModelsValue()); |
124 | 94 | builder.setObjectModelProvider(modelProvider); |
125 | 95 | |
126 | - /** Create DTLS security mode | |
127 | - * There can be only one DTLS security mode | |
128 | - */ | |
129 | - this.LwM2MSetSecurityStoreServer(builder, dtlsMode); | |
96 | + /** Create credentials */ | |
97 | + this.setServerWithCredentials(builder); | |
98 | + | |
99 | + /** Set securityStore with new registrationStore */ | |
100 | + builder.setSecurityStore(lwM2mInMemorySecurityStore); | |
101 | + | |
130 | 102 | |
131 | 103 | /** Create DTLS Config */ |
132 | 104 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); |
133 | - if (dtlsMode==PSK) { | |
134 | - dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getCtxServer().isRecommendedCiphers()); | |
135 | - dtlsConfig.setRecommendedSupportedGroupsOnly(this.context.getCtxServer().isRecommendedSupportedGroups()); | |
136 | - dtlsConfig.setSupportedCipherSuites(TLS_PSK_WITH_AES_128_CBC_SHA256); | |
137 | - } | |
138 | - else { | |
139 | - dtlsConfig.setRecommendedSupportedGroupsOnly(!this.context.getCtxServer().isRecommendedSupportedGroups()); | |
140 | - dtlsConfig.setRecommendedCipherSuitesOnly(!this.context.getCtxServer().isRecommendedCiphers()); | |
141 | - } | |
105 | + dtlsConfig.setRecommendedSupportedGroupsOnly(!this.context.getCtxServer().isRecommendedSupportedGroups()); | |
106 | + dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getCtxServer().isRecommendedCiphers()); | |
107 | + dtlsConfig.setSupportedCipherSuites(TLS_PSK_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256); | |
108 | + | |
142 | 109 | /** Set DTLS Config */ |
143 | 110 | builder.setDtlsConfig(dtlsConfig); |
144 | 111 | |
... | ... | @@ -150,154 +117,42 @@ public class LwM2MTransportServerConfiguration { |
150 | 117 | return builder.build(); |
151 | 118 | } |
152 | 119 | |
153 | - private void LwM2MSetSecurityStoreServer(LeshanServerBuilder builder, LwM2MSecurityMode dtlsMode) { | |
154 | - /** Set securityStore with new registrationStore */ | |
155 | - EditableSecurityStore securityStore = lwM2mInMemorySecurityStore; | |
156 | - switch (dtlsMode) { | |
157 | - /** Use PSK only */ | |
158 | - case PSK: | |
159 | - generatePSK_RPK(); | |
160 | - infoParamsPSK(); | |
161 | - break; | |
162 | - /** Use RPK only */ | |
163 | - case RPK: | |
164 | - generatePSK_RPK(); | |
165 | - if (this.publicKey != null && this.publicKey.getEncoded().length > 0 && | |
166 | - this.privateKey != null && this.privateKey.getEncoded().length > 0) { | |
167 | - builder.setPublicKey(this.publicKey); | |
168 | - builder.setPrivateKey(this.privateKey); | |
169 | - infoParamsRPK(); | |
170 | - } | |
171 | - break; | |
172 | - /** Use x509 only */ | |
173 | - case X509: | |
174 | - setServerWithX509Cert(builder); | |
175 | - break; | |
176 | - /** No security */ | |
177 | - case NO_SEC: | |
178 | - builder.setTrustedCertificates(new X509Certificate[0]); | |
179 | - break; | |
180 | - /** Use x509 with EST */ | |
181 | - case X509_EST: | |
182 | - // TODO support sentinel pool and make pool configurable | |
183 | - break; | |
184 | - case REDIS: | |
185 | - /** | |
186 | - * Set securityStore with new registrationStore (if use redis store) | |
187 | - * Connect to redis | |
188 | - */ | |
189 | - Pool<Jedis> jedis = null; | |
190 | - try { | |
191 | - jedis = new JedisPool(new URI(this.context.getCtxServer().getRedisUrl())); | |
192 | - securityStore = new RedisSecurityStore(jedis); | |
193 | - builder.setRegistrationStore(new RedisRegistrationStore(jedis)); | |
194 | - } catch (URISyntaxException e) { | |
195 | - log.error("", e); | |
196 | - } | |
197 | - break; | |
198 | - default: | |
199 | - } | |
200 | - | |
201 | - /** Set securityStore with registrationStore (if x509)*/ | |
202 | - if (dtlsMode == X509) { | |
203 | - builder.setAuthorizer(new DefaultAuthorizer(securityStore, new SecurityChecker() { | |
204 | - @Override | |
205 | - protected boolean matchX509Identity(String endpoint, String receivedX509CommonName, | |
206 | - String expectedX509CommonName) { | |
207 | - return endpoint.startsWith(expectedX509CommonName); | |
208 | - } | |
209 | - })); | |
210 | - } | |
211 | - | |
212 | - /** Set securityStore with new registrationStore */ | |
213 | - builder.setSecurityStore(securityStore); | |
214 | - } | |
215 | - | |
216 | - private void generatePSK_RPK() { | |
217 | - try { | |
218 | - /** Get Elliptic Curve Parameter spec for secp256r1 */ | |
219 | - AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); | |
220 | - algoParameters.init(new ECGenParameterSpec("secp256r1")); | |
221 | - ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); | |
222 | - if (this.context.getCtxServer().getServerPublicX() != null && !this.context.getCtxServer().getServerPublicX().isEmpty() && this.context.getCtxServer().getServerPublicY() != null && !this.context.getCtxServer().getServerPublicY().isEmpty()) { | |
223 | - /** Get point values */ | |
224 | - byte[] publicX = Hex.decodeHex(this.context.getCtxServer().getServerPublicX().toCharArray()); | |
225 | - byte[] publicY = Hex.decodeHex(this.context.getCtxServer().getServerPublicY().toCharArray()); | |
226 | - /** Create key specs */ | |
227 | - KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), | |
228 | - parameterSpec); | |
229 | - /** Get keys */ | |
230 | - this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); | |
231 | - } | |
232 | - if (this.context.getCtxServer().getServerPrivateS() != null && !this.context.getCtxServer().getServerPrivateS().isEmpty()) { | |
233 | - /** Get point values */ | |
234 | - byte[] privateS = Hex.decodeHex(this.context.getCtxServer().getServerPrivateS().toCharArray()); | |
235 | - /** Create key specs */ | |
236 | - KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec); | |
237 | - /** Get keys */ | |
238 | - this.privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec); | |
239 | - } | |
240 | - } catch (GeneralSecurityException | IllegalArgumentException e) { | |
241 | - log.error("[{}] Failed generate Server PSK/RPK", e.getMessage()); | |
242 | - throw new RuntimeException(e); | |
243 | - } | |
244 | - } | |
245 | - | |
246 | - private void infoParamsPSK() { | |
247 | - log.info("\nServer uses PSK -> private key : \n security key : [{}] \n serverSecureURI : [{}]", | |
248 | - Hex.encodeHexString(this.privateKey.getEncoded()), | |
249 | - this.context.getCtxServer().getServerSecureHost() + ":" + Integer.toString(this.context.getCtxServer().getServerPortPsk())); | |
250 | - } | |
251 | - | |
252 | - private void infoParamsRPK() { | |
253 | - if (this.publicKey instanceof ECPublicKey) { | |
254 | - /** Get x coordinate */ | |
255 | - byte[] x = ((ECPublicKey) this.publicKey).getW().getAffineX().toByteArray(); | |
256 | - if (x[0] == 0) | |
257 | - x = Arrays.copyOfRange(x, 1, x.length); | |
258 | - | |
259 | - /** Get Y coordinate */ | |
260 | - byte[] y = ((ECPublicKey) this.publicKey).getW().getAffineY().toByteArray(); | |
261 | - if (y[0] == 0) | |
262 | - y = Arrays.copyOfRange(y, 1, y.length); | |
263 | - | |
264 | - /** Get Curves params */ | |
265 | - String params = ((ECPublicKey) this.publicKey).getParams().toString(); | |
266 | - log.info( | |
267 | - " \nServer uses RPK : \n Elliptic Curve parameters : [{}] \n Public x coord : [{}] \n Public y coord : [{}] \n Public Key (Hex): [{}] \n Private Key (Hex): [{}]", | |
268 | - params, Hex.encodeHexString(x), Hex.encodeHexString(y), | |
269 | - Hex.encodeHexString(this.publicKey.getEncoded()), | |
270 | - Hex.encodeHexString(this.privateKey.getEncoded())); | |
271 | - } else { | |
272 | - throw new IllegalStateException("Unsupported Public Key Format (only ECPublicKey supported)."); | |
273 | - } | |
274 | - } | |
275 | - | |
276 | - | |
277 | - private void setServerWithX509Cert(LeshanServerBuilder builder) { | |
120 | + private void setServerWithCredentials(LeshanServerBuilder builder) { | |
278 | 121 | try { |
279 | 122 | if (this.context.getCtxServer().getKeyStoreValue() != null) { |
280 | - setBuilderX509(builder); | |
281 | - X509Certificate rootCAX509Cert = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getRootAlias()); | |
282 | - if (rootCAX509Cert != null) { | |
283 | - X509Certificate[] trustedCertificates = new X509Certificate[1]; | |
284 | - trustedCertificates[0] = rootCAX509Cert; | |
285 | - builder.setTrustedCertificates(trustedCertificates); | |
123 | + if (this.setBuilderX509(builder)) { | |
124 | + X509Certificate rootCAX509Cert = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getRootAlias()); | |
125 | + if (rootCAX509Cert != null) { | |
126 | + X509Certificate[] trustedCertificates = new X509Certificate[1]; | |
127 | + trustedCertificates[0] = rootCAX509Cert; | |
128 | + builder.setTrustedCertificates(trustedCertificates); | |
129 | + } else { | |
130 | + /** by default trust all */ | |
131 | + builder.setTrustedCertificates(new X509Certificate[0]); | |
132 | + } | |
133 | + /** Set securityStore with registrationStore*/ | |
134 | + builder.setAuthorizer(new DefaultAuthorizer(lwM2mInMemorySecurityStore, new SecurityChecker() { | |
135 | + @Override | |
136 | + protected boolean matchX509Identity(String endpoint, String receivedX509CommonName, | |
137 | + String expectedX509CommonName) { | |
138 | + return endpoint.startsWith(expectedX509CommonName); | |
139 | + } | |
140 | + })); | |
141 | + } else if (this.setServerRPK(builder)) { | |
142 | + this.infoParamsServerRPK(); | |
286 | 143 | } else { |
287 | 144 | /** by default trust all */ |
288 | 145 | builder.setTrustedCertificates(new X509Certificate[0]); |
146 | + log.info("Unable to load X509 files for LWM2MServer"); | |
147 | + this.infoParamsServerPSK(); | |
289 | 148 | } |
290 | - } else { | |
291 | - /** by default trust all */ | |
292 | - builder.setTrustedCertificates(new X509Certificate[0]); | |
293 | - log.error("Unable to load X509 files for LWM2MServer"); | |
294 | 149 | } |
295 | 150 | } catch (KeyStoreException ex) { |
296 | 151 | log.error("[{}] Unable to load X509 files server", ex.getMessage()); |
297 | 152 | } |
298 | 153 | } |
299 | 154 | |
300 | - private void setBuilderX509(LeshanServerBuilder builder) { | |
155 | + private boolean setBuilderX509(LeshanServerBuilder builder) { | |
301 | 156 | /** |
302 | 157 | * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE |
303 | 158 | * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks |
... | ... | @@ -305,38 +160,122 @@ public class LwM2MTransportServerConfiguration { |
305 | 160 | try { |
306 | 161 | X509Certificate serverCertificate = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getServerAlias()); |
307 | 162 | PrivateKey privateKey = (PrivateKey) this.context.getCtxServer().getKeyStoreValue().getKey(this.context.getCtxServer().getServerAlias(), this.context.getCtxServer().getKeyStorePasswordServer() == null ? null : this.context.getCtxServer().getKeyStorePasswordServer().toCharArray()); |
308 | - builder.setPrivateKey(privateKey); | |
309 | - builder.setCertificateChain(new X509Certificate[]{serverCertificate}); | |
310 | - this.infoParamsX509(serverCertificate, privateKey); | |
163 | + PublicKey publicKey = serverCertificate.getPublicKey(); | |
164 | + if (serverCertificate != null && | |
165 | + privateKey != null && privateKey.getEncoded().length > 0 && | |
166 | + publicKey != null && publicKey.getEncoded().length > 0) { | |
167 | + builder.setPublicKey(serverCertificate.getPublicKey()); | |
168 | + builder.setPrivateKey(privateKey); | |
169 | + builder.setCertificateChain(new X509Certificate[]{serverCertificate}); | |
170 | + this.infoParamsServerX509(serverCertificate, publicKey, privateKey); | |
171 | + return true; | |
172 | + } | |
173 | + else { | |
174 | + return false; | |
175 | + } | |
311 | 176 | } catch (Exception ex) { |
312 | 177 | log.error("[{}] Unable to load KeyStore files server", ex.getMessage()); |
178 | + return false; | |
313 | 179 | } |
314 | -// /** | |
315 | -// * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE | |
316 | -// * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks | |
317 | -// */ | |
318 | -// try { | |
319 | -// X509Certificate serverCertificate = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getServerPrivateS()); | |
320 | -// this.privateKey = (PrivateKey) this.context.getCtxServer().getKeyStoreValue().getKey(this.context.getCtxServer().getServerAlias(), this.context.getCtxServer().getKeyStorePasswordServer() == null ? null : this.context.getCtxServer().getKeyStorePasswordServer().toCharArray()); | |
321 | -// if (this.privateKey != null && this.privateKey.getEncoded().length > 0) { | |
322 | -// builder.setPrivateKey(this.privateKey); | |
323 | -// } | |
324 | -// if (serverCertificate != null) { | |
325 | -// builder.setCertificateChain(new X509Certificate[]{serverCertificate}); | |
326 | -// this.infoParamsX509(serverCertificate); | |
327 | -// } | |
328 | -// } catch (Exception ex) { | |
329 | -// log.error("[{}] Unable to load KeyStore files server", ex.getMessage()); | |
330 | -// } | |
331 | 180 | } |
332 | 181 | |
333 | - private void infoParamsX509(X509Certificate certificate, PrivateKey privateKey) { | |
182 | + private void infoParamsServerX509(X509Certificate certificate, PublicKey publicKey, PrivateKey privateKey) { | |
334 | 183 | try { |
335 | - log.info("Server uses X509 : \n X509 Certificate (Hex): [{}] \n Private Key (Hex): [{}]", | |
184 | + log.info("Server uses X509 : \n X509 Certificate (Hex): [{}] \n Public Key (Hex): [{}] \n Private Key (Hex): [{}]", | |
336 | 185 | Hex.encodeHexString(certificate.getEncoded()), |
186 | + Hex.encodeHexString(publicKey.getEncoded()), | |
337 | 187 | Hex.encodeHexString(privateKey.getEncoded())); |
338 | 188 | } catch (CertificateEncodingException e) { |
339 | 189 | log.error("", e); |
340 | 190 | } |
341 | 191 | } |
192 | + | |
193 | + private boolean setServerRPK(LeshanServerBuilder builder) { | |
194 | + try { | |
195 | + this.generateKeyForRPK(); | |
196 | + if (this.publicKey != null && this.publicKey.getEncoded().length > 0 && | |
197 | + this.privateKey != null && this.privateKey.getEncoded().length > 0) { | |
198 | + builder.setPublicKey(this.publicKey); | |
199 | + builder.setPrivateKey(this.privateKey); | |
200 | + return true; | |
201 | + } | |
202 | + } catch (NoSuchAlgorithmException | InvalidParameterSpecException | InvalidKeySpecException e) { | |
203 | + log.error("Fail create Server with RPK", e); | |
204 | + } | |
205 | + return false; | |
206 | + } | |
207 | + | |
208 | + | |
209 | + /** | |
210 | + * From yml^ server | |
211 | + * public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" | |
212 | + * public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" | |
213 | + * private_s: "${LWM2M_SERVER_PRIVATE_S:274671fe40ce937b8a6352cf0a418e8a39e4bf0bb9bf74c910db953c20c73802}" | |
214 | + */ | |
215 | + private void generateKeyForRPK() throws NoSuchAlgorithmException, InvalidParameterSpecException, InvalidKeySpecException { | |
216 | + /** Get Elliptic Curve Parameter spec for secp256r1 */ | |
217 | + AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC"); | |
218 | + algoParameters.init(new ECGenParameterSpec("secp256r1")); | |
219 | + ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class); | |
220 | + if (this.context.getCtxServer().getServerPublicX() != null && | |
221 | + !this.context.getCtxServer().getServerPublicX().isEmpty() && | |
222 | + this.context.getCtxServer().getServerPublicY() != null && | |
223 | + !this.context.getCtxServer().getServerPublicY().isEmpty()) { | |
224 | + /** Get point values */ | |
225 | + byte[] publicX = Hex.decodeHex(this.context.getCtxServer().getServerPublicX().toCharArray()); | |
226 | + byte[] publicY = Hex.decodeHex(this.context.getCtxServer().getServerPublicY().toCharArray()); | |
227 | + /** Create key specs */ | |
228 | + KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)), | |
229 | + parameterSpec); | |
230 | + /** Get keys */ | |
231 | + this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec); | |
232 | + } | |
233 | + if (this.context.getCtxServer().getServerPrivateS() != null && | |
234 | + !this.context.getCtxServer().getServerPrivateS().isEmpty()) { | |
235 | + /** Get point values */ | |
236 | + byte[] privateS = Hex.decodeHex(this.context.getCtxServer().getServerPrivateS().toCharArray()); | |
237 | + /** Create key specs */ | |
238 | + KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec); | |
239 | + /** Get keys */ | |
240 | + this.privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec); | |
241 | + } | |
242 | + } | |
243 | + | |
244 | + private void infoParamsServerRPK() { | |
245 | + /** Get x coordinate */ | |
246 | + byte[] x = ((ECPublicKey) this.publicKey).getW().getAffineX().toByteArray(); | |
247 | + if (x[0] == 0) | |
248 | + x = Arrays.copyOfRange(x, 1, x.length); | |
249 | + | |
250 | + /** Get Y coordinate */ | |
251 | + byte[] y = ((ECPublicKey) this.publicKey).getW().getAffineY().toByteArray(); | |
252 | + if (y[0] == 0) | |
253 | + y = Arrays.copyOfRange(y, 1, y.length); | |
254 | + | |
255 | + /** Get Curves params */ | |
256 | + String params = ((ECPublicKey) this.publicKey).getParams().toString(); | |
257 | + String privHex = Hex.encodeHexString(this.privateKey.getEncoded()); | |
258 | + log.info("Server uses RPK -> serverNoSecureURI : [{}], serverSecureURI : [{}], \n" + | |
259 | + "Public Key (Hex): [{}] \n" + | |
260 | + "Private Key (Hex): [{}], \n" + | |
261 | + "- public_x : [{}] \n" + | |
262 | + "- public_y : [{}] \n" + | |
263 | + "- private_s : [{}] \n" + | |
264 | + "- Elliptic Curve parameters : [{}]", | |
265 | + this.context.getCtxServer().getServerHost() + ":" + this.context.getCtxServer().getServerPortNoSec(), | |
266 | + this.context.getCtxServer().getServerHostSecurity() + ":" + this.context.getCtxServer().getServerPortSecurity(), | |
267 | + Hex.encodeHexString(this.publicKey.getEncoded()), | |
268 | + Hex.encodeHexString(this.privateKey.getEncoded()), | |
269 | + Hex.encodeHexString(x), | |
270 | + Hex.encodeHexString(y), | |
271 | + privHex.substring(privHex.length() - 64), | |
272 | + params); | |
273 | + } | |
274 | + | |
275 | + private void infoParamsServerPSK() { | |
276 | + log.info("Server uses PSK -> serverNoSecureURI : [{}], serverSecureURI : [{}]", | |
277 | + this.context.getCtxServer().getServerHost() + ":" + Integer.toString(this.context.getCtxServer().getServerPortNoSec()), | |
278 | + this.context.getCtxServer().getServerHostSecurity() + ":" + Integer.toString(this.context.getCtxServer().getServerPortSecurity())); | |
279 | + } | |
280 | + | |
342 | 281 | } | ... | ... |
... | ... | @@ -18,7 +18,6 @@ package org.thingsboard.server.transport.lwm2m.server; |
18 | 18 | import lombok.extern.slf4j.Slf4j; |
19 | 19 | import org.eclipse.leshan.server.californium.LeshanServer; |
20 | 20 | import org.springframework.beans.factory.annotation.Autowired; |
21 | -import org.springframework.beans.factory.annotation.Qualifier; | |
22 | 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
23 | 22 | import org.springframework.stereotype.Component; |
24 | 23 | import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC; |
... | ... | @@ -31,69 +30,35 @@ import javax.annotation.PreDestroy; |
31 | 30 | @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") |
32 | 31 | public class LwM2MTransportServerInitializer { |
33 | 32 | |
34 | - | |
35 | 33 | @Autowired |
36 | 34 | private LwM2MTransportServiceImpl service; |
37 | 35 | |
38 | 36 | @Autowired(required = false) |
39 | - @Qualifier("leshanServerX509") | |
40 | - private LeshanServer lhServerX509; | |
41 | - | |
42 | - @Autowired(required = false) | |
43 | - @Qualifier("leshanServerPsk") | |
44 | - private LeshanServer lhServerPsk; | |
45 | - | |
46 | - @Autowired(required = false) | |
47 | - @Qualifier("leshanServerRpk") | |
48 | - private LeshanServer lhServerRpk; | |
37 | + private LeshanServer leshanServer; | |
49 | 38 | |
50 | 39 | @Autowired |
51 | 40 | private LwM2MTransportContextServer context; |
52 | 41 | |
53 | 42 | @PostConstruct |
54 | 43 | public void init() { |
55 | - if (this.context.getCtxServer().getEnableGenPskRpk()) new LWM2MGenerationPSkRPkECC(); | |
56 | - if (this.context.getCtxServer().isServerStartPsk()) { | |
57 | - this.startLhServerPsk(); | |
58 | - } | |
59 | - if (this.context.getCtxServer().isServerStartRpk()) { | |
60 | - this.startLhServerRpk(); | |
44 | + if (this.context.getCtxServer().getEnableGenPskRpk()) { | |
45 | + new LWM2MGenerationPSkRPkECC(); | |
61 | 46 | } |
62 | - if (this.context.getCtxServer().isServerStartX509()) { | |
63 | - this.startLhServerX509(); | |
64 | - } | |
65 | - } | |
66 | - | |
67 | - private void startLhServerPsk() { | |
68 | - this.lhServerPsk.start(); | |
69 | - LwM2mServerListener lhServerPskListener = new LwM2mServerListener(this.lhServerPsk, service); | |
70 | - this.lhServerPsk.getRegistrationService().addListener(lhServerPskListener.registrationListener); | |
71 | - this.lhServerPsk.getPresenceService().addListener(lhServerPskListener.presenceListener); | |
72 | - this.lhServerPsk.getObservationService().addListener(lhServerPskListener.observationListener); | |
73 | - } | |
74 | - | |
75 | - private void startLhServerRpk() { | |
76 | - this.lhServerRpk.start(); | |
77 | - LwM2mServerListener lhServerRpkListener = new LwM2mServerListener(this.lhServerRpk, service); | |
78 | - this.lhServerRpk.getRegistrationService().addListener(lhServerRpkListener.registrationListener); | |
79 | - this.lhServerRpk.getPresenceService().addListener(lhServerRpkListener.presenceListener); | |
80 | - this.lhServerRpk.getObservationService().addListener(lhServerRpkListener.observationListener); | |
47 | + this.startLhServer(); | |
81 | 48 | } |
82 | 49 | |
83 | - private void startLhServerX509() { | |
84 | - this.lhServerX509.start(); | |
85 | - LwM2mServerListener lhServerCertListener = new LwM2mServerListener(this.lhServerX509, service); | |
86 | - this.lhServerX509.getRegistrationService().addListener(lhServerCertListener.registrationListener); | |
87 | - this.lhServerX509.getPresenceService().addListener(lhServerCertListener.presenceListener); | |
88 | - this.lhServerX509.getObservationService().addListener(lhServerCertListener.observationListener); | |
50 | + private void startLhServer() { | |
51 | + this.leshanServer.start(); | |
52 | + LwM2mServerListener lhServerCertListener = new LwM2mServerListener(this.leshanServer, service); | |
53 | + this.leshanServer.getRegistrationService().addListener(lhServerCertListener.registrationListener); | |
54 | + this.leshanServer.getPresenceService().addListener(lhServerCertListener.presenceListener); | |
55 | + this.leshanServer.getObservationService().addListener(lhServerCertListener.observationListener); | |
89 | 56 | } |
90 | 57 | |
91 | 58 | @PreDestroy |
92 | 59 | public void shutdown() { |
93 | 60 | log.info("Stopping LwM2M transport Server!"); |
94 | - lhServerPsk.destroy(); | |
95 | - lhServerRpk.destroy(); | |
96 | - lhServerX509.destroy(); | |
61 | + leshanServer.destroy(); | |
97 | 62 | log.info("LwM2M transport Server stopped!"); |
98 | 63 | } |
99 | 64 | } | ... | ... |
... | ... | @@ -40,48 +40,20 @@ public class LwM2MTransportConfigBootstrap { |
40 | 40 | private Integer bootstrapServerId; |
41 | 41 | |
42 | 42 | @Getter |
43 | - @Value("${transport.lwm2m.bootstrap.secure.start_psk:}") | |
44 | - private Boolean bootstrapStartPsk; | |
45 | - | |
46 | - @Getter | |
47 | - @Value("${transport.lwm2m.bootstrap.secure.start_rpk:}") | |
48 | - private Boolean bootstrapStartRpk; | |
49 | - | |
50 | - @Getter | |
51 | - @Value("${transport.lwm2m.bootstrap.secure.start_x509:}") | |
52 | - private Boolean bootstrapStartX509; | |
53 | - | |
54 | - @Getter | |
55 | 43 | @Value("${transport.lwm2m.bootstrap.bind_address:}") |
56 | 44 | private String bootstrapHost; |
57 | 45 | |
58 | 46 | @Getter |
59 | - @Value("${transport.lwm2m.bootstrap.secure.bind_address:}") | |
60 | - private String bootstrapSecureHost; | |
61 | - | |
62 | - @Getter | |
63 | - @Value("${transport.lwm2m.bootstrap.bind_port_no_sec_psk:}") | |
64 | - private Integer bootstrapPortNoSecPsk; | |
65 | - | |
66 | - @Getter | |
67 | - @Value("${transport.lwm2m.bootstrap.bind_port_no_sec_rpk:}") | |
68 | - private Integer bootstrapPortNoSecRpk; | |
69 | - | |
70 | - @Getter | |
71 | - @Value("${transport.lwm2m.bootstrap.bind_port_no_sec_x509:}") | |
72 | - private Integer bootstrapPortNoSecX509; | |
73 | - | |
74 | - @Getter | |
75 | - @Value("${transport.lwm2m.bootstrap.secure.bind_port_psk:}") | |
76 | - private Integer bootstrapSecurePortPsk; | |
47 | + @Value("${transport.lwm2m.bootstrap.bind_port_no_sec:}") | |
48 | + private Integer bootstrapPortNoSec; | |
77 | 49 | |
78 | 50 | @Getter |
79 | - @Value("${transport.lwm2m.bootstrap.secure.bind_port_rpk:}") | |
80 | - private Integer bootstrapSecurePortRpk; | |
51 | + @Value("${transport.lwm2m.bootstrap.secure.bind_address_security:}") | |
52 | + private String bootstrapHostSecurity; | |
81 | 53 | |
82 | 54 | @Getter |
83 | - @Value("${transport.lwm2m.bootstrap.secure.bind_port_x509:}") | |
84 | - private Integer bootstrapSecurePortX509; | |
55 | + @Value("${transport.lwm2m.bootstrap.secure.bind_port_security:}") | |
56 | + private Integer bootstrapPortSecurity; | |
85 | 57 | |
86 | 58 | @Getter |
87 | 59 | @Value("${transport.lwm2m.bootstrap.secure.public_x:}") | ... | ... |
... | ... | @@ -79,7 +79,7 @@ public class LwM2MTransportConfigServer { |
79 | 79 | private String BASE_DIR_PATH = System.getProperty("user.dir"); |
80 | 80 | |
81 | 81 | @Getter |
82 | -// private String PATH_DATA_MICROSERVICE = "/usr/share/tb-lwm2m-transport/data$"; | |
82 | + // private String PATH_DATA_MICROSERVICE = "/usr/share/tb-lwm2m-transport/data$"; | |
83 | 83 | private String PATH_DATA = "data"; |
84 | 84 | |
85 | 85 | @Getter |
... | ... | @@ -147,57 +147,28 @@ public class LwM2MTransportConfigServer { |
147 | 147 | private String rootAlias; |
148 | 148 | |
149 | 149 | @Getter |
150 | - @Value("${transport.lwm2m.server.secure.start_psk:}") | |
151 | - private boolean serverStartPsk; | |
152 | - | |
153 | - @Getter | |
154 | - @Value("${transport.lwm2m.server.secure.start_rpk:}") | |
155 | - private boolean serverStartRpk; | |
156 | - | |
157 | - @Getter | |
158 | - @Value("${transport.lwm2m.server.secure.start_x509:}") | |
159 | - private boolean serverStartX509; | |
160 | - | |
161 | - @Getter | |
162 | 150 | @Value("${transport.lwm2m.secure.enable_gen_psk_rpk:}") |
163 | 151 | private Boolean enableGenPskRpk; |
164 | 152 | |
165 | 153 | @Getter |
166 | - @Value("${transport.lwm2m.server.bind_address:}") | |
167 | - private String serverHost; | |
168 | - | |
169 | - @Getter | |
170 | 154 | @Value("${transport.lwm2m.server.id:}") |
171 | 155 | private Integer serverId; |
172 | 156 | |
173 | 157 | @Getter |
174 | - @Value("${transport.lwm2m.server.secure.bind_address:}") | |
175 | - private String serverSecureHost; | |
176 | - | |
177 | - | |
178 | - @Getter | |
179 | - @Value("${transport.lwm2m.server.bind_port_no_sec_psk:}") | |
180 | - private Integer serverPortNoSecPsk; | |
181 | - | |
182 | - @Getter | |
183 | - @Value("${transport.lwm2m.server.bind_port_no_sec_rpk:}") | |
184 | - private Integer serverPortNoSecRpk; | |
185 | - | |
186 | - @Getter | |
187 | - @Value("${transport.lwm2m.server.bind_port_no_sec_x509:}") | |
188 | - private Integer serverPortNoSecX509; | |
158 | + @Value("${transport.lwm2m.server.bind_address:}") | |
159 | + private String serverHost; | |
189 | 160 | |
190 | 161 | @Getter |
191 | - @Value("${transport.lwm2m.server.secure.bind_port_psk:}") | |
192 | - private Integer serverPortPsk; | |
162 | + @Value("${transport.lwm2m.server.secure.bind_address_security:}") | |
163 | + private String serverHostSecurity; | |
193 | 164 | |
194 | 165 | @Getter |
195 | - @Value("${transport.lwm2m.server.secure.bind_port_rpk:}") | |
196 | - private Integer serverPortRpk; | |
166 | + @Value("${transport.lwm2m.server.bind_port_no_sec:}") | |
167 | + private Integer serverPortNoSec; | |
197 | 168 | |
198 | 169 | @Getter |
199 | - @Value("${transport.lwm2m.server.secure.bind_port_x509:}") | |
200 | - private Integer serverPortX509; | |
170 | + @Value("${transport.lwm2m.server.secure.bind_port_security:}") | |
171 | + private Integer serverPortSecurity; | |
201 | 172 | |
202 | 173 | @Getter |
203 | 174 | @Value("${transport.lwm2m.server.secure.public_x:}") |
... | ... | @@ -303,7 +274,4 @@ public class LwM2MTransportConfigServer { |
303 | 274 | ResourceModel resource = this.getResourceModel(registration, pathIds); |
304 | 275 | return (resource == null) ? ResourceModel.Operations.NONE : resource.operations; |
305 | 276 | } |
306 | - | |
307 | - | |
308 | - | |
309 | 277 | } | ... | ... |
... | ... | @@ -60,7 +60,7 @@ transport: |
60 | 60 | update_registered_pool_size: "${LWM2M_UPDATE_REGISTERED_POOL_SIZE:10}" |
61 | 61 | un_registered_pool_size: "${LWM2M_UN_REGISTERED_POOL_SIZE:10}" |
62 | 62 | secure: |
63 | - # Only Certificate_x509: | |
63 | + # Certificate_x509: | |
64 | 64 | # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format |
65 | 65 | # Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh |
66 | 66 | key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}" |
... | ... | @@ -73,18 +73,11 @@ transport: |
73 | 73 | server: |
74 | 74 | id: "${LWM2M_SERVER_ID:123}" |
75 | 75 | bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" |
76 | - bind_port_no_sec_psk: "${LWM2M_BIND_PORT_NO_SEC_PSK:5685}" | |
77 | - bind_port_no_sec_rpk: "${LWM2M_BIND_PORT_NO_SEC_RPK:5687}" | |
78 | - bind_port_no_sec_x509: "${LWM2M_BIND_PORT_NO_SEC_X509:5689}" | |
76 | + bind_port_no_sec: "${LWM2M_BIND_PORT_NO_SEC:5685}" | |
79 | 77 | secure: |
80 | - bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" | |
81 | - start_psk: "${START_SERVER_PSK:true}" | |
82 | - start_rpk: "${START_SERVER_RPK:true}" | |
83 | - start_x509: "${START_SERVER_X509:true}" | |
84 | - bind_port_psk: "${LWM2M_BIND_PORT_SEC_PSK:5686}" | |
85 | - bind_port_rpk: "${LWM2M_BIND_PORT_SEC_RPK:5688}" | |
86 | - bind_port_x509: "${LWM2M_BIND_PORT_SEC_X509:5690}" | |
87 | - # Only RPK: Public & Private Key | |
78 | + bind_address_security: "${LWM2M_BIND_ADDRESS_SECURITY:0.0.0.0}" | |
79 | + bind_port_security: "${LWM2M_BIND_PORT_SECURITY:5686}" | |
80 | + # Only for RPK: Public & Private Key. If the keystore file is missing or not working | |
88 | 81 | # create_rpk: "${CREATE_RPK:}" |
89 | 82 | public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" |
90 | 83 | public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" |
... | ... | @@ -92,28 +85,22 @@ transport: |
92 | 85 | # Only Certificate_x509: |
93 | 86 | alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}" |
94 | 87 | bootstrap: |
95 | - enable: "${BOOTSTRAP:true}" | |
88 | + enable: "${LWM2M_BOOTSTRAP_ENABLED:true}" | |
96 | 89 | id: "${LWM2M_SERVER_ID:111}" |
97 | 90 | bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" |
98 | - bind_port_no_sec_psk: "${LWM2M_BIND_PORT_NO_SEC_BS:5691}" | |
99 | - bind_port_no_sec_rpk: "${LWM2M_BIND_PORT_NO_SEC_BS:5693}" | |
100 | - bind_port_no_sec_x509: "${LWM2M_BIND_PORT_NO_SEC_BS:5695}" | |
91 | + bind_port_no_sec: "${LWM2M_BIND_PORT_NO_SEC_BS:5687}" | |
101 | 92 | secure: |
102 | - bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" | |
103 | - start_psk: "${START_SERVER_PSK_BS:true}" | |
104 | - start_rpk: "${START_SERVER_RPK_BS:true}" | |
105 | - start_x509: "${START_SERVER_X509_BS:true}" | |
106 | - bind_port_psk: "${LWM2M_BIND_PORT_SEC_PSK_BS:5692}" | |
107 | - bind_port_rpk: "${LWM2M_BIND_PORT_SER_RPK_BS:5694}" | |
108 | - bind_port_x509: "${LWM2M_BIND_PORT_SEC_X509_BS:5696}" | |
109 | - # Only RPK: Public & Private Key | |
93 | + bind_address_security: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" | |
94 | + bind_port_security: "${LWM2M_BIND_PORT_SEC_BS:5688}" | |
95 | + # Only for RPK: Public & Private Key. If the keystore file is missing or not working | |
110 | 96 | public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" |
111 | 97 | public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" |
112 | 98 | private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" |
113 | 99 | # Only Certificate_x509: |
114 | 100 | alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}" |
115 | - # Redis | |
101 | + # Redis | |
116 | 102 | redis_url: "${LWM2M_REDIS_URL:''}" |
103 | + | |
117 | 104 | sessions: |
118 | 105 | inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" |
119 | 106 | report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:30000}" | ... | ... |
... | ... | @@ -27,7 +27,7 @@ export const DEFAULT_ID_SERVER = 123; |
27 | 27 | export const DEFAULT_ID_BOOTSTRAP = 111; |
28 | 28 | export const DEFAULT_HOST_NAME = 'localhost'; |
29 | 29 | export const DEFAULT_PORT_SERVER_NO_SEC = 5685; |
30 | -export const DEFAULT_PORT_BOOTSTRAP_NO_SEC = 5691; | |
30 | +export const DEFAULT_PORT_BOOTSTRAP_NO_SEC = 5686; | |
31 | 31 | export const DEFAULT_CLIENT_HOLD_OFF_TIME = 1; |
32 | 32 | export const DEFAULT_LIFE_TIME = 300; |
33 | 33 | export const DEFAULT_MIN_PERIOD = 1; | ... | ... |