Commit 7ca626a0868422018a8489dce417b02ee31ef4c5

Authored by Yevhen Bondarenko
Committed by GitHub
1 parent 38af4d5d

Created LwM2M credentials (#4546)

* Created LwM2M credentials

* psk endpoint
Showing 17 changed files with 199 additions and 168 deletions
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.controller;
17 17
18 18 import com.fasterxml.jackson.databind.ObjectMapper;
19 19 import lombok.extern.slf4j.Slf4j;
  20 +import org.eclipse.leshan.core.SecurityMode;
20 21 import org.springframework.security.access.prepost.PreAuthorize;
21 22 import org.springframework.web.bind.annotation.PathVariable;
22 23 import org.springframework.web.bind.annotation.RequestBody;
... ... @@ -46,9 +47,11 @@ public class Lwm2mController extends BaseController {
46 47 @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
47 48 @RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{securityMode}/{bootstrapServerIs}", method = RequestMethod.GET)
48 49 @ResponseBody
49   - public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("securityMode") String securityMode,
  50 + public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("securityMode") String strSecurityMode,
50 51 @PathVariable("bootstrapServerIs") boolean bootstrapServer) throws ThingsboardException {
  52 + checkNotNull(strSecurityMode);
51 53 try {
  54 + SecurityMode securityMode = SecurityMode.valueOf(strSecurityMode);
52 55 return lwM2MServerSecurityInfoRepository.getServerSecurityInfo(securityMode, bootstrapServer);
53 56 } catch (Exception e) {
54 57 throw handleException(e);
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.service.lwm2m;
18 18
19 19 import lombok.RequiredArgsConstructor;
20 20 import lombok.extern.slf4j.Slf4j;
  21 +import org.eclipse.leshan.core.SecurityMode;
21 22 import org.eclipse.leshan.core.util.Hex;
22 23 import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
23 24 import org.springframework.stereotype.Service;
... ... @@ -25,7 +26,6 @@ import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
25 26 import org.thingsboard.server.transport.lwm2m.config.LwM2MSecureServerConfig;
26 27 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
27 28 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
28   -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
29 29
30 30 import java.math.BigInteger;
31 31 import java.security.AlgorithmParameters;
... ... @@ -55,17 +55,16 @@ public class LwM2MServerSecurityInfoRepository {
55 55 * @param bootstrapServer
56 56 * @return ServerSecurityConfig more value is default: Important - port, host, publicKey
57 57 */
58   - public ServerSecurityConfig getServerSecurityInfo(String securityMode, boolean bootstrapServer) {
59   - LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase());
60   - ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig, lwM2MSecurityMode);
  58 + public ServerSecurityConfig getServerSecurityInfo(SecurityMode securityMode, boolean bootstrapServer) {
  59 + ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig, securityMode);
61 60 result.setBootstrapServerIs(bootstrapServer);
62 61 return result;
63 62 }
64 63
65   - private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig, LwM2MSecurityMode mode) {
  64 + private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig, SecurityMode securityMode) {
66 65 ServerSecurityConfig bsServ = new ServerSecurityConfig();
67 66 bsServ.setServerId(serverConfig.getId());
68   - switch (mode) {
  67 + switch (securityMode) {
69 68 case NO_SEC:
70 69 bsServ.setHost(serverConfig.getHost());
71 70 bsServ.setPort(serverConfig.getPort());
... ...
... ... @@ -73,17 +73,17 @@ public class LwM2MBootstrapConfig {
73 73 configBs.servers.put(0, server0);
74 74 /* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */
75 75 this.bootstrapServer.setBootstrapServerIs(true);
76   - configBs.security.put(0, setServerSecuruty(this.bootstrapServer.getHost(), this.bootstrapServer.getPort(), this.bootstrapServer.isBootstrapServerIs(), this.bootstrapServer.getSecurityMode(), this.bootstrapServer.getClientPublicKeyOrId(), this.bootstrapServer.getServerPublicKey(), this.bootstrapServer.getClientSecretKey(), this.bootstrapServer.getServerId()));
  76 + configBs.security.put(0, setServerSecurity(this.bootstrapServer.getHost(), this.bootstrapServer.getPort(), this.bootstrapServer.isBootstrapServerIs(), this.bootstrapServer.getSecurityMode(), this.bootstrapServer.getClientPublicKeyOrId(), this.bootstrapServer.getServerPublicKey(), this.bootstrapServer.getClientSecretKey(), this.bootstrapServer.getServerId()));
77 77 /* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Server instance = 1 */
78   - configBs.security.put(1, setServerSecuruty(this.lwm2mServer.getHost(), this.lwm2mServer.getPort(), this.lwm2mServer.isBootstrapServerIs(), this.lwm2mServer.getSecurityMode(), this.lwm2mServer.getClientPublicKeyOrId(), this.lwm2mServer.getServerPublicKey(), this.lwm2mServer.getClientSecretKey(), this.lwm2mServer.getServerId()));
  78 + configBs.security.put(1, setServerSecurity(this.lwm2mServer.getHost(), this.lwm2mServer.getPort(), this.lwm2mServer.isBootstrapServerIs(), this.lwm2mServer.getSecurityMode(), this.lwm2mServer.getClientPublicKeyOrId(), this.lwm2mServer.getServerPublicKey(), this.lwm2mServer.getClientSecretKey(), this.lwm2mServer.getServerId()));
79 79 return configBs;
80 80 }
81 81
82   - private BootstrapConfig.ServerSecurity setServerSecuruty(String host, Integer port, boolean bootstrapServer, String securityMode, String clientPublicKey, String serverPublicKey, String secretKey, int serverId) {
  82 + private BootstrapConfig.ServerSecurity setServerSecurity(String host, Integer port, boolean bootstrapServer, SecurityMode securityMode, String clientPublicKey, String serverPublicKey, String secretKey, int serverId) {
83 83 BootstrapConfig.ServerSecurity serverSecurity = new BootstrapConfig.ServerSecurity();
84 84 serverSecurity.uri = "coaps://" + host + ":" + Integer.toString(port);
85 85 serverSecurity.bootstrapServer = bootstrapServer;
86   - serverSecurity.securityMode = SecurityMode.valueOf(securityMode);
  86 + serverSecurity.securityMode = securityMode;
87 87 serverSecurity.publicKeyOrId = setPublicKeyOrId(clientPublicKey, securityMode);
88 88 serverSecurity.serverPublicKey = (serverPublicKey != null && !serverPublicKey.isEmpty()) ? Hex.decodeHex(serverPublicKey.toCharArray()) : new byte[]{};
89 89 serverSecurity.secretKey = (secretKey != null && !secretKey.isEmpty()) ? Hex.decodeHex(secretKey.toCharArray()) : new byte[]{};
... ... @@ -91,9 +91,9 @@ public class LwM2MBootstrapConfig {
91 91 return serverSecurity;
92 92 }
93 93
94   - private byte[] setPublicKeyOrId(String publicKeyOrIdStr, String securityMode) {
  94 + private byte[] setPublicKeyOrId(String publicKeyOrIdStr, SecurityMode securityMode) {
95 95 return (publicKeyOrIdStr == null || publicKeyOrIdStr.isEmpty()) ? new byte[]{} :
96   - SecurityMode.valueOf(securityMode).equals(SecurityMode.PSK) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
  96 + SecurityMode.PSK.equals(securityMode) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
97 97 Hex.decodeHex(publicKeyOrIdStr.toCharArray());
98 98 }
99 99 }
... ...
... ... @@ -31,7 +31,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
31 31 import org.springframework.stereotype.Service;
32 32 import org.thingsboard.server.gen.transport.TransportProtos;
33 33 import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo;
34   -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
35 34 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
36 35 import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
37 36 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
... ... @@ -73,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
73 72 @Override
74 73 public List<SecurityInfo> getAllByEndpoint(String endPoint) {
75 74 EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
76   - if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
  75 + if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
77 76 /* add value to store from BootstrapJson */
78 77 this.setBootstrapConfigScurityInfo(store);
79 78 BootstrapConfig bsConfigNew = store.getBootstrapConfig();
... ... @@ -97,7 +96,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
97 96 @Override
98 97 public SecurityInfo getByIdentity(String identity) {
99 98 EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
100   - if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
  99 + if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
101 100 /* add value to store from BootstrapJson */
102 101 this.setBootstrapConfigScurityInfo(store);
103 102 BootstrapConfig bsConfig = store.getBootstrapConfig();
... ... @@ -118,29 +117,29 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
118 117 LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store);
119 118 if (lwM2MBootstrapConfig != null) {
120 119 /* Security info */
121   - switch (SecurityMode.valueOf(lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode())) {
  120 + switch (lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode()) {
122 121 /* Use RPK only */
123 122 case PSK:
124 123 store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndpoint(),
125 124 lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(),
126 125 Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientSecretKey().toCharArray())));
127   - store.setSecurityMode(SecurityMode.PSK.code);
  126 + store.setSecurityMode(SecurityMode.PSK);
128 127 break;
129 128 case RPK:
130 129 try {
131 130 store.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(store.getEndpoint(),
132 131 SecurityUtil.publicKey.decode(Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId().toCharArray()))));
133   - store.setSecurityMode(SecurityMode.RPK.code);
  132 + store.setSecurityMode(SecurityMode.RPK);
134 133 break;
135 134 } catch (IOException | GeneralSecurityException e) {
136 135 log.error("Unable to decode Client public key for [{}] [{}]", store.getEndpoint(), e.getMessage());
137 136 }
138 137 case X509:
139 138 store.setSecurityInfo(SecurityInfo.newX509CertInfo(store.getEndpoint()));
140   - store.setSecurityMode(SecurityMode.X509.code);
  139 + store.setSecurityMode(SecurityMode.X509);
141 140 break;
142 141 case NO_SEC:
143   - store.setSecurityMode(SecurityMode.NO_SEC.code);
  142 + store.setSecurityMode(SecurityMode.NO_SEC);
144 143 store.setSecurityInfo(null);
145 144 break;
146 145 default:
... ... @@ -152,10 +151,9 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
152 151
153 152 private LwM2MBootstrapConfig getParametersBootstrap(EndpointSecurityInfo store) {
154 153 try {
155   - JsonObject bootstrapJsonCredential = store.getBootstrapJsonCredential();
156   - if (bootstrapJsonCredential != null) {
  154 + LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig();
  155 + if (lwM2MBootstrapConfig != null) {
157 156 ObjectMapper mapper = new ObjectMapper();
158   - LwM2MBootstrapConfig lwM2MBootstrapConfig = mapper.readValue(bootstrapJsonCredential.toString(), LwM2MBootstrapConfig.class);
159 157 JsonObject bootstrapObject = getBootstrapParametersFromThingsboard(store.getDeviceProfile());
160 158 lwM2MBootstrapConfig.servers = mapper.readValue(bootstrapObject.get(SERVERS).toString(), LwM2MBootstrapServers.class);
161 159 LwM2MServerBootstrap profileServerBootstrap = mapper.readValue(bootstrapObject.get(BOOTSTRAP_SERVER).toString(), LwM2MServerBootstrap.class);
... ...
... ... @@ -32,7 +32,7 @@ public class LwM2MServerBootstrap {
32 32 String host = "0.0.0.0";
33 33 Integer port = 0;
34 34
35   - String securityMode = SecurityMode.NO_SEC.name();
  35 + SecurityMode securityMode = SecurityMode.NO_SEC;
36 36
37 37 Integer serverId = 123;
38 38 boolean bootstrapServerIs = false;
... ...
... ... @@ -15,25 +15,23 @@
15 15 */
16 16 package org.thingsboard.server.transport.lwm2m.secure;
17 17
18   -import com.google.gson.JsonObject;
19 18 import lombok.Data;
  19 +import org.eclipse.leshan.core.SecurityMode;
20 20 import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
21 21 import org.eclipse.leshan.server.security.SecurityInfo;
22 22 import org.thingsboard.server.common.data.DeviceProfile;
23 23 import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
24   -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
25   -
26   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.DEFAULT_MODE;
  24 +import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig;
27 25
28 26 @Data
29 27 public class EndpointSecurityInfo {
30 28 private ValidateDeviceCredentialsResponse msg;
31 29 private SecurityInfo securityInfo;
32   - private int securityMode = DEFAULT_MODE.code;
  30 + private SecurityMode securityMode;
33 31
34 32 /** bootstrap */
35 33 private DeviceProfile deviceProfile;
36   - private JsonObject bootstrapJsonCredential;
  34 + private LwM2MBootstrapConfig bootstrapCredentialConfig;
37 35 private String endpoint;
38 36 private BootstrapConfig bootstrapConfig;
39 37 }
... ...
... ... @@ -33,16 +33,6 @@ import java.util.Arrays;
33 33 @Slf4j
34 34 public class LWM2MGenerationPSkRPkECC {
35 35
36   - public LWM2MGenerationPSkRPkECC(Integer dtlsMode) {
37   - switch (LwM2MSecurityMode.fromSecurityMode(dtlsMode)) {
38   - case PSK:
39   - generationPSkKey();
40   - break;
41   - case RPK:
42   - generationRPKECCKey();
43   - }
44   - }
45   -
46 36 public LWM2MGenerationPSkRPkECC() {
47 37 generationPSkKey();
48 38 generationRPKECCKey();
... ... @@ -102,12 +92,12 @@ public class LWM2MGenerationPSkRPkECC {
102 92 /* Get Curves params */
103 93 String privHex = Hex.encodeHexString(privKey.getEncoded());
104 94 log.info("\nCreating new RPK for the next start... \n" +
105   - " Public Key (Hex): [{}]\n" +
106   - " Private Key (Hex): [{}]" +
107   - " public_x : [{}] \n" +
108   - " public_y : [{}] \n" +
109   - " private_encode : [{}] \n" +
110   - " Elliptic Curve parameters : [{}] \n",
  95 + " Public Key (Hex): [{}]\n" +
  96 + " Private Key (Hex): [{}]" +
  97 + " public_x : [{}] \n" +
  98 + " public_y : [{}] \n" +
  99 + " private_encode : [{}] \n" +
  100 + " Elliptic Curve parameters : [{}] \n",
111 101 Hex.encodeHexString(pubKey.getEncoded()),
112 102 privHex,
113 103 Hex.encodeHexString(x),
... ...
1   -/**
2   - * Copyright © 2016-2021 The Thingsboard Authors
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -package org.thingsboard.server.transport.lwm2m.secure;
17   -
18   -public enum LwM2MSecurityMode {
19   -
20   - PSK(0, "psk"),
21   - RPK(1, "rpk"),
22   - X509(2, "x509"),
23   - NO_SEC(3, "no_sec"),
24   - X509_EST(4, "x509_est"),
25   - REDIS(7, "redis"),
26   - DEFAULT_MODE(255, "default_mode");
27   -
28   - public int code;
29   - public String subEndpoint;
30   -
31   - LwM2MSecurityMode(int code, String subEndpoint) {
32   - this.code = code;
33   - this.subEndpoint = subEndpoint;
34   - }
35   -
36   - public static LwM2MSecurityMode fromSecurityMode(long code) {
37   - return fromSecurityMode((int) code);
38   - }
39   -
40   - public static LwM2MSecurityMode fromSecurityMode(int code) {
41   - for (LwM2MSecurityMode sm : LwM2MSecurityMode.values()) {
42   - if (sm.code == code) {
43   - return sm;
44   - }
45   - }
46   - throw new IllegalArgumentException(String.format("Unsupported security code : %d", code));
47   - }
48   -
49   -
50   - public static LwM2MSecurityMode fromSecurityMode(String subEndpoint) {
51   - for (LwM2MSecurityMode sm : LwM2MSecurityMode.values()) {
52   - if (sm.subEndpoint.equals(subEndpoint)) {
53   - return sm;
54   - }
55   - }
56   - throw new IllegalArgumentException(String.format("Unsupported security subEndpoint : %d", subEndpoint));
57   - }
58   -}
... ... @@ -15,34 +15,36 @@
15 15 */
16 16 package org.thingsboard.server.transport.lwm2m.secure;
17 17
18   -import com.google.gson.JsonObject;
19 18 import lombok.RequiredArgsConstructor;
20 19 import lombok.extern.slf4j.Slf4j;
21   -import org.eclipse.leshan.core.util.Hex;
  20 +import org.eclipse.leshan.core.SecurityMode;
22 21 import org.eclipse.leshan.core.util.SecurityUtil;
23 22 import org.eclipse.leshan.server.security.SecurityInfo;
24 23 import org.springframework.stereotype.Component;
25   -import org.thingsboard.server.common.data.DeviceProfile;
  24 +import org.thingsboard.common.util.JacksonUtil;
  25 +import org.thingsboard.server.common.data.StringUtils;
26 26 import org.thingsboard.server.common.transport.TransportServiceCallback;
27 27 import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
28   -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
29 28 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
30 29 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
31 30 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
  31 +import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MClientCredentialsConfig;
  32 +import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials;
  33 +import org.thingsboard.server.transport.lwm2m.secure.credentials.PSKClientCredentialsConfig;
  34 +import org.thingsboard.server.transport.lwm2m.secure.credentials.RPKClientCredentialsConfig;
32 35 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
33 36 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
34 37
35 38 import java.io.IOException;
36 39 import java.security.GeneralSecurityException;
37 40 import java.security.PublicKey;
38   -import java.util.Optional;
39 41 import java.util.concurrent.CountDownLatch;
40 42 import java.util.concurrent.TimeUnit;
41 43
42   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
43   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.PSK;
44   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RPK;
45   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509;
  44 +import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
  45 +import static org.eclipse.leshan.core.SecurityMode.PSK;
  46 +import static org.eclipse.leshan.core.SecurityMode.RPK;
  47 +import static org.eclipse.leshan.core.SecurityMode.X509;
46 48
47 49 @Slf4j
48 50 @Component
... ... @@ -53,7 +55,6 @@ public class LwM2mCredentialsSecurityInfoValidator {
53 55 private final LwM2mTransportContext context;
54 56 private final LwM2MTransportServerConfig config;
55 57
56   -
57 58 public EndpointSecurityInfo getEndpointSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
58 59 CountDownLatch latch = new CountDownLatch(1);
59 60 final EndpointSecurityInfo[] resultSecurityStore = new EndpointSecurityInfo[1];
... ... @@ -92,39 +93,32 @@ public class LwM2mCredentialsSecurityInfoValidator {
92 93 */
93 94 private EndpointSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
94 95 EndpointSecurityInfo result = new EndpointSecurityInfo();
95   - JsonObject objectMsg = LwM2mTransportUtil.validateJson(jsonStr);
96   - if (objectMsg != null && !objectMsg.isJsonNull()) {
97   - JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null;
98   - /**
99   - * Only PSK
100   - */
101   - String endpointPsk = (objectMsg.has("client")
102   - && objectMsg.get("client").getAsJsonObject().has("endpoint")
103   - && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null;
104   - endpoint = (endpointPsk == null || endpointPsk.isEmpty()) ? endpoint : endpointPsk;
105   - if (object != null && !object.isJsonNull()) {
106   - if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
107   - result.setBootstrapJsonCredential(object);
108   - result.setEndpoint(endpoint);
109   - result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code);
110   - } else {
111   - LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(object.get("securityConfigClientMode").getAsString().toLowerCase());
112   - switch (lwM2MSecurityMode) {
113   - case NO_SEC:
114   - createClientSecurityInfoNoSec(result);
115   - break;
116   - case PSK:
117   - createClientSecurityInfoPSK(result, endpoint, object);
118   - break;
119   - case RPK:
120   - createClientSecurityInfoRPK(result, endpoint, object);
121   - break;
122   - case X509:
123   - createClientSecurityInfoX509(result, endpoint);
124   - break;
125   - default:
126   - break;
127   - }
  96 + LwM2MCredentials credentials = JacksonUtil.fromString(jsonStr, LwM2MCredentials.class);
  97 + if (credentials != null) {
  98 + if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
  99 + result.setBootstrapCredentialConfig(credentials.getBootstrap());
  100 + if (SecurityMode.PSK.equals(credentials.getClient().getSecurityConfigClientMode())) {
  101 + PSKClientCredentialsConfig pskClientConfig = (PSKClientCredentialsConfig) credentials.getClient();
  102 + endpoint = StringUtils.isNotEmpty(pskClientConfig.getEndpoint()) ? pskClientConfig.getEndpoint() : endpoint;
  103 + }
  104 + result.setEndpoint(endpoint);
  105 + result.setSecurityMode(credentials.getBootstrap().getBootstrapServer().getSecurityMode());
  106 + } else {
  107 + switch (credentials.getClient().getSecurityConfigClientMode()) {
  108 + case NO_SEC:
  109 + createClientSecurityInfoNoSec(result);
  110 + break;
  111 + case PSK:
  112 + createClientSecurityInfoPSK(result, endpoint, credentials.getClient());
  113 + break;
  114 + case RPK:
  115 + createClientSecurityInfoRPK(result, endpoint, credentials.getClient());
  116 + break;
  117 + case X509:
  118 + createClientSecurityInfoX509(result, endpoint, credentials.getClient());
  119 + break;
  120 + default:
  121 + break;
128 122 }
129 123 }
130 124 }
... ... @@ -133,19 +127,18 @@ public class LwM2mCredentialsSecurityInfoValidator {
133 127
134 128 private void createClientSecurityInfoNoSec(EndpointSecurityInfo result) {
135 129 result.setSecurityInfo(null);
136   - result.setSecurityMode(NO_SEC.code);
  130 + result.setSecurityMode(NO_SEC);
137 131 }
138 132
139   - private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, JsonObject object) {
140   - /** PSK Deserialization */
141   - String identity = (object.has("identity") && object.get("identity").isJsonPrimitive()) ? object.get("identity").getAsString() : null;
142   - if (identity != null && !identity.isEmpty()) {
  133 + private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentialsConfig clientCredentialsConfig) {
  134 + PSKClientCredentialsConfig pskConfig = (PSKClientCredentialsConfig) clientCredentialsConfig;
  135 + if (StringUtils.isNotEmpty(pskConfig.getIdentity())) {
143 136 try {
144   - byte[] key = (object.has("key") && object.get("key").isJsonPrimitive()) ? Hex.decodeHex(object.get("key").getAsString().toCharArray()) : null;
145   - if (key != null && key.length > 0) {
  137 + if (pskConfig.getKey() != null && pskConfig.getKey().length > 0) {
  138 + endpoint = StringUtils.isNotEmpty(pskConfig.getEndpoint()) ? pskConfig.getEndpoint() : endpoint;
146 139 if (endpoint != null && !endpoint.isEmpty()) {
147   - result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, identity, key));
148   - result.setSecurityMode(PSK.code);
  140 + result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, pskConfig.getIdentity(), pskConfig.getKey()));
  141 + result.setSecurityMode(PSK);
149 142 }
150 143 }
151 144 } catch (IllegalArgumentException e) {
... ... @@ -156,13 +149,13 @@ public class LwM2mCredentialsSecurityInfoValidator {
156 149 }
157 150 }
158 151
159   - private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, JsonObject object) {
  152 + private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentialsConfig clientCredentialsConfig) {
  153 + RPKClientCredentialsConfig rpkConfig = (RPKClientCredentialsConfig) clientCredentialsConfig;
160 154 try {
161   - if (object.has("key") && object.get("key").isJsonPrimitive()) {
162   - byte[] rpkkey = Hex.decodeHex(object.get("key").getAsString().toLowerCase().toCharArray());
163   - PublicKey key = SecurityUtil.publicKey.decode(rpkkey);
  155 + if (rpkConfig.getKey() != null) {
  156 + PublicKey key = SecurityUtil.publicKey.decode(rpkConfig.getKey());
164 157 result.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(endpoint, key));
165   - result.setSecurityMode(RPK.code);
  158 + result.setSecurityMode(RPK);
166 159 } else {
167 160 log.error("Missing RPK key");
168 161 }
... ... @@ -171,8 +164,8 @@ public class LwM2mCredentialsSecurityInfoValidator {
171 164 }
172 165 }
173 166
174   - private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint) {
  167 + private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentialsConfig clientCredentialsConfig) {
175 168 result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint));
176   - result.setSecurityMode(X509.code);
  169 + result.setSecurityMode(X509);
177 170 }
178 171 }
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import org.eclipse.leshan.core.util.Hex;
  4 +
  5 +public class HasKey {
  6 + private byte[] key;
  7 +
  8 + public void setKey(String key) {
  9 + if (key != null) {
  10 + this.key = Hex.decodeHex(key.toLowerCase().toCharArray());
  11 + }
  12 + }
  13 +
  14 + public byte[] getKey() {
  15 + return key;
  16 + }
  17 +}
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonIgnore;
  4 +import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
  5 +import com.fasterxml.jackson.annotation.JsonSubTypes;
  6 +import com.fasterxml.jackson.annotation.JsonTypeInfo;
  7 +import org.eclipse.leshan.core.SecurityMode;
  8 +
  9 +@JsonIgnoreProperties(ignoreUnknown = true)
  10 +@JsonTypeInfo(
  11 + use = JsonTypeInfo.Id.NAME,
  12 + property = "securityConfigClientMode")
  13 +@JsonSubTypes({
  14 + @JsonSubTypes.Type(value = NoSecClientCredentialsConfig.class, name = "NO_SEC"),
  15 + @JsonSubTypes.Type(value = PSKClientCredentialsConfig.class, name = "PSK"),
  16 + @JsonSubTypes.Type(value = RPKClientCredentialsConfig.class, name = "RPK"),
  17 + @JsonSubTypes.Type(value = X509ClientCredentialsConfig.class, name = "X509")})
  18 +public interface LwM2MClientCredentialsConfig {
  19 +
  20 + @JsonIgnore
  21 + SecurityMode getSecurityConfigClientMode();
  22 +}
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import lombok.Data;
  4 +import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig;
  5 +
  6 +@Data
  7 +public class LwM2MCredentials {
  8 + private LwM2MClientCredentialsConfig client;
  9 + private LwM2MBootstrapConfig bootstrap;
  10 +}
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import org.eclipse.leshan.core.SecurityMode;
  4 +
  5 +import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
  6 +
  7 +public class NoSecClientCredentialsConfig implements LwM2MClientCredentialsConfig {
  8 +
  9 + @Override
  10 + public SecurityMode getSecurityConfigClientMode() {
  11 + return NO_SEC;
  12 + }
  13 +}
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import lombok.Data;
  4 +import org.eclipse.leshan.core.SecurityMode;
  5 +
  6 +import static org.eclipse.leshan.core.SecurityMode.PSK;
  7 +
  8 +@Data
  9 +public class PSKClientCredentialsConfig extends HasKey implements LwM2MClientCredentialsConfig {
  10 + private String identity;
  11 + private String endpoint;
  12 +
  13 + @Override
  14 + public SecurityMode getSecurityConfigClientMode() {
  15 + return PSK;
  16 + }
  17 +}
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import org.eclipse.leshan.core.SecurityMode;
  4 +
  5 +import static org.eclipse.leshan.core.SecurityMode.RPK;
  6 +
  7 +public class RPKClientCredentialsConfig extends HasKey implements LwM2MClientCredentialsConfig {
  8 +
  9 + @Override
  10 + public SecurityMode getSecurityConfigClientMode() {
  11 + return RPK;
  12 + }
  13 +}
... ...
  1 +package org.thingsboard.server.transport.lwm2m.secure.credentials;
  2 +
  3 +import lombok.Data;
  4 +import org.eclipse.leshan.core.SecurityMode;
  5 +
  6 +import static org.eclipse.leshan.core.SecurityMode.X509;
  7 +
  8 +@Data
  9 +public class X509ClientCredentialsConfig implements LwM2MClientCredentialsConfig {
  10 + private boolean allowTrustedOnly;
  11 + private String cert;
  12 +
  13 + @Override
  14 + public SecurityMode getSecurityConfigClientMode() {
  15 + return X509;
  16 + }
  17 +}
... ...
... ... @@ -25,7 +25,6 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes
25 25 import org.thingsboard.server.gen.transport.TransportProtos;
26 26 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
27 27 import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo;
28   -import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
29 28 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
30 29 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
31 30 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
... ... @@ -38,7 +37,7 @@ import java.util.Set;
38 37 import java.util.UUID;
39 38 import java.util.concurrent.ConcurrentHashMap;
40 39
41   -import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
  40 +import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
42 41 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
43 42
44 43 @Service
... ... @@ -111,7 +110,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
111 110 @Override
112 111 public LwM2mClient fetchClientByEndpoint(String endpoint) {
113 112 EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);
114   - if (securityInfo.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
  113 + if (securityInfo.getSecurityMode() != null) {
115 114 if (securityInfo.getDeviceProfile() != null) {
116 115 toClientProfile(securityInfo.getDeviceProfile());
117 116 UUID profileUuid = securityInfo.getDeviceProfile().getUuidId();
... ... @@ -120,7 +119,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
120 119 client = new LwM2mClient(context.getNodeId(), securityInfo.getSecurityInfo().getEndpoint(),
121 120 securityInfo.getSecurityInfo().getIdentity(), securityInfo.getSecurityInfo(),
122 121 securityInfo.getMsg(), profileUuid, UUID.randomUUID());
123   - } else if (securityInfo.getSecurityMode() == NO_SEC.code) {
  122 + } else if (NO_SEC.equals(securityInfo.getSecurityMode())) {
124 123 client = new LwM2mClient(context.getNodeId(), endpoint,
125 124 null, null,
126 125 securityInfo.getMsg(), profileUuid, UUID.randomUUID());
... ...