diff --git a/application/src/main/data/upgrade/3.4.3/schema_update.sql b/application/src/main/data/upgrade/3.4.3/schema_update.sql index 78203951ec..2aaa574bb4 100644 --- a/application/src/main/data/upgrade/3.4.3/schema_update.sql +++ b/application/src/main/data/upgrade/3.4.3/schema_update.sql @@ -31,9 +31,6 @@ CREATE INDEX IF NOT EXISTS idx_alarm_comment_alarm_id ON alarm_comment(alarm_id) ALTER TABLE device_profile ADD COLUMN IF NOT EXISTS certificate_hash varchar, - ADD COLUMN IF NOT EXISTS certificate_value varchar, - ADD COLUMN IF NOT EXISTS certificate_regex_pattern varchar(255), - ADD COLUMN IF NOT EXISTS allow_create_device_by_x509 boolean, DROP CONSTRAINT IF EXISTS device_profile_credentials_hash_unq_key, ADD CONSTRAINT device_profile_credentials_hash_unq_key UNIQUE (certificate_hash); diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index f434df2faa..6a3780d529 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfig import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.data.PowerSavingConfiguration; import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; +import org.thingsboard.server.common.data.device.profile.X509CertificateChainProvisionConfiguration; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -173,7 +174,7 @@ public class DefaultTransportApiService implements TransportApiService { result = validateCredentials(msg.getHash(), DeviceCredentialsType.X509_CERTIFICATE); } else if (transportApiRequestMsg.hasValidateOrCreateX509CertRequestMsg()) { TransportProtos.ValidateOrCreateDeviceX509CertRequestMsg msg = transportApiRequestMsg.getValidateOrCreateX509CertRequestMsg(); - result = validateOrCreateDeviceX509Certificate(msg.getCertificate(), DeviceCredentialsType.X509_CERTIFICATE); + result = validateOrCreateDeviceX509Certificate(msg.getCertificateChain(), DeviceCredentialsType.X509_CERTIFICATE); } else if (transportApiRequestMsg.hasGetOrCreateDeviceRequestMsg()) { result = handle(transportApiRequestMsg.getGetOrCreateDeviceRequestMsg()); } else if (transportApiRequestMsg.hasEntityProfileRequestMsg()) { @@ -258,7 +259,11 @@ public class DefaultTransportApiService implements TransportApiService { } DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileByCertificateHash(certificateHash); if (deviceProfile != null) { - String deviceName = extractDeviceNameFromCNByRegEx(deviceCommonName, deviceProfile.getCertificateRegexPattern()); + X509CertificateChainProvisionConfiguration x509Configuration = new X509CertificateChainProvisionConfiguration(); + if (deviceProfile.getProfileData().getProvisionConfiguration() instanceof X509CertificateChainProvisionConfiguration) { + x509Configuration = (X509CertificateChainProvisionConfiguration) deviceProfile.getProfileData().getProvisionConfiguration(); + } + String deviceName = extractDeviceNameFromCNByRegEx(deviceCommonName, x509Configuration.getCertificateRegExPattern()); if (deviceName == null) { log.error("Device name cannot be unmatched from CN!"); return getEmptyTransportApiResponseFuture(); @@ -272,7 +277,7 @@ public class DefaultTransportApiService implements TransportApiService { deviceCredentials = createDeviceCredentials(device.getTenantId(), device.getId(), updateDeviceCertificateValue, updateDeviceCertificateHash, credentialsType); } return getDeviceInfo(deviceCredentials); - } else if (deviceProfile.getProvisionType() == DeviceProfileProvisionType.ALLOW_CREATING_NEW_DEVICES_BY_X509_CERTIFICATE && deviceProfile.isAllowCreateNewDevicesByX509Strategy()) { + } else if (deviceProfile.getProvisionType() == DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN && x509Configuration.isAllowCreateNewDevicesByX509Certificate()) { Device savedDevice = createDevice(deviceProfile.getTenantId(), deviceProfile.getId(), deviceName, deviceProfile.getName()); DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(savedDevice.getTenantId(), savedDevice.getId()); deviceCredentials = updateDeviceCredentials(savedDevice.getTenantId(), deviceCredentials, updateDeviceCertificateValue, updateDeviceCertificateHash, credentialsType); diff --git a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java index 4a2ff07978..71a2f8b70c 100644 --- a/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/transport/DefaultTransportApiServiceTest.java @@ -29,6 +29,9 @@ import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceProfileProvisionType; +import org.thingsboard.server.common.data.device.profile.X509CertificateChainProvisionConfiguration; +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.DeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.common.data.security.DeviceCredentialsType; @@ -158,11 +161,15 @@ public class DefaultTransportApiServiceTest { private DeviceProfile createDeviceProfile(String certificateValue) { DeviceProfile deviceProfile = new DeviceProfile(); - deviceProfile.setCertificateValue(certificateValue); + DeviceProfileData deviceProfileData = new DeviceProfileData(); + X509CertificateChainProvisionConfiguration provision = new X509CertificateChainProvisionConfiguration(); + provision.setCertificateValue(certificateValue); + provision.setCertificateRegExPattern("^$"); + provision.setAllowCreateNewDevicesByX509Certificate(true); + deviceProfileData.setProvisionConfiguration(provision); + deviceProfile.setProfileData(deviceProfileData); deviceProfile.setCertificateHash(EncryptionUtil.getSha3Hash(certificateValue)); - deviceProfile.setCertificateRegexPattern("^$"); - deviceProfile.setAllowCreateNewDevicesByX509Strategy(true); - deviceProfile.setProvisionType(DeviceProfileProvisionType.ALLOW_CREATING_NEW_DEVICES_BY_X509_CERTIFICATE); + deviceProfile.setProvisionType(DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN); return deviceProfile; } diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java index 69b1f87502..917e41d1b4 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/AbstractMqttIntegrationTest.java @@ -27,7 +27,6 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.AllowCreateNewDevicesDeviceProfileProvisionConfiguration; -import org.thingsboard.server.common.data.device.profile.AllowCreatingNewDevicesByX509CertificateProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration; import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; @@ -95,9 +94,6 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg deviceProfile.setProvisionType(provisionType); deviceProfile.setProvisionDeviceKey(config.getProvisionKey()); deviceProfile.setDescription(transportPayloadType.name() + " Test"); - deviceProfile.setAllowCreateNewDevicesByX509Strategy(config.allowCreatingNewDeviceByX509Strategy); - deviceProfile.setCertificateValue("Device Profile certificate value"); - deviceProfile.setCertificateRegexPattern(config.getRegEx()); DeviceProfileData deviceProfileData = new DeviceProfileData(); DefaultDeviceProfileConfiguration configuration = new DefaultDeviceProfileConfiguration(); MqttDeviceProfileTransportConfiguration mqttDeviceProfileTransportConfiguration = new MqttDeviceProfileTransportConfiguration(); @@ -148,9 +144,6 @@ public abstract class AbstractMqttIntegrationTest extends AbstractTransportInteg case CHECK_PRE_PROVISIONED_DEVICES: provisionConfiguration = new CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration(config.getProvisionSecret()); break; - case ALLOW_CREATING_NEW_DEVICES_BY_X509_CERTIFICATE: - provisionConfiguration = new AllowCreatingNewDevicesByX509CertificateProvisionConfiguration(config.getProvisionSecret()); - break; case DISABLED: default: provisionConfiguration = new DisabledDeviceProfileProvisionConfiguration(config.getProvisionSecret()); diff --git a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestConfigProperties.java b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestConfigProperties.java index 4c57f413c9..bc535b424b 100644 --- a/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestConfigProperties.java +++ b/application/src/test/java/org/thingsboard/server/transport/mqtt/MqttTestConfigProperties.java @@ -40,14 +40,9 @@ public class MqttTestConfigProperties { boolean enableCompatibilityWithJsonPayloadFormat; boolean useJsonPayloadFormatForDefaultDownlinkTopics; boolean sendAckOnValidationException; - boolean allowCreatingNewDeviceByX509Strategy; DeviceProfileProvisionType provisionType; String provisionKey; String provisionSecret; - String x509DeviceCertificate; - String x509DeviceProfileCertificate; - String commonName; - String regEx; } diff --git a/common/cluster-api/src/main/proto/queue.proto b/common/cluster-api/src/main/proto/queue.proto index b9741429f7..6e9ec38be8 100644 --- a/common/cluster-api/src/main/proto/queue.proto +++ b/common/cluster-api/src/main/proto/queue.proto @@ -170,7 +170,7 @@ message ValidateDeviceX509CertRequestMsg { } message ValidateOrCreateDeviceX509CertRequestMsg { - string certificate = 1; + string certificateChain = 1; } message ValidateBasicMqttCredRequestMsg { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java index e226261227..05f8ae19ba 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfile.java @@ -66,14 +66,8 @@ public class DeviceProfile extends SearchTextBased implements H private DeviceTransportType transportType; @ApiModelProperty(position = 15, value = "Provisioning strategy.") private DeviceProfileProvisionType provisionType; - @ApiModelProperty(position = 18, value = "CA certificate value. ") - private String certificateValue; - @ApiModelProperty(position = 19, value = "CA certificate hash. ") + @ApiModelProperty(position = 18, value = "CA certificate hash. ") private String certificateHash; - @ApiModelProperty(position = 20, value = "Regex to fetch deviceName from CN. ") - private String certificateRegexPattern; - @ApiModelProperty(position = 21, value = "Allow to create new devices by x509 provision strategy. ") - private boolean allowCreateNewDevicesByX509Strategy; @ApiModelProperty(position = 7, value = "Reference to the rule chain. " + @@ -131,9 +125,6 @@ public class DeviceProfile extends SearchTextBased implements H this.firmwareId = deviceProfile.getFirmwareId(); this.softwareId = deviceProfile.getSoftwareId(); this.defaultEdgeRuleChainId = deviceProfile.getDefaultEdgeRuleChainId(); - this.allowCreateNewDevicesByX509Strategy = deviceProfile.isAllowCreateNewDevicesByX509Strategy(); - this.certificateRegexPattern = deviceProfile.getCertificateRegexPattern(); - this.certificateValue = deviceProfile.getCertificateValue(); this.certificateHash = deviceProfile.getCertificateHash(); this.externalId = deviceProfile.getExternalId(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java index 7ee03d7227..f2daf71cca 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DeviceProfileProvisionType.java @@ -19,5 +19,5 @@ public enum DeviceProfileProvisionType { DISABLED, ALLOW_CREATE_NEW_DEVICES, CHECK_PRE_PROVISIONED_DEVICES, - ALLOW_CREATING_NEW_DEVICES_BY_X509_CERTIFICATE + X509_CERTIFICATE_CHAIN } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java index 7a70c00b98..048e10739f 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DeviceProfileProvisionConfiguration.java @@ -32,7 +32,7 @@ import java.io.Serializable; @JsonSubTypes.Type(value = DisabledDeviceProfileProvisionConfiguration.class, name = "DISABLED"), @JsonSubTypes.Type(value = AllowCreateNewDevicesDeviceProfileProvisionConfiguration.class, name = "ALLOW_CREATE_NEW_DEVICES"), @JsonSubTypes.Type(value = CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.class, name = "CHECK_PRE_PROVISIONED_DEVICES"), - @JsonSubTypes.Type(value = AllowCreatingNewDevicesByX509CertificateProvisionConfiguration.class, name = "ALLOW_CREATING_NEW_DEVICES_BY_X509_CERTIFICATE")}) + @JsonSubTypes.Type(value = X509CertificateChainProvisionConfiguration.class, name = "X509_CERTIFICATE_CHAIN")}) public interface DeviceProfileProvisionConfiguration extends Serializable { String getProvisionDeviceSecret(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreatingNewDevicesByX509CertificateProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/X509CertificateChainProvisionConfiguration.java similarity index 67% rename from common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreatingNewDevicesByX509CertificateProvisionConfiguration.java rename to common/data/src/main/java/org/thingsboard/server/common/data/device/profile/X509CertificateChainProvisionConfiguration.java index e84d09829f..0b500f3e52 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreatingNewDevicesByX509CertificateProvisionConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/X509CertificateChainProvisionConfiguration.java @@ -17,16 +17,21 @@ package org.thingsboard.server.common.data.device.profile; import lombok.Data; +import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.DeviceProfileProvisionType; @Data -public class AllowCreatingNewDevicesByX509CertificateProvisionConfiguration implements DeviceProfileProvisionConfiguration { +@NoArgsConstructor +public class X509CertificateChainProvisionConfiguration implements DeviceProfileProvisionConfiguration { - private final String provisionDeviceSecret; + private String provisionDeviceSecret; + private String certificateValue; + private String certificateRegExPattern; + private boolean allowCreateNewDevicesByX509Certificate; @Override public DeviceProfileProvisionType getType() { - return DeviceProfileProvisionType.ALLOW_CREATING_NEW_DEVICES_BY_X509_CERTIFICATE; + return DeviceProfileProvisionType.X509_CERTIFICATE_CHAIN; } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java index d73743e6b5..d5ff77837b 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java @@ -147,7 +147,7 @@ public class MqttSslHandlerProvider { try { String certificateChain = SslUtil.getCertificateChainString(chain); transportService.process(DeviceTransportType.MQTT, TransportProtos.ValidateOrCreateDeviceX509CertRequestMsg - .newBuilder().setCertificate(certificateChain).build(), + .newBuilder().setCertificateChain(certificateChain).build(), new TransportServiceCallback<>() { @Override public void onSuccess(ValidateDeviceCredentialsResponse msg) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java index 48e6a5b6b6..f558eb2c7e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceProfileServiceImpl.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileCon import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; +import org.thingsboard.server.common.data.device.profile.X509CertificateChainProvisionConfiguration; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.HasId; @@ -134,8 +135,12 @@ public class DeviceProfileServiceImpl extends AbstractCachedEntityService impl @Column(name = ModelConstants.EXTERNAL_ID_PROPERTY) private UUID externalId; - @Column(name = ModelConstants.DEVICE_PROFILE_CERTIFICATE_VALUE_PROPERTY) - private String certificateValue; - @Column(name = ModelConstants.DEVICE_PROFILE_CERTIFICATE_HASH_PROPERTY) private String certificateHash; - @Column(name = ModelConstants.DEVICE_PROFILE_CERTIFICATE_REGEX_PATTERN_PROPERTY) - private String certificateRegexPattern; - - @Column(name = ModelConstants.ALLOW_CREATE_NEW_DEVICES_BY_X509_PROVISION) - private boolean allowCreateDevice; - public DeviceProfileEntity() { super(); } @@ -139,9 +130,6 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl this.transportType = deviceProfile.getTransportType(); this.provisionType = deviceProfile.getProvisionType(); this.certificateHash = deviceProfile.getCertificateHash(); - this.certificateValue = deviceProfile.getCertificateValue(); - this.certificateRegexPattern = deviceProfile.getCertificateRegexPattern(); - this.allowCreateDevice = deviceProfile.isAllowCreateNewDevicesByX509Strategy(); this.description = deviceProfile.getDescription(); this.isDefault = deviceProfile.isDefault(); this.profileData = JacksonUtil.convertValue(deviceProfile.getProfileData(), ObjectNode.class); @@ -205,9 +193,6 @@ public final class DeviceProfileEntity extends BaseSqlEntity impl } deviceProfile.setProvisionDeviceKey(provisionDeviceKey); deviceProfile.setCertificateHash(certificateHash); - deviceProfile.setCertificateValue(certificateValue); - deviceProfile.setCertificateRegexPattern(certificateRegexPattern); - deviceProfile.setAllowCreateNewDevicesByX509Strategy(allowCreateDevice); if (firmwareId != null) { deviceProfile.setFirmwareId(new OtaPackageId(firmwareId)); diff --git a/dao/src/main/resources/sql/schema-entities.sql b/dao/src/main/resources/sql/schema-entities.sql index eed6f237b6..bd61d9a7c3 100644 --- a/dao/src/main/resources/sql/schema-entities.sql +++ b/dao/src/main/resources/sql/schema-entities.sql @@ -292,12 +292,9 @@ CREATE TABLE IF NOT EXISTS device_profile ( default_dashboard_id uuid, default_queue_name varchar(255), provision_device_key varchar, - certificate_value varchar, certificate_hash varchar, - certificate_regex_pattern varchar(255), default_edge_rule_chain_id uuid, external_id uuid, - allow_create_device_by_x509 boolean, CONSTRAINT device_profile_credentials_hash_unq_key UNIQUE (certificate_hash), CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name), CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),