mirror of
https://github.com/Steffo99/unimore-oop-2020-cleaver.git
synced 2024-11-26 01:54:20 +00:00
Do some things that I haven't finished yet
This commit is contained in:
parent
823736aecc
commit
b90693550a
40 changed files with 478 additions and 322 deletions
|
@ -2,7 +2,7 @@ package eu.steffo.cleaver;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import eu.steffo.cleaver.gui.CleaverFrame;
|
import eu.steffo.cleaver.gui.CleaverFrame;
|
||||||
import eu.steffo.cleaver.logic.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package eu.steffo.cleaver;
|
package eu.steffo.cleaver;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.ChopJob;
|
import eu.steffo.cleaver.logic.stream.output.CleaverSplitFileOutputStream;
|
||||||
import eu.steffo.cleaver.logic.Job;
|
|
||||||
import eu.steffo.cleaver.logic.split.SplitFileOutputStream;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -10,7 +8,7 @@ import java.io.OutputStream;
|
||||||
//TODO: delet this
|
//TODO: delet this
|
||||||
public class Test {
|
public class Test {
|
||||||
public static void main(String[] args) {
|
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++) {
|
for(int i = 0; i < 256; i++) {
|
||||||
try {
|
try {
|
||||||
stream.write(i);
|
stream.write(i);
|
||||||
|
|
|
@ -3,8 +3,7 @@ package eu.steffo.cleaver.gui;
|
||||||
import eu.steffo.cleaver.gui.panels.ChopAndStitchPanel;
|
import eu.steffo.cleaver.gui.panels.ChopAndStitchPanel;
|
||||||
import eu.steffo.cleaver.gui.panels.JobsButtonsPanel;
|
import eu.steffo.cleaver.gui.panels.JobsButtonsPanel;
|
||||||
import eu.steffo.cleaver.gui.panels.JobsTablePanel;
|
import eu.steffo.cleaver.gui.panels.JobsTablePanel;
|
||||||
import eu.steffo.cleaver.logic.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
import eu.steffo.cleaver.logic.progress.NotStartedProgress;
|
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package eu.steffo.cleaver.gui.panels;
|
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 javax.swing.*;
|
||||||
import java.awt.event.ActionListener;
|
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 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.
|
* @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 ChopPanel#createAndAddJobs(ArrayList, Runnable)
|
||||||
* @see eu.steffo.cleaver.logic.ChopJob
|
* @see ChopJob
|
||||||
* @see eu.steffo.cleaver.gui.CleaverFrame
|
* @see eu.steffo.cleaver.gui.CleaverFrame
|
||||||
*/
|
*/
|
||||||
public void createAndAddChopJobs(ArrayList<Job> jobs, Runnable onProgressChange) {
|
public void createAndAddChopJobs(ArrayList<Job> jobs, Runnable onProgressChange) {
|
||||||
|
@ -60,7 +61,7 @@ public class ChopAndStitchPanel extends JPanel {
|
||||||
* @param jobs The {@link ArrayList} of jobs that should be manipulated.
|
* @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.
|
* @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 StitchPanel#createAndAddJobs(ArrayList, Runnable)
|
||||||
* @see eu.steffo.cleaver.logic.ChopJob
|
* @see ChopJob
|
||||||
* @see eu.steffo.cleaver.gui.CleaverFrame
|
* @see eu.steffo.cleaver.gui.CleaverFrame
|
||||||
*/
|
*/
|
||||||
public void createAndAddStitchJobs(ArrayList<Job> jobs, Runnable onProgressChange) {
|
public void createAndAddStitchJobs(ArrayList<Job> jobs, Runnable onProgressChange) {
|
||||||
|
|
|
@ -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.CompressRow;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.option.CryptRow;
|
import eu.steffo.cleaver.gui.panels.rows.option.CryptRow;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.option.SplitRow;
|
import eu.steffo.cleaver.gui.panels.rows.option.SplitRow;
|
||||||
import eu.steffo.cleaver.logic.ChopJob;
|
import eu.steffo.cleaver.logic.job.ChopJob;
|
||||||
import eu.steffo.cleaver.logic.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
import eu.steffo.cleaver.logic.compress.CompressConfig;
|
import eu.steffo.cleaver.logic.config.CompressConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptConfig;
|
import eu.steffo.cleaver.logic.config.CryptConfig;
|
||||||
import eu.steffo.cleaver.logic.split.SplitConfig;
|
import eu.steffo.cleaver.logic.config.SplitConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package eu.steffo.cleaver.gui.panels;
|
package eu.steffo.cleaver.gui.panels;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
import eu.steffo.cleaver.logic.compress.CompressConfig;
|
import eu.steffo.cleaver.logic.config.CompressConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptConfig;
|
import eu.steffo.cleaver.logic.config.CryptConfig;
|
||||||
import eu.steffo.cleaver.logic.split.SplitConfig;
|
import eu.steffo.cleaver.logic.config.SplitConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.table.AbstractTableModel;
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
|
|
@ -4,8 +4,8 @@ import eu.steffo.cleaver.errors.ChpFileError;
|
||||||
import eu.steffo.cleaver.errors.ProgrammingError;
|
import eu.steffo.cleaver.errors.ProgrammingError;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.CreateJobButtonRow;
|
import eu.steffo.cleaver.gui.panels.rows.CreateJobButtonRow;
|
||||||
import eu.steffo.cleaver.gui.panels.rows.option.KeyRow;
|
import eu.steffo.cleaver.gui.panels.rows.option.KeyRow;
|
||||||
import eu.steffo.cleaver.logic.Job;
|
import eu.steffo.cleaver.logic.job.Job;
|
||||||
import eu.steffo.cleaver.logic.StitchJob;
|
import eu.steffo.cleaver.logic.job.StitchJob;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
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.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
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.*;
|
import javax.swing.*;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
package eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
|
|
||||||
|
import eu.steffo.cleaver.logic.config.CryptConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
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.
|
* This configuration is used only if the selected *.chp file specifies that the *.cXX are encrypted.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package eu.steffo.cleaver.gui.panels.rows.option;
|
package eu.steffo.cleaver.gui.panels.rows.option;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.split.SplitByPartsConfig;
|
import eu.steffo.cleaver.logic.config.SplitByPartsConfig;
|
||||||
import eu.steffo.cleaver.logic.split.SplitBySizeConfig;
|
import eu.steffo.cleaver.logic.config.SplitBySizeConfig;
|
||||||
import eu.steffo.cleaver.logic.split.SplitConfig;
|
import eu.steffo.cleaver.logic.config.SplitConfig;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
|
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
/**
|
|
||||||
* The package containing classes related to the (de)compression functionality.
|
|
||||||
*/
|
|
||||||
package eu.steffo.cleaver.logic.compress;
|
|
13
src/eu/steffo/cleaver/logic/config/CompressConfig.java
Normal file
13
src/eu/steffo/cleaver/logic/config/CompressConfig.java
Normal file
|
@ -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)";
|
||||||
|
}
|
||||||
|
}
|
30
src/eu/steffo/cleaver/logic/config/CryptConfig.java
Normal file
30
src/eu/steffo/cleaver/logic/config/CryptConfig.java
Normal file
|
@ -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 "••••••••";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.
|
* A {@link SplitConfig} created by reading a *.chp file, containing the number of parts and their size, but not the resulting file size.
|
|
@ -1,4 +1,4 @@
|
||||||
package eu.steffo.cleaver.logic.split;
|
package eu.steffo.cleaver.logic.config;
|
||||||
|
|
||||||
public class SplitByPartsConfig extends SplitConfig {
|
public class SplitByPartsConfig extends SplitConfig {
|
||||||
/**
|
/**
|
|
@ -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.
|
* A {@link SplitConfig} for splitting a file in parts of a specific part size.
|
29
src/eu/steffo/cleaver/logic/config/SplitConfig.java
Normal file
29
src/eu/steffo/cleaver/logic/config/SplitConfig.java
Normal file
|
@ -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();
|
||||||
|
}
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
/**
|
|
||||||
* The package containing classes related to the encryption/decryption functionality.
|
|
||||||
*/
|
|
||||||
package eu.steffo.cleaver.logic.crypt;
|
|
|
@ -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.errors.ProgrammingError;
|
||||||
import eu.steffo.cleaver.logic.compress.CompressConfig;
|
import eu.steffo.cleaver.logic.config.CompressConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptConfig;
|
import eu.steffo.cleaver.logic.config.CryptConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptOutputStream;
|
import eu.steffo.cleaver.logic.stream.output.CleaverCryptOutputStream;
|
||||||
import eu.steffo.cleaver.logic.progress.ErrorProgress;
|
import eu.steffo.cleaver.logic.progress.ErrorProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.Progress;
|
import eu.steffo.cleaver.logic.progress.Progress;
|
||||||
import eu.steffo.cleaver.logic.progress.WorkingProgress;
|
import eu.steffo.cleaver.logic.progress.WorkingProgress;
|
||||||
import eu.steffo.cleaver.logic.split.SplitConfig;
|
import eu.steffo.cleaver.logic.config.SplitConfig;
|
||||||
import eu.steffo.cleaver.logic.split.SplitFileOutputStream;
|
import eu.steffo.cleaver.logic.stream.output.CleaverSplitFileOutputStream;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ public class ChopJob extends Job {
|
||||||
OutputStream outputStream;
|
OutputStream outputStream;
|
||||||
|
|
||||||
if(splitConfig != null) {
|
if(splitConfig != null) {
|
||||||
outputStream = new SplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize());
|
outputStream = new CleaverSplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
outputStream = new FileOutputStream(String.format("%s.c0", file.getAbsolutePath()));
|
outputStream = new FileOutputStream(String.format("%s.c0", file.getAbsolutePath()));
|
||||||
|
@ -106,7 +106,7 @@ public class ChopJob extends Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cryptConfig != null) {
|
if(cryptConfig != null) {
|
||||||
outputStream = new CryptOutputStream(outputStream, cryptConfig.getKey());
|
outputStream = new CleaverCryptOutputStream(outputStream, cryptConfig.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create the .chp file
|
//Create the .chp file
|
|
@ -1,13 +1,13 @@
|
||||||
package eu.steffo.cleaver.logic;
|
package eu.steffo.cleaver.logic.job;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import eu.steffo.cleaver.logic.compress.CompressConfig;
|
import eu.steffo.cleaver.logic.config.CompressConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptConfig;
|
import eu.steffo.cleaver.logic.config.CryptConfig;
|
||||||
import eu.steffo.cleaver.logic.progress.NotStartedProgress;
|
import eu.steffo.cleaver.logic.progress.NotStartedProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.Progress;
|
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 .
|
* A {@link Thread} that allows access to the basic .
|
|
@ -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.ChpFileError;
|
||||||
import eu.steffo.cleaver.errors.ProgrammingError;
|
import eu.steffo.cleaver.errors.ProgrammingError;
|
||||||
import eu.steffo.cleaver.logic.compress.CompressConfig;
|
import eu.steffo.cleaver.logic.config.CompressConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptConfig;
|
import eu.steffo.cleaver.logic.config.CryptConfig;
|
||||||
import eu.steffo.cleaver.logic.crypt.CryptInputStream;
|
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.ErrorProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
import eu.steffo.cleaver.logic.progress.FinishedProgress;
|
||||||
import eu.steffo.cleaver.logic.progress.Progress;
|
import eu.steffo.cleaver.logic.progress.Progress;
|
||||||
import eu.steffo.cleaver.logic.progress.WorkingProgress;
|
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.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -21,7 +23,6 @@ import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.zip.DeflaterInputStream;
|
|
||||||
import java.util.zip.InflaterInputStream;
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -190,7 +191,7 @@ public class StitchJob extends Job {
|
||||||
OutputStream outputStream = new FileOutputStream(resultFile);
|
OutputStream outputStream = new FileOutputStream(resultFile);
|
||||||
|
|
||||||
if (splitConfig != null) {
|
if (splitConfig != null) {
|
||||||
inputStream = new SplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize());
|
inputStream = new CleaverSplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inputStream = new FileInputStream(String.format("%s.c0", resultFile.getAbsolutePath()));
|
inputStream = new FileInputStream(String.format("%s.c0", resultFile.getAbsolutePath()));
|
4
src/eu/steffo/cleaver/logic/job/package-info.java
Normal file
4
src/eu/steffo/cleaver/logic/job/package-info.java
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* The package containing all possible {@link eu.steffo.cleaver.logic.job.Job Jobs}.
|
||||||
|
*/
|
||||||
|
package eu.steffo.cleaver.logic.job;
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.steffo.cleaver.logic.progress;
|
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 {
|
public class ErrorProgress extends Progress {
|
||||||
private final Throwable error;
|
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() {
|
public Throwable getError() {
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.steffo.cleaver.logic.progress;
|
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 {
|
public class FinishedProgress extends Progress {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.steffo.cleaver.logic.progress;
|
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 {
|
public class NotStartedProgress extends Progress {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package eu.steffo.cleaver.logic.progress;
|
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 class WorkingProgress extends Progress {
|
||||||
public final float progress;
|
public final float progress;
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
/**
|
|
||||||
* The package containing classes related to the file splitting/merging functionality.
|
|
||||||
*/
|
|
||||||
package eu.steffo.cleaver.logic.split;
|
|
4
src/eu/steffo/cleaver/logic/stream/ICleaverStream.java
Normal file
4
src/eu/steffo/cleaver/logic/stream/ICleaverStream.java
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
package eu.steffo.cleaver.logic.stream;
|
||||||
|
|
||||||
|
public interface ICleaverStream {
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
package eu.steffo.cleaver.logic.split;
|
package eu.steffo.cleaver.logic.stream.input;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
public class SplitFileInputStream extends InputStream {
|
public class CleaverSplitFileInputStream extends InputStream {
|
||||||
private final String fileBaseName;
|
private final String fileBaseName;
|
||||||
private long currentByteCount;
|
private long currentByteCount;
|
||||||
private long maximumByteCount;
|
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 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.
|
* @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.fileBaseName = fileBaseName;
|
||||||
this.maximumByteCount = maximumByteCount;
|
this.maximumByteCount = maximumByteCount;
|
||||||
this.currentByteCount = 0;
|
this.currentByteCount = 0;
|
|
@ -1,4 +1,4 @@
|
||||||
package eu.steffo.cleaver.logic.crypt;
|
package eu.steffo.cleaver.logic.stream.input;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.NoSuchPaddingException;
|
import javax.crypto.NoSuchPaddingException;
|
|
@ -0,0 +1,6 @@
|
||||||
|
package eu.steffo.cleaver.logic.stream.input;
|
||||||
|
|
||||||
|
import eu.steffo.cleaver.logic.stream.ICleaverStream;
|
||||||
|
|
||||||
|
public interface ICleaverInputStream extends ICleaverStream {
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 (<a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard">Advanced Encryption Standard</a>).
|
||||||
|
*/
|
||||||
|
public static final String ENCRYPTION_ALGORITHM = "AES";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mode of operation used for the encryption (<a href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_(CFB)">Cipher FeedBack</a> with 8-bit blocks).
|
||||||
|
*/
|
||||||
|
public static final String MODE_OF_OPERATION = "CFB8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The padding standard used for the encryption (<a href="https://en.wikipedia.org/wiki/PKCS">PKCS#5</a>).
|
||||||
|
*/
|
||||||
|
public static final String PADDING = "PKCS5Padding";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The size in bytes of the <a href="https://en.wikipedia.org/wiki/Salt_(cryptography)">salt</a>.
|
||||||
|
*/
|
||||||
|
public static final int SALT_SIZE = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the key derivation algorithm to be used (<a href="https://en.wikipedia.org/wiki/PBKDF2">Password-Based Key Derivation Function 2</a> with <a href="https://en.wikipedia.org/wiki/HMAC">HMAC</a>-<a href="https://it.wikipedia.org/wiki/Secure_Hash_Algorithm>SHA512</a>).
|
||||||
|
*/
|
||||||
|
public static final String KEY_DERIVATION_ALGORITHM = "PBKDF2WithHmacSHA512";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The iteration count for the {@link #KEY_DERIVATION_ALGORITHM}.
|
||||||
|
*/
|
||||||
|
public static final int KEY_ITERATION_COUNT = 65535;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length in bits of the key to be generated with the {@link #KEY_DERIVATION_ALGORITHM}.
|
||||||
|
*/
|
||||||
|
public static final int KEY_LENGTH = 512;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The full transformation string as required by {@link Cipher#getInstance(String)}.
|
||||||
|
*/
|
||||||
|
public String getTransformationString() {
|
||||||
|
return String.format("%s/%s/%s", ENCRYPTION_ALGORITHM, MODE_OF_OPERATION, PADDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an array of secure random bytes.
|
||||||
|
* @param size The size of the array.
|
||||||
|
* @return The generated array of secure random bytes.
|
||||||
|
* @see SecureRandom
|
||||||
|
*/
|
||||||
|
protected byte[] generateSecure(int size) {
|
||||||
|
byte[] salt = new byte[8];
|
||||||
|
SecureRandom secureRandom = new SecureRandom();
|
||||||
|
secureRandom.nextBytes(salt);
|
||||||
|
return salt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a new <a href="https://en.wikipedia.org/wiki/Initialization_vector">Initialization Vector</a> 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.FileOutputStream;
|
||||||
import java.io.IOException;
|
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).
|
* 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 final String fileBaseName;
|
||||||
private long currentByteCount;
|
private long currentByteCount;
|
||||||
private long maximumByteCount;
|
private long maximumByteCount;
|
||||||
|
private long totalByteCount;
|
||||||
private int currentFileCount;
|
private int currentFileCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,11 +26,11 @@ public class SplitFileOutputStream extends OutputStream {
|
||||||
protected FileOutputStream currentFileOutputStream;
|
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 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.
|
* @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.fileBaseName = fileBaseName;
|
||||||
this.maximumByteCount = maximumByteCount;
|
this.maximumByteCount = maximumByteCount;
|
||||||
this.currentByteCount = 0;
|
this.currentByteCount = 0;
|
||||||
|
@ -49,11 +54,13 @@ public class SplitFileOutputStream extends OutputStream {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(int b) throws IOException {
|
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) {
|
if(currentFileOutputStream == null || currentByteCount >= maximumByteCount) {
|
||||||
createNextFileOutputStream();
|
createNextFileOutputStream();
|
||||||
}
|
}
|
||||||
currentFileOutputStream.write(b);
|
currentFileOutputStream.write(b);
|
||||||
currentByteCount += 1;
|
currentByteCount += 1;
|
||||||
|
totalByteCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,4 +95,31 @@ public class SplitFileOutputStream extends OutputStream {
|
||||||
public int getCurrentFileCount() {
|
public int getCurrentFileCount() {
|
||||||
return currentFileCount;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in a new issue