Esempio n. 1
0
    def testPluginReturnsMalformedJson(self, os_get_method, popen_method):
        """Test when plugin returns non-json response."""
        plugin_response = b'abc'
        plugin_response_len = struct.pack('<I', len(plugin_response))

        # process returns sign response in json
        mock_communicate_method = mock.MagicMock()
        mock_communicate_method.return_value = [
            plugin_response_len + plugin_response
        ]

        # process returns with return code of 0
        mock_wait_method = mock.MagicMock()
        mock_wait_method.return_value = 0

        process_mock = mock.MagicMock()
        process_mock.communicate = mock_communicate_method
        process_mock.wait = mock_wait_method

        popen_method.return_value = process_mock

        # Call Authenticate()
        challenge_data = [{
            'key': SIGN_SUCCESS['registered_key'],
            'challenge': SIGN_SUCCESS['challenge']
        }]

        authenticator = customauthenticator.CustomAuthenticator(
            SIGN_SUCCESS['origin'])
        with self.assertRaises(errors.PluginError):
            authenticator.Authenticate(SIGN_SUCCESS['app_id'], challenge_data)
Esempio n. 2
0
    def testEnvVarNotSet(self, os_get_method):
        authenticator = customauthenticator.CustomAuthenticator('testorigin')

        self.assertFalse(authenticator.IsAvailable(),
                         'Should return false when no env var is present')

        # Assert exception if Authenticate is called when no env var is set
        with self.assertRaises(errors.PluginError):
            authenticator.Authenticate('appid', {})
Esempio n. 3
0
    def testPluginReturnsWrongData(self, os_get_method, popen_method):
        """Test when plugin with error 'wrong data'."""
        valid_plugin_response = {
            'type': 'sign_helper_reply',
            'errorDetail': '',
            'code': customauthenticator.SK_SIGNING_PLUGIN_WRONG_DATA,
            'responseData': {
                'appIdHash': SIGN_SUCCESS['app_id_hash_encoded'],
                'challengeHash': SIGN_SUCCESS['challenge_hash_encoded'],
                'keyHandle': SIGN_SUCCESS['key_handle_encoded'],
                'version': SIGN_SUCCESS['u2f_version'],
                'signatureData': SIGN_SUCCESS['signature_data_encoded']
            },
            'data': None
        }
        plugin_response_json = json.dumps(valid_plugin_response).encode()
        plugin_response_len = struct.pack('<I', len(plugin_response_json))

        # process returns sign response in json
        mock_communicate_method = mock.MagicMock()
        mock_communicate_method.return_value = [
            plugin_response_len + plugin_response_json
        ]

        # process returns with return code of 0
        mock_wait_method = mock.MagicMock()
        mock_wait_method.return_value = 0

        process_mock = mock.MagicMock()
        process_mock.communicate = mock_communicate_method
        process_mock.wait = mock_wait_method

        popen_method.return_value = process_mock

        # Call Authenticate()
        challenge_data = [{
            'key': SIGN_SUCCESS['registered_key'],
            'challenge': SIGN_SUCCESS['challenge']
        }]

        authenticator = customauthenticator.CustomAuthenticator(
            SIGN_SUCCESS['origin'])

        with self.assertRaises(errors.U2FError) as cm:
            authenticator.Authenticate(SIGN_SUCCESS['app_id'], challenge_data)
        self.assertEquals(cm.exception.code, errors.U2FError.DEVICE_INELIGIBLE)
Esempio n. 4
0
    def testPluginReturnsIncompleteResponse(self, os_get_method, popen_method):
        """Test when plugin response has missing fields."""
        valid_plugin_response = {
            'type': 'sign_helper_reply',
            'errorDetail': '',
            'responseData': {
                'appIdHash': SIGN_SUCCESS['app_id_hash_encoded'],
                'challengeHash': SIGN_SUCCESS['challenge_hash_encoded'],
                'keyHandle': SIGN_SUCCESS['key_handle_encoded'],
                'version': SIGN_SUCCESS['u2f_version'],
                'signatureData': SIGN_SUCCESS['signature_data_encoded']
            },
            'data': None
        }
        plugin_response_json = json.dumps(valid_plugin_response).encode()
        plugin_response_len = struct.pack('<I', len(plugin_response_json))

        # process returns sign response in json
        mock_communicate_method = mock.MagicMock()
        mock_communicate_method.return_value = [
            plugin_response_len + plugin_response_json
        ]

        # process returns with return code of 0
        mock_wait_method = mock.MagicMock()
        mock_wait_method.return_value = 0

        process_mock = mock.MagicMock()
        process_mock.communicate = mock_communicate_method
        process_mock.wait = mock_wait_method

        popen_method.return_value = process_mock

        # Call Authenticate()
        challenge_data = [{
            'key': SIGN_SUCCESS['registered_key'],
            'challenge': SIGN_SUCCESS['challenge']
        }]

        authenticator = customauthenticator.CustomAuthenticator(
            SIGN_SUCCESS['origin'])
        with self.assertRaises(errors.PluginError):
            authenticator.Authenticate(SIGN_SUCCESS['app_id'], challenge_data)
Esempio n. 5
0
    def testSuccessAuthenticate(self, os_get_method, popen_method):
        """Test plugin Authenticate success."""
        valid_plugin_response = {
            'type': 'sign_helper_reply',
            'code': 0,
            'errorDetail': '',
            'responseData': {
                'appIdHash': SIGN_SUCCESS['app_id_hash_encoded'],
                'challengeHash': SIGN_SUCCESS['challenge_hash_encoded'],
                'keyHandle': SIGN_SUCCESS['key_handle_encoded'],
                'version': SIGN_SUCCESS['u2f_version'],
                'signatureData': SIGN_SUCCESS['signature_data_encoded']
            },
            'data': None
        }
        valid_plugin_response_json = json.dumps(valid_plugin_response).encode()
        valid_plugin_response_len = struct.pack(
            '<I', len(valid_plugin_response_json))

        # process returns sign response in json
        mock_communicate_method = mock.MagicMock()
        mock_communicate_method.return_value = [
            valid_plugin_response_len + valid_plugin_response_json
        ]

        # process returns with return code of 0
        mock_wait_method = mock.MagicMock()
        mock_wait_method.return_value = 0

        process_mock = mock.MagicMock()
        process_mock.communicate = mock_communicate_method
        process_mock.wait = mock_wait_method

        popen_method.return_value = process_mock

        # Call IsAvailable()
        authenticator = customauthenticator.CustomAuthenticator(
            SIGN_SUCCESS['origin'])

        self.assertTrue(authenticator.IsAvailable(),
                        'Should return true if env var is present')
        self.assertTrue(os_get_method.called)

        # Call Authenticate()
        challenge_data = [{
            'key': SIGN_SUCCESS['registered_key'],
            'challenge': SIGN_SUCCESS['challenge']
        }]
        result = authenticator.Authenticate(SIGN_SUCCESS['app_id'],
                                            challenge_data)

        # Validate expected plugin request
        self.assertTrue(popen_method.called)

        self.assertTrue(mock_communicate_method.called)
        communicate_args = mock_communicate_method.call_args[0]
        self.assertEquals(
            len(communicate_args), 1,
            'communicate() should have been called with two args')

        communicate_stdin = communicate_args[0]
        communicate_json_len_le = communicate_stdin[:4]
        communicate_json_len = struct.unpack('<I', communicate_json_len_le)[0]
        communicate_json = communicate_stdin[4:]
        self.assertEquals(
            len(communicate_json), communicate_json_len,
            'communicate() should have been called with correct'
            'length field')

        communicate_dict = json.loads(communicate_json)
        self.assertEquals(communicate_dict.get('type'), 'sign_helper_request')
        self.assertEquals(communicate_dict.get('timeoutSeconds'), 5)
        self.assertEquals(communicate_dict.get('localAlways'), True)
        challenges = communicate_dict.get('signData')

        # Validate Challenge portion of plugin request
        self.assertIsNotNone(challenges)
        self.assertEquals(len(challenges), 1)
        challenge = challenges[0]
        self.assertEquals(challenge.get('appIdHash'),
                          SIGN_SUCCESS['app_id_hash_encoded'])
        self.assertEquals(challenge.get('challengeHash'),
                          SIGN_SUCCESS['challenge_hash_encoded'])
        self.assertEquals(challenge.get('keyHandle'),
                          SIGN_SUCCESS['key_handle_encoded'])
        self.assertEquals(challenge.get('version'),
                          SIGN_SUCCESS['u2f_version'])

        mock_wait_method.assert_called_with()

        # Validate Authenticate() response
        self.assertEquals(result['applicationId'], SIGN_SUCCESS['app_id'])
        self.assertEquals(result['clientData'],
                          SIGN_SUCCESS['client_data_encoded'])
        self.assertEquals(result['keyHandle'],
                          SIGN_SUCCESS['key_handle_encoded'])
        self.assertEquals(result['signatureData'],
                          SIGN_SUCCESS['signature_data_encoded'])
Esempio n. 6
0
def CreateCompositeAuthenticator(origin):
  authenticators = [customauthenticator.CustomAuthenticator(origin),
                    localauthenticator.LocalAuthenticator(origin)]
  return CompositeAuthenticator(authenticators)