Browse Source

Created LwM2M credentials (#4546)

* Created LwM2M credentials

* psk endpoint
pull/4564/head
Yevhen Bondarenko 5 years ago
committed by GitHub
parent
commit
7ca626a086
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java
  2. 11
      application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java
  3. 12
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java
  4. 20
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java
  5. 2
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MServerBootstrap.java
  6. 10
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/EndpointSecurityInfo.java
  7. 22
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LWM2MGenerationPSkRPkECC.java
  8. 58
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2MSecurityMode.java
  9. 111
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java
  10. 17
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/HasKey.java
  11. 22
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MClientCredentialsConfig.java
  12. 10
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MCredentials.java
  13. 13
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/NoSecClientCredentialsConfig.java
  14. 17
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/PSKClientCredentialsConfig.java
  15. 13
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/RPKClientCredentialsConfig.java
  16. 17
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/X509ClientCredentialsConfig.java
  17. 7
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java

5
application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java

@ -17,6 +17,7 @@ package org.thingsboard.server.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
@ -46,9 +47,11 @@ public class Lwm2mController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{securityMode}/{bootstrapServerIs}", method = RequestMethod.GET)
@ResponseBody
public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("securityMode") String securityMode,
public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("securityMode") String strSecurityMode,
@PathVariable("bootstrapServerIs") boolean bootstrapServer) throws ThingsboardException {
checkNotNull(strSecurityMode);
try {
SecurityMode securityMode = SecurityMode.valueOf(strSecurityMode);
return lwM2MServerSecurityInfoRepository.getServerSecurityInfo(securityMode, bootstrapServer);
} catch (Exception e) {
throw handleException(e);

11
application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MServerSecurityInfoRepository.java

@ -18,6 +18,7 @@ package org.thingsboard.server.service.lwm2m;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.util.Hex;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
@ -25,7 +26,6 @@ import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MSecureServerConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
@ -55,17 +55,16 @@ public class LwM2MServerSecurityInfoRepository {
* @param bootstrapServer
* @return ServerSecurityConfig more value is default: Important - port, host, publicKey
*/
public ServerSecurityConfig getServerSecurityInfo(String securityMode, boolean bootstrapServer) {
LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase());
ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig, lwM2MSecurityMode);
public ServerSecurityConfig getServerSecurityInfo(SecurityMode securityMode, boolean bootstrapServer) {
ServerSecurityConfig result = getServerSecurityConfig(bootstrapServer ? bootstrapConfig : serverConfig, securityMode);
result.setBootstrapServerIs(bootstrapServer);
return result;
}
private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig, LwM2MSecurityMode mode) {
private ServerSecurityConfig getServerSecurityConfig(LwM2MSecureServerConfig serverConfig, SecurityMode securityMode) {
ServerSecurityConfig bsServ = new ServerSecurityConfig();
bsServ.setServerId(serverConfig.getId());
switch (mode) {
switch (securityMode) {
case NO_SEC:
bsServ.setHost(serverConfig.getHost());
bsServ.setPort(serverConfig.getPort());

12
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java

@ -73,17 +73,17 @@ public class LwM2MBootstrapConfig {
configBs.servers.put(0, server0);
/* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */
this.bootstrapServer.setBootstrapServerIs(true);
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()));
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()));
/* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Server instance = 1 */
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()));
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()));
return configBs;
}
private BootstrapConfig.ServerSecurity setServerSecuruty(String host, Integer port, boolean bootstrapServer, String securityMode, String clientPublicKey, String serverPublicKey, String secretKey, int serverId) {
private BootstrapConfig.ServerSecurity setServerSecurity(String host, Integer port, boolean bootstrapServer, SecurityMode securityMode, String clientPublicKey, String serverPublicKey, String secretKey, int serverId) {
BootstrapConfig.ServerSecurity serverSecurity = new BootstrapConfig.ServerSecurity();
serverSecurity.uri = "coaps://" + host + ":" + Integer.toString(port);
serverSecurity.bootstrapServer = bootstrapServer;
serverSecurity.securityMode = SecurityMode.valueOf(securityMode);
serverSecurity.securityMode = securityMode;
serverSecurity.publicKeyOrId = setPublicKeyOrId(clientPublicKey, securityMode);
serverSecurity.serverPublicKey = (serverPublicKey != null && !serverPublicKey.isEmpty()) ? Hex.decodeHex(serverPublicKey.toCharArray()) : new byte[]{};
serverSecurity.secretKey = (secretKey != null && !secretKey.isEmpty()) ? Hex.decodeHex(secretKey.toCharArray()) : new byte[]{};
@ -91,9 +91,9 @@ public class LwM2MBootstrapConfig {
return serverSecurity;
}
private byte[] setPublicKeyOrId(String publicKeyOrIdStr, String securityMode) {
private byte[] setPublicKeyOrId(String publicKeyOrIdStr, SecurityMode securityMode) {
return (publicKeyOrIdStr == null || publicKeyOrIdStr.isEmpty()) ? new byte[]{} :
SecurityMode.valueOf(securityMode).equals(SecurityMode.PSK) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
SecurityMode.PSK.equals(securityMode) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
Hex.decodeHex(publicKeyOrIdStr.toCharArray());
}
}

20
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java

@ -31,7 +31,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
@ -73,7 +72,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
@Override
public List<SecurityInfo> getAllByEndpoint(String endPoint) {
EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
/* add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
BootstrapConfig bsConfigNew = store.getBootstrapConfig();
@ -97,7 +96,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
@Override
public SecurityInfo getByIdentity(String identity) {
EndpointSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
/* add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
BootstrapConfig bsConfig = store.getBootstrapConfig();
@ -118,29 +117,29 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store);
if (lwM2MBootstrapConfig != null) {
/* Security info */
switch (SecurityMode.valueOf(lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode())) {
switch (lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode()) {
/* Use RPK only */
case PSK:
store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndpoint(),
lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(),
Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientSecretKey().toCharArray())));
store.setSecurityMode(SecurityMode.PSK.code);
store.setSecurityMode(SecurityMode.PSK);
break;
case RPK:
try {
store.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(store.getEndpoint(),
SecurityUtil.publicKey.decode(Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId().toCharArray()))));
store.setSecurityMode(SecurityMode.RPK.code);
store.setSecurityMode(SecurityMode.RPK);
break;
} catch (IOException | GeneralSecurityException e) {
log.error("Unable to decode Client public key for [{}] [{}]", store.getEndpoint(), e.getMessage());
}
case X509:
store.setSecurityInfo(SecurityInfo.newX509CertInfo(store.getEndpoint()));
store.setSecurityMode(SecurityMode.X509.code);
store.setSecurityMode(SecurityMode.X509);
break;
case NO_SEC:
store.setSecurityMode(SecurityMode.NO_SEC.code);
store.setSecurityMode(SecurityMode.NO_SEC);
store.setSecurityInfo(null);
break;
default:
@ -152,10 +151,9 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
private LwM2MBootstrapConfig getParametersBootstrap(EndpointSecurityInfo store) {
try {
JsonObject bootstrapJsonCredential = store.getBootstrapJsonCredential();
if (bootstrapJsonCredential != null) {
LwM2MBootstrapConfig lwM2MBootstrapConfig = store.getBootstrapCredentialConfig();
if (lwM2MBootstrapConfig != null) {
ObjectMapper mapper = new ObjectMapper();
LwM2MBootstrapConfig lwM2MBootstrapConfig = mapper.readValue(bootstrapJsonCredential.toString(), LwM2MBootstrapConfig.class);
JsonObject bootstrapObject = getBootstrapParametersFromThingsboard(store.getDeviceProfile());
lwM2MBootstrapConfig.servers = mapper.readValue(bootstrapObject.get(SERVERS).toString(), LwM2MBootstrapServers.class);
LwM2MServerBootstrap profileServerBootstrap = mapper.readValue(bootstrapObject.get(BOOTSTRAP_SERVER).toString(), LwM2MServerBootstrap.class);

2
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MServerBootstrap.java

@ -32,7 +32,7 @@ public class LwM2MServerBootstrap {
String host = "0.0.0.0";
Integer port = 0;
String securityMode = SecurityMode.NO_SEC.name();
SecurityMode securityMode = SecurityMode.NO_SEC;
Integer serverId = 123;
boolean bootstrapServerIs = false;

10
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/EndpointSecurityInfo.java

@ -15,25 +15,23 @@
*/
package org.thingsboard.server.transport.lwm2m.secure;
import com.google.gson.JsonObject;
import lombok.Data;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.DEFAULT_MODE;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig;
@Data
public class EndpointSecurityInfo {
private ValidateDeviceCredentialsResponse msg;
private SecurityInfo securityInfo;
private int securityMode = DEFAULT_MODE.code;
private SecurityMode securityMode;
/** bootstrap */
private DeviceProfile deviceProfile;
private JsonObject bootstrapJsonCredential;
private LwM2MBootstrapConfig bootstrapCredentialConfig;
private String endpoint;
private BootstrapConfig bootstrapConfig;
}

22
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LWM2MGenerationPSkRPkECC.java

@ -33,16 +33,6 @@ import java.util.Arrays;
@Slf4j
public class LWM2MGenerationPSkRPkECC {
public LWM2MGenerationPSkRPkECC(Integer dtlsMode) {
switch (LwM2MSecurityMode.fromSecurityMode(dtlsMode)) {
case PSK:
generationPSkKey();
break;
case RPK:
generationRPKECCKey();
}
}
public LWM2MGenerationPSkRPkECC() {
generationPSkKey();
generationRPKECCKey();
@ -102,12 +92,12 @@ public class LWM2MGenerationPSkRPkECC {
/* Get Curves params */
String privHex = Hex.encodeHexString(privKey.getEncoded());
log.info("\nCreating new RPK for the next start... \n" +
" Public Key (Hex): [{}]\n" +
" Private Key (Hex): [{}]" +
" public_x : [{}] \n" +
" public_y : [{}] \n" +
" private_encode : [{}] \n" +
" Elliptic Curve parameters : [{}] \n",
" Public Key (Hex): [{}]\n" +
" Private Key (Hex): [{}]" +
" public_x : [{}] \n" +
" public_y : [{}] \n" +
" private_encode : [{}] \n" +
" Elliptic Curve parameters : [{}] \n",
Hex.encodeHexString(pubKey.getEncoded()),
privHex,
Hex.encodeHexString(x),

58
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2MSecurityMode.java

@ -1,58 +0,0 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.secure;
public enum LwM2MSecurityMode {
PSK(0, "psk"),
RPK(1, "rpk"),
X509(2, "x509"),
NO_SEC(3, "no_sec"),
X509_EST(4, "x509_est"),
REDIS(7, "redis"),
DEFAULT_MODE(255, "default_mode");
public int code;
public String subEndpoint;
LwM2MSecurityMode(int code, String subEndpoint) {
this.code = code;
this.subEndpoint = subEndpoint;
}
public static LwM2MSecurityMode fromSecurityMode(long code) {
return fromSecurityMode((int) code);
}
public static LwM2MSecurityMode fromSecurityMode(int code) {
for (LwM2MSecurityMode sm : LwM2MSecurityMode.values()) {
if (sm.code == code) {
return sm;
}
}
throw new IllegalArgumentException(String.format("Unsupported security code : %d", code));
}
public static LwM2MSecurityMode fromSecurityMode(String subEndpoint) {
for (LwM2MSecurityMode sm : LwM2MSecurityMode.values()) {
if (sm.subEndpoint.equals(subEndpoint)) {
return sm;
}
}
throw new IllegalArgumentException(String.format("Unsupported security subEndpoint : %d", subEndpoint));
}
}

111
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java

@ -15,34 +15,36 @@
*/
package org.thingsboard.server.transport.lwm2m.secure;
import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MClientCredentialsConfig;
import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials;
import org.thingsboard.server.transport.lwm2m.secure.credentials.PSKClientCredentialsConfig;
import org.thingsboard.server.transport.lwm2m.secure.credentials.RPKClientCredentialsConfig;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.PSK;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RPK;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509;
import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
import static org.eclipse.leshan.core.SecurityMode.PSK;
import static org.eclipse.leshan.core.SecurityMode.RPK;
import static org.eclipse.leshan.core.SecurityMode.X509;
@Slf4j
@Component
@ -53,7 +55,6 @@ public class LwM2mCredentialsSecurityInfoValidator {
private final LwM2mTransportContext context;
private final LwM2MTransportServerConfig config;
public EndpointSecurityInfo getEndpointSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
CountDownLatch latch = new CountDownLatch(1);
final EndpointSecurityInfo[] resultSecurityStore = new EndpointSecurityInfo[1];
@ -92,39 +93,32 @@ public class LwM2mCredentialsSecurityInfoValidator {
*/
private EndpointSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
EndpointSecurityInfo result = new EndpointSecurityInfo();
JsonObject objectMsg = LwM2mTransportUtil.validateJson(jsonStr);
if (objectMsg != null && !objectMsg.isJsonNull()) {
JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null;
/**
* Only PSK
*/
String endpointPsk = (objectMsg.has("client")
&& objectMsg.get("client").getAsJsonObject().has("endpoint")
&& objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null;
endpoint = (endpointPsk == null || endpointPsk.isEmpty()) ? endpoint : endpointPsk;
if (object != null && !object.isJsonNull()) {
if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
result.setBootstrapJsonCredential(object);
result.setEndpoint(endpoint);
result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code);
} else {
LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(object.get("securityConfigClientMode").getAsString().toLowerCase());
switch (lwM2MSecurityMode) {
case NO_SEC:
createClientSecurityInfoNoSec(result);
break;
case PSK:
createClientSecurityInfoPSK(result, endpoint, object);
break;
case RPK:
createClientSecurityInfoRPK(result, endpoint, object);
break;
case X509:
createClientSecurityInfoX509(result, endpoint);
break;
default:
break;
}
LwM2MCredentials credentials = JacksonUtil.fromString(jsonStr, LwM2MCredentials.class);
if (credentials != null) {
if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
result.setBootstrapCredentialConfig(credentials.getBootstrap());
if (SecurityMode.PSK.equals(credentials.getClient().getSecurityConfigClientMode())) {
PSKClientCredentialsConfig pskClientConfig = (PSKClientCredentialsConfig) credentials.getClient();
endpoint = StringUtils.isNotEmpty(pskClientConfig.getEndpoint()) ? pskClientConfig.getEndpoint() : endpoint;
}
result.setEndpoint(endpoint);
result.setSecurityMode(credentials.getBootstrap().getBootstrapServer().getSecurityMode());
} else {
switch (credentials.getClient().getSecurityConfigClientMode()) {
case NO_SEC:
createClientSecurityInfoNoSec(result);
break;
case PSK:
createClientSecurityInfoPSK(result, endpoint, credentials.getClient());
break;
case RPK:
createClientSecurityInfoRPK(result, endpoint, credentials.getClient());
break;
case X509:
createClientSecurityInfoX509(result, endpoint, credentials.getClient());
break;
default:
break;
}
}
}
@ -133,19 +127,18 @@ public class LwM2mCredentialsSecurityInfoValidator {
private void createClientSecurityInfoNoSec(EndpointSecurityInfo result) {
result.setSecurityInfo(null);
result.setSecurityMode(NO_SEC.code);
result.setSecurityMode(NO_SEC);
}
private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, JsonObject object) {
/** PSK Deserialization */
String identity = (object.has("identity") && object.get("identity").isJsonPrimitive()) ? object.get("identity").getAsString() : null;
if (identity != null && !identity.isEmpty()) {
private void createClientSecurityInfoPSK(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentialsConfig clientCredentialsConfig) {
PSKClientCredentialsConfig pskConfig = (PSKClientCredentialsConfig) clientCredentialsConfig;
if (StringUtils.isNotEmpty(pskConfig.getIdentity())) {
try {
byte[] key = (object.has("key") && object.get("key").isJsonPrimitive()) ? Hex.decodeHex(object.get("key").getAsString().toCharArray()) : null;
if (key != null && key.length > 0) {
if (pskConfig.getKey() != null && pskConfig.getKey().length > 0) {
endpoint = StringUtils.isNotEmpty(pskConfig.getEndpoint()) ? pskConfig.getEndpoint() : endpoint;
if (endpoint != null && !endpoint.isEmpty()) {
result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, identity, key));
result.setSecurityMode(PSK.code);
result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endpoint, pskConfig.getIdentity(), pskConfig.getKey()));
result.setSecurityMode(PSK);
}
}
} catch (IllegalArgumentException e) {
@ -156,13 +149,13 @@ public class LwM2mCredentialsSecurityInfoValidator {
}
}
private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, JsonObject object) {
private void createClientSecurityInfoRPK(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentialsConfig clientCredentialsConfig) {
RPKClientCredentialsConfig rpkConfig = (RPKClientCredentialsConfig) clientCredentialsConfig;
try {
if (object.has("key") && object.get("key").isJsonPrimitive()) {
byte[] rpkkey = Hex.decodeHex(object.get("key").getAsString().toLowerCase().toCharArray());
PublicKey key = SecurityUtil.publicKey.decode(rpkkey);
if (rpkConfig.getKey() != null) {
PublicKey key = SecurityUtil.publicKey.decode(rpkConfig.getKey());
result.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(endpoint, key));
result.setSecurityMode(RPK.code);
result.setSecurityMode(RPK);
} else {
log.error("Missing RPK key");
}
@ -171,8 +164,8 @@ public class LwM2mCredentialsSecurityInfoValidator {
}
}
private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint) {
private void createClientSecurityInfoX509(EndpointSecurityInfo result, String endpoint, LwM2MClientCredentialsConfig clientCredentialsConfig) {
result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint));
result.setSecurityMode(X509.code);
result.setSecurityMode(X509);
}
}

17
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/HasKey.java

@ -0,0 +1,17 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import org.eclipse.leshan.core.util.Hex;
public class HasKey {
private byte[] key;
public void setKey(String key) {
if (key != null) {
this.key = Hex.decodeHex(key.toLowerCase().toCharArray());
}
}
public byte[] getKey() {
return key;
}
}

22
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MClientCredentialsConfig.java

@ -0,0 +1,22 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.eclipse.leshan.core.SecurityMode;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "securityConfigClientMode")
@JsonSubTypes({
@JsonSubTypes.Type(value = NoSecClientCredentialsConfig.class, name = "NO_SEC"),
@JsonSubTypes.Type(value = PSKClientCredentialsConfig.class, name = "PSK"),
@JsonSubTypes.Type(value = RPKClientCredentialsConfig.class, name = "RPK"),
@JsonSubTypes.Type(value = X509ClientCredentialsConfig.class, name = "X509")})
public interface LwM2MClientCredentialsConfig {
@JsonIgnore
SecurityMode getSecurityConfigClientMode();
}

10
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MCredentials.java

@ -0,0 +1,10 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import lombok.Data;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig;
@Data
public class LwM2MCredentials {
private LwM2MClientCredentialsConfig client;
private LwM2MBootstrapConfig bootstrap;
}

13
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/NoSecClientCredentialsConfig.java

@ -0,0 +1,13 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import org.eclipse.leshan.core.SecurityMode;
import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
public class NoSecClientCredentialsConfig implements LwM2MClientCredentialsConfig {
@Override
public SecurityMode getSecurityConfigClientMode() {
return NO_SEC;
}
}

17
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/PSKClientCredentialsConfig.java

@ -0,0 +1,17 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import lombok.Data;
import org.eclipse.leshan.core.SecurityMode;
import static org.eclipse.leshan.core.SecurityMode.PSK;
@Data
public class PSKClientCredentialsConfig extends HasKey implements LwM2MClientCredentialsConfig {
private String identity;
private String endpoint;
@Override
public SecurityMode getSecurityConfigClientMode() {
return PSK;
}
}

13
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/RPKClientCredentialsConfig.java

@ -0,0 +1,13 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import org.eclipse.leshan.core.SecurityMode;
import static org.eclipse.leshan.core.SecurityMode.RPK;
public class RPKClientCredentialsConfig extends HasKey implements LwM2MClientCredentialsConfig {
@Override
public SecurityMode getSecurityConfigClientMode() {
return RPK;
}
}

17
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/X509ClientCredentialsConfig.java

@ -0,0 +1,17 @@
package org.thingsboard.server.transport.lwm2m.secure.credentials;
import lombok.Data;
import org.eclipse.leshan.core.SecurityMode;
import static org.eclipse.leshan.core.SecurityMode.X509;
@Data
public class X509ClientCredentialsConfig implements LwM2MClientCredentialsConfig {
private boolean allowTrustedOnly;
private String cert;
@Override
public SecurityMode getSecurityConfigClientMode() {
return X509;
}
}

7
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java

@ -25,7 +25,6 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.secure.EndpointSecurityInfo;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
@ -38,7 +37,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
@Service
@ -111,7 +110,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
@Override
public LwM2mClient fetchClientByEndpoint(String endpoint) {
EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);
if (securityInfo.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
if (securityInfo.getSecurityMode() != null) {
if (securityInfo.getDeviceProfile() != null) {
toClientProfile(securityInfo.getDeviceProfile());
UUID profileUuid = securityInfo.getDeviceProfile().getUuidId();
@ -120,7 +119,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
client = new LwM2mClient(context.getNodeId(), securityInfo.getSecurityInfo().getEndpoint(),
securityInfo.getSecurityInfo().getIdentity(), securityInfo.getSecurityInfo(),
securityInfo.getMsg(), profileUuid, UUID.randomUUID());
} else if (securityInfo.getSecurityMode() == NO_SEC.code) {
} else if (NO_SEC.equals(securityInfo.getSecurityMode())) {
client = new LwM2mClient(context.getNodeId(), endpoint,
null, null,
securityInfo.getMsg(), profileUuid, UUID.randomUUID());

Loading…
Cancel
Save