Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes
nsPKCS12Blob Class Reference

#include <nsPKCS12Blob.h>

Collaboration diagram for nsPKCS12Blob:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsPKCS12Blob ()
virtual ~nsPKCS12Blob ()
nsresult SetToken (nsIPK11Token *token)
nsresult ImportFromFile (nsILocalFile *file)
nsresult ExportToFile (nsILocalFile *file, nsIX509Cert **certs, int numCerts)

Private Types

enum  RetryReason { rr_do_not_retry, rr_bad_password, rr_auto_retry_empty_password_flavors }
enum  ImportMode { im_standard_prompt, im_try_zero_length_secitem }

Private Member Functions

nsresult getPKCS12FilePassword (SECItem *)
nsresult newPKCS12FilePassword (SECItem *)
nsresult inputToDecoder (SEC_PKCS12DecoderContext *, nsILocalFile *)
void unicodeToItem (const PRUnichar *, SECItem *)
PRBool handleError (int myerr=0)
nsresult ImportFromFileHelper (nsILocalFile *file, ImportMode aImportMode, RetryReason &aWantRetry)

Static Private Member Functions

static SECStatus PR_CALLBACK digest_open (void *, PRBool)
static SECStatus PR_CALLBACK digest_close (void *, PRBool)
static int PR_CALLBACK digest_read (void *, unsigned char *, unsigned long)
static int PR_CALLBACK digest_write (void *, unsigned char *, unsigned long)
static SECItem *PR_CALLBACK nickname_collision (SECItem *, PRBool *, void *)
static void PR_CALLBACK write_export_file (void *arg, const char *buf, unsigned long len)

Private Attributes

nsCOMPtr< nsIPK11TokenmToken
nsCOMPtr< nsIMutableArraymCertArray
nsCOMPtr< nsIInterfaceRequestormUIContext
PRFileDescmTmpFile
char * mTmpFilePath
nsCStringmDigest
nsCString::const_iterator * mDigestIterator
PRBool mTokenSet

Detailed Description

Definition at line 63 of file nsPKCS12Blob.h.


Member Enumeration Documentation

enum nsPKCS12Blob::ImportMode [private]
Enumerator:
im_standard_prompt 
im_try_zero_length_secitem 

Definition at line 108 of file nsPKCS12Blob.h.

enum nsPKCS12Blob::RetryReason [private]
Enumerator:
rr_do_not_retry 
rr_bad_password 
rr_auto_retry_empty_password_flavors 

Definition at line 107 of file nsPKCS12Blob.h.


Constructor & Destructor Documentation

Definition at line 99 of file nsPKCS12Blob.cpp.

{
  delete mDigestIterator;
  delete mDigest;
}

Member Function Documentation

SECStatus PR_CALLBACK nsPKCS12Blob::digest_close ( void arg,
PRBool  remove_it 
) [static, private]

Definition at line 684 of file nsPKCS12Blob.cpp.

Here is the caller graph for this function:

SECStatus PR_CALLBACK nsPKCS12Blob::digest_open ( void arg,
PRBool  reading 
) [static, private]

Definition at line 649 of file nsPKCS12Blob.cpp.

{
  nsPKCS12Blob *cx = NS_REINTERPRET_POINTER_CAST(nsPKCS12Blob *, arg);
  NS_ENSURE_TRUE(cx, SECFailure);
  
  if (reading) {
    NS_ENSURE_TRUE(cx->mDigest, SECFailure);

    delete cx->mDigestIterator;
    cx->mDigestIterator = new nsCString::const_iterator;

    if (!cx->mDigestIterator) {
      PORT_SetError(SEC_ERROR_NO_MEMORY);
      return SECFailure;
    }

    cx->mDigest->BeginReading(*cx->mDigestIterator);
  }
  else {
    delete cx->mDigest;
    cx->mDigest = new nsCString;

    if (!cx->mDigest) {
      PORT_SetError(SEC_ERROR_NO_MEMORY);
      return SECFailure;
    }
  }

  return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PR_CALLBACK nsPKCS12Blob::digest_read ( void arg,
unsigned char *  buf,
unsigned long  len 
) [static, private]

Definition at line 703 of file nsPKCS12Blob.cpp.

{
  nsPKCS12Blob *cx = NS_REINTERPRET_POINTER_CAST(nsPKCS12Blob *, arg);
  NS_ENSURE_TRUE(cx, SECFailure);
  NS_ENSURE_TRUE(cx->mDigest, SECFailure);

  // iterator object must exist when digest has been opened in read mode
  NS_ENSURE_TRUE(cx->mDigestIterator, SECFailure);

  unsigned long available = cx->mDigestIterator->size_forward();
  
  if (len > available)
    len = available;

  memcpy(buf, cx->mDigestIterator->get(), len);
  cx->mDigestIterator->advance(len);
  
  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int PR_CALLBACK nsPKCS12Blob::digest_write ( void arg,
unsigned char *  buf,
unsigned long  len 
) [static, private]

Definition at line 726 of file nsPKCS12Blob.cpp.

{
  nsPKCS12Blob *cx = NS_REINTERPRET_POINTER_CAST(nsPKCS12Blob *, arg);
  NS_ENSURE_TRUE(cx, SECFailure);
  NS_ENSURE_TRUE(cx->mDigest, SECFailure);

  // make sure we are in write mode, read iterator has not yet been allocated
  NS_ENSURE_FALSE(cx->mDigestIterator, SECFailure);
  
  cx->mDigest->Append(NS_REINTERPRET_CAST(char *, buf),
                     NS_STATIC_CAST(PRUint32, len));
  
  return len;
}

Here is the caller graph for this function:

nsresult nsPKCS12Blob::ExportToFile ( nsILocalFile file,
nsIX509Cert **  certs,
int  numCerts 
)

Definition at line 346 of file nsPKCS12Blob.cpp.

{
  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  SECStatus srv = SECSuccess;
  SEC_PKCS12ExportContext *ecx = NULL;
  SEC_PKCS12SafeInfo *certSafe = NULL, *keySafe = NULL;
  SECItem unicodePw;
  nsAutoString filePath;
  int i;
  nsCOMPtr<nsILocalFile> localFileRef;
  NS_ASSERTION(mToken, "Need to set the token before exporting");
  // init slot

  PRBool InformedUserNoSmartcardBackup = PR_FALSE;
  int numCertsExported = 0;

  rv = mToken->Login(PR_TRUE);
  if (NS_FAILED(rv)) goto finish;
  // get file password (unicode)
  unicodePw.data = NULL;
  rv = newPKCS12FilePassword(&unicodePw);
  if (NS_FAILED(rv)) goto finish;
  if (unicodePw.data == NULL) {
    handleError(PIP_PKCS12_USER_CANCELED);
    return NS_OK;
  }
  // 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;
#if 0
  // count the number of certs to export
  nrv = mCertArray->Count(&numCerts);
  if (NS_FAILED(nrv)) goto finish;
  // loop over the certs
  for (i=0; i<numCerts; i++) {
    nsCOMPtr<nsIX509Cert> cert;
    nrv = mCertArray->GetElementAt(i, getter_AddRefs(cert));
    if (NS_FAILED(nrv)) goto finish;
#endif
  for (i=0; i<numCerts; i++) {
//    nsNSSCertificate *cert = NS_REINTREPRET_POINTER_CAST(nsNSSCertificate *,
//                                                         certs[i]);
    nsNSSCertificate *cert = (nsNSSCertificate *)certs[i];
    // get it as a CERTCertificate XXX
    CERTCertificate *nssCert = NULL;
    CERTCertificateCleaner nssCertCleaner(nssCert);
    nssCert = cert->GetCert();
    if (!nssCert) {
      rv = NS_ERROR_FAILURE;
      goto finish;
    }
    // We can only successfully export certs that are on 
    // internal token.  Most, if not all, smart card vendors
    // won't let you extract the private key (in any way
    // shape or form) from the card.  So let's punt if 
    // the cert is not in the internal db.
    if (nssCert->slot && !PK11_IsInternal(nssCert->slot)) {
      // we aren't the internal token, see if the key is extractable.
      SECKEYPrivateKey *privKey=PK11_FindKeyByDERCert(nssCert->slot,
                                                      nssCert, this);

      if (privKey) {
        PRBool privKeyIsExtractable = isExtractable(privKey);

        SECKEY_DestroyPrivateKey(privKey);

        if (!privKeyIsExtractable) {
          if (!InformedUserNoSmartcardBackup) {
            InformedUserNoSmartcardBackup = PR_TRUE;
            handleError(PIP_PKCS12_NOSMARTCARD_EXPORT);
          }
          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) {
      rv = NS_ERROR_FAILURE;
      goto finish;
    }
    // add the cert and key to the blob
    srv = SEC_PKCS12AddCertAndKey(ecx, certSafe, NULL, nssCert,
                                  CERT_GetDefaultCertDB(), // XXX
                                  keySafe, NULL, PR_TRUE, &unicodePw,
                      SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC);
    if (srv) goto finish;
    // cert was dup'ed, so release it
    ++numCertsExported;
  }
  
  if (!numCertsExported) goto finish;
  
  // prepare the instance to write to an export file
  this->mTmpFile = NULL;
  file->GetPath(filePath);
  // Use the nsCOMPtr var localFileRef so that
  // the reference to the nsILocalFile we create gets released as soon as
  // we're out of scope, ie when this function exits.
  if (filePath.RFind(".p12", PR_TRUE, -1, 4) < 0) {
    // We're going to add the .p12 extension to the file name just like
    // Communicator used to.  We create a new nsILocalFile and initialize
    // it with the new patch.
    filePath.AppendLiteral(".p12");
    localFileRef = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
    if (NS_FAILED(rv)) goto finish;
    localFileRef->InitWithPath(filePath);
    file = localFileRef;
  }
  rv = file->OpenNSPRFileDesc(PR_RDWR|PR_CREATE_FILE|PR_TRUNCATE, 0664, 
                              &mTmpFile);
  if (NS_FAILED(rv) || !this->mTmpFile) goto finish;
  // encode and write
  srv = SEC_PKCS12Encode(ecx, write_export_file, this);
  if (srv) goto finish;
  handleError(PIP_PKCS12_BACKUP_OK);
finish:
  if (NS_FAILED(rv) || srv != SECSuccess) {
    handleError(PIP_PKCS12_BACKUP_FAILED);
  }
  if (ecx)
    SEC_PKCS12DestroyExportContext(ecx);
  if (this->mTmpFile) {
    PR_Close(this->mTmpFile);
    this->mTmpFile = NULL;
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPKCS12Blob::getPKCS12FilePassword ( SECItem *  unicodePw) [private]

Definition at line 555 of file nsPKCS12Blob.cpp.

{
  nsresult rv = NS_OK;
  nsAutoString password;
  nsCOMPtr<nsICertificateDialogs> certDialogs;
  rv = ::getNSSDialogs(getter_AddRefs(certDialogs), 
                       NS_GET_IID(nsICertificateDialogs),
                       NS_CERTIFICATEDIALOGS_CONTRACTID);
  if (NS_FAILED(rv)) return rv;
  PRBool pressedOK;
  {
    nsPSMUITracker tracker;
    if (tracker.isUIForbidden()) {
      rv = NS_ERROR_NOT_AVAILABLE;
    }
    else {
      rv = certDialogs->GetPKCS12FilePassword(mUIContext, password, &pressedOK);
    }
  }
  if (NS_FAILED(rv) || !pressedOK) return rv;
  unicodeToItem(password.get(), unicodePw);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsPKCS12Blob::handleError ( int  myerr = 0) [private]

Definition at line 832 of file nsPKCS12Blob.cpp.

{
  nsPSMUITracker tracker;
  if (tracker.isUIForbidden()) {
    return PR_FALSE;
  }

  nsresult rv;
  PRBool keepGoing = PR_FALSE;
  int prerr = PORT_GetError();
  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PKCS12: NSS/NSPR error(%d)", prerr));
  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PKCS12: I called(%d)", myerr));
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv)) return PR_FALSE;
  nsCOMPtr<nsIProxyObjectManager> proxyman(
                                      do_GetService(NS_XPCOMPROXY_CONTRACTID));
  if (!proxyman) return PR_FALSE;
  nsCOMPtr<nsIPrompt> errPrompt;
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
  if (wwatch) {
    wwatch->GetNewPrompter(0, getter_AddRefs(errPrompt));
    if (errPrompt) {
      nsCOMPtr<nsIPrompt> proxyPrompt;
      proxyman->GetProxyForObject(NS_UI_THREAD_EVENTQ, NS_GET_IID(nsIPrompt),
                                  errPrompt, PROXY_SYNC, 
                                  getter_AddRefs(proxyPrompt));
      if (!proxyPrompt) return PR_FALSE;
    } else {
      return PR_FALSE;
    }
  } else {
    return PR_FALSE;
  }
  nsAutoString errorMsg;
  switch (myerr) {
  case PIP_PKCS12_RESTORE_OK:
    rv = nssComponent->GetPIPNSSBundleString("SuccessfulP12Restore", errorMsg);
    if (NS_FAILED(rv)) return rv;
    errPrompt->Alert(nsnull, errorMsg.get());
    return PR_TRUE;
  case PIP_PKCS12_BACKUP_OK:
    rv = nssComponent->GetPIPNSSBundleString("SuccessfulP12Backup", errorMsg);
    if (NS_FAILED(rv)) return rv;
    errPrompt->Alert(nsnull, errorMsg.get());
    return PR_TRUE;
  case PIP_PKCS12_USER_CANCELED:
    return PR_TRUE;  /* Just ignore it for now */
  case PIP_PKCS12_NOSMARTCARD_EXPORT:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12InfoNoSmartcardBackup", errorMsg);
    if (NS_FAILED(rv)) return rv;
    errPrompt->Alert(nsnull, errorMsg.get());
    return PR_TRUE;
  case PIP_PKCS12_RESTORE_FAILED:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErrRestore", errorMsg);
    if (NS_FAILED(rv)) return rv;
    errPrompt->Alert(nsnull, errorMsg.get());
    return PR_TRUE;
  case PIP_PKCS12_BACKUP_FAILED:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErrBackup", errorMsg);
    if (NS_FAILED(rv)) return rv;
    errPrompt->Alert(nsnull, errorMsg.get());
    return PR_TRUE;
  case PIP_PKCS12_NSS_ERROR:
    switch (prerr) {
    // The following errors have the potential to be "handled", by asking
    // the user (via a dialog) whether s/he wishes to continue
    case 0: break;
    case SEC_ERROR_PKCS12_CERT_COLLISION:
      /* pop a dialog saying the cert is already in the database */
      /* ask to keep going?  what happens if one collision but others ok? */
      // The following errors cannot be "handled", notify the user (via an alert)
      // that the operation failed.
#if 0
      // XXX a boy can dream...
      //     but the PKCS12 lib never throws this error
      //     but then again, how would it?  anyway, convey the info below
    case SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT:
      rv = nssComponent->GetPIPNSSBundleString("PKCS12PasswordInvalid", errorMsg);
      if (NS_FAILED(rv)) return rv;
      errPrompt->Alert(nsnull, errorMsg.get());
    break;
#endif
    case SEC_ERROR_BAD_PASSWORD:
      rv = nssComponent->GetPIPNSSBundleString("PK11BadPassword", errorMsg);
      if (NS_FAILED(rv)) return rv;
      errPrompt->Alert(nsnull, errorMsg.get());
      break;
    case SEC_ERROR_BAD_DER:
    case SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE:
    case SEC_ERROR_PKCS12_INVALID_MAC:
      rv = nssComponent->GetPIPNSSBundleString("PKCS12DecodeErr", errorMsg);
      if (NS_FAILED(rv)) return rv;
      errPrompt->Alert(nsnull, errorMsg.get());
      break;
    case SEC_ERROR_PKCS12_DUPLICATE_DATA:
      rv = nssComponent->GetPIPNSSBundleString("PKCS12DupData", errorMsg);
      if (NS_FAILED(rv)) return rv;
      errPrompt->Alert(nsnull, errorMsg.get());
      break;
    default:
      rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErr", errorMsg);
      if (NS_FAILED(rv)) return rv;
      errPrompt->Alert(nsnull, errorMsg.get());
    }
    break;
  case 0: 
  default:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErr", errorMsg);
    if (NS_FAILED(rv)) return rv;
    errPrompt->Alert(nsnull, errorMsg.get());
    break;
  }
  if (NS_FAILED(rv)) return rv;
  return keepGoing;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 134 of file nsPKCS12Blob.cpp.

{
  nsNSSShutDownPreventionLock locker;
  nsresult rv = NS_OK;

  if (!mToken) {
    if (!mTokenSet) {
      rv = SetToken(NULL); // Ask the user to pick a slot
      if (NS_FAILED(rv)) {
        handleError(PIP_PKCS12_USER_CANCELED);
        return rv;
      }
    }
  }

  if (!mToken) {
    handleError(PIP_PKCS12_RESTORE_FAILED);
    return NS_ERROR_NOT_AVAILABLE;
  }

  // init slot
  rv = mToken->Login(PR_TRUE);
  if (NS_FAILED(rv)) return rv;
  
  RetryReason wantRetry;
  
  do {
    rv = ImportFromFileHelper(file, im_standard_prompt, wantRetry);
    
    if (NS_SUCCEEDED(rv) && wantRetry == rr_auto_retry_empty_password_flavors)
    {
      rv = ImportFromFileHelper(file, im_try_zero_length_secitem, wantRetry);
    }
  }
  while (NS_SUCCEEDED(rv) && (wantRetry != rr_do_not_retry));
  
  return rv;
}

Here is the call graph for this function:

Definition at line 174 of file nsPKCS12Blob.cpp.

{
  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  SECStatus srv = SECSuccess;
  SEC_PKCS12DecoderContext *dcx = NULL;
  SECItem unicodePw;

  PK11SlotInfo *slot=nsnull;
  nsXPIDLString tokenName;
  unicodePw.data = NULL;
  
  aWantRetry = rr_do_not_retry;

  if (aImportMode == im_try_zero_length_secitem)
  {
    unicodePw.len = 0;
  }
  else
  {
    // get file password (unicode)
    rv = getPKCS12FilePassword(&unicodePw);
    if (NS_FAILED(rv)) goto finish;
    if (unicodePw.data == NULL) {
      handleError(PIP_PKCS12_USER_CANCELED);
      return NS_OK;
    }
  }
  
  mToken->GetTokenName(getter_Copies(tokenName));
  {
    NS_ConvertUTF16toUTF8 tokenNameCString(tokenName);
    slot = PK11_FindSlotByName(tokenNameCString.get());
  }
  if (!slot) {
    srv = SECFailure;
    goto finish;
  }

  // initialize the decoder
  dcx = SEC_PKCS12DecoderStart(&unicodePw, slot, NULL,
                               digest_open, digest_close,
                               digest_read, digest_write,
                               this);
  if (!dcx) {
    srv = SECFailure;
    goto finish;
  }
  // read input file and feed it to the decoder
  rv = inputToDecoder(dcx, file);
  if (NS_FAILED(rv)) {
    if (NS_ERROR_ABORT == rv) {
      // inputToDecoder indicated a NSS error
      srv = SECFailure;
    }
    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 cert and key
  srv = SEC_PKCS12DecoderImportBags(dcx);
  if (srv) goto finish;
  // Later - check to see if this should become default email cert
  handleError(PIP_PKCS12_RESTORE_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) {
    if (SEC_ERROR_BAD_PASSWORD == PORT_GetError()) {
      if (unicodePw.len == sizeof(PRUnichar))
      {
        // no password chars available, 
        // unicodeToItem allocated space for the trailing zero character only.
        aWantRetry = rr_auto_retry_empty_password_flavors;
      }
      else
      {
        aWantRetry = rr_bad_password;
        handleError(PIP_PKCS12_NSS_ERROR);
      }
    }
    else
    {
      handleError(PIP_PKCS12_NSS_ERROR);
    }
  } else if (NS_FAILED(rv)) { 
    handleError(PIP_PKCS12_RESTORE_FAILED);
  }
  if (slot)
    PK11_FreeSlot(slot);
  // finish the decoder
  if (dcx)
    SEC_PKCS12DecoderFinish(dcx);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPKCS12Blob::inputToDecoder ( SEC_PKCS12DecoderContext *  dcx,
nsILocalFile file 
) [private]

Definition at line 583 of file nsPKCS12Blob.cpp.

{
  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  SECStatus srv;
  PRUint32 amount;
  char buf[PIP_PKCS12_BUFFER_SIZE];

  nsCOMPtr<nsIInputStream> fileStream;
  rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
  
  if (NS_FAILED(rv)) {
    return rv;
  }

  while (PR_TRUE) {
    rv = fileStream->Read(buf, PIP_PKCS12_BUFFER_SIZE, &amount);
    if (NS_FAILED(rv)) {
      return rv;
    }
    // feed the file data into the decoder
    srv = SEC_PKCS12DecoderUpdate(dcx, 
                              (unsigned char*) buf, 
                              amount);
    if (srv) {
      // don't allow the close call to overwrite our precious error code
      int pr_err = PORT_GetError();
      PORT_SetError(pr_err);
      return NS_ERROR_ABORT;
    }
    if (amount < PIP_PKCS12_BUFFER_SIZE)
      break;
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsPKCS12Blob::newPKCS12FilePassword ( SECItem *  unicodePw) [private]

Definition at line 526 of file nsPKCS12Blob.cpp.

{
  nsresult rv = NS_OK;
  nsAutoString password;
  nsCOMPtr<nsICertificateDialogs> certDialogs;
  rv = ::getNSSDialogs(getter_AddRefs(certDialogs), 
                       NS_GET_IID(nsICertificateDialogs),
                       NS_CERTIFICATEDIALOGS_CONTRACTID);
  if (NS_FAILED(rv)) return rv;
  PRBool pressedOK;
  {
    nsPSMUITracker tracker;
    if (tracker.isUIForbidden()) {
      rv = NS_ERROR_NOT_AVAILABLE;
    }
    else {
      rv = certDialogs->SetPKCS12FilePassword(mUIContext, password, &pressedOK);
    }
  }
  if (NS_FAILED(rv) || !pressedOK) return rv;
  unicodeToItem(password.get(), unicodePw);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECItem *PR_CALLBACK nsPKCS12Blob::nickname_collision ( SECItem *  oldNick,
PRBool cancel,
void wincx 
) [static, private]

Definition at line 745 of file nsPKCS12Blob.cpp.

{
  nsNSSShutDownPreventionLock locker;
  *cancel = PR_FALSE;
  nsresult rv;
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv)) return nsnull;
  int count = 1;
  nsCString nickname;
  nsAutoString nickFromProp;
  nssComponent->GetPIPNSSBundleString("P12DefaultNickname", nickFromProp);
  NS_ConvertUTF16toUTF8 nickFromPropC(nickFromProp);
  // The user is trying to import a PKCS#12 file that doesn't have the
  // attribute we use to set the nickname.  So in order to reduce the
  // number of interactions we require with the user, we'll build a nickname
  // for the user.  The nickname isn't prominently displayed in the UI, 
  // so it's OK if we generate one on our own here.
  //   XXX If the NSS API were smarter and actually passed a pointer to
  //       the CERTCertificate* we're importing we could actually just
  //       call default_nickname (which is what the issuance code path
  //       does) and come up with a reasonable nickname.  Alas, the NSS
  //       API limits our ability to produce a useful nickname without
  //       bugging the user.  :(
  while (1) {
    // If we've gotten this far, that means there isn't a certificate
    // in the database that has the same subject name as the cert we're
    // trying to import.  So we need to come up with a "nickname" to 
    // satisfy the NSS requirement or fail in trying to import.  
    // Basically we use a default nickname from a properties file and 
    // see if a certificate exists with that nickname.  If there isn't, then
    // create update the count by one and append the string '#1' Or 
    // whatever the count currently is, and look for a cert with 
    // that nickname.  Keep updating the count until we find a nickname
    // without a corresponding cert.
    //  XXX If a user imports *many* certs without the 'friendly name'
    //      attribute, then this may take a long time.  :(
    if (count > 1) {
      nickname.Adopt(PR_smprintf("%s #%d", nickFromPropC.get(), count));
    } else {
      nickname = nickFromPropC;
    }
    CERTCertificate *cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(),
                                           NS_CONST_CAST(char*,nickname.get()));
    if (!cert) {
      break;
    }
    CERT_DestroyCertificate(cert);
    count++;
  }
  SECItem *newNick = new SECItem;
  if (!newNick)
    return nsnull;

  newNick->type = siAsciiString;
  newNick->data = (unsigned char*) nsCRT::strdup(nickname.get());
  newNick->len  = strlen((char*)newNick->data);
  return newNick;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 109 of file nsPKCS12Blob.cpp.

{
 nsNSSShutDownPreventionLock locker;
 nsresult rv = NS_OK;
 if (token) {
   mToken = token;
 } else {
   PK11SlotInfo *slot;
   rv = GetSlotWithMechanism(CKM_RSA_PKCS, mUIContext,&slot);
   if (NS_FAILED(rv)) {
      mToken = 0;  
   } else {
     mToken = new nsPK11Token(slot);
     PK11_FreeSlot(slot);
   }
 }
 mTokenSet = PR_TRUE;
 return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsPKCS12Blob::unicodeToItem ( const PRUnichar uni,
SECItem *  item 
) [private]

Definition at line 505 of file nsPKCS12Blob.cpp.

{
  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
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PR_CALLBACK nsPKCS12Blob::write_export_file ( void arg,
const char *  buf,
unsigned long  len 
) [static, private]

Definition at line 807 of file nsPKCS12Blob.cpp.

Here is the caller graph for this function:


Member Data Documentation

Definition at line 85 of file nsPKCS12Blob.h.

Definition at line 117 of file nsPKCS12Blob.h.

nsCString::const_iterator* nsPKCS12Blob::mDigestIterator [private]

Definition at line 118 of file nsPKCS12Blob.h.

Definition at line 113 of file nsPKCS12Blob.h.

char* nsPKCS12Blob::mTmpFilePath [private]

Definition at line 114 of file nsPKCS12Blob.h.

Definition at line 84 of file nsPKCS12Blob.h.

Definition at line 120 of file nsPKCS12Blob.h.

Definition at line 86 of file nsPKCS12Blob.h.


The documentation for this class was generated from the following files: