Add daily CertificateTransparencyJob
Following a conversation with the Experiments team (b/374692404), it appears we will not be able to use device config flags to trigger the download of CT log lists. This CL is the first of a series that will allow us to move away from flags and instead rely on a daily job execution. For scheduling we rely on the Android AlarmManager. I previously attempted to schedule the daily job using the Android JobScheduler. However, those attempts were unsuccessful beacause the Tethering apex is not on the system_server classpath, so the system would crash when attempting to load the class to execute the job. Flag: com.android.net.ct.flags.certificate_transparency_job Bug: 374692404 Test: NetworkSecurityUnitTests Change-Id: I6ce44dcea464cab20d2df73b065e35c0f76dcbab
This commit is contained in:
parent
5c66824a44
commit
70c4de8edc
5 changed files with 129 additions and 13 deletions
|
|
@ -8,3 +8,12 @@ flag {
|
|||
bug: "319829948"
|
||||
is_fixed_read_only: true
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "certificate_transparency_job"
|
||||
is_exported: true
|
||||
namespace: "network_security"
|
||||
description: "Enable daily job service for certificate transparency instead of flags listener"
|
||||
bug: "319829948"
|
||||
is_fixed_read_only: true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,12 +88,17 @@ class CertificateTransparencyDownloader extends BroadcastReceiver {
|
|||
}
|
||||
|
||||
void setPublicKey(String publicKey) throws GeneralSecurityException {
|
||||
mPublicKey =
|
||||
Optional.of(
|
||||
KeyFactory.getInstance("RSA")
|
||||
.generatePublic(
|
||||
new X509EncodedKeySpec(
|
||||
Base64.getDecoder().decode(publicKey))));
|
||||
try {
|
||||
mPublicKey =
|
||||
Optional.of(
|
||||
KeyFactory.getInstance("RSA")
|
||||
.generatePublic(
|
||||
new X509EncodedKeySpec(
|
||||
Base64.getDecoder().decode(publicKey))));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Invalid public key Base64 encoding", e);
|
||||
mPublicKey = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
package com.android.server.net.ct;
|
||||
|
||||
import android.annotation.RequiresApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.DeviceConfig.Properties;
|
||||
|
|
@ -35,10 +34,11 @@ class CertificateTransparencyFlagsListener implements DeviceConfig.OnPropertiesC
|
|||
private final DataStore mDataStore;
|
||||
private final CertificateTransparencyDownloader mCertificateTransparencyDownloader;
|
||||
|
||||
CertificateTransparencyFlagsListener(Context context) {
|
||||
mDataStore = new DataStore(Config.PREFERENCES_FILE);
|
||||
mCertificateTransparencyDownloader =
|
||||
new CertificateTransparencyDownloader(context, mDataStore);
|
||||
CertificateTransparencyFlagsListener(
|
||||
DataStore dataStore,
|
||||
CertificateTransparencyDownloader certificateTransparencyDownloader) {
|
||||
mDataStore = dataStore;
|
||||
mCertificateTransparencyDownloader = certificateTransparencyDownloader;
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (C) 2024 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 com.android.server.net.ct;
|
||||
|
||||
import android.annotation.RequiresApi;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/** Implementation of the Certificate Transparency job */
|
||||
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
||||
public class CertificateTransparencyJob extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = "CertificateTransparencyJob";
|
||||
|
||||
private static final String ACTION_JOB_START = "com.android.server.net.ct.action.JOB_START";
|
||||
|
||||
private final Context mContext;
|
||||
private final DataStore mDataStore;
|
||||
private final CertificateTransparencyDownloader mCertificateTransparencyDownloader;
|
||||
// TODO(b/374692404): remove dependency to flags.
|
||||
private final CertificateTransparencyFlagsListener mFlagsListener;
|
||||
private final AlarmManager mAlarmManager;
|
||||
|
||||
/** Creates a new {@link CertificateTransparencyJob} object. */
|
||||
public CertificateTransparencyJob(
|
||||
Context context,
|
||||
DataStore dataStore,
|
||||
CertificateTransparencyDownloader certificateTransparencyDownloader,
|
||||
CertificateTransparencyFlagsListener flagsListener) {
|
||||
mContext = context;
|
||||
mFlagsListener = flagsListener;
|
||||
mDataStore = dataStore;
|
||||
mCertificateTransparencyDownloader = certificateTransparencyDownloader;
|
||||
mAlarmManager = context.getSystemService(AlarmManager.class);
|
||||
}
|
||||
|
||||
void initialize() {
|
||||
mDataStore.load();
|
||||
mCertificateTransparencyDownloader.initialize();
|
||||
|
||||
mContext.registerReceiver(
|
||||
this, new IntentFilter(ACTION_JOB_START), Context.RECEIVER_EXPORTED);
|
||||
mAlarmManager.setInexactRepeating(
|
||||
AlarmManager.ELAPSED_REALTIME,
|
||||
SystemClock.elapsedRealtime(), // schedule first job at earliest convenient time.
|
||||
AlarmManager.INTERVAL_DAY,
|
||||
PendingIntent.getBroadcast(
|
||||
mContext, 0, new Intent(ACTION_JOB_START), PendingIntent.FLAG_IMMUTABLE));
|
||||
|
||||
if (Config.DEBUG) {
|
||||
Log.d(TAG, "CertificateTransparencyJob scheduled successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!ACTION_JOB_START.equals(intent.getAction())) {
|
||||
Log.w(TAG, "Received unexpected broadcast with action " + intent);
|
||||
return;
|
||||
}
|
||||
mFlagsListener.onPropertiesChanged(
|
||||
new DeviceConfig.Properties(Config.NAMESPACE_NETWORK_SECURITY, new HashMap<>()));
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,10 @@ import com.android.server.SystemService;
|
|||
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
||||
public class CertificateTransparencyService extends ICertificateTransparencyManager.Stub {
|
||||
|
||||
private final DataStore mDataStore;
|
||||
private final CertificateTransparencyDownloader mCertificateTransparencyDownloader;
|
||||
private final CertificateTransparencyFlagsListener mFlagsListener;
|
||||
private final CertificateTransparencyJob mCertificateTransparencyJob;
|
||||
|
||||
/**
|
||||
* @return true if the CertificateTransparency service is enabled.
|
||||
|
|
@ -41,7 +44,15 @@ public class CertificateTransparencyService extends ICertificateTransparencyMana
|
|||
|
||||
/** Creates a new {@link CertificateTransparencyService} object. */
|
||||
public CertificateTransparencyService(Context context) {
|
||||
mFlagsListener = new CertificateTransparencyFlagsListener(context);
|
||||
mDataStore = new DataStore(Config.PREFERENCES_FILE);
|
||||
mCertificateTransparencyDownloader =
|
||||
new CertificateTransparencyDownloader(context, mDataStore);
|
||||
mFlagsListener =
|
||||
new CertificateTransparencyFlagsListener(
|
||||
mDataStore, mCertificateTransparencyDownloader);
|
||||
mCertificateTransparencyJob =
|
||||
new CertificateTransparencyJob(
|
||||
context, mDataStore, mCertificateTransparencyDownloader, mFlagsListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -53,7 +64,11 @@ public class CertificateTransparencyService extends ICertificateTransparencyMana
|
|||
|
||||
switch (phase) {
|
||||
case SystemService.PHASE_BOOT_COMPLETED:
|
||||
mFlagsListener.initialize();
|
||||
if (Flags.certificateTransparencyJob()) {
|
||||
mCertificateTransparencyJob.initialize();
|
||||
} else {
|
||||
mFlagsListener.initialize();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue