Replace native tool deps (keytool/openssl/certbot) with pure Java APIs#403
Replace native tool deps (keytool/openssl/certbot) with pure Java APIs#403
Conversation
…e Java APIs xRTCertificateManager previously shelled out to keytool, openssl, and certbot via ProcessBuilder — unversioned system binaries that the build couldn't declare as dependencies. This replaces all three with pure Java: - keytool → java.security.KeyStore API - openssl (RSA keygen, CSR, PEM→PKCS12) → BouncyCastle + JDK crypto - certbot (ACME/Let's Encrypt) → acme4j New versioned dependencies in libs.versions.toml: acme4j 3.5.1, BouncyCastle 1.82. Extracted KeyStoreOperations utility class (no XVM dependencies) with unit tests covering self-signed cert generation, symmetric key, password storage, keystore password change, key extraction, and entry deletion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
I have not tested any of it with the platform; please hold on the merge
ggleyzer
left a comment
There was a problem hiding this comment.
In addition to two reported issues I still didn't have time to test this in the real world, having to talk to the "real" CA authority. After the changes I requested are submitted I'm going to test it with the platform.
| return xException.makeHandle(frame, | ||
| "Unsupported certificate provider: " + hProvider.getStringValue()); | ||
| private void pollAuthUntilValid(Authorization auth, String sDomain) throws Exception { | ||
| for (int i = 0; i < MAX_POLL_ATTEMPTS && auth.getStatus() != Status.VALID; i++) { |
There was a problem hiding this comment.
This is a very questionable implementation. Sleeping for five seconds for something that may come back in a millisecond seems to be wrong. I realize that Process.waitFor() we are using now seems to use the same approach, but (i) they only sleep for 100 millis; (ii) jdk can improve or make it native at any time; (ii) one of the points of this exercise is to improve the current behavior.
|
|
||
| if (cert instanceof X509Certificate x509Cert) { | ||
| var session = new Session(acmeServerUri(fStaging)); | ||
| var accountKeyPair = KeyPairUtils.createKeyPair(2048); |
There was a problem hiding this comment.
This seems to be wrong; the key pair we pass to the org.shredzone.acme4j.Certificate.revoke() API must be a key pair associated with the certificate being revoked, but a randomly generated one
| : frameCaller.assignValue(iReturn, | ||
| xArray.makeByteArrayHandle(key.getEncoded(), Mutability.Constant)); | ||
| } catch (Throwable e) { | ||
| // TODO: catching Throwable and discarding the cause is bad practice; the |
There was a problem hiding this comment.
To be fair we don't fully discard it; the message we log carries at least some information about it. Clearly we could improve it though
Summary
ProcessBuildercalls tokeytool,openssl, andcertbotinxRTCertificateManagerwith pure Java equivalentskeytool→java.security.KeyStoreAPI (JDK)openssl(RSA keygen, CSR generation, PEM→PKCS12 conversion) → BouncyCastle + JDK cryptocertbot(ACME/Let's Encrypt protocol) → acme4jlibs.versions.toml)KeyStoreOperationsutility class with no XVM runtime dependenciesNotes
certbot/certbot-stagingprovider names are preserved for backward compatibility.challengewebroot directory as beforeTest plan
KeyStoreOperationsTesttests pass (self-signed cert, symmetric key, password, password change, key extraction, deletion)🤖 Generated with Claude Code