Index: remoting/android/java/src/org/chromium/chromoting/ThirdPartyTokenFetcher.java |
diff --git a/remoting/android/java/src/org/chromium/chromoting/ThirdPartyTokenFetcher.java b/remoting/android/java/src/org/chromium/chromoting/ThirdPartyTokenFetcher.java |
index ac195cf617acbc1cbb598000b5dd1fa87c2dd55c..71a23f50bd8f70e7ec29ea0dbe42ffa86c2d221b 100644 |
--- a/remoting/android/java/src/org/chromium/chromoting/ThirdPartyTokenFetcher.java |
+++ b/remoting/android/java/src/org/chromium/chromoting/ThirdPartyTokenFetcher.java |
@@ -4,6 +4,7 @@ |
package org.chromium.chromoting; |
+import android.annotation.SuppressLint; |
import android.app.Activity; |
import android.content.ActivityNotFoundException; |
import android.content.ComponentName; |
@@ -14,6 +15,8 @@ import android.text.TextUtils; |
import android.util.Base64; |
import android.util.Log; |
+import java.io.FileInputStream; |
+import java.io.IOException; |
import java.security.SecureRandom; |
import java.util.ArrayList; |
@@ -38,8 +41,21 @@ public class ThirdPartyTokenFetcher { |
*/ |
private static final String RESPONSE_TYPE = "code token"; |
+ /** Used to initialize the random number generator. */ |
+ private static final int NUM_RANDOM_BYTES = 16; |
+ |
/** This is used to securely generate an opaque 128 bit for the |mState| variable. */ |
- private static SecureRandom sSecureRandom = new SecureRandom(); |
+ @SuppressLint("TrulyRandom") |
+ private static SecureRandom sSecureRandom; |
+ |
+ static { |
+ // Versions of SecureRandom from Android <= 4.3 do not seed themselves as |
+ // securely as possible. This workaround should suffice until the fixed version |
+ // is deployed to all users. It reads random data from /dev/urandom, which is as good as |
+ // the platform can get. |
+ sSecureRandom = new SecureRandom(); |
+ sSecureRandom.setSeed(getRandomBytes(NUM_RANDOM_BYTES)); |
kelvinp
2014/08/13 02:33:26
As discussed, maybe it is better to move the initi
Lambros
2014/08/13 23:48:51
Discussed offline. The refactoring to do this is n
|
+ } |
/** This is used to launch the third party login page in the browser. */ |
private Activity mContext; |
@@ -61,6 +77,28 @@ public class ThirdPartyTokenFetcher { |
private final String mRedirectUri; |
+ private static byte[] getRandomBytes(int numBytes) { |
+ FileInputStream fis = null; |
+ try { |
+ fis = new FileInputStream("/dev/urandom"); |
+ byte[] bytes = new byte[numBytes]; |
+ if (bytes.length != fis.read(bytes)) { |
+ throw new SecurityException("Failed to get enough random data."); |
+ } |
+ return bytes; |
+ } catch (IOException e) { |
+ throw new SecurityException("Error reading random data."); |
+ } finally { |
+ try { |
+ if (fis != null) { |
+ fis.close(); |
+ } |
+ } catch (IOException e) { |
+ // Ignore exception closing the device. |
+ } |
+ } |
+ } |
+ |
public ThirdPartyTokenFetcher(Activity context, |
ArrayList<String> tokenUrlPatterns, |
Callback callback) { |