NS_IMETHODIMP nsNSSCertificate::ContainsEmailAddress(const nsAString &aEmailAddress, bool *result) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; NS_ENSURE_ARG(result); *result = false; const char *aAddr = nullptr; for (aAddr = CERT_GetFirstEmailAddress(mCert) ; aAddr ; aAddr = CERT_GetNextEmailAddress(mCert, aAddr)) { NS_ConvertUTF8toUTF16 certAddr(aAddr); ToLowerCase(certAddr); nsAutoString testAddr(aEmailAddress); ToLowerCase(testAddr); if (certAddr == testAddr) { *result = true; break; } } return NS_OK; }
NS_IMETHODIMP nsNSSCertificate::GetEmailAddresses(uint32_t *aLength, PRUnichar*** aAddresses) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; NS_ENSURE_ARG(aLength); NS_ENSURE_ARG(aAddresses); *aLength = 0; const char *aAddr; for (aAddr = CERT_GetFirstEmailAddress(mCert) ; aAddr ; aAddr = CERT_GetNextEmailAddress(mCert, aAddr)) { ++(*aLength); } *aAddresses = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * (*aLength)); if (!*aAddresses) return NS_ERROR_OUT_OF_MEMORY; uint32_t iAddr; for (aAddr = CERT_GetFirstEmailAddress(mCert), iAddr = 0 ; aAddr ; aAddr = CERT_GetNextEmailAddress(mCert, aAddr), ++iAddr) { (*aAddresses)[iAddr] = ToNewUnicode(NS_ConvertUTF8toUTF16(aAddr)); } return NS_OK; }
static int verify1(struct message *m, int n) { SECItem **digests; NSSCMSMessage *msg; PLArenaPool *poolp; SECAlgorithmID **algids; CERTCertDBHandle *handle; int nlevels, i; int status = 0; int foundsender = 0; char *sender; if ((m = getsig(m, n, &msg)) == NULL) return 1; sender = getsender(m); handle = CERT_GetDefaultCertDB(); nlevels = NSS_CMSMessage_ContentLevelCount(msg); for (i = 0; i < nlevels; i++) { NSSCMSContentInfo *content; SECOidTag tag; content = NSS_CMSMessage_ContentLevel(msg, i); tag = NSS_CMSContentInfo_GetContentTypeTag(content); if (tag == SEC_OID_PKCS7_SIGNED_DATA) { NSSCMSSignedData *data; int nsigners, j; if ((data = NSS_CMSContentInfo_GetContent(content)) == NULL) { fprintf(stderr, "Signed data missing for " "message %d.\n", n); status = -1; break; } if (!NSS_CMSSignedData_HasDigests(data)) { algids = NSS_CMSSignedData_GetDigestAlgs(data); if (getdig(m, n, &digests, &poolp, algids) != OKAY) { status = -1; break; } if (NSS_CMSSignedData_SetDigests(data, algids, digests) != SECSuccess) { fprintf(stderr, "Cannot set digests " "for message %d.\n", n); status = -1; break; } PORT_FreeArena(poolp, PR_FALSE); } if (NSS_CMSSignedData_ImportCerts(data, handle, certUsageEmailSigner, PR_FALSE) != SECSuccess) { fprintf(stderr, "Cannot temporarily import " "certificates for " "message %d.\n", n); status = -1; break; } nsigners = NSS_CMSSignedData_SignerInfoCount(data); if (nsigners == 0) { fprintf(stderr, "Message %d has no signers.\n", n); status = -1; break; } if (!NSS_CMSSignedData_HasDigests(data)) { fprintf(stderr, "Message %d has no digests.\n", n); status = -1; break; } for (j = 0; j < nsigners; j++) { const char *svs; NSSCMSSignerInfo *info; NSSCMSVerificationStatus vs; SECStatus bad; CERTCertificate *cert; const char *addr; int passed = 0; info = NSS_CMSSignedData_GetSignerInfo(data, j); cert = NSS_CMSSignerInfo_GetSigningCertificate (info, handle); bad = NSS_CMSSignedData_VerifySignerInfo(data, j, handle, certUsageEmailSigner); vs = NSS_CMSSignerInfo_GetVerificationStatus (info); svs = NSS_CMSUtil_VerificationStatusToString (vs); addr = CERT_GetCertEmailAddress(&cert->subject); if (sender != NULL && addr != NULL && asccasecmp(sender, addr) == 0) foundsender++; else { addr = CERT_GetFirstEmailAddress(cert); while (sender && addr) { if (!asccasecmp(sender, addr)) { foundsender++; break; } addr = CERT_GetNextEmailAddress (cert, addr); } } if (CERT_VerifyCertNow(handle, cert, PR_TRUE, certUsageEmailSigner, NULL) != SECSuccess) fprintf(stderr, "Bad certificate for " "signer <%s> of " "message %d: %s.\n", addr ? addr : "?", n, bad_cert_str()); else passed++; if (bad) fprintf(stderr, "Bad status for " "signer <%s> of " "message %d: %s.\n", addr ? addr : "?", n, svs); else passed++; if (passed < 2) status = -1; else if (status == 0) status = 1; } } } if (foundsender == 0) { if (sender) { fprintf(stderr, "Signers of message " "%d do not include the sender <%s>\n", n, sender); status = -1; } else fprintf(stderr, "Warning: Message %d has no From: " "header field.\n", n); } else if (status == 1) printf("Message %d was verified successfully.\n", n); if (status == 0) fprintf(stderr, "No verification information found in " "message %d.\n", n); NSS_CMSMessage_Destroy(msg); return status != 1; }
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; }
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; }