lwm2m - update lwm2mController by base64 and createte BootstrpServerCredentials by Profile (Base64 validate)
This commit is contained in:
parent
1dada1526f
commit
bad6653a50
@ -17,6 +17,7 @@ package org.thingsboard.server.service.lwm2m;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.eclipse.leshan.core.util.Hex;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Service;
|
||||
@ -50,22 +51,26 @@ public class LwM2MServiceImpl implements LwM2MService {
|
||||
bsServ.setPort(serverConfig.getPort());
|
||||
bsServ.setSecurityHost(serverConfig.getSecureHost());
|
||||
bsServ.setSecurityPort(serverConfig.getSecurePort());
|
||||
bsServ.setServerPublicKey(getPublicKey(serverConfig));
|
||||
byte[] publicKeyBase64 = getPublicKey(serverConfig);
|
||||
if (publicKeyBase64 == null) {
|
||||
bsServ.setServerPublicKey("");
|
||||
} else {
|
||||
bsServ.setServerPublicKey(Base64.encodeBase64String(getPublicKey(serverConfig)));
|
||||
}
|
||||
return bsServ;
|
||||
}
|
||||
|
||||
private String getPublicKey(LwM2MSecureServerConfig config) {
|
||||
private byte[] getPublicKey(LwM2MSecureServerConfig config) {
|
||||
try {
|
||||
KeyStore keyStore = serverConfig.getKeyStoreValue();
|
||||
if (keyStore != null) {
|
||||
X509Certificate serverCertificate = (X509Certificate) serverConfig.getKeyStoreValue().getCertificate(config.getCertificateAlias());
|
||||
return Hex.encodeHexString(serverCertificate.getPublicKey().getEncoded());
|
||||
return serverCertificate.getPublicKey().getEncoded();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.trace("Failed to fetch public key from key store!", e);
|
||||
|
||||
}
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
package org.thingsboard.server.common.data.device.data.lwm2m;
|
||||
|
||||
import lombok.Data;
|
||||
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.ServerCredentials;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -24,7 +25,7 @@ public class BootstrapConfiguration {
|
||||
|
||||
//TODO: define the objects;
|
||||
private Map<String, Object> servers;
|
||||
private Map<String, Object> lwm2mServer;
|
||||
private Map<String, Object> bootstrapServer;
|
||||
private ServerCredentials lwm2mServer;
|
||||
private ServerCredentials bootstrapServer;
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* 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.profile.lwm2m.bootstrap;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbstractServerCredentials extends ServerSecurityConfig implements ServerCredentials {
|
||||
|
||||
@JsonIgnore
|
||||
public byte[] getDecodedCServerPublicKey() {
|
||||
return getDecoded(serverPublicKey);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private static byte[] getDecoded(String key) {
|
||||
return Base64.decodeBase64(key.getBytes());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.profile.lwm2m.bootstrap;
|
||||
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
|
||||
|
||||
public class NoSecServerCredentials extends AbstractServerCredentials{
|
||||
@Override
|
||||
public LwM2MSecurityMode getSecurityMode() {
|
||||
return LwM2MSecurityMode.NO_SEC;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.profile.lwm2m.bootstrap;
|
||||
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
|
||||
|
||||
public class PSKServerCredentials extends AbstractServerCredentials{
|
||||
@Override
|
||||
public LwM2MSecurityMode getSecurityMode() {
|
||||
return LwM2MSecurityMode.PSK;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.profile.lwm2m.bootstrap;
|
||||
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
|
||||
|
||||
public class RPKServerCredentials extends AbstractServerCredentials{
|
||||
@Override
|
||||
public LwM2MSecurityMode getSecurityMode() {
|
||||
return LwM2MSecurityMode.RPK;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.profile.lwm2m.bootstrap;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ServerConfig {
|
||||
private Integer shortId = 123;
|
||||
private Integer lifetime = 300;
|
||||
private Integer defaultMinPeriod = 1;
|
||||
private boolean notifIfDisabled = true;
|
||||
private String binding = "U";
|
||||
}
|
||||
@ -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.profile.lwm2m.bootstrap;
|
||||
|
||||
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.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
|
||||
|
||||
@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 ServerCredentials {
|
||||
@JsonIgnore
|
||||
LwM2MSecurityMode getSecurityMode();
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* 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.profile.lwm2m.bootstrap;
|
||||
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
|
||||
|
||||
public class X509ServerCredentials extends AbstractServerCredentials{
|
||||
@Override
|
||||
public LwM2MSecurityMode getSecurityMode() {
|
||||
return LwM2MSecurityMode.X509;
|
||||
}
|
||||
}
|
||||
@ -22,23 +22,23 @@ import lombok.Data;
|
||||
@ApiModel
|
||||
@Data
|
||||
public class ServerSecurityConfig {
|
||||
@ApiModelProperty(position = 1, value = "Is Bootstrap Server", example = "true", readOnly = true)
|
||||
boolean bootstrapServerIs = true;
|
||||
@ApiModelProperty(position = 1, value = "Is Bootstrap Server or Lwm2m Server", example = "true or false", readOnly = true)
|
||||
protected boolean bootstrapServerIs = true;
|
||||
@ApiModelProperty(position = 2, value = "Host for 'No Security' mode", example = "0.0.0.0", readOnly = true)
|
||||
String host;
|
||||
@ApiModelProperty(position = 3, value = "Port for 'No Security' mode", example = "5687", readOnly = true)
|
||||
Integer port;
|
||||
protected String host;
|
||||
@ApiModelProperty(position = 3, value = "Port for Lwm2m Server: 'No Security' mode: Lwm2m Server or Bootstrap Server", example = "'5685' or '5687'", readOnly = true)
|
||||
protected Integer port;
|
||||
@ApiModelProperty(position = 4, value = "Host for 'Security' mode (DTLS)", example = "0.0.0.0", readOnly = true)
|
||||
String securityHost;
|
||||
@ApiModelProperty(position = 5, value = "Port for 'Security' mode (DTLS)", example = "5688", readOnly = true)
|
||||
Integer securityPort;
|
||||
@ApiModelProperty(position = 5, value = "Server short Id", example = "111", readOnly = true)
|
||||
Integer serverId = 111;
|
||||
@ApiModelProperty(position = 7, value = "Client Hold Off Time", example = "1", readOnly = true)
|
||||
Integer clientHoldOffTime = 1;
|
||||
@ApiModelProperty(position = 8, value = "Server Public Key (base64 encoded)", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" +
|
||||
protected String securityHost;
|
||||
@ApiModelProperty(position = 5, value = "Port for 'Security' mode (DTLS): Lwm2m Server or Bootstrap Server", example = "5686 or 5688", readOnly = true)
|
||||
protected Integer securityPort;
|
||||
@ApiModelProperty(position = 6, value = "Server short Id", example = "111", readOnly = true)
|
||||
protected Integer serverId = 111;
|
||||
@ApiModelProperty(position = 7, value = "Client Hold Off Time. The number of seconds to wait before initiating a Client Initiated Bootstrap once the LwM2M Client has determined it should initiate this bootstrap mode. (This information is relevant for use with a Bootstrap-Server only.)", example = "1", readOnly = true)
|
||||
protected Integer clientHoldOffTime = 1;
|
||||
@ApiModelProperty(position = 8, value = "Server Public Key for 'Security' mode (DTLS): RPK or X509. Format: base64 encoded", example = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAZ0pSaGKHk/GrDaUDnQZpeEdGwX7m3Ws+U/kiVat\n" +
|
||||
"+44sgk3c8g0LotfMpLlZJPhPwJ6ipXV+O1r7IZUjBs3LNA==", readOnly = true)
|
||||
String serverPublicKey;
|
||||
@ApiModelProperty(position = 9, value = "Bootstrap Server Account Timeout", example = "0", readOnly = true)
|
||||
protected String serverPublicKey;
|
||||
@ApiModelProperty(position = 9, value = "Bootstrap Server Account Timeout (If the value is set to 0, or if this resource is not instantiated, the Bootstrap-Server Account lifetime is infinite.)", example = "0", readOnly = true)
|
||||
Integer bootstrapServerAccountTimeout = 0;
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ import com.squareup.wire.schema.internal.parser.ProtoFileElement;
|
||||
import com.squareup.wire.schema.internal.parser.ProtoParser;
|
||||
import com.squareup.wire.schema.internal.parser.TypeElement;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.leshan.core.util.SecurityUtil;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -58,16 +59,21 @@ import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTrans
|
||||
import org.thingsboard.server.common.data.device.profile.MqttDeviceProfileTransportConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration;
|
||||
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.RPKServerCredentials;
|
||||
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.ServerCredentials;
|
||||
import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.X509ServerCredentials;
|
||||
import org.thingsboard.server.common.data.ota.OtaPackageType;
|
||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||
import org.thingsboard.server.common.data.id.TenantId;
|
||||
import org.thingsboard.server.common.data.page.PageData;
|
||||
import org.thingsboard.server.common.data.page.PageLink;
|
||||
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||
import org.thingsboard.server.common.msg.EncryptionUtil;
|
||||
import org.thingsboard.server.common.msg.queue.ServiceType;
|
||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||
import org.thingsboard.server.dao.entity.AbstractEntityService;
|
||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||
import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException;
|
||||
import org.thingsboard.server.dao.ota.OtaPackageService;
|
||||
import org.thingsboard.server.dao.rule.RuleChainService;
|
||||
import org.thingsboard.server.dao.service.DataValidator;
|
||||
@ -695,6 +701,42 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
|
||||
}
|
||||
}
|
||||
|
||||
private void validateLwm2mServersCredentialOfBootstrapForClient(ServerCredentials bootstrapServerConfig, String server) {
|
||||
switch (bootstrapServerConfig.getSecurityMode()) {
|
||||
case NO_SEC:
|
||||
case PSK:
|
||||
break;
|
||||
case RPK:
|
||||
RPKServerCredentials rpkServerCredentials = (RPKServerCredentials) bootstrapServerConfig;
|
||||
if (StringUtils.isEmpty(rpkServerCredentials.getServerPublicKey())) {
|
||||
throw new DeviceCredentialsValidationException(server + " RPK public key must be specified!");
|
||||
}
|
||||
try {
|
||||
String pubkRpkSever = EncryptionUtil.pubkTrimNewLines(rpkServerCredentials.getServerPublicKey());
|
||||
rpkServerCredentials.setServerPublicKey(pubkRpkSever);
|
||||
SecurityUtil.publicKey.decode(rpkServerCredentials.getDecodedCServerPublicKey());
|
||||
} catch (Exception e) {
|
||||
throw new DeviceCredentialsValidationException(server + " RPK public key must be in standard [RFC7250] and then encoded to Base64 format!");
|
||||
}
|
||||
break;
|
||||
case X509:
|
||||
X509ServerCredentials x509ServerCredentials = (X509ServerCredentials) bootstrapServerConfig;
|
||||
// X509BootstrapServerCredentials x509ServerCredentials = (X509BootstrapServerCredentials) bootstrapServerConfig;
|
||||
if (StringUtils.isEmpty(x509ServerCredentials.getServerPublicKey())) {
|
||||
throw new DeviceCredentialsValidationException(server + " X509 public key must be specified!");
|
||||
}
|
||||
|
||||
try {
|
||||
String certServer = EncryptionUtil.certTrimNewLines(x509ServerCredentials.getServerPublicKey());
|
||||
x509ServerCredentials.setServerPublicKey(certServer);
|
||||
SecurityUtil.publicKey.decode(x509ServerCredentials.getDecodedCServerPublicKey());
|
||||
} catch (Exception e) {
|
||||
throw new DeviceCredentialsValidationException(server + " X509 public key must be in standard [RFC7250] and then encoded to Base64 format!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private PaginatedRemover<TenantId, DeviceProfile> tenantDeviceProfilesRemover =
|
||||
new PaginatedRemover<TenantId, DeviceProfile>() {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user