Support converting EapTtlsConfig to/from PersistableBundle am: 4f4708bc74 am: afeaab72c5
Original change: https://android-review.googlesource.com/c/platform/packages/modules/IPsec/+/1493167
Change-Id: I6ddb7c9ddf14af837b2ffd19bbf086459c52405f
diff --git a/src/java/android/net/eap/EapSessionConfig.java b/src/java/android/net/eap/EapSessionConfig.java
index 25ecfac..7ab7a8a 100644
--- a/src/java/android/net/eap/EapSessionConfig.java
+++ b/src/java/android/net/eap/EapSessionConfig.java
@@ -30,8 +30,10 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.eap.message.EapData.EapMethod;
+import com.android.internal.net.ipsec.ike.utils.IkeCertUtils;
import com.android.server.vcn.util.PersistableBundleUtils;
+import java.security.cert.CertificateEncodingException;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
@@ -375,6 +377,8 @@
return EapAkaPrimeConfig.fromPersistableBundle(in);
case EAP_TYPE_MSCHAP_V2:
return EapMsChapV2Config.fromPersistableBundle(in);
+ case EAP_TYPE_TTLS:
+ return EapTtlsConfig.fromPersistableBundle(in);
default:
throw new IllegalArgumentException("Invalid EAP Type: " + methodType);
}
@@ -745,6 +749,9 @@
* @hide
*/
public static class EapTtlsConfig extends EapMethodConfig {
+ private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY";
+ private static final String EAP_SESSION_CONFIG_KEY = "EAP_SESSION_CONFIG_KEY";
+
@Nullable private final TrustAnchor mOverrideTrustAnchor;
@NonNull private final EapSessionConfig mInnerEapSessionConfig;
@@ -767,6 +774,58 @@
: new TrustAnchor(serverCaCert, null /* nameConstraints */);
}
+ /**
+ * Constructs this object by deserializing a PersistableBundle.
+ *
+ * @hide
+ */
+ @NonNull
+ public static EapTtlsConfig fromPersistableBundle(@NonNull PersistableBundle in) {
+ Objects.requireNonNull(in, "PersistableBundle is null");
+
+ PersistableBundle trustCertBundle = in.getPersistableBundle(TRUST_CERT_KEY);
+ X509Certificate caCert = null;
+ if (trustCertBundle != null) {
+ byte[] encodedCert = PersistableBundleUtils.toByteArray(trustCertBundle);
+ caCert = IkeCertUtils.certificateFromByteArray(encodedCert);
+ }
+
+ PersistableBundle eapSessionConfigBundle =
+ in.getPersistableBundle(EAP_SESSION_CONFIG_KEY);
+ Objects.requireNonNull(eapSessionConfigBundle, "eapSessionConfigBundle is null");
+ EapSessionConfig eapSessionConfig =
+ EapSessionConfig.fromPersistableBundle(eapSessionConfigBundle);
+
+ return new EapTtlsConfig(caCert, eapSessionConfig);
+ }
+
+ /**
+ * Serializes this object to a PersistableBundle.
+ *
+ * @hide
+ */
+ @Override
+ @NonNull
+ protected PersistableBundle toPersistableBundle() {
+ final PersistableBundle result = super.toPersistableBundle();
+
+ try {
+ if (mOverrideTrustAnchor != null) {
+ result.putPersistableBundle(
+ TRUST_CERT_KEY,
+ PersistableBundleUtils.fromByteArray(
+ mOverrideTrustAnchor.getTrustedCert().getEncoded()));
+ }
+
+ result.putPersistableBundle(
+ EAP_SESSION_CONFIG_KEY, mInnerEapSessionConfig.toPersistableBundle());
+ } catch (CertificateEncodingException e) {
+ throw new IllegalArgumentException("Fail to encode the certificate");
+ }
+
+ return result;
+ }
+
/** @hide */
@Override
public boolean isEapOnlySafeMethod() {
@@ -795,6 +854,31 @@
public EapSessionConfig getInnerEapSessionConfig() {
return mInnerEapSessionConfig;
}
+
+ /** @hide */
+ @Override
+ public int hashCode() {
+ // Use #getTrustedCert() because TrustAnchor does not override #hashCode()
+ return Objects.hash(
+ super.hashCode(),
+ mOverrideTrustAnchor.getTrustedCert(),
+ mInnerEapSessionConfig);
+ }
+
+ /** @hide */
+ @Override
+ public boolean equals(Object o) {
+ if (!super.equals(o) || !(o instanceof EapTtlsConfig)) {
+ return false;
+ }
+
+ EapTtlsConfig other = (EapTtlsConfig) o;
+
+ return Objects.equals(
+ mOverrideTrustAnchor.getTrustedCert(),
+ other.mOverrideTrustAnchor.getTrustedCert())
+ && Objects.equals(mInnerEapSessionConfig, other.mInnerEapSessionConfig);
+ }
}
/**
diff --git a/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java b/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
index 02eb97c..906b446 100644
--- a/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
+++ b/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
@@ -166,6 +166,15 @@
assertEquals(trustedCa, config.getServerCaCert());
}
+ @Test
+ public void testPersistableBundleEncodeDecodeEapTtls() throws Exception {
+ EapSessionConfig innerConfig =
+ new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
+ X509Certificate trustedCa = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
+
+ verifyPersistableBundleEncodeDecodeIsLossless(new EapTtlsConfig(trustedCa, innerConfig));
+ }
+
@Test(expected = NullPointerException.class)
public void testSetEapIdentityNull() {
new EapSessionConfig.Builder().setEapIdentity(null);