added SslUtil and tests
This commit is contained in:
parent
9d19a15413
commit
cf32544e71
@ -36,6 +36,14 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcpkix-jdk15on</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-core</artifactId>
|
<artifactId>spring-core</artifactId>
|
||||||
|
|||||||
@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2023 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.common.util;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||||
|
import org.bouncycastle.cert.X509CertificateHolder;
|
||||||
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.bouncycastle.openssl.PEMDecryptorProvider;
|
||||||
|
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
|
||||||
|
import org.bouncycastle.openssl.PEMKeyPair;
|
||||||
|
import org.bouncycastle.openssl.PEMParser;
|
||||||
|
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||||
|
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
|
||||||
|
import org.bouncycastle.operator.InputDecryptorProvider;
|
||||||
|
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
||||||
|
import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder;
|
||||||
|
import org.thingsboard.server.common.data.StringUtils;
|
||||||
|
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SslUtil {
|
||||||
|
|
||||||
|
public static final char[] EMPTY_PASS = {};
|
||||||
|
|
||||||
|
public static final BouncyCastleProvider DEFAULT_PROVIDER = new BouncyCastleProvider();
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
|
||||||
|
Security.addProvider(DEFAULT_PROVIDER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SslUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static List<X509Certificate> readCertFile(String fileContent) {
|
||||||
|
List<X509Certificate> certificates = new ArrayList<>();
|
||||||
|
JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
|
||||||
|
try (PEMParser pemParser = new PEMParser(new StringReader(fileContent))) {
|
||||||
|
Object object;
|
||||||
|
while ((object = pemParser.readObject()) != null) {
|
||||||
|
if (object instanceof X509CertificateHolder) {
|
||||||
|
X509Certificate x509Cert = certConverter.getCertificate((X509CertificateHolder) object);
|
||||||
|
certificates.add(x509Cert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return certificates;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static PrivateKey readPrivateKey(String fileContent, String passStr) {
|
||||||
|
char[] password = StringUtils.isEmpty(passStr) ? EMPTY_PASS : passStr.toCharArray();
|
||||||
|
|
||||||
|
PrivateKey privateKey = null;
|
||||||
|
JcaPEMKeyConverter keyConverter = new JcaPEMKeyConverter();
|
||||||
|
if (StringUtils.isNotEmpty(fileContent)) {
|
||||||
|
try (PEMParser pemParser = new PEMParser(new StringReader(fileContent))) {
|
||||||
|
Object object;
|
||||||
|
while ((object = pemParser.readObject()) != null) {
|
||||||
|
if (object instanceof PEMEncryptedKeyPair) {
|
||||||
|
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password);
|
||||||
|
privateKey = keyConverter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv)).getPrivate();
|
||||||
|
break;
|
||||||
|
} else if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
|
||||||
|
InputDecryptorProvider decProv =
|
||||||
|
new JcePKCSPBEInputDecryptorProviderBuilder().setProvider(DEFAULT_PROVIDER).build(password);
|
||||||
|
privateKey = keyConverter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decProv));
|
||||||
|
break;
|
||||||
|
} else if (object instanceof PEMKeyPair) {
|
||||||
|
privateKey = keyConverter.getKeyPair((PEMKeyPair) object).getPrivate();
|
||||||
|
break;
|
||||||
|
} else if (object instanceof PrivateKeyInfo) {
|
||||||
|
privateKey = keyConverter.getPrivateKey((PrivateKeyInfo) object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -20,35 +20,17 @@ import io.netty.handler.ssl.SslContext;
|
|||||||
import io.netty.handler.ssl.SslContextBuilder;
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
import org.thingsboard.common.util.SslUtil;
|
||||||
import org.bouncycastle.cert.X509CertificateHolder;
|
|
||||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
||||||
import org.bouncycastle.openssl.PEMDecryptorProvider;
|
|
||||||
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
|
|
||||||
import org.bouncycastle.openssl.PEMKeyPair;
|
|
||||||
import org.bouncycastle.openssl.PEMParser;
|
|
||||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
|
||||||
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
|
|
||||||
import org.bouncycastle.operator.InputDecryptorProvider;
|
|
||||||
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
|
||||||
import org.bouncycastle.pkcs.PKCSException;
|
|
||||||
import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder;
|
|
||||||
import org.thingsboard.server.common.data.StringUtils;
|
import org.thingsboard.server.common.data.StringUtils;
|
||||||
|
|
||||||
import javax.net.ssl.KeyManagerFactory;
|
import javax.net.ssl.KeyManagerFactory;
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.StringReader;
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.Security;
|
|
||||||
import java.security.cert.CertPath;
|
import java.security.cert.CertPath;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -61,16 +43,11 @@ public class CertPemCredentials implements ClientCredentials {
|
|||||||
public static final String X_509 = "X.509";
|
public static final String X_509 = "X.509";
|
||||||
public static final String CERT_ALIAS_PREFIX = "cert-";
|
public static final String CERT_ALIAS_PREFIX = "cert-";
|
||||||
public static final String CA_CERT_CERT_ALIAS_PREFIX = "caCert-cert-";
|
public static final String CA_CERT_CERT_ALIAS_PREFIX = "caCert-cert-";
|
||||||
|
|
||||||
protected String caCert;
|
protected String caCert;
|
||||||
private String cert;
|
private String cert;
|
||||||
private String privateKey;
|
private String privateKey;
|
||||||
private String password;
|
private String password = "";
|
||||||
|
|
||||||
public CertPemCredentials() {
|
|
||||||
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
|
|
||||||
Security.addProvider(new BouncyCastleProvider());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CredentialsType getType() {
|
public CredentialsType getType() {
|
||||||
@ -95,7 +72,7 @@ public class CertPemCredentials implements ClientCredentials {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected TrustManagerFactory createAndInitTrustManagerFactory() throws Exception {
|
protected TrustManagerFactory createAndInitTrustManagerFactory() throws Exception {
|
||||||
List<X509Certificate> caCerts = readCertFile(caCert);
|
List<X509Certificate> caCerts = SslUtil.readCertFile(caCert);
|
||||||
|
|
||||||
KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
KeyStore caKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
caKeyStore.load(null, null);
|
caKeyStore.load(null, null);
|
||||||
@ -108,15 +85,15 @@ public class CertPemCredentials implements ClientCredentials {
|
|||||||
return trustManagerFactory;
|
return trustManagerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected KeyManagerFactory createAndInitKeyManagerFactory() throws Exception {
|
private KeyManagerFactory createAndInitKeyManagerFactory() throws Exception {
|
||||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
|
||||||
kmf.init(loadKeyStore(), password.toCharArray());
|
kmf.init(loadKeyStore(), password.toCharArray());
|
||||||
return kmf;
|
return kmf;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyStore loadKeyStore() throws Exception {
|
protected KeyStore loadKeyStore() throws Exception {
|
||||||
List<X509Certificate> certificates = readCertFile(this.cert);
|
List<X509Certificate> certificates = SslUtil.readCertFile(this.cert);
|
||||||
PrivateKey privateKey = readPrivateKey(this.privateKey, this.password);
|
PrivateKey privateKey = SslUtil.readPrivateKey(this.privateKey, password);
|
||||||
|
|
||||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
keyStore.load(null);
|
keyStore.load(null);
|
||||||
@ -135,47 +112,4 @@ public class CertPemCredentials implements ClientCredentials {
|
|||||||
return keyStore;
|
return keyStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<X509Certificate> readCertFile(String fileContent) throws IOException, GeneralSecurityException {
|
|
||||||
List<X509Certificate> certificates = new ArrayList<>();
|
|
||||||
JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
|
|
||||||
try (PEMParser pemParser = new PEMParser(new StringReader(fileContent))) {
|
|
||||||
Object object;
|
|
||||||
while ((object = pemParser.readObject()) != null) {
|
|
||||||
if (object instanceof X509CertificateHolder) {
|
|
||||||
X509Certificate x509Cert = certConverter.getCertificate((X509CertificateHolder) object);
|
|
||||||
certificates.add(x509Cert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return certificates;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PrivateKey readPrivateKey(String fileContent, String password) throws IOException, PKCSException {
|
|
||||||
PrivateKey privateKey = null;
|
|
||||||
JcaPEMKeyConverter keyConverter = new JcaPEMKeyConverter();
|
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(fileContent)) {
|
|
||||||
try (PEMParser pemParser = new PEMParser(new StringReader(fileContent))) {
|
|
||||||
Object object;
|
|
||||||
while ((object = pemParser.readObject()) != null) {
|
|
||||||
if (object instanceof PEMEncryptedKeyPair) {
|
|
||||||
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
|
|
||||||
privateKey = keyConverter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(decProv)).getPrivate();
|
|
||||||
break;
|
|
||||||
} else if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
|
|
||||||
InputDecryptorProvider decProv =
|
|
||||||
new JcePKCSPBEInputDecryptorProviderBuilder().setProvider(new BouncyCastleProvider()).build(password.toCharArray());
|
|
||||||
privateKey = keyConverter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(decProv));
|
|
||||||
break;
|
|
||||||
} else if (object instanceof PEMKeyPair) {
|
|
||||||
privateKey = keyConverter.getKeyPair((PEMKeyPair) object).getPrivate();
|
|
||||||
break;
|
|
||||||
} else if (object instanceof PrivateKeyInfo) {
|
|
||||||
privateKey = keyConverter.getPrivateKey((PrivateKeyInfo) object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return privateKey;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,28 +22,32 @@ import org.junit.jupiter.api.Assertions;
|
|||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.thingsboard.common.util.SslUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.PrivateKey;
|
import java.security.Key;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class CertPemCredentialsTest {
|
import static org.thingsboard.rule.engine.credentials.CertPemCredentials.CERT_ALIAS_PREFIX;
|
||||||
|
import static org.thingsboard.rule.engine.credentials.CertPemCredentials.PRIVATE_KEY_ALIAS;
|
||||||
|
|
||||||
private final CertPemCredentials credentials = new CertPemCredentials();
|
public class CertPemCredentialsTest {
|
||||||
|
|
||||||
private static final String PASS = "test";
|
private static final String PASS = "test";
|
||||||
private static final String EMPTY_PASS = "";
|
private static final String EMPTY_PASS = "";
|
||||||
private static final String RSA = "RSA";
|
private static final String RSA = "RSA";
|
||||||
private static final String ECDSA = "ECDSA";
|
private static final String EC = "EC";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChainOfCertificates() throws Exception {
|
public void testChainOfCertificates() throws Exception {
|
||||||
String fileContent = fileContent("pem/tb-cloud-chain.pem");
|
String fileContent = fileContent("pem/tb-cloud-chain.pem");
|
||||||
|
|
||||||
List<X509Certificate> x509Certificates = credentials.readCertFile(fileContent);
|
List<X509Certificate> x509Certificates = SslUtil.readCertFile(fileContent);
|
||||||
|
|
||||||
Assert.assertEquals(4, x509Certificates.size());
|
Assert.assertEquals(4, x509Certificates.size());
|
||||||
Assert.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US",
|
Assert.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US",
|
||||||
@ -60,7 +64,7 @@ public class CertPemCredentialsTest {
|
|||||||
public void testSingleCertificate() throws Exception {
|
public void testSingleCertificate() throws Exception {
|
||||||
String fileContent = fileContent("pem/tb-cloud.pem");
|
String fileContent = fileContent("pem/tb-cloud.pem");
|
||||||
|
|
||||||
List<X509Certificate> x509Certificates = credentials.readCertFile(fileContent);
|
List<X509Certificate> x509Certificates = SslUtil.readCertFile(fileContent);
|
||||||
|
|
||||||
Assert.assertEquals(1, x509Certificates.size());
|
Assert.assertEquals(1, x509Certificates.size());
|
||||||
Assert.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US",
|
Assert.assertEquals("CN=*.thingsboard.cloud, O=\"ThingsBoard, Inc.\", ST=New York, C=US",
|
||||||
@ -71,26 +75,41 @@ public class CertPemCredentialsTest {
|
|||||||
public void testEmptyFileContent() throws Exception {
|
public void testEmptyFileContent() throws Exception {
|
||||||
String fileContent = fileContent("pem/empty.pem");
|
String fileContent = fileContent("pem/empty.pem");
|
||||||
|
|
||||||
List<X509Certificate> x509Certificates = credentials.readCertFile(fileContent);
|
List<X509Certificate> x509Certificates = SslUtil.readCertFile(fileContent);
|
||||||
|
|
||||||
Assert.assertEquals(0, x509Certificates.size());
|
Assert.assertEquals(0, x509Certificates.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<Arguments> testReadPrivateKey() {
|
private static Stream<Arguments> testLoadKeyStore() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
Arguments.of("pem/rsa_key.pem", EMPTY_PASS, RSA),
|
Arguments.of("pem/rsa_cert.pem", "pem/rsa_key.pem", EMPTY_PASS, RSA),
|
||||||
Arguments.of("pem/rsa_encrypted_key.pem", PASS, RSA),
|
Arguments.of("pem/rsa_encrypted_cert.pem", "pem/rsa_encrypted_key.pem", PASS, RSA),
|
||||||
Arguments.of("pem/rsa_encrypted_traditional_key.pem", PASS, RSA),
|
Arguments.of("pem/rsa_encrypted_traditional_cert.pem", "pem/rsa_encrypted_traditional_key.pem", PASS, RSA),
|
||||||
Arguments.of("pem/ec_key.pem", EMPTY_PASS, ECDSA)
|
Arguments.of("pem/ec_cert.pem", "pem/ec_key.pem", EMPTY_PASS, EC)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource
|
@MethodSource
|
||||||
public void testReadPrivateKey(String keyPath, String password, String algorithm) throws Exception {
|
public void testLoadKeyStore(String certPath, String keyPath, String password, String algorithm) throws Exception {
|
||||||
PrivateKey privateKey = credentials.readPrivateKey(fileContent(keyPath), password);
|
CertPemCredentials certPemCredentials = new CertPemCredentials();
|
||||||
Assertions.assertNotNull(privateKey);
|
String certContent = fileContent(certPath);
|
||||||
Assertions.assertEquals(algorithm, privateKey.getAlgorithm());
|
certPemCredentials.setCert(certContent);
|
||||||
|
certPemCredentials.setPrivateKey(fileContent(keyPath));
|
||||||
|
certPemCredentials.setPassword(password);
|
||||||
|
KeyStore keyStore = certPemCredentials.loadKeyStore();
|
||||||
|
Assertions.assertNotNull(keyStore);
|
||||||
|
Key key = keyStore.getKey(PRIVATE_KEY_ALIAS, password.toCharArray());
|
||||||
|
Assertions.assertNotNull(key);
|
||||||
|
Assertions.assertEquals(algorithm, key.getAlgorithm());
|
||||||
|
|
||||||
|
List<X509Certificate> certs = SslUtil.readCertFile(certContent);
|
||||||
|
for (X509Certificate cert : certs) {
|
||||||
|
String alias = CERT_ALIAS_PREFIX + cert.getIssuerDN().getName();
|
||||||
|
Certificate certificate = keyStore.getCertificate(alias);
|
||||||
|
Assertions.assertNotNull(certificate);
|
||||||
|
Assertions.assertEquals(new String(cert.getEncoded()), new String(certificate.getEncoded()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String fileContent(String fileName) throws IOException {
|
private String fileContent(String fileName) throws IOException {
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICCDCCAa2gAwIBAgIUGx/SZqIWza/i/gaKFUVIyTEu2oMwCgYIKoZIzj0EAwIw
|
||||||
|
WTELMAkGA1UEBhMCVUExDTALBgNVBAgMBEtZSVYxDTALBgNVBAcMBEtZSVYxCzAJ
|
||||||
|
BgNVBAoMAlRCMQswCQYDVQQLDAJUQjESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIz
|
||||||
|
MTAxNjEyMjMyMVoXDTI0MTAxNTEyMjMyMVowWTELMAkGA1UEBhMCVUExDTALBgNV
|
||||||
|
BAgMBEtZSVYxDTALBgNVBAcMBEtZSVYxCzAJBgNVBAoMAlRCMQswCQYDVQQLDAJU
|
||||||
|
QjESMBAGA1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
|
||||||
|
z4MgawieJfVc5zUOPiw5WFxfHGJf7dOMsHvudDxdOs27PXPbJfi09BVJ3+JjNxA2
|
||||||
|
wQz9KUk877oWRYrN/e+MbKNTMFEwHQYDVR0OBBYEFDTV8VD3m+8IBQOBJ+V/bcbl
|
||||||
|
4preMB8GA1UdIwQYMBaAFDTV8VD3m+8IBQOBJ+V/bcbl4preMA8GA1UdEwEB/wQF
|
||||||
|
MAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAOgIkl8j8m51W7pWlNUAuUnHnOVhVjGr
|
||||||
|
h8Rc6cbwTapKAiEA2CLrduTweXEF5fBRtWyOsG8c9af6+MWHKmwHL1IDw9Q=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDkzCCAnugAwIBAgIUKAylzm/K5OfbXSjm1zY9bX1a8HQwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwWTELMAkGA1UEBhMCVUExDTALBgNVBAgMBEtZSVYxDTALBgNVBAcMBEtZSVYx
|
||||||
|
CzAJBgNVBAoMAlRCMQswCQYDVQQLDAJUQjESMBAGA1UEAwwJbG9jYWxob3N0MB4X
|
||||||
|
DTIzMTAxNjIxMDQwNVoXDTI0MTAxNTIxMDQwNVowWTELMAkGA1UEBhMCVUExDTAL
|
||||||
|
BgNVBAgMBEtZSVYxDTALBgNVBAcMBEtZSVYxCzAJBgNVBAoMAlRCMQswCQYDVQQL
|
||||||
|
DAJUQjESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||||
|
MIIBCgKCAQEA87nLliszEWml8QvyAC+H80NZCxf4TcG826NBOp0AUPJ8xQBHCzc1
|
||||||
|
t1ohVm2/fn2VJZAYXG2xSVcHyXjjjv3iGLE2AIDbXh06/yFg4TVjlbrWrAHFehyN
|
||||||
|
FwrK8ez36oGLa3ZVq+mx1fLfBQw5mStbh09NXmKTzqP6m9ggKtt63cUwoWdUTemT
|
||||||
|
qrjryJd69LiJi+MVqtbKO2j30/lgAZmaHtbojl9EcvWfeXLb20TnXRIctaIS1VGo
|
||||||
|
SluzjbNQErdN/VRW4RAOP6UFsK0xID2EuLODBmAWnI49fXO/OS+u3Kd3suABE0o9
|
||||||
|
slfDXqNTp0r5N0OoSAFcc4EsV3+9Gf+mqwIDAQABo1MwUTAdBgNVHQ4EFgQUhS5K
|
||||||
|
XQDxGvaBCpKY1de+JZl8zjYwHwYDVR0jBBgwFoAUhS5KXQDxGvaBCpKY1de+JZl8
|
||||||
|
zjYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAxez4vLtBCBNM
|
||||||
|
l6AQghViNAR9iiwYMxUwKwlU+uZftRGnT+6dXgfTR3PV6LCfMMmtuNs0JTGy0ff8
|
||||||
|
erbzfZxExvHfIFXCwepwTWawQhvRRn9GHOJXIzESDRRhsXoJDzd0JVOx0wWxp1cz
|
||||||
|
EUts+ZbKLoC+kIhsOGY+0a+sopeV2rMO5bUMpA8P0mKZlGynEGMLzKxz65E/IA9h
|
||||||
|
EQKpJjpvYfN+7eUkF6ZRXNV2LI/8BCoG6mOVoOMEXnloPwwBtOevoCB43U3sT9Er
|
||||||
|
WQWgZdbeI4gEyEqgMTibNogZZF0KW+5as3iv7avDd8pCgONvD0iwKSlvi9RNjiw8
|
||||||
|
p6bwNmBcuA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDkzCCAnugAwIBAgIUIo+5l07ZrQR/LxEEmUbnn4yxCwIwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwWTELMAkGA1UEBhMCVUExDTALBgNVBAgMBEtZSVYxDTALBgNVBAcMBEtZSVYx
|
||||||
|
CzAJBgNVBAoMAlRCMQswCQYDVQQLDAJUQjESMBAGA1UEAwwJbG9jYWxob3N0MB4X
|
||||||
|
DTIzMTAxNjIxMDMxNVoXDTI0MTAxNTIxMDMxNVowWTELMAkGA1UEBhMCVUExDTAL
|
||||||
|
BgNVBAgMBEtZSVYxDTALBgNVBAcMBEtZSVYxCzAJBgNVBAoMAlRCMQswCQYDVQQL
|
||||||
|
DAJUQjESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||||
|
MIIBCgKCAQEA87nLliszEWml8QvyAC+H80NZCxf4TcG826NBOp0AUPJ8xQBHCzc1
|
||||||
|
t1ohVm2/fn2VJZAYXG2xSVcHyXjjjv3iGLE2AIDbXh06/yFg4TVjlbrWrAHFehyN
|
||||||
|
FwrK8ez36oGLa3ZVq+mx1fLfBQw5mStbh09NXmKTzqP6m9ggKtt63cUwoWdUTemT
|
||||||
|
qrjryJd69LiJi+MVqtbKO2j30/lgAZmaHtbojl9EcvWfeXLb20TnXRIctaIS1VGo
|
||||||
|
SluzjbNQErdN/VRW4RAOP6UFsK0xID2EuLODBmAWnI49fXO/OS+u3Kd3suABE0o9
|
||||||
|
slfDXqNTp0r5N0OoSAFcc4EsV3+9Gf+mqwIDAQABo1MwUTAdBgNVHQ4EFgQUhS5K
|
||||||
|
XQDxGvaBCpKY1de+JZl8zjYwHwYDVR0jBBgwFoAUhS5KXQDxGvaBCpKY1de+JZl8
|
||||||
|
zjYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAiUTgjnsVIg90
|
||||||
|
Dm+XSlscIPbZEj/mJanoFFfAfbVJz1DadygG9viVUMf3jVQBcsJGeBDckR2b3OHY
|
||||||
|
82cQVpdu3Heqld+gnfsyi8QBi7EdK4i0q8NVqFgpw83KxNm9xt7xrgHtxhE0kWfW
|
||||||
|
dpTgeIu0hFf0qLUObw/g8+0awBuxNY2crLtLXQM/dRgtv5Zt/DilW3jMLAE5wke+
|
||||||
|
/HM4/emOJO6DSI9BC8iUsmNpIpq45267jcjpczNBo3ap7Bad+jM/paRDng9Uavvr
|
||||||
|
VCsaJFaL5HG6TtNXN60npBouOWnivPzUeuTI4PnjGRgdp3lgb0IuXbuwxIW6FVG/
|
||||||
|
73RHc0gGOA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
Loading…
x
Reference in New Issue
Block a user