/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This code is made available to you under your choice of the following sets
 * of licensing terms:
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
/* Copyright 2013 Mozilla Contributors
 *
 * 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 "pkixgtest.h"

#include "mozpkix/pkixder.h"
#include "mozpkix/test/pkixtestutil.h"

using namespace mozilla::pkix;
using namespace mozilla::pkix::test;

// Creates a self-signed certificate with the given extension.
static ByteString
CreateCertWithExtensions(const char* subjectCN,
                         const ByteString* extensions)
{
  static long serialNumberValue = 0;
  ++serialNumberValue;
  ByteString serialNumber(CreateEncodedSerialNumber(serialNumberValue));
  EXPECT_FALSE(ENCODING_FAILED(serialNumber));
  ByteString issuerDER(CNToDERName(subjectCN));
  EXPECT_FALSE(ENCODING_FAILED(issuerDER));
  ByteString subjectDER(CNToDERName(subjectCN));
  EXPECT_FALSE(ENCODING_FAILED(subjectDER));
  ScopedTestKeyPair subjectKey(CloneReusedKeyPair());
  return CreateEncodedCertificate(v3, sha256WithRSAEncryption(),
                                  serialNumber, issuerDER,
                                  oneDayBeforeNow, oneDayAfterNow,
                                  subjectDER, *subjectKey, extensions,
                                  *subjectKey,
                                  sha256WithRSAEncryption());
}

// Creates a self-signed certificate with the given extension.
static ByteString
CreateCertWithOneExtension(const char* subjectStr, const ByteString& extension)
{
  const ByteString extensions[] = { extension, ByteString() };
  return CreateCertWithExtensions(subjectStr, extensions);
}

class TrustEverythingTrustDomain final : public DefaultCryptoTrustDomain
{
private:
  Result GetCertTrust(EndEntityOrCA, const CertPolicyId&, Input,
                      /*out*/ TrustLevel& trustLevel) override
  {
    trustLevel = TrustLevel::TrustAnchor;
    return Success;
  }

  Result CheckRevocation(EndEntityOrCA, const CertID&, Time, Duration,
                         /*optional*/ const Input*, /*optional*/ const Input*)
                         override
  {
    return Success;
  }

  Result IsChainValid(const DERArray&, Time, const CertPolicyId&) override
  {
    return Success;
  }
};

// python DottedOIDToCode.py --tlv unknownExtensionOID 1.3.6.1.4.1.13769.666.666.666.1.500.9.3
static const uint8_t tlv_unknownExtensionOID[] = {
  0x06, 0x12, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a, 0x85, 0x1a,
  0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03
};

// python DottedOIDToCode.py --tlv id-pe-authorityInformationAccess 1.3.6.1.5.5.7.1.1
static const uint8_t tlv_id_pe_authorityInformationAccess[] = {
  0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
};

// python DottedOIDToCode.py --tlv wrongExtensionOID 1.3.6.6.1.5.5.7.1.1
// (there is an extra "6" that shouldn't be in this OID)
static const uint8_t tlv_wrongExtensionOID[] = {
  0x06, 0x09, 0x2b, 0x06, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
};

// python DottedOIDToCode.py --tlv id-ce-unknown 2.5.29.55
// (this is a made-up OID for testing "id-ce"-prefixed OIDs that mozilla::pkix
// doesn't handle)
static const uint8_t tlv_id_ce_unknown[] = {
  0x06, 0x03, 0x55, 0x1d, 0x37
};

// python DottedOIDToCode.py --tlv id-ce-inhibitAnyPolicy 2.5.29.54
static const uint8_t tlv_id_ce_inhibitAnyPolicy[] = {
  0x06, 0x03, 0x55, 0x1d, 0x36
};

// python DottedOIDToCode.py --tlv id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5
static const uint8_t tlv_id_pkix_ocsp_nocheck[] = {
  0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05
};

struct ExtensionTestcase
{
  ByteString extension;
  Result expectedResult;
};

::std::ostream& operator<<(::std::ostream& os, const ExtensionTestcase&)
{
  return os << "TODO (bug 1318770)";
}

static const ExtensionTestcase EXTENSION_TESTCASES[] =
{
  // Tests that a non-critical extension not in the id-ce or id-pe arcs (which
  // is thus unknown to us) verifies successfully even if empty (extensions we
  // know about aren't normally allowed to be empty).
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_unknownExtensionOID) +
        TLV(der::OCTET_STRING, ByteString())),
    Success
  },

  // Tests that a critical extension not in the id-ce or id-pe arcs (which is
  // thus unknown to us) is detected and that verification fails with the
  // appropriate error.
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_unknownExtensionOID) +
        Boolean(true) +
        TLV(der::OCTET_STRING, ByteString())),
    Result::ERROR_UNKNOWN_CRITICAL_EXTENSION
  },

  // Tests that a id-pe-authorityInformationAccess critical extension
  // is detected and that verification succeeds.
  // XXX: According to RFC 5280 an AIA that consists of an empty sequence is
  // not legal, but we accept it and that is not what we're testing here.
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_id_pe_authorityInformationAccess) +
        Boolean(true) +
        TLV(der::OCTET_STRING, TLV(der::SEQUENCE, ByteString()))),
    Success
  },

  // Tests that an incorrect OID for id-pe-authorityInformationAccess
  // (when marked critical) is detected and that verification fails.
  // (Until bug 1020993 was fixed, this wrong value was used for
  // id-pe-authorityInformationAccess.)
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_wrongExtensionOID) +
        Boolean(true) +
        TLV(der::OCTET_STRING, ByteString())),
    Result::ERROR_UNKNOWN_CRITICAL_EXTENSION
  },

  // We know about some id-ce extensions (OID arc 2.5.29), but not all of them.
  // Tests that an unknown id-ce extension is detected and that verification
  // fails.
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_id_ce_unknown) +
        Boolean(true) +
        TLV(der::OCTET_STRING, ByteString())),
    Result::ERROR_UNKNOWN_CRITICAL_EXTENSION
  },

  // Tests that a certificate with a known critical id-ce extension (in this
  // case, OID 2.5.29.54, which is id-ce-inhibitAnyPolicy), verifies
  // successfully.
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_id_ce_inhibitAnyPolicy) +
        Boolean(true) +
        TLV(der::OCTET_STRING, Integer(0))),
    Success
  },

  // Tests that a certificate with the id-pkix-ocsp-nocheck extension (marked
  // critical) verifies successfully.
  // RFC 6960:
  //   ext-ocsp-nocheck EXTENSION ::= { SYNTAX NULL IDENTIFIED
  //                                    BY id-pkix-ocsp-nocheck }
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_id_pkix_ocsp_nocheck) +
        Boolean(true) +
        TLV(der::OCTET_STRING, TLV(der::NULLTag, ByteString()))),
    Success
  },

  // Tests that a certificate with another representation of the
  // id-pkix-ocsp-nocheck extension (marked critical) verifies successfully.
  // According to http://comments.gmane.org/gmane.ietf.x509/30947,
  // some code creates certificates where value of the extension is
  // an empty OCTET STRING.
  { TLV(der::SEQUENCE,
        BytesToByteString(tlv_id_pkix_ocsp_nocheck) +
        Boolean(true) +
        TLV(der::OCTET_STRING, ByteString())),
    Success
  },
};

class pkixcert_extension
  : public ::testing::Test
  , public ::testing::WithParamInterface<ExtensionTestcase>
{
protected:
  static TrustEverythingTrustDomain trustDomain;
};

/*static*/ TrustEverythingTrustDomain pkixcert_extension::trustDomain;

TEST_P(pkixcert_extension, ExtensionHandledProperly)
{
  const ExtensionTestcase& testcase(GetParam());
  const char* cn = "Cert Extension Test";
  ByteString cert(CreateCertWithOneExtension(cn, testcase.extension));
  ASSERT_FALSE(ENCODING_FAILED(cert));
  Input certInput;
  ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
  ASSERT_EQ(testcase.expectedResult,
            BuildCertChain(trustDomain, certInput, Now(),
                           EndEntityOrCA::MustBeEndEntity,
                           KeyUsage::noParticularKeyUsageRequired,
                           KeyPurposeId::anyExtendedKeyUsage,
                           CertPolicyId::anyPolicy,
                           nullptr/*stapledOCSPResponse*/));
}

INSTANTIATE_TEST_CASE_P(pkixcert_extension,
                        pkixcert_extension,
                        testing::ValuesIn(EXTENSION_TESTCASES));

// Two subjectAltNames must result in an error.
TEST_F(pkixcert_extension, DuplicateSubjectAltName)
{
  // python DottedOIDToCode.py --tlv id-ce-subjectAltName 2.5.29.17
  static const uint8_t tlv_id_ce_subjectAltName[] = {
    0x06, 0x03, 0x55, 0x1d, 0x11
  };

  ByteString subjectAltName(
    TLV(der::SEQUENCE,
        BytesToByteString(tlv_id_ce_subjectAltName) +
        TLV(der::OCTET_STRING, TLV(der::SEQUENCE, DNSName("example.com")))));
  static const ByteString extensions[] = { subjectAltName, subjectAltName,
                                           ByteString() };
  static const char* certCN = "Cert With Duplicate subjectAltName";
  ByteString cert(CreateCertWithExtensions(certCN, extensions));
  ASSERT_FALSE(ENCODING_FAILED(cert));
  Input certInput;
  ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
  ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID,
            BuildCertChain(trustDomain, certInput, Now(),
                           EndEntityOrCA::MustBeEndEntity,
                           KeyUsage::noParticularKeyUsageRequired,
                           KeyPurposeId::anyExtendedKeyUsage,
                           CertPolicyId::anyPolicy,
                           nullptr/*stapledOCSPResponse*/));
}
