use cached grpc ssl credential

pull/18336/head
Muxi Yan 6 years ago
parent ee500f1963
commit 33ebf719a5
  1. 9
      include/grpc/grpc_security.h
  2. 5
      src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.h
  3. 32
      src/objective-c/GRPCClient/private/GRPCSecureChannelFactory.m

@ -191,6 +191,15 @@ typedef struct {
try to get the roots set by grpc_override_ssl_default_roots. Eventually,
if all these fail, it will try to get the roots from a well-known place on
disk (in the grpc install directory).
gRPC has implemented root cache if the underlying OpenSSL library supports
it. The gRPC root certificates cache is only applicable on the default
root certificates, which is used when this parameter is nullptr. If user
provides their own pem_root_certs, when creating an SSL credential object,
gRPC would not be able to cache it, and each subchannel will generate a
copy of the root store. So it is recommended to avoid providing large room
pem with pem_root_certs parameter to avoid excessive memory consumption,
particularly on mobile platforms such as iOS.
- pem_key_cert_pair is a pointer on the object containing client's private
key and certificate chain. This parameter can be NULL if the client does
not have such a key/cert pair.

@ -23,6 +23,11 @@ NS_ASSUME_NONNULL_BEGIN
@interface GRPCSecureChannelFactory : NSObject<GRPCChannelFactory>
/**
* Creates a secure channel factory which uses provided root certificates and client authentication
* credentials. If rootCerts is nil, gRPC will use its default root certificates. If rootCerts is
* provided, it must only contain the server's CA to avoid memory issue.
*/
+ (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts
privateKey:(nullable NSString *)privateKey
certChain:(nullable NSString *)certChain

@ -52,44 +52,20 @@
privateKey:(NSString *)privateKey
certChain:(NSString *)certChain
error:(NSError **)errorPtr {
static NSData *defaultRootsASCII;
static NSError *defaultRootsError;
static dispatch_once_t loading;
dispatch_once(&loading, ^{
NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
// Do not use NSBundle.mainBundle, as it's nil for tests of library projects.
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"];
NSError *error;
// Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the
// issuer). Load them as UTF8 and produce an ASCII equivalent.
NSString *contentInUTF8 =
[NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (contentInUTF8 == nil) {
defaultRootsError = error;
return;
}
defaultRootsASCII = [self nullTerminatedDataWithString:contentInUTF8];
setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR,
[path cStringUsingEncoding:NSUTF8StringEncoding], 1);
});
NSData *rootsASCII;
NSData *rootsASCII = nil;
// if rootCerts is not provided, gRPC will use its own default certs
if (rootCerts != nil) {
rootsASCII = [self nullTerminatedDataWithString:rootCerts];
} else {
if (defaultRootsASCII == nil) {
if (errorPtr) {
*errorPtr = defaultRootsError;
}
NSAssert(
defaultRootsASCII, NSObjectNotAvailableException,
@"Could not read gRPCCertificates.bundle/roots.pem. This file, "
"with the root certificates, is needed to establish secure (TLS) connections. "
"Because the file is distributed with the gRPC library, this error is usually a sign "
"that the library wasn't configured correctly for your project. Error: %@",
defaultRootsError);
return nil;
}
rootsASCII = defaultRootsASCII;
}
grpc_channel_credentials *creds = NULL;

Loading…
Cancel
Save