diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java index 9a4615cb..51d290bd 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/LaunchServer.java @@ -16,6 +16,7 @@ import pro.gravit.launchserver.binary.LauncherBinary; import pro.gravit.launchserver.config.LaunchServerConfig; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; +import pro.gravit.launchserver.helper.SignHelper; import pro.gravit.launchserver.launchermodules.LauncherModuleLoader; import pro.gravit.launchserver.manangers.*; import pro.gravit.launchserver.manangers.hook.AuthHookManager; @@ -40,9 +41,14 @@ import java.lang.invoke.MethodType; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; +import java.security.KeyStore; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -185,6 +191,10 @@ public LaunchServer(LaunchServerDirectories directories, LaunchServerEnv env, La } launcherModuleLoader.init(); nettyServerSocketHandler = new NettyServerSocketHandler(this); + if(config.sign.checkCertificateExpired) { + checkCertificateExpired(); + service.scheduleAtFixedRate(this::checkCertificateExpired, 24, 24, TimeUnit.HOURS); + } // post init modules modulesManager.invokeEvent(new LaunchServerPostInitPhase(this)); } @@ -269,6 +279,25 @@ public void invoke(String... args) throws Exception { return commands; } + public void checkCertificateExpired() { + if(!config.sign.enabled) { + return; + } + try { + KeyStore keyStore = SignHelper.getStore(Paths.get(config.sign.keyStore), config.sign.keyStorePass, config.sign.keyStoreType); + Instant date = SignHelper.getCertificateExpired(keyStore, config.sign.keyAlias); + if(date == null) { + logger.debug("The certificate will expire at unlimited"); + } else if(date.minus(Duration.ofDays(30)).isBefore(Instant.now())) { + logger.warn("The certificate will expire at {}", date.toString()); + } else { + logger.debug("The certificate will expire at {}", date.toString()); + } + } catch (Throwable e) { + logger.error("Can't get certificate expire date", e); + } + } + private LauncherBinary binary() { LaunchServerLauncherExeInit event = new LaunchServerLauncherExeInit(this, null); modulesManager.invokeEvent(event); diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java index 49966b8e..f89c74c6 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/config/LaunchServerConfig.java @@ -259,6 +259,7 @@ public static class JarSignerConf { public String metaInfKeyName = "SIGNUMO.RSA"; public String metaInfSfName = "SIGNUMO.SF"; public String signAlgo = "SHA256WITHRSA"; + public boolean checkCertificateExpired = true; } public static class NettyUpdatesBind { diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/SignHelper.java b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/SignHelper.java index d2f16da1..582bf741 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/helper/SignHelper.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/helper/SignHelper.java @@ -21,8 +21,11 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.time.Instant; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.List; public class SignHelper { @@ -46,6 +49,24 @@ public static KeyStore getStore(Path file, String storepass, String algo) throws } } + + + public static Instant getCertificateExpired(KeyStore keyStore, String keyAlias) throws KeyStoreException { + List certChain = new ArrayList<>(Arrays.asList(keyStore.getCertificateChain(keyAlias))); + Date date = null; + for(var e : certChain) { + if(e instanceof X509Certificate x509Certificate) { + if(x509Certificate.getNotAfter() == null) { + continue; + } + if(date == null || date.before(x509Certificate.getNotAfter())) { + date = x509Certificate.getNotAfter(); + } + } + } + return date == null ? null : date.toInstant(); + } + /** * Creates the beast that can actually sign the data (for JKS, for other make it). */