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 //}