Merge pull request #1988 from murgatroid99/grpc-js_securecontext_creds

grpc-js: Add credentials.createFromSecureContext
This commit is contained in:
Michael Lumish 2022-01-10 14:05:58 -08:00 committed by GitHub
commit 81ef5e33c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 26 deletions

View File

@ -15,7 +15,7 @@
*
*/
import { ConnectionOptions, createSecureContext, PeerCertificate } from 'tls';
import { ConnectionOptions, createSecureContext, PeerCertificate, SecureContext } from 'tls';
import { CallCredentials } from './call-credentials';
import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers';
@ -110,6 +110,7 @@ export abstract class ChannelCredentials {
* @param rootCerts The root certificate data.
* @param privateKey The client certificate private key, if available.
* @param certChain The client certificate key chain, if available.
* @param verifyOptions Additional options to modify certificate verification
*/
static createSsl(
rootCerts?: Buffer | null,
@ -130,14 +131,35 @@ export abstract class ChannelCredentials {
'Certificate chain must be given with accompanying private key'
);
}
const secureContext = createSecureContext({
ca: rootCerts ?? getDefaultRootsData() ?? undefined,
key: privateKey ?? undefined,
cert: certChain ?? undefined,
ciphers: CIPHER_SUITES,
});
return new SecureChannelCredentialsImpl(
rootCerts || getDefaultRootsData(),
privateKey || null,
certChain || null,
verifyOptions || {}
secureContext,
verifyOptions ?? {}
);
}
/**
* Return a new ChannelCredentials instance with credentials created using
* the provided secureContext. The resulting instances can be used to
* construct a Channel that communicates over TLS. gRPC will not override
* anything in the provided secureContext, so the environment variables
* GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will
* not be applied.
* @param secureContext The return value of tls.createSecureContext()
* @param verifyOptions Additional options to modify certificate verification
*/
static createFromSecureContext(secureContext: SecureContext, verifyOptions?: VerifyOptions): ChannelCredentials {
return new SecureChannelCredentialsImpl(
secureContext,
verifyOptions ?? {}
)
}
/**
* Return a new ChannelCredentials instance with no credentials.
*/
@ -170,18 +192,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials {
connectionOptions: ConnectionOptions;
constructor(
private rootCerts: Buffer | null,
private privateKey: Buffer | null,
private certChain: Buffer | null,
private secureContext: SecureContext,
private verifyOptions: VerifyOptions
) {
super();
const secureContext = createSecureContext({
ca: rootCerts || undefined,
key: privateKey || undefined,
cert: certChain || undefined,
ciphers: CIPHER_SUITES,
});
this.connectionOptions = {
secureContext
};
@ -210,19 +224,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials {
return true;
}
if (other instanceof SecureChannelCredentialsImpl) {
if (!bufferOrNullEqual(this.rootCerts, other.rootCerts)) {
return false;
}
if (!bufferOrNullEqual(this.privateKey, other.privateKey)) {
return false;
}
if (!bufferOrNullEqual(this.certChain, other.certChain)) {
return false;
}
return (
this.verifyOptions.checkServerIdentity ===
other.verifyOptions.checkServerIdentity
);
this.secureContext === other.secureContext &&
this.verifyOptions.checkServerIdentity === other.verifyOptions.checkServerIdentity
);
} else {
return false;
}

View File

@ -109,6 +109,7 @@ export const credentials = {
// from channel-credentials.ts
createInsecure: ChannelCredentials.createInsecure,
createSsl: ChannelCredentials.createSsl,
createFromSecureContext: ChannelCredentials.createFromSecureContext,
// from call-credentials.ts
createFromMetadataGenerator: CallCredentials.createFromMetadataGenerator,