1414package  io .dapr .utils ;
1515
1616import  io .dapr .config .Properties ;
17+ import  io .dapr .exceptions .DaprError ;
18+ import  io .dapr .exceptions .DaprException ;
19+ import  io .grpc .ChannelCredentials ;
1720import  io .grpc .ClientInterceptor ;
21+ import  io .grpc .Grpc ;
1822import  io .grpc .ManagedChannel ;
1923import  io .grpc .ManagedChannelBuilder ;
24+ import  io .grpc .TlsChannelCredentials ;
25+ import  io .grpc .netty .shaded .io .grpc .netty .GrpcSslContexts ;
26+ import  io .grpc .netty .shaded .io .grpc .netty .NettyChannelBuilder ;
27+ import  io .grpc .netty .shaded .io .netty .handler .ssl .util .InsecureTrustManagerFactory ;
2028
29+ import  java .io .FileInputStream ;
2130import  java .io .IOException ;
31+ import  java .io .InputStream ;
2232import  java .net .InetAddress ;
2333import  java .net .InetSocketAddress ;
2434import  java .net .Socket ;
2535import  java .util .regex .Pattern ;
2636
2737import  static  io .dapr .config .Properties .GRPC_ENDPOINT ;
2838import  static  io .dapr .config .Properties .GRPC_PORT ;
39+ import  static  io .dapr .config .Properties .GRPC_TLS_CA_PATH ;
40+ import  static  io .dapr .config .Properties .GRPC_TLS_CERT_PATH ;
41+ import  static  io .dapr .config .Properties .GRPC_TLS_INSECURE ;
42+ import  static  io .dapr .config .Properties .GRPC_TLS_KEY_PATH ;
2943import  static  io .dapr .config .Properties .SIDECAR_IP ;
3044
31- 
3245/** 
3346 * Utility methods for network, internal to Dapr SDK. 
3447 */ 
@@ -56,19 +69,20 @@ public final class NetworkUtils {
5669  private  static  final  String  GRPC_ENDPOINT_HOSTNAME_REGEX_PART  = "(([A-Za-z0-9_\\ -\\ .]+)|(\\ ["  + IPV6_REGEX  + "\\ ]))" ;
5770
5871  private  static  final  String  GRPC_ENDPOINT_DNS_AUTHORITY_REGEX_PART  =
59-       "(?<dnsWithAuthority>dns://)(?<authorityEndpoint>"  + GRPC_ENDPOINT_HOSTNAME_REGEX_PART  + ":[0-9]+)?/" ;
72+           "(?<dnsWithAuthority>dns://)(?<authorityEndpoint>" 
73+       + GRPC_ENDPOINT_HOSTNAME_REGEX_PART  + ":[0-9]+)?/" ;
6074
6175  private  static  final  String  GRPC_ENDPOINT_PARAM_REGEX_PART  = "(\\ ?(?<param>tls\\ =((true)|(false))))?" ;
6276
63-   private  static  final  String  GRPC_ENDPOINT_SOCKET_REGEX_PART  =
64-       "(?<socket>((unix:)|(unix://)|(unix-abstract:))"   + GRPC_ENDPOINT_FILENAME_REGEX_PART  + ")" ;
77+   private  static  final  String  GRPC_ENDPOINT_SOCKET_REGEX_PART  =  "(?<socket>((unix:)|(unix://)|(unix-abstract:))" 
78+       + GRPC_ENDPOINT_FILENAME_REGEX_PART  + ")" ;
6579
66-   private  static  final  String  GRPC_ENDPOINT_VSOCKET_REGEX_PART  =
67-       "(?<vsocket>vsock:"  +  GRPC_ENDPOINT_HOSTNAME_REGEX_PART   + ":[0-9]+)" ;
68-   private  static  final  String  GRPC_ENDPOINT_HOST_REGEX_PART  =
69-       "((?<http>http://)|(?<https>https://)|(?<dns>dns:)|("   + GRPC_ENDPOINT_DNS_AUTHORITY_REGEX_PART  + "))?" 
70-            + "(?<hostname>"  + GRPC_ENDPOINT_HOSTNAME_REGEX_PART  + ")?+" 
71-            + "(:(?<port>[0-9]+))?" ;
80+   private  static  final  String  GRPC_ENDPOINT_VSOCKET_REGEX_PART  =  "(?<vsocket>vsock:"  +  GRPC_ENDPOINT_HOSTNAME_REGEX_PART 
81+       + ":[0-9]+)" ;
82+   private  static  final  String  GRPC_ENDPOINT_HOST_REGEX_PART  =  "((?<http>http://)|(?<https>https://)|(?<dns>dns:)|(" 
83+       + GRPC_ENDPOINT_DNS_AUTHORITY_REGEX_PART  + "))?" 
84+       + "(?<hostname>"  + GRPC_ENDPOINT_HOSTNAME_REGEX_PART  + ")?+" 
85+       + "(:(?<port>[0-9]+))?" ;
7286
7387  private  static  final  String  GRPC_ENDPOINT_REGEX  = "^(" 
7488      + "("  + GRPC_ENDPOINT_HOST_REGEX_PART  + ")|" 
@@ -107,17 +121,76 @@ public static void waitForSocket(String host, int port, int timeoutInMillisecond
107121
108122  /** 
109123   * Creates a GRPC managed channel. 
110-    * @param properties instance to set up the GrpcEndpoint 
124+    *  
125+    * @param properties   instance to set up the GrpcEndpoint 
111126   * @param interceptors Optional interceptors to add to the channel. 
112127   * @return GRPC managed channel to communicate with the sidecar. 
113128   */ 
114129  public  static  ManagedChannel  buildGrpcManagedChannel (Properties  properties , ClientInterceptor ... interceptors ) {
115130    var  settings  = GrpcEndpointSettings .parse (properties );
116-     ManagedChannelBuilder <?> builder  = ManagedChannelBuilder .forTarget (settings .endpoint )
117-         .userAgent (Version .getSdkVersion ());
118-     if  (!settings .secure ) {
131+ 
132+     boolean  insecureTls  = properties .getValue (GRPC_TLS_INSECURE );
133+     if  (insecureTls ) {
134+       try  {
135+         ManagedChannelBuilder <?> builder  = NettyChannelBuilder .forTarget (settings .endpoint )
136+             .sslContext (GrpcSslContexts .forClient ()
137+                 .trustManager (InsecureTrustManagerFactory .INSTANCE )
138+                 .build ());
139+         builder .userAgent (Version .getSdkVersion ());
140+         if  (interceptors  != null  && interceptors .length  > 0 ) {
141+           builder  = builder .intercept (interceptors );
142+         }
143+         return  builder .build ();
144+       } catch  (Exception  e ) {
145+         throw  new  DaprException (
146+             new  DaprError ().setErrorCode ("TLS_CREDENTIALS_ERROR" )
147+                 .setMessage ("Failed to create insecure TLS credentials" ), e );
148+       }
149+     }
150+ 
151+     String  clientKeyPath  = settings .tlsPrivateKeyPath ;
152+     String  clientCertPath  = settings .tlsCertPath ;
153+     String  caCertPath  = settings .tlsCaPath ;
154+ 
155+     ManagedChannelBuilder <?> builder  = ManagedChannelBuilder .forTarget (settings .endpoint );
156+ 
157+     if  (clientCertPath  != null  && clientKeyPath  != null ) {
158+       // mTLS case - using client cert and key, with optional CA cert for server authentication 
159+       try  (
160+           InputStream  clientCertInputStream  = new  FileInputStream (clientCertPath );
161+           InputStream  clientKeyInputStream  = new  FileInputStream (clientKeyPath );
162+           InputStream  caCertInputStream  = caCertPath  != null  ? new  FileInputStream (caCertPath ) : null 
163+       ) {
164+         TlsChannelCredentials .Builder  builderCreds  = TlsChannelCredentials .newBuilder ()
165+             .keyManager (clientCertInputStream , clientKeyInputStream );  // For client authentication 
166+         if  (caCertInputStream  != null ) {
167+           builderCreds .trustManager (caCertInputStream );  // For server authentication 
168+         }
169+         ChannelCredentials  credentials  = builderCreds .build ();
170+         builder  = Grpc .newChannelBuilder (settings .endpoint , credentials );
171+       } catch  (IOException  e ) {
172+         throw  new  DaprException (
173+             new  DaprError ().setErrorCode ("TLS_CREDENTIALS_ERROR" )
174+                 .setMessage ("Failed to create mTLS credentials"  + (caCertPath  != null  ? " with CA cert"  : "" )), e );
175+       }
176+     } else  if  (caCertPath  != null ) {
177+       // Simple TLS case - using CA cert only for server authentication 
178+       try  (InputStream  caCertInputStream  = new  FileInputStream (caCertPath )) {
179+         ChannelCredentials  credentials  = TlsChannelCredentials .newBuilder ()
180+             .trustManager (caCertInputStream )
181+             .build ();
182+         builder  = Grpc .newChannelBuilder (settings .endpoint , credentials );
183+       } catch  (IOException  e ) {
184+         throw  new  DaprException (
185+             new  DaprError ().setErrorCode ("TLS_CREDENTIALS_ERROR" )
186+                 .setMessage ("Failed to create TLS credentials with CA cert" ), e );
187+       }
188+     } else  if  (!settings .secure ) {
119189      builder  = builder .usePlaintext ();
120190    }
191+ 
192+     builder .userAgent (Version .getSdkVersion ());
193+ 
121194    if  (interceptors  != null  && interceptors .length  > 0 ) {
122195      builder  = builder .intercept (interceptors );
123196    }
@@ -128,15 +201,26 @@ public static ManagedChannel buildGrpcManagedChannel(Properties properties, Clie
128201  static  final  class  GrpcEndpointSettings  {
129202    final  String  endpoint ;
130203    final  boolean  secure ;
204+     final  String  tlsPrivateKeyPath ;
205+     final  String  tlsCertPath ;
206+     final  String  tlsCaPath ;
131207
132-     private  GrpcEndpointSettings (String  endpoint , boolean  secure ) {
208+     private  GrpcEndpointSettings (
209+             String  endpoint , boolean  secure , String  tlsPrivateKeyPath , String  tlsCertPath , String  tlsCaPath ) {
133210      this .endpoint  = endpoint ;
134211      this .secure  = secure ;
212+       this .tlsPrivateKeyPath  = tlsPrivateKeyPath ;
213+       this .tlsCertPath  = tlsCertPath ;
214+       this .tlsCaPath  = tlsCaPath ;
135215    }
136216
137217    static  GrpcEndpointSettings  parse (Properties  properties ) {
138218      String  address  = properties .getValue (SIDECAR_IP );
139219      int  port  = properties .getValue (GRPC_PORT );
220+       String  clientKeyPath  = properties .getValue (GRPC_TLS_KEY_PATH );
221+       String  clientCertPath  = properties .getValue (GRPC_TLS_CERT_PATH );
222+       String  caCertPath  = properties .getValue (GRPC_TLS_CA_PATH );
223+ 
140224      boolean  secure  = false ;
141225      String  grpcEndpoint  = properties .getValue (GRPC_ENDPOINT );
142226      if  ((grpcEndpoint  != null ) && !grpcEndpoint .isEmpty ()) {
@@ -172,21 +256,31 @@ static GrpcEndpointSettings parse(Properties properties) {
172256
173257        var  authorityEndpoint  = matcher .group ("authorityEndpoint" );
174258        if  (authorityEndpoint  != null ) {
175-           return  new  GrpcEndpointSettings (String .format ("dns://%s/%s:%d" , authorityEndpoint , address , port ), secure );
259+           return  new  GrpcEndpointSettings (
260+                   String .format (
261+                           "dns://%s/%s:%d" ,
262+                           authorityEndpoint ,
263+                           address ,
264+                           port 
265+                   ), secure , clientKeyPath , clientCertPath , caCertPath );
176266        }
177267
178268        var  socket  = matcher .group ("socket" );
179269        if  (socket  != null ) {
180-           return  new  GrpcEndpointSettings (socket , secure );
270+           return  new  GrpcEndpointSettings (socket , secure ,  clientKeyPath ,  clientCertPath ,  caCertPath );
181271        }
182272
183273        var  vsocket  = matcher .group ("vsocket" );
184274        if  (vsocket  != null ) {
185-           return  new  GrpcEndpointSettings (vsocket , secure );
275+           return  new  GrpcEndpointSettings (vsocket , secure ,  clientKeyPath ,  clientCertPath ,  caCertPath );
186276        }
187277      }
188278
189-       return  new  GrpcEndpointSettings (String .format ("dns:///%s:%d" , address , port ), secure );
279+       return  new  GrpcEndpointSettings (String .format (
280+               "dns:///%s:%d" ,
281+               address ,
282+               port 
283+       ), secure , clientKeyPath , clientCertPath , caCertPath );
190284    }
191285
192286  }
0 commit comments