/*************************************************************************** * Copyright (c) 2014-2015 VMware, Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ package com.vmware.bdd.security.tls; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.text.SimpleDateFormat; import java.util.Scanner; import com.vmware.bdd.utils.ByteArrayUtils; /** * Helper class for application specific functionality */ public class TlsHelper { /** * Present the user with the certificate thumbprint through a UI. Accepts * user input as whether the certificate is to be trusted or not * * @param certInfo * @param os an output stream for */ public static void presentUserWithCert(CertificateInfo certInfo, OutputStream os) { /** * This is where the user explicitly trusts the certificate. * Re-implement as per application needs */ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); PrintStream ps = new PrintStream(os); ps.println("Certificate"); ps.println("================================================================"); ps.println("Subject: " + certInfo.getSubjectDn()); ps.println("Issuer: " + certInfo.getIssuerDn()); ps.println("Serial Number: " + certInfo.getSerialNumber()); ps.println("Issued on: " + dateFormat.format(certInfo.getNotBefore())); ps.println("Expires on: " + dateFormat.format(certInfo.getNotAfter())); ps.println("SHA Fingerprint: " + certInfo.getSha1Fingerprint()); ps.println(); } public static String getUserInput() { Scanner in = new Scanner(System.in); String response = in.nextLine(); in.close(); return response; } /** * @param certificate An X509 certificate. See RFC 5280 */ public static CertificateInfo getCertificateInfo(X509Certificate certificate) { char[] sha1Hash = new char[0]; try { sha1Hash = ByteArrayUtils.byteArrayToHexChars(TlsHelper.getSha1Digest(certificate.getEncoded())); } catch (CertificateEncodingException e) { e.printStackTrace(); } CertificateInfo certInfo = new CertificateInfo(); certInfo.setSubjectDn(certificate.getSubjectDN().toString()); certInfo.setIssuerDn(certificate.getIssuerDN().toString()); certInfo.setSha1Fingerprint(String.valueOf(sha1Hash)); certInfo.setNotBefore(certificate.getNotBefore()); certInfo.setNotAfter(certificate.getNotAfter()); // certInfo.setSignature(String.valueOf(Helper.byteArrayToHex(certificate.getSignature()))); certInfo.setSerialNumber(String.valueOf(ByteArrayUtils.byteArrayToHexString(certificate.getSerialNumber().toByteArray()))); return certInfo; } private final static int FIND_ROOT_CAUSE_LEVEL = 4; public static <T> T findRootCause(IOException ioEx, Class<T> klass) { if (ioEx == null) { return null; } T uce = null; int j = 0; Throwable throwable = ioEx.getCause(); while (throwable != null && j < FIND_ROOT_CAUSE_LEVEL) { if (klass.isInstance(throwable)) { uce = klass.cast(throwable); break; } else { throwable = throwable.getCause(); } } return uce; } public static byte[] getSha1Digest(byte[] data) { try { MessageDigest sha1 = MessageDigest.getInstance("SHA1"); sha1.update(data); return sha1.digest(); } catch (NoSuchAlgorithmException e) { //should not happen } return null; } }