1 /*
2  * Copyright (C) 2016 Square, Inc.
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 package okhttp3.internal.tls;
17
18 import java.security.PublicKey;
19 import java.security.cert.X509Certificate;
20 import java.util.LinkedHashMap;
21 import java.util.LinkedHashSet;
22 import java.util.Map;
23 import java.util.Set;
24 import javax.security.auth.x500.X500Principal;
25
26 /** A simple index that of trusted root certificates that have been loaded into memory. */
27 public final class BasicTrustRootIndex implements TrustRootIndex {
28   private final Map<X500Principal, Set<X509Certificate>> subjectToCaCerts;
29
30   public BasicTrustRootIndex(X509Certificate... caCerts) {
31     subjectToCaCerts = new LinkedHashMap<>();
32     for (X509Certificate caCert : caCerts) {
33       X500Principal subject = caCert.getSubjectX500Principal();
34       Set<X509Certificate> subjectCaCerts = subjectToCaCerts.get(subject);
35       if (subjectCaCerts == null) {
36         subjectCaCerts = new LinkedHashSet<>(1);
37         subjectToCaCerts.put(subject, subjectCaCerts);
38       }
39       subjectCaCerts.add(caCert);
40     }
41   }
42
43   @Override public X509Certificate findByIssuerAndSignature(X509Certificate cert) {
44     X500Principal issuer = cert.getIssuerX500Principal();
45     Set<X509Certificate> subjectCaCerts = subjectToCaCerts.get(issuer);
46     if (subjectCaCerts == nullreturn null;
47
48     for (X509Certificate caCert : subjectCaCerts) {
49       PublicKey publicKey = caCert.getPublicKey();
50       try {
51         cert.verify(publicKey);
52         return caCert;
53       } catch (Exception ignored) {
54       }
55     }
56
57     return null;
58   }
59
60   @Override public boolean equals(Object other) {
61     if (other == thisreturn true;
62     return other instanceof okhttp3.internal.tls.BasicTrustRootIndex
63         && ((okhttp3.internal.tls.BasicTrustRootIndex) other).subjectToCaCerts.equals(
64         subjectToCaCerts);
65   }
66
67   @Override public int hashCode() {
68     return subjectToCaCerts.hashCode();
69   }
70 }
71