Letsencrypt Challenge Keymanager

Key Manager that handle the AMCE tls-sni-01 challenge. It is written in plain java using sun methods but no external dependency. ACME is the protocol used by Letsencrypt
package org.suche.web.acme;

import java.net.Socket;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.security.spec.ECGenParameterSpec;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.net.ssl.ExtendedSSLSession;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509ExtendedKeyManager;

import sun.security.x509.AlgorithmId;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateExtensions;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.GeneralName;
import sun.security.x509.GeneralNames;
import sun.security.x509.SubjectAlternativeNameExtension;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;

public final class ChallengeKeyManager extends X509ExtendedKeyManager {
	private final Logger log = Logger.getLogger(this.getClass().getCanonicalName());
	private final KeyPair kp; // secp256r1 , secp384r1 , secp521r1
	private final String KEY_CURVE = "secp521r1";
	private final String SIG_ALG = "SHA256withECDSA"; // SHA256withRSA, SHA256withECDSA, SHA384withRSA, SHA384withECDSA, SHA1withRSA, SHA1withECDSA
	private static final List valid = new LinkedList<>();

	public static final void addValid(final String fqdn) {
		if(fqdn == null) return;
		if(valid.size() >= 10) valid.remove(0);
		valid.add(fqdn.toLowerCase());
	}

	public ChallengeKeyManager() {
		try {
			final KeyPairGenerator g = KeyPairGenerator.getInstance("EC");
			g.initialize(new ECGenParameterSpec(this.KEY_CURVE));
			this.kp = g.generateKeyPair();
		} catch(final Throwable t) { throw new RuntimeException(t); }
	}

	private String chooseServerAlias(final String keyType, final Principal[] issuers, final SSLSession session) {
		if("RSA".equals(keyType)) return null;
		if(!(session instanceof ExtendedSSLSession)) return null;
		final List snis = ((ExtendedSSLSession)session).getRequestedServerNames();
		if(snis == null || snis.size() == 0) return null;
		final SNIServerName n = snis.get(0);
		if(!(n instanceof SNIHostName)) return null;
		final SNIHostName shn = (SNIHostName)n;
		final String fqdn = shn.getAsciiName().toLowerCase();
		if(!fqdn.endsWith(".acme.invalid")) return null;
		if(valid.contains(shn.getAsciiName().toLowerCase())) {
			this.log.log(Level.WARNING, "chooseEngineServerAlias("+keyType+", "+(issuers==null?-1:issuers.length)+" , {sni:"+shn.getAsciiName()+"})="+shn.getAsciiName());
			return shn.getAsciiName();
		}
		this.log.log(Level.WARNING, "chooseEngineServerAlias("+keyType+", "+(issuers==null?-1:issuers.length)+" , {sni:"+shn.getAsciiName()+"})=>Unknown");
		throw new RuntimeException("BLOCKED");
	}

	@Override public String   chooseEngineClientAlias(final String[] keyType, final Principal[] issuers, final SSLEngine engine) { return null; }
	@Override public String   chooseClientAlias      (final String[] keyType, final Principal[] issuers, final Socket socket) { return null; }
	@Override public String[] getClientAliases       (final String   keyType, final Principal[] issuers) { return null; }
	@Override public String[] getServerAliases(final String keyType, final Principal[] issuers) { return null; }

	@Override public String chooseEngineServerAlias(final String keyType, final Principal[] issuers, final SSLEngine engine) {
		return chooseServerAlias(keyType, issuers, engine.getHandshakeSession());
	}

	@Override public String chooseServerAlias(final String keyType, final Principal[] issuers, final Socket socket) {
		return chooseServerAlias(keyType, issuers, ((SSLSocket)socket).getHandshakeSession());
	}

	@Override public X509Certificate[] getCertificateChain(final String alias) {
		try {
			final X500Name              name = new X500Name("cn=dummy");
			final X509CertInfo          ci = new X509CertInfo();
			final CertificateExtensions ext = new CertificateExtensions();
			final GeneralNames          gnames = new GeneralNames();
			ci.set(X509CertInfo.VERSION      , new CertificateVersion(2));
			ci.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new Random().nextInt() & 0x7FFFFFFF));
			ci.set(X509CertInfo.ALGORITHM_ID , new CertificateAlgorithmId(AlgorithmId.get(this.SIG_ALG)));
			ci.set(X509CertInfo.SUBJECT      , name);
			ci.set(X509CertInfo.KEY          , new CertificateX509Key(this.kp.getPublic()));
			ci.set(X509CertInfo.VALIDITY     , new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 3600000))); // 1.Hour
			ci.set(X509CertInfo.ISSUER       , name);
			gnames.add(new GeneralName(new AcmeDNSName(alias)));
			ext.set(SubjectAlternativeNameExtension.NAME, new SubjectAlternativeNameExtension(false, gnames));
			ci.set(X509CertInfo.EXTENSIONS   , ext);
			final X509CertImpl certImpl = new  X509CertImpl(ci);
			certImpl.sign(this.kp.getPrivate(), this.SIG_ALG);
			return new X509Certificate[]{certImpl};
		} catch(final Throwable t) {
			this.log.log(Level.SEVERE, "getCertificateChain()=>"+t.getMessage(), t);
			return null;
		}
	}
	@Override public PrivateKey getPrivateKey(final String alias) { return this.kp.getPrivate(); }
}