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,23 +217,19 @@ public class LwM2MModelsRepository { | ||
217 | switch (mode) { | 217 | switch (mode) { |
218 | case NO_SEC: | 218 | case NO_SEC: |
219 | bsServ.setHost(contextBootStrap.getBootstrapHost()); | 219 | bsServ.setHost(contextBootStrap.getBootstrapHost()); |
220 | - bsServ.setPort(contextBootStrap.getBootstrapPortNoSecPsk()); | 220 | + bsServ.setPort(contextBootStrap.getBootstrapPortNoSec()); |
221 | bsServ.setServerPublicKey(""); | 221 | bsServ.setServerPublicKey(""); |
222 | break; | 222 | break; |
223 | case PSK: | 223 | case PSK: |
224 | - bsServ.setHost(contextBootStrap.getBootstrapSecureHost()); | ||
225 | - bsServ.setPort(contextBootStrap.getBootstrapSecurePortPsk()); | 224 | + bsServ.setHost(contextBootStrap.getBootstrapHostSecurity()); |
225 | + bsServ.setPort(contextBootStrap.getBootstrapPortSecurity()); | ||
226 | bsServ.setServerPublicKey(""); | 226 | bsServ.setServerPublicKey(""); |
227 | break; | 227 | break; |
228 | case RPK: | 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 | case X509: | 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 | break; | 233 | break; |
238 | default: | 234 | default: |
239 | break; | 235 | break; |
@@ -243,23 +239,19 @@ public class LwM2MModelsRepository { | @@ -243,23 +239,19 @@ public class LwM2MModelsRepository { | ||
243 | switch (mode) { | 239 | switch (mode) { |
244 | case NO_SEC: | 240 | case NO_SEC: |
245 | bsServ.setHost(contextServer.getServerHost()); | 241 | bsServ.setHost(contextServer.getServerHost()); |
246 | - bsServ.setPort(contextServer.getServerPortNoSecPsk()); | 242 | + bsServ.setPort(contextServer.getServerPortNoSec()); |
247 | bsServ.setServerPublicKey(""); | 243 | bsServ.setServerPublicKey(""); |
248 | break; | 244 | break; |
249 | case PSK: | 245 | case PSK: |
250 | - bsServ.setHost(contextServer.getServerSecureHost()); | ||
251 | - bsServ.setPort(contextServer.getServerPortPsk()); | 246 | + bsServ.setHost(contextServer.getServerHostSecurity()); |
247 | + bsServ.setPort(contextServer.getServerPortSecurity()); | ||
252 | bsServ.setServerPublicKey(""); | 248 | bsServ.setServerPublicKey(""); |
253 | break; | 249 | break; |
254 | case RPK: | 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 | case X509: | 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 | break; | 255 | break; |
264 | default: | 256 | default: |
265 | break; | 257 | break; |
@@ -268,6 +260,11 @@ public class LwM2MModelsRepository { | @@ -268,6 +260,11 @@ public class LwM2MModelsRepository { | ||
268 | return bsServ; | 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 | * @param alias | 269 | * @param alias |
273 | * @return PublicKey format HexString or null | 270 | * @return PublicKey format HexString or null |
@@ -584,7 +584,7 @@ transport: | @@ -584,7 +584,7 @@ transport: | ||
584 | update_registered_pool_size: "${LWM2M_UPDATE_REGISTERED_POOL_SIZE:10}" | 584 | update_registered_pool_size: "${LWM2M_UPDATE_REGISTERED_POOL_SIZE:10}" |
585 | un_registered_pool_size: "${LWM2M_UN_REGISTERED_POOL_SIZE:10}" | 585 | un_registered_pool_size: "${LWM2M_UN_REGISTERED_POOL_SIZE:10}" |
586 | secure: | 586 | secure: |
587 | - # Only Certificate_x509: | 587 | + # Certificate_x509: |
588 | # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format | 588 | # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format |
589 | # Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh | 589 | # Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh |
590 | key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}" | 590 | key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}" |
@@ -597,18 +597,11 @@ transport: | @@ -597,18 +597,11 @@ transport: | ||
597 | server: | 597 | server: |
598 | id: "${LWM2M_SERVER_ID:123}" | 598 | id: "${LWM2M_SERVER_ID:123}" |
599 | bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" | 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 | secure: | 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 | # create_rpk: "${CREATE_RPK:}" | 605 | # create_rpk: "${CREATE_RPK:}" |
613 | public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" | 606 | public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" |
614 | public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" | 607 | public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" |
@@ -619,18 +612,11 @@ transport: | @@ -619,18 +612,11 @@ transport: | ||
619 | enable: "${LWM2M_BOOTSTRAP_ENABLED:true}" | 612 | enable: "${LWM2M_BOOTSTRAP_ENABLED:true}" |
620 | id: "${LWM2M_SERVER_ID:111}" | 613 | id: "${LWM2M_SERVER_ID:111}" |
621 | bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" | 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 | secure: | 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 | public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" | 620 | public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" |
635 | public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" | 621 | public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" |
636 | private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" | 622 | private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" |
@@ -25,20 +25,18 @@ import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuil | @@ -25,20 +25,18 @@ import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuil | ||
25 | import org.springframework.beans.factory.annotation.Autowired; | 25 | import org.springframework.beans.factory.annotation.Autowired; |
26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
27 | import org.springframework.context.annotation.Bean; | 27 | import org.springframework.context.annotation.Bean; |
28 | -import org.springframework.context.annotation.Primary; | ||
29 | import org.springframework.stereotype.Component; | 28 | import org.springframework.stereotype.Component; |
30 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore; | 29 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore; |
31 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore; | 30 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore; |
32 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager; | 31 | import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager; |
33 | -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; | ||
34 | import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer; | 32 | import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer; |
35 | 33 | ||
36 | import java.math.BigInteger; | 34 | import java.math.BigInteger; |
37 | import java.security.AlgorithmParameters; | 35 | import java.security.AlgorithmParameters; |
38 | -import java.security.GeneralSecurityException; | ||
39 | import java.security.KeyFactory; | 36 | import java.security.KeyFactory; |
40 | import java.security.KeyStore; | 37 | import java.security.KeyStore; |
41 | import java.security.KeyStoreException; | 38 | import java.security.KeyStoreException; |
39 | +import java.security.NoSuchAlgorithmException; | ||
42 | import java.security.PrivateKey; | 40 | import java.security.PrivateKey; |
43 | import java.security.PublicKey; | 41 | import java.security.PublicKey; |
44 | import java.security.cert.CertificateEncodingException; | 42 | import java.security.cert.CertificateEncodingException; |
@@ -49,14 +47,13 @@ import java.security.spec.ECParameterSpec; | @@ -49,14 +47,13 @@ import java.security.spec.ECParameterSpec; | ||
49 | import java.security.spec.ECPoint; | 47 | import java.security.spec.ECPoint; |
50 | import java.security.spec.ECPrivateKeySpec; | 48 | import java.security.spec.ECPrivateKeySpec; |
51 | import java.security.spec.ECPublicKeySpec; | 49 | import java.security.spec.ECPublicKeySpec; |
50 | +import java.security.spec.InvalidKeySpecException; | ||
51 | +import java.security.spec.InvalidParameterSpecException; | ||
52 | import java.security.spec.KeySpec; | 52 | import java.security.spec.KeySpec; |
53 | import java.util.Arrays; | 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 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; | 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 | import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; | 57 | import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; |
61 | 58 | ||
62 | @Slf4j | 59 | @Slf4j |
@@ -78,61 +75,42 @@ public class LwM2MTransportBootstrapServerConfiguration { | @@ -78,61 +75,42 @@ public class LwM2MTransportBootstrapServerConfiguration { | ||
78 | @Autowired | 75 | @Autowired |
79 | private LwM2MInMemoryBootstrapConfigStore lwM2MInMemoryBootstrapConfigStore; | 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 | LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder(); | 86 | LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder(); |
105 | builder.setLocalAddress(this.contextBs.getCtxBootStrap().getBootstrapHost(), bootstrapPortNoSec); | 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 | /** Create CoAP Config */ | 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 | builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore); | 100 | builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore); |
113 | 101 | ||
114 | /** SecurityStore */ | 102 | /** SecurityStore */ |
115 | builder.setSecurityStore(lwM2MBootstrapSecurityStore); | 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 | /** Create and Set DTLS Config */ | 106 | /** Create and Set DTLS Config */ |
124 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); | 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 | BootstrapSessionManager sessionManager = new LwM2mDefaultBootstrapSessionManager(lwM2MBootstrapSecurityStore); | 115 | BootstrapSessionManager sessionManager = new LwM2mDefaultBootstrapSessionManager(lwM2MBootstrapSecurityStore); |
138 | builder.setSessionManager(sessionManager); | 116 | builder.setSessionManager(sessionManager); |
@@ -141,150 +119,153 @@ public class LwM2MTransportBootstrapServerConfiguration { | @@ -141,150 +119,153 @@ public class LwM2MTransportBootstrapServerConfiguration { | ||
141 | return builder.build(); | 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 | try { | 123 | try { |
211 | if (this.contextS.getCtxServer().getKeyStoreValue() != null) { | 124 | if (this.contextS.getCtxServer().getKeyStoreValue() != null) { |
212 | KeyStore keyStoreServer = this.contextS.getCtxServer().getKeyStoreValue(); | 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 | } else { | 138 | } else { |
220 | /** by default trust all */ | 139 | /** by default trust all */ |
221 | builder.setTrustedCertificates(new X509Certificate[0]); | 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 | } catch (KeyStoreException ex) { | 145 | } catch (KeyStoreException ex) { |
230 | log.error("[{}] Unable to load X509 files server", ex.getMessage()); | 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 | * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE | 152 | * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE |
238 | * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks | 153 | * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks |
239 | */ | 154 | */ |
240 | try { | 155 | try { |
241 | X509Certificate serverCertificate = (X509Certificate) this.contextS.getCtxServer().getKeyStoreValue().getCertificate(this.contextBs.getCtxBootStrap().getBootstrapAlias()); | 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 | builder.setCertificateChain(new X509Certificate[]{serverCertificate}); | 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 | } catch (Exception ex) { | 170 | } catch (Exception ex) { |
251 | log.error("[{}] Unable to load KeyStore files server", ex.getMessage()); | 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 | try { | 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 | Hex.encodeHexString(certificate.getEncoded()), | 179 | Hex.encodeHexString(certificate.getEncoded()), |
283 | - Hex.encodeHexString(this.privateKey.getEncoded())); | 180 | + Hex.encodeHexString(publicKey.getEncoded()), |
181 | + Hex.encodeHexString(privateKey.getEncoded())); | ||
284 | } catch (CertificateEncodingException e) { | 182 | } catch (CertificateEncodingException e) { |
285 | log.error("", e); | 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,7 +18,6 @@ package org.thingsboard.server.transport.lwm2m.bootstrap; | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer; | 19 | import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer; |
20 | import org.springframework.beans.factory.annotation.Autowired; | 20 | import org.springframework.beans.factory.annotation.Autowired; |
21 | -import org.springframework.beans.factory.annotation.Qualifier; | ||
22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
23 | import org.springframework.stereotype.Service; | 22 | import org.springframework.stereotype.Service; |
24 | 23 | ||
@@ -31,39 +30,20 @@ import javax.annotation.PreDestroy; | @@ -31,39 +30,20 @@ import javax.annotation.PreDestroy; | ||
31 | public class LwM2MTransportBootstrapServerInitializer { | 30 | public class LwM2MTransportBootstrapServerInitializer { |
32 | 31 | ||
33 | @Autowired(required = false) | 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 | @Autowired | 35 | @Autowired |
46 | private LwM2MTransportContextBootstrap contextBS; | 36 | private LwM2MTransportContextBootstrap contextBS; |
47 | 37 | ||
48 | @PostConstruct | 38 | @PostConstruct |
49 | public void init() { | 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 | @PreDestroy | 43 | @PreDestroy |
62 | public void shutdown() throws InterruptedException { | 44 | public void shutdown() throws InterruptedException { |
63 | log.info("Stopping LwM2M transport Bootstrap Server!"); | 45 | log.info("Stopping LwM2M transport Bootstrap Server!"); |
64 | - lhBServerPsk.destroy(); | ||
65 | - lhBServerRpk.destroy(); | ||
66 | - lhBServerCert.destroy(); | 46 | + lhBServer.destroy(); |
67 | log.info("LwM2M transport Bootstrap Server stopped!"); | 47 | log.info("LwM2M transport Bootstrap Server stopped!"); |
68 | } | 48 | } |
69 | } | 49 | } |
@@ -25,31 +25,20 @@ import org.eclipse.leshan.server.californium.LeshanServer; | @@ -25,31 +25,20 @@ import org.eclipse.leshan.server.californium.LeshanServer; | ||
25 | import org.eclipse.leshan.server.californium.LeshanServerBuilder; | 25 | import org.eclipse.leshan.server.californium.LeshanServerBuilder; |
26 | import org.eclipse.leshan.server.model.LwM2mModelProvider; | 26 | import org.eclipse.leshan.server.model.LwM2mModelProvider; |
27 | import org.eclipse.leshan.server.model.VersionedModelProvider; | 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 | import org.eclipse.leshan.server.security.DefaultAuthorizer; | 28 | import org.eclipse.leshan.server.security.DefaultAuthorizer; |
31 | -import org.eclipse.leshan.server.security.EditableSecurityStore; | ||
32 | import org.eclipse.leshan.server.security.SecurityChecker; | 29 | import org.eclipse.leshan.server.security.SecurityChecker; |
33 | import org.springframework.beans.factory.annotation.Autowired; | 30 | import org.springframework.beans.factory.annotation.Autowired; |
34 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 31 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
35 | import org.springframework.context.annotation.Bean; | 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 | import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore; | 34 | import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore; |
41 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; | 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 | import java.math.BigInteger; | 37 | import java.math.BigInteger; |
47 | -import java.net.URI; | ||
48 | -import java.net.URISyntaxException; | ||
49 | import java.security.AlgorithmParameters; | 38 | import java.security.AlgorithmParameters; |
50 | -import java.security.GeneralSecurityException; | ||
51 | import java.security.KeyFactory; | 39 | import java.security.KeyFactory; |
52 | import java.security.KeyStoreException; | 40 | import java.security.KeyStoreException; |
41 | +import java.security.NoSuchAlgorithmException; | ||
53 | import java.security.PrivateKey; | 42 | import java.security.PrivateKey; |
54 | import java.security.PublicKey; | 43 | import java.security.PublicKey; |
55 | import java.security.cert.CertificateEncodingException; | 44 | import java.security.cert.CertificateEncodingException; |
@@ -60,20 +49,17 @@ import java.security.spec.ECParameterSpec; | @@ -60,20 +49,17 @@ import java.security.spec.ECParameterSpec; | ||
60 | import java.security.spec.ECPoint; | 49 | import java.security.spec.ECPoint; |
61 | import java.security.spec.ECPrivateKeySpec; | 50 | import java.security.spec.ECPrivateKeySpec; |
62 | import java.security.spec.ECPublicKeySpec; | 51 | import java.security.spec.ECPublicKeySpec; |
52 | +import java.security.spec.InvalidKeySpecException; | ||
53 | +import java.security.spec.InvalidParameterSpecException; | ||
63 | import java.security.spec.KeySpec; | 54 | import java.security.spec.KeySpec; |
64 | import java.util.Arrays; | 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 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; | 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 | import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; | 59 | import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig; |
71 | 60 | ||
72 | - | ||
73 | @Slf4j | 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 | @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") | 63 | @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") |
78 | public class LwM2MTransportServerConfiguration { | 64 | public class LwM2MTransportServerConfiguration { |
79 | private PublicKey publicKey; | 65 | private PublicKey publicKey; |
@@ -85,32 +71,16 @@ public class LwM2MTransportServerConfiguration { | @@ -85,32 +71,16 @@ public class LwM2MTransportServerConfiguration { | ||
85 | @Autowired | 71 | @Autowired |
86 | private LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore; | 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 | LeshanServerBuilder builder = new LeshanServerBuilder(); | 81 | LeshanServerBuilder builder = new LeshanServerBuilder(); |
112 | builder.setLocalAddress(this.context.getCtxServer().getServerHost(), serverPortNoSec); | 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 | builder.setEncoder(new DefaultLwM2mNodeEncoder()); | 84 | builder.setEncoder(new DefaultLwM2mNodeEncoder()); |
115 | LwM2mNodeDecoder decoder = new DefaultLwM2mNodeDecoder(); | 85 | LwM2mNodeDecoder decoder = new DefaultLwM2mNodeDecoder(); |
116 | builder.setDecoder(decoder); | 86 | builder.setDecoder(decoder); |
@@ -123,22 +93,19 @@ public class LwM2MTransportServerConfiguration { | @@ -123,22 +93,19 @@ public class LwM2MTransportServerConfiguration { | ||
123 | LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getCtxServer().getModelsValue()); | 93 | LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getCtxServer().getModelsValue()); |
124 | builder.setObjectModelProvider(modelProvider); | 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 | /** Create DTLS Config */ | 103 | /** Create DTLS Config */ |
132 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); | 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 | /** Set DTLS Config */ | 109 | /** Set DTLS Config */ |
143 | builder.setDtlsConfig(dtlsConfig); | 110 | builder.setDtlsConfig(dtlsConfig); |
144 | 111 | ||
@@ -150,154 +117,42 @@ public class LwM2MTransportServerConfiguration { | @@ -150,154 +117,42 @@ public class LwM2MTransportServerConfiguration { | ||
150 | return builder.build(); | 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 | try { | 121 | try { |
279 | if (this.context.getCtxServer().getKeyStoreValue() != null) { | 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 | } else { | 143 | } else { |
287 | /** by default trust all */ | 144 | /** by default trust all */ |
288 | builder.setTrustedCertificates(new X509Certificate[0]); | 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 | } catch (KeyStoreException ex) { | 150 | } catch (KeyStoreException ex) { |
296 | log.error("[{}] Unable to load X509 files server", ex.getMessage()); | 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 | * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE | 157 | * For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE |
303 | * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks | 158 | * For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks |
@@ -305,38 +160,122 @@ public class LwM2MTransportServerConfiguration { | @@ -305,38 +160,122 @@ public class LwM2MTransportServerConfiguration { | ||
305 | try { | 160 | try { |
306 | X509Certificate serverCertificate = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getServerAlias()); | 161 | X509Certificate serverCertificate = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getServerAlias()); |
307 | PrivateKey privateKey = (PrivateKey) this.context.getCtxServer().getKeyStoreValue().getKey(this.context.getCtxServer().getServerAlias(), this.context.getCtxServer().getKeyStorePasswordServer() == null ? null : this.context.getCtxServer().getKeyStorePasswordServer().toCharArray()); | 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 | } catch (Exception ex) { | 176 | } catch (Exception ex) { |
312 | log.error("[{}] Unable to load KeyStore files server", ex.getMessage()); | 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 | try { | 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 | Hex.encodeHexString(certificate.getEncoded()), | 185 | Hex.encodeHexString(certificate.getEncoded()), |
186 | + Hex.encodeHexString(publicKey.getEncoded()), | ||
337 | Hex.encodeHexString(privateKey.getEncoded())); | 187 | Hex.encodeHexString(privateKey.getEncoded())); |
338 | } catch (CertificateEncodingException e) { | 188 | } catch (CertificateEncodingException e) { |
339 | log.error("", e); | 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,7 +18,6 @@ package org.thingsboard.server.transport.lwm2m.server; | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.eclipse.leshan.server.californium.LeshanServer; | 19 | import org.eclipse.leshan.server.californium.LeshanServer; |
20 | import org.springframework.beans.factory.annotation.Autowired; | 20 | import org.springframework.beans.factory.annotation.Autowired; |
21 | -import org.springframework.beans.factory.annotation.Qualifier; | ||
22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; | 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; |
23 | import org.springframework.stereotype.Component; | 22 | import org.springframework.stereotype.Component; |
24 | import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC; | 23 | import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC; |
@@ -31,69 +30,35 @@ import javax.annotation.PreDestroy; | @@ -31,69 +30,35 @@ import javax.annotation.PreDestroy; | ||
31 | @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") | 30 | @ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')") |
32 | public class LwM2MTransportServerInitializer { | 31 | public class LwM2MTransportServerInitializer { |
33 | 32 | ||
34 | - | ||
35 | @Autowired | 33 | @Autowired |
36 | private LwM2MTransportServiceImpl service; | 34 | private LwM2MTransportServiceImpl service; |
37 | 35 | ||
38 | @Autowired(required = false) | 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 | @Autowired | 39 | @Autowired |
51 | private LwM2MTransportContextServer context; | 40 | private LwM2MTransportContextServer context; |
52 | 41 | ||
53 | @PostConstruct | 42 | @PostConstruct |
54 | public void init() { | 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 | @PreDestroy | 58 | @PreDestroy |
92 | public void shutdown() { | 59 | public void shutdown() { |
93 | log.info("Stopping LwM2M transport Server!"); | 60 | log.info("Stopping LwM2M transport Server!"); |
94 | - lhServerPsk.destroy(); | ||
95 | - lhServerRpk.destroy(); | ||
96 | - lhServerX509.destroy(); | 61 | + leshanServer.destroy(); |
97 | log.info("LwM2M transport Server stopped!"); | 62 | log.info("LwM2M transport Server stopped!"); |
98 | } | 63 | } |
99 | } | 64 | } |
@@ -40,48 +40,20 @@ public class LwM2MTransportConfigBootstrap { | @@ -40,48 +40,20 @@ public class LwM2MTransportConfigBootstrap { | ||
40 | private Integer bootstrapServerId; | 40 | private Integer bootstrapServerId; |
41 | 41 | ||
42 | @Getter | 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 | @Value("${transport.lwm2m.bootstrap.bind_address:}") | 43 | @Value("${transport.lwm2m.bootstrap.bind_address:}") |
56 | private String bootstrapHost; | 44 | private String bootstrapHost; |
57 | 45 | ||
58 | @Getter | 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 | @Getter | 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 | @Getter | 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 | @Getter | 58 | @Getter |
87 | @Value("${transport.lwm2m.bootstrap.secure.public_x:}") | 59 | @Value("${transport.lwm2m.bootstrap.secure.public_x:}") |
@@ -79,7 +79,7 @@ public class LwM2MTransportConfigServer { | @@ -79,7 +79,7 @@ public class LwM2MTransportConfigServer { | ||
79 | private String BASE_DIR_PATH = System.getProperty("user.dir"); | 79 | private String BASE_DIR_PATH = System.getProperty("user.dir"); |
80 | 80 | ||
81 | @Getter | 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 | private String PATH_DATA = "data"; | 83 | private String PATH_DATA = "data"; |
84 | 84 | ||
85 | @Getter | 85 | @Getter |
@@ -147,57 +147,28 @@ public class LwM2MTransportConfigServer { | @@ -147,57 +147,28 @@ public class LwM2MTransportConfigServer { | ||
147 | private String rootAlias; | 147 | private String rootAlias; |
148 | 148 | ||
149 | @Getter | 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 | @Value("${transport.lwm2m.secure.enable_gen_psk_rpk:}") | 150 | @Value("${transport.lwm2m.secure.enable_gen_psk_rpk:}") |
163 | private Boolean enableGenPskRpk; | 151 | private Boolean enableGenPskRpk; |
164 | 152 | ||
165 | @Getter | 153 | @Getter |
166 | - @Value("${transport.lwm2m.server.bind_address:}") | ||
167 | - private String serverHost; | ||
168 | - | ||
169 | - @Getter | ||
170 | @Value("${transport.lwm2m.server.id:}") | 154 | @Value("${transport.lwm2m.server.id:}") |
171 | private Integer serverId; | 155 | private Integer serverId; |
172 | 156 | ||
173 | @Getter | 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 | @Getter | 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 | @Getter | 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 | @Getter | 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 | @Getter | 173 | @Getter |
203 | @Value("${transport.lwm2m.server.secure.public_x:}") | 174 | @Value("${transport.lwm2m.server.secure.public_x:}") |
@@ -303,7 +274,4 @@ public class LwM2MTransportConfigServer { | @@ -303,7 +274,4 @@ public class LwM2MTransportConfigServer { | ||
303 | ResourceModel resource = this.getResourceModel(registration, pathIds); | 274 | ResourceModel resource = this.getResourceModel(registration, pathIds); |
304 | return (resource == null) ? ResourceModel.Operations.NONE : resource.operations; | 275 | return (resource == null) ? ResourceModel.Operations.NONE : resource.operations; |
305 | } | 276 | } |
306 | - | ||
307 | - | ||
308 | - | ||
309 | } | 277 | } |
@@ -60,7 +60,7 @@ transport: | @@ -60,7 +60,7 @@ transport: | ||
60 | update_registered_pool_size: "${LWM2M_UPDATE_REGISTERED_POOL_SIZE:10}" | 60 | update_registered_pool_size: "${LWM2M_UPDATE_REGISTERED_POOL_SIZE:10}" |
61 | un_registered_pool_size: "${LWM2M_UN_REGISTERED_POOL_SIZE:10}" | 61 | un_registered_pool_size: "${LWM2M_UN_REGISTERED_POOL_SIZE:10}" |
62 | secure: | 62 | secure: |
63 | - # Only Certificate_x509: | 63 | + # Certificate_x509: |
64 | # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format | 64 | # To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format |
65 | # Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh | 65 | # Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh |
66 | key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}" | 66 | key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}" |
@@ -73,18 +73,11 @@ transport: | @@ -73,18 +73,11 @@ transport: | ||
73 | server: | 73 | server: |
74 | id: "${LWM2M_SERVER_ID:123}" | 74 | id: "${LWM2M_SERVER_ID:123}" |
75 | bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}" | 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 | secure: | 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 | # create_rpk: "${CREATE_RPK:}" | 81 | # create_rpk: "${CREATE_RPK:}" |
89 | public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" | 82 | public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}" |
90 | public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" | 83 | public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}" |
@@ -92,28 +85,22 @@ transport: | @@ -92,28 +85,22 @@ transport: | ||
92 | # Only Certificate_x509: | 85 | # Only Certificate_x509: |
93 | alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}" | 86 | alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}" |
94 | bootstrap: | 87 | bootstrap: |
95 | - enable: "${BOOTSTRAP:true}" | 88 | + enable: "${LWM2M_BOOTSTRAP_ENABLED:true}" |
96 | id: "${LWM2M_SERVER_ID:111}" | 89 | id: "${LWM2M_SERVER_ID:111}" |
97 | bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}" | 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 | secure: | 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 | public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" | 96 | public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}" |
111 | public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" | 97 | public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}" |
112 | private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" | 98 | private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}" |
113 | # Only Certificate_x509: | 99 | # Only Certificate_x509: |
114 | alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}" | 100 | alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}" |
115 | - # Redis | 101 | + # Redis |
116 | redis_url: "${LWM2M_REDIS_URL:''}" | 102 | redis_url: "${LWM2M_REDIS_URL:''}" |
103 | + | ||
117 | sessions: | 104 | sessions: |
118 | inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" | 105 | inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" |
119 | report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:30000}" | 106 | report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:30000}" |
@@ -27,7 +27,7 @@ export const DEFAULT_ID_SERVER = 123; | @@ -27,7 +27,7 @@ export const DEFAULT_ID_SERVER = 123; | ||
27 | export const DEFAULT_ID_BOOTSTRAP = 111; | 27 | export const DEFAULT_ID_BOOTSTRAP = 111; |
28 | export const DEFAULT_HOST_NAME = 'localhost'; | 28 | export const DEFAULT_HOST_NAME = 'localhost'; |
29 | export const DEFAULT_PORT_SERVER_NO_SEC = 5685; | 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 | export const DEFAULT_CLIENT_HOLD_OFF_TIME = 1; | 31 | export const DEFAULT_CLIENT_HOLD_OFF_TIME = 1; |
32 | export const DEFAULT_LIFE_TIME = 300; | 32 | export const DEFAULT_LIFE_TIME = 300; |
33 | export const DEFAULT_MIN_PERIOD = 1; | 33 | export const DEFAULT_MIN_PERIOD = 1; |