/* -*- 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 2014 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 "mozpkix/pkixutil.h"

namespace mozilla { namespace pkix {

Result
BackCert::Init()
{
  Result rv;

  // Certificate  ::=  SEQUENCE  {
  //         tbsCertificate       TBSCertificate,
  //         signatureAlgorithm   AlgorithmIdentifier,
  //         signatureValue       BIT STRING  }

  Reader tbsCertificate;

  // The scope of |input| and |certificate| are limited to this block so we
  // don't accidentally confuse them for tbsCertificate later.
  {
    Reader certificate;
    rv = der::ExpectTagAndGetValueAtEnd(der, der::SEQUENCE, certificate);
    if (rv != Success) {
      return rv;
    }
    rv = der::SignedData(certificate, tbsCertificate, signedData);
    if (rv != Success) {
      return rv;
    }
    rv = der::End(certificate);
    if (rv != Success) {
      return rv;
    }
  }

  // TBSCertificate  ::=  SEQUENCE  {
  //      version         [0]  EXPLICIT Version DEFAULT v1,
  //      serialNumber         CertificateSerialNumber,
  //      signature            AlgorithmIdentifier,
  //      issuer               Name,
  //      validity             Validity,
  //      subject              Name,
  //      subjectPublicKeyInfo SubjectPublicKeyInfo,
  //      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
  //                           -- If present, version MUST be v2 or v3
  //      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
  //                           -- If present, version MUST be v2 or v3
  //      extensions      [3]  EXPLICIT Extensions OPTIONAL
  //                           -- If present, version MUST be v3
  //      }
  rv = der::OptionalVersion(tbsCertificate, version);
  if (rv != Success) {
    return rv;
  }
  rv = der::CertificateSerialNumber(tbsCertificate, serialNumber);
  if (rv != Success) {
    return rv;
  }
  rv = der::ExpectTagAndGetValue(tbsCertificate, der::SEQUENCE, signature);
  if (rv != Success) {
    return rv;
  }
  rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE, issuer);
  if (rv != Success) {
    return rv;
  }
  rv = der::ExpectTagAndGetValue(tbsCertificate, der::SEQUENCE, validity);
  if (rv != Success) {
    return rv;
  }
  // TODO(bug XXXXXXX): We rely on the the caller of mozilla::pkix to validate
  // that the name is syntactically valid, if they care. In Gecko we do this
  // implicitly by parsing the certificate into a CERTCertificate object.
  // Instead of relying on the caller to do this, we should do it ourselves.
  rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE, subject);
  if (rv != Success) {
    return rv;
  }
  rv = der::ExpectTagAndGetTLV(tbsCertificate, der::SEQUENCE,
                               subjectPublicKeyInfo);
  if (rv != Success) {
    return rv;
  }

  // According to RFC 5280, all fields below this line are forbidden for
  // certificate versions less than v3.  However, for compatibility reasons,
  // we parse v1/v2 certificates in the same way as v3 certificates.  So if
  // these fields appear in a v1 certificate, they will be used.

  // Ignore issuerUniqueID if present.
  rv = der::SkipOptionalImplicitPrimitiveTag(tbsCertificate, 1);
  if (rv != Success) {
    return rv;
  }

  // Ignore subjectUniqueID if present.
  rv = der::SkipOptionalImplicitPrimitiveTag(tbsCertificate, 2);
  if (rv != Success) {
    return rv;
  }

  static const uint8_t CSC = der::CONTEXT_SPECIFIC | der::CONSTRUCTED;
  rv = der::OptionalExtensions(
         tbsCertificate, CSC | 3,
         [this](Reader& extnID, const Input& extnValue, bool critical,
                /*out*/ bool& understood) {
           return RememberExtension(extnID, extnValue, critical, understood);
         });
  if (rv != Success) {
    return rv;
  }

  // The Netscape Certificate Type extension is an obsolete
  // Netscape-proprietary mechanism that we ignore in favor of the standard
  // extensions. However, some CAs have issued certificates with the Netscape
  // Cert Type extension marked critical. Thus, for compatibility reasons, we
  // "understand" this extension by ignoring it when it is not critical, and
  // by ensuring that the equivalent standardized extensions are present when
  // it is marked critical, based on the assumption that the information in
  // the Netscape Cert Type extension is consistent with the information in
  // the standard extensions.
  //
  // Here is a mapping between the Netscape Cert Type extension and the
  // standard extensions:
  //
  // Netscape Cert Type  |  BasicConstraints.cA  |  Extended Key Usage
  // --------------------+-----------------------+----------------------
  // SSL Server          |  false                |  id_kp_serverAuth
  // SSL Client          |  false                |  id_kp_clientAuth
  // S/MIME Client       |  false                |  id_kp_emailProtection
  // Object Signing      |  false                |  id_kp_codeSigning
  // SSL Server CA       |  true                 |  id_kp_serverAuth
  // SSL Client CA       |  true                 |  id_kp_clientAuth
  // S/MIME CA           |  true                 |  id_kp_emailProtection
  // Object Signing CA   |  true                 |  id_kp_codeSigning
  if (criticalNetscapeCertificateType.GetLength() > 0 &&
      (basicConstraints.GetLength() == 0 || extKeyUsage.GetLength() == 0)) {
    return Result::ERROR_UNKNOWN_CRITICAL_EXTENSION;
  }

  return der::End(tbsCertificate);
}

Result
BackCert::RememberExtension(Reader& extnID, Input extnValue,
                            bool critical, /*out*/ bool& understood)
{
  understood = false;

  // python DottedOIDToCode.py id-ce-keyUsage 2.5.29.15
  static const uint8_t id_ce_keyUsage[] = {
    0x55, 0x1d, 0x0f
  };
  // python DottedOIDToCode.py id-ce-subjectAltName 2.5.29.17
  static const uint8_t id_ce_subjectAltName[] = {
    0x55, 0x1d, 0x11
  };
  // python DottedOIDToCode.py id-ce-basicConstraints 2.5.29.19
  static const uint8_t id_ce_basicConstraints[] = {
    0x55, 0x1d, 0x13
  };
  // python DottedOIDToCode.py id-ce-nameConstraints 2.5.29.30
  static const uint8_t id_ce_nameConstraints[] = {
    0x55, 0x1d, 0x1e
  };
  // python DottedOIDToCode.py id-ce-certificatePolicies 2.5.29.32
  static const uint8_t id_ce_certificatePolicies[] = {
    0x55, 0x1d, 0x20
  };
  // python DottedOIDToCode.py id-ce-policyConstraints 2.5.29.36
  static const uint8_t id_ce_policyConstraints[] = {
    0x55, 0x1d, 0x24
  };
  // python DottedOIDToCode.py id-ce-extKeyUsage 2.5.29.37
  static const uint8_t id_ce_extKeyUsage[] = {
    0x55, 0x1d, 0x25
  };
  // python DottedOIDToCode.py id-ce-inhibitAnyPolicy 2.5.29.54
  static const uint8_t id_ce_inhibitAnyPolicy[] = {
    0x55, 0x1d, 0x36
  };
  // python DottedOIDToCode.py id-pe-authorityInfoAccess 1.3.6.1.5.5.7.1.1
  static const uint8_t id_pe_authorityInfoAccess[] = {
    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
  };
  // python DottedOIDToCode.py id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5
  static const uint8_t id_pkix_ocsp_nocheck[] = {
    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05
  };
  // python DottedOIDToCode.py Netscape-certificate-type 2.16.840.1.113730.1.1
  static const uint8_t Netscape_certificate_type[] = {
    0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01
  };
  // python DottedOIDToCode.py id-pe-tlsfeature 1.3.6.1.5.5.7.1.24
  static const uint8_t id_pe_tlsfeature[] = {
    0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x18
  };
  // python DottedOIDToCode.py id-embeddedSctList 1.3.6.1.4.1.11129.2.4.2
  // See Section 3.3 of RFC 6962.
  static const uint8_t id_embeddedSctList[] = {
    0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x04, 0x02
  };

  Input* out = nullptr;

  // We already enforce the maximum possible constraints for policies so we
  // can safely ignore even critical policy constraint extensions.
  //
  // XXX: Doing it this way won't allow us to detect duplicate
  // policyConstraints extensions, but that's OK because (and only because) we
  // ignore the extension.
  Input dummyPolicyConstraints;

  // We don't need to save the contents of this extension if it is present. We
  // just need to handle its presence (it is essentially ignored right now).
  Input dummyOCSPNocheck;

  // For compatibility reasons, for some extensions we have to allow empty
  // extension values. This would normally interfere with our duplicate
  // extension checking code. However, as long as the extensions we allow to
  // have empty values are also the ones we implicitly allow duplicates of,
  // this will work fine.
  bool emptyValueAllowed = false;

  // RFC says "Conforming CAs MUST mark this extension as non-critical" for
  // both authorityKeyIdentifier and subjectKeyIdentifier, and we do not use
  // them for anything, so we totally ignore them here.

  if (extnID.MatchRest(id_ce_keyUsage)) {
    out = &keyUsage;
  } else if (extnID.MatchRest(id_ce_subjectAltName)) {
    out = &subjectAltName;
  } else if (extnID.MatchRest(id_ce_basicConstraints)) {
    out = &basicConstraints;
  } else if (extnID.MatchRest(id_ce_nameConstraints)) {
    out = &nameConstraints;
  } else if (extnID.MatchRest(id_ce_certificatePolicies)) {
    out = &certificatePolicies;
  } else if (extnID.MatchRest(id_ce_policyConstraints)) {
    out = &dummyPolicyConstraints;
  } else if (extnID.MatchRest(id_ce_extKeyUsage)) {
    out = &extKeyUsage;
  } else if (extnID.MatchRest(id_ce_inhibitAnyPolicy)) {
    out = &inhibitAnyPolicy;
  } else if (extnID.MatchRest(id_pe_authorityInfoAccess)) {
    out = &authorityInfoAccess;
  } else if (extnID.MatchRest(id_pe_tlsfeature)) {
    out = &requiredTLSFeatures;
  } else if (extnID.MatchRest(id_embeddedSctList)) {
    out = &signedCertificateTimestamps;
  } else if (extnID.MatchRest(id_pkix_ocsp_nocheck) && critical) {
    // We need to make sure we don't reject delegated OCSP response signing
    // certificates that contain the id-pkix-ocsp-nocheck extension marked as
    // critical when validating OCSP responses. Without this, an application
    // that implements soft-fail OCSP might ignore a valid Revoked or Unknown
    // response, and an application that implements hard-fail OCSP might fail
    // to connect to a server given a valid Good response.
    out = &dummyOCSPNocheck;
    // We allow this extension to have an empty value.
    // See http://comments.gmane.org/gmane.ietf.x509/30947
    emptyValueAllowed = true;
  } else if (extnID.MatchRest(Netscape_certificate_type) && critical) {
    out = &criticalNetscapeCertificateType;
  }

  if (out) {
    // Don't allow an empty value for any extension we understand. This way, we
    // can test out->GetLength() != 0 or out->Init() to check for duplicates.
    if (extnValue.GetLength() == 0 && !emptyValueAllowed) {
      return Result::ERROR_EXTENSION_VALUE_INVALID;
    }
    if (out->Init(extnValue) != Success) {
      // Duplicate extension
      return Result::ERROR_EXTENSION_VALUE_INVALID;
    }
    understood = true;
  }

  return Success;
}

Result
ExtractSignedCertificateTimestampListFromExtension(Input extnValue,
                                                   Input& sctList)
{
  Reader decodedValue;
  Result rv = der::ExpectTagAndGetValueAtEnd(extnValue, der::OCTET_STRING,
                                             decodedValue);
  if (rv != Success) {
    return rv;
  }
  return decodedValue.SkipToEnd(sctList);
}

} } // namespace mozilla::pkix
