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