[Git][java-team/netty][master] 3 commits: apply upstream compatibility patch

Tony Mancill (@tmancill) gitlab at salsa.debian.org
Sat Dec 9 04:49:31 GMT 2023



Tony Mancill pushed to branch master at Debian Java Maintainers / netty


Commits:
c59a83dc by Vladimir Petko at 2023-11-28T08:53:02+13:00
apply upstream compatibility patch

- - - - -
6df8499f by Vladimir Petko at 2023-11-28T08:53:06+13:00
changelog

- - - - -
c5fedfa1 by Tony Mancill at 2023-12-09T04:49:17+00:00
Merge branch 'java21-compat' into 'master'

Resolve Java 21 FTBFS

See merge request java-team/netty!2
- - - - -


3 changed files:

- debian/changelog
- + debian/patches/22-java-21.patch
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+netty (1:4.1.48-9) UNRELEASED; urgency=medium
+
+  * d/p/22-java-21.patch: apply upstream Java 21 compatibility patch
+    (Closes: #1053066).
+
+ -- Vladimir Petko <vladimir.petko at canonical.com>  Tue, 28 Nov 2023 08:30:44 +1300
+
 netty (1:4.1.48-8) unstable; urgency=medium
 
   * Team upload.


=====================================
debian/patches/22-java-21.patch
=====================================
@@ -0,0 +1,566 @@
+Description: Java 21 compatibility patch
+ Use reflection to access sun.x509 API due to the breaking changes
+ between Java 17 and Java 21. Cherry-pick self-signed certificate
+ generator changes from netty-4.1.91.Final.
+Author: Norman Maurer <norman_maurer at apple.com>
+Bug: https://github.com/netty/netty/pull/13295
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1053066
+Applied-Upstream: https://github.com/netty/netty/commit/44b7e5b12d8dff3d07dfb773680120cc20f7e203
+Last-Update: 2023-11-28
+--- a/handler/src/main/java/io/netty/handler/ssl/util/OpenJdkSelfSignedCertGenerator.java
++++ b/handler/src/main/java/io/netty/handler/ssl/util/OpenJdkSelfSignedCertGenerator.java
+@@ -5,7 +5,7 @@
+  * version 2.0 (the "License"); you may not use this file except in compliance
+  * with the License. You may obtain a copy of the License at:
+  *
+- *   http://www.apache.org/licenses/LICENSE-2.0
++ *   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
+@@ -16,10 +16,12 @@
+ 
+ package io.netty.handler.ssl.util;
+ 
++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 sun.security.x509.AlgorithmId;
+ import sun.security.x509.CertificateAlgorithmId;
+-import sun.security.x509.CertificateIssuerName;
+ import sun.security.x509.CertificateSerialNumber;
+ import sun.security.x509.CertificateSubjectName;
+ import sun.security.x509.CertificateValidity;
+@@ -29,6 +31,11 @@
+ import sun.security.x509.X509CertImpl;
+ import sun.security.x509.X509CertInfo;
+ 
++import java.lang.reflect.Constructor;
++import java.lang.reflect.InvocationTargetException;
++import java.lang.reflect.Method;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import java.util.Date;
+ import java.math.BigInteger;
+ import java.security.KeyPair;
+@@ -42,41 +49,166 @@
+  * Generates a self-signed certificate using {@code sun.security.x509} package provided by OpenJDK.
+  */
+ final class OpenJdkSelfSignedCertGenerator {
++    private static final InternalLogger logger =
++            InternalLoggerFactory.getInstance(OpenJdkSelfSignedCertGenerator.class);
++    private static final Method CERT_INFO_SET_METHOD;
++    private static final Constructor<?> ISSUER_NAME_CONSTRUCTOR;
++    private static final Constructor<X509CertImpl> CERT_IMPL_CONSTRUCTOR;
++    private static final Method CERT_IMPL_GET_METHOD;
++    private static final Method CERT_IMPL_SIGN_METHOD;
++
++    // Use reflection as JDK20+ did change things quite a bit.
++    static {
++        Method certInfoSetMethod = null;
++        Constructor<?> issuerNameConstructor = null;
++        Constructor<X509CertImpl> certImplConstructor = null;
++        Method certImplGetMethod = null;
++        Method certImplSignMethod = null;
++        try {
++            Object maybeCertInfoSetMethod = AccessController.doPrivileged(new PrivilegedAction<Object>() {
++                @Override
++                public Object run() {
++                    try {
++                        return X509CertInfo.class.getMethod("set", String.class, Object.class);
++                    } catch (Throwable cause) {
++                        return cause;
++                    }
++                }
++            });
++            if (maybeCertInfoSetMethod instanceof Method) {
++                certInfoSetMethod = (Method) maybeCertInfoSetMethod;
++            } else {
++                throw (Throwable) maybeCertInfoSetMethod;
++            }
++
++            Object maybeIssuerNameConstructor = AccessController.doPrivileged(new PrivilegedAction<Object>() {
++                @Override
++                public Object run() {
++                    try {
++                        Class<?> issuerName = Class.forName("sun.security.x509.CertificateIssuerName", false,
++                                PlatformDependent.getClassLoader(OpenJdkSelfSignedCertGenerator.class));
++                        return issuerName.getConstructor(X500Name.class);
++                    } catch (Throwable cause) {
++                        return cause;
++                    }
++                }
++            });
++            if (maybeIssuerNameConstructor instanceof Constructor) {
++                issuerNameConstructor = (Constructor<?>) maybeIssuerNameConstructor;
++            } else {
++                throw (Throwable) maybeIssuerNameConstructor;
++            }
++
++            Object maybeCertImplConstructor = AccessController.doPrivileged(new PrivilegedAction<Object>() {
++                @Override
++                public Object run() {
++                    try {
++                        return X509CertImpl.class.getConstructor(X509CertInfo.class);
++                    } catch (Throwable cause) {
++                        return cause;
++                    }
++                }
++            });
++            if (maybeCertImplConstructor instanceof Constructor) {
++                @SuppressWarnings("unchecked")
++                Constructor<X509CertImpl> constructor = (Constructor<X509CertImpl>) maybeCertImplConstructor;
++                certImplConstructor = constructor;
++            } else {
++                throw (Throwable) maybeCertImplConstructor;
++            }
++
++            Object maybeCertImplGetMethod = AccessController.doPrivileged(new PrivilegedAction<Object>() {
++                @Override
++                public Object run() {
++                    try {
++                        return X509CertImpl.class.getMethod("get", String.class);
++                    } catch (Throwable cause) {
++                        return cause;
++                    }
++                }
++            });
++            if (maybeCertImplGetMethod instanceof Method) {
++                certImplGetMethod = (Method) maybeCertImplGetMethod;
++            } else {
++                throw (Throwable) maybeCertImplGetMethod;
++            }
++
++            Object maybeCertImplSignMethod = AccessController.doPrivileged(new PrivilegedAction<Object>() {
++                @Override
++                public Object run() {
++                    try {
++                        return X509CertImpl.class.getMethod("sign", PrivateKey.class, String.class);
++                    } catch (Throwable cause) {
++                        return cause;
++                    }
++                }
++            });
++            if (maybeCertImplSignMethod instanceof Method) {
++                certImplSignMethod = (Method) maybeCertImplSignMethod;
++            } else {
++                throw (Throwable) maybeCertImplSignMethod;
++            }
++        } catch (Throwable cause) {
++            logger.debug(OpenJdkSelfSignedCertGenerator.class.getSimpleName() + " not supported", cause);
++        }
++        CERT_INFO_SET_METHOD = certInfoSetMethod;
++        ISSUER_NAME_CONSTRUCTOR = issuerNameConstructor;
++        CERT_IMPL_CONSTRUCTOR = certImplConstructor;
++        CERT_IMPL_GET_METHOD = certImplGetMethod;
++        CERT_IMPL_SIGN_METHOD = certImplSignMethod;
++    }
+ 
+     @SuppressJava6Requirement(reason = "Usage guarded by dependency check")
+-    static String[] generate(String fqdn, KeyPair keypair, SecureRandom random, Date notBefore, Date notAfter)
+-            throws Exception {
++    static String[] generate(String fqdn, KeyPair keypair, SecureRandom random, Date notBefore, Date notAfter,
++                             String algorithm) throws Exception {
++        if (CERT_INFO_SET_METHOD == null || ISSUER_NAME_CONSTRUCTOR == null ||
++                CERT_IMPL_CONSTRUCTOR == null || CERT_IMPL_GET_METHOD == null || CERT_IMPL_SIGN_METHOD == null) {
++            throw new UnsupportedOperationException(
++                    OpenJdkSelfSignedCertGenerator.class.getSimpleName() + " not supported on the used JDK version");
++        }
+         PrivateKey key = keypair.getPrivate();
+ 
+         // Prepare the information required for generating an X.509 certificate.
+         X509CertInfo info = new X509CertInfo();
+         X500Name owner = new X500Name("CN=" + fqdn);
+-        info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
+-        info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new BigInteger(64, random)));
++
++        CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
++        CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.SERIAL_NUMBER,
++                new CertificateSerialNumber(new BigInteger(64, random)));
+         try {
+-            info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
+-        } catch (CertificateException ignore) {
+-            info.set(X509CertInfo.SUBJECT, owner);
++            CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
++        } catch (InvocationTargetException ex) {
++            if (ex.getCause() instanceof CertificateException) {
++                CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.SUBJECT, owner);
++            } else {
++                throw ex;
++            }
+         }
+         try {
+-            info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
+-        } catch (CertificateException ignore) {
+-            info.set(X509CertInfo.ISSUER, owner);
++            CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.ISSUER, ISSUER_NAME_CONSTRUCTOR.newInstance(owner));
++        } catch (InvocationTargetException ex) {
++            if (ex.getCause() instanceof CertificateException) {
++                CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.ISSUER, owner);
++            } else {
++                throw ex;
++            }
+         }
+-        info.set(X509CertInfo.VALIDITY, new CertificateValidity(notBefore, notAfter));
+-        info.set(X509CertInfo.KEY, new CertificateX509Key(keypair.getPublic()));
+-        info.set(X509CertInfo.ALGORITHM_ID,
++        CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.VALIDITY, new CertificateValidity(notBefore, notAfter));
++        CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.KEY, new CertificateX509Key(keypair.getPublic()));
++        CERT_INFO_SET_METHOD.invoke(info, X509CertInfo.ALGORITHM_ID,
+                 // sha256WithRSAEncryption
+                 new CertificateAlgorithmId(AlgorithmId.get("1.2.840.113549.1.1.11")));
+ 
+         // Sign the cert to identify the algorithm that's used.
+-        X509CertImpl cert = new X509CertImpl(info);
+-        cert.sign(key, "SHA256withRSA");
++        X509CertImpl cert = CERT_IMPL_CONSTRUCTOR.newInstance(info);
++        CERT_IMPL_SIGN_METHOD.invoke(cert, key, algorithm.equalsIgnoreCase("EC") ? "SHA256withECDSA" : "SHA256withRSA");
+ 
+         // Update the algorithm and sign again.
+-        info.set(CertificateAlgorithmId.NAME + '.' + CertificateAlgorithmId.ALGORITHM, cert.get(X509CertImpl.SIG_ALG));
+-        cert = new X509CertImpl(info);
+-        cert.sign(key, "SHA256withRSA");
++        CERT_INFO_SET_METHOD.invoke(info, CertificateAlgorithmId.NAME + ".algorithm",
++                CERT_IMPL_GET_METHOD.invoke(cert, "x509.algorithm"));
++        cert = CERT_IMPL_CONSTRUCTOR.newInstance(info);
++        CERT_IMPL_SIGN_METHOD.invoke(cert, key,
++                algorithm.equalsIgnoreCase("EC") ? "SHA256withECDSA" : "SHA256withRSA");
+         cert.verify(keypair.getPublic());
+ 
+         return newSelfSignedCertificate(fqdn, key, cert);
+--- a/handler/src/main/java/io/netty/handler/ssl/util/SelfSignedCertificate.java
++++ b/handler/src/main/java/io/netty/handler/ssl/util/SelfSignedCertificate.java
+@@ -5,7 +5,7 @@
+  * version 2.0 (the "License"); you may not use this file except in compliance
+  * with the License. You may obtain a copy of the License at:
+  *
+- *   http://www.apache.org/licenses/LICENSE-2.0
++ *   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
+@@ -31,7 +31,6 @@
+ import java.io.FileOutputStream;
+ import java.io.IOException;
+ import java.io.OutputStream;
+-import java.nio.file.Files;
+ import java.security.KeyPair;
+ import java.security.KeyPairGenerator;
+ import java.security.NoSuchAlgorithmException;
+@@ -51,12 +50,12 @@
+  * It is purely for testing purposes, and thus it is very insecure.
+  * It even uses an insecure pseudo-random generator for faster generation internally.
+  * </p><p>
+- * An X.509 certificate file and a RSA private key file are generated in a system's temporary directory using
++ * An X.509 certificate file and a EC/RSA private key file are generated in a system's temporary directory using
+  * {@link java.io.File#createTempFile(String, String)}, and they are deleted when the JVM exits using
+  * {@link java.io.File#deleteOnExit()}.
+  * </p><p>
+  * At first, this method tries to use OpenJDK's X.509 implementation (the {@code sun.security.x509} package).
+- * If it fails, it tries to use <a href="http://www.bouncycastle.org/">Bouncy Castle</a> as a fallback.
++ * If it fails, it tries to use <a href="https://www.bouncycastle.org/">Bouncy Castle</a> as a fallback.
+  * </p>
+  */
+ public final class SelfSignedCertificate {
+@@ -71,7 +70,7 @@
+             "io.netty.selfSignedCertificate.defaultNotAfter", 253402300799000L));
+ 
+     /**
+-     * FIPS 140-2 encryption requires the key length to be 2048 bits or greater.
++     * FIPS 140-2 encryption requires the RSA key length to be 2048 bits or greater.
+      * Let's use that as a sane default but allow the default to be set dynamically
+      * for those that need more stringent security requirements.
+      */
+@@ -85,86 +84,168 @@
+ 
+     /**
+      * Creates a new instance.
++     * <p> Algorithm: RSA </p>
+      */
+     public SelfSignedCertificate() throws CertificateException {
+-        this(DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
++        this(DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER, "RSA", DEFAULT_KEY_LENGTH_BITS);
+     }
+ 
+     /**
+      * Creates a new instance.
++     * <p> Algorithm: RSA </p>
++     *
++     * @param notBefore Certificate is not valid before this time
++     * @param notAfter  Certificate is not valid after this time
++     */
++    public SelfSignedCertificate(Date notBefore, Date notAfter)
++            throws CertificateException {
++        this("localhost", notBefore, notAfter, "RSA", DEFAULT_KEY_LENGTH_BITS);
++    }
++
++    /**
++     * Creates a new instance.
++     *
+      * @param notBefore Certificate is not valid before this time
+-     * @param notAfter Certificate is not valid after this time
++     * @param notAfter  Certificate is not valid after this time
++     * @param algorithm Key pair algorithm
++     * @param bits      the number of bits of the generated private key
+      */
+-    public SelfSignedCertificate(Date notBefore, Date notAfter) throws CertificateException {
+-        this("example.com", notBefore, notAfter);
++    public SelfSignedCertificate(Date notBefore, Date notAfter, String algorithm, int bits)
++            throws CertificateException {
++        this("localhost", notBefore, notAfter, algorithm, bits);
+     }
+ 
+     /**
+      * Creates a new instance.
++     * <p> Algorithm: RSA </p>
+      *
+      * @param fqdn a fully qualified domain name
+      */
+     public SelfSignedCertificate(String fqdn) throws CertificateException {
+-        this(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
++        this(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER, "RSA", DEFAULT_KEY_LENGTH_BITS);
+     }
+ 
+     /**
+      * Creates a new instance.
+      *
+-     * @param fqdn a fully qualified domain name
++     * @param fqdn      a fully qualified domain name
++     * @param algorithm Key pair algorithm
++     * @param bits      the number of bits of the generated private key
++     */
++    public SelfSignedCertificate(String fqdn, String algorithm, int bits) throws CertificateException {
++        this(fqdn, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER, algorithm, bits);
++    }
++
++    /**
++     * Creates a new instance.
++     * <p> Algorithm: RSA </p>
++     *
++     * @param fqdn      a fully qualified domain name
+      * @param notBefore Certificate is not valid before this time
+-     * @param notAfter Certificate is not valid after this time
++     * @param notAfter  Certificate is not valid after this time
+      */
+     public SelfSignedCertificate(String fqdn, Date notBefore, Date notAfter) throws CertificateException {
+         // Bypass entropy collection by using insecure random generator.
+         // We just want to generate it without any delay because it's for testing purposes only.
+-        this(fqdn, ThreadLocalInsecureRandom.current(), DEFAULT_KEY_LENGTH_BITS, notBefore, notAfter);
++        this(fqdn, ThreadLocalInsecureRandom.current(), DEFAULT_KEY_LENGTH_BITS, notBefore, notAfter, "RSA");
+     }
+ 
+     /**
+      * Creates a new instance.
+      *
+-     * @param fqdn a fully qualified domain name
+-     * @param random the {@link java.security.SecureRandom} to use
+-     * @param bits the number of bits of the generated private key
++     * @param fqdn      a fully qualified domain name
++     * @param notBefore Certificate is not valid before this time
++     * @param notAfter  Certificate is not valid after this time
++     * @param algorithm Key pair algorithm
++     * @param bits      the number of bits of the generated private key
+      */
+-    public SelfSignedCertificate(String fqdn, SecureRandom random, int bits) throws CertificateException {
+-        this(fqdn, random, bits, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER);
++    public SelfSignedCertificate(String fqdn, Date notBefore, Date notAfter, String algorithm, int bits)
++            throws CertificateException {
++        // Bypass entropy collection by using insecure random generator.
++        // We just want to generate it without any delay because it's for testing purposes only.
++        this(fqdn, ThreadLocalInsecureRandom.current(), bits, notBefore, notAfter, algorithm);
+     }
+ 
+     /**
+      * Creates a new instance.
++     * <p> Algorithm: RSA </p>
+      *
+-     * @param fqdn a fully qualified domain name
+-     * @param random the {@link java.security.SecureRandom} to use
+-     * @param bits the number of bits of the generated private key
++     * @param fqdn      a fully qualified domain name
++     * @param random    the {@link SecureRandom} to use
++     * @param bits      the number of bits of the generated private key
++     */
++    public SelfSignedCertificate(String fqdn, SecureRandom random, int bits)
++            throws CertificateException {
++        this(fqdn, random, bits, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER, "RSA");
++    }
++
++    /**
++     * Creates a new instance.
++     *
++     * @param fqdn      a fully qualified domain name
++     * @param random    the {@link SecureRandom} to use
++     * @param algorithm Key pair algorithm
++     * @param bits      the number of bits of the generated private key
++     */
++    public SelfSignedCertificate(String fqdn, SecureRandom random, String algorithm, int bits)
++            throws CertificateException {
++        this(fqdn, random, bits, DEFAULT_NOT_BEFORE, DEFAULT_NOT_AFTER, algorithm);
++    }
++
++    /**
++     * Creates a new instance.
++     * <p> Algorithm: RSA </p>
++     *
++     * @param fqdn      a fully qualified domain name
++     * @param random    the {@link SecureRandom} to use
++     * @param bits      the number of bits of the generated private key
+      * @param notBefore Certificate is not valid before this time
+-     * @param notAfter Certificate is not valid after this time
++     * @param notAfter  Certificate is not valid after this time
+      */
+     public SelfSignedCertificate(String fqdn, SecureRandom random, int bits, Date notBefore, Date notAfter)
+             throws CertificateException {
+-        // Generate an RSA key pair.
++        this(fqdn, random, bits, notBefore, notAfter, "RSA");
++    }
++
++    /**
++     * Creates a new instance.
++     *
++     * @param fqdn      a fully qualified domain name
++     * @param random    the {@link SecureRandom} to use
++     * @param bits      the number of bits of the generated private key
++     * @param notBefore Certificate is not valid before this time
++     * @param notAfter  Certificate is not valid after this time
++     * @param algorithm Key pair algorithm
++     */
++    public SelfSignedCertificate(String fqdn, SecureRandom random, int bits, Date notBefore, Date notAfter,
++                                 String algorithm) throws CertificateException {
++
++        if (!"EC".equalsIgnoreCase(algorithm) && !"RSA".equalsIgnoreCase(algorithm)) {
++            throw new IllegalArgumentException("Algorithm not valid: " + algorithm);
++        }
++
+         final KeyPair keypair;
+         try {
+-            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
++            KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
+             keyGen.initialize(bits, random);
+             keypair = keyGen.generateKeyPair();
+         } catch (NoSuchAlgorithmException e) {
+-            // Should not reach here because every Java implementation must have RSA key pair generator.
++            // Should not reach here because every Java implementation must have RSA and EC key pair generator.
+             throw new Error(e);
+         }
+ 
+         String[] paths;
+         try {
+-            // Try the OpenJDK's proprietary implementation.
+-            paths = OpenJdkSelfSignedCertGenerator.generate(fqdn, keypair, random, notBefore, notAfter);
++            // Try Bouncy Castle first as otherwise we will see an IllegalAccessError on more recent JDKs.
++            paths = BouncyCastleSelfSignedCertGenerator.generate(
++                    fqdn, keypair, random, notBefore, notAfter, algorithm);
+         } catch (Throwable t) {
+-            logger.debug("Failed to generate a self-signed X.509 certificate using sun.security.x509:", t);
++            logger.debug("Failed to generate a self-signed X.509 certificate using Bouncy Castle:", t);
+             try {
+-                // Try Bouncy Castle if the current JVM didn't have sun.security.x509.
+-                paths = BouncyCastleSelfSignedCertGenerator.generate(fqdn, keypair, random, notBefore, notAfter);
++                // Try the OpenJDK's proprietary implementation.
++                paths = OpenJdkSelfSignedCertGenerator.generate(fqdn, keypair, random, notBefore, notAfter, algorithm);
+             } catch (Throwable t2) {
+-                logger.debug("Failed to generate a self-signed X.509 certificate using Bouncy Castle:", t2);
++                logger.debug("Failed to generate a self-signed X.509 certificate using sun.security.x509:", t2);
+                 final CertificateException certificateException = new CertificateException(
+                         "No provider succeeded to generate a self-signed certificate. " +
+                                 "See debug log for the root cause.", t2);
+@@ -203,7 +284,7 @@
+     }
+ 
+     /**
+-     * Returns the generated RSA private key file in PEM format.
++     * Returns the generated EC/RSA private key file in PEM format.
+      */
+     public File privateKey() {
+         return privateKey;
+@@ -217,14 +298,14 @@
+     }
+ 
+     /**
+-     * Returns the generated RSA private key.
++     * Returns the generated EC/RSA private key.
+      */
+     public PrivateKey key() {
+         return key;
+     }
+ 
+     /**
+-     * Deletes the generated X.509 certificate file and RSA private key file.
++     * Deletes the generated X.509 certificate file and EC/RSA private key file.
+      */
+     public void delete() {
+         safeDelete(certificate);
+@@ -241,8 +322,8 @@
+             encodedBuf = Base64.encode(wrappedBuf, true);
+             try {
+                 keyText = "-----BEGIN PRIVATE KEY-----\n" +
+-                          encodedBuf.toString(CharsetUtil.US_ASCII) +
+-                          "\n-----END PRIVATE KEY-----\n";
++                        encodedBuf.toString(CharsetUtil.US_ASCII) +
++                        "\n-----END PRIVATE KEY-----\n";
+             } finally {
+                 encodedBuf.release();
+             }
+@@ -250,6 +331,9 @@
+             wrappedBuf.release();
+         }
+ 
++        // Change all asterisk to 'x' for file name safety.
++        fqdn = fqdn.replaceAll("[^\\w.-]", "x");
++
+         File keyFile = PlatformDependent.createTempFile("keyutil_" + fqdn + '_', ".key", null);
+         keyFile.deleteOnExit();
+ 
+@@ -272,8 +356,8 @@
+             try {
+                 // Encode the certificate into a CRT file.
+                 certText = "-----BEGIN CERTIFICATE-----\n" +
+-                           encodedBuf.toString(CharsetUtil.US_ASCII) +
+-                           "\n-----END CERTIFICATE-----\n";
++                        encodedBuf.toString(CharsetUtil.US_ASCII) +
++                        "\n-----END CERTIFICATE-----\n";
+             } finally {
+                 encodedBuf.release();
+             }
+--- a/handler/src/main/java/io/netty/handler/ssl/util/BouncyCastleSelfSignedCertGenerator.java
++++ b/handler/src/main/java/io/netty/handler/ssl/util/BouncyCastleSelfSignedCertGenerator.java
+@@ -5,7 +5,7 @@
+  * version 2.0 (the "License"); you may not use this file except in compliance
+  * with the License. You may obtain a copy of the License at:
+  *
+- *   http://www.apache.org/licenses/LICENSE-2.0
++ *   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
+@@ -36,14 +36,14 @@
+ import static io.netty.handler.ssl.util.SelfSignedCertificate.newSelfSignedCertificate;
+ 
+ /**
+- * Generates a self-signed certificate using <a href="http://www.bouncycastle.org/">Bouncy Castle</a>.
++ * Generates a self-signed certificate using <a href="https://www.bouncycastle.org/">Bouncy Castle</a>.
+  */
+ final class BouncyCastleSelfSignedCertGenerator {
+ 
+     private static final Provider PROVIDER = new BouncyCastleProvider();
+ 
+-    static String[] generate(String fqdn, KeyPair keypair, SecureRandom random, Date notBefore, Date notAfter)
+-            throws Exception {
++    static String[] generate(String fqdn, KeyPair keypair, SecureRandom random, Date notBefore, Date notAfter,
++                             String algorithm) throws Exception {
+         PrivateKey key = keypair.getPrivate();
+ 
+         // Prepare the information required for generating an X.509 certificate.
+@@ -51,7 +51,8 @@
+         X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
+                 owner, new BigInteger(64, random), notBefore, notAfter, owner, keypair.getPublic());
+ 
+-        ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSAEncryption").build(key);
++        ContentSigner signer = new JcaContentSignerBuilder(
++                algorithm.equalsIgnoreCase("EC") ? "SHA256withECDSA" : "SHA256WithRSAEncryption").build(key);
+         X509CertificateHolder certHolder = builder.build(signer);
+         X509Certificate cert = new JcaX509CertificateConverter().setProvider(PROVIDER).getCertificate(certHolder);
+         cert.verify(keypair.getPublic());


=====================================
debian/patches/series
=====================================
@@ -23,3 +23,4 @@ CVE-2022-41881.patch
 CVE-2022-41915.patch
 CVE-2023-34462.patch
 CVE-2023-44487.patch
+22-java-21.patch



View it on GitLab: https://salsa.debian.org/java-team/netty/-/compare/538e85cc9d5a9ff26afcab6d242db4df18a57ce3...c5fedfa17cf04c2cc68c52ab37694e32a4d7fa6d

-- 
View it on GitLab: https://salsa.debian.org/java-team/netty/-/compare/538e85cc9d5a9ff26afcab6d242db4df18a57ce3...c5fedfa17cf04c2cc68c52ab37694e32a4d7fa6d
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20231209/c91899f9/attachment.htm>


More information about the pkg-java-commits mailing list