diff --git a/jams-ca/crl.pem b/jams-ca/crl.pem new file mode 100644 index 0000000000000000000000000000000000000000..f7d7e1ca04c1b47c7d6b46cdd1820dbb5de5757a Binary files /dev/null and b/jams-ca/crl.pem differ 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 0000000000000000000000000000000000000000..ab191b0c2247c013f189a8c165e6c72019d915f4 --- /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 7cbafa56029dfeb364b3882f065dfc06ec6efa73..cfd80cd0349c3c95d69cecf3a0240c56ce9c4d18 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 6c8e6fa856fea1a7e47c23c242b9d31795b7dc2f..2a3f77f158216a659f88916b9be87255c69297d1 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 0000000000000000000000000000000000000000..6f3a6b4036eb01bd49d12e89f2d9cdef5456aca2 --- /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(); + } + + + +}