Line | Hits | Source |
---|---|---|
1 | /******************************************************************************* | |
2 | *InternetCafe is a software solution that helps the management of Cybercafes | |
3 | * according with the ITALIAN DECREE LAW ON ANTI-TERROR MEASURES, 27 JULY 2005. | |
4 | * Copyright (C) 2006 Guido Angelo Ingenito | |
5 | ||
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version 2 | |
9 | * of the License, or (at your option) any later version. | |
10 | ||
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | *******************************************************************************/ | |
20 | package base.jdbs; | |
21 | ||
22 | import java.io.File; | |
23 | import java.io.FileWriter; | |
24 | import java.io.IOException; | |
25 | import java.io.PrintStream; | |
26 | ||
27 | import javax.xml.parsers.DocumentBuilderFactory; | |
28 | import javax.xml.transform.Transformer; | |
29 | import javax.xml.transform.TransformerFactory; | |
30 | import javax.xml.transform.dom.DOMSource; | |
31 | import javax.xml.transform.stream.StreamResult; | |
32 | ||
33 | import org.apache.log4j.Logger; | |
34 | import org.w3c.dom.Document; | |
35 | ||
36 | import base.jdbs.cryptography.asymmetric.KeyPair; | |
37 | import base.jdbs.cryptography.asymmetric.RSAAsymmetricCipher; | |
38 | import base.jdbs.cryptography.symmetric.DESSymmetricCipher; | |
39 | import base.jdbs.cryptography.symmetric.SymmetricKey; | |
40 | import base.util.FileUtil; | |
41 | import base.util.ZipUtil; | |
42 | ||
43 | /** | |
44 | * This class provided methods and utils to assembly a backup. | |
45 | * @author Guido Angelo Ingenito | |
46 | */ | |
47 | 0 | public class BackupArtifactAssembler { |
48 | ||
49 | public static final String ENCRYPTION_DIRECTORY_NAME = "enc"; | |
50 | public static final String DECRYPTION_DIRECTORY_NAME = "dec"; | |
51 | ||
52 | 0 | private static final transient Logger logger = Logger.getLogger(BackupArtifactAssembler.class.getName()); |
53 | ||
54 | 0 | /** |
55 | * This method builds a new signed backup artifact placing it into a temp directory. | |
56 | * The backup building process is fully described in the JDBS analysis and it consists of some phases: | |
57 | * Phase 1: backup files encryption (only in the case of PRIVATE content). | |
58 | * Phase 2: backup info file creation. | |
59 | * Phase 3: backup compression. | |
60 | * Phase 4: backup CRC32 Checksum, MD5 Digest and X509 certificate file creation. | |
61 | * Phase 5: backup asymmetric signature ( the signature is placed on the MD5 Digest file and a new signed file is created ). | |
62 | * @param symmetricKey The symmetric key to use in the encryption process. | |
63 | * @param keyPair The asymmetric key pair to be used during the signing phase. | |
64 | * @param backup The input backup from which the backup artifact must be created. | |
65 | * @return The directory where the backup has been created and that contains the Compressed and Encrypted Backup Artifact and | |
66 | * some info files. This outputted directory reference should be moved to the local JDBS users'repository. | |
67 | * @throws IOException If something wrong happens with the filesystem. | |
68 | */ | |
69 | public static File buildNewBackupArtifact(File repositoryDirectory, SymmetricKey symmetricKey, KeyPair keyPair, Backup backup) throws IOException{ | |
70 | ||
71 | 0 | final String backupArtifactName = backup.getGuId()+"-"+backup.getName(); |
72 | //This is the backup directory under the local Repository | |
73 | 0 | final File backupDirectory = new File(repositoryDirectory,backupArtifactName); |
74 | 0 | backupDirectory.mkdir(); |
75 | 0 | logger.debug("Backup Directory on local Repository: "+ backupDirectory); |
76 | 0 | |
77 | 0 | final File encryptionDir = new File(backupDirectory,ENCRYPTION_DIRECTORY_NAME); |
78 | 0 | final File decryptionDir = new File(backupDirectory,DECRYPTION_DIRECTORY_NAME); |
79 | 0 | |
80 | 0 | logger.debug("Backup Encryption Directory: "+ encryptionDir); |
81 | 0 | encryptionDir.mkdir(); |
82 | 0 | logger.debug("Backup Decryption Directory: "+ decryptionDir); |
83 | 0 | decryptionDir.mkdir(); |
84 | 0 | |
85 | 0 | //Each backups' file must be encrypted preserving the directory structure on the filesystem... |
86 | 0 | logger.debug("Backup's security level: "+backup.getSecurityLevel()); |
87 | 0 | if(backup.getSecurityLevel().equals(SecurityLevel.PRIVATE)){ |
88 | 0 | logger.debug("Symmetric encryption with key: "+symmetricKey.getValue()+"..."); |
89 | 0 | |
90 | 0 | DESSymmetricCipher symmetricCipher = new DESSymmetricCipher(symmetricKey); |
91 | ||
92 | //Here starts the file encryption | |
93 | 0 | for(int i=0;i<backup.getFileDescriptor().length;i++){ |
94 | 0 | File encFile = new File(encryptionDir, backup.getFileDescriptor()[i].getFile().getAbsolutePath()); |
95 | 0 | encFile.getParentFile().mkdirs(); |
96 | 0 | encFile.createNewFile(); |
97 | 0 | symmetricCipher.encrypt(backup.getFileDescriptor()[i].getFile(),encFile); |
98 | } | |
99 | 0 | |
100 | 0 | |
101 | 0 | }else{ |
102 | 0 | logger.debug("Moving backup's files under the decryption folder, backup has PUBLIC content..."); |
103 | 0 | //Here starts the file copy |
104 | 0 | for(int i=0;i<backup.getFileDescriptor().length;i++){ |
105 | 0 | File decFile = new File(decryptionDir, backup.getFileDescriptor()[i].getFile().getAbsolutePath()); |
106 | 0 | decFile.getParentFile().mkdirs(); |
107 | 0 | decFile.createNewFile(); |
108 | 0 | FileUtil.copyFile(backup.getFileDescriptor()[i].getFile(),decFile); |
109 | } | |
110 | ||
111 | 0 | } |
112 | 0 | |
113 | 0 | final File compressedFile; |
114 | 0 | if(backup.getSecurityLevel().equals(SecurityLevel.PRIVATE)){ |
115 | 0 | logger.debug("Backup has PRIVATE content, compressing the encryption directory..."); |
116 | 0 | compressedFile = new File(backupDirectory,backupArtifactName+JDBSConstant.DOTTED_ZIP_EXTENSION); |
117 | 0 | compressedFile.createNewFile(); |
118 | 0 | ZipUtil.zipDirectory(encryptionDir,compressedFile); |
119 | 0 | } |
120 | 0 | else{ |
121 | 0 | logger.debug("Backup has PUBLIC content, compressing the decryption directory..."); |
122 | 0 | compressedFile = new File(backupDirectory,backupArtifactName+JDBSConstant.DOTTED_ZIP_EXTENSION); |
123 | 0 | compressedFile.createNewFile(); |
124 | 0 | ZipUtil.zipDirectory(decryptionDir,compressedFile); |
125 | ||
126 | 0 | } |
127 | 0 | |
128 | 0 | //Here must be stored in xml the informations relative to the backup content... |
129 | 0 | logger.debug("Building the backup's xml info file..."); |
130 | 0 | final File infoFile = new File(backupDirectory,JDBSConstant.XML_INFO_FILE_NAME); |
131 | 0 | writeBackupXmlInfoFile(backup, infoFile); |
132 | ||
133 | 0 | //Making a CRC32 for the compressed backup artifact... |
134 | 0 | logger.debug("Writing backup's CRC32 Checksum..."); |
135 | 0 | final File crc32File = new File(backupDirectory,JDBSConstant.CRC32_FILE_NAME); |
136 | 0 | writeBackupCRC32Checksum(crc32File, compressedFile); |
137 | ||
138 | //Making an MD5 digest for the compressed backup artifact, this will be signed with the users'private key... | |
139 | 0 | logger.debug("Writing backup's MD5 Digest..."); |
140 | 0 | final File md5File = new File(backupDirectory,JDBSConstant.MD5_FILE_NAME); |
141 | 0 | writeBackupMD5Digest(md5File, compressedFile); |
142 | ||
143 | //In each case, PRIVATE or PUBLIC content the backup MD5 must be signed with the privateKey to check integrity and security... | |
144 | 0 | logger.debug("Signing the backup artifact's MD5 digest..."); |
145 | 0 | RSAAsymmetricCipher asymmetricCipher = new RSAAsymmetricCipher(); |
146 | 0 | final File signedDigest = new File(md5File+JDBSConstant.DOTTED_SIGNED_EXTENSION); |
147 | 0 | if(keyPair == null)throw new IllegalArgumentException("AFFF1"); |
148 | 0 | if(keyPair.getPrivateKey() == null)throw new IllegalArgumentException("AFFF2"); |
149 | 0 | |
150 | 0 | asymmetricCipher.sign(md5File, signedDigest,keyPair.getPrivateKey() ); |
151 | ||
152 | 0 | //The keyPair associated certificate must be stored to the output directory... |
153 | 0 | logger.debug("Writing the X509Certificate..."); |
154 | 0 | File certificateFile = new File(backupDirectory,JDBSConstant.CERTIFICATE_FILE_NAME); |
155 | 0 | writeX509Certificate(keyPair.getCertificate(), certificateFile); |
156 | 0 | |
157 | 0 | logger.debug("Encryption Directory Deletion Result: " + FileUtil.deleteDirectory(encryptionDir)); |
158 | 0 | logger.debug("Decryption Directory Deletion Result: " + FileUtil.deleteDirectory(decryptionDir)); |
159 | 0 | |
160 | 0 | logger.debug("Backup artifact successfully created..."); |
161 | 0 | return backupDirectory; |
162 | 0 | } |
163 | 0 | |
164 | 0 | /** |
165 | 0 | * This method writes to a file the info associated to a backup, in xml format. |
166 | 0 | * @param backup The backup whose info must be stored to the output file. |
167 | 0 | * @param outputInfo The outputFile where the info will be stored. |
168 | 0 | */ |
169 | protected static void writeBackupXmlInfoFile(Backup backup, File outputInfo){ | |
170 | 0 | try { |
171 | 0 | Document backupInfoDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); |
172 | 0 | backupInfoDocument.appendChild(backup.toXml(backupInfoDocument)); |
173 | 0 | Transformer transformer = TransformerFactory.newInstance().newTransformer(); |
174 | 0 | DOMSource source = new DOMSource(backupInfoDocument); |
175 | 0 | StreamResult streamResult = new StreamResult(new PrintStream(outputInfo)); |
176 | 0 | transformer.transform(source, streamResult); |
177 | 0 | } catch (Exception ex) { |
178 | 0 | logger.error(ex.getMessage()); |
179 | 0 | ex.printStackTrace(); |
180 | 0 | } |
181 | 0 | } |
182 | 0 | |
183 | 0 | /** |
184 | 0 | * This method writes a CRC32 Checksum to a file. |
185 | 0 | * @param crc32Output The CRC32 Checksum file to be written. |
186 | 0 | * @param compressedBackup The Compressed Backup Artifact from which the CRC32 must be computed. |
187 | 0 | */ |
188 | 0 | protected static void writeBackupCRC32Checksum(File crc32Output, File compressedBackup){ |
189 | 0 | FileWriter fileWriter; |
190 | try { | |
191 | 0 | fileWriter = new FileWriter(crc32Output); |
192 | 0 | String backupCRC32 = FileUtil.createCRC32Checksum(compressedBackup).toString(); |
193 | 0 | logger.debug("File: "+compressedBackup + " CRC32: "+backupCRC32); |
194 | 0 | fileWriter.write(backupCRC32); |
195 | 0 | fileWriter.close(); |
196 | 0 | } catch (IOException ex) { |
197 | 0 | logger.error(ex.getMessage()); |
198 | 0 | ex.printStackTrace(); |
199 | 0 | } |
200 | 0 | } |
201 | 0 | |
202 | 0 | /** |
203 | 0 | * This method writes a MD5 Digest to a file. |
204 | 0 | * @param MD5DigestOutput The MD5 Digest file to be written. |
205 | 0 | * @param compressedBackup The Compressed Backup Artifact from which the CRC32 must be computed. |
206 | 0 | */ |
207 | 0 | protected static void writeBackupMD5Digest(File MD5DigestOutput, File compressedBackup){ |
208 | 0 | FileWriter fileWriter; |
209 | try { | |
210 | 0 | fileWriter = new FileWriter(MD5DigestOutput); |
211 | 0 | String backupMD5Digest = FileUtil.createMD5Digest(compressedBackup); |
212 | 0 | logger.debug("File: "+compressedBackup + " MD5: "+backupMD5Digest); |
213 | 0 | fileWriter.write(backupMD5Digest); |
214 | 0 | fileWriter.close(); |
215 | 0 | } catch (IOException ex) { |
216 | 0 | logger.error(ex.getMessage()); |
217 | 0 | ex.printStackTrace(); |
218 | 0 | } |
219 | 0 | } |
220 | 0 | |
221 | 0 | |
222 | 0 | /** |
223 | 0 | * This method writes to a file an X509Certificate. |
224 | 0 | * @param certificate The certificate that must be saved. |
225 | 0 | * @param certificateFile The output file where the certificate must be stored. |
226 | 0 | */ |
227 | 0 | protected static void writeX509Certificate(java.security.cert.X509Certificate certificate, File certificateFile){ |
228 | FileWriter fileWriter; | |
229 | try { | |
230 | 0 | fileWriter = new FileWriter(certificateFile); |
231 | 0 | logger.debug("Certificate: \n"+ certificate + "\nSaved in file: "+certificateFile); |
232 | 0 | fileWriter.write(certificate.toString()); |
233 | 0 | fileWriter.close(); |
234 | 0 | } catch (IOException ex) { |
235 | 0 | logger.error(ex.getMessage()); |
236 | 0 | ex.printStackTrace(); |
237 | 0 | } |
238 | 0 | } |
239 | 0 | } |
this report was generated by version 1.0.5 of jcoverage. |
copyright © 2003, jcoverage ltd. all rights reserved. |