Index: components/cronet/android/api/src/org/chromium/net/CronetEngine.java |
diff --git a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java |
index 4307b35b1ab3cadd9e1a376a19a5b5614124d4c5..ca4cae7103025138f6c9dd43536d8e1d861c7163 100644 |
--- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java |
+++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java |
@@ -6,6 +6,7 @@ package org.chromium.net; |
import android.content.Context; |
import android.support.annotation.IntDef; |
+import android.util.Base64; |
import android.util.Log; |
import org.json.JSONArray; |
@@ -20,8 +21,11 @@ import java.net.Proxy; |
import java.net.URL; |
import java.net.URLConnection; |
import java.net.URLStreamHandlerFactory; |
+import java.util.Collection; |
+import java.util.HashSet; |
import java.util.List; |
import java.util.Map; |
+import java.util.Set; |
import java.util.concurrent.Executor; |
/** |
@@ -301,6 +305,61 @@ public abstract class CronetEngine { |
} |
/** |
+ * Adds public key pinning for a given host. |
+ * |
+ * @param hostName name of the host that should be pinned. |
mef
2015/11/02 17:56:56
that -> which public keys
kapishnikov
2015/11/02 22:45:48
Done.
|
+ * @param pinsSha256 a collection of SHA-256 pins. |
+ * @param includeSubdomains indicates whether the pinning policy should be applied to |
+ * subdomains of the host's domain name. |
+ * @return the builder to facilitate chaining. |
+ */ |
+ public Builder addPublicKeyPins( |
+ String hostName, Collection<byte[]> pinsSha256, boolean includeSubdomains) { |
+ // Validate the input |
+ if (hostName == null) { |
+ throw new NullPointerException("The hostname cannot be null"); |
+ } |
+ if (pinsSha256 == null) { |
+ throw new NullPointerException("The collection of SHA256 pins cannot be null"); |
+ } |
+ try { |
+ // Add HPKP_LIST json array element if it is not present |
+ JSONArray hpkpList = mConfig.optJSONArray(CronetEngineBuilderList.HPKP_LIST); |
+ if (hpkpList == null) { |
+ hpkpList = new JSONArray(); |
+ mConfig.put(CronetEngineBuilderList.HPKP_LIST, hpkpList); |
+ } |
+ |
+ // Convert the pint to BASE64 encoding. |
mef
2015/11/02 17:56:56
the pint?
kapishnikov
2015/11/02 22:45:49
Done.
|
+ Set<String> hashes = new HashSet<>(pinsSha256.size()); |
+ for (byte[] pinSha256 : pinsSha256) { |
+ hashes.add(convertSha256ToBase64WithPrefix(pinSha256)); |
+ } |
+ |
+ // Add new element to HPKP_LIST json array |
+ JSONObject hpkp = new JSONObject(); |
+ hpkp.put(CronetEngineBuilderList.HPKP_HOST, hostName); |
+ hpkp.put(CronetEngineBuilderList.HPKP_PIN_HASHES, new JSONArray(hashes)); |
+ hpkp.put(CronetEngineBuilderList.HPKP_INCLUDE_SUBDOMAINS, includeSubdomains); |
+ hpkpList.put(hpkp); |
+ } catch (JSONException e) { |
+ Log.e(TAG, "Unable to add public key pins", e); |
+ } |
+ return this; |
+ } |
+ |
+ /** |
+ * Converts a given SHA256 array of bytes to BASE64 encoding with the prefix. The format |
+ * corresponds to the format that is expected by net::HashValue class. |
+ * |
+ * @param sha256 SHA256 bytes to convert to BASE64. |
+ * @return the BASE64 conversion, |
+ */ |
+ private String convertSha256ToBase64WithPrefix(byte[] sha256) { |
+ return "sha256/" + Base64.encodeToString(sha256, Base64.NO_WRAP); |
mef
2015/11/02 17:56:56
add validation that sha256 is 32 bytes long?
kapishnikov
2015/11/02 22:45:49
Done.
|
+ } |
+ |
+ /** |
* Sets experimental QUIC connection options, overwriting any pre-existing |
* options. List of options is subject to change. |
* |