# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import hashlib

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import g2f_utils
from autotest_lib.client.common_lib.cros import tpm_utils
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest

U2F_AUTH_ENFORCE=3

class firmware_Cr50U2fPowerwash(FirmwareTest):
    """
    A test that runs sanity checks for U2F register and authenticate functions,
    and checks that key handles are invalidated after TPM clear.
    """
    version = 1

    def _safe_power_short_press(self):
        """Stop powerd before pressing the power button."""
        # Validating U2F requires pressing the power button. If those power button
        # presses power off the AP, stop powerd before the test to ignore them.
        if self.faft_config.ec_forwards_short_pp_press:
            self.stop_powerd()
        self.servo.power_short_press()

    def parse_g2ftool_output(self, stdout):
        """Parses the key-value pairs returned by g2ftool

        @param stdout: g2ftool output.
        """
        return dict((k, v)
                    for k,v in (line.split('=')
                                for line in stdout.strip().split('\n')))

    def run_once(self, host=None):
        """Tests that U2F keys are invalidated by powerwash."""
        self.client = host

        # Start by clearing TPM to make sure the device is in a known state.
        tpm_utils.ClearTPMOwnerRequest(self.client, wait_for_ready=True)

        # u2fd reads files from the user's home dir, so we need to log in.
        g2f_utils.ChromeOSLogin(self.client);

        # U2fd does will not start normally if the device has not gone
        # through OOBE. Force it to startup.
        cr50_dev = g2f_utils.StartU2fd(self.client)

        # Register requires physical presence.
        self._safe_power_short_press()

        # Register to create a new key handle.
        g2f_reg = g2f_utils.G2fRegister(
            self.client,
            cr50_dev,
            hashlib.sha256('test_challenge').hexdigest(),
            hashlib.sha256('test_application').hexdigest(),
            U2F_AUTH_ENFORCE)

        # Sanity check that we managed to register.
        if not g2f_reg.exit_status == 0:
          raise error.TestError('Register failed.')

        # Extract newly created key handle.
        key_handle = self.parse_g2ftool_output(g2f_reg.stdout)['key_handle']

        # Auth requires physical presence.
        self._safe_power_short_press()

        # Sanity check that we can authenticate with the new key handle.
        g2f_auth = g2f_utils.G2fAuth(
            self.client,
            cr50_dev,
            hashlib.sha256('test_challenge').hexdigest(),
            hashlib.sha256('test_application').hexdigest(),
            key_handle,
            U2F_AUTH_ENFORCE)

        if not g2f_auth.exit_status == 0:
          raise error.TestError('Authenticate failed.')

        # Clear TPM. We should no longer be able to authenticate with the
        # key handle after this.
        tpm_utils.ClearTPMOwnerRequest(self.client, wait_for_ready=True)

        # u2fd reads files from the user's home dir, so we need to log in.
        g2f_utils.ChromeOSLogin(self.client)

        # U2fd does will not start normally if the device has not gone
        # through OOBE. Force it to startup.
        cr50_dev = g2f_utils.StartU2fd(self.client)

        # Check the key handle is no longer valid.
        self._safe_power_short_press()
        g2f_auth_clear = g2f_utils.G2fAuth(
            self.client,
            cr50_dev,
            hashlib.sha256('test_challenge').hexdigest(),
            hashlib.sha256('test_application').hexdigest(),
            key_handle,
            U2F_AUTH_ENFORCE)

        if g2f_auth_clear.exit_status == 0:
          raise error.TestError('Authenticate succeeded; should have failed')


    def cleanup(self):
        """Leave the device in a predictable state"""
        g2f_utils.ChromeOSLogout(self.client)

        super(firmware_Cr50U2fPowerwash, self).cleanup()
