fix: support es256 raw format signature (#490)

es256 signature in id_token has raw format, however, cryptography library verification/signing only works for asn1 encoded format. Therefore in verification/signing process, we need to convert between the ans1 encoded format and the raw format.
diff --git a/google/auth/crypt/es256.py b/google/auth/crypt/es256.py
index 5bfd57f..6955efc 100644
--- a/google/auth/crypt/es256.py
+++ b/google/auth/crypt/es256.py
@@ -15,12 +15,15 @@
 """ECDSA (ES256) verifier and signer that use the ``cryptography`` library.
 """
 
+from cryptography import utils
 import cryptography.exceptions
 from cryptography.hazmat import backends
 from cryptography.hazmat.primitives import hashes
 from cryptography.hazmat.primitives import serialization
 from cryptography.hazmat.primitives.asymmetric import ec
 from cryptography.hazmat.primitives.asymmetric import padding
+from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
+from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature
 import cryptography.x509
 import pkg_resources
 
@@ -58,9 +61,17 @@
 
     @_helpers.copy_docstring(base.Verifier)
     def verify(self, message, signature):
+        # First convert (r||s) raw signature to ASN1 encoded signature.
+        sig_bytes = _helpers.to_bytes(signature)
+        if len(sig_bytes) != 64:
+            return False
+        r = utils.int_from_bytes(sig_bytes[:32], byteorder="big")
+        s = utils.int_from_bytes(sig_bytes[32:], byteorder="big")
+        asn1_sig = encode_dss_signature(r, s)
+
         message = _helpers.to_bytes(message)
         try:
-            self._pubkey.verify(signature, message, ec.ECDSA(hashes.SHA256()))
+            self._pubkey.verify(asn1_sig, message, ec.ECDSA(hashes.SHA256()))
             return True
         except (ValueError, cryptography.exceptions.InvalidSignature):
             return False
@@ -118,7 +129,11 @@
     @_helpers.copy_docstring(base.Signer)
     def sign(self, message):
         message = _helpers.to_bytes(message)
-        return self._key.sign(message, ec.ECDSA(hashes.SHA256()))
+        asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256()))
+
+        # Convert ASN1 encoded signature to (r||s) raw signature.
+        (r, s) = decode_dss_signature(asn1_signature)
+        return utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32)
 
     @classmethod
     def from_string(cls, key, key_id=None):
diff --git a/tests/crypt/test_es256.py b/tests/crypt/test_es256.py
index 087ce6e..5bb9050 100644
--- a/tests/crypt/test_es256.py
+++ b/tests/crypt/test_es256.py
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import base64
 import json
 import os
 
@@ -72,6 +73,17 @@
         bad_signature2 = b"a"
         assert not verifier.verify(b"foo", bad_signature2)
 
+    def test_verify_failure_with_wrong_raw_signature(self):
+        to_sign = b"foo"
+
+        # This signature has a wrong "r" value in the "(r,s)" raw signature.
+        wrong_signature = base64.urlsafe_b64decode(
+            b"m7oaRxUDeYqjZ8qiMwo0PZLTMZWKJLFQREpqce1StMIa_yXQQ-C5WgeIRHW7OqlYSDL0XbUrj_uAw9i-QhfOJQ=="
+        )
+
+        verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
+        assert not verifier.verify(to_sign, wrong_signature)
+
     def test_from_string_pub_key(self):
         verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
         assert isinstance(verifier, es256.ES256Verifier)