// 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_certificate.h"

#include <CommonCrypto/CommonDigest.h>
#include <Security/Security.h>
#include <vector>

#include <cryptohi.h>
#include <cert.h>
#include <keyhi.h>
#include <nss.h>
#include <pk11pub.h>
#include <prerror.h>
#include <prtime.h>
#include <prtypes.h>
#include <secder.h>
#include <secerr.h>
#include <sslerr.h>

#include "base/logging.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/memory/scoped_ptr.h"
#include "base/pickle.h"
#include "base/time.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
#include "net/base/asn1_util.h"
#include "net/base/cert_status_flags.h"
#include "net/base/cert_verify_result.h"
#include "net/base/ev_root_ca_metadata.h"
#include "net/base/net_errors.h"
#include "net/base/x509_util_ios.h"
#include "net/base/x509_util_nss.h"

using base::mac::ScopedCFTypeRef;

namespace net {
namespace {
// Returns true if a given |cert_handle| is actually a valid X.509 certificate
// handle.
//
// SecCertificateCreateFromData() does not always force the immediate parsing of
// the certificate, and as such, may return a SecCertificateRef for an
// invalid/unparsable certificate. Force parsing to occur to ensure that the
// SecCertificateRef is correct. On later versions where
// SecCertificateCreateFromData() immediately parses, rather than lazily, this
// call is cheap, as the subject is cached.
bool IsValidOSCertHandle(SecCertificateRef cert_handle) {
  ScopedCFTypeRef<CFStringRef> sanity_check(
      SecCertificateCopySubjectSummary(cert_handle));
  return sanity_check != NULL;
}
}  // namespace

void X509Certificate::Initialize() {
  x509_util_ios::NSSCertificate nss_cert(cert_handle_);
  CERTCertificate* cert_handle = nss_cert.cert_handle();
  if (cert_handle) {
    x509_util::ParsePrincipal(&cert_handle->subject, &subject_);
    x509_util::ParsePrincipal(&cert_handle->issuer, &issuer_);
    x509_util::ParseDate(&cert_handle->validity.notBefore, &valid_start_);
    x509_util::ParseDate(&cert_handle->validity.notAfter, &valid_expiry_);
    serial_number_ = x509_util::ParseSerialNumber(cert_handle);
  }
  fingerprint_ = CalculateFingerprint(cert_handle_);
  ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
}

// static
X509Certificate* X509Certificate::CreateSelfSigned(
    crypto::RSAPrivateKey* key,
    const std::string& subject,
    uint32 serial_number,
    base::TimeDelta valid_duration) {
  DCHECK(key);
  DCHECK(!subject.empty());
  NOTIMPLEMENTED();
  return NULL;
}

void X509Certificate::GetSubjectAltName(
    std::vector<std::string>* dns_names,
    std::vector<std::string>* ip_addrs) const {
  x509_util_ios::NSSCertificate nss_cert(cert_handle_);
  CERTCertificate* cert_handle = nss_cert.cert_handle();
  if (!cert_handle) {
    if (dns_names)
      dns_names->clear();
    if (ip_addrs)
      ip_addrs->clear();
    return;
  }
  x509_util::GetSubjectAltName(cert_handle, dns_names, ip_addrs);
}

// static
bool X509Certificate::GetDEREncoded(OSCertHandle cert_handle,
                                    std::string* encoded) {
  ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle));
  if (!der_data)
    return false;
  encoded->assign(reinterpret_cast<const char*>(CFDataGetBytePtr(der_data)),
                  CFDataGetLength(der_data));
  return true;
}

// static
bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
                                   X509Certificate::OSCertHandle b) {
  DCHECK(a && b);
  if (a == b)
    return true;
  if (CFEqual(a, b))
    return true;
  ScopedCFTypeRef<CFDataRef> a_data(SecCertificateCopyData(a));
  ScopedCFTypeRef<CFDataRef> b_data(SecCertificateCopyData(b));
  return a_data && b_data &&
         CFDataGetLength(a_data) == CFDataGetLength(b_data) &&
         memcmp(CFDataGetBytePtr(a_data), CFDataGetBytePtr(b_data),
                CFDataGetLength(a_data)) == 0;
}

// static
X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
    const char* data, int length) {
  ScopedCFTypeRef<CFDataRef> cert_data(CFDataCreateWithBytesNoCopy(
      kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data), length,
      kCFAllocatorNull));
  if (!cert_data)
    return NULL;
  OSCertHandle cert_handle = SecCertificateCreateWithData(NULL, cert_data);
  if (!cert_handle)
    return NULL;
  if (!IsValidOSCertHandle(cert_handle)) {
    CFRelease(cert_handle);
    return NULL;
  }
  return cert_handle;
}

// static
X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
    const char* data,
    int length,
    Format format) {
  return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
}

// static
X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
    OSCertHandle handle) {
  if (!handle)
    return NULL;
  return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
}

// static
void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
  CFRelease(cert_handle);
}

// static
SHA1HashValue X509Certificate::CalculateFingerprint(
    OSCertHandle cert) {
  SHA1HashValue sha1;
  memset(sha1.data, 0, sizeof(sha1.data));

  ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert));
  if (!cert_data)
    return sha1;
  DCHECK(CFDataGetBytePtr(cert_data));
  DCHECK_NE(0, CFDataGetLength(cert_data));
  CC_SHA1(CFDataGetBytePtr(cert_data), CFDataGetLength(cert_data), sha1.data);

  return sha1;
}

// static
SHA1HashValue X509Certificate::CalculateCAFingerprint(
    const OSCertHandles& intermediates) {
  SHA1HashValue sha1;
  memset(sha1.data, 0, sizeof(sha1.data));

  // The CC_SHA(3cc) man page says all CC_SHA1_xxx routines return 1, so
  // we don't check their return values.
  CC_SHA1_CTX sha1_ctx;
  CC_SHA1_Init(&sha1_ctx);
  for (size_t i = 0; i < intermediates.size(); ++i) {
    ScopedCFTypeRef<CFDataRef>
        cert_data(SecCertificateCopyData(intermediates[i]));
    if (!cert_data)
      return sha1;
    CC_SHA1_Update(&sha1_ctx,
                   CFDataGetBytePtr(cert_data),
                   CFDataGetLength(cert_data));
  }
  CC_SHA1_Final(sha1.data, &sha1_ctx);
  return sha1;
}

// static
X509Certificate::OSCertHandle
X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) {
  return x509_util::ReadOSCertHandleFromPickle(pickle_iter);
}

// static
bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
                                                Pickle* pickle) {
  ScopedCFTypeRef<CFDataRef> cert_data(SecCertificateCopyData(cert_handle));
  if (!cert_data)
    return false;

  return pickle->WriteData(
      reinterpret_cast<const char*>(CFDataGetBytePtr(cert_data)),
      CFDataGetLength(cert_data));
}

// static
void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
                                       size_t* size_bits,
                                       PublicKeyType* type) {
  x509_util_ios::NSSCertificate nss_cert(cert_handle);
  x509_util::GetPublicKeyInfo(nss_cert.cert_handle(), size_bits, type);
}

}  // namespace net
