Rewrite test using self-signed test x509 certificate

This commit is contained in:
Andrii Landiak 2023-03-29 18:53:36 +03:00
parent 394ed516c4
commit e842c3da08
3 changed files with 77 additions and 9 deletions

View File

@ -252,15 +252,17 @@ public class DefaultTransportApiService implements TransportApiService {
}
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileByCertificateHash(certificateHash);
if (deviceProfile != null) {
X509CertificateChainProvisionConfiguration x509Configuration = new X509CertificateChainProvisionConfiguration();
X509CertificateChainProvisionConfiguration x509Configuration;
if (deviceProfile.getProfileData().getProvisionConfiguration() instanceof X509CertificateChainProvisionConfiguration) {
x509Configuration = (X509CertificateChainProvisionConfiguration) deviceProfile.getProfileData().getProvisionConfiguration();
} else {
log.warn("Device Profile provision configuration is not X509CertificateChainProvisionConfiguration");
return getEmptyTransportApiResponseFuture();
}
String deviceName = extractDeviceNameFromCertificateCNByRegEx(chain.get(0), x509Configuration.getCertificateRegExPattern());
if (deviceName == null) {
log.warn("Device name has to be extract by regex from CN.");
log.warn("Cannot extract device name from device's CN using regex [{}]", x509Configuration.getCertificateRegExPattern());
return getEmptyTransportApiResponseFuture();
}
Device device = deviceService.findDeviceByTenantIdAndName(deviceProfile.getTenantId(), deviceName);
String updateDeviceCertificateValue = chain.get(0);

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.service.transport;
import com.google.common.util.concurrent.Futures;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.mock.mockito.MockBean;
@ -49,7 +50,14 @@ import org.thingsboard.server.service.executors.DbCallbackExecutorService;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.service.resource.TbResourceService;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
@ -94,9 +102,20 @@ public class DefaultTransportApiServiceTest {
@SpyBean
DefaultTransportApiService service;
private final String deviceCertificate = "-----BEGIN CERTIFICATE-----Device certificate value-----END CERTIFICATE-----";
private final String deviceProfileCertificate = "-----BEGIN CERTIFICATE-----Device profile certificate value-----END CERTIFICATE-----";
private final String[] chain = new String[]{deviceCertificate, deviceProfileCertificate};
private String certificateChain;
private String[] chain;
@Before
public void setUp() {
String filePath = "src/test/resources/mqtt/x509ChainProvisionTest.pem";
try {
certificateChain = Files.readString(Paths.get(filePath));
certificateChain = certTrimNewLinesForChainInDeviceProfile(certificateChain);
chain = fetchLeafCertificateFromChain(certificateChain);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void validateExistingDeviceX509Certificate() {
@ -106,7 +125,7 @@ public class DefaultTransportApiServiceTest {
var deviceCredentials = createDeviceCredentials(chain[0], device.getId());
when(deviceCredentialsService.findDeviceCredentialsByCredentialsId(any())).thenReturn(deviceCredentials);
service.validateOrCreateDeviceX509Certificate(chain[0]);
service.validateOrCreateDeviceX509Certificate(certificateChain);
verify(deviceCredentialsService, times(1)).findDeviceCredentialsByCredentialsId(any());
}
@ -123,7 +142,7 @@ public class DefaultTransportApiServiceTest {
when(deviceCredentialsService.findDeviceCredentialsByDeviceId(any(), any())).thenReturn(deviceCredentials);
when(deviceCredentialsService.updateDeviceCredentials(any(), any())).thenReturn(deviceCredentials);
service.validateOrCreateDeviceX509Certificate(chain[1]);
service.validateOrCreateDeviceX509Certificate(certificateChain);
verify(deviceProfileService, times(1)).findDeviceProfileByCertificateHash(any());
verify(deviceService, times(1)).findDeviceByTenantIdAndName(any(), any());
verify(deviceCredentialsService, times(1)).findDeviceCredentialsByDeviceId(any(), any());
@ -143,7 +162,7 @@ public class DefaultTransportApiServiceTest {
when(deviceCredentialsService.findDeviceCredentialsByDeviceId(any(), any())).thenReturn(deviceCredentials);
when(deviceCredentialsService.updateDeviceCredentials(any(), any())).thenReturn(deviceCredentials);
service.validateOrCreateDeviceX509Certificate(chain[1]);
service.validateOrCreateDeviceX509Certificate(certificateChain);
verify(deviceProfileService, times(1)).findDeviceProfileByCertificateHash(any());
verify(deviceService, times(1)).findDeviceByTenantIdAndName(any(), any());
verify(deviceCredentialsService, times(1)).findDeviceCredentialsByDeviceId(any(), any());
@ -164,7 +183,7 @@ public class DefaultTransportApiServiceTest {
DeviceProfileData deviceProfileData = new DeviceProfileData();
X509CertificateChainProvisionConfiguration provision = new X509CertificateChainProvisionConfiguration();
provision.setCertificateValue(certificateValue);
provision.setCertificateRegExPattern("^$");
provision.setCertificateRegExPattern("([^@]+)");
provision.setAllowCreateNewDevicesByX509Certificate(true);
deviceProfileData.setProvisionConfiguration(provision);
deviceProfile.setProfileData(deviceProfileData);
@ -178,4 +197,23 @@ public class DefaultTransportApiServiceTest {
device.setId(new DeviceId(UUID.randomUUID()));
return device;
}
public static String certTrimNewLinesForChainInDeviceProfile(String input) {
return input.replaceAll("\n", "")
.replaceAll("\r", "")
.replaceAll("-----BEGIN CERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n")
.replaceAll("-----END CERTIFICATE-----", "\n-----END CERTIFICATE-----\n")
.trim();
}
private String[] fetchLeafCertificateFromChain(String value) {
List<String> chain = new ArrayList<>();
String regex = "-----BEGIN CERTIFICATE-----\\s*.*?\\s*-----END CERTIFICATE-----";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(value);
while (matcher.find()) {
chain.add(matcher.group(0));
}
return chain.toArray(new String[0]);
}
}

View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIICMTCCAdegAwIBAgIUI9dBuwN6pTtK6uZ03rkiCwV4wEYwCgYIKoZIzj0EAwIw
bjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGlu
Z3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVBy
b3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTYxN1oXDTI0MDMyODE0NTYxN1ow
bjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGlu
Z3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlQ2VydGlmaWNhdGVAWDUwOVBy
b3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9Zo791qK
QiGNBm11r4ZGxh+w+ossZL3xc46ufq5QckQHP7zkD2XDAcmP5GvdkM1sBFN9AWaC
kQfNnWmfERsOOKNTMFEwHQYDVR0OBBYEFFFc5uyCyglQoZiKhzXzMcQ3BKORMB8G
A1UdIwQYMBaAFFFc5uyCyglQoZiKhzXzMcQ3BKORMA8GA1UdEwEB/wQFMAMBAf8w
CgYIKoZIzj0EAwIDSAAwRQIhANbA9CuhoOifZMMmqkpuld+65CR+ItKdXeRAhLMZ
uccuAiB0FSQB34zMutXrZj1g8Gl5OkE7YryFHbei1z0SveHR8g==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICMTCCAdegAwIBAgIUUEKxS9hTz4l+oLUMF0LV6TC/gCIwCgYIKoZIzj0EAwIw
bjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGlu
Z3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlUHJvZmlsZUNlcnRAWDUwOVBy
b3Zpc2lvblN0cmF0ZWd5MB4XDTIzMDMyOTE0NTczNloXDTI0MDMyODE0NTczNlow
bjELMAkGA1UEBhMCVVMxETAPBgNVBAgMCE5ldyBZb3JrMRowGAYDVQQKDBFUaGlu
Z3NCb2FyZCwgSW5jLjEwMC4GA1UEAwwnZGV2aWNlUHJvZmlsZUNlcnRAWDUwOVBy
b3Zpc2lvblN0cmF0ZWd5MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECMlWO72k
rDoUL9FQjUmSCetkhaEGJUfQkdSfkLSNa0GyAEIMbfmzI4zITeapunu4rGet3EMy
LydQzuQanBicp6NTMFEwHQYDVR0OBBYEFHpZ78tPnztNii4Da/yCw6mhEIL3MB8G
A1UdIwQYMBaAFHpZ78tPnztNii4Da/yCw6mhEIL3MA8GA1UdEwEB/wQFMAMBAf8w
CgYIKoZIzj0EAwIDSAAwRQIgJ7qyMFqNcwSYkH6o+UlQXzLWfwZbNjVk+aR7foAZ
NGsCIQDsd7v3WQIGHiArfZeDs1DLEDuV/2h6L+ZNoGNhEKL+1A==
-----END CERTIFICATE-----