From c0985f466120427b0f1c8484a86785b3ca347036 Mon Sep 17 00:00:00 2001 From: Felix Sidokhine <felix.sidokhine@randstad.ca> Date: Sun, 31 May 2020 13:52:22 +0300 Subject: [PATCH] added persisting of CRL to file --- jams-ca/crl.pem | Bin 0 -> 681 bytes .../jams/ca/workers/crl/CRLFileStorage.java | 21 +++++++++ .../jami/jams/ca/workers/crl/CRLWorker.java | 40 ++++++++++++++--- .../builders/SystemAccountBuilderTest.java | 9 ++-- .../common/serialization/fs/FileStorage.java | 42 ++++++++++++++++++ 5 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 jams-ca/crl.pem create mode 100644 jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLFileStorage.java create mode 100644 jams-common/src/main/java/net/jami/jams/common/serialization/fs/FileStorage.java diff --git a/jams-ca/crl.pem b/jams-ca/crl.pem new file mode 100644 index 0000000000000000000000000000000000000000..f7d7e1ca04c1b47c7d6b46cdd1820dbb5de5757a GIT binary patch literal 681 zcmXqLVp?j@*vG`kXu!+HsnzDu_MMlJk(ZUhK;BTmfRBwil!cjxJtVcbM8Vn7klTP0 zB*G@l<Q62(Yh++xYHVm|U}|V;5oO?Ipv=U=$ev+~F2Q5K1=J)f%EHXW$O%%!T4^*1 zMUh#Q0jeTYr!Y4$F)}niO#8c#Pf?2J?2`W_+^4suUpw)dtF%;DX#3tJ%u9DIcfZ~& zJNf9950)Q2Zf~fsw3spLZT+b?{WrDrg!rRxb6VuN>88~#+a)}y{gq%}P<Xbn;Zmi# zpx9jPNp?KDuUcljJLh<nTQ<Mo+XmJ%@(0Y<|M;ryrEuiT&h_Qn8lKMIDfg2(e6D}* zrXBL;UjM~28Z)b79;q(BU>dX_SM!FHiji;Yf%81+(yHGcR%<4+{!mR5dR6$RI^o;V zUz4`){x!G$ecbxx!aPgw>4ZPBPkMF3M^(cpuIu)n4QsaD(yf0Qe=}qGw`E*5YI}dU zwUlnxQ7yUf)4-pz_r~!GABDpcW1k%|zdPr1)GV1xh81Vzr1{0FrkB_?+SjF<WyF73 z9GvBA@LlDpMSYr>*|MU}DSRi-cfE=+KV2^`=h5@E?#R9^+^^sNPY(GyuS4<wp(Qqs zQolSe=1WvOzo@^rZB?P&x0k2+5@(%Cd9srA<kX6%HqZadI$V}MnV8*ScWQb8yBp`G z*TqH4C1$;@k<-r<%56O)$1wez*4~eoUvJj1V3;ggEz2FA?O3jOclvS#m79lOpWUYE zlDDg5=J5jVMF)};Kh3??v2eff7V!guc`1J-uO;a0`{%UkkIjZ_6O)d)_57Fm<h}N! mm3XDGTTn-TS;FZ#ey0^)uIcb?Sn8N&>U6Sgr-tN5mI?r!3mZoO literal 0 HcmV?d00001 diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLFileStorage.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLFileStorage.java new file mode 100644 index 00000000..ab191b0c --- /dev/null +++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLFileStorage.java @@ -0,0 +1,21 @@ +package net.jami.jams.ca.workers.crl; + +import net.jami.jams.common.serialization.fs.FileStorage; +import org.bouncycastle.cert.X509CRLHolder; + +public class CRLFileStorage extends FileStorage<X509CRLHolder> { + + public CRLFileStorage(String file) { + super(file); + } + + @Override + public X509CRLHolder getObject(byte[] bytes) throws Exception{ + return new X509CRLHolder(bytes); + } + + @Override + public byte[] getBytesFromObject(X509CRLHolder object) throws Exception { + return object.getEncoded(); + } +} diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java index 7cbafa56..cfd80cd0 100644 --- a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java +++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java @@ -28,12 +28,15 @@ import lombok.extern.slf4j.Slf4j; import net.jami.jams.ca.JamsCA; import net.jami.jams.ca.workers.X509Worker; import net.jami.jams.common.objects.requests.RevocationRequest; +import net.jami.jams.common.serialization.fs.FileStorage; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import java.io.File; +import java.io.SyncFailedException; import java.security.PrivateKey; import java.security.cert.X509Certificate; import java.util.Date; @@ -44,15 +47,31 @@ import java.util.concurrent.atomic.AtomicReference; public class CRLWorker extends X509Worker<RevocationRequest> { @Getter - private AtomicReference<X509CRLHolder> existingCRL = null; + private final AtomicReference<X509CRLHolder> existingCRL = new AtomicReference<>(); + + @Getter + private final CRLFileStorage crlFileStorage = new CRLFileStorage(System.getProperty("user.dir") + File.separator + "crl.pem"); @Getter @Setter private AtomicBoolean stop = new AtomicBoolean(false); public CRLWorker(PrivateKey privateKey, X509Certificate certificate) { super(privateKey, certificate); - //TODO: The CRL needs to be loaded from somewhere. - + try{ + existingCRL.set(crlFileStorage.getData()); + } + catch (Exception e){ + log.warn("Could not find existing CRL file, if this is the first" + + " time you are starting the server or no CRL existed, this is fine"); + X509v2CRLBuilder crlBuilder = new X509v2CRLBuilder(new X500Name((getCertificate()).getSubjectDN().getName()), new Date()); + try { + existingCRL.set(crlBuilder.build(new JcaContentSignerBuilder("SHA512WITHRSA").setProvider("BC").build(getSigningKey()))); + crlFileStorage.storeData(existingCRL.get()); + } + catch (Exception e1){ + log.error("Could not create blank CRL!"); + } + } this.setDaemon(true); this.start(); log.info("Instantiated & started a CRL Worker..."); @@ -65,11 +84,18 @@ public class CRLWorker extends X509Worker<RevocationRequest> { if(revocationRequest != null) { crlBuilder.addCRLEntry(revocationRequest.getIdentifier(), new Date(), CRLReason.privilegeWithdrawn); } - if (existingCRL != null){ - crlBuilder.addCRL(existingCRL.get()); - } - else existingCRL = new AtomicReference<>(); + crlBuilder.addCRL(existingCRL.get()); existingCRL.set(crlBuilder.build(new JcaContentSignerBuilder("SHA512WITHRSA").setProvider("BC").build(getSigningKey()))); + boolean failedWrite = true; + while(failedWrite){ + try{ + crlFileStorage.storeData(existingCRL.get()); + failedWrite = false; + } + catch (Exception e){ + log.warn("Failed to write file, trying again!"); + } + } log.info("Successfully ran revocation routine"); } catch (Exception e){ diff --git a/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java b/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java index 6c8e6fa8..2a3f77f1 100644 --- a/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java +++ b/jams-ca/src/test/java/net/jami/jams/ca/workers/csr/builders/SystemAccountBuilderTest.java @@ -110,7 +110,7 @@ class SystemAccountBuilderTest { JamsCA jamsCA = new JamsCA(); - jamsCA.init(JsonStream.serialize(config),caAccount,null); + jamsCA.init(JsonStream.serialize(config),caAccount,caAccount); RevocationRequest revocationRequest = new RevocationRequest(); revocationRequest.setIdentifier(new BigInteger("91828882")); revocationRequest.setRevocationType(RevocationType.USER); @@ -119,7 +119,7 @@ class SystemAccountBuilderTest { this.wait(2_000); } Assertions.assertNotNull(jamsCA.getLatestCRL()); - Assertions.assertEquals(jamsCA.getLatestCRL().get().getRevokedCertificates().toArray().length,1,"Expected only 1 certificate!"); + Assertions.assertEquals(1,jamsCA.getLatestCRL().get().getRevokedCertificates().toArray().length,"Expected only 1 certificate!"); revocationRequest = new RevocationRequest(); revocationRequest.setIdentifier(new BigInteger("17262653")); @@ -129,9 +129,6 @@ class SystemAccountBuilderTest { this.wait(2_000); } Assertions.assertNotNull(jamsCA.getLatestCRL()); - Assertions.assertEquals(jamsCA.getLatestCRL().get().getRevokedCertificates().toArray().length,2,"Expected only 2 certificates!"); - - - + Assertions.assertEquals(2,jamsCA.getLatestCRL().get().getRevokedCertificates().toArray().length,"Expected only 2 certificates!"); } } \ No newline at end of file diff --git a/jams-common/src/main/java/net/jami/jams/common/serialization/fs/FileStorage.java b/jams-common/src/main/java/net/jami/jams/common/serialization/fs/FileStorage.java new file mode 100644 index 00000000..6f3a6b40 --- /dev/null +++ b/jams-common/src/main/java/net/jami/jams/common/serialization/fs/FileStorage.java @@ -0,0 +1,42 @@ +package net.jami.jams.common.serialization.fs; + +import lombok.Getter; +import lombok.Setter; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +@Getter +@Setter +public abstract class FileStorage<T> { + + private File file; + private FileInputStream fileInputStream; + private FileOutputStream fileOutputStream; + private FileDescriptor fileDescriptor; + + public FileStorage(String file) { + this.file = new File(file); + } + + public abstract T getObject(byte[] bytes) throws Exception; + public abstract byte[] getBytesFromObject(T object) throws Exception; + + public T getData() throws Exception{ + fileInputStream = new FileInputStream(file); + return getObject(fileInputStream.readAllBytes()); + } + + public void storeData(T data) throws Exception{ + fileOutputStream = new FileOutputStream(file); + fileDescriptor = fileOutputStream.getFD(); + fileOutputStream.write(getBytesFromObject(data)); + fileOutputStream.flush(); + fileDescriptor.sync(); + } + + + +} -- GitLab