Skip to content

Commit

Permalink
Fix tests and warnings on Java 17
Browse files Browse the repository at this point in the history
SelfSignedCertificate is not available on Java 17 because
OpenJdkSelfSignedCertGenerator is not available. This only impacted
tests.

AccessController is being removed, and these locations are doing simple
reflection which is unlikely to require it even when a security policy
is in effect. There's other places we do reflection without the
AccessController, so either no security policies care or the users can
update their policies to allow it.
  • Loading branch information
ejona86 committed Mar 1, 2024
1 parent feab4e5 commit ac62c8b
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 127 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
jre: [8, 11]
jre: [8, 11, 17]
fail-fast: false # Should swap to true if we grow a large matrix

steps:
Expand Down
2 changes: 0 additions & 2 deletions core/src/main/java/io/grpc/internal/ProxyDetectorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ public PasswordAuthentication requestPasswordAuthentication(
Level.WARNING,
"failed to create URL for Authenticator: {0} {1}", new Object[] {protocol, host});
}
// TODO(spencerfang): consider using java.security.AccessController here
return Authenticator.requestPasswordAuthentication(
host, addr, port, protocol, prompt, scheme, url, Authenticator.RequestorType.PROXY);
}
Expand All @@ -144,7 +143,6 @@ public PasswordAuthentication requestPasswordAuthentication(
new Supplier<ProxySelector>() {
@Override
public ProxySelector get() {
// TODO(spencerfang): consider using java.security.AccessController here
return ProxySelector.getDefault();
}
};
Expand Down
10 changes: 1 addition & 9 deletions netty/src/main/java/io/grpc/netty/JettyTlsUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package io.grpc.netty;

import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

Expand All @@ -42,13 +40,7 @@ static Throwable checkAlpnAvailability() {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, null, null);
SSLEngine engine = context.createSSLEngine();
Method getApplicationProtocol =
AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
@Override
public Method run() throws Exception {
return SSLEngine.class.getMethod("getApplicationProtocol");
}
});
Method getApplicationProtocol = SSLEngine.class.getMethod("getApplicationProtocol");
getApplicationProtocol.invoke(engine);
return null;
} catch (Throwable t) {
Expand Down
36 changes: 22 additions & 14 deletions netty/src/test/java/io/grpc/netty/ProtocolNegotiatorsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import io.grpc.netty.ProtocolNegotiators.ServerTlsHandler;
import io.grpc.netty.ProtocolNegotiators.WaitUntilActiveHandler;
import io.grpc.testing.TlsTesting;
import io.grpc.util.CertificateUtils;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
Expand Down Expand Up @@ -107,16 +108,13 @@
import io.netty.handler.proxy.ProxyConnectException;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import java.io.File;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayDeque;
import java.util.Arrays;
Expand Down Expand Up @@ -478,19 +476,26 @@ public void from_tls_clientAuthOptional_clientCert() throws Exception {

@Test
public void from_tls_managers() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate(TestUtils.TEST_SERVER_HOST);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setKeyEntry("mykey", cert.key(), new char[0], new Certificate[] {cert.cert()});
try (InputStream server1Chain = TlsTesting.loadCert("server1.pem");
InputStream server1Key = TlsTesting.loadCert("server1.key")) {
X509Certificate[] chain = CertificateUtils.getX509Certificates(server1Chain);
keyStore.setKeyEntry("key", CertificateUtils.getPrivateKey(server1Key), new char[0], chain);
}
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, new char[0]);

KeyStore certStore = KeyStore.getInstance(KeyStore.getDefaultType());
certStore.load(null);
certStore.setCertificateEntry("mycert", cert.cert());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
try (InputStream ca = TlsTesting.loadCert("ca.pem")) {
for (X509Certificate cert : CertificateUtils.getX509Certificates(ca)) {
certStore.setCertificateEntry(cert.getSubjectX500Principal().getName("RFC2253"), cert);
}
}
trustManagerFactory.init(certStore);

ServerCredentials serverCreds = TlsServerCredentials.newBuilder()
Expand All @@ -504,8 +509,7 @@ public void from_tls_managers() throws Exception {
.build();
InternalChannelz.Tls tls = expectSuccessfulHandshake(channelCreds, serverCreds);
assertThat(((X509Certificate) tls.remoteCert).getSubjectX500Principal().getName())
.isEqualTo("CN=" + TestUtils.TEST_SERVER_HOST);
cert.delete();
.isEqualTo("CN=*.test.google.com,O=Example\\, Co.,L=Chicago,ST=Illinois,C=US");
}

@Test
Expand Down Expand Up @@ -1214,11 +1218,15 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {

@Test
public void clientTlsHandler_firesNegotiation() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate("authority");
SslContext clientSslContext =
GrpcSslContexts.configure(SslContextBuilder.forClient().trustManager(cert.cert())).build();
SslContext serverSslContext =
GrpcSslContexts.configure(SslContextBuilder.forServer(cert.key(), cert.cert())).build();
SslContext clientSslContext;
try (InputStream ca = TlsTesting.loadCert("ca.pem")) {
clientSslContext = GrpcSslContexts.forClient().trustManager(ca).build();
}
SslContext serverSslContext;
try (InputStream server1Key = TlsTesting.loadCert("server1.key");
InputStream server1Chain = TlsTesting.loadCert("server1.pem")) {
serverSslContext = GrpcSslContexts.forServer(server1Chain, server1Key).build();
}
FakeGrpcHttp2ConnectionHandler gh = FakeGrpcHttp2ConnectionHandler.newHandler();
ClientTlsProtocolNegotiator pn = new ClientTlsProtocolNegotiator(clientSslContext, null);
WriteBufferingAndExceptionHandler clientWbaeh =
Expand Down Expand Up @@ -1404,7 +1412,7 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {

@Override
public String getAuthority() {
return "authority";
return "foo.test.google.fr";
}
}

Expand Down
37 changes: 22 additions & 15 deletions okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import io.grpc.util.CertificateUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.GeneralSecurityException;
Expand Down Expand Up @@ -667,21 +668,24 @@ static SslSocketFactoryResult sslSocketFactoryFrom(ChannelCredentials creds) {

static KeyManager[] createKeyManager(byte[] certChain, byte[] privateKey)
throws GeneralSecurityException {
X509Certificate[] chain;
ByteArrayInputStream inCertChain = new ByteArrayInputStream(certChain);
InputStream certChainStream = new ByteArrayInputStream(certChain);
InputStream privateKeyStream = new ByteArrayInputStream(privateKey);
try {
chain = CertificateUtils.getX509Certificates(inCertChain);
return createKeyManager(certChainStream, privateKeyStream);
} finally {
GrpcUtil.closeQuietly(inCertChain);
GrpcUtil.closeQuietly(certChainStream);
GrpcUtil.closeQuietly(privateKeyStream);
}
}

static KeyManager[] createKeyManager(InputStream certChain, InputStream privateKey)
throws GeneralSecurityException {
X509Certificate[] chain = CertificateUtils.getX509Certificates(certChain);
PrivateKey key;
ByteArrayInputStream inPrivateKey = new ByteArrayInputStream(privateKey);
try {
key = CertificateUtils.getPrivateKey(inPrivateKey);
key = CertificateUtils.getPrivateKey(privateKey);
} catch (IOException uee) {
throw new GeneralSecurityException("Unable to decode private key", uee);
} finally {
GrpcUtil.closeQuietly(inPrivateKey);
}
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try {
Expand All @@ -699,20 +703,23 @@ static KeyManager[] createKeyManager(byte[] certChain, byte[] privateKey)
}

static TrustManager[] createTrustManager(byte[] rootCerts) throws GeneralSecurityException {
InputStream rootCertsStream = new ByteArrayInputStream(rootCerts);
try {
return createTrustManager(rootCertsStream);
} finally {
GrpcUtil.closeQuietly(rootCertsStream);
}
}

static TrustManager[] createTrustManager(InputStream rootCerts) throws GeneralSecurityException {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try {
ks.load(null, null);
} catch (IOException ex) {
// Shouldn't really happen, as we're not loading any data.
throw new GeneralSecurityException(ex);
}
X509Certificate[] certs;
ByteArrayInputStream in = new ByteArrayInputStream(rootCerts);
try {
certs = CertificateUtils.getX509Certificates(in);
} finally {
GrpcUtil.closeQuietly(in);
}
X509Certificate[] certs = CertificateUtils.getX509Certificates(rootCerts);
for (X509Certificate cert : certs) {
X500Principal principal = cert.getSubjectX500Principal();
ks.setCertificateEntry(principal.getName("RFC2253"), cert);
Expand Down
103 changes: 45 additions & 58 deletions okhttp/src/test/java/io/grpc/okhttp/OkHttpChannelBuilderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,20 @@
import io.grpc.internal.FakeClock;
import io.grpc.internal.GrpcUtil;
import io.grpc.internal.SharedResourceHolder;
import io.grpc.internal.testing.TestUtils;
import io.grpc.testing.GrpcCleanupRule;
import io.grpc.testing.TlsTesting;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.concurrent.ScheduledExecutorService;
import javax.net.SocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.TrustManager;
import javax.security.auth.x500.X500Principal;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -168,16 +165,12 @@ public void sslSocketFactoryFrom_unsupportedTls() {

@Test
public void sslSocketFactoryFrom_tls_customRoots() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate(TestUtils.TEST_SERVER_HOST);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setKeyEntry("mykey", cert.key(), new char[0], new Certificate[] {cert.cert()});
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, new char[0]);

SSLContext serverContext = SSLContext.getInstance("TLS");
serverContext.init(keyManagerFactory.getKeyManagers(), null, null);
try (InputStream server1Chain = TlsTesting.loadCert("server1.pem");
InputStream server1Key = TlsTesting.loadCert("server1.key")) {
serverContext.init(
OkHttpChannelBuilder.createKeyManager(server1Chain, server1Key), null, null);
}
final SSLServerSocket serverListenSocket =
(SSLServerSocket) serverContext.getServerSocketFactory().createServerSocket(0);
final SettableFuture<SSLSocket> serverSocket = SettableFuture.create();
Expand All @@ -194,9 +187,12 @@ public void sslSocketFactoryFrom_tls_customRoots() throws Exception {
}
}).start();

ChannelCredentials creds = TlsChannelCredentials.newBuilder()
.trustManager(cert.certificate())
ChannelCredentials creds;
try (InputStream ca = TlsTesting.loadCert("ca.pem")) {
creds = TlsChannelCredentials.newBuilder()
.trustManager(ca)
.build();
}
OkHttpChannelBuilder.SslSocketFactoryResult result =
OkHttpChannelBuilder.sslSocketFactoryFrom(creds);
SSLSocket socket =
Expand All @@ -208,24 +204,19 @@ public void sslSocketFactoryFrom_tls_customRoots() throws Exception {

@Test
public void sslSocketFactoryFrom_tls_mtls() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate(TestUtils.TEST_SERVER_HOST);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setKeyEntry("mykey", cert.key(), new char[0], new Certificate[] {cert.cert()});
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, new char[0]);

KeyStore certStore = KeyStore.getInstance(KeyStore.getDefaultType());
certStore.load(null);
certStore.setCertificateEntry("mycert", cert.cert());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(certStore);
KeyManager[] keyManagers;
try (InputStream server1Chain = TlsTesting.loadCert("server1.pem");
InputStream server1Key = TlsTesting.loadCert("server1.key")) {
keyManagers = OkHttpChannelBuilder.createKeyManager(server1Chain, server1Key);
}

TrustManager[] trustManagers;
try (InputStream ca = TlsTesting.loadCert("ca.pem")) {
trustManagers = OkHttpChannelBuilder.createTrustManager(ca);
}

SSLContext serverContext = SSLContext.getInstance("TLS");
serverContext.init(
keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
serverContext.init(keyManagers, trustManagers, null);
final SSLServerSocket serverListenSocket =
(SSLServerSocket) serverContext.getServerSocketFactory().createServerSocket(0);
serverListenSocket.setNeedClientAuth(true);
Expand All @@ -244,40 +235,31 @@ public void sslSocketFactoryFrom_tls_mtls() throws Exception {
}).start();

ChannelCredentials creds = TlsChannelCredentials.newBuilder()
.keyManager(keyManagerFactory.getKeyManagers())
.trustManager(trustManagerFactory.getTrustManagers())
.keyManager(keyManagers)
.trustManager(trustManagers)
.build();
OkHttpChannelBuilder.SslSocketFactoryResult result =
OkHttpChannelBuilder.sslSocketFactoryFrom(creds);
SSLSocket socket =
(SSLSocket) result.factory.createSocket("localhost", serverListenSocket.getLocalPort());
socket.getSession(); // Force handshake
assertThat(((X500Principal) serverSocket.get().getSession().getPeerPrincipal()).getName())
.isEqualTo("CN=" + TestUtils.TEST_SERVER_HOST);
.isEqualTo("CN=*.test.google.com,O=Example\\, Co.,L=Chicago,ST=Illinois,C=US");
socket.close();
serverSocket.get().close();
}

@Test
public void sslSocketFactoryFrom_tls_mtls_keyFile() throws Exception {
SelfSignedCertificate cert = new SelfSignedCertificate(TestUtils.TEST_SERVER_HOST);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
keyStore.setKeyEntry("mykey", cert.key(), new char[0], new Certificate[] {cert.cert()});
KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, new char[0]);

KeyStore certStore = KeyStore.getInstance(KeyStore.getDefaultType());
certStore.load(null);
certStore.setCertificateEntry("mycert", cert.cert());
TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(certStore);

SSLContext serverContext = SSLContext.getInstance("TLS");
serverContext.init(
keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
try (InputStream server1Chain = TlsTesting.loadCert("server1.pem");
InputStream server1Key = TlsTesting.loadCert("server1.key");
InputStream ca = TlsTesting.loadCert("ca.pem")) {
serverContext.init(
OkHttpChannelBuilder.createKeyManager(server1Chain, server1Key),
OkHttpChannelBuilder.createTrustManager(ca),
null);
}
final SSLServerSocket serverListenSocket =
(SSLServerSocket) serverContext.getServerSocketFactory().createServerSocket(0);
serverListenSocket.setNeedClientAuth(true);
Expand All @@ -295,17 +277,22 @@ public void sslSocketFactoryFrom_tls_mtls_keyFile() throws Exception {
}
}).start();

ChannelCredentials creds = TlsChannelCredentials.newBuilder()
.keyManager(cert.certificate(), cert.privateKey())
.trustManager(cert.certificate())
.build();
ChannelCredentials creds;
try (InputStream server1Chain = TlsTesting.loadCert("server1.pem");
InputStream server1Key = TlsTesting.loadCert("server1.key");
InputStream ca = TlsTesting.loadCert("ca.pem")) {
creds = TlsChannelCredentials.newBuilder()
.keyManager(server1Chain, server1Key)
.trustManager(ca)
.build();
}
OkHttpChannelBuilder.SslSocketFactoryResult result =
OkHttpChannelBuilder.sslSocketFactoryFrom(creds);
SSLSocket socket =
(SSLSocket) result.factory.createSocket("localhost", serverListenSocket.getLocalPort());
socket.getSession(); // Force handshake
assertThat(((X500Principal) serverSocket.get().getSession().getPeerPrincipal()).getName())
.isEqualTo("CN=" + TestUtils.TEST_SERVER_HOST);
.isEqualTo("CN=*.test.google.com,O=Example\\, Co.,L=Chicago,ST=Illinois,C=US");
socket.close();
serverSocket.get().close();
}
Expand Down
Loading

0 comments on commit ac62c8b

Please sign in to comment.