1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi; 18 19 import static com.android.server.wifi.InsecureEapNetworkHandler.TOFU_ANONYMOUS_IDENTITY; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertNotNull; 23 import static org.junit.Assert.assertTrue; 24 import static org.junit.Assume.assumeFalse; 25 import static org.junit.Assume.assumeTrue; 26 import static org.mockito.Mockito.any; 27 import static org.mockito.Mockito.anyInt; 28 import static org.mockito.Mockito.anyString; 29 import static org.mockito.Mockito.argThat; 30 import static org.mockito.Mockito.atLeastOnce; 31 import static org.mockito.Mockito.eq; 32 import static org.mockito.Mockito.mock; 33 import static org.mockito.Mockito.never; 34 import static org.mockito.Mockito.spy; 35 import static org.mockito.Mockito.validateMockitoUsage; 36 import static org.mockito.Mockito.verify; 37 import static org.mockito.Mockito.when; 38 import static org.mockito.Mockito.withSettings; 39 40 import android.app.Notification; 41 import android.content.BroadcastReceiver; 42 import android.content.Intent; 43 import android.net.wifi.WifiConfiguration; 44 import android.net.wifi.WifiContext; 45 import android.net.wifi.WifiEnterpriseConfig; 46 import android.os.Handler; 47 import android.text.TextUtils; 48 import android.text.format.DateFormat; 49 50 import androidx.test.filters.SmallTest; 51 52 import com.android.dx.mockito.inline.extended.ExtendedMockito; 53 import com.android.modules.utils.build.SdkLevel; 54 import com.android.server.wifi.util.CertificateSubjectInfo; 55 import com.android.wifi.resources.R; 56 57 import org.junit.After; 58 import org.junit.Before; 59 import org.junit.Test; 60 import org.mockito.Answers; 61 import org.mockito.ArgumentCaptor; 62 import org.mockito.Captor; 63 import org.mockito.Mock; 64 import org.mockito.MockitoAnnotations; 65 import org.mockito.MockitoSession; 66 import org.mockito.stubbing.Answer; 67 68 import java.io.ByteArrayInputStream; 69 import java.io.InputStream; 70 import java.security.cert.CertificateFactory; 71 import java.security.cert.X509Certificate; 72 73 /** 74 * Unit tests for {@link com.android.server.wifi.InsecureEapNetworkHandlerTest}. 75 */ 76 @SmallTest 77 public class InsecureEapNetworkHandlerTest extends WifiBaseTest { 78 79 private static final int ACTION_ACCEPT = 0; 80 private static final int ACTION_REJECT = 1; 81 private static final int ACTION_TAP = 2; 82 private static final String WIFI_IFACE_NAME = "wlan-test-9"; 83 private static final int FRAMEWORK_NETWORK_ID = 2; 84 private static final String TEST_SSID = "\"test_ssid\""; 85 private static final String TEST_IDENTITY = "userid"; 86 private static final String TEST_PASSWORD = "myPassWord!"; 87 private static final String TEST_EXPECTED_SHA_256_SIGNATURE = "54:59:5D:FC:64:9C:17:72:C0:59:" 88 + "9D:25:BD:1F:04:18:E6:00:AB:F4:0A:F0:78:D8:9A:FF:56:C0:7C:89:96:2F"; 89 private static final int TEST_GEN_CA_CERT = 0; 90 private static final int TEST_GEN_CA2_CERT = 1; 91 private static final int TEST_GEN_SERVER_CERT = 2; 92 private static final int TEST_GEN_SELF_SIGNED_CERT = 3; 93 private static final int TEST_GEN_FAKE_CA_CERT = 4; 94 95 private static final String TEST_SERVER_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" 96 + "MIIGPjCCBCagAwIBAgIUN2Ss1JmvjveRe97iWoNh4V+Y5LYwDQYJKoZIhvcNAQEM\n" 97 + "BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQK\n" 98 + "DBJBbmRyb2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8\n" 99 + "MDoGA1UEAwwzQW5kcm9pZCBQYXJ0bmVyIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5k\n" 100 + "IGRldmVsb3BtZW50MB4XDTIzMDQxMzAyMTYwMVoXDTQzMDQwODAyMTYwMVowgYMx\n" 101 + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMR0wGwYDVQQKDBRBbmRy\n" 102 + "b2lkIFdpLUZpIFRlc3RlcjEYMBYGA1UECwwPYW5kcm9pZHdpZmkub2VtMSYwJAYD\n" 103 + "VQQDDB1BbmRyb2lkIFdpLUZpIE9FTSBUZXN0IFNlcnZlcjCCAiIwDQYJKoZIhvcN\n" 104 + "AQEBBQADggIPADCCAgoCggIBAKveC9QnsxvM2TMzkUINabtM2Bi5M5gzV4v1MN0h\n" 105 + "n1XjXhfRXwwLMK9xtV05r91YQaOTPkHNgA6nhjmL7agcquGPlR7nuS04oxCaqfo4\n" 106 + "unbroyyqDMaXd8U6B1VlvWSbWAAhBEEAPYDhFXF9V83XHEGcp61Hs4VetGmlC3tW\n" 107 + "W1CLIk+o9JRYsZeK4Q1DurAY7YPU8U84QNxPG7OXg+ensGtspuLLNFEdnd9tSi45\n" 108 + "u5KyPpnSwTdRGSCfMVocxj0EINpdrLnWZyf9NX8Uo7tg/D0TFVBo+MbKjgItIdMg\n" 109 + "STLQwceOdOGHZTPiItzpFcP9EA5ug5gXobPjzDTJO2S3NhUt5NURfGr/wyepxR25\n" 110 + "PDRhBgc/xwc7JrtDGaqmknguZuf7Zai/m4iquC0Wh38bWKms8R0ND/H923aFppxp\n" 111 + "vzX/sWotsTYWiGMehh7v6iwIYADifsXBlJXTUhTZt6cnwttZYfp5oqymCsIhXKVU\n" 112 + "IXOE/PLcU71G9U+jCa7PNs5X5LgqorNPABOpkVL+fDpvopNCdhOEVvwCAIl4tIxl\n" 113 + "M0goFbBmY1wnFFYIUki91UfbeUimCUbBq/RSxuXn3liVB/X+dnyjJ3RnNxJ3Wy1m\n" 114 + "mcHFIVV5VxN6tC7XTXYgZAv0EJGCcVn0RN3ldPWGRLTEIQu7cXRSfqs89N4S31Et\n" 115 + "SjaxAgMBAAGjgZMwgZAwHQYDVR0OBBYEFHh9fcIU3LHamK7PdpasvHmzyRoLMB8G\n" 116 + "A1UdIwQYMBaAFH7ro7AWsBlMNpyRXHGW1hG4c1ocMAkGA1UdEwQCMAAwCwYDVR0P\n" 117 + "BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMCEGA1UdEQQaMBiCFnNlcnZlci5h\n" 118 + "bmRyb2lkd2lmaS5vZW0wDQYJKoZIhvcNAQEMBQADggIBAOIkOLyF8mmYvj8TeM2V\n" 119 + "d4YMj4sWf7L5C2lq9OGBJwZad1xytymWWZ7PpNf1MopabfUzxPjw5EfMC94MJmpf\n" 120 + "gqYOwFAye5fXQ8CLC39tb681u44tv/B5vqP74TKVhCR8O1YCsIssa8t8e5nIwcYr\n" 121 + "fj3SBu7iOLtL7zjfEXFo3oSEwVYnvS3lhZL8NTrrHscy/ZLFE3nGRq2d3jPbyuoH\n" 122 + "1FJwenxnD6a/AztERPkRNGk2oSFkWecNU9PC9w3bI5wF4I2AIaFgBOj20S7pVtq7\n" 123 + "7nhKnQFrZYVeWbqbInQcRAcSopI6D6tB/F/T9R1WCWBxvpwdciv7BeNgOtGKAszA\n" 124 + "z0sOxI6O4U77R+tFeb0vCwC0OhVL3W0zX3Fy2835D/hC2P1jmMBlxLVKYHY48RBC\n" 125 + "sG1I1qAMD4eXle8rG9MkB9cE5KfncjCrzSQjT8gs7QBTafb6B3WDdwzfaCaQTOOF\n" 126 + "Tsyrdq0TTJP71bt5qWTr6UZIBE5Tjel+DPpvQlPZPYygXPrI3WBcT12VLhti0II6\n" 127 + "1jgkS8fPLR0VypHR02V5fqCRmy9ln0rSyHXFwL3JpeXYD92eLOKdS1MhIUN4bDxZ\n" 128 + "fiXXVKpKU4gqqWAan2RjbBzQjsi6Eh3yuDm2SAqNZVacpOt7BIslqEZ+Og6KhTTk\n" 129 + "DCzyEOB87ySrUWu3PN3r2sJN\n" 130 + "-----END CERTIFICATE-----"; 131 132 private static final String TEST_CA_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" 133 + "MIIGADCCA+igAwIBAgIUFkmrYCj/UYNrizDdMATu6dE3lBIwDQYJKoZIhvcNAQEM\n" 134 + "BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQK\n" 135 + "DBJBbmRyb2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8\n" 136 + "MDoGA1UEAwwzQW5kcm9pZCBQYXJ0bmVyIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5k\n" 137 + "IGRldmVsb3BtZW50MB4XDTIzMDQxMzAyMTYwMVoXDTQzMDQwODAyMTYwMVowgZcx\n" 138 + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQKDBJBbmRy\n" 139 + "b2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8MDoGA1UE\n" 140 + "AwwzQW5kcm9pZCBQYXJ0bmVyIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5kIGRldmVs\n" 141 + "b3BtZW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9JERd2HVp/PI\n" 142 + "3WmaaHDKHDuWZoxUDlyVrTDd1Vu2zhH3A5KJ232QOMxJiLdZ/KxgcpGlAEllijae\n" 143 + "xihxhkHEYr7ff2/p6ZhUWr+0vuk8f4TZsKDAE0SoZoDBHTIbrJf8hHM5/+R//sx1\n" 144 + "/fTf8abOj20zyeWmXqvUNXoVKiRvjiZD69tcRHmfmTOMX0lAirOel8ZwwDFamH8d\n" 145 + "wov0IIyd58m6CV91WnScgg7TOzw/IGpccft73RbDw7cHU5i3G3KhOqamwJbErgya\n" 146 + "x97AsSVCqjBz7rEwm6pHjUagbgVAk9ULmI1McQzMINIrOWRF0Q8awWpvDNwPu86J\n" 147 + "W/LfyzAruWtriimycpl7wv0b/f7JhKerG0+44JUI0sgTz/kobAsU8nfYSyVu8+cX\n" 148 + "HwnDE2jBGB6co2Y00eVKxy6+gWTekpQTyHuPoCieNDukC/38Mj+U0KUZkgGv4CL7\n" 149 + "zaVBGzjSjtnAp47aXciaDvDbpST23ICS7TN5cUnXQ1fWfNUMNkEbIPy2mrlRoCxg\n" 150 + "OJ67UEvGIygE0IUvwDfFvF21+1yKk6D/kU9gMgd6DKtvWj1CIyKXWf+rQ01OHNhX\n" 151 + "YcOTkF5aF2WU558DuS+utGBzXWFsLxqBRe9nDb9W/SlrT2jajfwLelMddvtZmVsY\n" 152 + "NG8IeY8lDs5hcFBvm/BDr0SvBDhs9H0CAwEAAaNCMEAwHQYDVR0OBBYEFH7ro7AW\n" 153 + "sBlMNpyRXHGW1hG4c1ocMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGG\n" 154 + "MA0GCSqGSIb3DQEBDAUAA4ICAQBINF6auWUhCO0l/AqO5pLgOqZ7BjAzHGDNapW+\n" 155 + "3nn2YicDD/X2eJASfsd3jN5JluBlbLqRBBWnIsNG/fyKxY8I4+IrR1x8ovwBjeJ3\n" 156 + "McQeCW2zedluVp2SW3LaNQS+aptXHATJ6O8EOny2LDM+obEtFyLuDC89a1TXjEdj\n" 157 + "XGIYmSJ8RwpKAi4u6ff4jhtNTSEa/eIUE5zUREV0916xtmu5y1vlmsEbpLEquOph\n" 158 + "ZWxpUVTqGEyc0hHaivAWyBG1dtRgov5olzHchM2TsEq/VufiRAw5uzRQ/sAyVjj4\n" 159 + "pcvWnLDLTYk/+uIG1zmbc0rNpAC7b3tplA4OqTtFb3yX0ppPFUg4OaxhMyu4WqS3\n" 160 + "roNiXc8BmtfzMqyWAG21QUfosLa8heiiHgnvkiUa9V2oJ4kWAhOTmLdU70aocu4N\n" 161 + "pcN5jcT5hSl/A91Lvfht0C9BLOrXU+RDCNAVIUnnWSrgduUPTydKVdUkLxau4G/+\n" 162 + "G8fKAyeCouFNq7bp4DEMkgqAWpx96Qe6FLxAS59Ig3tI8MZSieBZezJyjP4GWtuq\n" 163 + "QsnARbwD7z73FWQ+eqXOhkoqDoQc8E2lQGe8OGbacGuUwXo3PUgGaJobz+2Hqa9g\n" 164 + "6AnBkH6AbvooUwSWSCyYIf2LA+GvZotI+PXWuQL7dqWtkaNf98qqfnlZXjp51e+h\n" 165 + "B8nquw==\n" 166 + "-----END CERTIFICATE-----"; 167 168 private static final String TEST_CA2_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" 169 + "MIIGADCCA+igAwIBAgIUGm2nmrZw4ADU7h/TGKd67Uz5bJIwDQYJKoZIhvcNAQEM\n" 170 + "BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQK\n" 171 + "DBJBbmRyb2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8\n" 172 + "MDoGA1UEAwwzQW5vdGhlciBBbmRyb2lkIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5k\n" 173 + "IGRldmVsb3BtZW50MB4XDTIzMDQxMzAyMTkxOVoXDTQzMDQwODAyMTkxOVowgZcx\n" 174 + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQKDBJBbmRy\n" 175 + "b2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8MDoGA1UE\n" 176 + "AwwzQW5vdGhlciBBbmRyb2lkIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5kIGRldmVs\n" 177 + "b3BtZW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvv7PYhFHK+nC\n" 178 + "KoDiQI7dhDFTNU4RxTTsxMRSt1n/FJGZX/r8nnr76gB+oofFVjKQusYhuquKGPGq\n" 179 + "ZfrfmtsNhcVBMnNRjZkBWpNb3XO+7F+Qd/gT7yoiZ0L3Ef4QMCGqNrf10EWmXvVQ\n" 180 + "tpaM7RrkmlW6Zu2VbfP/iQQ7EVFrFWmnZfkCxpkLT+LK+pxwNxtJz5l7VRYkXelw\n" 181 + "9vFdq81C+obBpLWg62mNVNa25g6y46YrSOPyxhiemiRih+avIZ9Z6/7qRoVu7t8U\n" 182 + "NpxzMdsDL5bJREadsjpQWZr7A+umm0nlod1DB204K18Y5Z4GuOEGifdHIUmb+3c4\n" 183 + "Kz14FzBahyc3xsZL73AsGEVWLHIQQ/kjepomVl8HuSHdgw6SZR30JhWgU/bcVl01\n" 184 + "8qc6qH7x3e64Ip9xHdng42oPJHEKYipRed3AXzlCQ7Lc9MeAeR+nB9JuSNc6HW0L\n" 185 + "eh9Po0cDJa194UfNeqJ7SG2uNpeg/OUbM+M3iO3dmCRcV3GzirbT8eHZk3Cor3gb\n" 186 + "h9AzmJnHyRaRc9Xtj7AE8swJRvAoWVlCzcBcvaLAW0hn2DWXbWXHDf63Q8n5F4J5\n" 187 + "pf//2eXWaOXFLvkm9wYUj6kXOehcibB2O1F1YvqWE3XZ5GTDq/+E5wK55aifq+bz\n" 188 + "l1Mb1ILIB3cEEL9w+0ClHCno+2XGMOkCAwEAAaNCMEAwHQYDVR0OBBYEFH0KeaUK\n" 189 + "koS2PMYfpcanoTkRBTzmMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGG\n" 190 + "MA0GCSqGSIb3DQEBDAUAA4ICAQCnnL83fEA3g8fiJHpeSNSVZ4R3VunQU2BDkwUj\n" 191 + "NgFWPMsZNQcKoChUA5mb8wOM/fk9tdjMsQR5fRO30B94Eoo9NM39HztBcvvLV9i7\n" 192 + "qNQCTjFE7zf4weX6K3tZICR8nZ1Ogccp3itEDkNpOylFLdQxkc29RrKcuculb3PM\n" 193 + "C7IMREKROKFzrAwWkFAaxJGfByTRfjOqWJFgdRq/GHU2yCKkCLN4zRLjr5ZaAk2J\n" 194 + "+8b+Y1/pIW4j2FAB7ebmq0ZbMbdc+EFdVf36WrsWf54L3DsZOuoaC+2wTsyWQ0b/\n" 195 + "8tqJ/XS39I4uo8KpI5//aQpM1usxP0/pWUm9sTXE618Yf2Ynh64eDQHPIAmt+Xoh\n" 196 + "BfIx+nXVkCl4DGGdwvOURUULdHN9wf6YPOXxaMEYxQRGMwmBAlmiDaH41xeaht/A\n" 197 + "+iv3y918rJFDAXWKvGia8oDi1xIL+IDZ1AGVByNp+C/AE5BTV2m9UHZyXsXrMiQA\n" 198 + "ezUrVpiWB6h4C4rUuaucQv1gO6gEPZGEDdvIG8TGJg8wvLL0oZiyaL3gQxlGs0CZ\n" 199 + "tbDGqugtlh4RLeJ1N/TTFkLzf4CAgDTxfqhMKXkFvpMvO6ZHOT7xC0sdaD2FbZRj\n" 200 + "h5ziC9nvWEdTA8RLr0i/r5nFb6GsxmEk6NYFmpnyo5pvlxf5xqOhsJZlcKnUJ8SQ\n" 201 + "NIGLmw==\n" 202 + "-----END CERTIFICATE-----"; 203 204 private static final String TEST_SELF_SIGNED_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" 205 + "MIIFxzCCA6+gAwIBAgIUB8Kqwhhhs1liW23ve7pZsFlv0zAwDQYJKoZIhvcNAQEM\n" 206 + "BQAwezELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExGzAZBgNVBAoM\n" 207 + "EkFuZHJvaWQgV2ktRmkgVGVzdDEYMBYGA1UECwwPYW5kcm9pZHdpZmkuZGV2MSAw\n" 208 + "HgYDVQQDDBdTZWxmLXNpZ25lZCBjZXJ0aWZpY2F0ZTAeFw0yMzA0MTMwMjE0MTda\n" 209 + "Fw00MzA0MDgwMjE0MTdaMHsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y\n" 210 + "bmlhMRswGQYDVQQKDBJBbmRyb2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJv\n" 211 + "aWR3aWZpLmRldjEgMB4GA1UEAwwXU2VsZi1zaWduZWQgY2VydGlmaWNhdGUwggIi\n" 212 + "MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDD0oI2c+1D4D2wc4PnhkXbtA7g\n" 213 + "64Mp/JSbnVbl7PseJKnFD/pdos5joFXFbySFqu60S905T1a3AWNwbucKc7C7IwQw\n" 214 + "gtO7uMEPr35j7MhItyAbmj89dY729yXJ8gBnNnqc8PyYEIfZmnBvSry0Tsm60298\n" 215 + "GGZ9yCQfOOb4TJFX/CIKjniI170eLCiGybOrBvG11Rx6BwwHnk1cjkDspejrkhb0\n" 216 + "13RfkQ1S0cEnylrgnn/nRDAAnOscpHRerJ6Ud2vM64iIJy206ZyU/CrhcGeBWwi9\n" 217 + "C1F4ojzvgoFW7bJahXiyEaC5R3G5WdvX5qOr/eu/yMaCAner0LHUibHc5XA02F/c\n" 218 + "LO0LpN59tTT4dx9sLJVjZQGSUxyXnKHiR5TKkoAMWAZSO5hbE4drgivKLnYmYnhC\n" 219 + "Z1rGM5R0D0gB2llAvecItmynDJNApY6L1F8wnNA9NfGUYFpeqJ8uEOn7RxAvyYmB\n" 220 + "trmUFOqL7W84d1/XzORPGQ7n1wyPfBG3xyGIm2MMvanVsLs0/9NXAYAz2ZAHJPnS\n" 221 + "DsiV+7OHtMCdgTI5BJFmiJpXKgVE+IaewQdSjXDU7bgMlll3lTVoVAiKJmxpOmZ6\n" 222 + "FFz7mkd0pYhsO5jQpNGMfl+IaoIiTx4Zg9ZjwjTcPn9eGunBLJJ8SofkhM4boLrC\n" 223 + "KSen8NYuHVDPwAOwpQIDAQABo0MwQTAdBgNVHQ4EFgQU2IB1Q35ysx0HpRttAqMU\n" 224 + "FO9OhIAwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3\n" 225 + "DQEBDAUAA4ICAQBqf4zbooJ4hHeZs7Nd31G7i2WEr6/8OWTuEuDAmJkGW8WBeyUG\n" 226 + "JMrxF3U+kGxVGops4mSxMwVpcsqQa+IwkrP807dSqkuntLVGFqVo7rcQ+l8OcNUv\n" 227 + "oNQIFGPLlWPyMnjXvmWbfvgbgFoY9yUFoxFlHqsVf+1mEvTmW9ya4BGT2hlfvtb6\n" 228 + "Jfvrrocg9zGSnBs9oyI+GzP4Xdqd0riXfk6OuFH3R05/cQj7SlPm8LU1J7ZML/4H\n" 229 + "1AuMg+Ql8vxql4IzIk93CDR8Hq1jb3MhF/ae9UfttuNnHT4vu5X/6qLqWNKMs3zP\n" 230 + "DQQaYkqxWTUWiNlWV7i7pXn8e2J8ZkRHVELvrpdXLKIfL6RxjzKWY+TKiHY+F48I\n" 231 + "JwCAbL1FX+NzB2dS0RxXk/RTAxagenfmDcY1notHNsnDZB54cP9nv+N3wqkDoaKg\n" 232 + "nqOZTlIRWJ4agygqGaxieUuZRgy/AE/dSGpetlXAScKUvhCcO22qXL2jSjBAg5+k\n" 233 + "AynUuiZxdogXbvXrAwSWAVwlz8qEOK3NPFYnEKcjgNbTxiUHp3P/ULBgHQo55o9K\n" 234 + "DdUEbIurd02xG6usEDWxR5ds/RPy6VZ5c6bFUiTEsfMMmQotPL/btuPVXsSdJUR4\n" 235 + "xcxpcV7zx9IjFs/IylyQ1YEYDKWV+nH7iiOigO5WiZ5ck2Wa/Tk3uXg1Ew==\n" 236 + "-----END CERTIFICATE-----\n"; 237 238 private static final String TEST_FAKE_CA_CERTIFICATE = "-----BEGIN CERTIFICATE-----\n" 239 + "MIIGADCCA+igAwIBAgIUIxVGWM5Wrs86DpDA2+fo53UryqMwDQYJKoZIhvcNAQEM\n" 240 + "BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQK\n" 241 + "DBJBbmRyb2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8\n" 242 + "MDoGA1UEAwwzQW5kcm9pZCBQYXJ0bmVyIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5k\n" 243 + "IGRldmVsb3BtZW50MB4XDTIzMDQxMzE1MzkyM1oXDTQzMDQwODE1MzkyM1owgZcx\n" 244 + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRswGQYDVQQKDBJBbmRy\n" 245 + "b2lkIFdpLUZpIFRlc3QxGDAWBgNVBAsMD2FuZHJvaWR3aWZpLm9lbTE8MDoGA1UE\n" 246 + "AwwzQW5kcm9pZCBQYXJ0bmVyIFJvb3QgQ0EgZm9yIHRlc3RpbmcgYW5kIGRldmVs\n" 247 + "b3BtZW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAhTF8MJsucR5P\n" 248 + "6oN/Nho92EYz9b3m7n52m9KgI/G6/9bK9PSDZ6Z6U3qNxpG7nFML+5qyk+qeBHP8\n" 249 + "39lGNNoH1c2dQDXw3oLjOmd1UoN+zSZBznLwkDD8YQYafz1GWRcI34FYDgiPuSx7\n" 250 + "o4+O4hxcimrelhoNRQcRsrZFoUyJZjtPy2Z5DTZTB7udg1QwZ+7+pHCme3DB2Im/\n" 251 + "Eszsmm2TAG6yM3G/lxphLZMhUFy6kjeeIiuar56ED6dg7qEqdeIznt2gGKolXRWs\n" 252 + "vPW4a5NX1RUjsQxOcKEQnrXZXJ9mATptY1hOxuP6kg8Jzh0tN/NzyyERGFvnvhGz\n" 253 + "sN7CkTUhPOKUW3dVrKl9ZJ9PbYZ6xbpbOWOR/5znYQ/f3+bxxibbFI3WN/89VO50\n" 254 + "WEzwfmiGiWC6Bz0iBoAmGjCxySbJg8iDCjrbRexkFsOJ84jlY0fDrfaqY1+WuyYu\n" 255 + "vdk+w4lzk0wYRbp+oRuIXplMyZDsS15CPq+svoYeNCCOXlkRiMLuq/SpkdM8lRKp\n" 256 + "Mrsc1AckI+BGVqh8S9lyJoP67uDmba1FUw7X3IMCkZQwvFduLkJLNYwO6QDV2M6R\n" 257 + "nUCVCx+vxJdlIOLNQIAeKW9jzfASom4ehZY2HHErbUYGKzFQJJ/2+uQLLYn7PsaE\n" 258 + "gYTYA1naakQegCgbD2UsbKqrEfOiHEECAwEAAaNCMEAwHQYDVR0OBBYEFBiYeS/E\n" 259 + "IQ5+IoQ3bsXoibK3QuMzMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGG\n" 260 + "MA0GCSqGSIb3DQEBDAUAA4ICAQACOOZdfcQ53BF43glA/0VuFeXQ+VS+keR9aFBX\n" 261 + "caKrIbFXSns9EsnvKj1L/IoHem5k4LkMFoNgE1Skit2iktPYs6unV83p99PG6EQo\n" 262 + "RG1CeZ50cHzZK6N56MbwZUGRy/p6Zr9ak9d6XE8GpvSwMW8XebrLPtgSBvpI+WIZ\n" 263 + "epMVg7v8AIIRQuoR2VtZ7RZF/X1kwfU5t2aASVBnxTjlSy6KtBLuL+Vu4Aefa+Z0\n" 264 + "d9Ma2jZV+hwWp0X6piSrVKkMZIR5tlvwJootNBlO0J1Jn4J0ecGNEGXmFwz4adnK\n" 265 + "eYfpuNBJI4CKq7mv2Aszsvg0rQxfKlN8LV7gSNu3H6BjjkNUtHI6uwsajJfEmGKD\n" 266 + "YRpAFgZq7FzRwoI8uWr0Bucz6+qxpISi48t0pmceSVpn6UV1UdSebLo8CX5P283F\n" 267 + "yUqlw2hMpo22Gm3uW8GfPyHfMfsqfMU+7BCP38DDnhcGUO3CTINjREXUGtn6CuWS\n" 268 + "ImhmATld6KJNtRCql3zQnaEO84IvKdFVOkm5q9qQjNWDr1oYsLhxoZJZjKK2rP5F\n" 269 + "GRbMvqDhmzrV0yG+sIyW+aEjBl44bVjWQnFhGjtNr1BOOftSyjnseYiioLbiiaYG\n" 270 + "9Mqu78VmTWJzfxyOP2QPK5K00jnVBZ+jQH0NyIE9yf2Cg/llfYRoHsz80cfY/DNt\n" 271 + "jUR49A==\n" 272 + "-----END CERTIFICATE-----"; 273 274 @Mock WifiContext mContext; 275 @Mock WifiConfigManager mWifiConfigManager; 276 @Mock WifiNative mWifiNative; 277 @Mock FrameworkFacade mFrameworkFacade; 278 @Mock WifiNotificationManager mWifiNotificationManager; 279 @Mock WifiDialogManager mWifiDialogManager; 280 @Mock Handler mHandler; 281 @Mock InsecureEapNetworkHandler.InsecureEapNetworkHandlerCallbacks mCallbacks; 282 283 @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Notification.Builder mNotificationBuilder; 284 @Mock private WifiDialogManager.DialogHandle mTofuAlertDialog; 285 @Mock private java.text.DateFormat mDateFormat; 286 @Captor ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor; 287 288 MockResources mResources; 289 InsecureEapNetworkHandler mInsecureEapNetworkHandler; 290 291 private MockitoSession mSession; 292 293 /** 294 * Sets up for unit test 295 */ 296 @Before setUp()297 public void setUp() throws Exception { 298 MockitoAnnotations.initMocks(this); 299 mResources = new MockResources(); 300 when(mContext.getString(anyInt())).thenReturn("TestString"); 301 when(mContext.getString(anyInt(), any())).thenReturn("TestStringWithArgument"); 302 when(mContext.getText(anyInt())).thenReturn("TestStr"); 303 when(mContext.getString(eq(R.string.wifi_ca_cert_dialog_message_issuer_name_text), 304 anyString())) 305 .thenAnswer((Answer<String>) invocation -> 306 "Issuer Name:\n" + invocation.getArguments()[1] + "\n\n"); 307 when(mContext.getString(eq(R.string.wifi_ca_cert_dialog_message_server_name_text), 308 anyString())) 309 .thenAnswer((Answer<String>) invocation -> 310 "Server Name:\n" + invocation.getArguments()[1] + "\n\n"); 311 when(mContext.getString(eq(R.string.wifi_ca_cert_dialog_message_organization_text), 312 anyString())) 313 .thenAnswer((Answer<String>) invocation -> 314 "Organization:\n" + invocation.getArguments()[1] + "\n\n"); 315 when(mContext.getString(eq(R.string.wifi_ca_cert_dialog_message_contact_text), 316 anyString())) 317 .thenAnswer((Answer<String>) invocation -> 318 "Contact:\n" + invocation.getArguments()[1] + "\n\n"); 319 when(mContext.getString(eq(R.string.wifi_ca_cert_dialog_message_signature_name_text), 320 anyString())) 321 .thenAnswer((Answer<String>) invocation -> 322 "SHA-256 Fingerprint:\n" + invocation.getArguments()[1] + "\n\n"); 323 when(mContext.getWifiOverlayApkPkgName()).thenReturn("test.com.android.wifi.resources"); 324 when(mContext.getResources()).thenReturn(mResources); 325 when(mWifiDialogManager.createSimpleDialogWithUrl( 326 any(), any(), any(), anyInt(), anyInt(), any(), any(), any(), any(), any())) 327 .thenReturn(mTofuAlertDialog); 328 when(mWifiDialogManager.createSimpleDialog( 329 any(), any(), any(), any(), any(), any(), any())) 330 .thenReturn(mTofuAlertDialog); 331 332 when(mFrameworkFacade.makeNotificationBuilder(any(), any())) 333 .thenReturn(mNotificationBuilder); 334 335 // static mocking 336 mSession = ExtendedMockito.mockitoSession() 337 .mockStatic(DateFormat.class, withSettings().lenient()) 338 .startMocking(); 339 when(DateFormat.getMediumDateFormat(any())).thenReturn(mDateFormat); 340 when(mDateFormat.format(any())).thenReturn("April 12, 2023"); 341 } 342 343 @After cleanUp()344 public void cleanUp() throws Exception { 345 validateMockitoUsage(); 346 mSession.finishMocking(); 347 } 348 349 /** 350 * Verify Trust On First Use flow. 351 * - This network is selected by a user. 352 * - Accept the connection. 353 */ 354 @Test verifyTrustOnFirstUseAcceptWhenConnectByUser()355 public void verifyTrustOnFirstUseAcceptWhenConnectByUser() throws Exception { 356 assumeTrue(SdkLevel.isAtLeastT()); 357 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 358 boolean needUserApproval = true; 359 360 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 361 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 362 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_ACCEPT, 363 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 364 } 365 366 /** 367 * Verify Trust On First Use flow. 368 * - This network is selected by a user. 369 * - Reject the connection. 370 */ 371 @Test verifyTrustOnFirstUseRejectWhenConnectByUser()372 public void verifyTrustOnFirstUseRejectWhenConnectByUser() throws Exception { 373 assumeTrue(SdkLevel.isAtLeastT()); 374 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 375 boolean needUserApproval = true; 376 377 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 378 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 379 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_REJECT, 380 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 381 } 382 383 /** 384 * Verify Trust On First Use flow. 385 * - This network is auto-connected. 386 * - Accept the connection. 387 */ 388 @Test verifyTrustOnFirstUseAcceptWhenConnectByAutoConnect()389 public void verifyTrustOnFirstUseAcceptWhenConnectByAutoConnect() throws Exception { 390 assumeTrue(SdkLevel.isAtLeastT()); 391 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = false; 392 boolean needUserApproval = true; 393 394 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 395 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 396 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_ACCEPT, 397 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 398 } 399 400 /** 401 * Verify Trust On First Use flow. 402 * - This network is auto-connected. 403 * - Reject the connection. 404 */ 405 @Test verifyTrustOnFirstUseRejectWhenConnectByAutoConnect()406 public void verifyTrustOnFirstUseRejectWhenConnectByAutoConnect() throws Exception { 407 assumeTrue(SdkLevel.isAtLeastT()); 408 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = false; 409 boolean needUserApproval = true; 410 411 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 412 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 413 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_REJECT, 414 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 415 } 416 417 /** 418 * Verify Trust On First Use flow. 419 * - This network is auto-connected. 420 * - Tap the notification to show the dialog. 421 */ 422 @Test verifyTrustOnFirstUseTapWhenConnectByAutoConnect()423 public void verifyTrustOnFirstUseTapWhenConnectByAutoConnect() throws Exception { 424 assumeTrue(SdkLevel.isAtLeastT()); 425 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = false; 426 boolean needUserApproval = true; 427 428 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 429 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 430 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_TAP, 431 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 432 } 433 434 /** 435 * Verify that it reports errors if there is no pending Root CA certifiate 436 * with Trust On First Use support. 437 */ 438 @Test verifyTrustOnFirstUseWhenTrustOnFirstUseNoPendingCert()439 public void verifyTrustOnFirstUseWhenTrustOnFirstUseNoPendingCert() throws Exception { 440 assumeTrue(SdkLevel.isAtLeastT()); 441 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 442 443 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 444 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 445 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 446 verify(mCallbacks).onError(eq(config.SSID)); 447 verify(mWifiConfigManager, atLeastOnce()).updateNetworkSelectionStatus(eq(config.networkId), 448 eq(WifiConfiguration.NetworkSelectionStatus 449 .DISABLED_BY_WIFI_MANAGER)); 450 } 451 452 /** 453 * Verify that Trust On First Use is not supported on T. 454 * It follows the same behavior on preT release. 455 */ 456 @Test verifyTrustOnFirstUseWhenTrustOnFirstUseNotSupported()457 public void verifyTrustOnFirstUseWhenTrustOnFirstUseNotSupported() throws Exception { 458 assumeTrue(SdkLevel.isAtLeastT()); 459 boolean isAtLeastT = true, isTrustOnFirstUseSupported = false, isUserSelected = true; 460 461 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 462 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 463 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 464 verify(mCallbacks, never()).onError(any()); 465 } 466 467 /** 468 * Verify legacy insecure EAP network flow. 469 * - This network is selected by a user. 470 * - Accept the connection. 471 */ 472 @Test verifyLegacyEapNetworkAcceptWhenConnectByUser()473 public void verifyLegacyEapNetworkAcceptWhenConnectByUser() throws Exception { 474 assumeFalse(SdkLevel.isAtLeastT()); 475 boolean isAtLeastT = false, isTrustOnFirstUseSupported = false, isUserSelected = true; 476 boolean needUserApproval = true; 477 478 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 479 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 480 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_ACCEPT, 481 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 482 } 483 484 /** 485 * Verify legacy insecure EAP network flow. 486 * - Trust On First Use is not supported. 487 * - This network is selected by a user. 488 * - Reject the connection. 489 */ 490 @Test verifyLegacyEapNetworkRejectWhenConnectByUser()491 public void verifyLegacyEapNetworkRejectWhenConnectByUser() throws Exception { 492 assumeFalse(SdkLevel.isAtLeastT()); 493 boolean isAtLeastT = false, isTrustOnFirstUseSupported = false, isUserSelected = true; 494 boolean needUserApproval = true; 495 496 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 497 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 498 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_REJECT, 499 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 500 } 501 502 /** 503 * Verify legacy insecure EAP network flow. 504 * - This network is auto-connected. 505 * - Accept the connection. 506 */ 507 @Test verifyLegacyEapNetworkAcceptWhenAutoConnect()508 public void verifyLegacyEapNetworkAcceptWhenAutoConnect() throws Exception { 509 assumeFalse(SdkLevel.isAtLeastT()); 510 boolean isAtLeastT = false, isTrustOnFirstUseSupported = false, isUserSelected = false; 511 boolean needUserApproval = true; 512 513 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 514 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 515 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_ACCEPT, 516 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 517 } 518 519 /** 520 * Verify legacy insecure EAP network flow. 521 * - Trust On First Use is not supported. 522 * - This network is auto-connected. 523 * - Reject the connection. 524 */ 525 @Test verifyLegacyEapNetworkRejectWhenAutoConnect()526 public void verifyLegacyEapNetworkRejectWhenAutoConnect() throws Exception { 527 assumeFalse(SdkLevel.isAtLeastT()); 528 boolean isAtLeastT = false, isTrustOnFirstUseSupported = false, isUserSelected = false; 529 boolean needUserApproval = true; 530 531 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 532 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 533 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_REJECT, 534 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 535 } 536 537 /** 538 * Verify legacy insecure EAP network flow. 539 * - This network is selected by a user. 540 * - Tap the notification 541 */ 542 @Test verifyLegacyEapNetworkOpenLinkWhenConnectByUser()543 public void verifyLegacyEapNetworkOpenLinkWhenConnectByUser() throws Exception { 544 assumeFalse(SdkLevel.isAtLeastT()); 545 boolean isAtLeastT = false, isTrustOnFirstUseSupported = false, isUserSelected = true; 546 boolean needUserApproval = true; 547 548 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 549 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 550 verifyTrustOnFirstUseFlowWithDefaultCerts(config, ACTION_TAP, 551 isTrustOnFirstUseSupported, isUserSelected, needUserApproval); 552 } 553 554 /** 555 * Verify Trust On First Use flow with server certificate pinning 556 * - Single depth server certificate by signed by some unknown issuer, CA flag not set 557 * - This network is selected by a user. 558 * - Accept the connection. 559 */ 560 @Test verifyTrustOnFirstUseFlowWithServerCertPinning1()561 public void verifyTrustOnFirstUseFlowWithServerCertPinning1() throws Exception { 562 assumeTrue(SdkLevel.isAtLeastT()); 563 runServerCertPinningTest(TEST_GEN_SERVER_CERT); 564 } 565 566 /** 567 * Verify Trust On First Use flow with server certificate pinning 568 * - Single depth server certificate by signed by some unknown issuer, CA flag set 569 * - This network is selected by a user. 570 * - Accept the connection. 571 */ 572 @Test verifyTrustOnFirstUseFlowWithServerCertPinning2()573 public void verifyTrustOnFirstUseFlowWithServerCertPinning2() throws Exception { 574 assumeTrue(SdkLevel.isAtLeastT()); 575 runServerCertPinningTest(TEST_GEN_CA_CERT); 576 } 577 runServerCertPinningTest(int type)578 private void runServerCertPinningTest(int type) 579 throws Exception { 580 WifiConfiguration config = prepareWifiConfiguration(true); 581 setupTest(config, true, true); 582 583 CertificateEventInfo mockServerCert = generateMockCertEventInfo(type); 584 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockServerCert); 585 verifyTrustOnFirstUseFlow(config, ACTION_ACCEPT, true, 586 true, false, null, mockServerCert.getCert()); 587 } 588 generateMockCertEventInfo(int type)589 private CertificateEventInfo generateMockCertEventInfo(int type) throws Exception { 590 CertificateEventInfo certificateEventInfo = mock(CertificateEventInfo.class); 591 X509Certificate cert = getCertificate(type); 592 593 when(certificateEventInfo.getCert()).thenReturn(cert); 594 when(certificateEventInfo.getCertHash()).thenReturn("12345678"); 595 return certificateEventInfo; 596 } 597 getCertificate(int type)598 private X509Certificate getCertificate(int type) throws Exception { 599 String certString; 600 601 if (type == TEST_GEN_CA_CERT) { 602 certString = TEST_CA_CERTIFICATE; 603 } else if (type == TEST_GEN_CA2_CERT) { 604 certString = TEST_CA2_CERTIFICATE; 605 } else if (type == TEST_GEN_SERVER_CERT) { 606 certString = TEST_SERVER_CERTIFICATE; 607 } else if (type == TEST_GEN_SELF_SIGNED_CERT) { 608 certString = TEST_SELF_SIGNED_CERTIFICATE; 609 } else if (type == TEST_GEN_FAKE_CA_CERT) { 610 certString = TEST_FAKE_CA_CERTIFICATE; 611 } else { 612 throw (new Exception()); 613 } 614 615 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 616 InputStream in = new ByteArrayInputStream(certString.getBytes()); 617 return (X509Certificate) certFactory.generateCertificate(in); 618 } 619 prepareWifiConfiguration(boolean isAtLeastT)620 private WifiConfiguration prepareWifiConfiguration(boolean isAtLeastT) { 621 WifiConfiguration config = spy(WifiConfigurationTestUtil.createEapNetwork( 622 WifiEnterpriseConfig.Eap.TTLS, WifiEnterpriseConfig.Phase2.MSCHAPV2)); 623 config.networkId = FRAMEWORK_NETWORK_ID; 624 config.SSID = TEST_SSID; 625 if (isAtLeastT) { 626 config.enterpriseConfig.enableTrustOnFirstUse(true); 627 } 628 config.enterpriseConfig.setCaPath(""); 629 config.enterpriseConfig.setDomainSuffixMatch(""); 630 config.enterpriseConfig.setIdentity(TEST_IDENTITY); 631 config.enterpriseConfig.setPassword(TEST_PASSWORD); 632 return config; 633 } 634 setupTest(WifiConfiguration config, boolean isAtLeastT, boolean isTrustOnFirstUseSupported)635 private void setupTest(WifiConfiguration config, 636 boolean isAtLeastT, boolean isTrustOnFirstUseSupported) { 637 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported, false); 638 } 639 setupTest(WifiConfiguration config, boolean isAtLeastT, boolean isTrustOnFirstUseSupported, boolean isInsecureEnterpriseConfigurationAllowed)640 private void setupTest(WifiConfiguration config, 641 boolean isAtLeastT, boolean isTrustOnFirstUseSupported, 642 boolean isInsecureEnterpriseConfigurationAllowed) { 643 mInsecureEapNetworkHandler = new InsecureEapNetworkHandler( 644 mContext, 645 mWifiConfigManager, 646 mWifiNative, 647 mFrameworkFacade, 648 mWifiNotificationManager, 649 mWifiDialogManager, 650 isTrustOnFirstUseSupported, 651 isInsecureEnterpriseConfigurationAllowed, 652 mCallbacks, 653 WIFI_IFACE_NAME, 654 mHandler); 655 656 if (isTrustOnFirstUseSupported 657 && (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TTLS 658 || config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.PEAP) 659 && config.enterpriseConfig.getPhase2Method() != WifiEnterpriseConfig.Phase2.NONE) { 660 // Verify that the configuration contains an identity 661 assertEquals(TEST_IDENTITY, config.enterpriseConfig.getIdentity()); 662 assertTrue(TextUtils.isEmpty(config.enterpriseConfig.getAnonymousIdentity())); 663 assertEquals(TEST_PASSWORD, config.enterpriseConfig.getPassword()); 664 } 665 mInsecureEapNetworkHandler.prepareConnection(config); 666 667 if (isTrustOnFirstUseSupported && config.enterpriseConfig.isTrustOnFirstUseEnabled() 668 && (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.TTLS 669 || config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.PEAP) 670 && config.enterpriseConfig.getPhase2Method() != WifiEnterpriseConfig.Phase2.NONE) { 671 // Verify identities are cleared 672 assertTrue(TextUtils.isEmpty(config.enterpriseConfig.getIdentity())); 673 assertEquals(TOFU_ANONYMOUS_IDENTITY, config.enterpriseConfig.getAnonymousIdentity()); 674 assertTrue(TextUtils.isEmpty(config.enterpriseConfig.getPassword())); 675 } 676 677 if (isTrustOnFirstUseSupported && config.enterpriseConfig.isTrustOnFirstUseEnabled()) { 678 verify(mContext, atLeastOnce()).registerReceiver( 679 mBroadcastReceiverCaptor.capture(), 680 argThat(f -> f.hasAction(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_TAP)), 681 eq(null), 682 eq(mHandler)); 683 } else if ((isTrustOnFirstUseSupported 684 && !config.enterpriseConfig.isTrustOnFirstUseEnabled() 685 && isInsecureEnterpriseConfigurationAllowed) 686 || !isTrustOnFirstUseSupported) { 687 verify(mContext, atLeastOnce()).registerReceiver( 688 mBroadcastReceiverCaptor.capture(), 689 argThat(f -> f.hasAction(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_ACCEPT) 690 && f.hasAction(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_REJECT)), 691 eq(null), 692 eq(mHandler)); 693 } 694 } 695 696 /** 697 * Verify Trust On First Use flow with a minimal cert chain 698 * - This network is selected by a user. 699 * - Accept the connection. 700 */ 701 @Test verifyTrustOnFirstUseAcceptWhenConnectByUserWithMinimalChain()702 public void verifyTrustOnFirstUseAcceptWhenConnectByUserWithMinimalChain() throws Exception { 703 assumeTrue(SdkLevel.isAtLeastT()); 704 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 705 boolean needUserApproval = true; 706 707 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 708 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 709 710 CertificateEventInfo mockCaCert = generateMockCertEventInfo(TEST_GEN_CA_CERT); 711 CertificateEventInfo mockServerCert = generateMockCertEventInfo(TEST_GEN_SERVER_CERT); 712 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 1, mockCaCert); 713 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockServerCert); 714 715 verifyTrustOnFirstUseFlow(config, ACTION_ACCEPT, isTrustOnFirstUseSupported, 716 isUserSelected, needUserApproval, mockCaCert.getCert(), mockServerCert.getCert()); 717 } 718 719 /** 720 * Verify that the connection should be terminated. 721 * - TOFU is supported. 722 * - Insecure EAP network is not allowed. 723 * - No cert is received. 724 */ 725 @Test verifyOnErrorWithoutCert()726 public void verifyOnErrorWithoutCert() throws Exception { 727 assumeTrue(SdkLevel.isAtLeastT()); 728 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 729 730 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 731 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 732 733 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 734 verify(mCallbacks).onError(eq(config.SSID)); 735 verify(mWifiConfigManager, atLeastOnce()).updateNetworkSelectionStatus(eq(config.networkId), 736 eq(WifiConfiguration.NetworkSelectionStatus 737 .DISABLED_BY_WIFI_MANAGER)); 738 } 739 740 /** 741 * Verify that the connection should be upgraded to TOFU. 742 * - TOFU is supported. 743 * - Insecure EAP network is not allowed. 744 * - TOFU is not enabled 745 */ 746 @Test verifyOnErrorWithTofuDisabledWhenInsecureEapNetworkIsNotAllowed()747 public void verifyOnErrorWithTofuDisabledWhenInsecureEapNetworkIsNotAllowed() 748 throws Exception { 749 assumeTrue(SdkLevel.isAtLeastT()); 750 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 751 752 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 753 config.enterpriseConfig.enableTrustOnFirstUse(false); 754 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 755 756 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 1, 757 generateMockCertEventInfo(TEST_GEN_CA_CERT)); 758 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, 759 generateMockCertEventInfo(TEST_GEN_SERVER_CERT)); 760 761 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 762 assertTrue(config.enterpriseConfig.isTrustOnFirstUseEnabled()); 763 } 764 765 /** 766 * Verify that no error occurs in insecure network handling flow. 767 * - TOFU is supported. 768 * - Insecure EAP network is allowed. 769 * - TOFU is not enabled 770 * - No user approval is needed. 771 */ 772 @Test verifyNoErrorWithTofuDisabledWhenInsecureEapNetworkIsAllowed()773 public void verifyNoErrorWithTofuDisabledWhenInsecureEapNetworkIsAllowed() 774 throws Exception { 775 assumeTrue(SdkLevel.isAtLeastT()); 776 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 777 boolean isInsecureEnterpriseConfigurationAllowed = true; 778 779 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 780 config.enterpriseConfig.enableTrustOnFirstUse(false); 781 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported, 782 isInsecureEnterpriseConfigurationAllowed); 783 784 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 1, 785 generateMockCertEventInfo(TEST_GEN_CA_CERT)); 786 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, 787 generateMockCertEventInfo(TEST_GEN_SERVER_CERT)); 788 789 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 790 verify(mCallbacks, never()).onError(any()); 791 } 792 793 /** 794 * Verify that is reports errors if the server cert issuer does not match the parent subject. 795 */ 796 @Test verifyOnErrorWithIncompleteChain()797 public void verifyOnErrorWithIncompleteChain() throws Exception { 798 assumeTrue(SdkLevel.isAtLeastT()); 799 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 800 801 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 802 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 803 804 CertificateEventInfo mockCaCert = generateMockCertEventInfo(TEST_GEN_CA2_CERT); 805 // Missing intermediate cert. 806 CertificateEventInfo mockServerCert = generateMockCertEventInfo(TEST_GEN_SERVER_CERT); 807 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 1, mockCaCert); 808 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockServerCert); 809 810 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 811 verify(mCallbacks).onError(eq(config.SSID)); 812 verify(mWifiConfigManager, atLeastOnce()).updateNetworkSelectionStatus(eq(config.networkId), 813 eq(WifiConfiguration.NetworkSelectionStatus 814 .DISABLED_BY_WIFI_MANAGER)); 815 } 816 817 /** 818 * Verify that it reports errors if the issuer is a fake Root CA with the same subject of the 819 * real Root CA. Simulates an attack where the leaf is copied from the real server but a fake 820 * Root CA that an attacker controls is attached. 821 */ 822 @Test verifyOnErrorWithFakeRootCaCertInTheChain()823 public void verifyOnErrorWithFakeRootCaCertInTheChain() throws Exception { 824 assumeTrue(SdkLevel.isAtLeastT()); 825 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 826 827 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 828 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 829 830 // Fake Root CA that didn't sign the server cert 831 CertificateEventInfo mockCaCert = generateMockCertEventInfo(TEST_GEN_FAKE_CA_CERT); 832 CertificateEventInfo mockServerCert = generateMockCertEventInfo(TEST_GEN_SERVER_CERT); 833 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 1, mockCaCert); 834 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockServerCert); 835 836 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 837 verify(mCallbacks).onError(eq(config.SSID)); 838 verify(mWifiConfigManager, atLeastOnce()).updateNetworkSelectionStatus(eq(config.networkId), 839 eq(WifiConfiguration.NetworkSelectionStatus 840 .DISABLED_BY_WIFI_MANAGER)); 841 } 842 843 /** 844 * Verify that setting pending certificate won't crash with no current configuration. 845 */ 846 @Test verifySetPendingCertificateNoCrashWithNoConfig()847 public void verifySetPendingCertificateNoCrashWithNoConfig() 848 throws Exception { 849 assumeTrue(SdkLevel.isAtLeastT()); 850 mInsecureEapNetworkHandler = new InsecureEapNetworkHandler( 851 mContext, 852 mWifiConfigManager, 853 mWifiNative, 854 mFrameworkFacade, 855 mWifiNotificationManager, 856 mWifiDialogManager, 857 true /* isTrustOnFirstUseSupported */, 858 false /* isInsecureEnterpriseConfigurationAllowed */, 859 mCallbacks, 860 WIFI_IFACE_NAME, 861 mHandler); 862 CertificateEventInfo mockSelfSignedCert = 863 generateMockCertEventInfo(TEST_GEN_SELF_SIGNED_CERT); 864 mInsecureEapNetworkHandler.addPendingCertificate("NotExist", 0, mockSelfSignedCert); 865 } 866 867 @Test testExistingCertChainIsClearedOnPreparingNewConnection()868 public void testExistingCertChainIsClearedOnPreparingNewConnection() throws Exception { 869 assumeTrue(SdkLevel.isAtLeastT()); 870 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 871 872 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 873 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 874 875 // Missing root CA cert. 876 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, 877 generateMockCertEventInfo(TEST_GEN_SERVER_CERT)); 878 879 // The wrong cert chain should be cleared after this call. 880 mInsecureEapNetworkHandler.prepareConnection(config); 881 882 CertificateEventInfo mockSelfSignedCert = 883 generateMockCertEventInfo(TEST_GEN_SELF_SIGNED_CERT); 884 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockSelfSignedCert); 885 886 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 887 verify(mCallbacks, never()).onError(any()); 888 } 889 890 @Test verifyUserApprovalIsNotNeededWithDifferentTargetConfig()891 public void verifyUserApprovalIsNotNeededWithDifferentTargetConfig() throws Exception { 892 assumeTrue(SdkLevel.isAtLeastT()); 893 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true, isUserSelected = true; 894 895 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 896 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 897 898 CertificateEventInfo mockSelfSignedCert = 899 generateMockCertEventInfo(TEST_GEN_SELF_SIGNED_CERT); 900 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockSelfSignedCert); 901 902 // Pass another PSK config which is not the same as the current one. 903 WifiConfiguration pskConfig = WifiConfigurationTestUtil.createPskNetwork(); 904 pskConfig.networkId = FRAMEWORK_NETWORK_ID + 2; 905 mInsecureEapNetworkHandler.prepareConnection(pskConfig); 906 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 907 verify(mCallbacks, never()).onError(any()); 908 909 // Pass another non-TOFU EAP config which is not the same as the current one. 910 WifiConfiguration anotherEapConfig = spy(WifiConfigurationTestUtil.createEapNetwork( 911 WifiEnterpriseConfig.Eap.SIM, WifiEnterpriseConfig.Phase2.NONE)); 912 anotherEapConfig.networkId = FRAMEWORK_NETWORK_ID + 1; 913 mInsecureEapNetworkHandler.prepareConnection(anotherEapConfig); 914 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 915 verify(mCallbacks, never()).onError(any()); 916 } 917 verifyTrustOnFirstUseFlowWithDefaultCerts(WifiConfiguration config, int action, boolean isTrustOnFirstUseSupported, boolean isUserSelected, boolean needUserApproval)918 private void verifyTrustOnFirstUseFlowWithDefaultCerts(WifiConfiguration config, 919 int action, boolean isTrustOnFirstUseSupported, boolean isUserSelected, 920 boolean needUserApproval) throws Exception { 921 CertificateEventInfo mockCaCert = generateMockCertEventInfo(TEST_GEN_CA_CERT); 922 CertificateEventInfo mockServerCert = generateMockCertEventInfo(TEST_GEN_SERVER_CERT); 923 if (isTrustOnFirstUseSupported) { 924 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 1, mockCaCert); 925 mInsecureEapNetworkHandler.addPendingCertificate(config.SSID, 0, mockServerCert); 926 } 927 verifyTrustOnFirstUseFlow(config, action, isTrustOnFirstUseSupported, 928 isUserSelected, needUserApproval, mockCaCert.getCert(), mockServerCert.getCert()); 929 } 930 verifyTrustOnFirstUseFlow(WifiConfiguration config, int action, boolean isTrustOnFirstUseSupported, boolean isUserSelected, boolean needUserApproval, X509Certificate expectedCaCert, X509Certificate expectedServerCert)931 private void verifyTrustOnFirstUseFlow(WifiConfiguration config, 932 int action, boolean isTrustOnFirstUseSupported, boolean isUserSelected, 933 boolean needUserApproval, X509Certificate expectedCaCert, 934 X509Certificate expectedServerCert) throws Exception { 935 mInsecureEapNetworkHandler.startUserApprovalIfNecessary(isUserSelected); 936 937 ArgumentCaptor<String> dialogMessageCaptor = ArgumentCaptor.forClass(String.class); 938 if (isUserSelected) { 939 ArgumentCaptor<WifiDialogManager.SimpleDialogCallback> dialogCallbackCaptor = 940 ArgumentCaptor.forClass(WifiDialogManager.SimpleDialogCallback.class); 941 verify(mWifiDialogManager).createSimpleDialogWithUrl( 942 any(), dialogMessageCaptor.capture(), any(), anyInt(), anyInt(), any(), any(), 943 any(), dialogCallbackCaptor.capture(), any()); 944 if (isTrustOnFirstUseSupported) { 945 assertTofuDialogMessage(expectedServerCert, 946 dialogMessageCaptor.getValue()); 947 } 948 if (action == ACTION_ACCEPT) { 949 dialogCallbackCaptor.getValue().onPositiveButtonClicked(); 950 } else if (action == ACTION_REJECT) { 951 dialogCallbackCaptor.getValue().onNegativeButtonClicked(); 952 } 953 } else { 954 verify(mFrameworkFacade, never()).makeAlertDialogBuilder(any()); 955 verify(mFrameworkFacade).makeNotificationBuilder( 956 eq(mContext), eq(WifiService.NOTIFICATION_NETWORK_ALERTS)); 957 958 // Trust On First Use notification has no accept and reject action buttons. 959 // It only supports TAP and launch the dialog. 960 if (isTrustOnFirstUseSupported) { 961 Intent intent = new Intent(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_TAP); 962 intent.putExtra(InsecureEapNetworkHandler.EXTRA_PENDING_CERT_SSID, TEST_SSID); 963 BroadcastReceiver br = mBroadcastReceiverCaptor.getValue(); 964 br.onReceive(mContext, intent); 965 ArgumentCaptor<WifiDialogManager.SimpleDialogCallback> dialogCallbackCaptor = 966 ArgumentCaptor.forClass(WifiDialogManager.SimpleDialogCallback.class); 967 verify(mWifiDialogManager).createSimpleDialogWithUrl( 968 any(), dialogMessageCaptor.capture(), any(), anyInt(), anyInt(), any(), 969 any(), any(), dialogCallbackCaptor.capture(), any()); 970 assertTofuDialogMessage(expectedServerCert, 971 dialogMessageCaptor.getValue()); 972 if (action == ACTION_ACCEPT) { 973 dialogCallbackCaptor.getValue().onPositiveButtonClicked(); 974 } else if (action == ACTION_REJECT) { 975 dialogCallbackCaptor.getValue().onNegativeButtonClicked(); 976 } 977 } else { 978 Intent intent = new Intent(); 979 if (action == ACTION_ACCEPT) { 980 intent = new Intent(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_ACCEPT); 981 } else if (action == ACTION_REJECT) { 982 intent = new Intent(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_REJECT); 983 } else if (action == ACTION_TAP) { 984 intent = new Intent(InsecureEapNetworkHandler.ACTION_CERT_NOTIF_TAP); 985 } 986 intent.putExtra(InsecureEapNetworkHandler.EXTRA_PENDING_CERT_SSID, TEST_SSID); 987 BroadcastReceiver br = mBroadcastReceiverCaptor.getValue(); 988 br.onReceive(mContext, intent); 989 } 990 } 991 992 if (action == ACTION_ACCEPT) { 993 verify(mWifiConfigManager).updateNetworkSelectionStatus(eq(config.networkId), 994 eq(WifiConfiguration.NetworkSelectionStatus.DISABLED_NONE)); 995 verify(mCallbacks).onAccept(eq(config.SSID), eq(config.networkId)); 996 } else if (action == ACTION_REJECT) { 997 verify(mWifiConfigManager, atLeastOnce()) 998 .updateNetworkSelectionStatus(eq(config.networkId), 999 eq(WifiConfiguration.NetworkSelectionStatus 1000 .DISABLED_BY_WIFI_MANAGER)); 1001 verify(mCallbacks).onReject(eq(config.SSID), eq(!isTrustOnFirstUseSupported)); 1002 } else if (action == ACTION_TAP) { 1003 verify(mWifiDialogManager).createSimpleDialogWithUrl( 1004 any(), any(), any(), anyInt(), anyInt(), any(), any(), any(), any(), any()); 1005 verify(mTofuAlertDialog).launchDialog(); 1006 } 1007 verify(mCallbacks, never()).onError(any()); 1008 } 1009 assertTofuDialogMessage( X509Certificate serverCert, String message)1010 private void assertTofuDialogMessage( 1011 X509Certificate serverCert, 1012 String message) { 1013 CertificateSubjectInfo serverCertSubjectInfo = 1014 CertificateSubjectInfo.parse(serverCert.getSubjectX500Principal().getName()); 1015 CertificateSubjectInfo serverCertIssuerInfo = 1016 CertificateSubjectInfo.parse(serverCert.getIssuerX500Principal().getName()); 1017 assertNotNull("Server cert subject info is null", serverCertSubjectInfo); 1018 assertNotNull("Server cert issuer info is null", serverCertIssuerInfo); 1019 1020 assertTrue("TOFU dialog message does not contain server cert subject name ", 1021 message.contains(serverCertSubjectInfo.commonName)); 1022 assertTrue("TOFU dialog message does not contain server cert issuer name", 1023 message.contains(serverCertIssuerInfo.commonName)); 1024 if (!TextUtils.isEmpty(serverCertSubjectInfo.organization)) { 1025 assertTrue("TOFU dialog message does not contain server cert organization", 1026 message.contains(serverCertSubjectInfo.organization)); 1027 } 1028 } 1029 1030 @Test testCleanUp()1031 public void testCleanUp() throws Exception { 1032 assumeTrue(SdkLevel.isAtLeastT()); 1033 1034 boolean isAtLeastT = true, isTrustOnFirstUseSupported = true; 1035 WifiConfiguration config = prepareWifiConfiguration(isAtLeastT); 1036 setupTest(config, isAtLeastT, isTrustOnFirstUseSupported); 1037 1038 BroadcastReceiver br = mBroadcastReceiverCaptor.getValue(); 1039 mInsecureEapNetworkHandler.cleanup(); 1040 verify(mContext).unregisterReceiver(br); 1041 } 1042 1043 /** 1044 * Verify the getDigest and fingerprint methods 1045 */ 1046 @Test verifyGetDigest()1047 public void verifyGetDigest() throws Exception { 1048 CertificateEventInfo mockServerCert = generateMockCertEventInfo(TEST_GEN_SERVER_CERT); 1049 assertEquals(TEST_EXPECTED_SHA_256_SIGNATURE, 1050 mInsecureEapNetworkHandler.getDigest(mockServerCert.getCert(), "SHA256")); 1051 } 1052 } 1053