From bbbe14387c8d60931fdb81f3df64ad5582f010e3 Mon Sep 17 00:00:00 2001 From: Kevin Lau Fang Date: Thu, 14 Nov 2019 20:06:19 +0000 Subject: Revert submission Reason for revert: This causes a boot issue on Taimen (b/144480969). It wasn't caught by TreeHugger due to Taimen tests being disabled due to a different lab outage (b/144350336). Change-Id: I3374b4ede6fd1e64284bad78d3b6d3c520a73e63 (cherry picked from commit 4ccf5a2aa0899fc37fca2f8f1102e41a58815047) --- service/java/com/android/server/wifi/hotspot2/SystemInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/java/com/android/server/wifi/hotspot2/SystemInfo.java b/service/java/com/android/server/wifi/hotspot2/SystemInfo.java index 374b8f5c0..e39eb185b 100644 --- a/service/java/com/android/server/wifi/hotspot2/SystemInfo.java +++ b/service/java/com/android/server/wifi/hotspot2/SystemInfo.java @@ -133,7 +133,7 @@ public class SystemInfo { * @return the build release version. */ public String getSoftwareVersion() { - return new StringBuffer("Android ").append(Build.VERSION.RELEASE_OR_CODENAME).toString(); + return new StringBuffer("Android ").append(Build.VERSION.RELEASE).toString(); } /** -- cgit v1.2.3 From 41a7999299a1c84652fbeddf98edb863e82aabf6 Mon Sep 17 00:00:00 2001 From: Hai Shalom Date: Wed, 22 Jul 2020 14:36:40 -0700 Subject: [WPA3-Enterprise] Fix connection issues to ECDSA networks Fix connection issues with ECDSA networks. The initialization of the Suite-B ciphers was not performed due to a bug in the logic that checked if KeyStore is required for the connection. Bug: 161570436 Test: atest WifiKeyStoreTest Test: Connect to WPA3-Enterprise 192-bit ECDSA and RSA networks Test: Connect to WPA2-Enterprise network Change-Id: I34489a69f91802cc9bf0c64ae3734ae237ead47b Merged-In: I34489a69f91802cc9bf0c64ae3734ae237ead47b (cherry picked from commit 27e757ab5d4c65462295b1a985eb823a8e1199d1) --- .../java/com/android/server/wifi/WifiKeyStore.java | 4 +- .../src/com/android/server/wifi/FakeKeys.java | 442 ++++++++++++++++++++- .../server/wifi/WifiConfigurationTestUtil.java | 19 + .../com/android/server/wifi/WifiKeyStoreTest.java | 64 ++- 4 files changed, 521 insertions(+), 8 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiKeyStore.java b/service/java/com/android/server/wifi/WifiKeyStore.java index d59dd1d47..70daa0d55 100644 --- a/service/java/com/android/server/wifi/WifiKeyStore.java +++ b/service/java/com/android/server/wifi/WifiKeyStore.java @@ -65,7 +65,9 @@ public class WifiKeyStore { // Certificate and private key management for EnterpriseConfig private static boolean needsKeyStore(WifiEnterpriseConfig config) { - return (config.getClientCertificate() != null || config.getCaCertificate() != null); + return (config.getClientCertificate() != null || config.getCaCertificate() != null + || config.getCaCertificateAlias() != null + || config.getClientCertificateAlias() != null); } private static boolean isHardwareBackedKey(Key key) { diff --git a/tests/wifitests/src/com/android/server/wifi/FakeKeys.java b/tests/wifitests/src/com/android/server/wifi/FakeKeys.java index 99ce196c8..5145b1345 100644 --- a/tests/wifitests/src/com/android/server/wifi/FakeKeys.java +++ b/tests/wifitests/src/com/android/server/wifi/FakeKeys.java @@ -196,7 +196,443 @@ public class FakeKeys { (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1, (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51 }; - public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1); + public static final PrivateKey RSA_KEY1 = loadPrivateKey("RSA", FAKE_RSA_KEY_1); + + private static final String CA_SUITE_B_RSA3072_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIEnTCCAwWgAwIBAgIUD87Y8fFLzLr1HQ/64aEnjNq2R/4wDQYJKoZIhvcNAQEM\n" + + "BQAwXjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAO\n" + + "BgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0\n" + + "Q0EwHhcNMjAwNzIxMDIxNzU0WhcNMzAwNTMwMDIxNzU0WjBeMQswCQYDVQQGEwJV\n" + + "UzELMAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEO\n" + + "MAwGA1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTCCAaIwDQYJKoZIhvcN\n" + + "AQEBBQADggGPADCCAYoCggGBAMtrsT0otlxh0QS079KpRRbU1PQjCihSoltXnrxF\n" + + "sTWZs2weVEeYVyYU5LaauCDDgISCMtjtfbfylMBeYjpWB5hYzYQOiTzo0anWhMyb\n" + + "Ngb7gpMVZuIl6lwMYRyVRKwHWnTo2EUg1ZzW5rGe5fs/KHj6//hoNFm+3Oju0TQd\n" + + "nraQULpoERPF5B7p85Cssk8uNbviBfZXvtCuJ4N6w7PNceOY/9bbwc1mC+pPZmzV\n" + + "SOAg0vvbIQRzChm63C3jBC3xmxSOOZVrKN4zKDG2s8P0oCNGt0NlgRMrgbPRekzg\n" + + "4avkbA0vTuc2AyriTEYkdea/Mt4EpRg9XuOb43U/GJ/d/vQv2/9fsxhXmsZrn8kr\n" + + "Qo5MMHJFUd96GgHmvYSU3Mf/5r8gF626lvqHioGuTAuHUSnr02ri1WUxZ15LDRgY\n" + + "quMjDCFZfucjJPDAdtiHcFSej/4SLJlN39z8oKKNPn3aL9Gv49oAKs9S8tfDVzMk\n" + + "fDLROQFHFuW715GnnMgEAoOpRwIDAQABo1MwUTAdBgNVHQ4EFgQUeVuGmSVN4ARs\n" + + "mesUMWSJ2qWLbxUwHwYDVR0jBBgwFoAUeVuGmSVN4ARsmesUMWSJ2qWLbxUwDwYD\n" + + "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwFAAOCAYEAit1Lo/hegZpPuT9dlWZJ\n" + + "bC8JvAf95O8lnn6LFb69pgYOHCLgCIlvYXu9rdBUJgZo+V1MzJJljiO6RxWRfKbQ\n" + + "8WBYkoqR1EqriR3Kn8q/SjIZCdFSaznTyU1wQMveBQ6RJWXSUhYVfE9RjyFTp7B4\n" + + "UyH2uCluR/0T06HQNGfH5XpIYQqCk1Zgng5lmEmheLDPoJpa92lKeQFJMC6eYz9g\n" + + "lF1GHxPxkPfbMJ6ZDp5X6Yopu6Q6uEXhVKM/iQVcgzRkx9rid+xTYl+nOKyK/XfC\n" + + "z8P0/TFIoPTW02DLge5wKagdoCpy1B7HdrAXyUjoH4B8MsUkq3kYPFSjPzScuTtV\n" + + "kUuDw5ipCNeXCRnhbYqRDk6PX5GUu2cmN9jtaH3tbgm3fKNOsd/BO1fLIl7qjXlR\n" + + "27HHbC0JXjNvlm2DLp23v4NTxS7WZGYsxyUj5DZrxBxqCsTXu/01w1BrQKWKh9FM\n" + + "aVrlA8omfVODK2CSuw+KhEMHepRv/AUgsLl4L4+RMoa+\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_SUITE_B_RSA3072_CERT = + loadCertificate(CA_SUITE_B_RSA3072_CERT_STRING); + + private static final String CA_SUITE_B_ECDSA_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIICTzCCAdSgAwIBAgIUdnLttwNPnQzFufplGOr9bTrGCqMwCgYIKoZIzj0EAwMw\n" + + "XjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNV\n" + + "BAoMB0FuZHJvaWQxDjAMBgNVBAsMBVdpLUZpMRIwEAYDVQQDDAl1bml0ZXN0Q0Ew\n" + + "HhcNMjAwNzIxMDIyNDA1WhcNMzAwNTMwMDIyNDA1WjBeMQswCQYDVQQGEwJVUzEL\n" + + "MAkGA1UECAwCQ0ExDDAKBgNVBAcMA01UVjEQMA4GA1UECgwHQW5kcm9pZDEOMAwG\n" + + "A1UECwwFV2ktRmkxEjAQBgNVBAMMCXVuaXRlc3RDQTB2MBAGByqGSM49AgEGBSuB\n" + + "BAAiA2IABFmntXwk9icqhDQFUP1xy04WyEpaGW4q6Q+8pujlSl/X3iotPZ++GZfp\n" + + "Mfv3YDHDBl6sELPQ2BEjyPXmpsKjOUdiUe69e88oGEdeqT2xXiQ6uzpTfJD4170i\n" + + "O/TwLrQGKKNTMFEwHQYDVR0OBBYEFCjptsX3g4g5W0L4oEP6N3gfyiZXMB8GA1Ud\n" + + "IwQYMBaAFCjptsX3g4g5W0L4oEP6N3gfyiZXMA8GA1UdEwEB/wQFMAMBAf8wCgYI\n" + + "KoZIzj0EAwMDaQAwZgIxAK61brUYRbLmQKiaEboZgrHtnPAcGo7Yzx3MwHecx3Dm\n" + + "5soIeLVYc8bPYN1pbhXW1gIxALdEe2sh03nBHyQH4adYoZungoCwt8mp/7sJFxou\n" + + "9UnRegyBgGzf74ROWdpZHzh+Pg==\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CA_SUITE_B_ECDSA_CERT = + loadCertificate(CA_SUITE_B_ECDSA_CERT_STRING); + + private static final String CLIENT_SUITE_B_RSA3072_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIERzCCAq8CFDopjyNgaj+c2TN2k06h7okEWpHJMA0GCSqGSIb3DQEBDAUAMF4x\n" + + "CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQK\n" + + "DAdBbmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4X\n" + + "DTIwMDcyMTAyMjkxMVoXDTMwMDUzMDAyMjkxMVowYjELMAkGA1UEBhMCVVMxCzAJ\n" + + "BgNVBAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNV\n" + + "BAsMBVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MIIBojANBgkqhkiG9w0B\n" + + "AQEFAAOCAY8AMIIBigKCAYEAwSK3C5K5udtCKTnE14e8z2cZvwmB4Xe+a8+7QLud\n" + + "Hooc/lQzClgK4MbVUC0D3FE+U32C78SxKoTaRWtvPmNm+UaFT8KkwyUno/dv+2XD\n" + + "pd/zARQ+3FwAfWopAhEyCVSxwsCa+slQ4juRIMIuUC1Mm0NaptZyM3Tj/ICQEfpk\n" + + "o9qVIbiK6eoJMTkY8EWfAn7RTFdfR1OLuO0mVOjgLW9/+upYv6hZ19nAMAxw4QTJ\n" + + "x7lLwALX7B+tDYNEZHDqYL2zyvQWAj2HClere8QYILxkvktgBg2crEJJe4XbDH7L\n" + + "A3rrXmsiqf1ZbfFFEzK9NFqovL+qGh+zIP+588ShJFO9H/RDnDpiTnAFTWXQdTwg\n" + + "szSS0Vw2PB+JqEABAa9DeMvXT1Oy+NY3ItPHyy63nQZVI2rXANw4NhwS0Z6DF+Qs\n" + + "TNrj+GU7e4SG/EGR8SvldjYfQTWFLg1l/UT1hOOkQZwdsaW1zgKyeuiFB2KdMmbA\n" + + "Sq+Ux1L1KICo0IglwWcB/8nnAgMBAAEwDQYJKoZIhvcNAQEMBQADggGBAMYwJkNw\n" + + "BaCviKFmReDTMwWPRy4AMNViEeqAXgERwDEKwM7efjsaj5gctWfKsxX6UdLzkhgg\n" + + "6S/T6PxVWKzJ6l7SoOuTa6tMQOZp+h3R1mdfEQbw8B5cXBxZ+batzAai6Fiy1FKS\n" + + "/ka3INbcGfYuIYghfTrb4/NJKN06ZaQ1bpPwq0e4gN7800T2nbawvSf7r+8ZLcG3\n" + + "6bGCjRMwDSIipNvOwoj3TG315XC7TccX5difQ4sKOY+d2MkVJ3RiO0Ciw2ZbEW8d\n" + + "1FH5vUQJWnBUfSFznosGzLwH3iWfqlP+27jNE+qB2igEwCRFgVAouURx5ou43xuX\n" + + "qf6JkdI3HTJGLIWxkp7gOeln4dEaYzKjYw+P0VqJvKVqQ0IXiLjHgE0J9p0vgyD6\n" + + "HVVcP7U8RgqrbIjL1QgHU4KBhGi+WSUh/mRplUCNvHgcYdcHi/gHpj/j6ubwqIGV\n" + + "z4iSolAHYTmBWcLyE0NgpzE6ntp+53r2KaUJA99l2iGVzbWTwqPSm0XAVw==\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CLIENT_SUITE_B_RSA3072_CERT = + loadCertificate(CLIENT_SUITE_B_RSA3072_CERT_STRING); + + private static final byte[] CLIENT_SUITE_B_RSA3072_KEY_DATA = new byte[]{ + (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xfe, (byte) 0x02, (byte) 0x01, + (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, + (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, + (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82, + (byte) 0x06, (byte) 0xe8, (byte) 0x30, (byte) 0x82, (byte) 0x06, (byte) 0xe4, + (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x82, (byte) 0x01, + (byte) 0x81, (byte) 0x00, (byte) 0xc1, (byte) 0x22, (byte) 0xb7, (byte) 0x0b, + (byte) 0x92, (byte) 0xb9, (byte) 0xb9, (byte) 0xdb, (byte) 0x42, (byte) 0x29, + (byte) 0x39, (byte) 0xc4, (byte) 0xd7, (byte) 0x87, (byte) 0xbc, (byte) 0xcf, + (byte) 0x67, (byte) 0x19, (byte) 0xbf, (byte) 0x09, (byte) 0x81, (byte) 0xe1, + (byte) 0x77, (byte) 0xbe, (byte) 0x6b, (byte) 0xcf, (byte) 0xbb, (byte) 0x40, + (byte) 0xbb, (byte) 0x9d, (byte) 0x1e, (byte) 0x8a, (byte) 0x1c, (byte) 0xfe, + (byte) 0x54, (byte) 0x33, (byte) 0x0a, (byte) 0x58, (byte) 0x0a, (byte) 0xe0, + (byte) 0xc6, (byte) 0xd5, (byte) 0x50, (byte) 0x2d, (byte) 0x03, (byte) 0xdc, + (byte) 0x51, (byte) 0x3e, (byte) 0x53, (byte) 0x7d, (byte) 0x82, (byte) 0xef, + (byte) 0xc4, (byte) 0xb1, (byte) 0x2a, (byte) 0x84, (byte) 0xda, (byte) 0x45, + (byte) 0x6b, (byte) 0x6f, (byte) 0x3e, (byte) 0x63, (byte) 0x66, (byte) 0xf9, + (byte) 0x46, (byte) 0x85, (byte) 0x4f, (byte) 0xc2, (byte) 0xa4, (byte) 0xc3, + (byte) 0x25, (byte) 0x27, (byte) 0xa3, (byte) 0xf7, (byte) 0x6f, (byte) 0xfb, + (byte) 0x65, (byte) 0xc3, (byte) 0xa5, (byte) 0xdf, (byte) 0xf3, (byte) 0x01, + (byte) 0x14, (byte) 0x3e, (byte) 0xdc, (byte) 0x5c, (byte) 0x00, (byte) 0x7d, + (byte) 0x6a, (byte) 0x29, (byte) 0x02, (byte) 0x11, (byte) 0x32, (byte) 0x09, + (byte) 0x54, (byte) 0xb1, (byte) 0xc2, (byte) 0xc0, (byte) 0x9a, (byte) 0xfa, + (byte) 0xc9, (byte) 0x50, (byte) 0xe2, (byte) 0x3b, (byte) 0x91, (byte) 0x20, + (byte) 0xc2, (byte) 0x2e, (byte) 0x50, (byte) 0x2d, (byte) 0x4c, (byte) 0x9b, + (byte) 0x43, (byte) 0x5a, (byte) 0xa6, (byte) 0xd6, (byte) 0x72, (byte) 0x33, + (byte) 0x74, (byte) 0xe3, (byte) 0xfc, (byte) 0x80, (byte) 0x90, (byte) 0x11, + (byte) 0xfa, (byte) 0x64, (byte) 0xa3, (byte) 0xda, (byte) 0x95, (byte) 0x21, + (byte) 0xb8, (byte) 0x8a, (byte) 0xe9, (byte) 0xea, (byte) 0x09, (byte) 0x31, + (byte) 0x39, (byte) 0x18, (byte) 0xf0, (byte) 0x45, (byte) 0x9f, (byte) 0x02, + (byte) 0x7e, (byte) 0xd1, (byte) 0x4c, (byte) 0x57, (byte) 0x5f, (byte) 0x47, + (byte) 0x53, (byte) 0x8b, (byte) 0xb8, (byte) 0xed, (byte) 0x26, (byte) 0x54, + (byte) 0xe8, (byte) 0xe0, (byte) 0x2d, (byte) 0x6f, (byte) 0x7f, (byte) 0xfa, + (byte) 0xea, (byte) 0x58, (byte) 0xbf, (byte) 0xa8, (byte) 0x59, (byte) 0xd7, + (byte) 0xd9, (byte) 0xc0, (byte) 0x30, (byte) 0x0c, (byte) 0x70, (byte) 0xe1, + (byte) 0x04, (byte) 0xc9, (byte) 0xc7, (byte) 0xb9, (byte) 0x4b, (byte) 0xc0, + (byte) 0x02, (byte) 0xd7, (byte) 0xec, (byte) 0x1f, (byte) 0xad, (byte) 0x0d, + (byte) 0x83, (byte) 0x44, (byte) 0x64, (byte) 0x70, (byte) 0xea, (byte) 0x60, + (byte) 0xbd, (byte) 0xb3, (byte) 0xca, (byte) 0xf4, (byte) 0x16, (byte) 0x02, + (byte) 0x3d, (byte) 0x87, (byte) 0x0a, (byte) 0x57, (byte) 0xab, (byte) 0x7b, + (byte) 0xc4, (byte) 0x18, (byte) 0x20, (byte) 0xbc, (byte) 0x64, (byte) 0xbe, + (byte) 0x4b, (byte) 0x60, (byte) 0x06, (byte) 0x0d, (byte) 0x9c, (byte) 0xac, + (byte) 0x42, (byte) 0x49, (byte) 0x7b, (byte) 0x85, (byte) 0xdb, (byte) 0x0c, + (byte) 0x7e, (byte) 0xcb, (byte) 0x03, (byte) 0x7a, (byte) 0xeb, (byte) 0x5e, + (byte) 0x6b, (byte) 0x22, (byte) 0xa9, (byte) 0xfd, (byte) 0x59, (byte) 0x6d, + (byte) 0xf1, (byte) 0x45, (byte) 0x13, (byte) 0x32, (byte) 0xbd, (byte) 0x34, + (byte) 0x5a, (byte) 0xa8, (byte) 0xbc, (byte) 0xbf, (byte) 0xaa, (byte) 0x1a, + (byte) 0x1f, (byte) 0xb3, (byte) 0x20, (byte) 0xff, (byte) 0xb9, (byte) 0xf3, + (byte) 0xc4, (byte) 0xa1, (byte) 0x24, (byte) 0x53, (byte) 0xbd, (byte) 0x1f, + (byte) 0xf4, (byte) 0x43, (byte) 0x9c, (byte) 0x3a, (byte) 0x62, (byte) 0x4e, + (byte) 0x70, (byte) 0x05, (byte) 0x4d, (byte) 0x65, (byte) 0xd0, (byte) 0x75, + (byte) 0x3c, (byte) 0x20, (byte) 0xb3, (byte) 0x34, (byte) 0x92, (byte) 0xd1, + (byte) 0x5c, (byte) 0x36, (byte) 0x3c, (byte) 0x1f, (byte) 0x89, (byte) 0xa8, + (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0xaf, (byte) 0x43, (byte) 0x78, + (byte) 0xcb, (byte) 0xd7, (byte) 0x4f, (byte) 0x53, (byte) 0xb2, (byte) 0xf8, + (byte) 0xd6, (byte) 0x37, (byte) 0x22, (byte) 0xd3, (byte) 0xc7, (byte) 0xcb, + (byte) 0x2e, (byte) 0xb7, (byte) 0x9d, (byte) 0x06, (byte) 0x55, (byte) 0x23, + (byte) 0x6a, (byte) 0xd7, (byte) 0x00, (byte) 0xdc, (byte) 0x38, (byte) 0x36, + (byte) 0x1c, (byte) 0x12, (byte) 0xd1, (byte) 0x9e, (byte) 0x83, (byte) 0x17, + (byte) 0xe4, (byte) 0x2c, (byte) 0x4c, (byte) 0xda, (byte) 0xe3, (byte) 0xf8, + (byte) 0x65, (byte) 0x3b, (byte) 0x7b, (byte) 0x84, (byte) 0x86, (byte) 0xfc, + (byte) 0x41, (byte) 0x91, (byte) 0xf1, (byte) 0x2b, (byte) 0xe5, (byte) 0x76, + (byte) 0x36, (byte) 0x1f, (byte) 0x41, (byte) 0x35, (byte) 0x85, (byte) 0x2e, + (byte) 0x0d, (byte) 0x65, (byte) 0xfd, (byte) 0x44, (byte) 0xf5, (byte) 0x84, + (byte) 0xe3, (byte) 0xa4, (byte) 0x41, (byte) 0x9c, (byte) 0x1d, (byte) 0xb1, + (byte) 0xa5, (byte) 0xb5, (byte) 0xce, (byte) 0x02, (byte) 0xb2, (byte) 0x7a, + (byte) 0xe8, (byte) 0x85, (byte) 0x07, (byte) 0x62, (byte) 0x9d, (byte) 0x32, + (byte) 0x66, (byte) 0xc0, (byte) 0x4a, (byte) 0xaf, (byte) 0x94, (byte) 0xc7, + (byte) 0x52, (byte) 0xf5, (byte) 0x28, (byte) 0x80, (byte) 0xa8, (byte) 0xd0, + (byte) 0x88, (byte) 0x25, (byte) 0xc1, (byte) 0x67, (byte) 0x01, (byte) 0xff, + (byte) 0xc9, (byte) 0xe7, (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, + (byte) 0x01, (byte) 0x02, (byte) 0x82, (byte) 0x01, (byte) 0x80, (byte) 0x04, + (byte) 0xb1, (byte) 0xcc, (byte) 0x53, (byte) 0x3a, (byte) 0xb0, (byte) 0xcb, + (byte) 0x04, (byte) 0xba, (byte) 0x59, (byte) 0xf8, (byte) 0x2e, (byte) 0x81, + (byte) 0xb2, (byte) 0xa9, (byte) 0xf3, (byte) 0x3c, (byte) 0xa5, (byte) 0x52, + (byte) 0x90, (byte) 0x6f, (byte) 0x98, (byte) 0xc4, (byte) 0x69, (byte) 0x5b, + (byte) 0x83, (byte) 0x84, (byte) 0x20, (byte) 0xb1, (byte) 0xae, (byte) 0xc3, + (byte) 0x04, (byte) 0x46, (byte) 0x6a, (byte) 0x24, (byte) 0x2f, (byte) 0xcd, + (byte) 0x6b, (byte) 0x90, (byte) 0x70, (byte) 0x20, (byte) 0x45, (byte) 0x25, + (byte) 0x1a, (byte) 0xc3, (byte) 0x02, (byte) 0x42, (byte) 0xf3, (byte) 0x49, + (byte) 0xe2, (byte) 0x3e, (byte) 0x21, (byte) 0x87, (byte) 0xdd, (byte) 0x6a, + (byte) 0x94, (byte) 0x2a, (byte) 0x1e, (byte) 0x0f, (byte) 0xdb, (byte) 0x77, + (byte) 0x5f, (byte) 0xc1, (byte) 0x2c, (byte) 0x03, (byte) 0xfb, (byte) 0xcf, + (byte) 0x91, (byte) 0x82, (byte) 0xa1, (byte) 0xbf, (byte) 0xb0, (byte) 0x73, + (byte) 0xfa, (byte) 0xda, (byte) 0xbc, (byte) 0xf8, (byte) 0x9f, (byte) 0x45, + (byte) 0xd3, (byte) 0xe8, (byte) 0xbb, (byte) 0x38, (byte) 0xfb, (byte) 0xc2, + (byte) 0x2d, (byte) 0x76, (byte) 0x51, (byte) 0x96, (byte) 0x18, (byte) 0x03, + (byte) 0x15, (byte) 0xd9, (byte) 0xea, (byte) 0x82, (byte) 0x25, (byte) 0x83, + (byte) 0xff, (byte) 0x5c, (byte) 0x85, (byte) 0x06, (byte) 0x09, (byte) 0xb2, + (byte) 0x46, (byte) 0x12, (byte) 0x64, (byte) 0x02, (byte) 0x74, (byte) 0x4f, + (byte) 0xbc, (byte) 0x9a, (byte) 0x25, (byte) 0x18, (byte) 0x01, (byte) 0x07, + (byte) 0x17, (byte) 0x25, (byte) 0x55, (byte) 0x7c, (byte) 0xdc, (byte) 0xe1, + (byte) 0xd1, (byte) 0x5a, (byte) 0x2f, (byte) 0x25, (byte) 0xaf, (byte) 0xf6, + (byte) 0x8f, (byte) 0xa4, (byte) 0x9a, (byte) 0x5a, (byte) 0x3a, (byte) 0xfe, + (byte) 0x2e, (byte) 0x93, (byte) 0x24, (byte) 0xa0, (byte) 0x27, (byte) 0xac, + (byte) 0x07, (byte) 0x75, (byte) 0x33, (byte) 0x01, (byte) 0x54, (byte) 0x23, + (byte) 0x0f, (byte) 0xe8, (byte) 0x9f, (byte) 0xfa, (byte) 0x36, (byte) 0xe6, + (byte) 0x3a, (byte) 0xd5, (byte) 0x78, (byte) 0xb0, (byte) 0xe4, (byte) 0x6a, + (byte) 0x16, (byte) 0x50, (byte) 0xbd, (byte) 0x0f, (byte) 0x9f, (byte) 0x32, + (byte) 0xa1, (byte) 0x6b, (byte) 0xf5, (byte) 0xa4, (byte) 0x34, (byte) 0x58, + (byte) 0xb6, (byte) 0xa4, (byte) 0xb3, (byte) 0xc3, (byte) 0x83, (byte) 0x08, + (byte) 0x18, (byte) 0xc7, (byte) 0xef, (byte) 0x95, (byte) 0xe2, (byte) 0x1b, + (byte) 0xba, (byte) 0x35, (byte) 0x61, (byte) 0xa3, (byte) 0xb4, (byte) 0x30, + (byte) 0xe0, (byte) 0xd1, (byte) 0xc1, (byte) 0xa2, (byte) 0x3a, (byte) 0xc6, + (byte) 0xb4, (byte) 0xd2, (byte) 0x80, (byte) 0x5a, (byte) 0xaf, (byte) 0xa4, + (byte) 0x54, (byte) 0x3c, (byte) 0x66, (byte) 0x5a, (byte) 0x1c, (byte) 0x4d, + (byte) 0xe1, (byte) 0xd9, (byte) 0x98, (byte) 0x44, (byte) 0x01, (byte) 0x1b, + (byte) 0x8c, (byte) 0xe9, (byte) 0x80, (byte) 0x54, (byte) 0x83, (byte) 0x3d, + (byte) 0x96, (byte) 0x25, (byte) 0x41, (byte) 0x1c, (byte) 0xad, (byte) 0xae, + (byte) 0x3b, (byte) 0x7a, (byte) 0xd7, (byte) 0x9d, (byte) 0x10, (byte) 0x7c, + (byte) 0xd1, (byte) 0xa7, (byte) 0x96, (byte) 0x39, (byte) 0xa5, (byte) 0x2f, + (byte) 0xbe, (byte) 0xc3, (byte) 0x2c, (byte) 0x64, (byte) 0x01, (byte) 0xfe, + (byte) 0xa2, (byte) 0xd1, (byte) 0x6a, (byte) 0xcf, (byte) 0x4c, (byte) 0x76, + (byte) 0x3b, (byte) 0xc8, (byte) 0x35, (byte) 0x21, (byte) 0xda, (byte) 0x98, + (byte) 0xcf, (byte) 0xf9, (byte) 0x29, (byte) 0xff, (byte) 0x30, (byte) 0x59, + (byte) 0x36, (byte) 0x53, (byte) 0x0b, (byte) 0xbb, (byte) 0xfa, (byte) 0xba, + (byte) 0xc4, (byte) 0x03, (byte) 0x23, (byte) 0xe0, (byte) 0xd3, (byte) 0x33, + (byte) 0xff, (byte) 0x32, (byte) 0xdb, (byte) 0x30, (byte) 0x64, (byte) 0xc7, + (byte) 0x56, (byte) 0xca, (byte) 0x55, (byte) 0x14, (byte) 0xee, (byte) 0x58, + (byte) 0xfe, (byte) 0x96, (byte) 0x7e, (byte) 0x1c, (byte) 0x34, (byte) 0x16, + (byte) 0xeb, (byte) 0x76, (byte) 0x26, (byte) 0x48, (byte) 0xe2, (byte) 0xe5, + (byte) 0x5c, (byte) 0xd5, (byte) 0x83, (byte) 0x37, (byte) 0xd9, (byte) 0x09, + (byte) 0x71, (byte) 0xbc, (byte) 0x54, (byte) 0x25, (byte) 0xca, (byte) 0x2e, + (byte) 0xdb, (byte) 0x36, (byte) 0x39, (byte) 0xcc, (byte) 0x3a, (byte) 0x81, + (byte) 0x95, (byte) 0x9e, (byte) 0xf4, (byte) 0x01, (byte) 0xa7, (byte) 0xc0, + (byte) 0x20, (byte) 0xce, (byte) 0x70, (byte) 0x55, (byte) 0x2c, (byte) 0xe0, + (byte) 0x93, (byte) 0x72, (byte) 0xa6, (byte) 0x25, (byte) 0xda, (byte) 0x64, + (byte) 0x19, (byte) 0x18, (byte) 0xd2, (byte) 0x31, (byte) 0xe2, (byte) 0x7c, + (byte) 0xf2, (byte) 0x30, (byte) 0x9e, (byte) 0x8d, (byte) 0xc6, (byte) 0x14, + (byte) 0x8a, (byte) 0x38, (byte) 0xf0, (byte) 0x94, (byte) 0xeb, (byte) 0xf4, + (byte) 0x64, (byte) 0x92, (byte) 0x3d, (byte) 0x67, (byte) 0xa6, (byte) 0x2c, + (byte) 0x52, (byte) 0xfc, (byte) 0x60, (byte) 0xca, (byte) 0x2a, (byte) 0xcf, + (byte) 0x24, (byte) 0xd5, (byte) 0x42, (byte) 0x5f, (byte) 0xc7, (byte) 0x9f, + (byte) 0xf3, (byte) 0xb4, (byte) 0xdf, (byte) 0x76, (byte) 0x6e, (byte) 0x53, + (byte) 0xa1, (byte) 0x7b, (byte) 0xae, (byte) 0xa5, (byte) 0x84, (byte) 0x1f, + (byte) 0xfa, (byte) 0xc0, (byte) 0xb4, (byte) 0x6c, (byte) 0xc9, (byte) 0x02, + (byte) 0x81, (byte) 0xc1, (byte) 0x00, (byte) 0xf3, (byte) 0x17, (byte) 0xd9, + (byte) 0x48, (byte) 0x17, (byte) 0x87, (byte) 0x84, (byte) 0x16, (byte) 0xea, + (byte) 0x2d, (byte) 0x31, (byte) 0x1b, (byte) 0xce, (byte) 0xec, (byte) 0xaf, + (byte) 0xdc, (byte) 0x6b, (byte) 0xaf, (byte) 0xc8, (byte) 0xf1, (byte) 0x40, + (byte) 0xa7, (byte) 0x4f, (byte) 0xef, (byte) 0x48, (byte) 0x08, (byte) 0x5e, + (byte) 0x9a, (byte) 0xd1, (byte) 0xc0, (byte) 0xb1, (byte) 0xfe, (byte) 0xe7, + (byte) 0x03, (byte) 0xd5, (byte) 0x96, (byte) 0x01, (byte) 0xe8, (byte) 0x40, + (byte) 0xca, (byte) 0x78, (byte) 0xcb, (byte) 0xb3, (byte) 0x28, (byte) 0x1a, + (byte) 0xf0, (byte) 0xe5, (byte) 0xf6, (byte) 0x46, (byte) 0xef, (byte) 0xcd, + (byte) 0x1a, (byte) 0x0f, (byte) 0x13, (byte) 0x2d, (byte) 0x38, (byte) 0xf8, + (byte) 0xf7, (byte) 0x88, (byte) 0x21, (byte) 0x15, (byte) 0xce, (byte) 0x48, + (byte) 0xf4, (byte) 0x92, (byte) 0x7e, (byte) 0x9b, (byte) 0x2e, (byte) 0x2f, + (byte) 0x22, (byte) 0x3e, (byte) 0x5c, (byte) 0x67, (byte) 0xd7, (byte) 0x58, + (byte) 0xf6, (byte) 0xef, (byte) 0x1f, (byte) 0xb4, (byte) 0x04, (byte) 0xc7, + (byte) 0xfd, (byte) 0x8c, (byte) 0x4e, (byte) 0x27, (byte) 0x9e, (byte) 0xb9, + (byte) 0xef, (byte) 0x0f, (byte) 0xf7, (byte) 0x4a, (byte) 0xc2, (byte) 0xf4, + (byte) 0x64, (byte) 0x6b, (byte) 0xe0, (byte) 0xfb, (byte) 0xe3, (byte) 0x45, + (byte) 0xd5, (byte) 0x37, (byte) 0xa0, (byte) 0x2a, (byte) 0xc6, (byte) 0xf3, + (byte) 0xf6, (byte) 0xcc, (byte) 0xb5, (byte) 0x94, (byte) 0xbf, (byte) 0x56, + (byte) 0xa0, (byte) 0x61, (byte) 0x36, (byte) 0x88, (byte) 0x35, (byte) 0xd5, + (byte) 0xa5, (byte) 0xad, (byte) 0x20, (byte) 0x48, (byte) 0xda, (byte) 0x70, + (byte) 0x35, (byte) 0xd9, (byte) 0x75, (byte) 0x66, (byte) 0xa5, (byte) 0xac, + (byte) 0x86, (byte) 0x7a, (byte) 0x75, (byte) 0x49, (byte) 0x88, (byte) 0x40, + (byte) 0xce, (byte) 0xb0, (byte) 0x6f, (byte) 0x57, (byte) 0x15, (byte) 0x54, + (byte) 0xd3, (byte) 0x2f, (byte) 0x11, (byte) 0x9b, (byte) 0xe3, (byte) 0x87, + (byte) 0xc8, (byte) 0x8d, (byte) 0x98, (byte) 0xc6, (byte) 0xe0, (byte) 0xbc, + (byte) 0x85, (byte) 0xb9, (byte) 0x04, (byte) 0x43, (byte) 0xa9, (byte) 0x41, + (byte) 0xce, (byte) 0x42, (byte) 0x1a, (byte) 0x57, (byte) 0x10, (byte) 0xd8, + (byte) 0xe4, (byte) 0x6a, (byte) 0x51, (byte) 0x10, (byte) 0x0a, (byte) 0xec, + (byte) 0xe4, (byte) 0x57, (byte) 0xc7, (byte) 0xee, (byte) 0xe9, (byte) 0xd6, + (byte) 0xcb, (byte) 0x3e, (byte) 0xba, (byte) 0xfa, (byte) 0xe9, (byte) 0x0e, + (byte) 0xed, (byte) 0x87, (byte) 0x04, (byte) 0x9a, (byte) 0x48, (byte) 0xba, + (byte) 0xaf, (byte) 0x08, (byte) 0xf5, (byte) 0x02, (byte) 0x81, (byte) 0xc1, + (byte) 0x00, (byte) 0xcb, (byte) 0x63, (byte) 0xd6, (byte) 0x54, (byte) 0xb6, + (byte) 0xf3, (byte) 0xf3, (byte) 0x8c, (byte) 0xf8, (byte) 0xd0, (byte) 0xd2, + (byte) 0x84, (byte) 0xc1, (byte) 0xf5, (byte) 0x12, (byte) 0xe0, (byte) 0x02, + (byte) 0x80, (byte) 0x42, (byte) 0x92, (byte) 0x4e, (byte) 0xa4, (byte) 0x5c, + (byte) 0xa5, (byte) 0x64, (byte) 0xec, (byte) 0xb7, (byte) 0xdc, (byte) 0xe0, + (byte) 0x2d, (byte) 0x5d, (byte) 0xac, (byte) 0x0e, (byte) 0x24, (byte) 0x48, + (byte) 0x13, (byte) 0x05, (byte) 0xe8, (byte) 0xff, (byte) 0x96, (byte) 0x93, + (byte) 0xba, (byte) 0x3c, (byte) 0x88, (byte) 0xcc, (byte) 0x80, (byte) 0xf9, + (byte) 0xdb, (byte) 0xa8, (byte) 0x4d, (byte) 0x86, (byte) 0x47, (byte) 0xc8, + (byte) 0xbf, (byte) 0x34, (byte) 0x2d, (byte) 0xda, (byte) 0xb6, (byte) 0x28, + (byte) 0xf0, (byte) 0x1e, (byte) 0xd2, (byte) 0x46, (byte) 0x0d, (byte) 0x6f, + (byte) 0x36, (byte) 0x8e, (byte) 0x84, (byte) 0xd8, (byte) 0xaf, (byte) 0xf7, + (byte) 0x69, (byte) 0x23, (byte) 0x77, (byte) 0xfb, (byte) 0xc5, (byte) 0x04, + (byte) 0x08, (byte) 0x18, (byte) 0xac, (byte) 0x85, (byte) 0x80, (byte) 0x87, + (byte) 0x1c, (byte) 0xfe, (byte) 0x8e, (byte) 0x5d, (byte) 0x00, (byte) 0x7f, + (byte) 0x5b, (byte) 0x33, (byte) 0xf5, (byte) 0xdf, (byte) 0x70, (byte) 0x81, + (byte) 0xad, (byte) 0x81, (byte) 0xf4, (byte) 0x5a, (byte) 0x37, (byte) 0x8a, + (byte) 0x79, (byte) 0x09, (byte) 0xc5, (byte) 0x55, (byte) 0xab, (byte) 0x58, + (byte) 0x7c, (byte) 0x47, (byte) 0xca, (byte) 0xa5, (byte) 0x80, (byte) 0x49, + (byte) 0x5f, (byte) 0x71, (byte) 0x83, (byte) 0xfb, (byte) 0x3b, (byte) 0x06, + (byte) 0xec, (byte) 0x75, (byte) 0x23, (byte) 0xc4, (byte) 0x32, (byte) 0xc7, + (byte) 0x18, (byte) 0xf6, (byte) 0x82, (byte) 0x95, (byte) 0x98, (byte) 0x39, + (byte) 0xf7, (byte) 0x92, (byte) 0x31, (byte) 0xc0, (byte) 0x89, (byte) 0xba, + (byte) 0xd4, (byte) 0xd4, (byte) 0x58, (byte) 0x4e, (byte) 0x38, (byte) 0x35, + (byte) 0x10, (byte) 0xb9, (byte) 0xf1, (byte) 0x27, (byte) 0xdc, (byte) 0xff, + (byte) 0xc7, (byte) 0xb2, (byte) 0xba, (byte) 0x1f, (byte) 0x27, (byte) 0xaf, + (byte) 0x99, (byte) 0xd5, (byte) 0xb0, (byte) 0x39, (byte) 0xe7, (byte) 0x43, + (byte) 0x88, (byte) 0xd3, (byte) 0xce, (byte) 0x38, (byte) 0xc2, (byte) 0x99, + (byte) 0x43, (byte) 0xfc, (byte) 0x8a, (byte) 0xe3, (byte) 0x60, (byte) 0x0d, + (byte) 0x0a, (byte) 0xb8, (byte) 0xc4, (byte) 0x29, (byte) 0xca, (byte) 0x0d, + (byte) 0x30, (byte) 0xaf, (byte) 0xca, (byte) 0xd0, (byte) 0xaa, (byte) 0x67, + (byte) 0xb1, (byte) 0xdd, (byte) 0xdb, (byte) 0x7a, (byte) 0x11, (byte) 0xad, + (byte) 0xeb, (byte) 0x02, (byte) 0x81, (byte) 0xc0, (byte) 0x71, (byte) 0xb8, + (byte) 0xcf, (byte) 0x72, (byte) 0x35, (byte) 0x67, (byte) 0xb5, (byte) 0x38, + (byte) 0x8f, (byte) 0x16, (byte) 0xd3, (byte) 0x29, (byte) 0x82, (byte) 0x35, + (byte) 0x21, (byte) 0xd4, (byte) 0x49, (byte) 0x20, (byte) 0x74, (byte) 0x2d, + (byte) 0xc0, (byte) 0xa4, (byte) 0x44, (byte) 0xf5, (byte) 0xd8, (byte) 0xc9, + (byte) 0xe9, (byte) 0x90, (byte) 0x1d, (byte) 0xde, (byte) 0x3a, (byte) 0xa6, + (byte) 0xd7, (byte) 0xe5, (byte) 0xe8, (byte) 0x4e, (byte) 0x83, (byte) 0xd7, + (byte) 0xe6, (byte) 0x2f, (byte) 0x92, (byte) 0x31, (byte) 0x21, (byte) 0x3f, + (byte) 0xfa, (byte) 0xd2, (byte) 0x85, (byte) 0x92, (byte) 0x1f, (byte) 0xff, + (byte) 0x61, (byte) 0x00, (byte) 0xf6, (byte) 0xda, (byte) 0x6e, (byte) 0xc6, + (byte) 0x7f, (byte) 0x5a, (byte) 0x35, (byte) 0x79, (byte) 0xdc, (byte) 0xdc, + (byte) 0xa3, (byte) 0x2e, (byte) 0x9f, (byte) 0x35, (byte) 0xd1, (byte) 0x5c, + (byte) 0xda, (byte) 0xb9, (byte) 0xf7, (byte) 0x58, (byte) 0x7d, (byte) 0x4f, + (byte) 0xb6, (byte) 0x13, (byte) 0xd7, (byte) 0x2c, (byte) 0x0a, (byte) 0xa8, + (byte) 0x4d, (byte) 0xf2, (byte) 0xe4, (byte) 0x67, (byte) 0x4f, (byte) 0x8b, + (byte) 0xa6, (byte) 0xca, (byte) 0x1a, (byte) 0xbb, (byte) 0x02, (byte) 0x63, + (byte) 0x8f, (byte) 0xb7, (byte) 0x46, (byte) 0xec, (byte) 0x7a, (byte) 0x8a, + (byte) 0x09, (byte) 0x0a, (byte) 0x45, (byte) 0x3a, (byte) 0x8d, (byte) 0xa8, + (byte) 0x83, (byte) 0x4b, (byte) 0x0a, (byte) 0xdb, (byte) 0x4b, (byte) 0x99, + (byte) 0xf3, (byte) 0x69, (byte) 0x95, (byte) 0xf0, (byte) 0xcf, (byte) 0xe9, + (byte) 0xf7, (byte) 0x67, (byte) 0xc9, (byte) 0x45, (byte) 0x18, (byte) 0x2f, + (byte) 0xf0, (byte) 0x5c, (byte) 0x90, (byte) 0xbd, (byte) 0xa6, (byte) 0x66, + (byte) 0x8c, (byte) 0xfe, (byte) 0x60, (byte) 0x5d, (byte) 0x6c, (byte) 0x27, + (byte) 0xec, (byte) 0xc1, (byte) 0x84, (byte) 0xb2, (byte) 0xa1, (byte) 0x97, + (byte) 0x9e, (byte) 0x16, (byte) 0x29, (byte) 0xa7, (byte) 0xe0, (byte) 0x38, + (byte) 0xa2, (byte) 0x36, (byte) 0x05, (byte) 0x5f, (byte) 0xda, (byte) 0x72, + (byte) 0x1a, (byte) 0x5f, (byte) 0xa8, (byte) 0x7d, (byte) 0x41, (byte) 0x35, + (byte) 0xf6, (byte) 0x4e, (byte) 0x0a, (byte) 0x88, (byte) 0x8e, (byte) 0x00, + (byte) 0x98, (byte) 0xa6, (byte) 0xca, (byte) 0xc1, (byte) 0xdf, (byte) 0x72, + (byte) 0x6c, (byte) 0xfe, (byte) 0x29, (byte) 0xbe, (byte) 0xa3, (byte) 0x9b, + (byte) 0x0b, (byte) 0x5c, (byte) 0x0b, (byte) 0x9d, (byte) 0xa7, (byte) 0x71, + (byte) 0xce, (byte) 0x04, (byte) 0xfa, (byte) 0xac, (byte) 0x01, (byte) 0x8d, + (byte) 0x52, (byte) 0xa0, (byte) 0x3d, (byte) 0xdd, (byte) 0x02, (byte) 0x81, + (byte) 0xc1, (byte) 0x00, (byte) 0xc1, (byte) 0xc0, (byte) 0x2e, (byte) 0xa9, + (byte) 0xee, (byte) 0xca, (byte) 0xff, (byte) 0xe4, (byte) 0xf8, (byte) 0x15, + (byte) 0xfd, (byte) 0xa5, (byte) 0x68, (byte) 0x1b, (byte) 0x2d, (byte) 0x4a, + (byte) 0xe6, (byte) 0x37, (byte) 0x06, (byte) 0xb3, (byte) 0xd7, (byte) 0x64, + (byte) 0xad, (byte) 0xb9, (byte) 0x05, (byte) 0x26, (byte) 0x97, (byte) 0x94, + (byte) 0x3a, (byte) 0x9e, (byte) 0x1c, (byte) 0xd0, (byte) 0xcd, (byte) 0x7b, + (byte) 0xf4, (byte) 0x88, (byte) 0xe2, (byte) 0xa5, (byte) 0x6d, (byte) 0xed, + (byte) 0x24, (byte) 0x77, (byte) 0x52, (byte) 0x39, (byte) 0x43, (byte) 0x0f, + (byte) 0x4e, (byte) 0x75, (byte) 0xd8, (byte) 0xa3, (byte) 0x59, (byte) 0x5a, + (byte) 0xc2, (byte) 0xba, (byte) 0x9a, (byte) 0x5b, (byte) 0x60, (byte) 0x31, + (byte) 0x0d, (byte) 0x58, (byte) 0x89, (byte) 0x13, (byte) 0xe8, (byte) 0x95, + (byte) 0xdd, (byte) 0xae, (byte) 0xcc, (byte) 0x1f, (byte) 0x73, (byte) 0x48, + (byte) 0x55, (byte) 0xd8, (byte) 0xfb, (byte) 0x67, (byte) 0xce, (byte) 0x18, + (byte) 0x85, (byte) 0x59, (byte) 0xad, (byte) 0x1f, (byte) 0x93, (byte) 0xe1, + (byte) 0xb7, (byte) 0x54, (byte) 0x80, (byte) 0x8e, (byte) 0x5f, (byte) 0xbc, + (byte) 0x1c, (byte) 0x96, (byte) 0x66, (byte) 0x2e, (byte) 0x40, (byte) 0x17, + (byte) 0x2e, (byte) 0x01, (byte) 0x7a, (byte) 0x7d, (byte) 0xaa, (byte) 0xff, + (byte) 0xa3, (byte) 0xd2, (byte) 0xdf, (byte) 0xe2, (byte) 0xf3, (byte) 0x54, + (byte) 0x51, (byte) 0xeb, (byte) 0xba, (byte) 0x7c, (byte) 0x2a, (byte) 0x22, + (byte) 0xc6, (byte) 0x42, (byte) 0xbc, (byte) 0xa1, (byte) 0x6c, (byte) 0xcf, + (byte) 0x73, (byte) 0x2e, (byte) 0x07, (byte) 0xfc, (byte) 0xf5, (byte) 0x67, + (byte) 0x25, (byte) 0xd0, (byte) 0xfa, (byte) 0xeb, (byte) 0xb4, (byte) 0xd4, + (byte) 0x19, (byte) 0xcc, (byte) 0x64, (byte) 0xa1, (byte) 0x2e, (byte) 0x78, + (byte) 0x45, (byte) 0xd9, (byte) 0x7f, (byte) 0x1b, (byte) 0x4c, (byte) 0x10, + (byte) 0x31, (byte) 0x44, (byte) 0xe8, (byte) 0xcc, (byte) 0xf9, (byte) 0x1b, + (byte) 0x87, (byte) 0x31, (byte) 0xd6, (byte) 0x69, (byte) 0x85, (byte) 0x4a, + (byte) 0x49, (byte) 0xf6, (byte) 0xb2, (byte) 0xe0, (byte) 0xb8, (byte) 0x98, + (byte) 0x3c, (byte) 0xf6, (byte) 0x78, (byte) 0x46, (byte) 0xc8, (byte) 0x3d, + (byte) 0x60, (byte) 0xc1, (byte) 0xaa, (byte) 0x2f, (byte) 0x28, (byte) 0xa1, + (byte) 0x14, (byte) 0x6b, (byte) 0x75, (byte) 0x4d, (byte) 0xb1, (byte) 0x3d, + (byte) 0x80, (byte) 0x49, (byte) 0x33, (byte) 0xfd, (byte) 0x71, (byte) 0xc0, + (byte) 0x13, (byte) 0x1e, (byte) 0x16, (byte) 0x69, (byte) 0x80, (byte) 0xa4, + (byte) 0x9c, (byte) 0xd7, (byte) 0x02, (byte) 0x81, (byte) 0xc1, (byte) 0x00, + (byte) 0x8c, (byte) 0x33, (byte) 0x2d, (byte) 0xd9, (byte) 0xf3, (byte) 0x42, + (byte) 0x4d, (byte) 0xca, (byte) 0x5e, (byte) 0x60, (byte) 0x14, (byte) 0x10, + (byte) 0xf6, (byte) 0xf3, (byte) 0x71, (byte) 0x15, (byte) 0x88, (byte) 0x54, + (byte) 0x84, (byte) 0x21, (byte) 0x04, (byte) 0xb1, (byte) 0xaf, (byte) 0x02, + (byte) 0x11, (byte) 0x7f, (byte) 0x42, (byte) 0x3e, (byte) 0x86, (byte) 0xcb, + (byte) 0x6c, (byte) 0xf5, (byte) 0x57, (byte) 0x78, (byte) 0x4a, (byte) 0x03, + (byte) 0x9b, (byte) 0x80, (byte) 0xc2, (byte) 0x04, (byte) 0x3a, (byte) 0x6b, + (byte) 0xb3, (byte) 0x30, (byte) 0x31, (byte) 0x7e, (byte) 0xc3, (byte) 0x89, + (byte) 0x09, (byte) 0x4e, (byte) 0x86, (byte) 0x59, (byte) 0x41, (byte) 0xb5, + (byte) 0xae, (byte) 0xd5, (byte) 0xc6, (byte) 0x38, (byte) 0xbc, (byte) 0xd7, + (byte) 0xd7, (byte) 0x8e, (byte) 0xa3, (byte) 0x1a, (byte) 0xde, (byte) 0x32, + (byte) 0xad, (byte) 0x8d, (byte) 0x15, (byte) 0x81, (byte) 0xfe, (byte) 0xac, + (byte) 0xbd, (byte) 0xd0, (byte) 0xca, (byte) 0xbc, (byte) 0xd8, (byte) 0x6a, + (byte) 0xe1, (byte) 0xfe, (byte) 0xda, (byte) 0xc4, (byte) 0xd8, (byte) 0x62, + (byte) 0x71, (byte) 0x20, (byte) 0xa3, (byte) 0xd3, (byte) 0x06, (byte) 0x11, + (byte) 0xa9, (byte) 0x53, (byte) 0x7a, (byte) 0x44, (byte) 0x89, (byte) 0x3d, + (byte) 0x28, (byte) 0x5e, (byte) 0x7d, (byte) 0xf0, (byte) 0x60, (byte) 0xeb, + (byte) 0xb5, (byte) 0xdf, (byte) 0xed, (byte) 0x4f, (byte) 0x6d, (byte) 0x05, + (byte) 0x59, (byte) 0x06, (byte) 0xb0, (byte) 0x62, (byte) 0x50, (byte) 0x1c, + (byte) 0xb7, (byte) 0x2c, (byte) 0x44, (byte) 0xa4, (byte) 0x49, (byte) 0xf8, + (byte) 0x4f, (byte) 0x4b, (byte) 0xab, (byte) 0x71, (byte) 0x5b, (byte) 0xcb, + (byte) 0x31, (byte) 0x10, (byte) 0x41, (byte) 0xe0, (byte) 0x1a, (byte) 0x15, + (byte) 0xdc, (byte) 0x4c, (byte) 0x5d, (byte) 0x4f, (byte) 0x62, (byte) 0x83, + (byte) 0xa4, (byte) 0x80, (byte) 0x06, (byte) 0x36, (byte) 0xba, (byte) 0xc9, + (byte) 0xe2, (byte) 0xa4, (byte) 0x11, (byte) 0x98, (byte) 0x6b, (byte) 0x4c, + (byte) 0xe9, (byte) 0x90, (byte) 0x55, (byte) 0x18, (byte) 0xde, (byte) 0xe1, + (byte) 0x42, (byte) 0x38, (byte) 0x28, (byte) 0xa3, (byte) 0x54, (byte) 0x56, + (byte) 0x31, (byte) 0xaf, (byte) 0x5a, (byte) 0xd6, (byte) 0xf0, (byte) 0x26, + (byte) 0xe0, (byte) 0x7a, (byte) 0xd9, (byte) 0x6c, (byte) 0x64, (byte) 0xca, + (byte) 0x5d, (byte) 0x6d, (byte) 0x3d, (byte) 0x9a, (byte) 0xfe, (byte) 0x36, + (byte) 0x93, (byte) 0x9e, (byte) 0x62, (byte) 0x94, (byte) 0xc6, (byte) 0x07, + (byte) 0x83, (byte) 0x96, (byte) 0xd6, (byte) 0x27, (byte) 0xa6, (byte) 0xd8 + }; + public static final PrivateKey CLIENT_SUITE_B_RSA3072_KEY = + loadPrivateKey("RSA", CLIENT_SUITE_B_RSA3072_KEY_DATA); + + private static final String CLIENT_SUITE_B_ECDSA_CERT_STRING = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB9zCCAX4CFDpfSZh3AH07BEfGWuMDa7Ynz6y+MAoGCCqGSM49BAMDMF4xCzAJ\n" + + "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDTVRWMRAwDgYDVQQKDAdB\n" + + "bmRyb2lkMQ4wDAYDVQQLDAVXaS1GaTESMBAGA1UEAwwJdW5pdGVzdENBMB4XDTIw\n" + + "MDcyMTAyMjk1MFoXDTMwMDUzMDAyMjk1MFowYjELMAkGA1UEBhMCVVMxCzAJBgNV\n" + + "BAgMAkNBMQwwCgYDVQQHDANNVFYxEDAOBgNVBAoMB0FuZHJvaWQxDjAMBgNVBAsM\n" + + "BVdpLUZpMRYwFAYDVQQDDA11bml0ZXN0Q2xpZW50MHYwEAYHKoZIzj0CAQYFK4EE\n" + + "ACIDYgAEhxhVJ7dcSqrto0X+dgRxtd8BWG8cWmPjBji3MIxDLfpcMDoIB84ae1Ew\n" + + "gJn4YUYHrWsUDiVNihv8j7a/Ol1qcIY2ybH7tbezefLmagqA4vXEUXZXoUyL4ZNC\n" + + "DWcdw6LrMAoGCCqGSM49BAMDA2cAMGQCMH4aP73HrriRUJRguiuRic+X4Cqj/7YQ\n" + + "ueJmP87KF92/thhoQ9OrRo8uJITPmNDswwIwP2Q1AZCSL4BI9dYrqu07Ar+pSkXE\n" + + "R7oOqGdZR+d/MvXcFSrbIaLKEoHXmQamIHLe\n" + + "-----END CERTIFICATE-----\n"; + public static final X509Certificate CLIENT_SUITE_B_ECDSA_CERT = + loadCertificate(CLIENT_SUITE_B_ECDSA_CERT_STRING); + + private static final byte[] CLIENT_SUITE_B_ECC_KEY_DATA = new byte[]{ + (byte) 0x30, (byte) 0x81, (byte) 0xb6, (byte) 0x02, (byte) 0x01, (byte) 0x00, + (byte) 0x30, (byte) 0x10, (byte) 0x06, (byte) 0x07, (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06, + (byte) 0x05, (byte) 0x2b, (byte) 0x81, (byte) 0x04, (byte) 0x00, (byte) 0x22, + (byte) 0x04, (byte) 0x81, (byte) 0x9e, (byte) 0x30, (byte) 0x81, (byte) 0x9b, + (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x04, (byte) 0x30, (byte) 0xea, + (byte) 0x6c, (byte) 0x4b, (byte) 0x6d, (byte) 0x43, (byte) 0xf9, (byte) 0x6c, + (byte) 0x91, (byte) 0xdc, (byte) 0x2d, (byte) 0x6e, (byte) 0x87, (byte) 0x4f, + (byte) 0x0a, (byte) 0x0b, (byte) 0x97, (byte) 0x25, (byte) 0x1c, (byte) 0x79, + (byte) 0xa2, (byte) 0x07, (byte) 0xdc, (byte) 0x94, (byte) 0xc2, (byte) 0xee, + (byte) 0x64, (byte) 0x51, (byte) 0x6d, (byte) 0x4e, (byte) 0x35, (byte) 0x1c, + (byte) 0x22, (byte) 0x2f, (byte) 0xc0, (byte) 0xea, (byte) 0x09, (byte) 0x47, + (byte) 0x3e, (byte) 0xb9, (byte) 0xb6, (byte) 0xb8, (byte) 0x83, (byte) 0x9e, + (byte) 0xed, (byte) 0x59, (byte) 0xe5, (byte) 0xe7, (byte) 0x0f, (byte) 0xa1, + (byte) 0x64, (byte) 0x03, (byte) 0x62, (byte) 0x00, (byte) 0x04, (byte) 0x87, + (byte) 0x18, (byte) 0x55, (byte) 0x27, (byte) 0xb7, (byte) 0x5c, (byte) 0x4a, + (byte) 0xaa, (byte) 0xed, (byte) 0xa3, (byte) 0x45, (byte) 0xfe, (byte) 0x76, + (byte) 0x04, (byte) 0x71, (byte) 0xb5, (byte) 0xdf, (byte) 0x01, (byte) 0x58, + (byte) 0x6f, (byte) 0x1c, (byte) 0x5a, (byte) 0x63, (byte) 0xe3, (byte) 0x06, + (byte) 0x38, (byte) 0xb7, (byte) 0x30, (byte) 0x8c, (byte) 0x43, (byte) 0x2d, + (byte) 0xfa, (byte) 0x5c, (byte) 0x30, (byte) 0x3a, (byte) 0x08, (byte) 0x07, + (byte) 0xce, (byte) 0x1a, (byte) 0x7b, (byte) 0x51, (byte) 0x30, (byte) 0x80, + (byte) 0x99, (byte) 0xf8, (byte) 0x61, (byte) 0x46, (byte) 0x07, (byte) 0xad, + (byte) 0x6b, (byte) 0x14, (byte) 0x0e, (byte) 0x25, (byte) 0x4d, (byte) 0x8a, + (byte) 0x1b, (byte) 0xfc, (byte) 0x8f, (byte) 0xb6, (byte) 0xbf, (byte) 0x3a, + (byte) 0x5d, (byte) 0x6a, (byte) 0x70, (byte) 0x86, (byte) 0x36, (byte) 0xc9, + (byte) 0xb1, (byte) 0xfb, (byte) 0xb5, (byte) 0xb7, (byte) 0xb3, (byte) 0x79, + (byte) 0xf2, (byte) 0xe6, (byte) 0x6a, (byte) 0x0a, (byte) 0x80, (byte) 0xe2, + (byte) 0xf5, (byte) 0xc4, (byte) 0x51, (byte) 0x76, (byte) 0x57, (byte) 0xa1, + (byte) 0x4c, (byte) 0x8b, (byte) 0xe1, (byte) 0x93, (byte) 0x42, (byte) 0x0d, + (byte) 0x67, (byte) 0x1d, (byte) 0xc3, (byte) 0xa2, (byte) 0xeb + }; + public static final PrivateKey CLIENT_SUITE_B_ECC_KEY = + loadPrivateKey("EC", CLIENT_SUITE_B_ECC_KEY_DATA); private static X509Certificate loadCertificate(String blob) { try { @@ -210,9 +646,9 @@ public class FakeKeys { } } - private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) { + private static PrivateKey loadPrivateKey(String algorithm, byte[] fakeKey) { try { - KeyFactory kf = KeyFactory.getInstance("RSA"); + KeyFactory kf = KeyFactory.getInstance(algorithm); return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey)); } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { return null; diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java index 5a03d1411..589a30a8a 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigurationTestUtil.java @@ -86,6 +86,7 @@ public class WifiConfigurationTestUtil { public static final String TEST_STATIC_PROXY_EXCLUSION_LIST = ""; public static final String TEST_PAC_PROXY_LOCATION = "http://"; public static final String TEST_CA_CERT_ALIAS = "WifiConfigurationTestUtilCaCertAlias"; + public static final String TEST_CA_CERT_SUITE_B_ALIAS = "SuiteBCaCertAlias"; public static final String TEST_CA_CERT_PATH = "caPath"; public static final String TEST_DOM_SUBJECT_MATCH = "domSubjectMatch"; @@ -169,6 +170,8 @@ public class WifiConfigurationTestUtil { } if ((security & SECURITY_EAP_SUITE_B) != 0) { + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); config.requirePmf = true; } @@ -375,6 +378,10 @@ public class WifiConfigurationTestUtil { } public static WifiConfiguration createEapSuiteBNetwork() { + return createEapSuiteBNetwork(WifiConfiguration.SuiteBCipher.ECDHE_RSA); + } + + public static WifiConfiguration createEapSuiteBNetwork(int signatureType) { WifiConfiguration configuration = generateWifiConfig(TEST_NETWORK_ID, TEST_UID, createNewSSID(), true, true, null, null, SECURITY_EAP_SUITE_B); @@ -382,6 +389,18 @@ public class WifiConfigurationTestUtil { configuration.requirePmf = true; configuration.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); configuration.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE); + + if (signatureType == WifiConfiguration.SuiteBCipher.ECDHE_ECDSA) { + configuration.enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_ECDSA_CERT); + configuration.enterpriseConfig.setClientKeyEntryWithCertificateChain( + FakeKeys.CLIENT_SUITE_B_ECC_KEY, + new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_ECDSA_CERT}); + } else { + configuration.enterpriseConfig.setCaCertificate(FakeKeys.CA_SUITE_B_RSA3072_CERT); + configuration.enterpriseConfig.setClientKeyEntryWithCertificateChain( + FakeKeys.CLIENT_SUITE_B_RSA3072_KEY, + new X509Certificate[] {FakeKeys.CLIENT_SUITE_B_RSA3072_CERT}); + } return configuration; } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java b/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java index 842ffe96d..8eef7e7d0 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiKeyStoreTest.java @@ -52,7 +52,8 @@ public class WifiKeyStoreTest extends WifiBaseTest { private WifiKeyStore mWifiKeyStore; private static final String TEST_KEY_ID = "blah"; private static final String USER_CERT_ALIAS = "aabbccddee"; - private static final String [] USER_CA_CERT_ALIAS = {"aacccddd"}; + private static final String USER_CA_CERT_ALIAS = "aacccddd"; + private static final String [] USER_CA_CERT_ALIASES = {"aacccddd", "bbbccccaaa"}; private static final String TEST_PACKAGE_NAME = "TestApp"; /** @@ -64,8 +65,9 @@ public class WifiKeyStoreTest extends WifiBaseTest { mWifiKeyStore = new WifiKeyStore(mKeyStore); when(mWifiEnterpriseConfig.getClientCertificateAlias()).thenReturn(USER_CERT_ALIAS); + when(mWifiEnterpriseConfig.getCaCertificateAlias()).thenReturn(USER_CA_CERT_ALIAS); when(mWifiEnterpriseConfig.getCaCertificateAliases()) - .thenReturn(USER_CA_CERT_ALIAS); + .thenReturn(USER_CA_CERT_ALIASES); when(mWifiEnterpriseConfig.getClientPrivateKey()).thenReturn(FakeKeys.RSA_KEY1); when(mWifiEnterpriseConfig.getClientCertificate()).thenReturn(FakeKeys.CLIENT_CERT); when(mWifiEnterpriseConfig.getCaCertificate()).thenReturn(FakeKeys.CA_CERT0); @@ -95,7 +97,7 @@ public class WifiKeyStoreTest extends WifiBaseTest { // Method calls the KeyStore#delete method 4 times, user key, user cert, and 2 CA cert verify(mKeyStore).deleteEntry(USER_CERT_ALIAS); - verify(mKeyStore).deleteEntry(USER_CA_CERT_ALIAS[0]); + verify(mKeyStore).deleteEntry(USER_CA_CERT_ALIASES[0]); } /** @@ -124,7 +126,8 @@ public class WifiKeyStoreTest extends WifiBaseTest { mWifiKeyStore.removeKeys(mWifiEnterpriseConfig); // Method calls the KeyStore#delete method 2 times: 2 CA certs - verify(mKeyStore).deleteEntry(USER_CA_CERT_ALIAS[0]); + verify(mKeyStore).deleteEntry(USER_CA_CERT_ALIASES[0]); + verify(mKeyStore).deleteEntry(USER_CA_CERT_ALIASES[1]); verifyNoMoreInteractions(mKeyStore); } @@ -213,4 +216,57 @@ public class WifiKeyStoreTest extends WifiBaseTest { mWifiKeyStore.removeKeys(suggestionNetwork.enterpriseConfig); verify(mKeyStore, never()).deleteEntry(any()); } + + /** + * Test configuring WPA3-Enterprise in 192-bit mode for RSA 3072 correctly when CA and client + * certificates are of RSA 3072 type and the network is Suite-B. + */ + @Test + public void testConfigureSuiteBRsa3072() throws Exception { + when(mWifiEnterpriseConfig.getClientPrivateKey()) + .thenReturn(FakeKeys.CLIENT_SUITE_B_RSA3072_KEY); + when(mWifiEnterpriseConfig.getClientCertificate()).thenReturn( + FakeKeys.CLIENT_SUITE_B_RSA3072_CERT); + when(mWifiEnterpriseConfig.getCaCertificate()).thenReturn(FakeKeys.CA_SUITE_B_RSA3072_CERT); + when(mWifiEnterpriseConfig.getClientCertificateChain()) + .thenReturn(new X509Certificate[]{FakeKeys.CLIENT_SUITE_B_RSA3072_CERT}); + when(mWifiEnterpriseConfig.getCaCertificates()) + .thenReturn(new X509Certificate[]{FakeKeys.CA_SUITE_B_RSA3072_CERT}); + when(mKeyStore.getCertificate(eq(USER_CERT_ALIAS))).thenReturn( + FakeKeys.CLIENT_SUITE_B_RSA3072_CERT); + when(mKeyStore.getCertificate(eq(USER_CA_CERT_ALIASES[0]))).thenReturn( + FakeKeys.CA_SUITE_B_RSA3072_CERT); + WifiConfiguration savedNetwork = WifiConfigurationTestUtil.createEapSuiteBNetwork( + WifiConfiguration.SuiteBCipher.ECDHE_RSA); + savedNetwork.enterpriseConfig = mWifiEnterpriseConfig; + assertTrue(mWifiKeyStore.updateNetworkKeys(savedNetwork, null)); + assertTrue(savedNetwork.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)); + } + + /** + * Test configuring WPA3-Enterprise in 192-bit mode for ECDSA correctly when CA and client + * certificates are of ECDSA type and the network is Suite-B. + */ + @Test + public void testConfigureSuiteBEcdsa() throws Exception { + when(mWifiEnterpriseConfig.getClientPrivateKey()) + .thenReturn(FakeKeys.CLIENT_SUITE_B_ECC_KEY); + when(mWifiEnterpriseConfig.getClientCertificate()).thenReturn( + FakeKeys.CLIENT_SUITE_B_ECDSA_CERT); + when(mWifiEnterpriseConfig.getCaCertificate()).thenReturn(FakeKeys.CA_SUITE_B_ECDSA_CERT); + when(mWifiEnterpriseConfig.getClientCertificateChain()) + .thenReturn(new X509Certificate[]{FakeKeys.CLIENT_SUITE_B_ECDSA_CERT}); + when(mWifiEnterpriseConfig.getCaCertificates()) + .thenReturn(new X509Certificate[]{FakeKeys.CA_SUITE_B_ECDSA_CERT}); + when(mKeyStore.getCertificate(eq(USER_CERT_ALIAS))).thenReturn( + FakeKeys.CLIENT_SUITE_B_ECDSA_CERT); + when(mKeyStore.getCertificate(eq(USER_CA_CERT_ALIASES[0]))).thenReturn( + FakeKeys.CA_SUITE_B_ECDSA_CERT); + WifiConfiguration savedNetwork = WifiConfigurationTestUtil.createEapSuiteBNetwork( + WifiConfiguration.SuiteBCipher.ECDHE_ECDSA); + savedNetwork.enterpriseConfig = mWifiEnterpriseConfig; + assertTrue(mWifiKeyStore.updateNetworkKeys(savedNetwork, null)); + assertTrue( + savedNetwork.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)); + } } -- cgit v1.2.3 From 65bfcc085766588910758922f4d31a305d23c70d Mon Sep 17 00:00:00 2001 From: Nate Jiang Date: Thu, 3 Dec 2020 14:31:30 -0800 Subject: [Suggestion] Check foreground user for API call Also, squashes the follow up commit to create a single CL for backporting: ======= PasspointManager: Don't allow bg user to modify passpoint profiles Also, add safety net logging for this bug. ======= Bug: 174749461 Test: atest com.android.server.wifi Change-Id: Ifc79ffeb04a7be99a9c60d9414b72e88275c0514 Merged-In: Ifc79ffeb04a7be99a9c60d9414b72e88275c0514 (cherry picked from commit e799efba85cbe52044a067869af71d9c15b573bb) (cherry picked from commit 23685b8604571ec623e539f4f9c66db65c9dde81) (cherry picked from commit 1ffc81e5470b3e98f86ac04a7e4f9daec89768b3) --- .../com/android/server/wifi/WifiConfigManager.java | 45 ++++---------- .../java/com/android/server/wifi/WifiInjector.java | 3 +- .../server/wifi/WifiNetworkSuggestionsManager.java | 29 ++++++++- .../com/android/server/wifi/WifiServiceImpl.java | 13 ++-- .../server/wifi/hotspot2/PasspointManager.java | 15 ++++- .../server/wifi/util/WifiPermissionsUtil.java | 29 +++++++++ .../android/server/wifi/WifiConfigManagerTest.java | 17 +++++- .../wifi/WifiNetworkSuggestionsManagerTest.java | 71 +++++++++++++++++----- .../android/server/wifi/WifiServiceImplTest.java | 10 +-- .../server/wifi/hotspot2/PasspointManagerTest.java | 53 +++++++++++++++- 10 files changed, 216 insertions(+), 69 deletions(-) diff --git a/service/java/com/android/server/wifi/WifiConfigManager.java b/service/java/com/android/server/wifi/WifiConfigManager.java index 6d04b7a68..c0cb899d2 100644 --- a/service/java/com/android/server/wifi/WifiConfigManager.java +++ b/service/java/com/android/server/wifi/WifiConfigManager.java @@ -912,32 +912,6 @@ public class WifiConfigManager { && mWifiPermissionsUtil.checkNetworkSettingsPermission(uid); } - /** - * Check if the given UID belongs to the current foreground user. This is - * used to prevent apps running in background users from modifying network - * configurations. - *

- * UIDs belonging to system internals (such as SystemUI) are always allowed, - * since they always run as {@link UserHandle#USER_SYSTEM}. - * - * @param uid uid of the app. - * @return true if the given UID belongs to the current foreground user, - * otherwise false. - */ - private boolean doesUidBelongToCurrentUser(int uid) { - if (uid == android.os.Process.SYSTEM_UID - // UIDs with the NETWORK_SETTINGS permission are always allowed since they are - // acting on behalf of the user. - || mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) { - return true; - } else { - UserHandle currentUser = UserHandle.of(mCurrentUserId); - UserHandle callingUser = UserHandle.getUserHandleForUid(uid); - return currentUser.equals(callingUser) - || mUserManager.isSameProfileGroup(currentUser, callingUser); - } - } - /** * Copy over public elements from an external WifiConfiguration object to the internal * configuration object if element has been set in the provided external WifiConfiguration. @@ -1334,7 +1308,7 @@ public class WifiConfigManager { */ public NetworkUpdateResult addOrUpdateNetwork(WifiConfiguration config, int uid, @Nullable String packageName) { - if (!doesUidBelongToCurrentUser(uid)) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return new NetworkUpdateResult(WifiConfiguration.INVALID_NETWORK_ID); } @@ -1440,7 +1414,7 @@ public class WifiConfigManager { * @return true if successful, false otherwise. */ public boolean removeNetwork(int networkId, int uid, String packageName) { - if (!doesUidBelongToCurrentUser(uid)) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return false; } @@ -1849,7 +1823,7 @@ public class WifiConfigManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "Enabling network " + networkId + " (disableOthers " + disableOthers + ")"); } - if (!doesUidBelongToCurrentUser(uid)) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return false; } @@ -1887,7 +1861,7 @@ public class WifiConfigManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "Disabling network " + networkId); } - if (!doesUidBelongToCurrentUser(uid)) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return false; } @@ -1955,7 +1929,7 @@ public class WifiConfigManager { if (mVerboseLoggingEnabled) { Log.v(TAG, "Update network last connect UID for " + networkId); } - if (!doesUidBelongToCurrentUser(uid)) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { Log.e(TAG, "UID " + uid + " not visible to the current user"); return false; } @@ -2927,7 +2901,8 @@ public class WifiConfigManager { Set removedNetworkIds = new HashSet<>(); // Remove any private networks of the old user before switching the userId. for (WifiConfiguration config : getConfiguredNetworks()) { - if (!config.shared && doesUidBelongToCurrentUser(config.creatorUid)) { + if ((!config.shared && !mWifiPermissionsUtil + .doesUidBelongToCurrentUser(config.creatorUid))) { removedNetworkIds.add(config.networkId); localLog("clearInternalUserData: removed config." + " netId=" + config.networkId @@ -3146,7 +3121,8 @@ public class WifiConfigManager { // Migrate the legacy Passpoint configurations owned by the current user to // {@link PasspointManager}. - if (config.isLegacyPasspointConfig && doesUidBelongToCurrentUser(config.creatorUid)) { + if (config.isLegacyPasspointConfig && !mWifiPermissionsUtil + .doesUidBelongToCurrentUser(config.creatorUid)) { legacyPasspointNetId.add(config.networkId); // Migrate the legacy Passpoint configuration and add it to PasspointManager. if (!PasspointManager.addLegacyPasspointConfig(config)) { @@ -3166,7 +3142,8 @@ public class WifiConfigManager { // because all networks were previously stored in a central file. We cannot // write these private networks to the user specific store until the corresponding // user logs in. - if (config.shared || !doesUidBelongToCurrentUser(config.creatorUid)) { + if (config.shared || !mWifiPermissionsUtil + .doesUidBelongToCurrentUser(config.creatorUid)) { sharedConfigurations.add(config); } else { userConfigurations.add(config); diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index b9aa0521f..5531c4e98 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -304,7 +304,8 @@ public class WifiInjector { mWifiCarrierInfoManager, mWifiKeyStore, mLruConnectionTracker); mPasspointManager = new PasspointManager(mContext, this, wifiHandler, mWifiNative, mWifiKeyStore, mClock, new PasspointObjectFactory(), - mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager); + mWifiConfigManager, mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager, + mWifiPermissionsUtil); PasspointNetworkNominateHelper nominateHelper = new PasspointNetworkNominateHelper(mPasspointManager, mWifiConfigManager, mConnectivityLocalLog); diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java index 464ced0ad..2632835e6 100644 --- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java +++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java @@ -390,6 +390,7 @@ public class WifiNetworkSuggestionsManager { private boolean mIsLastUserApprovalUiDialog = false; private boolean mUserDataLoaded = false; + /** * Listener for app-ops changes for active suggestor apps. */ @@ -833,6 +834,10 @@ public class WifiNetworkSuggestionsManager { public @WifiManager.NetworkSuggestionsStatusCode int add( List networkSuggestions, int uid, String packageName, @Nullable String featureId) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { + Log.e(TAG, "UID " + uid + " not visible to the current user"); + return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; + } if (!mUserDataLoaded) { Log.e(TAG, "Add Network suggestion before boot complete is not allowed."); return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; @@ -1108,6 +1113,10 @@ public class WifiNetworkSuggestionsManager { */ public @WifiManager.NetworkSuggestionsStatusCode int remove( List networkSuggestions, int uid, String packageName) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { + Log.e(TAG, "UID " + uid + " not visible to the current user"); + return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; + } if (!mUserDataLoaded) { Log.e(TAG, "Remove Network suggestion before boot complete is not allowed."); return WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL; @@ -1166,8 +1175,12 @@ public class WifiNetworkSuggestionsManager { * Get all network suggestion for target App * @return List of WifiNetworkSuggestions */ - public @NonNull List get(@NonNull String packageName) { + public @NonNull List get(@NonNull String packageName, int uid) { List networkSuggestionList = new ArrayList<>(); + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { + Log.e(TAG, "UID " + uid + " not visible to the current user"); + return networkSuggestionList; + } if (!mUserDataLoaded) { Log.e(TAG, "Get Network suggestion before boot complete is not allowed."); return networkSuggestionList; @@ -1923,11 +1936,16 @@ public class WifiNetworkSuggestionsManager { * @param binder IBinder instance to allow cleanup if the app dies. * @param listener ISuggestionNetworkCallback instance to add. * @param listenerIdentifier identifier of the listener, should be hash code of listener. + * @param uid uid of the app. * @return true if succeed otherwise false. */ public boolean registerSuggestionConnectionStatusListener(@NonNull IBinder binder, @NonNull ISuggestionConnectionStatusListener listener, - int listenerIdentifier, String packageName) { + int listenerIdentifier, String packageName, int uid) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { + Log.e(TAG, "UID " + uid + " not visible to the current user"); + return false; + } ExternalCallbackTracker listenersTracker = mSuggestionStatusListenerPerApp.get(packageName); if (listenersTracker == null) { @@ -1942,9 +1960,14 @@ public class WifiNetworkSuggestionsManager { /** * Unregister a listener on network connection failure. * @param listenerIdentifier identifier of the listener, should be hash code of listener. + * @param uid uid of the app. */ public void unregisterSuggestionConnectionStatusListener(int listenerIdentifier, - String packageName) { + String packageName, int uid) { + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { + Log.e(TAG, "UID " + uid + " not visible to the current user"); + return; + } ExternalCallbackTracker listenersTracker = mSuggestionStatusListenerPerApp.get(packageName); if (listenersTracker == null || listenersTracker.remove(listenerIdentifier) == null) { diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java index a398eacaf..20e82d845 100644 --- a/service/java/com/android/server/wifi/WifiServiceImpl.java +++ b/service/java/com/android/server/wifi/WifiServiceImpl.java @@ -3888,13 +3888,15 @@ public class WifiServiceImpl extends BaseWifiService { * @return a list of network suggestions suggested by this app */ public List getNetworkSuggestions(String callingPackageName) { - mAppOps.checkPackage(Binder.getCallingUid(), callingPackageName); + int callingUid = Binder.getCallingUid(); + mAppOps.checkPackage(callingUid, callingPackageName); enforceAccessPermission(); if (mVerboseLoggingEnabled) { mLog.info("getNetworkSuggestionList uid=%").c(Binder.getCallingUid()).flush(); } return mWifiThreadRunner.call(() -> - mWifiNetworkSuggestionsManager.get(callingPackageName), Collections.emptyList()); + mWifiNetworkSuggestionsManager.get(callingPackageName, callingUid), + Collections.emptyList()); } /** @@ -4213,7 +4215,7 @@ public class WifiServiceImpl extends BaseWifiService { mWifiThreadRunner.post(() -> mWifiNetworkSuggestionsManager .registerSuggestionConnectionStatusListener(binder, listener, - listenerIdentifier, packageName)); + listenerIdentifier, packageName, uid)); } /** @@ -4223,14 +4225,15 @@ public class WifiServiceImpl extends BaseWifiService { public void unregisterSuggestionConnectionStatusListener( int listenerIdentifier, String packageName) { enforceAccessPermission(); + int uid = Binder.getCallingUid(); if (mVerboseLoggingEnabled) { mLog.info("unregisterSuggestionConnectionStatusListener uid=%") - .c(Binder.getCallingUid()).flush(); + .c(uid).flush(); } mWifiThreadRunner.post(() -> mWifiNetworkSuggestionsManager .unregisterSuggestionConnectionStatusListener(listenerIdentifier, - packageName)); + packageName, uid)); } @Override diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java index 25553b8fe..2c291f024 100644 --- a/service/java/com/android/server/wifi/hotspot2/PasspointManager.java +++ b/service/java/com/android/server/wifi/hotspot2/PasspointManager.java @@ -54,6 +54,7 @@ import com.android.server.wifi.hotspot2.anqp.HSOsuProvidersElement; import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo; import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent; import com.android.server.wifi.util.InformationElementUtil; +import com.android.server.wifi.util.WifiPermissionsUtil; import java.io.IOException; import java.io.PrintWriter; @@ -118,7 +119,7 @@ public class PasspointManager { private final PasspointProvisioner mPasspointProvisioner; private final AppOpsManager mAppOps; private final WifiCarrierInfoManager mWifiCarrierInfoManager; - + private final WifiPermissionsUtil mWifiPermissionsUtil; /** * Map of package name of an app to the app ops changed listener for the app. */ @@ -304,7 +305,8 @@ public class PasspointManager { PasspointObjectFactory objectFactory, WifiConfigManager wifiConfigManager, WifiConfigStore wifiConfigStore, WifiMetrics wifiMetrics, - WifiCarrierInfoManager wifiCarrierInfoManager) { + WifiCarrierInfoManager wifiCarrierInfoManager, + WifiPermissionsUtil wifiPermissionsUtil) { mPasspointEventHandler = objectFactory.makePasspointEventHandler(wifiNative, new CallbackHandler(context)); mWifiInjector = wifiInjector; @@ -326,6 +328,7 @@ public class PasspointManager { this, wifiMetrics); mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); sPasspointManager = this; + mWifiPermissionsUtil = wifiPermissionsUtil; } /** @@ -406,6 +409,10 @@ public class PasspointManager { Log.e(TAG, "Set isTrusted to false on a non suggestion passpoint is not allowed"); return false; } + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(uid)) { + Log.e(TAG, "UID " + uid + " not visible to the current user"); + return false; + } mWifiCarrierInfoManager.tryUpdateCarrierIdForPasspoint(config); // Create a provider and install the necessary certificates and keys. @@ -499,6 +506,10 @@ public class PasspointManager { + provider.getCreatorUid()); return false; } + if (!mWifiPermissionsUtil.doesUidBelongToCurrentUser(callingUid)) { + Log.e(TAG, "UID " + callingUid + " not visible to the current user"); + return false; + } provider.uninstallCertsAndKeys(); String packageName = provider.getPackageName(); // Remove any configs corresponding to the profile in WifiConfigManager. diff --git a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java index 63197ea6d..ebe7ea481 100644 --- a/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java +++ b/service/java/com/android/server/wifi/util/WifiPermissionsUtil.java @@ -30,6 +30,7 @@ import android.os.Build; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; +import android.util.EventLog; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -589,4 +590,32 @@ public class WifiPermissionsUtil { if (devicePolicyManager == null) return false; return devicePolicyManager.isProfileOwnerApp(packageName); } + + /** + * Check if the given UID belongs to the current foreground user. This is + * used to prevent apps running in background users from modifying network + * configurations. + *

+ * UIDs belonging to system internals (such as SystemUI) are always allowed, + * since they always run as {@link UserHandle#USER_SYSTEM}. + * + * @param uid uid of the app. + * @return true if the given UID belongs to the current foreground user, + * otherwise false. + */ + public boolean doesUidBelongToCurrentUser(int uid) { + if (uid == android.os.Process.SYSTEM_UID + // UIDs with the NETWORK_SETTINGS permission are always allowed since they are + // acting on behalf of the user. + || checkNetworkSettingsPermission(uid)) { + return true; + } + boolean isCurrentProfile = isCurrentProfile(uid); + if (!isCurrentProfile) { + // Fix for b/174749461 + EventLog.writeEvent(0x534e4554, "174749461", -1, + "Non foreground user trying to modify wifi configuration"); + } + return isCurrentProfile; + } } diff --git a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java index d2584adbc..9d96116eb 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiConfigManagerTest.java @@ -222,6 +222,7 @@ public class WifiConfigManagerTest extends WifiBaseTest { .thenReturn(false); when(mWifiInjector.getMacAddressUtil()).thenReturn(mMacAddressUtil); when(mWifiInjector.getWifiMetrics()).thenReturn(mWifiMetrics); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true); when(mMacAddressUtil.calculatePersistentMac(any(), any())).thenReturn(TEST_RANDOMIZED_MAC); when(mWifiScoreCard.lookupNetwork(any())).thenReturn(mPerNetwork); @@ -2912,6 +2913,8 @@ public class WifiConfigManagerTest extends WifiBaseTest { setupStoreDataForUserRead(user2Networks, new HashMap<>()); // Now switch the user to user 2 and ensure that user 1's private network has been removed. when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user1Network.creatorUid)) + .thenReturn(false); Set removedNetworks = mWifiConfigManager.handleUserSwitch(user2); verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class)); assertTrue((removedNetworks.size() == 1) && (removedNetworks.contains(user1NetworkId))); @@ -2991,7 +2994,7 @@ public class WifiConfigManagerTest extends WifiBaseTest { public void testHandleUserSwitchPushesOtherPrivateNetworksToSharedStore() throws Exception { int user1 = TEST_DEFAULT_USER; int user2 = TEST_DEFAULT_USER + 1; - setupUserProfiles(user2); + setupUserProfiles(user1); int appId = 674; @@ -3029,6 +3032,8 @@ public class WifiConfigManagerTest extends WifiBaseTest { } }; setupStoreDataForUserRead(userNetworks, new HashMap<>()); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user2Network.creatorUid)) + .thenReturn(false); mWifiConfigManager.handleUserUnlock(user1); verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class)); // Capture the written data for the user 1 and ensure that it corresponds to what was @@ -3043,6 +3048,10 @@ public class WifiConfigManagerTest extends WifiBaseTest { // Now switch the user to user2 and ensure that user 2's private network has been moved to // the user store. when(mUserManager.isUserUnlockingOrUnlocked(UserHandle.of(user2))).thenReturn(true); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user1Network.creatorUid)) + .thenReturn(true).thenReturn(false); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user2Network.creatorUid)) + .thenReturn(false).thenReturn(true); mWifiConfigManager.handleUserSwitch(user2); // Set the expected network list before comparing. user1Network should be in shared data. // Note: In the real world, user1Network will no longer be visible now because it should @@ -3107,6 +3116,8 @@ public class WifiConfigManagerTest extends WifiBaseTest { // Unlock the owner of the legacy Passpoint configuration, verify it is removed from // the configured networks (migrated to PasspointManager). setupStoreDataForUserRead(new ArrayList(), new HashMap<>()); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(passpointConfig.creatorUid)) + .thenReturn(false); mWifiConfigManager.handleUserUnlock(user1); verify(mWifiConfigStore).switchUserStoresAndRead(any(List.class)); Pair, List> writtenNetworkList = @@ -3234,7 +3245,8 @@ public class WifiConfigManagerTest extends WifiBaseTest { // Ensure that we have 2 networks in the database before the stop. assertEquals(2, mWifiConfigManager.getConfiguredNetworks().size()); - + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(user1Network.creatorUid)) + .thenReturn(false); mWifiConfigManager.handleUserStop(user1); // Ensure that we only have 1 shared network in the database after the stop. @@ -3436,6 +3448,7 @@ public class WifiConfigManagerTest extends WifiBaseTest { int creatorUid = UserHandle.getUid(user2, 674); when(mWifiPermissionsUtil.checkNetworkSettingsPermission(creatorUid)).thenReturn(false); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(creatorUid)).thenReturn(false); // Create a network for user2 try adding it. This should be rejected. final WifiConfiguration user2Network = WifiConfigurationTestUtil.createPskNetwork(); diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java index 38a0026df..fd27dcc06 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkSuggestionsManagerTest.java @@ -66,6 +66,7 @@ import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Handler; import android.os.IBinder; import android.os.UserHandle; +import android.os.UserManager; import android.os.test.TestLooper; import android.telephony.TelephonyManager; import android.test.suitebuilder.annotation.SmallTest; @@ -150,6 +151,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { private @Mock Notification.Builder mNotificationBuilder; private @Mock Notification mNotification; private @Mock LruConnectionTracker mLruConnectionTracker; + private @Mock UserManager mUserManager; private TestLooper mLooper; private ArgumentCaptor mAppOpChangedListenerCaptor = ArgumentCaptor.forClass(AppOpsManager.OnOpChangedListener.class); @@ -216,6 +218,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { when(mActivityManager.isLowRamDevice()).thenReturn(false); when(mActivityManager.getPackageImportance(any())).thenReturn( IMPORTANCE_FOREGROUND_SERVICE); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true); // setup resource strings for notification. when(mResources.getString(eq(R.string.wifi_suggestion_title), anyString())) @@ -560,7 +563,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { TEST_PACKAGE_1, TEST_FEATURE)); assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, mWifiNetworkSuggestionsManager - .get(TEST_PACKAGE_1).get(0).wifiConfiguration.meteredOverride); + .get(TEST_PACKAGE_1, TEST_UID_1).get(0).wifiConfiguration.meteredOverride); // Verify we did not update config in WCM. verify(mWifiConfigManager, never()).addOrUpdateNetwork(any(), anyInt(), any()); } @@ -607,7 +610,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { TEST_PACKAGE_1, TEST_FEATURE)); assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED, mWifiNetworkSuggestionsManager - .get(TEST_PACKAGE_1).get(0).wifiConfiguration.meteredOverride); + .get(TEST_PACKAGE_1, TEST_UID_1).get(0).wifiConfiguration.meteredOverride); verify(mWifiMetrics, never()).incrementNetworkSuggestionApiUsageNumOfAppInType(anyInt()); // Verify we did update config in WCM. ArgumentCaptor configCaptor = @@ -1066,7 +1069,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { public void testOnNetworkConnectionSuccessWithOneMatch() throws Exception { assertTrue(mWifiNetworkSuggestionsManager .registerSuggestionConnectionStatusListener(mBinder, mListener, - NETWORK_CALLBACK_ID, TEST_PACKAGE_1)); + NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion( WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, true, true); List networkSuggestionList = @@ -1103,7 +1106,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { public void testOnNetworkConnectionSuccessWithOneMatchFromCarrierPrivilegedApp() { assertTrue(mWifiNetworkSuggestionsManager .registerSuggestionConnectionStatusListener(mBinder, mListener, - NETWORK_CALLBACK_ID, TEST_PACKAGE_1)); + NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); when(mWifiCarrierInfoManager.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1)) .thenReturn(TEST_CARRIER_ID); WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion( @@ -1138,6 +1141,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { mWifiNetworkSuggestionsManager.remove(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1)); verify(mWifiConfigManager).removeSuggestionConfiguredNetwork(anyString()); + mInorder.verify(mWifiPermissionsUtil).doesUidBelongToCurrentUser(eq(TEST_UID_1)); // Verify no more broadcast were sent out. mInorder.verifyNoMoreInteractions(); @@ -1152,7 +1156,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { public void testOnSavedOpenNetworkConnectionSuccessWithMultipleMatch() throws Exception { assertTrue(mWifiNetworkSuggestionsManager .registerSuggestionConnectionStatusListener(mBinder, mListener, - NETWORK_CALLBACK_ID, TEST_PACKAGE_1)); + NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); when(mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(TEST_UID_1)) .thenReturn(true); WifiConfiguration config = WifiConfigurationTestUtil.createOpenNetwork(); @@ -1199,7 +1203,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { ArgumentCaptor.forClass(IBinder.DeathRecipient.class); assertTrue(mWifiNetworkSuggestionsManager .registerSuggestionConnectionStatusListener(mBinder, mListener, - NETWORK_CALLBACK_ID, TEST_PACKAGE_1)); + NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); verify(mBinder).linkToDeath(drCaptor.capture(), anyInt()); WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion( WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, true, true); @@ -1249,7 +1253,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { public void testOnNetworkConnectionFailureWithOneMatch() throws Exception { assertTrue(mWifiNetworkSuggestionsManager .registerSuggestionConnectionStatusListener(mBinder, mListener, - NETWORK_CALLBACK_ID, TEST_PACKAGE_1)); + NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion( WifiConfigurationTestUtil.createOpenNetwork(), null, true, false, true, true); List networkSuggestionList = @@ -2467,7 +2471,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { public void testGetNetworkSuggestions() { // test App never suggested. List storedNetworkSuggestionListPerApp = - mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1); + mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1); assertEquals(storedNetworkSuggestionListPerApp.size(), 0); // App add network suggestions then get stored suggestions. @@ -2489,7 +2493,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { TEST_PACKAGE_1, TEST_FEATURE)); mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(true, TEST_PACKAGE_1); storedNetworkSuggestionListPerApp = - mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1); + mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1); assertEquals(new HashSet<>(networkSuggestionList), new HashSet<>(storedNetworkSuggestionListPerApp)); @@ -2498,7 +2502,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { mWifiNetworkSuggestionsManager.remove(new ArrayList<>(), TEST_UID_1, TEST_PACKAGE_1)); storedNetworkSuggestionListPerApp = - mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1); + mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1); assertEquals(storedNetworkSuggestionListPerApp.size(), 0); } @@ -3222,7 +3226,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE); assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_NOT_ALLOWED, status); verify(mNotificationManger, never()).notify(anyInt(), any()); - assertEquals(0, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size()); + assertEquals(0, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1).size()); verify(mWifiMetrics, never()).incrementNetworkSuggestionApiUsageNumOfAppInType(anyInt()); } @@ -3246,7 +3250,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE); assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, status); verify(mNotificationManger, never()).notify(anyInt(), any()); - assertEquals(1, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size()); + assertEquals(1, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1).size()); verify(mWifiMetrics).incrementNetworkSuggestionApiUsageNumOfAppInType( WifiNetworkSuggestionsManager.APP_TYPE_CARRIER_PRIVILEGED); } @@ -3271,7 +3275,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE); assertEquals(status, WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS); verify(mNotificationManger, never()).notify(anyInt(), any()); - assertEquals(1, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size()); + assertEquals(1, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1).size()); } /** @@ -3333,7 +3337,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { when(mWifiCarrierInfoManager.getCarrierIdForPackageWithCarrierPrivileges(TEST_PACKAGE_1)) .thenReturn(TelephonyManager.UNKNOWN_CARRIER_ID); mWifiNetworkSuggestionsManager.resetCarrierPrivilegedApps(); - assertEquals(0, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1).size()); + assertEquals(0, mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1).size()); verify(mWifiConfigManager, times(2)).saveToStore(true); status = mWifiNetworkSuggestionsManager .add(networkSuggestionList, TEST_UID_1, TEST_PACKAGE_1, TEST_FEATURE); @@ -4033,7 +4037,7 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { public void testUnregisterSuggestionConnectionStatusListenerNeverRegistered() { int listenerIdentifier = 1234; mWifiNetworkSuggestionsManager.unregisterSuggestionConnectionStatusListener( - listenerIdentifier, TEST_PACKAGE_1); + listenerIdentifier, TEST_PACKAGE_1, TEST_UID_1); } /** @@ -4083,6 +4087,43 @@ public class WifiNetworkSuggestionsManagerTest extends WifiBaseTest { mWifiNetworkSuggestionsManager.getAllApprovedNetworkSuggestions()); } + /** + * Verify when calling API from background user will fail. + */ + @Test + public void testCallingFromBackgroundUserWillFailed() { + WifiConfiguration wifiConfiguration = WifiConfigurationTestUtil.createOpenNetwork(); + WifiNetworkSuggestion networkSuggestion = new WifiNetworkSuggestion( + wifiConfiguration, null, false, false, true, true); + + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1, + TEST_PACKAGE_1, TEST_FEATURE)); + // When switch the user to background + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(TEST_UID_1)).thenReturn(false); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL, + mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1, + TEST_PACKAGE_1, TEST_FEATURE)); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_INTERNAL, + mWifiNetworkSuggestionsManager.remove(Arrays.asList(networkSuggestion), TEST_UID_1, + TEST_PACKAGE_1)); + assertTrue(mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1).isEmpty()); + assertFalse(mWifiNetworkSuggestionsManager.registerSuggestionConnectionStatusListener( + mBinder, mListener, NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); + + // When switch the user back to foreground + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(TEST_UID_1)).thenReturn(true); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.add(Arrays.asList(networkSuggestion), TEST_UID_1, + TEST_PACKAGE_1, TEST_FEATURE)); + assertFalse(mWifiNetworkSuggestionsManager.get(TEST_PACKAGE_1, TEST_UID_1).isEmpty()); + assertEquals(WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS, + mWifiNetworkSuggestionsManager.remove(Arrays.asList(networkSuggestion), TEST_UID_1, + TEST_PACKAGE_1)); + assertTrue(mWifiNetworkSuggestionsManager.registerSuggestionConnectionStatusListener( + mBinder, mListener, NETWORK_CALLBACK_ID, TEST_PACKAGE_1, TEST_UID_1)); + } + /** * Helper function for creating a test configuration with user credential. * diff --git a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java index 6d1ae2927..55f35e380 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java @@ -4587,12 +4587,12 @@ public class WifiServiceImplTest extends WifiBaseTest { @Test public void testGetNetworkSuggestions() { List testList = new ArrayList<>(); - when(mWifiNetworkSuggestionsManager.get(anyString())).thenReturn(testList); + when(mWifiNetworkSuggestionsManager.get(anyString(), anyInt())).thenReturn(testList); mLooper.startAutoDispatch(); assertEquals(testList, mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME)); mLooper.stopAutoDispatchAndIgnoreExceptions(); - verify(mWifiNetworkSuggestionsManager).get(eq(TEST_PACKAGE_NAME)); + verify(mWifiNetworkSuggestionsManager).get(eq(TEST_PACKAGE_NAME), anyInt()); } /** @@ -4607,7 +4607,7 @@ public class WifiServiceImplTest extends WifiBaseTest { assertTrue(mWifiServiceImpl.getNetworkSuggestions(TEST_PACKAGE_NAME).isEmpty()); mLooper.stopAutoDispatchAndIgnoreExceptions(); - verify(mWifiNetworkSuggestionsManager, never()).get(eq(TEST_PACKAGE_NAME)); + verify(mWifiNetworkSuggestionsManager, never()).get(eq(TEST_PACKAGE_NAME), anyInt()); } /** @@ -5389,12 +5389,12 @@ public class WifiServiceImplTest extends WifiBaseTest { mLooper.dispatchAll(); verify(mWifiNetworkSuggestionsManager).registerSuggestionConnectionStatusListener( eq(mAppBinder), eq(mSuggestionConnectionStatusListener), eq(NETWORK_CALLBACK_ID), - eq(TEST_PACKAGE_NAME)); + eq(TEST_PACKAGE_NAME), anyInt()); mWifiServiceImpl.unregisterSuggestionConnectionStatusListener(NETWORK_CALLBACK_ID, TEST_PACKAGE_NAME); mLooper.dispatchAll(); verify(mWifiNetworkSuggestionsManager).unregisterSuggestionConnectionStatusListener( - eq(NETWORK_CALLBACK_ID), eq(TEST_PACKAGE_NAME)); + eq(NETWORK_CALLBACK_ID), eq(TEST_PACKAGE_NAME), anyInt()); } diff --git a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java index dbc38d493..ad207bfe2 100644 --- a/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java +++ b/tests/wifitests/src/com/android/server/wifi/hotspot2/PasspointManagerTest.java @@ -99,6 +99,7 @@ import com.android.server.wifi.hotspot2.anqp.OsuProviderInfo; import com.android.server.wifi.proto.nano.WifiMetricsProto.UserActionEvent; import com.android.server.wifi.util.InformationElementUtil; import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium; +import com.android.server.wifi.util.WifiPermissionsUtil; import org.junit.Before; import org.junit.Test; @@ -188,6 +189,7 @@ public class PasspointManagerTest extends WifiBaseTest { @Mock TelephonyManager mTelephonyManager; @Mock SubscriptionManager mSubscriptionManager; @Mock WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; + @Mock WifiPermissionsUtil mWifiPermissionsUtil; Handler mHandler; TestLooper mLooper; @@ -216,6 +218,7 @@ public class PasspointManagerTest extends WifiBaseTest { when(mWifiInjector.getClientModeImpl()).thenReturn(mClientModeImpl); when(mWifiInjector.getWifiNetworkSuggestionsManager()) .thenReturn(mWifiNetworkSuggestionsManager); + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(true); mWifiCarrierInfoManager = new WifiCarrierInfoManager(mTelephonyManager, mSubscriptionManager, mWifiInjector, mock(FrameworkFacade.class), mock(WifiContext.class), mWifiConfigStore, mock(Handler.class), mWifiMetrics); @@ -223,7 +226,7 @@ public class PasspointManagerTest extends WifiBaseTest { mHandler = new Handler(mLooper.getLooper()); mManager = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative, mWifiKeyStore, mClock, mObjectFactory, mWifiConfigManager, - mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager); + mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager, mWifiPermissionsUtil); ArgumentCaptor callbacks = ArgumentCaptor.forClass(PasspointEventHandler.Callbacks.class); verify(mObjectFactory).makePasspointEventHandler(any(WifiNative.class), @@ -519,6 +522,29 @@ public class PasspointManagerTest extends WifiBaseTest { verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); } + /** + * Verify that adding a provider from a background user will fail. + * + * @throws Exception + */ + @Test + public void addProviderWithBackgroundUser() throws Exception { + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(false); + + PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, + TEST_FRIENDLY_NAME); + PasspointProvider provider = createMockProvider(config); + when(provider.getPackageName()).thenReturn(TEST_PACKAGE); + when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), + eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), + eq(false))).thenReturn(provider); + assertFalse(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, + TEST_PACKAGE, false, true)); + + verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); + verify(mWifiMetrics, never()).incrementNumPasspointProviderInstallSuccess(); + } + /** * Verify that adding a user saved provider with a valid configuration and user credential will * succeed. @@ -749,7 +775,7 @@ public class PasspointManagerTest extends WifiBaseTest { .thenReturn(true); PasspointManager ut = new PasspointManager(mContext, mWifiInjector, mHandler, mWifiNative, mWifiKeyStore, mClock, spyFactory, mWifiConfigManager, - mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager); + mWifiConfigStore, mWifiMetrics, mWifiCarrierInfoManager, mWifiPermissionsUtil); assertTrue(ut.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, true, true)); @@ -1894,6 +1920,29 @@ public class PasspointManagerTest extends WifiBaseTest { assertFalse(mManager.getProviderConfigs(TEST_CREATOR_UID, false).isEmpty()); } + /** + * Verify that removing a provider from a background user will fail. + * + * @throws Exception + */ + @Test + public void removeProviderWithBackgroundUser() throws Exception { + PasspointConfiguration config = createTestConfigWithUserCredential(TEST_FQDN, + TEST_FRIENDLY_NAME); + PasspointProvider provider = createMockProvider(config); + when(mObjectFactory.makePasspointProvider(eq(config), eq(mWifiKeyStore), + eq(mWifiCarrierInfoManager), anyLong(), eq(TEST_CREATOR_UID), eq(TEST_PACKAGE), + eq(false))).thenReturn(provider); + assertTrue(mManager.addOrUpdateProvider(config, TEST_CREATOR_UID, TEST_PACKAGE, + false, true)); + verifyInstalledConfig(config); + verify(mWifiMetrics).incrementNumPasspointProviderInstallation(); + verify(mWifiMetrics).incrementNumPasspointProviderInstallSuccess(); + + when(mWifiPermissionsUtil.doesUidBelongToCurrentUser(anyInt())).thenReturn(false); + assertFalse(mManager.removeProvider(TEST_CREATOR_UID, false, null, TEST_FQDN)); + } + /** * Verify that adding a suggestion provider with a valid configuration and user credential will * succeed. -- cgit v1.2.3