|
|
@ -29,22 +29,21 @@ import org.eclipse.californium.scandium.dtls.HandshakeResultHandler; |
|
|
import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier; |
|
|
import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier; |
|
|
import org.eclipse.californium.scandium.dtls.x509.StaticCertificateVerifier; |
|
|
import org.eclipse.californium.scandium.dtls.x509.StaticCertificateVerifier; |
|
|
import org.eclipse.californium.scandium.util.ServerNames; |
|
|
import org.eclipse.californium.scandium.util.ServerNames; |
|
|
|
|
|
import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; |
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
import org.springframework.stereotype.Component; |
|
|
import org.springframework.stereotype.Component; |
|
|
import org.springframework.util.StringUtils; |
|
|
|
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
import org.thingsboard.common.util.JacksonUtil; |
|
|
import org.thingsboard.server.common.data.DeviceProfile; |
|
|
import org.thingsboard.server.common.data.DeviceProfile; |
|
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; |
|
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode; |
|
|
|
|
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredentials; |
|
|
import org.thingsboard.server.common.msg.EncryptionUtil; |
|
|
import org.thingsboard.server.common.msg.EncryptionUtil; |
|
|
import org.thingsboard.server.common.transport.TransportService; |
|
|
|
|
|
import org.thingsboard.server.common.transport.TransportServiceCallback; |
|
|
|
|
|
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
|
|
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
|
|
import org.thingsboard.server.common.transport.util.SslUtil; |
|
|
import org.thingsboard.server.common.transport.util.SslUtil; |
|
|
import org.thingsboard.server.gen.transport.TransportProtos; |
|
|
|
|
|
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
|
|
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
|
|
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
|
|
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; |
|
|
import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; |
|
|
import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; |
|
|
import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredentials; |
|
|
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; |
|
|
|
|
|
import org.thingsboard.server.transport.lwm2m.server.store.TbEditableSecurityStore; |
|
|
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
|
|
import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
|
|
|
|
|
|
|
|
import javax.annotation.PostConstruct; |
|
|
import javax.annotation.PostConstruct; |
|
|
@ -57,8 +56,6 @@ import java.security.cert.CertificateNotYetValidException; |
|
|
import java.security.cert.X509Certificate; |
|
|
import java.security.cert.X509Certificate; |
|
|
import java.util.Arrays; |
|
|
import java.util.Arrays; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.concurrent.CountDownLatch; |
|
|
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
|
|
|
|
@Slf4j |
|
|
@Slf4j |
|
|
@Component |
|
|
@Component |
|
|
@ -66,9 +63,10 @@ import java.util.concurrent.TimeUnit; |
|
|
@RequiredArgsConstructor |
|
|
@RequiredArgsConstructor |
|
|
public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVerifier { |
|
|
public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVerifier { |
|
|
|
|
|
|
|
|
private final TransportService transportService; |
|
|
|
|
|
private final TbLwM2MDtlsSessionStore sessionStorage; |
|
|
private final TbLwM2MDtlsSessionStore sessionStorage; |
|
|
private final LwM2MTransportServerConfig config; |
|
|
private final LwM2MTransportServerConfig config; |
|
|
|
|
|
private final LwM2mCredentialsSecurityInfoValidator securityInfoValidator; |
|
|
|
|
|
private final TbEditableSecurityStore securityStore; |
|
|
|
|
|
|
|
|
@SuppressWarnings("deprecation") |
|
|
@SuppressWarnings("deprecation") |
|
|
private StaticCertificateVerifier staticCertificateVerifier; |
|
|
private StaticCertificateVerifier staticCertificateVerifier; |
|
|
@ -119,48 +117,33 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer |
|
|
|
|
|
|
|
|
String strCert = SslUtil.getCertificateString(cert); |
|
|
String strCert = SslUtil.getCertificateString(cert); |
|
|
String sha3Hash = EncryptionUtil.getSha3Hash(strCert); |
|
|
String sha3Hash = EncryptionUtil.getSha3Hash(strCert); |
|
|
final ValidateDeviceCredentialsResponse[] deviceCredentialsResponse = new ValidateDeviceCredentialsResponse[1]; |
|
|
TbLwM2MSecurityInfo securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(sha3Hash, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); |
|
|
CountDownLatch latch = new CountDownLatch(1); |
|
|
ValidateDeviceCredentialsResponse msg = securityInfo != null ? securityInfo.getMsg() : null; |
|
|
transportService.process(TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(sha3Hash).build(), |
|
|
if (msg != null && org.thingsboard.server.common.data.StringUtils.isNotEmpty(msg.getCredentials())) { |
|
|
new TransportServiceCallback<>() { |
|
|
LwM2MCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MCredentials.class); |
|
|
@Override |
|
|
if (!credentials.getClient().getSecurityConfigClientMode().equals(LwM2MSecurityMode.X509)) { |
|
|
public void onSuccess(ValidateDeviceCredentialsResponse msg) { |
|
|
continue; |
|
|
if (!StringUtils.isEmpty(msg.getCredentials())) { |
|
|
} |
|
|
deviceCredentialsResponse[0] = msg; |
|
|
X509ClientCredentials config = (X509ClientCredentials) credentials.getClient(); |
|
|
} |
|
|
String certBody = config.getCert(); |
|
|
latch.countDown(); |
|
|
String endpoint = config.getEndpoint(); |
|
|
} |
|
|
if (strCert.equals(certBody)) { |
|
|
|
|
|
x509CredentialsFound = true; |
|
|
@Override |
|
|
DeviceProfile deviceProfile = msg.getDeviceProfile(); |
|
|
public void onError(Throwable e) { |
|
|
if (msg.hasDeviceInfo() && deviceProfile != null) { |
|
|
log.error(e.getMessage(), e); |
|
|
sessionStorage.put(endpoint, new TbX509DtlsSessionInfo(cert.getSubjectX500Principal().getName(), msg)); |
|
|
latch.countDown(); |
|
|
try { |
|
|
} |
|
|
securityStore.put(securityInfo); |
|
|
}); |
|
|
} catch (NonUniqueSecurityInfoException e) { |
|
|
if (latch.await(10, TimeUnit.SECONDS)) { |
|
|
log.trace("Failed to add security info: {}", securityInfo, e); |
|
|
ValidateDeviceCredentialsResponse msg = deviceCredentialsResponse[0]; |
|
|
|
|
|
if (msg != null && org.thingsboard.server.common.data.StringUtils.isNotEmpty(msg.getCredentials())) { |
|
|
|
|
|
LwM2MCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MCredentials.class); |
|
|
|
|
|
if(!credentials.getClient().getSecurityConfigClientMode().equals(LwM2MSecurityMode.X509)){ |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
X509ClientCredentials config = (X509ClientCredentials) credentials.getClient(); |
|
|
|
|
|
String certBody = config.getCert(); |
|
|
|
|
|
String endpoint = config.getEndpoint(); |
|
|
|
|
|
if (strCert.equals(certBody)) { |
|
|
|
|
|
x509CredentialsFound = true; |
|
|
|
|
|
DeviceProfile deviceProfile = msg.getDeviceProfile(); |
|
|
|
|
|
if (msg.hasDeviceInfo() && deviceProfile != null) { |
|
|
|
|
|
sessionStorage.put(endpoint, new TbX509DtlsSessionInfo(cert.getSubjectX500Principal().getName(), msg)); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
} |
|
|
} else { |
|
|
break; |
|
|
log.trace("[{}][{}] Certificate mismatch. Expected: {}, Actual: {}", endpoint, sha3Hash, strCert, certBody); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
log.trace("[{}][{}] Certificate mismatch. Expected: {}, Actual: {}", endpoint, sha3Hash, strCert, certBody); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} catch (InterruptedException | |
|
|
} catch (CertificateEncodingException | |
|
|
CertificateEncodingException | |
|
|
|
|
|
CertificateExpiredException | |
|
|
CertificateExpiredException | |
|
|
CertificateNotYetValidException e) { |
|
|
CertificateNotYetValidException e) { |
|
|
log.error(e.getMessage(), e); |
|
|
log.error(e.getMessage(), e); |
|
|
|