Merge pull request #5619 from thingsboard/lwm2m_cert_trust
[3.3.3] lwm2m - trust Certificate
This commit is contained in:
commit
bfd206fa5b
@ -161,7 +161,7 @@ public abstract class AbstractSecurityLwM2MIntegrationTest extends AbstractLwM2M
|
||||
rootCAX509Cert = (X509Certificate) serverKeyStore.getCertificate("rootCA");
|
||||
serverX509Cert = (X509Certificate) serverKeyStore.getCertificate("server");
|
||||
serverX509CertSelfSigned = (X509Certificate) serverKeyStore.getCertificate("server_self_signed");
|
||||
trustedCertificates[0] = rootCAX509Cert;
|
||||
trustedCertificates[0] = serverX509Cert;
|
||||
} catch (GeneralSecurityException | IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@ -29,11 +29,13 @@ import org.eclipse.californium.scandium.dtls.HandshakeResultHandler;
|
||||
import org.eclipse.californium.scandium.dtls.x509.NewAdvancedCertificateVerifier;
|
||||
import org.eclipse.californium.scandium.dtls.x509.StaticCertificateVerifier;
|
||||
import org.eclipse.californium.scandium.util.ServerNames;
|
||||
import org.eclipse.leshan.core.util.SecurityUtil;
|
||||
import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.common.util.JacksonUtil;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.StringUtils;
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.LwM2MSecurityMode;
|
||||
import org.thingsboard.server.common.data.device.credentials.lwm2m.X509ClientCredential;
|
||||
import org.thingsboard.server.common.msg.EncryptionUtil;
|
||||
@ -114,13 +116,24 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer
|
||||
cert.checkValidity();
|
||||
}
|
||||
|
||||
|
||||
TbLwM2MSecurityInfo securityInfo = null;
|
||||
// verify if trust
|
||||
if (config.getTrustSslCredentials().getTrustedCertificates().length > 0) {
|
||||
if (searchIssuer(cert, config.getTrustSslCredentials().getTrustedCertificates()) != null) {
|
||||
String endpoint = config.getTrustSslCredentials().getValueFromSubjectNameByKey(cert.getSubjectX500Principal().getName(), "CN");
|
||||
securityInfo = StringUtils.isNotEmpty(endpoint) ? securityInfoValidator.getEndpointSecurityInfoByCredentialsId(endpoint, CLIENT) : null;
|
||||
}
|
||||
}
|
||||
// if not trust or cert trust securityInfo == null
|
||||
String strCert = SslUtil.getCertificateString(cert);
|
||||
String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
|
||||
TbLwM2MSecurityInfo securityInfo;
|
||||
try {
|
||||
securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(sha3Hash, CLIENT);
|
||||
} catch (LwM2MAuthException e) {
|
||||
securityInfo = null;
|
||||
if (securityInfo == 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 && org.thingsboard.server.common.data.StringUtils.isNotEmpty(msg.getCredentials())) {
|
||||
@ -131,7 +144,7 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer
|
||||
X509ClientCredential config = (X509ClientCredential) credentials.getClient();
|
||||
String certBody = config.getCert();
|
||||
String endpoint = config.getEndpoint();
|
||||
if (strCert.equals(certBody)) {
|
||||
if (StringUtils.isBlank(certBody) || strCert.equals(certBody)) {
|
||||
x509CredentialsFound = true;
|
||||
DeviceProfile deviceProfile = msg.getDeviceProfile();
|
||||
if (msg.hasDeviceInfo() && deviceProfile != null) {
|
||||
@ -179,4 +192,29 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer
|
||||
public void setResultHandler(HandshakeResultHandler resultHandler) {
|
||||
|
||||
}
|
||||
|
||||
private static X509Certificate searchIssuer(X509Certificate certificate, X509Certificate[] certificates) {
|
||||
X500Principal subject = certificate.getIssuerX500Principal();
|
||||
for (int index = 0; index < certificates.length; ++index) {
|
||||
X509Certificate trust = certificates[index];
|
||||
if (trust != null && subject.equals(trust.getIssuerX500Principal())) {
|
||||
if (verifyCertificate(certificate)) {
|
||||
return certificate;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,9 +31,11 @@ import java.security.UnrecoverableEntryException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class AbstractSslCredentials implements SslCredentials {
|
||||
@ -113,6 +115,7 @@ public abstract class AbstractSslCredentials implements SslCredentials {
|
||||
return this.trusts;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TrustManagerFactory createTrustManagerFactory() throws NoSuchAlgorithmException, KeyStoreException {
|
||||
TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
@ -127,6 +130,15 @@ public abstract class AbstractSslCredentials implements SslCredentials {
|
||||
return kmf;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getValueFromSubjectNameByKey(String subjectName, String key) {
|
||||
String[] dns = subjectName.split(",");
|
||||
Optional<String> cn = (Arrays.stream(dns).filter(dn -> dn.contains(key + "="))).findFirst();
|
||||
String value = cn.isPresent() ? cn.get().replace(key + "=", "") : null;
|
||||
return StringUtils.isNotEmpty(value) ? value : null;
|
||||
}
|
||||
|
||||
protected abstract boolean canUse();
|
||||
|
||||
protected abstract KeyStore loadKeyStore(boolean isPrivateKeyRequired, char[] keyPasswordArray) throws IOException, GeneralSecurityException;
|
||||
|
||||
@ -49,4 +49,5 @@ public interface SslCredentials {
|
||||
|
||||
KeyManagerFactory createKeyManagerFactory() throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException;
|
||||
|
||||
String getValueFromSubjectNameByKey(String subjectName, String key);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user