Add benchmarks for SSLEngine implementations
Motivation: As we provide our own SSLEngine implementation we should have benchmarks to compare it against JDK impl. Modifications: Add benchmarks for wrap / unwrap and handshake performance. Result: Benchmarks FTW.
This commit is contained in:
parent
7aff6b0330
commit
d73477c7bd
@ -106,6 +106,12 @@
|
||||
<artifactId>Agrona</artifactId>
|
||||
<version>0.5.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>${tcnative.artifactId}</artifactId>
|
||||
<classifier>${tcnative.classifier}</classifier>
|
||||
<optional>false</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.microbench.handler.ssl;
|
||||
|
||||
import io.netty.buffer.PooledByteBufAllocator;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.SslProvider;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.netty.microbench.util.AbstractMicrobenchmark;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
|
||||
import javax.net.ssl.SSLEngine;
|
||||
import javax.net.ssl.SSLEngineResult;
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
public class AbstractSslEngineBenchmark extends AbstractMicrobenchmark {
|
||||
|
||||
private static final String PROTOCOL_TLS_V1_2 = "TLSv1.2";
|
||||
|
||||
public enum SslEngineProvider {
|
||||
JDK {
|
||||
@Override
|
||||
SslProvider sslProvider() {
|
||||
return SslProvider.JDK;
|
||||
}
|
||||
},
|
||||
OPENSSL {
|
||||
@Override
|
||||
SslProvider sslProvider() {
|
||||
return SslProvider.OPENSSL;
|
||||
}
|
||||
},
|
||||
OPENSSL_REFCNT {
|
||||
@Override
|
||||
SslProvider sslProvider() {
|
||||
return SslProvider.OPENSSL_REFCNT;
|
||||
}
|
||||
};
|
||||
private final SslContext clientContext = newClientContext();
|
||||
private final SslContext serverContext = newServerContext();
|
||||
|
||||
private SslContext newClientContext() {
|
||||
try {
|
||||
return SslContextBuilder.forClient()
|
||||
.sslProvider(sslProvider())
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||
.build();
|
||||
} catch (SSLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private SslContext newServerContext() {
|
||||
try {
|
||||
File keyFile = new File(getClass().getResource("test_unencrypted.pem").getFile());
|
||||
File crtFile = new File(getClass().getResource("test.crt").getFile());
|
||||
|
||||
return SslContextBuilder.forServer(crtFile, keyFile)
|
||||
.sslProvider(sslProvider())
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
SSLEngine newClientEngine(String cipher) {
|
||||
return configureEngine(clientContext.newEngine(PooledByteBufAllocator.DEFAULT), cipher);
|
||||
}
|
||||
|
||||
SSLEngine newServerEngine(String cipher) {
|
||||
return configureEngine(serverContext.newEngine(PooledByteBufAllocator.DEFAULT), cipher);
|
||||
}
|
||||
|
||||
abstract SslProvider sslProvider();
|
||||
|
||||
static SSLEngine configureEngine(SSLEngine engine, String cipher) {
|
||||
engine.setEnabledProtocols(new String[]{ PROTOCOL_TLS_V1_2 });
|
||||
engine.setEnabledCipherSuites(new String[]{ cipher });
|
||||
return engine;
|
||||
}
|
||||
}
|
||||
|
||||
public enum BufferType {
|
||||
HEAP {
|
||||
@Override
|
||||
ByteBuffer newBuffer(int size) {
|
||||
return ByteBuffer.allocate(size);
|
||||
}
|
||||
},
|
||||
DIRECT {
|
||||
@Override
|
||||
ByteBuffer newBuffer(int size) {
|
||||
return ByteBuffer.allocateDirect(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
void freeBuffer(ByteBuffer buffer) {
|
||||
PlatformDependent.freeDirectBuffer(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
abstract ByteBuffer newBuffer(int size);
|
||||
|
||||
void freeBuffer(ByteBuffer buffer) { }
|
||||
}
|
||||
|
||||
@Param
|
||||
public SslEngineProvider sslProvider;
|
||||
|
||||
@Param
|
||||
public BufferType bufferType;
|
||||
|
||||
// Includes cipher required by HTTP/2
|
||||
@Param({ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" })
|
||||
public String cipher;
|
||||
|
||||
protected SSLEngine clientEngine;
|
||||
protected SSLEngine serverEngine;
|
||||
|
||||
private ByteBuffer cTOs;
|
||||
private ByteBuffer sTOc;
|
||||
private ByteBuffer serverAppReadBuffer;
|
||||
private ByteBuffer clientAppReadBuffer;
|
||||
private ByteBuffer empty;
|
||||
|
||||
protected final void initEngines() {
|
||||
clientEngine = newClientEngine();
|
||||
serverEngine = newServerEngine();
|
||||
}
|
||||
|
||||
protected final void destroyEngines() {
|
||||
ReferenceCountUtil.release(clientEngine);
|
||||
ReferenceCountUtil.release(serverEngine);
|
||||
}
|
||||
|
||||
protected final void initHandshakeBuffers() {
|
||||
cTOs = allocateBuffer(clientEngine.getSession().getPacketBufferSize());
|
||||
sTOc = allocateBuffer(serverEngine.getSession().getPacketBufferSize());
|
||||
|
||||
serverAppReadBuffer = allocateBuffer(
|
||||
serverEngine.getSession().getApplicationBufferSize());
|
||||
clientAppReadBuffer = allocateBuffer(
|
||||
clientEngine.getSession().getApplicationBufferSize());
|
||||
empty = allocateBuffer(0);
|
||||
}
|
||||
|
||||
protected final void destroyHandshakeBuffers() {
|
||||
freeBuffer(cTOs);
|
||||
freeBuffer(sTOc);
|
||||
freeBuffer(serverAppReadBuffer);
|
||||
freeBuffer(clientAppReadBuffer);
|
||||
freeBuffer(empty);
|
||||
}
|
||||
|
||||
protected final boolean doHandshake() throws SSLException {
|
||||
clientEngine.beginHandshake();
|
||||
serverEngine.beginHandshake();
|
||||
|
||||
SSLEngineResult clientResult = null;
|
||||
SSLEngineResult serverResult = null;
|
||||
|
||||
boolean clientHandshakeFinished = false;
|
||||
boolean serverHandshakeFinished = false;
|
||||
|
||||
do {
|
||||
int cTOsPos = cTOs.position();
|
||||
int sTOcPos = sTOc.position();
|
||||
|
||||
if (!clientHandshakeFinished) {
|
||||
clientResult = clientEngine.wrap(empty, cTOs);
|
||||
runDelegatedTasks(clientResult, clientEngine);
|
||||
assert empty.remaining() == clientResult.bytesConsumed();
|
||||
assert cTOs.position() - cTOsPos == clientResult.bytesProduced();
|
||||
|
||||
clientHandshakeFinished = isHandshakeFinished(clientResult);
|
||||
}
|
||||
|
||||
if (!serverHandshakeFinished) {
|
||||
serverResult = serverEngine.wrap(empty, sTOc);
|
||||
runDelegatedTasks(serverResult, serverEngine);
|
||||
assert empty.remaining() == serverResult.bytesConsumed();
|
||||
assert sTOc.position() - sTOcPos == serverResult.bytesProduced();
|
||||
|
||||
serverHandshakeFinished = isHandshakeFinished(serverResult);
|
||||
}
|
||||
|
||||
cTOs.flip();
|
||||
sTOc.flip();
|
||||
|
||||
cTOsPos = cTOs.position();
|
||||
sTOcPos = sTOc.position();
|
||||
|
||||
if (!clientHandshakeFinished) {
|
||||
int clientAppReadBufferPos = clientAppReadBuffer.position();
|
||||
clientResult = clientEngine.unwrap(sTOc, clientAppReadBuffer);
|
||||
|
||||
runDelegatedTasks(clientResult, clientEngine);
|
||||
assert sTOc.position() - sTOcPos == clientResult.bytesConsumed();
|
||||
assert clientAppReadBuffer.position() - clientAppReadBufferPos == clientResult.bytesProduced();
|
||||
|
||||
clientHandshakeFinished = isHandshakeFinished(clientResult);
|
||||
} else {
|
||||
assert !sTOc.hasRemaining();
|
||||
}
|
||||
|
||||
if (!serverHandshakeFinished) {
|
||||
int serverAppReadBufferPos = serverAppReadBuffer.position();
|
||||
serverResult = serverEngine.unwrap(cTOs, serverAppReadBuffer);
|
||||
runDelegatedTasks(serverResult, serverEngine);
|
||||
assert cTOs.position() - cTOsPos == serverResult.bytesConsumed();
|
||||
assert serverAppReadBuffer.position() - serverAppReadBufferPos == serverResult.bytesProduced();
|
||||
|
||||
serverHandshakeFinished = isHandshakeFinished(serverResult);
|
||||
} else {
|
||||
assert !cTOs.hasRemaining();
|
||||
}
|
||||
|
||||
sTOc.compact();
|
||||
cTOs.compact();
|
||||
} while (!clientHandshakeFinished || !serverHandshakeFinished);
|
||||
return clientResult.getStatus() == SSLEngineResult.Status.OK &&
|
||||
serverResult.getStatus() == SSLEngineResult.Status.OK;
|
||||
}
|
||||
|
||||
protected final SSLEngine newClientEngine() {
|
||||
return sslProvider.newClientEngine(cipher);
|
||||
}
|
||||
|
||||
protected final SSLEngine newServerEngine() {
|
||||
return sslProvider.newServerEngine(cipher);
|
||||
}
|
||||
|
||||
protected static boolean checkSslEngineResult(SSLEngineResult result, ByteBuffer src, ByteBuffer dst) {
|
||||
return result.getStatus() == SSLEngineResult.Status.OK && !src.hasRemaining() && dst.hasRemaining();
|
||||
}
|
||||
|
||||
protected final ByteBuffer allocateBuffer(int size) {
|
||||
return bufferType.newBuffer(size);
|
||||
}
|
||||
|
||||
protected final void freeBuffer(ByteBuffer buffer) {
|
||||
bufferType.freeBuffer(buffer);
|
||||
}
|
||||
|
||||
private static boolean isHandshakeFinished(SSLEngineResult result) {
|
||||
return result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED;
|
||||
}
|
||||
|
||||
private static void runDelegatedTasks(SSLEngineResult result, SSLEngine engine) {
|
||||
if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
|
||||
for (;;) {
|
||||
Runnable task = engine.getDelegatedTask();
|
||||
if (task == null) {
|
||||
break;
|
||||
}
|
||||
task.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.microbench.handler.ssl;
|
||||
|
||||
import io.netty.util.internal.ThreadLocalRandom;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Param;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
|
||||
import javax.net.ssl.SSLEngineResult;
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public abstract class AbstractSslEngineThroughputBenchmark extends AbstractSslEngineBenchmark {
|
||||
|
||||
@Param({ "64", "128", "512", "1024", "4096" })
|
||||
public int messageSize;
|
||||
|
||||
protected ByteBuffer wrapSrcBuffer;
|
||||
private ByteBuffer wrapDstBuffer;
|
||||
|
||||
@Setup(Level.Iteration)
|
||||
public final void setup() throws Exception {
|
||||
initEngines();
|
||||
initHandshakeBuffers();
|
||||
|
||||
wrapDstBuffer = allocateBuffer(clientEngine.getSession().getPacketBufferSize());
|
||||
wrapSrcBuffer = allocateBuffer(messageSize);
|
||||
|
||||
byte[] bytes = new byte[messageSize];
|
||||
ThreadLocalRandom.current().nextBytes(bytes);
|
||||
wrapSrcBuffer.put(bytes);
|
||||
wrapSrcBuffer.flip();
|
||||
|
||||
// Complete the initial TLS handshake.
|
||||
if (!doHandshake()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
doSetup();
|
||||
}
|
||||
|
||||
protected void doSetup() throws Exception { }
|
||||
|
||||
@TearDown(Level.Iteration)
|
||||
public final void tearDown() throws Exception {
|
||||
destroyEngines();
|
||||
destroyHandshakeBuffers();
|
||||
freeBuffer(wrapSrcBuffer);
|
||||
freeBuffer(wrapDstBuffer);
|
||||
doTearDown();
|
||||
}
|
||||
|
||||
protected void doTearDown() throws Exception { }
|
||||
|
||||
protected final ByteBuffer doWrap() throws SSLException {
|
||||
wrapSrcBuffer.position(0).limit(messageSize);
|
||||
|
||||
wrapDstBuffer.clear();
|
||||
|
||||
SSLEngineResult wrapResult = clientEngine.wrap(wrapSrcBuffer, wrapDstBuffer);
|
||||
|
||||
assert checkSslEngineResult(wrapResult, wrapSrcBuffer, wrapDstBuffer);
|
||||
return wrapDstBuffer;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.microbench.handler.ssl;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Threads;
|
||||
|
||||
import javax.net.ssl.SSLEngineResult;
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@Threads(1)
|
||||
public class SslEngineEchoBenchmark extends AbstractSslEngineThroughputBenchmark {
|
||||
|
||||
private ByteBuffer unwrapDstBuffer;
|
||||
|
||||
@Override
|
||||
protected void doSetup() {
|
||||
unwrapDstBuffer = allocateBuffer(serverEngine.getSession().getApplicationBufferSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doTearDown() {
|
||||
freeBuffer(unwrapDstBuffer);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public ByteBuffer wrapUnwrap() throws SSLException {
|
||||
ByteBuffer src = doWrap();
|
||||
src.flip();
|
||||
|
||||
unwrapDstBuffer.clear();
|
||||
|
||||
SSLEngineResult unwrapResult = serverEngine.unwrap(src, unwrapDstBuffer);
|
||||
|
||||
assert checkSslEngineResult(unwrapResult, src, unwrapDstBuffer);
|
||||
return unwrapDstBuffer;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.microbench.handler.ssl;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.annotations.Threads;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@Threads(1)
|
||||
public class SslEngineHandshakeBenchmark extends AbstractSslEngineBenchmark {
|
||||
|
||||
@Setup(Level.Iteration)
|
||||
public void setup() {
|
||||
// Init an engine one time and create the buffers needed for an handshake so we can use them in the benchmark
|
||||
initEngines();
|
||||
initHandshakeBuffers();
|
||||
destroyEngines();
|
||||
}
|
||||
|
||||
@TearDown(Level.Iteration)
|
||||
public void teardown() {
|
||||
destroyHandshakeBuffers();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
public boolean handshake() throws Exception {
|
||||
initEngines();
|
||||
boolean ok = doHandshake();
|
||||
destroyEngines();
|
||||
assert ok;
|
||||
return ok;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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 io.netty.microbench.handler.ssl;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.Threads;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@Threads(1)
|
||||
public class SslEngineWrapBenchmark extends AbstractSslEngineThroughputBenchmark {
|
||||
|
||||
@Benchmark
|
||||
public ByteBuffer wrap() throws SSLException {
|
||||
return doWrap();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2017 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you 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.
|
||||
*/
|
||||
/**
|
||||
* Benchmarks for SSL.
|
||||
*/
|
||||
package io.netty.microbench.handler.ssl;
|
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC/jCCAeagAwIBAgIIIMONxElm0AIwDQYJKoZIhvcNAQELBQAwPjE8MDoGA1UE
|
||||
AwwzZThhYzAyZmEwZDY1YTg0MjE5MDE2MDQ1ZGI4YjA1YzQ4NWI0ZWNkZi5uZXR0
|
||||
eS50ZXN0MCAXDTEzMDgwMjA3NTEzNloYDzk5OTkxMjMxMjM1OTU5WjA+MTwwOgYD
|
||||
VQQDDDNlOGFjMDJmYTBkNjVhODQyMTkwMTYwNDVkYjhiMDVjNDg1YjRlY2RmLm5l
|
||||
dHR5LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb+HBO3C0U
|
||||
RBKvDUgJHbhIlBye8X/cbNH3lDq3XOOFBz7L4XZKLDIXS+FeQqSAUMo2otmU+Vkj
|
||||
0KorshMjbUXfE1KkTijTMJlaga2M2xVVt21fRIkJNWbIL0dWFLWyRq7OXdygyFkI
|
||||
iW9b2/LYaePBgET22kbtHSCAEj+BlSf265+1rNxyAXBGGGccCKzEbcqASBKHOgVp
|
||||
6pLqlQAfuSy6g/OzGzces3zXRrGu1N3pBIzAIwCW429n52ZlYfYR0nr+REKDnRrP
|
||||
IIDsWASmEHhBezTD+v0qCJRyLz2usFgWY+7agUJE2yHHI2mTu2RAFngBilJXlMCt
|
||||
VwT0xGuQxkbHAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEv8N7Xm8qaY2FgrOc6P
|
||||
a1GTgA+AOb3aU33TGwAR86f+nLf6BSPaohcQfOeJid7FkFuYInuXl+oqs+RqM/j8
|
||||
R0E5BuGYY2wOKpL/PbFi1yf/Kyvft7KVh8e1IUUec/i1DdYTDB0lNWvXXxjfMKGL
|
||||
ct3GMbEHKvLfHx42Iwz/+fva6LUrO4u2TDfv0ycHuR7UZEuC1DJ4xtFhbpq/QRAj
|
||||
CyfNx3cDc7L2EtJWnCmivTFA9l8MF1ZPMDSVd4ecQ7B0xZIFQ5cSSFt7WGaJCsGM
|
||||
zYkU4Fp4IykQcWxdlNX7wJZRwQ2TZJFFglpTiFZdeq6I6Ad9An1Encpz5W8UJ4tv
|
||||
hmw=
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,24 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDb+HBO3C0URBKvDUgJHbhIlBye
|
||||
8X/cbNH3lDq3XOOFBz7L4XZKLDIXS+FeQqSAUMo2otmU+Vkj0KorshMjbUXfE1KkTijTMJlaga2M
|
||||
2xVVt21fRIkJNWbIL0dWFLWyRq7OXdygyFkIiW9b2/LYaePBgET22kbtHSCAEj+BlSf265+1rNxy
|
||||
AXBGGGccCKzEbcqASBKHOgVp6pLqlQAfuSy6g/OzGzces3zXRrGu1N3pBIzAIwCW429n52ZlYfYR
|
||||
0nr+REKDnRrPIIDsWASmEHhBezTD+v0qCJRyLz2usFgWY+7agUJE2yHHI2mTu2RAFngBilJXlMCt
|
||||
VwT0xGuQxkbHAgMBAAECggEBAJJdKaVfXWNptCDkLnVaYB9y5eRgfppVkhQxfiw5023Vl1QjrgjG
|
||||
hYH4zHli0IBMwXA/RZWZoFVzZ3dxoshk0iQPgGKxWvrDEJcnSCo8MGL7jPvh52jILp6uzsGZQBji
|
||||
bTgFPmOBS7ShdgZiQKD9PD2psrmqHZ1yTwjIm5cGfzQM8Y6tjm0xLBn676ecJNdS1TL10y9vmSUM
|
||||
Ofdkmeg9Z9TEK95lP2fF/NIcxCo0LF9JcHUvTuYBDnBH0XMZi0w0ZcRReMSdAZ2lLiXgBeCO53el
|
||||
2NIrtkRx+qOvLua9UfwO2h/0rs66ZeV0YuFCjv067nytyZf2zhU/QbCHRypzfrkCgYEA/facuAJs
|
||||
6MQKsNvhozoBeDRMkrZPMh8Sb0w50EqzIGz3pdms6UvCiggoMbhxKOwuYWZ689fBPGwm7x0RdwDO
|
||||
jyUuEbFnQFe+CpdHy6VK7vIQed1SwAcdTMDwCYbkJNglqHEB7qUYYTFLr8okGyWVdthUoh4IAubU
|
||||
TR3TFbGraDUCgYEA3bwJ/UNA5pHtb/nh4/dNL7/bRMwXyPZPpC5z+gjjgUMgsSRBz8+iPNTB4iSQ
|
||||
1j9zm+pnXGi35zWZcI4jvIcFusb08eS7xcZDb+7X2r2wenLNmyuTOa1812y233FicU+ah91fa9aD
|
||||
yUfTjj3GFawbgNNhMyWa3aEMV+c73t6sKosCgYEA35oQZhsMlOx2lT0jrzlVLeauPMZzeCfPbVrp
|
||||
1DDRAg2vBcFf8pCXmjyQVyaTy3oXY/585tDh/DclGIa5Z9O4CmSr6TwPMqGOW3jS58SC81sBkqqB
|
||||
Pz2EWJ3POjQgDyiYD3RgRSPrETf78azCmXw/2sGh0pMqbpOZ/MPzpDgoOLkCgYEAsdv4g09kCs75
|
||||
Dz34hRzErE2P+8JePdPdlEuyudhRbUlEOvNjWucpMvRSRSyhhUnGWUWP/V7+TRcAanmJjtsbrHOU
|
||||
3Udlm0HqrCmAubQ4kC/wXsx4Pua7Yi2RDvBrT4rT4LGgreaXNWhI+Srx7kZslUx5Bkbez3I0bXpM
|
||||
2vvwS/sCgYAducNt1KC4W7jzMWUivvuy5hQQmX/G0JHtu1pfv9cmA8agnc1I/r7xoirftuSG25Pm
|
||||
r+eP5SKbKb8ZQlp10JeBkNnk8eAG8OkQyBaECYDBadEr1/LK2LmIEjYKzKAjYQ4cX2KMtY271jjX
|
||||
WrzzXNqBdThFfMHiJE8k9xYmaLDKhQ==
|
||||
-----END PRIVATE KEY-----
|
Loading…
Reference in New Issue
Block a user