Search in sources :

Example 1 with TbLwM2MSecurityInfo

use of org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo 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 TbLwM2MSecurityInfo

use of org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo in project thingsboard by thingsboard.

the class LwM2mClientContextImpl method register.

@Override
public Optional<TransportProtos.SessionInfoProto> register(LwM2mClient client, Registration registration) throws LwM2MClientStateException {
    TransportProtos.SessionInfoProto oldSession;
    client.lock();
    try {
        if (LwM2MClientState.UNREGISTERED.equals(client.getState())) {
            throw new LwM2MClientStateException(client.getState(), "Client is in invalid state.");
        }
        oldSession = client.getSession();
        TbLwM2MSecurityInfo securityInfo = securityStore.getTbLwM2MSecurityInfoByEndpoint(client.getEndpoint());
        if (securityInfo.getSecurityMode() != null) {
            if (SecurityMode.X509.equals(securityInfo.getSecurityMode())) {
                securityStore.registerX509(registration.getEndpoint(), registration.getId());
            }
            if (securityInfo.getDeviceProfile() != null) {
                profileUpdate(securityInfo.getDeviceProfile());
                if (securityInfo.getSecurityInfo() != null) {
                    client.init(securityInfo.getMsg(), UUID.randomUUID());
                } else if (NO_SEC.equals(securityInfo.getSecurityMode())) {
                    client.init(securityInfo.getMsg(), UUID.randomUUID());
                } else {
                    throw new RuntimeException(String.format("Registration failed: device %s not found.", client.getEndpoint()));
                }
            } else {
                throw new RuntimeException(String.format("Registration failed: device %s not found.", client.getEndpoint()));
            }
        } else {
            throw new RuntimeException(String.format("Registration failed: FORBIDDEN, endpointId: %s", client.getEndpoint()));
        }
        client.setRegistration(registration);
        this.lwM2mClientsByRegistrationId.put(registration.getId(), client);
        client.setState(LwM2MClientState.REGISTERED);
        onUplink(client);
        if (!compareAndSetSleepFlag(client, false)) {
            clientStore.put(client);
        }
    } finally {
        client.unlock();
    }
    return Optional.ofNullable(oldSession);
}
Also used : TbLwM2MSecurityInfo(org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo) TransportProtos(org.thingsboard.server.gen.transport.TransportProtos)

Example 3 with TbLwM2MSecurityInfo

use of org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo in project thingsboard by thingsboard.

the class TbInMemorySecurityStore method put.

@Override
public void put(TbLwM2MSecurityInfo tbSecurityInfo) throws NonUniqueSecurityInfoException {
    writeLock.lock();
    try {
        String identity = null;
        if (tbSecurityInfo.getSecurityInfo() != null) {
            identity = tbSecurityInfo.getSecurityInfo().getIdentity();
            if (identity != null) {
                TbLwM2MSecurityInfo infoByIdentity = securityByIdentity.get(identity);
                if (infoByIdentity != null && !tbSecurityInfo.getSecurityInfo().getEndpoint().equals(infoByIdentity.getEndpoint())) {
                    throw new NonUniqueSecurityInfoException("PSK Identity " + identity + " is already used");
                }
                securityByIdentity.put(tbSecurityInfo.getSecurityInfo().getIdentity(), tbSecurityInfo);
            }
        }
        TbLwM2MSecurityInfo previous = securityByEp.put(tbSecurityInfo.getEndpoint(), tbSecurityInfo);
        if (previous != null && previous.getSecurityInfo() != null) {
            String previousIdentity = previous.getSecurityInfo().getIdentity();
            if (previousIdentity != null && !previousIdentity.equals(identity)) {
                securityByIdentity.remove(previousIdentity);
            }
        }
    } finally {
        writeLock.unlock();
    }
}
Also used : NonUniqueSecurityInfoException(org.eclipse.leshan.server.security.NonUniqueSecurityInfoException) TbLwM2MSecurityInfo(org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo)

Example 4 with TbLwM2MSecurityInfo

use of org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo in project thingsboard by thingsboard.

the class TbLwM2mRedisSecurityStore method getByEndpoint.

@Override
public SecurityInfo getByEndpoint(String endpoint) {
    Lock lock = null;
    try (var connection = connectionFactory.getConnection()) {
        lock = redisLock.obtain(toLockKey(endpoint));
        lock.lock();
        byte[] data = connection.get((SEC_EP + endpoint).getBytes());
        if (data == null || data.length == 0) {
            return null;
        } else {
            if (SecurityMode.NO_SEC.equals(((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityMode())) {
                return SecurityInfo.newPreSharedKeyInfo(SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString(), SecurityMode.NO_SEC.toString().getBytes());
            } else {
                return ((TbLwM2MSecurityInfo) serializer.asObject(data)).getSecurityInfo();
            }
        }
    } finally {
        if (lock != null) {
            lock.unlock();
        }
    }
}
Also used : TbLwM2MSecurityInfo(org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo) Lock(java.util.concurrent.locks.Lock)

Example 5 with TbLwM2MSecurityInfo

use of org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo in project thingsboard by thingsboard.

the class TbLwM2mRedisSecurityStore method getTbLwM2MSecurityInfoByEndpoint.

@Override
public TbLwM2MSecurityInfo getTbLwM2MSecurityInfoByEndpoint(String endpoint) {
    Lock lock = null;
    try (var connection = connectionFactory.getConnection()) {
        lock = redisLock.obtain(endpoint);
        lock.lock();
        byte[] data = connection.get((SEC_EP + endpoint).getBytes());
        if (data != null && data.length > 0) {
            return (TbLwM2MSecurityInfo) serializer.asObject(data);
        } else {
            return null;
        }
    } finally {
        if (lock != null) {
            lock.unlock();
        }
    }
}
Also used : TbLwM2MSecurityInfo(org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo) Lock(java.util.concurrent.locks.Lock)

Aggregations

TbLwM2MSecurityInfo (org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo)13 Lock (java.util.concurrent.locks.Lock)5 SecurityInfo (org.eclipse.leshan.server.security.SecurityInfo)4 LwM2MAuthException (org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException)3 BootstrapConfig (org.eclipse.leshan.server.bootstrap.BootstrapConfig)2 InvalidConfigurationException (org.eclipse.leshan.server.bootstrap.InvalidConfigurationException)2 NonUniqueSecurityInfoException (org.eclipse.leshan.server.security.NonUniqueSecurityInfoException)2 TransportProtos (org.thingsboard.server.gen.transport.TransportProtos)2 LwM2MBootstrapConfig (org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapConfig)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 X509Certificate (java.security.cert.X509Certificate)1 Collections (java.util.Collections)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1