Browse Source

Add support for TLS mutual auth

Nate Armstrong 7 years ago
parent
commit
0251dd84f9
3 changed files with 14 additions and 4 deletions
  1. 2 0
      Sources/CgRPC/shim/cgrpc.h
  2. 7 1
      Sources/CgRPC/shim/channel.c
  3. 5 3
      Sources/SwiftGRPC/Core/Channel.swift

+ 2 - 0
Sources/CgRPC/shim/cgrpc.h

@@ -166,6 +166,8 @@ cgrpc_channel *cgrpc_channel_create(const char *address,
                                     int num_args);
 cgrpc_channel *cgrpc_channel_create_secure(const char *address,
                                            const char *pem_root_certs,
+                                           const char *client_certs,
+                                           const char *client_key,
                                            grpc_arg *args,
                                            int num_args);
 

+ 7 - 1
Sources/CgRPC/shim/channel.c

@@ -39,6 +39,8 @@ cgrpc_channel *cgrpc_channel_create(const char *address,
 
 cgrpc_channel *cgrpc_channel_create_secure(const char *address,
                                            const char *pem_root_certs,
+                                           const char *client_certs,
+                                           const char *client_private_key,
                                            grpc_arg *args,
                                            int num_args) {
   cgrpc_channel *c = (cgrpc_channel *) malloc(sizeof (cgrpc_channel));
@@ -47,7 +49,11 @@ cgrpc_channel *cgrpc_channel_create_secure(const char *address,
   channel_args.args = args;
   channel_args.num_args = num_args;
 
-  grpc_channel_credentials *creds = grpc_ssl_credentials_create(pem_root_certs, NULL, NULL);
+  grpc_ssl_pem_key_cert_pair client_credentials;
+  client_credentials.cert_chain = client_certs;
+  client_credentials.private_key = client_private_key;
+
+  grpc_channel_credentials *creds = grpc_ssl_credentials_create(pem_root_certs, &client_credentials, NULL);
   c->channel = grpc_secure_channel_create(creds, address, &channel_args, NULL);
   c->completion_queue = grpc_completion_queue_create_for_next(NULL);
   return c;

+ 5 - 3
Sources/SwiftGRPC/Core/Channel.swift

@@ -48,7 +48,7 @@ public class Channel {
     var argumentValues = argumentWrappers.map { $0.wrapped }
 
     if secure {
-      underlyingChannel = cgrpc_channel_create_secure(address, roots_pem(), &argumentValues, Int32(arguments.count))
+      underlyingChannel = cgrpc_channel_create_secure(address, roots_pem(), nil, nil, &argumentValues, Int32(arguments.count))
     } else {
       underlyingChannel = cgrpc_channel_create(address, &argumentValues, Int32(arguments.count))
     }
@@ -60,14 +60,16 @@ public class Channel {
   ///
   /// - Parameter address: the address of the server to be called
   /// - Parameter certificates: a PEM representation of certificates to use
+  /// - Parameter clientCertificates: a PEM representation of the client certificates to use
+  /// - Parameter clientKey: a PEM representation of the client key to use
   /// - Parameter arguments: list of channel configuration options
-  public init(address: String, certificates: String, arguments: [Argument] = []) {
+  public init(address: String, certificates: String, clientCertificates: String? = nil, clientKey: String? = nil, arguments: [Argument] = []) {
     gRPC.initialize()
     host = address
     let argumentWrappers = arguments.map { $0.toCArg() }
     var argumentValues = argumentWrappers.map { $0.wrapped }
 
-    underlyingChannel = cgrpc_channel_create_secure(address, certificates, &argumentValues, Int32(arguments.count))
+    underlyingChannel = cgrpc_channel_create_secure(address, certificates, clientCertificates, clientKey, &argumentValues, Int32(arguments.count))
     completionQueue = CompletionQueue(underlyingCompletionQueue: cgrpc_channel_completion_queue(underlyingChannel), name: "Client")
     completionQueue.run() // start a loop that watches the channel's completion queue
   }