Add smoke test to verify Redis SSL connection

See gh-34815
This commit is contained in:
Scott Frederick 2023-05-02 13:39:01 -05:00
parent 161b54b1d4
commit 3bb271e320
17 changed files with 592 additions and 3 deletions

View File

@ -151,8 +151,7 @@ abstract class RedisConnectionConfiguration {
}
protected boolean isSslEnabled() {
return getConnectionDetails() instanceof PropertiesRedisConnectionDetails
&& getProperties().getSsl().isEnabled();
return getProperties().getSsl().isEnabled();
}
protected boolean isPoolEnabled(Pool pool) {

View File

@ -47,7 +47,7 @@ public final class DockerImageNames {
private static final String RABBIT_VERSION = "3.11-alpine";
private static final String REDIS_VERSION = "4.0.14";
private static final String REDIS_VERSION = "7.0.11";
private static final String REDPANDA_VERSION = "v23.1.2";

View File

@ -0,0 +1,23 @@
plugins {
id "java"
id "org.springframework.boot.conventions"
}
description = "Spring Boot Data Redis smoke test"
dependencies {
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-redis"))
testImplementation(project(":spring-boot-project:spring-boot-test"))
testImplementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-test"))
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
testImplementation(project(":spring-boot-project:spring-boot-testcontainers"))
testImplementation("io.projectreactor:reactor-core")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.junit.platform:junit-platform-engine")
testImplementation("org.junit.platform:junit-platform-launcher")
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:testcontainers")
testImplementation("redis.clients:jedis")
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
@RedisHash("persons")
public class PersonHash {
@Id
private String id;
private String description;
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SampleRedisApplication {
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import org.springframework.data.repository.CrudRepository;
interface SampleRepository extends CrudRepository<PersonHash, String> {
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.stereotype.Service;
@Service
public class SampleService {
private static final Charset CHARSET = StandardCharsets.UTF_8;
private final RedisOperations<Object, Object> operations;
public SampleService(RedisOperations<Object, Object> operations) {
this.operations = operations;
}
public boolean hasRecord(PersonHash personHash) {
return this.operations.execute((RedisConnection connection) -> connection.keyCommands()
.exists(("persons:" + personHash.getId()).getBytes(CHARSET)));
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.data.redis.core.RedisOperations;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Smoke tests for Redis using Jedis with SSL.
*
* @author Scott Frederick
*/
@Testcontainers(disabledWithoutDocker = true)
@ClassPathExclusions("lettuce-core-*.jar")
@SpringBootTest(properties = { "spring.data.redis.ssl.bundle=client",
"spring.ssl.bundle.pem.client.keystore.certificate=classpath:ssl/test-client.crt",
"spring.ssl.bundle.pem.client.keystore.private-key=classpath:ssl/test-client.key",
"spring.ssl.bundle.pem.client.truststore.certificate=classpath:ssl/test-ca.crt" })
class SampleRedisApplicationJedisSslTests {
private static final Charset CHARSET = StandardCharsets.UTF_8;
@Container
@ServiceConnection
static RedisContainer redis = new SecureRedisContainer();
@Autowired
private RedisOperations<Object, Object> operations;
@Autowired
private SampleRepository exampleRepository;
@Test
void testRepository() {
PersonHash personHash = new PersonHash();
personHash.setDescription("Look, new @DataRedisTest!");
assertThat(personHash.getId()).isNull();
PersonHash savedEntity = this.exampleRepository.save(personHash);
assertThat(savedEntity.getId()).isNotNull();
assertThat(this.operations
.execute((org.springframework.data.redis.connection.RedisConnection connection) -> connection.keyCommands()
.exists(("persons:" + savedEntity.getId()).getBytes(CHARSET))))
.isTrue();
this.exampleRepository.deleteAll();
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import reactor.test.StepVerifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.data.redis.core.ReactiveRedisOperations;
/**
* Smoke tests for Redis using reactive operations and SSL.
*
* @author Scott Frederick
*/
@Testcontainers(disabledWithoutDocker = true)
@SpringBootTest(properties = { "spring.data.redis.ssl.bundle=client",
"spring.ssl.bundle.pem.client.keystore.certificate=classpath:ssl/test-client.crt",
"spring.ssl.bundle.pem.client.keystore.private-key=classpath:ssl/test-client.key",
"spring.ssl.bundle.pem.client.truststore.certificate=classpath:ssl/test-ca.crt" })
class SampleRedisApplicationReactiveSslTests {
@Container
@ServiceConnection
static RedisContainer redis = new SecureRedisContainer();
@Autowired
private ReactiveRedisOperations<Object, Object> operations;
@Test
void testRepository() {
String id = UUID.randomUUID().toString();
StepVerifier.create(this.operations.opsForValue().set(id, "Hello World"))
.expectNext(Boolean.TRUE)
.verifyComplete();
StepVerifier.create(this.operations.opsForValue().get(id)).expectNext("Hello World").verifyComplete();
StepVerifier.create(this.operations.execute((action) -> action.serverCommands().flushDb()))
.expectNext("OK")
.verifyComplete();
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
import org.springframework.data.redis.core.RedisOperations;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Smoke tests for Redis with SSL.
*
* @author Scott Frederick
*/
@Testcontainers(disabledWithoutDocker = true)
@SpringBootTest(properties = { "spring.data.redis.ssl.bundle=client",
"spring.ssl.bundle.pem.client.keystore.certificate=classpath:ssl/test-client.crt",
"spring.ssl.bundle.pem.client.keystore.private-key=classpath:ssl/test-client.key",
"spring.ssl.bundle.pem.client.truststore.certificate=classpath:ssl/test-ca.crt" })
class SampleRedisApplicationSslTests {
private static final Charset CHARSET = StandardCharsets.UTF_8;
@Container
@ServiceConnection
static RedisContainer redis = new SecureRedisContainer();
@Autowired
private RedisOperations<Object, Object> operations;
@Autowired
private SampleRepository exampleRepository;
@Test
void testRepository() {
PersonHash personHash = new PersonHash();
personHash.setDescription("Look, new @DataRedisTest!");
assertThat(personHash.getId()).isNull();
PersonHash savedEntity = this.exampleRepository.save(personHash);
assertThat(savedEntity.getId()).isNotNull();
assertThat(this.operations
.execute((org.springframework.data.redis.connection.RedisConnection connection) -> connection.keyCommands()
.exists(("persons:" + savedEntity.getId()).getBytes(CHARSET))))
.isTrue();
this.exampleRepository.deleteAll();
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2012-2023 the original author or 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
*
* https://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 smoketest.data.redis;
import org.testcontainers.utility.MountableFile;
import org.springframework.boot.testsupport.testcontainers.RedisContainer;
/**
* A {@link RedisContainer} for Redis with SSL configuration.
*
* @author Scott Frederick
*/
class SecureRedisContainer extends RedisContainer {
SecureRedisContainer() {
withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/test-server.crt"), "/ssl/server.crt");
withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/test-server.key"), "/ssl/server.key");
withCopyFileToContainer(MountableFile.forClasspathResource("/ssl/test-ca.crt"), "/ssl/ca.crt");
withCommand("redis-server --tls-port 6379 --port 0 "
+ "--tls-cert-file /ssl/server.crt --tls-key-file /ssl/server.key --tls-ca-cert-file /ssl/ca.crt");
}
}

View File

@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFhjCCA26gAwIBAgIUERZP46qinK0dKmJzlCsoD/k1nWYwDQYJKoZIhvcNAQEL
BQAwOzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MB4XDTIzMDUwMTIwNDkxMFoXDTMzMDQyODIwNDkxMFow
OzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlmaWNh
dGUgQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApWYo
UQjDY98oVOO5HOjheWeBN+C6gozg4aPY0VdRDTKmZ5SzNjuYtX6jsd8e5UF+ceeL
Aw9E3FAKG80F/81c6mtFhFUNUaBCbK2/+igs+Ae6r42i6iLImvgYLbZ0rGpPwszT
KGlwyobsI8n1bRFrVRdtGWVfn3Dfc5k/+dnZ03kOpViv/gd/xNWMcMOlj64F1s8L
6Nx9bfeJvOcsX+5qMiy/B6dZS0lkvXZISJbFhvX/+5Tb/vkP41AnrYff8hO8OBs+
G2srr2xNAIcgNBSjedDVUaRO+a2WHdX/1fHOlNqz335XMo79FOqRWDCZET3YW36A
hqiSPPiDq8AA7hmVxnq7vxWo/qclaqVuk5Dxp+ZD7d8deSGehTPajeCZCDtNhw6C
jtlU8v/LdwMRhqZp5/fjDlOEkutFh6B/aMjq3ZPYQad4MtQixDifgEs4iwnIMoVS
Wqpn24qn0qddfP0Y00U1F79UuJ2cJpyqdjtMRvbdNv6udWhD0rtrjdLvGFDOryzD
W7xQD2NLWW0IC9YNuXR0FzrJFFqWBW+lfF1u1PdW7ITFtUhj8RcIZZgUS/w1Yh8/
d6ja18UROEgiJ/Isgvl8sNTe2oNQK9HM6XtyEif5G5J7cv5FAH3si98My5h+rKq9
AMGfQLtDOM+Ivg7D63iiuxB57Rq91xCsKCC2QNECAwEAAaOBgTB/MB0GA1UdDgQW
BBQuNq1dmybivJy6XnHIFBYqEfqtMDAfBgNVHSMEGDAWgBQuNq1dmybivJy6XnHI
FBYqEfqtMDAPBgNVHRMBAf8EBTADAQH/MCwGA1UdEQQlMCOCC2V4YW1wbGUuY29t
gglsb2NhbGhvc3SCCTEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAgEAJFpeqQB9
pJLn4idrp7M1lSCrBJu2tu2UsOVcKTGZ3uqgKgKa+bn0kw9yN1CMISLSOV9B1Zt5
/+2U24/9iC1nGIzEpk2uQ2GwGaxFsy38gP6FF+UFltEvLbhfHWZ/j8gWQhTRQ/sT
TMd0L0CysmDswoEHcuNgdX+V4WVchPqdHTxp5qLM3GRas5JCuNcVi+vFEWCQsYRh
iTpsCEVfRsVJKUvPKVLR8PSEjSt8S+SQjIuTVWSmdG358uRVxpBzAzMwz9sQw4G6
Rv3S4LaQpWXUyHVYM1OxQz0fhEug5qgSR75GTFwG1oVd5rdk7iK/J3WbRJZ9FcKx
ipZ3jdl5mmI6p87OjgQVtUInv8KK88AhJmypBXaHE64nn8+YUsh/ud6+Vr8vyMPK
TZJivCtVKoX+nd3Zb3qX2YGORKQmn4GPX551FCk1CFOa+qlGfXtfqV2Z9LEQmqx3
ygqVnmSf34oTz04sSMdK7m3ULqLyv3RFJJ4F+VsHHAEdJYO+v/GdGz/0FA7ZZ4t+
7r1qY7uK4NSMRBn+DGlUL9oVp26uss/Qvi1WTI0g9W1YImxYSlaR0tm9jZQckirm
KMLMDyGJFvHqR8LRa3DU6L5pU99LxZSHRxBAY6oexKSYWt7BSE1kwaL3Exjg/RG/
ap5/GNJS1STNnbgq5TtWUbvZcXuhuBe8ClI=
-----END CERTIFICATE-----

View File

@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEGjCCAgKgAwIBAgIUCNvMLf/1EZcO6R9L/PQVWN8agbkwDQYJKoZIhvcNAQEL
BQAwOzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MB4XDTIzMDUwMTIwNDkxMFoXDTI0MDQzMDIwNDkxMFow
LzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDESMBAGA1UEAwwJbG9jYWxob3N0
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzP5NGFAhk6hAVr3YshRJ
YGxS2IGphFaq/c99QZQ62JbcSwceFo0p8Px9JiaT38n7NejEy6t6U0PQP2B9r3pJ
p0RwplvITLd1lp96DdMQeGXKa2rqJ62u9//u/XxFboVU6QYC90Pnqi6sRWejKEI8
Yowg6erjNMCQiIAKqhWPfdsJOxf79102gdahuTT8A89p551u7a84oTRtX4fLksP2
x0BVFb0/Dirz5ngwm6YHpN+8z7BYIyj4dLzzFjaqU1gptxtGygap1GtD1X9fJ61l
k6K8vMww4+/zYOoGratUTNeKHOvvXf9SnjoqyMTvJFyTX+5snkyL81q3+XgXJOYL
ZQIDAQABoyIwIDALBgNVHQ8EBAMCBaAwEQYJYIZIAYb4QgEBBAQDAgeAMA0GCSqG
SIb3DQEBCwUAA4ICAQAq5Em7EVkGhPgIMDmxhm398Kv8OivFxX6x5aGnJ+m8+mZV
+wrkjRvpqN/+CtTsid2q4+qYdlov8hJ2oxwVhfnrF5b7Xj7caC2FJifPXPiaMogT
5VI4uCABBuVQR0kDtnPF8bRiTWCKC3DC84GqMp0cUs3Qyf1dLcjhcc9dSROn00y8
/qmIz8roJ2esnqG12rTGdIAaWSgBCMKFjrV8YmxLf+z72VHSx6uC5CARG+UYa5Mu
vga0Q77QmwSstKBvGUBtvzQoML3/UFCikdfOxDgvJbr8Q0yEEw8hK7vGZLaj00zB
U4B5+DfV285RW09ihp2YMxuz3mL2tM5++RYJphB9/VTN3/f+geKt2pPA3Rkk11Ug
LP3NdpT5ZnQL9ehtmIExk2NVBi+RmGCcP7KcMtlq44FdyRF7p6qdg/Eq5n/sOMxQ
DnamgWDQltm6cuZ49haCXLZIbfqM2cHARIw/Sv3Dgd9SSDL2pooWI2U82fQ9A71q
u/hUlNDZm0v51IfgzJcbAtlAYd2OVlgCkkkFtbgdOaQUShIkcCKcpxtgQzpynNMO
DJoO41VXpMzBN7/ppVi0JrF7RkaXGeoNsqfvcmjQEuXUOluge2q8kHDf7gEUddKa
ijPHtkFQF2ujCGr/AVYjCMSlOk5WhRh8ZVxN0KbiWZJUN8akX4gU4KIpTe1big==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAzP5NGFAhk6hAVr3YshRJYGxS2IGphFaq/c99QZQ62JbcSwce
Fo0p8Px9JiaT38n7NejEy6t6U0PQP2B9r3pJp0RwplvITLd1lp96DdMQeGXKa2rq
J62u9//u/XxFboVU6QYC90Pnqi6sRWejKEI8Yowg6erjNMCQiIAKqhWPfdsJOxf7
9102gdahuTT8A89p551u7a84oTRtX4fLksP2x0BVFb0/Dirz5ngwm6YHpN+8z7BY
Iyj4dLzzFjaqU1gptxtGygap1GtD1X9fJ61lk6K8vMww4+/zYOoGratUTNeKHOvv
Xf9SnjoqyMTvJFyTX+5snkyL81q3+XgXJOYLZQIDAQABAoIBAFNG/Arkgr95mqmi
dmXh1+1UFFPgWP1qOAzkPf5mOYHDx7qzKYX/0woTiMP26BwB8gv0g/45q3goFHGq
wWSISWOqahkrMDP6U8rc/rifBhHjSFhbFsUHygz17CEOWyaLA/OmfY32CCcazuFj
OOUiA2YFh1mAEs1bbVwGqE5wc9qsZtBlJxudSWtSZoJuFECDNqLfQXkJ39KnKhp4
D337nOR/xww81202mlfF/vvhRMfUIUS2Ij9USndp9huBHFSxf1mYjD1ljjx6U7el
new8TPf76J7nuy/6SxZ9wF6P2dk/eQcN5AnIcDGq0WzS3VcJc/KG/+maflCvH0dB
SLfx4AECgYEA7e+5/UhWZ62BfF1/Nat95+t+bh8UYN8gPEUos7oS/cUrme7YAPQT
MTWNulpmgGCRDxeXU9XBaPGyF7cU5bx28sK64ZUe8D1ySgGpVeSEQtjCLFEf6eat
801TQVNaH2WlDZTm+Onfr7ppFN1pLrBY+83m9TDJd6v4qHsvtNkcx38CgYEA3I5U
OvvoTEj8+Xc0U296NU+aWJLNrkDH6lFtdXsLyoumxh0DDbKSw8ia28Z5+8tz0mdB
33sIsnnsQ+83YoiXyopM9GFZdZH3luKrXgOGH8QFygJI8xGqqcLjeWNkW0b0KCkv
AoiedqOOmCdRMUfy3v5irH+4O90ZmW6VxNKbfxsCgYEAtjjFOQwAWHCR3TwBo4nN
6CL7dbzJr5LSLjZNAK/9wWoShVZdCQXj+OjpvRFktOa/0U4g7+yhrgyEdxMYpwUa
F7s4wnCg/B4i/Difhg93l3ZH5wbOKSUojU/n9fyu5aLDsE4cQf9i90MNHRSgbEhU
Law4OAmAEe2bhvSoyZkJKGMCgYBgW25BNr0OVvTuqD2cFh/2Goj8GWbysiqlHF4N
7WwBWXHLK/Ghklq8XnAJhHTWpNQ9IA+Pa1kpYErwgxpXWgW23yUvvzguPU9GBFGK
CVAXoLRGxSjJyPYepJ5s8hduKVmSEiwPl1Bj1KD/qG24cg6RjeHeKw56WOZOOhoE
m16D8QKBgBHXU31OJ2KMDnwjsMW2SlpYKoIQlJyTg3qvN7gu+ZGo5B7hviqh5wN1
y577N/NT9No8qGNEGTZl35hkyw8DmB4RAZp7G1qbVCGszUBt/vS6Guv82/EgMVo2
ZgiQBkI1kEOtj5LMVBfOKTRBEpyAm5fSZ+eQtSIc5LCbQ8aEvio4
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEGjCCAgKgAwIBAgIUCNvMLf/1EZcO6R9L/PQVWN8agbgwDQYJKoZIhvcNAQEL
BQAwOzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDEeMBwGA1UEAwwVQ2VydGlm
aWNhdGUgQXV0aG9yaXR5MB4XDTIzMDUwMTIwNDkxMFoXDTI0MDQzMDIwNDkxMFow
LzEZMBcGA1UECgwQU3ByaW5nIEJvb3QgVGVzdDESMBAGA1UEAwwJbG9jYWxob3N0
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqgji6StU0UkWfYmZumQO
L7SnFg7/xBM5ubMtXJsBOS0RaRWJ0WwIsQ2ksDOf2ybDyXiePplbtR/4GsnXPyNp
H1vgY/Mt/PeiP/lHw9dDTdSx6YMMxGVoILsHkblaeHwh8yVGCg2gdoRROscgjS+e
j7gTr4H2UBlepHsjZBKc+hamDrIC3vK42iQUyzbClJ8lpY+KbL4R4KhsuhTb2jRL
wye3m2w+YU1jvE+IioQfozlZTAw0SX7whcCw0B3hLVQg6hsdSeSYkCUZiZY72ySR
fI+mDcnJVcetH2ShK1zVFBpDs9qkJSA9YumO1ZKVDdDseeuHHsEUG2/pszQ2cHH6
EwIDAQABoyIwIDALBgNVHQ8EBAMCBaAwEQYJYIZIAYb4QgEBBAQDAgZAMA0GCSqG
SIb3DQEBCwUAA4ICAQACFGGWNTEDCvkfEuZZT84zT8JQ9O5wDzgYDX/xRSXbB1Jv
fd9QQfwlVFXg3jewIgWZG0TgQt/7yF6RYOtU+GRP6meJhSm9/11KnYYLNlHQU1QE
7imreHAnsJiueHXPmpe9EL4jv2mQt7GSccABMf1pfBQ+C0dETnUoH68oO3LttU16
f43H1royvOm3G6LnJb83rLYVe07P1PTjk/37gaFCf54J1eDfqntVDiSq8H6fV+nL
9ZvsVuC4BcREnB3oY7vsJFBhGeK/3+QFX4Zr3DTwLxiWe2pqSQfUbn4+d6+uwIY7
pixgNorpebKQn0vX/G4llVjOmBNjlgSzDyVTYObBz316GojF7yRk3oBbxK//3w/t
XVhLwrPpqB5Jehh2HsKKZrdfnjB1Gn+pDpSEMVDrCbWxzAJz4WOu2ihCYYsF3Gts
lzI1ZzD+UpFyeHG/1wQHzyQwADBiaYfh1oAnpNcOvJhT1S6IVGImcOBNa8u14aVG
NjvnJWVn3v3dcvAVO1ZUwX9TdHP11oIpn7fGYZzSxCDrhGaFeW0tscxddHRrXdwk
IHyHZ3o2RgivhaSc4C04nuZEX00ohTgtKo2rpK1SP+gn64Yh+u+O6AH8r+q7cZy2
gZNscwHAmkEalP78D5vnOFRUYEVrNc/X2f+rwFoQD7B8GNGa/visAkD7myg7JQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqgji6StU0UkWfYmZumQOL7SnFg7/xBM5ubMtXJsBOS0RaRWJ
0WwIsQ2ksDOf2ybDyXiePplbtR/4GsnXPyNpH1vgY/Mt/PeiP/lHw9dDTdSx6YMM
xGVoILsHkblaeHwh8yVGCg2gdoRROscgjS+ej7gTr4H2UBlepHsjZBKc+hamDrIC
3vK42iQUyzbClJ8lpY+KbL4R4KhsuhTb2jRLwye3m2w+YU1jvE+IioQfozlZTAw0
SX7whcCw0B3hLVQg6hsdSeSYkCUZiZY72ySRfI+mDcnJVcetH2ShK1zVFBpDs9qk
JSA9YumO1ZKVDdDseeuHHsEUG2/pszQ2cHH6EwIDAQABAoIBAQCLTuiJ3OSK63Sv
udLncR5mW34hhnxqas36pSBfJOflrlT7YZgeqoKcfO8XJdSsup/iKx6Lbx5B0UV2
vTPLGPoBpUa83PoqrcCS5Wu0umL8G20AQkxthB/B4TocXF4RJLK0AS/XAL8dGt9q
Zsb2pbMlUM1gF/x0N7Tg0bp3PQC7rAgYe7JFvArxRrmDP38FE9Cg5EIAVMN8Fw2b
dxKZxJ+mqj1t1bU4/bsrYBs9QpNrBjQc0KTFOamwkvWI7FhHXQtIZfJvvBj8mN7z
He7B5j/JcfGC5LN1UpL4tziOrKwMGGIvpAnpbVEv29SWxOG5Vbccb4ghBN+VJqSH
6WON791hAoGBAN7Q5nuCk+L/8BQh29WHZuP6dbLyMMjWMyuDm2xEYD0fjjacvU7r
KIQDcQY3E7bXu6OXKQmxARFY7HuZUyGg8R4QBeAEVfDPjRKzGZgA1+gF325eQwAQ
giXqg0paE2ePfbawi21NfQPCMMhb4n3QzpYd4eEsFFwMvt4oZCPkHubJAoGBAMNb
pGajPKW19dFWP5OsKc1U6itej78RQRjO7zpQ3JWvNuMa/SZzEa2blFuks585u6M2
XdVPhhspc0TwS+asizNEMDYaPpAjmg9X9LY87hcYTC0FXT0Axx+7A/JtmMAVF3Pn
4lvhfdB5XSV5jo/BtUJ3vDx5FSFIHQbbj1agGpv7AoGAdv6pmJyLzldRJ+9NMCQ3
1tkTspWVaCy89yg6AQAjRYFsuc3LbDI6WQZdfiw74xIjq6I20G4vW8xZv0iLFRKW
sq9r889c9lZhyPLNYFhS9h7szEybC5XFa+pqY3Lnmg8P3Fk8nQsdELzMwLQRqY+y
RImA8HhSBzbnWE3J7UEPH8ECgYAXyNGEOX2Jw1SRTwnghcZ1HFCCRToFDim5xn/z
vqKMis+I6OFHTB0r4NQ4MB46VYIVxem4rbzrE6nYC9WB2SH9dODVxW42iE8abR/7
DAIEx82Gca+/XJfhshgx7Mv7HtZDI0k43IQ/3HbNuDX2JKRX2lINnsRG0AvQqOyT
pFx4/wKBgQCXU0LGSCgNwuqdhXHoaFEzAzzspDjCI+9KDuchkvoYWfCWElX035O9
TbEybMjCuv08eAqeJv++a1jnTmJwf+w+WhBG+DpYcro1JXmo8Lu9KAbiq0lJGQP6
tX9gr0XY3IC+L5ndOANuFH6mjGlnp7Z+J8i7HFFoSa+MI2JkoQ5yVA==
-----END RSA PRIVATE KEY-----