2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  2014  gRPC  authors . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      http : //www.apache.org/licenses/LICENSE-2.0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  credentials  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"crypto/tls" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"crypto/x509" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 18:05:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"google.golang.org/grpc/grpclog" 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									credinternal  "google.golang.org/grpc/internal/credentials" 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 18:05:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"google.golang.org/grpc/internal/envconfig" 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 18:05:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  logger  =  grpclog . Component ( "credentials" )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// TLSInfo contains the auth information for a TLS authenticated connection.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// It implements the AuthInfo interface.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  TLSInfo  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									State  tls . ConnectionState 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CommonAuthInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This API is experimental. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SPIFFEID  * url . URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// AuthType returns the type of TLSInfo as a string.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  TLSInfo )  AuthType ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "tls" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// cipherSuiteLookup returns the string version of a TLS cipher suite ID.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  cipherSuiteLookup ( cipherSuiteID  uint16 )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  s  :=  range  tls . CipherSuites ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  s . ID  ==  cipherSuiteID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  s . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  s  :=  range  tls . InsecureCipherSuites ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  s . ID  ==  cipherSuiteID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  s . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fmt . Sprintf ( "unknown ID: %v" ,  cipherSuiteID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// GetSecurityValue returns security info requested by channelz.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  TLSInfo )  GetSecurityValue ( )  ChannelzSecurityValue  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v  :=  & TLSChannelzSecurityValue { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										StandardName :  cipherSuiteLookup ( t . State . CipherSuite ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Currently there's no way to get LocalCertificate info from tls package. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( t . State . PeerCertificates )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v . RemoteCertificate  =  t . State . PeerCertificates [ 0 ] . Raw 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// tlsCreds is the credentials required for authenticating a connection using TLS.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  tlsCreds  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TLS configuration 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config  * tls . Config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  tlsCreds )  Info ( )  ProtocolInfo  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ProtocolInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SecurityProtocol :  "tls" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SecurityVersion :   "1.2" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ServerName :        c . config . ServerName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * tlsCreds )  ClientHandshake ( ctx  context . Context ,  authority  string ,  rawConn  net . Conn )  ( _  net . Conn ,  _  AuthInfo ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// use local cfg to avoid clobbering ServerName if using multiple endpoints 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  :=  credinternal . CloneTLSConfig ( c . config ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cfg . ServerName  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										serverName ,  _ ,  err  :=  net . SplitHostPort ( authority ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// If the authority had no host port or if the authority cannot be parsed, use it as-is. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											serverName  =  authority 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cfg . ServerName  =  serverName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									conn  :=  tls . Client ( rawConn ,  cfg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errChannel  :=  make ( chan  error ,  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errChannel  <-  conn . Handshake ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( errChannel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  err  :=  <- errChannel : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  <- ctx . Done ( ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  ctx . Err ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 18:05:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The negotiated protocol can be either of the following: 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 1. h2: When the server supports ALPN. Only HTTP/2 can be negotiated since 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//    it is the only protocol advertised by the client during the handshake. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//    The tls library ensures that the server chooses a protocol advertised 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//    by the client. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 2. "" (empty string): If the server doesn't support ALPN. ALPN is a requirement 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//    for using HTTP/2 over TLS. We can terminate the connection immediately. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									np  :=  conn . ConnectionState ( ) . NegotiatedProtocol 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  np  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  envconfig . EnforceALPNEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  fmt . Errorf ( "credentials: cannot check peer: missing selected ALPN property" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . Warningf ( "Allowing TLS connection to server %q with ALPN disabled. TLS connections to servers with ALPN disabled will be disallowed in future grpc-go releases" ,  cfg . ServerName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									tlsInfo  :=  TLSInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										State :  conn . ConnectionState ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CommonAuthInfo :  CommonAuthInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SecurityLevel :  PrivacyAndIntegrity , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									id  :=  credinternal . SPIFFEIDFromState ( conn . ConnectionState ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  id  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tlsInfo . SPIFFEID  =  id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  credinternal . WrapSyscallConn ( rawConn ,  conn ) ,  tlsInfo ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * tlsCreds )  ServerHandshake ( rawConn  net . Conn )  ( net . Conn ,  AuthInfo ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									conn  :=  tls . Server ( rawConn ,  c . config ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  conn . Handshake ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 18:05:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cs  :=  conn . ConnectionState ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The negotiated application protocol can be empty only if the client doesn't 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// support ALPN. In such cases, we can close the connection since ALPN is required 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// for using HTTP/2 over TLS. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cs . NegotiatedProtocol  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  envconfig . EnforceALPNEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											conn . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  fmt . Errorf ( "credentials: cannot check peer: missing selected ALPN property" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  logger . V ( 2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . Info ( "Allowing TLS connection from client with ALPN disabled. TLS connections with ALPN disabled will be disallowed in future grpc-go releases" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									tlsInfo  :=  TLSInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-26 18:05:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										State :  cs , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										CommonAuthInfo :  CommonAuthInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SecurityLevel :  PrivacyAndIntegrity , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									id  :=  credinternal . SPIFFEIDFromState ( conn . ConnectionState ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  id  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tlsInfo . SPIFFEID  =  id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  credinternal . WrapSyscallConn ( rawConn ,  conn ) ,  tlsInfo ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * tlsCreds )  Clone ( )  TransportCredentials  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NewTLS ( c . config ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( c  * tlsCreds )  OverrideServerName ( serverNameOverride  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									c . config . ServerName  =  serverNameOverride 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The following cipher suites are forbidden for use with HTTP/2 by  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://datatracker.ietf.org/doc/html/rfc7540#appendix-A  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  tls12ForbiddenCipherSuites  =  map [ uint16 ] struct { } {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_RSA_WITH_AES_128_CBC_SHA :          { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_RSA_WITH_AES_256_CBC_SHA :          { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_RSA_WITH_AES_128_GCM_SHA256 :       { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_RSA_WITH_AES_256_GCM_SHA384 :       { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :  { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :    { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tls . TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :    { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// NewTLS uses c to construct a TransportCredentials based on TLS.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewTLS ( c  * tls . Config )  TransportCredentials  {  
						 
					
						
							
								
									
										
										
										
											2025-02-06 12:14:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config  :=  applyDefaults ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  config . GetConfigForClient  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oldFn  :=  config . GetConfigForClient 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . GetConfigForClient  =  func ( hello  * tls . ClientHelloInfo )  ( * tls . Config ,  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cfgForClient ,  err  :=  oldFn ( hello ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  ||  cfgForClient  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  cfgForClient ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  applyDefaults ( cfgForClient ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & tlsCreds { config :  config } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  applyDefaults ( c  * tls . Config )  * tls . Config  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config  :=  credinternal . CloneTLSConfig ( c ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config . NextProtos  =  credinternal . AppendH2ToNextProtos ( config . NextProtos ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If the user did not configure a MinVersion and did not configure a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// MaxVersion < 1.2, use MinVersion=1.2, which is required by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// https://datatracker.ietf.org/doc/html/rfc7540#section-9.2 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-06 12:14:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  config . MinVersion  ==  0  &&  ( config . MaxVersion  ==  0  ||  config . MaxVersion  >=  tls . VersionTLS12 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . MinVersion  =  tls . VersionTLS12 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the user did not configure CipherSuites, use all "secure" cipher 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// suites reported by the TLS package, but remove some explicitly forbidden 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// by https://datatracker.ietf.org/doc/html/rfc7540#appendix-A 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-06 12:14:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  config . CipherSuites  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  cs  :=  range  tls . CipherSuites ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  tls12ForbiddenCipherSuites [ cs . ID ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-06 12:14:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												config . CipherSuites  =  append ( config . CipherSuites ,  cs . ID ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-11 15:34:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-06 12:14:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  config 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-09 19:19:48 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewClientTLSFromCert constructs TLS credentials from the provided root  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// certificate authority certificate(s) to validate server connections. If  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// certificates to establish the identity of the client need to be included in  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the credentials (eg: for mTLS), use NewTLS instead, where a complete  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// tls.Config can be specified.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// serverNameOverride is for testing only. If set to a non empty string,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it will override the virtual host name of authority (e.g. :authority header  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// field) in requests.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewClientTLSFromCert ( cp  * x509 . CertPool ,  serverNameOverride  string )  TransportCredentials  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NewTLS ( & tls . Config { ServerName :  serverNameOverride ,  RootCAs :  cp } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewClientTLSFromFile constructs TLS credentials from the provided root  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// certificate authority certificate file(s) to validate server connections. If  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// certificates to establish the identity of the client need to be included in  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the credentials (eg: for mTLS), use NewTLS instead, where a complete  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// tls.Config can be specified.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// serverNameOverride is for testing only. If set to a non empty string,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it will override the virtual host name of authority (e.g. :authority header  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// field) in requests.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewClientTLSFromFile ( certFile ,  serverNameOverride  string )  ( TransportCredentials ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									b ,  err  :=  os . ReadFile ( certFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cp  :=  x509 . NewCertPool ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! cp . AppendCertsFromPEM ( b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  fmt . Errorf ( "credentials: failed to append certificates" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NewTLS ( & tls . Config { ServerName :  serverNameOverride ,  RootCAs :  cp } ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewServerTLSFromCert constructs TLS credentials from the input certificate for server.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewServerTLSFromCert ( cert  * tls . Certificate )  TransportCredentials  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NewTLS ( & tls . Config { Certificates :  [ ] tls . Certificate { * cert } } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NewServerTLSFromFile constructs TLS credentials from the input certificate file and key  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// file for server.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewServerTLSFromFile ( certFile ,  keyFile  string )  ( TransportCredentials ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cert ,  err  :=  tls . LoadX509KeyPair ( certFile ,  keyFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NewTLS ( & tls . Config { Certificates :  [ ] tls . Certificate { cert } } ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TLSChannelzSecurityValue defines the struct that TLS protocol should return  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// from GetSecurityValue(), containing security info like cipher and certificate used.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// # Experimental  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Notice: This type is EXPERIMENTAL and may be changed or removed in a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// later release.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  TLSChannelzSecurityValue  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ChannelzSecurityValue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StandardName       string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LocalCertificate   [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RemoteCertificate  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}