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