package cc.blynk.server; import cc.blynk.server.acme.AcmeClient; import cc.blynk.server.acme.ContentHolder; import cc.blynk.utils.ServerProperties; import cc.blynk.utils.SslUtil; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SslProvider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * The Blynk Project. * Created by Dmitriy Dumanskiy. * Created on 30.04.17. */ public class SslContextHolder { private static final Logger log = LogManager.getLogger(SslContextHolder.class); public volatile SslContext sslCtx; public final AcmeClient acmeClient; public final boolean isAutoGenerationEnabled; public final boolean isNeedInitializeOnStart; public final ContentHolder contentHolder; public SslContextHolder(ServerProperties props, String email) { this.contentHolder = new ContentHolder(); String certPath = props.getProperty("server.ssl.cert"); String keyPath = props.getProperty("server.ssl.key"); String keyPass = props.getProperty("server.ssl.key.pass"); if (certPath == null || certPath.isEmpty()) { log.info("Didn't find custom user certificates."); isAutoGenerationEnabled = true; } else { isAutoGenerationEnabled = false; } String host = props.getProperty("server.host"); if (AcmeClient.DOMAIN_CHAIN_FILE.exists() && AcmeClient.DOMAIN_KEY_FILE.exists()) { log.info("Found generated with Let's Encrypt certificates."); certPath = AcmeClient.DOMAIN_CHAIN_FILE.getAbsolutePath(); keyPath = AcmeClient.DOMAIN_KEY_FILE.getAbsolutePath(); keyPass = null; this.isNeedInitializeOnStart = false; this.acmeClient = new AcmeClient(email, host, contentHolder); } else { log.info("Didn't find Let's Encrypt certificates."); if (host == null || host.isEmpty() || email == null || email.isEmpty() || email.equals("example@gmail.com") || email.startsWith("SMTP")) { log.warn("You didn't specified 'server.host' or 'contact.email' properties in server.properties file. " + "Automatic certificate generation is turned off. Please specify above properties for automatic certificates retrieval."); this.acmeClient = null; this.isNeedInitializeOnStart = false; } else { log.info("Automatic certificate generation is turned ON."); this.acmeClient = new AcmeClient(email, host, contentHolder); this.isNeedInitializeOnStart = true; } } SslProvider sslProvider = SslUtil.fetchSslProvider(props); this.sslCtx = SslUtil.initSslContext(certPath, keyPath, keyPass, sslProvider, true); } public void regenerate(ServerProperties props) { String certPath = AcmeClient.DOMAIN_CHAIN_FILE.getAbsolutePath(); String keyPath = AcmeClient.DOMAIN_KEY_FILE.getAbsolutePath(); SslProvider sslProvider = SslUtil.fetchSslProvider(props); this.sslCtx = SslUtil.initSslContext(certPath, keyPath, null, sslProvider, true); } public void generateInitialCertificates(ServerProperties props) { if (isAutoGenerationEnabled && isNeedInitializeOnStart) { System.out.println("Generating own initial certificates..."); try { if (this.acmeClient.requestCertificate()) { System.out.println("Success! The certificate for your domain has been generated!"); regenerate(props); } } catch (Exception e) { System.out.println("Error during certificate generation."); System.out.println(e.getMessage()); } } } }