1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.android_webview; 6 7 import java.security.PrivateKey; 8 import java.util.Arrays; 9 import java.util.HashMap; 10 import java.util.HashSet; 11 import java.util.Map; 12 import java.util.Set; 13 14 /** 15 * Store user's client certificate decision for a host and port pair. Not 16 * thread-safe. All accesses are done on UI thread. 17 */ 18 public class ClientCertLookupTable { 19 20 /** 21 * A container for the certificate data. 22 */ 23 public static class Cert { 24 PrivateKey mPrivateKey; 25 byte[][] mCertChain; Cert(PrivateKey privateKey, byte[][] certChain)26 public Cert(PrivateKey privateKey, byte[][] certChain) { 27 this.mPrivateKey = privateKey; 28 byte[][] newChain = new byte[certChain.length][]; 29 for (int i = 0; i < certChain.length; i++) { 30 newChain[i] = Arrays.copyOf(certChain[i], certChain[i].length); 31 } 32 this.mCertChain = newChain; 33 } 34 } 35 36 private final Map<String, Cert> mCerts; 37 private final Set<String> mDenieds; 38 39 // Clear client certificate preferences clear()40 public void clear() { 41 mCerts.clear(); 42 mDenieds.clear(); 43 } 44 ClientCertLookupTable()45 public ClientCertLookupTable() { 46 mCerts = new HashMap<String, Cert>(); 47 mDenieds = new HashSet<String>(); 48 } 49 allow(String host, int port, PrivateKey privateKey, byte[][] chain)50 public void allow(String host, int port, PrivateKey privateKey, byte[][] chain) { 51 String host_and_port = hostAndPort(host, port); 52 mCerts.put(host_and_port, new Cert(privateKey, chain)); 53 mDenieds.remove(host_and_port); 54 } 55 deny(String host, int port)56 public void deny(String host, int port) { 57 String host_and_port = hostAndPort(host, port); 58 mCerts.remove(host_and_port); 59 mDenieds.add(host_and_port); 60 } 61 getCertData(String host, int port)62 public Cert getCertData(String host, int port) { 63 return mCerts.get(hostAndPort(host, port)); 64 } 65 isDenied(String host, int port)66 public boolean isDenied(String host, int port) { 67 return mDenieds.contains(hostAndPort(host, port)); 68 } 69 70 // TODO(sgurun) add a test for this. Not separating host and pair properly will be 71 // a security issue. hostAndPort(String host, int port)72 private static String hostAndPort(String host, int port) { 73 return host + ":" + port; 74 } 75 } 76