1924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra/* 2924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * Copyright (C) 2012 The Android Open Source Project 3924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * 4924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * Licensed under the Apache License, Version 2.0 (the "License"); 5924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * you may not use this file except in compliance with the License. 6924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * You may obtain a copy of the License at 7924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * 8924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * http://www.apache.org/licenses/LICENSE-2.0 9924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * 10924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * Unless required by applicable law or agreed to in writing, software 11924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * distributed under the License is distributed on an "AS IS" BASIS, 12924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * See the License for the specific language governing permissions and 14924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra * limitations under the License. 15924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra */ 16924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 17924af71bb26b7c35f702de9a3425109c73184a53Geremy Condrapackage org.apache.harmony.xnet.provider.jsse; 18924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 195ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condraimport java.security.cert.CertificateEncodingException; 20924af71bb26b7c35f702de9a3425109c73184a53Geremy Condraimport java.security.cert.X509Certificate; 21924af71bb26b7c35f702de9a3425109c73184a53Geremy Condraimport java.util.List; 225ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condraimport libcore.io.Base64; 235ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condraimport libcore.io.DropBox; 24924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 25924af71bb26b7c35f702de9a3425109c73184a53Geremy Condrapublic class PinFailureLogger { 26924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 27924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra private static final long LOG_INTERVAL_NANOS = 1000 * 1000 * 1000 * 60 * 60; 28924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 29924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra private static long lastLoggedNanos = 0; 30924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 31924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra public static synchronized void log(String cn, boolean chainContainsUserCert, 32924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra boolean pinIsEnforcing, 33924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra List<X509Certificate> chain) { 34924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra // if we've logged recently, don't do it again 35924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra if (!timeToLog()) { 36924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra return; 37924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra } 38924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra // otherwise, log the event 39924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra writeToLog(cn, chainContainsUserCert, pinIsEnforcing, chain); 40924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra // update the last logged time 41924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra lastLoggedNanos = System.nanoTime(); 42924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra } 43924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 44924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra protected static synchronized void writeToLog(String cn, boolean chainContainsUserCert, 45924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra boolean pinIsEnforcing, 46924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra List<X509Certificate> chain) { 475ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra StringBuilder sb = new StringBuilder(); 485ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append(cn); 495ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append("|"); 505ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append(chainContainsUserCert); 515ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append("|"); 525ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append(pinIsEnforcing); 535ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append("|"); 545ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra for (X509Certificate cert : chain) { 555ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra try { 565ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append(Base64.encode(cert.getEncoded())); 575ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra } catch (CertificateEncodingException e) { 585ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append("Error: could not encode certificate"); 595ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra } 605ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra sb.append("|"); 61924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra } 625ab2ad7ebf828d06710868f33458fb1fbe1aa50bGeremy Condra DropBox.addText("cert_pin_failure", sb.toString()); 63924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra } 64924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 65924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra protected static boolean timeToLog() { 66924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra long currentTimeNanos = System.nanoTime(); 67924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra return ((currentTimeNanos - lastLoggedNanos) > LOG_INTERVAL_NANOS); 68924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra } 69924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra} 70924af71bb26b7c35f702de9a3425109c73184a53Geremy Condra 71