From d209eb0e18ed52ee1817fa4a9f1e9ec8a16497f0 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 21 Jan 2021 11:12:54 +0100 Subject: [PATCH] Move OpenSsl*X509Certificate to util package and rename it (#10955) Motivation: Creating certificates from a byte[] while lazy parse it is general useful and is also needed by https://github.com/netty/netty-incubator-codec-quic/pull/141 Modifications: Move classes, rename these and make them public Result: Be able to reuse code --- .../ssl/ReferenceCountedOpenSslContext.java | 3 ++- .../ssl/ReferenceCountedOpenSslEngine.java | 14 ++++++----- .../LazyJavaxX509Certificate.java} | 13 +++++++--- .../LazyX509Certificate.java} | 25 +++++++++++++++---- 4 files changed, 39 insertions(+), 16 deletions(-) rename handler/src/main/java/io/netty/handler/ssl/{OpenSslJavaxX509Certificate.java => util/LazyJavaxX509Certificate.java} (90%) rename handler/src/main/java/io/netty/handler/ssl/{OpenSslX509Certificate.java => util/LazyX509Certificate.java} (88%) 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 cf445dd4cd..fa913a01d7 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; @@ -605,7 +606,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 d5689bb501..069a6849d0 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; @@ -2364,13 +2366,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); } } @@ -2380,8 +2382,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 0e7ed3b666..8dd0f572a6 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,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.auth.x500.X500Principal; import java.io.ByteArrayInputStream; @@ -28,6 +30,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; @@ -36,13 +39,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 @@ -215,7 +230,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);