// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/x509_util.h"
#include "net/base/x509_util_nss.h"

#include <cert.h>
#include <cryptohi.h>
#include <nss.h>
#include <pk11pub.h>
#include <prerror.h>
#include <secder.h>
#include <secmod.h>
#include <secport.h>

#include "base/debug/leak_annotations.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/pickle.h"
#include "crypto/ec_private_key.h"
#include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "crypto/scoped_nss_types.h"
#include "crypto/third_party/nss/chromium-nss.h"
#include "net/base/x509_certificate.h"

namespace net {

namespace {

class DomainBoundCertOIDWrapper {
 public:
  static DomainBoundCertOIDWrapper* GetInstance() {
    // Instantiated as a leaky singleton to allow the singleton to be
    // constructed on a worker thead that is not joined when a process
    // shuts down.
    return Singleton<DomainBoundCertOIDWrapper,
                     LeakySingletonTraits<DomainBoundCertOIDWrapper> >::get();
  }

  SECOidTag domain_bound_cert_oid_tag() const {
    return domain_bound_cert_oid_tag_;
  }

 private:
  friend struct DefaultSingletonTraits<DomainBoundCertOIDWrapper>;

  DomainBoundCertOIDWrapper();

  SECOidTag domain_bound_cert_oid_tag_;

  DISALLOW_COPY_AND_ASSIGN(DomainBoundCertOIDWrapper);
};

DomainBoundCertOIDWrapper::DomainBoundCertOIDWrapper()
    : domain_bound_cert_oid_tag_(SEC_OID_UNKNOWN) {
  // 1.3.6.1.4.1.11129.2.1.6
  // (iso.org.dod.internet.private.enterprises.google.googleSecurity.
  //  certificateExtensions.originBoundCertificate)
  static const uint8 kObCertOID[] = {
    0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x06
  };
  SECOidData oid_data;
  memset(&oid_data, 0, sizeof(oid_data));
  oid_data.oid.data = const_cast<uint8*>(kObCertOID);
  oid_data.oid.len = sizeof(kObCertOID);
  oid_data.offset = SEC_OID_UNKNOWN;
  oid_data.desc = "Origin Bound Certificate";
  oid_data.mechanism = CKM_INVALID_MECHANISM;
  oid_data.supportedExtension = SUPPORTED_CERT_EXTENSION;
  domain_bound_cert_oid_tag_ = SECOID_AddEntry(&oid_data);
  if (domain_bound_cert_oid_tag_ == SEC_OID_UNKNOWN)
    LOG(ERROR) << "OB_CERT OID tag creation failed";
}

// Creates a Certificate object that may be passed to the SignCertificate
// method to generate an X509 certificate.
// Returns NULL if an error is encountered in the certificate creation
// process.
// Caller responsible for freeing returned certificate object.
CERTCertificate* CreateCertificate(
    SECKEYPublicKey* public_key,
    const std::string& subject,
    uint32 serial_number,
    base::Time not_valid_before,
    base::Time not_valid_after) {
  // Create info about public key.
  CERTSubjectPublicKeyInfo* spki =
      SECKEY_CreateSubjectPublicKeyInfo(public_key);
  if (!spki)
    return NULL;

  // Create the certificate request.
  CERTName* subject_name =
      CERT_AsciiToName(const_cast<char*>(subject.c_str()));
  CERTCertificateRequest* cert_request =
      CERT_CreateCertificateRequest(subject_name, spki, NULL);
  SECKEY_DestroySubjectPublicKeyInfo(spki);

  if (!cert_request) {
    PRErrorCode prerr = PR_GetError();
    LOG(ERROR) << "Failed to create certificate request: " << prerr;
    CERT_DestroyName(subject_name);
    return NULL;
  }

  CERTValidity* validity = CERT_CreateValidity(
      crypto::BaseTimeToPRTime(not_valid_before),
      crypto::BaseTimeToPRTime(not_valid_after));
  if (!validity) {
    PRErrorCode prerr = PR_GetError();
    LOG(ERROR) << "Failed to create certificate validity object: " << prerr;
    CERT_DestroyName(subject_name);
    CERT_DestroyCertificateRequest(cert_request);
    return NULL;
  }
  CERTCertificate* cert = CERT_CreateCertificate(serial_number, subject_name,
                                                 validity, cert_request);
  if (!cert) {
    PRErrorCode prerr = PR_GetError();
    LOG(ERROR) << "Failed to create certificate: " << prerr;
  }

  // Cleanup for resources used to generate the cert.
  CERT_DestroyName(subject_name);
  CERT_DestroyValidity(validity);
  CERT_DestroyCertificateRequest(cert_request);

  return cert;
}

// Signs a certificate object, with |key| generating a new X509Certificate
// and destroying the passed certificate object (even when NULL is returned).
// The logic of this method references SignCert() in NSS utility certutil:
// http://mxr.mozilla.org/security/ident?i=SignCert.
// Returns true on success or false if an error is encountered in the
// certificate signing process.
bool SignCertificate(
    CERTCertificate* cert,
    SECKEYPrivateKey* key) {
  // |arena| is used to encode the cert.
  PLArenaPool* arena = cert->arena;
  SECOidTag algo_id = SEC_GetSignatureAlgorithmOidTag(key->keyType,
                                                      SEC_OID_SHA1);
  if (algo_id == SEC_OID_UNKNOWN)
    return false;

  SECStatus rv = SECOID_SetAlgorithmID(arena, &cert->signature, algo_id, 0);
  if (rv != SECSuccess)
    return false;

  // Generate a cert of version 3.
  *(cert->version.data) = 2;
  cert->version.len = 1;

  SECItem der = { siBuffer, NULL, 0 };

  // Use ASN1 DER to encode the cert.
  void* encode_result = SEC_ASN1EncodeItem(
      NULL, &der, cert, SEC_ASN1_GET(CERT_CertificateTemplate));
  if (!encode_result)
    return false;

  // Allocate space to contain the signed cert.
  SECItem result = { siBuffer, NULL, 0 };

  // Sign the ASN1 encoded cert and save it to |result|.
  rv = DerSignData(arena, &result, &der, key, algo_id);
  PORT_Free(der.data);
  if (rv != SECSuccess) {
    DLOG(ERROR) << "DerSignData: " << PORT_GetError();
    return false;
  }

  // Save the signed result to the cert.
  cert->derCert = result;

  return true;
}

bool CreateDomainBoundCertInternal(
    SECKEYPublicKey* public_key,
    SECKEYPrivateKey* private_key,
    const std::string& domain,
    uint32 serial_number,
    base::Time not_valid_before,
    base::Time not_valid_after,
    std::string* der_cert) {
  CERTCertificate* cert = CreateCertificate(public_key,
                                            "CN=anonymous.invalid",
                                            serial_number,
                                            not_valid_before,
                                            not_valid_after);

  if (!cert)
    return false;

  // Create opaque handle used to add extensions later.
  void* cert_handle;
  if ((cert_handle = CERT_StartCertExtensions(cert)) == NULL) {
    LOG(ERROR) << "Unable to get opaque handle for adding extensions";
    CERT_DestroyCertificate(cert);
    return false;
  }

  // Create SECItem for IA5String encoding.
  SECItem domain_string_item = {
    siAsciiString,
    (unsigned char*)domain.data(),
    static_cast<unsigned>(domain.size())
  };

  // IA5Encode and arena allocate SECItem
  SECItem* asn1_domain_string = SEC_ASN1EncodeItem(
      cert->arena, NULL, &domain_string_item,
      SEC_ASN1_GET(SEC_IA5StringTemplate));
  if (asn1_domain_string == NULL) {
    LOG(ERROR) << "Unable to get ASN1 encoding for domain in domain_bound_cert"
                  " extension";
    CERT_DestroyCertificate(cert);
    return false;
  }

  // Add the extension to the opaque handle
  if (CERT_AddExtension(
      cert_handle,
      DomainBoundCertOIDWrapper::GetInstance()->domain_bound_cert_oid_tag(),
      asn1_domain_string, PR_TRUE, PR_TRUE) != SECSuccess){
    LOG(ERROR) << "Unable to add domain bound cert extension to opaque handle";
    CERT_DestroyCertificate(cert);
    return false;
  }

  // Copy extension into x509 cert
  if (CERT_FinishExtensions(cert_handle) != SECSuccess){
    LOG(ERROR) << "Unable to copy extension to X509 cert";
    CERT_DestroyCertificate(cert);
    return false;
  }

  if (!SignCertificate(cert, private_key)) {
    CERT_DestroyCertificate(cert);
    return false;
  }

  DCHECK(cert->derCert.len);
  // XXX copied from X509Certificate::GetDEREncoded
  der_cert->clear();
  der_cert->append(reinterpret_cast<char*>(cert->derCert.data),
                   cert->derCert.len);
  CERT_DestroyCertificate(cert);
  return true;
}

#if defined(USE_NSS) || defined(OS_IOS)
// Callback for CERT_DecodeCertPackage(), used in
// CreateOSCertHandlesFromBytes().
SECStatus PR_CALLBACK CollectCertsCallback(void* arg,
                                           SECItem** certs,
                                           int num_certs) {
  X509Certificate::OSCertHandles* results =
      reinterpret_cast<X509Certificate::OSCertHandles*>(arg);

  for (int i = 0; i < num_certs; ++i) {
    X509Certificate::OSCertHandle handle =
        X509Certificate::CreateOSCertHandleFromBytes(
            reinterpret_cast<char*>(certs[i]->data), certs[i]->len);
    if (handle)
      results->push_back(handle);
  }

  return SECSuccess;
}
#endif  // defined(USE_NSS) || defined(OS_IOS)

}  // namespace

namespace x509_util {

CERTCertificate* CreateSelfSignedCert(
    SECKEYPublicKey* public_key,
    SECKEYPrivateKey* private_key,
    const std::string& subject,
    uint32 serial_number,
    base::Time not_valid_before,
    base::Time not_valid_after) {
  CERTCertificate* cert = CreateCertificate(public_key,
                                            subject,
                                            serial_number,
                                            not_valid_before,
                                            not_valid_after);
  if (!cert)
    return NULL;

  if (!SignCertificate(cert, private_key)) {
    CERT_DestroyCertificate(cert);
    return NULL;
  }

  return cert;
}

bool IsSupportedValidityRange(base::Time not_valid_before,
                              base::Time not_valid_after) {
  CERTValidity* validity = CERT_CreateValidity(
      crypto::BaseTimeToPRTime(not_valid_before),
      crypto::BaseTimeToPRTime(not_valid_after));

  if (!validity)
    return false;

  CERT_DestroyValidity(validity);
  return true;
}

bool CreateDomainBoundCertEC(
    crypto::ECPrivateKey* key,
    const std::string& domain,
    uint32 serial_number,
    base::Time not_valid_before,
    base::Time not_valid_after,
    std::string* der_cert) {
  DCHECK(key);
  return CreateDomainBoundCertInternal(key->public_key(),
                                       key->key(),
                                       domain,
                                       serial_number,
                                       not_valid_before,
                                       not_valid_after,
                                       der_cert);
}

#if defined(USE_NSS) || defined(OS_IOS)
void ParsePrincipal(CERTName* name, CertPrincipal* principal) {
  typedef char* (*CERTGetNameFunc)(CERTName* name);

  // TODO(jcampan): add business_category and serial_number.
  // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and
  // CERT_GetDomainComponentName functions, but they return only the most
  // general (the first) RDN.  NSS doesn't have a function for the street
  // address.
  static const SECOidTag kOIDs[] = {
    SEC_OID_AVA_STREET_ADDRESS,
    SEC_OID_AVA_ORGANIZATION_NAME,
    SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
    SEC_OID_AVA_DC };

  std::vector<std::string>* values[] = {
    &principal->street_addresses,
    &principal->organization_names,
    &principal->organization_unit_names,
    &principal->domain_components };
  DCHECK_EQ(arraysize(kOIDs), arraysize(values));

  CERTRDN** rdns = name->rdns;
  for (size_t rdn = 0; rdns[rdn]; ++rdn) {
    CERTAVA** avas = rdns[rdn]->avas;
    for (size_t pair = 0; avas[pair] != 0; ++pair) {
      SECOidTag tag = CERT_GetAVATag(avas[pair]);
      for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) {
        if (kOIDs[oid] == tag) {
          SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value);
          if (!decode_item)
            break;
          // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote.
          std::string value(reinterpret_cast<char*>(decode_item->data),
                            decode_item->len);
          values[oid]->push_back(value);
          SECITEM_FreeItem(decode_item, PR_TRUE);
          break;
        }
      }
    }
  }

  // Get CN, L, S, and C.
  CERTGetNameFunc get_name_funcs[4] = {
    CERT_GetCommonName, CERT_GetLocalityName,
    CERT_GetStateName, CERT_GetCountryName };
  std::string* single_values[4] = {
    &principal->common_name, &principal->locality_name,
    &principal->state_or_province_name, &principal->country_name };
  for (size_t i = 0; i < arraysize(get_name_funcs); ++i) {
    char* value = get_name_funcs[i](name);
    if (value) {
      single_values[i]->assign(value);
      PORT_Free(value);
    }
  }
}

void ParseDate(const SECItem* der_date, base::Time* result) {
  PRTime prtime;
  SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date);
  DCHECK_EQ(SECSuccess, rv);
  *result = crypto::PRTimeToBaseTime(prtime);
}

std::string ParseSerialNumber(const CERTCertificate* certificate) {
  return std::string(reinterpret_cast<char*>(certificate->serialNumber.data),
                     certificate->serialNumber.len);
}

void GetSubjectAltName(CERTCertificate* cert_handle,
                       std::vector<std::string>* dns_names,
                       std::vector<std::string>* ip_addrs) {
  if (dns_names)
    dns_names->clear();
  if (ip_addrs)
    ip_addrs->clear();

  SECItem alt_name;
  SECStatus rv = CERT_FindCertExtension(cert_handle,
                                        SEC_OID_X509_SUBJECT_ALT_NAME,
                                        &alt_name);
  if (rv != SECSuccess)
    return;

  PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  DCHECK(arena != NULL);

  CERTGeneralName* alt_name_list;
  alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name);
  SECITEM_FreeItem(&alt_name, PR_FALSE);

  CERTGeneralName* name = alt_name_list;
  while (name) {
    // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs
    // respectively, both of which can be byte copied from
    // SECItemType::data into the appropriate output vector.
    if (dns_names && name->type == certDNSName) {
      dns_names->push_back(std::string(
          reinterpret_cast<char*>(name->name.other.data),
          name->name.other.len));
    } else if (ip_addrs && name->type == certIPAddress) {
      ip_addrs->push_back(std::string(
          reinterpret_cast<char*>(name->name.other.data),
          name->name.other.len));
    }
    name = CERT_GetNextGeneralName(name);
    if (name == alt_name_list)
      break;
  }
  PORT_FreeArena(arena, PR_FALSE);
}

X509Certificate::OSCertHandles CreateOSCertHandlesFromBytes(
    const char* data,
    int length,
    X509Certificate::Format format) {
  X509Certificate::OSCertHandles results;
  if (length < 0)
    return results;

  crypto::EnsureNSSInit();

  if (!NSS_IsInitialized())
    return results;

  switch (format) {
    case X509Certificate::FORMAT_SINGLE_CERTIFICATE: {
      X509Certificate::OSCertHandle handle =
          X509Certificate::CreateOSCertHandleFromBytes(data, length);
      if (handle)
        results.push_back(handle);
      break;
    }
    case X509Certificate::FORMAT_PKCS7: {
      // Make a copy since CERT_DecodeCertPackage may modify it
      std::vector<char> data_copy(data, data + length);

      SECStatus result = CERT_DecodeCertPackage(&data_copy[0],
          length, CollectCertsCallback, &results);
      if (result != SECSuccess)
        results.clear();
      break;
    }
    default:
      NOTREACHED() << "Certificate format " << format << " unimplemented";
      break;
  }

  return results;
}

X509Certificate::OSCertHandle ReadOSCertHandleFromPickle(
    PickleIterator* pickle_iter) {
  const char* data;
  int length;
  if (!pickle_iter->ReadData(&data, &length))
    return NULL;

  return X509Certificate::CreateOSCertHandleFromBytes(data, length);
}

void GetPublicKeyInfo(CERTCertificate* handle,
                      size_t* size_bits,
                      X509Certificate::PublicKeyType* type) {
  // Since we might fail, set the output parameters to default values first.
  *type = X509Certificate::kPublicKeyTypeUnknown;
  *size_bits = 0;

  crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(handle));
  if (!key.get())
    return;

  *size_bits = SECKEY_PublicKeyStrengthInBits(key.get());

  switch (key->keyType) {
    case rsaKey:
      *type = X509Certificate::kPublicKeyTypeRSA;
      break;
    case dsaKey:
      *type = X509Certificate::kPublicKeyTypeDSA;
      break;
    case dhKey:
      *type = X509Certificate::kPublicKeyTypeDH;
      break;
    case ecKey:
      *type = X509Certificate::kPublicKeyTypeECDSA;
      break;
    default:
      *type = X509Certificate::kPublicKeyTypeUnknown;
      *size_bits = 0;
      break;
  }
}
#endif  // defined(USE_NSS) || defined(OS_IOS)

} // namespace x509_util

} // namespace net
