20
20
import static java .util .Objects .requireNonNull ;
21
21
import static net .devh .boot .grpc .common .util .GrpcUtils .DOMAIN_SOCKET_ADDRESS_SCHEME ;
22
22
23
- import java .io .IOException ;
24
23
import java .io .InputStream ;
25
24
import java .net .URI ;
26
25
import java .util .List ;
27
26
27
+ import javax .net .ssl .KeyManagerFactory ;
28
28
import javax .net .ssl .SSLException ;
29
+ import javax .net .ssl .TrustManagerFactory ;
29
30
30
31
import org .springframework .core .io .Resource ;
31
32
40
41
import net .devh .boot .grpc .client .config .GrpcChannelsProperties ;
41
42
import net .devh .boot .grpc .client .config .NegotiationType ;
42
43
import net .devh .boot .grpc .client .interceptor .GlobalClientInterceptorRegistry ;
44
+ import net .devh .boot .grpc .common .security .KeyStoreUtils ;
43
45
import net .devh .boot .grpc .common .util .GrpcUtils ;
44
46
45
47
/**
51
53
*
52
54
* @author Michael ([email protected] )
53
55
* @author Daniel Theuke ([email protected] )
54
- * @since 5/17/16
55
56
*/
56
57
// Keep this file in sync with ShadedNettyChannelFactory
57
58
public class NettyChannelFactory extends AbstractChannelFactory <NettyChannelBuilder > {
@@ -88,6 +89,7 @@ protected NettyChannelBuilder newChannelBuilder(final String name) {
88
89
}
89
90
90
91
@ Override
92
+ // Keep this in sync with ShadedNettyChannelFactory#configureSecurity
91
93
protected void configureSecurity (final NettyChannelBuilder builder , final String name ) {
92
94
final GrpcChannelProperties properties = getPropertiesFor (name );
93
95
@@ -103,28 +105,8 @@ protected void configureSecurity(final NettyChannelBuilder builder, final String
103
105
}
104
106
105
107
final SslContextBuilder sslContextBuilder = GrpcSslContexts .forClient ();
106
-
107
- if (security .isClientAuthEnabled ()) {
108
- final Resource certificateChain =
109
- requireNonNull (security .getCertificateChain (), "certificateChain not configured" );
110
- final Resource privateKey = requireNonNull (security .getPrivateKey (), "privateKey not configured" );
111
- try (InputStream certificateChainStream = certificateChain .getInputStream ();
112
- InputStream privateKeyStream = privateKey .getInputStream ()) {
113
- sslContextBuilder .keyManager (certificateChainStream , privateKeyStream ,
114
- security .getPrivateKeyPassword ());
115
- } catch (IOException | RuntimeException e ) {
116
- throw new IllegalArgumentException ("Failed to create SSLContext (PK/Cert)" , e );
117
- }
118
- }
119
-
120
- final Resource trustCertCollection = security .getTrustCertCollection ();
121
- if (trustCertCollection != null ) {
122
- try (InputStream trustCertCollectionStream = trustCertCollection .getInputStream ()) {
123
- sslContextBuilder .trustManager (trustCertCollectionStream );
124
- } catch (IOException | RuntimeException e ) {
125
- throw new IllegalArgumentException ("Failed to create SSLContext (TrustStore)" , e );
126
- }
127
- }
108
+ configureProvidedClientCertificate (security , sslContextBuilder );
109
+ configureAcceptedServerCertificates (security , sslContextBuilder );
128
110
129
111
if (security .getCiphers () != null && !security .getCiphers ().isEmpty ()) {
130
112
sslContextBuilder .ciphers (security .getCiphers ());
@@ -142,12 +124,81 @@ protected void configureSecurity(final NettyChannelBuilder builder, final String
142
124
}
143
125
}
144
126
127
+ /**
128
+ * Configures the client certificate provided by the ssl context.
129
+ *
130
+ * @param security The security configuration to use.
131
+ * @param sslContextBuilder The ssl context builder to configure.
132
+ */
133
+ // Keep this in sync with ShadedNettyChannelFactory#configureProvidedClientCertificate
134
+ protected static void configureProvidedClientCertificate (final Security security ,
135
+ final SslContextBuilder sslContextBuilder ) {
136
+ if (security .isClientAuthEnabled ()) {
137
+ try {
138
+ final Resource privateKey = security .getPrivateKey ();
139
+ final Resource keyStore = security .getKeyStore ();
140
+
141
+ if (privateKey != null ) {
142
+ final Resource certificateChain =
143
+ requireNonNull (security .getCertificateChain (), "certificateChain" );
144
+ final String privateKeyPassword = security .getPrivateKeyPassword ();
145
+ try (InputStream certificateChainStream = certificateChain .getInputStream ();
146
+ InputStream privateKeyStream = privateKey .getInputStream ()) {
147
+ sslContextBuilder .keyManager (certificateChainStream , privateKeyStream , privateKeyPassword );
148
+ }
149
+
150
+ } else if (keyStore != null ) {
151
+ final KeyManagerFactory keyManagerFactory = KeyStoreUtils .loadKeyManagerFactory (
152
+ security .getKeyStoreFormat (), keyStore , security .getKeyStorePassword ());
153
+ sslContextBuilder .keyManager (keyManagerFactory );
154
+
155
+ } else {
156
+ throw new IllegalStateException ("Neither privateKey nor keyStore configured" );
157
+ }
158
+ } catch (final Exception e ) {
159
+ throw new IllegalArgumentException ("Failed to create SSLContext (PK/Cert)" , e );
160
+ }
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Configures the server certificates accepted by the ssl context.
166
+ *
167
+ * @param security The security configuration to use.
168
+ * @param sslContextBuilder The ssl context builder to configure.
169
+ */
170
+ // Keep this in sync with ShadedNettyChannelFactory#configureAcceptedServerCertificates
171
+ protected static void configureAcceptedServerCertificates (final Security security ,
172
+ final SslContextBuilder sslContextBuilder ) {
173
+ try {
174
+ final Resource trustCertCollection = security .getTrustCertCollection ();
175
+ final Resource trustStore = security .getTrustStore ();
176
+
177
+ if (trustCertCollection != null ) {
178
+ try (InputStream trustCertCollectionStream = trustCertCollection .getInputStream ()) {
179
+ sslContextBuilder .trustManager (trustCertCollectionStream );
180
+ }
181
+
182
+ } else if (trustStore != null ) {
183
+ final TrustManagerFactory trustManagerFactory = KeyStoreUtils .loadTrustManagerFactory (
184
+ security .getTrustStoreFormat (), trustStore , security .getTrustStorePassword ());
185
+ sslContextBuilder .trustManager (trustManagerFactory );
186
+
187
+ } else {
188
+ // Use system default
189
+ }
190
+ } catch (final Exception e ) {
191
+ throw new IllegalArgumentException ("Failed to create SSLContext (TrustStore)" , e );
192
+ }
193
+ }
194
+
145
195
/**
146
196
* Converts the given negotiation type to netty's negotiation type.
147
197
*
148
198
* @param negotiationType The negotiation type to convert.
149
199
* @return The converted negotiation type.
150
200
*/
201
+ // Keep this in sync with ShadedNettyChannelFactory#of
151
202
protected static io .grpc .netty .NegotiationType of (final NegotiationType negotiationType ) {
152
203
switch (negotiationType ) {
153
204
case PLAINTEXT :
0 commit comments