• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The gRPC Authors
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 io.grpc.testing;
18 
19 import io.grpc.ExperimentalApi;
20 import io.grpc.Metadata;
21 import io.grpc.ServerCall;
22 import io.grpc.ServerCallHandler;
23 import io.grpc.ServerInterceptor;
24 import java.io.BufferedInputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.security.KeyStore;
30 import java.security.NoSuchAlgorithmException;
31 import java.security.Provider;
32 import java.security.cert.CertificateException;
33 import java.security.cert.CertificateFactory;
34 import java.security.cert.X509Certificate;
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.concurrent.atomic.AtomicReference;
39 import javax.net.ssl.SSLContext;
40 import javax.net.ssl.SSLSocketFactory;
41 import javax.net.ssl.TrustManagerFactory;
42 import javax.security.auth.x500.X500Principal;
43 
44 /**
45  * Common utility functions useful for writing tests.
46  */
47 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1791")
48 public class TestUtils {
49   /**
50    * Capture the request headers from a client. Useful for testing metadata propagation.
51    */
recordRequestHeadersInterceptor( final AtomicReference<Metadata> headersCapture)52   public static ServerInterceptor recordRequestHeadersInterceptor(
53       final AtomicReference<Metadata> headersCapture) {
54     return new ServerInterceptor() {
55       @Override
56       public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
57           ServerCall<ReqT, RespT> call,
58           Metadata requestHeaders,
59           ServerCallHandler<ReqT, RespT> next) {
60         headersCapture.set(requestHeaders);
61         return next.startCall(call, requestHeaders);
62       }
63     };
64   }
65 
66   /**
67    * Returns the ciphers preferred to use during tests. They may be chosen because they are widely
68    * available or because they are fast. There is no requirement that they provide confidentiality
69    * or integrity.
70    *
71    * @deprecated Not for public use
72    */
73   @Deprecated
74   public static List<String> preferredTestCiphers() {
75     String[] ciphers;
76     try {
77       ciphers = SSLContext.getDefault().getDefaultSSLParameters().getCipherSuites();
78     } catch (NoSuchAlgorithmException ex) {
79       throw new RuntimeException(ex);
80     }
81     List<String> ciphersMinusGcm = new ArrayList<>();
82     for (String cipher : ciphers) {
83       // The GCM implementation in Java is _very_ slow (~1 MB/s)
84       if (cipher.contains("_GCM_")) {
85         continue;
86       }
87       ciphersMinusGcm.add(cipher);
88     }
89     return Collections.unmodifiableList(ciphersMinusGcm);
90   }
91 
92   /**
93    * Loads an X.509 certificate from the classpath resources in src/main/resources/certs.
94    *
95    * @param fileName  name of a file in src/main/resources/certs.
96    *
97    * @deprecated Not for public use
98    */
99   @Deprecated
100   public static X509Certificate loadX509Cert(String fileName)
101       throws CertificateException, IOException {
102     CertificateFactory cf = CertificateFactory.getInstance("X.509");
103 
104     InputStream in = TestUtils.class.getResourceAsStream("/certs/" + fileName);
105     try {
106       return (X509Certificate) cf.generateCertificate(in);
107     } finally {
108       in.close();
109     }
110   }
111 
112   /**
113    * Creates an SSLSocketFactory which contains {@code certChainFile} as its only root certificate.
114    *
115    * @deprecated Not for public use
116    */
117   @Deprecated
118   public static SSLSocketFactory newSslSocketFactoryForCa(Provider provider,
119       File certChainFile) throws Exception {
120     KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
121     ks.load(null, null);
122     CertificateFactory cf = CertificateFactory.getInstance("X.509");
123     X509Certificate cert = (X509Certificate) cf.generateCertificate(
124         new BufferedInputStream(new FileInputStream(certChainFile)));
125     X500Principal principal = cert.getSubjectX500Principal();
126     ks.setCertificateEntry(principal.getName("RFC2253"), cert);
127 
128     // Set up trust manager factory to use our key store.
129     TrustManagerFactory trustManagerFactory =
130         TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
131     trustManagerFactory.init(ks);
132     SSLContext context = SSLContext.getInstance("TLS", provider);
133     context.init(null, trustManagerFactory.getTrustManagers(), null);
134     return context.getSocketFactory();
135   }
136 
137   private TestUtils() {}
138 }
139