1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.conscrypt; 18 19 import java.security.cert.CertificateEncodingException; 20 import java.security.cert.X509Certificate; 21 import java.util.List; 22 import libcore.io.Base64; 23 import libcore.io.DropBox; 24 25 public class PinFailureLogger { 26 27 private static final long LOG_INTERVAL_NANOS = 1000 * 1000 * 1000 * 60 * 60; 28 29 private static long lastLoggedNanos = 0; 30 31 public static synchronized void log(String cn, boolean chainContainsUserCert, 32 boolean pinIsEnforcing, 33 List<X509Certificate> chain) { 34 // if we've logged recently, don't do it again 35 if (!timeToLog()) { 36 return; 37 } 38 // otherwise, log the event 39 writeToLog(cn, chainContainsUserCert, pinIsEnforcing, chain); 40 // update the last logged time 41 lastLoggedNanos = System.nanoTime(); 42 } 43 44 protected static synchronized void writeToLog(String cn, boolean chainContainsUserCert, 45 boolean pinIsEnforcing, 46 List<X509Certificate> chain) { 47 StringBuilder sb = new StringBuilder(); 48 sb.append(cn); 49 sb.append("|"); 50 sb.append(chainContainsUserCert); 51 sb.append("|"); 52 sb.append(pinIsEnforcing); 53 sb.append("|"); 54 for (X509Certificate cert : chain) { 55 try { 56 sb.append(Base64.encode(cert.getEncoded())); 57 } catch (CertificateEncodingException e) { 58 sb.append("Error: could not encode certificate"); 59 } 60 sb.append("|"); 61 } 62 DropBox.addText("exp_det_cert_pin_failure", sb.toString()); 63 } 64 65 protected static boolean timeToLog() { 66 long currentTimeNanos = System.nanoTime(); 67 return ((currentTimeNanos - lastLoggedNanos) > LOG_INTERVAL_NANOS); 68 } 69 } 70 71