Added support for tls
diff --git a/README.md b/README.md
index 6bf65ea..de53791 100644
--- a/README.md
+++ b/README.md
@@ -20,17 +20,16 @@
 
     mkdir -p $HOME/go/bin $HOME/go/pkg $HOME/go/src/github.com/maps-booking
 
-
 Next, add the following to your ~/.bashrc
 
-	export PATH=$PATH:$(go env GOPATH)/bin
-	export GOPATH=$(go env GOPATH)
-	export GOBIN=$(go env GOPATH)/bin
-	
+    export PATH=$PATH:$(go env GOPATH)/bin
+    export GOPATH=$(go env GOPATH)
+    export GOBIN=$(go env GOPATH)/bin
+
 Source changes
-	
-	source ~/.bashrc
-	
+
+    source ~/.bashrc
+
 Next, retrieve the utility from the
 [maps-booking repository](https://maps-booking.googlesource.com/)
 
@@ -38,8 +37,8 @@
 
 Lastly, download all dependencies and install the tool.
 
-	cd $HOME/go
-	go get -d ./...
+    cd $HOME/go
+    go get -d ./...
     go install $HOME/go/src/github.com/maps-booking/testclient/main.go
 
 ### Installing the utility with Windows Powershell
@@ -74,7 +73,7 @@
 After following the install steps above an executable should now live in
 
     $HOME/go/bin/main
-	
+
 or
 
     $env:HOME\go\bin\main.exe
@@ -113,9 +112,45 @@
 Example Usage:
 
     bin/main -health_check_test=true -check_availability_test=true
-    -output_dir="/tmp" -server_addr="localhost:50051”
+    -output_dir="/tmp" -server_addr="grpc-service.google.com:50051”
     -availability_feed="/tmp/test.json"
 
+#### Enabling TLS
+Using the TLS feature of this utility is slightly more complicated than the
+standard non-TLS runs and requires a few additional steps.
+
+- Begin by overriding your server's RootCAs file with the provided root.pem
+  located in maps-booking/certs/root.pem. Details regarding your server's root
+  certs can be found on the [maps-booking developer site.]
+  (https://developers.google.com/maps-booking/guides/partner-implementing-grpc-server-2)
+
+- Point the ca_file flag of the client utility to the location of your original
+  roots file. If you don't have one yet you can [download these
+  roots](https://pki.google.com/roots.pem) that have been recommended by the
+  Google Internet Authority.
+
+- Enable TLS by setting the tls flag to true.
+
+Example Usage:
+
+    bin/main -health_check_test=true -check_availability_test=true
+    -output_dir="/tmp" -server_addr="grpc-service.google.com:50051”
+    -availability_feed="/tmp/test.json" -tls -ca_file="/tmp/trusted_roots.pem"
+
+#### Optional TLS Feature
+
+It's possible to override the FQDN your client attempts to use during the TLS
+handshake. If you find a need to use an alias when testing your implementation,
+simply override using the servername_override flag.
+
+Example Usage:
+
+    bin/main -health_check_test=true -check_availability_test=true
+    -output_dir="/tmp" -server_addr="localhost:50051”
+    -availability_feed="/tmp/test.json" -tls -ca_file="/tmp/trusted_roots.pem"
+    -servername_override="myservice.google.com"
+
+
 ### Parsing the output
 
 The test utility will output a file with the prefix 'grpc_test_client_log_'
diff --git a/certs/root.pem b/certs/root.pem
new file mode 100644
index 0000000..4193c2e
--- /dev/null
+++ b/certs/root.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIFzTCCA7WgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxITAf
+BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GA1UEAwwYbWFwcy1i
+b29raW5nX3Rlc3QtY2xpZW50MB4XDTE3MTAyNzAxNDIxN1oXDTI3MTAyNTAxNDIx
+N1owgYAxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBM
+dGQxITAfBgNVBAMMGG1hcHMtYm9va2luZ190ZXN0LWNsaWVudDCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBALZhw3cOlpLbecQzE7WHNN+aPSVboI01Wy2G
+y18bw6abeKqrd6IotKnd9EUzLrY6c2cWmlA6EgUYEJ5Qsdzso2+IF9d2Dcmlz7A0
+sK4scjzoxD/Qj8E+iyQASXxla86l/1XpvXwPv2ZcfOqJDmaSsCptAiR6qLc2+6g4
+m/d3MpLx1BFH0MlQNB0XG4SNeCTEA959AgexWBFelTQUl5QKmUXkPOd6BRvGedzp
+uj4nA+AFWpMgvgXYi7tiDOaS8cXfhXIuPMB1P9dk8pn/etFKPELFq1Fvuw/DF08y
+dkkyORrbXNTJNbIQRhBQj17VG6GoKypyVQ6EHgWHFlMqqzgs3+JWlaoSC/f3GvX1
+uuSakG66KLN6ZBQU+KcvmhZHhsxikynmvlAVPLeu+cNlVJZMS1OfjEiPyxs3M9VL
+bEBxYgSLpjyuKCY50fxK67tKgiCLDTwXpX/R/herIHAAMoQMM0qBmMgj9iuReAjU
+Zu4IC3kSL6/ZPRqivZAXAciGVC2CVx6cHQQA66iO1/u9ETN+QX3cPo/rf+ki1Cte
+cdVCfzAh3FA06wDgx/96JL6cwn6TUfjUnPNwSL1rvzdaULadL29SQWUlFjASV4WE
+ppyjh/Z6xEr+FcUroNXE/16LagM4HR/IDvDd6ZQ9sVHqlBR1xEtA7VxptgFcMi6o
+t+RPam+nAgMBAAGjUDBOMB0GA1UdDgQWBBSwnp+00yr82MUrKAIkoVMTWtzoozAf
+BgNVHSMEGDAWgBSwnp+00yr82MUrKAIkoVMTWtzoozAMBgNVHRMEBTADAQH/MA0G
+CSqGSIb3DQEBCwUAA4ICAQCPloUFKtlQWmXEQPPwpFX8tnC0SEJDKTMV4S+1kpOQ
+edoSY6544wChdUwvIvgiePce1R1SUu+sOr9XYl7uBZ+j1+iKm5mPcyxr7HczRtdM
+HOIRVQxLRrL/sgbW3XP2OIb9nNSGRRpuOvc9U3xvS51YzshoweSGaPqPrM1uwqWD
+3tVTNSycePj00gx1ajtv1M5QDZnhtMOPdtSPqYajuV1QgsDJfR957GEf1KrjZScA
+raw/K/JbqkHBJR9CD629ARCGQfx2xTRxlFJfYZxvtBucUZUv2eTAbio92WdVBTaM
+G4BYW+wl8zZeKsb/3nyh852D65desLTLGb1vSqyd5QxTJ1H3wWe1SiW14fxreuXQ
+pyuH8Qnj7ZHvQSvQjMqgJlnfbMMcwQ8a7UJXJtnstE4EbsC9mIpM/YUPwP5BnnVw
+Ry99cwxdtKfpUwspWORsPQcfsLJgBTIdLqcBaWr8huYf1pjJX604rLcXN8vRzo/X
+GMXc6h7ogMB3SJ7Lc4XMXFvowF7yUOyHk3zgthZzxivyTuHrlCpL9asgqW+HTmyv
+N4DBiJQdvBEfnFrP2jXOMD2C8QbbZ/QQjtpOos+o+B7UMld+tshVrrbLc2Njy57c
+9pGz4BakZkGA32+Quoy5fyziYpDL7ilEBDG4OBYIrsbg7iqrO6LH580qFw3VaY6g
+WA==
+-----END CERTIFICATE-----
diff --git a/certs/test_client_cert.pem b/certs/test_client_cert.pem
new file mode 100644
index 0000000..57febfa
--- /dev/null
+++ b/certs/test_client_cert.pem
@@ -0,0 +1,102 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=California, L=Mountain View, O=Internet Widgits Pty Ltd, CN=maps-booking_test-client
+        Validity
+            Not Before: Oct 27 01:53:28 2017 GMT
+            Not After : Oct 25 01:53:28 2027 GMT
+        Subject: C=US, ST=California, O=Internet Widgits Pty Ltd, CN=maps-booking_test-client-cert
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b8:4a:8a:a7:b5:6f:ac:cb:38:dd:c3:96:a7:d8:
+                    79:0f:e1:9a:1b:b9:4a:ff:8b:d7:93:67:9b:9b:fc:
+                    9a:47:9c:a1:c4:ff:1a:40:14:02:37:3e:28:bb:6f:
+                    89:af:66:56:c4:6b:34:6c:28:97:34:2d:0f:b7:85:
+                    b9:41:41:dc:01:c4:5f:d0:3c:49:47:d7:47:c3:e6:
+                    e8:52:70:e3:a9:2f:3e:4c:f7:09:57:f9:c0:cb:4a:
+                    b5:e1:0e:22:8c:f7:13:d8:f4:e9:69:c9:d2:14:bb:
+                    f1:5b:53:c5:7e:80:8b:22:6e:bb:82:39:40:7d:d9:
+                    a3:0a:4e:46:4c:c2:03:11:6c:f2:01:1c:5e:08:b0:
+                    b3:83:9b:62:50:8b:21:45:11:b2:63:7b:79:95:99:
+                    0b:47:c8:ba:16:0b:05:94:ef:9c:2d:22:01:6d:ed:
+                    68:5e:4d:21:30:d8:8a:68:b5:94:d3:de:74:02:aa:
+                    18:6b:62:f5:2f:73:06:27:8f:b0:83:ff:5f:27:ec:
+                    29:40:ff:b9:df:df:e7:fe:d5:69:19:5f:a1:88:4e:
+                    f5:c4:7b:70:3c:46:3d:28:7a:cf:dc:66:5c:d9:3b:
+                    46:95:c6:6a:2c:9c:04:22:22:dd:8b:5a:e8:ac:2e:
+                    bb:3f:fe:54:04:84:09:7f:ad:19:75:64:7a:04:f8:
+                    b3:8b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                8A:F7:40:6F:73:C8:C4:78:AB:83:E1:98:14:6A:4D:10:0A:2E:5B:CA
+            X509v3 Authority Key Identifier: 
+                keyid:B0:9E:9F:B4:D3:2A:FC:D8:C5:2B:28:02:24:A1:53:13:5A:DC:E8:A3
+
+    Signature Algorithm: sha256WithRSAEncryption
+         b4:9a:05:63:44:d5:64:fe:12:c2:72:da:5f:a8:41:11:bb:f7:
+         0a:f2:21:2f:fd:3c:59:27:1e:d5:ee:3c:5c:a6:42:5a:72:fe:
+         36:6c:45:26:ed:74:d9:04:96:8d:7c:29:17:55:ec:08:43:94:
+         8e:11:16:b0:e7:e6:2d:0d:3f:cf:93:e2:7a:ab:23:f5:c7:f1:
+         bd:f1:fc:43:c0:59:90:2f:6c:87:29:10:ac:ed:07:83:f2:29:
+         f9:5b:14:dc:a4:a9:92:97:a1:8f:47:1f:52:e3:ee:30:56:56:
+         98:fa:2e:64:69:e9:c9:33:17:1b:1f:c2:2f:b4:9e:a8:10:4f:
+         6b:74:e5:4a:93:8d:af:92:15:ac:8d:23:e0:08:1f:bf:4f:aa:
+         81:ae:c3:7d:05:18:ea:3b:31:c7:cb:95:c6:5e:a3:6e:91:41:
+         c7:b5:17:7a:44:da:68:83:fe:5a:aa:b4:1f:dc:7f:c9:66:2d:
+         f8:ae:b2:5a:66:f9:4c:70:31:fe:94:cd:39:46:06:16:21:67:
+         5b:9e:9f:51:aa:75:52:03:c4:17:4b:cd:64:71:d8:67:27:03:
+         85:e3:ec:77:d8:e5:a2:60:f7:1b:7f:2d:06:63:39:a9:de:42:
+         1f:73:87:f5:2d:94:d8:29:c2:d6:27:c3:3f:a0:f1:c6:53:47:
+         3c:50:b1:93:a6:2b:21:2b:b9:7c:49:72:fa:47:1b:7f:73:cd:
+         28:99:6a:b4:82:f8:fc:64:58:b0:3d:5e:d1:e5:4d:4c:c1:21:
+         e6:2f:aa:80:69:c4:a0:4a:d5:9e:50:d3:33:ec:68:95:fd:43:
+         27:34:80:de:e3:4e:3f:a1:dc:70:d1:83:71:5e:13:78:fb:d0:
+         f4:a5:37:00:23:2d:04:23:41:6c:ba:90:9b:5a:fb:7b:c5:3a:
+         33:30:e6:01:43:97:84:3b:d7:32:fe:e9:74:b1:4d:88:9b:dd:
+         b8:3f:df:69:19:e1:02:df:40:b1:10:b3:d4:78:d8:c7:b6:8d:
+         cf:98:e9:07:bb:99:0a:b0:e5:0e:6b:85:1b:11:bc:89:e2:27:
+         40:ca:c0:4d:4c:fe:13:c6:1f:ce:1f:dd:e6:4e:54:d2:33:a0:
+         47:e2:23:3c:aa:5a:ab:a6:78:7a:3c:20:e2:2f:6f:5b:b1:09:
+         f2:8f:8d:93:5a:0c:07:42:0c:8c:02:62:fd:43:99:97:dc:d1:
+         00:db:dc:57:13:b9:4f:c7:66:b3:17:56:b7:f9:7a:f1:b7:63:
+         3f:e8:d8:d6:f8:d0:f7:c7:9b:4d:fa:3e:ab:57:13:34:3a:0e:
+         d2:70:c9:1c:ec:3f:34:37:a6:c5:33:e0:51:ad:51:b3:9b:ca:
+         e5:cd:90:f1:85:c1:4e:25
+-----BEGIN CERTIFICATE-----
+MIIE5DCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxITAf
+BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GA1UEAwwYbWFwcy1i
+b29raW5nX3Rlc3QtY2xpZW50MB4XDTE3MTAyNzAxNTMyOFoXDTI3MTAyNTAxNTMy
+OFowbTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEmMCQGA1UEAwwdbWFwcy1ib29raW5n
+X3Rlc3QtY2xpZW50LWNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQC4SoqntW+syzjdw5an2HkP4ZobuUr/i9eTZ5ub/JpHnKHE/xpAFAI3Pii7b4mv
+ZlbEazRsKJc0LQ+3hblBQdwBxF/QPElH10fD5uhScOOpLz5M9wlX+cDLSrXhDiKM
+9xPY9OlpydIUu/FbU8V+gIsibruCOUB92aMKTkZMwgMRbPIBHF4IsLODm2JQiyFF
+EbJje3mVmQtHyLoWCwWU75wtIgFt7WheTSEw2IpotZTT3nQCqhhrYvUvcwYnj7CD
+/18n7ClA/7nf3+f+1WkZX6GITvXEe3A8Rj0oes/cZlzZO0aVxmosnAQiIt2LWuis
+Lrs//lQEhAl/rRl1ZHoE+LOLAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4
+QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSK
+90Bvc8jEeKuD4ZgUak0QCi5byjAfBgNVHSMEGDAWgBSwnp+00yr82MUrKAIkoVMT
+WtzoozANBgkqhkiG9w0BAQsFAAOCAgEAtJoFY0TVZP4SwnLaX6hBEbv3CvIhL/08
+WSce1e48XKZCWnL+NmxFJu102QSWjXwpF1XsCEOUjhEWsOfmLQ0/z5Pieqsj9cfx
+vfH8Q8BZkC9shykQrO0Hg/Ip+VsU3KSpkpehj0cfUuPuMFZWmPouZGnpyTMXGx/C
+L7SeqBBPa3TlSpONr5IVrI0j4Agfv0+qga7DfQUY6jsxx8uVxl6jbpFBx7UXekTa
+aIP+Wqq0H9x/yWYt+K6yWmb5THAx/pTNOUYGFiFnW56fUap1UgPEF0vNZHHYZycD
+hePsd9jlomD3G38tBmM5qd5CH3OH9S2U2CnC1ifDP6DxxlNHPFCxk6YrISu5fEly
++kcbf3PNKJlqtIL4/GRYsD1e0eVNTMEh5i+qgGnEoErVnlDTM+xolf1DJzSA3uNO
+P6HccNGDcV4TePvQ9KU3ACMtBCNBbLqQm1r7e8U6MzDmAUOXhDvXMv7pdLFNiJvd
+uD/faRnhAt9AsRCz1HjYx7aNz5jpB7uZCrDlDmuFGxG8ieInQMrATUz+E8Yfzh/d
+5k5U0jOgR+IjPKpaq6Z4ejwg4i9vW7EJ8o+Nk1oMB0IMjAJi/UOZl9zRANvcVxO5
+T8dmsxdWt/l68bdjP+jY1vjQ98ebTfo+q1cTNDoO0nDJHOw/NDemxTPgUa1Rs5vK
+5c2Q8YXBTiU=
+-----END CERTIFICATE-----
diff --git a/certs/test_client_key.pem b/certs/test_client_key.pem
new file mode 100644
index 0000000..c8989f6
--- /dev/null
+++ b/certs/test_client_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAuEqKp7VvrMs43cOWp9h5D+GaG7lK/4vXk2ebm/yaR5yhxP8a
+QBQCNz4ou2+Jr2ZWxGs0bCiXNC0Pt4W5QUHcAcRf0DxJR9dHw+boUnDjqS8+TPcJ
+V/nAy0q14Q4ijPcT2PTpacnSFLvxW1PFfoCLIm67gjlAfdmjCk5GTMIDEWzyARxe
+CLCzg5tiUIshRRGyY3t5lZkLR8i6FgsFlO+cLSIBbe1oXk0hMNiKaLWU0950AqoY
+a2L1L3MGJ4+wg/9fJ+wpQP+539/n/tVpGV+hiE71xHtwPEY9KHrP3GZc2TtGlcZq
+LJwEIiLdi1rorC67P/5UBIQJf60ZdWR6BPiziwIDAQABAoIBAQCbJy6ayTauzB0h
+HxSMVMR/aVj8NEB+6rXgxN6OMdmVprnPB1KLVg0Tg0J5owrQ36D3FqZ41KeP5swP
+nwZ7eT4HQtPDla3ATO9/b7xyA9a3Ti3uUCDOr1bwEAMV6XePJEjSZEbKqH40tJIb
+aGih+wioQX+dwCOakIsiFwo6fzBkDtsj4V3qVunuZ5TRufUSrXebAMSsE5U+POch
+FznfqsD/vhus5ggbhM/8wG1NgEtO5apkc+KjA/vnWpcpSeWxnBYmQZr0dU9iZJr+
+vCxMKY+kdVfjohbeGQt51TqUkBdLbfUlun8fE1X9hrsA5aYonP82unJ+hWn3Wg60
+fP9vr1gBAoGBAPWcsKoCG6DisgLAjNhAMC2Q7lp2qsM7Y01p4epLX8UxOHRMlpnr
+erNRc4k75hZDp7/rtrO6eb3F+76mlPVbqi/JRRqY5xM8vsDF8KYSAW8XJXZ6AP+Z
+G7sxjJ8QnlT1lAWK+XNxAEk6U3jj6eB+CfGSZJJh3tbjhX69BseE5uQBAoGBAMAV
+6cpOq+F0ZSlh3sljvlDEPY0BaUtlAF5LOX6Vdg7c/zeWJtAAE24hPYwxSi9e4jYx
+eHBM3Xk5yQVGsIbxl/dvgWGY2nbzb1YdbOEEzrVBh7hm8YW3DER+HwNcDpMhoWCf
+O8uD59YNsyvrqD/vb7KpVDWr+yD8ClO7zjLL3ueLAoGAdAZMElOil5LfgptRLYrM
+94mCf2uVaVqxo01EcnieyjlhMNdJQXbS5Miyan7IR3Y4VVpVWXvarMJNFRf+QBXI
+RICwy0q1xgmpFsmqz9iror3tbZVeyV+bkQdsJWwlT38fKKspAda8ytrpua74uZrw
+uZRtPBVNvneGhYNoI3Jt3AECgYB5bGDBdkHI3x8jra57eAXSYHrYK9A3zL0S3lKV
+5j0e4CylItGeIq4lq/WQLYhLsZslztfnhW9rNlAQecMVSptZ2q7a1xkioHf849Tz
+2Wohwi7dLpX2hOPIWEGaihLchyHQRlgyKkvfUAG2/dz5rY3aTpfg5bp1+1072Thb
+e+yISQKBgGgtchLhw26f+wIvDDJx6AExEbbnV5V84riqZR4PpBz4e88xWdtpfYT7
+J0nidjfbgcpfIysD8ELn/bGtNsYWrTkX8rqB5buBGf+WP7+ChWLwdm1GPtYJJN4s
+ewhN35RpB6EjTdp9jp5ifTfSSBAoHN8yJeeHxU64HHb8nDdBwxmW
+-----END RSA PRIVATE KEY-----
diff --git a/testclient/main.go b/testclient/main.go
index 0a3eb5e..0ed4589 100644
--- a/testclient/main.go
+++ b/testclient/main.go
@@ -16,8 +16,12 @@
 package main
 
 import (
+	"crypto/tls"
+	"crypto/x509"
+	"errors"
 	"flag"
 	"fmt"
+	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
@@ -27,6 +31,7 @@
 	"github.com/maps-booking/utils"
 	"golang.org/x/net/context"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
 
 	mpb "github.com/maps-booking/bookingservice"
 	fpb "github.com/maps-booking/feeds"
@@ -34,6 +39,84 @@
 
 const logFile = "grpc_test_client_log_"
 
+/*
+Below is a string representation of the client certificate and private key.
+This is a self signed cert. To use this cert, maps-booking/certs/root.pem
+must be added to your server.
+
+Viewing the contents of this cert in a human readable format can be achieved using openssl.
+The command and subsequent output are below for your convenience.
+
+	openssl x509 -in .../maps-booking/certs/test_client_cert.pem -inform pem -noout -text
+
+	Certificate:
+			Data:
+					Version: 3 (0x2)
+					Serial Number: 1 (0x1)
+			Signature Algorithm: sha256WithRSAEncryption
+					Issuer: C=US, ST=California, L=Mountain View, O=Internet Widgits Pty Ltd, CN=maps-booking_test-client
+					Validity
+							Not Before: Oct 27 01:53:28 2017 GMT
+							Not After : Oct 25 01:53:28 2027 GMT
+					Subject: C=US, ST=California, O=Internet Widgits Pty Ltd, CN=maps-booking_test-client-cert
+*/
+const clientCert = `-----BEGIN CERTIFICATE-----
+MIIE5DCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxITAf
+BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEhMB8GA1UEAwwYbWFwcy1i
+b29raW5nX3Rlc3QtY2xpZW50MB4XDTE3MTAyNzAxNTMyOFoXDTI3MTAyNTAxNTMy
+OFowbTELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEmMCQGA1UEAwwdbWFwcy1ib29raW5n
+X3Rlc3QtY2xpZW50LWNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQC4SoqntW+syzjdw5an2HkP4ZobuUr/i9eTZ5ub/JpHnKHE/xpAFAI3Pii7b4mv
+ZlbEazRsKJc0LQ+3hblBQdwBxF/QPElH10fD5uhScOOpLz5M9wlX+cDLSrXhDiKM
+9xPY9OlpydIUu/FbU8V+gIsibruCOUB92aMKTkZMwgMRbPIBHF4IsLODm2JQiyFF
+EbJje3mVmQtHyLoWCwWU75wtIgFt7WheTSEw2IpotZTT3nQCqhhrYvUvcwYnj7CD
+/18n7ClA/7nf3+f+1WkZX6GITvXEe3A8Rj0oes/cZlzZO0aVxmosnAQiIt2LWuis
+Lrs//lQEhAl/rRl1ZHoE+LOLAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4
+QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSK
+90Bvc8jEeKuD4ZgUak0QCi5byjAfBgNVHSMEGDAWgBSwnp+00yr82MUrKAIkoVMT
+WtzoozANBgkqhkiG9w0BAQsFAAOCAgEAtJoFY0TVZP4SwnLaX6hBEbv3CvIhL/08
+WSce1e48XKZCWnL+NmxFJu102QSWjXwpF1XsCEOUjhEWsOfmLQ0/z5Pieqsj9cfx
+vfH8Q8BZkC9shykQrO0Hg/Ip+VsU3KSpkpehj0cfUuPuMFZWmPouZGnpyTMXGx/C
+L7SeqBBPa3TlSpONr5IVrI0j4Agfv0+qga7DfQUY6jsxx8uVxl6jbpFBx7UXekTa
+aIP+Wqq0H9x/yWYt+K6yWmb5THAx/pTNOUYGFiFnW56fUap1UgPEF0vNZHHYZycD
+hePsd9jlomD3G38tBmM5qd5CH3OH9S2U2CnC1ifDP6DxxlNHPFCxk6YrISu5fEly
++kcbf3PNKJlqtIL4/GRYsD1e0eVNTMEh5i+qgGnEoErVnlDTM+xolf1DJzSA3uNO
+P6HccNGDcV4TePvQ9KU3ACMtBCNBbLqQm1r7e8U6MzDmAUOXhDvXMv7pdLFNiJvd
+uD/faRnhAt9AsRCz1HjYx7aNz5jpB7uZCrDlDmuFGxG8ieInQMrATUz+E8Yfzh/d
+5k5U0jOgR+IjPKpaq6Z4ejwg4i9vW7EJ8o+Nk1oMB0IMjAJi/UOZl9zRANvcVxO5
+T8dmsxdWt/l68bdjP+jY1vjQ98ebTfo+q1cTNDoO0nDJHOw/NDemxTPgUa1Rs5vK
+5c2Q8YXBTiU=
+-----END CERTIFICATE-----`
+const clientKey = `-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAuEqKp7VvrMs43cOWp9h5D+GaG7lK/4vXk2ebm/yaR5yhxP8a
+QBQCNz4ou2+Jr2ZWxGs0bCiXNC0Pt4W5QUHcAcRf0DxJR9dHw+boUnDjqS8+TPcJ
+V/nAy0q14Q4ijPcT2PTpacnSFLvxW1PFfoCLIm67gjlAfdmjCk5GTMIDEWzyARxe
+CLCzg5tiUIshRRGyY3t5lZkLR8i6FgsFlO+cLSIBbe1oXk0hMNiKaLWU0950AqoY
+a2L1L3MGJ4+wg/9fJ+wpQP+539/n/tVpGV+hiE71xHtwPEY9KHrP3GZc2TtGlcZq
+LJwEIiLdi1rorC67P/5UBIQJf60ZdWR6BPiziwIDAQABAoIBAQCbJy6ayTauzB0h
+HxSMVMR/aVj8NEB+6rXgxN6OMdmVprnPB1KLVg0Tg0J5owrQ36D3FqZ41KeP5swP
+nwZ7eT4HQtPDla3ATO9/b7xyA9a3Ti3uUCDOr1bwEAMV6XePJEjSZEbKqH40tJIb
+aGih+wioQX+dwCOakIsiFwo6fzBkDtsj4V3qVunuZ5TRufUSrXebAMSsE5U+POch
+FznfqsD/vhus5ggbhM/8wG1NgEtO5apkc+KjA/vnWpcpSeWxnBYmQZr0dU9iZJr+
+vCxMKY+kdVfjohbeGQt51TqUkBdLbfUlun8fE1X9hrsA5aYonP82unJ+hWn3Wg60
+fP9vr1gBAoGBAPWcsKoCG6DisgLAjNhAMC2Q7lp2qsM7Y01p4epLX8UxOHRMlpnr
+erNRc4k75hZDp7/rtrO6eb3F+76mlPVbqi/JRRqY5xM8vsDF8KYSAW8XJXZ6AP+Z
+G7sxjJ8QnlT1lAWK+XNxAEk6U3jj6eB+CfGSZJJh3tbjhX69BseE5uQBAoGBAMAV
+6cpOq+F0ZSlh3sljvlDEPY0BaUtlAF5LOX6Vdg7c/zeWJtAAE24hPYwxSi9e4jYx
+eHBM3Xk5yQVGsIbxl/dvgWGY2nbzb1YdbOEEzrVBh7hm8YW3DER+HwNcDpMhoWCf
+O8uD59YNsyvrqD/vb7KpVDWr+yD8ClO7zjLL3ueLAoGAdAZMElOil5LfgptRLYrM
+94mCf2uVaVqxo01EcnieyjlhMNdJQXbS5Miyan7IR3Y4VVpVWXvarMJNFRf+QBXI
+RICwy0q1xgmpFsmqz9iror3tbZVeyV+bkQdsJWwlT38fKKspAda8ytrpua74uZrw
+uZRtPBVNvneGhYNoI3Jt3AECgYB5bGDBdkHI3x8jra57eAXSYHrYK9A3zL0S3lKV
+5j0e4CylItGeIq4lq/WQLYhLsZslztfnhW9rNlAQecMVSptZ2q7a1xkioHf849Tz
+2Wohwi7dLpX2hOPIWEGaihLchyHQRlgyKkvfUAG2/dz5rY3aTpfg5bp1+1072Thb
+e+yISQKBgGgtchLhw26f+wIvDDJx6AExEbbnV5V84riqZR4PpBz4e88xWdtpfYT7
+J0nidjfbgcpfIysD8ELn/bGtNsYWrTkX8rqB5buBGf+WP7+ChWLwdm1GPtYJJN4s
+ewhN35RpB6EjTdp9jp5ifTfSSBAoHN8yJeeHxU64HHb8nDdBwxmW
+-----END RSA PRIVATE KEY-----`
+
 var (
 	serverAddr       = flag.String("server_addr", "example.com:80", "Your grpc server's address in the format of host:port")
 	rpcTimeout       = flag.Duration("rpc_timeout", 30*time.Second, "Number of seconds to wait before abandoning request")
@@ -47,6 +130,9 @@
 	rescheduleFlow   = flag.Bool("rescheduling_test", false, "Whether to test the UpdateBooking endpoint.")
 	availabilityFeed = flag.String("availability_feed", "", "Absolute path to availability feed required for all tests except health. Feeds can be in either json or pb3 format")
 	outputDir        = flag.String("output_dir", "", "Absolute path of dir to dump log file.")
+	enableTLS        = flag.Bool("tls", false, "Whether to enable TLS when using the test client. Please review the README.md before attempting to use this flag.")
+	caFile           = flag.String("ca_file", "", "Absolute path to your server's Certificate Authority root cert. Downloading all roots currently recommended by the Google Internet Authority is a suitable alternative https://pki.google.com/roots.pem")
+	serverName       = flag.String("servername_override", "", "Override FQDN to use. Please see README for additional details")
 )
 
 type counters struct {
@@ -101,10 +187,10 @@
 			return nil, err
 		}
 	}
-	
+
 	now := time.Now().UTC()
 	nowString := fmt.Sprintf("%d-%02d-%02d_%02d-%02d-%02d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
-	outFile := filepath.Join(outPath, fmt.Sprintf("%s%s", logFile, nowString))	
+	outFile := filepath.Join(outPath, fmt.Sprintf("%s%s", logFile, nowString))
 
 	return os.Create(outFile)
 }
@@ -165,6 +251,33 @@
 	os.Exit(0)
 }
 
+func buildGrpcConnection() (*grpc.ClientConn, error) {
+	var opts []grpc.DialOption
+	if *enableTLS {
+		cert, err := tls.X509KeyPair([]byte(clientCert), []byte(clientKey))
+		if err != nil {
+			return nil, err
+		}
+		b, err := ioutil.ReadFile(*caFile)
+		if err != nil {
+			return nil, fmt.Errorf("failed to read root certificates file: %v", err)
+		}
+		cp := x509.NewCertPool()
+		if !cp.AppendCertsFromPEM(b) {
+			return nil, errors.New("failed to parse root certificates, please check your roots file (ca_file flag) and try again")
+		}
+		config := &tls.Config{Certificates: []tls.Certificate{cert}, RootCAs: cp}
+		if *serverName != "" {
+			config.ServerName = *serverName
+		}
+		creds := credentials.NewTLS(config)
+		opts = append(opts, grpc.WithTransportCredentials(creds))
+	} else {
+		opts = append(opts, grpc.WithInsecure())
+	}
+	return grpc.Dial(*serverAddr, opts...)
+}
+
 func main() {
 	flag.Parse()
 	var stats counters
@@ -177,10 +290,9 @@
 	defer f.Close()
 	log.SetOutput(f)
 
-	opts := append([]grpc.DialOption{}, grpc.WithInsecure())
-	conn, err := grpc.Dial(*serverAddr, opts...)
+	conn, err := buildGrpcConnection()
 	if err != nil {
-		log.Fatalf("fail to dial: %v", err)
+		log.Fatalf("failed to dial: %v", err)
 	}
 	defer conn.Close()
 	client := mpb.NewBookingServiceClient(conn)