diff options
| author | 2018-12-11 11:46:02 +0000 | |
|---|---|---|
| committer | 2018-12-11 11:46:02 +0000 | |
| commit | 49b86ef6f064f43a0ec1261fdc55c2d9d6e8fee7 (patch) | |
| tree | 2c8a07145bb2af609f40ce3d47d8aa72a08824eb | |
| parent | 3a381f5c0d4f2c416f1a64ac7d44931644355364 (diff) | |
| parent | 1b1639dbc77d916f7f12bbffa526ab8819a65b8d (diff) | |
Merge "Apply signed config on package upgrade/install."
4 files changed, 87 insertions, 4 deletions
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index de6afcbad9a6..9380695f39c4 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -12852,6 +12852,13 @@ public final class Settings { public static final String HIDDEN_API_POLICY = "hidden_api_policy"; /** + * Current version of signed configuration applied. + * + * @hide + */ + public static final String SIGNED_CONFIG_VERSION = "signed_config_version"; + + /** * Timeout for a single {@link android.media.soundtrigger.SoundTriggerDetectionService} * operation (in ms). * diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 49a7555c2ac4..3a37fb627b26 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -415,6 +415,7 @@ public class SettingsBackupTest { Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, Settings.Global.SHOW_TEMPERATURE_WARNING, + Settings.Global.SIGNED_CONFIG_VERSION, Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL, Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL, Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java index 7ce071faab04..2312f5f0a2a2 100644 --- a/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java +++ b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java @@ -17,12 +17,86 @@ package com.android.server.signedconfig; import android.content.Context; +import android.os.Build; +import android.provider.Settings; +import android.util.ArraySet; +import android.util.Slog; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; +import java.util.Set; class SignedConfigApplicator { - static void applyConfig(Context context, String config, String signature) { - //TODO verify signature - //TODO parse & apply config + private static final String TAG = "SignedConfig"; + + private static final Set<String> ALLOWED_KEYS = Collections.unmodifiableSet(new ArraySet<>( + Arrays.asList( + Settings.Global.HIDDEN_API_POLICY, + Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS + ))); + + private final Context mContext; + private final String mSourcePackage; + + SignedConfigApplicator(Context context, String sourcePackage) { + mContext = context; + mSourcePackage = sourcePackage; } + private boolean checkSignature(String data, String signature) { + Slog.w(TAG, "SIGNATURE CHECK NOT IMPLEMENTED YET!"); + return false; + } + + private int getCurrentConfigVersion() { + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.SIGNED_CONFIG_VERSION, 0); + } + + private void updateCurrentConfig(int version, Map<String, String> values) { + for (Map.Entry<String, String> e: values.entrySet()) { + Settings.Global.putString( + mContext.getContentResolver(), + e.getKey(), + e.getValue()); + } + Settings.Global.putInt( + mContext.getContentResolver(), Settings.Global.SIGNED_CONFIG_VERSION, version); + } + + + void applyConfig(String configStr, String signature) { + if (!checkSignature(configStr, signature)) { + Slog.e(TAG, "Signature check on signed configuration in package " + mSourcePackage + + " failed; ignoring"); + return; + } + SignedConfig config; + try { + config = SignedConfig.parse(configStr, ALLOWED_KEYS); + } catch (InvalidConfigException e) { + Slog.e(TAG, "Failed to parse config from package " + mSourcePackage, e); + return; + } + int currentVersion = getCurrentConfigVersion(); + if (currentVersion >= config.version) { + Slog.i(TAG, "Config from package " + mSourcePackage + " is older than existing: " + + config.version + "<=" + currentVersion); + return; + } + // We have new config! + Slog.i(TAG, "Got new signed config from package " + mSourcePackage + ": version " + + config.version + " replacing existing version " + currentVersion); + SignedConfig.PerSdkConfig matchedConfig = + config.getMatchingConfig(Build.VERSION.SDK_INT); + if (matchedConfig == null) { + Slog.i(TAG, "Config is not applicable to current SDK version; ignoring"); + return; + } + + Slog.i(TAG, "Updating signed config to version " + config.version); + updateCurrentConfig(config.version, matchedConfig.values); + } } diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigService.java b/services/core/java/com/android/server/signedconfig/SignedConfigService.java index 148568628397..be1d41dd392b 100644 --- a/services/core/java/com/android/server/signedconfig/SignedConfigService.java +++ b/services/core/java/com/android/server/signedconfig/SignedConfigService.java @@ -85,7 +85,8 @@ public class SignedConfigService { Slog.d(TAG, "Got signed config: " + config); Slog.d(TAG, "Got config signature: " + signature); } - SignedConfigApplicator.applyConfig(mContext, config, signature); + new SignedConfigApplicator(mContext, packageName).applyConfig( + config, signature); } else { if (DBG) Slog.d(TAG, "Package has no config/signature."); } |