Merge pull request #18336 from muxi/memory-issue

Use cached grpc ssl credential for ObjC library
pull/18352/head
Yang Gao 6 years ago committed by GitHub
commit 5cfc1a63cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  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, 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 if all these fail, it will try to get the roots from a well-known place on
disk (in the grpc install directory). 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 - 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 key and certificate chain. This parameter can be NULL if the client does
not have such a key/cert pair. not have such a key/cert pair.

@ -23,6 +23,11 @@ NS_ASSUME_NONNULL_BEGIN
@interface GRPCSecureChannelFactory : NSObject<GRPCChannelFactory> @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 + (nullable instancetype)factoryWithPEMRootCertificates:(nullable NSString *)rootCerts
privateKey:(nullable NSString *)privateKey privateKey:(nullable NSString *)privateKey
certChain:(nullable NSString *)certChain certChain:(nullable NSString *)certChain

@ -52,44 +52,20 @@
privateKey:(NSString *)privateKey privateKey:(NSString *)privateKey
certChain:(NSString *)certChain certChain:(NSString *)certChain
error:(NSError **)errorPtr { error:(NSError **)errorPtr {
static NSData *defaultRootsASCII;
static NSError *defaultRootsError;
static dispatch_once_t loading; static dispatch_once_t loading;
dispatch_once(&loading, ^{ dispatch_once(&loading, ^{
NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
// Do not use NSBundle.mainBundle, as it's nil for tests of library projects. // Do not use NSBundle.mainBundle, as it's nil for tests of library projects.
NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"]; NSString *path = [bundle pathForResource:defaultPath ofType:@"pem"];
NSError *error; setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR,
// Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the [path cStringUsingEncoding:NSUTF8StringEncoding], 1);
// 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];
}); });
NSData *rootsASCII; NSData *rootsASCII = nil;
// if rootCerts is not provided, gRPC will use its own default certs
if (rootCerts != nil) { if (rootCerts != nil) {
rootsASCII = [self nullTerminatedDataWithString:rootCerts]; 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; grpc_channel_credentials *creds = NULL;

Loading…
Cancel
Save