Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | package org.mozilla.gecko.tests; |
michael@0 | 2 | |
michael@0 | 3 | import java.io.File; |
michael@0 | 4 | |
michael@0 | 5 | import org.json.JSONObject; |
michael@0 | 6 | import org.mozilla.gecko.NSSBridge; |
michael@0 | 7 | import org.mozilla.gecko.db.BrowserContract; |
michael@0 | 8 | |
michael@0 | 9 | import android.content.ContentResolver; |
michael@0 | 10 | import android.content.ContentValues; |
michael@0 | 11 | import android.content.Context; |
michael@0 | 12 | import android.database.Cursor; |
michael@0 | 13 | import android.net.Uri; |
michael@0 | 14 | |
michael@0 | 15 | public class testPasswordEncrypt extends BaseTest { |
michael@0 | 16 | public void testPasswordEncrypt() { |
michael@0 | 17 | Context context = (Context)getActivity(); |
michael@0 | 18 | ContentResolver cr = context.getContentResolver(); |
michael@0 | 19 | mAsserter.isnot(cr, null, "Found a content resolver"); |
michael@0 | 20 | ContentValues cvs = new ContentValues(); |
michael@0 | 21 | |
michael@0 | 22 | blockForGeckoReady(); |
michael@0 | 23 | |
michael@0 | 24 | File db = new File(mProfile, "signons.sqlite"); |
michael@0 | 25 | String dbPath = db.getPath(); |
michael@0 | 26 | |
michael@0 | 27 | Uri passwordUri; |
michael@0 | 28 | cvs.put("hostname", "http://www.example.com"); |
michael@0 | 29 | cvs.put("encryptedUsername", "username"); |
michael@0 | 30 | cvs.put("encryptedPassword", "password"); |
michael@0 | 31 | |
michael@0 | 32 | // Attempt to insert into the db |
michael@0 | 33 | passwordUri = BrowserContract.Passwords.CONTENT_URI; |
michael@0 | 34 | Uri.Builder builder = passwordUri.buildUpon(); |
michael@0 | 35 | passwordUri = builder.appendQueryParameter("profilePath", mProfile).build(); |
michael@0 | 36 | |
michael@0 | 37 | Uri uri = cr.insert(passwordUri, cvs); |
michael@0 | 38 | Uri expectedUri = passwordUri.buildUpon().appendPath("1").build(); |
michael@0 | 39 | mAsserter.is(uri.toString(), expectedUri.toString(), "Insert returned correct uri"); |
michael@0 | 40 | |
michael@0 | 41 | Cursor list = mActions.querySql(dbPath, "SELECT encryptedUsername FROM moz_logins"); |
michael@0 | 42 | list.moveToFirst(); |
michael@0 | 43 | String decryptedU = null; |
michael@0 | 44 | try { |
michael@0 | 45 | decryptedU = NSSBridge.decrypt(context, mProfile, list.getString(0)); |
michael@0 | 46 | } catch (Exception e) { |
michael@0 | 47 | mAsserter.ok(false, "NSSBridge.decrypt through Exception " + e, ""); // TODO: What is diag? |
michael@0 | 48 | } |
michael@0 | 49 | mAsserter.is(decryptedU, "username", "Username was encrypted correctly when inserting"); |
michael@0 | 50 | |
michael@0 | 51 | list = mActions.querySql(dbPath, "SELECT encryptedPassword, encType FROM moz_logins"); |
michael@0 | 52 | list.moveToFirst(); |
michael@0 | 53 | String decryptedP = null; |
michael@0 | 54 | try { |
michael@0 | 55 | decryptedP = NSSBridge.decrypt(context, mProfile, list.getString(0)); |
michael@0 | 56 | } catch (Exception e) { |
michael@0 | 57 | mAsserter.ok(false, "NSSBridge.decrypt through Exception " + e, ""); // TODO: What is diag? |
michael@0 | 58 | } |
michael@0 | 59 | mAsserter.is(decryptedP, "password", "Password was encrypted correctly when inserting"); |
michael@0 | 60 | mAsserter.is(list.getInt(1), 1, "Password has correct encryption type"); |
michael@0 | 61 | |
michael@0 | 62 | cvs.put("encryptedUsername", "username2"); |
michael@0 | 63 | cvs.put("encryptedPassword", "password2"); |
michael@0 | 64 | cr.update(passwordUri, cvs, null, null); |
michael@0 | 65 | |
michael@0 | 66 | list = mActions.querySql(dbPath, "SELECT encryptedUsername FROM moz_logins"); |
michael@0 | 67 | list.moveToFirst(); |
michael@0 | 68 | try { |
michael@0 | 69 | decryptedU = NSSBridge.decrypt(context, mProfile, list.getString(0)); |
michael@0 | 70 | } catch (Exception e) { |
michael@0 | 71 | mAsserter.ok(false, "NSSBridge.decrypt through Exception " + e, ""); // TODO: What is diag? |
michael@0 | 72 | } |
michael@0 | 73 | mAsserter.is(decryptedU, "username2", "Username was encrypted when updating"); |
michael@0 | 74 | |
michael@0 | 75 | list = mActions.querySql(dbPath, "SELECT encryptedPassword FROM moz_logins"); |
michael@0 | 76 | list.moveToFirst(); |
michael@0 | 77 | try { |
michael@0 | 78 | decryptedP = NSSBridge.decrypt(context, mProfile, list.getString(0)); |
michael@0 | 79 | } catch (Exception e) { |
michael@0 | 80 | mAsserter.ok(false, "NSSBridge.decrypt through Exception " + e, ""); // TODO: What is diag? |
michael@0 | 81 | } |
michael@0 | 82 | mAsserter.is(decryptedP, "password2", "Password was encrypted when updating"); |
michael@0 | 83 | |
michael@0 | 84 | // Trying to store a password while master password is enabled should throw, |
michael@0 | 85 | // but because Android can't send Exceptions across processes |
michael@0 | 86 | // it just results in a null uri/cursor being returned. |
michael@0 | 87 | toggleMasterPassword("password"); |
michael@0 | 88 | try { |
michael@0 | 89 | uri = cr.insert(passwordUri, cvs); |
michael@0 | 90 | // TODO: restore this assertion -- see bug 764901 |
michael@0 | 91 | // mAsserter.is(uri, null, "Storing a password while MP was set should fail"); |
michael@0 | 92 | |
michael@0 | 93 | Cursor c = cr.query(passwordUri, null, null, null, null); |
michael@0 | 94 | // TODO: restore this assertion -- see bug 764901 |
michael@0 | 95 | // mAsserter.is(c, null, "Querying passwords while MP was set should fail"); |
michael@0 | 96 | } catch (Exception ex) { |
michael@0 | 97 | // Password provider currently can not throw across process |
michael@0 | 98 | // so we should not catch this exception here |
michael@0 | 99 | mAsserter.ok(false, "Caught exception", ex.toString()); |
michael@0 | 100 | } |
michael@0 | 101 | toggleMasterPassword("password"); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | private void toggleMasterPassword(String passwd) { |
michael@0 | 105 | JSONObject jsonPref = new JSONObject(); |
michael@0 | 106 | try { |
michael@0 | 107 | jsonPref.put("name", "privacy.masterpassword.enabled"); |
michael@0 | 108 | jsonPref.put("type", "string"); |
michael@0 | 109 | jsonPref.put("value", passwd); |
michael@0 | 110 | setPreferenceAndWaitForChange(jsonPref); |
michael@0 | 111 | } catch (Exception ex) { |
michael@0 | 112 | mAsserter.ok(false, "exception in toggleMasterPassword", ex.toString()); |
michael@0 | 113 | } |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | @Override |
michael@0 | 117 | public void tearDown() throws Exception { |
michael@0 | 118 | // remove the entire signons.sqlite file |
michael@0 | 119 | File profile = new File(mProfile); |
michael@0 | 120 | File db = new File(profile, "signons.sqlite"); |
michael@0 | 121 | if (db.delete()) { |
michael@0 | 122 | mAsserter.dumpLog("tearDown deleted "+db.toString()); |
michael@0 | 123 | } else { |
michael@0 | 124 | mAsserter.dumpLog("tearDown did not delete "+db.toString()); |
michael@0 | 125 | } |
michael@0 | 126 | |
michael@0 | 127 | super.tearDown(); |
michael@0 | 128 | } |
michael@0 | 129 | } |