1 package SnowMailClient.crypto; 2 3 import snow.utils.storage.*; 4 import snow.crypto.*; 5 import snow.Language.Language; 6 7 import java.security.*; 8 import java.security.spec.*; 9 import javax.crypto.spec.*; 10 import javax.crypto.*; 11 import java.io.*; 12 import java.util.zip.*; 13 import java.util.*; 14 import javax.swing.*; 15 16 17 19 public final class FileCipherManager 20 { 21 private static FileCipherManager instance = null; 22 23 private FileCipherManager() 24 { 25 } 26 27 public static FileCipherManager getInstance() 28 { 29 if(instance==null) 30 { 31 instance = new FileCipherManager(); 32 } 33 return instance; 34 } 35 36 37 public void encipherVectorToFile(Vector<Object > v, File out, SecretKey key) throws Exception 38 { 39 encipherVectorWithHeadToFile(new Vector<Object >(), new Vector<Object >(), v, out, key); 40 } 41 42 45 public void encipherVectorWithHeadToFile(Vector<Object > uncipheredHead, Vector<Object > cipheredHead, Vector<Object > v, File out, SecretKey key) throws Exception 46 { 47 48 Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); 49 cipher.init(Cipher.ENCRYPT_MODE, key); 50 51 FileOutputStream fos = null; 52 DataOutputStream dos = null; 53 GZIPOutputStream zos = null; 54 CipherOutputStream cos = null; 55 try 56 { 57 fos = new FileOutputStream(out); 58 dos = new DataOutputStream(fos); 59 dos.writeInt(3); 60 dos.writeUTF("Blowfish"); 61 dos.writeInt(key.getEncoded().length); 62 SecretKeyID ski = SecretKeyUtilities.computeSignature(key); 63 dos.write(ski.signature,0,4); 64 65 cos = new CipherOutputStream(dos, cipher); 66 zos = new GZIPOutputStream(cos); 67 68 DataOutputStream dos2 = new DataOutputStream(zos); 69 VectorUtils.vectorToStream(dos2, cipheredHead); 70 VectorUtils.vectorToStream(dos2, v); 71 72 zos.close(); 73 } 74 catch(Exception e) 75 { 76 throw e; 77 } 78 finally 79 { 80 if(fos!=null) fos.close(); 81 } 82 } 83 84 85 87 public SecretKeyID getKeyIDFromFile(File in) throws Exception 88 { 89 FileInputStream fis = null; 90 DataInputStream dis = null; 91 try 92 { 93 fis = new FileInputStream(in); 94 dis = new DataInputStream(fis); 95 int version = dis.readInt(); 97 if(version==1) 98 { 99 String algo = dis.readUTF(); 100 if(algo.equalsIgnoreCase("Blowfish")) 101 { 102 throw new Exception (Language.translate("Bad encryption algorithm %",algo)); 103 } 104 int keyLength = dis.readInt(); 105 byte[] sign = new byte[4]; 106 dis.readFully(sign,0,4); 107 dis.close(); 108 109 SecretKeyID ski = new SecretKeyID(sign, keyLength); 110 if( keyLength>20 ) 111 { 112 throw new Exception (Language.translate("Bad key length found %",""+keyLength)); 113 } 114 return ski; 115 } 116 else if(version>=2) 117 { 118 String algo = dis.readUTF(); 119 int keyLength = dis.readInt(); 120 byte[] sign = new byte[4]; 121 dis.readFully(sign,0,4); 122 dis.close(); 123 124 SecretKeyID ski = new SecretKeyID(sign, keyLength); 125 return ski; 126 } 127 else 128 { 129 throw new Exception (Language.translate("Bad version %",""+version)); 130 } 131 } 132 catch(Exception e) 133 { 134 throw e; 135 } 136 finally 137 { 138 if(fis!=null) fis.close(); 139 } 140 141 } 142 143 144 146 public Vector<Object > decipherVectorFromFile_ASK_KEY_IF_NEEDED( 147 File file, 148 Object frameOrDialog_owner, 149 String title, String explanation 150 ) throws Exception 151 { 152 153 SecretKeyID keyID = null; 154 try 155 { 156 keyID = this.getKeyIDFromFile(file); 157 } 158 catch(Exception e) 159 { 160 System.out.println("No key for "+file.getAbsolutePath()+" trying old version"); 163 Vector<Object > v = FileUtils.loadVectorFromFile(file); 164 return v; 165 } 166 167 SecretKey sk = SecretKeyManager.getInstance().getKey(keyID); 168 169 if(sk==null) 170 { 171 System.out.println("No keyID for "+file.getAbsolutePath()); 172 173 PassphraseDialog pd = null; 174 if(frameOrDialog_owner instanceof JFrame) 175 { 176 pd = new PassphraseDialog((JFrame) frameOrDialog_owner, title, true, keyID, file, explanation); 177 } 178 else 179 { 180 pd = new PassphraseDialog((JDialog) frameOrDialog_owner, title, true, keyID, file, explanation); 181 } 182 183 if(pd.wasCancelled()) 184 { 185 throw new BadPasswordException(Language.translate("Password not entered")); 186 } 187 188 if(!pd.matchesID()) 189 { 190 throw new BadPasswordException(Language.translate("Bad password")); 191 } 192 193 sk = pd.getKey(); 195 SecretKeyManager.getInstance().addKey(sk); 196 197 } 198 199 try 200 { 201 Vector<Object > v = FileCipherManager.getInstance().decipherVectorFromFile(file, 202 sk); 203 return v; 205 } 206 catch(Exception ee) 207 { 208 throw ee; 209 } 210 } 211 212 213 215 public static Vector<Object > decipherVectorFromFile(File in, SecretKey key) throws Exception 216 { 217 final Vector<Object > v = new Vector<Object >(); 218 final Vector<Object > head = new Vector<Object >(); 219 220 FileInputStream fis = null; 221 DataInputStream dis = null; 222 CipherInputStream cis = null; 223 GZIPInputStream zis = null; 224 225 try 226 { 227 fis = new FileInputStream(in); 228 dis = new DataInputStream(fis); 230 231 int version = dis.readInt(); 234 if(version==1) 235 { 236 String algo = dis.readUTF(); 238 int keyLength = dis.readInt(); 239 byte[] sign = new byte[4]; 240 dis.readFully(sign,0,4); 241 SecretKeyID ski = new SecretKeyID(sign, keyLength); 242 key = SecretKeyManager.getInstance().getDefaultKeyVersion1_(); 243 } 244 else if(version>=2) 245 { 246 String algo = dis.readUTF(); 248 int keyLength = dis.readInt(); 249 byte[] sign = new byte[4]; 250 dis.readFully(sign,0,4); 251 SecretKeyID ski = new SecretKeyID(sign, keyLength); 252 if(!SecretKeyUtilities.computeSignature(key).equals(ski)) 253 { 254 throw new BadPasswordException(Language.translate("Bad key")); 255 } 256 } 257 else 258 { 259 throw new Exception ("Bad file version "+version); 260 } 261 262 265 long t = System.currentTimeMillis(); 266 Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); 267 cipher.init(Cipher.DECRYPT_MODE, key); 268 269 cis = new CipherInputStream(dis, cipher); 270 zis = new GZIPInputStream(cis); 271 DataInputStream dis2 = new DataInputStream(zis); 272 if(version>=3) 273 { 274 VectorUtils.streamToVector(dis2, head); 275 } 277 VectorUtils.streamToVector(dis2, v); 278 279 long t2 = System.currentTimeMillis(); 280 282 283 zis.close(); 284 } 285 catch(Exception e) 286 { 287 throw e; 288 } 289 finally 290 { 291 if(fis!=null) fis.close(); 292 } 293 return v; 294 } 295 296 297 299 public Vector<Object > decipherVectorHeaderFromFile(File in, SecretKey key) throws Exception 300 { 301 final Vector<Object > head = new Vector<Object >(); 302 303 FileInputStream fis = null; 304 DataInputStream dis = null; 305 CipherInputStream cis = null; 306 GZIPInputStream zis = null; 307 308 try 309 { 310 fis = new FileInputStream(in); 311 dis = new DataInputStream(fis); 312 313 int version = dis.readInt(); 316 if(version==1) 317 { 318 String algo = dis.readUTF(); 320 int keyLength = dis.readInt(); 321 byte[] sign = new byte[4]; 322 dis.readFully(sign,0,4); 323 key = SecretKeyManager.getInstance().getDefaultKeyVersion1_(); 325 } 326 else if(version>=2) 327 { 328 String algo = dis.readUTF(); 330 int keyLength = dis.readInt(); 331 byte[] sign = new byte[4]; 332 dis.readFully(sign,0,4); 333 SecretKeyID ski = new SecretKeyID(sign, keyLength); 334 if(!SecretKeyUtilities.computeSignature(key).equals(ski)) 335 { 336 throw new BadPasswordException(Language.translate("Bad key")); 337 } 338 } 339 else 340 { 341 throw new Exception ("Bad file version "+version); 342 } 343 344 347 Cipher cipher = Cipher.getInstance("Blowfish/ECB/PKCS5Padding"); 348 cipher.init(Cipher.DECRYPT_MODE, key); 349 350 cis = new CipherInputStream(dis, cipher); 351 zis = new GZIPInputStream(cis); 352 DataInputStream dis2 = new DataInputStream(zis); 353 if(version>=3) 354 { 355 VectorUtils.streamToVector(dis2, head); 356 } 358 zis.close(); 359 } 360 catch(Exception e) 361 { 362 throw e; 363 } 364 finally 365 { 366 if(fis!=null) fis.close(); 367 } 368 return head; 369 } 370 371 } | Popular Tags |