From b90693550a7581be3a923b2a91269a51fd090b3a Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 7 Jan 2020 21:18:49 +0100 Subject: [PATCH] Do some things that I haven't finished yet --- src/eu/steffo/cleaver/Main.java | 2 +- src/eu/steffo/cleaver/Test.java | 6 +- src/eu/steffo/cleaver/gui/CleaverFrame.java | 3 +- .../gui/panels/ChopAndStitchPanel.java | 7 +- .../steffo/cleaver/gui/panels/ChopPanel.java | 10 +- .../cleaver/gui/panels/JobsTablePanel.java | 8 +- .../cleaver/gui/panels/StitchPanel.java | 4 +- .../gui/panels/rows/option/CompressRow.java | 2 +- .../gui/panels/rows/option/CryptRow.java | 2 +- .../gui/panels/rows/option/KeyRow.java | 4 +- .../gui/panels/rows/option/SplitRow.java | 6 +- .../logic/compress/CompressConfig.java | 25 --- .../cleaver/logic/compress/package-info.java | 4 - .../cleaver/logic/config/CompressConfig.java | 13 ++ .../cleaver/logic/config/CryptConfig.java | 30 +++ .../logic/{split => config}/MergeConfig.java | 2 +- .../{split => config}/SplitByPartsConfig.java | 2 +- .../{split => config}/SplitBySizeConfig.java | 2 +- .../cleaver/logic/config/SplitConfig.java | 29 +++ .../cleaver/logic/crypt/CryptConfig.java | 42 ----- .../logic/crypt/CryptOutputStream.java | 122 ------------ .../cleaver/logic/crypt/package-info.java | 4 - .../cleaver/logic/{ => job}/ChopJob.java | 16 +- .../steffo/cleaver/logic/{ => job}/Job.java | 8 +- .../cleaver/logic/{ => job}/StitchJob.java | 15 +- .../cleaver/logic/job/package-info.java | 4 + .../cleaver/logic/progress/ErrorProgress.java | 6 +- .../logic/progress/FinishedProgress.java | 4 +- .../logic/progress/NotStartedProgress.java | 4 +- .../logic/progress/WorkingProgress.java | 4 +- .../cleaver/logic/split/SplitConfig.java | 59 ------ .../cleaver/logic/split/package-info.java | 4 - .../cleaver/logic/stream/ICleaverStream.java | 4 + .../input/CleaverSplitFileInputStream.java} | 6 +- .../input}/CryptInputStream.java | 2 +- .../stream/input/ICleaverInputStream.java | 6 + .../output/CleaverCompressOutputStream.java | 98 ++++++++++ .../output/CleaverCryptOutputStream.java | 174 ++++++++++++++++++ .../output/CleaverSplitFileOutputStream.java} | 42 ++++- .../stream/output/ICleaverOutputStream.java | 15 ++ 40 files changed, 478 insertions(+), 322 deletions(-) delete mode 100644 src/eu/steffo/cleaver/logic/compress/CompressConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/compress/package-info.java create mode 100644 src/eu/steffo/cleaver/logic/config/CompressConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/CryptConfig.java rename src/eu/steffo/cleaver/logic/{split => config}/MergeConfig.java (96%) rename src/eu/steffo/cleaver/logic/{split => config}/SplitByPartsConfig.java (95%) rename src/eu/steffo/cleaver/logic/{split => config}/SplitBySizeConfig.java (96%) create mode 100644 src/eu/steffo/cleaver/logic/config/SplitConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/crypt/CryptConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java delete mode 100644 src/eu/steffo/cleaver/logic/crypt/package-info.java rename src/eu/steffo/cleaver/logic/{ => job}/ChopJob.java (91%) rename src/eu/steffo/cleaver/logic/{ => job}/Job.java (94%) rename src/eu/steffo/cleaver/logic/{ => job}/StitchJob.java (94%) create mode 100644 src/eu/steffo/cleaver/logic/job/package-info.java delete mode 100644 src/eu/steffo/cleaver/logic/split/SplitConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/split/package-info.java create mode 100644 src/eu/steffo/cleaver/logic/stream/ICleaverStream.java rename src/eu/steffo/cleaver/logic/{split/SplitFileInputStream.java => stream/input/CleaverSplitFileInputStream.java} (93%) rename src/eu/steffo/cleaver/logic/{crypt => stream/input}/CryptInputStream.java (98%) create mode 100644 src/eu/steffo/cleaver/logic/stream/input/ICleaverInputStream.java create mode 100644 src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java create mode 100644 src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java rename src/eu/steffo/cleaver/logic/{split/SplitFileOutputStream.java => stream/output/CleaverSplitFileOutputStream.java} (68%) create mode 100644 src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java diff --git a/src/eu/steffo/cleaver/Main.java b/src/eu/steffo/cleaver/Main.java index f8d447b..64dbc3b 100644 --- a/src/eu/steffo/cleaver/Main.java +++ b/src/eu/steffo/cleaver/Main.java @@ -2,7 +2,7 @@ package eu.steffo.cleaver; import javax.swing.*; import eu.steffo.cleaver.gui.CleaverFrame; -import eu.steffo.cleaver.logic.Job; +import eu.steffo.cleaver.logic.job.Job; import java.util.ArrayList; diff --git a/src/eu/steffo/cleaver/Test.java b/src/eu/steffo/cleaver/Test.java index a523a8a..fd6203f 100644 --- a/src/eu/steffo/cleaver/Test.java +++ b/src/eu/steffo/cleaver/Test.java @@ -1,8 +1,6 @@ package eu.steffo.cleaver; -import eu.steffo.cleaver.logic.ChopJob; -import eu.steffo.cleaver.logic.Job; -import eu.steffo.cleaver.logic.split.SplitFileOutputStream; +import eu.steffo.cleaver.logic.stream.output.CleaverSplitFileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -10,7 +8,7 @@ import java.io.OutputStream; //TODO: delet this public class Test { public static void main(String[] args) { - OutputStream stream = new SplitFileOutputStream("test", 64); + OutputStream stream = new CleaverSplitFileOutputStream("test", 64); for(int i = 0; i < 256; i++) { try { stream.write(i); diff --git a/src/eu/steffo/cleaver/gui/CleaverFrame.java b/src/eu/steffo/cleaver/gui/CleaverFrame.java index b15ec90..ebb040e 100644 --- a/src/eu/steffo/cleaver/gui/CleaverFrame.java +++ b/src/eu/steffo/cleaver/gui/CleaverFrame.java @@ -3,8 +3,7 @@ package eu.steffo.cleaver.gui; import eu.steffo.cleaver.gui.panels.ChopAndStitchPanel; import eu.steffo.cleaver.gui.panels.JobsButtonsPanel; import eu.steffo.cleaver.gui.panels.JobsTablePanel; -import eu.steffo.cleaver.logic.Job; -import eu.steffo.cleaver.logic.progress.NotStartedProgress; +import eu.steffo.cleaver.logic.job.Job; import java.awt.*; import java.awt.event.ActionEvent; diff --git a/src/eu/steffo/cleaver/gui/panels/ChopAndStitchPanel.java b/src/eu/steffo/cleaver/gui/panels/ChopAndStitchPanel.java index a4779ac..d46c4d0 100644 --- a/src/eu/steffo/cleaver/gui/panels/ChopAndStitchPanel.java +++ b/src/eu/steffo/cleaver/gui/panels/ChopAndStitchPanel.java @@ -1,6 +1,7 @@ package eu.steffo.cleaver.gui.panels; -import eu.steffo.cleaver.logic.Job; +import eu.steffo.cleaver.logic.job.Job; +import eu.steffo.cleaver.logic.job.ChopJob; import javax.swing.*; import java.awt.event.ActionListener; @@ -48,7 +49,7 @@ public class ChopAndStitchPanel extends JPanel { * @param jobs The {@link ArrayList} of jobs that should be manipulated. * @param onProgressChange The function that should be invoked when the {@link Job} {@link eu.steffo.cleaver.logic.progress.Progress Progress} changes. * @see ChopPanel#createAndAddJobs(ArrayList, Runnable) - * @see eu.steffo.cleaver.logic.ChopJob + * @see ChopJob * @see eu.steffo.cleaver.gui.CleaverFrame */ public void createAndAddChopJobs(ArrayList jobs, Runnable onProgressChange) { @@ -60,7 +61,7 @@ public class ChopAndStitchPanel extends JPanel { * @param jobs The {@link ArrayList} of jobs that should be manipulated. * @param onProgressChange The function that should be invoked when the {@link Job} {@link eu.steffo.cleaver.logic.progress.Progress Progress} changes. * @see StitchPanel#createAndAddJobs(ArrayList, Runnable) - * @see eu.steffo.cleaver.logic.ChopJob + * @see ChopJob * @see eu.steffo.cleaver.gui.CleaverFrame */ public void createAndAddStitchJobs(ArrayList jobs, Runnable onProgressChange) { diff --git a/src/eu/steffo/cleaver/gui/panels/ChopPanel.java b/src/eu/steffo/cleaver/gui/panels/ChopPanel.java index b3f16e1..14456cc 100644 --- a/src/eu/steffo/cleaver/gui/panels/ChopPanel.java +++ b/src/eu/steffo/cleaver/gui/panels/ChopPanel.java @@ -4,11 +4,11 @@ import eu.steffo.cleaver.gui.panels.rows.CreateJobButtonRow; import eu.steffo.cleaver.gui.panels.rows.option.CompressRow; import eu.steffo.cleaver.gui.panels.rows.option.CryptRow; import eu.steffo.cleaver.gui.panels.rows.option.SplitRow; -import eu.steffo.cleaver.logic.ChopJob; -import eu.steffo.cleaver.logic.Job; -import eu.steffo.cleaver.logic.compress.CompressConfig; -import eu.steffo.cleaver.logic.crypt.CryptConfig; -import eu.steffo.cleaver.logic.split.SplitConfig; +import eu.steffo.cleaver.logic.job.ChopJob; +import eu.steffo.cleaver.logic.job.Job; +import eu.steffo.cleaver.logic.config.CompressConfig; +import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.config.SplitConfig; import javax.swing.*; import java.awt.event.ActionListener; diff --git a/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java b/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java index 04897bd..d700f92 100644 --- a/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java +++ b/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java @@ -1,9 +1,9 @@ package eu.steffo.cleaver.gui.panels; -import eu.steffo.cleaver.logic.Job; -import eu.steffo.cleaver.logic.compress.CompressConfig; -import eu.steffo.cleaver.logic.crypt.CryptConfig; -import eu.steffo.cleaver.logic.split.SplitConfig; +import eu.steffo.cleaver.logic.job.Job; +import eu.steffo.cleaver.logic.config.CompressConfig; +import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.config.SplitConfig; import javax.swing.*; import javax.swing.table.AbstractTableModel; diff --git a/src/eu/steffo/cleaver/gui/panels/StitchPanel.java b/src/eu/steffo/cleaver/gui/panels/StitchPanel.java index 904e09c..ca1328f 100644 --- a/src/eu/steffo/cleaver/gui/panels/StitchPanel.java +++ b/src/eu/steffo/cleaver/gui/panels/StitchPanel.java @@ -4,8 +4,8 @@ import eu.steffo.cleaver.errors.ChpFileError; import eu.steffo.cleaver.errors.ProgrammingError; import eu.steffo.cleaver.gui.panels.rows.CreateJobButtonRow; import eu.steffo.cleaver.gui.panels.rows.option.KeyRow; -import eu.steffo.cleaver.logic.Job; -import eu.steffo.cleaver.logic.StitchJob; +import eu.steffo.cleaver.logic.job.Job; +import eu.steffo.cleaver.logic.job.StitchJob; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java index 47bac7c..1122f45 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java @@ -1,6 +1,6 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.compress.CompressConfig; +import eu.steffo.cleaver.logic.config.CompressConfig; import javax.swing.*; diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java index da9021d..5c8c962 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java @@ -1,6 +1,6 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.crypt.CryptConfig; +import eu.steffo.cleaver.logic.config.CryptConfig; import javax.swing.*; diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java index 57804bc..88c6bbc 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java @@ -1,9 +1,11 @@ package eu.steffo.cleaver.gui.panels.rows.option; +import eu.steffo.cleaver.logic.config.CryptConfig; + import javax.swing.*; /** - * A {@link OptionRow} allowing the {@link eu.steffo.cleaver.logic.crypt.CryptConfig configuration of the crypt step} of the file stitch process. + * A {@link OptionRow} allowing the {@link CryptConfig configuration of the crypt step} of the file stitch process. * * This configuration is used only if the selected *.chp file specifies that the *.cXX are encrypted. * diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java index a29d655..11f1fb4 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java @@ -1,8 +1,8 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.split.SplitByPartsConfig; -import eu.steffo.cleaver.logic.split.SplitBySizeConfig; -import eu.steffo.cleaver.logic.split.SplitConfig; +import eu.steffo.cleaver.logic.config.SplitByPartsConfig; +import eu.steffo.cleaver.logic.config.SplitBySizeConfig; +import eu.steffo.cleaver.logic.config.SplitConfig; import javax.swing.*; import javax.swing.event.DocumentEvent; diff --git a/src/eu/steffo/cleaver/logic/compress/CompressConfig.java b/src/eu/steffo/cleaver/logic/compress/CompressConfig.java deleted file mode 100644 index 313290e..0000000 --- a/src/eu/steffo/cleaver/logic/compress/CompressConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package eu.steffo.cleaver.logic.compress; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * A class containing the configuration for the compression step of a {@link eu.steffo.cleaver.logic.Job Job}. - */ -public class CompressConfig { - @Override - public String toString() { - return "Yes (Deflate)"; - } - - /** - * Create a {@link Element} representing this CompressConfig (to be used in *.chp metadata files). - * @param doc The {@link Document} the {@link Element} should be created in. - * @return The created {@link Element}. - * @see eu.steffo.cleaver.logic.ChopJob - * @see eu.steffo.cleaver.logic.StitchJob - */ - public Element toElement(Document doc) { - return doc.createElement("Compress"); - } -} diff --git a/src/eu/steffo/cleaver/logic/compress/package-info.java b/src/eu/steffo/cleaver/logic/compress/package-info.java deleted file mode 100644 index 277fc56..0000000 --- a/src/eu/steffo/cleaver/logic/compress/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * The package containing classes related to the (de)compression functionality. - */ -package eu.steffo.cleaver.logic.compress; \ No newline at end of file diff --git a/src/eu/steffo/cleaver/logic/config/CompressConfig.java b/src/eu/steffo/cleaver/logic/config/CompressConfig.java new file mode 100644 index 0000000..65d1a57 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/CompressConfig.java @@ -0,0 +1,13 @@ +package eu.steffo.cleaver.logic.config; + +import eu.steffo.cleaver.logic.job.Job; + +/** + * A class containing the configuration for the compression step of a {@link Job Job}. + */ +public class CompressConfig { + @Override + public String toString() { + return "Yes (Deflate)"; + } +} diff --git a/src/eu/steffo/cleaver/logic/config/CryptConfig.java b/src/eu/steffo/cleaver/logic/config/CryptConfig.java new file mode 100644 index 0000000..db2667c --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/CryptConfig.java @@ -0,0 +1,30 @@ +package eu.steffo.cleaver.logic.config; + +import eu.steffo.cleaver.logic.job.Job; + +/** + * A class containing the configuration for the encryption/decryption step of a {@link Job Job}. + */ +public class CryptConfig { + protected final String key; + + /** + * Construct a new CryptConfig with a specific encryption key. + * @param key The encryption key. + */ + public CryptConfig(String key) { + this.key = key; + } + + /** + * @return The encryption key. + */ + public String getKey() { + return key; + } + + @Override + public String toString() { + return "••••••••"; + } +} diff --git a/src/eu/steffo/cleaver/logic/split/MergeConfig.java b/src/eu/steffo/cleaver/logic/config/MergeConfig.java similarity index 96% rename from src/eu/steffo/cleaver/logic/split/MergeConfig.java rename to src/eu/steffo/cleaver/logic/config/MergeConfig.java index adad42a..fcea8f0 100644 --- a/src/eu/steffo/cleaver/logic/split/MergeConfig.java +++ b/src/eu/steffo/cleaver/logic/config/MergeConfig.java @@ -1,4 +1,4 @@ -package eu.steffo.cleaver.logic.split; +package eu.steffo.cleaver.logic.config; /** * A {@link SplitConfig} created by reading a *.chp file, containing the number of parts and their size, but not the resulting file size. diff --git a/src/eu/steffo/cleaver/logic/split/SplitByPartsConfig.java b/src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java similarity index 95% rename from src/eu/steffo/cleaver/logic/split/SplitByPartsConfig.java rename to src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java index 4c7b35f..70d9440 100644 --- a/src/eu/steffo/cleaver/logic/split/SplitByPartsConfig.java +++ b/src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java @@ -1,4 +1,4 @@ -package eu.steffo.cleaver.logic.split; +package eu.steffo.cleaver.logic.config; public class SplitByPartsConfig extends SplitConfig { /** diff --git a/src/eu/steffo/cleaver/logic/split/SplitBySizeConfig.java b/src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java similarity index 96% rename from src/eu/steffo/cleaver/logic/split/SplitBySizeConfig.java rename to src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java index 128977b..21b8c2e 100644 --- a/src/eu/steffo/cleaver/logic/split/SplitBySizeConfig.java +++ b/src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java @@ -1,4 +1,4 @@ -package eu.steffo.cleaver.logic.split; +package eu.steffo.cleaver.logic.config; /** * A {@link SplitConfig} for splitting a file in parts of a specific part size. diff --git a/src/eu/steffo/cleaver/logic/config/SplitConfig.java b/src/eu/steffo/cleaver/logic/config/SplitConfig.java new file mode 100644 index 0000000..2bd9387 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/SplitConfig.java @@ -0,0 +1,29 @@ +package eu.steffo.cleaver.logic.config; + +import eu.steffo.cleaver.logic.job.Job; + +/** + * A class containing the configuration for the split/merge step of a {@link Job Job}. + */ +public abstract class SplitConfig { + /** + * @return The size in bytes of a single part of the file. + */ + public abstract long getPartSize(); + + /** + * @return The number of parts the file should be split in. + */ + public abstract int getPartCount(); + + /** + * @return The total size of the original file. + */ + public abstract long getTotalSize(); + + /** + * @return The string representation of the {@link SplitConfig}, to be used in the jobs table. + * @see eu.steffo.cleaver.gui.panels.JobsTablePanel + */ + public abstract String toString(); +} diff --git a/src/eu/steffo/cleaver/logic/crypt/CryptConfig.java b/src/eu/steffo/cleaver/logic/crypt/CryptConfig.java deleted file mode 100644 index 3f7768f..0000000 --- a/src/eu/steffo/cleaver/logic/crypt/CryptConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -package eu.steffo.cleaver.logic.crypt; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * A class containing the configuration for the encryption/decryption step of a {@link eu.steffo.cleaver.logic.Job Job}. - */ -public class CryptConfig { - protected final String key; - - /** - * Construct a new CryptConfig with a specific encryption key. - * @param key The encryption key. - */ - public CryptConfig(String key) { - this.key = key; - } - - /** - * @return The encryption key. - */ - public String getKey() { - return key; - } - - @Override - public String toString() { - return "••••••••"; - } - - /** - * Create a {@link Element} representing this CryptConfig (to be used in *.chp metadata files). - * @param doc The {@link Document} the {@link Element} should be created in. - * @return The created {@link Element}. - * @see eu.steffo.cleaver.logic.ChopJob - * @see eu.steffo.cleaver.logic.StitchJob - */ - public Element toElement(Document doc) { - return doc.createElement("Crypt"); - } -} diff --git a/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java b/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java deleted file mode 100644 index ae7eec3..0000000 --- a/src/eu/steffo/cleaver/logic/crypt/CryptOutputStream.java +++ /dev/null @@ -1,122 +0,0 @@ -package eu.steffo.cleaver.logic.crypt; - -import eu.steffo.cleaver.errors.ProgrammingError; - -import javax.crypto.Cipher; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; -import javax.crypto.spec.SecretKeySpec; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; - -public class CryptOutputStream extends FilterOutputStream { - private Cipher cipher; - - /** - * @return The algorithm used for the encryption. - */ - public String getAlgorithm() { - return "AES"; - } - - /** - * @return The mode of operation used for the encryption. - */ - public String getModeOfOperation() { - return "CFB8"; - } - - /** - * @return The padding used for the encryption. - */ - public String getPadding() { - return "PKCS5Padding"; - } - - /** - * @return The secret key algorithm used in the generation of the final key. - */ - public String getKeyAlgorithm() { - return "PBKDF2WithHmacSHA1"; - } - - /** - * @return The full transformation string as required by {@link Cipher#getInstance(String)}. - */ - public String getTransformationString() { - return String.format("%s/%s/%s", getAlgorithm(), getModeOfOperation(), getPadding()); - } - - /** - * Create a new CryptOutputStream with default {@link Cipher} parameters. - * (AES algorithm in operation mode CFB8 with PKCS5 padding) - * - * Does not use this as {@literal try} and {@literal catch} are not supported. - * - * @param out The {@link OutputStream} to connect this {@link FilterOutputStream} to. - * @param key The desired encryption key. - */ - public CryptOutputStream(OutputStream out, String key) throws InvalidKeyException { - super(out); - - //Setup the cipher object - try { - cipher = Cipher.getInstance(getTransformationString()); - } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { - //Should never happen, as it's predefined - e.printStackTrace(); - return; - } - - //Create the salt - byte[] salt = new byte[8]; - SecureRandom secureRandom = new SecureRandom(); - secureRandom.nextBytes(salt); - - //Create the KeySpec - //Using the recommended 65536 as iteration count - KeySpec spec = new PBEKeySpec(key.toCharArray(), salt, 65536, 256); - - SecretKeyFactory factory; - try { - factory = SecretKeyFactory.getInstance(getKeyAlgorithm()); - } catch (NoSuchAlgorithmException e) { - //Should never happen, as it's predefined - e.printStackTrace(); - return; - } - - //Create the pbkdf secret key - SecretKey pbkdf; - try { - pbkdf = factory.generateSecret(spec); - } catch (InvalidKeySpecException e) { - //Should never happen, as it's predefined - e.printStackTrace(); - return; - } - - //"Convert" the secret key to a AES secret key - SecretKey aes = new SecretKeySpec(pbkdf.getEncoded(), getAlgorithm()); - - //Init the cipher instance - cipher.init(Cipher.ENCRYPT_MODE, aes); - } - - @Override - public void write(int decryptedInt) throws IOException { - byte[] decryptedByte = new byte[1]; - decryptedByte[0] = (byte)decryptedInt; - byte[] encryptedByte = cipher.update(decryptedByte); - int encryptedInt = encryptedByte[0]; - super.write(encryptedInt); - } -} diff --git a/src/eu/steffo/cleaver/logic/crypt/package-info.java b/src/eu/steffo/cleaver/logic/crypt/package-info.java deleted file mode 100644 index 6ab3f40..0000000 --- a/src/eu/steffo/cleaver/logic/crypt/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * The package containing classes related to the encryption/decryption functionality. - */ -package eu.steffo.cleaver.logic.crypt; \ No newline at end of file diff --git a/src/eu/steffo/cleaver/logic/ChopJob.java b/src/eu/steffo/cleaver/logic/job/ChopJob.java similarity index 91% rename from src/eu/steffo/cleaver/logic/ChopJob.java rename to src/eu/steffo/cleaver/logic/job/ChopJob.java index 3d5efcd..2ad69de 100644 --- a/src/eu/steffo/cleaver/logic/ChopJob.java +++ b/src/eu/steffo/cleaver/logic/job/ChopJob.java @@ -1,15 +1,15 @@ -package eu.steffo.cleaver.logic; +package eu.steffo.cleaver.logic.job; import eu.steffo.cleaver.errors.ProgrammingError; -import eu.steffo.cleaver.logic.compress.CompressConfig; -import eu.steffo.cleaver.logic.crypt.CryptConfig; -import eu.steffo.cleaver.logic.crypt.CryptOutputStream; +import eu.steffo.cleaver.logic.config.CompressConfig; +import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.stream.output.CleaverCryptOutputStream; import eu.steffo.cleaver.logic.progress.ErrorProgress; import eu.steffo.cleaver.logic.progress.FinishedProgress; import eu.steffo.cleaver.logic.progress.Progress; import eu.steffo.cleaver.logic.progress.WorkingProgress; -import eu.steffo.cleaver.logic.split.SplitConfig; -import eu.steffo.cleaver.logic.split.SplitFileOutputStream; +import eu.steffo.cleaver.logic.config.SplitConfig; +import eu.steffo.cleaver.logic.stream.output.CleaverSplitFileOutputStream; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -95,7 +95,7 @@ public class ChopJob extends Job { OutputStream outputStream; if(splitConfig != null) { - outputStream = new SplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize()); + outputStream = new CleaverSplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize()); } else { outputStream = new FileOutputStream(String.format("%s.c0", file.getAbsolutePath())); @@ -106,7 +106,7 @@ public class ChopJob extends Job { } if(cryptConfig != null) { - outputStream = new CryptOutputStream(outputStream, cryptConfig.getKey()); + outputStream = new CleaverCryptOutputStream(outputStream, cryptConfig.getKey()); } //Create the .chp file diff --git a/src/eu/steffo/cleaver/logic/Job.java b/src/eu/steffo/cleaver/logic/job/Job.java similarity index 94% rename from src/eu/steffo/cleaver/logic/Job.java rename to src/eu/steffo/cleaver/logic/job/Job.java index 32f6251..aa05a32 100644 --- a/src/eu/steffo/cleaver/logic/Job.java +++ b/src/eu/steffo/cleaver/logic/job/Job.java @@ -1,13 +1,13 @@ -package eu.steffo.cleaver.logic; +package eu.steffo.cleaver.logic.job; import java.io.File; import javax.swing.SwingUtilities; -import eu.steffo.cleaver.logic.compress.CompressConfig; -import eu.steffo.cleaver.logic.crypt.CryptConfig; +import eu.steffo.cleaver.logic.config.CompressConfig; +import eu.steffo.cleaver.logic.config.CryptConfig; import eu.steffo.cleaver.logic.progress.NotStartedProgress; import eu.steffo.cleaver.logic.progress.Progress; -import eu.steffo.cleaver.logic.split.SplitConfig; +import eu.steffo.cleaver.logic.config.SplitConfig; /** * A {@link Thread} that allows access to the basic . diff --git a/src/eu/steffo/cleaver/logic/StitchJob.java b/src/eu/steffo/cleaver/logic/job/StitchJob.java similarity index 94% rename from src/eu/steffo/cleaver/logic/StitchJob.java rename to src/eu/steffo/cleaver/logic/job/StitchJob.java index c95623a..ff01e94 100644 --- a/src/eu/steffo/cleaver/logic/StitchJob.java +++ b/src/eu/steffo/cleaver/logic/job/StitchJob.java @@ -1,16 +1,18 @@ -package eu.steffo.cleaver.logic; +package eu.steffo.cleaver.logic.job; import eu.steffo.cleaver.errors.ChpFileError; import eu.steffo.cleaver.errors.ProgrammingError; -import eu.steffo.cleaver.logic.compress.CompressConfig; -import eu.steffo.cleaver.logic.crypt.CryptConfig; -import eu.steffo.cleaver.logic.crypt.CryptInputStream; +import eu.steffo.cleaver.logic.config.CompressConfig; +import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.config.MergeConfig; +import eu.steffo.cleaver.logic.config.SplitConfig; +import eu.steffo.cleaver.logic.stream.input.CryptInputStream; import eu.steffo.cleaver.logic.progress.ErrorProgress; import eu.steffo.cleaver.logic.progress.FinishedProgress; import eu.steffo.cleaver.logic.progress.Progress; import eu.steffo.cleaver.logic.progress.WorkingProgress; -import eu.steffo.cleaver.logic.split.*; +import eu.steffo.cleaver.logic.stream.input.CleaverSplitFileInputStream; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -21,7 +23,6 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import java.io.*; -import java.util.zip.DeflaterInputStream; import java.util.zip.InflaterInputStream; /** @@ -190,7 +191,7 @@ public class StitchJob extends Job { OutputStream outputStream = new FileOutputStream(resultFile); if (splitConfig != null) { - inputStream = new SplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize()); + inputStream = new CleaverSplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize()); } else { inputStream = new FileInputStream(String.format("%s.c0", resultFile.getAbsolutePath())); diff --git a/src/eu/steffo/cleaver/logic/job/package-info.java b/src/eu/steffo/cleaver/logic/job/package-info.java new file mode 100644 index 0000000..609c4ba --- /dev/null +++ b/src/eu/steffo/cleaver/logic/job/package-info.java @@ -0,0 +1,4 @@ +/** + * The package containing all possible {@link eu.steffo.cleaver.logic.job.Job Jobs}. + */ +package eu.steffo.cleaver.logic.job; diff --git a/src/eu/steffo/cleaver/logic/progress/ErrorProgress.java b/src/eu/steffo/cleaver/logic/progress/ErrorProgress.java index 80522d5..57d599a 100644 --- a/src/eu/steffo/cleaver/logic/progress/ErrorProgress.java +++ b/src/eu/steffo/cleaver/logic/progress/ErrorProgress.java @@ -1,7 +1,9 @@ package eu.steffo.cleaver.logic.progress; +import eu.steffo.cleaver.logic.job.Job; + /** - * A {@link Progress} that specifies that a {@link eu.steffo.cleaver.logic.Job} stopped because an exception occoured. + * A {@link Progress} that specifies that a {@link Job} stopped because an exception occoured. */ public class ErrorProgress extends Progress { private final Throwable error; @@ -15,7 +17,7 @@ public class ErrorProgress extends Progress { } /** - * @return The error encountered by the {@link eu.steffo.cleaver.logic.Job}. + * @return The error encountered by the {@link Job}. */ public Throwable getError() { return error; diff --git a/src/eu/steffo/cleaver/logic/progress/FinishedProgress.java b/src/eu/steffo/cleaver/logic/progress/FinishedProgress.java index e33efd7..e82fa0a 100644 --- a/src/eu/steffo/cleaver/logic/progress/FinishedProgress.java +++ b/src/eu/steffo/cleaver/logic/progress/FinishedProgress.java @@ -1,7 +1,9 @@ package eu.steffo.cleaver.logic.progress; +import eu.steffo.cleaver.logic.job.Job; + /** - * A {@link Progress} that specifies that a {@link eu.steffo.cleaver.logic.Job} has finished. + * A {@link Progress} that specifies that a {@link Job} has finished. */ public class FinishedProgress extends Progress { @Override diff --git a/src/eu/steffo/cleaver/logic/progress/NotStartedProgress.java b/src/eu/steffo/cleaver/logic/progress/NotStartedProgress.java index 1e0d2f7..446b8c4 100644 --- a/src/eu/steffo/cleaver/logic/progress/NotStartedProgress.java +++ b/src/eu/steffo/cleaver/logic/progress/NotStartedProgress.java @@ -1,7 +1,9 @@ package eu.steffo.cleaver.logic.progress; +import eu.steffo.cleaver.logic.job.Job; + /** - * A {@link Progress} that specifies that a {@link eu.steffo.cleaver.logic.Job} hasn't started yet. + * A {@link Progress} that specifies that a {@link Job} hasn't started yet. */ public class NotStartedProgress extends Progress { @Override diff --git a/src/eu/steffo/cleaver/logic/progress/WorkingProgress.java b/src/eu/steffo/cleaver/logic/progress/WorkingProgress.java index 7d714fa..036173a 100644 --- a/src/eu/steffo/cleaver/logic/progress/WorkingProgress.java +++ b/src/eu/steffo/cleaver/logic/progress/WorkingProgress.java @@ -1,7 +1,9 @@ package eu.steffo.cleaver.logic.progress; +import eu.steffo.cleaver.logic.job.Job; + /** - * A {@link Progress} that specifies that a {@link eu.steffo.cleaver.logic.Job} is currently running and has progressed to {@link #progress} %. + * A {@link Progress} that specifies that a {@link Job} is currently running and has progressed to {@link #progress} %. */ public class WorkingProgress extends Progress { public final float progress; diff --git a/src/eu/steffo/cleaver/logic/split/SplitConfig.java b/src/eu/steffo/cleaver/logic/split/SplitConfig.java deleted file mode 100644 index fce9ca4..0000000 --- a/src/eu/steffo/cleaver/logic/split/SplitConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -package eu.steffo.cleaver.logic.split; - -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -/** - * A class containing the configuration for the split/merge step of a {@link eu.steffo.cleaver.logic.Job Job}. - */ -public abstract class SplitConfig { - //TODO REBUILD ERRORS - /** - * Create a {@link Element} representing this SplitConfig (to be used in *.chp metadata files). - * - * @param doc The {@link Document} the {@link Element} should be created in. - * @return The created {@link Element}. - * - * @see eu.steffo.cleaver.logic.ChopJob - * @see eu.steffo.cleaver.logic.StitchJob - */ - public Element toElement(Document doc) { - Element element = doc.createElement("Split"); - - Attr partSizeAttr = doc.createAttribute("part-size"); - partSizeAttr.setValue(Long.toString(getPartSize())); - element.setAttributeNode(partSizeAttr); - - Attr partCountAttr = doc.createAttribute("parts"); - partCountAttr.setValue(Long.toString(getPartCount())); - element.setAttributeNode(partCountAttr); - - Attr totalSizeAttr = doc.createAttribute("total-size"); - totalSizeAttr.setValue(Long.toString(getPartCount())); - element.setAttributeNode(totalSizeAttr); - - return element; - } - - /** - * @return The size in bytes of a single part of the file. - */ - public abstract long getPartSize(); - - /** - * @return The number of parts the file should be split in. - */ - public abstract int getPartCount(); - - /** - * @return The total size of the original file. - */ - public abstract long getTotalSize(); - - /** - * @return The string representation of the {@link SplitConfig}, to be used in the jobs table. - * @see eu.steffo.cleaver.gui.panels.JobsTablePanel - */ - public abstract String toString(); -} diff --git a/src/eu/steffo/cleaver/logic/split/package-info.java b/src/eu/steffo/cleaver/logic/split/package-info.java deleted file mode 100644 index 0d58b3c..0000000 --- a/src/eu/steffo/cleaver/logic/split/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * The package containing classes related to the file splitting/merging functionality. - */ -package eu.steffo.cleaver.logic.split; \ No newline at end of file diff --git a/src/eu/steffo/cleaver/logic/stream/ICleaverStream.java b/src/eu/steffo/cleaver/logic/stream/ICleaverStream.java new file mode 100644 index 0000000..f59da7e --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/ICleaverStream.java @@ -0,0 +1,4 @@ +package eu.steffo.cleaver.logic.stream; + +public interface ICleaverStream { +} diff --git a/src/eu/steffo/cleaver/logic/split/SplitFileInputStream.java b/src/eu/steffo/cleaver/logic/stream/input/CleaverSplitFileInputStream.java similarity index 93% rename from src/eu/steffo/cleaver/logic/split/SplitFileInputStream.java rename to src/eu/steffo/cleaver/logic/stream/input/CleaverSplitFileInputStream.java index 06f1d22..e069bfd 100644 --- a/src/eu/steffo/cleaver/logic/split/SplitFileInputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/input/CleaverSplitFileInputStream.java @@ -1,10 +1,10 @@ -package eu.steffo.cleaver.logic.split; +package eu.steffo.cleaver.logic.stream.input; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -public class SplitFileInputStream extends InputStream { +public class CleaverSplitFileInputStream extends InputStream { private final String fileBaseName; private long currentByteCount; private long maximumByteCount; @@ -20,7 +20,7 @@ public class SplitFileInputStream extends InputStream { * @param fileBaseName The name of the files without the extension. If it is {@literal example}, the opened files will be {@literal example.c1}, {@literal example.c2}, and so on. * @param maximumByteCount The number of bytes that should be read from a file before switching to the next one. */ - public SplitFileInputStream(String fileBaseName, long maximumByteCount) { + public CleaverSplitFileInputStream(String fileBaseName, long maximumByteCount) { this.fileBaseName = fileBaseName; this.maximumByteCount = maximumByteCount; this.currentByteCount = 0; diff --git a/src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java b/src/eu/steffo/cleaver/logic/stream/input/CryptInputStream.java similarity index 98% rename from src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java rename to src/eu/steffo/cleaver/logic/stream/input/CryptInputStream.java index 9049393..8185322 100644 --- a/src/eu/steffo/cleaver/logic/crypt/CryptInputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/input/CryptInputStream.java @@ -1,4 +1,4 @@ -package eu.steffo.cleaver.logic.crypt; +package eu.steffo.cleaver.logic.stream.input; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; diff --git a/src/eu/steffo/cleaver/logic/stream/input/ICleaverInputStream.java b/src/eu/steffo/cleaver/logic/stream/input/ICleaverInputStream.java new file mode 100644 index 0000000..6bb6513 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/input/ICleaverInputStream.java @@ -0,0 +1,6 @@ +package eu.steffo.cleaver.logic.stream.input; + +import eu.steffo.cleaver.logic.stream.ICleaverStream; + +public interface ICleaverInputStream extends ICleaverStream { +} diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java new file mode 100644 index 0000000..6bd19c8 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java @@ -0,0 +1,98 @@ +package eu.steffo.cleaver.logic.stream.output; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.OutputStream; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; + +public class CleaverCompressOutputStream extends DeflaterOutputStream implements ICleaverOutputStream { + /** + * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. + * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int, boolean) + */ + public CleaverCompressOutputStream(OutputStream out, Deflater def, int size, boolean syncFlush) { + super(out, def, size, syncFlush); + if(!(out instanceof ICleaverOutputStream)) { + throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); + } + } + + /** + * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. + * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int) + */ + public CleaverCompressOutputStream(OutputStream out, Deflater def, int size) { + super(out, def, size); + if(!(out instanceof ICleaverOutputStream)) { + throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); + } + } + + /** + * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. + * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, boolean) + */ + public CleaverCompressOutputStream(OutputStream out, Deflater def, boolean syncFlush) { + super(out, def, syncFlush); + if(!(out instanceof ICleaverOutputStream)) { + throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); + } + } + + /** + * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. + * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater) + */ + public CleaverCompressOutputStream(OutputStream out, Deflater def) { + super(out, def); + if(!(out instanceof ICleaverOutputStream)) { + throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); + } + } + + /** + * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. + * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, boolean) + */ + public CleaverCompressOutputStream(OutputStream out, boolean syncFlush) { + super(out, syncFlush); + if(!(out instanceof ICleaverOutputStream)) { + throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); + } + } + + /** + * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. + * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream) + */ + public CleaverCompressOutputStream(OutputStream out) { + super(out); + if(!(out instanceof ICleaverOutputStream)) { + throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); + } + } + + /** + * @return The name of the used compression algorithm (currently only {@literal Deflate}). + */ + public String getAlgorithm() { + return "Deflate"; + } + + @Override + public Element toElement(Document doc) { + Element element = doc.createElement("Compress"); + + Element child = ((ICleaverOutputStream)out).toElement(doc); + element.appendChild(child); + + Attr algorithmAttr = doc.createAttribute("algorithm"); + algorithmAttr.setValue(getAlgorithm()); + element.setAttributeNode(algorithmAttr); + + return element; + } +} diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java new file mode 100644 index 0000000..69cc1f4 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java @@ -0,0 +1,174 @@ +package eu.steffo.cleaver.logic.stream.output; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; + +public class CleaverCryptOutputStream extends FilterOutputStream implements ICleaverOutputStream { + private Cipher cipher; + + /** + * The algorithm used for the encryption (Advanced Encryption Standard). + */ + public static final String ENCRYPTION_ALGORITHM = "AES"; + + /** + * The mode of operation used for the encryption (Cipher FeedBack with 8-bit blocks). + */ + public static final String MODE_OF_OPERATION = "CFB8"; + + /** + * The padding standard used for the encryption (PKCS#5). + */ + public static final String PADDING = "PKCS5Padding"; + + /** + * The size in bytes of the salt. + */ + public static final int SALT_SIZE = 8; + + /** + * The name of the key derivation algorithm to be used (Password-Based Key Derivation Function 2 with HMAC-Initialization Vector with the specified size. + * @param size The size of the initialization vector. + * @return The generated IV. + */ + protected IvParameterSpec generateIV(int size) { + return new IvParameterSpec(generateSecure(size)); + } + + /** + * Generate a key starting from a character array. + * @throws NoSuchAlgorithmException If the {@link #KEY_DERIVATION_ALGORITHM} is invalid. + * @throws InvalidKeySpecException If the generated {@link KeySpec} is invalid. + */ + private SecretKey generatePasswordKey(char[] key) throws NoSuchAlgorithmException, InvalidKeySpecException { + KeySpec spec = new PBEKeySpec(key, generateSecure(SALT_SIZE), KEY_ITERATION_COUNT, KEY_LENGTH); + SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_DERIVATION_ALGORITHM); + return factory.generateSecret(spec); + } + + /** + * Create and initialize the {@link Cipher} {@link #cipher} to be used by the CleaverCryptOutputStream. + * @param key The string to be used in the {@link Cipher} as encryption key. + * @throws NoSuchPaddingException If the {@link #PADDING} is invalid. + * @throws NoSuchAlgorithmException If the {@link #ENCRYPTION_ALGORITHM} is invalid. + * @throws InvalidKeySpecException If the generated {@link KeySpec} is invalid. + */ + private void createCipher(char[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException { + //Setup the cipher object + cipher = Cipher.getInstance(getTransformationString()); + + //"Convert" the secret key to a AES secret key + SecretKey aes = new SecretKeySpec(generatePasswordKey(key).getEncoded(), ENCRYPTION_ALGORITHM); + + //Init the cipher instance + cipher.init(Cipher.ENCRYPT_MODE, aes, generateIV(1)); + } + + /** + * Create a new CleaverCryptOutputStream with default {@link Cipher} parameters (AES algorithm in operation mode CFB8 with PKCS5 padding). + * + * @param out The {@link OutputStream} to connect this {@link FilterOutputStream} to. + * @param key The desired encryption key. + */ + public CleaverCryptOutputStream(OutputStream out, String key) { + super(out); + try { + createCipher(key.toCharArray()); + } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException e) { + e.printStackTrace(); + } + } + + @Override + public void write(int decryptedInt) throws IOException { + byte[] decryptedByte = new byte[1]; + decryptedByte[0] = (byte)decryptedInt; + byte[] encryptedByte = cipher.update(decryptedByte); + int encryptedInt = encryptedByte[0]; + super.write(encryptedInt); + } + + @Override + public Element toElement(Document doc) { + Element element = doc.createElement("Crypt"); + + Element child = ((ICleaverOutputStream)out).toElement(doc); + element.appendChild(child); + + Attr algorithmAttr = doc.createAttribute("algorithm"); + algorithmAttr.setValue(ENCRYPTION_ALGORITHM); + element.setAttributeNode(algorithmAttr); + + Attr modeOfOperationAttr = doc.createAttribute("mode-of-operation"); + modeOfOperationAttr.setValue(MODE_OF_OPERATION); + element.setAttributeNode(modeOfOperationAttr); + + Attr paddingAttr = doc.createAttribute("padding"); + paddingAttr.setValue(PADDING); + element.setAttributeNode(paddingAttr); + + Attr keyAlgorithmAttr = doc.createAttribute("key-algorithm"); + keyAlgorithmAttr.setValue(KEY_DERIVATION_ALGORITHM); + element.setAttributeNode(keyAlgorithmAttr); + + Attr iterationCountAttr = doc.createAttribute("iteration-count"); + iterationCountAttr.setValue(Integer.toString(KEY_ITERATION_COUNT)); + element.setAttributeNode(iterationCountAttr); + + Attr keyLengthAttr = doc.createAttribute("key-length"); + keyLengthAttr.setValue(Integer.toString(KEY_LENGTH)); + element.setAttributeNode(keyLengthAttr); + + return element; + } +} diff --git a/src/eu/steffo/cleaver/logic/split/SplitFileOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java similarity index 68% rename from src/eu/steffo/cleaver/logic/split/SplitFileOutputStream.java rename to src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java index 4fb2de4..af236b4 100644 --- a/src/eu/steffo/cleaver/logic/split/SplitFileOutputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java @@ -1,4 +1,8 @@ -package eu.steffo.cleaver.logic.split; +package eu.steffo.cleaver.logic.stream.output; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; import java.io.FileOutputStream; import java.io.IOException; @@ -9,10 +13,11 @@ import java.io.OutputStream; * * Bytes are written to a file until its length reaches {@link #maximumByteCount}, then the program switches to the following file (.c2 if .c1 is full, .c3 if .c2 is full, and so on). */ -public class SplitFileOutputStream extends OutputStream { +public class CleaverSplitFileOutputStream extends OutputStream implements ICleaverOutputStream { private final String fileBaseName; private long currentByteCount; private long maximumByteCount; + private long totalByteCount; private int currentFileCount; /** @@ -21,11 +26,11 @@ public class SplitFileOutputStream extends OutputStream { protected FileOutputStream currentFileOutputStream; /** - * Construct a SplitFileOutputStream. + * Construct a CleaverSplitFileOutputStream. * @param fileBaseName The name of the files without the extension. If it is {@literal example}, the created files will be {@literal example.c1}, {@literal example.c2}, and so on. * @param maximumByteCount The number of bytes that should be written to a file before switching to the next one. */ - public SplitFileOutputStream(String fileBaseName, long maximumByteCount) { + public CleaverSplitFileOutputStream(String fileBaseName, long maximumByteCount) { this.fileBaseName = fileBaseName; this.maximumByteCount = maximumByteCount; this.currentByteCount = 0; @@ -49,11 +54,13 @@ public class SplitFileOutputStream extends OutputStream { @Override public void write(int b) throws IOException { + // Can be optimized using the modulo operation, not doing it now for clarity if(currentFileOutputStream == null || currentByteCount >= maximumByteCount) { createNextFileOutputStream(); } currentFileOutputStream.write(b); currentByteCount += 1; + totalByteCount += 1; } @Override @@ -88,4 +95,31 @@ public class SplitFileOutputStream extends OutputStream { public int getCurrentFileCount() { return currentFileCount; } + + /** + * @return The number of bytes that have already been written. + */ + public long getTotalByteCount() { + return totalByteCount; + } + + @Override + public Element toElement(Document doc) { + Element element = doc.createElement("Split"); + element.setTextContent(fileBaseName); + + Attr partSizeAttr = doc.createAttribute("part-size"); + partSizeAttr.setValue(Long.toString(maximumByteCount)); + element.setAttributeNode(partSizeAttr); + + Attr partCountAttr = doc.createAttribute("parts"); + partCountAttr.setValue(Long.toString(currentFileCount)); + element.setAttributeNode(partCountAttr); + + Attr totalSizeAttr = doc.createAttribute("total-size"); + totalSizeAttr.setValue(Long.toString(totalByteCount)); + element.setAttributeNode(totalSizeAttr); + + return element; + } } diff --git a/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java new file mode 100644 index 0000000..1d23a5a --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java @@ -0,0 +1,15 @@ +package eu.steffo.cleaver.logic.stream.output; + +import eu.steffo.cleaver.logic.stream.ICleaverStream; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +public interface ICleaverOutputStream extends ICleaverStream { + /** + * Create a {@link Element} representing the stream (to be used in *.chp metadata files). + * + * @param doc The {@link Document} the {@link Element} should be created in. + * @return The created {@link Element}. + */ + public Element toElement(Document doc); +}