1 /* 2 * hunt-proton: AMQP Protocol library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.proton.engine.impl.ssl.SslEngineFacadeFactory; 13 14 //import java.io.Closeable; 15 //import java.io.FileInputStream; 16 //import java.io.FileNotFoundException; 17 //import java.io.FileReader; 18 //import java.io.IOException; 19 //import java.io.InputStream; 20 //import java.io.Reader; 21 //import java.lang.reflect.Constructor; 22 //import java.lang.reflect.InvocationTargetException; 23 //import java.lang.reflect.Method; 24 //import java.security.KeyManagementException; 25 //import java.security.KeyPair; 26 //import java.security.KeyStore; 27 //import java.security.KeyStoreException; 28 //import java.security.NoSuchAlgorithmException; 29 //import java.security.PrivateKey; 30 //import java.security.Provider; 31 //import java.security.Security; 32 //import java.security.UnrecoverableKeyException; 33 //import java.security.cert.Certificate; 34 //import java.security.cert.CertificateException; 35 //import java.security.cert.CertificateFactory; 36 //import java.security.cert.X509Certificate; 37 //import java.util.ArrayList; 38 //import java.util.Arrays; 39 //import java.util.Collection; 40 //import java.util.List; 41 //import java.util.logging.Level; 42 //import java.util.logging.Logger; 43 // 44 //import javax.net.ssl.KeyManagerFactory; 45 //import javax.net.ssl.SSLContext; 46 //import javax.net.ssl.SSLEngine; 47 //import javax.net.ssl.SSLParameters; 48 //import javax.net.ssl.TrustManager; 49 //import javax.net.ssl.TrustManagerFactory; 50 //import javax.net.ssl.X509TrustManager; 51 // 52 //import hunt.proton.engine.SslDomain; 53 //import hunt.proton.engine.SslPeerDetails; 54 //import hunt.proton.engine.TransportException; 55 // 56 //class SslEngineFacadeFactory 57 //{ 58 // private static Logger _logger = Logger.getLogger(SslEngineFacadeFactory.class.getName()); 59 // 60 // /** 61 // * The protocol name used to create an {@link SSLContext}, taken from Java's list of 62 // * standard names at http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html 63 // * 64 // * TODO allow the protocol name to be overridden somehow 65 // */ 66 // private static String TLS_PROTOCOL = "TLS"; 67 // 68 // // BouncyCastle Reflection Helpers 69 // private static Constructor<?> pemParserCons; 70 // private static Method pemReadMethod; 71 // 72 // private static Constructor<?> JcaPEMKeyConverterCons; 73 // private static Class<?> PEMKeyPairClass; 74 // private static Method getKeyPairMethod; 75 // private static Method getPrivateKeyMethod; 76 // 77 // private static Class<?> PEMEncryptedKeyPairClass; 78 // private static Method decryptKeyPairMethod; 79 // 80 // private static Constructor<?> JcePEMDecryptorProviderBuilderCons; 81 // private static Method builderMethod; 82 // 83 // private static Class<?> PrivateKeyInfoClass; 84 // private static Exception bouncyCastleSetupException; 85 // 86 // static 87 // { 88 // // Setup BouncyCastle Reflection artifacts 89 // Constructor<?> pemParserConsResult = null; 90 // Method pemReadMethodResult = null; 91 // Constructor<?> JcaPEMKeyConverterConsResult = null; 92 // Class<?> PEMKeyPairClassResult = null; 93 // Method getKeyPairMethodResult = null; 94 // Method getPrivateKeyMethodResult = null; 95 // Class<?> PEMEncryptedKeyPairClassResult = null; 96 // Method decryptKeyPairMethodResult = null; 97 // Constructor<?> JcePEMDecryptorProviderBuilderConsResult = null; 98 // Method builderMethodResult = null; 99 // Class<?> PrivateKeyInfoClassResult = null; 100 // Exception bouncyCastleSetupExceptionResult = null; 101 // 102 // try 103 // { 104 // Class<?> pemParserClass = Class.forName("org.bouncycastle.openssl.PEMParser"); 105 // pemParserConsResult = pemParserClass.getConstructor(Reader.class); 106 // pemReadMethodResult = pemParserClass.getMethod("readObject"); 107 // 108 // Class<?> jcaPEMKeyConverterClass = Class.forName("org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter"); 109 // JcaPEMKeyConverterConsResult = jcaPEMKeyConverterClass.getConstructor(); 110 // PEMKeyPairClassResult = Class.forName("org.bouncycastle.openssl.PEMKeyPair"); 111 // getKeyPairMethodResult = jcaPEMKeyConverterClass.getMethod("getKeyPair", PEMKeyPairClassResult); 112 // 113 // Class<?> PEMDecrypterProvider = Class.forName("org.bouncycastle.openssl.PEMDecryptorProvider"); 114 // 115 // PEMEncryptedKeyPairClassResult = Class.forName("org.bouncycastle.openssl.PEMEncryptedKeyPair"); 116 // decryptKeyPairMethodResult = PEMEncryptedKeyPairClassResult.getMethod("decryptKeyPair", PEMDecrypterProvider); 117 // 118 // Class<?> jcePEMDecryptorProviderBuilderClass = Class.forName( 119 // "org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder"); 120 // JcePEMDecryptorProviderBuilderConsResult = jcePEMDecryptorProviderBuilderClass.getConstructor(); 121 // builderMethodResult = jcePEMDecryptorProviderBuilderClass.getMethod("build", char[].class); 122 // 123 // PrivateKeyInfoClassResult = Class.forName("org.bouncycastle.asn1.pkcs.PrivateKeyInfo"); 124 // getPrivateKeyMethodResult = jcaPEMKeyConverterClass.getMethod("getPrivateKey", PrivateKeyInfoClassResult); 125 // 126 // registerBouncyCastleProvider(); 127 // } 128 // catch (Exception e) 129 // { 130 // bouncyCastleSetupExceptionResult = e; 131 // } 132 // finally { 133 // pemParserCons = pemParserConsResult; 134 // pemReadMethod = pemReadMethodResult; 135 // JcaPEMKeyConverterCons = JcaPEMKeyConverterConsResult; 136 // PEMKeyPairClass = PEMKeyPairClassResult; 137 // getKeyPairMethod = getKeyPairMethodResult; 138 // getPrivateKeyMethod = getPrivateKeyMethodResult; 139 // PEMEncryptedKeyPairClass = PEMEncryptedKeyPairClassResult; 140 // decryptKeyPairMethod = decryptKeyPairMethodResult; 141 // JcePEMDecryptorProviderBuilderCons = JcePEMDecryptorProviderBuilderConsResult; 142 // builderMethod = builderMethodResult; 143 // PrivateKeyInfoClass = PrivateKeyInfoClassResult; 144 // bouncyCastleSetupException = bouncyCastleSetupExceptionResult; 145 // } 146 // } 147 // 148 // static void registerBouncyCastleProvider() 149 // throws ClassNotFoundException, InstantiationException, IllegalAccessException, 150 // InvocationTargetException, NoSuchMethodException 151 // { 152 // // Try loading BC as a provider 153 // Class<?> klass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider"); 154 // 155 // Provider bouncyCastleProvider = (Provider) klass.getConstructor().newInstance(); 156 // synchronized (Security.class) 157 // { 158 // if(Security.getProvider(bouncyCastleProvider.getName()) is null) 159 // { 160 // Security.addProvider(bouncyCastleProvider); 161 // } 162 // } 163 // } 164 // 165 // SslEngineFacadeFactory() 166 // { 167 // } 168 // 169 // /** 170 // * This is a list of all anonymous cipher suites supported by Java 6, excluding those that 171 // * use MD5. These are all supported by both Oracle's and IBM's Java 6 implementation. 172 // */ 173 // private static List<String> ANONYMOUS_CIPHER_SUITES = Arrays.asList( 174 // "TLS_DH_anon_WITH_AES_128_CBC_SHA", 175 // "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", 176 // "SSL_DH_anon_WITH_DES_CBC_SHA", 177 // "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"); 178 // 179 // /** lazily initialized */ 180 // private SSLContext _sslContext; 181 // 182 // 183 // /** 184 // * Returns a {@link ProtonSslEngine}. May cache the domain's settings so callers should invoke 185 // * {@link #resetCache()} if the domain changes. 186 // * 187 // * @param peerDetails may be used to return an engine that supports SSL resume. 188 // */ 189 // public ProtonSslEngine createProtonSslEngine(SslDomain domain, SslPeerDetails peerDetails) 190 // { 191 // SSLEngine engine = createAndInitialiseSslEngine(domain, peerDetails); 192 // if(_logger.isLoggable(Level.FINE)) 193 // { 194 // _logger.fine("Created SSL engine: " + engineToString(engine)); 195 // } 196 // return new DefaultSslEngineFacade(engine); 197 // } 198 // 199 // 200 // /** 201 // * Guarantees that no cached settings are used in subsequent calls to 202 // * {@link #createProtonSslEngine(SslDomain, SslPeerDetails)}. 203 // */ 204 // public void resetCache() 205 // { 206 // _sslContext = null; 207 // } 208 // 209 // 210 // private SSLEngine createAndInitialiseSslEngine(SslDomain domain, SslPeerDetails peerDetails) 211 // { 212 // SslDomain.Mode mode = domain.getMode(); 213 // 214 // SSLContext sslContext = getOrCreateSslContext(domain); 215 // SSLEngine sslEngine = createSslEngine(sslContext, peerDetails); 216 // 217 // if (domain.getPeerAuthentication() == SslDomain.VerifyMode.ANONYMOUS_PEER) 218 // { 219 // addAnonymousCipherSuites(sslEngine); 220 // } 221 // else 222 // { 223 // if (mode == SslDomain.Mode.SERVER) 224 // { 225 // sslEngine.setNeedClientAuth(true); 226 // } 227 // 228 // if(domain.getPeerAuthentication() == SslDomain.VerifyMode.VERIFY_PEER_NAME) 229 // { 230 // SSLParameters sslParameters = sslEngine.getSSLParameters(); 231 // sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); 232 // sslEngine.setSSLParameters(sslParameters); 233 // } 234 // } 235 // 236 // if(_logger.isLoggable(Level.FINE)) 237 // { 238 // _logger.log(Level.FINE, mode + " Enabled cipher suites " + Arrays.asList(sslEngine.getEnabledCipherSuites())); 239 // } 240 // 241 // boolean useClientMode = mode == SslDomain.Mode.CLIENT; 242 // sslEngine.setUseClientMode(useClientMode); 243 // 244 // removeSSLv3Support(sslEngine); 245 // 246 // return sslEngine; 247 // } 248 // 249 // private static String SSLV3_PROTOCOL = "SSLv3"; 250 // 251 // private static void removeSSLv3Support(SSLEngine engine) 252 // { 253 // List<String> enabledProtocols = Arrays.asList(engine.getEnabledProtocols()); 254 // if(enabledProtocols.contains(SSLV3_PROTOCOL)) 255 // { 256 // List<String> allowedProtocols = new ArrayList<String>(enabledProtocols); 257 // allowedProtocols.remove(SSLV3_PROTOCOL); 258 // engine.setEnabledProtocols(allowedProtocols.toArray(new String[allowedProtocols.size()])); 259 // } 260 // } 261 // 262 // /** 263 // * @param sslPeerDetails is allowed to be null. A non-null value is used to hint that SSL resumption 264 // * should be attempted 265 // */ 266 // private SSLEngine createSslEngine(SSLContext sslContext, SslPeerDetails sslPeerDetails) 267 // { 268 // SSLEngine sslEngine; 269 // if(sslPeerDetails is null) 270 // { 271 // sslEngine = sslContext.createSSLEngine(); 272 // } 273 // else 274 // { 275 // sslEngine = sslContext.createSSLEngine(sslPeerDetails.getHostname(), sslPeerDetails.getPort()); 276 // } 277 // return sslEngine; 278 // } 279 // 280 // private SSLContext getOrCreateSslContext(SslDomain sslDomain) 281 // { 282 // if(_sslContext is null && sslDomain.getSslContext() !is null) 283 // { 284 // _sslContext = sslDomain.getSslContext(); 285 // } 286 // else if(_sslContext is null) 287 // { 288 // if(_logger.isLoggable(Level.FINE)) 289 // { 290 // _logger.fine("lazily creating new SSLContext using domain " + sslDomain); 291 // } 292 // 293 // char[] dummyPassword = "unused-passphrase".toCharArray(); // Dummy password required by KeyStore and KeyManagerFactory, but never referred to again 294 // 295 // try 296 // { 297 // SSLContext sslContext = SSLContext.getInstance(TLS_PROTOCOL); 298 // KeyStore ksKeys = createKeyStoreFrom(sslDomain, dummyPassword); 299 // 300 // KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 301 // kmf.init(ksKeys, dummyPassword); 302 // 303 // TrustManager[] trustManagers; 304 // if (sslDomain.getPeerAuthentication() == SslDomain.VerifyMode.ANONYMOUS_PEER) 305 // { 306 // trustManagers = new TrustManager[] { new AlwaysTrustingTrustManager() }; 307 // } 308 // else 309 // { 310 // TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 311 // tmf.init(ksKeys); 312 // trustManagers = tmf.getTrustManagers(); 313 // } 314 // 315 // sslContext.init(kmf.getKeyManagers(), trustManagers, null); 316 // _sslContext = sslContext; 317 // } 318 // catch (NoSuchAlgorithmException e) 319 // { 320 // throw new TransportException("Unexpected exception creating SSLContext", e); 321 // } 322 // catch (KeyStoreException e) 323 // { 324 // throw new TransportException("Unexpected exception creating SSLContext", e); 325 // } 326 // catch (UnrecoverableKeyException e) 327 // { 328 // throw new TransportException("Unexpected exception creating SSLContext", e); 329 // } 330 // catch (KeyManagementException e) 331 // { 332 // throw new TransportException("Unexpected exception creating SSLContext", e); 333 // } 334 // } 335 // return _sslContext; 336 // } 337 // 338 // private KeyStore createKeyStoreFrom(SslDomain sslDomain, char[] dummyPassword) 339 // { 340 // try 341 // { 342 // KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 343 // keystore.load(null, null); 344 // 345 // if (sslDomain.getTrustedCaDb() !is null) 346 // { 347 // String caCertAlias = "cacert"; 348 // 349 // if(_logger.isLoggable(Level.FINE)) 350 // { 351 // _logger.log(Level.FINE, "_sslParams.getTrustedCaDb() : " + sslDomain.getTrustedCaDb()); 352 // } 353 // int i = 1; 354 // for(Certificate trustedCaCert : readCertificates(sslDomain.getTrustedCaDb())) 355 // { 356 // keystore.setCertificateEntry(caCertAlias + (i++), trustedCaCert); 357 // } 358 // } 359 // 360 // if (sslDomain.getCertificateFile() !is null 361 // && sslDomain.getPrivateKeyFile() !is null) 362 // { 363 // String clientPrivateKeyAlias = "clientPrivateKey"; 364 // 365 // Certificate clientCertificate = (Certificate) readCertificate(sslDomain.getCertificateFile()); 366 // PrivateKey clientPrivateKey = readPrivateKey(sslDomain.getPrivateKeyFile(), sslDomain.getPrivateKeyPassword()); 367 // 368 // keystore.setKeyEntry(clientPrivateKeyAlias, clientPrivateKey, 369 // dummyPassword, new Certificate[] { clientCertificate }); 370 // } 371 // 372 // return keystore; 373 // } 374 // catch (KeyStoreException e) 375 // { 376 // throw new TransportException("Unexpected exception creating keystore", e); 377 // } 378 // catch (NoSuchAlgorithmException e) 379 // { 380 // throw new TransportException("Unexpected exception creating keystore", e); 381 // } 382 // catch (CertificateException e) 383 // { 384 // throw new TransportException("Unexpected exception creating keystore", e); 385 // } 386 // catch (IOException e) 387 // { 388 // throw new TransportException("Unexpected exception creating keystore", e); 389 // } 390 // } 391 // 392 // private void addAnonymousCipherSuites(SSLEngine sslEngine) 393 // { 394 // List<String> supportedSuites = Arrays.asList(sslEngine.getSupportedCipherSuites()); 395 // List<String> currentEnabledSuites = Arrays.asList(sslEngine.getEnabledCipherSuites()); 396 // 397 // List<String> enabledSuites = buildEnabledSuitesIncludingAnonymous(ANONYMOUS_CIPHER_SUITES, supportedSuites, currentEnabledSuites); 398 // sslEngine.setEnabledCipherSuites(enabledSuites.toArray(new String[0])); 399 // } 400 // 401 // private List<String> buildEnabledSuitesIncludingAnonymous( 402 // List<String> anonymousCipherSuites, List<String> supportedSuites, List<String> currentEnabled) 403 // { 404 // List<String> newEnabled = new ArrayList<String>(currentEnabled); 405 // 406 // int addedAnonymousCipherSuites = 0; 407 // for (String anonymousCipherSuiteName : anonymousCipherSuites) 408 // { 409 // if (supportedSuites.contains(anonymousCipherSuiteName)) 410 // { 411 // newEnabled.add(anonymousCipherSuiteName); 412 // addedAnonymousCipherSuites++; 413 // } 414 // } 415 // 416 // if (addedAnonymousCipherSuites > 0 && _logger.isLoggable(Level.FINE)) 417 // { 418 // _logger.fine("There are now " + newEnabled.size() 419 // + " cipher suites enabled (previously " + currentEnabled.size() 420 // + "), including " + addedAnonymousCipherSuites + " out of the " 421 // + anonymousCipherSuites.size() + " requested anonymous ones." ); 422 // } 423 // 424 // return newEnabled; 425 // } 426 // 427 // private String engineToString(SSLEngine engine) 428 // { 429 // return new StringBuilder("[ " ) 430 // .append(engine) 431 // .append(", needClientAuth=").append(engine.getNeedClientAuth()) 432 // .append(", useClientMode=").append(engine.getUseClientMode()) 433 // .append(", peerHost=").append(engine.getPeerHost()) 434 // .append(", peerPort=").append(engine.getPeerPort()) 435 // .append(" ]").toString(); 436 // } 437 // 438 // Certificate readCertificate(String pemFile) 439 // { 440 // InputStream is = null; 441 // 442 // try 443 // { 444 // CertificateFactory cFactory = CertificateFactory.getInstance("X.509"); 445 // is = new FileInputStream(pemFile); 446 // return cFactory.generateCertificate(is); 447 // } 448 // catch (CertificateException ce) 449 // { 450 // String msg = "Failed to load certificate [" + pemFile + "]"; 451 // _logger.log(Level.SEVERE, msg, ce); 452 // throw new TransportException(msg, ce); 453 // } 454 // catch (FileNotFoundException e) 455 // { 456 // String msg = "Certificate file not found [" + pemFile + "]"; 457 // _logger.log(Level.SEVERE, msg); 458 // throw new TransportException(msg, e); 459 // } 460 // finally 461 // { 462 // closeSafely(is); 463 // } 464 // } 465 // 466 // Collection<? extends Certificate> readCertificates(String pemFile) 467 // { 468 // InputStream is = null; 469 // 470 // try 471 // { 472 // CertificateFactory cFactory = CertificateFactory.getInstance("X.509"); 473 // is = new FileInputStream(pemFile); 474 // return cFactory.generateCertificates(is); 475 // } 476 // catch (CertificateException ce) 477 // { 478 // String msg = "Failed to load certificates [" + pemFile + "]"; 479 // _logger.log(Level.SEVERE, msg, ce); 480 // throw new TransportException(msg, ce); 481 // } 482 // catch (FileNotFoundException e) 483 // { 484 // String msg = "Certificates file not found [" + pemFile + "]"; 485 // _logger.log(Level.SEVERE, msg); 486 // throw new TransportException(msg, e); 487 // } 488 // finally 489 // { 490 // closeSafely(is); 491 // } 492 // } 493 // 494 // 495 // PrivateKey readPrivateKey(String pemFile, String password) 496 // { 497 // if (bouncyCastleSetupException !is null) 498 // { 499 // throw new TransportException("BouncyCastle failed to load", bouncyCastleSetupException); 500 // } 501 // 502 // Object pemObject = readPemObject(pemFile); 503 // PrivateKey privateKey = null; 504 // 505 // try 506 // { 507 // Object keyConverter = JcaPEMKeyConverterCons.newInstance(); 508 // setProvider(keyConverter, "BC"); 509 // 510 // if (PEMEncryptedKeyPairClass.isInstance(pemObject)) 511 // { 512 // Object decryptorBuilder = JcePEMDecryptorProviderBuilderCons.newInstance(); 513 // 514 // // Build a PEMDecryptProvider 515 // Object decryptProvider = builderMethod.invoke(decryptorBuilder, password.toCharArray()); 516 // 517 // Object decryptedKeyPair = decryptKeyPairMethod.invoke(pemObject, decryptProvider); 518 // KeyPair keyPair = (KeyPair) getKeyPairMethod.invoke(keyConverter, decryptedKeyPair); 519 // 520 // privateKey = keyPair.getPrivate(); 521 // } 522 // else if (PEMKeyPairClass.isInstance(pemObject)) 523 // { 524 // // It's a KeyPair but not encrypted. 525 // KeyPair keyPair = (KeyPair) getKeyPairMethod.invoke(keyConverter, pemObject); 526 // privateKey = keyPair.getPrivate(); 527 // } 528 // else if (PrivateKeyInfoClass.isInstance(pemObject)) 529 // { 530 // // It's an unencrypted private key 531 // privateKey = (PrivateKey) getPrivateKeyMethod.invoke(keyConverter, pemObject); 532 // } 533 // else 534 // { 535 // String msg = "Unable to load PrivateKey, Unpexected Object [" + pemObject.getClass().getName() 536 // + "]"; 537 // _logger.log(Level.SEVERE, msg); 538 // throw new TransportException(msg); 539 // } 540 // } 541 // catch (InstantiationException | IllegalAccessException | IllegalArgumentException 542 // | InvocationTargetException | NoSuchMethodException | SecurityException e) 543 // { 544 // String msg = "Failed to process key file [" + pemFile + "] - " + e.getMessage(); 545 // throw new TransportException(msg, e); 546 // } 547 // 548 // return privateKey; 549 // } 550 // 551 // private Object readPemObject(String pemFile) 552 // { 553 // Reader reader = null; 554 // Object pemParser = null; 555 // Object pemObject = null; 556 // 557 // try 558 // { 559 // reader = new FileReader(pemFile); 560 // pemParser = pemParserCons.newInstance(reader); // = new PEMParser(reader); 561 // pemObject = pemReadMethod.invoke(pemParser); // = pemParser.readObject(); 562 // } 563 // catch (IOException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) 564 // { 565 // _logger.log(Level.SEVERE, "Unable to read PEM object. Perhaps you need the unlimited strength libraries in <java-home>/jre/lib/security/ ?", e); 566 // throw new TransportException("Unable to read PEM object from file " + pemFile, e); 567 // } 568 // finally 569 // { 570 // closeSafely(reader); 571 // } 572 // 573 // return pemObject; 574 // } 575 // 576 // private void setProvider(Object obj, String provider) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException 577 // { 578 // Class<?> aClz = obj.getClass(); 579 // Method setProvider = aClz.getMethod("setProvider", String.class); 580 // setProvider.invoke(obj, provider); 581 // } 582 // 583 // private void closeSafely(Closeable c) 584 // { 585 // if (c !is null) 586 // { 587 // try 588 // { 589 // c.close(); 590 // } 591 // catch (IOException e) 592 // { 593 // // Swallow 594 // } 595 // } 596 // } 597 // 598 // private static class AlwaysTrustingTrustManager implements X509TrustManager 599 // { 600 // @Override 601 // public X509Certificate[] getAcceptedIssuers() 602 // { 603 // return null; 604 // } 605 // 606 // @Override 607 // public void checkServerTrusted(X509Certificate[] arg0, String arg1) 608 // throws CertificateException 609 // { 610 // // Do not check certificate 611 // } 612 // 613 // @Override 614 // public void checkClientTrusted(X509Certificate[] arg0, String arg1) 615 // throws CertificateException 616 // { 617 // // Do not check certificate 618 // } 619 // } 620 //}