-
-
Save anonymous/077471026fa975186876 to your computer and use it in GitHub Desktop.
diff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
## | |
# diffing platform/build | |
## | |
# | |
diff --git a/core/build_id.mk b/core/build_id.mk | |
index 73a3313..cf00cee 100644 | |
--- a/core/build_id.mk | |
+++ b/core/build_id.mk | |
@@ -18,4 +18,4 @@ | |
# (like "CRB01"). It must be a single word, and is | |
# capitalized by convention. | |
-export BUILD_ID=LRX21T | |
+export BUILD_ID=LRX21V | |
# | |
## | |
# diffing platform/external/chromium_org | |
## | |
# | |
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java | |
index 7e64190..ec49dc0 100644 | |
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java | |
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java | |
@@ -20,6 +20,7 @@ import android.net.http.SslCertificate; | |
import android.os.AsyncTask; | |
import android.os.Build; | |
import android.os.Bundle; | |
+import android.os.Handler; | |
import android.os.Message; | |
import android.text.TextUtils; | |
import android.util.Log; | |
@@ -52,6 +53,7 @@ import org.chromium.content.browser.ContentViewStatics; | |
import org.chromium.content.browser.LoadUrlParams; | |
import org.chromium.content.browser.NavigationHistory; | |
import org.chromium.content.browser.PageTransitionTypes; | |
+import org.chromium.content.browser.SmartClipProvider; | |
import org.chromium.content.common.CleanupReference; | |
import org.chromium.content_public.Referrer; | |
import org.chromium.content_public.browser.GestureStateListener; | |
@@ -77,7 +79,7 @@ import java.util.concurrent.Callable; | |
* continuous build & test in the open source SDK-based tree). | |
*/ | |
@JNINamespace("android_webview") | |
-public class AwContents { | |
+public class AwContents implements SmartClipProvider { | |
private static final String TAG = "AwContents"; | |
private static final String WEB_ARCHIVE_EXTENSION = ".mht"; | |
@@ -2167,12 +2169,34 @@ public class AwContents { | |
return null; | |
} | |
+ @Override | |
public void extractSmartClipData(int x, int y, int width, int height) { | |
mContentViewCore.extractSmartClipData(x, y, width, height); | |
} | |
- public void setSmartClipDataListener(ContentViewCore.SmartClipDataListener listener) { | |
- mContentViewCore.setSmartClipDataListener(listener); | |
+ @Override | |
+ public void setSmartClipResultHandler(final Handler resultHandler) { | |
+ if (resultHandler == null) { | |
+ mContentViewCore.setSmartClipDataListener(null); | |
+ return; | |
+ } | |
+ mContentViewCore.setSmartClipDataListener(new ContentViewCore.SmartClipDataListener() { | |
+ public void onSmartClipDataExtracted(String text, String html, Rect clipRect) { | |
+ Bundle bundle = new Bundle(); | |
+ bundle.putString("url", mContentViewCore.getWebContents().getVisibleUrl()); | |
+ bundle.putString("title", mContentViewCore.getWebContents().getTitle()); | |
+ bundle.putParcelable("rect", clipRect); | |
+ bundle.putString("text", text); | |
+ bundle.putString("html", html); | |
+ try { | |
+ Message msg = Message.obtain(resultHandler, 0); | |
+ msg.setData(bundle); | |
+ msg.sendToTarget(); | |
+ } catch (Exception e) { | |
+ Log.e(TAG, "Error calling handler for smart clip data: ", e); | |
+ } | |
+ } | |
+ }); | |
} | |
// -------------------------------------------------------------------------------------------- | |
# | |
## | |
# diffing platform/frameworks/base | |
## | |
# | |
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java | |
index 7edf4b9..fdc54ae 100644 | |
--- a/core/java/android/content/pm/Signature.java | |
+++ b/core/java/android/content/pm/Signature.java | |
@@ -22,12 +22,14 @@ import android.os.Parcelable; | |
import com.android.internal.util.ArrayUtils; | |
import java.io.ByteArrayInputStream; | |
+import java.io.InputStream; | |
import java.lang.ref.SoftReference; | |
import java.security.PublicKey; | |
import java.security.cert.Certificate; | |
import java.security.cert.CertificateEncodingException; | |
import java.security.cert.CertificateException; | |
import java.security.cert.CertificateFactory; | |
+import java.security.cert.X509Certificate; | |
import java.util.Arrays; | |
/** | |
@@ -252,4 +254,53 @@ public class Signature implements Parcelable { | |
return (a.length == b.length) && ArrayUtils.containsAll(a, b) | |
&& ArrayUtils.containsAll(b, a); | |
} | |
+ | |
+ /** | |
+ * Test if given {@link Signature} sets are effectively equal. In rare | |
+ * cases, certificates can have slightly malformed encoding which causes | |
+ * exact-byte checks to fail. | |
+ * <p> | |
+ * To identify effective equality, we bounce the certificates through an | |
+ * decode/encode pass before doing the exact-byte check. To reduce attack | |
+ * surface area, we only allow a byte size delta of a few bytes. | |
+ * | |
+ * @throws CertificateException if the before/after length differs | |
+ * substantially, usually a signal of something fishy going on. | |
+ * @hide | |
+ */ | |
+ public static boolean areEffectiveMatch(Signature[] a, Signature[] b) | |
+ throws CertificateException { | |
+ final CertificateFactory cf = CertificateFactory.getInstance("X.509"); | |
+ | |
+ final Signature[] aPrime = new Signature[a.length]; | |
+ for (int i = 0; i < a.length; i++) { | |
+ aPrime[i] = bounce(cf, a[i]); | |
+ } | |
+ final Signature[] bPrime = new Signature[b.length]; | |
+ for (int i = 0; i < b.length; i++) { | |
+ bPrime[i] = bounce(cf, b[i]); | |
+ } | |
+ | |
+ return areExactMatch(aPrime, bPrime); | |
+ } | |
+ | |
+ /** | |
+ * Bounce the given {@link Signature} through a decode/encode cycle. | |
+ * | |
+ * @throws CertificateException if the before/after length differs | |
+ * substantially, usually a signal of something fishy going on. | |
+ * @hide | |
+ */ | |
+ public static Signature bounce(CertificateFactory cf, Signature s) throws CertificateException { | |
+ final InputStream is = new ByteArrayInputStream(s.mSignature); | |
+ final X509Certificate cert = (X509Certificate) cf.generateCertificate(is); | |
+ final Signature sPrime = new Signature(cert.getEncoded()); | |
+ | |
+ if (Math.abs(sPrime.mSignature.length - s.mSignature.length) > 2) { | |
+ throw new CertificateException("Bounced cert length looks fishy; before " | |
+ + s.mSignature.length + ", after " + sPrime.mSignature.length); | |
+ } | |
+ | |
+ return sPrime; | |
+ } | |
} | |
diff --git a/core/tests/coretests/src/android/content/pm/SignatureTest.java b/core/tests/coretests/src/android/content/pm/SignatureTest.java | |
new file mode 100644 | |
index 0000000..89d5997 | |
--- /dev/null | |
+++ b/core/tests/coretests/src/android/content/pm/SignatureTest.java | |
@@ -0,0 +1,57 @@ | |
+/* | |
+ * Copyright (C) 2014 The Android Open Source Project | |
+ * | |
+ * Licensed under the Apache License, Version 2.0 (the "License"); | |
+ * you may not use this file except in compliance with the License. | |
+ * You may obtain a copy of the License at | |
+ * | |
+ * http://www.apache.org/licenses/LICENSE-2.0 | |
+ * | |
+ * Unless required by applicable law or agreed to in writing, software | |
+ * distributed under the License is distributed on an "AS IS" BASIS, | |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
+ * See the License for the specific language governing permissions and | |
+ * limitations under the License. | |
+ */ | |
+ | |
+package android.content.pm; | |
+ | |
+import junit.framework.TestCase; | |
+ | |
+public class SignatureTest extends TestCase { | |
+ | |
+ /** Cert A with valid syntax */ | |
+ private static final Signature A = new Signature("308201D33082013CA0030201020219373565373461363A31336534333439623635343A2D38303030300D06092A864886F70D01010505003017311530130603550403130C6269736F6E416E64726F6964301E170D3133303432343232323134345A170D3338303432353232323134345A3017311530130603550403130C6269736F6E416E64726F696430819F300D06092A864886F70D010101050003818D00308189028181009214CE08563B77FF3128D3A303254287301263A842D19D5D4EAF024EBEDF864F3802C215B2F3EA85432F3EFF1DB8F591B0854FA7C1C6E4A8A85132FA762CC2D12A8EBD34D8B15C241A91716577F03BB3D2AFFC24367AB1E5E03C387891E34E646E47FAD75B178C1FD077B9199B3ABA6D48E2464801F6592E98245124046E51A90203010001A317301530130603551D25040C300A06082B06010505070303300D06092A864886F70D0101050500038181000B71581EDDC20E8C18C1C140BEE72501A97E04CA12030C51D4C38767B6A9FB5155CF4858C565EF77E5E2C22687C1AAB04BBA2B81C9A73CFB8DE118B624094AAE43D8FC2D585D90839DAFA5033AF7B8C0DE27E6ADAE44C40508CE493E9C80F1F5DA9EC87ECA1844BAB12C83CC8EB5937E1BE36A42CD22086A826E00FB763CD577"); | |
+ /** Cert A with malformed syntax */ | |
+ private static final Signature M = new Signature("308201D43082013CA0030201020219373565373461363A31336534333439623635343A2D38303030300D06092A864886F70D01010505003017311530130603550403130C6269736F6E416E64726F6964301E170D3133303432343232323134345A170D3338303432353232323134345A3017311530130603550403130C6269736F6E416E64726F696430819F300D06092A864886F70D010101050003818D00308189028181009214CE08563B77FF3128D3A303254287301263A842D19D5D4EAF024EBEDF864F3802C215B2F3EA85432F3EFF1DB8F591B0854FA7C1C6E4A8A85132FA762CC2D12A8EBD34D8B15C241A91716577F03BB3D2AFFC24367AB1E5E03C387891E34E646E47FAD75B178C1FD077B9199B3ABA6D48E2464801F6592E98245124046E51A90203010001A317301530130603551D25040C300A06082B06010505070303300D06092A864886F70D010105050003820081000B71581EDDC20E8C18C1C140BEE72501A97E04CA12030C51D4C38767B6A9FB5155CF4858C565EF77E5E2C22687C1AAB04BBA2B81C9A73CFB8DE118B624094AAE43D8FC2D585D90839DAFA5033AF7B8C0DE27E6ADAE44C40508CE493E9C80F1F5DA9EC87ECA1844BAB12C83CC8EB5937E1BE36A42CD22086A826E00FB763CD577"); | |
+ /** Cert B with valid syntax */ | |
+ private static final Signature B = new Signature("308204a830820390a003020102020900a1573d0f45bea193300d06092a864886f70d0101050500308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d301e170d3131303931393138343232355a170d3339303230343138343232355a308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d30820120300d06092a864886f70d01010105000382010d00308201080282010100de1b51336afc909d8bcca5920fcdc8940578ec5c253898930e985481cfdea75ba6fc54b1f7bb492a03d98db471ab4200103a8314e60ee25fef6c8b83bc1b2b45b084874cffef148fa2001bb25c672b6beba50b7ac026b546da762ea223829a22b80ef286131f059d2c9b4ca71d54e515a8a3fd6bf5f12a2493dfc2619b337b032a7cf8bbd34b833f2b93aeab3d325549a93272093943bb59dfc0197ae4861ff514e019b73f5cf10023ad1a032adb4b9bbaeb4debecb4941d6a02381f1165e1ac884c1fca9525c5854dce2ad8ec839b8ce78442c16367efc07778a337d3ca2cdf9792ac722b95d67c345f1c00976ec372f02bfcbef0262cc512a6845e71cfea0d020103a381fc3081f9301d0603551d0e0416041478a0fc4517fb70ff52210df33c8d32290a44b2bb3081c90603551d230481c13081be801478a0fc4517fb70ff52210df33c8d32290a44b2bba1819aa48197308194310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e20566965773110300e060355040a1307416e64726f69643110300e060355040b1307416e64726f69643110300e06035504031307416e64726f69643122302006092a864886f70d0109011613616e64726f696440616e64726f69642e636f6d820900a1573d0f45bea193300c0603551d13040530030101ff300d06092a864886f70d01010505000382010100977302dfbf668d7c61841c9c78d2563bcda1b199e95e6275a799939981416909722713531157f3cdcfea94eea7bb79ca3ca972bd8058a36ad1919291df42d7190678d4ea47a4b9552c9dfb260e6d0d9129b44615cd641c1080580e8a990dd768c6ab500c3b964e185874e4105109d94c5bd8c405deb3cf0f7960a563bfab58169a956372167a7e2674a04c4f80015d8f7869a7a4139aecbbdca2abc294144ee01e4109f0e47a518363cf6e9bf41f7560e94bdd4a5d085234796b05c7a1389adfd489feec2a107955129d7991daa49afb3d327dc0dc4fe959789372b093a89c8dbfa41554f771c18015a6cb242a17e04d19d55d3b4664eae12caf2a11cd2b836e"); | |
+ | |
+ public void testExactlyEqual() throws Exception { | |
+ assertTrue(Signature.areExactMatch(asArray(A), asArray(A))); | |
+ assertTrue(Signature.areExactMatch(asArray(M), asArray(M))); | |
+ | |
+ assertFalse(Signature.areExactMatch(asArray(A), asArray(B))); | |
+ assertFalse(Signature.areExactMatch(asArray(A), asArray(M))); | |
+ assertFalse(Signature.areExactMatch(asArray(M), asArray(A))); | |
+ | |
+ assertTrue(Signature.areExactMatch(asArray(A, M), asArray(M, A))); | |
+ } | |
+ | |
+ public void testEffectiveMatch() throws Exception { | |
+ assertTrue(Signature.areEffectiveMatch(asArray(A), asArray(A))); | |
+ assertTrue(Signature.areEffectiveMatch(asArray(M), asArray(M))); | |
+ | |
+ assertFalse(Signature.areEffectiveMatch(asArray(A), asArray(B))); | |
+ assertTrue(Signature.areEffectiveMatch(asArray(A), asArray(M))); | |
+ assertTrue(Signature.areEffectiveMatch(asArray(M), asArray(A))); | |
+ | |
+ assertTrue(Signature.areEffectiveMatch(asArray(A, M), asArray(M, A))); | |
+ assertTrue(Signature.areEffectiveMatch(asArray(A, B), asArray(M, B))); | |
+ assertFalse(Signature.areEffectiveMatch(asArray(A, M), asArray(A, B))); | |
+ } | |
+ | |
+ private static Signature[] asArray(Signature... s) { | |
+ return s; | |
+ } | |
+} | |
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java | |
index b79e157..3e1647e 100644 | |
--- a/services/core/java/com/android/server/pm/PackageManagerService.java | |
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java | |
@@ -2860,6 +2860,38 @@ public class PackageManagerService extends IPackageManager.Stub { | |
return PackageManager.SIGNATURE_NO_MATCH; | |
} | |
+ private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) { | |
+ if (isExternal(scannedPkg)) { | |
+ return mSettings.isExternalDatabaseVersionOlderThan( | |
+ DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); | |
+ } else { | |
+ return mSettings.isInternalDatabaseVersionOlderThan( | |
+ DatabaseVersion.SIGNATURE_MALFORMED_RECOVER); | |
+ } | |
+ } | |
+ | |
+ private int compareSignaturesRecover(PackageSignatures existingSigs, | |
+ PackageParser.Package scannedPkg) { | |
+ if (!isRecoverSignatureUpdateNeeded(scannedPkg)) { | |
+ return PackageManager.SIGNATURE_NO_MATCH; | |
+ } | |
+ | |
+ String msg = null; | |
+ try { | |
+ if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) { | |
+ logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for " | |
+ + scannedPkg.packageName); | |
+ return PackageManager.SIGNATURE_MATCH; | |
+ } | |
+ } catch (CertificateException e) { | |
+ msg = e.getMessage(); | |
+ } | |
+ | |
+ logCriticalInfo(Log.INFO, | |
+ "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg); | |
+ return PackageManager.SIGNATURE_NO_MATCH; | |
+ } | |
+ | |
@Override | |
public String[] getPackagesForUid(int uid) { | |
uid = UserHandle.getAppId(uid); | |
@@ -4148,7 +4180,8 @@ public class PackageManagerService extends IPackageManager.Stub { | |
if (ps != null | |
&& ps.codePath.equals(srcFile) | |
&& ps.timeStamp == srcFile.lastModified() | |
- && !isCompatSignatureUpdateNeeded(pkg)) { | |
+ && !isCompatSignatureUpdateNeeded(pkg) | |
+ && !isRecoverSignatureUpdateNeeded(pkg)) { | |
long mSigningKeySetId = ps.keySetData.getProperSigningKeySet(); | |
if (ps.signatures.mSignatures != null | |
&& ps.signatures.mSignatures.length != 0 | |
@@ -4423,6 +4456,10 @@ public class PackageManagerService extends IPackageManager.Stub { | |
== PackageManager.SIGNATURE_MATCH; | |
} | |
if (!match) { | |
+ match = compareSignaturesRecover(pkgSetting.signatures, pkg) | |
+ == PackageManager.SIGNATURE_MATCH; | |
+ } | |
+ if (!match) { | |
throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package " | |
+ pkg.packageName + " signatures do not match the " | |
+ "previously installed version; ignoring!"); | |
@@ -4439,6 +4476,10 @@ public class PackageManagerService extends IPackageManager.Stub { | |
== PackageManager.SIGNATURE_MATCH; | |
} | |
if (!match) { | |
+ match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg) | |
+ == PackageManager.SIGNATURE_MATCH; | |
+ } | |
+ if (!match) { | |
throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE, | |
"Package " + pkg.packageName | |
+ " has no signatures that match those in shared user " | |
@@ -5386,6 +5427,9 @@ public class PackageManagerService extends IPackageManager.Stub { | |
if (!pkgSetting.keySetData.isUsingUpgradeKeySets() || pkgSetting.sharedUser != null) { | |
try { | |
verifySignaturesLP(pkgSetting, pkg); | |
+ // We just determined the app is signed correctly, so bring | |
+ // over the latest parsed certs. | |
+ pkgSetting.signatures.mSignatures = pkg.mSignatures; | |
} catch (PackageManagerException e) { | |
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) { | |
throw e; | |
@@ -5418,7 +5462,8 @@ public class PackageManagerService extends IPackageManager.Stub { | |
+ pkg.packageName + " upgrade keys do not match the " | |
+ "previously installed version"); | |
} else { | |
- // signatures may have changed as result of upgrade | |
+ // We just determined the app is signed correctly, so bring | |
+ // over the latest parsed certs. | |
pkgSetting.signatures.mSignatures = pkg.mSignatures; | |
} | |
} | |
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java | |
index 7de56c8..699adef 100644 | |
--- a/services/core/java/com/android/server/pm/Settings.java | |
+++ b/services/core/java/com/android/server/pm/Settings.java | |
@@ -103,7 +103,7 @@ final class Settings { | |
* Note that care should be taken to make sure all database upgrades are | |
* idempotent. | |
*/ | |
- private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_END_ENTITY; | |
+ private static final int CURRENT_DATABASE_VERSION = DatabaseVersion.SIGNATURE_MALFORMED_RECOVER; | |
/** | |
* This class contains constants that can be referred to from upgrade code. | |
@@ -121,6 +121,14 @@ final class Settings { | |
* just the signing certificate. | |
*/ | |
public static final int SIGNATURE_END_ENTITY = 2; | |
+ | |
+ /** | |
+ * There was a window of time in | |
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP} where we persisted | |
+ * certificates after potentially mutating them. To switch back to the | |
+ * original untouched certificates, we need to force a collection pass. | |
+ */ | |
+ public static final int SIGNATURE_MALFORMED_RECOVER = 3; | |
} | |
private static final boolean DEBUG_STOPPED = false; | |
# | |
## | |
# diffing platform/frameworks/webview | |
## | |
# | |
diff --git a/chromium/java/com/android/webview/chromium/WebViewChromium.java b/chromium/java/com/android/webview/chromium/WebViewChromium.java | |
index a485bd2..76a11ca 100644 | |
--- a/chromium/java/com/android/webview/chromium/WebViewChromium.java | |
+++ b/chromium/java/com/android/webview/chromium/WebViewChromium.java | |
@@ -32,6 +32,7 @@ import android.net.http.SslCertificate; | |
import android.os.Build; | |
import android.os.Bundle; | |
import android.os.Looper; | |
+import android.os.Handler; | |
import android.os.Message; | |
import android.print.PrintDocumentAdapter; | |
import android.text.TextUtils; | |
@@ -71,6 +72,7 @@ import org.chromium.android_webview.AwSettings; | |
import org.chromium.android_webview.AwPrintDocumentAdapter; | |
import org.chromium.base.ThreadUtils; | |
import org.chromium.content.browser.LoadUrlParams; | |
+import org.chromium.content.browser.SmartClipProvider; | |
import org.chromium.net.NetworkChangeNotifier; | |
import java.io.BufferedWriter; | |
@@ -93,7 +95,7 @@ import java.util.Queue; | |
* and a small set of no-op deprecated APIs. | |
*/ | |
class WebViewChromium implements WebViewProvider, | |
- WebViewProvider.ScrollDelegate, WebViewProvider.ViewDelegate { | |
+ WebViewProvider.ScrollDelegate, WebViewProvider.ViewDelegate, SmartClipProvider { | |
private class WebViewChromiumRunQueue { | |
public WebViewChromiumRunQueue() { | |
@@ -2246,4 +2248,19 @@ class WebViewChromium implements WebViewProvider, | |
return mWebViewPrivate.super_onHoverEvent(event); | |
} | |
} | |
+ | |
+ // Implements SmartClipProvider | |
+ @Override | |
+ public void extractSmartClipData(int x, int y, int width, int height) { | |
+ checkThread(); | |
+ mAwContents.extractSmartClipData(x, y, width, height); | |
+ } | |
+ | |
+ // Implements SmartClipProvider | |
+ @Override | |
+ public void setSmartClipResultHandler(final Handler resultHandler) { | |
+ checkThread(); | |
+ mAwContents.setSmartClipResultHandler(resultHandler); | |
+ } | |
+ | |
} | |
diff --git a/chromium/proguard.flags b/chromium/proguard.flags | |
index 6401a8c..b19519f 100644 | |
--- a/chromium/proguard.flags | |
+++ b/chromium/proguard.flags | |
@@ -80,6 +80,12 @@ | |
*** startFinalizer(java.lang.Class,java.lang.Object); | |
} | |
+# Keep support framework support for SmartClip. | |
+-keep class com.android.webview.chromium.WebViewChromium { | |
+ public void extractSmartClipData(int,int,int,int); | |
+ public void setSmartClipResultHandler(android.os.Handler); | |
+} | |
+ | |
# We need to explicitly keep classes and constructors referenced only in | |
# layout resources. | |
-keep class com.android.org.chromium.ui.ColorPickerAdvanced { | |
# | |
## | |
# diffing platform/libcore | |
## | |
# | |
diff --git a/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java b/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java | |
index d11c8dd..e7f3596 100644 | |
--- a/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java | |
+++ b/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java | |
@@ -31,6 +31,7 @@ import java.security.NoSuchAlgorithmException; | |
import java.security.Principal; | |
import java.security.Signature; | |
import java.security.cert.Certificate; | |
+import java.security.cert.CertificateEncodingException; | |
import java.security.cert.CertificateFactory; | |
import java.security.cert.X509Certificate; | |
import java.util.ArrayList; | |
@@ -82,8 +83,10 @@ public class JarUtils { | |
CertificateFactory cf = CertificateFactory.getInstance("X.509"); | |
int i = 0; | |
for (org.apache.harmony.security.x509.Certificate encCert : encCerts) { | |
- final InputStream is = new ByteArrayInputStream(encCert.getEncoded()); | |
- certs[i++] = (X509Certificate) cf.generateCertificate(is); | |
+ final byte[] encoded = encCert.getEncoded(); | |
+ final InputStream is = new ByteArrayInputStream(encoded); | |
+ certs[i++] = new VerbatimX509Certificate((X509Certificate) cf.generateCertificate(is), | |
+ encoded); | |
} | |
List<SignerInfo> sigInfos = signedData.getSignerInfos(); | |
@@ -264,4 +267,22 @@ public class JarUtils { | |
return null; | |
} | |
+ /** | |
+ * For legacy reasons we need to return exactly the original encoded | |
+ * certificate bytes, instead of letting the underlying implementation have | |
+ * a shot at re-encoding the data. | |
+ */ | |
+ private static class VerbatimX509Certificate extends WrappedX509Certificate { | |
+ private byte[] encodedVerbatim; | |
+ | |
+ public VerbatimX509Certificate(X509Certificate wrapped, byte[] encodedVerbatim) { | |
+ super(wrapped); | |
+ this.encodedVerbatim = encodedVerbatim; | |
+ } | |
+ | |
+ @Override | |
+ public byte[] getEncoded() throws CertificateEncodingException { | |
+ return encodedVerbatim; | |
+ } | |
+ } | |
} | |
diff --git a/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java b/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java | |
new file mode 100644 | |
index 0000000..2b09309 | |
--- /dev/null | |
+++ b/luni/src/main/java/org/apache/harmony/security/utils/WrappedX509Certificate.java | |
@@ -0,0 +1,175 @@ | |
+/* | |
+ * Copyright (C) 2014 The Android Open Source Project | |
+ * | |
+ * Licensed under the Apache License, Version 2.0 (the "License"); | |
+ * you may not use this file except in compliance with the License. | |
+ * You may obtain a copy of the License at | |
+ * | |
+ * http://www.apache.org/licenses/LICENSE-2.0 | |
+ * | |
+ * Unless required by applicable law or agreed to in writing, software | |
+ * distributed under the License is distributed on an "AS IS" BASIS, | |
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
+ * See the License for the specific language governing permissions and | |
+ * limitations under the License. | |
+ */ | |
+ | |
+package org.apache.harmony.security.utils; | |
+ | |
+import java.math.BigInteger; | |
+import java.security.InvalidKeyException; | |
+import java.security.NoSuchAlgorithmException; | |
+import java.security.NoSuchProviderException; | |
+import java.security.Principal; | |
+import java.security.PublicKey; | |
+import java.security.SignatureException; | |
+import java.security.cert.CertificateEncodingException; | |
+import java.security.cert.CertificateException; | |
+import java.security.cert.CertificateExpiredException; | |
+import java.security.cert.CertificateNotYetValidException; | |
+import java.security.cert.X509Certificate; | |
+import java.util.Date; | |
+import java.util.Set; | |
+ | |
+public class WrappedX509Certificate extends X509Certificate { | |
+ private final X509Certificate wrapped; | |
+ | |
+ public WrappedX509Certificate(X509Certificate wrapped) { | |
+ this.wrapped = wrapped; | |
+ } | |
+ | |
+ @Override | |
+ public Set<String> getCriticalExtensionOIDs() { | |
+ return wrapped.getCriticalExtensionOIDs(); | |
+ } | |
+ | |
+ @Override | |
+ public byte[] getExtensionValue(String oid) { | |
+ return wrapped.getExtensionValue(oid); | |
+ } | |
+ | |
+ @Override | |
+ public Set<String> getNonCriticalExtensionOIDs() { | |
+ return wrapped.getNonCriticalExtensionOIDs(); | |
+ } | |
+ | |
+ @Override | |
+ public boolean hasUnsupportedCriticalExtension() { | |
+ return wrapped.hasUnsupportedCriticalExtension(); | |
+ } | |
+ | |
+ @Override | |
+ public void checkValidity() throws CertificateExpiredException, | |
+ CertificateNotYetValidException { | |
+ wrapped.checkValidity(); | |
+ } | |
+ | |
+ @Override | |
+ public void checkValidity(Date date) throws CertificateExpiredException, | |
+ CertificateNotYetValidException { | |
+ wrapped.checkValidity(date); | |
+ } | |
+ | |
+ @Override | |
+ public int getVersion() { | |
+ return wrapped.getVersion(); | |
+ } | |
+ | |
+ @Override | |
+ public BigInteger getSerialNumber() { | |
+ return wrapped.getSerialNumber(); | |
+ } | |
+ | |
+ @Override | |
+ public Principal getIssuerDN() { | |
+ return wrapped.getIssuerDN(); | |
+ } | |
+ | |
+ @Override | |
+ public Principal getSubjectDN() { | |
+ return wrapped.getSubjectDN(); | |
+ } | |
+ | |
+ @Override | |
+ public Date getNotBefore() { | |
+ return wrapped.getNotBefore(); | |
+ } | |
+ | |
+ @Override | |
+ public Date getNotAfter() { | |
+ return wrapped.getNotAfter(); | |
+ } | |
+ | |
+ @Override | |
+ public byte[] getTBSCertificate() throws CertificateEncodingException { | |
+ return wrapped.getTBSCertificate(); | |
+ } | |
+ | |
+ @Override | |
+ public byte[] getSignature() { | |
+ return wrapped.getSignature(); | |
+ } | |
+ | |
+ @Override | |
+ public String getSigAlgName() { | |
+ return wrapped.getSigAlgName(); | |
+ } | |
+ | |
+ @Override | |
+ public String getSigAlgOID() { | |
+ return wrapped.getSigAlgOID(); | |
+ } | |
+ | |
+ @Override | |
+ public byte[] getSigAlgParams() { | |
+ return wrapped.getSigAlgParams(); | |
+ } | |
+ | |
+ @Override | |
+ public boolean[] getIssuerUniqueID() { | |
+ return wrapped.getIssuerUniqueID(); | |
+ } | |
+ | |
+ @Override | |
+ public boolean[] getSubjectUniqueID() { | |
+ return wrapped.getSubjectUniqueID(); | |
+ } | |
+ | |
+ @Override | |
+ public boolean[] getKeyUsage() { | |
+ return wrapped.getKeyUsage(); | |
+ } | |
+ | |
+ @Override | |
+ public int getBasicConstraints() { | |
+ return wrapped.getBasicConstraints(); | |
+ } | |
+ | |
+ @Override | |
+ public byte[] getEncoded() throws CertificateEncodingException { | |
+ return wrapped.getEncoded(); | |
+ } | |
+ | |
+ @Override | |
+ public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, | |
+ InvalidKeyException, NoSuchProviderException, SignatureException { | |
+ wrapped.verify(key); | |
+ } | |
+ | |
+ @Override | |
+ public void verify(PublicKey key, String sigProvider) throws CertificateException, | |
+ NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, | |
+ SignatureException { | |
+ verify(key, sigProvider); | |
+ } | |
+ | |
+ @Override | |
+ public String toString() { | |
+ return wrapped.toString(); | |
+ } | |
+ | |
+ @Override | |
+ public PublicKey getPublicKey() { | |
+ return wrapped.getPublicKey(); | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment