示例#1
0
/* void deleteCert (in nsIX509Cert cert); */
NS_IMETHODIMP
nsNSSCertList::DeleteCert(nsIX509Cert *aCert)
{
  /* This should be a query interface, but currently this his how the
   * rest of PSM is working */
  nsCOMPtr<nsIX509Cert2> nssCert = do_QueryInterface(aCert);
  CERTCertificate *cert = nssCert->GetCert();
  CERTCertListNode *node;

  if (cert == nullptr) {
    NS_ERROR("Somehow got nullptr for mCertificate in nsNSSCertificate.");
    return NS_ERROR_FAILURE;
  }

  if (mCertList == nullptr) {
    NS_ERROR("Somehow got nullptr for mCertList in nsNSSCertList.");
    return NS_ERROR_FAILURE;
  }

  for (node = CERT_LIST_HEAD(mCertList); !CERT_LIST_END(node,mCertList);
                                             node = CERT_LIST_NEXT(node)) {
    if (node->cert == cert) {
	CERT_RemoveCertListNode(node);
        return NS_OK;
    }
  }
  return NS_OK; /* should we fail if we couldn't find it? */
}
示例#2
0
/* nsISupports getNext(); */
NS_IMETHODIMP
nsNSSCertListEnumerator::GetNext(nsISupports **_retval) 
{
  NS_ENSURE_TRUE(mCertList, NS_ERROR_FAILURE);

  CERTCertListNode *node = CERT_LIST_HEAD(mCertList);
  if (CERT_LIST_END(node, mCertList)) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(node->cert);
  if (!nssCert) { 
    return NS_ERROR_OUT_OF_MEMORY;
  }

  *_retval = nssCert;
  NS_ADDREF(*_retval);

  CERT_RemoveCertListNode(node);
  return NS_OK;
}
/*
 * Find all user certificates that match the given criteria.
 * 
 *	"handle" - database to search
 *	"usage" - certificate usage to match
 *	"oneCertPerName" - if set then only return the "best" cert per
 *			name
 *	"validOnly" - only return certs that are curently valid
 *	"proto_win" - window handle passed to pkcs11
 */
CERTCertList *
CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
			  SECCertUsage usage,
			  PRBool oneCertPerName,
			  PRBool validOnly,
			  void *proto_win)
{
    CERTCertNicknames *nicknames = NULL;
    char **nnptr;
    int nn;
    CERTCertificate *cert = NULL;
    CERTCertList *certList = NULL;
    SECStatus rv;
    int64 time;
    CERTCertListNode *node = NULL;
    CERTCertListNode *freenode = NULL;
    int n;
    
    time = PR_Now();
    
    nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER,
				      proto_win);
    
    if ( ( nicknames == NULL ) || ( nicknames->numnicknames == 0 ) ) {
	goto loser;
    }

    nnptr = nicknames->nicknames;
    nn = nicknames->numnicknames;

    while ( nn > 0 ) {
	cert = NULL;
	/* use the pk11 call so that we pick up any certs on tokens,
	 * which may require login
	 */
	if ( proto_win != NULL ) {
	    cert = PK11_FindCertFromNickname(*nnptr,proto_win);
	}

	/* Sigh, It turns out if the cert is already in the temp db, because
	 * it's in the perm db, then the nickname lookup doesn't work.
	 * since we already have the cert here, though, than we can just call
	 * CERT_CreateSubjectCertList directly. For those cases where we didn't
	 * find the cert in pkcs #11 (because we didn't have a password arg,
	 * or because the nickname is for a peer, server, or CA cert, then we
	 * go look the cert up.
	 */
	if (cert == NULL) { 
	    cert = CERT_FindCertByNickname(handle,*nnptr);
	}

	if ( cert != NULL ) {
	   /* collect certs for this nickname, sorting them into the list */
	    certList = CERT_CreateSubjectCertList(certList, handle, 
				&cert->derSubject, time, validOnly);

	    CERT_FilterCertListForUserCerts(certList);
	
	    /* drop the extra reference */
	    CERT_DestroyCertificate(cert);
	}
	
	nnptr++;
	nn--;
    }

    /* remove certs with incorrect usage */
    rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);

    if ( rv != SECSuccess ) {
	goto loser;
    }

    /* remove any extra certs for each name */
    if ( oneCertPerName ) {
	PRBool *flags;

	nn = nicknames->numnicknames;
	nnptr = nicknames->nicknames;
	
	flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn);
	if ( flags == NULL ) {
	    goto loser;
	}
	
	node = CERT_LIST_HEAD(certList);
	
	/* treverse all certs in the list */
	while ( !CERT_LIST_END(node, certList) ) {

	    /* find matching nickname index */
	    for ( n = 0; n < nn; n++ ) {
		if ( CERT_MatchNickname(nnptr[n], node->cert->nickname) ) {
		    /* We found a match.  If this is the first one, then
		     * set the flag and move on to the next cert.  If this
		     * is not the first one then delete it from the list.
		     */
		    if ( flags[n] ) {
			/* We have already seen a cert with this nickname,
			 * so delete this one.
			 */
			freenode = node;
			node = CERT_LIST_NEXT(node);
			CERT_RemoveCertListNode(freenode);
		    } else {
			/* keep the first cert for each nickname, but set the
			 * flag so we know to delete any others with the same
			 * nickname.
			 */
			flags[n] = PR_TRUE;
			node = CERT_LIST_NEXT(node);
		    }
		    break;
		}
	    }
	    if ( n == nn ) {
		/* if we get here it means that we didn't find a matching
		 * nickname, which should not happen.
		 */
		PORT_Assert(0);
		node = CERT_LIST_NEXT(node);
	    }
	}
	PORT_Free(flags);
    }

    goto done;
    
loser:
    if ( certList != NULL ) {
	CERT_DestroyCertList(certList);
	certList = NULL;
    }

done:
    if ( nicknames != NULL ) {
	CERT_FreeNicknames(nicknames);
    }

    return(certList);
}