diff options
author | Sandro Montanari <sandrom@google.com> | 2023-12-07 12:55:31 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2023-12-07 12:55:31 +0000 |
commit | e03f2fb6089aaf632b2a3d5c1031599da208e86f (patch) | |
tree | 327cd64236970105724abd56e35efce1e49f4208 | |
parent | aa33aca9424e142acdd03874beef0f4fb3d6b1f8 (diff) | |
parent | 38b09712cbeeac84a01f42c36e4fa773791ee163 (diff) | |
download | base-e03f2fb6089aaf632b2a3d5c1031599da208e86f.tar.gz |
Merge "Add CertificateTransparencyVerificationRequired to NetworkSecurityConfig" into main
7 files changed, 104 insertions, 8 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 9bcbd720358a..b44ff6c8e0ea 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -39342,6 +39342,7 @@ package android.security { public class NetworkSecurityPolicy { method public static android.security.NetworkSecurityPolicy getInstance(); + method @FlaggedApi("android.security.certificate_transparency_configuration") public boolean isCertificateTransparencyVerificationRequired(@NonNull String); method public boolean isCleartextTrafficPermitted(); method public boolean isCleartextTrafficPermitted(String); } diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java index 0c4eedab2fc0..e679d201c58f 100644 --- a/core/java/android/security/NetworkSecurityPolicy.java +++ b/core/java/android/security/NetworkSecurityPolicy.java @@ -16,6 +16,8 @@ package android.security; +import android.annotation.FlaggedApi; +import android.annotation.NonNull; import android.content.Context; import android.content.pm.PackageManager; import android.security.net.config.ApplicationConfig; @@ -26,9 +28,6 @@ import android.security.net.config.ManifestConfigSource; * * <p>Network stacks/components should honor this policy to make it possible to centrally control * the relevant aspects of network security behavior. - * - * <p>The policy currently consists of a single flag: whether cleartext network traffic is - * permitted. See {@link #isCleartextTrafficPermitted()}. */ public class NetworkSecurityPolicy { @@ -94,6 +93,22 @@ public class NetworkSecurityPolicy { } /** + * Returns {@code true} if Certificate Transparency information is required to be verified by + * the client in TLS connections to {@code hostname}. + * + * <p>See RFC6962 section 3.3 for more details. + * + * @param hostname hostname to check whether certificate transparency verification is required + * @return {@code true} if certificate transparency verification is required and {@code false} + * otherwise + */ + @FlaggedApi(Flags.FLAG_CERTIFICATE_TRANSPARENCY_CONFIGURATION) + public boolean isCertificateTransparencyVerificationRequired(@NonNull String hostname) { + return libcore.net.NetworkSecurityPolicy.getInstance() + .isCertificateTransparencyVerificationRequired(hostname); + } + + /** * Handle an update to the system or user certificate stores. * @hide */ diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index e94f23a6f4ce..ef1d682ee786 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -1,6 +1,13 @@ package: "android.security" flag { + name: "certificate_transparency_configuration" + namespace: "network_security" + description: "Enable certificate transparency setting in the network security config" + bug: "28746284" +} + +flag { name: "fsverity_api" namespace: "hardware_backed_security" description: "Feature flag for fs-verity API" diff --git a/core/java/android/security/net/config/ApplicationConfig.java b/core/java/android/security/net/config/ApplicationConfig.java index 801ecebc616f..4cc870bfb47a 100644 --- a/core/java/android/security/net/config/ApplicationConfig.java +++ b/core/java/android/security/net/config/ApplicationConfig.java @@ -16,10 +16,15 @@ package android.security.net.config; +import static android.security.Flags.certificateTransparencyConfiguration; + +import android.annotation.NonNull; import android.util.Pair; + import java.util.HashSet; import java.util.Locale; import java.util.Set; + import javax.net.ssl.X509TrustManager; /** @@ -147,6 +152,22 @@ public final class ApplicationConfig { return getConfigForHostname(hostname).isCleartextTrafficPermitted(); } + /** + * Returns {@code true} if Certificate Transparency information is required to be verified by + * the client in TLS connections to {@code hostname}. + * + * <p>See RFC6962 section 3.3 for more details. + * + * @param hostname hostname to check whether certificate transparency verification is required + * @return {@code true} if certificate transparency verification is required and {@code false} + * otherwise + */ + public boolean isCertificateTransparencyVerificationRequired(@NonNull String hostname) { + return certificateTransparencyConfiguration() + ? getConfigForHostname(hostname).isCertificateTransparencyVerificationRequired() + : NetworkSecurityConfig.DEFAULT_CERTIFICATE_TRANSPARENCY_VERIFICATION_REQUIRED; + } + public void handleTrustStorageUpdate() { synchronized(mLock) { // If the config is uninitialized then there is no work to be done to handle an update, diff --git a/core/java/android/security/net/config/ConfigNetworkSecurityPolicy.java b/core/java/android/security/net/config/ConfigNetworkSecurityPolicy.java index a708f5b57dc9..801b32b055aa 100644 --- a/core/java/android/security/net/config/ConfigNetworkSecurityPolicy.java +++ b/core/java/android/security/net/config/ConfigNetworkSecurityPolicy.java @@ -40,6 +40,6 @@ public class ConfigNetworkSecurityPolicy extends libcore.net.NetworkSecurityPoli @Override public boolean isCertificateTransparencyVerificationRequired(String hostname) { - return false; + return mConfig.isCertificateTransparencyVerificationRequired(hostname); } } diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java index 00872fb3b62d..129ae63ec9c0 100644 --- a/core/java/android/security/net/config/NetworkSecurityConfig.java +++ b/core/java/android/security/net/config/NetworkSecurityConfig.java @@ -38,9 +38,12 @@ public final class NetworkSecurityConfig { public static final boolean DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED = true; /** @hide */ public static final boolean DEFAULT_HSTS_ENFORCED = false; + /** @hide */ + public static final boolean DEFAULT_CERTIFICATE_TRANSPARENCY_VERIFICATION_REQUIRED = false; private final boolean mCleartextTrafficPermitted; private final boolean mHstsEnforced; + private final boolean mCertificateTransparencyVerificationRequired; private final PinSet mPins; private final List<CertificatesEntryRef> mCertificatesEntryRefs; private Set<TrustAnchor> mAnchors; @@ -48,10 +51,15 @@ public final class NetworkSecurityConfig { private NetworkSecurityTrustManager mTrustManager; private final Object mTrustManagerLock = new Object(); - private NetworkSecurityConfig(boolean cleartextTrafficPermitted, boolean hstsEnforced, - PinSet pins, List<CertificatesEntryRef> certificatesEntryRefs) { + private NetworkSecurityConfig( + boolean cleartextTrafficPermitted, + boolean hstsEnforced, + boolean certificateTransparencyVerificationRequired, + PinSet pins, + List<CertificatesEntryRef> certificatesEntryRefs) { mCleartextTrafficPermitted = cleartextTrafficPermitted; mHstsEnforced = hstsEnforced; + mCertificateTransparencyVerificationRequired = certificateTransparencyVerificationRequired; mPins = pins; mCertificatesEntryRefs = certificatesEntryRefs; // Sort the certificates entry refs so that all entries that override pins come before @@ -104,6 +112,11 @@ public final class NetworkSecurityConfig { return mHstsEnforced; } + // TODO(b/28746284): add exceptions for user-added certificates and enterprise overrides. + public boolean isCertificateTransparencyVerificationRequired() { + return mCertificateTransparencyVerificationRequired; + } + public PinSet getPins() { return mPins; } @@ -208,6 +221,9 @@ public final class NetworkSecurityConfig { private boolean mHstsEnforced = DEFAULT_HSTS_ENFORCED; private boolean mCleartextTrafficPermittedSet = false; private boolean mHstsEnforcedSet = false; + private boolean mCertificateTransparencyVerificationRequired = + DEFAULT_CERTIFICATE_TRANSPARENCY_VERIFICATION_REQUIRED; + private boolean mCertificateTransparencyVerificationRequiredSet = false; private Builder mParentBuilder; /** @@ -313,12 +329,35 @@ public final class NetworkSecurityConfig { return mCertificatesEntryRefs; } + Builder setCertificateTransparencyVerificationRequired(boolean required) { + mCertificateTransparencyVerificationRequired = required; + mCertificateTransparencyVerificationRequiredSet = true; + return this; + } + + private boolean getCertificateTransparencyVerificationRequired() { + if (mCertificateTransparencyVerificationRequiredSet) { + return mCertificateTransparencyVerificationRequired; + } + if (mParentBuilder != null) { + return mParentBuilder.getCertificateTransparencyVerificationRequired(); + } + return DEFAULT_CERTIFICATE_TRANSPARENCY_VERIFICATION_REQUIRED; + } + public NetworkSecurityConfig build() { boolean cleartextPermitted = getEffectiveCleartextTrafficPermitted(); boolean hstsEnforced = getEffectiveHstsEnforced(); + boolean certificateTransparencyVerificationRequired = + getCertificateTransparencyVerificationRequired(); PinSet pinSet = getEffectivePinSet(); List<CertificatesEntryRef> entryRefs = getEffectiveCertificatesEntryRefs(); - return new NetworkSecurityConfig(cleartextPermitted, hstsEnforced, pinSet, entryRefs); + return new NetworkSecurityConfig( + cleartextPermitted, + hstsEnforced, + certificateTransparencyVerificationRequired, + pinSet, + entryRefs); } } } diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java index 311a8d23b964..b1c14793bbbd 100644 --- a/core/java/android/security/net/config/XmlConfigSource.java +++ b/core/java/android/security/net/config/XmlConfigSource.java @@ -171,6 +171,11 @@ public class XmlConfigSource implements ConfigSource { return new Domain(domain, includeSubdomains); } + private boolean parseCertificateTransparency(XmlResourceParser parser) + throws IOException, XmlPullParserException, ParserException { + return parser.getAttributeBooleanValue(null, "enabled", false); + } + private CertificatesEntryRef parseCertificatesEntry(XmlResourceParser parser, boolean defaultOverridePins) throws IOException, XmlPullParserException, ParserException { @@ -226,7 +231,6 @@ public class XmlConfigSource implements ConfigSource { boolean seenPinSet = false; boolean seenTrustAnchors = false; boolean defaultOverridePins = configType == CONFIG_DEBUG; - String configName = parser.getName(); int outerDepth = parser.getDepth(); // Add this builder now so that this builder occurs before any of its children. This // makes the final build pass easier. @@ -279,6 +283,15 @@ public class XmlConfigSource implements ConfigSource { "Nested domain-config not allowed in " + getConfigString(configType)); } builders.addAll(parseConfigEntry(parser, seenDomains, builder, configType)); + } else if ("certificateTransparency".equals(tagName)) { + if (configType != CONFIG_BASE && configType != CONFIG_DOMAIN) { + throw new ParserException( + parser, + "certificateTransparency not allowed in " + + getConfigString(configType)); + } + builder.setCertificateTransparencyVerificationRequired( + parseCertificateTransparency(parser)); } else { XmlUtils.skipCurrentTag(parser); } |