[Git][java-team/apache-directory-server][master] 7 commits: add reflection patch

Tony Mancill (@tmancill) gitlab at salsa.debian.org
Wed Nov 22 21:21:57 GMT 2023



Tony Mancill pushed to branch master at Debian Java Maintainers / apache-directory-server


Commits:
78a61dae by Vladimir Petko at 2023-11-20T13:43:00+13:00
add reflection patch

- - - - -
f584959a by Vladimir Petko at 2023-11-20T14:10:49+13:00
add x509 opens

- - - - -
a64fa8ad by Vladimir Petko at 2023-11-20T14:21:07+13:00
fix patch header

- - - - -
fc3dbecd by Vladimir Petko at 2023-11-20T14:54:50+13:00
reformat patch

- - - - -
5457697c by Vladimir Petko at 2023-11-20T14:54:50+13:00
changelog

- - - - -
cb30e654 by Vladimir Petko at 2023-11-21T17:30:45+13:00
remove accidentally added patch hunk

- - - - -
91e93ba3 by Tony Mancill at 2023-11-22T21:21:43+00:00
Merge branch 'master' into 'master'

Resolve Java 21 FTBFS

See merge request java-team/apache-directory-server!1
- - - - -


4 changed files:

- debian/apacheds.default
- debian/changelog
- + debian/patches/do-not-use-x509certinfo-set.patch
- debian/patches/series


Changes:

=====================================
debian/apacheds.default
=====================================
@@ -2,7 +2,7 @@
 JAVA_HOME=/usr/lib/jvm/default-java
 
 # Any additional java options (ex: -Xms:256m)
-JAVA_OPTS="-Djava.awt.headless=true -Xmx256m --add-opens=java.base/sun.security.util=ALL-UNNAMED"
+JAVA_OPTS="-Djava.awt.headless=true -Xmx256m --add-opens=java.base/sun.security.util=ALL-UNNAMED --add-opens=java.base/sun.security.x509=ALL-UNNAMED"
 
 # To enable remote debugging uncomment the following line.
 # You will then be able to use a java debugger on port 8000.


=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+apache-directory-server (2.0.0~M26-4) UNRELEASED; urgency=medium
+
+  * d/p/do-not-use-x509certinfo-set.patch, d/apacheds.default: add patch
+    to use reflection for the access to internal x509 API, add --add-
+    opens statement for sun.security.x509 (Closes: #1052589).
+
+ -- Vladimir Petko <vladimir.petko at canonical.com>  Mon, 20 Nov 2023 14:22:27 +1300
+
 apache-directory-server (2.0.0~M26-3) unstable; urgency=medium
 
   * Team upload.


=====================================
debian/patches/do-not-use-x509certinfo-set.patch
=====================================
@@ -0,0 +1,420 @@
+Description: Use reflection to access internal X509 API
+ sun.security.x509 has breaking API changes between Java 17 and Java 21. 
+ Use reflection to access internal API until .M27 release of Apache DS that
+ switches to Bouncycastle API for certificate manipulation.
+Author: Vladimir Petko <vladimir.petko at canonical.com>
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1052589
+Forwarded: not-needed
+Last-Update: 2023-11-20
+--- a/core/src/main/java/org/apache/directory/server/core/security/CertificateUtil.java
++++ b/core/src/main/java/org/apache/directory/server/core/security/CertificateUtil.java
+@@ -63,6 +63,304 @@
+ import sun.security.x509.X500Name;
+ import sun.security.x509.X509CertImpl;
+ import sun.security.x509.X509CertInfo;
++import  sun.security.x509.Extension;
++
++import java.lang.reflect.InvocationTargetException;
++import java.lang.reflect.Method;
++
++final class X509ImplFactory
++{
++    private static Method NEW_SIGNED = null;
++    private static Method SIGN = null;
++
++    static
++    {
++        try
++        {
++            NEW_SIGNED = X509CertImpl.class.getMethod( "newSigned", X509CertInfo.class, java.security.PrivateKey.class, String.class );
++        }
++        catch ( NoSuchMethodException | SecurityException e )
++        {
++            try
++            {
++                SIGN = X509CertImpl.class.getMethod( "sign", java.security.PrivateKey.class, String.class );
++            }
++            catch ( NoSuchMethodException | SecurityException ex )
++            {
++                throw new RuntimeException( ex );
++            }
++        }
++    }
++
++    private X509ImplFactory( )
++    {
++    }
++
++    public static X509CertImpl create( X509CertInfo info, java.security.PrivateKey pk, String algo )
++    {
++        try
++        {
++            if ( NEW_SIGNED == null )
++            {
++                X509CertImpl impl = X509CertImpl.class.getConstructor( X509CertInfo.class ).newInstance( info );
++                SIGN.invoke( impl, pk, algo );
++                return impl;
++            }
++            return ( X509CertImpl ) NEW_SIGNED.invoke( null, info, pk, algo );
++        }
++        catch ( IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException | NoSuchMethodException | SecurityException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++}
++
++class CertificateExtensionsProxy
++{
++    private static Method SET = null;
++    private static Method SET_EXTENSION = null;
++    private CertificateExtensions _ext = null;
++    static
++    {
++        try
++        {
++            SET = CertificateExtensions.class.getMethod( "set", String.class, Object.class );
++        }
++        catch ( NoSuchMethodException | SecurityException e )
++        {
++            try
++            {
++                SET_EXTENSION = CertificateExtensions.class.getMethod( "setExtension", String.class, Extension.class );
++            }
++            catch ( NoSuchMethodException | SecurityException ex )
++            {
++                throw new RuntimeException( ex );
++            }
++        }
++    }
++
++    CertificateExtensionsProxy( CertificateExtensions ext )
++    {
++        _ext = ext;
++    }
++
++    public void set( String name, Extension o )
++    {
++        try
++        {
++            if ( SET == null )
++            {
++                SET_EXTENSION.invoke( _ext, name, o );
++            }
++            else
++            {
++                SET.invoke( _ext, name, o );
++            }
++        }
++        catch ( IllegalAccessException | IllegalArgumentException | InvocationTargetException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++}
++
++class X509CertInfoProxy
++{
++    private static Method SET = null;
++    private static Method SET_VERSION = null;
++    private static Method SET_SERIAL_NUMBER = null;
++    private static Method SET_ALGORITHM_ID = null;
++    private static Method SET_ISSUER = null;
++    private static Method SET_VALIDITY = null;
++    private static Method SET_SUBJECT = null;
++    private static Method SET_KEY = null;
++    private static Method SET_EXTENSIONS = null;
++    private X509CertInfo _info = null;
++
++    static
++    {
++        Class clazz = X509CertInfo.class;
++        try
++        {
++            SET = clazz.getMethod( "set", String.class, Object.class );
++        }
++        catch ( NoSuchMethodException | SecurityException e )
++        {
++            try
++            {
++                SET_VERSION = clazz.getMethod( "setVersion", CertificateVersion.class );
++                SET_SERIAL_NUMBER = clazz.getMethod( "setSerialNumber", CertificateSerialNumber.class  );
++                SET_ALGORITHM_ID =  clazz.getMethod( "setAlgorithmId", CertificateAlgorithmId.class );
++                SET_ISSUER = clazz.getMethod( "setIssuer", X500Name.class );
++                SET_VALIDITY = clazz.getMethod( "setValidity", CertificateValidity.class );
++                SET_SUBJECT =  clazz.getMethod( "setSubject", X500Name.class );
++                SET_KEY = clazz.getMethod( "setKey", CertificateX509Key.class );
++                SET_EXTENSIONS = clazz.getMethod( "setExtensions", CertificateExtensions.class );
++            }
++            catch ( NoSuchMethodException | SecurityException ex )
++            {
++                throw new RuntimeException( ex );
++            }
++        }
++    }
++
++    X509CertInfoProxy( X509CertInfo info )
++    {
++        _info = info;
++    }
++
++    public void setVersion( CertificateVersion v )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.VERSION, v );
++            }
++            else
++            {
++                SET_VERSION.invoke( _info, v );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setSerialNumber( CertificateSerialNumber sn )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.SERIAL_NUMBER, sn );
++            }
++            else
++            {
++                SET_SERIAL_NUMBER.invoke( _info, sn );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setAlgorithmId( CertificateAlgorithmId id )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.ALGORITHM_ID, id );
++            }
++            else
++            {
++                SET_ALGORITHM_ID.invoke( _info, id );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setIssuer( X500Name id )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.ISSUER, id );
++            }
++            else
++            {
++                SET_ISSUER.invoke( _info, id );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setValidity( CertificateValidity id )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.VALIDITY, id );
++            }
++            else
++            {
++                SET_VALIDITY.invoke( _info, id );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setSubject( X500Name id )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.SUBJECT, id );
++            }
++            else
++            {
++                SET_SUBJECT.invoke( _info, id );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setKey( CertificateX509Key id )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.KEY, id );
++            }
++            else
++            {
++                SET_KEY.invoke( _info, id );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++
++    public void setExtensions( CertificateExtensions id )
++    {
++        try
++        {
++            if ( SET != null )
++            {
++                SET.invoke( _info, X509CertInfo.EXTENSIONS, id );
++            }
++            else
++            {
++                SET_EXTENSIONS.invoke( _info, id  );
++            }
++        }
++        catch ( InvocationTargetException | IllegalAccessException e )
++        {
++            throw new RuntimeException( e );
++        }
++    }
++}
+ 
+ /**
+  * Helper class used to generate self-signed certificates, and load a KeyStore
+@@ -90,19 +388,21 @@
+         Date to = new Date( from.getTime() + days * 86_400_000L );
+         CertificateValidity interval = new CertificateValidity( from, to );
+ 
++        X509CertInfoProxy proxy = new X509CertInfoProxy( info );
++
+         // Feed the certificate info structure
+         // version         [0]  EXPLICIT Version DEFAULT v1
+         // Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+-        info.set( X509CertInfo.VERSION, new CertificateVersion( CertificateVersion.V3 ) );
++        proxy.setVersion( new CertificateVersion( CertificateVersion.V3 ) );
+         
+         // serialNumber         CertificateSerialNumber
+         // CertificateSerialNumber  ::=  INTEGER
+         BigInteger serialNumber = new BigInteger( 64, new SecureRandom() );
+-        info.set( X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber( serialNumber ) );
++        proxy.setSerialNumber( new CertificateSerialNumber( serialNumber ) );
+ 
+         // signature            AlgorithmIdentifier
+         AlgorithmId algo = AlgorithmId.get( algoStr );
+-        info.set( X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId( algo ) );
++        proxy.setAlgorithmId( new CertificateAlgorithmId( algo ) );
+ 
+         // issuer               Name
+         // Name ::= CHOICE {
+@@ -115,13 +415,13 @@
+         //          value    AttributeValue }
+         // AttributeType ::= OBJECT IDENTIFIER
+         // AttributeValue ::= ANY DEFINED BY AttributeType
+-        info.set( X509CertInfo.ISSUER, issuer );
++        proxy.setIssuer( issuer );
+         
+         // validity             Validity,
+         // Validity ::= SEQUENCE {
+         //          notBefore      Time,
+         //          notAfter       Time }
+-        info.set( X509CertInfo.VALIDITY, interval );
++        proxy.setValidity( interval );
+         
+         // subject              Name
+         // Name ::= CHOICE {
+@@ -134,17 +434,17 @@
+         //          value    AttributeValue }
+         // AttributeType ::= OBJECT IDENTIFIER
+         // AttributeValue ::= ANY DEFINED BY AttributeType
+-        info.set( X509CertInfo.SUBJECT, subject );
++        proxy.setSubject( subject );
+         
+         // subjectPublicKeyInfo SubjectPublicKeyInfo,
+         // SubjectPublicKeyInfo  ::=  SEQUENCE  {
+         //          algorithm            AlgorithmIdentifier,
+         //          subjectPublicKey     BIT STRING  }
+-        info.set( X509CertInfo.KEY, new CertificateX509Key( keyPair.getPublic() ) );
++        proxy.setKey( new CertificateX509Key( keyPair.getPublic() ) );
+ 
+         // Extensions. Basically, a subjectAltName and a Basic-Constraint 
+         CertificateExtensions extensions = new CertificateExtensions();
+-
++        CertificateExtensionsProxy extProxy = new CertificateExtensionsProxy(extensions);
+         // SubjectAltName
+         GeneralNames names = new GeneralNames();
+         names.add( new GeneralName( new DNSName( InetAddress.getLocalHost().getHostName() ) ) );
+@@ -158,17 +458,16 @@
+         //            DerValue.tag_IA5String, "*.apache.org" ) ) ) );
+         SubjectAlternativeNameExtension subjectAltName = new SubjectAlternativeNameExtension( names );
+         
+-        extensions.set( subjectAltName.getExtensionId().toString(), subjectAltName );
++        extProxy.set( subjectAltName.getExtensionId().toString(), subjectAltName );
+ 
+         // The Basic-Constraint,
+         BasicConstraintsExtension basicConstraint = new BasicConstraintsExtension( CRITICAL, isCA, -1 );
+-        extensions.set( basicConstraint.getExtensionId().toString(), basicConstraint );
++        extProxy.set( basicConstraint.getExtensionId().toString(), basicConstraint );
+ 
+         // Inject the extensions into the cert
+-        info.set( X509CertInfo.EXTENSIONS, extensions );
++        proxy.setExtensions( extensions );
+     }
+-    
+-    
++
+     /**
+      * Create a self signed certificate
+      * 
+@@ -194,8 +493,7 @@
+         setInfo( info, issuer, issuer, keyPair, days, algoStr, SELF_SIGNED );
+         
+         // Sign the cert to identify the algorithm that's used.
+-        X509CertImpl certificate = new X509CertImpl( info );
+-        certificate.sign( keyPair.getPrivate(), algoStr );
++        X509CertImpl certificate = X509ImplFactory.create(info, keyPair.getPrivate(), algoStr);
+ 
+         return certificate;
+     }
+@@ -226,8 +524,7 @@
+         setInfo( info, subject, issuer, keyPair, days, algoStr, CA_SIGNED );
+          
+         // Sign the cert to identify the algorithm that's used.
+-        X509CertImpl certificate = new X509CertImpl( info );
+-        certificate.sign( keyPair.getPrivate(), algoStr );
++        X509CertImpl certificate = X509ImplFactory.create(info, keyPair.getPrivate(), algoStr);
+ 
+         return certificate;
+     }
+


=====================================
debian/patches/series
=====================================
@@ -1,3 +1,4 @@
 01-jar-packaging.patch
 mina-2.2-update.patch
 directory-api-compatibility.patch
+do-not-use-x509certinfo-set.patch



View it on GitLab: https://salsa.debian.org/java-team/apache-directory-server/-/compare/afe9dc884a94abe4fa231b0f61c03199b96ff5f1...91e93ba37c0ed55fbf9860067774f919cead60fd

-- 
View it on GitLab: https://salsa.debian.org/java-team/apache-directory-server/-/compare/afe9dc884a94abe4fa231b0f61c03199b96ff5f1...91e93ba37c0ed55fbf9860067774f919cead60fd
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/20231122/8577439c/attachment.htm>


More information about the pkg-java-commits mailing list