// 
// Decompiled by Procyon v0.6.0
// 

package io.netty.handler.ssl.util;

import io.netty.util.internal.PlatformDependent;
import java.nio.file.LinkOption;
import java.nio.file.Paths;
import java.util.Locale;
import java.security.GeneralSecurityException;
import java.io.InputStream;
import io.netty.buffer.ByteBuf;
import java.security.cert.X509Certificate;
import java.nio.file.OpenOption;
import java.security.KeyStore;
import java.nio.charset.StandardCharsets;
import io.netty.buffer.Unpooled;
import java.io.InterruptedIOException;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.time.temporal.TemporalUnit;
import java.time.temporal.Temporal;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAccessor;
import java.time.ZoneId;
import java.nio.file.Files;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.Path;
import java.time.format.DateTimeFormatter;

final class KeytoolSelfSignedCertGenerator
{
    private static final DateTimeFormatter DATE_FORMAT;
    private static final String ALIAS = "alias";
    private static final String PASSWORD = "insecurepassword";
    private static final Path KEYTOOL;
    private static final String KEY_STORE_TYPE;
    
    private KeytoolSelfSignedCertGenerator() {
    }
    
    static boolean isAvailable() {
        return KeytoolSelfSignedCertGenerator.KEYTOOL != null;
    }
    
    static void generate(final SelfSignedCertificate.Builder builder) throws IOException, GeneralSecurityException {
        final String dirFqdn = builder.fqdn.replaceAll("[^\\w.-]", "x");
        final Path directory = Files.createTempDirectory("keytool_" + dirFqdn, (FileAttribute<?>[])new FileAttribute[0]);
        final Path keyStore = directory.resolve("keystore.jks");
        try {
            final Process process = new ProcessBuilder(new String[0]).command(KeytoolSelfSignedCertGenerator.KEYTOOL.toAbsolutePath().toString(), "-genkeypair", "-keyalg", builder.algorithm, "-keysize", String.valueOf(builder.bits), "-startdate", KeytoolSelfSignedCertGenerator.DATE_FORMAT.format(builder.notBefore.toInstant().atZone(ZoneId.systemDefault())), "-validity", String.valueOf(builder.notBefore.toInstant().until(builder.notAfter.toInstant(), ChronoUnit.DAYS)), "-keystore", keyStore.toString(), "-alias", "alias", "-keypass", "insecurepassword", "-storepass", "insecurepassword", "-dname", "CN=" + builder.fqdn, "-storetype", KeytoolSelfSignedCertGenerator.KEY_STORE_TYPE).redirectErrorStream(true).start();
            try {
                if (!process.waitFor(60L, TimeUnit.SECONDS)) {
                    process.destroyForcibly();
                    throw new IOException("keytool timeout");
                }
            }
            catch (final InterruptedException e) {
                process.destroyForcibly();
                Thread.currentThread().interrupt();
                throw new InterruptedIOException();
            }
            if (process.exitValue() != 0) {
                final ByteBuf buffer = Unpooled.buffer();
                try {
                    try (final InputStream stream = process.getInputStream()) {
                        while (buffer.writeBytes(stream, 4096) != -1) {}
                    }
                    final String log = buffer.toString(StandardCharsets.UTF_8);
                    throw new IOException("Keytool exited with status " + process.exitValue() + ": " + log);
                }
                finally {
                    buffer.release();
                }
            }
            final KeyStore ks = KeyStore.getInstance(KeytoolSelfSignedCertGenerator.KEY_STORE_TYPE);
            try (final InputStream is = Files.newInputStream(keyStore, new OpenOption[0])) {
                ks.load(is, "insecurepassword".toCharArray());
            }
            final KeyStore.PrivateKeyEntry entry = (KeyStore.PrivateKeyEntry)ks.getEntry("alias", new KeyStore.PasswordProtection("insecurepassword".toCharArray()));
            builder.paths = SelfSignedCertificate.newSelfSignedCertificate(builder.fqdn, entry.getPrivateKey(), (X509Certificate)entry.getCertificate());
            builder.privateKey = entry.getPrivateKey();
        }
        finally {
            Files.deleteIfExists(keyStore);
            Files.delete(directory);
        }
    }
    
    static {
        DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss", Locale.ROOT);
        final String home = System.getProperty("java.home");
        if (home == null) {
            KEYTOOL = null;
        }
        else {
            final Path likely = Paths.get(home, new String[0]).resolve("bin").resolve("keytool");
            if (Files.exists(likely, new LinkOption[0])) {
                KEYTOOL = likely;
            }
            else {
                KEYTOOL = null;
            }
        }
        KEY_STORE_TYPE = ((PlatformDependent.javaVersion() >= 11) ? "PKCS12" : "JKS");
    }
}
