15
15
*
16
16
*/
17
17
18
- import { ConnectionOptions , createSecureContext , PeerCertificate } from 'tls' ;
18
+ import { ConnectionOptions , createSecureContext , PeerCertificate , SecureContext } from 'tls' ;
19
19
20
20
import { CallCredentials } from './call-credentials' ;
21
21
import { CIPHER_SUITES , getDefaultRootsData } from './tls-helpers' ;
@@ -110,6 +110,7 @@ export abstract class ChannelCredentials {
110
110
* @param rootCerts The root certificate data.
111
111
* @param privateKey The client certificate private key, if available.
112
112
* @param certChain The client certificate key chain, if available.
113
+ * @param verifyOptions Additional options to modify certificate verification
113
114
*/
114
115
static createSsl (
115
116
rootCerts ?: Buffer | null ,
@@ -130,14 +131,35 @@ export abstract class ChannelCredentials {
130
131
'Certificate chain must be given with accompanying private key'
131
132
) ;
132
133
}
134
+ const secureContext = createSecureContext ( {
135
+ ca : rootCerts ?? getDefaultRootsData ( ) ?? undefined ,
136
+ key : privateKey ?? undefined ,
137
+ cert : certChain ?? undefined ,
138
+ ciphers : CIPHER_SUITES ,
139
+ } ) ;
133
140
return new SecureChannelCredentialsImpl (
134
- rootCerts || getDefaultRootsData ( ) ,
135
- privateKey || null ,
136
- certChain || null ,
137
- verifyOptions || { }
141
+ secureContext ,
142
+ verifyOptions ?? { }
138
143
) ;
139
144
}
140
145
146
+ /**
147
+ * Return a new ChannelCredentials instance with credentials created using
148
+ * the provided secureContext. The resulting instances can be used to
149
+ * construct a Channel that communicates over TLS. gRPC will not override
150
+ * anything in the provided secureContext, so the environment variables
151
+ * GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will
152
+ * not be applied.
153
+ * @param secureContext The return value of tls.createSecureContext()
154
+ * @param verifyOptions Additional options to modify certificate verification
155
+ */
156
+ static createFromSecureContext ( secureContext : SecureContext , verifyOptions ?: VerifyOptions ) : ChannelCredentials {
157
+ return new SecureChannelCredentialsImpl (
158
+ secureContext ,
159
+ verifyOptions ?? { }
160
+ )
161
+ }
162
+
141
163
/**
142
164
* Return a new ChannelCredentials instance with no credentials.
143
165
*/
@@ -170,18 +192,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials {
170
192
connectionOptions : ConnectionOptions ;
171
193
172
194
constructor (
173
- private rootCerts : Buffer | null ,
174
- private privateKey : Buffer | null ,
175
- private certChain : Buffer | null ,
195
+ private secureContext : SecureContext ,
176
196
private verifyOptions : VerifyOptions
177
197
) {
178
198
super ( ) ;
179
- const secureContext = createSecureContext ( {
180
- ca : rootCerts || undefined ,
181
- key : privateKey || undefined ,
182
- cert : certChain || undefined ,
183
- ciphers : CIPHER_SUITES ,
184
- } ) ;
185
199
this . connectionOptions = {
186
200
secureContext
187
201
} ;
@@ -210,19 +224,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials {
210
224
return true ;
211
225
}
212
226
if ( other instanceof SecureChannelCredentialsImpl ) {
213
- if ( ! bufferOrNullEqual ( this . rootCerts , other . rootCerts ) ) {
214
- return false ;
215
- }
216
- if ( ! bufferOrNullEqual ( this . privateKey , other . privateKey ) ) {
217
- return false ;
218
- }
219
- if ( ! bufferOrNullEqual ( this . certChain , other . certChain ) ) {
220
- return false ;
221
- }
222
227
return (
223
- this . verifyOptions . checkServerIdentity ===
224
- other . verifyOptions . checkServerIdentity
225
- ) ;
228
+ this . secureContext === other . secureContext &&
229
+ this . verifyOptions . checkServerIdentity === other . verifyOptions . checkServerIdentity
230
+ ) ;
226
231
} else {
227
232
return false ;
228
233
}
0 commit comments