From 6a370dc6436830fbaf885db83d18066ac24dc4ff Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 26 Jan 2022 17:24:11 +0200 Subject: [PATCH 01/51] lwm2m: tests associated with different security mode (successful): - connection only to lwm2m server - connect bootstrap server, update two client security sections and then connect lwm2m server --- .../controller/AbstractWebsocketTest.java | 2 + .../controller/TbTestWebSocketClient.java | 2 +- .../lwm2m/AbstractLwM2MIntegrationTest.java | 281 ++++++++++++++++-- .../transport/lwm2m/Lwm2mTestHelper.java | 129 ++++++-- .../lwm2m/client/LwM2MTestClient.java | 92 +++++- .../ota/sql/OtaLwM2MIntegrationTest.java | 156 ++++------ .../rpc/AbstractRpcLwM2MIntegrationTest.java | 121 +++----- .../AbstractSecurityLwM2MIntegrationTest.java | 174 ++++++++++- .../sql/NoSecLwM2MIntegrationTest.java | 36 ++- .../security/sql/PskLwm2mIntegrationTest.java | 66 +++- .../security/sql/RpkLwM2MIntegrationTest.java | 72 ++++- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 69 ++++- .../sql/X509_TrustLwM2MIntegrationTest.java | 65 +++- .../resources/application-test.properties | 8 - ...LwM2MBootstrapConfigStoreTaskProvider.java | 14 +- .../lwm2m/server/LwM2MNetworkConfig.java | 12 +- .../server/LwM2mVersionedModelProvider.java | 10 +- 17 files changed, 970 insertions(+), 339 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java index 4760a024c1..2edc985301 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java @@ -22,6 +22,7 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.Header; import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwts; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.hamcrest.Matcher; @@ -34,6 +35,7 @@ import org.junit.rules.TestWatcher; import org.junit.runner.Description; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootContextLoader; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; diff --git a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java index 1b27fb6a62..3abd311aa3 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java +++ b/application/src/test/java/org/thingsboard/server/controller/TbTestWebSocketClient.java @@ -54,7 +54,7 @@ public class TbTestWebSocketClient extends WebSocketClient { @Override public void onClose(int i, String s, boolean b) { - log.error("CLOSED:"); + log.info("CLOSED."); } @Override diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index fd4c748f85..67e17e3d8d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -16,6 +16,7 @@ package org.thingsboard.server.transport.lwm2m; import com.fasterxml.jackson.core.type.TypeReference; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.eclipse.californium.elements.config.Configuration; import org.eclipse.leshan.client.object.Security; @@ -35,12 +36,22 @@ import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecBootstrapClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKBootstrapClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKBootstrapClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredential; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.OtherConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.TelemetryMappingConfiguration; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.NoSecLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.query.EntityData; import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; @@ -58,17 +69,157 @@ import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; import org.thingsboard.server.service.telemetry.cmd.v2.LatestValueCmd; import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import static org.awaitility.Awaitility.await; +import static org.eclipse.californium.core.config.CoapConfig.COAP_PORT; +import static org.eclipse.californium.core.config.CoapConfig.COAP_SECURE_PORT; +import static org.eclipse.leshan.client.object.Security.noSec; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_INIT; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; +@Slf4j @DaoSqlTest public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { + + // Lwm2m Server + public static final int port = 5685; + public static final int securityPort = 5686; + public static final int portBs = 5687; + public static final int securityPortBs = 5688; + + public static final String host = "localhost"; + public static final String hostBs = "localhost"; + public static final int shortServerId = 123; + public static final int shortServerIdBs = 111; + public static final String COAP = "coap://"; + public static final String COAPS = "coaps://"; + public static final String URI = COAP + host + ":" + port; + public static final String SECURE_URI = COAPS + host + ":" + securityPort; + public static final Configuration COAP_CONFIG = new Configuration().set(COAP_PORT, port).set(COAP_SECURE_PORT, securityPort); + public static final Security SECURITY_NO_SEC = noSec(URI, shortServerId); + + public static final Configuration SECURE_COAP_CONFIG = COAP_CONFIG.set(COAP_SECURE_PORT, securityPort); + public static final Configuration COAP_CONFIG_BS = new Configuration().set(COAP_PORT, portBs); + + + public static final String URI_BS = COAP + hostBs + ":" + portBs; + + public static final String SECURE_URI_BS = COAPS + hostBs + ":" + securityPortBs; + + protected final String OBSERVE_ATTRIBUTES_WITHOUT_PARAMS = + " {\n" + + " \"keyName\": {},\n" + + " \"observe\": [],\n" + + " \"attribute\": [],\n" + + " \"telemetry\": [],\n" + + " \"attributeLwm2m\": {}\n" + + " }"; + + protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS = + + " {\n" + + " \"keyName\": {\n" + + " \"/3_1.0/0/9\": \"batteryLevel\"\n" + + " },\n" + + " \"observe\": [],\n" + + " \"attribute\": [\n" + + " ],\n" + + " \"telemetry\": [\n" + + " \"/3_1.0/0/9\"\n" + + " ],\n" + + " \"attributeLwm2m\": {}\n" + + " }"; + + protected final String CLIENT_LWM2M_SETTINGS = + " {\n" + + " \"edrxCycle\": null,\n" + + " \"powerMode\": \"DRX\",\n" + + " \"fwUpdateResource\": null,\n" + + " \"fwUpdateStrategy\": 1,\n" + + " \"psmActivityTimer\": null,\n" + + " \"swUpdateResource\": null,\n" + + " \"swUpdateStrategy\": 1,\n" + + " \"pagingTransmissionWindow\": null,\n" + + " \"clientOnlyObserveAfterConnect\": 1\n" + + " }"; + + + protected final String TRANSPORT_CONFIGURATION_NO_SEC_WITHOUT_ATTRIBUTES = "{\n" + + " \"type\": \"LWM2M\",\n" + + " \"observeAttr\": {\n" + + " \"keyName\": {},\n" + + " \"observe\": [],\n" + + " \"attribute\": [],\n" + + " \"telemetry\": [],\n" + + " \"attributeLwm2m\": {}\n" + + " },\n" + + " \"bootstrapServerUpdateEnable\": true,\n" + + " \"bootstrap\": [\n" + + " {\n" + + " \"host\": \"" + hostBs + "\",\n" + + " \"port\": " + portBs + ",\n" + + " \"binding\": \"U\",\n" + + " \"lifetime\": 300,\n" + + " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + + " \"shortServerId\": " + shortServerIdBs + ",\n" + + " \"notifIfDisabled\": true,\n" + + " \"serverPublicKey\": \"\",\n" + + " \"defaultMinPeriod\": 1,\n" + + " \"bootstrapServerIs\": true,\n" + + " \"clientHoldOffTime\": 1,\n" + + " \"bootstrapServerAccountTimeout\": 0\n" + + " },\n" + + " {\n" + + " \"host\": \"" + host + "\",\n" + + " \"port\": " + port + ",\n" + + " \"binding\": \"U\",\n" + + " \"lifetime\": 300,\n" + + " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + + " \"shortServerId\": " + shortServerId + ",\n" + + " \"notifIfDisabled\": true,\n" + + " \"serverPublicKey\": \"\",\n" + + " \"defaultMinPeriod\": 1,\n" + + " \"bootstrapServerIs\": false,\n" + + " \"clientHoldOffTime\": 1,\n" + + " \"bootstrapServerAccountTimeout\": 0\n" + + " }\n" + + " ],\n" + + " \"clientLwM2mSettings\": {\n" + + " \"edrxCycle\": null,\n" + + " \"powerMode\": \"DRX\",\n" + + " \"fwUpdateResource\": null,\n" + + " \"fwUpdateStrategy\": 1,\n" + + " \"psmActivityTimer\": null,\n" + + " \"swUpdateResource\": null,\n" + + " \"swUpdateStrategy\": 1,\n" + + " \"pagingTransmissionWindow\": null,\n" + + " \"clientOnlyObserveAfterConnect\": 1\n" + + " }\n" + + "}"; + + protected final String TRANSPORT_CONFIGURATION = "{\n" + " \"type\": \"LWM2M\",\n" + " \"observeAttr\": {\n" + @@ -86,12 +237,12 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest " \"bootstrapServerUpdateEnable\": true,\n" + " \"bootstrap\": [\n" + " {\n" + - " \"host\": \"0.0.0.0\",\n" + - " \"port\": 5687,\n" + + " \"host\": \"" + hostBs + "\",\n" + + " \"port\": " + portBs + ",\n" + " \"binding\": \"U\",\n" + " \"lifetime\": 300,\n" + - " \"securityMode\": \"NO_SEC\",\n" + - " \"shortServerId\": 111,\n" + + " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + + " \"shortServerId\": " + shortServerIdBs + ",\n" + " \"notifIfDisabled\": true,\n" + " \"serverPublicKey\": \"\",\n" + " \"defaultMinPeriod\": 1,\n" + @@ -100,12 +251,12 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest " \"bootstrapServerAccountTimeout\": 0\n" + " },\n" + " {\n" + - " \"host\": \"0.0.0.0\",\n" + - " \"port\": 5685,\n" + + " \"host\": \"" + host + "\",\n" + + " \"port\": " + port + ",\n" + " \"binding\": \"U\",\n" + " \"lifetime\": 300,\n" + - " \"securityMode\": \"NO_SEC\",\n" + - " \"shortServerId\": 123,\n" + + " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + + " \"shortServerId\": " + shortServerId + ",\n" + " \"notifIfDisabled\": true,\n" + " \"serverPublicKey\": \"\",\n" + " \"defaultMinPeriod\": 1,\n" + @@ -127,21 +278,20 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest " }\n" + "}"; + protected final Lwm2mDeviceProfileTransportConfiguration LWM2M_TRANSPORT_CONFIGURATION_NO_SEC_WITH_ATTRIBUTES = JacksonUtil.fromString(TRANSPORT_CONFIGURATION, Lwm2mDeviceProfileTransportConfiguration.class); + protected final Lwm2mDeviceProfileTransportConfiguration LWM2M_TRANSPORT_CONFIGURATION_NO_SEC_WITHOUT_ATTRIBUTES = JacksonUtil.fromString(TRANSPORT_CONFIGURATION_NO_SEC_WITHOUT_ATTRIBUTES, Lwm2mDeviceProfileTransportConfiguration.class); + protected final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); + protected final Set expectedStatusesRegistrationBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected DeviceProfile deviceProfile; protected ScheduledExecutorService executor; protected TbTestWebSocketClient wsClient; protected LwM2MTestClient client; - private final LwM2MBootstrapClientCredentials defaultBootstrapCredentials; private String[] resources; public AbstractLwM2MIntegrationTest() { - this.defaultBootstrapCredentials = new LwM2MBootstrapClientCredentials(); - NoSecBootstrapClientCredential serverCredentials = new NoSecBootstrapClientCredential(); - this.defaultBootstrapCredentials.setBootstrapServer(serverCredentials); - this.defaultBootstrapCredentials.setLwm2mServer(serverCredentials); } - public void init () throws Exception{ + public void init() throws Exception { executor = Executors.newScheduledThreadPool(10, ThingsBoardThreadFactory.forName("test-lwm2m-scheduled")); loginTenantAdmin(); @@ -167,17 +317,42 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest @After public void after() { - wsClient.close(); clientDestroy(); executor.shutdownNow(); } + public void basicTestConnection(Security security, + LwM2MDeviceCredentials deviceCredentials, + Configuration coapConfig, + String endpoint, + Lwm2mDeviceProfileTransportConfiguration transportConfiguration, + String awaitAlias, Set expectedStatuses, + boolean isBootstrap, LwM2MSecurityMode mode) throws Exception { + createDeviceProfile(transportConfiguration); + createDevice(deviceCredentials, endpoint); + createNewClient(security, coapConfig, false, endpoint, isBootstrap); + + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); + Assert.assertEquals(expectedStatuses, client.getClientStates()); + + client.destroy(); + expectedStatuses.add(ON_DEREGISTRATION_STARTED); + expectedStatuses.add(ON_DEREGISTRATION_SUCCESS); + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState())); + Assert.assertEquals(expectedStatuses, client.getClientStates()); + } + public void basicTestConnectionObserveTelemetry(Security security, - LwM2MClientCredential credentials, + LwM2MDeviceCredentials deviceCredentials, Configuration coapConfig, String endpoint) throws Exception { - createDeviceProfile(TRANSPORT_CONFIGURATION); - Device device = createDevice(credentials); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITH_PARAMS, getBootstrapServerCredentialsNoSec(NONE)); + createDeviceProfile(transportConfiguration); + Device device = createDevice(deviceCredentials, endpoint); SingleEntityFilter sef = new SingleEntityFilter(); sef.setSingleEntity(device.getId()); @@ -194,7 +369,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest wsClient.waitForReply(); wsClient.registerWaitForUpdate(); - createNewClient(security, coapConfig, false, endpoint); + createNewClient(security, coapConfig, false, endpoint, false); String msg = wsClient.waitForUpdate(); EntityDataUpdate update = mapper.readValue(msg, EntityDataUpdate.class); @@ -208,7 +383,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest Assert.assertEquals(42, Long.parseLong(tsValue.getValue())); } - protected void createDeviceProfile(String transportConfiguration) throws Exception { + protected void createDeviceProfile(Lwm2mDeviceProfileTransportConfiguration transportConfiguration) throws Exception { deviceProfile = new DeviceProfile(); deviceProfile.setName("LwM2M"); deviceProfile.setType(DeviceProfileType.DEFAULT); @@ -220,16 +395,16 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest DeviceProfileData deviceProfileData = new DeviceProfileData(); deviceProfileData.setConfiguration(new DefaultDeviceProfileConfiguration()); deviceProfileData.setProvisionConfiguration(new DisabledDeviceProfileProvisionConfiguration(null)); - deviceProfileData.setTransportConfiguration(JacksonUtil.fromString(transportConfiguration, Lwm2mDeviceProfileTransportConfiguration.class)); + deviceProfileData.setTransportConfiguration(transportConfiguration); deviceProfile.setProfileData(deviceProfileData); deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); Assert.assertNotNull(deviceProfile); } - protected Device createDevice(LwM2MClientCredential clientCredentials) throws Exception { + protected Device createDevice(LwM2MDeviceCredentials credentials, String endpoint) throws Exception { Device device = new Device(); - device.setName("Device A"); + device.setName(endpoint); device.setDeviceProfileId(deviceProfile.getId()); device.setTenantId(tenantId); device = doPost("/api/device", device, Device.class); @@ -239,11 +414,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest doGet("/api/device/" + device.getId().getId().toString() + "/credentials", DeviceCredentials.class); Assert.assertEquals(device.getId(), deviceCredentials.getDeviceId()); deviceCredentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); - - LwM2MDeviceCredentials credentials = new LwM2MDeviceCredentials(); - credentials.setClient(clientCredentials); - credentials.setBootstrap(defaultBootstrapCredentials); - +// LwM2MDeviceCredentials credentials = getDeviceCredentials(clientCredentials, mode); deviceCredentials.setCredentialsValue(JacksonUtil.toString(credentials)); doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk()); return device; @@ -259,11 +430,11 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest this.resources = resources; } - public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint) throws Exception { + public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint, boolean isBootstrap) throws Exception { clientDestroy(); client = new LwM2MTestClient(this.executor, endpoint); int clientPort = SocketUtils.findAvailableTcpPort(); - client.init(security, coapConfig, clientPort, isRpc); + client.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs); } private void clientDestroy() { @@ -271,4 +442,54 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest client.destroy(); } } + + protected Lwm2mDeviceProfileTransportConfiguration getTransportConfiguration(String observeAttr, List bootstrapServerCredentials) { + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = new Lwm2mDeviceProfileTransportConfiguration(); + TelemetryMappingConfiguration observeAttrConfiguration = JacksonUtil.fromString(observeAttr, TelemetryMappingConfiguration.class); + OtherConfiguration clientLwM2mSettings = JacksonUtil.fromString(CLIENT_LWM2M_SETTINGS, OtherConfiguration.class); + transportConfiguration.setBootstrapServerUpdateEnable(true); + transportConfiguration.setObserveAttr(observeAttrConfiguration); + transportConfiguration.setClientLwM2mSettings(clientLwM2mSettings); + transportConfiguration.setBootstrap(bootstrapServerCredentials); + return transportConfiguration; + } + + protected List getBootstrapServerCredentialsNoSec(LwM2MProfileBootstrapConfigType bootstrapConfigType) { + List bootstrap = new ArrayList<>(); + switch (bootstrapConfigType) { + case BOTH: + bootstrap.add(getBootstrapServerCredentialNoSec(false)); + bootstrap.add(getBootstrapServerCredentialNoSec(true)); + break; + case BOOTSTRAP_ONLY: + bootstrap.add(getBootstrapServerCredentialNoSec(true)); + break; + case LWM2M_ONLY: + bootstrap.add(getBootstrapServerCredentialNoSec(false)); + break; + case NONE: + } + return bootstrap; + } + + private AbstractLwM2MBootstrapServerCredential getBootstrapServerCredentialNoSec(boolean isBootstrap) { + AbstractLwM2MBootstrapServerCredential bootstrapServerCredential = new NoSecLwM2MBootstrapServerCredential(); + bootstrapServerCredential.setServerPublicKey(""); + bootstrapServerCredential.setShortServerId(isBootstrap ? shortServerIdBs : shortServerId); + bootstrapServerCredential.setBootstrapServerIs(isBootstrap); + bootstrapServerCredential.setHost(isBootstrap ? hostBs : host); + bootstrapServerCredential.setPort(isBootstrap ? portBs : port); + return bootstrapServerCredential; + } + + protected LwM2MDeviceCredentials getDeviceCredentialsNoSec(LwM2MClientCredential clientCredentials) { + LwM2MDeviceCredentials credentials = new LwM2MDeviceCredentials(); + credentials.setClient(clientCredentials); + LwM2MBootstrapClientCredentials bootstrapCredentials = new LwM2MBootstrapClientCredentials(); + NoSecBootstrapClientCredential serverCredentials = new NoSecBootstrapClientCredential(); + bootstrapCredentials.setBootstrapServer(serverCredentials); + bootstrapCredentials.setLwm2mServer(serverCredentials); + credentials.setBootstrap(bootstrapCredentials); + return credentials; + } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java index 2d10c50bc4..532b1920b2 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java @@ -15,29 +15,34 @@ */ package org.thingsboard.server.transport.lwm2m; -import org.eclipse.californium.elements.config.Configuration; -import org.eclipse.leshan.client.object.Security; - -import static org.eclipse.californium.core.config.CoapConfig.COAP_PORT; -import static org.eclipse.californium.core.config.CoapConfig.COAP_SECURE_PORT; -import static org.eclipse.leshan.client.object.Security.noSec; - public class Lwm2mTestHelper { - // Server - public static final int SECURE_PORT = 5686; - public static final int SECURE_PORT_BS = 5688; - public static final int PORT = 5685; - public static final int PORT_BS = 5687; - public static final String HOST = "localhost"; - public static final String HOST_BS = "localhost"; - public static final int SHORT_SERVER_ID = 123; - public static final int SHORT_SERVER_ID_BS = 111; - - public static final Configuration SECURE_COAP_CONFIG = new Configuration().set(COAP_SECURE_PORT, SECURE_PORT); - public static final String SECURE_URI = "coaps://" + HOST + ":" + SECURE_PORT; - public static final Security SECURITY = noSec("coap://"+ HOST +":" + PORT, SHORT_SERVER_ID); - public static final Configuration COAP_CONFIG = new Configuration().set(COAP_PORT, PORT); +// // Server +// public static final int SECURE_PORT = 5686; +// public static final int SECURE_PORT_BS = 5688; +// +//// public static final String HOST = "localhost"; +//// public static final int PORT = 5685; +////public static final String URI = "coap://" + HOST + ":" + PORT; +//public static final String SECURE_URI = "coaps://" + HOST + ":" + SECURE_PORT; +// public static final Configuration COAP_CONFIG = new Configuration().set(EXCHANGE_LIFETIME , 200, TimeUnit.SECONDS).set(COAP_PORT, PORT).set(COAP_SECURE_PORT, SECURE_PORT); +// public static final Security SECURITY_NO_SEC = noSec(URI, SHORT_SERVER_ID); +// +// public static final int PORT_BS = 5687; +// +// public static final String HOST_BS = "localhost"; +// public static final int SHORT_SERVER_ID = 123; +// public static final int SHORT_SERVER_ID_BS = 111; +// +// +// public static final Configuration SECURE_COAP_CONFIG = COAP_CONFIG.set(COAP_SECURE_PORT, SECURE_PORT); +// public static final Configuration COAP_CONFIG_BS = new Configuration().set(COAP_PORT, PORT_BS); +// +// +// public static final String URI_BS = "coap://" + HOST_BS + ":" + PORT_BS; +// +// public static final String SECURE_URI_BS = "coaps://" + HOST_BS + ":" + SECURE_PORT_BS; + // Models public static final String[] resources = new String[]{"0.xml", "1.xml", "2.xml", "3.xml", "5.xml", "6.xml", "9.xml", "19.xml", "3303.xml"}; @@ -67,4 +72,86 @@ public class Lwm2mTestHelper { public static final String RESOURCE_ID_NAME_3_14 = "UtfOffset"; public static final String RESOURCE_ID_NAME_19_0_0 = "dataRead"; public static final String RESOURCE_ID_NAME_19_1_0 = "dataWrite"; + + public enum LwM2MClientState { + + ON_INIT(1, "onInit"), + ON_BOOTSTRAP_STARTED(1, "onBootstrapStarted"), + ON_BOOTSTRAP_SUCCESS(2, "onBootstrapSuccess"), + ON_BOOTSTRAP_FAILURE(3, "onBootstrapFailure"), + ON_BOOTSTRAP_TIMEOUT(4, "onBootstrapTimeout"), + ON_REGISTRATION_STARTED(5, "onRegistrationStarted"), + ON_REGISTRATION_SUCCESS(6, "onRegistrationSuccess"), + ON_REGISTRATION_FAILURE(7, "onRegistrationFailure"), + ON_REGISTRATION_TIMEOUT(7, "onRegistrationTimeout"), + ON_UPDATE_STARTED(8, "onUpdateStarted"), + ON_UPDATE_SUCCESS(9, "onUpdateSuccess"), + ON_UPDATE_FAILURE(10, "onUpdateFailure"), + ON_UPDATE_TIMEOUT(11, "onUpdateTimeout"), + ON_DEREGISTRATION_STARTED(12, "onDeregistrationStarted"), + ON_DEREGISTRATION_SUCCESS(13, "onDeregistrationSuccess"), + ON_DEREGISTRATION_FAILURE(14, "onDeregistrationFailure"), + ON_DEREGISTRATION_TIMEOUT(15, "onDeregistrationTimeout"), + ON_EXPECTED_ERROR(16, "onUnexpectedError"); + + public int code; + public String type; + + LwM2MClientState(int code, String type) { + this.code = code; + this.type = type; + } + + public static LwM2MClientState fromLwM2MClientStateByType(String type) { + for (LwM2MClientState to : LwM2MClientState.values()) { + if (to.type.equals(type)) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported Client State type : %s", type)); + } + + public static LwM2MClientState fromLwM2MClientStateByCode(int code) { + for (LwM2MClientState to : LwM2MClientState.values()) { + if (to.code == code) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported Client State code : %s", code)); + } + } + + public enum LwM2MProfileBootstrapConfigType { + + LWM2M_ONLY(1, "only Lwm2m Server"), + BOOTSTRAP_ONLY(2, "only Bootstrap Server"), + BOTH(3, "Lwm2m Server and Bootstrap Server"), + NONE(4, "Without Lwm2m Server and Bootstrap Server"); + + public int code; + public String type; + + LwM2MProfileBootstrapConfigType(int code, String type) { + this.code = code; + this.type = type; + } + + public static LwM2MProfileBootstrapConfigType fromLwM2MBootstrapConfigByType(String type) { + for (LwM2MProfileBootstrapConfigType to : LwM2MProfileBootstrapConfigType.values()) { + if (to.type.equals(type)) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported Profile Bootstrap Config type : %s", type)); + } + + public static LwM2MProfileBootstrapConfigType fromLwM2MBootstrapConfigByCode(int code) { + for (LwM2MProfileBootstrapConfigType to : LwM2MProfileBootstrapConfigType.values()) { + if (to.code == code) { + return to; + } + } + throw new IllegalArgumentException(String.format("Unsupported Profile Bootstrap Config code : %s", code)); + } + } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java index 9180617846..bd3ca6ef9a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -45,7 +45,9 @@ import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import static org.eclipse.californium.scandium.config.DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY; @@ -57,6 +59,25 @@ import static org.eclipse.leshan.core.LwM2mId.SECURITY; import static org.eclipse.leshan.core.LwM2mId.SERVER; import static org.eclipse.leshan.core.LwM2mId.SOFTWARE_MANAGEMENT; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.BINARY_APP_DATA_CONTAINER; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_FAILURE; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_TIMEOUT; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_FAILURE; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_TIMEOUT; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_EXPECTED_ERROR; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_INIT; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_FAILURE; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_TIMEOUT; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_UPDATE_FAILURE; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_UPDATE_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_UPDATE_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_UPDATE_TIMEOUT; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_0; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_1; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_12; @@ -79,18 +100,23 @@ public class LwM2MTestClient { private LwM2mBinaryAppDataContainer lwM2MBinaryAppDataContainer; private LwM2MLocationParams locationParams; private LwM2mTemperatureSensor lwM2MTemperatureSensor; + private LwM2MClientState clientState; + private Set clientStates; - public void init(Security security, Configuration coapConfig, int port, boolean isRpc) throws InvalidDDFFileException, IOException { + public void init(Security security, Configuration coapConfig, int port, boolean isRpc, boolean isBootstrap, int shortServerId, int shortServerIdBs) throws InvalidDDFFileException, IOException { Assert.assertNull("client already initialized", client); List models = new ArrayList<>(); for (String resourceName : resources) { models.addAll(ObjectLoader.loadDdfFile(LwM2MTestClient.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName), resourceName)); } - LwM2mModel model = new StaticModel(models); ObjectsInitializer initializer = new ObjectsInitializer(model); initializer.setInstancesForObject(SECURITY, security); - initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(123, 300)); + if (isBootstrap) { + initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerIdBs, 300)); + } else { + initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerId, 300)); + } initializer.setInstancesForObject(DEVICE, lwM2MDevice = new SimpleLwM2MDevice()); initializer.setInstancesForObject(FIRMWARE, fwLwM2MDevice = new FwLwM2MDevice()); initializer.setInstancesForObject(SOFTWARE_MANAGEMENT, swLwM2MDevice = new SwLwM2MDevice()); @@ -119,94 +145,128 @@ public class LwM2MTestClient { builder.setDecoder(new DefaultLwM2mDecoder(false)); builder.setEncoder(new DefaultLwM2mEncoder(new LwM2mValueConverterImpl(), false)); + clientState = ON_INIT; + clientStates = new HashSet<>(); + clientStates.add(clientState); client = builder.build(); LwM2mClientObserver observer = new LwM2mClientObserver() { @Override public void onBootstrapStarted(ServerIdentity bsserver, BootstrapRequest request) { - log.info("ClientObserver -> onBootstrapStarted..."); + clientState = ON_BOOTSTRAP_STARTED; + clientStates.add(clientState); +// log.info("ClientObserver -> onBootstrapStarted..."); } @Override public void onBootstrapSuccess(ServerIdentity bsserver, BootstrapRequest request) { - log.info("ClientObserver -> onBootstrapSuccess..."); + clientState = ON_BOOTSTRAP_SUCCESS; + clientStates.add(clientState); +// log.info("ClientObserver -> onBootstrapSuccess..."); } @Override public void onBootstrapFailure(ServerIdentity bsserver, BootstrapRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { - log.info("ClientObserver -> onBootstrapFailure..."); + clientState = ON_BOOTSTRAP_FAILURE; + clientStates.add(clientState); +// log.info("ClientObserver -> onBootstrapFailure..."); } @Override public void onBootstrapTimeout(ServerIdentity bsserver, BootstrapRequest request) { - log.info("ClientObserver -> onBootstrapTimeout..."); + clientState = ON_BOOTSTRAP_TIMEOUT; + clientStates.add(clientState); +// log.info("ClientObserver -> onBootstrapTimeout..."); } @Override public void onRegistrationStarted(ServerIdentity server, RegisterRequest request) { + clientState = ON_REGISTRATION_STARTED; + clientStates.add(clientState); // log.info("ClientObserver -> onRegistrationStarted... EndpointName [{}]", request.getEndpointName()); } @Override public void onRegistrationSuccess(ServerIdentity server, RegisterRequest request, String registrationID) { - log.info("ClientObserver -> onRegistrationSuccess... EndpointName [{}] [{}]", request.getEndpointName(), registrationID); + clientState = ON_REGISTRATION_SUCCESS; + clientStates.add(clientState); +// log.info("ClientObserver -> onRegistrationSuccess... EndpointName [{}] [{}]", request.getEndpointName(), registrationID); } @Override public void onRegistrationFailure(ServerIdentity server, RegisterRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { - log.info("ClientObserver -> onRegistrationFailure... ServerIdentity [{}]", server); + clientState = ON_REGISTRATION_FAILURE; + clientStates.add(clientState); +// log.info("ClientObserver -> onRegistrationFailure... ServerIdentity [{}]", server); } @Override public void onRegistrationTimeout(ServerIdentity server, RegisterRequest request) { - log.info("ClientObserver -> onRegistrationTimeout... RegisterRequest [{}]", request); + clientState = ON_REGISTRATION_TIMEOUT; + clientStates.add(clientState); +// log.info("ClientObserver -> onRegistrationTimeout... RegisterRequest [{}]", request); } @Override public void onUpdateStarted(ServerIdentity server, UpdateRequest request) { + clientState = ON_UPDATE_STARTED; + clientStates.add(clientState); // log.info("ClientObserver -> onUpdateStarted... UpdateRequest [{}]", request); } @Override public void onUpdateSuccess(ServerIdentity server, UpdateRequest request) { + clientState = ON_UPDATE_SUCCESS; + clientStates.add(clientState); // log.info("ClientObserver -> onUpdateSuccess... UpdateRequest [{}]", request); } @Override public void onUpdateFailure(ServerIdentity server, UpdateRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { - + clientState = ON_UPDATE_FAILURE; + clientStates.add(clientState); } @Override public void onUpdateTimeout(ServerIdentity server, UpdateRequest request) { - + clientState = ON_UPDATE_TIMEOUT; + clientStates.add(clientState); } @Override public void onDeregistrationStarted(ServerIdentity server, DeregisterRequest request) { - log.info("ClientObserver ->onDeregistrationStarted... DeregisterRequest [{}]", request.getRegistrationId()); + clientState = ON_DEREGISTRATION_STARTED; + clientStates.add(clientState); +// log.info("ClientObserver ->onDeregistrationStarted... DeregisterRequest [{}]", request.getRegistrationId()); } @Override public void onDeregistrationSuccess(ServerIdentity server, DeregisterRequest request) { + clientState = ON_DEREGISTRATION_SUCCESS; + clientStates.add(clientState); log.info("ClientObserver ->onDeregistrationSuccess... DeregisterRequest [{}]", request.getRegistrationId()); } @Override public void onDeregistrationFailure(ServerIdentity server, DeregisterRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { - log.info("ClientObserver ->onDeregistrationFailure... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); + clientState = ON_DEREGISTRATION_FAILURE; + clientStates.add(clientState); +// log.info("ClientObserver ->onDeregistrationFailure... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); } @Override public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request) { - log.info("ClientObserver ->onDeregistrationTimeout... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); + clientState = ON_DEREGISTRATION_TIMEOUT; + clientStates.add(clientState); +// log.info("ClientObserver ->onDeregistrationTimeout... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); } @Override public void onUnexpectedError(Throwable unexpectedError) { - + clientState = ON_EXPECTED_ERROR; + clientStates.add(clientState); } }; this.client.addObserver(observer); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java index 3095f28f28..c05e5d6dda 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java @@ -20,7 +20,8 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Test; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.kv.KvEntry; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus; @@ -46,102 +47,59 @@ import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.QUEU import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURITY; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @Slf4j public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { public static final int TIMEOUT = 30; - private final String OTA_TRANSPORT_CONFIGURATION = "{\n" + - " \"type\": \"LWM2M\",\n" + - " \"observeAttr\": {\n" + - " \"keyName\": {\n" + - " \"/5_1.0/0/3\": \"state\",\n" + - " \"/5_1.0/0/5\": \"updateResult\",\n" + - " \"/5_1.0/0/6\": \"pkgname\",\n" + - " \"/5_1.0/0/7\": \"pkgversion\",\n" + - " \"/5_1.0/0/9\": \"firmwareUpdateDeliveryMethod\",\n" + - " \"/9_1.0/0/0\": \"pkgname\",\n" + - " \"/9_1.0/0/1\": \"pkgversion\",\n" + - " \"/9_1.0/0/7\": \"updateState\",\n" + - " \"/9_1.0/0/9\": \"updateResult\"\n" + - " },\n" + - " \"observe\": [\n" + - " \"/5_1.0/0/3\",\n" + - " \"/5_1.0/0/5\",\n" + - " \"/5_1.0/0/6\",\n" + - " \"/5_1.0/0/7\",\n" + - " \"/5_1.0/0/9\",\n" + - " \"/9_1.0/0/0\",\n" + - " \"/9_1.0/0/1\",\n" + - " \"/9_1.0/0/7\",\n" + - " \"/9_1.0/0/9\"\n" + - " ],\n" + - " \"attribute\": [],\n" + - " \"telemetry\": [\n" + - " \"/5_1.0/0/3\",\n" + - " \"/5_1.0/0/5\",\n" + - " \"/5_1.0/0/6\",\n" + - " \"/5_1.0/0/7\",\n" + - " \"/5_1.0/0/9\",\n" + - " \"/9_1.0/0/0\",\n" + - " \"/9_1.0/0/1\",\n" + - " \"/9_1.0/0/7\",\n" + - " \"/9_1.0/0/9\"\n" + - " ],\n" + - " \"attributeLwm2m\": {}\n" + - " },\n" + - " \"bootstrapServerUpdateEnable\": true,\n" + - " \"bootstrap\": [\n" + - " {\n" + - " \"host\": \"0.0.0.0\",\n" + - " \"port\": 5687,\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"NO_SEC\",\n" + - " \"shortServerId\": 111,\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": true,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " },\n" + - " {\n" + - " \"host\": \"0.0.0.0\",\n" + - " \"port\": 5685,\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"NO_SEC\",\n" + - " \"shortServerId\": 123,\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": false,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " }\n" + - " ],\n" + - " \"clientLwM2mSettings\": {\n" + - " \"edrxCycle\": null,\n" + - " \"powerMode\": \"DRX\",\n" + - " \"fwUpdateResource\": null,\n" + - " \"fwUpdateStrategy\": 1,\n" + - " \"psmActivityTimer\": null,\n" + - " \"swUpdateResource\": null,\n" + - " \"swUpdateStrategy\": 1,\n" + - " \"pagingTransmissionWindow\": null,\n" + - " \"clientOnlyObserveAfterConnect\": 1\n" + - " }\n" + - "}"; - @Test + protected final String OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA = + + " {\n" + + " \"keyName\": {\n" + + " \"/5_1.0/0/3\": \"state\",\n" + + " \"/5_1.0/0/5\": \"updateResult\",\n" + + " \"/5_1.0/0/6\": \"pkgname\",\n" + + " \"/5_1.0/0/7\": \"pkgversion\",\n" + + " \"/5_1.0/0/9\": \"firmwareUpdateDeliveryMethod\",\n" + + " \"/9_1.0/0/0\": \"pkgname\",\n" + + " \"/9_1.0/0/1\": \"pkgversion\",\n" + + " \"/9_1.0/0/7\": \"updateState\",\n" + + " \"/9_1.0/0/9\": \"updateResult\"\n" + + " },\n" + + " \"observe\": [\n" + + " \"/5_1.0/0/3\",\n" + + " \"/5_1.0/0/5\",\n" + + " \"/5_1.0/0/6\",\n" + + " \"/5_1.0/0/7\",\n" + + " \"/5_1.0/0/9\",\n" + + " \"/9_1.0/0/0\",\n" + + " \"/9_1.0/0/1\",\n" + + " \"/9_1.0/0/7\",\n" + + " \"/9_1.0/0/9\"\n" + + " ],\n" + + " \"attribute\": [],\n" + + " \"telemetry\": [\n" + + " \"/5_1.0/0/3\",\n" + + " \"/5_1.0/0/5\",\n" + + " \"/5_1.0/0/6\",\n" + + " \"/5_1.0/0/7\",\n" + + " \"/5_1.0/0/9\",\n" + + " \"/9_1.0/0/0\",\n" + + " \"/9_1.0/0/1\",\n" + + " \"/9_1.0/0/7\",\n" + + " \"/9_1.0/0/9\"\n" + + " ],\n" + + " \"attributeLwm2m\": {}\n" + + " }"; + @Test public void testFirmwareUpdateWithClientWithoutFirmwareOtaInfoFromProfile() throws Exception { - createDeviceProfile(TRANSPORT_CONFIGURATION); - NoSecClientCredential credentials = createNoSecClientCredentials(this.CLIENT_ENDPOINT_WITHOUT_FW_INFO); - final Device device = createDevice(credentials); - createNewClient(SECURITY, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITH_PARAMS, getBootstrapServerCredentialsNoSec(NONE)); + createDeviceProfile(transportConfiguration); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_WITHOUT_FW_INFO)); + final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO, false); Thread.sleep(1000); @@ -163,10 +121,11 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { @Test public void testFirmwareUpdateByObject5() throws Exception { - createDeviceProfile(OTA_TRANSPORT_CONFIGURATION); - NoSecClientCredential credentials = createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA5); - final Device device = createDevice(credentials); - createNewClient(SECURITY, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA, getBootstrapServerCredentialsNoSec(NONE)); + createDeviceProfile(transportConfiguration); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA5)); + final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA5); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5, false); Thread.sleep(1000); @@ -200,10 +159,11 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { * */ @Test public void testSoftwareUpdateByObject9() throws Exception { - createDeviceProfile(OTA_TRANSPORT_CONFIGURATION); - NoSecClientCredential credentials = createNoSecClientCredentials(CLIENT_ENDPOINT_OTA9); - final Device device = createDevice(credentials); - createNewClient(SECURITY, COAP_CONFIG, false, CLIENT_ENDPOINT_OTA9); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITH_PARAMS_OTA, getBootstrapServerCredentialsNoSec(NONE)); + createDeviceProfile(transportConfiguration); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA9)); + final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA9); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA9, false); Thread.sleep(1000); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index 0252c77071..251fccb450 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -17,9 +17,11 @@ package org.thingsboard.server.transport.lwm2m.rpc; import org.junit.Before; import org.thingsboard.server.common.data.Device; -import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; + import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -31,8 +33,6 @@ import static org.eclipse.leshan.core.LwM2mId.FIRMWARE; import static org.eclipse.leshan.core.LwM2mId.SERVER; import static org.eclipse.leshan.core.LwM2mId.SOFTWARE_MANAGEMENT; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.BINARY_APP_DATA_CONTAINER; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURITY; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.TEMPERATURE_SENSOR; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_ID_0; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_INSTANCE_ID_0; @@ -45,12 +45,12 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_14; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_9; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.resources; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @DaoSqlTest public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { - protected String RPC_TRANSPORT_CONFIGURATION; - + protected String OBSERVE_ATTRIBUTES_WITH_PARAMS_RPC; protected String deviceId; public Set expectedObjects; public Set expectedObjectIdVers; @@ -71,7 +71,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg protected static AtomicInteger endpointSequence = new AtomicInteger(); protected static String DEVICE_ENDPOINT_RPC_PREF = "deviceEndpointRpc"; - public AbstractRpcLwM2MIntegrationTest(){ + public AbstractRpcLwM2MIntegrationTest() { setResources(resources); } @@ -79,7 +79,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg public void beforeTest() throws Exception { String endpoint = DEVICE_ENDPOINT_RPC_PREF + endpointSequence.incrementAndGet(); init(); - createNewClient (SECURITY, COAP_CONFIG, true, endpoint); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, true, endpoint, false); expectedObjects = ConcurrentHashMap.newKeySet(); expectedObjectIdVers = ConcurrentHashMap.newKeySet(); @@ -103,8 +103,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg String ver_Id_0 = client.getClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_0).version; if ("1.0".equals(ver_Id_0)) { objectIdVer_0 = "/" + OBJECT_ID_0; - } - else { + } else { objectIdVer_0 = "/" + OBJECT_ID_0 + "_" + ver_Id_0; } objectIdVer_2 = (String) expectedObjectIdVers.stream().filter(path -> ((String) path).contains("/" + ACCESS_CONTROL)).findFirst().get(); @@ -116,86 +115,44 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg objectInstanceIdVer_5 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + FIRMWARE)).findFirst().get(); objectInstanceIdVer_9 = (String) expectedObjectIdVerInstances.stream().filter(path -> ((String) path).contains("/" + SOFTWARE_MANAGEMENT)).findFirst().get(); - RPC_TRANSPORT_CONFIGURATION = "{\n" + - " \"type\": \"LWM2M\",\n" + - " \"observeAttr\": {\n" + - " \"keyName\": {\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\": \"" + RESOURCE_ID_NAME_3_9 + "\",\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\": \"" + RESOURCE_ID_NAME_3_14 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\": \"" + RESOURCE_ID_NAME_19_0_0 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "\": \"" + RESOURCE_ID_NAME_19_1_0 + "\"\n" + - " },\n" + - " \"observe\": [\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\"\n" + - " ],\n" + - " \"attribute\": [\n" + - " ],\n" + - " \"telemetry\": [\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\",\n" + - " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\",\n" + - " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "\"\n" + - " ],\n" + - " \"attributeLwm2m\": {}\n" + - " },\n" + - " \"bootstrapServerUpdateEnable\": true,\n" + - " \"bootstrap\": [\n" + + OBSERVE_ATTRIBUTES_WITH_PARAMS_RPC = " {\n" + - " \"host\": \"0.0.0.0\",\n" + - " \"port\": 5687,\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"NO_SEC\",\n" + - " \"shortServerId\": 111,\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": true,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " },\n" + - " {\n" + - " \"host\": \"0.0.0.0\",\n" + - " \"port\": 5685,\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"NO_SEC\",\n" + - " \"shortServerId\": 123,\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": false,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " }\n" + - " ],\n" + - " \"clientLwM2mSettings\": {\n" + - " \"edrxCycle\": null,\n" + - " \"powerMode\": \"DRX\",\n" + - " \"fwUpdateResource\": null,\n" + - " \"fwUpdateStrategy\": 1,\n" + - " \"psmActivityTimer\": null,\n" + - " \"swUpdateResource\": null,\n" + - " \"swUpdateStrategy\": 1,\n" + - " \"pagingTransmissionWindow\": null,\n" + - " \"clientOnlyObserveAfterConnect\": 1\n" + - " }\n" + - "}"; - createDeviceProfile(RPC_TRANSPORT_CONFIGURATION); + " \"keyName\": {\n" + + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\": \"" + RESOURCE_ID_NAME_3_9 + "\",\n" + + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\": \"" + RESOURCE_ID_NAME_3_14 + "\",\n" + + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\": \"" + RESOURCE_ID_NAME_19_0_0 + "\",\n" + + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "\": \"" + RESOURCE_ID_NAME_19_1_0 + "\"\n" + + " },\n" + + " \"observe\": [\n" + + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\",\n" + + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\"\n" + + " ],\n" + + " \"attribute\": [\n" + + " ],\n" + + " \"telemetry\": [\n" + + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_9 + "\",\n" + + " \"" + objectIdVer_3 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_14 + "\",\n" + + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_0 + "/" + RESOURCE_ID_0 + "\",\n" + + " \"" + objectIdVer_19 + "/" + OBJECT_INSTANCE_ID_1 + "/" + RESOURCE_ID_0 + "\"\n" + + " ],\n" + + " \"attributeLwm2m\": {}\n" + + " }"; + + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITH_PARAMS_RPC, getBootstrapServerCredentialsNoSec(NONE)); + createDeviceProfile(transportConfiguration); - NoSecClientCredential credentials = createNoSecClientCredentials(endpoint); - final Device device = createDevice(credentials); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(endpoint)); + final Device device = createDevice(deviceCredentials, endpoint); deviceId = device.getId().getId().toString(); client.start(); - } + } protected String pathIdVerToObjectId(String pathIdVer) { - if (pathIdVer.contains("_")){ - String [] objVer = pathIdVer.split("/"); - objVer[1] = objVer[1].split("_")[0]; - return String.join("/", objVer); + if (pathIdVer.contains("_")) { + String[] objVer = pathIdVer.split("/"); + objVer[1] = objVer[1].split("_")[0]; + return String.join("/", objVer); } return pathIdVer; } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index c4108a2921..1e22748676 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -15,10 +15,25 @@ */ package org.thingsboard.server.transport.lwm2m.security; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Base64; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredentials; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecBootstrapClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKBootstrapClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKBootstrapClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.X509BootstrapClientCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.PSKLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.RPKLwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.X509LwM2MBootstrapServerCredential; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; +import org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType; import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; import java.io.IOException; @@ -27,28 +42,39 @@ import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; @DaoSqlTest +@Slf4j public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { - protected final String CREDENTIALS_PATH = "lwm2m/credentials/"; // client public key or id used for PSK + protected final String CREDENTIALS_PATH = "lwm2m/credentials/"; // client public key or id used for PSK // Get keys PSK - protected final String CLIENT_PSK_IDENTITY = "SOME_PSK_ID"; // client public key or id used for PSK + protected final String CLIENT_PSK_IDENTITY = "SOME_PSK_ID"; // client public key or id used for PSK + protected final String CLIENT_PSK_IDENTITY_BS = "SOME_PSK_ID_BS"; // client public key or id used for PSK protected final String CLIENT_PSK_KEY = "73656372657450534b73656372657450"; // client private/secret key used for PSK // Server protected static final String SERVER_JKS_FOR_TEST = "lwm2mserver"; protected static final String SERVER_STORE_PWD = "server_ks_password"; protected static final String SERVER_CERT_ALIAS = "server"; -protected final X509Certificate serverX509Cert; // server certificate signed by rootCA - protected final PublicKey serverPublicKeyFromCert; // server public key used for RPK + protected static final String SERVER_CERT_ALIAS_BS = "bootstrap"; + protected final X509Certificate serverX509Cert; // server certificate signed by rootCA + protected final X509Certificate serverX509CertBs; // serverBs certificate signed by rootCA + protected final PublicKey serverPublicKeyFromCert; // server public key used for RPK + protected final PublicKey serverPublicKeyFromCertBs; // serverBs public key used for RPK // Client protected LwM2MTestClient client; protected static final String CLIENT_ENDPOINT_NO_SEC = "LwNoSec00000000"; + protected static final String CLIENT_ENDPOINT_NO_SEC_BS = "LwNoSecBs00000000"; protected static final String CLIENT_ENDPOINT_PSK = "LwPsk00000000"; + protected static final String CLIENT_ENDPOINT_PSK_BS = "LwPskBs00000000"; protected static final String CLIENT_ENDPOINT_RPK = "LwRpk00000000"; + protected static final String CLIENT_ENDPOINT_RPK_BS = "LwRpkBs00000000"; protected static final String CLIENT_ENDPOINT_X509_TRUST = "LwX50900000000"; protected static final String CLIENT_ENDPOINT_X509_TRUST_NO = "LwX509TrustNo"; protected static final String CLIENT_JKS_FOR_TEST = "lwm2mclient"; @@ -56,19 +82,16 @@ protected final X509Certificate serverX509Cert; protected static final String CLIENT_ALIAS_CERT_TRUST = "client_alias_00000000"; protected static final String CLIENT_ALIAS_CERT_TRUST_NO = "client_alias_trust_no"; - protected final X509Certificate clientX509CertTrust; // client certificate signed by intermediate, rootCA with a good CN ("host name") - protected final PrivateKey clientPrivateKeyFromCertTrust; // client private key used for X509 and RPK - protected final PublicKey clientPublicKeyFromCertTrust; // client public key used for RPK - protected final X509Certificate clientX509CertTrustNo; // client certificate signed by intermediate, rootCA with a good CN ("host name") - protected final PrivateKey clientPrivateKeyFromCertTrustNo; // client private key used for X509 and RPK - protected final PublicKey clientPublicKeyFromCertTrustNo; // client public key used for RPK - private final String[] RESOURCES_SECURITY = new String[]{"1.xml", "2.xml", "3.xml", "5.xml", "9.xml"}; + protected final X509Certificate clientX509CertTrust; // client certificate signed by intermediate, rootCA with a good CN ("host name") + protected final PrivateKey clientPrivateKeyFromCertTrust; // client private key used for X509 and RPK + protected final X509Certificate clientX509CertTrustNo; // client certificate signed by intermediate, rootCA with a good CN ("host name") + protected final PrivateKey clientPrivateKeyFromCertTrustNo; // client private key used for X509 and RPK + private final String[] RESOURCES_SECURITY = new String[]{"1.xml", "2.xml", "3.xml", "5.xml", "9.xml"}; private final LwM2MBootstrapClientCredentials defaultBootstrapCredentials; - public AbstractSecurityLwM2MIntegrationTest() { // create client credentials setResources(this.RESOURCES_SECURITY); @@ -82,12 +105,9 @@ protected final X509Certificate serverX509Cert; // Trust clientPrivateKeyFromCertTrust = (PrivateKey) clientKeyStore.getKey(CLIENT_ALIAS_CERT_TRUST, clientKeyStorePwd); clientX509CertTrust = (X509Certificate) clientKeyStore.getCertificate(CLIENT_ALIAS_CERT_TRUST); - clientPublicKeyFromCertTrust = clientX509CertTrust != null ? clientX509CertTrust.getPublicKey() : null; // No trust clientPrivateKeyFromCertTrustNo = (PrivateKey) clientKeyStore.getKey(CLIENT_ALIAS_CERT_TRUST_NO, clientKeyStorePwd); clientX509CertTrustNo = (X509Certificate) clientKeyStore.getCertificate(CLIENT_ALIAS_CERT_TRUST_NO); - clientPublicKeyFromCertTrustNo = clientX509CertTrustNo != null ? clientX509CertTrustNo.getPublicKey() : null; - } catch (GeneralSecurityException | IOException e) { throw new RuntimeException(e); } @@ -103,6 +123,9 @@ protected final X509Certificate serverX509Cert; serverX509Cert = (X509Certificate) serverKeyStore.getCertificate(SERVER_CERT_ALIAS); serverPublicKeyFromCert = serverX509Cert.getPublicKey(); + serverX509CertBs = (X509Certificate) serverKeyStore.getCertificate(SERVER_CERT_ALIAS_BS); + serverPublicKeyFromCertBs = serverX509CertBs.getPublicKey(); + } catch (GeneralSecurityException | IOException e) { throw new RuntimeException(e); } @@ -114,4 +137,125 @@ protected final X509Certificate serverX509Cert; defaultBootstrapCredentials.setBootstrapServer(serverCredentials); defaultBootstrapCredentials.setLwm2mServer(serverCredentials); } + + + protected List getBootstrapServerCredentialsSecure(LwM2MSecurityMode mode, LwM2MProfileBootstrapConfigType bootstrapConfigType) { + List bootstrap = new ArrayList<>(); + switch (bootstrapConfigType) { + case BOTH: + bootstrap.add(getBootstrapServerCredential(mode, false)); + bootstrap.add(getBootstrapServerCredential(mode, true)); + break; + case BOOTSTRAP_ONLY: + bootstrap.add(getBootstrapServerCredential(mode, true)); + break; + case LWM2M_ONLY: + bootstrap.add(getBootstrapServerCredential(mode, false)); + break; + case NONE: + } + return bootstrap; + } + + private AbstractLwM2MBootstrapServerCredential getBootstrapServerCredential(LwM2MSecurityMode mode, boolean isBootstrap) { + AbstractLwM2MBootstrapServerCredential bootstrapServerCredential; + switch (mode) { + case PSK: + bootstrapServerCredential = new PSKLwM2MBootstrapServerCredential(); + bootstrapServerCredential.setServerPublicKey(""); + break; + case RPK: + bootstrapServerCredential = new RPKLwM2MBootstrapServerCredential(); + if (isBootstrap) { + bootstrapServerCredential.setServerPublicKey(Base64.encodeBase64String(serverPublicKeyFromCertBs.getEncoded())); + } else { + bootstrapServerCredential.setServerPublicKey(Base64.encodeBase64String(serverPublicKeyFromCert.getEncoded())); + } + break; + case X509: + bootstrapServerCredential = new X509LwM2MBootstrapServerCredential(); + try { + if (isBootstrap) { + bootstrapServerCredential.setServerPublicKey(Base64.encodeBase64String(serverX509CertBs.getEncoded())); + } else { + bootstrapServerCredential.setServerPublicKey(Base64.encodeBase64String(serverX509Cert.getEncoded())); + } + } catch (CertificateEncodingException e) { + e.printStackTrace(); + } + break; + default: + throw new IllegalStateException("Unexpected value: " + mode); + } + bootstrapServerCredential.setShortServerId(isBootstrap ? shortServerIdBs : shortServerId); + bootstrapServerCredential.setBootstrapServerIs(isBootstrap); + bootstrapServerCredential.setHost(isBootstrap ? hostBs : host); + bootstrapServerCredential.setPort(isBootstrap ? securityPortBs : securityPort); + return bootstrapServerCredential; + } + + + protected LwM2MDeviceCredentials getDeviceCredentialsSecure(LwM2MClientCredential clientCredentials, + PrivateKey privateKey, + X509Certificate certificate, + LwM2MSecurityMode mode) { + LwM2MDeviceCredentials credentials = new LwM2MDeviceCredentials(); + credentials.setClient(clientCredentials); + LwM2MBootstrapClientCredentials bootstrapCredentials; + switch (mode) { + case PSK: + bootstrapCredentials = getBootstrapClientCredentialsPsk(clientCredentials); + break; + case RPK: + bootstrapCredentials = getBootstrapClientCredentialsRpk(certificate, privateKey); + break; + case X509: + bootstrapCredentials = getBootstrapClientCredentialsX509(certificate, privateKey); + break; + default: + throw new IllegalStateException("Unexpected value: " + mode); + } + credentials.setBootstrap(bootstrapCredentials); + return credentials; + } + + private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsPsk(LwM2MClientCredential clientCredentials) { + LwM2MBootstrapClientCredentials bootstrapCredentials = new LwM2MBootstrapClientCredentials(); + PSKBootstrapClientCredential serverCredentials = new PSKBootstrapClientCredential(); + if (clientCredentials != null) { + serverCredentials.setClientSecretKey(((PSKClientCredential) clientCredentials).getKey()); + serverCredentials.setClientPublicKeyOrId(((PSKClientCredential) clientCredentials).getIdentity()); + } + bootstrapCredentials.setBootstrapServer(serverCredentials); + bootstrapCredentials.setLwm2mServer(serverCredentials); + return bootstrapCredentials; + } + + private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsRpk(X509Certificate certificate, PrivateKey privateKey) { + LwM2MBootstrapClientCredentials bootstrapCredentials = new LwM2MBootstrapClientCredentials(); + RPKBootstrapClientCredential serverCredentials = new RPKBootstrapClientCredential(); + if (certificate != null && certificate.getPublicKey() != null && privateKey != null) { + serverCredentials.setClientPublicKeyOrId(Base64.encodeBase64String(certificate.getPublicKey().getEncoded())); + serverCredentials.setClientSecretKey(Base64.encodeBase64String(privateKey.getEncoded())); + } + bootstrapCredentials.setBootstrapServer(serverCredentials); + bootstrapCredentials.setLwm2mServer(serverCredentials); + return bootstrapCredentials; + } + + private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsX509(X509Certificate certificate, PrivateKey privateKey) { + LwM2MBootstrapClientCredentials bootstrapCredentials = new LwM2MBootstrapClientCredentials(); + X509BootstrapClientCredential serverCredentials = new X509BootstrapClientCredential(); + if (certificate != null) { + try { + serverCredentials.setClientPublicKeyOrId(Base64.encodeBase64String(certificate.getEncoded())); + serverCredentials.setClientSecretKey(Base64.encodeBase64String(privateKey.getEncoded())); + } catch (CertificateEncodingException e) { + log.error("Client`s certificate [{}] is bad. [{}]", certificate, e.getMessage()); + } + } + bootstrapCredentials.setBootstrapServer(serverCredentials); + bootstrapCredentials.setLwm2mServer(serverCredentials); + return bootstrapCredentials; + } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java index c324480e17..56874f57aa 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java @@ -15,21 +15,41 @@ */ package org.thingsboard.server.transport.lwm2m.security.sql; -import lombok.extern.slf4j.Slf4j; +import org.eclipse.leshan.client.object.Security; import org.junit.Test; -import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURITY; +import static org.eclipse.leshan.client.object.Security.noSecBootstap; +import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; -@Slf4j public class NoSecLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { + //Lwm2m only @Test - public void testConnectAndObserveTelemetry() throws Exception { - NoSecClientCredential clientCredentials = createNoSecClientCredentials(CLIENT_ENDPOINT_NO_SEC); - super.basicTestConnectionObserveTelemetry(SECURITY, clientCredentials, COAP_CONFIG, CLIENT_ENDPOINT_NO_SEC); + public void testWithNoSecConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC; + LwM2MDeviceCredentials clientCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); + super.basicTestConnectionObserveTelemetry(SECURITY_NO_SEC, clientCredentials, COAP_CONFIG, clientEndpoint); } + // Bootstrap + Lwm2m + @Test + public void testWithNoSecConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS; + Security securityBs = noSecBootstap(URI_BS); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); + this.basicTestConnection(securityBs, + deviceCredentials, + COAP_CONFIG_BS, + clientEndpoint, + transportConfiguration, + "await on client state (NoSecBS two section)", + expectedStatusesRegistrationBsSuccess, + true, + NO_SEC); + } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index f93ab67db9..9afa25c0b3 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -18,28 +18,70 @@ package org.thingsboard.server.transport.lwm2m.security.sql; import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.core.util.Hex; import org.junit.Test; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; import java.nio.charset.StandardCharsets; import static org.eclipse.leshan.client.object.Security.psk; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_URI; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SHORT_SERVER_ID; +import static org.eclipse.leshan.client.object.Security.pskBootstrap; +import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.PSK; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { + //Lwm2m only @Test - public void testConnectWithPSKAndObserveTelemetry() throws Exception { + public void testWithPskConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_PSK; + String identity = CLIENT_PSK_IDENTITY; + String keyPsk = CLIENT_PSK_KEY; PSKClientCredential clientCredentials = new PSKClientCredential(); - clientCredentials.setEndpoint(CLIENT_ENDPOINT_PSK); - clientCredentials.setKey(CLIENT_PSK_KEY); - clientCredentials.setIdentity(CLIENT_PSK_IDENTITY); - Security security = psk(SECURE_URI, - SHORT_SERVER_ID, - CLIENT_PSK_IDENTITY.getBytes(StandardCharsets.UTF_8), - Hex.decodeHex(CLIENT_PSK_KEY.toCharArray())); - super.basicTestConnectionObserveTelemetry(security, clientCredentials, SECURE_COAP_CONFIG, CLIENT_ENDPOINT_PSK); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setIdentity(identity); + clientCredentials.setKey(keyPsk); + Security securityBs = psk(SECURE_URI, + shortServerId, + identity.getBytes(StandardCharsets.UTF_8), + Hex.decodeHex(keyPsk.toCharArray())); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); + this.basicTestConnection(securityBs, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (Psk_Lwm2m)", + expectedStatusesRegistrationLwm2mSuccess, + false, + PSK); + } + + // Bootstrap + Lwm2m + @Test + public void testWithPskConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_PSK_BS; + String identity = CLIENT_PSK_IDENTITY_BS; + String keyPsk = CLIENT_PSK_KEY; + PSKClientCredential clientCredentials = new PSKClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setIdentity(identity); + clientCredentials.setKey(keyPsk); + Security securityBs = pskBootstrap(SECURE_URI_BS, + identity.getBytes(StandardCharsets.UTF_8), + Hex.decodeHex(keyPsk.toCharArray())); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); + this.basicTestConnection(securityBs, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (PskBS two section)", + expectedStatusesRegistrationBsSuccess, + true, + PSK); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index 880d436e69..a28d72117a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -15,30 +15,74 @@ */ package org.thingsboard.server.transport.lwm2m.security.sql; +import org.apache.commons.codec.binary.Base64; import org.eclipse.leshan.client.object.Security; import org.junit.Test; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredential; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; -import org.apache.commons.codec.binary.Base64;; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; import static org.eclipse.leshan.client.object.Security.rpk; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_URI; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SHORT_SERVER_ID; +import static org.eclipse.leshan.client.object.Security.rpkBootstrap; +import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.RPK; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { + //Lwm2m only @Test - public void testConnectWithRPKAndObserveTelemetry() throws Exception { - RPKClientCredential rpkClientCredentials = new RPKClientCredential(); - rpkClientCredentials.setEndpoint(CLIENT_ENDPOINT_RPK); - rpkClientCredentials.setKey(new String(Base64.encodeBase64(clientPublicKeyFromCertTrust.getEncoded()))); - Security security = rpk(SECURE_URI, - SHORT_SERVER_ID, - clientPublicKeyFromCertTrust.getEncoded(), - clientPrivateKeyFromCertTrust.getEncoded(), - serverPublicKeyFromCert.getEncoded()); - super.basicTestConnectionObserveTelemetry(security, rpkClientCredentials, SECURE_COAP_CONFIG, CLIENT_ENDPOINT_RPK); + public void testWithRpkConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_RPK; + X509Certificate certificate = clientX509CertTrust; + PrivateKey privateKey = clientPrivateKeyFromCertTrust; + RPKClientCredential clientCredentials = new RPKClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setKey(Base64.encodeBase64String(certificate.getPublicKey().getEncoded())); + Security securityBs = rpk(SECURE_URI, + shortServerId, + certificate.getPublicKey().getEncoded(), + privateKey.getEncoded(), + serverX509Cert.getPublicKey().getEncoded()); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, RPK); + this.basicTestConnection(securityBs, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (Rpk_Lwm2m)", + expectedStatusesRegistrationLwm2mSuccess, + false, + RPK); + } + + // Bootstrap + Lwm2m + @Test + public void testWithRpkConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_RPK_BS; + X509Certificate certificate = clientX509CertTrust; + PrivateKey privateKey = clientPrivateKeyFromCertTrust; + RPKClientCredential clientCredentials = new RPKClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setKey(Base64.encodeBase64String(certificate.getPublicKey().getEncoded())); + Security securityBs = rpkBootstrap(SECURE_URI_BS, + certificate.getPublicKey().getEncoded(), + privateKey.getEncoded(), + serverX509CertBs.getPublicKey().getEncoded()); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, clientPrivateKeyFromCertTrust, certificate, RPK); + this.basicTestConnection(securityBs, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (RpkBS two section)", + expectedStatusesRegistrationBsSuccess, + true, + RPK); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index c7cc24d7ee..1281adc36a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -17,27 +17,72 @@ package org.thingsboard.server.transport.lwm2m.security.sql; import org.eclipse.leshan.client.object.Security; import org.junit.Test; +import org.springframework.util.Base64Utils; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential; -import org.thingsboard.server.common.transport.util.SslUtil; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + import static org.eclipse.leshan.client.object.Security.x509; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_URI; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SHORT_SERVER_ID; +import static org.eclipse.leshan.client.object.Security.x509Bootstrap; +import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { + //Lwm2m only @Test - public void testConnectWithCertAndObserveTelemetry() throws Exception { - X509ClientCredential credentials = new X509ClientCredential(); - credentials.setEndpoint(CLIENT_ENDPOINT_X509_TRUST_NO); - credentials.setCert(SslUtil.getCertificateString(clientX509CertTrustNo)); + public void testWithX509NoTrustConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO; + X509Certificate certificate = clientX509CertTrustNo; + PrivateKey privateKey = clientPrivateKeyFromCertTrustNo; + X509ClientCredential clientCredentials = new X509ClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setCert(Base64Utils.encodeToString(certificate.getEncoded())); Security security = x509(SECURE_URI, - SHORT_SERVER_ID, - clientX509CertTrustNo.getEncoded(), - clientPrivateKeyFromCertTrustNo.getEncoded(), + shortServerId, + certificate.getEncoded(), + privateKey.getEncoded(), serverX509Cert.getEncoded()); - super.basicTestConnectionObserveTelemetry(security, credentials, SECURE_COAP_CONFIG, CLIENT_ENDPOINT_X509_TRUST_NO); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + this.basicTestConnection(security, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (X509_Trust_Lwm2m)", + expectedStatusesRegistrationLwm2mSuccess, + false, + X509); + } + + // Bootstrap + Lwm2m + @Test + public void testWithX509NoTrustConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO; + X509Certificate certificate = clientX509CertTrustNo; + PrivateKey privateKey = clientPrivateKeyFromCertTrustNo; + X509ClientCredential clientCredentials = new X509ClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setCert(Base64Utils.encodeToString(certificate.getEncoded())); + Security security = x509Bootstrap(SECURE_URI_BS, + certificate.getEncoded(), + privateKey.getEncoded(), + serverX509CertBs.getEncoded()); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + this.basicTestConnection(security, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (X509NoTrust two section)", + expectedStatusesRegistrationBsSuccess, + true, + X509); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java index d59f6ee4ea..40f094a96a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java @@ -17,26 +17,71 @@ package org.thingsboard.server.transport.lwm2m.security.sql; import org.eclipse.leshan.client.object.Security; import org.junit.Test; +import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + import static org.eclipse.leshan.client.object.Security.x509; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_COAP_CONFIG; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SECURE_URI; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.SHORT_SERVER_ID; +import static org.eclipse.leshan.client.object.Security.x509Bootstrap; +import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { + //Lwm2m only @Test - public void testConnectAndObserveTelemetry() throws Exception { - X509ClientCredential credentials = new X509ClientCredential(); - credentials.setEndpoint(CLIENT_ENDPOINT_X509_TRUST); + public void testWithX509TrustConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST; + X509Certificate certificate = clientX509CertTrust; + PrivateKey privateKey = clientPrivateKeyFromCertTrust; + X509ClientCredential clientCredentials = new X509ClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setCert(""); Security security = x509(SECURE_URI, - SHORT_SERVER_ID, - clientX509CertTrust.getEncoded(), - clientPrivateKeyFromCertTrust.getEncoded(), + shortServerId, + certificate.getEncoded(), + privateKey.getEncoded(), serverX509Cert.getEncoded()); - super.basicTestConnectionObserveTelemetry(security, credentials, SECURE_COAP_CONFIG, CLIENT_ENDPOINT_X509_TRUST); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + this.basicTestConnection(security, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (X509_Trust_Lwm2m)", + expectedStatusesRegistrationLwm2mSuccess, + false, + X509); } + // Bootstrap + Lwm2m + @Test + public void testWithX509TrustConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST; + X509Certificate certificate = clientX509CertTrust; + PrivateKey privateKey = clientPrivateKeyFromCertTrust; + X509ClientCredential clientCredentials = new X509ClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setCert(""); + Security security = x509Bootstrap(SECURE_URI_BS, + certificate.getEncoded(), + privateKey.getEncoded(), + serverX509CertBs.getEncoded()); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + this.basicTestConnection(security, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + "await on client state (X509Trust two section)", + expectedStatusesRegistrationBsSuccess, + true, + X509); + } } diff --git a/application/src/test/resources/application-test.properties b/application/src/test/resources/application-test.properties index 7f7cb6e8b9..d919319096 100644 --- a/application/src/test/resources/application-test.properties +++ b/application/src/test/resources/application-test.properties @@ -1,20 +1,12 @@ transport.lwm2m.server.security.credentials.enabled=true transport.lwm2m.server.security.credentials.type=KEYSTORE transport.lwm2m.server.security.credentials.keystore.store_file=lwm2m/credentials/lwm2mserver.jks -#transport.lwm2m.server.security.credentials.keystore.store_password=server -#transport.lwm2m.server.security.credentials.keystore.key_alias=server -#transport.lwm2m.server.security.credentials.keystore.key_password=server -transport.lwm2m.bootstrap.enabled=false transport.lwm2m.bootstrap.security.credentials.enabled=true transport.lwm2m.bootstrap.security.credentials.type=KEYSTORE transport.lwm2m.bootstrap.security.credentials.keystore.store_file=lwm2m/credentials/lwm2mserver.jks -#transport.lwm2m.bootstrap.security.credentials.keystore.store_password=server -#transport.lwm2m.bootstrap.security.credentials.keystore.key_alias=server -#transport.lwm2m.bootstrap.security.credentials.keystore.key_password=server transport.lwm2m.security.trust-credentials.enabled=true transport.lwm2m.security.trust-credentials.type=KEYSTORE transport.lwm2m.security.trust-credentials.keystore.store_file=lwm2m/credentials/lwm2mtruststorechain.jks -#transport.lwm2m.security.trust-credentials.keystore.store_password=server edges.enabled=true edges.storage.no_read_records_sleep=500 diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java index 0582ff5450..0bcf65fd70 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java @@ -33,6 +33,8 @@ import org.eclipse.leshan.server.bootstrap.BootstrapSession; import org.eclipse.leshan.server.bootstrap.BootstrapTaskProvider; import org.eclipse.leshan.server.bootstrap.BootstrapUtil; +import java.math.BigInteger; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -43,6 +45,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.stream.Collectors; +import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; import static org.eclipse.leshan.server.bootstrap.BootstrapUtil.toWriteRequest; @Slf4j @@ -164,9 +167,14 @@ public class LwM2MBootstrapConfigStoreTaskProvider implements BootstrapTaskProvi protected void findServerInstanceId(BootstrapReadResponse readResponse) { this.serverInstances = new HashMap<>(); - ((LwM2mObject) readResponse.getContent()).getInstances().values().forEach(instance -> { - serverInstances.put(((Long) instance.getResource(0).getValue()).intValue(), instance.getId()); - }); + try { + ((LwM2mObject) readResponse.getContent()).getInstances().values().forEach(instance -> { + Integer shortId = OPAQUE.equals(instance.getResource(0).getType()) ? new BigInteger((byte[]) instance.getResource(0).getValue()).intValue() : (Integer) instance.getResource(0).getValue(); + serverInstances.put(shortId, instance.getId()); + }); + } catch (Exception e) { + log.error("", e); + } if (this.securityInstances != null && this.securityInstances.size() > 0 && this.serverInstances != null && this.serverInstances.size() > 0) { this.findBootstrapServerId(); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java index b47e548b56..f3ab8d2cb8 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MNetworkConfig.java @@ -33,12 +33,12 @@ public class LwM2MNetworkConfig { coapConfig.set(CoapConfig.COAP_SECURE_PORT, serverSecurePort); /** Example:Property for large packet: - #NetworkConfig config = new NetworkConfig(); - #config.setInt(CoapConfig.MAX_MESSAGE_SIZE,32); - #config.setInt(CoapConfig.PREFERRED_BLOCK_SIZE,32); - #config.setInt(CoapConfig.MAX_RESOURCE_BODY_SIZE,2048); - #config.setInt(CoapConfig.MAX_RETRANSMIT,3); - #config.setInt(CoapConfig.MAX_TRANSMIT_WAIT,120000); + #NetworkConfig config = new Configuration(); + #config.sett(CoapConfig.MAX_MESSAGE_SIZE,32); + #config.set(CoapConfig.PREFERRED_BLOCK_SIZE,32); + #config.set(CoapConfig.MAX_RESOURCE_BODY_SIZE,2048); + #config.set(CoapConfig.MAX_RETRANSMIT,3); + #config.set(CoapConfig.MAX_TRANSMIT_WAIT,120000); */ /** diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java index 40514577c3..8f754bc142 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java @@ -85,7 +85,11 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { this.registration = registration; this.tenantId = lwM2mClientContext.getClientByEndpoint(registration.getEndpoint()).getTenantId(); this.modelsLock = new ReentrantLock(); - models.computeIfAbsent(tenantId, t -> new ConcurrentHashMap<>()); + log.info("tenantId: [{}]", tenantId); + log.info("models: [{}]", models); + if (tenantId != null) { + models.computeIfAbsent(tenantId, t -> new ConcurrentHashMap<>()); + } } @Override @@ -127,8 +131,8 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { private ObjectModel getObjectModelDynamic(Integer objectId, String version) { String key = getKeyIdVer(objectId, version); - ObjectModel objectModel = models.get(tenantId).get(key); - if (objectModel == null) { + ObjectModel objectModel = tenantId != null ? models.get(tenantId).get(key) : null; + if (tenantId != null && objectModel == null) { modelsLock.lock(); try { objectModel = models.get(tenantId).get(key); From 3cd9454a980628cefb2a599199e63b22de4d36c6 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 26 Jan 2022 19:05:16 +0200 Subject: [PATCH 02/51] lwm2m: tests with PSK security mode (bad request): - "bad length key" --- .../lwm2m/AbstractLwM2MIntegrationTest.java | 10 +------ .../AbstractSecurityLwM2MIntegrationTest.java | 22 +++++++++++++++ .../security/sql/PskLwm2mIntegrationTest.java | 28 +++++++++++++++++-- .../security/sql/RpkLwM2MIntegrationTest.java | 5 ++-- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 5 ++-- .../sql/X509_TrustLwM2MIntegrationTest.java | 5 ++-- 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index 67e17e3d8d..cd04e8a304 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -39,10 +39,6 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCr import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecBootstrapClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; -import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKBootstrapClientCredential; -import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; -import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKBootstrapClientCredential; -import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredential; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; @@ -95,7 +91,6 @@ import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClient import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @Slf4j @@ -278,9 +273,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest " }\n" + "}"; - protected final Lwm2mDeviceProfileTransportConfiguration LWM2M_TRANSPORT_CONFIGURATION_NO_SEC_WITH_ATTRIBUTES = JacksonUtil.fromString(TRANSPORT_CONFIGURATION, Lwm2mDeviceProfileTransportConfiguration.class); - protected final Lwm2mDeviceProfileTransportConfiguration LWM2M_TRANSPORT_CONFIGURATION_NO_SEC_WITHOUT_ATTRIBUTES = JacksonUtil.fromString(TRANSPORT_CONFIGURATION_NO_SEC_WITHOUT_ATTRIBUTES, Lwm2mDeviceProfileTransportConfiguration.class); - protected final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); + protected final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected final Set expectedStatusesRegistrationBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected DeviceProfile deviceProfile; protected ScheduledExecutorService executor; @@ -414,7 +407,6 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest doGet("/api/device/" + device.getId().getId().toString() + "/credentials", DeviceCredentials.class); Assert.assertEquals(device.getId(), deviceCredentials.getDeviceId()); deviceCredentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); -// LwM2MDeviceCredentials credentials = getDeviceCredentials(clientCredentials, mode); deviceCredentials.setCredentialsValue(JacksonUtil.toString(credentials)); doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk()); return device; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index 1e22748676..8c90fc20bb 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -17,6 +17,10 @@ package org.thingsboard.server.transport.lwm2m.security; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; +import org.junit.Assert; +import org.springframework.test.web.servlet.MvcResult; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; @@ -31,6 +35,8 @@ import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBo import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.PSKLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.RPKLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.X509LwM2MBootstrapServerCredential; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; import org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType; @@ -258,4 +264,20 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M bootstrapCredentials.setLwm2mServer(serverCredentials); return bootstrapCredentials; } + + protected MvcResult createDeviceWithMvcResult(LwM2MDeviceCredentials credentials, String endpoint) throws Exception { + Device device = new Device(); + device.setName(endpoint); + device.setDeviceProfileId(deviceProfile.getId()); + device.setTenantId(tenantId); + device = doPost("/api/device", device, Device.class); + Assert.assertNotNull(device); + + DeviceCredentials deviceCredentials = + doGet("/api/device/" + device.getId().getId().toString() + "/credentials", DeviceCredentials.class); + Assert.assertEquals(device.getId(), deviceCredentials.getDeviceId()); + deviceCredentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); + deviceCredentials.setCredentialsValue(JacksonUtil.toString(credentials)); + return doPost("/api/device/credentials", deviceCredentials).andReturn(); + } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index 9afa25c0b3..19cbab14f3 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -18,23 +18,28 @@ package org.thingsboard.server.transport.lwm2m.security.sql; import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.core.util.Hex; import org.junit.Test; +import org.springframework.test.web.servlet.MvcResult; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; +import javax.servlet.http.HttpServletResponse; import java.nio.charset.StandardCharsets; import static org.eclipse.leshan.client.object.Security.psk; import static org.eclipse.leshan.client.object.Security.pskBootstrap; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.PSK; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { //Lwm2m only @Test - public void testWithPskConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + public void testWithPskConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_PSK; String identity = CLIENT_PSK_IDENTITY; String keyPsk = CLIENT_PSK_KEY; @@ -46,7 +51,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes shortServerId, identity.getBytes(StandardCharsets.UTF_8), Hex.decodeHex(keyPsk.toCharArray())); - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, BOTH)); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, NONE)); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); this.basicTestConnection(securityBs, deviceCredentials, @@ -59,6 +64,25 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes PSK); } + @Test + public void testWithPskConnectLwm2mBadPskKeyByLength_BAD_REQUEST() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_PSK; + String identity = CLIENT_PSK_IDENTITY + "_BadLength"; + String keyPsk = CLIENT_PSK_KEY + "05AC"; + PSKClientCredential clientCredentials = new PSKClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setIdentity(identity); + clientCredentials.setKey(keyPsk); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, NONE)); + createDeviceProfile(transportConfiguration); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); + MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint); + assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus()); + String msgExpected = "Key must be HexDec format: 32, 64, 128 characters!"; + assertTrue(result.getResponse().getContentAsString().contains(msgExpected)); + } + + // Bootstrap + Lwm2m @Test public void testWithPskConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index a28d72117a..ed2dbfa01f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -30,12 +30,13 @@ import static org.eclipse.leshan.client.object.Security.rpk; import static org.eclipse.leshan.client.object.Security.rpkBootstrap; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.RPK; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { //Lwm2m only @Test - public void testWithRpkConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + public void testWithRpkConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_RPK; X509Certificate certificate = clientX509CertTrust; PrivateKey privateKey = clientPrivateKeyFromCertTrust; @@ -47,7 +48,7 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes certificate.getPublicKey().getEncoded(), privateKey.getEncoded(), serverX509Cert.getPublicKey().getEncoded()); - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, BOTH)); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, NONE)); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, RPK); this.basicTestConnection(securityBs, deviceCredentials, diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index 1281adc36a..692f1ef7a7 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -30,12 +30,13 @@ import static org.eclipse.leshan.client.object.Security.x509; import static org.eclipse.leshan.client.object.Security.x509Bootstrap; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { //Lwm2m only @Test - public void testWithX509NoTrustConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + public void testWithX509NoTrustConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO; X509Certificate certificate = clientX509CertTrustNo; PrivateKey privateKey = clientPrivateKeyFromCertTrustNo; @@ -47,7 +48,7 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg certificate.getEncoded(), privateKey.getEncoded(), serverX509Cert.getEncoded()); - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE)); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); this.basicTestConnection(security, deviceCredentials, diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java index 40f094a96a..04b658ad5e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java @@ -29,12 +29,13 @@ import static org.eclipse.leshan.client.object.Security.x509; import static org.eclipse.leshan.client.object.Security.x509Bootstrap; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { //Lwm2m only @Test - public void testWithX509TrustConnectLwm2mSuccessAndObserveTelemetry() throws Exception { + public void testWithX509TrustConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST; X509Certificate certificate = clientX509CertTrust; PrivateKey privateKey = clientPrivateKeyFromCertTrust; @@ -46,7 +47,7 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra certificate.getEncoded(), privateKey.getEncoded(), serverX509Cert.getEncoded()); - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE)); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); this.basicTestConnection(security, deviceCredentials, From 41274180c567809701845cc1efa305a9966c2b1f Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 27 Jan 2022 14:30:43 +0200 Subject: [PATCH 03/51] lwm2m: tests NoSec bootstrap update: - connecting the client to the bootstrap server and updating the bootstrap - client connection to lwm2m server, reboot when after executing "1/0/9" and update boostrap --- .../lwm2m/AbstractLwM2MIntegrationTest.java | 32 +--- .../transport/lwm2m/Lwm2mTestHelper.java | 1 + .../lwm2m/client/LwM2MTestClient.java | 22 ++- .../ota/sql/OtaLwM2MIntegrationTest.java | 6 +- .../rpc/AbstractRpcLwM2MIntegrationTest.java | 2 +- .../AbstractSecurityLwM2MIntegrationTest.java | 143 +++++++++++++++++- .../sql/NoSecLwM2MIntegrationTest.java | 72 +++++++-- .../security/sql/PskLwm2mIntegrationTest.java | 9 +- .../security/sql/RpkLwM2MIntegrationTest.java | 5 +- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 5 +- .../sql/X509_TrustLwM2MIntegrationTest.java | 5 +- 11 files changed, 238 insertions(+), 64 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index cd04e8a304..a061eaa187 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -273,6 +273,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest " }\n" + "}"; + protected final Set expectedStatusesBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS)); protected final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected final Set expectedStatusesRegistrationBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected DeviceProfile deviceProfile; @@ -314,31 +315,6 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest executor.shutdownNow(); } - public void basicTestConnection(Security security, - LwM2MDeviceCredentials deviceCredentials, - Configuration coapConfig, - String endpoint, - Lwm2mDeviceProfileTransportConfiguration transportConfiguration, - String awaitAlias, Set expectedStatuses, - boolean isBootstrap, LwM2MSecurityMode mode) throws Exception { - createDeviceProfile(transportConfiguration); - createDevice(deviceCredentials, endpoint); - createNewClient(security, coapConfig, false, endpoint, isBootstrap); - - await(awaitAlias) - .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); - Assert.assertEquals(expectedStatuses, client.getClientStates()); - - client.destroy(); - expectedStatuses.add(ON_DEREGISTRATION_STARTED); - expectedStatuses.add(ON_DEREGISTRATION_SUCCESS); - await(awaitAlias) - .atMost(1000, TimeUnit.MILLISECONDS) - .until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState())); - Assert.assertEquals(expectedStatuses, client.getClientStates()); - } - public void basicTestConnectionObserveTelemetry(Security security, LwM2MDeviceCredentials deviceCredentials, Configuration coapConfig, @@ -362,7 +338,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest wsClient.waitForReply(); wsClient.registerWaitForUpdate(); - createNewClient(security, coapConfig, false, endpoint, false); + createNewClient(security, coapConfig, false, endpoint, false, null); String msg = wsClient.waitForUpdate(); EntityDataUpdate update = mapper.readValue(msg, EntityDataUpdate.class); @@ -422,11 +398,11 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest this.resources = resources; } - public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint, boolean isBootstrap) throws Exception { + public void createNewClient(Security security, Configuration coapConfig, boolean isRpc, String endpoint, boolean isBootstrap, Security securityBs) throws Exception { clientDestroy(); client = new LwM2MTestClient(this.executor, endpoint); int clientPort = SocketUtils.findAvailableTcpPort(); - client.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs); + client.init(security, coapConfig, clientPort, isRpc, isBootstrap, this.shortServerId, this.shortServerIdBs, securityBs); } private void clientDestroy() { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java index 532b1920b2..b8e3017236 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/Lwm2mTestHelper.java @@ -51,6 +51,7 @@ public class Lwm2mTestHelper { // Ids in Client public static final int OBJECT_ID_0 = 0; + public static final int OBJECT_ID_1 = 1; public static final int OBJECT_INSTANCE_ID_0 = 0; public static final int OBJECT_INSTANCE_ID_1 = 1; public static final int OBJECT_INSTANCE_ID_2 = 2; diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java index bd3ca6ef9a..23c48098f5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -26,6 +26,7 @@ import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.client.object.Server; import org.eclipse.leshan.client.observer.LwM2mClientObserver; import org.eclipse.leshan.client.resource.DummyInstanceEnabler; +import org.eclipse.leshan.client.resource.LwM2mInstanceEnabler; import org.eclipse.leshan.client.resource.ObjectsInitializer; import org.eclipse.leshan.client.servers.ServerIdentity; import org.eclipse.leshan.core.ResponseCode; @@ -103,7 +104,7 @@ public class LwM2MTestClient { private LwM2MClientState clientState; private Set clientStates; - public void init(Security security, Configuration coapConfig, int port, boolean isRpc, boolean isBootstrap, int shortServerId, int shortServerIdBs) throws InvalidDDFFileException, IOException { + public void init(Security security, Configuration coapConfig, int port, boolean isRpc, boolean isBootstrap, int shortServerId, int shortServerIdBs, Security securityBs) throws InvalidDDFFileException, IOException { Assert.assertNull("client already initialized", client); List models = new ArrayList<>(); for (String resourceName : resources) { @@ -111,11 +112,24 @@ public class LwM2MTestClient { } LwM2mModel model = new StaticModel(models); ObjectsInitializer initializer = new ObjectsInitializer(model); - initializer.setInstancesForObject(SECURITY, security); + if (securityBs == null) { + initializer.setInstancesForObject(SECURITY, security); + } else { + LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{securityBs, security}; + initializer.setInstancesForObject(SECURITY, instances); + } if (isBootstrap) { initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerIdBs, 300)); } else { - initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerId, 300)); + if (securityBs == null) { + initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerId, 300)); + } else { + Server serverBootstrap = new Server(shortServerIdBs, 300); + Server serverLwm2m = new Server(shortServerId, 300); + LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{serverBootstrap, serverLwm2m}; + initializer.setClassForObject(SERVER, Server.class); + initializer.setInstancesForObject(SERVER, instances); + } } initializer.setInstancesForObject(DEVICE, lwM2MDevice = new SimpleLwM2MDevice()); initializer.setInstancesForObject(FIRMWARE, fwLwM2MDevice = new FwLwM2MDevice()); @@ -245,7 +259,7 @@ public class LwM2MTestClient { public void onDeregistrationSuccess(ServerIdentity server, DeregisterRequest request) { clientState = ON_DEREGISTRATION_SUCCESS; clientStates.add(clientState); - log.info("ClientObserver ->onDeregistrationSuccess... DeregisterRequest [{}]", request.getRegistrationId()); +// log.info("ClientObserver ->onDeregistrationSuccess... DeregisterRequest [{}]", request.getRegistrationId()); } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java index c05e5d6dda..e572b854b5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/ota/sql/OtaLwM2MIntegrationTest.java @@ -99,7 +99,7 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { createDeviceProfile(transportConfiguration); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_WITHOUT_FW_INFO)); final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO); - createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO, false); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_WITHOUT_FW_INFO, false, null); Thread.sleep(1000); @@ -125,7 +125,7 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { createDeviceProfile(transportConfiguration); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA5)); final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA5); - createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5, false); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA5, false, null); Thread.sleep(1000); @@ -163,7 +163,7 @@ public class OtaLwM2MIntegrationTest extends AbstractOtaLwM2MIntegrationTest { createDeviceProfile(transportConfiguration); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(this.CLIENT_ENDPOINT_OTA9)); final Device device = createDevice(deviceCredentials, this.CLIENT_ENDPOINT_OTA9); - createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA9, false); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, false, this.CLIENT_ENDPOINT_OTA9, false, null); Thread.sleep(1000); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java index 251fccb450..1105e94ccd 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/AbstractRpcLwM2MIntegrationTest.java @@ -79,7 +79,7 @@ public abstract class AbstractRpcLwM2MIntegrationTest extends AbstractLwM2MInteg public void beforeTest() throws Exception { String endpoint = DEVICE_ENDPOINT_RPC_PREF + endpointSequence.incrementAndGet(); init(); - createNewClient(SECURITY_NO_SEC, COAP_CONFIG, true, endpoint, false); + createNewClient(SECURITY_NO_SEC, COAP_CONFIG, true, endpoint, false, null); expectedObjects = ConcurrentHashMap.newKeySet(); expectedObjectIdVers = ConcurrentHashMap.newKeySet(); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index 8c90fc20bb..0de6cd37a1 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -15,8 +15,12 @@ */ package org.thingsboard.server.transport.lwm2m.security; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; +import org.eclipse.californium.elements.config.Configuration; +import org.eclipse.leshan.client.object.Security; +import org.eclipse.leshan.core.ResponseCode; import org.junit.Assert; import org.springframework.test.web.servlet.MvcResult; import org.thingsboard.common.util.JacksonUtil; @@ -30,6 +34,7 @@ import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKBootstrapC import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKBootstrapClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.X509BootstrapClientCredential; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.AbstractLwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MBootstrapServerCredential; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.PSKLwM2MBootstrapServerCredential; @@ -39,8 +44,8 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.transport.lwm2m.AbstractLwM2MIntegrationTest; +import org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState; import org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType; -import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; import java.io.IOException; import java.io.InputStream; @@ -52,6 +57,20 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import static org.awaitility.Awaitility.await; +import static org.eclipse.leshan.client.object.Security.noSec; +import static org.eclipse.leshan.client.object.Security.noSecBootstap; +import static org.junit.Assert.assertEquals; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_STARTED; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.OBJECT_ID_1; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.RESOURCE_ID_9; @DaoSqlTest @Slf4j @@ -74,7 +93,6 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M protected final PublicKey serverPublicKeyFromCertBs; // serverBs public key used for RPK // Client - protected LwM2MTestClient client; protected static final String CLIENT_ENDPOINT_NO_SEC = "LwNoSec00000000"; protected static final String CLIENT_ENDPOINT_NO_SEC_BS = "LwNoSecBs00000000"; protected static final String CLIENT_ENDPOINT_PSK = "LwPsk00000000"; @@ -144,6 +162,111 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M defaultBootstrapCredentials.setLwm2mServer(serverCredentials); } + public void basicTestConnectionBefore(String clientEndpoint, + String awaitAlias, + LwM2MProfileBootstrapConfigType type, + Set expectedStatuses, + LwM2MClientState finishState) throws Exception { + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(type)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); + this.basicTestConnection(noSecBootstap(URI_BS), + deviceCredentials, + COAP_CONFIG_BS, + clientEndpoint, + transportConfiguration, + awaitAlias, + expectedStatuses, + true, + finishState); + } + + protected void basicTestConnection(Security security, + LwM2MDeviceCredentials deviceCredentials, + Configuration coapConfig, + String endpoint, + Lwm2mDeviceProfileTransportConfiguration transportConfiguration, + String awaitAlias, + Set expectedStatuses, + boolean isBootstrap, + LwM2MClientState finishState) throws Exception { + createDeviceProfile(transportConfiguration); + createDevice(deviceCredentials, endpoint); + createNewClient(security, coapConfig, false, endpoint, isBootstrap, null); + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> finishState.equals(client.getClientState())); + Assert.assertEquals(expectedStatuses, client.getClientStates()); + + client.destroy(); + if (ON_BOOTSTRAP_SUCCESS != finishState) { + expectedStatuses.add(ON_DEREGISTRATION_STARTED); + expectedStatuses.add(ON_DEREGISTRATION_SUCCESS); + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState())); + Assert.assertEquals(expectedStatuses, client.getClientStates()); + } + } + + + + public void basicTestConnectionBootstrapRequestTriggerBefore(String clientEndpoint, String awaitAlias, LwM2MProfileBootstrapConfigType type) throws Exception { + Security securityBs = noSecBootstap(URI_BS); + Security security = noSec(URI, shortServerId); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(type)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); + this.basicTestConnectionBootstrapRequestTrigger( + security, + deviceCredentials, + COAP_CONFIG_BS, + clientEndpoint, + transportConfiguration, + awaitAlias, + expectedStatusesRegistrationLwm2mSuccess, + expectedStatusesRegistrationBsSuccess, + false, + securityBs); + + } + + private void basicTestConnectionBootstrapRequestTrigger(Security security, + LwM2MDeviceCredentials deviceCredentials, + Configuration coapConfig, + String endpoint, + Lwm2mDeviceProfileTransportConfiguration transportConfiguration, + String awaitAlias, + Set expectedStatusesLwm2m, + Set expectedStatusesBs, + boolean isBootstrap, + Security securityBs) throws Exception { + createDeviceProfile(transportConfiguration); + final Device device = createDevice(deviceCredentials, endpoint); + String deviceId = device.getId().getId().toString(); + createNewClient(security, coapConfig, false, endpoint, isBootstrap, securityBs); + + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); + Assert.assertEquals(expectedStatusesLwm2m, client.getClientStates()); + + String executedPath = getObjectIdVer_1() + "/0/" + RESOURCE_ID_9; + String actualResult = sendRPCExecuteById(executedPath, deviceId); + ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); + assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText()); + + expectedStatusesBs.add(ON_DEREGISTRATION_STARTED); + expectedStatusesBs.add(ON_DEREGISTRATION_SUCCESS); + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> ON_REGISTRATION_SUCCESS.equals(client.getClientState())); + Assert.assertEquals(expectedStatusesBs, client.getClientStates()); + + client.destroy(); + await(awaitAlias) + .atMost(1000, TimeUnit.MILLISECONDS) + .until(() -> ON_DEREGISTRATION_SUCCESS.equals(client.getClientState())); + Assert.assertEquals(expectedStatusesBs, client.getClientStates()); + } protected List getBootstrapServerCredentialsSecure(LwM2MSecurityMode mode, LwM2MProfileBootstrapConfigType bootstrapConfigType) { List bootstrap = new ArrayList<>(); @@ -280,4 +403,20 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M deviceCredentials.setCredentialsValue(JacksonUtil.toString(credentials)); return doPost("/api/device/credentials", deviceCredentials).andReturn(); } + + private String sendRPCExecuteById(String path, String deviceId) throws Exception { + String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\"}}"; + return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk()); + } + + private String getObjectIdVer_1() { + String ver_Id_0 = client.getClient().getObjectTree().getModel().getObjectModel(OBJECT_ID_1).version; + String objectIdVer_1; + if ("1.0".equals(ver_Id_0)) { + objectIdVer_1 = "/" + OBJECT_ID_1; + } else { + objectIdVer_1 = "/" + OBJECT_ID_1 + "_" + ver_Id_0; + } + return objectIdVer_1; + } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java index 56874f57aa..345902aa6e 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/NoSecLwM2MIntegrationTest.java @@ -15,15 +15,16 @@ */ package org.thingsboard.server.transport.lwm2m.security.sql; -import org.eclipse.leshan.client.object.Security; import org.junit.Test; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; -import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; -import static org.eclipse.leshan.client.object.Security.noSecBootstap; -import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOOTSTRAP_ONLY; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.LWM2M_ONLY; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; public class NoSecLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTest { @@ -39,17 +40,56 @@ public class NoSecLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationT @Test public void testWithNoSecConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS; - Security securityBs = noSecBootstap(URI_BS); - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(BOTH)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); - this.basicTestConnection(securityBs, - deviceCredentials, - COAP_CONFIG_BS, - clientEndpoint, - transportConfiguration, - "await on client state (NoSecBS two section)", - expectedStatusesRegistrationBsSuccess, - true, - NO_SEC); + String awaitAlias = "await on client state (NoSecBS two section)"; + basicTestConnectionBefore(clientEndpoint, awaitAlias, BOTH, expectedStatusesRegistrationBsSuccess, ON_REGISTRATION_SUCCESS); + } + + @Test + public void testWithNoSecConnectBsSuccess_UpdateLwm2mSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + LWM2M_ONLY.name(); + String awaitAlias = "await on client state (NoSecBS Lwm2m section)"; + basicTestConnectionBefore(clientEndpoint, awaitAlias, LWM2M_ONLY, expectedStatusesRegistrationBsSuccess, ON_REGISTRATION_SUCCESS); + } + + @Test + public void testWithNoSecConnectBsSuccess_UpdateBootstrapSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC + BOOTSTRAP_ONLY.name(); + String awaitAlias = "await on client state (NoSecBS Bootstrap section)"; + basicTestConnectionBefore(clientEndpoint, awaitAlias, BOOTSTRAP_ONLY, expectedStatusesBsSuccess, ON_BOOTSTRAP_SUCCESS); + } + + @Test + public void testWithNoSecConnectBsSuccess_UpdateNoneSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC + NONE.name(); + String awaitAlias = "await on client state (NoSecBS None section)"; + basicTestConnectionBefore(clientEndpoint, awaitAlias, NONE, expectedStatusesBsSuccess, ON_BOOTSTRAP_SUCCESS); + } + + @Test + public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateTwoSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + BOTH.name(); + String awaitAlias = "await on client state (NoSecBS Trigger Two section)"; + basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, BOTH); + } + + @Test + public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateBootstrapSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + BOOTSTRAP_ONLY.name(); + String awaitAlias = "await on client state (NoSecBS Trigger Bootstrap section)"; + basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, BOOTSTRAP_ONLY); + } + + @Test + public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateLwm2mSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + LWM2M_ONLY.name(); + String awaitAlias = "await on client state (NoSecBS Trigger Lwm2m section)"; + basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, LWM2M_ONLY); + } + + @Test + public void testWithNoSecBootstrapRequestTriggerConnectBsSuccess_UpdateNoneSectionAndLm2m_ConnectLwm2mSuccess() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_NO_SEC_BS + "Trigger" + NONE.name(); + String awaitAlias = "await on client state (NoSecBS Trigger None section)"; + basicTestConnectionBootstrapRequestTriggerBefore(clientEndpoint, awaitAlias, NONE); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index 19cbab14f3..475771d4c1 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -32,6 +32,7 @@ import static org.eclipse.leshan.client.object.Security.pskBootstrap; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.PSK; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @@ -47,13 +48,13 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes clientCredentials.setEndpoint(clientEndpoint); clientCredentials.setIdentity(identity); clientCredentials.setKey(keyPsk); - Security securityBs = psk(SECURE_URI, + Security security = psk(SECURE_URI, shortServerId, identity.getBytes(StandardCharsets.UTF_8), Hex.decodeHex(keyPsk.toCharArray())); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, NONE)); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); - this.basicTestConnection(securityBs, + this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, clientEndpoint, @@ -61,7 +62,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (Psk_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - PSK); + ON_REGISTRATION_SUCCESS); } @Test @@ -106,6 +107,6 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (PskBS two section)", expectedStatusesRegistrationBsSuccess, true, - PSK); + ON_REGISTRATION_SUCCESS); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index ed2dbfa01f..ed94443f03 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -29,6 +29,7 @@ import java.security.cert.X509Certificate; import static org.eclipse.leshan.client.object.Security.rpk; import static org.eclipse.leshan.client.object.Security.rpkBootstrap; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.RPK; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @@ -58,7 +59,7 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (Rpk_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - RPK); + ON_REGISTRATION_SUCCESS); } // Bootstrap + Lwm2m @@ -84,6 +85,6 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes "await on client state (RpkBS two section)", expectedStatusesRegistrationBsSuccess, true, - RPK); + ON_REGISTRATION_SUCCESS); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index 692f1ef7a7..b226bc1dad 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -29,6 +29,7 @@ import java.security.cert.X509Certificate; import static org.eclipse.leshan.client.object.Security.x509; import static org.eclipse.leshan.client.object.Security.x509Bootstrap; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @@ -58,7 +59,7 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg "await on client state (X509_Trust_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - X509); + ON_REGISTRATION_SUCCESS); } // Bootstrap + Lwm2m @@ -84,6 +85,6 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg "await on client state (X509NoTrust two section)", expectedStatusesRegistrationBsSuccess, true, - X509); + ON_REGISTRATION_SUCCESS); } } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java index 04b658ad5e..e5e047ac0f 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java @@ -28,6 +28,7 @@ import java.security.cert.X509Certificate; import static org.eclipse.leshan.client.object.Security.x509; import static org.eclipse.leshan.client.object.Security.x509Bootstrap; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; +import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.NONE; @@ -57,7 +58,7 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra "await on client state (X509_Trust_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, - X509); + ON_REGISTRATION_SUCCESS); } // Bootstrap + Lwm2m @@ -83,6 +84,6 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra "await on client state (X509Trust two section)", expectedStatusesRegistrationBsSuccess, true, - X509); + ON_REGISTRATION_SUCCESS); } } From 45a6ce0dbf19a946b247f2aec027dba2de5eed3c Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Thu, 27 Jan 2022 16:01:15 +0200 Subject: [PATCH 04/51] lwm2m: tests RPK and X509 client validate base64 format: --- .../lwm2m/client/LwM2MTestClient.java | 16 ------- .../AbstractSecurityLwM2MIntegrationTest.java | 26 +++++++---- .../security/sql/PskLwm2mIntegrationTest.java | 6 +-- .../security/sql/RpkLwM2MIntegrationTest.java | 43 ++++++++++++++++++- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 43 ++++++++++++++++++- .../sql/X509_TrustLwM2MIntegrationTest.java | 4 +- 6 files changed, 105 insertions(+), 33 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java index 23c48098f5..e01dc22665 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -169,70 +169,60 @@ public class LwM2MTestClient { public void onBootstrapStarted(ServerIdentity bsserver, BootstrapRequest request) { clientState = ON_BOOTSTRAP_STARTED; clientStates.add(clientState); -// log.info("ClientObserver -> onBootstrapStarted..."); } @Override public void onBootstrapSuccess(ServerIdentity bsserver, BootstrapRequest request) { clientState = ON_BOOTSTRAP_SUCCESS; clientStates.add(clientState); -// log.info("ClientObserver -> onBootstrapSuccess..."); } @Override public void onBootstrapFailure(ServerIdentity bsserver, BootstrapRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { clientState = ON_BOOTSTRAP_FAILURE; clientStates.add(clientState); -// log.info("ClientObserver -> onBootstrapFailure..."); } @Override public void onBootstrapTimeout(ServerIdentity bsserver, BootstrapRequest request) { clientState = ON_BOOTSTRAP_TIMEOUT; clientStates.add(clientState); -// log.info("ClientObserver -> onBootstrapTimeout..."); } @Override public void onRegistrationStarted(ServerIdentity server, RegisterRequest request) { clientState = ON_REGISTRATION_STARTED; clientStates.add(clientState); -// log.info("ClientObserver -> onRegistrationStarted... EndpointName [{}]", request.getEndpointName()); } @Override public void onRegistrationSuccess(ServerIdentity server, RegisterRequest request, String registrationID) { clientState = ON_REGISTRATION_SUCCESS; clientStates.add(clientState); -// log.info("ClientObserver -> onRegistrationSuccess... EndpointName [{}] [{}]", request.getEndpointName(), registrationID); } @Override public void onRegistrationFailure(ServerIdentity server, RegisterRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { clientState = ON_REGISTRATION_FAILURE; clientStates.add(clientState); -// log.info("ClientObserver -> onRegistrationFailure... ServerIdentity [{}]", server); } @Override public void onRegistrationTimeout(ServerIdentity server, RegisterRequest request) { clientState = ON_REGISTRATION_TIMEOUT; clientStates.add(clientState); -// log.info("ClientObserver -> onRegistrationTimeout... RegisterRequest [{}]", request); } @Override public void onUpdateStarted(ServerIdentity server, UpdateRequest request) { clientState = ON_UPDATE_STARTED; clientStates.add(clientState); -// log.info("ClientObserver -> onUpdateStarted... UpdateRequest [{}]", request); } @Override public void onUpdateSuccess(ServerIdentity server, UpdateRequest request) { clientState = ON_UPDATE_SUCCESS; clientStates.add(clientState); -// log.info("ClientObserver -> onUpdateSuccess... UpdateRequest [{}]", request); } @Override @@ -251,30 +241,24 @@ public class LwM2MTestClient { public void onDeregistrationStarted(ServerIdentity server, DeregisterRequest request) { clientState = ON_DEREGISTRATION_STARTED; clientStates.add(clientState); -// log.info("ClientObserver ->onDeregistrationStarted... DeregisterRequest [{}]", request.getRegistrationId()); - } @Override public void onDeregistrationSuccess(ServerIdentity server, DeregisterRequest request) { clientState = ON_DEREGISTRATION_SUCCESS; clientStates.add(clientState); -// log.info("ClientObserver ->onDeregistrationSuccess... DeregisterRequest [{}]", request.getRegistrationId()); - } @Override public void onDeregistrationFailure(ServerIdentity server, DeregisterRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { clientState = ON_DEREGISTRATION_FAILURE; clientStates.add(clientState); -// log.info("ClientObserver ->onDeregistrationFailure... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); } @Override public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request) { clientState = ON_DEREGISTRATION_TIMEOUT; clientStates.add(clientState); -// log.info("ClientObserver ->onDeregistrationTimeout... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); } @Override diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index 0de6cd37a1..a82eb8d86c 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -21,6 +21,7 @@ import org.apache.commons.codec.binary.Base64; import org.eclipse.californium.elements.config.Configuration; import org.eclipse.leshan.client.object.Security; import org.eclipse.leshan.core.ResponseCode; +import org.eclipse.leshan.core.util.Hex; import org.junit.Assert; import org.springframework.test.web.servlet.MvcResult; import org.thingsboard.common.util.JacksonUtil; @@ -226,7 +227,6 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M expectedStatusesRegistrationBsSuccess, false, securityBs); - } private void basicTestConnectionBootstrapRequestTrigger(Security security, @@ -327,7 +327,8 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M protected LwM2MDeviceCredentials getDeviceCredentialsSecure(LwM2MClientCredential clientCredentials, PrivateKey privateKey, X509Certificate certificate, - LwM2MSecurityMode mode) { + LwM2MSecurityMode mode, + boolean privateKeyIsBad) { LwM2MDeviceCredentials credentials = new LwM2MDeviceCredentials(); credentials.setClient(clientCredentials); LwM2MBootstrapClientCredentials bootstrapCredentials; @@ -336,10 +337,10 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M bootstrapCredentials = getBootstrapClientCredentialsPsk(clientCredentials); break; case RPK: - bootstrapCredentials = getBootstrapClientCredentialsRpk(certificate, privateKey); + bootstrapCredentials = getBootstrapClientCredentialsRpk(certificate, privateKey, privateKeyIsBad); break; case X509: - bootstrapCredentials = getBootstrapClientCredentialsX509(certificate, privateKey); + bootstrapCredentials = getBootstrapClientCredentialsX509(certificate, privateKey, privateKeyIsBad); break; default: throw new IllegalStateException("Unexpected value: " + mode); @@ -360,25 +361,34 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M return bootstrapCredentials; } - private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsRpk(X509Certificate certificate, PrivateKey privateKey) { + private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsRpk(X509Certificate certificate, PrivateKey privateKey, boolean privateKeyIsBad) { LwM2MBootstrapClientCredentials bootstrapCredentials = new LwM2MBootstrapClientCredentials(); RPKBootstrapClientCredential serverCredentials = new RPKBootstrapClientCredential(); if (certificate != null && certificate.getPublicKey() != null && privateKey != null) { serverCredentials.setClientPublicKeyOrId(Base64.encodeBase64String(certificate.getPublicKey().getEncoded())); - serverCredentials.setClientSecretKey(Base64.encodeBase64String(privateKey.getEncoded())); + if (privateKeyIsBad) { + serverCredentials.setClientSecretKey(Hex.encodeHexString(privateKey.getEncoded())); + } else { + serverCredentials.setClientSecretKey(Base64.encodeBase64String(privateKey.getEncoded())); + + } } bootstrapCredentials.setBootstrapServer(serverCredentials); bootstrapCredentials.setLwm2mServer(serverCredentials); return bootstrapCredentials; } - private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsX509(X509Certificate certificate, PrivateKey privateKey) { + private LwM2MBootstrapClientCredentials getBootstrapClientCredentialsX509(X509Certificate certificate, PrivateKey privateKey, boolean privateKeyIsBad) { LwM2MBootstrapClientCredentials bootstrapCredentials = new LwM2MBootstrapClientCredentials(); X509BootstrapClientCredential serverCredentials = new X509BootstrapClientCredential(); if (certificate != null) { try { serverCredentials.setClientPublicKeyOrId(Base64.encodeBase64String(certificate.getEncoded())); - serverCredentials.setClientSecretKey(Base64.encodeBase64String(privateKey.getEncoded())); + if (privateKeyIsBad) { + serverCredentials.setClientSecretKey(Hex.encodeHexString(privateKey.getEncoded())); + } else { + serverCredentials.setClientSecretKey(Base64.encodeBase64String(privateKey.getEncoded())); + } } catch (CertificateEncodingException e) { log.error("Client`s certificate [{}] is bad. [{}]", certificate, e.getMessage()); } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index 475771d4c1..9db90a9fdb 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -53,7 +53,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes identity.getBytes(StandardCharsets.UTF_8), Hex.decodeHex(keyPsk.toCharArray())); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, NONE)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK, false); this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, @@ -76,7 +76,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes clientCredentials.setKey(keyPsk); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, NONE)); createDeviceProfile(transportConfiguration); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK, false); MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint); assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus()); String msgExpected = "Key must be HexDec format: 32, 64, 128 characters!"; @@ -98,7 +98,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes identity.getBytes(StandardCharsets.UTF_8), Hex.decodeHex(keyPsk.toCharArray())); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(PSK, BOTH)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK, false); this.basicTestConnection(securityBs, deviceCredentials, COAP_CONFIG, diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index ed94443f03..082642690d 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -17,17 +17,22 @@ package org.thingsboard.server.transport.lwm2m.security.sql; import org.apache.commons.codec.binary.Base64; import org.eclipse.leshan.client.object.Security; +import org.eclipse.leshan.core.util.Hex; import org.junit.Test; +import org.springframework.test.web.servlet.MvcResult; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredential; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; +import javax.servlet.http.HttpServletResponse; import java.security.PrivateKey; import java.security.cert.X509Certificate; import static org.eclipse.leshan.client.object.Security.rpk; import static org.eclipse.leshan.client.object.Security.rpkBootstrap; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.RPK; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; @@ -50,7 +55,7 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes privateKey.getEncoded(), serverX509Cert.getPublicKey().getEncoded()); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, NONE)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, RPK); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, RPK, false); this.basicTestConnection(securityBs, deviceCredentials, COAP_CONFIG, @@ -62,6 +67,40 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes ON_REGISTRATION_SUCCESS); } + @Test + public void testWithRpkValidationPublicKeyBase64format_BAD_REQUEST() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_RPK + "BadPublicKey"; + X509Certificate certificate = clientX509CertTrust; + PrivateKey privateKey = clientPrivateKeyFromCertTrust; + RPKClientCredential clientCredentials = new RPKClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setKey(Hex.encodeHexString(certificate.getPublicKey().getEncoded())); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, NONE)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, RPK, false); + createDeviceProfile(transportConfiguration); + MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint); + assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus()); + String msgExpected = "LwM2M client RPK key must be in standard [RFC7250] and support only EC algorithm and then encoded to Base64 format!"; + assertTrue(result.getResponse().getContentAsString().contains(msgExpected)); + } + + @Test + public void testWithRpkValidationPrivateKeyBase64format_BAD_REQUEST() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_RPK + "BadPrivateKey"; + X509Certificate certificate = clientX509CertTrust; + PrivateKey privateKey = clientPrivateKeyFromCertTrust; + RPKClientCredential clientCredentials = new RPKClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setKey(Base64.encodeBase64String(certificate.getPublicKey().getEncoded())); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, NONE)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, RPK, true); + createDeviceProfile(transportConfiguration); + MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint); + assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus()); + String msgExpected = "Bootstrap server client RPK secret key must be in PKCS#8 format (DER encoding, standard [RFC5958]) and then encoded to Base64 format!"; + assertTrue(result.getResponse().getContentAsString().contains(msgExpected)); + } + // Bootstrap + Lwm2m @Test public void testWithRpkConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { @@ -76,7 +115,7 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes privateKey.getEncoded(), serverX509CertBs.getPublicKey().getEncoded()); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(RPK, BOTH)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, clientPrivateKeyFromCertTrust, certificate, RPK); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, clientPrivateKeyFromCertTrust, certificate, RPK, false); this.basicTestConnection(securityBs, deviceCredentials, COAP_CONFIG, diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index b226bc1dad..76f5af8965 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -16,18 +16,23 @@ package org.thingsboard.server.transport.lwm2m.security.sql; import org.eclipse.leshan.client.object.Security; +import org.eclipse.leshan.core.util.Hex; import org.junit.Test; +import org.springframework.test.web.servlet.MvcResult; import org.springframework.util.Base64Utils; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest; +import javax.servlet.http.HttpServletResponse; import java.security.PrivateKey; import java.security.cert.X509Certificate; import static org.eclipse.leshan.client.object.Security.x509; import static org.eclipse.leshan.client.object.Security.x509Bootstrap; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.X509; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MProfileBootstrapConfigType.BOTH; @@ -50,7 +55,7 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg privateKey.getEncoded(), serverX509Cert.getEncoded()); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, @@ -62,6 +67,40 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg ON_REGISTRATION_SUCCESS); } + @Test + public void testWithX509NoTrustValidationPublicKeyBase64format_BAD_REQUEST() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO + "BadPublicKey"; + X509Certificate certificate = clientX509CertTrustNo; + PrivateKey privateKey = clientPrivateKeyFromCertTrustNo; + X509ClientCredential clientCredentials = new X509ClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setCert(Hex.encodeHexString(certificate.getEncoded())); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); + createDeviceProfile(transportConfiguration); + MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint); + assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus()); + String msgExpected = "LwM2M client X509 certificate must be in DER-encoded X509v3 format and support only EC algorithm and then encoded to Base64 format!"; + assertTrue(result.getResponse().getContentAsString().contains(msgExpected)); + } + + @Test + public void testWithX509NoTrustValidationPrivateKeyBase64format_BAD_REQUEST() throws Exception { + String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO + "BadPrivateKey"; + X509Certificate certificate = clientX509CertTrustNo; + PrivateKey privateKey = clientPrivateKeyFromCertTrustNo; + X509ClientCredential clientCredentials = new X509ClientCredential(); + clientCredentials.setEndpoint(clientEndpoint); + clientCredentials.setCert(Base64Utils.encodeToString(certificate.getEncoded())); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, true); + createDeviceProfile(transportConfiguration); + MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint); + assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus()); + String msgExpected = "Bootstrap server client X509 secret key must be in PKCS#8 format (DER encoding, standard [RFC5958]) and then encoded to Base64 format!"; + assertTrue(result.getResponse().getContentAsString().contains(msgExpected)); + } + // Bootstrap + Lwm2m @Test public void testWithX509NoTrustConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception { @@ -76,7 +115,7 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg privateKey.getEncoded(), serverX509CertBs.getEncoded()); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java index e5e047ac0f..a7087bc072 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java @@ -49,7 +49,7 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra privateKey.getEncoded(), serverX509Cert.getEncoded()); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, @@ -75,7 +75,7 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra privateKey.getEncoded(), serverX509CertBs.getEncoded()); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, From c3081c45cf0db6ab63106e790dd77528e06e2241 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 28 Jan 2022 09:50:31 +0200 Subject: [PATCH 05/51] lwm2m: tests with execute "/1/0/9" - add Security and Server with instanceId --- .../lwm2m/AbstractLwM2MIntegrationTest.java | 20 +++--------- .../lwm2m/client/LwM2MTestClient.java | 31 ++++++++++++++----- .../AbstractSecurityLwM2MIntegrationTest.java | 30 +++++++++++------- ...LwM2MBootstrapConfigStoreTaskProvider.java | 11 +++++-- 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index a061eaa187..510d978046 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -36,7 +36,6 @@ import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapClientCredentials; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials; -import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecBootstrapClientCredential; import org.thingsboard.server.common.data.device.credentials.lwm2m.NoSecClientCredential; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; @@ -74,19 +73,13 @@ import java.util.List; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import static org.awaitility.Awaitility.await; -import static org.eclipse.californium.core.config.CoapConfig.COAP_PORT; -import static org.eclipse.californium.core.config.CoapConfig.COAP_SECURE_PORT; import static org.eclipse.leshan.client.object.Security.noSec; +import static org.eclipse.leshan.client.object.Security.noSecBootstap; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_STARTED; -import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_DEREGISTRATION_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_INIT; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_REGISTRATION_SUCCESS; @@ -112,16 +105,11 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest public static final String COAPS = "coaps://"; public static final String URI = COAP + host + ":" + port; public static final String SECURE_URI = COAPS + host + ":" + securityPort; - public static final Configuration COAP_CONFIG = new Configuration().set(COAP_PORT, port).set(COAP_SECURE_PORT, securityPort); - public static final Security SECURITY_NO_SEC = noSec(URI, shortServerId); - - public static final Configuration SECURE_COAP_CONFIG = COAP_CONFIG.set(COAP_SECURE_PORT, securityPort); - public static final Configuration COAP_CONFIG_BS = new Configuration().set(COAP_PORT, portBs); - - public static final String URI_BS = COAP + hostBs + ":" + portBs; - public static final String SECURE_URI_BS = COAPS + hostBs + ":" + securityPortBs; + public static final Configuration COAP_CONFIG = new Configuration(); + public static final Security SECURITY_NO_SEC = noSec(URI, shortServerId); + public static final Security SECURITY_NO_SEC_BS = noSecBootstap(URI_BS); protected final String OBSERVE_ATTRIBUTES_WITHOUT_PARAMS = " {\n" + diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java index e01dc22665..c079513841 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -94,7 +94,10 @@ public class LwM2MTestClient { private final String endpoint; private LeshanClient client; + private Security lwm2mSecurity; + private Security lwm2mSecurityBs; private Server lwm2mServer; + private Server lwm2mServerBs; private SimpleLwM2MDevice lwM2MDevice; private FwLwM2MDevice fwLwM2MDevice; private SwLwM2MDevice swLwM2MDevice; @@ -113,20 +116,25 @@ public class LwM2MTestClient { LwM2mModel model = new StaticModel(models); ObjectsInitializer initializer = new ObjectsInitializer(model); if (securityBs == null) { - initializer.setInstancesForObject(SECURITY, security); + initializer.setInstancesForObject(SECURITY, this.lwm2mSecurity = security); } else { - LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{securityBs, security}; + securityBs.setId(0); + security.setId(1); + LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{this.lwm2mSecurityBs = securityBs, this.lwm2mSecurity = security}; + initializer.setClassForObject(SECURITY, Security.class); initializer.setInstancesForObject(SECURITY, instances); } if (isBootstrap) { - initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerIdBs, 300)); + initializer.setInstancesForObject(SERVER, lwm2mServerBs = new Server(shortServerIdBs, 300)); } else { if (securityBs == null) { initializer.setInstancesForObject(SERVER, lwm2mServer = new Server(shortServerId, 300)); } else { - Server serverBootstrap = new Server(shortServerIdBs, 300); - Server serverLwm2m = new Server(shortServerId, 300); - LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{serverBootstrap, serverLwm2m}; + lwm2mServerBs = new Server(shortServerIdBs, 300); + lwm2mServerBs.setId(0); + lwm2mServer =new Server(shortServerId, 300); + lwm2mServer.setId(1); + LwM2mInstanceEnabler[] instances = new LwM2mInstanceEnabler[]{lwm2mServerBs, lwm2mServer}; initializer.setClassForObject(SERVER, Server.class); initializer.setInstancesForObject(SERVER, instances); } @@ -277,7 +285,16 @@ public class LwM2MTestClient { if (client != null) { client.destroy(true); } - if (lwm2mServer != null) { + if (lwm2mSecurityBs != null) { + lwm2mSecurityBs = null; + } + if (lwm2mSecurity != null) { + lwm2mSecurity = null; + } + if (lwm2mServerBs != null) { + lwm2mServerBs = null; + } + if (lwm2mServer != null) { lwm2mServer = null; } if (lwM2MDevice != null) { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index a82eb8d86c..05cf0216cc 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -20,7 +20,9 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.eclipse.californium.elements.config.Configuration; import org.eclipse.leshan.client.object.Security; +import org.eclipse.leshan.core.CertificateUsage; import org.eclipse.leshan.core.ResponseCode; +import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.core.util.Hex; import org.junit.Assert; import org.springframework.test.web.servlet.MvcResult; @@ -62,7 +64,6 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import static org.awaitility.Awaitility.await; -import static org.eclipse.leshan.client.object.Security.noSec; import static org.eclipse.leshan.client.object.Security.noSecBootstap; import static org.junit.Assert.assertEquals; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -172,7 +173,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); this.basicTestConnection(noSecBootstap(URI_BS), deviceCredentials, - COAP_CONFIG_BS, + COAP_CONFIG, clientEndpoint, transportConfiguration, awaitAlias, @@ -190,9 +191,12 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M Set expectedStatuses, boolean isBootstrap, LwM2MClientState finishState) throws Exception { + createNewClient(security, coapConfig, true, endpoint, isBootstrap, null); createDeviceProfile(transportConfiguration); - createDevice(deviceCredentials, endpoint); - createNewClient(security, coapConfig, false, endpoint, isBootstrap, null); + final Device device = createDevice(deviceCredentials, endpoint); + device.getId().getId().toString(); + client.start(); + await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) .until(() -> finishState.equals(client.getClientState())); @@ -212,21 +216,19 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M public void basicTestConnectionBootstrapRequestTriggerBefore(String clientEndpoint, String awaitAlias, LwM2MProfileBootstrapConfigType type) throws Exception { - Security securityBs = noSecBootstap(URI_BS); - Security security = noSec(URI, shortServerId); Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(type)); LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); this.basicTestConnectionBootstrapRequestTrigger( - security, + SECURITY_NO_SEC, deviceCredentials, - COAP_CONFIG_BS, + COAP_CONFIG, clientEndpoint, transportConfiguration, awaitAlias, expectedStatusesRegistrationLwm2mSuccess, expectedStatusesRegistrationBsSuccess, false, - securityBs); + SECURITY_NO_SEC_BS); } private void basicTestConnectionBootstrapRequestTrigger(Security security, @@ -239,10 +241,11 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M Set expectedStatusesBs, boolean isBootstrap, Security securityBs) throws Exception { + createNewClient(security, coapConfig, true, endpoint, isBootstrap, securityBs); createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); String deviceId = device.getId().getId().toString(); - createNewClient(security, coapConfig, false, endpoint, isBootstrap, securityBs); + client.start(); await(awaitAlias) .atMost(1000, TimeUnit.MILLISECONDS) @@ -250,7 +253,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M Assert.assertEquals(expectedStatusesLwm2m, client.getClientStates()); String executedPath = getObjectIdVer_1() + "/0/" + RESOURCE_ID_9; - String actualResult = sendRPCExecuteById(executedPath, deviceId); + String actualResult = sendRPCSecurityExecuteById(executedPath, deviceId, endpoint); ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.CHANGED.getName(), rpcActualResult.get("result").asText()); @@ -414,7 +417,10 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M return doPost("/api/device/credentials", deviceCredentials).andReturn(); } - private String sendRPCExecuteById(String path, String deviceId) throws Exception { + private String sendRPCSecurityExecuteById(String path, String deviceId, String endpoint) throws Exception { + log.info("endpoint1: [{}]", endpoint); + + String setRpcRequest = "{\"method\": \"Execute\", \"params\": {\"id\": \"" + path + "\"}}"; return doPostAsync("/api/plugins/rpc/twoway/" + deviceId, setRpcRequest, String.class, status().isOk()); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java index 0bcf65fd70..cf4809f11a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/store/LwM2MBootstrapConfigStoreTaskProvider.java @@ -34,7 +34,6 @@ import org.eclipse.leshan.server.bootstrap.BootstrapTaskProvider; import org.eclipse.leshan.server.bootstrap.BootstrapUtil; import java.math.BigInteger; -import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -169,7 +168,13 @@ public class LwM2MBootstrapConfigStoreTaskProvider implements BootstrapTaskProvi this.serverInstances = new HashMap<>(); try { ((LwM2mObject) readResponse.getContent()).getInstances().values().forEach(instance -> { - Integer shortId = OPAQUE.equals(instance.getResource(0).getType()) ? new BigInteger((byte[]) instance.getResource(0).getValue()).intValue() : (Integer) instance.getResource(0).getValue(); + var shId = OPAQUE.equals(instance.getResource(0).getType()) ? new BigInteger((byte[]) instance.getResource(0).getValue()).intValue() : instance.getResource(0).getValue(); + int shortId; + if (shId instanceof Long) { + shortId = ((Long) shId).intValue(); + } else { + shortId = ((Integer) shId).intValue(); + } serverInstances.put(shortId, instance.getId()); }); } catch (Exception e) { @@ -259,7 +264,7 @@ public class LwM2MBootstrapConfigStoreTaskProvider implements BootstrapTaskProvi if (this.bootstrapServerIdNew != null && server.getValue().shortId == this.bootstrapServerIdNew && (this.bootstrapServerIdNew != this.bootstrapServerIdOld || securityInstanceId != this.serverInstances.get(this.bootstrapServerIdOld))) { pathsDelete.add("/1/" + this.serverInstances.get(this.bootstrapServerIdOld)); - /** Delete instance if serverIdNew is present in serverInstances and securityInstanceIdOld by serverIdNew not equals serverInstanceIdOld */ + /** Delete instance if serverIdNew is present in serverInstances and securityInstanceIdOld by serverIdNew not equals serverInstanceIdOld */ } else if (this.serverInstances.containsKey(server.getValue().shortId) && securityInstanceId != this.serverInstances.get(server.getValue().shortId)) { pathsDelete.add("/1/" + this.serverInstances.get(server.getValue().shortId)); } From cad54fa70cb4308db19cd36636e6f3eae4718fef Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Fri, 28 Jan 2022 12:45:05 +0200 Subject: [PATCH 06/51] lwm2m: fix bug security tests --- .../controller/AbstractWebsocketTest.java | 63 --------- .../lwm2m/AbstractLwM2MIntegrationTest.java | 124 +----------------- .../AbstractSecurityLwM2MIntegrationTest.java | 65 +++++---- .../security/sql/PskLwm2mIntegrationTest.java | 2 +- .../security/sql/RpkLwM2MIntegrationTest.java | 2 +- .../sql/X509_NoTrustLwM2MIntegrationTest.java | 2 +- .../sql/X509_TrustLwM2MIntegrationTest.java | 2 +- 7 files changed, 42 insertions(+), 218 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java index 2edc985301..15884f38a0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebsocketTest.java @@ -15,83 +15,20 @@ */ package org.thingsboard.server.controller; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Header; -import io.jsonwebtoken.Jwt; -import io.jsonwebtoken.Jwts; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.hamcrest.Matcher; -import org.junit.After; import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.TestRule; -import org.junit.rules.TestWatcher; -import org.junit.runner.Description; import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.context.SpringBootContextLoader; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.StringHttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; -import org.springframework.mock.http.MockHttpInputMessage; -import org.springframework.mock.http.MockHttpOutputMessage; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.ResultActions; -import org.springframework.test.web.servlet.ResultMatcher; -import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.context.WebApplicationContext; -import org.thingsboard.server.common.data.BaseData; -import org.thingsboard.server.common.data.Customer; -import org.thingsboard.server.common.data.Tenant; -import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.id.UUIDBased; -import org.thingsboard.server.common.data.page.PageLink; -import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.common.data.security.Authority; -import org.thingsboard.server.config.ThingsboardSecurityConfiguration; -import org.thingsboard.server.service.mail.TestMailService; -import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRequest; -import org.thingsboard.server.service.security.auth.rest.LoginRequest; - -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.List; - -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; @ActiveProfiles("test") @RunWith(SpringRunner.class) diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java index 510d978046..c63901a7dc 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -74,10 +74,11 @@ import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import static org.eclipse.californium.core.config.CoapConfig.COAP_PORT; +import static org.eclipse.californium.core.config.CoapConfig.COAP_SECURE_PORT; import static org.eclipse.leshan.client.object.Security.noSec; import static org.eclipse.leshan.client.object.Security.noSecBootstap; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode.NO_SEC; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_STARTED; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_BOOTSTRAP_SUCCESS; import static org.thingsboard.server.transport.lwm2m.Lwm2mTestHelper.LwM2MClientState.ON_INIT; @@ -107,7 +108,8 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest public static final String SECURE_URI = COAPS + host + ":" + securityPort; public static final String URI_BS = COAP + hostBs + ":" + portBs; public static final String SECURE_URI_BS = COAPS + hostBs + ":" + securityPortBs; - public static final Configuration COAP_CONFIG = new Configuration(); + public static final Configuration COAP_CONFIG = new Configuration().set(COAP_PORT, port).set(COAP_SECURE_PORT, securityPort); + public static Configuration COAP_CONFIG_BS = new Configuration().set(COAP_PORT, portBs).set(COAP_SECURE_PORT, securityPortBs); public static final Security SECURITY_NO_SEC = noSec(URI, shortServerId); public static final Security SECURITY_NO_SEC_BS = noSecBootstap(URI_BS); @@ -148,121 +150,8 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest " \"clientOnlyObserveAfterConnect\": 1\n" + " }"; - - protected final String TRANSPORT_CONFIGURATION_NO_SEC_WITHOUT_ATTRIBUTES = "{\n" + - " \"type\": \"LWM2M\",\n" + - " \"observeAttr\": {\n" + - " \"keyName\": {},\n" + - " \"observe\": [],\n" + - " \"attribute\": [],\n" + - " \"telemetry\": [],\n" + - " \"attributeLwm2m\": {}\n" + - " },\n" + - " \"bootstrapServerUpdateEnable\": true,\n" + - " \"bootstrap\": [\n" + - " {\n" + - " \"host\": \"" + hostBs + "\",\n" + - " \"port\": " + portBs + ",\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + - " \"shortServerId\": " + shortServerIdBs + ",\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": true,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " },\n" + - " {\n" + - " \"host\": \"" + host + "\",\n" + - " \"port\": " + port + ",\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + - " \"shortServerId\": " + shortServerId + ",\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": false,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " }\n" + - " ],\n" + - " \"clientLwM2mSettings\": {\n" + - " \"edrxCycle\": null,\n" + - " \"powerMode\": \"DRX\",\n" + - " \"fwUpdateResource\": null,\n" + - " \"fwUpdateStrategy\": 1,\n" + - " \"psmActivityTimer\": null,\n" + - " \"swUpdateResource\": null,\n" + - " \"swUpdateStrategy\": 1,\n" + - " \"pagingTransmissionWindow\": null,\n" + - " \"clientOnlyObserveAfterConnect\": 1\n" + - " }\n" + - "}"; - - - protected final String TRANSPORT_CONFIGURATION = "{\n" + - " \"type\": \"LWM2M\",\n" + - " \"observeAttr\": {\n" + - " \"keyName\": {\n" + - " \"/3_1.0/0/9\": \"batteryLevel\"\n" + - " },\n" + - " \"observe\": [],\n" + - " \"attribute\": [\n" + - " ],\n" + - " \"telemetry\": [\n" + - " \"/3_1.0/0/9\"\n" + - " ],\n" + - " \"attributeLwm2m\": {}\n" + - " },\n" + - " \"bootstrapServerUpdateEnable\": true,\n" + - " \"bootstrap\": [\n" + - " {\n" + - " \"host\": \"" + hostBs + "\",\n" + - " \"port\": " + portBs + ",\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + - " \"shortServerId\": " + shortServerIdBs + ",\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": true,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " },\n" + - " {\n" + - " \"host\": \"" + host + "\",\n" + - " \"port\": " + port + ",\n" + - " \"binding\": \"U\",\n" + - " \"lifetime\": 300,\n" + - " \"securityMode\": \"" + NO_SEC.name() + "\",\n" + - " \"shortServerId\": " + shortServerId + ",\n" + - " \"notifIfDisabled\": true,\n" + - " \"serverPublicKey\": \"\",\n" + - " \"defaultMinPeriod\": 1,\n" + - " \"bootstrapServerIs\": false,\n" + - " \"clientHoldOffTime\": 1,\n" + - " \"bootstrapServerAccountTimeout\": 0\n" + - " }\n" + - " ],\n" + - " \"clientLwM2mSettings\": {\n" + - " \"edrxCycle\": null,\n" + - " \"powerMode\": \"DRX\",\n" + - " \"fwUpdateResource\": null,\n" + - " \"fwUpdateStrategy\": 1,\n" + - " \"psmActivityTimer\": null,\n" + - " \"swUpdateResource\": null,\n" + - " \"swUpdateStrategy\": 1,\n" + - " \"pagingTransmissionWindow\": null,\n" + - " \"clientOnlyObserveAfterConnect\": 1\n" + - " }\n" + - "}"; - - protected final Set expectedStatusesBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS)); - protected final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); + protected final Set expectedStatusesBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS)); + protected final Set expectedStatusesRegistrationLwm2mSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected final Set expectedStatusesRegistrationBsSuccess = new HashSet<>(Arrays.asList(ON_INIT, ON_BOOTSTRAP_STARTED, ON_BOOTSTRAP_SUCCESS, ON_REGISTRATION_STARTED, ON_REGISTRATION_SUCCESS)); protected DeviceProfile deviceProfile; protected ScheduledExecutorService executor; @@ -299,6 +188,7 @@ public abstract class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest @After public void after() { + wsClient.close(); clientDestroy(); executor.shutdownNow(); } diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java index 05cf0216cc..2f1d528573 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/AbstractSecurityLwM2MIntegrationTest.java @@ -20,9 +20,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.eclipse.californium.elements.config.Configuration; import org.eclipse.leshan.client.object.Security; -import org.eclipse.leshan.core.CertificateUsage; import org.eclipse.leshan.core.ResponseCode; -import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.core.util.Hex; import org.junit.Assert; import org.springframework.test.web.servlet.MvcResult; @@ -173,7 +171,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); this.basicTestConnection(noSecBootstap(URI_BS), deviceCredentials, - COAP_CONFIG, + COAP_CONFIG_BS, clientEndpoint, transportConfiguration, awaitAlias, @@ -183,14 +181,14 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M } protected void basicTestConnection(Security security, - LwM2MDeviceCredentials deviceCredentials, - Configuration coapConfig, - String endpoint, - Lwm2mDeviceProfileTransportConfiguration transportConfiguration, - String awaitAlias, - Set expectedStatuses, - boolean isBootstrap, - LwM2MClientState finishState) throws Exception { + LwM2MDeviceCredentials deviceCredentials, + Configuration coapConfig, + String endpoint, + Lwm2mDeviceProfileTransportConfiguration transportConfiguration, + String awaitAlias, + Set expectedStatuses, + boolean isBootstrap, + LwM2MClientState finishState) throws Exception { createNewClient(security, coapConfig, true, endpoint, isBootstrap, null); createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); @@ -214,33 +212,32 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M } - public void basicTestConnectionBootstrapRequestTriggerBefore(String clientEndpoint, String awaitAlias, LwM2MProfileBootstrapConfigType type) throws Exception { - Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(type)); - LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); - this.basicTestConnectionBootstrapRequestTrigger( - SECURITY_NO_SEC, - deviceCredentials, - COAP_CONFIG, - clientEndpoint, - transportConfiguration, - awaitAlias, - expectedStatusesRegistrationLwm2mSuccess, - expectedStatusesRegistrationBsSuccess, - false, - SECURITY_NO_SEC_BS); + Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsNoSec(type)); + LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsNoSec(createNoSecClientCredentials(clientEndpoint)); + this.basicTestConnectionBootstrapRequestTrigger( + SECURITY_NO_SEC, + deviceCredentials, + COAP_CONFIG, + clientEndpoint, + transportConfiguration, + awaitAlias, + expectedStatusesRegistrationLwm2mSuccess, + expectedStatusesRegistrationBsSuccess, + false, + SECURITY_NO_SEC_BS); } private void basicTestConnectionBootstrapRequestTrigger(Security security, - LwM2MDeviceCredentials deviceCredentials, - Configuration coapConfig, - String endpoint, - Lwm2mDeviceProfileTransportConfiguration transportConfiguration, - String awaitAlias, - Set expectedStatusesLwm2m, - Set expectedStatusesBs, - boolean isBootstrap, - Security securityBs) throws Exception { + LwM2MDeviceCredentials deviceCredentials, + Configuration coapConfig, + String endpoint, + Lwm2mDeviceProfileTransportConfiguration transportConfiguration, + String awaitAlias, + Set expectedStatusesLwm2m, + Set expectedStatusesBs, + boolean isBootstrap, + Security securityBs) throws Exception { createNewClient(security, coapConfig, true, endpoint, isBootstrap, securityBs); createDeviceProfile(transportConfiguration); final Device device = createDevice(deviceCredentials, endpoint); diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java index 9db90a9fdb..feff1ee926 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/PskLwm2mIntegrationTest.java @@ -101,7 +101,7 @@ public class PskLwm2mIntegrationTest extends AbstractSecurityLwM2MIntegrationTes LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, null, null, PSK, false); this.basicTestConnection(securityBs, deviceCredentials, - COAP_CONFIG, + COAP_CONFIG_BS, clientEndpoint, transportConfiguration, "await on client state (PskBS two section)", diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java index 082642690d..cfc55fae9a 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/RpkLwM2MIntegrationTest.java @@ -118,7 +118,7 @@ public class RpkLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegrationTes LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, clientPrivateKeyFromCertTrust, certificate, RPK, false); this.basicTestConnection(securityBs, deviceCredentials, - COAP_CONFIG, + COAP_CONFIG_BS, clientEndpoint, transportConfiguration, "await on client state (RpkBS two section)", diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java index 76f5af8965..6e9dc615e5 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_NoTrustLwM2MIntegrationTest.java @@ -118,7 +118,7 @@ public class X509_NoTrustLwM2MIntegrationTest extends AbstractSecurityLwM2MInteg LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); this.basicTestConnection(security, deviceCredentials, - COAP_CONFIG, + COAP_CONFIG_BS, clientEndpoint, transportConfiguration, "await on client state (X509NoTrust two section)", diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java index a7087bc072..59c7360d20 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/security/sql/X509_TrustLwM2MIntegrationTest.java @@ -78,7 +78,7 @@ public class X509_TrustLwM2MIntegrationTest extends AbstractSecurityLwM2MIntegra LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false); this.basicTestConnection(security, deviceCredentials, - COAP_CONFIG, + COAP_CONFIG_BS, clientEndpoint, transportConfiguration, "await on client state (X509Trust two section)", From 1f2eaf07edb14d63ec3597c09f00e2f587559161 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sun, 30 Jan 2022 22:21:00 +0200 Subject: [PATCH 07/51] lwm2m: del shell from tests --- .../lwm2m/lwm2m_cfssl_chain_all_for_test.sh | 70 ++++++++++++++----- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/tools/src/main/shell/lwm2m/lwm2m_cfssl_chain_all_for_test.sh b/tools/src/main/shell/lwm2m/lwm2m_cfssl_chain_all_for_test.sh index de7538bc36..5856d07932 100755 --- a/tools/src/main/shell/lwm2m/lwm2m_cfssl_chain_all_for_test.sh +++ b/tools/src/main/shell/lwm2m/lwm2m_cfssl_chain_all_for_test.sh @@ -29,26 +29,41 @@ cd -- "$( dirname "${0}" )" || exit 1 -Help() +ResultInfo() { - # Display Help - echo "Description of the script functions." - echo - echo "Syntax: scriptTemplate [-g|h|v|V]" - echo "options:" - echo "h Print this Help." - echo "v Verbose mode." - echo "V Print software version and exit." - echo +# # Display Help +# echo "Description of the script functions." +# echo +# echo "Syntax: scriptTemplate [-g|h|v|V]" +# echo "options:" +# echo "h Print this Help." +# echo "v Verbose mode." +# echo "V Print software version and exit." +# echo +if [ "$IS_IHFO" = false ] ; then + if [ "$IS_SERVER_CREATED_KEY" = true ] ; then + ./lwm2m_cfssl_chain_server_for_test.sh > /dev/null 2>&1 & + fi + if [ "$IS_TRUST_CLIENT_CREATED_KEY" = true ] ; then + ./lwM2M_cfssl_chain_clients_for_test.sh ${INTERMEDIATE_START} ${INTERMEDIATE_FINISH} ${CLIENT_START} ${CLIENT_FINISH} > /dev/null 2>&1 & + fi +else + if [ "$IS_SERVER_CREATED_KEY" = true ] ; then + ./lwm2m_cfssl_chain_server_for_test.sh + fi + if [ "$IS_TRUST_CLIENT_CREATED_KEY" = true ] ; then + ./lwM2M_cfssl_chain_clients_for_test.sh ${INTERMEDIATE_START} ${INTERMEDIATE_FINISH} ${CLIENT_START} ${CLIENT_FINISH} + fi +fi } -if [ "$1" == "-h" ] ; then - echo -e "Usage 1: ./`basename $0` \"Information is not displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are generated\"" - echo -e "Usage 2: ./`basename $0` true \"Information is displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are generated\"" - echo -e "Usage 3: ./`basename $0` true false \"Information is displayed\" : \"Keys for the server are not generated\" : \"Keys for the clients and trusts are generated\"" - echo -e "Usage 4: ./`basename $0` true false false \"Information is displayed\" : \"Keys for the server are not generated\" : \"Keys for the clients and trusts are not generated\"" - echo -e "Usage 5: ./`basename $0` true true false \"Information is displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are not generated\"" - echo "This Help File: ./`basename $0` -h" +if [ "$1" == "-h" ] ||[ "$1" == "-?" ] || [ "$1" == "-help" ] ; then + echo -e "Usage 1: \"Information is not displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are generated\"\n./`basename $0`" + echo -e "Usage 2: \"Information is displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are generated\"\n./`basename $0` true \n./`basename $0` true true true " + echo -e "Usage 3: \"Information is displayed\" : \"Keys for the server are not generated\" : \"Keys for the clients and trusts are generated\"\n./`basename $0` true false \n./`basename $0` true false true" + echo -e "Usage 4: \"Information is displayed\" : \"Keys for the server are not generated\" : \"Keys for the clients and trusts are not generated\"\n./`basename $0` true false false" + echo -e "Usage 5: \"Information is displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are not generated\"\n./`basename $0` true true false" + echo -e "This Help File: \n./`basename $0` -h | -? | -help" exit 0 fi @@ -64,6 +79,14 @@ if [ -n "$3" ]; then IS_TRUST_CLIENT_CREATED_KEY=$3 fi +if [ "$IS_SERVER_CREATED_KEY" = false ] && [ "$IS_TRUST_CLIENT_CREATED_KEY" = false ] ; then + echo -e "Result is null" + echo -e "This Help File: \n./`basename $0` -h | -? | -help" + exit 0 +fi + + + if [ "$IS_IHFO" = false ] ; then if [ "$IS_SERVER_CREATED_KEY" = true ] ; then ./lwm2m_cfssl_chain_server_for_test.sh > /dev/null 2>&1 & @@ -78,4 +101,15 @@ else if [ "$IS_TRUST_CLIENT_CREATED_KEY" = true ] ; then ./lwM2M_cfssl_chain_clients_for_test.sh ${INTERMEDIATE_START} ${INTERMEDIATE_FINISH} ${CLIENT_START} ${CLIENT_FINISH} fi -fi \ No newline at end of file +fi + +echo -e "Result into:" +if [ "$IS_SERVER_CREATED_KEY" = true ] ; then + echo -e "./Server" +fi +if [ "$IS_TRUST_CLIENT_CREATED_KEY" = true ] ; then + echo -e "./Client" + echo -e "./Trust" +fi + +echo -e "Finish" \ No newline at end of file From 11140fe89ba5283d9a76723f8afa0f58d9d612ac Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sun, 30 Jan 2022 22:24:29 +0200 Subject: [PATCH 08/51] lwm2m: del shell from tests --- ...cfssl_chain_trusts_and_clients_for_test.sh | 299 ------------------ .../shell/lwm2m_cfssl_chain_for_test_All.sh | 65 ---- .../lwm2m_cfssl_chain_server_for_test.sh | 298 ----------------- 3 files changed, 662 deletions(-) delete mode 100755 application/src/test/resources/lwm2m/credentials/shell/lwM2M_cfssl_chain_trusts_and_clients_for_test.sh delete mode 100755 application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_for_test_All.sh delete mode 100755 application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_server_for_test.sh diff --git a/application/src/test/resources/lwm2m/credentials/shell/lwM2M_cfssl_chain_trusts_and_clients_for_test.sh b/application/src/test/resources/lwm2m/credentials/shell/lwM2M_cfssl_chain_trusts_and_clients_for_test.sh deleted file mode 100755 index 26f47266a7..0000000000 --- a/application/src/test/resources/lwm2m/credentials/shell/lwM2M_cfssl_chain_trusts_and_clients_for_test.sh +++ /dev/null @@ -1,299 +0,0 @@ -#!/usr/bin/env bash - -# Change working directory -cd -- "$( - dirname "${0}" -)" || exit 1 - -readonly TRUST_PATH="Trust" -readonly CA_ROOT_CERT_KEY="ca-root" -readonly CA_ROOT_ALIAS="root" -readonly CA_INTERMEDIATE_CERT_KEY_PREF="intermediate_ca" -CA_INTERMEDIATE_START=0 -CA_INTERMEDIATE_FINISH=2 -CA_INTERMEDIATE_NUMBER=${CA_INTERMEDIATE_START} -CA_INTERMEDIATE_CERT_SIGN=${CA_ROOT_CERT_KEY} -CA_LIST_CERT_FOR_CAT="" -readonly CA_TRUST_STORE_ALL_CHAIN="lwm2mtruststorechain" -readonly CA_TRUST_STORE_PWD="server_ks_password" -readonly CA_TRUST_CERT_ALIAS="root" -readonly CA_TRUST_CERT_CHAIN_JKS="lwm2mtruststorechain" -readonly CA_TRUST_STORE_CHAIN_ALIAS="trust_cert_chain_alias" - -readonly CLIENT_PATH="Client" -readonly CLIENT_JKS_FOR_TEST="lwm2mclient" -readonly CLIENT_CERT_KEY_PREF="LwX509" -readonly CLIENT_CERT_ALIAS_PREF="client_alias_" -readonly CLIENT_STORE_PWD="client_ks_password" -readonly CLIENT_HOST_NAME="thingsboard_test.io" -CLIENT_START=0 -CLIENT_FINISH=1 -CLIENT_NUMBER=${CLIENT_START} - -SERVER_HOST_NAME="localhost.localdomain" -SERVER_LOCAL_HOST_NAME="localhost" -SERVER_PUBLIC_HOST_NAMES="-" - -readonly CF_COMMANDS=" - cfssl - cfssljson -" - -if [ ! -z "$1" ]; then - CA_INTERMEDIATE_START=$1 - CA_INTERMEDIATE_NUMBER=${CA_INTERMEDIATE_START} -fi - -if [ ! -z "$2" ]; then - CA_INTERMEDIATE_FINISH=$2 -fi - -if [ ! -z "$3" ]; then - CLIENT_START=$1 - CLIENT_NUMBER=${CLIENT_START} -fi - -if [ ! -z "$4" ]; then - CLIENT_FINISH=$4 -fi - -# Change working directory -rm -rf ${TRUST_PATH} -mkdir -p ${TRUST_PATH} -rm -rf ${CLIENT_PATH} -mkdir -p ${CLIENT_PATH} -cd -- "$( - dirname "${0}" -)" || exit 1 - - -rm *.csr -rm *.p12 -rm *.json -rm *.pem -rm *.jks - -intermediate_common_name() { - echo "${CA_INTERMEDIATE_CERT_KEY_PREF}${CA_INTERMEDIATE_NUMBER}" -} - -set_list_sert_for_cat() { - local first="$1" - echo "$first ${CA_LIST_CERT_FOR_CAT}" -} - -client_common_name() { - echo "${CLIENT_CERT_KEY_PREF}$(printf "%08d" ${CLIENT_NUMBER})" -} - -client_alias_name() { - echo "${CLIENT_CERT_ALIAS_PREF}$(printf "%08d" ${CLIENT_NUMBER})" -} - -for COMMAND in ${CF_COMMANDS}; do - if ! command -v ${COMMAND} &> /dev/null; then - echo "ERROR: Missing command ${COMMAND}" >&2 - echo "Install the package from: https://pkg.cfssl.org/" >&2 - exit 1 - fi -done - -tee ./${TRUST_PATH}/ca-config.json 1> /dev/null <<-CONFIG -{ - "signing": { - "default": { - "expiry": "8760h", - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ] - }, - "profiles": { - "server": { - "expiry": "43800h", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "signing", - "key encipherment", - "server auth" - ] - }, - "client": { - "expiry": "43800h", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "signing", - "key encipherment", - "client auth" - ] - }, - "client-server": { - "expiry": "43800h", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "signing", - "key encipherment", - "server auth", - "client auth" - ] - } - } - } -} -CONFIG - -tee ./${TRUST_PATH}/ca-root-to-intermediate-config.json 1> /dev/null <<-CONFIG -{ - "signing": { - "default": { - "expiry": "43800h", - "ca_constraint": { - "is_ca": true, - "max_path_len": 0, - "max_path_len_zero": true - }, - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "digital signature", - "cert sign", - "crl sign", - "signing" - ] - } - } -} -CONFIG - -echo "====================================================" -echo -e "Generate the root of certificates: \n-${CA_ROOT_KEY}-key.pem (certificate key)\n-${CA_ROOT_KEY}.pem (certificate)\n-${CA_ROOT_KEY}.csr (sign request)" -echo "====================================================" -cfssl genkey \ - -initca \ - - \ - <<-CONFIG | cfssljson -bare ./${TRUST_PATH}/${CA_ROOT_CERT_KEY} -{ - "CN": "ROOT CA", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ], - "ca": { - "expiry": "131400h" - } -} -CONFIG -CA_LIST_CERT_FOR_CAT=$(set_list_sert_for_cat ./${TRUST_PATH}/${CA_ROOT_CERT_KEY}.pem) - -echo "====================================================" -echo -e "Generate and Signed the intermediates of our certificates: \n-${CA_INTERMEDIATE_CERT_KEY_PREF}?-key.pem (certificate key)\n-${CA_INTERMEDIATE_CERT_KEY_PREF}?.pem (certificate)\n-${CA_INTERMEDIATE_CERT_KEY_PREF}?.csr (sign request)" -echo "====================================================" - -while [[ ${CA_INTERMEDIATE_NUMBER} -lt ${CA_INTERMEDIATE_FINISH} ]]; -do - CA_INTERMEDIATE_CERT_KEY=$(intermediate_common_name) - CA_INTERMEDIATE_NUMBER=$((${CA_INTERMEDIATE_NUMBER} + 1)) - - cfssl gencert \ - -ca ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_SIGN}.pem \ - -ca-key ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_SIGN}-key.pem \ - -config ./${TRUST_PATH}/ca-root-to-intermediate-config.json \ - -hostname "${SERVER_HOST_NAME},${SERVER_LOCAL_HOST_NAME}${SERVER_PUBLIC_HOST_NAMES:+, }${SERVER_PUBLIC_HOST_NAMES}" \ - - \ - <<-CONFIG | cfssljson -bare ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY} - { - "CN": "${CA_INTERMEDIATE_CERT_KEY}", - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ] - } -CONFIG - #openssl x509 -in ${CA_INTERMEDIATE_CERT_KEY}.pem -text -noout - CA_LIST_CERT_FOR_CAT=$(set_list_sert_for_cat ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem) - CA_INTERMEDIATE_CERT_SIGN=${CA_INTERMEDIATE_CERT_KEY} -done - -echo "====================================================" -echo -e "Add the CA_certificate to keystore: ${CA_TRUST_CERT_CHAIN_JKS}.jks" -echo "====================================================" -cat ${CA_LIST_CERT_FOR_CAT} > ./${TRUST_PATH}/${CA_TRUST_STORE_ALL_CHAIN}.pem -openssl pkcs12 -export -in ./${TRUST_PATH}/${CA_TRUST_STORE_ALL_CHAIN}.pem -inkey ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}-key.pem -out ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}.p12 -name ${CA_TRUST_STORE_CHAIN_ALIAS} -CAfile ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem -caname ${CA_ROOT_ALIAS} -passin pass:${CA_TRUST_STORE_PWD} -passout pass:${CA_TRUST_STORE_PWD} -keytool -importkeystore -deststorepass ${CA_TRUST_STORE_PWD} -destkeypass ${CA_TRUST_STORE_PWD} -destkeystore ./${TRUST_PATH}/${CA_TRUST_CERT_CHAIN_JKS}.jks -srckeystore ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}.p12 -srcstoretype PKCS12 -srcstorepass ${CA_TRUST_STORE_PWD} -alias ${CA_TRUST_STORE_CHAIN_ALIAS} - -keytool -list -v -keystore ./${TRUST_PATH}/lwm2mtruststorechain.jks -storepass server_ks_password -storetype PKCS12 - -echo "====================================================" -echo -e "Generate and Signed the clients of our certificates: \n-${CLIENT_CERT_KEY_PREF}?-key.pem (certificate key)\n-${CLIENT_CERT_KEY_PREF}?.pem (certificate)\n-${CCLIENT_CERT_KEY_PREF}?.csr (sign request)" -echo "====================================================" - - -while [[ ${CLIENT_NUMBER} -lt ${CLIENT_FINISH} ]]; -do - CLIENT_CERT_KEY=$(client_common_name) - CLIENT_CERT_ALIAS=$(client_alias_name) - CLIENT_NUMBER=$((${CLIENT_NUMBER} + 1)) - - cfssl gencert \ - -ca ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem \ - -ca-key ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}-key.pem \ - -config ./${TRUST_PATH}/ca-config.json \ - -profile client \ - -hostname "${CLIENT_HOST_NAME}" \ - - \ - <<-CONFIG | cfssljson -bare ./${CLIENT_PATH}/${CLIENT_CERT_KEY} -{ - "CN": "${CLIENT_CERT_KEY}" -} -CONFIG - -echo "====================================================" -echo -e "Add the client certificate (${CLIENT_CERT_KEY}.pem) to keystore: ${CLIENT_JKS_FOR_TEST}.jks" -echo "====================================================" -cat ./${CLIENT_PATH}/${CLIENT_CERT_KEY}.pem ${CA_LIST_CERT_FOR_CAT} > ./${CLIENT_PATH}/${CLIENT_CERT_KEY}_chain.pem -openssl pkcs12 -export -in ./${CLIENT_PATH}/${CLIENT_CERT_KEY}_chain.pem -inkey ./${CLIENT_PATH}/${CLIENT_CERT_KEY}-key.pem -out ./${CLIENT_PATH}/${CLIENT_CERT_KEY}.p12 -name ${CLIENT_CERT_ALIAS} -CAfile ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem -caname ${CA_ROOT_ALIAS} -passin pass:${CLIENT_STORE_PWD} -passout pass:${CLIENT_STORE_PWD} -keytool -importkeystore -deststorepass ${CLIENT_STORE_PWD} -destkeypass ${CLIENT_STORE_PWD} -destkeystore ./${CLIENT_PATH}/${CLIENT_JKS_FOR_TEST}.jks -srckeystore ./${CLIENT_PATH}/${CLIENT_CERT_KEY}.p12 -srcstoretype PKCS12 -srcstorepass ${CLIENT_STORE_PWD} -alias ${CLIENT_CERT_ALIAS} - -done - -keytool -list -v -keystore ./${CLIENT_PATH}/lwm2mclient.jks -storepass client_ks_password -storetype PKCS12 - -rm ./${TRUST_PATH}/*.p12 -rm ./${TRUST_PATH}/*.csr -rm ./${TRUST_PATH}/*.json -rm ./${TRUST_PATH}/${CA_ROOT_CERT_KEY}* -rm ./${TRUST_PATH}/${CA_INTERMEDIATE_CERT_KEY_PREF}* - - -rm ./${CLIENT_PATH}/*.p12 2> /dev/null -rm ./${CLIENT_PATH}/*.csr 2> /dev/null diff --git a/application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_for_test_All.sh b/application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_for_test_All.sh deleted file mode 100755 index b3b114cb28..0000000000 --- a/application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_for_test_All.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - -readonly INTERMEDIATE_START=0 -readonly INTERMEDIATE_FINISH=2 -readonly CLIENT_START=0 -readonly CLIENT_FINISH=5 - -IS_IHFO=false -IS_SERVER_CREATED_KEY=true -IS_TRUST_CLIENT_CREATED_KEY=true - -cd -- "$( - dirname "${0}" -)" || exit 1 - -Help() -{ - # Display Help - echo "Description of the script functions." - echo - echo "Syntax: scriptTemplate [-g|h|v|V]" - echo "options:" - echo "h Print this Help." - echo "v Verbose mode." - echo "V Print software version and exit." - echo -} - -if [ "$1" == "-h" ] ; then - echo -e "Usage 2: ./`basename $0` \"Information is not displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are generated\"" - echo -e "Usage 1: ./`basename $0` true \"Information is displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are generated\"" - echo -e "Usage 3: ./`basename $0` true false \"Information is displayed\" : \"Keys for the server are not generated\" : \"Keys for the clients and trusts are generated\"" - echo -e "Usage 4: ./`basename $0` true false false \"Information is displayed\" : \"Keys for the server are not generated\" : \"Keys for the clients and trusts are not generated\"" - echo -e "Usage 4: ./`basename $0` true true false \"Information is displayed\" : \"Keys for the server are generated\" : \"Keys for the clients and trusts are not generated\"" - echo "This Help File: ./`basename $0` -h" - exit 0 -fi - -if [ -n "$1" ]; then - IS_IHFO=$1 -fi - -if [ -n "$2" ]; then - IS_SERVER_CREATED_KEY=$2 -fi - -if [ -n "$3" ]; then - IS_TRUST_CLIENT_CREATED_KEY=$3 -fi - -if [ "$IS_IHFO" = false ] ; then - if [ "$IS_SERVER_CREATED_KEY" = true ] ; then - ./lwm2m_cfssl_chain_server_for_test.sh > /dev/null 2>&1 & - fi - if [ "$IS_TRUST_CLIENT_CREATED_KEY" = true ] ; then - ./lwM2M_cfssl_chain_trusts_and_clients_for_test.sh ${INTERMEDIATE_START} ${INTERMEDIATE_FINISH} ${CLIENT_START} ${CLIENT_FINISH} > /dev/null 2>&1 & - fi -else - if [ "$IS_SERVER_CREATED_KEY" = true ] ; then - ./lwm2m_cfssl_chain_server_for_test.sh - fi - if [ "$IS_TRUST_CLIENT_CREATED_KEY" = true ] ; then - ./lwM2M_cfssl_chain_trusts_and_clients_for_test.sh ${INTERMEDIATE_START} ${INTERMEDIATE_FINISH} ${CLIENT_START} ${CLIENT_FINISH} - fi -fi \ No newline at end of file diff --git a/application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_server_for_test.sh b/application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_server_for_test.sh deleted file mode 100755 index efe6ed46dd..0000000000 --- a/application/src/test/resources/lwm2m/credentials/shell/lwm2m_cfssl_chain_server_for_test.sh +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/env bash - -# REF: https://github.com/cloudflare/cfssl - -# Change working directory -cd -- "$( - dirname "${0}" -)" || exit 1 - -readonly CA_ROOT_CERT_KEY="ca-root" -readonly CA_ROOT_ALIAS="root" -readonly CA_INTERMEDIATE_CERT_KEY_PREF="intermediate_ca" -CA_INTERMEDIATE_NUMBER=0 -CA_LIST_CERT_FOR_CAT="" - -readonly CF_COMMANDS=" - cfssl - cfssljson -" - -readonly SERVER_JKS_FOR_TEST="lwm2mserver" -readonly STORE_PASS_PWD="server_ks_password" -readonly SERVER_PATH="Server" -readonly SERVER_CERT_KEY="lwm2mserver" -readonly SERVER_CERT_CHAIN="lwm2mserver_chain" -readonly SERVER_CERT_ALIAS="server" -readonly BS_SERVER_CERT_KEY="lwm2mserverbs" -readonly BS_SERVER_CERT_CHAIN="lwm2mserverbs_chain" -readonly BS_SERVER_CERT_ALIAS="bootstrap" - -SERVER_HOST_NAME="localhost.localdomain" -SERVER_LOCAL_HOST_NAME="localhost" -SERVER_PUBLIC_HOST_NAMES="-" - -intermediate_common_name() { - echo "${CA_INTERMEDIATE_CERT_KEY_PREF}${CA_INTERMEDIATE_NUMBER}" -} - -set_list_sert_for_cat() { - local first="$1" - echo "$first ${CA_LIST_CERT_FOR_CAT}" -} - - -# Change working directory -rm -rf ${SERVER_PATH} -mkdir -p ${SERVER_PATH} - -cd -- "$( - dirname ./${SERVER_PATH} -)" || exit 1 - - -rm *.csr -rm *.p12 -rm *.json -rm *.pem -rm *.jks - -CA_INTERMEDIATE_CERT_SIGN=${CA_ROOT_CERT_KEY} -CA_INTERMEDIATE_CERT_KEY=$(intermediate_common_name) -CA_INTERMEDIATE_NUMBER=$((${CA_INTERMEDIATE_NUMBER} + 1)) -CA_LIST_CERT_FOR_CAT="" - -for COMMAND in ${CF_COMMANDS}; do - if ! command -v ${COMMAND} &> /dev/null; then - echo "ERROR: Missing command ${COMMAND}" >&2 - echo "Install the package from: https://pkg.cfssl.org/" >&2 - exit 1 - fi -done - -tee ./${SERVER_PATH}/ca-config.json 1> /dev/null <<-CONFIG -{ - "signing": { - "default": { - "expiry": "8760h", - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ] - }, - "profiles": { - "server": { - "expiry": "43800h", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "signing", - "key encipherment", - "server auth" - ] - }, - "client": { - "expiry": "43800h", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "signing", - "key encipherment", - "client auth" - ] - }, - "client-server": { - "expiry": "43800h", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "signing", - "key encipherment", - "server auth", - "client auth" - ] - } - } - } -} -CONFIG - -tee ./${SERVER_PATH}/ca-root-to-intermediate-config.json 1> /dev/null <<-CONFIG -{ - "signing": { - "default": { - "expiry": "43800h", - "ca_constraint": { - "is_ca": true, - "max_path_len": 0, - "max_path_len_zero": true - }, - "key": { - "algo": "ecdsa", - "size": 256 - }, - "usages": [ - "digital signature", - "cert sign", - "crl sign", - "signing" - ] - } - } -} -CONFIG - -echo "====================================================" -echo -e "Generate the root of certificates: \n-${CA_ROOT_KEY}-key.pem (certificate key)\n-${CA_ROOT_KEY}.pem (certificate)\n-${CA_ROOT_KEY}.csr (sign request)" -echo "====================================================" -cfssl genkey \ - -initca \ - - \ - <<-CONFIG | cfssljson -bare ./${SERVER_PATH}/${CA_ROOT_CERT_KEY} -{ - "CN": "ROOT CA for servers", - "key": { - "algo": "ecdsa", - "size": 256 - }, - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ], - "ca": { - "expiry": "131400h" - } -} -CONFIG -CA_LIST_CERT_FOR_CAT=$(set_list_sert_for_cat ./${SERVER_PATH}/${CA_ROOT_CERT_KEY}.pem) - -echo "====================================================" -echo -e "Generate and Signed the first intermediates of our certificates: \n-${CA_INTERMEDIATE_CERT_KEY}-key.pem (certificate key)\n-${CA_INTERMEDIATE_CERT_KEY}.pem (certificate)\n-${CA_INTERMEDIATE_CERT_KEY}.csr (sign request)" -echo "====================================================" -cfssl gencert \ - -ca ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_SIGN}.pem \ - -ca-key ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_SIGN}-key.pem \ - -config ./${SERVER_PATH}/ca-root-to-intermediate-config.json \ - -hostname "${SERVER_HOST_NAME},${SERVER_LOCAL_HOST_NAME}${SERVER_PUBLIC_HOST_NAMES:+, }${SERVER_PUBLIC_HOST_NAMES}" \ - - \ - <<-CONFIG | cfssljson -bare ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY} -{ - "CN": "${CA_INTERMEDIATE_CERT_KEY}", - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ] -} -CONFIG -CA_LIST_CERT_FOR_CAT=$(set_list_sert_for_cat ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem) - - -## Lwm2m Server certificate -echo "====================================================" -echo -e "Generate and Signed the server certificate: \n-${SERVER_CERT_KEY}-key.pem (certificate key)\n-${SERVER_CERT_KEY}.pem (certificate)\n-${SERVER_CERT_KEY}.csr (sign request)" -echo "====================================================" -cfssl gencert \ - -ca ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem \ - -ca-key ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}-key.pem \ - -config ./${SERVER_PATH}/ca-config.json \ - -profile server \ - -hostname "${SERVER_HOST_NAME},${SERVER_LOCAL_HOST_NAME}${SERVER_PUBLIC_HOST_NAMES:+, }${SERVER_PUBLIC_HOST_NAMES}" \ - - \ - <<-CONFIG | cfssljson -bare ./${SERVER_PATH}/${SERVER_CERT_KEY} -{ - "CN": "${SERVER_LOCAL_HOST_NAME}" -} -CONFIG - -echo "====================================================" -echo -e "Add the server certificate (${SERVER_CERT_KEY}.pem) to keystore: ${SERVER_JKS_FOR_TEST}.jks" -echo "====================================================" -cat ./${SERVER_PATH}/${SERVER_CERT_KEY}.pem ${CA_LIST_CERT_FOR_CAT} > ./${SERVER_PATH}/${SERVER_CERT_CHAIN}.pem -openssl pkcs12 -export -in ./${SERVER_PATH}/${SERVER_CERT_CHAIN}.pem -inkey ./${SERVER_PATH}/${SERVER_CERT_KEY}-key.pem -out ./${SERVER_PATH}/${SERVER_CERT_KEY}.p12 -name ${SERVER_CERT_ALIAS} -CAfile ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem -caname ${CA_ROOT_ALIAS} -passin pass:${STORE_PASS_PWD} -passout pass:${STORE_PASS_PWD} -keytool -importkeystore -deststorepass ${STORE_PASS_PWD} -destkeypass ${STORE_PASS_PWD} -destkeystore ./${SERVER_PATH}/${SERVER_JKS_FOR_TEST}.jks -srckeystore ./${SERVER_PATH}/${SERVER_CERT_KEY}.p12 -srcstoretype PKCS12 -srcstorepass ${STORE_PASS_PWD} -alias ${SERVER_CERT_ALIAS} - - -CA_INTERMEDIATE_CERT_SIGN=${CA_INTERMEDIATE_CERT_KEY} -CA_INTERMEDIATE_CERT_KEY=$(intermediate_common_name) -CA_INTERMEDIATE_NUMBER=$((${CA_INTERMEDIATE_NUMBER} + 1)) -echo "====================================================" -echo -e "Generate and Signed the second intermediates of our certificates: \n-${CA_INTERMEDIATE_CERT_KEY}-key.pem (certificate key)\n-${CA_INTERMEDIATE_CERT_KEY}.pem (certificate)\n-${CA_INTERMEDIATE_CERT_KEY}.csr (sign request)" -echo "====================================================" -cfssl gencert \ - -ca ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_SIGN}.pem \ - -ca-key ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_SIGN}-key.pem \ - -config ./${SERVER_PATH}/ca-root-to-intermediate-config.json \ - -hostname "${SERVER_HOST_NAME},${SERVER_LOCAL_HOST_NAME}${SERVER_PUBLIC_HOST_NAMES:+, }${SERVER_PUBLIC_HOST_NAMES}" \ - - \ - <<-CONFIG | cfssljson -bare ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY} -{ - "CN": "${CA_INTERMEDIATE_CERT_KEY}", - "names": [ - { - "C": "UK", - "ST": "Kyiv city", - "L": "Kyiv", - "O": "Thingsboard", - "OU": "DEVELOPER_TEST" - } - ] -} -CONFIG -CA_LIST_CERT_FOR_CAT=$(set_list_sert_for_cat ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem) - -## Bootstrap server certificate -echo "====================================================" -echo -e "Generate and Signed the server certificate: \n-${BS_SERVER_CERT_KEY}-key.pem (certificate key)\n-${BS_SERVER_CERT_KEY}.pem (certificate)\n-${BS_SERVER_CERT_KEY}.csr (sign request)" -echo "====================================================" -cfssl gencert \ - -ca ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem \ - -ca-key ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}-key.pem \ - -config ./${SERVER_PATH}/ca-config.json \ - -profile server \ - -hostname "${SERVER_HOST_NAME},${SERVER_LOCAL_HOST_NAME}${SERVER_PUBLIC_HOST_NAMES:+, }${SERVER_PUBLIC_HOST_NAMES}" \ - - \ - <<-CONFIG | cfssljson -bare ./${SERVER_PATH}/${BS_SERVER_CERT_KEY} -{ - "CN": "${SERVER_LOCAL_HOST_NAME}" -} -CONFIG - -echo "====================================================" -echo -e "Add the Bootstrap server certificate (${BS_SERVER_CERT_KEY}.pem) to keystore: ${SERVER_JKS_FOR_TEST}.jks" -echo "====================================================" -cat ./${SERVER_PATH}/${BS_SERVER_CERT_KEY}.pem ${CA_LIST_CERT_FOR_CAT} > ./${SERVER_PATH}/${BS_SERVER_CERT_CHAIN}.pem -openssl pkcs12 -export -in ./${SERVER_PATH}/${BS_SERVER_CERT_CHAIN}.pem -inkey ./${SERVER_PATH}/${BS_SERVER_CERT_KEY}-key.pem -out ./${SERVER_PATH}/${BS_SERVER_CERT_KEY}.p12 -name ${BS_SERVER_CERT_ALIAS} -CAfile ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY}.pem -caname ${CA_ROOT_ALIAS} -passin pass:${STORE_PASS_PWD} -passout pass:${STORE_PASS_PWD} -keytool -importkeystore -deststorepass ${STORE_PASS_PWD} -destkeypass ${STORE_PASS_PWD} -destkeystore ./${SERVER_PATH}/${SERVER_JKS_FOR_TEST}.jks -srckeystore ./${SERVER_PATH}/${BS_SERVER_CERT_KEY}.p12 -srcstoretype PKCS12 -srcstorepass ${STORE_PASS_PWD} -alias ${BS_SERVER_CERT_ALIAS} - - -keytool -list -v -keystore ./${SERVER_PATH}/lwm2mserver.jks -storepass server_ks_password -storetype PKCS12 - -rm ./${SERVER_PATH}/*.p12 2> /dev/null -rm ./${SERVER_PATH}/*.csr 2> /dev/null -rm ./${SERVER_PATH}/*.json 2> /dev/null -rm ./${SERVER_PATH}/${CA_INTERMEDIATE_CERT_KEY_PREF}* 2> /dev/null -rm ./${SERVER_PATH}/${CA_ROOT_CERT_KEY}* 2> /dev/null -mv ./${SERVER_PATH}/${SERVER_CERT_KEY}-key.pem ./${SERVER_PATH}/${SERVER_CERT_KEY}_key.pem -mv ./${SERVER_PATH}/${BS_SERVER_CERT_KEY}-key.pem ./${SERVER_PATH}/${BS_SERVER_CERT_KEY}_key.pem - From 8480f219949476736a591b82095b663a4e23effc Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 1 Feb 2022 10:05:15 +0200 Subject: [PATCH 09/51] lwm2m: del info debug --- .../transport/lwm2m/server/LwM2mVersionedModelProvider.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java index 8f754bc142..8bf8c8396e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java @@ -85,8 +85,6 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider { this.registration = registration; this.tenantId = lwM2mClientContext.getClientByEndpoint(registration.getEndpoint()).getTenantId(); this.modelsLock = new ReentrantLock(); - log.info("tenantId: [{}]", tenantId); - log.info("models: [{}]", models); if (tenantId != null) { models.computeIfAbsent(tenantId, t -> new ConcurrentHashMap<>()); } From e8dfb9684fb60b161fa820b81da4488067e3a5d4 Mon Sep 17 00:00:00 2001 From: "pinkevycdima@gmail.com" Date: Tue, 1 Feb 2022 19:00:50 +0200 Subject: [PATCH 10/51] Fix bug with clear alarm --- .../components/widget/lib/alarms-table-widget.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.html index 269138151f..6a0a4fc3e1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.html @@ -51,7 +51,7 @@ (click)="ackAlarms($event)"> done -