Home | History | Annotate | Download | only in ssl
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      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 org.conscrypt.javax.net.ssl;
     18 
     19 import java.io.PrintStream;
     20 import java.net.Socket;
     21 import java.security.cert.CertificateException;
     22 import java.security.cert.X509Certificate;
     23 import javax.net.ssl.SSLEngine;
     24 import javax.net.ssl.TrustManager;
     25 import javax.net.ssl.X509ExtendedTrustManager;
     26 import javax.net.ssl.X509TrustManager;
     27 import libcore.java.io.NullPrintStream;
     28 import libcore.java.security.StandardNames;
     29 
     30 /**
     31  * TestTrustManager is a simple proxy class that wraps an existing
     32  * X509ExtendedTrustManager to provide debug logging and recording of
     33  * values.
     34  */
     35 public abstract class TestTrustManager {
     36     private static final boolean LOG = false;
     37     private static final PrintStream out = LOG ? System.out : new NullPrintStream();
     38     private static final Class<?> EXTENDED_TRUST_MANAGER_CLASS = getExtendedTrustManagerClass();
     39 
     40     public static TrustManager[] wrap(TrustManager[] trustManagers) {
     41         TrustManager[] result = trustManagers.clone();
     42         for (int i = 0; i < result.length; i++) {
     43             result[i] = wrap(result[i]);
     44         }
     45         return result;
     46     }
     47 
     48     public static TrustManager wrap(TrustManager trustManager) {
     49         if (EXTENDED_TRUST_MANAGER_CLASS != null && EXTENDED_TRUST_MANAGER_CLASS.isInstance(trustManager)) {
     50             return new ExtendedWrapper((X509ExtendedTrustManager) trustManager);
     51         } else if (trustManager instanceof X509TrustManager) {
     52             return new Wrapper((X509TrustManager) trustManager);
     53         }
     54         return trustManager;
     55     }
     56 
     57     private static Class<?> getExtendedTrustManagerClass() {
     58         try {
     59             return Class.forName("javax.net.ssl.X509ExtendedTrustManager");
     60         } catch (ClassNotFoundException e) {
     61             return null;
     62         }
     63     }
     64 
     65     private static void assertClientAuthType(String authType) {
     66         if (!StandardNames.CLIENT_AUTH_TYPES.contains(authType)) {
     67             throw new AssertionError("Unexpected client auth type " + authType);
     68         }
     69     }
     70 
     71     private static void assertServerAuthType(String authType) {
     72         if (!StandardNames.SERVER_AUTH_TYPES.contains(authType)) {
     73             throw new AssertionError("Unexpected server auth type " + authType);
     74         }
     75     }
     76 
     77     private static final class Wrapper implements X509TrustManager {
     78         private final X509TrustManager trustManager;
     79 
     80         private Wrapper(X509TrustManager trustManager) {
     81             out.println("TestTrustManager.<init> trustManager=" + trustManager);
     82             this.trustManager = trustManager;
     83         }
     84 
     85         @Override
     86         public void checkClientTrusted(X509Certificate[] chain, String authType)
     87             throws CertificateException {
     88             out.print("TestTrustManager.checkClientTrusted "
     89                 + "chain=" + chain.length + " "
     90                 + "authType=" + authType + " ");
     91             try {
     92                 assertClientAuthType(authType);
     93                 trustManager.checkClientTrusted(chain, authType);
     94                 out.println("OK");
     95             } catch (CertificateException e) {
     96                 e.printStackTrace(out);
     97                 throw e;
     98             }
     99         }
    100 
    101 
    102 
    103         @Override
    104         public void checkServerTrusted(X509Certificate[] chain, String authType)
    105             throws CertificateException {
    106             out.print("TestTrustManager.checkServerTrusted "
    107                 + "chain=" + chain.length + " "
    108                 + "authType=" + authType + " ");
    109             try {
    110                 assertServerAuthType(authType);
    111                 trustManager.checkServerTrusted(chain, authType);
    112                 out.println("OK");
    113             } catch (CertificateException e) {
    114                 e.printStackTrace(out);
    115                 throw e;
    116             }
    117         }
    118 
    119         /**
    120          * Returns the list of certificate issuer authorities which are trusted for
    121          * authentication of peers.
    122          *
    123          * @return the list of certificate issuer authorities which are trusted for
    124          *         authentication of peers.
    125          */
    126         @Override
    127         public X509Certificate[] getAcceptedIssuers() {
    128             X509Certificate[] result = trustManager.getAcceptedIssuers();
    129             out.print("TestTrustManager.getAcceptedIssuers result=" + result.length);
    130             return result;
    131         }
    132     }
    133 
    134     private static final class ExtendedWrapper extends X509ExtendedTrustManager {
    135         private final X509ExtendedTrustManager extendedTrustManager;
    136         private final X509TrustManager trustManager;
    137 
    138         ExtendedWrapper(X509ExtendedTrustManager trustManager) {
    139             out.println("TestTrustManager.<init> extendedTrustManager=" + trustManager);
    140             this.extendedTrustManager = trustManager;
    141             this.trustManager = trustManager;
    142         }
    143 
    144         @Override
    145         public void checkClientTrusted(X509Certificate[] chain, String authType)
    146             throws CertificateException {
    147             out.print("TestTrustManager.checkClientTrusted "
    148                 + "chain=" + chain.length + " "
    149                 + "authType=" + authType + " ");
    150             try {
    151                 assertClientAuthType(authType);
    152                 trustManager.checkClientTrusted(chain, authType);
    153                 out.println("OK");
    154             } catch (CertificateException e) {
    155                 e.printStackTrace(out);
    156                 throw e;
    157             }
    158         }
    159 
    160 
    161 
    162         @Override
    163         public void checkServerTrusted(X509Certificate[] chain, String authType)
    164             throws CertificateException {
    165             out.print("TestTrustManager.checkServerTrusted "
    166                 + "chain=" + chain.length + " "
    167                 + "authType=" + authType + " ");
    168             try {
    169                 assertServerAuthType(authType);
    170                 trustManager.checkServerTrusted(chain, authType);
    171                 out.println("OK");
    172             } catch (CertificateException e) {
    173                 e.printStackTrace(out);
    174                 throw e;
    175             }
    176         }
    177 
    178         @Override
    179         public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket)
    180             throws CertificateException {
    181             if (extendedTrustManager == null) {
    182                 out.print("(fallback to X509TrustManager) ");
    183                 checkClientTrusted(chain, authType);
    184                 return;
    185             }
    186             out.print("TestTrustManager.checkClientTrusted "
    187                 + "chain=" + chain.length + " "
    188                 + "authType=" + authType + " "
    189                 + "socket=" + socket + " ");
    190             try {
    191                 assertClientAuthType(authType);
    192                 extendedTrustManager.checkClientTrusted(chain, authType, socket);
    193                 out.println("OK");
    194             } catch (CertificateException e) {
    195                 e.printStackTrace(out);
    196                 throw e;
    197             }
    198         }
    199 
    200         @Override
    201         public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
    202             throws CertificateException {
    203             if (extendedTrustManager == null) {
    204                 out.print("(fallback to X509TrustManager) ");
    205                 checkClientTrusted(chain, authType);
    206                 return;
    207             }
    208             out.print("TestTrustManager.checkClientTrusted "
    209                 + "chain=" + chain.length + " "
    210                 + "authType=" + authType + " "
    211                 + "engine=" + engine + " ");
    212             try {
    213                 assertClientAuthType(authType);
    214                 extendedTrustManager.checkClientTrusted(chain, authType, engine);
    215                 out.println("OK");
    216             } catch (CertificateException e) {
    217                 e.printStackTrace(out);
    218                 throw e;
    219             }
    220         }
    221 
    222         @Override
    223         public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket)
    224             throws CertificateException {
    225             if (extendedTrustManager == null) {
    226                 out.print("(fallback to X509TrustManager) ");
    227                 checkServerTrusted(chain, authType);
    228                 return;
    229             }
    230             out.print("TestTrustManager.checkServerTrusted "
    231                 + "chain=" + chain.length + " "
    232                 + "authType=" + authType + " "
    233                 + "socket=" + socket.toString() + " ");
    234             try {
    235                 assertServerAuthType(authType);
    236                 extendedTrustManager.checkServerTrusted(chain, authType, socket);
    237                 out.println("OK");
    238             } catch (CertificateException e) {
    239                 e.printStackTrace(out);
    240                 throw e;
    241             }
    242         }
    243 
    244         @Override
    245         public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine)
    246             throws CertificateException {
    247             if (extendedTrustManager == null) {
    248                 out.print("(fallback to X509TrustManager) ");
    249                 checkServerTrusted(chain, authType);
    250                 return;
    251             }
    252             out.print("TestTrustManager.checkServerTrusted "
    253                 + "chain=" + chain.length + " "
    254                 + "authType=" + authType + " "
    255                 + "engine=" + engine.toString() + " ");
    256             try {
    257                 assertServerAuthType(authType);
    258                 extendedTrustManager.checkServerTrusted(chain, authType, engine);
    259                 out.println("OK");
    260             } catch (CertificateException e) {
    261                 e.printStackTrace(out);
    262                 throw e;
    263             }
    264         }
    265 
    266         /**
    267          * Returns the list of certificate issuer authorities which are trusted for
    268          * authentication of peers.
    269          *
    270          * @return the list of certificate issuer authorities which are trusted for
    271          *         authentication of peers.
    272          */
    273         @Override
    274         public X509Certificate[] getAcceptedIssuers() {
    275             X509Certificate[] result = trustManager.getAcceptedIssuers();
    276             out.print("TestTrustManager.getAcceptedIssuers result=" + result.length);
    277             return result;
    278         }
    279     }
    280 }
    281