} else {\r
is = contentResolver.openInputStream(fileUri);\r
outputPath = Environment\r
- .getExternalStorageDirectory().toString() + "/test.abc";\r
+ .getExternalStorageDirectory().toString() + "/tmp.oisafe";\r
}\r
\r
FileOutputStream os = new FileOutputStream(outputPath);\r
Log.e(TAG, "IO Exception", e);\r
}\r
\r
- return Uri.parse("file://" + outputPath);\r
+ return Uri.parse("file://" + outputPath); // TODO: UUEncode\r
}\r
\r
/**\r
* @return decrypted String\r
* @throws Exception\r
*/\r
- public Uri decryptFileWithSessionKey(Uri fileUri) throws CryptoHelperException {\r
- /*\r
+ public Uri decryptFileWithSessionKey(ContentResolver contentResolver, Uri fileUri) throws CryptoHelperException {\r
+ Log.d(TAG, "decryptFileWithSessionKey");\r
status=false; // assume failure\r
if(password == null) {\r
String msg = "Must call setPassword before running decrypt.";\r
throw new CryptoHelperException(msg);\r
}\r
- \r
- if ((ciphertext==null) || (ciphertext=="")) {\r
- return "";\r
- }\r
- String cipherVersion = null;\r
- String cipherSessionKey = null;\r
- \r
- // Split cipher into session key and text\r
+\r
+ String outputPath = "";\r
try {\r
- cipherVersion = ciphertext.substring(0,1);\r
- if (cipherVersion.equals("A")) {\r
- cipherSessionKey = ciphertext.substring(1,97); // 64 if init(128) had been chosen\r
- ciphertext = ciphertext.substring(97);\r
+ InputStream is;\r
+ if (fileUri.getScheme().equals("file")) {\r
+ is = new java.io.FileInputStream(fileUri.getPath());\r
+ String encryptedFile = fileUri.getPath();\r
+ outputPath = fileUri.getPath() + ".decrypted";\r
+ if (encryptedFile.endsWith(".oisafe")) {\r
+ outputPath = encryptedFile.substring(0, encryptedFile.length() - 7);\r
+ }\r
+ Log.d(TAG, "Decrypt: Input from " + fileUri.getPath());\r
+ Log.d(TAG, "Decrypt: Output to " + outputPath);\r
} else {\r
- Log.e(TAG, "Unknown cipher version" + cipherVersion);\r
- return "";\r
+ is = contentResolver.openInputStream(fileUri);\r
+ outputPath = Environment\r
+ .getExternalStorageDirectory().toString() + "/tmp.decrypted";\r
}\r
- } catch (IndexOutOfBoundsException e) {\r
- Log.e(TAG, "Invalid ciphertext (with session key)");\r
- return "";\r
- }\r
- \r
- // Decrypt the session key\r
- byte[] byteCipherSessionKey=hexStringToBytes(cipherSessionKey);\r
- byte[] byteSessionKey = {};\r
- \r
- try {\r
- pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);\r
- byteSessionKey = pbeCipher.doFinal(byteCipherSessionKey);\r
- status=true;\r
- } catch (IllegalBlockSizeException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- } catch (BadPaddingException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- } catch (InvalidKeyException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- } catch (InvalidAlgorithmParameterException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- }\r
-\r
- // Convert the session key into a Pbe key\r
- String stringSessionKey = new String(byteSessionKey);\r
- PBEKeySpec sessionPbeKeySpec = new PBEKeySpec(stringSessionKey.toCharArray());\r
- SecretKey sessionPbeKey = null;\r
- try {\r
- sessionPbeKey = keyFac.generateSecret(sessionPbeKeySpec);\r
- } catch (InvalidKeySpecException e) {\r
- Log.e(TAG,"setPassword(): "+e.toString());\r
- }\r
-\r
- // Use the session key to decrypt the text\r
- byte[] byteCiphertext=hexStringToBytes(ciphertext);\r
- byte[] plaintext = {};\r
- \r
- try {\r
- pbeCipher.init(Cipher.DECRYPT_MODE, sessionPbeKey, pbeParamSpec);\r
- plaintext = pbeCipher.doFinal(byteCiphertext);\r
- status=true;\r
- } catch (IllegalBlockSizeException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- } catch (BadPaddingException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- } catch (InvalidKeyException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
- } catch (InvalidAlgorithmParameterException e) {\r
- Log.e(TAG,"decrypt(): "+e.toString());\r
+ \r
+ FileOutputStream os = new FileOutputStream(outputPath);\r
+ \r
+ int numReadTotal = 0;\r
+ int numRead = 0;\r
+ \r
+ byte[] byteCipherVersion = new byte[1];\r
+ while ((numRead = is.read(byteCipherVersion, numRead, \r
+ byteCipherVersion.length - numRead)) >= 0\r
+ && numReadTotal < byteCipherVersion.length) {\r
+ Log.d(TAG, "read bytes: " + numRead);\r
+ numReadTotal += numRead;\r
+ }\r
+ String cipherVersion = new String(byteCipherVersion);\r
+ \r
+ byte[] byteCipherSessionKey = null;\r
+ \r
+ // Split cipher into session key and text\r
+ try {\r
+ Log.d(TAG, "cipherVersion : " + cipherVersion);\r
+ if (cipherVersion.equals("A")) {\r
+ \r
+ numRead = 0;\r
+ numReadTotal = 0;\r
+ byteCipherSessionKey = new byte[48];\r
+ // Read the first few bytes that contain the encrypted key\r
+ while ((numRead = is.read(byteCipherSessionKey, numRead, \r
+ byteCipherSessionKey.length - numRead)) >= 0\r
+ && numReadTotal < byteCipherSessionKey.length) {\r
+ Log.d(TAG, "read bytes sessionKey: " + numRead);\r
+ numReadTotal += numRead;\r
+ }\r
+ } else {\r
+ Log.e(TAG, "Unknown cipher version" + cipherVersion);\r
+ return null;\r
+ }\r
+ } catch (IndexOutOfBoundsException e) {\r
+ Log.e(TAG, "Invalid ciphertext (with session key)");\r
+ return null;\r
+ }\r
+ \r
+ // Decrypt the session key\r
+ byte[] byteSessionKey = {};\r
+ \r
+ try {\r
+ pbeCipher.init(Cipher.DECRYPT_MODE, pbeKey, pbeParamSpec);\r
+ byteSessionKey = pbeCipher.doFinal(byteCipherSessionKey);\r
+ status=true;\r
+ } catch (IllegalBlockSizeException e) {\r
+ Log.e(TAG,"decrypt(): "+e.toString());\r
+ } catch (BadPaddingException e) {\r
+ Log.e(TAG,"decrypt(): "+e.toString());\r
+ } catch (InvalidKeyException e) {\r
+ Log.e(TAG,"decrypt(): "+e.toString());\r
+ } catch (InvalidAlgorithmParameterException e) {\r
+ Log.e(TAG,"decrypt(): "+e.toString());\r
+ }\r
+ \r
+ // Now decrypt the message\r
+ Trivium tri = new Trivium();\r
+ try {\r
+ tri.setupKey(Trivium.MODE_DECRYPT,\r
+ byteSessionKey, 0);\r
+ tri.setupNonce(byteSessionKey, 10);\r
+ \r
+ // Create the byte array to hold the data\r
+ final int bytesLen = 4096; // buffer length\r
+ byte[] bytesIn = new byte[bytesLen];\r
+ byte[] bytesOut = new byte[bytesLen];\r
+ \r
+ int offset = 0;\r
+ numRead = 0;\r
+ while ((numRead = is.read(bytesIn, 0, bytesLen)) >= 0) {\r
+ if ((numRead | 3) != 0) {\r
+ Log.d(TAG, "Bytes read is inappropriate number: " + numRead);\r
+ }\r
+ \r
+ tri.process(bytesIn, 0,\r
+ bytesOut, 0, numRead);\r
+ \r
+ os.write(bytesOut, 0, numRead);\r
+ offset += numRead;\r
+ }\r
+ \r
+ // Ensure all the bytes have been read in\r
+ if (offset < is.available()) {\r
+ throw new IOException("Could not completely read file ");\r
+ }\r
+ \r
+ // Close the input stream and return bytes\r
+ is.close();\r
+ os.close();\r
+ \r
+ } catch (ESJException e) {\r
+ Log.e(TAG, "Error encrypting file", e);\r
+ }\r
+ \r
+ } catch (FileNotFoundException e) {\r
+ Log.e(TAG, "File not found", e);\r
+ } catch (IOException e) {\r
+ Log.e(TAG, "IOException", e);\r
}\r
- \r
- return new String(plaintext);\r
- */\r
- return null;\r
+ return Uri.parse("file://" + outputPath); // TODO: UUEncode\r
}\r
}\r