in netty-handler-ssl, drop conscrypt because of https://github.com/google/conscrypt/issues/838, move bouncycastle to separate subproject

main
Jörg Prante 8 months ago
parent 3d532a821f
commit 07c6dd718a

2
.gitignore vendored

@ -12,5 +12,3 @@
.DS_Store
*.iml
*~
*.key
*.crt

@ -11,6 +11,8 @@ module org.xbib.io.netty.channel {
exports io.netty.channel.oio;
exports io.netty.channel.pool;
exports io.netty.channel.socket;
exports io.netty.channel.socket.nio;
exports io.netty.channel.socket.oio;
uses ChannelInitializerExtension;
requires org.xbib.io.netty.buffer;
requires org.xbib.io.netty.resolver;

@ -3,6 +3,7 @@ dependencies {
testImplementation testLibs.gson
testImplementation testLibs.assertj
testImplementation testLibs.mockito.core
testImplementation project(':netty-handler-ssl-bouncycastle')
testRuntimeOnly project(path: ':netty-tcnative-boringssl-static', configuration: osdetector.classifier)
testRuntimeOnly libs.brotli4j.native."${osdetector.os}"."${osdetector.arch.replace('_','')}"
}

@ -42,7 +42,7 @@ import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;
import io.netty.util.ReferenceCountUtil;

@ -3,4 +3,5 @@ dependencies {
api project(':netty-handler-codec-quic')
testImplementation testLibs.assertj
testImplementation testLibs.mockito.core
testImplementation project(':netty-handler-ssl-bouncycastle')
}

@ -54,7 +54,7 @@ import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.codec.quic.InsecureQuicTokenHandler;
import io.netty.handler.codec.quic.QuicChannel;
import io.netty.handler.codec.quic.QuicSslContextBuilder;

@ -23,7 +23,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.codec.quic.InsecureQuicTokenHandler;
import io.netty.handler.codec.quic.QuicChannel;
import io.netty.handler.codec.quic.QuicSslContext;

@ -23,7 +23,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.codec.http3.DefaultHttp3DataFrame;
import io.netty.handler.codec.http3.DefaultHttp3HeadersFrame;
import io.netty.handler.codec.http3.Http3;

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC7TCCAdUCFDuGBhl3l5Z++VCLkvaav4yteBonMA0GCSqGSIb3DQEBCwUAMEUx
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjAwMzIzMTYwNzU0WhcNNDcwODA5MTYw
NzU0WjAhMQswCQYDVQQGEwJHQjESMBAGA1UEAwwJcXVpYy50ZWNoMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz5bOL7LD9kiIagcVrZqZ13ZcR0KhMuzs
brqULbZKyqC+uBRgINxYJ7LPnJ4LPYuCt/nAaQ7CLXfKgzAMFu8eIK6UEvZA6+7b
20E4rvOpPbTB/T4JbYZNQKyM9AEwr6j0P6vFgrWT7aBzhkmiqEe5vv/7ZOEGb+Ab
+cvMeszfBbk93nyzKdNaUuh95x7/p0Ow315np2PRuoT0QQnA9zE/9eZ3Jah3cNZn
NuQ6BDHlkegzTV5JhYYblRo/pmt2E9E0ha+NWsRLf3ZJUYhkYR3UqMltEKuLglCO
VWBbPmKd4IZUNIotpKMVQSVb9agNBF49hH9iBhN3fBm7Hp8KBpjJLwIDAQABMA0G
CSqGSIb3DQEBCwUAA4IBAQCo/Rn4spa5XFk0cCoKypP27DxePkGD9rQZk/CY4inV
JV16anZ1pr9yfO61+m3fRKTZq7yxtHRDWxDdROHx9LqV1dXLAmh1ecV9Kn6/796O
EHsOcVB0Lfi9Ili7//oUqlhGNploRuQbgWAXU+Eo1xJRWIXeedhzBSgEOMaQk3Zn
TdYFhP0/Ao/fEdI4VULv1A43ztnZIB2KXWgUQoFT32woL47eWge8LxxVmmH3STtz
nNcGnYxIorCQemDHDzMrvxRWgHxkpFGGqAhkFFyCmhKFPglKwt+yVTx26T8tShID
ISMj0rgVMptmtWKJfzNCvFG52gsuO4w3yGdjgjRRrBDm
-----END CERTIFICATE-----

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDPls4vssP2SIhq
BxWtmpnXdlxHQqEy7OxuupQttkrKoL64FGAg3Fgnss+cngs9i4K3+cBpDsItd8qD
MAwW7x4grpQS9kDr7tvbQTiu86k9tMH9Pglthk1ArIz0ATCvqPQ/q8WCtZPtoHOG
SaKoR7m+//tk4QZv4Bv5y8x6zN8FuT3efLMp01pS6H3nHv+nQ7DfXmenY9G6hPRB
CcD3MT/15nclqHdw1mc25DoEMeWR6DNNXkmFhhuVGj+ma3YT0TSFr41axEt/dklR
iGRhHdSoyW0Qq4uCUI5VYFs+Yp3ghlQ0ii2koxVBJVv1qA0EXj2Ef2IGE3d8Gbse
nwoGmMkvAgMBAAECggEBAMtFkpUmablKgTnBwjqCvs47OlUVK6AgW8x5qwuwC0Cr
ctXyLcc/vJry/1UPdVZIvDHGv+Cf8Qhw2r7nV49FiqzaBmki9aOR+3uRPB4kvr6L
t8Fw8+5pqlAAJu3wFGqN+M44N2mswDPaAAWpKTu7MGmVY+f+aT03qG1MYOiGoISK
gP6DHiinddD38spM2muyCUyFZk9a+aBEfaQzZoU3gc0yB6R/qBOWZ7NIoIUMicku
Zf3L6/06uunyZp+ueR83j1YWbg3JoYKlGAuQtDRF709+MQrim8lKTnfuHiBeZKYZ
GNLSo7lGjrp6ccSyfXmlA36hSfdlrWtZJ4+utZShftECgYEA+NNOFNa1BLfDw3ot
a6L4W6FE45B32bLbnBdg8foyEYrwzHLPFCbws1Z60pNr7NaCHDIMiKVOXvKQa78d
qdWuPUVJ83uVs9GI8tAo00RAvBn6ut9yaaLa8mIv6ZpfU20IgE5sDjB7IBY9tTVd
EDyJcDuKQXzQ48qmEw86wINQMd0CgYEA1ZMdt7yLnpDiYa6M/BuKjp7PWKcRlzVM
BcCEYHA4LJ6xEOH4y9DEx2y5ljwOcXgJhXAfAyGQr7s1xiP/nXurqfmdP8u7bawp
VwuWJ8Vv0ZXITaU0isezG2Dpnseuion3qSraWlmWUlWLVVgKETZmk7cF7VIXa0NT
LFREdObI5HsCgYBUbm8KRyi5Zxm4VNbgtTYM8ZYMmdLxPe2i85PjyAABT+IRncuC
jQwT7n5Swc9XWBpiMuFp5J3JPgmfZgRMwsMS61YClqbfk3Qi4FtaBMjqiu43Rubt
zWL56DNV0xoRlufRkcq8rdq5spJR0L+5aLFCMhHh0taW1QaxZPOMq4IkyQKBgQC3
GetubGzewqPyzuz77ri5URm+jW0dT4ofnE9hRpRCXMK9EJ52TkOGHYZ2cIKJcTno
dpl/27Tpk/ykJJSu9SnVDbVszkOf4OuIPty6uCAHdPxG5Q3ItTCulkVz5QmUqHf1
RlHxB8FCUSilQFdRLmx+03h3X9vID+4soQoXlwxAJQKBgE5SQpN+TG5V+E4zHgNd
6cy6gA5dGDJ0KbsgxJwlKTFA9nIcs2ssBxLY9U4x75EGuqpeVNmq6xwwmPtBs0rp
M3W4zdFrZQ3BneFRW7WbSBbsUSprkJW/p4GXa17GzGUq/MDXlGhNlApP1nknzFvE
xGaH0/H/TZxpLCogVP9npUkj
-----END PRIVATE KEY-----

@ -1,4 +0,0 @@
dependencies {
api project(':netty-handler-codec')
implementation libs.protobuf
}

@ -1,133 +0,0 @@
/*
* Copyright 2015 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:
*
* 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 io.netty.handler.codec.protobuf;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.ExtensionRegistryLite;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.internal.ObjectUtil;
import java.util.List;
/**
* Decodes a received {@link ByteBuf} into a
* <a href="https://github.com/google/protobuf">Google Protocol Buffers</a>
* {@link Message} and {@link MessageLite}. Please note that this decoder must
* be used with a proper {@link ByteToMessageDecoder} such as {@link ProtobufVarint32FrameDecoder}
* or {@link LengthFieldBasedFrameDecoder} if you are using a stream-based
* transport such as TCP/IP. A typical setup for TCP/IP would be:
* <pre>
* {@link ChannelPipeline} pipeline = ...;
*
* // Decoders
* pipeline.addLast("frameDecoder",
* new {@link LengthFieldBasedFrameDecoder}(1048576, 0, 4, 0, 4));
* pipeline.addLast("protobufDecoder",
* new {@link ProtobufDecoder}(MyMessage.getDefaultInstance()));
*
* // Encoder
* pipeline.addLast("frameEncoder", new {@link LengthFieldPrepender}(4));
* pipeline.addLast("protobufEncoder", new {@link ProtobufEncoder}());
* </pre>
* and then you can use a {@code MyMessage} instead of a {@link ByteBuf}
* as a message:
* <pre>
* void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
* MyMessage req = (MyMessage) msg;
* MyMessage res = MyMessage.newBuilder().setText(
* "Did you say '" + req.getText() + "'?").build();
* ch.write(res);
* }
* </pre>
*/
@Sharable
public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf> {
private static final boolean HAS_PARSER;
static {
boolean hasParser = false;
try {
// MessageLite.getParserForType() is not available until protobuf 2.5.0.
MessageLite.class.getDeclaredMethod("getParserForType");
hasParser = true;
} catch (Throwable t) {
// Ignore
}
HAS_PARSER = hasParser;
}
private final MessageLite prototype;
private final ExtensionRegistryLite extensionRegistry;
/**
* Creates a new instance.
*/
public ProtobufDecoder(MessageLite prototype) {
this(prototype, null);
}
public ProtobufDecoder(MessageLite prototype, ExtensionRegistry extensionRegistry) {
this(prototype, (ExtensionRegistryLite) extensionRegistry);
}
public ProtobufDecoder(MessageLite prototype, ExtensionRegistryLite extensionRegistry) {
this.prototype = ObjectUtil.checkNotNull(prototype, "prototype").getDefaultInstanceForType();
this.extensionRegistry = extensionRegistry;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)
throws Exception {
final byte[] array;
final int offset;
final int length = msg.readableBytes();
if (msg.hasArray()) {
array = msg.array();
offset = msg.arrayOffset() + msg.readerIndex();
} else {
array = ByteBufUtil.getBytes(msg, msg.readerIndex(), length, false);
offset = 0;
}
if (extensionRegistry == null) {
if (HAS_PARSER) {
out.add(prototype.getParserForType().parseFrom(array, offset, length));
} else {
out.add(prototype.newBuilderForType().mergeFrom(array, offset, length).build());
}
} else {
if (HAS_PARSER) {
out.add(prototype.getParserForType().parseFrom(
array, offset, length, extensionRegistry));
} else {
out.add(prototype.newBuilderForType().mergeFrom(
array, offset, length, extensionRegistry).build());
}
}
}
}

@ -1,74 +0,0 @@
/*
* Copyright 2015 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:
*
* 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 io.netty.handler.codec.protobuf;
import com.google.protobuf.Message;
import com.google.protobuf.MessageLite;
import com.google.protobuf.MessageLiteOrBuilder;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
import static io.netty.buffer.Unpooled.*;
/**
* Encodes the requested <a href="https://github.com/google/protobuf">Google
* Protocol Buffers</a> {@link Message} and {@link MessageLite} into a
* {@link ByteBuf}. A typical setup for TCP/IP would be:
* <pre>
* {@link ChannelPipeline} pipeline = ...;
*
* // Decoders
* pipeline.addLast("frameDecoder",
* new {@link LengthFieldBasedFrameDecoder}(1048576, 0, 4, 0, 4));
* pipeline.addLast("protobufDecoder",
* new {@link ProtobufDecoder}(MyMessage.getDefaultInstance()));
*
* // Encoder
* pipeline.addLast("frameEncoder", new {@link LengthFieldPrepender}(4));
* pipeline.addLast("protobufEncoder", new {@link ProtobufEncoder}());
* </pre>
* and then you can use a {@code MyMessage} instead of a {@link ByteBuf}
* as a message:
* <pre>
* void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
* MyMessage req = (MyMessage) msg;
* MyMessage res = MyMessage.newBuilder().setText(
* "Did you say '" + req.getText() + "'?").build();
* ch.write(res);
* }
* </pre>
*/
@Sharable
public class ProtobufEncoder extends MessageToMessageEncoder<MessageLiteOrBuilder> {
@Override
protected void encode(ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out)
throws Exception {
if (msg instanceof MessageLite) {
out.add(wrappedBuffer(((MessageLite) msg).toByteArray()));
return;
}
if (msg instanceof MessageLite.Builder) {
out.add(wrappedBuffer(((MessageLite.Builder) msg).build().toByteArray()));
}
}
}

@ -1,119 +0,0 @@
/*
* Copyright 2015 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:
*
* 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 io.netty.handler.codec.protobuf;
import com.google.protobuf.CodedInputStream;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.CorruptedFrameException;
import java.util.List;
/**
* A decoder that splits the received {@link ByteBuf}s dynamically by the
* value of the Google Protocol Buffers
* <a href="https://developers.google.com/protocol-buffers/docs/encoding#varints">Base
* 128 Varints</a> integer length field in the message. For example:
* <pre>
* BEFORE DECODE (302 bytes) AFTER DECODE (300 bytes)
* +--------+---------------+ +---------------+
* | Length | Protobuf Data |----->| Protobuf Data |
* | 0xAC02 | (300 bytes) | | (300 bytes) |
* +--------+---------------+ +---------------+
* </pre>
*
* @see CodedInputStream
*/
public class ProtobufVarint32FrameDecoder extends ByteToMessageDecoder {
// TODO maxFrameLength + safe skip + fail-fast option
// (just like LengthFieldBasedFrameDecoder)
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
throws Exception {
in.markReaderIndex();
int preIndex = in.readerIndex();
int length = readRawVarint32(in);
if (preIndex == in.readerIndex()) {
return;
}
if (length < 0) {
throw new CorruptedFrameException("negative length: " + length);
}
if (in.readableBytes() < length) {
in.resetReaderIndex();
} else {
out.add(in.readRetainedSlice(length));
}
}
/**
* Reads variable length 32bit int from buffer
*
* @return decoded int if buffers readerIndex has been forwarded else nonsense value
*/
private static int readRawVarint32(ByteBuf buffer) {
if (!buffer.isReadable()) {
return 0;
}
buffer.markReaderIndex();
byte tmp = buffer.readByte();
if (tmp >= 0) {
return tmp;
} else {
int result = tmp & 127;
if (!buffer.isReadable()) {
buffer.resetReaderIndex();
return 0;
}
if ((tmp = buffer.readByte()) >= 0) {
result |= tmp << 7;
} else {
result |= (tmp & 127) << 7;
if (!buffer.isReadable()) {
buffer.resetReaderIndex();
return 0;
}
if ((tmp = buffer.readByte()) >= 0) {
result |= tmp << 14;
} else {
result |= (tmp & 127) << 14;
if (!buffer.isReadable()) {
buffer.resetReaderIndex();
return 0;
}
if ((tmp = buffer.readByte()) >= 0) {
result |= tmp << 21;
} else {
result |= (tmp & 127) << 21;
if (!buffer.isReadable()) {
buffer.resetReaderIndex();
return 0;
}
result |= (tmp = buffer.readByte()) << 28;
if (tmp < 0) {
throw new CorruptedFrameException("malformed varint.");
}
}
}
}
return result;
}
}
}

@ -1,88 +0,0 @@
/*
* Copyright 2015 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:
*
* 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 io.netty.handler.codec.protobuf;
import com.google.protobuf.CodedOutputStream;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
/**
* An encoder that prepends the Google Protocol Buffers
* <a href="https://developers.google.com/protocol-buffers/docs/encoding?csw=1#varints">Base
* 128 Varints</a> integer length field. For example:
* <pre>
* BEFORE ENCODE (300 bytes) AFTER ENCODE (302 bytes)
* +---------------+ +--------+---------------+
* | Protobuf Data |-------------->| Length | Protobuf Data |
* | (300 bytes) | | 0xAC02 | (300 bytes) |
* +---------------+ +--------+---------------+
* </pre> *
*
* @see CodedOutputStream
*/
@Sharable
public class ProtobufVarint32LengthFieldPrepender extends MessageToByteEncoder<ByteBuf> {
@Override
protected void encode(
ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
int bodyLen = msg.readableBytes();
int headerLen = computeRawVarint32Size(bodyLen);
out.ensureWritable(headerLen + bodyLen);
writeRawVarint32(out, bodyLen);
out.writeBytes(msg, msg.readerIndex(), bodyLen);
}
/**
* Writes protobuf varint32 to (@link ByteBuf).
* @param out to be written to
* @param value to be written
*/
static void writeRawVarint32(ByteBuf out, int value) {
while (true) {
if ((value & ~0x7F) == 0) {
out.writeByte(value);
return;
} else {
out.writeByte((value & 0x7F) | 0x80);
value >>>= 7;
}
}
}
/**
* Computes size of protobuf varint32 after encoding.
* @param value which is to be encoded.
* @return size of value encoded as protobuf varint32.
*/
static int computeRawVarint32Size(final int value) {
if ((value & (0xffffffff << 7)) == 0) {
return 1;
}
if ((value & (0xffffffff << 14)) == 0) {
return 2;
}
if ((value & (0xffffffff << 21)) == 0) {
return 3;
}
if ((value & (0xffffffff << 28)) == 0) {
return 4;
}
return 5;
}
}

@ -1,23 +0,0 @@
/*
* Copyright 2012 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:
*
* 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.
*/
/**
* Encoder and decoder which transform a
* <a href="https://github.com/google/protobuf">Google Protocol Buffers</a>
* {@link com.google.protobuf.Message} into a
* {@link io.netty.buffer.ByteBuf} and vice versa.
*/
package io.netty.handler.codec.protobuf;

@ -1,8 +0,0 @@
module org.xbib.io.netty.handler.codec.protobuf {
exports io.netty.handler.codec.protobuf;
requires org.xbib.io.netty.buffer;
requires org.xbib.io.netty.channel;
requires org.xbib.io.netty.util;
requires org.xbib.io.netty.handler.codec;
requires com.google.protobuf;
}

@ -3,6 +3,7 @@ module org.xbib.io.netty.handler.codec {
exports io.netty.handler.codec.base64;
exports io.netty.handler.codec.bytes;
exports io.netty.handler.codec.json;
exports io.netty.handler.codec.serialization;
exports io.netty.handler.codec.string;
exports io.netty.handler.codec.xml;
requires org.xbib.io.netty.buffer;

@ -0,0 +1,7 @@
dependencies {
api project(':netty-buffer')
api project(':netty-handler-codec')
api project(':netty-handler-ssl')
api project(':netty-util')
implementation libs.bouncycastle
}

@ -13,12 +13,14 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.ssl;
package io.netty.handler.ssl.bouncycastle;
import io.netty.handler.ssl.PrivateKeyProvider;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMDecryptorProvider;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMKeyPair;
@ -37,60 +39,16 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.Provider;
final class BouncyCastlePemReader {
private static final String BC_PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider";
private static final String BC_PEMPARSER = "org.bouncycastle.openssl.PEMParser";
private static final InternalLogger logger = InternalLoggerFactory.getInstance(BouncyCastlePemReader.class);
private static volatile Throwable unavailabilityCause;
private static volatile Provider bcProvider;
private static volatile boolean attemptedLoading;
public final class BouncyCastlePemReader implements PrivateKeyProvider {
public static boolean hasAttemptedLoading() {
return attemptedLoading;
}
public static boolean isAvailable() {
if (!hasAttemptedLoading()) {
tryLoading();
}
return unavailabilityCause == null;
}
private static final InternalLogger logger = InternalLoggerFactory.getInstance(BouncyCastlePemReader.class);
/**
* @return the cause if unavailable. {@code null} if available.
*/
public static Throwable unavailabilityCause() {
return unavailabilityCause;
}
private static final Provider bcProvider = new BouncyCastleProvider();
private static void tryLoading() {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
try {
ClassLoader classLoader = getClass().getClassLoader();
// Check for bcprov-jdk15on:
Class<Provider> bcProviderClass =
(Class<Provider>) Class.forName(BC_PROVIDER, true, classLoader);
// Check for bcpkix-jdk15on:
Class.forName(BC_PEMPARSER, true, classLoader);
bcProvider = bcProviderClass.getConstructor().newInstance();
logger.debug("Bouncy Castle provider available");
attemptedLoading = true;
} catch (Throwable e) {
logger.debug("Cannot load Bouncy Castle provider", e);
unavailabilityCause = e;
attemptedLoading = true;
}
return null;
}
});
public BouncyCastlePemReader() {
}
/**
@ -101,13 +59,7 @@ final class BouncyCastlePemReader {
* {@code null} if it's not password-protected.
* @return generated {@link PrivateKey}.
*/
public static PrivateKey getPrivateKey(InputStream keyInputStream, String keyPassword) {
if (!isAvailable()) {
if (logger.isDebugEnabled()) {
logger.debug("Bouncy castle provider is unavailable.", unavailabilityCause());
}
return null;
}
public PrivateKey getPrivateKey(InputStream keyInputStream, String keyPassword) {
try {
PEMParser parser = newParser(keyInputStream);
return getPrivateKey(parser, keyPassword);
@ -125,13 +77,7 @@ final class BouncyCastlePemReader {
* {@code null} if it's not password-protected.
* @return generated {@link PrivateKey}.
*/
public static PrivateKey getPrivateKey(File keyFile, String keyPassword) {
if (!isAvailable()) {
if (logger.isDebugEnabled()) {
logger.debug("Bouncy castle provider is unavailable.", unavailabilityCause());
}
return null;
}
public PrivateKey getPrivateKey(File keyFile, String keyPassword) {
try {
PEMParser parser = newParser(keyFile);
return getPrivateKey(parser, keyPassword);
@ -218,6 +164,4 @@ final class BouncyCastlePemReader {
private static PEMParser newParser(InputStream keyInputStream) {
return new PEMParser(new InputStreamReader(keyInputStream, CharsetUtil.US_ASCII));
}
private BouncyCastlePemReader() { }
}

@ -14,7 +14,7 @@
* under the License.
*/
package io.netty.handler.ssl.util;
package io.netty.handler.ssl.bouncycastle;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509CertificateHolder;
@ -33,8 +33,6 @@ import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Date;
import static io.netty.handler.ssl.util.SelfSignedCertificate.newSelfSignedCertificate;
/**
* Generates a self-signed certificate using <a href="https://www.bouncycastle.org/">Bouncy Castle</a>.
*/
@ -57,7 +55,7 @@ final class BouncyCastleSelfSignedCertGenerator {
X509Certificate cert = new JcaX509CertificateConverter().setProvider(PROVIDER).getCertificate(certHolder);
cert.verify(keypair.getPublic());
return newSelfSignedCertificate(fqdn, key, cert);
return SelfSignedCertificate.newSelfSignedCertificate(fqdn, key, cert);
}
private BouncyCastleSelfSignedCertGenerator() { }

@ -14,7 +14,7 @@
* under the License.
*/
package io.netty.handler.ssl.util;
package io.netty.handler.ssl.bouncycastle;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

@ -14,7 +14,7 @@
* under the License.
*/
package io.netty.handler.ssl.util;
package io.netty.handler.ssl.bouncycastle;
import io.netty.util.internal.PlatformDependent;

@ -0,0 +1,13 @@
import io.netty.handler.ssl.PrivateKeyProvider;
import io.netty.handler.ssl.bouncycastle.BouncyCastlePemReader;
module org.xbib.io.netty.handler.ssl.bouncycastle {
exports io.netty.handler.ssl.bouncycastle;
requires org.xbib.io.netty.buffer;
requires org.xbib.io.netty.handler.codec;
requires org.xbib.io.netty.handler.ssl;
requires org.xbib.io.netty.util;
requires org.bouncycastle.pkix;
requires org.bouncycastle.provider;
provides PrivateKeyProvider with BouncyCastlePemReader;
}

@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.ssl.util;
package io.netty.handler.ssl.bouncycastle;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

@ -5,11 +5,10 @@ dependencies {
api project(':netty-handler-codec')
api project(':netty-internal-tcnative')
api project(':netty-channel-unix')
implementation libs.bouncycastle
implementation libs.conscrypt
testImplementation testLibs.mockito.core
testImplementation testLibs.assertj
testImplementation project(':netty-handler')
testImplementation project(':netty-handler-ssl-bouncycastle')
testImplementation (testLibs.amazonCorrettoCrypt) {
artifact {
classifier = osdetector.classifier

@ -15,6 +15,9 @@
*/
package io.netty.handler.ssl;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import java.security.Provider;
import javax.net.ssl.SSLEngine;
/**
@ -22,8 +25,18 @@ import javax.net.ssl.SSLEngine;
*/
final class BouncyCastle {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(BouncyCastle.class);
private static final boolean BOUNCY_CASTLE_ON_CLASSPATH;
private static final String BC_PROVIDER = "org.bouncycastle.jce.provider.BouncyCastleProvider";
private static final String BC_PEMPARSER = "org.bouncycastle.openssl.PEMParser";
private static volatile Throwable unavailabilityCause;
private static volatile boolean attemptedLoading;
static {
boolean bcOnClasspath = false;
try {
@ -38,7 +51,7 @@ final class BouncyCastle {
/**
* Indicates whether or not BouncyCastle is available on the current system.
*/
static boolean isAvailable() {
public static boolean isAvailable() {
return BOUNCY_CASTLE_ON_CLASSPATH;
}
@ -49,6 +62,40 @@ final class BouncyCastle {
return engine.getClass().getPackage().getName().startsWith("org.bouncycastle.jsse.provider");
}
public static boolean isPemParserAvailable() {
if (!hasAttemptedLoading()) {
tryLoading();
}
return unavailabilityCause == null;
}
public static boolean hasAttemptedLoading() {
return attemptedLoading;
}
/**
* @return the cause if unavailable. {@code null} if available.
*/
public static Throwable unavailabilityCause() {
return unavailabilityCause;
}
private static void tryLoading() {
try {
ClassLoader classLoader = BouncyCastle.class.getClassLoader();
// Check for bcprov-jdk15on:
Class<Provider> bcProviderClass = (Class<Provider>) Class.forName(BC_PROVIDER, true, classLoader);
// Check for bcpkix-jdk15on:
Class.forName(BC_PEMPARSER, true, classLoader);
logger.debug("Bouncy Castle provider available");
attemptedLoading = true;
} catch (Throwable e) {
logger.debug("Cannot load Bouncy Castle provider", e);
unavailabilityCause = e;
attemptedLoading = true;
}
}
private BouncyCastle() {
}
}

@ -1,62 +0,0 @@
/*
* Copyright 2021 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:
*
* 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 io.netty.handler.ssl;
import io.netty.util.internal.SuppressJava6Requirement;
import javax.net.ssl.SSLEngine;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@SuppressJava6Requirement(reason = "Usage guarded by java version check")
final class BouncyCastleAlpnSslEngine extends JdkAlpnSslEngine {
BouncyCastleAlpnSslEngine(SSLEngine engine,
@SuppressWarnings("deprecation") JdkApplicationProtocolNegotiator applicationNegotiator,
boolean isServer) {
super(engine, applicationNegotiator, isServer,
new BiConsumer<SSLEngine, AlpnSelector>() {
@Override
public void accept(SSLEngine e, AlpnSelector s) {
BouncyCastleAlpnSslUtils.setHandshakeApplicationProtocolSelector(e, s);
}
},
new BiConsumer<SSLEngine, List<String>>() {
@Override
public void accept(SSLEngine e, List<String> p) {
BouncyCastleAlpnSslUtils.setApplicationProtocols(e, p);
}
});
}
public String getApplicationProtocol() {
return BouncyCastleAlpnSslUtils.getApplicationProtocol(getWrappedEngine());
}
public String getHandshakeApplicationProtocol() {
return BouncyCastleAlpnSslUtils.getHandshakeApplicationProtocol(getWrappedEngine());
}
public void setHandshakeApplicationProtocolSelector(BiFunction<SSLEngine, List<String>, String> selector) {
BouncyCastleAlpnSslUtils.setHandshakeApplicationProtocolSelector(getWrappedEngine(), selector);
}
public BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector() {
return BouncyCastleAlpnSslUtils.getHandshakeApplicationProtocolSelector(getWrappedEngine());
}
}

@ -1,259 +0,0 @@
/*
* Copyright 2021 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:
*
* 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 io.netty.handler.ssl;
import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.SuppressJava6Requirement;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.function.BiFunction;
import static io.netty.handler.ssl.SslUtils.getSSLContext;
@SuppressJava6Requirement(reason = "Usage guarded by java version check")
final class BouncyCastleAlpnSslUtils {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(BouncyCastleAlpnSslUtils.class);
private static final Method SET_PARAMETERS;
private static final Method GET_PARAMETERS;
private static final Method SET_APPLICATION_PROTOCOLS;
private static final Method GET_APPLICATION_PROTOCOL;
private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL;
private static final Method SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR;
private static final Method GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR;
private static final Class BC_APPLICATION_PROTOCOL_SELECTOR;
private static final Method BC_APPLICATION_PROTOCOL_SELECTOR_SELECT;
static {
Class bcSslEngine;
Method getParameters;
Method setParameters;
Method setApplicationProtocols;
Method getApplicationProtocol;
Method getHandshakeApplicationProtocol;
Method setHandshakeApplicationProtocolSelector;
Method getHandshakeApplicationProtocolSelector;
Method bcApplicationProtocolSelectorSelect;
Class bcApplicationProtocolSelector;
try {
bcSslEngine = Class.forName("org.bouncycastle.jsse.BCSSLEngine");
final Class testBCSslEngine = bcSslEngine;
bcApplicationProtocolSelector =
Class.forName("org.bouncycastle.jsse.BCApplicationProtocolSelector");
final Class testBCApplicationProtocolSelector = bcApplicationProtocolSelector;
bcApplicationProtocolSelectorSelect = AccessController.doPrivileged(
new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCApplicationProtocolSelector.getMethod("select", Object.class, List.class);
}
});
SSLContext context = getSSLContext("BCJSSE");
SSLEngine engine = context.createSSLEngine();
getParameters = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCSslEngine.getMethod("getParameters");
}
});
final Object bcSslParameters = getParameters.invoke(engine);
final Class<?> bCSslParametersClass = bcSslParameters.getClass();
setParameters = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCSslEngine.getMethod("setParameters", bCSslParametersClass);
}
});
setParameters.invoke(engine, bcSslParameters);
setApplicationProtocols = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return bCSslParametersClass.getMethod("setApplicationProtocols", String[].class);
}
});
setApplicationProtocols.invoke(bcSslParameters, new Object[]{EmptyArrays.EMPTY_STRINGS});
getApplicationProtocol = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCSslEngine.getMethod("getApplicationProtocol");
}
});
getApplicationProtocol.invoke(engine);
getHandshakeApplicationProtocol = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCSslEngine.getMethod("getHandshakeApplicationProtocol");
}
});
getHandshakeApplicationProtocol.invoke(engine);
setHandshakeApplicationProtocolSelector =
AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCSslEngine.getMethod("setBCHandshakeApplicationProtocolSelector",
testBCApplicationProtocolSelector);
}
});
getHandshakeApplicationProtocolSelector =
AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return testBCSslEngine.getMethod("getBCHandshakeApplicationProtocolSelector");
}
});
getHandshakeApplicationProtocolSelector.invoke(engine);
} catch (Throwable t) {
logger.error("Unable to initialize BouncyCastleAlpnSslUtils.", t);
setParameters = null;
getParameters = null;
setApplicationProtocols = null;
getApplicationProtocol = null;
getHandshakeApplicationProtocol = null;
setHandshakeApplicationProtocolSelector = null;
getHandshakeApplicationProtocolSelector = null;
bcApplicationProtocolSelectorSelect = null;
bcApplicationProtocolSelector = null;
}
SET_PARAMETERS = setParameters;
GET_PARAMETERS = getParameters;
SET_APPLICATION_PROTOCOLS = setApplicationProtocols;
GET_APPLICATION_PROTOCOL = getApplicationProtocol;
GET_HANDSHAKE_APPLICATION_PROTOCOL = getHandshakeApplicationProtocol;
SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = setHandshakeApplicationProtocolSelector;
GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getHandshakeApplicationProtocolSelector;
BC_APPLICATION_PROTOCOL_SELECTOR_SELECT = bcApplicationProtocolSelectorSelect;
BC_APPLICATION_PROTOCOL_SELECTOR = bcApplicationProtocolSelector;
}
private BouncyCastleAlpnSslUtils() {
}
static String getApplicationProtocol(SSLEngine sslEngine) {
try {
return (String) GET_APPLICATION_PROTOCOL.invoke(sslEngine);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
static void setApplicationProtocols(SSLEngine engine, List<String> supportedProtocols) {
String[] protocolArray = supportedProtocols.toArray(EmptyArrays.EMPTY_STRINGS);
try {
Object bcSslParameters = GET_PARAMETERS.invoke(engine);
SET_APPLICATION_PROTOCOLS.invoke(bcSslParameters, new Object[]{protocolArray});
SET_PARAMETERS.invoke(engine, bcSslParameters);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
if (PlatformDependent.javaVersion() >= 9) {
JdkAlpnSslUtils.setApplicationProtocols(engine, supportedProtocols);
}
}
static String getHandshakeApplicationProtocol(SSLEngine sslEngine) {
try {
return (String) GET_HANDSHAKE_APPLICATION_PROTOCOL.invoke(sslEngine);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
static void setHandshakeApplicationProtocolSelector(
SSLEngine engine, final BiFunction<SSLEngine, List<String>, String> selector) {
try {
Object selectorProxyInstance = Proxy.newProxyInstance(
BouncyCastleAlpnSslUtils.class.getClassLoader(),
new Class[]{BC_APPLICATION_PROTOCOL_SELECTOR},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("select")) {
try {
return selector.apply((SSLEngine) args[0], (List<String>) args[1]);
} catch (ClassCastException e) {
throw new RuntimeException("BCApplicationProtocolSelector select method " +
"parameter of invalid type.", e);
}
} else {
throw new UnsupportedOperationException(String.format("Method '%s' not supported.",
method.getName()));
}
}
});
SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(engine, selectorProxyInstance);
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
@SuppressWarnings("unchecked")
static BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector(SSLEngine engine) {
try {
final Object selector = GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(engine);
return new BiFunction<SSLEngine, List<String>, String>() {
@Override
public String apply(SSLEngine sslEngine, List<String> strings) {
try {
return (String) BC_APPLICATION_PROTOCOL_SELECTOR_SELECT.invoke(selector, sslEngine,
strings);
} catch (Exception e) {
throw new RuntimeException("Could not call getHandshakeApplicationProtocolSelector", e);
}
}
};
} catch (UnsupportedOperationException ex) {
throw ex;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}

@ -15,8 +15,6 @@
*/
package io.netty.handler.ssl;
import io.netty.util.internal.PlatformDependent;
import javax.net.ssl.SSLEngine;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@ -30,25 +28,8 @@ final class Conscrypt {
private static final Method IS_CONSCRYPT_SSLENGINE;
static {
Method isConscryptSSLEngine = null;
if ((PlatformDependent.javaVersion() >= 8 &&
// Only works on Java14 and earlier for now
// See https://github.com/google/conscrypt/issues/838
PlatformDependent.javaVersion() < 15) || PlatformDependent.isAndroid()) {
try {
Class<?> providerClass = Class.forName("org.conscrypt.OpenSSLProvider", true,
PlatformDependent.getClassLoader(ConscryptAlpnSslEngine.class));
providerClass.newInstance();
Class<?> conscryptClass = Class.forName("org.conscrypt.Conscrypt", true,
PlatformDependent.getClassLoader(ConscryptAlpnSslEngine.class));
isConscryptSSLEngine = conscryptClass.getMethod("isConscrypt", SSLEngine.class);
} catch (Throwable ignore) {
// ignore
}
}
IS_CONSCRYPT_SSLENGINE = isConscryptSSLEngine;
// disable Conscrypt
IS_CONSCRYPT_SSLENGINE = null;
}
/**

@ -1,212 +0,0 @@
/*
* 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:
*
* 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 io.netty.handler.ssl;
import static io.netty.handler.ssl.SslUtils.toSSLHandshakeException;
import static io.netty.util.internal.ObjectUtil.checkNotNull;
import static java.lang.Math.min;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectionListener;
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLException;
import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.SystemPropertyUtil;
import org.conscrypt.AllocatedBuffer;
import org.conscrypt.BufferAllocator;
import org.conscrypt.Conscrypt;
import org.conscrypt.HandshakeListener;
/**
* A {@link JdkSslEngine} that uses the Conscrypt provider or SSL with ALPN.
*/
abstract class ConscryptAlpnSslEngine extends JdkSslEngine {
private static final boolean USE_BUFFER_ALLOCATOR = SystemPropertyUtil.getBoolean(
"io.netty.handler.ssl.conscrypt.useBufferAllocator", true);
static ConscryptAlpnSslEngine newClientEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator) {
return new ClientEngine(engine, alloc, applicationNegotiator);
}
static ConscryptAlpnSslEngine newServerEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator) {
return new ServerEngine(engine, alloc, applicationNegotiator);
}
private ConscryptAlpnSslEngine(SSLEngine engine, ByteBufAllocator alloc, List<String> protocols) {
super(engine);
// Configure the Conscrypt engine to use Netty's buffer allocator. This is a trade-off of memory vs
// performance.
//
// If no allocator is provided, the engine will internally allocate a direct buffer of max packet size in
// order to optimize JNI calls (this happens the first time it is provided a non-direct buffer from the
// application).
//
// Alternatively, if an allocator is provided, no internal buffer will be created and direct buffers will be
// retrieved from the allocator on-demand.
if (USE_BUFFER_ALLOCATOR) {
Conscrypt.setBufferAllocator(engine, new BufferAllocatorAdapter(alloc));
}
// Set the list of supported ALPN protocols on the engine.
Conscrypt.setApplicationProtocols(engine, protocols.toArray(EmptyArrays.EMPTY_STRINGS));
}
/**
* Calculates the maximum size of the encrypted output buffer required to wrap the given plaintext bytes. Assumes
* as a worst case that there is one TLS record per buffer.
*
* @param plaintextBytes the number of plaintext bytes to be wrapped.
* @param numBuffers the number of buffers that the plaintext bytes are spread across.
* @return the maximum size of the encrypted output buffer required for the wrap operation.
*/
final int calculateOutNetBufSize(int plaintextBytes, int numBuffers) {
// Assuming a max of one frame per component in a composite buffer.
return calculateSpace(plaintextBytes, numBuffers, Integer.MAX_VALUE);
}
/**
* Calculate the space necessary in an out buffer to hold the max size that the given
* plaintextBytes and numBuffers can produce when encrypted. Assumes as a worst case
* that there is one TLS record per buffer.
* @param plaintextBytes the number of plaintext bytes to be wrapped.
* @param numBuffers the number of buffers that the plaintext bytes are spread across.
* @return the maximum size of the encrypted output buffer required for the wrap operation.
*/
final int calculateRequiredOutBufSpace(int plaintextBytes, int numBuffers) {
return calculateSpace(plaintextBytes, numBuffers, Conscrypt.maxEncryptedPacketLength());
}
private int calculateSpace(int plaintextBytes, int numBuffers, long maxPacketLength) {
long maxOverhead = (long) Conscrypt.maxSealOverhead(getWrappedEngine()) * numBuffers;
return (int) min(maxPacketLength, plaintextBytes + maxOverhead);
}
final SSLEngineResult unwrap(ByteBuffer[] srcs, ByteBuffer[] dests) throws SSLException {
return Conscrypt.unwrap(getWrappedEngine(), srcs, dests);
}
private static final class ClientEngine extends ConscryptAlpnSslEngine {
private final ProtocolSelectionListener protocolListener;
ClientEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator) {
super(engine, alloc, applicationNegotiator.protocols());
// Register for completion of the handshake.
Conscrypt.setHandshakeListener(engine, new HandshakeListener() {
@Override
public void onHandshakeFinished() throws SSLException {
selectProtocol();
}
});
protocolListener = checkNotNull(applicationNegotiator
.protocolListenerFactory().newListener(this, applicationNegotiator.protocols()),
"protocolListener");
}
private void selectProtocol() throws SSLException {
String protocol = Conscrypt.getApplicationProtocol(getWrappedEngine());
try {
protocolListener.selected(protocol);
} catch (Throwable e) {
throw toSSLHandshakeException(e);
}
}
}
private static final class ServerEngine extends ConscryptAlpnSslEngine {
private final ProtocolSelector protocolSelector;
ServerEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator) {
super(engine, alloc, applicationNegotiator.protocols());
// Register for completion of the handshake.
Conscrypt.setHandshakeListener(engine, new HandshakeListener() {
@Override
public void onHandshakeFinished() throws SSLException {
selectProtocol();
}
});
protocolSelector = checkNotNull(applicationNegotiator.protocolSelectorFactory()
.newSelector(this,
new LinkedHashSet<String>(applicationNegotiator.protocols())),
"protocolSelector");
}
private void selectProtocol() throws SSLException {
try {
String protocol = Conscrypt.getApplicationProtocol(getWrappedEngine());
protocolSelector.select(protocol != null ? Collections.singletonList(protocol)
: Collections.<String>emptyList());
} catch (Throwable e) {
throw toSSLHandshakeException(e);
}
}
}
private static final class BufferAllocatorAdapter extends BufferAllocator {
private final ByteBufAllocator alloc;
BufferAllocatorAdapter(ByteBufAllocator alloc) {
this.alloc = alloc;
}
@Override
public AllocatedBuffer allocateDirectBuffer(int capacity) {
return new BufferAdapter(alloc.directBuffer(capacity));
}
}
private static final class BufferAdapter extends AllocatedBuffer {
private final ByteBuf nettyBuffer;
private final ByteBuffer buffer;
BufferAdapter(ByteBuf nettyBuffer) {
this.nettyBuffer = nettyBuffer;
buffer = nettyBuffer.nioBuffer(0, nettyBuffer.capacity());
}
@Override
public ByteBuffer nioBuffer() {
return buffer;
}
@Override
public AllocatedBuffer retain() {
nettyBuffer.retain();
return this;
}
@Override
public AllocatedBuffer release() {
nettyBuffer.release();
return this;
}
}
}

@ -26,7 +26,7 @@ import javax.net.ssl.SSLEngine;
*/
@Deprecated
public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicationProtocolNegotiator {
private static final boolean AVAILABLE = Conscrypt.isAvailable() ||
private static final boolean AVAILABLE =
JdkAlpnSslUtils.supportsAlpn() ||
BouncyCastle.isAvailable();
@ -129,17 +129,6 @@ public final class JdkAlpnApplicationProtocolNegotiator extends JdkBaseApplicati
@Override
public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc,
JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) {
if (Conscrypt.isEngineSupported(engine)) {
return isServer ? ConscryptAlpnSslEngine.newServerEngine(engine, alloc, applicationNegotiator)
: ConscryptAlpnSslEngine.newClientEngine(engine, alloc, applicationNegotiator);
}
if (BouncyCastle.isInUse(engine)) {
return new BouncyCastleAlpnSslEngine(engine, applicationNegotiator, isServer);
}
// ALPN support was recently backported to Java8 as
// https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8230977.
// Because of this lets not do a Java version runtime check but just depend on if the required methods are
// present
if (JdkAlpnSslUtils.supportsAlpn()) {
return new JdkAlpnSslEngine(engine, applicationNegotiator, isServer);
}

@ -33,15 +33,15 @@ import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSele
import static io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
@SuppressJava6Requirement(reason = "Usage guarded by java version check")
class JdkAlpnSslEngine extends JdkSslEngine {
public class JdkAlpnSslEngine extends JdkSslEngine {
private final ProtocolSelectionListener selectionListener;
private final AlpnSelector alpnSelector;
final class AlpnSelector implements BiFunction<SSLEngine, List<String>, String> {
public final class AlpnSelector implements BiFunction<SSLEngine, List<String>, String> {
private final ProtocolSelector selector;
private boolean called;
AlpnSelector(ProtocolSelector selector) {
public AlpnSelector(ProtocolSelector selector) {
this.selector = selector;
}
@ -80,7 +80,7 @@ class JdkAlpnSslEngine extends JdkSslEngine {
}
}
JdkAlpnSslEngine(SSLEngine engine,
public JdkAlpnSslEngine(SSLEngine engine,
@SuppressWarnings("deprecation") JdkApplicationProtocolNegotiator applicationNegotiator,
boolean isServer, BiConsumer<SSLEngine, AlpnSelector> setHandshakeApplicationProtocolSelector,
BiConsumer<SSLEngine, List<String>> setApplicationProtocols) {
@ -98,7 +98,7 @@ class JdkAlpnSslEngine extends JdkSslEngine {
}
}
JdkAlpnSslEngine(SSLEngine engine,
public JdkAlpnSslEngine(SSLEngine engine,
@SuppressWarnings("deprecation") JdkApplicationProtocolNegotiator applicationNegotiator,
boolean isServer) {
this(engine, applicationNegotiator, isServer,

@ -0,0 +1,12 @@
package io.netty.handler.ssl;
import java.io.File;
import java.io.InputStream;
import java.security.PrivateKey;
public interface PrivateKeyProvider {
PrivateKey getPrivateKey(File privateKeyFile, String keyPassword);
PrivateKey getPrivateKey(InputStream inputStream, String keyPassword);
}

@ -31,6 +31,7 @@ import io.netty.util.internal.PlatformDependent;
import java.io.BufferedInputStream;
import java.security.Provider;
import java.util.ServiceLoader;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.crypto.Cipher;
@ -102,6 +103,16 @@ public abstract class SslContext {
}
}
static final List<PrivateKeyProvider> privateKeyProviders;
static {
try {
privateKeyProviders = ServiceLoader.load(PrivateKeyProvider.class).stream()
.map(ServiceLoader.Provider::get).toList();
} catch (Exception e) {
throw new IllegalStateException("unable to load private key providers");
}
}
private final boolean startTls;
private final AttributeMap attributes = new DefaultAttributeMap();
private static final String OID_PKCS5_PBES2 = "1.2.840.113549.1.5.13";
@ -1156,9 +1167,9 @@ public abstract class SslContext {
return null;
}
// try BC first, if this fail fallback to original key extraction process
if (tryBouncyCastle && BouncyCastlePemReader.isAvailable()) {
PrivateKey pk = BouncyCastlePemReader.getPrivateKey(keyFile, keyPassword);
// look for private key providers, if this fail fallback to original key extraction process
for (PrivateKeyProvider privateKeyProvider : privateKeyProviders) {
PrivateKey pk = privateKeyProvider.getPrivateKey(keyFile, keyPassword);
if (pk != null) {
return pk;
}
@ -1176,18 +1187,18 @@ public abstract class SslContext {
return null;
}
// try BC first, if this fail fallback to original key extraction process
if (BouncyCastlePemReader.isAvailable()) {
// look for private key providers, if this fail fallback to original key extraction process
for (PrivateKeyProvider privateKeyProvider : privateKeyProviders) {
if (!keyInputStream.markSupported()) {
// We need an input stream that supports resetting, in case BouncyCastle fails to read.
keyInputStream = new BufferedInputStream(keyInputStream);
}
keyInputStream.mark(1048576); // Be able to reset up to 1 MiB of data.
PrivateKey pk = BouncyCastlePemReader.getPrivateKey(keyInputStream, keyPassword);
PrivateKey pk = privateKeyProvider.getPrivateKey(keyInputStream, keyPassword);
if (pk != null) {
return pk;
}
// BouncyCastle could not read the key. Reset the input stream in case the input position changed.
// private key provider could not read the key. Reset the input stream in case the input position changed.
keyInputStream.reset();
}

@ -253,55 +253,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
return ((ReferenceCountedOpenSslEngine) engine).jdkCompatibilityMode;
}
},
CONSCRYPT(true, COMPOSITE_CUMULATOR) {
@Override
SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int len, ByteBuf out) throws SSLException {
int nioBufferCount = in.nioBufferCount();
int writerIndex = out.writerIndex();
final SSLEngineResult result;
if (nioBufferCount > 1) {
/*
* Use a special unwrap method without additional memory copies.
*/
try {
handler.singleBuffer[0] = toByteBuffer(out, writerIndex, out.writableBytes());
result = ((ConscryptAlpnSslEngine) handler.engine).unwrap(
in.nioBuffers(in.readerIndex(), len),
handler.singleBuffer);
} finally {
handler.singleBuffer[0] = null;
}
} else {
result = handler.engine.unwrap(toByteBuffer(in, in.readerIndex(), len),
toByteBuffer(out, writerIndex, out.writableBytes()));
}
out.writerIndex(writerIndex + result.bytesProduced());
return result;
}
@Override
ByteBuf allocateWrapBuffer(SslHandler handler, ByteBufAllocator allocator,
int pendingBytes, int numComponents) {
return allocator.directBuffer(
((ConscryptAlpnSslEngine) handler.engine).calculateOutNetBufSize(pendingBytes, numComponents));
}
@Override
int calculateRequiredOutBufSpace(SslHandler handler, int pendingBytes, int numComponents) {
return ((ConscryptAlpnSslEngine) handler.engine)
.calculateRequiredOutBufSpace(pendingBytes, numComponents);
}
@Override
int calculatePendingData(SslHandler handler, int guess) {
return guess;
}
@Override
boolean jdkCompatibilityMode(SSLEngine engine) {
return true;
}
},
JDK(false, MERGE_CUMULATOR) {
@Override
SSLEngineResult unwrap(SslHandler handler, ByteBuf in, int len, ByteBuf out) throws SSLException {
@ -360,8 +311,7 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
};
static SslEngineType forEngine(SSLEngine engine) {
return engine instanceof ReferenceCountedOpenSslEngine ? TCNATIVE :
engine instanceof ConscryptAlpnSslEngine ? CONSCRYPT : JDK;
return engine instanceof ReferenceCountedOpenSslEngine ? TCNATIVE : JDK;
}
SslEngineType(boolean wantsDirectBuffer, Cumulator cumulator) {

@ -45,15 +45,11 @@ public enum SslProvider {
*/
@SuppressWarnings("deprecation")
public static boolean isAlpnSupported(final SslProvider provider) {
switch (provider) {
case JDK:
return JdkAlpnApplicationProtocolNegotiator.isAlpnSupported();
case OPENSSL:
case OPENSSL_REFCNT:
return OpenSsl.isAlpnSupported();
default:
throw new Error("Unknown SslProvider: " + provider);
}
return switch (provider) {
case JDK -> true;
case OPENSSL, OPENSSL_REFCNT -> OpenSsl.isAlpnSupported();
default -> throw new Error("Unknown SslProvider: " + provider);
};
}
/**

@ -1,4 +1,5 @@
module org.xbib.io.netty.handler.ssl {
uses io.netty.handler.ssl.PrivateKeyProvider;
exports io.netty.handler.ssl;
exports io.netty.handler.ssl.util;
exports io.netty.handler.ssl.ocsp;
@ -8,7 +9,4 @@ module org.xbib.io.netty.handler.ssl {
requires org.xbib.io.netty.handler.codec;
requires org.xbib.io.netty.internal.tcnative;
requires org.xbib.io.netty.util;
requires org.bouncycastle.pkix;
requires org.bouncycastle.provider;
requires org.conscrypt;
}

@ -32,7 +32,7 @@ import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Promise;
import org.junit.jupiter.api.AfterAll;

@ -21,7 +21,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

@ -1,90 +0,0 @@
/*
* Copyright 2016 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:
*
* 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 io.netty.handler.ssl;
import java.security.Provider;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLSessionContext;
@DisabledIf("checkConscryptDisabled")
public class ConscryptJdkSslEngineInteropTest extends SSLEngineTest {
public ConscryptJdkSslEngineInteropTest() {
super(false);
}
static boolean checkConscryptDisabled() {
return !Conscrypt.isAvailable();
}
@Override
protected SslProvider sslClientProvider() {
return SslProvider.JDK;
}
@Override
protected SslProvider sslServerProvider() {
return SslProvider.JDK;
}
@Override
protected Provider clientSslContextProvider() {
return Java8SslTestUtils.conscryptProvider();
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled /* Does the JDK support a "max certificate chain length"? */
@Override
public void testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(SSLEngineTestParam param)
throws Exception {
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled /* Does the JDK support a "max certificate chain length"? */
@Override
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(SSLEngineTestParam param)
throws Exception {
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
protected boolean mySetupMutualAuthServerIsValidServerException(Throwable cause) {
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
return super.mySetupMutualAuthServerIsValidServerException(cause) || causedBySSLException(cause);
}
@Override
protected void invalidateSessionsAndAssert(SSLSessionContext context) {
// Not supported by conscrypt
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Disabled due a conscrypt bug")
@Override
public void testInvalidSNIIsIgnoredAndNotThrow(SSLEngineTestParam param) throws Exception {
super.testInvalidSNIIsIgnoredAndNotThrow(param);
}
}

@ -1,219 +0,0 @@
/*
* Copyright 2019 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:
*
* 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 io.netty.handler.ssl;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSessionContext;
import java.security.Provider;
import java.util.ArrayList;
import java.util.List;
import static io.netty.handler.ssl.OpenSslTestUtils.checkShouldUseKeyManagerFactory;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
@DisabledIf("checkConscryptDisabled")
public class ConscryptOpenSslEngineInteropTest extends ConscryptSslEngineTest {
@Override
protected List<SSLEngineTestParam> newTestParams() {
List<SSLEngineTestParam> params = super.newTestParams();
List<SSLEngineTestParam> testParams = new ArrayList<SSLEngineTestParam>();
for (SSLEngineTestParam param: params) {
testParams.add(new OpenSslEngineTestParam(true, param));
//testParams.add(new OpenSslEngineTestParam(false, param));
}
return testParams;
}
@BeforeAll
public static void checkOpenssl() {
OpenSsl.ensureAvailability();
}
@Override
protected SslProvider sslClientProvider() {
return SslProvider.JDK;
}
@Override
protected SslProvider sslServerProvider() {
return SslProvider.OPENSSL;
}
@Override
protected Provider serverSslContextProvider() {
return null;
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("TODO: Make this work with Conscrypt")
@Override
public void testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(SSLEngineTestParam param) {
super.testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("TODO: Make this work with Conscrypt")
@Override
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(SSLEngineTestParam param) {
super.testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(param);
}
@Override
protected boolean mySetupMutualAuthServerIsValidClientException(Throwable cause) {
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
return super.mySetupMutualAuthServerIsValidClientException(cause) || causedBySSLException(cause);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testMutualAuthInvalidIntermediateCASucceedWithOptionalClientAuth(SSLEngineTestParam param)
throws Exception {
checkShouldUseKeyManagerFactory();
super.testMutualAuthInvalidIntermediateCASucceedWithOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testMutualAuthInvalidIntermediateCAFailWithOptionalClientAuth(SSLEngineTestParam param)
throws Exception {
checkShouldUseKeyManagerFactory();
super.testMutualAuthInvalidIntermediateCAFailWithOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testMutualAuthInvalidIntermediateCAFailWithRequiredClientAuth(SSLEngineTestParam param)
throws Exception {
checkShouldUseKeyManagerFactory();
super.testMutualAuthInvalidIntermediateCAFailWithRequiredClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionAfterHandshakeKeyManagerFactory(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSessionAfterHandshakeKeyManagerFactory(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionAfterHandshakeKeyManagerFactoryMutualAuth(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSessionAfterHandshakeKeyManagerFactoryMutualAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSupportedSignatureAlgorithms(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSupportedSignatureAlgorithms(param);
}
@Override
protected boolean mySetupMutualAuthServerIsValidServerException(Throwable cause) {
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
return super.mySetupMutualAuthServerIsValidServerException(cause) || causedBySSLException(cause);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionLocalWhenNonMutualWithKeyManager(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSessionLocalWhenNonMutualWithKeyManager(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionLocalWhenNonMutualWithoutKeyManager(SSLEngineTestParam param) throws Exception {
// This only really works when the KeyManagerFactory is supported as otherwise we not really know when
// we need to provide a cert.
assumeTrue(OpenSsl.supportsKeyManagerFactory());
super.testSessionLocalWhenNonMutualWithoutKeyManager(param);
}
@Override
protected void invalidateSessionsAndAssert(SSLSessionContext context) {
// Not supported by conscrypt
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionCache(SSLEngineTestParam param) throws Exception {
assumeTrue(OpenSsl.isSessionCacheSupported());
super.testSessionCache(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionCacheTimeout(SSLEngineTestParam param) throws Exception {
assumeTrue(OpenSsl.isSessionCacheSupported());
super.testSessionCacheTimeout(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionCacheSize(SSLEngineTestParam param) throws Exception {
assumeTrue(OpenSsl.isSessionCacheSupported());
super.testSessionCacheSize(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Disabled due a conscrypt bug")
@Override
public void testInvalidSNIIsIgnoredAndNotThrow(SSLEngineTestParam param) throws Exception {
super.testInvalidSNIIsIgnoredAndNotThrow(param);
}
@Override
protected SSLEngine wrapEngine(SSLEngine engine) {
return Java8SslTestUtils.wrapSSLEngineForTesting(engine);
}
@SuppressWarnings("deprecation")
@Override
protected SslContext wrapContext(SSLEngineTestParam param, SslContext context) {
if (context instanceof OpenSslContext) {
if (param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
}
// Explicit enable the session cache as its disabled by default on the client side.
((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
}

@ -1,99 +0,0 @@
/*
* Copyright 2018 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:
*
* 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 io.netty.handler.ssl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLSessionContext;
import java.security.Provider;
@DisabledIf("checkConscryptDisabled")
public class ConscryptSslEngineTest extends SSLEngineTest {
static boolean checkConscryptDisabled() {
return !Conscrypt.isAvailable();
}
public ConscryptSslEngineTest() {
super(false);
}
@Override
protected SslProvider sslClientProvider() {
return SslProvider.JDK;
}
@Override
protected SslProvider sslServerProvider() {
return SslProvider.JDK;
}
@Override
protected Provider clientSslContextProvider() {
return Java8SslTestUtils.conscryptProvider();
}
@Override
protected Provider serverSslContextProvider() {
return Java8SslTestUtils.conscryptProvider();
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled /* Does the JDK support a "max certificate chain length"? */
@Override
public void testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(SSLEngineTestParam param) {
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled /* Does the JDK support a "max certificate chain length"? */
@Override
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(SSLEngineTestParam param) {
}
@Override
protected void invalidateSessionsAndAssert(SSLSessionContext context) {
// Not supported by conscrypt
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Possible Conscrypt bug")
@Override
public void testSessionCacheTimeout(SSLEngineTestParam param) throws Exception {
// Skip
// https://github.com/google/conscrypt/issues/851
}
@Disabled("Not supported")
@Override
public void testRSASSAPSS(SSLEngineTestParam param) {
// skip
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Disabled due a conscrypt bug")
@Override
public void testInvalidSNIIsIgnoredAndNotThrow(SSLEngineTestParam param) throws Exception {
super.testInvalidSNIIsIgnoredAndNotThrow(param);
}
}

@ -16,14 +16,11 @@
package io.netty.handler.ssl;
import org.conscrypt.OpenSSLProvider;
import javax.net.ssl.SNIMatcher;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import java.io.InputStream;
import java.security.Provider;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
@ -45,10 +42,6 @@ public final class Java8SslTestUtils {
parameters.setSNIMatchers(Collections.singleton(matcher));
}
static Provider conscryptProvider() {
return new OpenSSLProvider();
}
/**
* Wraps the given {@link SSLEngine} to add extra tests while executing methods if possible / needed.
*/

@ -1,105 +0,0 @@
/*
* 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:
*
* 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 io.netty.handler.ssl;
import java.security.Provider;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLSessionContext;
@DisabledIf("checkConscryptDisabled")
public class JdkConscryptSslEngineInteropTest extends SSLEngineTest {
static boolean checkConscryptDisabled() {
return !Conscrypt.isAvailable();
}
public JdkConscryptSslEngineInteropTest() {
super(false);
}
@Override
protected SslProvider sslClientProvider() {
return SslProvider.JDK;
}
@Override
protected SslProvider sslServerProvider() {
return SslProvider.JDK;
}
@Override
protected Provider serverSslContextProvider() {
return Java8SslTestUtils.conscryptProvider();
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("TODO: Make this work with Conscrypt")
@Override
public void testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(SSLEngineTestParam param)
throws Exception {
super.testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("TODO: Make this work with Conscrypt")
@Override
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(SSLEngineTestParam param)
throws Exception {
super.testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(param);
}
@Override
protected boolean mySetupMutualAuthServerIsValidClientException(Throwable cause) {
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
return super.mySetupMutualAuthServerIsValidClientException(cause) || causedBySSLException(cause);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Ignore due bug in Conscrypt")
@Override
public void testHandshakeSession(SSLEngineTestParam param) throws Exception {
// Ignore as Conscrypt does not correctly return the local certificates while the TrustManager is invoked.
// See https://github.com/google/conscrypt/issues/634
}
@Override
protected void invalidateSessionsAndAssert(SSLSessionContext context) {
// Not supported by conscrypt
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("Possible Conscrypt bug")
@Override
public void testSessionCacheTimeout(SSLEngineTestParam param) {
// Skip
// https://github.com/google/conscrypt/issues/851
}
@Disabled("Not supported")
@Override
public void testRSASSAPSS(SSLEngineTestParam param) {
// skip
}
}

@ -21,7 +21,7 @@ import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelector;
import io.netty.handler.ssl.JdkApplicationProtocolNegotiator.ProtocolSelectorFactory;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import java.security.Provider;
import io.netty.util.internal.EmptyArrays;

@ -28,7 +28,7 @@ import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalEventLoopGroup;
import io.netty.channel.local.LocalServerChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.internal.tcnative.CertificateCompressionAlgo;
import io.netty.util.concurrent.Promise;
import org.junit.jupiter.api.Assertions;

@ -1,191 +0,0 @@
/*
* Copyright 2019 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:
*
* 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 io.netty.handler.ssl;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.condition.DisabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSessionContext;
import java.security.Provider;
import java.util.ArrayList;
import java.util.List;
import static io.netty.handler.ssl.OpenSslTestUtils.checkShouldUseKeyManagerFactory;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
@DisabledIf("checkConscryptDisabled")
public class OpenSslConscryptSslEngineInteropTest extends ConscryptSslEngineTest {
@Override
protected List<SSLEngineTestParam> newTestParams() {
List<SSLEngineTestParam> params = super.newTestParams();
List<SSLEngineTestParam> testParams = new ArrayList<SSLEngineTestParam>();
for (SSLEngineTestParam param: params) {
testParams.add(new OpenSslEngineTestParam(true, param));
testParams.add(new OpenSslEngineTestParam(false, param));
}
return testParams;
}
@BeforeAll
public static void checkOpenssl() {
OpenSsl.ensureAvailability();
}
@Override
protected SslProvider sslClientProvider() {
return SslProvider.OPENSSL;
}
@Override
protected SslProvider sslServerProvider() {
return SslProvider.JDK;
}
@Override
protected Provider clientSslContextProvider() {
return null;
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("TODO: Make this work with Conscrypt")
@Override
public void testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(SSLEngineTestParam param) {
super.testMutualAuthValidClientCertChainTooLongFailOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Disabled("TODO: Make this work with Conscrypt")
@Override
public void testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(SSLEngineTestParam param) {
super.testMutualAuthValidClientCertChainTooLongFailRequireClientAuth(param);
}
@Override
protected boolean mySetupMutualAuthServerIsValidClientException(Throwable cause) {
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
return super.mySetupMutualAuthServerIsValidClientException(cause) || causedBySSLException(cause);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testMutualAuthInvalidIntermediateCASucceedWithOptionalClientAuth(SSLEngineTestParam param)
throws Exception {
checkShouldUseKeyManagerFactory();
super.testMutualAuthInvalidIntermediateCASucceedWithOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testMutualAuthInvalidIntermediateCAFailWithOptionalClientAuth(SSLEngineTestParam param)
throws Exception {
checkShouldUseKeyManagerFactory();
super.testMutualAuthInvalidIntermediateCAFailWithOptionalClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testMutualAuthInvalidIntermediateCAFailWithRequiredClientAuth(SSLEngineTestParam param)
throws Exception {
checkShouldUseKeyManagerFactory();
super.testMutualAuthInvalidIntermediateCAFailWithRequiredClientAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionAfterHandshakeKeyManagerFactoryMutualAuth(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSessionAfterHandshakeKeyManagerFactoryMutualAuth(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSupportedSignatureAlgorithms(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSupportedSignatureAlgorithms(param);
}
@Override
protected boolean mySetupMutualAuthServerIsValidServerException(Throwable cause) {
// TODO(scott): work around for a JDK issue. The exception should be SSLHandshakeException.
return super.mySetupMutualAuthServerIsValidServerException(cause) || causedBySSLException(cause);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionLocalWhenNonMutualWithKeyManager(SSLEngineTestParam param) throws Exception {
checkShouldUseKeyManagerFactory();
super.testSessionLocalWhenNonMutualWithKeyManager(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionCache(SSLEngineTestParam param) throws Exception {
assumeTrue(OpenSsl.isSessionCacheSupported());
super.testSessionCache(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionCacheTimeout(SSLEngineTestParam param) throws Exception {
assumeTrue(OpenSsl.isSessionCacheSupported());
super.testSessionCacheTimeout(param);
}
@MethodSource("newTestParams")
@ParameterizedTest
@Override
public void testSessionCacheSize(SSLEngineTestParam param) throws Exception {
assumeTrue(OpenSsl.isSessionCacheSupported());
super.testSessionCacheSize(param);
}
@Override
protected void invalidateSessionsAndAssert(SSLSessionContext context) {
// Not supported by conscrypt
}
@Override
protected SSLEngine wrapEngine(SSLEngine engine) {
return Java8SslTestUtils.wrapSSLEngineForTesting(engine);
}
@SuppressWarnings("deprecation")
@Override
protected SslContext wrapContext(SSLEngineTestParam param, SslContext context) {
if (context instanceof OpenSslContext) {
if (param instanceof OpenSslEngineTestParam) {
((OpenSslContext) context).setUseTasks(((OpenSslEngineTestParam) param).useTasks);
}
// Explicit enable the session cache as its disabled by default on the client side.
((OpenSslContext) context).sessionContext().setSessionCacheEnabled(true);
}
return context;
}
}

@ -20,7 +20,7 @@ import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.internal.tcnative.SSL;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.EmptyArrays;

@ -32,7 +32,7 @@ import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.ImmediateEventExecutor;

@ -37,7 +37,7 @@ import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.ssl.util.SimpleTrustManagerFactory;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;

@ -23,7 +23,7 @@ import java.security.PrivateKey;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.ReferenceCountUtil;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

@ -17,7 +17,7 @@
package io.netty.handler.ssl;
import io.netty.util.CharsetUtil;
import org.bouncycastle.util.encoders.Hex;
import io.netty.handler.ssl.util.Hex;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;

@ -27,7 +27,7 @@ import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalEventLoopGroup;
import io.netty.channel.local.LocalServerChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;

@ -35,7 +35,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.ssl.util.SimpleTrustManagerFactory;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;
@ -49,7 +49,6 @@ import io.netty.util.internal.EmptyArrays;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.StringUtil;
import io.netty.util.internal.SystemPropertyUtil;
import org.conscrypt.OpenSSLProvider;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
@ -4040,10 +4039,6 @@ public abstract class SSLEngineTest {
if (param.combo() != ProtocolCipherCombo.tlsv12()) {
return;
}
/*
* At the moment master key logging is not supported for conscrypt
*/
assumeFalse(serverSslContextProvider() instanceof OpenSSLProvider);
/*
* The JDK SSL engine master key retrieval relies on being able to set field access to true.

@ -28,7 +28,7 @@ import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.ssl.util.SimpleTrustManagerFactory;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Promise;

@ -26,7 +26,7 @@ import io.netty.channel.local.LocalAddress;
import io.netty.channel.local.LocalChannel;
import io.netty.channel.local.LocalServerChannel;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.Mapping;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Promise;

@ -53,7 +53,7 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.DomainNameMapping;
import io.netty.util.DomainNameMappingBuilder;
import io.netty.util.Mapping;

@ -16,7 +16,7 @@
package io.netty.handler.ssl;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.CharsetUtil;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;

@ -28,7 +28,7 @@ import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.ssl.util.SimpleTrustManagerFactory;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Promise;

@ -48,7 +48,7 @@ import io.netty.handler.codec.CodecException;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.UnsupportedMessageTypeException;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.AbstractReferenceCounted;
import io.netty.util.IllegalReferenceCountException;
import io.netty.util.ReferenceCountUtil;

@ -38,7 +38,7 @@ import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import org.hamcrest.CoreMatchers;

@ -0,0 +1,22 @@
package io.netty.handler.ssl.util;
/**
* Exception thrown if an attempt is made to decode invalid data, or some other failure occurs.
*/
public class DecoderException
extends IllegalStateException
{
private Throwable cause;
DecoderException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
public Throwable getCause()
{
return cause;
}
}

@ -0,0 +1,22 @@
package io.netty.handler.ssl.util;
/**
* Exception thrown if an attempt is made to encode invalid data, or some other failure occurs.
*/
public class EncoderException
extends IllegalStateException
{
private Throwable cause;
EncoderException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}
public Throwable getCause()
{
return cause;
}
}

@ -0,0 +1,214 @@
package io.netty.handler.ssl.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Utility class for converting hex data to bytes and back again.
*/
public class Hex
{
private static final HexEncoder encoder = new HexEncoder();
public static String toHexString(
byte[] data)
{
return toHexString(data, 0, data.length);
}
public static String toHexString(
byte[] data,
int off,
int length)
{
byte[] encoded = encode(data, off, length);
return fromByteArray(encoded);
}
/**
* Convert an array of 8 bit characters into a string.
*
* @param bytes 8 bit characters.
* @return resulting String.
*/
public static String fromByteArray(byte[] bytes)
{
return new String(asCharArray(bytes));
}
/**
* Do a simple conversion of an array of 8 bit characters into a string.
*
* @param bytes 8 bit characters.
* @return resulting String.
*/
public static char[] asCharArray(byte[] bytes)
{
char[] chars = new char[bytes.length];
for (int i = 0; i != chars.length; i++)
{
chars[i] = (char)(bytes[i] & 0xff);
}
return chars;
}
/**
* encode the input data producing a Hex encoded byte array.
*
* @return a byte array containing the Hex encoded data.
*/
public static byte[] encode(
byte[] data)
{
return encode(data, 0, data.length);
}
/**
* encode the input data producing a Hex encoded byte array.
*
* @return a byte array containing the Hex encoded data.
*/
public static byte[] encode(
byte[] data,
int off,
int length)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try
{
encoder.encode(data, off, length, bOut);
}
catch (Exception e)
{
throw new EncoderException("exception encoding Hex string: " + e.getMessage(), e);
}
return bOut.toByteArray();
}
/**
* Hex encode the byte data writing it to the given output stream.
*
* @return the number of bytes produced.
*/
public static int encode(
byte[] data,
OutputStream out)
throws IOException
{
return encoder.encode(data, 0, data.length, out);
}
/**
* Hex encode the byte data writing it to the given output stream.
*
* @return the number of bytes produced.
*/
public static int encode(
byte[] data,
int off,
int length,
OutputStream out)
throws IOException
{
return encoder.encode(data, off, length, out);
}
/**
* decode the Hex encoded input data. It is assumed the input data is valid.
*
* @return a byte array representing the decoded data.
*/
public static byte[] decode(
byte[] data)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try
{
encoder.decode(data, 0, data.length, bOut);
}
catch (Exception e)
{
throw new DecoderException("exception decoding Hex data: " + e.getMessage(), e);
}
return bOut.toByteArray();
}
/**
* decode the Hex encoded String data - whitespace will be ignored.
*
* @return a byte array representing the decoded data.
*/
public static byte[] decode(
String data)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
try
{
encoder.decode(data, bOut);
}
catch (Exception e)
{
throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
}
return bOut.toByteArray();
}
/**
* decode the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
*
* @return the number of bytes produced.
*/
public static int decode(
String data,
OutputStream out)
throws IOException
{
return encoder.decode(data, out);
}
/**
* Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
* considered an error.
*
* @return a byte array representing the decoded data.
*/
public static byte[] decodeStrict(String str)
{
try
{
return encoder.decodeStrict(str, 0, str.length());
}
catch (Exception e)
{
throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
}
}
/**
* Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
* considered an error.
*
* @return a byte array representing the decoded data.
*/
public static byte[] decodeStrict(String str, int off, int len)
{
try
{
return encoder.decodeStrict(str, off, len);
}
catch (Exception e)
{
throw new DecoderException("exception decoding Hex string: " + e.getMessage(), e);
}
}
}

@ -0,0 +1,279 @@
package io.netty.handler.ssl.util;
import java.io.IOException;
import java.io.OutputStream;
/**
* A streaming Hex encoder.
*/
public class HexEncoder
{
protected final byte[] encodingTable =
{
(byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
(byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
};
/*
* set up the decoding table.
*/
protected final byte[] decodingTable = new byte[128];
protected void initialiseDecodingTable()
{
for (int i = 0; i < decodingTable.length; i++)
{
decodingTable[i] = (byte)0xff;
}
for (int i = 0; i < encodingTable.length; i++)
{
decodingTable[encodingTable[i]] = (byte)i;
}
decodingTable['A'] = decodingTable['a'];
decodingTable['B'] = decodingTable['b'];
decodingTable['C'] = decodingTable['c'];
decodingTable['D'] = decodingTable['d'];
decodingTable['E'] = decodingTable['e'];
decodingTable['F'] = decodingTable['f'];
}
public HexEncoder()
{
initialiseDecodingTable();
}
public int encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff) throws IOException
{
int inPos = inOff;
int inEnd = inOff + inLen;
int outPos = outOff;
while (inPos < inEnd)
{
int b = inBuf[inPos++] & 0xFF;
outBuf[outPos++] = encodingTable[b >>> 4];
outBuf[outPos++] = encodingTable[b & 0xF];
}
return outPos - outOff;
}
public int getEncodedLength(int inputLength)
{
return inputLength * 2;
}
public int getMaxDecodedLength(int inputLength)
{
return inputLength / 2;
}
/**
* encode the input data producing a Hex output stream.
*
* @return the number of bytes produced.
*/
public int encode(byte[] buf, int off, int len, OutputStream out)
throws IOException
{
if (len < 0)
{
return 0;
}
byte[] tmp = new byte[72];
int remaining = len;
while (remaining > 0)
{
int inLen = Math.min(36, remaining);
int outLen = encode(buf, off, inLen, tmp, 0);
out.write(tmp, 0, outLen);
off += inLen;
remaining -= inLen;
}
return len * 2;
}
private static boolean ignore(
char c)
{
return c == '\n' || c =='\r' || c == '\t' || c == ' ';
}
/**
* decode the Hex encoded byte data writing it to the given output stream,
* whitespace characters will be ignored.
*
* @return the number of bytes produced.
*/
public int decode(
byte[] data,
int off,
int length,
OutputStream out)
throws IOException
{
byte b1, b2;
int outLen = 0;
byte[] buf = new byte[36];
int bufOff = 0;
int end = off + length;
while (end > off)
{
if (!ignore((char)data[end - 1]))
{
break;
}
end--;
}
int i = off;
while (i < end)
{
while (i < end && ignore((char)data[i]))
{
i++;
}
b1 = decodingTable[data[i++]];
while (i < end && ignore((char)data[i]))
{
i++;
}
b2 = decodingTable[data[i++]];
if ((b1 | b2) < 0)
{
throw new IOException("invalid characters encountered in Hex data");
}
buf[bufOff++] = (byte)((b1 << 4) | b2);
if (bufOff == buf.length)
{
out.write(buf);
bufOff = 0;
}
outLen++;
}
if (bufOff > 0)
{
out.write(buf, 0, bufOff);
}
return outLen;
}
/**
* decode the Hex encoded String data writing it to the given output stream,
* whitespace characters will be ignored.
*
* @return the number of bytes produced.
*/
public int decode(
String data,
OutputStream out)
throws IOException
{
byte b1, b2;
int length = 0;
byte[] buf = new byte[36];
int bufOff = 0;
int end = data.length();
while (end > 0)
{
if (!ignore(data.charAt(end - 1)))
{
break;
}
end--;
}
int i = 0;
while (i < end)
{
while (i < end && ignore(data.charAt(i)))
{
i++;
}
b1 = decodingTable[data.charAt(i++)];
while (i < end && ignore(data.charAt(i)))
{
i++;
}
b2 = decodingTable[data.charAt(i++)];
if ((b1 | b2) < 0)
{
throw new IOException("invalid characters encountered in Hex string");
}
buf[bufOff++] = (byte)((b1 << 4) | b2);
if (bufOff == buf.length)
{
out.write(buf);
bufOff = 0;
}
length++;
}
if (bufOff > 0)
{
out.write(buf, 0, bufOff);
}
return length;
}
byte[] decodeStrict(String str, int off, int len) throws IOException
{
if (null == str)
{
throw new NullPointerException("'str' cannot be null");
}
if (off < 0 || len < 0 || off > (str.length() - len))
{
throw new IndexOutOfBoundsException("invalid offset and/or length specified");
}
if (0 != (len & 1))
{
throw new IOException("a hexadecimal encoding must have an even number of characters");
}
int resultLen = len >>> 1;
byte[] result = new byte[resultLen];
int strPos = off;
for (int i = 0; i < resultLen; ++i)
{
byte b1 = decodingTable[str.charAt(strPos++)];
byte b2 = decodingTable[str.charAt(strPos++)];
int n = (b1 << 4) | b2;
if (n < 0)
{
throw new IOException("invalid characters encountered in Hex string");
}
result[i] = (byte)n;
}
return result;
}
}

@ -0,0 +1,23 @@
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,507B8C32AA1248741BE35C3E115A01AE
EkV7f25iEgIVRvUzTnqBWvCMY40BUsuGfC2l8SdhT02Q1i9u6Ra+BTtUTCJ4+uSn
WJb7sG20dYJ9FZFQeRpEyN8SeltE1wSzP78Xc414OAEVzVqx46bTVozAg0tXiMo0
D2rrGuBsLJRAx/aKOV4/vp9PMxKm0my/PvRlzdgC8RKGlAaOdLwMGqNk2SZ0XwTV
N/v18WK9gDBKebEv+Wx1Y7fuIFa+T/lvMMSzTSuS5l5NuAaF3960lWLH0wJ7nRBy
MsuWZE5I/zzcNpUQmVmTz3DWfXtWjTLEmttX57a7xJhQlYReruy51fW/Crx+6kVw
hKAflvQDjeLaGLSNpnCNniGc8riqKS8LCIZ63k1v2qskfSzdzx0Q2E0szQ6su5P+
ZnEy4Ln82xkv4swxAHGpsWalBELPY9XkQmeqf5B46Hs+pcaub7lPFlHZOr4RmHC9
KlhBuktpxxZdLpVg7zXx7B2PnY2cpbMl1J1yRjuj1VCt4P2C0afZcEdQ3V9Gao6J
f+vWqawqxbDTgT3fgZRyOu5PbGn8ONhcCHm4t6xrROOh9aqnRDGK2uFC6Qg2k8bS
HIU6Ye+RP8ZI0u7wnDk5O+f3RnosPL0FVz/ibvc9P7A66AGtX5Do1tPT6UFg7NGW
fzDdg1Iu8MZZMLZ0KjmmlvLrFgL8SHjJuTYms2MzkKBQWz1MhzPmbzEdjEH4jwku
ssiIzj9CySb9rEpC+XfJe7YSwkjtAk2g8l/2/D2UNGM+Pg7G87hmMvMTYhGZvVQD
+5RLn3PYg8YdyT89dUaI+Zc2BzUtAPuuBb0Wa/+lthNCtO9LIPZjrlkvAq6de91y
Zp7lZpvtkstoo05xp3kCVJ0WnYOiMD0eMxNJX0v35KLcYsPRTYMV3G8Swky8WklN
w5BAmZEkrFXSZ7jrFqM2g+gaL28Ftb0hRMr4nAfOSyRjjrsDW02j6mrUBSrgrldt
JnhDM1tFjIe2gEe/G/u2LBS/XOg2PBd39giOOsagWsdhaQaJLeemNb7jGf5Hw24C
z17LNxzD/JyLYKF9Ybw74w3HZwO7zu8gl22pQ55RsYxcNNdcES2S2Qjln38C7aQT
pRNg0oloJQa/Elr11uZf8Xf58VCAf+38H0CCO7qpOT3g1jbwDjjy3dk32BUuQyUR
-----END DSA PRIVATE KEY-----

@ -0,0 +1,23 @@
-----BEGIN DSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9A7E15E6414511DE
j95ay1Nc4912pJocqsPi3R/1RS8KJYB0JGXEvPtfMBSiQcUMA7jSNzRwb/uBhaRA
CI7yWVRis4d2nZH7ZtC5QNrzHKITsiAzJV56yXnFL3mgOyoACkdeGpWcCD2zSrQt
Z9kdokFfma7VO+Aa7sC/mIfOvzXcINIldnEAbA7Kc5W1S34CNEHJLpn4eSIpwoW6
OmFtT1b3pxpYD2dENFbd92b7v5lYO5TxOA6J13KYFs69kPS9dqQDqrKP0SMMuXEw
BBLDvNCRR8urKrv0Ip7LXyLtrHdVw5QVWJWow52y5BzTsOFfgpiAwWqCMjcM1rVE
SrPSELjRolUpZqjc7p81HHftAekFxRt2KK+hcHYWTqVxWw2GrmL48TyZ56WZexYg
V06SNdX0Jchch7OWIiV4zXhl/j/QM0Sqc5w5dGe+ohqUYOpcnpp9eqvaubV6fexi
mLIsY4Yj+sxm4C5cFF5wL6stWyZjf48jMj388vQZgbPsggnqnXlj87qa9vLov6K6
SYGFlO+O08O7LG1mZ6DOK3+UusHVNmf6Dq14QtqSyHz4pjYji1RlVebBWn9ohlBK
ndhC7AcHstzJXKrtI5MFtCmXuEYs2XSIEjfDyYYg2nhsbfMKTeS/IwOnMTqfcKHd
rvz5jt41UAoT5FGRMfugLpqXweqemyQ5HF8XvgpLWXAGncdS4RzhfBdePY3JgksT
HtkZGLzW1JIg4OU788JuWs0tRlW1CUaW4vPLh39JrcSrDKNaEslmTejLzdXaqGLf
8qaaG0BUXADDryy+KVR5dzn4NB83WKomiUY33bdpe9+Alq1FIiLvY3V9SDom4D0t
I0+7iqPPHxzww5elHqaxrdGNylpYynBSWIFRPufYJOmmxo865sYEHtGDZ1iVCMfb
9R6CVi/AeYvoEkBpPciPnoRupN77tNr5DWv2CJkZfeYzC5M0T4oy/cwY/6GPtGNd
DHdIhDtIGQ3LjZutu9KP39eu+n+vAc3d47BiMdBopCJL3J1yr0QlrR0IMAFneIab
iadl/UbVj1wBK24FmgGtj0BaBvRKSZMyzUEsoROVsAHxIXGZArJhPO/11QKvcDza
QuNwlEQBsji4HpUPGfXJXErzEqiLwe3VJRkASkzS1GRRdkS32LEQUGZ95+XM0zxA
-----END DSA PRIVATE KEY-----

@ -0,0 +1,20 @@
-----BEGIN DSA PRIVATE KEY-----
MIIDVQIBAAKCAQEAwHxpSuEsmW2VtqU0YXzkz+brp7eJLy/QlyfOOy6Os5UkguAc
50CZpbEOj0Qe3YhasgeDwnJ8ByEXvWEBsz5PN6OWrgJ475yAiPF0/HZoPe9q/6Gh
6A650mMS2Ha9KoPaOTESQ0ngoYFymSsA5VTr+us7q1ypRhgFvfJtWC3vQ2i6MCak
K3MZazYAAOlE7Wgh/ZQOg2/gzBOs86XM/cJX+oKk6A/kqUhO7VyvWmBzi3y14OPv
//DiHPVnmIEvfTWTqvaAItKDrbGl48XqY/hhJphHx70focNchb3fyJ1Bw2+zhBF8
i0Sf/x3RrugiUz8JWtkZWaRvOLQCfDKL9oQoNwIhAI7LCjl4OIQ+A+Ki+HGBQeub
L01lqKx+IhRynByB1ZEBAoIBAFVDof3OuP0i9ntn+dXRmxs6FNurdLzQvRDEkdHF
cRddKfCd++nDm9LSN/yUZhyOoSwYtAkXWUpJANvmf5+M647UHGlH0oh9FdpXPLRr
4vHnz6xGTSyxvD6YpN+r9ZPFQ1d6m9e9EKS+nPipmmSdE3aQUCVfpX9M4vTRVRwS
mcJ3RtC69J5lfTMYM/0hS84BngJ6zVr+MDOV3puV/yqziWis5Q2C7IAndO8PeA3h
vhdhzbRtO2ziKQn3WcVBCSK8OnO24XpOB7vV2rTOW9tx6o3CzqyiOSznmLAtJUXA
mK3GZRBzv07SDs8atzG3BACtObnGvnx+EeZ29D2AKFnlZ4UCggEAVpOjrxuIzrQ5
rRaAPLfMYzusSinp2jmA5m5cnST2+VOtZitToCQKmhW6B7T7dFuoGJoXu3RFMtst
KSg+uAyj+rKfJYIp0VJKuyquyVHcb9hBvp6HMqo682HYX7vMs3x9TqDz3RE/cydF
XvTfVjdmRxo3jt5WtbS0izcyNx7RwkPQ5SJPoygDrxPjN4R5KULptf3GnHcGqB09
hbM/SIOvunK37jmX8vH1iPdY4msfRo1/uuUKs+0mI3R8c76zvmDf+lySff1UdbY8
6Un2zQp0djM/8Bt6ivL39TuQ1mWs813/IbkYje5ub1MvswkP1hKPM/uAT44b7qWu
9ag7dsYAkgIgV1Hn5aSk43Nbz6nWpcJyqt2wkh2qL2RCD6dBeZO8yLA=
-----END DSA PRIVATE KEY-----

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDYrLtMlZzoe2BP
iCURF3So5XNLfsOLcAVERXXjnxqX6Mex55WdJiy6uWTFKbRHWJdbWELdZxVl5+GX
pMv3OdkKZt+19ZdSfByv6bB5RNdZOEGnKOHSY2XdnzYnF5JBaWEx0fvtvIPZOUlW
DWgsQzJk1UQhu+XnBc7P1hHYNvwsVNOR+HD9LGebDy+UcfiL34XwAyBdHUsbcIr8
hltABcj6vNbqOLndpU86DxU9z9b1PDmkFVfisElhpDEhpxmTCwI22Us1GC8D81LM
ZzMlbWSzTfNPEuqNzJYGiFt/XPwPkPPyVvti0XWPBQpwzJFFUX5xKsOGERolELRT
0yNQYznFAgMBAAECggEAOFR/xSNITbB1k3ejm1PrwlUUqlXkZIXU+LDOO0UL1t5v
vDKm1Not2sWECzYSZlID132UtJauG3YzUgdH95gUcv3XvyiAFLOriZhJht181vcn
KlwYiWfJ/dn8bCFWpqbM2/TpeB8AcCLSjAqkQI2ftlMziUmeNXdvEt1mej2hRay1
ULfoxlC0mftNRQptD5gBFzrc47O4mVpVEQt4yS3Qyzp2/9ds9UkhaCIFpXPVCalZ
ds7R+bDDP+wiYTkUcd8fvelaMkD3Wcy8DedGRShhILZvBYTDdWcpJ7+e5EkNlEq4
+Ys4Y/u6aFDJD53g3zCaJhatmdAZcct2MMmWH1vewQKBgQD3Y2S245cad1D9AqYD
ChZGp95EfRo3EzXk4VkE50bjZXjHq9fD8T0CWEZGWQZrXJCR+vBpEURy0mrPD8se
QQ0Q5+I27RadtfPnMd6ry9nDGMPxyd/10vzU6LazzLNE+uf9ljF1RHZu1iDAvInR
r1cQGbn/wKBF6BurPPIXABZEuQKBgQDgN6JHbIfDzHKhwEoUTvRrYJsTXqplD+h0
Whg+kSQyhtKdlpINFOoEj8FUNJvTjG8les1aoajyWIqikVdvHto/mrxrSIeRkEmt
X+KG+5ld2n466tzv1DmVcIGXSrBrH3lA0i6R8Ly26FLSqw0Z12fx5GUUa1qaVRqo
rwcrIZovbQKBgHa2mojs9AC+Sv3uvG1u9LuZKJ7jDaZqMI2R2d7xgOH0Op5Ohy6+
39D1PVvasqroc3Op4J36rEcRVDHi2Uy+WJ/JNpO2+AhcXRuPodP88ZWel8C6aB+V
zL/6oFntnAU5BgR5g2hLny2W0YbLsrMNmhDe15O0AvUo6cYla+K/pu/5AoGACr/g
EdiMMcDthf+4DX0zjqpVBPq25J18oYdoPierOpjoJBIB8oqcJZfWxvi2t8+1zHA0
xDGX7fZ8vwqEzJkIEaCTg/k4NqxaO+uq6pnJYoyFHMIB0aW1FQsNy3kTOC+MGqV5
Ahoukf5VajA1MpX3L8upZO84qsmFu6yYhWLZB4kCgYBlgSD5G4q6rX4ELa3XG61h
fDtu75IYEsjWm4vgJzHjeYT2xPIm9OFFYXjPghto0f1oH37ODD3DoXmsnmddgpmn
tH7aRWWHsSpB5zVgftV4urNCIsm87LWw8mvUGgCwYV1CtCX8warKokfeoA2ltz4u
oeuUzo98hN+aKRU5RO6Bmg==
-----END PRIVATE KEY-----

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDEkT/UNROZLBfR
LvmGv6TmP7IftPH3P2KQ16sCBEzsISy51kA7IdIEBsAEho3gTgqRsJwNpGQeRJTD
PFDEDDB5MJnxKsUkN2PAEC1VF5CD0E7grqrUXOn/sqNbE9jDe7sziVaZmV35EnNj
f+RW55mHtoFNW8pDb35v14oKiB4mp31fkFn84xeAwG+stAhY50qcmcSQ9woAx7vK
vv8CTZhEYeHrnd8FkLYF1RZkn2tvcLvS7RIUQOBIY9IZa+hf3AMJE0khJsQgO1Z3
eOLIlq2tOW4VVzb84M/9te9L/KXQcjWkEhX0qbITSRLd7Oqgs8/bUMY9oq7gMWSj
IXkzMGiLAgMBAAECggEAPlEyJCujh/bzogy7bN3LAHgHF4g9Ab6ll/fXri8A2Ad4
b34eJOEG/OHK9GRYDFmRfji4cJbCatohM3gmvtCCeZlP5KZDk8S/qf827/glh7R9
nTuiyuqeAMN4iIJVQTwz0BXlT5LQuQsBa/T6xhZslRrmCUllaVWqhviVOduHe4cl
ftK5D1IlsBElxeWSXy5Cbu7FhWz4dbJjduuXKfbEPpoHxk/Nsg7bhDh86kOablUG
FraqvMg9GfeOcFlP+PJV4Xlu02GmY7mYBgRnlccErDSFd6QvZIFcUW5hca+B937i
FiToQ+uvYaNeD3IZ/t8PDKIb2APxzRrwj3J5j+fcYQKBgQDtk95rH2xdncYlqYsg
3Lbvo/HZUv38uqjgUofMV87ijcRpKc8l7pbeg/xG5IIYwICaIVuc5idHJGpc63GC
ZZSxwPPfREU+9cZsf3Fn2pTP1Knf9gfjLW7UZi5SdJ7F6S6zMQawlTjKsvvvXTvE
vIeO5BU07jhhEE5W4W+aJ5AycQKBgQDTz0pJn5VkzigdMvyki+QKuF+DZUWUuesL
TzjPm6xblBARUL1vpOLUsm4IR7anOH/6UWQY7+ojTyo1S3QqfLVP4SMkqAEaP8j8
Qixy9KD0Ma2vUF2FaE55lHcnJbGjo8gd4elry1oLRsl26HKi8/fXAZfMkwASYr92
KaY6PjyQuwKBgCXs+w6iv4vaSe1tOVaPpWxwAYWt5/nWWmslAaSvR8mG1BntoLHv
eoofC8DNba9B28W/GX7chtymhYw70az9RlVx9fxoS52XYoujdJkdna/nxQ6Jmgy8
Dfs+LJrhHw99AAV/CBBcYeqJ1AoMGiR37DP1WSVP+hQUpEzeRBCZzD0hAoGAJHS5
RJLDE+an4N61vVyWk4HIbsUvhLm7SucH0DPrJpgFa/WJpX2rzRApACPXvFBtNphr
sh8ZHZqymRmzlNyCGI2XjuebyPjRjxmUrPSN/3nNey9J6XxahXKYT5SdTp0SBJKt
qnAFv4sfgefgU0vKjKcpiXyDtqZobd4dTkkIA6ECgYB2QkGweLbB+Auus5KcuWt1
iG1qJIv5cna0VGaUkhwYDsCBgTM5i8wpdl1UvCVWuETU8+FO19jBx5X/Gv6TwKE8
vWY83HzGvoIcHpXOHlfMFlZnY1Fl6RO5V1XlbzJzjButqdiGEG1oqygVbpn8ui9i
c0AdsCH2P2Ef28bVgiwYBA==
-----END PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIJddddGJqvzACAggA
MB0GCWCGSAFlAwQBKgQQ0SIWTVvrPdriTZKRZuWb7QSCBNDoU6Y1qeABJPV726zv
gymMUAZdfxqBlbS865q3RlnHO2xm4082l7VwFK9QGVFIxURx4QU76qjhsoJfmGiv
pAvkZCln90iguY0ssnAzBFi8B2AgBcZrIG1OMQpR0L/hjveIvorg4/vb5rIgyIdn
+3u7I077yF3udPnt0jUYcfonzsOglwa3FVun2yqM7/gAzGkQu/CeOshSQaJ9EV/0
ZQmemVCJbmm7I2iEq6RUXgBW8hPjo1cwuQznE2jBx3SlhQoSrWTGdy9WXLqwxrHX
e2W6LqaXqFOrgmtPz5h3JzhUh0AGtNS0SsB6AsyKD548NP7NGRlmbUXo8iQXS/Z6
QmwIh1bt67VecHKka17ZYGBQt/2/zcQddRvlVeT3SbRgGCGQeDnXWhfJIMb6bFDe
vdr0L44zyW6/OwYQU1RNBFclrjtFIAVQEI8L/BVciowsJ7J6W2UsxR3hrLtPjO9o
zH7bp85TlSaSZW3T2HfAPu6isMECzVzZ+x8qnpuDoHjIOZID630Amw1v2/gfFZTA
mXn4gld1JKUBrvBfXN4cjTDC1eO1zvzEZB6VZw6ePhggWijySoLUO+E/mJpP5mNA
4OQSMxNQ+UcZH+MT093cOJeOleOlbc9weIeNhXgONX/pbnq1gV23tN3mZbGIJojY
GZoH32ft76x+DxrMZrjtjL7dOUL5QjjUlpJ6319aaLFf6Z/AIWXBOyHC1i9l+lKv
2hpZ/YS+eyExy/axwx0J4eH+7csDrz63F1A9hRrIxx2wKdYjsKWR21Hb/mst/U4z
1MGWeIX1hqAe7VYUiZBZldnOYdmNG/sRtcHMrW9zqkJUuW25YjuGm9gVbIVw/YOY
lOd/9puSiRzuJLX02p1o1PN17+5rzMkpE4bVpd6Pvbex+oMSUVvd+V845bCB0qCt
eA5TUBi2gbLvj7TqoA+C0zoXGtXD1Ea/7hnmwC5Gzl4m6YmvZRpxXA6Mzs62CYgt
KWJSiuuTfSop/2B8+nnkZQAGKxvXkpFLXyGXfP+Y22X00BB43GtMB2ZPzmliQ+TA
bFePkPBoXqytJR9vrbWJIIzcxaYWTwqN1vZJzIgdFjK2yOiqopGi0sG0zjn8xryv
ZqraVnTznb5xUGojezIbtWwMNIRrmNU9b1HMtpMsnuNNPQy/UhgDqgM6bQOh23Q8
7DQRqXGlNqJc22ne1E/gN5IxdbrgoE6jnnoAzOlFRD1XdhLBW3hb2DpzTFAveDKi
ti5UHucXrURILD1ee9CtyKcYQajr3XNp0tMJJQFCybnX+zOgH6HXsrfXFT8CghDt
aeo7TBfhVC4MadvggLNWmyjyGJd7KeDGuiXVDsWr9icesDCUgC/T2Lq58boT70BM
T14pABDOqSylJdL0qWV7m8yZ0fNAkrTB/+2qdi4B632NIQ+ZGRZy5WK09jRUtVm0
+EZMoX6pAjBQR4RwgbyNTJDIt/tXOopBAoEjRc8qWotlJozc3RkpGBHgT8POZT60
Jxu3QaE9rJq8kfrO/e5gq7zDy4AK/ck1+aVxfiwM1D7vPvFt0WwztdvEGz3Hjpkv
qtj8ePpDBrBo1ISJqVmTi3pvRz/kuKFYvoYdWq2Wluz1NGZdCETwNYIao1/hfP52
NydFNZTmdrun22ezf6yVGiCaEw==
-----END ENCRYPTED PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,F87E93E4D6D3AA4C23CF2593880E5D35
P0LhS1vVJlorlzjMMMMx6eFwe7gs9Ykkx18AgsHpjrydrgZFmQexuiphFWQX4AZ+
tpPw6ogIul973o9hev5vOapskon4lx5C8taBbB00XZj3F1K98r+Tm6IFYN0DnExX
/qJqKHxsgdKDAJwdetobcI5p8bXzws0+RNqNYZ7QbtMKbfG5IWCt4Y40H9WHGrwe
pmExDsnKajY9N7+R1D4imj0eGrm779WKs5bYNmdYwLEoCNy41VpBeu2IgeQ5ZSfx
f8PnOu5/mxFOjP/gm+4kLoguvOTo3J5QHQ7bj3cnHgRhDX/CFbID1wjAQaz8utaU
CWnvt/4IyRrhhOIuyq54egTTYfnTBv4U6E0W0I6ODr/nJJ+2xkUntcsPwbmcGxlr
Lo560EbhrLOwgDU8YR0wcw/lXFA95TAReyLSspwwms+1W3XUB5bmWsriqAHfvlr6
dYxocPz2XydteAc/LopzhkYQZ7FdznrRNEHpg8IkRzRxvbHUQ2QfKjECCzhgGrcm
qY5bbkGQNvUzgZ+UpbFvwR/R4txQnOJG8NZ6q8n4f7BIK650jLhEWit7Jx65brT0
K6bQbk/9hw0VC1Pr9Y2EL9HC6ptRYez8eKo6krSRyowAklKWtFp+mS65d/3PXnR8
5n/Hr6ZPpOXaaOAK5s03U35vVSm0Zl9Q5sDHUH75SkYpmqsVKXc4qlv4FPwqm0cC
mcKigSjaONMGSami/dAaSlwPR3prp1tbPI528JaUeVryww5KesmFOQ34HaQwzefX
nRi8lXfbPRBoIuWLEHMcHGLociIUVGj6nae4/+p0j4o9Lg1wakGvY28wxZClOoSr
+gu/KTPeAuX2SuV9AGphcsijSMQNBwFIjA+vBQZZ/BYD7/uM9ckwOkgHSsd0+R6V
s4bTOLeQonJBSCrxux72rxeF7Q04iA814wHq3YChpNV2jCeCsBkOpN/ugVsxBzmb
xF1Gn4uplD0ghGBk8G99jksgUMlXKbH5F0eJ+BjeRJ9uOepPq/DQ1BY5Y1zJzpZF
WaySLnnsRCHq20g9rii3dRiWL9IL4nCp57j88kNL4QgdVegTQvfkFJ0xyIr4XRth
w6fNnueSy7obqIC3r5kL6rckd+wTRXzKNpzUtAqIo5tFRKjqjem7WG08IXDEtFHY
9oIrPRsnPLfcbABR1p0T6jBLX2CLTHD1t0OwlhCO8UBt9cVIRh/9eAm9BsNuKi0C
+6W4YQIpWCLLbCM0vujwlf2bnCADz3OWtxBnhuP6hIjwh3r/KY8T9SGfBj9szbMa
1OB6SKZh9v4F1+6cV4QDjoHeIB8/bi2kyIU7XNQk9QwYDRLR6ZA8pFrxRiI3B420
sHU234Y/eu+v+5zPgR1rODvfkUCi7YHUssE+MvDv8cK2XZKXXS2eOXIMcRMgc2lk
rrK8XX88nZtjP5TxelukiKPRNcBMFtfbFhcRloxi7IquE7PfSVD3/ynIRfz+r1Vd
3zfGq7mBTeziu/YsnxjVD4KlUpjb3MjP854draeY7NtxSUBqOgyNYofHjy2OIGAf
wGHUYimvMh7SKdyu1Hd59ixnYCJVA6rJcniBT/pzDuyA0DlwldsDQfsNSILw4FPA
-----END RSA PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,0DCF772A24BB3CBB
5RADMhfVwXiIeiQifAW7De2BguR6NLQe3TBzpJdguxDVo8aCMqFPPEf227icrILF
P85+iQyH5HNe3s6fr4ASAMq7eQLRLNMAxieq5nnMIYMZhDV2CSguoyPiI2knq1Lb
PpImyWWWUOxLuWi/Pw9Tyi58z69irawfDAg7Jg3lizOwQCYgFxAgR51/1uwDo1pa
fxdekk2+YqRs+QOFdKX3RDxl1w4IV8wrKVZ/3sJUSZCVMQt3BeQWhwVVNRO8W83q
QLX5RM/zC5Hl+WpR5O3hUyjRnRU+WRwxF/5U3E9wzUhbp0e2ae5uK1HotvMWAzIW
1WcbTLYVNYLy7MiPxQrhTfesO8p56NfUqaPmCw5MsAmwyFXUo30Puhq31eXkkzlP
uPe7QqSUPIPBT6YQBKf2W6wrJ9nN1Jwee36m+h945ECOSRKoaMV/HYuMYDZzOMJ+
Vwb3AAWh+fqUQpxktdfdf8qziBLfXNg8apglzxzUe3RicpxdKX/ou6SQR1VaMoOa
2FCuDRGEwewg5xY0BpZjc6qnGQJnzV1JLKjCn6voBtC2XEJ/8IReaz6lb8Xt6rxe
Ud+Ya1ZgGooEzPHeJhNvru1+YYsmb1xUx4fb5O7OSKytikBKEdRHl+Aeqh/MNPmy
kj8NuUx2lS+WxZkaJZoHIihYaoxq/YuKt6FSSrlvH3agLaa5j8/Twh5rkZCV+sn9
wLeUB17hrocq8VXIeQB17orc3b+28cgt8e+vnUxCbGGT4/qh59q5eIvAQ5q4IQKP
+bTMYLJMa/DMordisBfg0hSqB6ojpXU1KBrBdHDk6hZeordUW53RH6IlwPUfzLd4
UUyP8Xru/u1RE6IPB+Xx++yt0szgqqQo9UQUfi1QP3Jkn9k5fSoLXTvuvMPLMcZU
j//+1p0dYXgJS+vy5jPvoifBE2o4BfKtVeOT+cJomfngxWOpLJw2Q1o0MNDl8pOF
GntleXXMaNvd+KqUHaJz9IO9z0G+9a6+JphjFWpx6Es+3DRhNc77bEawxvzOLxSN
T/dXQD+oxX95766L6gA8kC9DVZblm6MtXXsHKi61n2tlPX1dXT4md9x0Wv1rr43R
IIp4C6ew0qfZdE01BA6P9VOk7It8HLur/JfNxe0vvtLCzR0LIis06CKwVSrvZQKi
v+vQ7iIj3gn0hqvTJr8TEChSSBYyMHBj+eUol8fcsRZQIDGl63bcBAI9VutdRK29
IuaCpwfVoNQYwk33zcTizmBWAb0eDKQqtFVs/I/mw8cu/v61P0/CzR19KSsOGdEm
orCWSXh89iSY0cTQCADJUxy97u/dReUD7qyZP4T6OSxr0KG2x7+Uf+gr0nsiJh3k
bWQ5tqgixWVCrdSq9nKdiGiyFeHncnc51rDT+cxzcobNhxaFt4YUCce/HtodqpGn
hf6Q9JEppEKZJ9KvdfumliGwvkNJQFDVCEf4x4oLm39dra/J/IcYRKDRMRpXq4F6
BWCiQQ7JF3ggpRRRaoLC4fcdZpHaGAY3Tex440/ITDrJ+DMfGnvBwCZnOCrjPGq3
84tJnB9N0w2jS1ggSm5q0jQOM8mF5dbzJwFby6QYBUvuTL7pBIj0Yg==
-----END RSA PRIVATE KEY-----

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAmbVFfs9junVAnbTslcknvl0udZ7YpjcjwwA4fsqKWGKqLCNj
MPiQk7jdnVZmrganEeABGEuwLCqeMr7ekheEGjh9TQV+ADEH9OC5FpMeT9BkrY6u
RGQTNsYJ3MV2vrLTqhVOAFBwqN5vrpLEGR5i3s4zg83rp10UhE8NFwffGfMOW+AQ
tsQN67EY9TXDeD2nuVjBhL8rfrFhWl+ZX5wsQb0v1AVzT2g+OF95ZazMQqhrjrfz
zIRpANGxoYf4qgwlT16+HpPW0HMZKQ65+yAYXgWsSidq18YkyxC/KD8MzOf8ODZD
/YDqfrk9UcR+HHeZLjmzUFPzz0D0PcObSU8L/wIDAQABAoIBAC/L0WdkX/OMIGKp
7uOI4IXufdLvaRkOjl1FxUuP+cMQMzB0dJS2xmZZFvik9FrrEKqbSFvgtVCWlAjd
l2JAU8C/jh8UNSEkHgBEnOlrKALTn2rkskXsBJmErW5sLMeR3gXGiDHK0a2BNaNI
WhghfccgwZ4bu0qYxBd8aWqe9P4hPcretO4zV8Py2YzXqBh7CYicObluES3DOwX+
AWBZFZpHGuOk1l3WLJqiVIXssoYHNtzdg0UVKQCtuEpeVWaWt/ObfT4qfNy/ANMw
vQE9DiBNyUgAvkWm877wD34dBScfMpepr/KNuhCs9rUi94MT0uRdk5JMqs/2Vf6F
cHcB1SkCgYEA1Mn72T/RzO5Ze6lUJBq3uH53Gee2mDHfOiob98bZYDLp6WWeHmse
nhdzgVd/NpGxjaf8QuBsvluM1XDZa4PsN1F562U/VcIM2sZ8MC/GRRf+6iikVTHG
BqJqPs/OgnJoiWmIdaqAKgsigqpWtHSJ4SF9FKymrFH07XYVuAaLl+0CgYEAuOvq
rQ7noHteWpvfjPKhwlAaBBlMhyRqofqS9JBgVk9o8twZGHxEke+d7qF20+02+Mhq
nVSnGQ358OdZkpoOtobTfVHPeQN/T2dwevi2Gc3sNSNiKzZcDcEXlCDb7eFLtZna
N6P+cfWayCTwfJZ9BqwxO6pRs4Op/Yx7XR5hXhsCgYEAkOaKjcIbyAV3AfKozX00
JnpX+FgFy1YKwLz0FqJeXFfPWZRNPEGNs/IcQbOneS11TxVZfuD8rBQDr0UNiV1o
ebMN5vInUuq1fjUzVEz0IxDYEfRjE3C1fMcUunkgE0x9SzWGKzpT1E2IzpnYOUIy
sg/v8Sgwx593vkxvNcWfQXECgYEAnUlUp3QZAcBNReZ0487wVXWKW1glZoFMDZAy
9L/koSUUEBWzZsc0D6ju/SzrBGEtM7hMLpv1MPNZV1WAM5jD0O6m7l3qiXS3EZPa
8U2gnhwvwBbjhfvLmotVgdHdHt1VZxaArHjZkJal23zH7ECYAVfu3GAG9BiWOyoF
N/QCP2cCgYA3mAqjPTFeP6IepTWev2bog+jV3U5++smzta0zX45SoPYnuemXE4ye
2j1Vapu1J9NuThl1FbtY66bfc8uHZvXiPrYjOPAC162wJpq02pAKm/93NHySzGDJ
vvkt8XT4pvu4Baticx1ztKSHPRCQsgmUO6DIVmbcBb1CDgu4qyHf0A==
-----END RSA PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQItjWHXZ45w0oCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBB3Jn2OzS+m50sENH6VtBhXBIIE
0D3aOguFpcfHpoRIAoktePENqbUAKbkLpfXzQDie5fcXz5WWn8kd5JpMdkeQRho9
Y3+XvuHBnPOHEYvv+yBIuTYLltdK1CF+xmE0ME0BOHc++0qc1WMCrKlz7LdnBC2V
ufLAlr3DmdC9fobIZVrbmSHgOiapm1hdHY+hJFV2YP3CRV0DkKRxeoXnFtcG0/Ag
Lwab4eQjvl9iAxWYBZl2vtN0Kgq3cLuCdEBV+doKpGZFWyu/3HN6rZdX8kR8e+Cp
iuprXUgdmWfA43v3y+9ZqE5D5Ihk29O5mZYXm6rz/yB2uMjYhoZ9WMq5gWRxXIbE
9jmpKzZfiqLohHO3Pm09klA6Yf6du3uTAsE5MxCSfZ7PCIry3xarond4hE+1O3zO
PJqkwe56vGRhQl9rd+NMzJ6e3Mo2W4osC6FKjivuPNNxEVX+KI9A6kLRLfgJd8PY
uN8mNA7ZhTyCaWy+F8uzulsgPKhpY93M6lXzxXL2GYyokuJZk24ErYGpsVeUuCnc
rUQCfohmVrW9Vzg+w4s4HLBlRLwr/tx2o1hSo2r87Bf6q1X9NdwzbSf5HiLuFKLI
4pszQ2aEaH4cJawGkh2yxNK9w/v8jvg/GKCnsewH76TkHpflvcfdJwYUaySIWg4M
uAGjS8sea3j64e/76y6a4ywqs5fDEXxbXvS993wwXj4IbGjz1ducgTIKutPYzf+Q
9O6wy785apSXiXtDJichyvJZoU2iOxtVBrue/BYaq8OqHK9CxaHCyTyJPLdMRUJ4
HN+so0bpDbUiVoRQw0RWj3F7+5v/+6KTjwGhi0LI496MS8370tpkOggkn2eMjjkZ
CR8UG34IcXAwrOwYQgtj1wfpV8wNfcEYNkRqvCQmQX3QTuRUDsldIC9ALTfPP1CV
bFeg/izt4zr+xQG7Qk2oLTvZrwHQHmLFULMe8RSMHHnp6gP3iwwhH2ovLUxaRaBq
5EuSzfhv2GHts8mq4Jx5/cCegOTFL1X9vJJ5rXoc2IDGs5XE5r14F4iAbG2OwnRl
3oHIEtoTr5T/AjI9wCn/9tyhDo5UELqhE9HLAFvzkYVUG7pSEDkxi07erjLEnqR2
k1xhMjG0Nb3+qMvH9U7rbJSuTzd7W7aTwLhU19N1CxWWc/2nyKVYtjYlx97qLS/S
xQS5WHRYhhlN2erbEYtb8TamtZrSiL/iApBZBgdv7bHe1xhkOL9yNhVg+NuSFVR7
2jfd0XQDBi9as8m+sWWoevu8PCmG+T05RNbrUfOUACfB55BVvl5h5Ba+zQ/CU+Ii
R7hEYjWX1I2abEA8NwFYwP3T/VLxWkL8TaJH3WZ76yCr0afA1BswCdto3qyLMzpN
t+J27Lh6j6KdTEvocB4Av41RSG45KqMk31KFnwA8Qe6ILwgItubzI9WeugALG9Vp
HxMeknK/wnyQn1o19dvCqf8QzJCFC1SYVt+qc4IzMHx57QR3BW0ftNJK/2OvNZEi
QLyMDX+K/qwgfVBUXwFp91bEm3pEoAbocjU+w9mgmgm9agWfBcuQBRnqhOB69nYO
z69rLXipbQM+U7OkBSisclT3wNvZnf0yV0Didw29z0hL+4pjIcQDgRhHU09RAjJi
gjACDtwb4AHVjGG1sJ3ODnCSnLA3vB1/A0OpQc5Yd23p
-----END ENCRYPTED PRIVATE KEY-----

@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIBIkz3oPiDsYCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECNRyq4kIQ2GiBIIEyP3njwj2TN5y
/4Gh4gayFdRiXGEhh8W200JVbiAzrq2gv8dcUYwrPSoi5BEg3Thetafd1+rlYBp8
MBLyOj5tc5pPCy9HVbVUcTxv+mXiWP+F5ySaOTGl9WBEqF9FLJ1PoJuoXXfvm/i+
1asyEwGmVsRF473vZptKt4CV1fE6PQnJtFoIh87X3kJiq7CtfDHbVjVxlFKdNZtm
eEzrmSDILesJBY+sw8iwUDxbaOQ0my9Ajnx0BwuHmsBN0gqa64VDHltNoPuj2/h3
FeBHATN0dbHxyQTVnXzcVNyLR1g0YWkOu5Fxww3vizdLEXMgVs+06YUQxkhVFu5D
kTjOkKhyzm+9CGZKa4GwdYL6GrzxYV8t23VCOOB8+RDTpBqIzFISza9IMFDvhg3h
JVPLGRA8csVA7TmS1C82qKMQ2s7Y/92oofIJF8okG4Rd9coIPQE/ex3EeC6mIgk8
onSGk7upmBLOyb7A6QtNx6RA9znEb2D2CW8jQg9GBur2QegWEPXGqSFj9grM6G0T
r41tE6HvWGn8gn50qxkCZ4SXjdT7bdvxyi2D9UNjrnTGfpMEi2LYNddqcsX4LGyn
yXXuZhdfGxj0a9pHPmstP+GHbAiA6Vt3NsXVlSIVf0aHjl11mz+pOpr67YJneTF/
qE1jmIbPJCGlz0871Uq4BRNwzwSjOf9qi6h+PRuP6WSktajpKKGzpZI6wUguZzAr
y7tUVFyVKFrYxWPdkUqUodMqzHiVU2mhQxXxa2TZRrI256yws1/wSmeYH+gdTj4e
EKQnq/DelY4q8s+D5Bx6VdXszUmCrAT/DaB1Lb6C9uvc0V9mtqeYPBizHWt9Nqf8
b8KlxHeogxhAOdFJUQgSYvISVU+HiKhH3kN+rSHcwF5eBS5qvI30GBUi7OLoLwYu
3kvSnMm3BKCBOYX+EQT5GQnxwRjhecwGj+07BIsf1GSlJf2KvlpJMTDUlDpwtSdi
kb41GpI70L+ZWlZ5qhLHNHbKfsTe+H5MWpJe5EVMAWEhN1jmTDdTY69LkK3SS7zX
+x+poxnxZsIPsMh0Yp3Cq7TqDqFB+bp1owKwtBNguZysL3GYDy+Oc/CH9FbRwS4X
Oh6Gc2iPwnmEVrWUa+FWf5UrU20yBCIFnaD+i5FaxwMg9vi3dHEO2SvO0Gn6NfOY
HAqVcvwG18N+l3wlacfszlagDRnSbQbxIcZpJU09rmcUNkHQ+srbrkXtxC3Nv0yk
S0Z0GOWyq+JLzEnYg/JNZ0dE2gfdccUsXnYMlhqmNVUQsLYcuqETFIkr1grm8yjm
9O0vLag4Mmu0Ey5Qi9nmuAHQOrcHVMpH1bLpVVYTHZQ2OV9d0v9n7d+6YTUmo+HM
xooGpDYBKrc56dzE41aS/ACeJMKbTkTqbLlSpNwPWte0PUIqfbb+fOqwbEs6ZEqb
ZmQNHzOvdQ+r0P1rLkB9FnP/pv6VXRDq+i6WpgvC5OnFK8hSuaCZLrsHTN64hxkB
DDML//J38h601znZeYl0OsIEhJKJIfzSbXieni8qh8WGOtAT7FO2oNxLZNHiDLG0
QxSqhYWce84n7EpUUCxkl7NhxvBvS1Ff38Xe9JVWAMJf7uzGxja9K9c1FPm7FJqX
ux7R4UAiAMJiJ43ViC6trg==
-----END ENCRYPTED PRIVATE KEY-----

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCRpgfif4RQMD4c
wGgMc0y6K2Tv7DkpHnrw+LUUbLUQwwc38svTvx/rGYczJ5SIpWeo1ZpXOxAkqPXj
7BAvTsU2KCo7PlaSN44OB8x5modFfv88s7Qy1VW5z1Vjj7RwX0V39JmL715CJsBh
nMUR5p6BVCUlx+7tQ0iNc8sCd0S5QLArxY9SsDwYO1PjbMLV2LO8gkf6bVWk4UHm
vUyIYeewYj7qIq0ObkoZe7/v+RIMl1j3bOzdRWObtPYYG4u8TcS4FXCRlUboU64n
1O/mwKdmZQaiEqJIMeohtHy1oRm3sXtpxdPUWW9avmN/lp7lNYwS2lntk8OByl/c
7lTWAHJLAgMBAAECggEACglK2cy3rV7lqM2JXfJEA0AiQHYiqjazeg9pSvMCtxj5
Ul2ktf6hkG2950R+87uSHQw7Cm/DeQM7jm0h4GCpLkYuQs7U4FZ7r3PSHz8Kuzs5
E1G+xRH2SkuDMs0gPe4St2Vff0kLUbuh3hgTbFxb58WImcXhLPBJ+5VTE+RsE+fK
niBBk6Xjezs8EY5fZ0HJxK0oRdTK6T43ldQHm3ECNWqXOGXnX4mEoqOg1SC4RA01
HJa+tA0QTAPiaFPSeqAFJlR7/8fTh+4AOpyFqCOIhjK8Exv5+PwlPuEqtMRRzEuq
P6+R/rO+2tYK9/R6vhGrCKRBE9kJd//WkfoGJXKGQQKBgQDEuqjdq6YNgGxJZXXI
JmzOFuM0fTpXLtd8wnAywqfTCtGeA+XM/JQWxzeoVZbs9/55EM6LJlTbvdwstMZc
sv5XK9YtaumdkEsxnKuWiFIetflSJmy4QkJ4lsn+QqMkL4L+5itITT+LYwv69kkZ
eZBNbiqIfjaIXYVwuNxEnZS1cwKBgQC9h5/FnKO9m7x8uphe0OmvUGyvGLBYI2/8
sVxwMZ/pMzzsAr6Wv33nWfXkxLKP1e5LDSyX+dgFpryITIgLEj0S8Q7VKaDRCfHN
dVnbtlfSSNaaE1crudqu0fqA1XTba8FGlaP5JUYEsyrvyt1apauH+qpHVsFhLUPh
qOl33/NZyQKBgHZ3VQMPv1H4GL1mDLQ3d2PvYmiUVJJ1kav+RqQ6lec/Z5U5EaQM
IX1KABktWVJf0GzFEyu2LHma7kA5qA3gd8q0iigVbpLEdpNsneNrOdBmkrnGi8e1
luOZIhArvqQmvEKVBlFmuzJLtcYtkz1099G42oIRRvN9JcMIfxQOtKNDAoGALZDJ
rKy4AQHMEwCZWVJInEltl7sLymTaq5nIa4DCvUIAR41xXLS1BEXwhAt2EnaQT6Lf
MbpzYQhxEyOzIVZFMKSbuEvFyfvmEktASz5PZtL0JR65Ol34YUdCPm8TJR2G3f1j
6qY3azHYBMZ06TIjRxHQlk4ZN8+2Hi6J0rQYwWECgYEApp7sj0oBDDlKyOwSDsTf
EISLeJCx9hFAwAi5dX5rh/rhr9b4bLfzh/CYPUW8vKZc5FvqW4g29vO8oB9sGQJt
38jQNywMTldPm+qyMRpY1xtng2nGRf6RQmnYI1UvccXflcKkHJiNZ2UoNnsetsFy
QOl50ZayLAj8dAwi/whvvqs=
-----END PRIVATE KEY-----

@ -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,18 @@
-----BEGIN CERTIFICATE-----
MIIC6DCCAdACCQCp0Mn/2UCl2TANBgkqhkiG9w0BAQsFADA2MTQwMgYDVQQDDCtj
ZmYyNGEwY2I4NGFmNjExZDdhODFjMGI4MDY4OTA2OC5uZXR0eS50ZXN0MB4XDTE0
MTAxNzE4NDczM1oXDTE0MTExNjE4NDczM1owNjE0MDIGA1UEAwwrY2ZmMjRhMGNi
ODRhZjYxMWQ3YTgxYzBiODA2ODkwNjgubmV0dHkudGVzdDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALgddI5XJcUK45ONr4QTfZZxbJJeOYKPEWVIWK/P
Wz6EJXt3hDdpmnaRUKAv4mMIFlxWVkxTqa/dB3hjcm5hPvNgPAUaEWzMtGd32p95
sJzbxiWvxhf5rqF0n1Zk5KX+EcasiCupNg3TL7gfTSSZfaGSWf460oaCS6WCU4X9
XTUhys7N5BFM+uQLE048CnkBCO1An980Fau/0+BLXgW+iJC6XWTJbpZ+r7rDpBKl
+HmQQ5tgGlCZcnhmS9bzYT3hoag6JkDoIwbFsVOkwemxZGb8GsGE74/rrzUJ9MdR
/ETCA2km1na6ESst0/wm0qD3clJahP8xEoaJ+W1TFGizRWkCAwEAATANBgkqhkiG
9w0BAQsFAAOCAQEAmeGPRWXzu7+f20ZJA/u6WjcmsUhSTtt0YcBNtii4Pm0snIE9
UyRBGlvS2uFHTilD7MOYOHX6ATlHZAsfegpiPE5jCvE4CzFPpQaVAT/sKNtsWH43
ZQHn4NK1DAFIVDysO3AGGhL0mub8iWEYHs81+6tSSFlbDFqwYtw7ueerhVLUIaIa
S0SvtXUVitX2LzMlYCEto2s50fcqOnj8uve/dG8BmiwR1DqqVKkAWAXf8uGhwwD+
659E3g9vNz6QUchd8K/TIv52i8EDuWu3FElohmfFUXu43A+Z+lbuDrEW3suqTC3y
0JIa2DfHWA7WTyF4UD32aAC+U6BLIOA6WoPi1Q==
-----END CERTIFICATE-----

@ -7,6 +7,7 @@ dependencies {
implementation project(':netty-handler-codec-spdy')
implementation project(':netty-handler')
implementation project(':netty-handler-ssl')
implementation project(':netty-handler-ssl-bouncycastle')
implementation testLibs.xz.tools
implementation testLibs.assertj
implementation testLibs.junit.jupiter.api

@ -31,7 +31,7 @@ import io.netty.handler.ssl.OpenSslServerContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.concurrent.Future;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

@ -34,7 +34,7 @@ import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.testsuite.util.TestUtils;
import io.netty.util.concurrent.Future;

@ -32,7 +32,7 @@ import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.internal.PlatformDependent;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

@ -30,7 +30,7 @@ import io.netty.handler.ssl.JdkSslClientContext;
import io.netty.handler.ssl.JdkSslServerContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory;

@ -34,7 +34,7 @@ import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.ssl.bouncycastle.SelfSignedCertificate;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.Future;

@ -0,0 +1,22 @@
module org.xbib.io.netty.testsuite {
exports io.netty.testsuite.transport;
exports io.netty.testsuite.transport.sctp;
exports io.netty.testsuite.transport.socket;
exports io.netty.testsuite.util;
requires org.xbib.io.netty.buffer;
requires org.xbib.io.netty.channel;
requires org.xbib.io.netty.util;
requires org.xbib.io.netty.channel.sctp;
requires org.xbib.io.netty.handler.codec;
requires org.xbib.io.netty.handler.codec.sctp;
requires org.xbib.io.netty.handler.codec.spdy;
requires org.xbib.io.netty.handler;
requires org.xbib.io.netty.handler.ssl;
requires org.xbib.io.netty.handler.ssl.bouncycastle;
requires org.tukaani.xz;
requires org.junit.jupiter.api;
requires org.junit.jupiter.params;
requires org.hamcrest;
requires org.assertj.core;
requires java.management;
}

@ -14,13 +14,14 @@ module org.xbib.io.netty.util {
org.xbib.io.netty.handler.codec.http,
org.xbib.io.netty.handler.codec.httptwo,
org.xbib.io.netty.handler.codec.httpthree,
org.xbib.io.netty.handler.codec.protobuf,
org.xbib.io.netty.handler.codec.quic,
org.xbib.io.netty.handler.codec.rtsp,
org.xbib.io.netty.handler.codec.sctp,
org.xbib.io.netty.handler.codec.spdy,
org.xbib.io.netty.handler.ssl,
org.xbib.io.netty.resolver;
org.xbib.io.netty.handler.ssl.bouncycastle,
org.xbib.io.netty.resolver,
org.xbib.io.netty.testsuite;
exports io.netty.util.internal.logging to
org.xbib.io.netty.buffer,
org.xbib.io.netty.channel,
@ -33,13 +34,14 @@ module org.xbib.io.netty.util {
org.xbib.io.netty.handler.codec.http,
org.xbib.io.netty.handler.codec.httptwo,
org.xbib.io.netty.handler.codec.httpthree,
org.xbib.io.netty.handler.codec.protobuf,
org.xbib.io.netty.handler.codec.quic,
org.xbib.io.netty.handler.codec.rtsp,
org.xbib.io.netty.handler.codec.sctp,
org.xbib.io.netty.handler.codec.spdy,
org.xbib.io.netty.handler.ssl,
org.xbib.io.netty.resolver;
org.xbib.io.netty.handler.ssl.bouncycastle,
org.xbib.io.netty.resolver,
org.xbib.io.netty.testsuite;
requires org.xbib.io.netty.jctools;
requires java.logging;
requires jdk.unsupported;

@ -29,7 +29,6 @@ dependencyResolutionManagement {
library('brotli4j-native-osx-x8664', 'com.aayushatharva.brotli4j', 'native-osx-x86_64').versionRef('brotli4j')
library('brotli4j-native-osx-aarch64', 'com.aayushatharva.brotli4j', 'native-osx-aarch64').versionRef('brotli4j')
library('brotli4j-native-windows-x8664', 'com.aayushatharva.brotli4j', 'native-windows-x86_64').versionRef('brotli4j')
library('protobuf', 'com.google.protobuf', 'protobuf-java').version('4.0.0-rc-2')
}
testLibs {
version('junit', '5.10.1')
@ -69,13 +68,13 @@ include 'netty-handler-codec-compression'
include 'netty-handler-codec-http'
include 'netty-handler-codec-http2'
include 'netty-handler-codec-http3'
include 'netty-handler-codec-protobuf'
include 'netty-handler-codec-quic'
include 'netty-handler-codec-quic-native'
include 'netty-handler-codec-rtsp'
include 'netty-handler-codec-sctp'
include 'netty-handler-codec-spdy'
include 'netty-handler-ssl'
include 'netty-handler-ssl-bouncycastle'
include 'netty-internal-tcnative'
include 'netty-jctools'
include 'netty-resolver'

Loading…
Cancel
Save