/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Netscape security libraries.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Ian McGreer <mcgreer@netscape.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "net/third_party/mozilla_security_manager/nsPKCS12Blob.h"

#include <pk11pub.h>
#include <pkcs12.h>
#include <p12plcy.h>
#include <secerr.h>

#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "crypto/nss_util_internal.h"
#include "net/base/net_errors.h"
#include "net/cert/x509_certificate.h"

namespace mozilla_security_manager {

namespace {

// unicodeToItem
//
// For the NSS PKCS#12 library, must convert PRUnichars (shorts) to
// a buffer of octets.  Must handle byte order correctly.
// TODO: Is there a Mozilla way to do this?  In the string lib?
void unicodeToItem(const PRUnichar *uni, SECItem *item)
{
  int len = 0;
  while (uni[len++] != 0);
  SECITEM_AllocItem(NULL, item, sizeof(PRUnichar) * len);
#ifdef IS_LITTLE_ENDIAN
  int i = 0;
  for (i=0; i<len; i++) {
    item->data[2*i  ] = (unsigned char )(uni[i] << 8);
    item->data[2*i+1] = (unsigned char )(uni[i]);
  }
#else
  memcpy(item->data, uni, item->len);
#endif
}

// write_export_data
// write bytes to the exported PKCS#12 data buffer
void write_export_data(void* arg, const char* buf, unsigned long len) {
  std::string* dest = reinterpret_cast<std::string*>(arg);
  dest->append(buf, len);
}

// nickname_collision
// what to do when the nickname collides with one already in the db.
// Based on P12U_NicknameCollisionCallback from nss/cmd/pk12util/pk12util.c
SECItem* PR_CALLBACK
nickname_collision(SECItem *old_nick, PRBool *cancel, void *wincx)
{
  char           *nick     = NULL;
  SECItem        *ret_nick = NULL;
  CERTCertificate* cert    = (CERTCertificate*)wincx;

  if (!cancel || !cert) {
    // pk12util calls this error user cancelled?
    return NULL;
  }

  if (!old_nick)
    VLOG(1) << "no nickname for cert in PKCS12 file.";

  nick = CERT_MakeCANickname(cert);
  if (!nick) {
    return NULL;
  }

  if(old_nick && old_nick->data && old_nick->len &&
     PORT_Strlen(nick) == old_nick->len &&
     !PORT_Strncmp((char *)old_nick->data, nick, old_nick->len)) {
    PORT_Free(nick);
    PORT_SetError(SEC_ERROR_IO);
    return NULL;
  }

  VLOG(1) << "using nickname " << nick;
  ret_nick = PORT_ZNew(SECItem);
  if(ret_nick == NULL) {
    PORT_Free(nick);
    return NULL;
  }

  ret_nick->data = (unsigned char *)nick;
  ret_nick->len = PORT_Strlen(nick);

  return ret_nick;
}

// pip_ucs2_ascii_conversion_fn
// required to be set by NSS (to do PKCS#12), but since we've already got
// unicode make this a no-op.
PRBool
pip_ucs2_ascii_conversion_fn(PRBool toUnicode,
                             unsigned char *inBuf,
                             unsigned int inBufLen,
                             unsigned char *outBuf,
                             unsigned int maxOutBufLen,
                             unsigned int *outBufLen,
                             PRBool swapBytes)
{
  CHECK_GE(maxOutBufLen, inBufLen);
  // do a no-op, since I've already got Unicode.  Hah!
  *outBufLen = inBufLen;
  memcpy(outBuf, inBuf, inBufLen);
  return PR_TRUE;
}

// Based on nsPKCS12Blob::ImportFromFileHelper.
int
nsPKCS12Blob_ImportHelper(const char* pkcs12_data,
                          size_t pkcs12_len,
                          const base::string16& password,
                          bool is_extractable,
                          bool try_zero_length_secitem,
                          PK11SlotInfo *slot,
                          net::CertificateList* imported_certs)
{
  DCHECK(pkcs12_data);
  DCHECK(slot);
  int import_result = net::ERR_PKCS12_IMPORT_FAILED;
  SECStatus srv = SECSuccess;
  SEC_PKCS12DecoderContext *dcx = NULL;
  SECItem unicodePw;
  SECItem attribute_value;
  CK_BBOOL attribute_data = CK_FALSE;
  const SEC_PKCS12DecoderItem* decoder_item = NULL;

  unicodePw.type = siBuffer;
  unicodePw.len = 0;
  unicodePw.data = NULL;
  if (!try_zero_length_secitem) {
    unicodeToItem(password.c_str(), &unicodePw);
  }

  // Initialize the decoder
  dcx = SEC_PKCS12DecoderStart(&unicodePw, slot,
                               // wincx
                               NULL,
                               // dOpen, dClose, dRead, dWrite, dArg: NULL
                               // specifies default impl using memory buffer.
                               NULL, NULL, NULL, NULL, NULL);
  if (!dcx) {
    srv = SECFailure;
    goto finish;
  }
  // feed input to the decoder
  srv = SEC_PKCS12DecoderUpdate(dcx,
                                (unsigned char*)pkcs12_data,
                                pkcs12_len);
  if (srv) goto finish;
  // verify the blob
  srv = SEC_PKCS12DecoderVerify(dcx);
  if (srv) goto finish;
  // validate bags
  srv = SEC_PKCS12DecoderValidateBags(dcx, nickname_collision);
  if (srv) goto finish;
  // import certificate and key
  srv = SEC_PKCS12DecoderImportBags(dcx);
  if (srv) goto finish;

  attribute_value.data = &attribute_data;
  attribute_value.len = sizeof(attribute_data);

  srv = SEC_PKCS12DecoderIterateInit(dcx);
  if (srv) goto finish;

  if (imported_certs)
    imported_certs->clear();

  // Collect the list of decoded certificates, and mark private keys
  // non-extractable if needed.
  while (SEC_PKCS12DecoderIterateNext(dcx, &decoder_item) == SECSuccess) {
    if (decoder_item->type != SEC_OID_PKCS12_V1_CERT_BAG_ID)
      continue;

    CERTCertificate* cert = PK11_FindCertFromDERCertItem(
        slot, decoder_item->der,
        NULL);  // wincx
    if (!cert) {
      LOG(ERROR) << "Could not grab a handle to the certificate in the slot "
                 << "from the corresponding PKCS#12 DER certificate.";
      continue;
    }

    // Add the cert to the list
    if (imported_certs) {
      // Empty list of intermediates.
      net::X509Certificate::OSCertHandles intermediates;
      scoped_refptr<net::X509Certificate> x509_cert =
          net::X509Certificate::CreateFromHandle(cert, intermediates);
      if (x509_cert)
        imported_certs->push_back(std::move(x509_cert));
    }

    // Once we have determined that the imported certificate has an
    // associated private key too, only then can we mark the key as
    // non-extractable.
    if (!decoder_item->hasKey) {
      CERT_DestroyCertificate(cert);
      continue;
    }

    // Iterate through all the imported PKCS12 items and mark any accompanying
    // private keys as non-extractable.
    if (!is_extractable) {
      SECKEYPrivateKey* privKey = PK11_FindPrivateKeyFromCert(slot, cert,
                                                              NULL);  // wincx
      if (privKey) {
        // Mark the private key as non-extractable.
        srv = PK11_WriteRawAttribute(PK11_TypePrivKey, privKey, CKA_EXTRACTABLE,
                                     &attribute_value);
        SECKEY_DestroyPrivateKey(privKey);
        if (srv) {
          LOG(ERROR) << "Could not set CKA_EXTRACTABLE attribute on private "
                     << "key.";
          CERT_DestroyCertificate(cert);
          break;
        }
      }
    }
    CERT_DestroyCertificate(cert);
    if (srv) goto finish;
  }
  import_result = net::OK;
finish:
  // If srv != SECSuccess, NSS probably set a specific error code.
  // We should use that error code instead of inventing a new one
  // for every error possible.
  if (srv != SECSuccess) {
    int error = PORT_GetError();
    LOG(ERROR) << "PKCS#12 import failed with error " << error;
    switch (error) {
      case SEC_ERROR_BAD_PASSWORD:
      case SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT:
        import_result = net::ERR_PKCS12_IMPORT_BAD_PASSWORD;
        break;
      case SEC_ERROR_PKCS12_INVALID_MAC:
        import_result = net::ERR_PKCS12_IMPORT_INVALID_MAC;
        break;
      case SEC_ERROR_BAD_DER:
      case SEC_ERROR_PKCS12_DECODING_PFX:
      case SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE:
        import_result = net::ERR_PKCS12_IMPORT_INVALID_FILE;
        break;
      case SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM:
      case SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE:
      case SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM:
      case SEC_ERROR_PKCS12_UNSUPPORTED_VERSION:
        import_result = net::ERR_PKCS12_IMPORT_UNSUPPORTED;
        break;
      default:
        import_result = net::ERR_PKCS12_IMPORT_FAILED;
        break;
    }
  }
  // Finish the decoder
  if (dcx)
    SEC_PKCS12DecoderFinish(dcx);
  SECITEM_ZfreeItem(&unicodePw, PR_FALSE);
  return import_result;
}


// Attempt to read the CKA_EXTRACTABLE attribute on a private key inside
// a token. On success, store the attribute in |extractable| and return
// SECSuccess.
SECStatus
isExtractable(SECKEYPrivateKey *privKey, PRBool *extractable)
{
  SECItem value;
  SECStatus rv;

  rv=PK11_ReadRawAttribute(PK11_TypePrivKey, privKey, CKA_EXTRACTABLE, &value);
  if (rv != SECSuccess)
    return rv;

  if ((value.len == 1) && (value.data != NULL))
    *extractable = !!(*(CK_BBOOL*)value.data);
  else
    rv = SECFailure;
  SECITEM_FreeItem(&value, PR_FALSE);
  return rv;
}

class PKCS12InitSingleton {
 public:
  // From the PKCS#12 section of nsNSSComponent::InitializeNSS in
  // nsNSSComponent.cpp.
  PKCS12InitSingleton() {
    // Enable ciphers for PKCS#12
    SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
    SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
    SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
    SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
    SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
    SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
    SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);

    // Set no-op ascii-ucs2 conversion function to work around weird NSS
    // interface.  Thankfully, PKCS12 appears to be the only thing in NSS that
    // uses PORT_UCS2_ASCIIConversion, so this doesn't break anything else.
    PORT_SetUCS2_ASCIIConversionFunction(pip_ucs2_ascii_conversion_fn);
  }
};

// Leaky so it can be initialized on worker threads and because there is no
// cleanup necessary.
static base::LazyInstance<PKCS12InitSingleton>::Leaky g_pkcs12_init_singleton =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

void EnsurePKCS12Init() {
  g_pkcs12_init_singleton.Get();
}

// Based on nsPKCS12Blob::ImportFromFile.
int nsPKCS12Blob_Import(PK11SlotInfo* slot,
                        const char* pkcs12_data,
                        size_t pkcs12_len,
                        const base::string16& password,
                        bool is_extractable,
                        net::CertificateList* imported_certs) {

  int rv = nsPKCS12Blob_ImportHelper(pkcs12_data, pkcs12_len, password,
                                     is_extractable, false, slot,
                                     imported_certs);

  // When the user entered a zero length password:
  //   An empty password should be represented as an empty
  //   string (a SECItem that contains a single terminating
  //   NULL UTF16 character), but some applications use a
  //   zero length SECItem.
  //   We try both variations, zero length item and empty string,
  //   without giving a user prompt when trying the different empty password
  //   flavors.
  if ((rv == net::ERR_PKCS12_IMPORT_BAD_PASSWORD ||
       rv == net::ERR_PKCS12_IMPORT_INVALID_MAC) &&
      password.empty()) {
    rv = nsPKCS12Blob_ImportHelper(pkcs12_data, pkcs12_len, password,
                                   is_extractable, true, slot, imported_certs);
  }
  return rv;
}

// Based on nsPKCS12Blob::ExportToFile
//
// Having already loaded the certs, form them into a blob (loading the keys
// also), encode the blob, and stuff it into the file.
//
// TODO: handle slots correctly
//       mirror "slotToUse" behavior from PSM 1.x
//       verify the cert array to start off with?
//       set appropriate error codes
int
nsPKCS12Blob_Export(std::string* output,
                    const net::CertificateList& certs,
                    const base::string16& password)
{
  int return_count = 0;
  SECStatus srv = SECSuccess;
  SEC_PKCS12ExportContext *ecx = NULL;
  SEC_PKCS12SafeInfo *certSafe = NULL, *keySafe = NULL;
  SECItem unicodePw;
  unicodePw.type = siBuffer;
  unicodePw.len = 0;
  unicodePw.data = NULL;

  int numCertsExported = 0;

  // get file password (unicode)
  unicodeToItem(password.c_str(), &unicodePw);

  // what about slotToUse in psm 1.x ???
  // create export context
  ecx = SEC_PKCS12CreateExportContext(NULL, NULL, NULL /*slot*/, NULL);
  if (!ecx) {
    srv = SECFailure;
    goto finish;
  }
  // add password integrity
  srv = SEC_PKCS12AddPasswordIntegrity(ecx, &unicodePw, SEC_OID_SHA1);
  if (srv) goto finish;

  for (size_t i=0; i<certs.size(); i++) {
    DCHECK(certs[i].get());
    CERTCertificate* nssCert = certs[i]->os_cert_handle();
    DCHECK(nssCert);

    // We only allow certificate and private key extraction if the corresponding
    // CKA_EXTRACTABLE private key attribute is set to CK_TRUE. Most hardware
    // tokens including smartcards enforce this behavior. An internal (soft)
    // token may ignore this attribute (and hence still be able to export) but
    // we still refuse to attempt an export.
    // In addition, some tokens may not support this attribute, in which case
    // we still attempt the export and let the token implementation dictate
    // the export behavior.
    if (nssCert->slot) {
      SECKEYPrivateKey *privKey=PK11_FindKeyByDERCert(nssCert->slot,
                                                      nssCert,
                                                      NULL);  // wincx
       if (privKey) {
        PRBool privKeyIsExtractable = PR_FALSE;
        SECStatus rv = isExtractable(privKey, &privKeyIsExtractable);
        SECKEY_DestroyPrivateKey(privKey);

        if (rv == SECSuccess && !privKeyIsExtractable) {
          LOG(ERROR) << "Private key is not extractable";
          continue;
        }
      }
    }

    // XXX this is why, to verify the slot is the same
    // PK11_FindObjectForCert(nssCert, NULL, slot);
    // create the cert and key safes
    keySafe = SEC_PKCS12CreateUnencryptedSafe(ecx);
    if (!SEC_PKCS12IsEncryptionAllowed() || PK11_IsFIPS()) {
      certSafe = keySafe;
    } else {
      certSafe = SEC_PKCS12CreatePasswordPrivSafe(ecx, &unicodePw,
                           SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
    }
    if (!certSafe || !keySafe) {
      LOG(ERROR) << "!certSafe || !keySafe " << certSafe << " " << keySafe;
      srv = SECFailure;
      goto finish;
    }
    // add the cert and key to the blob
    srv = SEC_PKCS12AddCertAndKey(ecx, certSafe, NULL, nssCert,
                                  CERT_GetDefaultCertDB(),
                                  keySafe, NULL, PR_TRUE, &unicodePw,
                      SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC);
    if (srv) goto finish;
    ++numCertsExported;
  }

  if (!numCertsExported) goto finish;

  // encode and write
  srv = SEC_PKCS12Encode(ecx, write_export_data, output);
  if (srv) goto finish;
  return_count = numCertsExported;
finish:
  if (srv)
    LOG(ERROR) << "PKCS#12 export failed with error " << PORT_GetError();
  if (ecx)
    SEC_PKCS12DestroyExportContext(ecx);
  SECITEM_ZfreeItem(&unicodePw, PR_FALSE);
  return return_count;
}

}  // namespace mozilla_security_manager
