/* * HttpsTrustManager.java * * Copyright (c) 2003-2004 Digi International * This program and the information contained in it is confidential and * proprietary to Digi International and may not be used, copied, or re- * produced without the prior written permission of Digi International. * */ package com.digi.config.util; import com.digi.config.ui.*; import javax.swing.*; import javax.net.ssl.*; import java.security.Security; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.cert.X509Certificate; import java.security.cert.CertificateException; import java.util.Enumeration; /** * Implements a trust manager that prompts the user when an unknown * certificate is received. Uses the default sun trust manager for * most of the work. * * NOTE: when running as an applet this isn't required because the Java * Plug-In handles this. When running as an application, however, the default * action of the underlying HTTPS support is to close the connection if the * certificate is not trusted (without prompting the user). * * This implementation is currently very simplistic because we use application * version for internal development and test only. */ public class HttpsTrustManager implements X509TrustManager { KeyStore keyStore = null; X509TrustManager sunX509TrustManager = null; public HttpsTrustManager() { // Create an empty keystore try { keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); initSunX509TrustManager(keyStore); } catch (Exception ex) { ex.printStackTrace(); } } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // Let the Sun trust manager do the work here. sunX509TrustManager.checkClientTrusted(chain, authType); } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { try { sunX509TrustManager.checkServerTrusted(chain, authType); } catch (CertificateException excep) { try { // Not in keystore. Ask the user if they trust this certificate chain. if (promptUser(chain)) { // User trusts chain. Add chain to the keyStore. for (int i = 0; i < chain.length; i++) { keyStore.setCertificateEntry(chain[i].getIssuerDN().toString(), chain[i]); } // Force new keystore info into sun trust manager. initSunX509TrustManager(keyStore); //TODO: write to keystore file. } else { throw new CertificateException("Server certificate not trusted by the user."); } } catch (Exception ex) { System.out.println("Exception checking with user if server trusted: "+ex); ex.printStackTrace(); throw new CertificateException("Server certificate validation error."); } } } // getAcceptedIssuers retrieves all of the certificates in the keyStore // and returns them in an X509Certificate array. public X509Certificate[] getAcceptedIssuers() { // Let the sun trust manager do the work here. return sunX509TrustManager.getAcceptedIssuers(); } private boolean promptUser(X509Certificate[] chain) { JOptionPane promptPane = new JOptionPane(); // Create the panel that will hold the server controls GridContentPanel content = new GridContentPanel(1); content.setOpaque(false); //TODO: display more details about the certificate (and each // certificate in the chain). Also pull strings from resource bundle. String subject = chain[0].getSubjectDN().toString(); String issuer = chain[0].getIssuerDN().toString(); String subjectMsg = "Do you want to accept the certificate from '"+subject+"' to exchange encrypted information?"; String issuerMsg = "The certificate was issued by '"+issuer+"'."; int trustEm = JOptionPane.showConfirmDialog(null, new Object[] {subjectMsg, new String(""), issuerMsg}, "Security Alert", JOptionPane.YES_NO_OPTION); return(trustEm == JOptionPane.YES_OPTION); } private void initSunX509TrustManager(KeyStore keystore) { try { // Initialize an instance of the sun trust manager factory with our keystore. TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(keyStore); // Get the sun trust manager for doing the brunt of the work. TrustManager[] mgrs = tmf.getTrustManagers(); sunX509TrustManager = (X509TrustManager) mgrs[0]; } catch (Exception ex) { ex.printStackTrace(); } } }