#!/usr/bin/env python

# Copyright 2020 Google, LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""This sample demonstrates how to verify HSM attestations using certificate
bundles obtained from Cloud HSM.

For more information, visit https://cloud.google.com/kms/docs/attest-key.
"""

# [START verify_attestations]
import gzip

from cryptography import exceptions
from cryptography import x509
from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import padding
import pem


def verify(attestation_file, bundle_file):
    """Verifies an attestation using a bundle of certificates.

    Args:
      attestation_file: The name of the attestation file.
      bundle_file: The name of the bundle file containing the certificates
        used to verify the attestation.

    Returns:
      True if at least one of the certificates in bundle_file can verify the
      attestation data and its signature.
    """
    with gzip.open(attestation_file, 'rb') as f:
        # An attestation file consists of a data portion and a 256 byte
        # signature portion concatenated together.
        attestation = f.read()
        # Separate the components.
        data = attestation[:-256]
        signature = attestation[-256:]

        # Verify the attestation with one of the certificates in the bundle
        for cert in pem.parse_file(bundle_file):
            cert_obj = x509.load_pem_x509_certificate(
                str(cert).encode('utf-8'), backends.default_backend())
            try:
                # Check if the data was signed by the private key assosicated
                # with the public key in the certificate. The data should have
                # been signed with PKCS1v15 padding.
                cert_obj.public_key().verify(
                    signature, data, padding.PKCS1v15(),
                    cert_obj.signature_hash_algorithm)
                return True
            except exceptions.InvalidSignature:
                # Certificate bundles contain certificates that will not be
                # able to verify the attestation, so the InvalidSignature
                # errors can be ignored.
                continue
        return False
# [END verify_attestations]

@@ -604,41 +604,28 @@
 his 
-sample demonstrates how to
+application
  verif
-y
+ies
  HSM
@@ -659,17 +659,17 @@
 cate
-%0A
+ 
 bundles
- 
+%0A
 obta
@@ -799,16 +799,32 @@
 ations%5D%0A
+import argparse%0A
 import g
@@ -2710,28 +2710,470 @@
 # %5BEND verify_attestations%5D%0A
+%0A%0Aif __name__ == '__main__':%0A    parser = argparse.ArgumentParser(%0A            description=__doc__)%0A    parser.add_argument('attestation_file', help=%22Name of attestation file.%22)%0A    parser.add_argument('bundle_file', help=%22Name of certificate bundle file.%22)%0A%0A    args = parser.parse_args()%0A%0A    if verify(args.attestation_file, args.bundle_file):%0A        print('Signature verified.')%0A    else:%0A        print('Signature verification failed.')%0A

Add main function to attestation verification script (#3705)