Example #1
0
NS_IMETHODIMP nsSecretDecoderRing::
LogoutAndTeardown()
{
  nsresult rv;
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return rv;

  {
    nsNSSShutDownPreventionLock locker;
    PK11_LogoutAll();
    SSL_ClearSessionCache();
  }

  rv = nssComponent->LogoutAuthenticatedPK11();

  // After we just logged out, we need to prune dead connections to make
  // sure that all connections that should be stopped, are stopped. See
  // bug 517584.
  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
  if (os)
    os->NotifyObservers(nsnull, "net:prune-dead-connections", nsnull);

  return rv;
}
Example #2
0
NS_IMETHODIMP
nsNSSCertificate::GetTokenName(nsAString &aTokenName)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  aTokenName.Truncate();
  if (mCert) {
    // HACK alert
    // When the trust of a builtin cert is modified, NSS copies it into the
    // cert db.  At this point, it is now "managed" by the user, and should
    // not be listed with the builtins.  However, in the collection code
    // used by PK11_ListCerts, the cert is found in the temp db, where it
    // has been loaded from the token.  Though the trust is correct (grabbed
    // from the cert db), the source is wrong.  I believe this is a safe
    // way to work around this.
    if (mCert->slot) {
      char *token = PK11_GetTokenName(mCert->slot);
      if (token) {
        aTokenName = NS_ConvertUTF8toUTF16(token);
      }
    } else {
      nsresult rv;
      nsAutoString tok;
      nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
      if (NS_FAILED(rv)) return rv;
      rv = nssComponent->GetPIPNSSBundleString("InternalToken", tok);
      if (NS_SUCCEEDED(rv))
        aTokenName = tok;
    }
  }
  return NS_OK;
}
Example #3
0
// nickname_collision
// what to do when the nickname collides with one already in the db.
// TODO: not handled, throw a dialog allowing the nick to be changed?
SECItem * PR_CALLBACK
nsPKCS12Blob::nickname_collision(SECItem *oldNick, PRBool *cancel, void *wincx)
{
  nsNSSShutDownPreventionLock locker;
  *cancel = 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(),
                                           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;
}
NS_IMETHODIMP 
nsCRLManager::RescheduleCRLAutoUpdate(void)
{
  nsresult rv;
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if(NS_FAILED(rv)){
    return rv;
  }
  rv = nssComponent->DefineNextTimer();
  return rv;
}
Example #5
0
TemporaryRef<CertVerifier>
GetDefaultCertVerifier()
{
  static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);

  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID));
  RefPtr<CertVerifier> certVerifier;
  if (nssComponent) {
    (void) nssComponent->GetDefaultCertVerifier(certVerifier);
  }
  return certVerifier;
}
Example #6
0
NS_IMETHODIMP nsPK11Token::LogoutAndDropAuthenticatedResources()
{
  nsresult rv = LogoutSimple();

  if (NS_FAILED(rv))
    return rv;

  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return rv;

  return nssComponent->LogoutAuthenticatedPK11();
}
Example #7
0
already_AddRefed<SharedCertVerifier>
GetDefaultCertVerifier()
{
  static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);

  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID));
  RefPtr<SharedCertVerifier> certVerifier;
  if (nssComponent) {
    return nssComponent->GetDefaultCertVerifier();
  }

  return nullptr;
}
Example #8
0
//
// helper function to pass the event off to nsNSSComponent.
//
nsresult
SmartCardMonitoringThread::SendEvent(const nsAString &eventType,
                                     const char *tokenName)
{
  nsresult rv;
  nsCOMPtr<nsINSSComponent> 
                    nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return rv;

  // NSS returns actual UTF8, not ASCII
  nssComponent->PostEvent(eventType, NS_ConvertUTF8toUTF16(tokenName));
  return NS_OK;
}
Example #9
0
NS_IMETHODIMP nsSecretDecoderRing::
Logout()
{
  nsresult rv;
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return rv;

  {
    nsNSSShutDownPreventionLock locker;
    PK11_LogoutAll();
    SSL_ClearSessionCache();
  }

  return NS_OK;
}
Example #10
0
void nsNSSCertificateDB::DisplayCertificateAlert(nsIInterfaceRequestor *ctx, 
                                                 const char *stringID, 
                                                 nsIX509Cert *certToShow)
{
  nsPSMUITracker tracker;
  if (!tracker.isUIForbidden()) {

    nsCOMPtr<nsIInterfaceRequestor> my_cxt = ctx;
    if (!my_cxt)
      my_cxt = new PipUIContext();

    // This shall be replaced by embedding ovverridable prompts
    // as discussed in bug 310446, and should make use of certToShow.

    nsresult rv;
    nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
    if (NS_SUCCEEDED(rv)) {
      nsAutoString tmpMessage;
      nssComponent->GetPIPNSSBundleString(stringID, tmpMessage);

      // The interface requestor object may not be safe, so proxy the call to get
      // the nsIPrompt.

      nsCOMPtr<nsIInterfaceRequestor> proxiedCallbacks;
      NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                           NS_GET_IID(nsIInterfaceRequestor),
                           my_cxt,
                           NS_PROXY_SYNC,
                           getter_AddRefs(proxiedCallbacks));
    
      nsCOMPtr<nsIPrompt> prompt (do_GetInterface(proxiedCallbacks));
      if (!prompt)
        return;
    
      // Finally, get a proxy for the nsIPrompt
    
      nsCOMPtr<nsIPrompt> proxyPrompt;
      NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                           NS_GET_IID(nsIPrompt),
                           prompt,
                           NS_PROXY_SYNC,
                           getter_AddRefs(proxyPrompt));
    
      proxyPrompt->Alert(nsnull, tmpMessage.get());
    }
  }
}
Example #11
0
NS_IMETHODIMP
nsNSSCertificate::GetEmailAddress(nsAString &aEmailAddress)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown())
    return NS_ERROR_NOT_AVAILABLE;

  if (mCert->emailAddr) {
    CopyUTF8toUTF16(mCert->emailAddr, aEmailAddress);
  } else {
    nsresult rv;
    nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
    if (NS_FAILED(rv) || !nssComponent) {
      return NS_ERROR_FAILURE;
    }
    nssComponent->GetPIPNSSBundleString("CertNoEmailAddress", aEmailAddress);
  }
  return NS_OK;
}
NS_IMETHODIMP 
nsCRLManager::UpdateCRLFromURL( const PRUnichar *url, const PRUnichar* key, bool *res)
{
  nsresult rv;
  nsAutoString downloadUrl(url);
  nsAutoString dbKey(key);
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if(NS_FAILED(rv)){
    *res = false;
    return rv;
  }

  rv = nssComponent->DownloadCRLDirectly(downloadUrl, dbKey);
  if(NS_FAILED(rv)){
    *res = false;
  } else {
    *res = true;
  }
  return NS_OK;

}
Example #13
0
// Add a new PKCS11 module to the user's profile.
NS_IMETHODIMP
nsPkcs11::AddModule(const nsAString& aModuleName,
                    const nsAString& aLibraryFullPath,
                    int32_t aCryptoMechanismFlags,
                    int32_t aCipherFlags)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  if (aModuleName.IsEmpty()) {
    return NS_ERROR_INVALID_ARG;
  }

  NS_ConvertUTF16toUTF8 moduleName(aModuleName);
  nsCString fullPath;
  // NSS doesn't support Unicode path.  Use native charset
  NS_CopyUnicodeToNative(aLibraryFullPath, fullPath);
  uint32_t mechFlags = SECMOD_PubMechFlagstoInternal(aCryptoMechanismFlags);
  uint32_t cipherFlags = SECMOD_PubCipherFlagstoInternal(aCipherFlags);
  SECStatus srv = SECMOD_AddNewModule(moduleName.get(), fullPath.get(),
                                      mechFlags, cipherFlags);
  if (srv != SECSuccess) {
    return NS_ERROR_FAILURE;
  }

#ifndef MOZ_NO_SMART_CARDS
  mozilla::UniqueSECMODModule module(SECMOD_FindModule(moduleName.get()));
  if (!module) {
    return NS_ERROR_FAILURE;
  }
  nsCOMPtr<nsINSSComponent> nssComponent(
    do_GetService(PSM_COMPONENT_CONTRACTID));
  nssComponent->LaunchSmartCardThread(module.get());
#endif

  return NS_OK;
}
Example #14
0
// Delete a PKCS11 module from the user's profile.
NS_IMETHODIMP
nsPkcs11::DeleteModule(const nsAString& aModuleName)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  if (aModuleName.IsEmpty()) {
    return NS_ERROR_INVALID_ARG;
  }

  NS_ConvertUTF16toUTF8 moduleName(aModuleName);
  // Introduce additional scope for module so all references to it are released
  // before we call SECMOD_DeleteModule, below.
#ifndef MOZ_NO_SMART_CARDS
  {
    mozilla::UniqueSECMODModule module(SECMOD_FindModule(moduleName.get()));
    if (!module) {
      return NS_ERROR_FAILURE;
    }
    nsCOMPtr<nsINSSComponent> nssComponent(
      do_GetService(PSM_COMPONENT_CONTRACTID));
    nssComponent->ShutdownSmartCardThread(module.get());
  }
#endif

  // modType is an output variable. We ignore it.
  int32_t modType;
  SECStatus srv = SECMOD_DeleteModule(moduleName.get(), &modType);
  if (srv != SECSuccess) {
    return NS_ERROR_FAILURE;
  }

  return NS_OK;
}
NS_IMETHODIMP 
nsCRLManager::ImportCrl (PRUint8 *aData, PRUint32 aLength, nsIURI * aURI, PRUint32 aType, PRBool doSilentDonwload, const PRUnichar* crlKey)
{
  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  PRArenaPool *arena = NULL;
  CERTCertificate *caCert;
  SECItem derName = { siBuffer, NULL, 0 };
  SECItem derCrl;
  CERTSignedData sd;
  SECStatus sec_rv;
  CERTSignedCrl *crl;
  nsCAutoString url;
  nsCOMPtr<nsICRLInfo> crlData;
  PRBool importSuccessful;
  PRInt32 errorCode;
  nsString errorMessage;
  
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv)) return rv;
	         
  aURI->GetSpec(url);
  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  if (!arena) {
    goto loser;
  }
  memset(&sd, 0, sizeof(sd));

  derCrl.data = (unsigned char*)aData;
  derCrl.len = aLength;
  sec_rv = CERT_KeyFromDERCrl(arena, &derCrl, &derName);
  if (sec_rv != SECSuccess) {
    goto loser;
  }

  caCert = CERT_FindCertByName(CERT_GetDefaultCertDB(), &derName);
  if (!caCert) {
    if (aType == SEC_KRL_TYPE){
      goto loser;
    }
  } else {
    sec_rv = SEC_ASN1DecodeItem(arena,
                            &sd, SEC_ASN1_GET(CERT_SignedDataTemplate), 
                            &derCrl);
    if (sec_rv != SECSuccess) {
      goto loser;
    }
    sec_rv = CERT_VerifySignedData(&sd, caCert, PR_Now(),
                               nsnull);
    if (sec_rv != SECSuccess) {
      goto loser;
    }
  }
  
  crl = SEC_NewCrl(CERT_GetDefaultCertDB(), const_cast<char*>(url.get()), &derCrl,
                   aType);
  
  if (!crl) {
    goto loser;
  }

  crlData = new nsCRLInfo(crl);
  SSL_ClearSessionCache();
  SEC_DestroyCrl(crl);
  
  importSuccessful = PR_TRUE;
  goto done;

loser:
  importSuccessful = PR_FALSE;
  errorCode = PR_GetError();
  switch (errorCode) {
    case SEC_ERROR_CRL_EXPIRED:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureExpired", errorMessage);
      break;

	case SEC_ERROR_CRL_BAD_SIGNATURE:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureBadSignature", errorMessage);
      break;

	case SEC_ERROR_CRL_INVALID:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureInvalid", errorMessage);
      break;

	case SEC_ERROR_OLD_CRL:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureOld", errorMessage);
      break;

	case SEC_ERROR_CRL_NOT_YET_VALID:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureNotYetValid", errorMessage);
      break;

    default:
      nssComponent->GetPIPNSSBundleString("CrlImportFailureReasonUnknown", errorMessage);
      errorMessage.AppendInt(errorCode,16);
      break;
  }

done:
          
  if(!doSilentDonwload){
    if (!importSuccessful){
      nsString message;
      nsString temp;
      nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
      nsCOMPtr<nsIPrompt> prompter;
      if (wwatch){
        wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
        nssComponent->GetPIPNSSBundleString("CrlImportFailure1x", message);
        message.Append(NS_LITERAL_STRING("\n").get());
        message.Append(errorMessage);
        nssComponent->GetPIPNSSBundleString("CrlImportFailure2", temp);
        message.Append(NS_LITERAL_STRING("\n").get());
        message.Append(temp);
     
        if(prompter) {
          nsPSMUITracker tracker;
          if (!tracker.isUIForbidden()) {
            prompter->Alert(0, message.get());
          }
        }
      }
    } else {
      nsCOMPtr<nsICertificateDialogs> certDialogs;
      // Not being able to display the success dialog should not
      // be a fatal error, so don't return a failure code.
      {
        nsPSMUITracker tracker;
        if (tracker.isUIForbidden()) {
          rv = NS_ERROR_NOT_AVAILABLE;
        }
        else {
          rv = ::getNSSDialogs(getter_AddRefs(certDialogs),
            NS_GET_IID(nsICertificateDialogs), NS_CERTIFICATEDIALOGS_CONTRACTID);
        }
      }
      if (NS_SUCCEEDED(rv)) {
        nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
        certDialogs->CrlImportStatusDialog(cxt, crlData);
      }
    }
  } else {
    if(crlKey == nsnull){
      return NS_ERROR_FAILURE;
    }
    nsCOMPtr<nsIPrefService> prefSvc = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv);
    nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID,&rv);
    if (NS_FAILED(rv)){
      return rv;
    }
    
    nsCAutoString updateErrCntPrefStr(CRL_AUTOUPDATE_ERRCNT_PREF);
    updateErrCntPrefStr.AppendWithConversion(crlKey);
    if(importSuccessful){
      PRUnichar *updateTime;
      nsCAutoString updateTimeStr;
      nsCString updateURL;
      PRInt32 timingTypePref;
      double dayCnt;
      char *dayCntStr;
      nsCAutoString updateTypePrefStr(CRL_AUTOUPDATE_TIMIINGTYPE_PREF);
      nsCAutoString updateTimePrefStr(CRL_AUTOUPDATE_TIME_PREF);
      nsCAutoString updateUrlPrefStr(CRL_AUTOUPDATE_URL_PREF);
      nsCAutoString updateDayCntPrefStr(CRL_AUTOUPDATE_DAYCNT_PREF);
      nsCAutoString updateFreqCntPrefStr(CRL_AUTOUPDATE_FREQCNT_PREF);
      updateTypePrefStr.AppendWithConversion(crlKey);
      updateTimePrefStr.AppendWithConversion(crlKey);
      updateUrlPrefStr.AppendWithConversion(crlKey);
      updateDayCntPrefStr.AppendWithConversion(crlKey);
      updateFreqCntPrefStr.AppendWithConversion(crlKey);

      pref->GetIntPref(updateTypePrefStr.get(),&timingTypePref);
      
      //Compute and update the next download instant
      if(timingTypePref == TYPE_AUTOUPDATE_TIME_BASED){
        pref->GetCharPref(updateDayCntPrefStr.get(),&dayCntStr);
      }else{
        pref->GetCharPref(updateFreqCntPrefStr.get(),&dayCntStr);
      }
      dayCnt = atof(dayCntStr);
      nsMemory::Free(dayCntStr);

      PRBool toBeRescheduled = PR_FALSE;
      if(NS_SUCCEEDED(ComputeNextAutoUpdateTime(crlData, timingTypePref, dayCnt, &updateTime))){
        updateTimeStr.AssignWithConversion(updateTime);
        nsMemory::Free(updateTime);
        pref->SetCharPref(updateTimePrefStr.get(),updateTimeStr.get());
        //Now, check if this update time is already in the past. This would
        //imply we have downloaded the same crl, or there is something wrong
        //with the next update date. We will not reschedule this crl in this
        //session anymore - or else, we land into a loop. It would anyway be
        //imported once the browser is restarted.
        PRTime nextTime;
        PR_ParseTimeString(updateTimeStr.get(),PR_TRUE, &nextTime);
        if(LL_CMP(nextTime, > , PR_Now())){
          toBeRescheduled = PR_TRUE;
        }
      }
      
      //Update the url to download from, next time
      crlData->GetLastFetchURL(updateURL);
      pref->SetCharPref(updateUrlPrefStr.get(),updateURL.get());
      
      pref->SetIntPref(updateErrCntPrefStr.get(),0);
      
      if (toBeRescheduled) {
        nsAutoString hashKey(crlKey);
        nssComponent->RemoveCrlFromList(hashKey);
        nssComponent->DefineNextTimer();
      }

    } else{
Example #16
0
void PR_CALLBACK HandshakeCallback(PRFileDesc* fd, void* client_data) {
  nsNSSShutDownPreventionLock locker;
  PRInt32 sslStatus;
  char* signer = nsnull;
  char* cipherName = nsnull;
  PRInt32 keyLength;
  nsresult rv;
  PRInt32 encryptBits;

  if (SECSuccess != SSL_SecurityStatus(fd, &sslStatus, &cipherName, &keyLength,
                                       &encryptBits, &signer, nsnull)) {
    return;
  }

  PRInt32 secStatus;
  if (sslStatus == SSL_SECURITY_STATUS_OFF)
    secStatus = nsIWebProgressListener::STATE_IS_BROKEN;
  else if (encryptBits >= 90)
    secStatus = (nsIWebProgressListener::STATE_IS_SECURE |
                 nsIWebProgressListener::STATE_SECURE_HIGH);
  else
    secStatus = (nsIWebProgressListener::STATE_IS_SECURE |
                 nsIWebProgressListener::STATE_SECURE_LOW);

  CERTCertificate *peerCert = SSL_PeerCertificate(fd);
  const char* caName = nsnull; // caName is a pointer only, no ownership
  char* certOrgName = CERT_GetOrgName(&peerCert->issuer);
  CERT_DestroyCertificate(peerCert);
  caName = certOrgName ? certOrgName : signer;

  const char* verisignName = "Verisign, Inc.";
  // If the CA name is RSA Data Security, then change the name to the real
  // name of the company i.e. VeriSign, Inc.
  if (nsCRT::strcmp((const char*)caName, "RSA Data Security, Inc.") == 0) {
    caName = verisignName;
  }

  nsAutoString shortDesc;
  const PRUnichar* formatStrings[1] = { ToNewUnicode(NS_ConvertUTF8toUTF16(caName)) };
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_SUCCEEDED(rv)) {
    rv = nssComponent->PIPBundleFormatStringFromName("SignedBy",
                                                   formatStrings, 1,
                                                   shortDesc);

    nsMemory::Free(const_cast<PRUnichar*>(formatStrings[0]));

    nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
    infoObject->SetSecurityState(secStatus);
    infoObject->SetShortSecurityDescription(shortDesc.get());

    /* Set the SSL Status information */
    nsRefPtr<nsSSLStatus> status = infoObject->SSLStatus();
    if (!status) {
      status = new nsSSLStatus();
      infoObject->SetSSLStatus(status);
    }

    CERTCertificate *serverCert = SSL_PeerCertificate(fd);
    if (serverCert) {
      nsRefPtr<nsNSSCertificate> nssc = new nsNSSCertificate(serverCert);
      CERT_DestroyCertificate(serverCert);
      serverCert = nsnull;

      nsCOMPtr<nsIX509Cert> prevcert;
      infoObject->GetPreviousCert(getter_AddRefs(prevcert));

      PRBool equals_previous = PR_FALSE;
      if (prevcert) {
        nsresult rv = nssc->Equals(prevcert, &equals_previous);
        if (NS_FAILED(rv)) {
          equals_previous = PR_FALSE;
        }
      }

      if (equals_previous) {
        PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
               ("HandshakeCallback using PREV cert %p\n", prevcert.get()));
        infoObject->SetCert(prevcert);
        status->mServerCert = prevcert;
      }
      else {
        if (status->mServerCert) {
          PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
                 ("HandshakeCallback KEEPING cert %p\n", status->mServerCert.get()));
          infoObject->SetCert(status->mServerCert);
        }
        else {
          PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
                 ("HandshakeCallback using NEW cert %p\n", nssc.get()));
          infoObject->SetCert(nssc);
          status->mServerCert = nssc;
        }
      }
    }

    status->mHaveKeyLengthAndCipher = PR_TRUE;
    status->mKeyLength = keyLength;
    status->mSecretKeyLength = encryptBits;
    status->mCipherName.Adopt(cipherName);
  }

  PR_FREEIF(certOrgName);
  PR_Free(signer);
}
Example #17
0
void
nsNSSCertificateDB::get_default_nickname(CERTCertificate *cert, 
                                         nsIInterfaceRequestor* ctx,
                                         nsCString &nickname)
{
  nickname.Truncate();

  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  CK_OBJECT_HANDLE keyHandle;

  CERTCertDBHandle *defaultcertdb = CERT_GetDefaultCertDB();
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
  if (NS_FAILED(rv))
    return;

  nsCAutoString username;
  char *temp_un = CERT_GetCommonName(&cert->subject);
  if (temp_un) {
    username = temp_un;
    PORT_Free(temp_un);
    temp_un = nsnull;
  }

  nsCAutoString caname;
  char *temp_ca = CERT_GetOrgName(&cert->issuer);
  if (temp_ca) {
    caname = temp_ca;
    PORT_Free(temp_ca);
    temp_ca = nsnull;
  }

  nsAutoString tmpNickFmt;
  nssComponent->GetPIPNSSBundleString("nick_template", tmpNickFmt);
  NS_ConvertUTF16toUTF8 nickFmt(tmpNickFmt);

  nsCAutoString baseName;
  char *temp_nn = PR_smprintf(nickFmt.get(), username.get(), caname.get());
  if (!temp_nn) {
    return;
  } else {
    baseName = temp_nn;
    PR_smprintf_free(temp_nn);
    temp_nn = nsnull;
  }

  nickname = baseName;

  /*
   * We need to see if the private key exists on a token, if it does
   * then we need to check for nicknames that already exist on the smart
   * card.
   */
  PK11SlotInfo *slot = PK11_KeyForCertExists(cert, &keyHandle, ctx);
  PK11SlotInfoCleaner slotCleaner(slot);
  if (!slot)
    return;

  if (!PK11_IsInternal(slot)) {
    char *tmp = PR_smprintf("%s:%s", PK11_GetTokenName(slot), baseName.get());
    if (!tmp) {
      nickname.Truncate();
      return;
    }
    baseName = tmp;
    PR_smprintf_free(tmp);

    nickname = baseName;
  }

  int count = 1;
  while (true) {
    if ( count > 1 ) {
      char *tmp = PR_smprintf("%s #%d", baseName.get(), count);
      if (!tmp) {
        nickname.Truncate();
        return;
      }
      nickname = tmp;
      PR_smprintf_free(tmp);
    }

    CERTCertificate *dummycert = nsnull;
    CERTCertificateCleaner dummycertCleaner(dummycert);

    if (PK11_IsInternal(slot)) {
      /* look up the nickname to make sure it isn't in use already */
      dummycert = CERT_FindCertByNickname(defaultcertdb, nickname.get());

    } else {
      /*
       * Check the cert against others that already live on the smart 
       * card.
       */
      dummycert = PK11_FindCertFromNickname(nickname.get(), ctx);
      if (dummycert != NULL) {
	/*
	 * Make sure the subject names are different.
	 */ 
	if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual)
	{
	  /*
	   * There is another certificate with the same nickname and
	   * the same subject name on the smart card, so let's use this
	   * nickname.
	   */
	  CERT_DestroyCertificate(dummycert);
	  dummycert = NULL;
	}
      }
    }
    if (!dummycert) 
      break;
    
    count++;
  }
}
Example #18
0
nsresult
nsNSSCertificate::FormatUIStrings(const nsAutoString &nickname, nsAutoString &nickWithSerial, nsAutoString &details)
{
  if (!NS_IsMainThread()) {
    NS_ERROR("nsNSSCertificate::FormatUIStrings called off the main thread");
    return NS_ERROR_NOT_SAME_THREAD;
  }
  
  nsresult rv = NS_OK;

  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));

  if (NS_FAILED(rv) || !nssComponent) {
    return NS_ERROR_FAILURE;
  }
  
  nsAutoString info;
  nsAutoString temp1;

  nickWithSerial.Append(nickname);

  if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoIssuedFor", info))) {
    details.Append(info);
    details.Append(PRUnichar(' '));
    if (NS_SUCCEEDED(GetSubjectName(temp1)) && !temp1.IsEmpty()) {
      details.Append(temp1);
    }
    details.Append(PRUnichar('\n'));
  }

  if (NS_SUCCEEDED(GetSerialNumber(temp1)) && !temp1.IsEmpty()) {
    details.AppendLiteral("  ");
    if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertDumpSerialNo", info))) {
      details.Append(info);
      details.AppendLiteral(": ");
    }
    details.Append(temp1);

    nickWithSerial.AppendLiteral(" [");
    nickWithSerial.Append(temp1);
    nickWithSerial.Append(PRUnichar(']'));

    details.Append(PRUnichar('\n'));
  }

  nsCOMPtr<nsIX509CertValidity> validity;
  rv = GetValidity(getter_AddRefs(validity));
  if (NS_SUCCEEDED(rv) && validity) {
    details.AppendLiteral("  ");
    if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoValid", info))) {
      details.Append(info);
    }

    if (NS_SUCCEEDED(validity->GetNotBeforeLocalTime(temp1)) && !temp1.IsEmpty()) {
      details.Append(PRUnichar(' '));
      if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoFrom", info))) {
        details.Append(info);
        details.Append(PRUnichar(' '));
      }
      details.Append(temp1);
    }

    if (NS_SUCCEEDED(validity->GetNotAfterLocalTime(temp1)) && !temp1.IsEmpty()) {
      details.Append(PRUnichar(' '));
      if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoTo", info))) {
        details.Append(info);
        details.Append(PRUnichar(' '));
      }
      details.Append(temp1);
    }

    details.Append(PRUnichar('\n'));
  }

  if (NS_SUCCEEDED(GetKeyUsagesString(mCert, nssComponent, temp1)) && !temp1.IsEmpty()) {
    details.AppendLiteral("  ");
    if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertDumpKeyUsage", info))) {
      details.Append(info);
      details.AppendLiteral(": ");
    }
    details.Append(temp1);
    details.Append(PRUnichar('\n'));
  }

  nsAutoString firstEmail;
  const char *aWalkAddr;
  for (aWalkAddr = CERT_GetFirstEmailAddress(mCert)
        ;
        aWalkAddr
        ;
        aWalkAddr = CERT_GetNextEmailAddress(mCert, aWalkAddr))
  {
    NS_ConvertUTF8toUTF16 email(aWalkAddr);
    if (email.IsEmpty())
      continue;

    if (firstEmail.IsEmpty()) {
      /*
        * If the first email address from the subject DN is also present
        * in the subjectAltName extension, GetEmailAddresses() will return
        * it twice (as received from NSS). Remember the first address so that
        * we can filter out duplicates later on.
        */
      firstEmail = email;

      details.AppendLiteral("  ");
      if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoEmail", info))) {
        details.Append(info);
        details.AppendLiteral(": ");
      }
      details.Append(email);
    }
    else {
      // Append current address if it's different from the first one.
      if (!firstEmail.Equals(email)) {
        details.AppendLiteral(", ");
        details.Append(email);
      }
    }
  }

  if (!firstEmail.IsEmpty()) {
    // We got at least one email address, so we want a newline
    details.Append(PRUnichar('\n'));
  }

  if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoIssuedBy", info))) {
    details.Append(info);
    details.Append(PRUnichar(' '));

    if (NS_SUCCEEDED(GetIssuerName(temp1)) && !temp1.IsEmpty()) {
      details.Append(temp1);
    }

    details.Append(PRUnichar('\n'));
  }

  if (NS_SUCCEEDED(nssComponent->GetPIPNSSBundleString("CertInfoStoredIn", info))) {
    details.Append(info);
    details.Append(PRUnichar(' '));

    if (NS_SUCCEEDED(GetTokenName(temp1)) && !temp1.IsEmpty()) {
      details.Append(temp1);
    }
  }

  /*
    the above produces the following output:

    Issued to: $subjectName
    Serial number: $serialNumber
    Valid from: $starting_date to $expiration_date
    Certificate Key usage: $usages
    Email: $address(es)
    Issued by: $issuerName
    Stored in: $token
  */
  
  return rv;
}
Example #19
0
void
nsPKCS12Blob::handleError(int myerr)
{
  nsPSMUITracker tracker;
  if (tracker.isUIForbidden()) {
    return;
  }

  nsresult rv;
  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;
  nsCOMPtr<nsIPrompt> errPrompt;
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
  if (wwatch) {
    wwatch->GetNewPrompter(0, getter_AddRefs(errPrompt));
    if (errPrompt) {
      nsCOMPtr<nsIPrompt> proxyPrompt;
      NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                           NS_GET_IID(nsIPrompt), errPrompt,
                           NS_PROXY_SYNC, getter_AddRefs(proxyPrompt));
      if (!proxyPrompt) return;
    } else {
      return;
    }
  } else {
    return;
  }
  nsAutoString errorMsg;
  switch (myerr) {
  case PIP_PKCS12_RESTORE_OK:
    rv = nssComponent->GetPIPNSSBundleString("SuccessfulP12Restore", errorMsg);
    if (NS_FAILED(rv)) return;
    errPrompt->Alert(nsnull, errorMsg.get());
    return;
  case PIP_PKCS12_BACKUP_OK:
    rv = nssComponent->GetPIPNSSBundleString("SuccessfulP12Backup", errorMsg);
    if (NS_FAILED(rv)) return;
    errPrompt->Alert(nsnull, errorMsg.get());
    return;
  case PIP_PKCS12_USER_CANCELED:
    return;  /* Just ignore it for now */
  case PIP_PKCS12_NOSMARTCARD_EXPORT:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12InfoNoSmartcardBackup", errorMsg);
    if (NS_FAILED(rv)) return;
    errPrompt->Alert(nsnull, errorMsg.get());
    return;
  case PIP_PKCS12_RESTORE_FAILED:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErrRestore", errorMsg);
    if (NS_FAILED(rv)) return;
    errPrompt->Alert(nsnull, errorMsg.get());
    return;
  case PIP_PKCS12_BACKUP_FAILED:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErrBackup", errorMsg);
    if (NS_FAILED(rv)) return;
    errPrompt->Alert(nsnull, errorMsg.get());
    return;
  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;
      errPrompt->Alert(nsnull, errorMsg.get());
    break;
#endif
    case SEC_ERROR_BAD_PASSWORD:
      rv = nssComponent->GetPIPNSSBundleString("PK11BadPassword", errorMsg);
      if (NS_FAILED(rv)) return;
      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;
      errPrompt->Alert(nsnull, errorMsg.get());
      break;
    case SEC_ERROR_PKCS12_DUPLICATE_DATA:
      rv = nssComponent->GetPIPNSSBundleString("PKCS12DupData", errorMsg);
      if (NS_FAILED(rv)) return;
      errPrompt->Alert(nsnull, errorMsg.get());
      break;
    default:
      rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErr", errorMsg);
      if (NS_FAILED(rv)) return;
      errPrompt->Alert(nsnull, errorMsg.get());
    }
    break;
  case 0: 
  default:
    rv = nssComponent->GetPIPNSSBundleString("PKCS12UnknownErr", errorMsg);
    if (NS_FAILED(rv)) return;
    errPrompt->Alert(nsnull, errorMsg.get());
    break;
  }
}
Example #20
0
char* PR_CALLBACK
PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg) {
  nsNSSShutDownPreventionLock locker;
  nsresult rv = NS_OK;
  PRUnichar *password = nsnull;
  PRBool value = PR_FALSE;
  nsIInterfaceRequestor *ir = static_cast<nsIInterfaceRequestor*>(arg);
  nsCOMPtr<nsIPrompt> proxyPrompt;

  /* TODO: Retry should generate a different dialog message */
/*
  if (retry)
    return nsnull;
*/

  if (!ir)
  {
    nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
    if (!wwatch)
      return nsnull;

    nsCOMPtr<nsIPrompt> prompter;
    wwatch->GetNewPrompter(0, getter_AddRefs(prompter));
    if (!prompter)
      return nsnull;

    NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                         NS_GET_IID(nsIPrompt),
                         prompter, NS_PROXY_SYNC,
                         getter_AddRefs(proxyPrompt));
    if (!proxyPrompt)
      return nsnull;
  }
  else
  {
    // The interface requestor object may not be safe, so
    // proxy the call to get the nsIPrompt.
  
    nsCOMPtr<nsIInterfaceRequestor> proxiedCallbacks;
    NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                         NS_GET_IID(nsIInterfaceRequestor),
                         ir,
                         NS_PROXY_SYNC,
                         getter_AddRefs(proxiedCallbacks));
  
    // Get the desired interface
    nsCOMPtr<nsIPrompt> prompt(do_GetInterface(proxiedCallbacks));
    if (!prompt) {
      NS_ASSERTION(PR_FALSE, "callbacks does not implement nsIPrompt");
      return nsnull;
    }
  
    // Finally, get a proxy for the nsIPrompt
    NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                         NS_GET_IID(nsIPrompt),
                         prompt,
                         NS_PROXY_SYNC,
                         getter_AddRefs(proxyPrompt));
  }

  if (PK11_ProtectedAuthenticationPath(slot))
    return ShowProtectedAuthPrompt(slot, ir);

  nsAutoString promptString;
  nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));

  if (NS_FAILED(rv))
    return nsnull; 

  const PRUnichar* formatStrings[1] = { ToNewUnicode(NS_ConvertUTF8toUTF16(PK11_GetTokenName(slot))) };
  rv = nssComponent->PIPBundleFormatStringFromName("CertPassPrompt",
                                      formatStrings, 1,
                                      promptString);
  nsMemory::Free(const_cast<PRUnichar*>(formatStrings[0]));

  if (NS_FAILED(rv))
    return nsnull;

  {
    nsPSMUITracker tracker;
    if (tracker.isUIForbidden()) {
      rv = NS_ERROR_NOT_AVAILABLE;
    }
    else {
      rv = proxyPrompt->PromptPassword(nsnull, promptString.get(),
                                       &password, nsnull, nsnull, &value);
    }
  }
  
  if (NS_SUCCEEDED(rv) && value) {
    char* str = ToNewUTF8String(nsDependentString(password));
    NS_Free(password);
    return str;
  }

  return nsnull;
}