]> hydra-www.ietfng.org Git - android-vcpass-oisafe/commitdiff
OI Safe: Implement decrypt routine for file URIs.
authorpeli0101 <peli0101@72b678ce-9140-0410-bee8-679b907dd61a>
Mon, 30 Mar 2009 22:37:30 +0000 (22:37 +0000)
committerpeli0101 <peli0101@72b678ce-9140-0410-bee8-679b907dd61a>
Mon, 30 Mar 2009 22:37:30 +0000 (22:37 +0000)
git-svn-id: http://openintents.googlecode.com/svn/trunk/Safe@2009 72b678ce-9140-0410-bee8-679b907dd61a

src/org/openintents/safe/CryptoHelper.java
src/org/openintents/safe/IntentHandler.java

index dfca0fd352f3f911b7fe22433a59b81187e59d12..51bcca3838ebeada5b37a53ecba75d6be07c3fab 100644 (file)
@@ -575,7 +575,7 @@ public class CryptoHelper {
                        } 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
@@ -666,7 +666,7 @@ public class CryptoHelper {
                        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
@@ -679,83 +679,133 @@ public class CryptoHelper {
      * @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
index a3ad44da6dfb04a0bfdecfa6325710261dae2cd1..685861f070abbfcd9b3ed16be6e0e9ada7fac8c5 100644 (file)
@@ -272,7 +272,7 @@ public class IntentHandler extends Activity {
                        }\r
                        \r
                        if (thisIntent.getData() != null) {\r
-                               // Encrypt file\r
+                               // Encrypt file from file URI\r
                                Uri fileUri = thisIntent.getData();\r
                                \r
                                Uri newFileUri = ch.encryptFileWithSessionKey(getContentResolver(), fileUri);\r
@@ -318,7 +318,15 @@ public class IntentHandler extends Activity {
                                }\r
                                callbackIntent.putExtra(CryptoIntents.EXTRA_TEXT_ARRAY, out);\r
                        }\r
-                       \r
+\r
+                       if (thisIntent.getData() != null) {\r
+                               // Decrypt file from file URI\r
+                               Uri fileUri = thisIntent.getData();\r
+                               \r
+                               Uri newFileUri = ch.decryptFileWithSessionKey(getContentResolver(), fileUri);\r
+                               \r
+                               callbackIntent.setData(newFileUri);\r
+                       }\r
                        // Support for binary fields could be added here (like images?)\r
                        \r
                        callbackResult = RESULT_OK;\r