• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 Google 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 
17 package benchmarks.regression;
18 
19 import com.google.caliper.Param;
20 import com.google.caliper.Runner;
21 import com.google.caliper.SimpleBenchmark;
22 import java.io.ByteArrayInputStream;
23 import java.net.URL;
24 import java.security.Principal;
25 import java.security.cert.Certificate;
26 import java.security.cert.CertificateFactory;
27 import javax.net.ssl.HostnameVerifier;
28 import javax.net.ssl.HttpsURLConnection;
29 import javax.net.ssl.SSLSession;
30 import javax.net.ssl.SSLSessionContext;
31 
32 /**
33  * This benchmark makes a real HTTP connection to a handful of hosts and
34  * captures the served certificates as a byte array. It then verifies each
35  * certificate in the benchmark loop, being careful to convert from the
36  * byte[] to the certificate each time. Otherwise the certificate class
37  * caches previous results which skews the results of the benchmark: In practice
38  * each certificate instance is verified once and then released.
39  */
40 public final class HostnameVerifierBenchmark extends SimpleBenchmark {
41 
42     @Param({"android.clients.google.com",
43             "m.google.com",
44             "www.google.com",
45             "www.amazon.com",
46             "www.ubs.com"}) String host;
47 
48     private String hostname;
49     private HostnameVerifier hostnameVerifier;
50     private byte[][] encodedCertificates;
51 
setUp()52     @Override protected void setUp() throws Exception {
53         URL url = new URL("https", host, "/");
54         hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
55         HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
56         connection.setHostnameVerifier(new HostnameVerifier() {
57             public boolean verify(String hostname, SSLSession sslSession) {
58                 try {
59                     encodedCertificates = certificatesToBytes(sslSession.getPeerCertificates());
60                 } catch (Exception e) {
61                     throw new RuntimeException(e);
62                 }
63                 HostnameVerifierBenchmark.this.hostname = hostname;
64                 return true;
65             }
66         });
67         connection.getInputStream();
68         connection.disconnect();
69     }
70 
timeVerify(int reps)71     public void timeVerify(int reps) throws Exception {
72         for (int i = 0; i < reps; i++) {
73             final Certificate[] certificates = bytesToCertificates(encodedCertificates);
74             FakeSSLSession sslSession = new FakeSSLSession() {
75                 @Override public Certificate[] getPeerCertificates() {
76                     return certificates;
77                 }
78             };
79             hostnameVerifier.verify(hostname, sslSession);
80         }
81     }
82 
certificatesToBytes(Certificate[] certificates)83     private byte[][] certificatesToBytes(Certificate[] certificates) throws Exception {
84         byte[][] result = new byte[certificates.length][];
85         for (int i = 0, certificatesLength = certificates.length; i < certificatesLength; i++) {
86             result[i] = certificates[i].getEncoded();
87         }
88         return result;
89     }
90 
bytesToCertificates(byte[][] encodedCertificates)91     private Certificate[] bytesToCertificates(byte[][] encodedCertificates) throws Exception {
92         CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
93         Certificate[] result = new Certificate[encodedCertificates.length];
94         for (int i = 0; i < encodedCertificates.length; i++) {
95             result[i] = certificateFactory.generateCertificate(
96                 new ByteArrayInputStream(encodedCertificates[i]));
97         }
98         return result;
99     }
100 
101     private static class FakeSSLSession implements SSLSession {
getApplicationBufferSize()102         public int getApplicationBufferSize() {
103             throw new UnsupportedOperationException();
104         }
getCipherSuite()105         public String getCipherSuite() {
106             throw new UnsupportedOperationException();
107         }
getCreationTime()108         public long getCreationTime() {
109             throw new UnsupportedOperationException();
110         }
getId()111         public byte[] getId() {
112             throw new UnsupportedOperationException();
113         }
getLastAccessedTime()114         public long getLastAccessedTime() {
115             throw new UnsupportedOperationException();
116         }
getLocalCertificates()117         public Certificate[] getLocalCertificates() {
118             throw new UnsupportedOperationException();
119         }
getLocalPrincipal()120         public Principal getLocalPrincipal() {
121             throw new UnsupportedOperationException();
122         }
getPacketBufferSize()123         public int getPacketBufferSize() {
124             throw new UnsupportedOperationException();
125         }
getPeerCertificateChain()126         public javax.security.cert.X509Certificate[] getPeerCertificateChain() {
127             throw new UnsupportedOperationException();
128         }
getPeerCertificates()129         public Certificate[] getPeerCertificates() {
130             throw new UnsupportedOperationException();
131         }
getPeerHost()132         public String getPeerHost() {
133             throw new UnsupportedOperationException();
134         }
getPeerPort()135         public int getPeerPort() {
136             throw new UnsupportedOperationException();
137         }
getPeerPrincipal()138         public Principal getPeerPrincipal() {
139             throw new UnsupportedOperationException();
140         }
getProtocol()141         public String getProtocol() {
142             throw new UnsupportedOperationException();
143         }
getSessionContext()144         public SSLSessionContext getSessionContext() {
145             throw new UnsupportedOperationException();
146         }
getValue(String name)147         public Object getValue(String name) {
148             throw new UnsupportedOperationException();
149         }
getValueNames()150         public String[] getValueNames() {
151             throw new UnsupportedOperationException();
152         }
invalidate()153         public void invalidate() {
154             throw new UnsupportedOperationException();
155         }
isValid()156         public boolean isValid() {
157             throw new UnsupportedOperationException();
158         }
putValue(String name, Object value)159         public void putValue(String name, Object value) {
160             throw new UnsupportedOperationException();
161         }
removeValue(String name)162         public void removeValue(String name) {
163             throw new UnsupportedOperationException();
164         }
165     }
166 
main(String[] args)167     public static void main(String[] args) {
168         Runner.main(HostnameVerifierBenchmark.class, args);
169     }
170 }
171