Bug 596221, PSM should use new function to find encryption certificates of email recipients -- Original patch contributed by Juergen Brauckmann, enhanced by me -- r=rrelyea -- Should fix bug 558337 and bug 337430, too.

This commit is contained in:
Kai Engert 2011-06-28 14:26:41 +02:00
parent 3f2027861d
commit d7ca4b6cc6

View File

@ -1497,27 +1497,65 @@ NS_IMETHODIMP
nsNSSCertificateDB::FindCertByEmailAddress(nsISupports *aToken, const char *aEmailAddress, nsIX509Cert **_retval)
{
nsNSSShutDownPreventionLock locker;
CERTCertificate *any_cert = CERT_FindCertByNicknameOrEmailAddr(CERT_GetDefaultCertDB(), (char*)aEmailAddress);
if (!any_cert)
return NS_ERROR_FAILURE;
nsCOMPtr<nsINSSComponent> inss;
nsRefPtr<nsCERTValInParamWrapper> survivingParams;
nsresult nsrv;
if (nsNSSComponent::globalConstFlagUsePKIXVerification) {
inss = do_GetService(kNSSComponentCID, &nsrv);
if (!inss)
return nsrv;
nsrv = inss->GetDefaultCERTValInParam(survivingParams);
if (NS_FAILED(nsrv))
return nsrv;
}
CERTCertificateCleaner certCleaner(any_cert);
// any_cert now contains a cert with the right subject, but it might not have the correct usage
CERTCertList *certlist = CERT_CreateSubjectCertList(
nsnull, CERT_GetDefaultCertDB(), &any_cert->derSubject, PR_Now(), PR_TRUE);
CERTCertList *certlist = PK11_FindCertsFromEmailAddress(aEmailAddress, nsnull);
if (!certlist)
return NS_ERROR_FAILURE;
// certlist now contains certificates with the right email address,
// but they might not have the correct usage or might even be invalid
CERTCertListCleaner listCleaner(certlist);
if (SECSuccess != CERT_FilterCertListByUsage(certlist, certUsageEmailRecipient, PR_FALSE))
return NS_ERROR_FAILURE;
if (CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist))
return NS_ERROR_FAILURE; // no certs found
CERTCertListNode *node;
// search for a valid certificate
for (node = CERT_LIST_HEAD(certlist);
!CERT_LIST_END(node, certlist);
node = CERT_LIST_NEXT(node)) {
if (!nsNSSComponent::globalConstFlagUsePKIXVerification) {
if (CERT_VerifyCert(CERT_GetDefaultCertDB(), node->cert,
PR_TRUE, certUsageEmailRecipient, PR_Now(), nsnull, nsnull) == SECSuccess) {
// found a valid certificate
break;
}
}
else {
CERTValOutParam cvout[1];
cvout[0].type = cert_po_end;
if (CERT_PKIXVerifyCert(node->cert, certificateUsageEmailRecipient,
survivingParams->GetRawPointerForNSS(),
cvout, nsnull)
== SECSuccess) {
// found a valid certificate
break;
}
}
}
if (CERT_LIST_END(node, certlist)) {
// no valid cert found
return NS_ERROR_FAILURE;
nsNSSCertificate *nssCert = nsNSSCertificate::Create(CERT_LIST_HEAD(certlist)->cert);
}
// node now contains the first valid certificate with correct usage
nsNSSCertificate *nssCert = nsNSSCertificate::Create(node->cert);
if (!nssCert)
return NS_ERROR_OUT_OF_MEMORY;