lwm2m validate trust certs
This commit is contained in:
		
							parent
							
								
									c655b58977
								
							
						
					
					
						commit
						ec602248c0
					
				@ -50,13 +50,22 @@ import org.thingsboard.server.transport.lwm2m.server.store.TbMainSecurityStore;
 | 
			
		||||
 | 
			
		||||
import javax.annotation.PostConstruct;
 | 
			
		||||
import javax.security.auth.x500.X500Principal;
 | 
			
		||||
import java.security.InvalidAlgorithmParameterException;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.PublicKey;
 | 
			
		||||
import java.security.cert.CertPath;
 | 
			
		||||
import java.security.cert.CertPathValidator;
 | 
			
		||||
import java.security.cert.CertPathValidatorException;
 | 
			
		||||
import java.security.cert.CertificateEncodingException;
 | 
			
		||||
import java.security.cert.CertificateException;
 | 
			
		||||
import java.security.cert.CertificateExpiredException;
 | 
			
		||||
import java.security.cert.CertificateFactory;
 | 
			
		||||
import java.security.cert.CertificateNotYetValidException;
 | 
			
		||||
import java.security.cert.PKIXParameters;
 | 
			
		||||
import java.security.cert.TrustAnchor;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.CLIENT;
 | 
			
		||||
@ -119,8 +128,8 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer
 | 
			
		||||
 | 
			
		||||
                        TbLwM2MSecurityInfo securityInfo = null;
 | 
			
		||||
                        // verify if trust
 | 
			
		||||
                        if (config.getTrustSslCredentials().getTrustedCertificates().length > 0) {
 | 
			
		||||
                            if (verifyIssuer(cert, config.getTrustSslCredentials().getTrustedCertificates()) != null) {
 | 
			
		||||
                        if (config.getTrustSslCredentials() != null && config.getTrustSslCredentials().getTrustedCertificates().length > 0) {
 | 
			
		||||
                            if (verifyTrust(cert, config.getTrustSslCredentials().getTrustedCertificates()) != null) {
 | 
			
		||||
                                String endpoint = config.getTrustSslCredentials().getValueFromSubjectNameByKey(cert.getSubjectX500Principal().getName(), "CN");
 | 
			
		||||
                                securityInfo = StringUtils.isNotEmpty(endpoint) ? securityInfoValidator.getEndpointSecurityInfoByCredentialsId(endpoint, CLIENT) : null;
 | 
			
		||||
                            }
 | 
			
		||||
@ -193,31 +202,26 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private X509Certificate verifyIssuer(X509Certificate certificate, X509Certificate[] certificates) {
 | 
			
		||||
        String issuerCN = config.getTrustSslCredentials().getValueFromSubjectNameByKey(certificate.getIssuerX500Principal().getName(), "CN");
 | 
			
		||||
        if (!StringUtils.isBlank(issuerCN)) {
 | 
			
		||||
    private X509Certificate verifyTrust(X509Certificate certificate, X509Certificate[] certificates) {
 | 
			
		||||
        try {
 | 
			
		||||
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
 | 
			
		||||
            CertPath cp = cf.generateCertPath(Arrays.asList(new X509Certificate[]{certificate}));
 | 
			
		||||
            for (int index = 0; index < certificates.length; ++index) {
 | 
			
		||||
                X509Certificate trust = certificates[index];
 | 
			
		||||
                String trustCN = config.getTrustSslCredentials().getValueFromSubjectNameByKey(trust.getSubjectX500Principal().getName(), "CN");
 | 
			
		||||
                if (!StringUtils.isBlank(trustCN) && issuerCN.length() >= trustCN.length() && issuerCN.substring(issuerCN.length()-trustCN.length()).equals(trustCN)) {
 | 
			
		||||
                    if (verifyCertificate(certificate)) {
 | 
			
		||||
                        return certificate;
 | 
			
		||||
                    }
 | 
			
		||||
                X509Certificate caCert = certificates[index];
 | 
			
		||||
                try {
 | 
			
		||||
                    TrustAnchor trustAnchor = new TrustAnchor(caCert, null);
 | 
			
		||||
                    CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
 | 
			
		||||
                    PKIXParameters pkixParams = new PKIXParameters(
 | 
			
		||||
                            Collections.singleton(trustAnchor));
 | 
			
		||||
                    pkixParams.setRevocationEnabled(false);
 | 
			
		||||
                    if (cpv.validate(cp, pkixParams) != null) return certificate;
 | 
			
		||||
                } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | CertPathValidatorException e) {
 | 
			
		||||
                    log.trace("[{}]. [{}]", certificate.getSubjectDN(), e.getMessage());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (CertificateException e) {
 | 
			
		||||
            log.trace("[{}] certPath not valid. [{}]", certificate.getSubjectDN(), e.getMessage());
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static boolean verifyCertificate(X509Certificate certificate) {
 | 
			
		||||
        try {
 | 
			
		||||
            // date
 | 
			
		||||
            certificate.checkValidity();
 | 
			
		||||
            // Validate X509.
 | 
			
		||||
            SecurityUtil.certificate.decode(certificate.getEncoded());
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -61,7 +61,7 @@ public abstract class AbstractSslCredentials implements SslCredentials {
 | 
			
		||||
            this.keyPasswordArray = keyPassword.toCharArray();
 | 
			
		||||
        }
 | 
			
		||||
        this.keyStore = this.loadKeyStore(trustsOnly, this.keyPasswordArray);
 | 
			
		||||
        Set<X509Certificate> trustedCerts = getTrustedCerts(this.keyStore);
 | 
			
		||||
        Set<X509Certificate> trustedCerts = getTrustedCerts(this.keyStore, trustsOnly);
 | 
			
		||||
        this.trusts = trustedCerts.toArray(new X509Certificate[0]);
 | 
			
		||||
        if (!trustsOnly) {
 | 
			
		||||
            PrivateKeyEntry privateKeyEntry = null;
 | 
			
		||||
@ -179,7 +179,7 @@ public abstract class AbstractSslCredentials implements SslCredentials {
 | 
			
		||||
        return entry;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Set<X509Certificate> getTrustedCerts(KeyStore ks) {
 | 
			
		||||
    private static Set<X509Certificate> getTrustedCerts(KeyStore ks, boolean trustsOnly) {
 | 
			
		||||
        Set<X509Certificate> set = new HashSet<>();
 | 
			
		||||
        try {
 | 
			
		||||
            for (Enumeration<String> e = ks.aliases(); e.hasMoreElements(); ) {
 | 
			
		||||
@ -187,19 +187,33 @@ public abstract class AbstractSslCredentials implements SslCredentials {
 | 
			
		||||
                if (ks.isCertificateEntry(alias)) {
 | 
			
		||||
                    Certificate cert = ks.getCertificate(alias);
 | 
			
		||||
                    if (cert instanceof X509Certificate) {
 | 
			
		||||
                        set.add((X509Certificate)cert);
 | 
			
		||||
                        if (trustsOnly) {
 | 
			
		||||
                            // is CA certificate
 | 
			
		||||
                            if (((X509Certificate) cert).getBasicConstraints()>=0) {
 | 
			
		||||
                                set.add((X509Certificate) cert);
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            set.add((X509Certificate) cert);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (ks.isKeyEntry(alias)) {
 | 
			
		||||
                    Certificate[] certs = ks.getCertificateChain(alias);
 | 
			
		||||
                    if ((certs != null) && (certs.length > 0) &&
 | 
			
		||||
                            (certs[0] instanceof X509Certificate)) {
 | 
			
		||||
                        set.add((X509Certificate)certs[0]);
 | 
			
		||||
                        if (trustsOnly) {
 | 
			
		||||
                            for (Certificate cert : certs) {
 | 
			
		||||
                                // is CA certificate
 | 
			
		||||
                                if (((X509Certificate) cert).getBasicConstraints()>=0) {
 | 
			
		||||
                                    set.add((X509Certificate) cert);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            set.add((X509Certificate)certs[0]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (KeyStoreException ignored) {}
 | 
			
		||||
        return Collections.unmodifiableSet(set);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user