зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1436271 - Replace calls to String.getBytes(String) with String.getBytes(Charset). r=nalexander
Also replace calls to String(byte[], String) with String(byte[], Charset). This removes some cannot-happen exception handling.
This commit is contained in:
Родитель
f1f556eac0
Коммит
80f292e771
|
@ -14,6 +14,7 @@ import org.mozilla.gecko.AppConstants;
|
||||||
import org.mozilla.gecko.dlc.catalog.DownloadContent;
|
import org.mozilla.gecko.dlc.catalog.DownloadContent;
|
||||||
import org.mozilla.gecko.dlc.catalog.DownloadContentBuilder;
|
import org.mozilla.gecko.dlc.catalog.DownloadContentBuilder;
|
||||||
import org.mozilla.gecko.dlc.catalog.DownloadContentCatalog;
|
import org.mozilla.gecko.dlc.catalog.DownloadContentCatalog;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
@ -223,7 +224,7 @@ public class TestDownloadAction {
|
||||||
verify(connection).getInputStream();
|
verify(connection).getInputStream();
|
||||||
verify(connection).setRequestProperty("Range", "bytes=1337-");
|
verify(connection).setRequestProperty("Range", "bytes=1337-");
|
||||||
|
|
||||||
Assert.assertEquals("HelloWorld", new String(outputStream.toByteArray(), "UTF-8"));
|
Assert.assertEquals("HelloWorld", new String(outputStream.toByteArray(), StringUtils.UTF_8));
|
||||||
|
|
||||||
verify(action).openFile(eq(temporaryFile), eq(true));
|
verify(action).openFile(eq(temporaryFile), eq(true));
|
||||||
verify(catalog).markAsDownloaded(content);
|
verify(catalog).markAsDownloaded(content);
|
||||||
|
@ -635,7 +636,7 @@ public class TestDownloadAction {
|
||||||
HttpURLConnection connection = mock(HttpURLConnection.class);
|
HttpURLConnection connection = mock(HttpURLConnection.class);
|
||||||
|
|
||||||
doReturn(statusCode).when(connection).getResponseCode();
|
doReturn(statusCode).when(connection).getResponseCode();
|
||||||
doReturn(new ByteArrayInputStream(content.getBytes("UTF-8"))).when(connection).getInputStream();
|
doReturn(new ByteArrayInputStream(content.getBytes(StringUtils.UTF_8))).when(connection).getInputStream();
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mozilla.gecko.AppConstants;
|
import org.mozilla.gecko.AppConstants;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -37,7 +38,7 @@ public class TestDownloadContentCatalog {
|
||||||
@Test
|
@Test
|
||||||
public void testUntouchedCatalogHasNotChangedAndWillNotBePersisted() throws Exception {
|
public void testUntouchedCatalogHasNotChangedAndWillNotBePersisted() throws Exception {
|
||||||
AtomicFile file = mock(AtomicFile.class);
|
AtomicFile file = mock(AtomicFile.class);
|
||||||
doReturn("{content:[]}".getBytes("UTF-8")).when(file).readFully();
|
doReturn("{content:[]}".getBytes(StringUtils.UTF_8)).when(file).readFully();
|
||||||
|
|
||||||
DownloadContentCatalog catalog = spy(new DownloadContentCatalog(file));
|
DownloadContentCatalog catalog = spy(new DownloadContentCatalog(file));
|
||||||
catalog.loadFromDisk();
|
catalog.loadFromDisk();
|
||||||
|
|
|
@ -7,6 +7,7 @@ import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -57,7 +58,7 @@ public class TestPushState {
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
try {
|
try {
|
||||||
fos = new FileOutputStream(file);
|
fos = new FileOutputStream(file);
|
||||||
fos.write("}".getBytes("UTF-8"));
|
fos.write("}".getBytes(StringUtils.UTF_8));
|
||||||
} finally {
|
} finally {
|
||||||
if (fos != null) {
|
if (fos != null) {
|
||||||
fos.close();
|
fos.close();
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.mozilla.gecko.sync.SynchronizerConfiguration;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
||||||
import org.mozilla.gecko.util.FileUtils;
|
import org.mozilla.gecko.util.FileUtils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import static org.mozilla.gecko.db.DBUtils.qualifyColumn;
|
import static org.mozilla.gecko.db.DBUtils.qualifyColumn;
|
||||||
|
|
||||||
|
@ -1782,18 +1783,13 @@ public class BrowserDatabaseHelper extends SQLiteOpenHelper {
|
||||||
@RobocopTarget
|
@RobocopTarget
|
||||||
public static String getReaderCacheFileNameForURL(String url) {
|
public static String getReaderCacheFileNameForURL(String url) {
|
||||||
try {
|
try {
|
||||||
// On KitKat and above we can use java.nio.charset.StandardCharsets.UTF_8 in place of "UTF8"
|
byte[] utf8 = url.getBytes(StringUtils.UTF_8);
|
||||||
// which avoids having to handle UnsupportedCodingException
|
|
||||||
byte[] utf8 = url.getBytes("UTF8");
|
|
||||||
|
|
||||||
final MessageDigest digester = MessageDigest.getInstance("MD5");
|
final MessageDigest digester = MessageDigest.getInstance("MD5");
|
||||||
byte[] hash = digester.digest(utf8);
|
byte[] hash = digester.digest(utf8);
|
||||||
|
|
||||||
final String hashString = new Base32().encodeAsString(hash);
|
final String hashString = new Base32().encodeAsString(hash);
|
||||||
return hashString.substring(0, hashString.indexOf('=')) + ".json";
|
return hashString.substring(0, hashString.indexOf('=')) + ".json";
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
// This should never happen
|
|
||||||
throw new IllegalStateException("UTF8 encoding not available - can't process readercache filename");
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// This should also never happen
|
// This should also never happen
|
||||||
throw new IllegalStateException("MD5 digester unavailable - can't process readercache filename");
|
throw new IllegalStateException("MD5 digester unavailable - can't process readercache filename");
|
||||||
|
|
|
@ -498,7 +498,7 @@ public class LoginsProvider extends SharedBrowserDatabaseProvider {
|
||||||
private String encrypt(@NonNull String initialValue) {
|
private String encrypt(@NonNull String initialValue) {
|
||||||
try {
|
try {
|
||||||
final Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
|
final Cipher cipher = getCipher(Cipher.ENCRYPT_MODE);
|
||||||
return Base64.encodeToString(cipher.doFinal(initialValue.getBytes("UTF-8")), Base64.URL_SAFE);
|
return Base64.encodeToString(cipher.doFinal(initialValue.getBytes(StringUtils.UTF_8)), Base64.URL_SAFE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
debug("encryption failed : " + e);
|
debug("encryption failed : " + e);
|
||||||
throw new IllegalStateException("Logins encryption failed", e);
|
throw new IllegalStateException("Logins encryption failed", e);
|
||||||
|
@ -509,7 +509,7 @@ public class LoginsProvider extends SharedBrowserDatabaseProvider {
|
||||||
try {
|
try {
|
||||||
final Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
|
final Cipher cipher = getCipher(Cipher.DECRYPT_MODE);
|
||||||
return new String(cipher.doFinal(Base64.decode(
|
return new String(cipher.doFinal(Base64.decode(
|
||||||
initialValue.getBytes("UTF-8"), Base64.URL_SAFE)), StringUtils.UTF_8);
|
initialValue.getBytes(StringUtils.UTF_8), Base64.URL_SAFE)), StringUtils.UTF_8);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
debug("Decryption failed : " + e);
|
debug("Decryption failed : " + e);
|
||||||
throw new IllegalStateException("Logins decryption failed", e);
|
throw new IllegalStateException("Logins decryption failed", e);
|
||||||
|
|
|
@ -14,12 +14,12 @@ import android.util.Log;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ public class DownloadContentCatalog {
|
||||||
JSONObject catalog;
|
JSONObject catalog;
|
||||||
|
|
||||||
synchronized (file) {
|
synchronized (file) {
|
||||||
catalog = new JSONObject(new String(file.readFully(), "UTF-8"));
|
catalog = new JSONObject(new String(file.readFully(), StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONArray array = catalog.getJSONArray(JSON_KEY_CONTENT);
|
JSONArray array = catalog.getJSONArray(JSON_KEY_CONTENT);
|
||||||
|
@ -233,10 +233,6 @@ public class DownloadContentCatalog {
|
||||||
Log.w(LOGTAG, "Unable to parse catalog JSON. Re-creating empty catalog.", e);
|
Log.w(LOGTAG, "Unable to parse catalog JSON. Re-creating empty catalog.", e);
|
||||||
loadedContent = new ArrayMap<>();
|
loadedContent = new ArrayMap<>();
|
||||||
hasCatalogChanged = true; // Indicate that we want to persist the new catalog
|
hasCatalogChanged = true; // Indicate that we want to persist the new catalog
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
AssertionError error = new AssertionError("Should not happen: This device does not speak UTF-8");
|
|
||||||
error.initCause(e);
|
|
||||||
throw error;
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.d(LOGTAG, "Can't read catalog due to IOException", e);
|
Log.d(LOGTAG, "Can't read catalog due to IOException", e);
|
||||||
}
|
}
|
||||||
|
@ -275,15 +271,11 @@ public class DownloadContentCatalog {
|
||||||
JSONObject catalog = new JSONObject();
|
JSONObject catalog = new JSONObject();
|
||||||
catalog.put(JSON_KEY_CONTENT, array);
|
catalog.put(JSON_KEY_CONTENT, array);
|
||||||
|
|
||||||
outputStream.write(catalog.toString().getBytes("UTF-8"));
|
outputStream.write(catalog.toString().getBytes(StringUtils.UTF_8));
|
||||||
|
|
||||||
file.finishWrite(outputStream);
|
file.finishWrite(outputStream);
|
||||||
|
|
||||||
hasCatalogChanged = false;
|
hasCatalogChanged = false;
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
AssertionError error = new AssertionError("Should not happen: This device does not speak UTF-8");
|
|
||||||
error.initCause(e);
|
|
||||||
throw error;
|
|
||||||
} catch (IOException | JSONException e) {
|
} catch (IOException | JSONException e) {
|
||||||
Log.e(LOGTAG, "IOException during writing catalog", e);
|
Log.e(LOGTAG, "IOException during writing catalog", e);
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@ import org.mozilla.gecko.icons.IconRequest;
|
||||||
import org.mozilla.gecko.icons.IconResponse;
|
import org.mozilla.gecko.icons.IconResponse;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.util.IOUtils;
|
import org.mozilla.gecko.util.IOUtils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -257,10 +257,10 @@ public class DiskStorage {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] data = prefix.getBytes("UTF-8");
|
byte[] data = prefix.getBytes(StringUtils.UTF_8);
|
||||||
NativeCrypto.sha256update(ctx, data, data.length);
|
NativeCrypto.sha256update(ctx, data, data.length);
|
||||||
|
|
||||||
data = url.getBytes("UTF-8");
|
data = url.getBytes(StringUtils.UTF_8);
|
||||||
NativeCrypto.sha256update(ctx, data, data.length);
|
NativeCrypto.sha256update(ctx, data, data.length);
|
||||||
return Utils.byte2Hex(NativeCrypto.sha256finalize(ctx));
|
return Utils.byte2Hex(NativeCrypto.sha256finalize(ctx));
|
||||||
} catch (NoClassDefFoundError | ExceptionInInitializerError error) {
|
} catch (NoClassDefFoundError | ExceptionInInitializerError error) {
|
||||||
|
@ -269,15 +269,13 @@ public class DiskStorage {
|
||||||
// we will have a lot of other problems if we can't load libmozglue.so
|
// we will have a lot of other problems if we can't load libmozglue.so
|
||||||
try {
|
try {
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||||
md.update(prefix.getBytes("UTF-8"));
|
md.update(prefix.getBytes(StringUtils.UTF_8));
|
||||||
md.update(url.getBytes("UTF-8"));
|
md.update(url.getBytes(StringUtils.UTF_8));
|
||||||
return Utils.byte2Hex(md.digest());
|
return Utils.byte2Hex(md.digest());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Just give up. And let everyone know.
|
// Just give up. And let everyone know.
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new AssertionError("Should not happen: Device does not understand UTF-8");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import android.util.Log;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -46,7 +47,7 @@ public class PushState {
|
||||||
file = new AtomicFile(new File(context.getApplicationInfo().dataDir, fileName));
|
file = new AtomicFile(new File(context.getApplicationInfo().dataDir, fileName));
|
||||||
synchronized (file) {
|
synchronized (file) {
|
||||||
try {
|
try {
|
||||||
final String s = new String(file.readFully(), "UTF-8");
|
final String s = new String(file.readFully(), StringUtils.UTF_8);
|
||||||
final JSONObject temp = new JSONObject(s);
|
final JSONObject temp = new JSONObject(s);
|
||||||
if (temp.optLong("version", 0L) != VERSION) {
|
if (temp.optLong("version", 0L) != VERSION) {
|
||||||
throw new JSONException("Unknown version!");
|
throw new JSONException("Unknown version!");
|
||||||
|
@ -91,7 +92,7 @@ public class PushState {
|
||||||
FileOutputStream fileOutputStream = null;
|
FileOutputStream fileOutputStream = null;
|
||||||
try {
|
try {
|
||||||
fileOutputStream = file.startWrite();
|
fileOutputStream = file.startWrite();
|
||||||
fileOutputStream.write(toJSONObject().toString().getBytes("UTF-8"));
|
fileOutputStream.write(toJSONObject().toString().getBytes(StringUtils.UTF_8));
|
||||||
file.finishWrite(fileOutputStream);
|
file.finishWrite(fileOutputStream);
|
||||||
return true;
|
return true;
|
||||||
} catch (JSONException | IOException e) {
|
} catch (JSONException | IOException e) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.background.fxa;
|
||||||
|
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
@ -25,7 +26,6 @@ public class FxAccount20CreateDelegate {
|
||||||
* @param preVerified
|
* @param preVerified
|
||||||
* true if account should be marked already verified; only effective
|
* true if account should be marked already verified; only effective
|
||||||
* for non-production auth servers.
|
* for non-production auth servers.
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* @throws GeneralSecurityException
|
* @throws GeneralSecurityException
|
||||||
*/
|
*/
|
||||||
public FxAccount20CreateDelegate(byte[] emailUTF8, byte[] quickStretchedPW, boolean preVerified) throws UnsupportedEncodingException, GeneralSecurityException {
|
public FxAccount20CreateDelegate(byte[] emailUTF8, byte[] quickStretchedPW, boolean preVerified) throws UnsupportedEncodingException, GeneralSecurityException {
|
||||||
|
@ -34,19 +34,15 @@ public class FxAccount20CreateDelegate {
|
||||||
this.preVerified = preVerified;
|
this.preVerified = preVerified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedJSONObject getCreateBody() throws FxAccountClientException {
|
public ExtendedJSONObject getCreateBody() {
|
||||||
final ExtendedJSONObject body = new ExtendedJSONObject();
|
final ExtendedJSONObject body = new ExtendedJSONObject();
|
||||||
try {
|
body.put("email", new String(emailUTF8, StringUtils.UTF_8));
|
||||||
body.put("email", new String(emailUTF8, "UTF-8"));
|
body.put("authPW", Utils.byte2Hex(authPW));
|
||||||
body.put("authPW", Utils.byte2Hex(authPW));
|
if (preVerified) {
|
||||||
if (preVerified) {
|
// Production endpoints do not allow preVerified; this assumes we only
|
||||||
// Production endpoints do not allow preVerified; this assumes we only
|
// set it when it's okay to send it.
|
||||||
// set it when it's okay to send it.
|
body.put("preVerified", preVerified);
|
||||||
body.put("preVerified", preVerified);
|
|
||||||
}
|
|
||||||
return body;
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new FxAccountClientException(e);
|
|
||||||
}
|
}
|
||||||
|
return body;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package org.mozilla.gecko.background.fxa;
|
||||||
|
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
@ -23,14 +24,10 @@ public class FxAccount20LoginDelegate {
|
||||||
this.authPW = FxAccountUtils.generateAuthPW(quickStretchedPW);
|
this.authPW = FxAccountUtils.generateAuthPW(quickStretchedPW);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedJSONObject getCreateBody() throws FxAccountClientException {
|
public ExtendedJSONObject getCreateBody() {
|
||||||
final ExtendedJSONObject body = new ExtendedJSONObject();
|
final ExtendedJSONObject body = new ExtendedJSONObject();
|
||||||
try {
|
body.put("email", new String(emailUTF8, StringUtils.UTF_8));
|
||||||
body.put("email", new String(emailUTF8, "UTF-8"));
|
body.put("authPW", Utils.byte2Hex(authPW));
|
||||||
body.put("authPW", Utils.byte2Hex(authPW));
|
return body;
|
||||||
return body;
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new FxAccountClientException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
|
||||||
import org.mozilla.gecko.sync.net.Resource;
|
import org.mozilla.gecko.sync.net.Resource;
|
||||||
import org.mozilla.gecko.sync.net.SyncResponse;
|
import org.mozilla.gecko.sync.net.SyncResponse;
|
||||||
import org.mozilla.gecko.sync.net.SyncStorageResponse;
|
import org.mozilla.gecko.sync.net.SyncStorageResponse;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -647,7 +648,7 @@ public class FxAccountClient20 implements FxAccountClient {
|
||||||
if (getKeys) {
|
if (getKeys) {
|
||||||
keyFetchToken = Utils.hex2Byte(body.getString(JSON_KEY_KEYFETCHTOKEN));
|
keyFetchToken = Utils.hex2Byte(body.getString(JSON_KEY_KEYFETCHTOKEN));
|
||||||
}
|
}
|
||||||
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, "UTF-8"), uid, verified, sessionToken, keyFetchToken);
|
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, StringUtils.UTF_8), uid, verified, sessionToken, keyFetchToken);
|
||||||
|
|
||||||
delegate.handleSuccess(loginResponse);
|
delegate.handleSuccess(loginResponse);
|
||||||
}
|
}
|
||||||
|
@ -697,7 +698,7 @@ public class FxAccountClient20 implements FxAccountClient {
|
||||||
if (getKeys) {
|
if (getKeys) {
|
||||||
keyFetchToken = Utils.hex2Byte(body.getString(JSON_KEY_KEYFETCHTOKEN));
|
keyFetchToken = Utils.hex2Byte(body.getString(JSON_KEY_KEYFETCHTOKEN));
|
||||||
}
|
}
|
||||||
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, "UTF-8"), uid, verified, sessionToken, keyFetchToken);
|
LoginResponse loginResponse = new LoginResponse(new String(emailUTF8, StringUtils.UTF_8), uid, verified, sessionToken, keyFetchToken);
|
||||||
|
|
||||||
delegate.handleSuccess(loginResponse);
|
delegate.handleSuccess(loginResponse);
|
||||||
}
|
}
|
||||||
|
@ -736,7 +737,7 @@ public class FxAccountClient20 implements FxAccountClient {
|
||||||
final RequestDelegate<LoginResponse> delegate) {
|
final RequestDelegate<LoginResponse> delegate) {
|
||||||
byte[] quickStretchedPW;
|
byte[] quickStretchedPW;
|
||||||
try {
|
try {
|
||||||
FxAccountUtils.pii(LOG_TAG, "Trying user provided email: '" + new String(emailUTF8, "UTF-8") + "'" );
|
FxAccountUtils.pii(LOG_TAG, "Trying user provided email: '" + new String(emailUTF8, StringUtils.UTF_8) + "'" );
|
||||||
quickStretchedPW = stretcher.getQuickStretchedPW(emailUTF8);
|
quickStretchedPW = stretcher.getQuickStretchedPW(emailUTF8);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
delegate.handleError(e);
|
delegate.handleError(e);
|
||||||
|
@ -768,7 +769,7 @@ public class FxAccountClient20 implements FxAccountClient {
|
||||||
try {
|
try {
|
||||||
// Nota bene: this is not recursive, since we call the fixed password
|
// Nota bene: this is not recursive, since we call the fixed password
|
||||||
// signature here, which invokes a non-retrying version.
|
// signature here, which invokes a non-retrying version.
|
||||||
byte[] alternateEmailUTF8 = alternateEmail.getBytes("UTF-8");
|
byte[] alternateEmailUTF8 = alternateEmail.getBytes(StringUtils.UTF_8);
|
||||||
byte[] alternateQuickStretchedPW = stretcher.getQuickStretchedPW(alternateEmailUTF8);
|
byte[] alternateQuickStretchedPW = stretcher.getQuickStretchedPW(alternateEmailUTF8);
|
||||||
login(alternateEmailUTF8, alternateQuickStretchedPW, getKeys, queryParameters, delegate);
|
login(alternateEmailUTF8, alternateQuickStretchedPW, getKeys, queryParameters, delegate);
|
||||||
} catch (Exception innerException) {
|
} catch (Exception innerException) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.crypto.HKDF;
|
import org.mozilla.gecko.sync.crypto.HKDF;
|
||||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||||
import org.mozilla.gecko.sync.crypto.PBKDF2;
|
import org.mozilla.gecko.sync.crypto.PBKDF2;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
@ -49,21 +50,21 @@ public class FxAccountUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String bytes(String string) throws UnsupportedEncodingException {
|
public static String bytes(String string) {
|
||||||
return Utils.byte2Hex(string.getBytes("UTF-8"));
|
return Utils.byte2Hex(string.getBytes(StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] KW(String name) throws UnsupportedEncodingException {
|
public static byte[] KW(String name) {
|
||||||
return Utils.concatAll(
|
return Utils.concatAll(
|
||||||
KW_VERSION_STRING.getBytes("UTF-8"),
|
KW_VERSION_STRING.getBytes(StringUtils.UTF_8),
|
||||||
name.getBytes("UTF-8"));
|
name.getBytes(StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] KWE(String name, byte[] emailUTF8) throws UnsupportedEncodingException {
|
public static byte[] KWE(String name, byte[] emailUTF8) {
|
||||||
return Utils.concatAll(
|
return Utils.concatAll(
|
||||||
KW_VERSION_STRING.getBytes("UTF-8"),
|
KW_VERSION_STRING.getBytes(StringUtils.UTF_8),
|
||||||
name.getBytes("UTF-8"),
|
name.getBytes(StringUtils.UTF_8),
|
||||||
":".getBytes("UTF-8"),
|
":".getBytes(StringUtils.UTF_8),
|
||||||
emailUTF8);
|
emailUTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +72,8 @@ public class FxAccountUtils {
|
||||||
* Calculate the SRP verifier <tt>x</tt> value.
|
* Calculate the SRP verifier <tt>x</tt> value.
|
||||||
*/
|
*/
|
||||||
public static BigInteger srpVerifierLowercaseX(byte[] emailUTF8, byte[] srpPWBytes, byte[] srpSaltBytes)
|
public static BigInteger srpVerifierLowercaseX(byte[] emailUTF8, byte[] srpPWBytes, byte[] srpSaltBytes)
|
||||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws NoSuchAlgorithmException {
|
||||||
byte[] inner = Utils.sha256(Utils.concatAll(emailUTF8, ":".getBytes("UTF-8"), srpPWBytes));
|
byte[] inner = Utils.sha256(Utils.concatAll(emailUTF8, ":".getBytes(StringUtils.UTF_8), srpPWBytes));
|
||||||
byte[] outer = Utils.sha256(Utils.concatAll(srpSaltBytes, inner));
|
byte[] outer = Utils.sha256(Utils.concatAll(srpSaltBytes, inner));
|
||||||
return new BigInteger(1, outer);
|
return new BigInteger(1, outer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
public class QuickPasswordStretcher implements PasswordStretcher {
|
public class QuickPasswordStretcher implements PasswordStretcher {
|
||||||
protected final String password;
|
protected final String password;
|
||||||
|
@ -26,7 +27,7 @@ public class QuickPasswordStretcher implements PasswordStretcher {
|
||||||
}
|
}
|
||||||
String key = Utils.byte2Hex(emailUTF8);
|
String key = Utils.byte2Hex(emailUTF8);
|
||||||
if (!cache.containsKey(key)) {
|
if (!cache.containsKey(key)) {
|
||||||
byte[] value = FxAccountUtils.generateQuickStretchedPW(emailUTF8, password.getBytes("UTF-8"));
|
byte[] value = FxAccountUtils.generateQuickStretchedPW(emailUTF8, password.getBytes(StringUtils.UTF_8));
|
||||||
cache.put(key, Utils.byte2Hex(value));
|
cache.put(key, Utils.byte2Hex(value));
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,16 @@
|
||||||
|
|
||||||
package org.mozilla.gecko.browserid;
|
package org.mozilla.gecko.browserid;
|
||||||
|
|
||||||
|
import static org.mozilla.apache.commons.codec.binary.StringUtils.newStringUtf8;
|
||||||
|
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.apache.commons.codec.binary.StringUtils;
|
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.NonObjectJSONException;
|
import org.mozilla.gecko.sync.NonObjectJSONException;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
@ -32,21 +33,21 @@ public class JSONWebTokenUtils {
|
||||||
public static final String DEFAULT_CERTIFICATE_ISSUER = "127.0.0.1";
|
public static final String DEFAULT_CERTIFICATE_ISSUER = "127.0.0.1";
|
||||||
public static final String DEFAULT_ASSERTION_ISSUER = "127.0.0.1";
|
public static final String DEFAULT_ASSERTION_ISSUER = "127.0.0.1";
|
||||||
|
|
||||||
public static String encode(String payload, SigningPrivateKey privateKey) throws UnsupportedEncodingException, GeneralSecurityException {
|
public static String encode(String payload, SigningPrivateKey privateKey) throws GeneralSecurityException {
|
||||||
final ExtendedJSONObject header = new ExtendedJSONObject();
|
final ExtendedJSONObject header = new ExtendedJSONObject();
|
||||||
header.put("alg", privateKey.getAlgorithm());
|
header.put("alg", privateKey.getAlgorithm());
|
||||||
String encodedHeader = Base64.encodeBase64URLSafeString(header.toJSONString().getBytes("UTF-8"));
|
String encodedHeader = Base64.encodeBase64URLSafeString(header.toJSONString().getBytes(StringUtils.UTF_8));
|
||||||
String encodedPayload = Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8"));
|
String encodedPayload = Base64.encodeBase64URLSafeString(payload.getBytes(StringUtils.UTF_8));
|
||||||
ArrayList<String> segments = new ArrayList<String>();
|
ArrayList<String> segments = new ArrayList<String>();
|
||||||
segments.add(encodedHeader);
|
segments.add(encodedHeader);
|
||||||
segments.add(encodedPayload);
|
segments.add(encodedPayload);
|
||||||
byte[] message = Utils.toDelimitedString(".", segments).getBytes("UTF-8");
|
byte[] message = Utils.toDelimitedString(".", segments).getBytes(StringUtils.UTF_8);
|
||||||
byte[] signature = privateKey.signMessage(message);
|
byte[] signature = privateKey.signMessage(message);
|
||||||
segments.add(Base64.encodeBase64URLSafeString(signature));
|
segments.add(Base64.encodeBase64URLSafeString(signature));
|
||||||
return Utils.toDelimitedString(".", segments);
|
return Utils.toDelimitedString(".", segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String decode(String token, VerifyingPublicKey publicKey) throws GeneralSecurityException, UnsupportedEncodingException {
|
public static String decode(String token, VerifyingPublicKey publicKey) throws GeneralSecurityException {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
throw new IllegalArgumentException("token must not be null");
|
throw new IllegalArgumentException("token must not be null");
|
||||||
}
|
}
|
||||||
|
@ -54,13 +55,13 @@ public class JSONWebTokenUtils {
|
||||||
if (segments == null || segments.length != 3) {
|
if (segments == null || segments.length != 3) {
|
||||||
throw new GeneralSecurityException("malformed token");
|
throw new GeneralSecurityException("malformed token");
|
||||||
}
|
}
|
||||||
byte[] message = (segments[0] + "." + segments[1]).getBytes("UTF-8");
|
byte[] message = (segments[0] + "." + segments[1]).getBytes(StringUtils.UTF_8);
|
||||||
byte[] signature = Base64.decodeBase64(segments[2]);
|
byte[] signature = Base64.decodeBase64(segments[2]);
|
||||||
boolean verifies = publicKey.verifyMessage(message, signature);
|
boolean verifies = publicKey.verifyMessage(message, signature);
|
||||||
if (!verifies) {
|
if (!verifies) {
|
||||||
throw new GeneralSecurityException("bad signature");
|
throw new GeneralSecurityException("bad signature");
|
||||||
}
|
}
|
||||||
String payload = StringUtils.newStringUtf8(Base64.decodeBase64(segments[1]));
|
String payload = newStringUtf8(Base64.decodeBase64(segments[1]));
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ import org.mozilla.gecko.sync.NonObjectJSONException;
|
||||||
import org.mozilla.gecko.sync.ThreadPool;
|
import org.mozilla.gecko.sync.ThreadPool;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.setup.Constants;
|
import org.mozilla.gecko.sync.setup.Constants;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -495,11 +496,7 @@ public class AndroidFxAccount {
|
||||||
public ExtendedJSONObject toJSONObject() {
|
public ExtendedJSONObject toJSONObject() {
|
||||||
ExtendedJSONObject o = unbundle();
|
ExtendedJSONObject o = unbundle();
|
||||||
o.put("email", account.name);
|
o.put("email", account.name);
|
||||||
try {
|
o.put("emailUTF8", Utils.byte2Hex(account.name.getBytes(StringUtils.UTF_8)));
|
||||||
o.put("emailUTF8", Utils.byte2Hex(account.name.getBytes("UTF-8")));
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
// Ignore.
|
|
||||||
}
|
|
||||||
o.put("fxaDeviceId", getDeviceId());
|
o.put("fxaDeviceId", getDeviceId());
|
||||||
o.put("fxaDeviceRegistrationVersion", getDeviceRegistrationVersion());
|
o.put("fxaDeviceRegistrationVersion", getDeviceRegistrationVersion());
|
||||||
o.put("fxaDeviceRegistrationTimestamp", getDeviceRegistrationTimestamp());
|
o.put("fxaDeviceRegistrationTimestamp", getDeviceRegistrationTimestamp());
|
||||||
|
|
|
@ -57,6 +57,7 @@ import org.mozilla.gecko.tokenserver.TokenServerClient;
|
||||||
import org.mozilla.gecko.tokenserver.TokenServerClientDelegate;
|
import org.mozilla.gecko.tokenserver.TokenServerClientDelegate;
|
||||||
import org.mozilla.gecko.tokenserver.TokenServerException;
|
import org.mozilla.gecko.tokenserver.TokenServerException;
|
||||||
import org.mozilla.gecko.tokenserver.TokenServerToken;
|
import org.mozilla.gecko.tokenserver.TokenServerToken;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
@ -408,7 +409,7 @@ public class FxAccountSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||||
// so we explicitly do not send payload verification hashes to the
|
// so we explicitly do not send payload verification hashes to the
|
||||||
// Sync storage endpoint.
|
// Sync storage endpoint.
|
||||||
final boolean includePayloadVerificationHash = false;
|
final boolean includePayloadVerificationHash = false;
|
||||||
final AuthHeaderProvider authHeaderProvider = new HawkAuthHeaderProvider(token.id, token.key.getBytes("UTF-8"), includePayloadVerificationHash, storageServerSkew);
|
final AuthHeaderProvider authHeaderProvider = new HawkAuthHeaderProvider(token.id, token.key.getBytes(StringUtils.UTF_8), includePayloadVerificationHash, storageServerSkew);
|
||||||
|
|
||||||
final Context context = getContext();
|
final Context context = getContext();
|
||||||
final SyncConfiguration syncConfig = new SyncConfiguration(token.uid, authHeaderProvider, sharedPrefs, syncKeyBundle);
|
final SyncConfiguration syncConfig = new SyncConfiguration(token.uid, authHeaderProvider, sharedPrefs, syncKeyBundle);
|
||||||
|
|
|
@ -21,8 +21,8 @@ import org.mozilla.gecko.sync.repositories.NullCursorException;
|
||||||
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
import org.mozilla.gecko.sync.repositories.android.ClientsDatabaseAccessor;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||||
import org.mozilla.gecko.sync.telemetry.TelemetryEventCollector;
|
import org.mozilla.gecko.sync.telemetry.TelemetryEventCollector;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -267,10 +267,10 @@ public class CommandProcessor {
|
||||||
extra.put("flowID", command.flowID);
|
extra.put("flowID", command.flowID);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
extra.put("deviceID", Utils.byte2Hex(Utils.sha256(clientID.concat(hashedFxAUID).getBytes("UTF-8"))));
|
extra.put("deviceID", Utils.byte2Hex(Utils.sha256(clientID.concat(hashedFxAUID).getBytes(StringUtils.UTF_8))));
|
||||||
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// Should not happen.
|
// Should not happen.
|
||||||
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
|
Log.e(LOG_TAG, "SHA-256 is not supported", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
TelemetryEventCollector.recordEvent(context, "sendcommand", command.commandType, null, extra);
|
TelemetryEventCollector.recordEvent(context, "sendcommand", command.commandType, null, extra);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
package org.mozilla.gecko.sync;
|
package org.mozilla.gecko.sync;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
|
@ -56,11 +55,10 @@ public class CryptoRecord extends Record {
|
||||||
* Input: JSONObject containing a valid payload (cipherText, IV, HMAC),
|
* Input: JSONObject containing a valid payload (cipherText, IV, HMAC),
|
||||||
* KeyBundle with keys for decryption. Output: byte[] clearText
|
* KeyBundle with keys for decryption. Output: byte[] clearText
|
||||||
* @throws CryptoException
|
* @throws CryptoException
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
*/
|
*/
|
||||||
private static byte[] decryptPayload(ExtendedJSONObject payload, KeyBundle keybundle) throws CryptoException, UnsupportedEncodingException {
|
private static byte[] decryptPayload(ExtendedJSONObject payload, KeyBundle keybundle) throws CryptoException {
|
||||||
byte[] ciphertext = Base64.decodeBase64(((String) payload.get(KEY_CIPHERTEXT)).getBytes("UTF-8"));
|
byte[] ciphertext = Base64.decodeBase64(((String) payload.get(KEY_CIPHERTEXT)).getBytes(StringUtils.UTF_8));
|
||||||
byte[] iv = Base64.decodeBase64(((String) payload.get(KEY_IV)).getBytes("UTF-8"));
|
byte[] iv = Base64.decodeBase64(((String) payload.get(KEY_IV)).getBytes(StringUtils.UTF_8));
|
||||||
byte[] hmac = Utils.hex2Byte((String) payload.get(KEY_HMAC));
|
byte[] hmac = Utils.hex2Byte((String) payload.get(KEY_HMAC));
|
||||||
|
|
||||||
return CryptoInfo.decrypt(ciphertext, iv, hmac, keybundle).getMessage();
|
return CryptoInfo.decrypt(ciphertext, iv, hmac, keybundle).getMessage();
|
||||||
|
@ -131,7 +129,7 @@ public class CryptoRecord extends Record {
|
||||||
*/
|
*/
|
||||||
public static CryptoRecord fromJSONRecord(String jsonRecord)
|
public static CryptoRecord fromJSONRecord(String jsonRecord)
|
||||||
throws NonObjectJSONException, IOException, RecordParseException {
|
throws NonObjectJSONException, IOException, RecordParseException {
|
||||||
byte[] bytes = jsonRecord.getBytes("UTF-8");
|
byte[] bytes = jsonRecord.getBytes(StringUtils.UTF_8);
|
||||||
ExtendedJSONObject object = ExtendedJSONObject.parseUTF8AsJSONObject(bytes);
|
ExtendedJSONObject object = ExtendedJSONObject.parseUTF8AsJSONObject(bytes);
|
||||||
|
|
||||||
return CryptoRecord.fromJSONRecord(object);
|
return CryptoRecord.fromJSONRecord(object);
|
||||||
|
@ -201,7 +199,7 @@ public class CryptoRecord extends Record {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CryptoRecord encrypt() throws CryptoException, UnsupportedEncodingException {
|
public CryptoRecord encrypt() throws CryptoException {
|
||||||
if (this.keyBundle == null) {
|
if (this.keyBundle == null) {
|
||||||
throw new NoKeyBundleException();
|
throw new NoKeyBundleException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.json.simple.parser.JSONParser;
|
||||||
import org.json.simple.parser.ParseException;
|
import org.json.simple.parser.ParseException;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.sync.UnexpectedJSONException.BadRequiredFieldJSONException;
|
import org.mozilla.gecko.sync.UnexpectedJSONException.BadRequiredFieldJSONException;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -138,7 +139,7 @@ public class ExtendedJSONObject implements Cloneable {
|
||||||
*/
|
*/
|
||||||
public static ExtendedJSONObject parseUTF8AsJSONObject(byte[] in)
|
public static ExtendedJSONObject parseUTF8AsJSONObject(byte[] in)
|
||||||
throws NonObjectJSONException, IOException {
|
throws NonObjectJSONException, IOException {
|
||||||
return new ExtendedJSONObject(new String(in, "UTF-8"));
|
return new ExtendedJSONObject(new String(in, StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedJSONObject() {
|
public ExtendedJSONObject() {
|
||||||
|
|
|
@ -7,7 +7,6 @@ package org.mozilla.gecko.sync;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
|
@ -127,11 +126,9 @@ public class Utils {
|
||||||
* An input string. Will be decoded as UTF-8.
|
* An input string. Will be decoded as UTF-8.
|
||||||
* @return
|
* @return
|
||||||
* A byte array of decoded values.
|
* A byte array of decoded values.
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* Should not occur.
|
|
||||||
*/
|
*/
|
||||||
public static byte[] decodeBase64(String base64) throws UnsupportedEncodingException {
|
public static byte[] decodeBase64(String base64) {
|
||||||
return Base64.decodeBase64(base64.getBytes("UTF-8"));
|
return Base64.decodeBase64(base64.getBytes(StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] decodeFriendlyBase32(String base32) {
|
public static byte[] decodeFriendlyBase32(String base32) {
|
||||||
|
@ -202,8 +199,8 @@ public class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static byte[] sha1(final String utf8)
|
protected static byte[] sha1(final String utf8)
|
||||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws NoSuchAlgorithmException {
|
||||||
final byte[] bytes = utf8.getBytes("UTF-8");
|
final byte[] bytes = utf8.getBytes(StringUtils.UTF_8);
|
||||||
try {
|
try {
|
||||||
return NativeCrypto.sha1(bytes);
|
return NativeCrypto.sha1(bytes);
|
||||||
} catch (final LinkageError e) {
|
} catch (final LinkageError e) {
|
||||||
|
@ -213,12 +210,12 @@ public class Utils {
|
||||||
Logger.warn(LOG_TAG, "Got throwable stretching password using native sha1 implementation; " +
|
Logger.warn(LOG_TAG, "Got throwable stretching password using native sha1 implementation; " +
|
||||||
"ignoring and using Java implementation.", e);
|
"ignoring and using Java implementation.", e);
|
||||||
final MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
final MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
|
||||||
return sha1.digest(utf8.getBytes("UTF-8"));
|
return sha1.digest(utf8.getBytes(StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String sha1Base32(final String utf8)
|
protected static String sha1Base32(final String utf8)
|
||||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws NoSuchAlgorithmException {
|
||||||
return new Base32().encodeAsString(sha1(utf8)).toLowerCase(Locale.US);
|
return new Base32().encodeAsString(sha1(utf8)).toLowerCase(Locale.US);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,10 +226,9 @@ public class Utils {
|
||||||
* An account string.
|
* An account string.
|
||||||
* @return
|
* @return
|
||||||
* An acceptable string.
|
* An acceptable string.
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
public static String usernameFromAccount(final String account) throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
public static String usernameFromAccount(final String account) throws NoSuchAlgorithmException {
|
||||||
if (account == null || account.equals("")) {
|
if (account == null || account.equals("")) {
|
||||||
throw new IllegalArgumentException("No account name provided.");
|
throw new IllegalArgumentException("No account name provided.");
|
||||||
}
|
}
|
||||||
|
@ -252,10 +248,9 @@ public class Utils {
|
||||||
* @param version the version of preferences to reference.
|
* @param version the version of preferences to reference.
|
||||||
* @return the path.
|
* @return the path.
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
*/
|
*/
|
||||||
public static String getPrefsPath(final String product, final String accountKey, final String serverURL, final String profile, final long version)
|
public static String getPrefsPath(final String product, final String accountKey, final String serverURL, final String profile, final long version)
|
||||||
throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws NoSuchAlgorithmException {
|
||||||
final String encodedAccount = sha1Base32(serverURL + ":" + usernameFromAccount(accountKey));
|
final String encodedAccount = sha1Base32(serverURL + ":" + usernameFromAccount(accountKey));
|
||||||
|
|
||||||
if (version <= 0) {
|
if (version <= 0) {
|
||||||
|
@ -515,13 +510,13 @@ public class Utils {
|
||||||
* This is the format produced by desktop Firefox when exchanging credentials
|
* This is the format produced by desktop Firefox when exchanging credentials
|
||||||
* containing non-ASCII characters.
|
* containing non-ASCII characters.
|
||||||
*/
|
*/
|
||||||
public static String decodeUTF8(final String in) throws UnsupportedEncodingException {
|
public static String decodeUTF8(final String in) {
|
||||||
final int length = in.length();
|
final int length = in.length();
|
||||||
final byte[] asciiBytes = new byte[length];
|
final byte[] asciiBytes = new byte[length];
|
||||||
for (int i = 0; i < length; ++i) {
|
for (int i = 0; i < length; ++i) {
|
||||||
asciiBytes[i] = (byte) in.codePointAt(i);
|
asciiBytes[i] = (byte) in.codePointAt(i);
|
||||||
}
|
}
|
||||||
return new String(asciiBytes, "UTF-8");
|
return new String(asciiBytes, StringUtils.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@ import javax.crypto.Mac;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A standards-compliant implementation of RFC 5869
|
* A standards-compliant implementation of RFC 5869
|
||||||
|
@ -25,11 +26,7 @@ public class HKDF {
|
||||||
* Used for conversion in cases in which you *know* the encoding exists.
|
* Used for conversion in cases in which you *know* the encoding exists.
|
||||||
*/
|
*/
|
||||||
public static final byte[] bytes(String in) {
|
public static final byte[] bytes(String in) {
|
||||||
try {
|
return in.getBytes(StringUtils.UTF_8);
|
||||||
return in.getBytes("UTF-8");
|
|
||||||
} catch (java.io.UnsupportedEncodingException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int BLOCKSIZE = 256 / 8;
|
public static final int BLOCKSIZE = 256 / 8;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.mozilla.gecko.sync.crypto;
|
package org.mozilla.gecko.sync.crypto;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -14,6 +13,7 @@ import javax.crypto.Mac;
|
||||||
|
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
public class KeyBundle {
|
public class KeyBundle {
|
||||||
private static final String KEY_ALGORITHM_SPEC = "AES";
|
private static final String KEY_ALGORITHM_SPEC = "AES";
|
||||||
|
@ -44,7 +44,7 @@ public class KeyBundle {
|
||||||
// Hash appropriately.
|
// Hash appropriately.
|
||||||
try {
|
try {
|
||||||
username = Utils.usernameFromAccount(username);
|
username = Utils.usernameFromAccount(username);
|
||||||
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
throw new IllegalArgumentException("Invalid username.");
|
throw new IllegalArgumentException("Invalid username.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,9 +77,9 @@ public class KeyBundle {
|
||||||
*
|
*
|
||||||
* @return A KeyBundle with the specified keys.
|
* @return A KeyBundle with the specified keys.
|
||||||
*/
|
*/
|
||||||
public static KeyBundle fromBase64EncodedKeys(String base64EncryptionKey, String base64HmacKey) throws UnsupportedEncodingException {
|
public static KeyBundle fromBase64EncodedKeys(String base64EncryptionKey, String base64HmacKey) {
|
||||||
return new KeyBundle(Base64.decodeBase64(base64EncryptionKey.getBytes("UTF-8")),
|
return new KeyBundle(Base64.decodeBase64(base64EncryptionKey.getBytes(StringUtils.UTF_8)),
|
||||||
Base64.decodeBase64(base64HmacKey.getBytes("UTF-8")));
|
Base64.decodeBase64(base64HmacKey.getBytes(StringUtils.UTF_8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
package org.mozilla.gecko.sync.middleware;
|
package org.mozilla.gecko.sync.middleware;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import org.mozilla.gecko.sync.CryptoRecord;
|
import org.mozilla.gecko.sync.CryptoRecord;
|
||||||
|
@ -161,7 +160,7 @@ public class Crypto5MiddlewareRepositorySession extends MiddlewareRepositorySess
|
||||||
rec.keyBundle = this.keyBundle;
|
rec.keyBundle = this.keyBundle;
|
||||||
try {
|
try {
|
||||||
rec.encrypt();
|
rec.encrypt();
|
||||||
} catch (UnsupportedEncodingException | CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
storeDelegate.onRecordStoreFailed(e, record.guid);
|
storeDelegate.onRecordStoreFailed(e, record.guid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.background.common.log.Logger;
|
import org.mozilla.gecko.background.common.log.Logger;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import ch.boye.httpclientandroidlib.Header;
|
import ch.boye.httpclientandroidlib.Header;
|
||||||
import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
|
import ch.boye.httpclientandroidlib.client.methods.HttpRequestBase;
|
||||||
|
@ -197,11 +198,10 @@ public class HMACAuthHeaderProvider implements AuthHeaderProvider {
|
||||||
* @return signature as base-64 encoded string.
|
* @return signature as base-64 encoded string.
|
||||||
* @throws InvalidKeyException
|
* @throws InvalidKeyException
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
*/
|
*/
|
||||||
protected static String getSignature(String requestString, String key)
|
protected static String getSignature(String requestString, String key)
|
||||||
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws InvalidKeyException, NoSuchAlgorithmException {
|
||||||
String macString = Base64.encodeBase64String(sha1(requestString.getBytes("UTF-8"), key.getBytes("UTF-8")));
|
String macString = Base64.encodeBase64String(sha1(requestString.getBytes(StringUtils.UTF_8), key.getBytes(StringUtils.UTF_8)));
|
||||||
|
|
||||||
return macString;
|
return macString;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import javax.crypto.spec.SecretKeySpec;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.background.common.log.Logger;
|
import org.mozilla.gecko.background.common.log.Logger;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import ch.boye.httpclientandroidlib.Header;
|
import ch.boye.httpclientandroidlib.Header;
|
||||||
import ch.boye.httpclientandroidlib.HttpEntity;
|
import ch.boye.httpclientandroidlib.HttpEntity;
|
||||||
|
@ -151,7 +152,7 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
|
||||||
String app = null;
|
String app = null;
|
||||||
String dlg = null;
|
String dlg = null;
|
||||||
String requestString = getRequestString(request, "header", timestamp, nonce, payloadHash, extra, app, dlg);
|
String requestString = getRequestString(request, "header", timestamp, nonce, payloadHash, extra, app, dlg);
|
||||||
String macString = getSignature(requestString.getBytes("UTF-8"), this.key);
|
String macString = getSignature(requestString.getBytes(StringUtils.UTF_8), this.key);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("Hawk id=\"");
|
sb.append("Hawk id=\"");
|
||||||
|
@ -191,12 +192,11 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
|
||||||
* to compute hash for.
|
* to compute hash for.
|
||||||
* @return verification hash, or null if the request does not enclose an entity.
|
* @return verification hash, or null if the request does not enclose an entity.
|
||||||
* @throws IllegalArgumentException if the request does not enclose a valid non-null entity.
|
* @throws IllegalArgumentException if the request does not enclose a valid non-null entity.
|
||||||
* @throws UnsupportedEncodingException
|
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected static String getPayloadHashString(HttpRequestBase request)
|
protected static String getPayloadHashString(HttpRequestBase request)
|
||||||
throws UnsupportedEncodingException, NoSuchAlgorithmException, IOException, IllegalArgumentException {
|
throws NoSuchAlgorithmException, IOException, IllegalArgumentException {
|
||||||
final boolean shouldComputePayloadHash = request instanceof HttpEntityEnclosingRequest;
|
final boolean shouldComputePayloadHash = request instanceof HttpEntityEnclosingRequest;
|
||||||
if (!shouldComputePayloadHash) {
|
if (!shouldComputePayloadHash) {
|
||||||
Logger.debug(LOG_TAG, "Not computing payload verification hash for non-enclosing request.");
|
Logger.debug(LOG_TAG, "Not computing payload verification hash for non-enclosing request.");
|
||||||
|
@ -278,14 +278,14 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
|
||||||
* @return hash.
|
* @return hash.
|
||||||
* @throws IllegalArgumentException if entity is not repeatable.
|
* @throws IllegalArgumentException if entity is not repeatable.
|
||||||
*/
|
*/
|
||||||
protected static byte[] getPayloadHash(HttpEntity entity) throws UnsupportedEncodingException, IOException, NoSuchAlgorithmException {
|
protected static byte[] getPayloadHash(HttpEntity entity) throws IOException, NoSuchAlgorithmException {
|
||||||
if (!entity.isRepeatable()) {
|
if (!entity.isRepeatable()) {
|
||||||
throw new IllegalArgumentException("entity must be repeatable");
|
throw new IllegalArgumentException("entity must be repeatable");
|
||||||
}
|
}
|
||||||
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
final MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
digest.update(("hawk." + HAWK_HEADER_VERSION + ".payload\n").getBytes("UTF-8"));
|
digest.update(("hawk." + HAWK_HEADER_VERSION + ".payload\n").getBytes(StringUtils.UTF_8));
|
||||||
digest.update(getBaseContentType(entity.getContentType()).getBytes("UTF-8"));
|
digest.update(getBaseContentType(entity.getContentType()).getBytes(StringUtils.UTF_8));
|
||||||
digest.update("\n".getBytes("UTF-8"));
|
digest.update("\n".getBytes(StringUtils.UTF_8));
|
||||||
InputStream stream = entity.getContent();
|
InputStream stream = entity.getContent();
|
||||||
try {
|
try {
|
||||||
int numRead;
|
int numRead;
|
||||||
|
@ -295,7 +295,7 @@ public class HawkAuthHeaderProvider implements AuthHeaderProvider {
|
||||||
digest.update(buffer, 0, numRead);
|
digest.update(buffer, 0, numRead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
digest.update("\n".getBytes("UTF-8")); // Trailing newline is specified by Hawk.
|
digest.update("\n".getBytes(StringUtils.UTF_8)); // Trailing newline is specified by Hawk.
|
||||||
return digest.digest();
|
return digest.digest();
|
||||||
} finally {
|
} finally {
|
||||||
stream.close();
|
stream.close();
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.io.UnsupportedEncodingException;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.mozilla.gecko.sync.CryptoRecord;
|
import org.mozilla.gecko.sync.CryptoRecord;
|
||||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record is the abstract base class for all entries that Sync processes:
|
* Record is the abstract base class for all entries that Sync processes:
|
||||||
|
@ -259,12 +260,7 @@ public abstract class Record {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] stringToJSONBytes(String in) {
|
public static byte[] stringToJSONBytes(String in) {
|
||||||
try {
|
return in.getBytes(StringUtils.UTF_8);
|
||||||
return in.getBytes("UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
// Can't happen.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,7 +11,6 @@ import android.support.annotation.NonNull;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -672,8 +671,6 @@ public class SyncClientsEngineStage extends AbstractSessionManagingSyncStage {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return cryptoRecord.encrypt();
|
return cryptoRecord.encrypt();
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
doAbort(e, encryptionFailure + " Unsupported encoding.");
|
|
||||||
} catch (CryptoException e) {
|
} catch (CryptoException e) {
|
||||||
doAbort(e, encryptionFailure);
|
doAbort(e, encryptionFailure);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ import org.mozilla.gecko.sync.net.SyncStorageResponse;
|
||||||
import org.mozilla.gecko.sync.repositories.FetchFailedException;
|
import org.mozilla.gecko.sync.repositories.FetchFailedException;
|
||||||
import org.mozilla.gecko.sync.repositories.StoreFailedException;
|
import org.mozilla.gecko.sync.repositories.StoreFailedException;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -77,11 +77,11 @@ public class TelemetryCollector {
|
||||||
this.hashedUID = uid;
|
this.hashedUID = uid;
|
||||||
try {
|
try {
|
||||||
this.hashedDeviceID = Utils.byte2Hex(Utils.sha256(
|
this.hashedDeviceID = Utils.byte2Hex(Utils.sha256(
|
||||||
deviceID.concat(uid).getBytes("UTF-8")
|
deviceID.concat(uid).getBytes(StringUtils.UTF_8)
|
||||||
));
|
));
|
||||||
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// Should not happen.
|
// Should not happen.
|
||||||
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
|
Log.e(LOG_TAG, "SHA-256 is not supported", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,11 +128,11 @@ public class TelemetryCollector {
|
||||||
try {
|
try {
|
||||||
device.putString(
|
device.putString(
|
||||||
TelemetryContract.KEY_DEVICE_ID,
|
TelemetryContract.KEY_DEVICE_ID,
|
||||||
Utils.byte2Hex(Utils.sha256(clientAndUid.getBytes("UTF-8")))
|
Utils.byte2Hex(Utils.sha256(clientAndUid.getBytes(StringUtils.UTF_8)))
|
||||||
);
|
);
|
||||||
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// Should not happen.
|
// Should not happen.
|
||||||
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
|
Log.e(LOG_TAG, "SHA-256 is not supported", e);
|
||||||
}
|
}
|
||||||
devices.add(device);
|
devices.add(device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.mozilla.gecko.sync.SharedPreferencesClientsDataDelegate;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
||||||
import org.mozilla.gecko.sync.net.BaseResource;
|
import org.mozilla.gecko.sync.net.BaseResource;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
@ -126,10 +127,10 @@ public class TelemetryEventCollector {
|
||||||
final ClientsDataDelegate clientsDataDelegate = new SharedPreferencesClientsDataDelegate(sharedPrefs, context);
|
final ClientsDataDelegate clientsDataDelegate = new SharedPreferencesClientsDataDelegate(sharedPrefs, context);
|
||||||
try {
|
try {
|
||||||
final String hashedDeviceID = Utils.byte2Hex(Utils.sha256(
|
final String hashedDeviceID = Utils.byte2Hex(Utils.sha256(
|
||||||
clientsDataDelegate.getAccountGUID().concat(hashedFxAUID).getBytes("UTF-8")
|
clientsDataDelegate.getAccountGUID().concat(hashedFxAUID).getBytes(StringUtils.UTF_8)
|
||||||
));
|
));
|
||||||
event.putString(TelemetryContract.KEY_LOCAL_DEVICE_ID, hashedDeviceID);
|
event.putString(TelemetryContract.KEY_LOCAL_DEVICE_ID, hashedDeviceID);
|
||||||
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
// Should not happen.
|
// Should not happen.
|
||||||
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
|
Log.e(LOG_TAG, "Either UTF-8 or SHA-256 are not supported", e);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.Provider;
|
import java.security.Provider;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
@ -330,10 +329,6 @@ public final class PRNGFixes {
|
||||||
if (serial != null) {
|
if (serial != null) {
|
||||||
result.append(serial);
|
result.append(serial);
|
||||||
}
|
}
|
||||||
try {
|
return result.toString().getBytes(StringUtils.UTF_8);
|
||||||
return result.toString().getBytes("UTF-8");
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new RuntimeException("UTF-8 encoding not supported");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.NonObjectJSONException;
|
import org.mozilla.gecko.sync.NonObjectJSONException;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
|
import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -53,7 +54,7 @@ public class TestCredentialsEndToEnd {
|
||||||
final String decoded = Utils.decodeUTF8(password);
|
final String decoded = Utils.decodeUTF8(password);
|
||||||
|
|
||||||
final byte[] expectedBytes = Utils.decodeBase64(BTOA_PASSWORD);
|
final byte[] expectedBytes = Utils.decodeBase64(BTOA_PASSWORD);
|
||||||
final String expected = new String(expectedBytes, "UTF-8");
|
final String expected = new String(expectedBytes, StringUtils.UTF_8);
|
||||||
|
|
||||||
assertEquals(DESKTOP_ASSERTED_SIZE, password.length());
|
assertEquals(DESKTOP_ASSERTED_SIZE, password.length());
|
||||||
assertEquals(expected, decoded);
|
assertEquals(expected, decoded);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.mozilla.gecko.sync.NoCollectionKeysSetException;
|
||||||
import org.mozilla.gecko.sync.NonObjectJSONException;
|
import org.mozilla.gecko.sync.NonObjectJSONException;
|
||||||
import org.mozilla.gecko.sync.crypto.CryptoException;
|
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -80,7 +81,7 @@ public class TestCollectionKeys {
|
||||||
rec.encrypt();
|
rec.encrypt();
|
||||||
CollectionKeys ck = new CollectionKeys();
|
CollectionKeys ck = new CollectionKeys();
|
||||||
ck.setKeyPairsFromWBO(rec, syncKeyBundle);
|
ck.setKeyPairsFromWBO(rec, syncKeyBundle);
|
||||||
byte[] input = "3fI6k1exImMgAKjilmMaAWxGqEIzFX/9K5EjEgH99vc=".getBytes("UTF-8");
|
byte[] input = "3fI6k1exImMgAKjilmMaAWxGqEIzFX/9K5EjEgH99vc=".getBytes(StringUtils.UTF_8);
|
||||||
byte[] expected = Base64.decodeBase64(input);
|
byte[] expected = Base64.decodeBase64(input);
|
||||||
assertSame(expected, ck.defaultKeyBundle().getEncryptionKey());
|
assertSame(expected, ck.defaultKeyBundle().getEncryptionKey());
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.HistoryRecord;
|
import org.mozilla.gecko.sync.repositories.domain.HistoryRecord;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.Record;
|
import org.mozilla.gecko.sync.repositories.domain.Record;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -109,8 +110,8 @@ public class TestCryptoRecord {
|
||||||
payload.put("hmac", base16Hmac);
|
payload.put("hmac", base16Hmac);
|
||||||
body.put("payload", payload.toJSONString());
|
body.put("payload", payload.toJSONString());
|
||||||
CryptoRecord record = CryptoRecord.fromJSONRecord(body);
|
CryptoRecord record = CryptoRecord.fromJSONRecord(body);
|
||||||
byte[] decodedKey = Base64.decodeBase64(base64EncryptionKey.getBytes("UTF-8"));
|
byte[] decodedKey = Base64.decodeBase64(base64EncryptionKey.getBytes(StringUtils.UTF_8));
|
||||||
byte[] decodedHMAC = Base64.decodeBase64(base64HmacKey.getBytes("UTF-8"));
|
byte[] decodedHMAC = Base64.decodeBase64(base64HmacKey.getBytes(StringUtils.UTF_8));
|
||||||
record.keyBundle = new KeyBundle(decodedKey, decodedHMAC);
|
record.keyBundle = new KeyBundle(decodedKey, decodedHMAC);
|
||||||
|
|
||||||
record.decrypt();
|
record.decrypt();
|
||||||
|
@ -125,14 +126,14 @@ public class TestCryptoRecord {
|
||||||
String user = "c6o7dvmr2c4ud2fyv6woz2u4zi22bcyd";
|
String user = "c6o7dvmr2c4ud2fyv6woz2u4zi22bcyd";
|
||||||
|
|
||||||
// Check our friendly base32 decoding.
|
// Check our friendly base32 decoding.
|
||||||
assertTrue(Arrays.equals(Utils.decodeFriendlyBase32(key), Base64.decodeBase64("8xbKrJfQYwbFkguKmlSm/g==".getBytes("UTF-8"))));
|
assertTrue(Arrays.equals(Utils.decodeFriendlyBase32(key), Base64.decodeBase64("8xbKrJfQYwbFkguKmlSm/g==".getBytes(StringUtils.UTF_8))));
|
||||||
KeyBundle bundle = new KeyBundle(user, key);
|
KeyBundle bundle = new KeyBundle(user, key);
|
||||||
String expectedEncryptKeyBase64 = "/8RzbFT396htpZu5rwgIg2WKfyARgm7dLzsF5pwrVz8=";
|
String expectedEncryptKeyBase64 = "/8RzbFT396htpZu5rwgIg2WKfyARgm7dLzsF5pwrVz8=";
|
||||||
String expectedHMACKeyBase64 = "NChGjrqoXYyw8vIYP2334cvmMtsjAMUZNqFwV2LGNkM=";
|
String expectedHMACKeyBase64 = "NChGjrqoXYyw8vIYP2334cvmMtsjAMUZNqFwV2LGNkM=";
|
||||||
byte[] computedEncryptKey = bundle.getEncryptionKey();
|
byte[] computedEncryptKey = bundle.getEncryptionKey();
|
||||||
byte[] computedHMACKey = bundle.getHMACKey();
|
byte[] computedHMACKey = bundle.getHMACKey();
|
||||||
assertTrue(Arrays.equals(computedEncryptKey, Base64.decodeBase64(expectedEncryptKeyBase64.getBytes("UTF-8"))));
|
assertTrue(Arrays.equals(computedEncryptKey, Base64.decodeBase64(expectedEncryptKeyBase64.getBytes(StringUtils.UTF_8))));
|
||||||
assertTrue(Arrays.equals(computedHMACKey, Base64.decodeBase64(expectedHMACKeyBase64.getBytes("UTF-8"))));
|
assertTrue(Arrays.equals(computedHMACKey, Base64.decodeBase64(expectedHMACKeyBase64.getBytes(StringUtils.UTF_8))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -264,8 +265,8 @@ public class TestCryptoRecord {
|
||||||
JSONArray keys = new ExtendedJSONObject(decrypted.payload.toJSONString()).getArray("default");
|
JSONArray keys = new ExtendedJSONObject(decrypted.payload.toJSONString()).getArray("default");
|
||||||
KeyBundle keyBundle = KeyBundle.fromBase64EncodedKeys((String)keys.get(0), (String)keys.get(1));
|
KeyBundle keyBundle = KeyBundle.fromBase64EncodedKeys((String)keys.get(0), (String)keys.get(1));
|
||||||
|
|
||||||
assertArrayEquals(Base64.decodeBase64(expectedBase64EncryptionKey.getBytes("UTF-8")), keyBundle.getEncryptionKey());
|
assertArrayEquals(Base64.decodeBase64(expectedBase64EncryptionKey.getBytes(StringUtils.UTF_8)), keyBundle.getEncryptionKey());
|
||||||
assertArrayEquals(Base64.decodeBase64(expectedBase64HmacKey.getBytes("UTF-8")), keyBundle.getHMACKey());
|
assertArrayEquals(Base64.decodeBase64(expectedBase64HmacKey.getBytes(StringUtils.UTF_8)), keyBundle.getHMACKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.mozilla.gecko.fxa.login.FxAccountLoginStateMachine.LoginStateMachineD
|
||||||
import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.Transition;
|
import org.mozilla.gecko.fxa.login.FxAccountLoginTransition.Transition;
|
||||||
import org.mozilla.gecko.fxa.login.State.StateLabel;
|
import org.mozilla.gecko.fxa.login.State.StateLabel;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
@ -39,10 +40,10 @@ public class TestFxAccountLoginStateMachine {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
if (TEST_EMAIL_UTF8 == null) {
|
if (TEST_EMAIL_UTF8 == null) {
|
||||||
TEST_EMAIL_UTF8 = TEST_EMAIL.getBytes("UTF-8");
|
TEST_EMAIL_UTF8 = TEST_EMAIL.getBytes(StringUtils.UTF_8);
|
||||||
}
|
}
|
||||||
if (TEST_PASSWORD_UTF8 == null) {
|
if (TEST_PASSWORD_UTF8 == null) {
|
||||||
TEST_PASSWORD_UTF8 = TEST_PASSWORD.getBytes("UTF-8");
|
TEST_PASSWORD_UTF8 = TEST_PASSWORD.getBytes(StringUtils.UTF_8);
|
||||||
}
|
}
|
||||||
if (TEST_QUICK_STRETCHED_PW == null) {
|
if (TEST_QUICK_STRETCHED_PW == null) {
|
||||||
TEST_QUICK_STRETCHED_PW = FxAccountUtils.generateQuickStretchedPW(TEST_EMAIL_UTF8, TEST_PASSWORD_UTF8);
|
TEST_QUICK_STRETCHED_PW = FxAccountUtils.generateQuickStretchedPW(TEST_EMAIL_UTF8, TEST_PASSWORD_UTF8);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.sync.crypto.CryptoException;
|
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||||
import org.mozilla.gecko.sync.crypto.CryptoInfo;
|
import org.mozilla.gecko.sync.crypto.CryptoInfo;
|
||||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -24,17 +25,17 @@ import static org.junit.Assert.assertTrue;
|
||||||
public class TestCryptoInfo {
|
public class TestCryptoInfo {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncryptedHMACIsSet() throws CryptoException, UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
public void testEncryptedHMACIsSet() throws CryptoException, InvalidKeyException, NoSuchAlgorithmException {
|
||||||
KeyBundle kb = KeyBundle.withRandomKeys();
|
KeyBundle kb = KeyBundle.withRandomKeys();
|
||||||
CryptoInfo encrypted = CryptoInfo.encrypt("plaintext".getBytes("UTF-8"), kb);
|
CryptoInfo encrypted = CryptoInfo.encrypt("plaintext".getBytes(StringUtils.UTF_8), kb);
|
||||||
assertSame(kb, encrypted.getKeys());
|
assertSame(kb, encrypted.getKeys());
|
||||||
assertTrue(encrypted.generatedHMACIsHMAC());
|
assertTrue(encrypted.generatedHMACIsHMAC());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRandomEncryptedDecrypted() throws CryptoException, UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
public void testRandomEncryptedDecrypted() throws CryptoException, InvalidKeyException, NoSuchAlgorithmException {
|
||||||
KeyBundle kb = KeyBundle.withRandomKeys();
|
KeyBundle kb = KeyBundle.withRandomKeys();
|
||||||
byte[] plaintext = "plaintext".getBytes("UTF-8");
|
byte[] plaintext = "plaintext".getBytes(StringUtils.UTF_8);
|
||||||
CryptoInfo info = CryptoInfo.encrypt(plaintext, kb);
|
CryptoInfo info = CryptoInfo.encrypt(plaintext, kb);
|
||||||
byte[] iv = info.getIV();
|
byte[] iv = info.getIV();
|
||||||
info.decrypt();
|
info.decrypt();
|
||||||
|
@ -141,4 +142,4 @@ public class TestCryptoInfo {
|
||||||
assertArrayEquals(Base64.decodeBase64(base64CipherText), encrypted.getMessage());
|
assertArrayEquals(Base64.decodeBase64(base64CipherText), encrypted.getMessage());
|
||||||
assertArrayEquals(Utils.hex2Byte(base16Hmac), encrypted.getHMAC());
|
assertArrayEquals(Utils.hex2Byte(base16Hmac), encrypted.getHMAC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import org.junit.runner.RunWith;
|
||||||
import org.mozilla.apache.commons.codec.binary.Base64;
|
import org.mozilla.apache.commons.codec.binary.Base64;
|
||||||
import org.mozilla.gecko.sync.crypto.CryptoException;
|
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -30,8 +31,8 @@ public class TestKeyBundle {
|
||||||
"dKj0O+b0fwI=";
|
"dKj0O+b0fwI=";
|
||||||
|
|
||||||
KeyBundle keys = new KeyBundle(username, friendlyBase32SyncKey);
|
KeyBundle keys = new KeyBundle(username, friendlyBase32SyncKey);
|
||||||
assertArrayEquals(keys.getEncryptionKey(), Base64.decodeBase64(base64EncryptionKey.getBytes("UTF-8")));
|
assertArrayEquals(keys.getEncryptionKey(), Base64.decodeBase64(base64EncryptionKey.getBytes(StringUtils.UTF_8)));
|
||||||
assertArrayEquals(keys.getHMACKey(), Base64.decodeBase64(base64HmacKey.getBytes("UTF-8")));
|
assertArrayEquals(keys.getHMACKey(), Base64.decodeBase64(base64HmacKey.getBytes(StringUtils.UTF_8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class TestHMACAuthHeaderProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getSignature(String requestString, String key)
|
public static String getSignature(String requestString, String key)
|
||||||
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws InvalidKeyException, NoSuchAlgorithmException {
|
||||||
return HMACAuthHeaderProvider.getSignature(requestString, key);
|
return HMACAuthHeaderProvider.getSignature(requestString, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import ch.boye.httpclientandroidlib.protocol.BasicHttpContext;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
|
import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -46,7 +47,7 @@ public class TestHawkAuthHeaderProvider {
|
||||||
// Public for testing.
|
// Public for testing.
|
||||||
public static String getSignature(String requestString, String key)
|
public static String getSignature(String requestString, String key)
|
||||||
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
return HawkAuthHeaderProvider.getSignature(requestString.getBytes("UTF-8"), key.getBytes("UTF-8"));
|
return HawkAuthHeaderProvider.getSignature(requestString.getBytes(StringUtils.UTF_8), key.getBytes(StringUtils.UTF_8));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public for testing.
|
// Public for testing.
|
||||||
|
@ -106,7 +107,7 @@ public class TestHawkAuthHeaderProvider {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpecPayloadExample() throws Exception {
|
public void testSpecPayloadExample() throws Exception {
|
||||||
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes("UTF-8"));
|
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes(StringUtils.UTF_8));
|
||||||
URI uri = new URI("http://example.com:8000/resource/1?b=1&a=2");
|
URI uri = new URI("http://example.com:8000/resource/1?b=1&a=2");
|
||||||
HttpPost req = new HttpPost(uri);
|
HttpPost req = new HttpPost(uri);
|
||||||
String body = "Thank you for flying Hawk";
|
String body = "Thank you for flying Hawk";
|
||||||
|
@ -119,7 +120,7 @@ public class TestHawkAuthHeaderProvider {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpecAuthorizationHeader() throws Exception {
|
public void testSpecAuthorizationHeader() throws Exception {
|
||||||
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes("UTF-8"));
|
LeakyHawkAuthHeaderProvider provider = new LeakyHawkAuthHeaderProvider("dh37fgj492je", "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes(StringUtils.UTF_8));
|
||||||
URI uri = new URI("http://example.com:8000/resource/1?b=1&a=2");
|
URI uri = new URI("http://example.com:8000/resource/1?b=1&a=2");
|
||||||
HttpGet req = new HttpGet(uri);
|
HttpGet req = new HttpGet(uri);
|
||||||
Header header = provider.getAuthHeader(req, null, null, 1353832234L, "j4h3g2", "some-app-ext-data", false);
|
Header header = provider.getAuthHeader(req, null, null, 1353832234L, "j4h3g2", "some-app-ext-data", false);
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.mozilla.gecko.sync.net.BaseResourceDelegate;
|
||||||
import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
|
import org.mozilla.gecko.sync.net.HawkAuthHeaderProvider;
|
||||||
import org.mozilla.gecko.sync.net.Resource;
|
import org.mozilla.gecko.sync.net.Resource;
|
||||||
import org.mozilla.gecko.sync.net.SyncResponse;
|
import org.mozilla.gecko.sync.net.SyncResponse;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
@ -39,7 +40,7 @@ public class TestLiveHawkAuth {
|
||||||
public void testHawkUsage() throws Exception {
|
public void testHawkUsage() throws Exception {
|
||||||
// Id and credentials are hard-coded in example/usage.js.
|
// Id and credentials are hard-coded in example/usage.js.
|
||||||
final String id = "dh37fgj492je";
|
final String id = "dh37fgj492je";
|
||||||
final byte[] key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes("UTF-8");
|
final byte[] key = "werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn".getBytes(StringUtils.UTF_8);
|
||||||
final BaseResource resource = new BaseResource("http://localhost:8000/", false);
|
final BaseResource resource = new BaseResource("http://localhost:8000/", false);
|
||||||
|
|
||||||
// Basic GET.
|
// Basic GET.
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.mozilla.gecko.sync.net.SyncStorageResponse;
|
||||||
import org.mozilla.gecko.sync.repositories.FetchFailedException;
|
import org.mozilla.gecko.sync.repositories.FetchFailedException;
|
||||||
import org.mozilla.gecko.sync.repositories.StoreFailedException;
|
import org.mozilla.gecko.sync.repositories.StoreFailedException;
|
||||||
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
import org.mozilla.gecko.sync.repositories.domain.ClientRecord;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -51,7 +52,7 @@ public class TelemetryCollectorTest {
|
||||||
assertEquals(uid, bundle.get("uid"));
|
assertEquals(uid, bundle.get("uid"));
|
||||||
// Expect device ID to be hashed with the UID.
|
// Expect device ID to be hashed with the UID.
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Utils.byte2Hex(Utils.sha256(deviceID.concat(uid).getBytes("UTF-8"))),
|
Utils.byte2Hex(Utils.sha256(deviceID.concat(uid).getBytes(StringUtils.UTF_8))),
|
||||||
bundle.get("deviceID")
|
bundle.get("deviceID")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,7 @@ public class TelemetryCollectorTest {
|
||||||
ArrayList<Bundle> devices = data.getParcelableArrayList("devices");
|
ArrayList<Bundle> devices = data.getParcelableArrayList("devices");
|
||||||
assertEquals(1, devices.size());
|
assertEquals(1, devices.size());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes("UTF-8"))),
|
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes(StringUtils.UTF_8))),
|
||||||
devices.get(0).getString("id")
|
devices.get(0).getString("id")
|
||||||
);
|
);
|
||||||
assertEquals("iOS", devices.get(0).getString("os"));
|
assertEquals("iOS", devices.get(0).getString("os"));
|
||||||
|
@ -98,14 +99,14 @@ public class TelemetryCollectorTest {
|
||||||
assertEquals("iOS", devices.get(0).getString("os"));
|
assertEquals("iOS", devices.get(0).getString("os"));
|
||||||
assertEquals("1.33.7", devices.get(0).getString("version"));
|
assertEquals("1.33.7", devices.get(0).getString("version"));
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes("UTF-8"))),
|
Utils.byte2Hex(Utils.sha256("client1-guid".concat("hashed-uid").getBytes(StringUtils.UTF_8))),
|
||||||
devices.get(0).getString("id")
|
devices.get(0).getString("id")
|
||||||
);
|
);
|
||||||
|
|
||||||
assertEquals("Android", devices.get(1).getString("os"));
|
assertEquals("Android", devices.get(1).getString("os"));
|
||||||
assertEquals("55.0a1", devices.get(1).getString("version"));
|
assertEquals("55.0a1", devices.get(1).getString("version"));
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Utils.byte2Hex(Utils.sha256("client2-guid".concat("hashed-uid").getBytes("UTF-8"))),
|
Utils.byte2Hex(Utils.sha256("client2-guid".concat("hashed-uid").getBytes(StringUtils.UTF_8))),
|
||||||
devices.get(1).getString("id")
|
devices.get(1).getString("id")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -346,4 +347,4 @@ public class TelemetryCollectorTest {
|
||||||
assertEquals("othererror", error.getString("name"));
|
assertEquals("othererror", error.getString("name"));
|
||||||
assertEquals("store:IllegalStateException", error.getString("error"));
|
assertEquals("store:IllegalStateException", error.getString("error"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||||
import org.mozilla.gecko.sync.NonArrayJSONException;
|
import org.mozilla.gecko.sync.NonArrayJSONException;
|
||||||
import org.mozilla.gecko.sync.NonObjectJSONException;
|
import org.mozilla.gecko.sync.NonObjectJSONException;
|
||||||
import org.mozilla.gecko.sync.UnexpectedJSONException.BadRequiredFieldJSONException;
|
import org.mozilla.gecko.sync.UnexpectedJSONException.BadRequiredFieldJSONException;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -102,7 +103,7 @@ public class TestExtendedJSONObject {
|
||||||
public void testParseUTF8AsJSONObject() throws Exception {
|
public void testParseUTF8AsJSONObject() throws Exception {
|
||||||
String TEST = "{\"key\":\"value\"}";
|
String TEST = "{\"key\":\"value\"}";
|
||||||
|
|
||||||
ExtendedJSONObject o = ExtendedJSONObject.parseUTF8AsJSONObject(TEST.getBytes("UTF-8"));
|
ExtendedJSONObject o = ExtendedJSONObject.parseUTF8AsJSONObject(TEST.getBytes(StringUtils.UTF_8));
|
||||||
assertNotNull(o);
|
assertNotNull(o);
|
||||||
assertEquals("value", o.getString("key"));
|
assertEquals("value", o.getString("key"));
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ public class TestExtendedJSONObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ExtendedJSONObject.parseUTF8AsJSONObject("{".getBytes("UTF-8"));
|
ExtendedJSONObject.parseUTF8AsJSONObject("{".getBytes(StringUtils.UTF_8));
|
||||||
fail();
|
fail();
|
||||||
} catch (NonObjectJSONException e) {
|
} catch (NonObjectJSONException e) {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.mozilla.gecko.db.BrowserDB;
|
||||||
import org.mozilla.gecko.db.URLMetadata;
|
import org.mozilla.gecko.db.URLMetadata;
|
||||||
import org.mozilla.gecko.db.URLImageDataTable;
|
import org.mozilla.gecko.db.URLImageDataTable;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import android.content.ContentProviderOperation;
|
import android.content.ContentProviderOperation;
|
||||||
import android.content.ContentProviderResult;
|
import android.content.ContentProviderResult;
|
||||||
|
@ -195,7 +196,7 @@ public class testBrowserProvider extends ContentProviderTest {
|
||||||
|
|
||||||
faviconEntry.put(BrowserContract.Favicons.PAGE_URL, pageUrl);
|
faviconEntry.put(BrowserContract.Favicons.PAGE_URL, pageUrl);
|
||||||
faviconEntry.put(BrowserContract.Favicons.URL, pageUrl + "/favicon.ico");
|
faviconEntry.put(BrowserContract.Favicons.URL, pageUrl + "/favicon.ico");
|
||||||
faviconEntry.put(BrowserContract.Favicons.DATA, data.getBytes("UTF8"));
|
faviconEntry.put(BrowserContract.Favicons.DATA, data.getBytes(StringUtils.UTF_8));
|
||||||
|
|
||||||
return faviconEntry;
|
return faviconEntry;
|
||||||
}
|
}
|
||||||
|
@ -204,7 +205,7 @@ public class testBrowserProvider extends ContentProviderTest {
|
||||||
ContentValues thumbnailEntry = new ContentValues();
|
ContentValues thumbnailEntry = new ContentValues();
|
||||||
|
|
||||||
thumbnailEntry.put(BrowserContract.Thumbnails.URL, pageUrl);
|
thumbnailEntry.put(BrowserContract.Thumbnails.URL, pageUrl);
|
||||||
thumbnailEntry.put(BrowserContract.Thumbnails.DATA, data.getBytes("UTF8"));
|
thumbnailEntry.put(BrowserContract.Thumbnails.DATA, data.getBytes(StringUtils.UTF_8));
|
||||||
|
|
||||||
return thumbnailEntry;
|
return thumbnailEntry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import org.mozilla.gecko.background.nativecode.NativeCrypto;
|
import org.mozilla.gecko.background.nativecode.NativeCrypto;
|
||||||
import org.mozilla.gecko.sync.Utils;
|
import org.mozilla.gecko.sync.Utils;
|
||||||
import org.mozilla.gecko.tests.helpers.GeckoHelper;
|
import org.mozilla.gecko.tests.helpers.GeckoHelper;
|
||||||
|
import org.mozilla.gecko.util.StringUtils;
|
||||||
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
@ -238,9 +239,9 @@ public class testNativeCrypto extends UITest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _testSHA256WithMultipleUpdatesFromStream() throws UnsupportedEncodingException {
|
private void _testSHA256WithMultipleUpdatesFromStream() {
|
||||||
final String input = "HelloWorldThisIsASuperLongStringThatIsReadAsAStreamOfBytes";
|
final String input = "HelloWorldThisIsASuperLongStringThatIsReadAsAStreamOfBytes";
|
||||||
final ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes("UTF-8"));
|
final ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes(StringUtils.UTF_8));
|
||||||
final String expected = "8b5cb76b80f7eb6fb83ee138bfd31e2922e71dd245daa21a8d9876e8dee9eef5";
|
final String expected = "8b5cb76b80f7eb6fb83ee138bfd31e2922e71dd245daa21a8d9876e8dee9eef5";
|
||||||
|
|
||||||
byte[] buffer = new byte[10];
|
byte[] buffer = new byte[10];
|
||||||
|
|
Загрузка…
Ссылка в новой задаче