CERTCertList * CERT_MatchUserCert(CERTCertDBHandle *handle, SECCertUsage usage, int nCANames, char **caNames, void *proto_win) { CERTCertList *certList = NULL; SECStatus rv; certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE, proto_win); if ( certList == NULL ) { goto loser; } rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage); if ( rv != SECSuccess ) { goto loser; } goto done; loser: if ( certList != NULL ) { CERT_DestroyCertList(certList); certList = NULL; } done: return(certList); }
static CERTCertificate * get_signer_cert(char *addr) { CERTCertDBHandle *handle; CERTCertList *list; CERTCertListNode *node; CERTCertificate *cert = NULL; const char *cp; char *nick; char *vn; int vs, found = 0; addr = skin(addr); vn = ac_alloc(vs = strlen(addr) + 30); snprintf(vn, vs, "smime-sign-nickname-%s", addr); if ((nick = value(vn)) == NULL) nick = value("smime-sign-nickname"); ac_free(vn); handle = CERT_GetDefaultCertDB(); if (nick) { cert = CERT_FindCertByNickname(handle, nick); if (cert == NULL) fprintf(stderr, "No certificate \"%s\" found.\n", nick); return cert; } if ((list = CERT_FindUserCertsByUsage(handle, certUsageEmailSigner, PR_TRUE, PR_TRUE, NULL)) == NULL) { fprintf(stderr, "Cannot find any certificates for signing.\n"); return NULL; } for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node)) { if ((cp = CERT_GetCertEmailAddress(&node->cert->subject)) != NULL && asccasecmp(cp, addr) == 0) { cert = node->cert; found++; } } if (cert == NULL) { for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node, list) && cert == NULL; node = CERT_LIST_NEXT(node)) { cp = CERT_GetFirstEmailAddress(node->cert); while (cp) { if (asccasecmp(cp, addr) == 0) { cert = node->cert; found++; } cp = CERT_GetNextEmailAddress(node->cert, cp); } } } if (found > 1) { fprintf(stderr, "More than one signing certificate found for <%s>.\n" "Use the smime-sign-nickname variable.\n", addr); return NULL; } if (cert == NULL) fprintf(stderr, "Cannot find a signing certificate for <%s>.\n", addr); return cert; }
NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx, const PRUnichar *selectedNickname, PRInt32 certUsage, bool allowInvalid, bool allowDuplicateNicknames, bool *canceled, nsIX509Cert **_retval) { nsNSSShutDownPreventionLock locker; PRInt32 selectedIndex = -1; bool selectionFound = false; PRUnichar **certNicknameList = nsnull; PRUnichar **certDetailsList = nsnull; CERTCertListNode* node = nsnull; nsresult rv = NS_OK; { // Iterate over all certs. This assures that user is logged in to all hardware tokens. CERTCertList *allcerts = nsnull; nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext(); allcerts = PK11_ListCerts(PK11CertListUnique, ctx); CERT_DestroyCertList(allcerts); } /* find all user certs that are valid and for SSL */ /* note that we are allowing expired certs in this list */ CERTCertList *certList = CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), (SECCertUsage)certUsage, !allowDuplicateNicknames, !allowInvalid, ctx); CERTCertListCleaner clc(certList); if (!certList) { return NS_ERROR_NOT_AVAILABLE; } CERTCertNicknames *nicknames = getNSSCertNicknamesFromCertList(certList); CERTCertNicknamesCleaner cnc(nicknames); if (!nicknames) { return NS_ERROR_NOT_AVAILABLE; } certNicknameList = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * nicknames->numnicknames); certDetailsList = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * nicknames->numnicknames); if (!certNicknameList || !certDetailsList) { nsMemory::Free(certNicknameList); nsMemory::Free(certDetailsList); return NS_ERROR_OUT_OF_MEMORY; } PRInt32 CertsToUse; for (CertsToUse = 0, node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList) && CertsToUse < nicknames->numnicknames; node = CERT_LIST_NEXT(node) ) { nsNSSCertificate *tempCert = nsNSSCertificate::Create(node->cert); if (tempCert) { // XXX we really should be using an nsCOMPtr instead of manually add-refing, // but nsNSSCertificate does not have a default constructor. NS_ADDREF(tempCert); nsAutoString i_nickname(NS_ConvertUTF8toUTF16(nicknames->nicknames[CertsToUse])); nsAutoString nickWithSerial; nsAutoString details; if (!selectionFound) { if (i_nickname == nsDependentString(selectedNickname)) { selectedIndex = CertsToUse; selectionFound = PR_TRUE; } } if (NS_SUCCEEDED(tempCert->FormatUIStrings(i_nickname, nickWithSerial, details))) { certNicknameList[CertsToUse] = ToNewUnicode(nickWithSerial); certDetailsList[CertsToUse] = ToNewUnicode(details); } else { certNicknameList[CertsToUse] = nsnull; certDetailsList[CertsToUse] = nsnull; } NS_RELEASE(tempCert); ++CertsToUse; } } if (CertsToUse) { nsICertPickDialogs *dialogs = nsnull; rv = getNSSDialogs((void**)&dialogs, NS_GET_IID(nsICertPickDialogs), NS_CERTPICKDIALOGS_CONTRACTID); if (NS_SUCCEEDED(rv)) { nsPSMUITracker tracker; if (tracker.isUIForbidden()) { rv = NS_ERROR_NOT_AVAILABLE; } else { /* Throw up the cert picker dialog and get back the index of the selected cert */ rv = dialogs->PickCertificate(ctx, (const PRUnichar**)certNicknameList, (const PRUnichar**)certDetailsList, CertsToUse, &selectedIndex, canceled); } NS_RELEASE(dialogs); } } PRInt32 i; for (i = 0; i < CertsToUse; ++i) { nsMemory::Free(certNicknameList[i]); nsMemory::Free(certDetailsList[i]); } nsMemory::Free(certNicknameList); nsMemory::Free(certDetailsList); if (!CertsToUse) { return NS_ERROR_NOT_AVAILABLE; } if (NS_SUCCEEDED(rv) && !*canceled) { for (i = 0, node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); ++i, node = CERT_LIST_NEXT(node)) { if (i == selectedIndex) { nsNSSCertificate *cert = nsNSSCertificate::Create(node->cert); if (!cert) { rv = NS_ERROR_OUT_OF_MEMORY; break; } nsIX509Cert *x509 = 0; nsresult rv = cert->QueryInterface(NS_GET_IID(nsIX509Cert), (void**)&x509); if (NS_FAILED(rv)) { break; } NS_ADDREF(x509); *_retval = x509; NS_RELEASE(cert); break; } } } return rv; }