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