added validation for lwm2m device credentials
This commit is contained in:
parent
3f5e77abb7
commit
fe2427e99f
@ -185,9 +185,9 @@ public class DeviceBulkImportService extends AbstractBulkImportService<Device> {
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.forEach(securityMode -> {
|
.forEach(securityMode -> {
|
||||||
try {
|
try {
|
||||||
LwM2MSecurityMode.valueOf(securityMode);
|
LwM2MSecurityMode.valueOf(securityMode.toUpperCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new DeviceCredentialsValidationException("Unknown LwM2M security mode: " + securityMode);
|
throw new DeviceCredentialsValidationException("Unknown LwM2M security mode: " + securityMode + ", (the mode should be: NO_SEC, PSK, RPK, X509)!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public abstract class AbstractLwM2MServerCredentialsWithKeys implements LwM2MServerCredentials {
|
||||||
|
|
||||||
|
private String clientPublicKeyOrId;
|
||||||
|
private String clientSecretKey;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public byte[] getDecodedClientPublicKeyOrId() {
|
||||||
|
return getDecoded(clientPublicKeyOrId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public byte[] getDecodedClientSecretKey() {
|
||||||
|
return getDecoded(clientSecretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static byte[] getDecoded(String key) {
|
||||||
|
return Hex.decodeHex(key.toLowerCase().toCharArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class LwM2MBootstrapCredentials {
|
||||||
|
private LwM2MServerCredentials bootstrapServer;
|
||||||
|
private LwM2MServerCredentials lwm2mServer;
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class LwM2MDeviceCredentials {
|
||||||
|
private LwM2MClientCredentials client;
|
||||||
|
private LwM2MBootstrapCredentials bootstrap;
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
|
||||||
|
@JsonTypeInfo(
|
||||||
|
use = JsonTypeInfo.Id.NAME,
|
||||||
|
property = "securityMode")
|
||||||
|
@JsonSubTypes({
|
||||||
|
@JsonSubTypes.Type(value = NoSecServerCredentials.class, name = "NO_SEC"),
|
||||||
|
@JsonSubTypes.Type(value = PSKServerCredentials.class, name = "PSK"),
|
||||||
|
@JsonSubTypes.Type(value = RPKServerCredentials.class, name = "RPK"),
|
||||||
|
@JsonSubTypes.Type(value = X509ServerCredentials.class, name = "X509")
|
||||||
|
})
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public interface LwM2MServerCredentials {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
LwM2MSecurityMode getSecurityMode();
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
public class NoSecServerCredentials implements LwM2MServerCredentials {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LwM2MSecurityMode getSecurityMode() {
|
||||||
|
return LwM2MSecurityMode.NO_SEC;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
public class PSKServerCredentials extends AbstractLwM2MServerCredentialsWithKeys {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LwM2MSecurityMode getSecurityMode() {
|
||||||
|
return LwM2MSecurityMode.PSK;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
public class RPKServerCredentials extends AbstractLwM2MServerCredentialsWithKeys {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LwM2MSecurityMode getSecurityMode() {
|
||||||
|
return LwM2MSecurityMode.RPK;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* 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.common.data.device.credentials.lwm2m;
|
||||||
|
|
||||||
|
public class X509ServerCredentials extends AbstractLwM2MServerCredentialsWithKeys {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LwM2MSecurityMode getSecurityMode() {
|
||||||
|
return LwM2MSecurityMode.X509;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -227,6 +227,10 @@
|
|||||||
<groupId>org.elasticsearch.client</groupId>
|
<groupId>org.elasticsearch.client</groupId>
|
||||||
<artifactId>rest</artifactId>
|
<artifactId>rest</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.leshan</groupId>
|
||||||
|
<artifactId>leshan-core</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|||||||
@ -16,9 +16,9 @@
|
|||||||
package org.thingsboard.server.dao.device;
|
package org.thingsboard.server.dao.device;
|
||||||
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.eclipse.leshan.core.util.SecurityUtil;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
@ -26,10 +26,18 @@ import org.springframework.cache.annotation.Cacheable;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
import org.thingsboard.server.common.data.Device;
|
import org.thingsboard.server.common.data.Device;
|
||||||
|
import org.thingsboard.server.common.data.StringUtils;
|
||||||
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
|
import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MBootstrapCredentials;
|
||||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredentials;
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MClientCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MServerCredentials;
|
||||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredentials;
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKClientCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.PSKServerCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKClientCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.RPKServerCredentials;
|
||||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredentials;
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredentials;
|
||||||
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ServerCredentials;
|
||||||
import org.thingsboard.server.common.data.id.DeviceId;
|
import org.thingsboard.server.common.data.id.DeviceId;
|
||||||
import org.thingsboard.server.common.data.id.EntityId;
|
import org.thingsboard.server.common.data.id.EntityId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
@ -129,7 +137,7 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
|
|||||||
if (StringUtils.isEmpty(mqttCredentials.getClientId()) && StringUtils.isEmpty(mqttCredentials.getUserName())) {
|
if (StringUtils.isEmpty(mqttCredentials.getClientId()) && StringUtils.isEmpty(mqttCredentials.getUserName())) {
|
||||||
throw new DeviceCredentialsValidationException("Both mqtt client id and user name are empty!");
|
throw new DeviceCredentialsValidationException("Both mqtt client id and user name are empty!");
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotEmpty(mqttCredentials.getClientId()) && StringUtils.isNotEmpty(mqttCredentials.getPassword())) {
|
if (StringUtils.isNotEmpty(mqttCredentials.getClientId()) && StringUtils.isNotEmpty(mqttCredentials.getPassword()) && StringUtils.isEmpty(mqttCredentials.getUserName())) {
|
||||||
throw new DeviceCredentialsValidationException("Password cannot be specified along with client id");
|
throw new DeviceCredentialsValidationException("Password cannot be specified along with client id");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,22 +162,16 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void formatSimpleLwm2mCredentials(DeviceCredentials deviceCredentials) {
|
private void formatSimpleLwm2mCredentials(DeviceCredentials deviceCredentials) {
|
||||||
LwM2MClientCredentials clientCredentials;
|
LwM2MDeviceCredentials lwM2MCredentials;
|
||||||
ObjectNode json;
|
|
||||||
try {
|
try {
|
||||||
json = JacksonUtil.fromString(deviceCredentials.getCredentialsValue(), ObjectNode.class);
|
lwM2MCredentials = JacksonUtil.fromString(deviceCredentials.getCredentialsValue(), LwM2MDeviceCredentials.class);
|
||||||
if (json == null) {
|
validateLwM2MDeviceCredentials(lwM2MCredentials);
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
clientCredentials = JacksonUtil.convertValue(json.get("client"), LwM2MClientCredentials.class);
|
|
||||||
if (clientCredentials == null) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new DeviceCredentialsValidationException("Invalid credentials body for LwM2M credentials!");
|
throw new DeviceCredentialsValidationException("Invalid credentials body for LwM2M credentials!");
|
||||||
}
|
}
|
||||||
|
|
||||||
String credentialsId = null;
|
String credentialsId = null;
|
||||||
|
LwM2MClientCredentials clientCredentials = lwM2MCredentials.getClient();
|
||||||
|
|
||||||
switch (clientCredentials.getSecurityConfigClientMode()) {
|
switch (clientCredentials.getSecurityConfigClientMode()) {
|
||||||
case NO_SEC:
|
case NO_SEC:
|
||||||
@ -185,8 +187,8 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
|
|||||||
String cert = EncryptionUtil.trimNewLines(x509Config.getCert());
|
String cert = EncryptionUtil.trimNewLines(x509Config.getCert());
|
||||||
String sha3Hash = EncryptionUtil.getSha3Hash(cert);
|
String sha3Hash = EncryptionUtil.getSha3Hash(cert);
|
||||||
x509Config.setCert(cert);
|
x509Config.setCert(cert);
|
||||||
((ObjectNode) json.get("client")).put("cert", cert);
|
((X509ClientCredentials) clientCredentials).setCert(cert);
|
||||||
deviceCredentials.setCredentialsValue(JacksonUtil.toString(json));
|
deviceCredentials.setCredentialsValue(JacksonUtil.toString(lwM2MCredentials));
|
||||||
credentialsId = sha3Hash;
|
credentialsId = sha3Hash;
|
||||||
} else {
|
} else {
|
||||||
credentialsId = x509Config.getEndpoint();
|
credentialsId = x509Config.getEndpoint();
|
||||||
@ -199,6 +201,158 @@ public class DeviceCredentialsServiceImpl extends AbstractEntityService implemen
|
|||||||
deviceCredentials.setCredentialsId(credentialsId);
|
deviceCredentials.setCredentialsId(credentialsId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateLwM2MDeviceCredentials(LwM2MDeviceCredentials lwM2MCredentials) {
|
||||||
|
if (lwM2MCredentials == null) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M credentials should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
LwM2MClientCredentials clientCredentials = lwM2MCredentials.getClient();
|
||||||
|
if (clientCredentials == null) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client credentials should be specified!");
|
||||||
|
}
|
||||||
|
validateLwM2MClientCredentials(clientCredentials);
|
||||||
|
|
||||||
|
LwM2MBootstrapCredentials bootstrapCredentials = lwM2MCredentials.getBootstrap();
|
||||||
|
if (bootstrapCredentials == null) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M bootstrap credentials should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
LwM2MServerCredentials bootstrapServerCredentials = bootstrapCredentials.getBootstrapServer();
|
||||||
|
if (bootstrapServerCredentials == null) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M bootstrap server credentials should be specified!");
|
||||||
|
}
|
||||||
|
validateServerCredentials(bootstrapServerCredentials, "Bootstrap server");
|
||||||
|
|
||||||
|
LwM2MServerCredentials lwm2mServerCredentials = bootstrapCredentials.getLwm2mServer();
|
||||||
|
if (lwm2mServerCredentials == null) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M lwm2m server credentials should be specified!");
|
||||||
|
}
|
||||||
|
validateServerCredentials(lwm2mServerCredentials, "LwM2M server");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateLwM2MClientCredentials(LwM2MClientCredentials clientCredentials) {
|
||||||
|
if (StringUtils.isEmpty(clientCredentials.getEndpoint())) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client endpoint should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (clientCredentials.getSecurityConfigClientMode()) {
|
||||||
|
case NO_SEC:
|
||||||
|
break;
|
||||||
|
case PSK:
|
||||||
|
PSKClientCredentials pskCredentials = (PSKClientCredentials) clientCredentials;
|
||||||
|
if (StringUtils.isEmpty(pskCredentials.getIdentity())) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client PSK identity should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String pskKey = pskCredentials.getKey();
|
||||||
|
if (StringUtils.isEmpty(pskKey)) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client PSK key should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pskKey.matches("-?[0-9a-fA-F]+")) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client PSK key should be HexDecimal format!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pskKey.length() % 32 != 0 || pskKey.length() > 128) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client PSK key must be 32, 64, 128 characters!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RPK:
|
||||||
|
RPKClientCredentials rpkCredentials = (RPKClientCredentials) clientCredentials;
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(rpkCredentials.getKey())) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client RPK key should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SecurityUtil.publicKey.decode(rpkCredentials.getDecodedKey());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client RPK key should be in RFC7250 standard!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case X509:
|
||||||
|
X509ClientCredentials x509CCredentials = (X509ClientCredentials) clientCredentials;
|
||||||
|
if (x509CCredentials.getCert() != null) {
|
||||||
|
try {
|
||||||
|
SecurityUtil.certificate.decode(Hex.decodeHex(x509CCredentials.getCert().toLowerCase().toCharArray()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new DeviceCredentialsValidationException("LwM2M client X509 certificate should be in DER-encoded X.509 format!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateServerCredentials(LwM2MServerCredentials serverCredentials, String server) {
|
||||||
|
switch (serverCredentials.getSecurityMode()) {
|
||||||
|
case NO_SEC:
|
||||||
|
break;
|
||||||
|
case PSK:
|
||||||
|
PSKServerCredentials pskCredentials = (PSKServerCredentials) serverCredentials;
|
||||||
|
if (StringUtils.isEmpty(pskCredentials.getClientPublicKeyOrId())) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client PSK public key or id should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String pskKey = pskCredentials.getClientSecretKey();
|
||||||
|
if (StringUtils.isEmpty(pskKey)) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client PSK key should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pskKey.matches("-?[0-9a-fA-F]+")) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client PSK key should be HexDecimal format!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pskKey.length() % 32 != 0 || pskKey.length() > 128) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client PSK key must be 32, 64, 128 characters!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RPK:
|
||||||
|
RPKServerCredentials rpkCredentials = (RPKServerCredentials) serverCredentials;
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(rpkCredentials.getClientPublicKeyOrId())) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client RPK public key or id should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SecurityUtil.publicKey.decode(rpkCredentials.getDecodedClientPublicKeyOrId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client RPK public key or id should be in RFC7250 standard!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(rpkCredentials.getClientSecretKey())) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client RPK secret key should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SecurityUtil.privateKey.decode(rpkCredentials.getDecodedClientSecretKey());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client RPK secret key should be in RFC5958 standard!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case X509:
|
||||||
|
X509ServerCredentials x509CCredentials = (X509ServerCredentials) serverCredentials;
|
||||||
|
if (StringUtils.isEmpty(x509CCredentials.getClientPublicKeyOrId())) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client X509 public key or id should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SecurityUtil.certificate.decode(x509CCredentials.getDecodedClientPublicKeyOrId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client X509 public key or id should be in DER-encoded X.509 format!");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(x509CCredentials.getClientSecretKey())) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client X509 secret key should be specified!");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
SecurityUtil.privateKey.decode(x509CCredentials.getDecodedClientSecretKey());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new DeviceCredentialsValidationException(server + " client X509 secret key should be in RFC5958 standard!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(cacheNames = DEVICE_CREDENTIALS_CACHE, key = "'deviceCredentials_' + #deviceCredentials.credentialsId")
|
@CacheEvict(cacheNames = DEVICE_CREDENTIALS_CACHE, key = "'deviceCredentials_' + #deviceCredentials.credentialsId")
|
||||||
public void deleteDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials) {
|
public void deleteDeviceCredentials(TenantId tenantId, DeviceCredentials deviceCredentials) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user