[ 
https://issues.apache.org/jira/browse/GEODE-10509?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jinwoo Hwang reassigned GEODE-10509:
------------------------------------

    Assignee: Jinwoo Hwang

> Replace Internal JDK APIs in CertificateBuilder with Public Alternatives
> ------------------------------------------------------------------------
>
>                 Key: GEODE-10509
>                 URL: https://issues.apache.org/jira/browse/GEODE-10509
>             Project: Geode
>          Issue Type: Improvement
>            Reporter: Jinwoo Hwang
>            Assignee: Jinwoo Hwang
>            Priority: Major
>
> h2. Summary
> Replace usage of internal proprietary {{sun.security.x509.*}} APIs in 
> {{CertificateBuilder.java}} with public, supported alternatives to ensure 
> compatibility with future JDK versions and eliminate compilation warnings.
> h2. Problem Statement
> h3. Current Behavior
> During compilation, the Java compiler produces warnings about usage of 
> internal proprietary APIs in 
> {{{}geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateBuilder.java{}}}:
> {noformat}
> warning: [class] is internal proprietary API and may be removed in a future 
> release
> {noformat}
> h3. Affected Internal APIs
> The following {{sun.security.x509.*}} classes are currently being used:
>  # {{AlgorithmId}}
>  # {{BasicConstraintsExtension}}
>  # {{CertificateAlgorithmId}}
>  # {{CertificateExtensions}}
>  # {{CertificateSerialNumber}}
>  # {{CertificateValidity}}
>  # {{CertificateVersion}}
>  # {{CertificateX509Key}}
>  # {{DNSName}}
>  # {{GeneralName}}
>  # {{GeneralNames}}
>  # {{IPAddressName}}
>  # {{KeyIdentifier}}
>  # {{KeyUsageExtension}}
>  # {{SubjectAlternativeNameExtension}}
>  # {{SubjectKeyIdentifierExtension}}
>  # {{X500Name}}
>  # {{X509CertImpl}}
>  # {{X509CertInfo}}
> h3. Root Cause
> {{CertificateBuilder}} is a test utility class that generates X.509 
> certificates for SSL/TLS testing. It currently relies on internal JDK APIs 
> from the {{sun.security.x509}} package, which are:
>  * Not part of the public Java API
>  * Not guaranteed to remain stable across JDK versions
>  * May be removed or restricted in future JDK releases (especially with 
> module system restrictions)
>  * Generate compiler warnings that clutter build output
> h3. Risk Assessment
> *Severity:* Medium-High
>  * *Immediate Impact:* Compilation warnings (non-blocking)
>  * *Future Impact:* Code may break in future JDK versions when these APIs are 
> removed
>  * *JDK Module System:* APIs may become inaccessible due to strong 
> encapsulation
>  * *Maintenance:* Makes upgrading to newer JDK versions risky
> h2. Proposed Solution
> h3. Option 1: Use Bouncycastle Library (Recommended)
> Replace internal JDK APIs with the Bouncycastle cryptography library, which 
> provides comprehensive X.509 certificate building capabilities through public 
> APIs.
> *Advantages:*
>  * Well-maintained, industry-standard library
>  * Public, stable API with long-term support
>  * Rich feature set for certificate manipulation
>  * Cross-JDK compatibility
>  * Already used in many Apache projects
>  * Extensive documentation and examples
> *Disadvantages:*
>  * Adds external dependency
>  * Slightly larger footprint (library size)
> *Implementation:*
> {code:java}
> // Add dependency
> dependencies {
>     implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
> }
> // Replace sun.security.x509.* imports with Bouncycastle equivalents
> import org.bouncycastle.asn1.x500.X500Name;
> import org.bouncycastle.asn1.x509.BasicConstraints;
> import org.bouncycastle.asn1.x509.Extension;
> import org.bouncycastle.asn1.x509.GeneralName;
> import org.bouncycastle.asn1.x509.GeneralNames;
> import org.bouncycastle.cert.X509CertificateHolder;
> import org.bouncycastle.cert.X509v3CertificateBuilder;
> import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
> import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
> import org.bouncycastle.operator.ContentSigner;
> import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
> {code}
> h3. Option 2: Use Java Standard APIs with Limited Functionality
> Use only public Java APIs like {{java.security.cert.X509Certificate}} and 
> {{{}javax.security.auth.x500.X500Principal{}}}.
> *Advantages:*
>  * No external dependencies
>  * Uses only standard JDK APIs
> *Disadvantages:*
>  * Limited certificate building capabilities
>  * May require workarounds for advanced features (extensions, constraints)
>  * Less flexible than current implementation
>  * May not support all current test scenarios
> h3. Option 3: Use JDK 21+ Certificate API Enhancements
> If upgrading to JDK 21+, leverage newer certificate APIs (if available).
> *Advantages:*
>  * Native JDK support
>  * No external dependencies
> *Disadvantages:*
>  * Requires JDK version upgrade
>  * Limited compared to Bouncycastle
>  * Still may not cover all use cases
> h2. Recommended Approach
> *Use Option 1 (Bouncycastle)* because:
>  # Most comprehensive solution with full feature parity
>  # Widely adopted in enterprise and Apache projects
>  # Stable, public API with long-term support
>  # Works across all supported JDK versions
>  # Better than maintaining fragile code dependent on internal APIs
> h2. Implementation Plan
> h3. Phase 1: Analysis
>  # Audit all usages of {{sun.security.x509.*}} APIs in {{CertificateBuilder}}
>  # Map each internal API to Bouncycastle equivalent
>  # Identify any unique features that need special handling
>  # Document the mapping for review
> h3. Phase 2: Dependency Addition
>  # Add Bouncycastle dependency to {{geode-junit}} module
>  # Update dependency management configuration
>  # Verify license compatibility (Bouncycastle uses MIT-like license)
>  # Document dependency rationale in build files
> h3. Phase 3: Code Migration
>  # Create new implementation using Bouncycastle APIs
>  # Maintain method signatures for backward compatibility
>  # Add comprehensive inline documentation
>  # Ensure feature parity with current implementation
> h3. Phase 4: Testing
>  # Run existing SSL/TLS test suite
>  # Verify generated certificates match expected structure
>  # Test certificate validation and chain building
>  # Performance comparison (if applicable)
>  # Cross-JDK testing (JDK 11, 17, 21)
> h3. Phase 5: Cleanup
>  # Remove all {{sun.security.x509.*}} imports
>  # Verify no compilation warnings
>  # Update any related documentation
>  # Add comments explaining why Bouncycastle was chosen
> h2. Expected Outcomes
> h3. Success Criteria
> (/) Zero compiler warnings about internal APIs
> (/) All existing SSL/TLS tests pass
> (/) Generated certificates are functionally equivalent
> (/) Code works on all supported JDK versions
> (/) No breaking changes to test utilities API
> h3. Impact Assessment
> ||Category||Impact||
> |*Risk Level*|Low - Changes isolated to test utilities|
> |*Scope*|geode-junit module only|
> |*Dependencies*|Adds Bouncycastle library|
> |*Compatibility*|Improved - works across all JDK versions|
> |*Maintenance*|Improved - uses stable public API|
> h2. Files to be Modified
>  # {{geode-junit/build.gradle}} - Add Bouncycastle dependency
>  # 
> {{geode-junit/src/main/java/org/apache/geode/cache/ssl/CertificateBuilder.java}}
>  - Replace internal APIs
>  # Potentially: Any other files using {{sun.security.*}} packages (TBD from 
> analysis)
> h2. Migration Mapping Examples
> h3. X509Certificate Creation
> {code:java}
> // Before (Internal API):
> X509CertInfo info = new X509CertInfo();
> info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
> // ... more configuration
> X509CertImpl cert = new X509CertImpl(info);
> // After (Bouncycastle):
> X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
>     issuer, serialNumber, notBefore, notAfter, subject, publicKey);
> // ... add extensions
> X509CertificateHolder certHolder = certBuilder.build(signer);
> X509Certificate cert = new 
> JcaX509CertificateConverter().getCertificate(certHolder);
> {code}
> h3. Subject Alternative Names
> {code:java}
> // Before (Internal API):
> GeneralNames generalNames = new GeneralNames();
> generalNames.add(new GeneralName(new DNSName(hostname)));
> SubjectAlternativeNameExtension san = new 
> SubjectAlternativeNameExtension(generalNames);
> // After (Bouncycastle):
> GeneralName[] generalNames = new GeneralName[] {
>     new GeneralName(GeneralName.dNSName, hostname)
> };
> GeneralNames subjectAltNames = new GeneralNames(generalNames);
> certBuilder.addExtension(Extension.subjectAlternativeName, false, 
> subjectAltNames);
> {code}
> h3. Basic Constraints
> {code:java}
> // Before (Internal API):
> BasicConstraintsExtension bce = new BasicConstraintsExtension(true, true, 0);
> extensions.set(BasicConstraintsExtension.NAME, bce);
> // After (Bouncycastle):
> BasicConstraints basicConstraints = new BasicConstraints(true);
> certBuilder.addExtension(Extension.basicConstraints, true, basicConstraints);
> {code}
> h2. Alternative Libraries (For Consideration)
> If Bouncycastle is not acceptable:
>  # *Apache Commons Crypto* - Limited cert building support
>  # *Conscrypt* - Google's Java crypto provider (primarily for performance)
>  # *JCA/JCE providers* - May still have limitations
> h2. Dependencies
>  * *License:* Bouncycastle uses MIT-like license (compatible with Apache 2.0)
>  * *Version:* Recommend bcpkix-jdk15on:1.70 or later
>  * *Maven Coordinates:* {{org.bouncycastle:bcpkix-jdk15on:1.70}}
> h2. References
>  * [JEP 260: Encapsulate Most Internal APIs|https://openjdk.org/jeps/260]
>  * [Bouncycastle 
> Documentation|https://www.bouncycastle.org/documentation.html]
>  * [Java X.509 Certificate 
> API|https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/security/cert/X509Certificate.html]
>  * [Bouncycastle PKIX 
> Examples|https://github.com/bcgit/bc-java/tree/main/pkix/src/test/java/org/bouncycastle/cert/test]
> h2. Testing Strategy
> h3. Unit Tests
>  * Verify certificate generation with various parameters
>  * Test all extension types (SAN, key usage, basic constraints)
>  * Validate certificate chain building
>  * Test self-signed and CA-signed certificates
> h3. Integration Tests
>  * Run full SSL/TLS test suite
>  * Test with different JDK versions (11, 17, 21)
>  * Verify interoperability with existing certificates
>  * Performance regression testing
> h3. Validation Criteria
>  * All existing tests pass without modification
>  * No new compiler warnings
>  * Generated certificates validate with standard tools (openssl, keytool)
>  * Certificate format matches previous implementation



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to