blob: 85582abba05177be34f2c1c2736c29ba59fd39af [file] [log] [blame]
/**
* Copyright (C) 2022 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.remoteprovisioner;
import android.security.remoteprovisioning.AttestationPoolStatus;
import android.util.Log;
public class StatsProcessor {
public static final double LIMIT_SCALER = .4;
private static final String TAG = "RemoteProvisioningService.KeyPoolStats";
private StatsProcessor() {}
public static int calcMinUnassignedToTriggerProvisioning(int extraSignedKeysAvailable) {
return (int) Math.ceil(LIMIT_SCALER * extraSignedKeysAvailable);
}
/**
* Creates a PoolStats. Takes an {@Code AttestationPoolStatus} and calculates different
* pieces of status to inform the caller if any action needs to be taken to reprovision the pool
* and what action is needed in terms of keys to generate.
*
* @parameter pool the current status of the keypool in Keystore2
* @parameter extraSignedKeysAvailable how many extra attested keys should ideally be available
* for assignment.
* @return the PoolStats object describing higher level info about the state of the key pool.
*/
public static PoolStats processPool(
AttestationPoolStatus pool, int extraSignedKeysAvailable) {
PoolStats stats = new PoolStats();
stats.unattestedKeys = pool.total - pool.attested;
stats.keysInUse = pool.attested - pool.unassigned;
stats.idealTotalSignedKeys = stats.keysInUse + extraSignedKeysAvailable;
// If nothing is expiring, and the amount of available unassigned keys is sufficient,
// then do nothing. Otherwise, generate the complete amount of idealTotalSignedKeys. It will
// reduce network usage if the app just provisions an entire new batch in one go, rather
// than consistently grabbing just a few at a time as the expiration dates become
// misaligned.
stats.provisioningNeeded =
pool.unassigned - pool.expiring
<= calcMinUnassignedToTriggerProvisioning(extraSignedKeysAvailable);
if (!stats.provisioningNeeded) {
Log.i(TAG, "Sufficient keys are available, no CSR needed.");
stats.keysToGenerate = 0;
} else {
stats.keysToGenerate = Math.max(0, stats.idealTotalSignedKeys - stats.unattestedKeys);
}
return stats;
}
public static class PoolStats {
public int unattestedKeys;
public int keysInUse;
public int idealTotalSignedKeys;
public int keysToGenerate;
public boolean provisioningNeeded = true;
}
}