Search in sources :

Example 1 with LwM2MAuthException

use of org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException in project thingsboard by thingsboard.

the class TbLwM2MDtlsBootstrapCertificateVerifier 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;
                    // verify if trust
                    if (staticCertificateVerifier != null) {
                        HandshakeException exception = staticCertificateVerifier.verifyCertificate(cid, serverName, remotePeer, clientUsage, verifySubject, truncateCertificatePath, message).getException();
                        if (exception == null) {
                            String endpoint = config.getTrustSslCredentials().getValueFromSubjectNameByKey(cert.getSubjectX500Principal().getName(), "CN");
                            if (StringUtils.isNotEmpty(endpoint)) {
                                securityInfo = bsSecurityStore.getX509ByEndpoint(endpoint);
                            }
                        } else {
                            log.trace("Certificate validation failed.", exception);
                        }
                    }
                    // if not trust or cert trust securityInfo == null
                    if (securityInfo == null || securityInfo.getMsg() == null) {
                        String strCert = SslUtil.getCertificateString(cert);
                        String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
                        try {
                            securityInfo = bsSecurityStore.getX509ByEndpoint(sha3Hash);
                        } catch (LwM2MAuthException e) {
                            log.trace("Failed to find security info: [{}]", sha3Hash, e);
                        }
                    }
                    ValidateDeviceCredentialsResponse msg = securityInfo != null ? securityInfo.getMsg() : null;
                    if (msg != null && StringUtils.isNotEmpty(msg.getCredentials())) {
                        x509CredentialsFound = true;
                        break;
                    }
                } catch (CertificateEncodingException | CertificateExpiredException | CertificateNotYetValidException e) {
                    log.trace("Failed to find security info: [{}]", cert.getSubjectX500Principal().getName(), 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) TbLwM2MSecurityInfo(org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo) 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 LwM2MAuthException

use of org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException 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 3 with LwM2MAuthException

use of org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException in project thingsboard by thingsboard.

the class LwM2mCredentialsSecurityInfoValidator method getEndpointSecurityInfoByCredentialsId.

public TbLwM2MSecurityInfo getEndpointSecurityInfoByCredentialsId(String credentialsId, LwM2mTypeServer keyValue) {
    CountDownLatch latch = new CountDownLatch(1);
    final TbLwM2MSecurityInfo[] resultSecurityStore = new TbLwM2MSecurityInfo[1];
    log.trace("Validating credentials [{}]", credentialsId);
    context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(credentialsId).build(), new TransportServiceCallback<>() {

        @Override
        public void onSuccess(ValidateDeviceCredentialsResponse msg) {
            log.trace("Validated credentials: [{}] [{}]", credentialsId, msg);
            resultSecurityStore[0] = createSecurityInfo(credentialsId, msg, keyValue);
            latch.countDown();
        }

        @Override
        public void onError(Throwable e) {
            log.trace("[{}] [{}] Failed to process credentials ", credentialsId, e);
            TbLwM2MSecurityInfo result = new TbLwM2MSecurityInfo();
            result.setEndpoint(credentialsId);
            resultSecurityStore[0] = result;
            latch.countDown();
        }
    });
    try {
        latch.await(config.getTimeout(), TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
        log.error("Failed to await credentials!", e);
    }
    TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0];
    if (securityInfo.getSecurityMode() == null) {
        throw new LwM2MAuthException();
    }
    return securityInfo;
}
Also used : LwM2MAuthException(org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException) CountDownLatch(java.util.concurrent.CountDownLatch) ValidateDeviceCredentialsResponse(org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse)

Example 4 with LwM2MAuthException

use of org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException in project thingsboard by thingsboard.

the class LwM2MBootstrapSecurityStore method getByIdentity.

@Override
public SecurityInfo getByIdentity(String identity) {
    try {
        TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(identity, BOOTSTRAP);
        if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
            /* add value to store  from BootstrapJson */
            this.setBootstrapConfigSecurityInfo(store);
            BootstrapConfig bsConfig = store.getBootstrapConfig();
            if (bsConfig.security != null) {
                try {
                    bootstrapConfigStore.add(store.getEndpoint(), bsConfig);
                } catch (InvalidConfigurationException e) {
                    log.trace("Invalid Bootstrap Configuration", e);
                    return null;
                }
            }
        }
        return store.getSecurityInfo();
    } catch (LwM2MAuthException e) {
        log.trace("Bootstrap Registration failed: No pre-shared key found for [identity: {}]", identity);
        return null;
    }
}
Also used : TbLwM2MSecurityInfo(org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo) BootstrapConfig(org.eclipse.leshan.server.bootstrap.BootstrapConfig) LwM2MBootstrapConfig(org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig) LwM2MAuthException(org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException) InvalidConfigurationException(org.eclipse.leshan.server.bootstrap.InvalidConfigurationException)

Example 5 with LwM2MAuthException

use of org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException in project thingsboard by thingsboard.

the class LwM2mDefaultBootstrapSessionManager method begin.

@Override
public BootstrapSession begin(BootstrapRequest request, Identity clientIdentity) {
    boolean authorized = true;
    Iterator<SecurityInfo> securityInfos = null;
    try {
        if (bsSecurityStore != null && securityChecker != null) {
            if (clientIdentity.isPSK()) {
                SecurityInfo securityInfo = bsSecurityStore.getByIdentity(clientIdentity.getPskIdentity());
                securityInfos = Collections.singletonList(securityInfo).iterator();
            } else if (!clientIdentity.isX509()) {
                securityInfos = bsSecurityStore.getAllByEndpoint(request.getEndpointName());
            }
            authorized = this.checkSecurityInfo(request.getEndpointName(), clientIdentity, securityInfos);
        }
    } catch (LwM2MAuthException e) {
        authorized = false;
    }
    DefaultBootstrapSession session = new DefaultBootstrapSession(request, clientIdentity, authorized);
    if (authorized) {
        this.sendLogs(request.getEndpointName(), String.format("%s: Bootstrap session started...", LOG_LWM2M_INFO, request.getEndpointName()));
    }
    return session;
}
Also used : DefaultBootstrapSession(org.eclipse.leshan.server.bootstrap.DefaultBootstrapSession) LwM2MAuthException(org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException) SecurityInfo(org.eclipse.leshan.server.security.SecurityInfo)

Aggregations

LwM2MAuthException (org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException)5 ValidateDeviceCredentialsResponse (org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse)3 PublicKey (java.security.PublicKey)2 CertPath (java.security.cert.CertPath)2 CertificateEncodingException (java.security.cert.CertificateEncodingException)2 CertificateExpiredException (java.security.cert.CertificateExpiredException)2 CertificateNotYetValidException (java.security.cert.CertificateNotYetValidException)2 X509Certificate (java.security.cert.X509Certificate)2 AlertMessage (org.eclipse.californium.scandium.dtls.AlertMessage)2 CertificateVerificationResult (org.eclipse.californium.scandium.dtls.CertificateVerificationResult)2 HandshakeException (org.eclipse.californium.scandium.dtls.HandshakeException)2 TbLwM2MSecurityInfo (org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo)2 CountDownLatch (java.util.concurrent.CountDownLatch)1 BootstrapConfig (org.eclipse.leshan.server.bootstrap.BootstrapConfig)1 DefaultBootstrapSession (org.eclipse.leshan.server.bootstrap.DefaultBootstrapSession)1 InvalidConfigurationException (org.eclipse.leshan.server.bootstrap.InvalidConfigurationException)1 NonUniqueSecurityInfoException (org.eclipse.leshan.server.security.NonUniqueSecurityInfoException)1 SecurityInfo (org.eclipse.leshan.server.security.SecurityInfo)1 DeviceProfile (org.thingsboard.server.common.data.DeviceProfile)1 X509ClientCredential (org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential)1