1package com.android.hotspot2.osu; 2 3import android.net.Network; 4import android.util.Base64; 5import android.util.Log; 6 7import com.android.hotspot2.Utils; 8import com.android.hotspot2.flow.PlatformAdapter; 9import com.android.hotspot2.pps.HomeSP; 10 11import java.io.ByteArrayInputStream; 12import java.io.IOException; 13import java.net.InetAddress; 14import java.net.InetSocketAddress; 15import java.net.Socket; 16import java.net.URL; 17import java.security.GeneralSecurityException; 18import java.security.KeyStore; 19import java.security.KeyStoreException; 20import java.security.PrivateKey; 21import java.security.cert.CertPath; 22import java.security.cert.CertPathValidator; 23import java.security.cert.CertPathValidatorException; 24import java.security.cert.Certificate; 25import java.security.cert.CertificateException; 26import java.security.cert.CertificateFactory; 27import java.security.cert.PKIXCertPathChecker; 28import java.security.cert.PKIXParameters; 29import java.security.cert.TrustAnchor; 30import java.security.cert.X509Certificate; 31import java.util.ArrayList; 32import java.util.Arrays; 33import java.util.Collection; 34import java.util.Collections; 35import java.util.HashSet; 36import java.util.List; 37import java.util.Map; 38import java.util.Set; 39 40import javax.net.SocketFactory; 41import javax.net.ssl.KeyManager; 42import javax.net.ssl.SSLContext; 43import javax.net.ssl.TrustManager; 44import javax.net.ssl.X509TrustManager; 45 46public class OSUSocketFactory { 47 private static final long ConnectionTimeout = 10000L; 48 private static final long ReconnectWait = 2000L; 49 50 private static final String SecureHTTP = "https"; 51 private static final String UnsecureHTTP = "http"; 52 private static final String EKU_ID = "2.5.29.37"; 53 private static final Set<String> EKU_ID_SET = new HashSet<>(Arrays.asList(EKU_ID)); 54 private static final EKUChecker sEKUChecker = new EKUChecker(); 55 56 private final Network mNetwork; 57 private final SocketFactory mSocketFactory; 58 private final KeyManager mKeyManager; 59 private final WFATrustManager mTrustManager; 60 private final List<InetSocketAddress> mRemotes; 61 62 public static Set<X509Certificate> buildCertSet() { 63 try { 64 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 65 Set<X509Certificate> set = new HashSet<>(); 66 for (String b64 : WFACerts) { 67 ByteArrayInputStream bis = new ByteArrayInputStream( 68 Base64.decode(b64, Base64.DEFAULT)); 69 X509Certificate cert = (X509Certificate) certFactory.generateCertificate(bis); 70 set.add(cert); 71 } 72 return set; 73 } catch (CertificateException ce) { 74 Log.e(OSUManager.TAG, "Cannot build CA cert set"); 75 return null; 76 } 77 } 78 79 public static OSUSocketFactory getSocketFactory(KeyStore ks, HomeSP homeSP, 80 OSUFlowManager.FlowType flowType, 81 Network network, URL url, KeyManager km, 82 boolean enforceSecurity) 83 throws GeneralSecurityException, IOException { 84 85 if (enforceSecurity && !url.getProtocol().equalsIgnoreCase(SecureHTTP)) { 86 throw new IOException("Protocol '" + url.getProtocol() + "' is not secure"); 87 } 88 return new OSUSocketFactory(ks, homeSP, flowType, network, url, km); 89 } 90 91 private OSUSocketFactory(KeyStore ks, HomeSP homeSP, OSUFlowManager.FlowType flowType, 92 Network network, 93 URL url, KeyManager km) throws GeneralSecurityException, IOException { 94 mNetwork = network; 95 mKeyManager = km; 96 mTrustManager = new WFATrustManager(ks, homeSP, flowType); 97 int port; 98 switch (url.getProtocol()) { 99 case UnsecureHTTP: 100 mSocketFactory = new DefaultSocketFactory(); 101 port = url.getPort() > 0 ? url.getPort() : 80; 102 break; 103 case SecureHTTP: 104 SSLContext tlsContext = SSLContext.getInstance("TLSv1"); 105 tlsContext.init(km != null ? new KeyManager[]{km} : null, 106 new TrustManager[]{mTrustManager}, null); 107 mSocketFactory = tlsContext.getSocketFactory(); 108 port = url.getPort() > 0 ? url.getPort() : 443; 109 break; 110 default: 111 throw new IOException("Bad URL: " + url); 112 } 113 if (OSUManager.R2_MOCK && url.getHost().endsWith(".wi-fi.org")) { 114 // !!! Warning: Ruckus hack! 115 mRemotes = new ArrayList<>(1); 116 mRemotes.add(new InetSocketAddress(InetAddress.getByName("10.123.107.107"), port)); 117 } else { 118 InetAddress[] remotes = mNetwork.getAllByName(url.getHost()); 119 android.util.Log.d(OSUManager.TAG, "'" + url.getHost() + "' resolves to " + 120 Arrays.toString(remotes)); 121 if (remotes == null || remotes.length == 0) { 122 throw new IOException("Failed to look up host from " + url); 123 } 124 mRemotes = new ArrayList<>(remotes.length); 125 for (InetAddress remote : remotes) { 126 mRemotes.add(new InetSocketAddress(remote, port)); 127 } 128 } 129 Collections.shuffle(mRemotes); 130 } 131 132 public void reloadKeys(Map<OSUCertType, List<X509Certificate>> certs, PrivateKey key) 133 throws IOException { 134 if (mKeyManager instanceof ClientKeyManager) { 135 ((ClientKeyManager) mKeyManager).reloadKeys(certs, key); 136 } 137 } 138 139 public Socket createSocket() throws IOException { 140 Socket socket = mSocketFactory.createSocket(); 141 mNetwork.bindSocket(socket); 142 143 long bail = System.currentTimeMillis() + ConnectionTimeout; 144 boolean success = false; 145 146 while (System.currentTimeMillis() < bail) { 147 for (InetSocketAddress remote : mRemotes) { 148 try { 149 socket.connect(remote); 150 Log.d(OSUManager.TAG, "Connection " + socket.getLocalSocketAddress() + 151 " to " + socket.getRemoteSocketAddress()); 152 success = true; 153 break; 154 } catch (IOException ioe) { 155 Log.d(OSUManager.TAG, "Failed to connect to " + remote + ": " + ioe); 156 socket = mSocketFactory.createSocket(); 157 mNetwork.bindSocket(socket); 158 } 159 } 160 if (success) { 161 break; 162 } 163 Utils.delay(ReconnectWait); 164 } 165 if (!success) { 166 throw new IOException("No available network"); 167 } 168 return socket; 169 } 170 171 public X509Certificate getOSUCertificate(URL url) throws GeneralSecurityException { 172 String fqdn = url.getHost(); 173 for (X509Certificate certificate : mTrustManager.getTrustChain()) { 174 for (List<?> name : certificate.getSubjectAlternativeNames()) { 175 if (name.size() >= SPVerifier.DNSName && 176 name.get(0).getClass() == Integer.class && 177 name.get(1).toString().equals(fqdn)) { 178 return certificate; 179 } 180 } 181 } 182 return null; 183 } 184 185 final class DefaultSocketFactory extends SocketFactory { 186 187 DefaultSocketFactory() { 188 } 189 190 @Override 191 public Socket createSocket() throws IOException { 192 return new Socket(); 193 } 194 195 @Override 196 public Socket createSocket(String host, int port) throws IOException { 197 return new Socket(host, port); 198 } 199 200 @Override 201 public Socket createSocket(String host, int port, InetAddress localHost, int localPort) 202 throws IOException { 203 return new Socket(host, port, localHost, localPort); 204 } 205 206 @Override 207 public Socket createSocket(InetAddress host, int port) throws IOException { 208 return new Socket(host, port); 209 } 210 211 @Override 212 public Socket createSocket(InetAddress address, int port, InetAddress localAddress, 213 int localPort) throws IOException { 214 return new Socket(address, port, localAddress, localPort); 215 } 216 } 217 218 private static class WFATrustManager implements X509TrustManager { 219 private final KeyStore mKeyStore; 220 private final HomeSP mHomeSP; 221 private final OSUFlowManager.FlowType mFlowType; 222 private X509Certificate[] mTrustChain; 223 224 private WFATrustManager(KeyStore ks, HomeSP homeSP, OSUFlowManager.FlowType flowType) 225 throws CertificateException { 226 mKeyStore = ks; 227 mHomeSP = homeSP; 228 mFlowType = flowType; 229 } 230 231 @Override 232 public void checkClientTrusted(X509Certificate[] chain, String authType) 233 throws CertificateException { 234 // N/A 235 } 236 237 @Override 238 public void checkServerTrusted(X509Certificate[] chain, String authType) 239 throws CertificateException { 240 Log.d("TLSOSU", "Checking " + chain.length + " certs."); 241 242 try { 243 CertPathValidator validator = 244 CertPathValidator.getInstance(CertPathValidator.getDefaultType()); 245 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 246 CertPath path = certFactory.generateCertPath( 247 Arrays.asList(chain)); 248 Set<TrustAnchor> trustAnchors = new HashSet<>(); 249 if (mHomeSP == null) { 250 for (X509Certificate cert : getRootCerts(mKeyStore)) { 251 trustAnchors.add(new TrustAnchor(cert, null)); 252 } 253 } else { 254 String prefix = mFlowType == OSUFlowManager.FlowType.Remediation ? 255 PlatformAdapter.CERT_REM_ALIAS : PlatformAdapter.CERT_POLICY_ALIAS; 256 257 X509Certificate cert = getCert(mKeyStore, prefix + mHomeSP.getFQDN()); 258 if (cert == null) { 259 cert = getCert(mKeyStore, 260 PlatformAdapter.CERT_SHARED_ALIAS + mHomeSP.getFQDN()); 261 } 262 if (cert == null) { 263 for (X509Certificate root : getRootCerts(mKeyStore)) { 264 trustAnchors.add(new TrustAnchor(root, null)); 265 } 266 } else { 267 trustAnchors.add(new TrustAnchor(cert, null)); 268 } 269 } 270 PKIXParameters params = new PKIXParameters(trustAnchors); 271 params.setRevocationEnabled(false); 272 params.addCertPathChecker(sEKUChecker); 273 validator.validate(path, params); 274 mTrustChain = chain; 275 } catch (GeneralSecurityException gse) { 276 throw new SecurityException(gse); 277 } 278 mTrustChain = chain; 279 } 280 281 @Override 282 public X509Certificate[] getAcceptedIssuers() { 283 return null; 284 } 285 286 public X509Certificate[] getTrustChain() { 287 return mTrustChain != null ? mTrustChain : new X509Certificate[0]; 288 } 289 } 290 291 private static X509Certificate getCert(KeyStore keyStore, String alias) 292 throws KeyStoreException { 293 Certificate cert = keyStore.getCertificate(alias); 294 if (cert != null && cert instanceof X509Certificate) { 295 return (X509Certificate) cert; 296 } 297 return null; 298 } 299 300 public static Set<X509Certificate> getRootCerts(KeyStore keyStore) throws KeyStoreException { 301 Set<X509Certificate> certSet = new HashSet<>(); 302 int index = 0; 303 for (int n = 0; n < 1000; n++) { 304 Certificate cert = keyStore.getCertificate( 305 String.format("%s%d", PlatformAdapter.CERT_WFA_ALIAS, index)); 306 if (cert == null) { 307 break; 308 } else if (cert instanceof X509Certificate) { 309 certSet.add((X509Certificate) cert); 310 } 311 index++; 312 } 313 return certSet; 314 } 315 316 private static class EKUChecker extends PKIXCertPathChecker { 317 @Override 318 public void init(boolean forward) throws CertPathValidatorException { 319 320 } 321 322 @Override 323 public boolean isForwardCheckingSupported() { 324 return true; 325 } 326 327 @Override 328 public Set<String> getSupportedExtensions() { 329 return EKU_ID_SET; 330 } 331 332 @Override 333 public void check(Certificate cert, Collection<String> unresolvedCritExts) 334 throws CertPathValidatorException { 335 Log.d(OSUManager.TAG, "Checking EKU " + unresolvedCritExts); 336 unresolvedCritExts.remove(EKU_ID); 337 } 338 } 339 340 /* 341 * 342 Subject: CN=osu-server.r2-testbed-rks.wi-fi.org, O=Intel Corporation CCG DRD, C=US 343 Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 344 Validity: [From: Wed Jan 28 16:00:00 PST 2015, 345 To: Sat Jan 28 15:59:59 PST 2017] 346 Issuer: CN="NetworkFX, Inc. Hotspot 2.0 Intermediate CA", OU=OSU CA - 01, O="NetworkFX, Inc.", C=US 347 SerialNumber: [ 312af3db 138eae19 1defbce2 e2b88b55] 348 * 349 * 350 Subject: CN="NetworkFX, Inc. Hotspot 2.0 Intermediate CA", OU=OSU CA - 01, O="NetworkFX, Inc.", C=US 351 Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 352 Validity: [From: Tue Nov 19 16:00:00 PST 2013, 353 To: Sun Nov 19 15:59:59 PST 2023] 354 Issuer: CN=Hotspot 2.0 Trust Root CA - 01, O=WFA Hotspot 2.0, C=US 355 SerialNumber: [ 4152b1b0 301495f3 8fa76428 2ef41046] 356 */ 357 358 public static final String[] WFACerts = { 359 "MIIFbDCCA1SgAwIBAgIQDLMPcPKGpDPguQmJ3gHttzANBgkqhkiG9w0BAQsFADBQ" + 360 "MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhvdHNwb3QgMi4wMScwJQYDVQQD" + 361 "Ex5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0gMDMwHhcNMTMxMjA4MTIwMDAw" + 362 "WhcNNDMxMjA4MTIwMDAwWjBQMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhv" + 363 "dHNwb3QgMi4wMScwJQYDVQQDEx5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0g" + 364 "MDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsdEtReIUbMlO+hR6b" + 365 "yQk4nGVITv3meYTaDeVwZnQVal8EjHuu4Kd89g8yRYVTv3J1kq9ukE7CDrDehrXK" + 366 "ym+8VlR7ro0lB/lwRyNk3W7yNccg3AknQ0x5fKVwcFznwD/FYg37owGmhGFtpMTB" + 367 "cxzreQaLXvLta8YNlJU10ZkfputBpzi9bLPWsLOkIrQw7KH1Wc+Oiy4hUMUbTlSi" + 368 "cjqacKPR188mVIoxxUoICHyVV1KvMmYZrVdc/b5dbmd0haMHxC0VSqbydXxxS7vv" + 369 "/lCrC2d5qbKE66PiuBPkhzyU7SI9C8GU/S7akYm1MMSTn5W7lSp2AWRDnf9LQg51" + 370 "dLvDxJ7t2fruXtSkkqG/cwY1yQI8O+WZYPDThKPcDmNbaxVE9lOizAHXFVsfYrXA" + 371 "PbbMOkzKehYwaIikmNgcpxtQNw+wikJiZb9N8VwwtwHK71XEFi+n5DGlPa9VDYgB" + 372 "YkBcxvVo2rbE3i3teQgHm+pWZNP08aFNWwMk9yQkm/SOGdLq1jLbQA9yd7fyR1Ct" + 373 "W1GLzKi1Ojr/6XiB9/noL3oxP/+gb8OSgcqVfkZp4QLvrGdlKiOI2fE7Bslmzn6l" + 374 "B3UTpApjab7BQ99rCXzDwt3Xd7IrCtAJNkxi302J7k6hnGlW8S4oPQBElkOtoH9y" + 375 "XEhp9rNS0lZiuwtFmWW2q50fkQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G" + 376 "A1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUZw5JLGEXnuvt4FTnhNmbrWRgc2UwDQYJ" + 377 "KoZIhvcNAQELBQADggIBAFPoGFDyzFg9B9+jJUPGW32omftBhChVcgjllI07RCie" + 378 "KTMBi47+auuLgiMox3xRyP7/dX7YaUeMXEQ1BMv6nlrsXWv1lH4yu+RNuehPlqRs" + 379 "fY351mAfPtQ654SBUi0Wg++9iyTOfgF5a9IWEDt4lnSZMvA4vlw8pUCz6zpKXHnA" + 380 "RXKrpY3bU+2dnrFDKR0XQhmAQdo7UvdsT1elVoFIxHhLpwfzx+kpEhtrXw3nGgt+" + 381 "M4jNp684XoWpxVGaQ4Vvv00Sm2DQ8jq2sf9F+kRWszZpQOTiMGKZr0lX2CI5cww1" + 382 "dfmd1BkAjI9cIWLkD8YSeaggZzvYe1o9d7e7lKfdJmjDlSQ0uBiG77keUK4tF2fi" + 383 "xFTxibtPux56p3GYQ2GdRsBaKjH3A3HMJSKXwIGR+wb1sgz/bBdlyJSylG8hYD//" + 384 "0Hyo+UrMUszAdszoPhMY+4Ol3QE3QRWzXi+W/NtKeYD2K8xUzjZM10wMdxCfoFOa" + 385 "8bzzWnxZQlnu880ULUSHIxDPeE+DDZYYOaN1hV2Rh/hrFKvvV+gJj2eXHF5G7y9u" + 386 "Yg7nHYCCf7Hy8UTIXDtAAeDCQNon1ReN8G+XOqhLQ9TalmnJ5U5ARtC0MdQDht7T" + 387 "DZpWeEVv+pQHARX9GDV/T85MV2RPJWKqfZ6kK0gvQDkunADdg8IhZAjwMMx3k6B/", 388 389 "MIIFbDCCA1SgAwIBAgIQaAV8NQv/Xdusi4IU+tpUfjANBgkqhkiG9w0BAQsFADBQ" + 390 "MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhvdHNwb3QgMi4wMScwJQYDVQQD" + 391 "Ex5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0gMDEwHhcNMTMxMTIwMDAwMDAw" + 392 "WhcNNDMxMTE5MjM1OTU5WjBQMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhv" + 393 "dHNwb3QgMi4wMScwJQYDVQQDEx5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0g" + 394 "MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/gf4CHxWjr2EcktAZ" + 395 "pHT4z1yFYZILD3ZVqvzzXBK+YKjWhjsgZ28Z1VwXqu51JvVzwTGDalPf5m7zMcJW" + 396 "CpPtPBdxxwQ/cBDPK4w+/sCuYYSddlMLzwZ/IgwFike12tKTR7Kk7Nk6ghrYaxCG" + 397 "R+QEZDVrxITj79vGpgk2otVnMI4d3H9mWt1o6Lx+hVioyBgOvmo2OWHR2uKkbg5h" + 398 "tktXqmBEtzK+qDqIIUY4WRRZHxlOaF2/EdIIGhXlf+Vlr13aPqOPiDiE08o+GARz" + 399 "TIp8BrW2boo0+2kpEFUKiqc427vOYEkUdSMfwu4aGOcuOewc8sk6ztquL/JcPROL" + 400 "VSFSSFR3HKhUto8EJcHEEG9wzcOi1OO/OOSVxjNwiaV/hB9Ed1wvoBhiJ+C+Q8/K" + 401 "HXmoH/ankXDaB06yjt2Ojemt0nO45qlarRj8tO7zbpghJuJxztur47U7PJta7Zcg" + 402 "z7kOPJPTAbzmOU2TXt1pXO1hVnSlV+M1rRwe7qivnSMMrTnkX15YWmyK27/tgJeu" + 403 "muR2YzvPwPtF/m1N0bRKI7FW05NYg3smItFq0E/eyf/orgolcXTZ7zNRyRGnjWNs" + 404 "/w9SDbdby0uVUfdN4V/5uC4HBmA1rikoBbGZ+nzCtesY4yW8eEwMfguVpNT3ueaU" + 405 "q30nufeY2VnA3Rv1WH8TaeZU+wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G" + 406 "A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU+RjGVZbebjpzEPfthaTLqbvXMiEwDQYJ" + 407 "KoZIhvcNAQELBQADggIBABj3LP1UXVa16HYeXC1+GU1dX/cla1n1bwpIlxRnCZ5/" + 408 "3I3zGw/nRnsLUTkGf8q3XCgin+jX22kyzzQNrgepn0zqBsmAj+pjUUwWzYQUzphc" + 409 "Uzmg4PJRWaEaGG3kvD+wJEC0pWvIhe48qcq8FZCCmjbvecEVn5mM0smPzPyUjf/o" + 410 "fjUMQvVWqug/Ff5HT6kbyDWhC3nD+8IZ5PjyO85OnoBnQkr8WYwr24XJgO2HS2rs" + 411 "W40CzQe3Kdg7HHyef+/iyLYTBJH7EUJPCHGVQtZ3q0aNqURkutXJ/CxKJYMcNTEB" + 412 "x+a09EhZ6DOHQDqsdTuAqGh3VyrxhFk+3suNsxoh6XaRK10VslvdNB/1YKfU8DWe" + 413 "V6XfDH/TR0NIL04exUp3rER8sERulpJGBOnaG6OQKh4bFYDB406+QfusQnvO0aYR" + 414 "UXJzf01B15HRJgpZsggpIuex0UDcJhTTpkRfTj8L4ayUce2ZRsGn3dBaT9ZMx4o9" + 415 "E/YsQyOpfw28gM5u+zZt4BJz4gAaRGbp4r4sk5Vm/P1/0EXJ70Du6K9d0HAHtpEv" + 416 "Y94Ww5W6fpMDdyAKYTXZBgTX3cqtikNkLX/kHH8l4o/XW2sXqU3X7vOYqgeVYoD9" + 417 "NnhZXYCerH4Se5Lgj8/KhXxRWtcn3XduMdkC6UTApMooA64Vs508173Z3lJn2SeQ", 418 419 "MIIFXTCCA0WgAwIBAgIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEY" + 420 "MBYGA1UECgwPV0ZBIEhvdHNwb3QgMi4wMScwJQYDVQQDDB5Ib3RzcG90IDIuMCBU" + 421 "cnVzdCBSb290IENBIC0gMDIwHhcNMTMxMjAyMjA1NzU3WhcNNDMxMjAyMjA1NTAz" + 422 "WjBQMQswCQYDVQQGEwJVUzEYMBYGA1UECgwPV0ZBIEhvdHNwb3QgMi4wMScwJQYD" + 423 "VQQDDB5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0gMDIwggIiMA0GCSqGSIb3" + 424 "DQEBAQUAA4ICDwAwggIKAoICAQDCSoMqNhtTwbnIsINp6nUhx5UFuq9ZQoTv+KDk" + 425 "vAajT0di6+cQG3sAVvZLySmJoiBAv3PizYYLOD4eGMrFQRqi7PmSJ83WqNv23ZYF" + 426 "ryFFJiy/URXc/ALDuB3dgElPt24Mx7n2xDPAh9t82HTmuskpQRrsyg9QPoi5rRRS" + 427 "Djm5mjFJjKChq99RWcweNV/KGH1sTwcmlDmNMScK16A+BBNiSvmZlsGJgAlP369k" + 428 "lnNqt6UiDhepcktuKpHmSvNel+c/xqzR0gURfUnXcZhzjzS94Rx5O+CNWL4EGiJq" + 429 "qKAfk99j/lbD0MWYo7Rh0UKQlXSdohWDiV93hxvvfugej8KUOIb+1wmd1Fi+lwDZ" + 430 "bR2yg2f0qyxbC/tAV4JJNnuDLFb19leD78x+68eAnlbMi+xMH5lINs15+26s2H5d" + 431 "lx9kwRDBJq02LuHnen6FLafWjejnnBQ/PuGD0ACvBegSsDKDaCuTAnTNS6MDmQr4" + 432 "wza08iX360ZN+BbSAnCK1YGa/7J7fhyydwxLJ7s5Eo0b6SUMY87FMc5XmkAk4xxL" + 433 "MLqS2HMtqsGBI5JQT0SgH0ghE6DjMWArBTZcD+swuzTi1/Cz5+Z9Es8xJ3MPvSZW" + 434 "pJi6VVB2eVMAqfHOj4ozHoVpvJypIVGRwWBzVRWom76R47utuRK6uKzoLiB1jwE5" + 435 "vwHpUQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBxjAd" + 436 "BgNVHQ4EFgQU5C9c1OMsB+/MOwl9OKG2D/XSwrUwDQYJKoZIhvcNAQELBQADggIB" + 437 "AGULYE/VrnA3K0ptgHrWlQoPfp5wGvScgsmy0wp9qE3b6n/4bLehBKb5w4Y3JVA9" + 438 "gjxoQ5xE2ssDtULZ3nKnGWmMN3qOBoRZCA6KjKs1860p09tm1ScUsajDJ15Tp1nI" + 439 "zfR0oP63+2bJx+JXM8fPKOJe245hj2rs1c3JXsGCe+UVrlGsotG+wR0PdrejaXJ8" + 440 "HbhBQHcbhgjsD1Gb6Egm4YxRKAtcVY3q9EKKWAGhbC1qvCh1iLNKo3FeGgm2r3EG" + 441 "L4cYJBb2fhSKltjISqCDhYq4tplOIeQSJJyJC8gfW/BnMU39lTjNgnSjjGPLQXGV" + 442 "+Ulb/CgNMJ3RhRJdBoLcpIm/EeLx6JLq/2Erxy7CxjaSOcD0UKa14+dzLSHVsXft" + 443 "HZuOy548X8m18KruSZsf5uAT3c7NqlXtr9YgOVUqSJykNAHTGi/BHB1dC2clKvxN" + 444 "ElfLWWrG9yaAd5TFW0+3wsaDIwRZL584AsFwwAD3KMo1oU/2zRvtm0E+VghsuD/Z" + 445 "IE1xaVGTPaL7ph/YgC9+0rGHieauT8SXz6Ryp3h0RtYMLFZOMTKM7xjmcbMZDwrO" + 446 "c+J/XjK9dbiCqlx5/B8P0xWaYYHzvE5/fafiPYzoGyFVUXquu0dFCCQrvjF/y0tC" + 447 "TPm4hQim3k1F+5NChcbeNggN+kq+VdlSqPhQEuOY+kNv" 448 }; 449 450 //private static final Set<TrustAnchor> sTrustAnchors = buildCertSet(); 451} 452