/*
 *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <time.h>
#include <memory>
#include <utility>

#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/time_utils.h"
#include "test/gtest.h"

namespace rtc {

namespace {

static const char* kTestCertCommonName = "RTCCertificateTest's certificate";

}  // namespace

class RTCCertificateTest : public testing::Test {
 protected:
  scoped_refptr<RTCCertificate> GenerateECDSA() {
    std::unique_ptr<SSLIdentity> identity(
        SSLIdentity::Generate(kTestCertCommonName, KeyParams::ECDSA()));
    RTC_CHECK(identity);
    return RTCCertificate::Create(std::move(identity));
  }

  // Timestamp note:
  //   All timestamps in this unittest are expressed in number of seconds since
  // epoch, 1970-01-01T00:00:00Z (UTC). The RTCCertificate interface uses ms,
  // but only seconds-precision is supported by SSLCertificate. To make the
  // tests clearer we convert everything to seconds since the precision matters
  // when generating certificates or comparing timestamps.
  //   As a result, ExpiresSeconds and HasExpiredSeconds are used instead of
  // RTCCertificate::Expires and ::HasExpired for ms -> s conversion.

  uint64_t NowSeconds() const { return TimeNanos() / kNumNanosecsPerSec; }

  uint64_t ExpiresSeconds(const scoped_refptr<RTCCertificate>& cert) const {
    uint64_t exp_ms = cert->Expires();
    uint64_t exp_s = exp_ms / kNumMillisecsPerSec;
    // Make sure this did not result in loss of precision.
    RTC_CHECK_EQ(exp_s * kNumMillisecsPerSec, exp_ms);
    return exp_s;
  }

  bool HasExpiredSeconds(const scoped_refptr<RTCCertificate>& cert,
                         uint64_t now_s) const {
    return cert->HasExpired(now_s * kNumMillisecsPerSec);
  }

  // An RTC_CHECK ensures that |expires_s| this is in valid range of time_t as
  // is required by SSLIdentityParams. On some 32-bit systems time_t is limited
  // to < 2^31. On such systems this will fail for expiration times of year 2038
  // or later.
  scoped_refptr<RTCCertificate> GenerateCertificateWithExpires(
      uint64_t expires_s) const {
    RTC_CHECK(IsValueInRangeForNumericType<time_t>(expires_s));

    SSLIdentityParams params;
    params.common_name = kTestCertCommonName;
    params.not_before = 0;
    params.not_after = static_cast<time_t>(expires_s);
    // Certificate type does not matter for our purposes, using ECDSA because it
    // is fast to generate.
    params.key_params = KeyParams::ECDSA();

    std::unique_ptr<SSLIdentity> identity(SSLIdentity::GenerateForTest(params));
    return RTCCertificate::Create(std::move(identity));
  }
};

TEST_F(RTCCertificateTest, NewCertificateNotExpired) {
  // Generate a real certificate without specifying the expiration time.
  // Certificate type doesn't matter, using ECDSA because it's fast to generate.
  scoped_refptr<RTCCertificate> certificate = GenerateECDSA();

  uint64_t now = NowSeconds();
  EXPECT_FALSE(HasExpiredSeconds(certificate, now));
  // Even without specifying the expiration time we would expect it to be valid
  // for at least half an hour.
  EXPECT_FALSE(HasExpiredSeconds(certificate, now + 30 * 60));
}

TEST_F(RTCCertificateTest, UsesExpiresAskedFor) {
  uint64_t now = NowSeconds();
  scoped_refptr<RTCCertificate> certificate =
      GenerateCertificateWithExpires(now);
  EXPECT_EQ(now, ExpiresSeconds(certificate));
}

TEST_F(RTCCertificateTest, ExpiresInOneSecond) {
  // Generate a certificate that expires in 1s.
  uint64_t now = NowSeconds();
  scoped_refptr<RTCCertificate> certificate =
      GenerateCertificateWithExpires(now + 1);
  // Now it should not have expired.
  EXPECT_FALSE(HasExpiredSeconds(certificate, now));
  // In 2s it should have expired.
  EXPECT_TRUE(HasExpiredSeconds(certificate, now + 2));
}

TEST_F(RTCCertificateTest, DifferentCertificatesNotEqual) {
  scoped_refptr<RTCCertificate> a = GenerateECDSA();
  scoped_refptr<RTCCertificate> b = GenerateECDSA();
  EXPECT_TRUE(*a != *b);
}

TEST_F(RTCCertificateTest, CloneWithPEMSerialization) {
  scoped_refptr<RTCCertificate> orig = GenerateECDSA();

  // To PEM.
  RTCCertificatePEM orig_pem = orig->ToPEM();
  // Clone from PEM.
  scoped_refptr<RTCCertificate> clone = RTCCertificate::FromPEM(orig_pem);
  EXPECT_TRUE(clone);
  EXPECT_TRUE(*orig == *clone);
  EXPECT_EQ(orig->Expires(), clone->Expires());
}

TEST_F(RTCCertificateTest, FromPEMWithInvalidPEM) {
  RTCCertificatePEM pem("not a valid PEM", "not a valid PEM");
  scoped_refptr<RTCCertificate> certificate = RTCCertificate::FromPEM(pem);
  EXPECT_FALSE(certificate);
}

}  // namespace rtc
