Search in sources :

Example 1 with X509ClientCredential

use of org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential in project thingsboard by thingsboard.

the class TbLwM2MDtlsCertificateVerifier method verifyCertificate.

@Override
public CertificateVerificationResult verifyCertificate(ConnectionId cid, ServerNames serverName, InetSocketAddress remotePeer, boolean clientUsage, boolean verifySubject, boolean truncateCertificatePath, CertificateMessage message) {
    CertPath certChain = message.getCertificateChain();
    if (certChain == null) {
        // We trust all RPK on this layer, and use TbLwM2MAuthorizer
        PublicKey publicKey = message.getPublicKey();
        return new CertificateVerificationResult(cid, publicKey, null);
    } else {
        try {
            boolean x509CredentialsFound = false;
            X509Certificate[] chain = certChain.getCertificates().toArray(new X509Certificate[0]);
            for (X509Certificate cert : chain) {
                try {
                    if (!skipValidityCheckForClientCert) {
                        cert.checkValidity();
                    }
                    TbLwM2MSecurityInfo securityInfo = null;
                    if (staticCertificateVerifier != null) {
                        HandshakeException exception = staticCertificateVerifier.verifyCertificate(cid, serverName, remotePeer, clientUsage, verifySubject, truncateCertificatePath, message).getException();
                        if (exception == null) {
                            try {
                                String endpoint = config.getTrustSslCredentials().getValueFromSubjectNameByKey(cert.getSubjectX500Principal().getName(), "CN");
                                if (StringUtils.isNotEmpty(endpoint)) {
                                    securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(endpoint, CLIENT);
                                }
                            } catch (LwM2MAuthException e) {
                                log.trace("Certificate trust validation failed.", e);
                            }
                        } else {
                            log.trace("Certificate trust validation failed.", exception);
                        }
                    }
                    // if not trust or cert trust securityInfo == null
                    String strCert = SslUtil.getCertificateString(cert);
                    String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
                    if (securityInfo == null || securityInfo.getMsg() == null) {
                        try {
                            securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(sha3Hash, CLIENT);
                        } catch (LwM2MAuthException e) {
                            log.trace("Failed find security info: {}", sha3Hash, e);
                        }
                    }
                    ValidateDeviceCredentialsResponse msg = securityInfo != null ? securityInfo.getMsg() : null;
                    if (msg != null && StringUtils.isNotEmpty(msg.getCredentials())) {
                        LwM2MClientCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MClientCredentials.class);
                        if (!credentials.getClient().getSecurityConfigClientMode().equals(LwM2MSecurityMode.X509)) {
                            continue;
                        }
                        X509ClientCredential config = (X509ClientCredential) credentials.getClient();
                        String certBody = config.getCert();
                        String endpoint = config.getEndpoint();
                        if (StringUtils.isBlank(certBody) || strCert.equals(certBody)) {
                            x509CredentialsFound = true;
                            DeviceProfile deviceProfile = msg.getDeviceProfile();
                            if (msg.hasDeviceInfo() && deviceProfile != null) {
                                sessionStorage.put(endpoint, new TbX509DtlsSessionInfo(cert.getSubjectX500Principal().getName(), msg));
                                try {
                                    securityStore.putX509(securityInfo);
                                } catch (NonUniqueSecurityInfoException e) {
                                    log.trace("Failed to add security info: {}", securityInfo, e);
                                }
                                break;
                            }
                        } else {
                            log.trace("[{}][{}] Certificate mismatch. Expected: {}, Actual: {}", endpoint, sha3Hash, strCert, certBody);
                        }
                    }
                } catch (CertificateEncodingException | CertificateExpiredException | CertificateNotYetValidException e) {
                    log.error(e.getMessage(), e);
                }
            }
            if (!x509CredentialsFound) {
                AlertMessage alert = new AlertMessage(AlertMessage.AlertLevel.FATAL, AlertMessage.AlertDescription.INTERNAL_ERROR);
                throw new HandshakeException("x509 verification not enabled!", alert);
            }
            return new CertificateVerificationResult(cid, certChain, null);
        } catch (HandshakeException e) {
            log.trace("Certificate validation failed!", e);
            return new CertificateVerificationResult(cid, e, null);
        }
    }
}
Also used : CertificateNotYetValidException(java.security.cert.CertificateNotYetValidException) CertificateExpiredException(java.security.cert.CertificateExpiredException) PublicKey(java.security.PublicKey) LwM2MAuthException(org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException) CertificateEncodingException(java.security.cert.CertificateEncodingException) X509Certificate(java.security.cert.X509Certificate) CertificateVerificationResult(org.eclipse.californium.scandium.dtls.CertificateVerificationResult) X509ClientCredential(org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential) DeviceProfile(org.thingsboard.server.common.data.DeviceProfile) NonUniqueSecurityInfoException(org.eclipse.leshan.server.security.NonUniqueSecurityInfoException) LwM2MClientCredentials(org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MClientCredentials) CertPath(java.security.cert.CertPath) HandshakeException(org.eclipse.californium.scandium.dtls.HandshakeException) ValidateDeviceCredentialsResponse(org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse) AlertMessage(org.eclipse.californium.scandium.dtls.AlertMessage)

Example 2 with X509ClientCredential

use of org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential in project thingsboard by thingsboard.

the class X509_NoTrustLwM2MIntegrationTest method testWithX509NoTrustConnectLwm2mSuccess.

// Lwm2m only
@Test
public void testWithX509NoTrustConnectLwm2mSuccess() throws Exception {
    String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO;
    X509Certificate certificate = clientX509CertTrustNo;
    PrivateKey privateKey = clientPrivateKeyFromCertTrustNo;
    X509ClientCredential clientCredentials = new X509ClientCredential();
    clientCredentials.setEndpoint(clientEndpoint);
    clientCredentials.setCert(Base64Utils.encodeToString(certificate.getEncoded()));
    Security security = x509(SECURE_URI, shortServerId, certificate.getEncoded(), privateKey.getEncoded(), serverX509Cert.getEncoded());
    Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE));
    LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false);
    this.basicTestConnection(security, deviceCredentials, COAP_CONFIG, clientEndpoint, transportConfiguration, "await on client state (X509_Trust_Lwm2m)", expectedStatusesRegistrationLwm2mSuccess, false, ON_REGISTRATION_SUCCESS, true);
}
Also used : PrivateKey(java.security.PrivateKey) LwM2MDeviceCredentials(org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials) Lwm2mDeviceProfileTransportConfiguration(org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration) Security(org.eclipse.leshan.client.object.Security) X509Certificate(java.security.cert.X509Certificate) X509ClientCredential(org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential) Test(org.junit.Test) AbstractSecurityLwM2MIntegrationTest(org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest)

Example 3 with X509ClientCredential

use of org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential in project thingsboard by thingsboard.

the class X509_NoTrustLwM2MIntegrationTest method testWithX509NoTrustValidationPrivateKeyBase64format_BAD_REQUEST.

@Test
public void testWithX509NoTrustValidationPrivateKeyBase64format_BAD_REQUEST() throws Exception {
    String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO + "BadPrivateKey";
    X509Certificate certificate = clientX509CertTrustNo;
    PrivateKey privateKey = clientPrivateKeyFromCertTrustNo;
    X509ClientCredential clientCredentials = new X509ClientCredential();
    clientCredentials.setEndpoint(clientEndpoint);
    clientCredentials.setCert(Base64Utils.encodeToString(certificate.getEncoded()));
    Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE));
    LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, true);
    createDeviceProfile(transportConfiguration);
    MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint);
    assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus());
    String msgExpected = "Bootstrap server client X509 secret key must be in PKCS#8 format (DER encoding, standard [RFC5958]) and then encoded to Base64 format!";
    assertTrue(result.getResponse().getContentAsString().contains(msgExpected));
}
Also used : PrivateKey(java.security.PrivateKey) LwM2MDeviceCredentials(org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials) Lwm2mDeviceProfileTransportConfiguration(org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration) MvcResult(org.springframework.test.web.servlet.MvcResult) X509Certificate(java.security.cert.X509Certificate) X509ClientCredential(org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential) Test(org.junit.Test) AbstractSecurityLwM2MIntegrationTest(org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest)

Example 4 with X509ClientCredential

use of org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential in project thingsboard by thingsboard.

the class X509_NoTrustLwM2MIntegrationTest method testWithX509NoTrustValidationPublicKeyBase64format_BAD_REQUEST.

@Test
public void testWithX509NoTrustValidationPublicKeyBase64format_BAD_REQUEST() throws Exception {
    String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO + "BadPublicKey";
    X509Certificate certificate = clientX509CertTrustNo;
    PrivateKey privateKey = clientPrivateKeyFromCertTrustNo;
    X509ClientCredential clientCredentials = new X509ClientCredential();
    clientCredentials.setEndpoint(clientEndpoint);
    clientCredentials.setCert(Hex.encodeHexString(certificate.getEncoded()));
    Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, NONE));
    LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false);
    createDeviceProfile(transportConfiguration);
    MvcResult result = createDeviceWithMvcResult(deviceCredentials, clientEndpoint);
    assertEquals(HttpServletResponse.SC_BAD_REQUEST, result.getResponse().getStatus());
    String msgExpected = "LwM2M client X509 certificate must be in DER-encoded X509v3 format and support only EC algorithm and then encoded to Base64 format!";
    assertTrue(result.getResponse().getContentAsString().contains(msgExpected));
}
Also used : PrivateKey(java.security.PrivateKey) LwM2MDeviceCredentials(org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials) Lwm2mDeviceProfileTransportConfiguration(org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration) MvcResult(org.springframework.test.web.servlet.MvcResult) X509Certificate(java.security.cert.X509Certificate) X509ClientCredential(org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential) Test(org.junit.Test) AbstractSecurityLwM2MIntegrationTest(org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest)

Example 5 with X509ClientCredential

use of org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential in project thingsboard by thingsboard.

the class X509_NoTrustLwM2MIntegrationTest method testWithX509NoTrustConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess.

// Bootstrap + Lwm2m
@Test
public void testWithX509NoTrustConnectBsSuccess_UpdateTwoSectionsBootstrapAndLm2m_ConnectLwm2mSuccess() throws Exception {
    String clientEndpoint = CLIENT_ENDPOINT_X509_TRUST_NO;
    X509Certificate certificate = clientX509CertTrustNo;
    PrivateKey privateKey = clientPrivateKeyFromCertTrustNo;
    X509ClientCredential clientCredentials = new X509ClientCredential();
    clientCredentials.setEndpoint(clientEndpoint);
    clientCredentials.setCert(Base64Utils.encodeToString(certificate.getEncoded()));
    Security security = x509Bootstrap(SECURE_URI_BS, certificate.getEncoded(), privateKey.getEncoded(), serverX509CertBs.getEncoded());
    Lwm2mDeviceProfileTransportConfiguration transportConfiguration = getTransportConfiguration(OBSERVE_ATTRIBUTES_WITHOUT_PARAMS, getBootstrapServerCredentialsSecure(X509, BOTH));
    LwM2MDeviceCredentials deviceCredentials = getDeviceCredentialsSecure(clientCredentials, privateKey, certificate, X509, false);
    this.basicTestConnection(security, deviceCredentials, COAP_CONFIG_BS, clientEndpoint, transportConfiguration, "await on client state (X509NoTrust two section)", expectedStatusesRegistrationBsSuccess, true, ON_REGISTRATION_SUCCESS, true);
}
Also used : PrivateKey(java.security.PrivateKey) LwM2MDeviceCredentials(org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials) Lwm2mDeviceProfileTransportConfiguration(org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration) Security(org.eclipse.leshan.client.object.Security) X509Certificate(java.security.cert.X509Certificate) X509ClientCredential(org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential) Test(org.junit.Test) AbstractSecurityLwM2MIntegrationTest(org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest)

Aggregations

X509ClientCredential (org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential)9 X509Certificate (java.security.cert.X509Certificate)7 LwM2MDeviceCredentials (org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MDeviceCredentials)7 PrivateKey (java.security.PrivateKey)6 Test (org.junit.Test)6 Lwm2mDeviceProfileTransportConfiguration (org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration)6 AbstractSecurityLwM2MIntegrationTest (org.thingsboard.server.transport.lwm2m.security.AbstractSecurityLwM2MIntegrationTest)6 Security (org.eclipse.leshan.client.object.Security)4 MvcResult (org.springframework.test.web.servlet.MvcResult)2 DeviceCredentialsValidationException (org.thingsboard.server.dao.exception.DeviceCredentialsValidationException)2 Validator.validateString (org.thingsboard.server.dao.service.Validator.validateString)2 PublicKey (java.security.PublicKey)1 CertPath (java.security.cert.CertPath)1 CertificateEncodingException (java.security.cert.CertificateEncodingException)1 CertificateExpiredException (java.security.cert.CertificateExpiredException)1 CertificateNotYetValidException (java.security.cert.CertificateNotYetValidException)1 AlertMessage (org.eclipse.californium.scandium.dtls.AlertMessage)1 CertificateVerificationResult (org.eclipse.californium.scandium.dtls.CertificateVerificationResult)1 HandshakeException (org.eclipse.californium.scandium.dtls.HandshakeException)1 NonUniqueSecurityInfoException (org.eclipse.leshan.server.security.NonUniqueSecurityInfoException)1