Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 package org.mozilla.gecko.sync.crypto;
7 import org.mozilla.gecko.background.common.log.Logger;
8 import org.mozilla.gecko.sync.CollectionKeys;
9 import org.mozilla.gecko.sync.CryptoRecord;
11 import android.content.SharedPreferences;
13 public class PersistedCrypto5Keys {
14 public static final String LOG_TAG = "PersistedC5Keys";
16 public static final String CRYPTO5_KEYS_SERVER_RESPONSE_BODY = "crypto5KeysServerResponseBody";
17 public static final String CRYPTO5_KEYS_LAST_MODIFIED = "crypto5KeysLastModified";
19 protected SharedPreferences prefs;
20 protected KeyBundle syncKeyBundle;
22 public PersistedCrypto5Keys(SharedPreferences prefs, KeyBundle syncKeyBundle) {
23 if (syncKeyBundle == null) {
24 throw new IllegalArgumentException("Null syncKeyBundle passed in to PersistedCrypto5Keys constructor.");
25 }
26 this.prefs = prefs;
27 this.syncKeyBundle = syncKeyBundle;
28 }
30 /**
31 * Get persisted crypto/keys.
32 * <p>
33 * crypto/keys is fetched from an encrypted JSON-encoded <code>CryptoRecord</code>.
34 *
35 * @return A <code>CollectionKeys</code> instance or <code>null</code> if none
36 * is currently persisted.
37 */
38 public CollectionKeys keys() {
39 String keysJSON = prefs.getString(CRYPTO5_KEYS_SERVER_RESPONSE_BODY, null);
40 if (keysJSON == null) {
41 return null;
42 }
43 try {
44 CryptoRecord cryptoRecord = CryptoRecord.fromJSONRecord(keysJSON);
45 CollectionKeys keys = new CollectionKeys();
46 keys.setKeyPairsFromWBO(cryptoRecord, syncKeyBundle);
47 return keys;
48 } catch (Exception e) {
49 Logger.warn(LOG_TAG, "Got exception decrypting persisted crypto/keys.", e);
50 return null;
51 }
52 }
54 /**
55 * Persist crypto/keys.
56 * <p>
57 * crypto/keys is stored as an encrypted JSON-encoded <code>CryptoRecord</code>.
58 *
59 * @param keys
60 * The <code>CollectionKeys</code> object to persist, which should
61 * have the same default key bundle as the sync key bundle.
62 */
63 public void persistKeys(CollectionKeys keys) {
64 if (keys == null) {
65 Logger.debug(LOG_TAG, "Clearing persisted crypto/keys.");
66 prefs.edit().remove(CRYPTO5_KEYS_SERVER_RESPONSE_BODY).commit();
67 return;
68 }
69 try {
70 CryptoRecord cryptoRecord = keys.asCryptoRecord();
71 cryptoRecord.keyBundle = syncKeyBundle;
72 cryptoRecord.encrypt();
73 String keysJSON = cryptoRecord.toJSONString();
74 Logger.debug(LOG_TAG, "Persisting crypto/keys.");
75 prefs.edit().putString(CRYPTO5_KEYS_SERVER_RESPONSE_BODY, keysJSON).commit();
76 } catch (Exception e) {
77 Logger.warn(LOG_TAG, "Got exception encrypting while persisting crypto/keys.", e);
78 }
79 }
81 public boolean persistedKeysExist() {
82 return lastModified() > 0;
83 }
85 public long lastModified() {
86 return prefs.getLong(CRYPTO5_KEYS_LAST_MODIFIED, -1);
87 }
89 public void persistLastModified(long lastModified) {
90 if (lastModified <= 0) {
91 Logger.debug(LOG_TAG, "Clearing persisted crypto/keys last modified timestamp.");
92 prefs.edit().remove(CRYPTO5_KEYS_LAST_MODIFIED).commit();
93 return;
94 }
95 Logger.debug(LOG_TAG, "Persisting crypto/keys last modified timestamp " + lastModified + ".");
96 prefs.edit().putLong(CRYPTO5_KEYS_LAST_MODIFIED, lastModified).commit();
97 }
99 public void purge() {
100 persistLastModified(-1);
101 persistKeys(null);
102 }
103 }