Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
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;
}