From: rmceoin Date: Sun, 5 Apr 2009 02:31:57 +0000 (+0000) Subject: OI Safe: updated decrypt intent and content provider X-Git-Url: https://hydra-www.ietfng.org/gitweb/?a=commitdiff_plain;h=9d106e482ec24b8a8b9e1333b3defa023090f576;p=android-vcpass-oisafe OI Safe: updated decrypt intent and content provider git-svn-id: http://openintents.googlecode.com/svn/trunk/Safe@2016 72b678ce-9140-0410-bee8-679b907dd61a --- diff --git a/AndroidManifest.xml b/AndroidManifest.xml index dfa25e0..d752829 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -33,7 +33,7 @@ android:resource="@raw/license_short" /> - + diff --git a/src/org/openintents/safe/CryptoContentProvider.java b/src/org/openintents/safe/CryptoContentProvider.java index a519ec8..4211729 100644 --- a/src/org/openintents/safe/CryptoContentProvider.java +++ b/src/org/openintents/safe/CryptoContentProvider.java @@ -5,18 +5,34 @@ import java.io.FileNotFoundException; import android.content.ContentProvider; import android.content.ContentValues; +import android.content.UriMatcher; import android.database.Cursor; -import android.database.MatrixCursor; import android.net.Uri; import android.os.ParcelFileDescriptor; -import android.provider.MediaStore.Images; +import android.util.Log; public class CryptoContentProvider extends ContentProvider { - private static final String MIME_TYPE_PREFIX = "content://org.openintents.safe/decrypted/"; + private static final boolean debug = true; private static final String TAG = "CryptoContentProvider"; + public static final String AUTHORITY = "org.openintents.safe"; + public static final Uri CONTENT_URI + =Uri.parse("content://"+AUTHORITY); + + public static final String SESSION_FILE = "session"; + + private static final int ENCRYPT_ID = 2; + private static final int DECRYPT_ID = 3; + + private static final UriMatcher sUriMatcher; + static { + sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + sUriMatcher.addURI(AUTHORITY, "encrypt/*", ENCRYPT_ID); + sUriMatcher.addURI(AUTHORITY, "decrypt/*", DECRYPT_ID); + } + @Override public boolean onCreate() { return true; @@ -62,18 +78,50 @@ public class CryptoContentProvider extends ContentProvider { @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { - if (uri.toString().startsWith( - MIME_TYPE_PREFIX)) { - int m = ParcelFileDescriptor.MODE_READ_ONLY; - if (mode.equalsIgnoreCase("rw")) - m = ParcelFileDescriptor.MODE_READ_WRITE; - - File f = new File(uri.toString().substring(20 + AUTHORITY.length())); - ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, m); - return pfd; - } else { - throw new RuntimeException("Unsupported uri"); + if (debug) Log.d(TAG,"openFile("+uri.toString()+","+mode+")"); + + ParcelFileDescriptor pfd = null; + try { + String filesDir=getContext().getFilesDir().toString(); + if (debug) Log.d(TAG,"openFile: filesDir="+filesDir); + + String path=filesDir; + String cryptSession; + String sessionFile; + int modeBits = 0; + switch (sUriMatcher.match(uri)) { + case ENCRYPT_ID: + if (debug) Log.d(TAG,"openFile: ENCRYPT"); + modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY | + ParcelFileDescriptor.MODE_CREATE; + cryptSession = uri.getPathSegments().get(1); + sessionFile=SESSION_FILE+"."+cryptSession; + path += "/"+sessionFile; + break; + case DECRYPT_ID: + if (debug) Log.d(TAG,"openFile: DECRYPT"); + modeBits = ParcelFileDescriptor.MODE_READ_ONLY; + cryptSession = uri.getPathSegments().get(1); + sessionFile=SESSION_FILE+"."+cryptSession; + path += "/"+sessionFile; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + + if (debug) Log.d(TAG,"openFile: path="+path); + pfd=ParcelFileDescriptor.open(new File(path), modeBits); + if (!getContext().deleteFile(sessionFile)) { + Log.e(TAG,"openFile: unable to delete: "+sessionFile); + } + } catch (FileNotFoundException e) { + if (debug) Log.d(TAG,"openFile: FileNotFound"); + throw e; + } catch (IllegalArgumentException e) { + throw e; } + + return pfd; } @Override diff --git a/src/org/openintents/safe/CryptoHelper.java b/src/org/openintents/safe/CryptoHelper.java index 1d289b5..c986816 100644 --- a/src/org/openintents/safe/CryptoHelper.java +++ b/src/org/openintents/safe/CryptoHelper.java @@ -44,6 +44,7 @@ import javax.crypto.spec.PBEParameterSpec; import org.openintents.util.SecureDelete; import android.content.ContentResolver; +import android.content.Context; import android.net.Uri; import android.os.Environment; import android.util.Log; @@ -63,7 +64,7 @@ import estreamj.framework.ESJException; */ public class CryptoHelper { - private static final boolean debug = false; + private static final boolean debug = true; private static String TAG = "CryptoHelper"; protected static PBEKeySpec pbeKeySpec; protected static PBEParameterSpec pbeParamSpec; @@ -684,33 +685,39 @@ public class CryptoHelper { * @return decrypted String * @throws Exception */ - public Uri decryptFileWithSessionKey(ContentResolver contentResolver, Uri fileUri) throws CryptoHelperException { + public Uri decryptFileWithSessionKey(Context ctx, ContentResolver contentResolver, Uri fileUri) throws CryptoHelperException { Log.d(TAG, "decryptFileWithSessionKey"); + Log.d(TAG, "fileUri="+fileUri.toString()); status=false; // assume failure if(password == null) { String msg = "Must call setPassword before running decrypt."; throw new CryptoHelperException(msg); } - String outputPath = ""; + String decryptSession; + try { + decryptSession=generateSalt(); + } catch (NoSuchAlgorithmException e1) { + e1.printStackTrace(); + String msg = "Decrypt error: "+e1.getLocalizedMessage(); + throw new CryptoHelperException(msg); + } + String outputFile = ""; try { InputStream is; if (fileUri.getScheme().equals("file")) { is = new java.io.FileInputStream(fileUri.getPath()); - String encryptedFile = fileUri.getPath(); - outputPath = fileUri.getPath() + ".decrypted"; - if (encryptedFile.endsWith(".oisafe")) { - outputPath = encryptedFile.substring(0, encryptedFile.length() - 7); - } - Log.d(TAG, "Decrypt: Input from " + fileUri.getPath()); - Log.d(TAG, "Decrypt: Output to " + outputPath); + if (debug) Log.d(TAG, "Decrypt: Input from " + fileUri.getPath()); } else { is = contentResolver.openInputStream(fileUri); - outputPath = Environment - .getExternalStorageDirectory().toString() + "/tmp.decrypted"; + if (debug) Log.d(TAG, "Decrypt: Input from " + fileUri.toString()); } - - FileOutputStream os = new FileOutputStream(outputPath); + outputFile = CryptoContentProvider.SESSION_FILE+"."+decryptSession; + if (debug) Log.d(TAG, "Decrypt: Output to " + outputFile); + String cache=Environment.getDownloadCacheDirectory().getAbsolutePath(); + if (debug) Log.d(TAG, "Decrypt: cache=" + cache); + FileOutputStream os = ctx.openFileOutput(outputFile, + Context.MODE_PRIVATE); int numReadTotal = 0; int numRead = 0; @@ -719,7 +726,7 @@ public class CryptoHelper { while ((numRead = is.read(byteCipherVersion, numRead, byteCipherVersion.length - numRead)) >= 0 && numReadTotal < byteCipherVersion.length) { - Log.d(TAG, "read bytes: " + numRead); + if (debug) Log.d(TAG, "read bytes: " + numRead); numReadTotal += numRead; } String cipherVersion = new String(byteCipherVersion); @@ -728,7 +735,7 @@ public class CryptoHelper { // Split cipher into session key and text try { - Log.d(TAG, "cipherVersion : " + cipherVersion); + if (debug) Log.d(TAG, "cipherVersion : " + cipherVersion); if (cipherVersion.equals("A")) { numRead = 0; @@ -738,7 +745,7 @@ public class CryptoHelper { while ((numRead = is.read(byteCipherSessionKey, numRead, byteCipherSessionKey.length - numRead)) >= 0 && numReadTotal < byteCipherSessionKey.length) { - Log.d(TAG, "read bytes sessionKey: " + numRead); + if (debug) Log.d(TAG, "read bytes sessionKey: " + numRead); numReadTotal += numRead; } } else { @@ -783,7 +790,7 @@ public class CryptoHelper { numRead = 0; while ((numRead = is.read(bytesIn, 0, bytesLen)) >= 0) { if ((numRead & 3) != 0) { - Log.d(TAG, "Bytes read is inappropriate number: " + numRead); + if (debug) Log.d(TAG, "Bytes read is inappropriate number: " + numRead); } tri.process(bytesIn, 0, @@ -803,7 +810,7 @@ public class CryptoHelper { os.close(); // Securely delete the original file: - SecureDelete.delete(new File(fileUri.getPath())); +// SecureDelete.delete(new File(fileUri.getPath())); } catch (ESJException e) { Log.e(TAG, "Error encrypting file", e); @@ -814,6 +821,8 @@ public class CryptoHelper { } catch (IOException e) { Log.e(TAG, "IOException", e); } - return Uri.parse("file://" + outputPath); // TODO: UUEncode +// return Uri.parse("file://" + outputPath); // TODO: UUEncode + Uri uri=Uri.withAppendedPath(CryptoContentProvider.CONTENT_URI, "decrypt/" + decryptSession); + return uri; } } diff --git a/src/org/openintents/safe/IntentHandler.java b/src/org/openintents/safe/IntentHandler.java index 685861f..8b56a01 100644 --- a/src/org/openintents/safe/IntentHandler.java +++ b/src/org/openintents/safe/IntentHandler.java @@ -323,7 +323,7 @@ public class IntentHandler extends Activity { // Decrypt file from file URI Uri fileUri = thisIntent.getData(); - Uri newFileUri = ch.decryptFileWithSessionKey(getContentResolver(), fileUri); + Uri newFileUri = ch.decryptFileWithSessionKey(this,getContentResolver(), fileUri); callbackIntent.setData(newFileUri); }