Is it possible to change keystore at runtime? Currently I am setting up SSL before I do a server.start() -
sslContextFactory.setTrustStore(ks);
sslContextFactor
After posting this question in Jetty mailing list, I got response that is it not really feasible
I'm not an expert in java's security packages but to my knowledge there is no straight forward way to create the keypair from public API.
However, I is possible if you could allow your code do an import from sun's restricted packages like:
import sun.security.x509.*;
Here is an outline of code you are looking for:
PrivateKey privkey = pair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
//Validity for next one year
Date to = new Date(from.getTime() + (365) * 86400000l);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger sn = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));
// Sign the cert
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privkey, algorithm);
//cert object is ready to use
Hope this helps
This has been fixed since Jetty 9.4.0, see https://github.com/eclipse/jetty.project/issues/918. You can now just override the Key/TrustStore etc. and call SslContextFactory.reload
.
Note however there is a caveat with TLS session resumption: https://github.com/eclipse/jetty.project/issues/918#issuecomment-250791417. According to the comments, it shouldn't be an issue with common browsers, but who knows about IE, Mobile, non-browser clients, etc.
Create your own KeyStore
implementation.
You can create a class that overrides KeyStore
and put this as a truststore to Jetty. Then you are free to return any Certificate
you want.
Probably you have to use a 3rd party library to create certificates on the fly as Java cannot create certificates (with the official API). You can use BouncyCastle for this.
It seems there are two issues here: generating the certificate on the dynamically ("What I would like to do is create a certificate at runtime and use it.") and setting it up without restarting ("Is it possible to change keystore at runtime?").
To generate a certificate dynamically, you can use BouncyCastle and its X509V3CertificateGenerator class.
First, generate a self-signed CA (with the CA basic constraint set), using keytool for example (look at the -ext
option for details). This will be your custom CA.
Export the certificate from that keystore (only the CA certificate, not its private key) and import it into the clients you're going to use.
In your application, using that private key for signing with the X509V3CertificateGenerator
, and make sure the Issuer DN you use matches the Subject DN of the CA cert you've generated above.
Then, you'll need to configure the certificate generate with a Subject DN (or Subject Alternative Name) that matches the host name your client intended to contact. This may be the tricky bit if you intend to do this automatically as some sort of transparent proxy. (As far as I know, current versions of Java can't read the name coming from the SNI extension, at least not in advance or without doing more manual processing.) The easier way would certainly be to have this host name as a configurable option in your tool.
To set it up without restarting the server, you could implement your own X509KeyManager
that stays in place in the SSLContext
you're using, but for which you keep a reference and custom accessors to re-configure the certificate later on. It's certainly not necessarily something "clean", and I haven't tried it, but it should work in principle. (You should certainly make sure the concurrency aspects are handled properly.)
This might allow you not to have to shut down the listening socket, reconfigure the SSLContext
and restart the socket. Considering that you might need to interact with your application anyway (to reconfigure the host name), this might be overkill.