Mercurial > 510Connectbot
view src/org/tn5250j/framework/transport/SSL/SSLImplementation.java @ 337:0d0d2fc9918c ganymed
merge
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 31 Jul 2014 15:00:28 -0700 |
parents | 77ac18bc1b2f |
children |
line wrap: on
line source
package org.tn5250j.framework.transport.SSL; /* * @(#)SSLImplementation.java * @author Stephen M. Kennedy * * Copyright: Copyright (c) 2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.net.Socket; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import com.five_ten_sg.connectbot.R; import com.five_ten_sg.connectbot.service.TerminalBridge; import com.five_ten_sg.connectbot.service.TerminalManager; import org.tn5250j.framework.transport.SSLInterface; import android.util.Log; /** * <p> * This class implements the SSLInterface and is used to create SSL socket * instances. * </p> * * @author Stephen M. Kennedy <skennedy@tenthpowertech.com> * */ public class SSLImplementation implements SSLInterface, X509TrustManager { private static final String TAG = "SSLImplementation"; SSLContext sslContext = null; KeyStore userks = null; private String userKsPath; private char[] userksPassword = "changeit".toCharArray(); TerminalBridge bridge = null; TerminalManager manager = null; String target = null; // destination:port KeyManagerFactory userkmf = null; TrustManagerFactory usertmf = null; TrustManager[] userTrustManagers = null; X509Certificate[] acceptedIssuers; public SSLImplementation(TerminalBridge bridge, TerminalManager manager) { this.bridge = bridge; this.manager = manager; } public void init(String sslType, String homeDirectory) { try { Log.d(TAG, "Initializing User KeyStore"); userKsPath = homeDirectory + File.separator + "keystore"; File userKsFile = new File(userKsPath); userks = KeyStore.getInstance(KeyStore.getDefaultType()); userks.load(userKsFile.exists() ? new FileInputStream(userKsFile) : null, userksPassword); Log.d(TAG, "Initializing User Key Manager Factory"); userkmf = KeyManagerFactory.getInstance(KeyManagerFactory .getDefaultAlgorithm()); userkmf.init(userks, userksPassword); Log.d(TAG, "Initializing User Trust Manager Factory"); usertmf = TrustManagerFactory.getInstance(TrustManagerFactory .getDefaultAlgorithm()); usertmf.init(userks); userTrustManagers = usertmf.getTrustManagers(); Log.d(TAG, "Initializing SSL Context"); sslContext = SSLContext.getInstance(sslType); sslContext.init(userkmf.getKeyManagers(), new TrustManager[] {this}, null); } catch (Exception ex) { Log.e(TAG, "Error initializing SSL [" + ex.getMessage() + "]"); } } public Socket createSSLSocket(String destination, int port) { if (sslContext == null) throw new IllegalStateException("SSL Context Not Initialized"); SSLSocket socket = null; try { target = destination + ":" + String.valueOf(port); socket = (SSLSocket) sslContext.getSocketFactory().createSocket( destination, port); } catch (Exception e) { Log.e(TAG, "Error creating ssl socket [" + e.getMessage() + "]"); } return socket; } // X509TrustManager Methods /* * (non-Javadoc) * * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() */ public X509Certificate[] getAcceptedIssuers() { return acceptedIssuers; } /* * (non-Javadoc) * * @see * javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert. * X509Certificate[], java.lang.String) */ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { throw new SecurityException("checkClientTrusted unsupported"); } /* * (non-Javadoc) * * @see * javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert. * X509Certificate[], java.lang.String) */ public void checkServerTrusted(X509Certificate[] chain, String type) throws CertificateException { try { for (int i = 0; i < userTrustManagers.length; i++) { if (userTrustManagers[i] instanceof X509TrustManager) { X509TrustManager trustManager = (X509TrustManager) userTrustManagers[i]; X509Certificate[] calist = trustManager .getAcceptedIssuers(); if (calist.length > 0) { trustManager.checkServerTrusted(chain, type); } else { throw new CertificateException( "Empty list of accepted issuers (a.k.a. root CA list)."); } } } return; } catch (CertificateException ce) { X509Certificate cert = chain[0]; String certInfo = manager.res.getString(R.string.host_cert_version) + cert.getVersion() + "\r\n"; certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_serial) + cert.getSerialNumber() + "\r\n"); certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_algorithm) + cert.getSigAlgName() + "\r\n"); certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_issuer) + cert.getIssuerDN().getName() + "\r\n"); certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_from) + cert.getNotBefore() + "\r\n"); certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_to) + cert.getNotAfter() + "\r\n"); certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_dn) + cert.getSubjectDN().getName() + "\r\n"); certInfo = certInfo.concat(manager.res.getString(R.string.host_cert_publickey) + cert.getPublicKey().getFormat() + "\r\n"); bridge.outputLine(manager.res.getString(R.string.host_authenticity_warning, target)); bridge.outputLine(manager.res.getString(R.string.host_certificate, certInfo)); Boolean result = bridge.promptHelper.requestBooleanPrompt(null, manager.res.getString(R.string.prompt_accept_certificate)); if ((result == null) || (!result.booleanValue())) { throw new java.security.cert.CertificateException( "Certificate Rejected"); } result = bridge.promptHelper.requestBooleanPrompt(null, manager.res.getString(R.string.prompt_save_certificate)); if ((result != null) && (result.booleanValue())) { try { userks.setCertificateEntry(cert.getSubjectDN().getName(), cert); userks.store(new FileOutputStream(userKsPath), userksPassword); } catch (Exception e) { Log.e(TAG, "Error saving certificate [" + e.getMessage() + "]"); e.printStackTrace(); } } } } }