Consolidate service account file loading logic. (#31)

diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index 5db1fa2..69575a1 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -43,12 +43,12 @@
 import base64
 import collections
 import datetime
-import io
 import json
 
 from six.moves import urllib
 
 from google.auth import _helpers
+from google.auth import _service_account_info
 from google.auth import credentials
 from google.auth import crypt
 
@@ -318,8 +318,28 @@
             self._additional_claims = {}
 
     @classmethod
+    def _from_signer_and_info(cls, signer, info, **kwargs):
+        """Creates a Credentials instance from a signer and service account
+        info.
+
+        Args:
+            signer (google.auth.crypt.Signer): The signer used to sign JWTs.
+            info (Mapping[str, str]): The service account info.
+            kwargs: Additional arguments to pass to the constructor.
+
+        Returns:
+            google.auth.jwt.Credentials: The constructed credentials.
+
+        Raises:
+            ValueError: If the info is not in the expected format.
+        """
+        kwargs.setdefault('subject', info['client_email'])
+        return cls(signer, issuer=info['client_email'], **kwargs)
+
+    @classmethod
     def from_service_account_info(cls, info, **kwargs):
-        """Creates a Credentials instance from parsed service account info.
+        """Creates a Credentials instance from a dictionary containing service
+        account info in Google format.
 
         Args:
             info (Mapping[str, str]): The service account info in Google
@@ -332,34 +352,25 @@
         Raises:
             ValueError: If the info is not in the expected format.
         """
-
-        try:
-            email = info['client_email']
-            key_id = info['private_key_id']
-            private_key = info['private_key']
-        except KeyError:
-            raise ValueError(
-                'Service account info was not in the expected format.')
-
-        signer = crypt.Signer.from_string(private_key, key_id)
-
-        kwargs.setdefault('subject', email)
-        return cls(signer, issuer=email, **kwargs)
+        signer = _service_account_info.from_dict(
+            info, require=['client_email'])
+        return cls._from_signer_and_info(signer, info, **kwargs)
 
     @classmethod
     def from_service_account_file(cls, filename, **kwargs):
-        """Creates a Credentials instance from a service account json file.
+        """Creates a Credentials instance from a service account .json file
+        in Google format.
 
         Args:
-            filename (str): The path to the service account json file.
+            filename (str): The path to the service account .json file.
             kwargs: Additional arguments to pass to the constructor.
 
         Returns:
             google.auth.jwt.Credentials: The constructed credentials.
         """
-        with io.open(filename, 'r', encoding='utf-8') as json_file:
-            info = json.load(json_file)
-        return cls.from_service_account_info(info, **kwargs)
+        info, signer = _service_account_info.from_filename(
+            filename, require=['client_email'])
+        return cls._from_signer_and_info(signer, info, **kwargs)
 
     def with_claims(self, issuer=None, subject=None, audience=None,
                     additional_claims=None):