diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java index 03e331c91b..7f631deba1 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslContext.java @@ -17,6 +17,7 @@ package io.netty.handler.ssl; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; +import io.netty.handler.ssl.util.LazyX509Certificate; import io.netty.internal.tcnative.CertificateVerifier; import io.netty.internal.tcnative.SSL; import io.netty.internal.tcnative.SSLContext; @@ -565,7 +566,7 @@ public abstract class ReferenceCountedOpenSslContext extends SslContext implemen protected static X509Certificate[] certificates(byte[][] chain) { X509Certificate[] peerCerts = new X509Certificate[chain.length]; for (int i = 0; i < peerCerts.length; i++) { - peerCerts[i] = new OpenSslX509Certificate(chain[i]); + peerCerts[i] = new LazyX509Certificate(chain[i]); } return peerCerts; } diff --git a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java index 86698172e1..a80fd2272c 100644 --- a/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java +++ b/handler/src/main/java/io/netty/handler/ssl/ReferenceCountedOpenSslEngine.java @@ -17,6 +17,8 @@ package io.netty.handler.ssl; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; +import io.netty.handler.ssl.util.LazyJavaxX509Certificate; +import io.netty.handler.ssl.util.LazyX509Certificate; import io.netty.internal.tcnative.Buffer; import io.netty.internal.tcnative.SSL; import io.netty.util.AbstractReferenceCounted; @@ -2318,13 +2320,13 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc x509PeerCerts = EmptyArrays.EMPTY_JAVAX_X509_CERTIFICATES; } else { if (isEmpty(chain)) { - peerCerts = new Certificate[] {new OpenSslX509Certificate(clientCert)}; - x509PeerCerts = new X509Certificate[] {new OpenSslJavaxX509Certificate(clientCert)}; + peerCerts = new Certificate[] {new LazyX509Certificate(clientCert)}; + x509PeerCerts = new X509Certificate[] {new LazyJavaxX509Certificate(clientCert)}; } else { peerCerts = new Certificate[chain.length + 1]; x509PeerCerts = new X509Certificate[chain.length + 1]; - peerCerts[0] = new OpenSslX509Certificate(clientCert); - x509PeerCerts[0] = new OpenSslJavaxX509Certificate(clientCert); + peerCerts[0] = new LazyX509Certificate(clientCert); + x509PeerCerts[0] = new LazyJavaxX509Certificate(clientCert); initCerts(chain, 1); } } @@ -2334,8 +2336,8 @@ public class ReferenceCountedOpenSslEngine extends SSLEngine implements Referenc private void initCerts(byte[][] chain, int startPos) { for (int i = 0; i < chain.length; i++) { int certPos = startPos + i; - peerCerts[certPos] = new OpenSslX509Certificate(chain[i]); - x509PeerCerts[certPos] = new OpenSslJavaxX509Certificate(chain[i]); + peerCerts[certPos] = new LazyX509Certificate(chain[i]); + x509PeerCerts[certPos] = new LazyJavaxX509Certificate(chain[i]); } } diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslJavaxX509Certificate.java b/handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java similarity index 90% rename from handler/src/main/java/io/netty/handler/ssl/OpenSslJavaxX509Certificate.java rename to handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java index e449851f68..65831c0628 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslJavaxX509Certificate.java +++ b/handler/src/main/java/io/netty/handler/ssl/util/LazyJavaxX509Certificate.java @@ -13,7 +13,9 @@ * License for the specific language governing permissions and limitations * under the License. */ -package io.netty.handler.ssl; +package io.netty.handler.ssl.util; + +import io.netty.util.internal.ObjectUtil; import javax.security.cert.CertificateException; import javax.security.cert.CertificateExpiredException; @@ -28,12 +30,15 @@ import java.security.PublicKey; import java.security.SignatureException; import java.util.Date; -final class OpenSslJavaxX509Certificate extends X509Certificate { +public final class LazyJavaxX509Certificate extends X509Certificate { private final byte[] bytes; private X509Certificate wrapped; - OpenSslJavaxX509Certificate(byte[] bytes) { - this.bytes = bytes; + /** + * Creates a new instance which will lazy parse the given bytes. Be aware that the bytes will not be cloned. + */ + public LazyJavaxX509Certificate(byte[] bytes) { + this.bytes = ObjectUtil.checkNotNull(bytes, "bytes"); } @Override diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSslX509Certificate.java b/handler/src/main/java/io/netty/handler/ssl/util/LazyX509Certificate.java similarity index 88% rename from handler/src/main/java/io/netty/handler/ssl/OpenSslX509Certificate.java rename to handler/src/main/java/io/netty/handler/ssl/util/LazyX509Certificate.java index 1655f9837a..840257720b 100644 --- a/handler/src/main/java/io/netty/handler/ssl/OpenSslX509Certificate.java +++ b/handler/src/main/java/io/netty/handler/ssl/util/LazyX509Certificate.java @@ -13,8 +13,9 @@ * License for the specific language governing permissions and limitations * under the License. */ -package io.netty.handler.ssl; +package io.netty.handler.ssl.util; +import io.netty.util.internal.ObjectUtil; import io.netty.util.internal.SuppressJava6Requirement; import javax.security.auth.x500.X500Principal; @@ -30,6 +31,7 @@ import java.security.SignatureException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; @@ -38,13 +40,25 @@ import java.util.Date; import java.util.List; import java.util.Set; -final class OpenSslX509Certificate extends X509Certificate { +public final class LazyX509Certificate extends X509Certificate { + + static final CertificateFactory X509_CERT_FACTORY; + static { + try { + X509_CERT_FACTORY = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + throw new ExceptionInInitializerError(e); + } + } private final byte[] bytes; private X509Certificate wrapped; - OpenSslX509Certificate(byte[] bytes) { - this.bytes = bytes; + /** + * Creates a new instance which will lazy parse the given bytes. Be aware that the bytes will not be cloned. + */ + public LazyX509Certificate(byte[] bytes) { + this.bytes = ObjectUtil.checkNotNull(bytes, "bytes"); } @Override @@ -217,7 +231,7 @@ final class OpenSslX509Certificate extends X509Certificate { X509Certificate wrapped = this.wrapped; if (wrapped == null) { try { - wrapped = this.wrapped = (X509Certificate) SslContext.X509_CERT_FACTORY.generateCertificate( + wrapped = this.wrapped = (X509Certificate) X509_CERT_FACTORY.generateCertificate( new ByteArrayInputStream(bytes)); } catch (CertificateException e) { throw new IllegalStateException(e);