//
// Copyright (C) 2014 The Android Open Source Project
//
// 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.
//

#include <string>

#include <gtest/gtest.h>

#include "trunks/password_authorization_delegate.h"

namespace trunks {

// This test looks at initialization of the delegate with no password.
// It should initailize with a zero length internal password buffer.
TEST(PasswordAuthorizationDelegateTest, NullInitialization) {
  PasswordAuthorizationDelegate delegate("");
  EXPECT_EQ(delegate.password_.size, 0);
}

// This test checks the generation of an authorization structure by the
// delegate. It compared the serialized structure generated by the delegate
// to the expected authorization string.
TEST(PasswordAuthorizationDelegateTest, SerializationTest) {
  std::string expected_auth("\x40\x00\x00\x09"  // session_handle = TPM_RS_PW
                            "\x00\x00"          // nonce = zero length buffer
                            "\x01"     // session_attributes = continueSession
                            "\x00\x06"          // password length
                            "secret",           // password
                            15);
  PasswordAuthorizationDelegate delegate("secret");
  std::string authorization;
  std::string command_hash;
  bool authorization_result = delegate.GetCommandAuthorization(command_hash,
                                                               false, false,
                                                               &authorization);
  EXPECT_EQ(authorization_result, true);
  EXPECT_EQ(authorization.length(), expected_auth.length());
  EXPECT_EQ(expected_auth.compare(authorization), 0);
}

// This test looks at the delegate's ability to parse and check authorization
// responses when the response is well formed.
TEST(PasswordAuthorizationDelegateTest, ParseGoodParams) {
  std::string auth_response("\x00\x00"   // nonceTpm = zero length buffer
                            "\x01"       // session_attributes = continueSession
                            "\x00\x00",  // hmac = zero length buffer
                            5);
  PasswordAuthorizationDelegate delegate("secret");
  std::string response_hash;
  bool authorization_result = delegate.CheckResponseAuthorization(
      response_hash,
      auth_response);
  EXPECT_EQ(authorization_result, true);
}

// This test checks the delegate's ability to correctly identify an incorrect
// authorization response.
TEST(PasswordAuthorizationDelegateTest, ParseBadParams) {
  std::string auth_response("\x00\x00"  // nonceTpm = zero length buffer
                            "\x01"      // session_attributes = continueSession
                            "\x00\x06"  // password length
                            "secret",   // password
                            11);
  PasswordAuthorizationDelegate delegate("secret");
  std::string response_hash;
  bool authorization_result = delegate.CheckResponseAuthorization(
      response_hash,
      auth_response);
  EXPECT_EQ(authorization_result, false);
}

// This test confirms that after encrypting and decrypting a parameter,
// we get the original parameter back.
TEST(PasswordAuthorizationDelegateTest, EncryptDecrypt) {
  PasswordAuthorizationDelegate delegate("secret");
  std::string plaintext_parameter("parameter");
  std::string encrypted_parameter(plaintext_parameter);
  ASSERT_EQ(plaintext_parameter.compare(encrypted_parameter), 0);
  delegate.EncryptCommandParameter(&encrypted_parameter);
  delegate.DecryptResponseParameter(&encrypted_parameter);
  EXPECT_EQ(plaintext_parameter.compare(encrypted_parameter), 0);
}

}  // namespace trunks
