Repository: netty/netty
File: pkitesting/src/main/java/io/netty/pkitesting/RevocationServer.java (Java)

Code before:
            throw new IllegalArgumentException("Not a registered issuer: " + issuer.getSubjectX500Principal());
        }
    }

    /**
     * Get the URI of the Certificate Revocation List for the given issuer.
     * @param issuer The issuer to get the CRL for.
     * @return The URI to the CRL for the given issuer,
     * or {@code null} if the issuer is not {@linkplain #register(X509Bundle) registered}.
     */
    public URI getCrlUri(X509Bundle issuer) {
        CrlInfo info = issuers.get(issuer.getCertificate());
        if (info != null) {
            return info.uri;
        }
        return null;
    }

    private static byte[] generateCrl(CrlInfo info) {
        X509Bundle issuer = info.issuer;
        Map<BigInteger, Instant> certs = info.revokedCerts;
        Instant now = Instant.now();
        CertificateList list = new CertificateList(issuer, now, now, certs.entrySet());
        try {
            Signed signed = new Signed(list.getEncoded(), issuer);
            return signed.getEncoded(null);
        } catch (Exception e) {
            throw new IllegalStateException("Failed to sign CRL", e);
        }
    }

    private static final class CrlInfo {
        private final X509Bundle issuer;
        private final URI uri;
        private final Map<BigInteger, Instant> revokedCerts;

        CrlInfo(X509Bundle issuer, URI uri) {
            this.issuer = issuer;
            this.uri = uri;
            revokedCerts = new ConcurrentHashMap<>();
        }
    }
}


Review comment (suggestion):
We should add a method to include a provider with the issuer cert, and store the provider in the `CrlInfo` so we can pass it here, if any.

Code after:
     * can be revoked.
     * @param cert The certificate to revoke.
     * @param time The time of revocation.
     */
    public void revoke(X509Bundle cert, Instant time) {
        X509Certificate[] certPath = cert.getCertificatePathWithRoot();
        X509Certificate issuer = certPath.length == 1 ? certPath[0] : certPath[1];
        CrlInfo info = issuers.get(issuer);
        if (info != null) {
            info.revokedCerts.put(cert.getCertificate().getSerialNumber(), time);
        } else {
            throw new IllegalArgumentException("Not a registered issuer: " + issuer.getSubjectX500Principal());
        }
    }

    /**
     * Get the URI of the Certificate Revocation List for the given issuer.
     * @param issuer The issuer to get the CRL for.
     * @return The URI to the CRL for the given issuer,
     * or {@code null} if the issuer is not {@linkplain #register(X509Bundle) registered}.
     */
    public URI getCrlUri(X509Bundle issuer) {
        CrlInfo info = issuers.get(issuer.getCertificate());
        if (info != null) {
            return info.uri;
        }
        return null;
    }

    private static byte[] generateCrl(CrlInfo info) {
        X509Bundle issuer = info.issuer;
        Map<BigInteger, Instant> certs = info.revokedCerts;
        Instant now = Instant.now();
        CertificateList list = new CertificateList(issuer, now, now, certs.entrySet());
        try {
            Signed signed = new Signed(list.getEncoded(), issuer);
            return signed.getEncoded(info.provider);
        } catch (Exception e) {
            throw new IllegalStateException("Failed to sign CRL", e);
        }
    }

    private static final class CrlInfo {
        private final X509Bundle issuer;
        private final URI uri;
        private final Map<BigInteger, Instant> revokedCerts;
        private final Provider provider;

        CrlInfo(X509Bundle issuer, URI uri, Provider provider) {
            this.issuer = issuer;
            this.uri = uri;