Log when an IOException when reading the public key, content or metadata
file for CT signature verification Flag: com.android.net.ct.flags.certificate_transparency_service Bug: 378626065 Test: atest NetworkSecurityUnitTests Change-Id: I2df5933f4cb39b82620f8bdd391ca800dfcf8ede
This commit is contained in:
parent
8590d2dfd9
commit
0bf58dac22
6 changed files with 60 additions and 12 deletions
|
|
@ -150,14 +150,7 @@ class CertificateTransparencyDownloader extends BroadcastReceiver {
|
|||
return;
|
||||
}
|
||||
|
||||
LogListUpdateStatus updateStatus;
|
||||
try {
|
||||
updateStatus = mSignatureVerifier.setPublicKeyFrom(publicKeyUri);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error setting the public Key", e);
|
||||
return;
|
||||
}
|
||||
|
||||
LogListUpdateStatus updateStatus = mSignatureVerifier.setPublicKeyFrom(publicKeyUri);
|
||||
if (!updateStatus.isPublicKeySet()) {
|
||||
mLogger.logCTLogListUpdateStateChangedEvent(updateStatus);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public interface CertificateTransparencyLogger {
|
|||
SIGNATURE_NOT_FOUND,
|
||||
SIGNATURE_VERIFICATION_FAILED,
|
||||
SUCCESS,
|
||||
UNABLE_TO_READ_FILE,
|
||||
VERSION_ALREADY_EXISTS
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFIC
|
|||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_SIGNATURE_NOT_FOUND;
|
||||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_SIGNATURE_VERIFICATION;
|
||||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_TOO_MANY_REDIRECTS;
|
||||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_UNABLE_TO_READ_FILE;
|
||||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_UNKNOWN;
|
||||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_VERSION_ALREADY_EXISTS;
|
||||
import static com.android.server.net.ct.CertificateTransparencyStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__PENDING_WAITING_FOR_WIFI;
|
||||
|
|
@ -149,6 +150,8 @@ class CertificateTransparencyLoggerImpl implements CertificateTransparencyLogger
|
|||
return CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_SIGNATURE_VERIFICATION;
|
||||
case SUCCESS:
|
||||
return CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__SUCCESS;
|
||||
case UNABLE_TO_READ_FILE:
|
||||
return CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_UNABLE_TO_READ_FILE;
|
||||
case VERSION_ALREADY_EXISTS:
|
||||
return CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED__UPDATE_STATUS__FAILURE_VERSION_ALREADY_EXISTS;
|
||||
case UNKNOWN_STATE:
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListU
|
|||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.SIGNATURE_NOT_FOUND;
|
||||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.SIGNATURE_VERIFICATION_FAILED;
|
||||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.SUCCESS;
|
||||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.UNABLE_TO_READ_FILE;
|
||||
|
||||
import com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState;
|
||||
|
||||
|
|
@ -45,7 +46,9 @@ public abstract class LogListUpdateStatus {
|
|||
|
||||
boolean isPublicKeySet() {
|
||||
// Check that none of the public key setting failures have been set as the state
|
||||
return state() != PUBLIC_KEY_INVALID && state() != PUBLIC_KEY_NOT_ALLOWED;
|
||||
return state() != PUBLIC_KEY_INVALID
|
||||
&& state() != PUBLIC_KEY_NOT_ALLOWED
|
||||
&& state() != UNABLE_TO_READ_FILE;
|
||||
}
|
||||
|
||||
boolean isSignatureVerified() {
|
||||
|
|
@ -53,7 +56,8 @@ public abstract class LogListUpdateStatus {
|
|||
return state() != PUBLIC_KEY_NOT_FOUND
|
||||
&& state() != SIGNATURE_INVALID
|
||||
&& state() != SIGNATURE_NOT_FOUND
|
||||
&& state() != SIGNATURE_VERIFICATION_FAILED;
|
||||
&& state() != SIGNATURE_VERIFICATION_FAILED
|
||||
&& state() != UNABLE_TO_READ_FILE;
|
||||
}
|
||||
|
||||
boolean hasSignature() {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListU
|
|||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.SIGNATURE_INVALID;
|
||||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.SIGNATURE_NOT_FOUND;
|
||||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.SIGNATURE_VERIFICATION_FAILED;
|
||||
import static com.android.server.net.ct.CertificateTransparencyLogger.CTLogListUpdateState.UNABLE_TO_READ_FILE;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.RequiresApi;
|
||||
|
|
@ -86,9 +87,12 @@ public class SignatureVerifier {
|
|||
mPublicKey = Optional.empty();
|
||||
}
|
||||
|
||||
LogListUpdateStatus setPublicKeyFrom(Uri file) throws IOException {
|
||||
LogListUpdateStatus setPublicKeyFrom(Uri file) {
|
||||
try (InputStream fileStream = mContext.getContentResolver().openInputStream(file)) {
|
||||
return setPublicKey(new String(fileStream.readAllBytes()));
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not read the public key file", e);
|
||||
return LogListUpdateStatus.builder().setState(UNABLE_TO_READ_FILE).build();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +157,11 @@ public class SignatureVerifier {
|
|||
Log.e(TAG, "Key invalid for log list verification", e);
|
||||
statusBuilder.setState(SIGNATURE_INVALID);
|
||||
return statusBuilder.build();
|
||||
} catch (IOException | GeneralSecurityException e) {
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not read log list file", e);
|
||||
statusBuilder.setState(UNABLE_TO_READ_FILE);
|
||||
return statusBuilder.build();
|
||||
} catch (GeneralSecurityException e) {
|
||||
Log.e(TAG, "Could not verify new log list", e);
|
||||
statusBuilder.setState(SIGNATURE_VERIFICATION_FAILED);
|
||||
return statusBuilder.build();
|
||||
|
|
|
|||
|
|
@ -182,6 +182,24 @@ public class CertificateTransparencyDownloaderTest {
|
|||
assertThat(mCertificateTransparencyDownloader.hasMetadataDownloadId()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloader_publicKeyDownloadSuccess_publicKeyFileNotRead_logsFailure()
|
||||
throws Exception {
|
||||
mCertificateTransparencyDownloader.startPublicKeyDownload();
|
||||
|
||||
File publicKeyFile = writePublicKeyToFile(mPublicKey);
|
||||
// Set the public key file to not be readable to simulate an IOException being thrown
|
||||
publicKeyFile.setReadable(false);
|
||||
mCertificateTransparencyDownloader.onReceive(
|
||||
mContext, makePublicKeyDownloadCompleteIntent(publicKeyFile));
|
||||
|
||||
verify(mLogger, times(1))
|
||||
.logCTLogListUpdateStateChangedEvent(
|
||||
LogListUpdateStatus.builder()
|
||||
.setState(CTLogListUpdateState.UNABLE_TO_READ_FILE)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
testDownloader_publicKeyDownloadSuccess_publicKeyNotAllowed_logsFailure()
|
||||
|
|
@ -400,6 +418,27 @@ public class CertificateTransparencyDownloaderTest {
|
|||
.isEqualTo(CTLogListUpdateState.PUBLIC_KEY_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloader_contentDownloadSuccess_signatureFileNotRead_logsSingleFailure()
|
||||
throws Exception {
|
||||
File logListFile = makeLogListFile("456");
|
||||
File metadataFile = sign(logListFile);
|
||||
mSignatureVerifier.setPublicKey(mPublicKey);
|
||||
mCertificateTransparencyDownloader.startMetadataDownload();
|
||||
|
||||
mCertificateTransparencyDownloader.onReceive(
|
||||
mContext, makeMetadataDownloadCompleteIntent(mCompatVersion, metadataFile));
|
||||
// Set the log list file to not be readable to simulate an IOException being thrown
|
||||
logListFile.setReadable(false);
|
||||
mCertificateTransparencyDownloader.onReceive(
|
||||
mContext, makeContentDownloadCompleteIntent(mCompatVersion, logListFile));
|
||||
|
||||
verify(mLogger, times(1))
|
||||
.logCTLogListUpdateStateChangedEvent(mUpdateStatusCaptor.capture());
|
||||
assertThat(mUpdateStatusCaptor.getValue().state())
|
||||
.isEqualTo(CTLogListUpdateState.UNABLE_TO_READ_FILE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDownloader_contentDownloadSuccess_wrongSignatureAlgo_logsSingleFailure()
|
||||
throws Exception {
|
||||
|
|
|
|||
Loading…
Reference in a new issue