зеркало из https://github.com/mozilla/pjs.git
b=50823 S/Mime: Support certificates with multiple listed email addresses
r=javi sr=alecf
This commit is contained in:
Родитель
9eae2082b5
Коммит
7f319292df
|
@ -225,6 +225,8 @@ MimeCMSHeadersAndCertsMatch(MimeObject *obj,
|
|||
*/
|
||||
if (content_info)
|
||||
{
|
||||
// Extract any address contained in the cert.
|
||||
// This will be used for testing, whether the cert contains no addresses at all.
|
||||
content_info->GetSignerEmailAddress (getter_Copies(cert_addr));
|
||||
}
|
||||
|
||||
|
@ -283,53 +285,54 @@ MimeCMSHeadersAndCertsMatch(MimeObject *obj,
|
|||
|
||||
/* Now compare them --
|
||||
consider it a match if the address in the cert matches either the
|
||||
address in the From or Sender field; and if the name in the cert
|
||||
matches either the name in the From or Sender field.
|
||||
|
||||
Consider it a match if the cert does not contain a name (address.)
|
||||
But do not consider it a match if the cert contains a name (address)
|
||||
but the message headers do not.
|
||||
address in the From or Sender field
|
||||
*/
|
||||
|
||||
/* ======================================================================
|
||||
First check the addresses.
|
||||
*/
|
||||
PRBool foundFrom = PR_FALSE;
|
||||
PRBool foundSender = PR_FALSE;
|
||||
|
||||
/* If there is no addr in the cert, it can not match and we fail. */
|
||||
/* If there is no addr in the cert at all, it can not match and we fail. */
|
||||
if (!cert_addr)
|
||||
match = PR_FALSE;
|
||||
|
||||
/* If there is both a from and sender address, and if neither of
|
||||
them match, then error. */
|
||||
else if (from_addr && *from_addr &&
|
||||
sender_addr && *sender_addr)
|
||||
{
|
||||
if (nsCRT::strcasecmp(cert_addr, from_addr) &&
|
||||
nsCRT::strcasecmp(cert_addr, sender_addr))
|
||||
match = PR_FALSE;
|
||||
}
|
||||
/* If there is a from but no sender, and it doesn't match, then error. */
|
||||
else if (from_addr && *from_addr)
|
||||
{
|
||||
if (nsCRT::strcasecmp(cert_addr, from_addr))
|
||||
match = PR_FALSE;
|
||||
}
|
||||
/* If there is a sender but no from, and it doesn't match, then error. */
|
||||
else if (sender_addr && *sender_addr)
|
||||
{
|
||||
if (nsCRT::strcasecmp(cert_addr, sender_addr))
|
||||
match = PR_FALSE;
|
||||
}
|
||||
/* Else there are no addresses at all -- error. */
|
||||
{
|
||||
match = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
match = PR_FALSE;
|
||||
}
|
||||
{
|
||||
nsCOMPtr<nsIX509Cert> signerCert;
|
||||
content_info->GetSignerCert(getter_AddRefs(signerCert));
|
||||
|
||||
if (signerCert)
|
||||
{
|
||||
if (from_addr && *from_addr)
|
||||
{
|
||||
NS_ConvertASCIItoUCS2 ucs2From(from_addr);
|
||||
if (NS_FAILED(signerCert->ContainsEmailAddress(ucs2From, &foundFrom)))
|
||||
{
|
||||
foundFrom = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (sender_addr && *sender_addr)
|
||||
{
|
||||
NS_ConvertASCIItoUCS2 ucs2Sender(sender_addr);
|
||||
if (NS_FAILED(signerCert->ContainsEmailAddress(ucs2Sender, &foundSender)))
|
||||
{
|
||||
foundSender = PR_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSender && !foundFrom)
|
||||
{
|
||||
match = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (sender_email_addr_return) {
|
||||
if (match && cert_addr)
|
||||
*sender_email_addr_return = nsCRT::strdup(cert_addr);
|
||||
if (match && foundFrom)
|
||||
*sender_email_addr_return = nsCRT::strdup(from_addr);
|
||||
if (match && foundSender)
|
||||
*sender_email_addr_return = nsCRT::strdup(sender_addr);
|
||||
else if (from_addr && *from_addr)
|
||||
*sender_email_addr_return = nsCRT::strdup(from_addr);
|
||||
else if (sender_addr && *sender_addr)
|
||||
|
|
|
@ -55,6 +55,27 @@ interface nsIX509Cert : nsISupports {
|
|||
*/
|
||||
readonly attribute AString emailAddress;
|
||||
|
||||
/**
|
||||
* Obtain a list of all email addresses
|
||||
* contained in the certificate.
|
||||
*
|
||||
* @param length The number of strings in the returned array.
|
||||
* @return An array of email addresses.
|
||||
*/
|
||||
void getEmailAddresses(out unsigned long length,
|
||||
[retval, array, size_is(length)] out wstring addresses);
|
||||
|
||||
/**
|
||||
* Check whether a given address is contained in the certificate.
|
||||
* The comparison will convert the email address to lowercase.
|
||||
* The behaviour for non ASCII characters is undefined.
|
||||
*
|
||||
* @param aEmailAddress The address to search for.
|
||||
*
|
||||
* @return True if the address is contained in the certificate.
|
||||
*/
|
||||
boolean containsEmailAddress(in AString aEmailAddress);
|
||||
|
||||
/**
|
||||
* The subject owning the certificate.
|
||||
*/
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
#include "nsUsageArrayHelper.h"
|
||||
#include "nsICertificateDialogs.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
|
||||
#include "nspr.h"
|
||||
extern "C" {
|
||||
|
@ -413,6 +415,7 @@ nsNSSCertificate::GetNickname(nsAString &_nickname)
|
|||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// XXX kaie: this is bad. We return a non localizable hardcoded string.
|
||||
const char *nickname = (mCert->nickname) ? mCert->nickname : "(no nickname)";
|
||||
_nickname = NS_ConvertUTF8toUCS2(nickname);
|
||||
return NS_OK;
|
||||
|
@ -425,11 +428,86 @@ nsNSSCertificate::GetEmailAddress(nsAString &_emailAddress)
|
|||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// XXX kaie: this is bad. We return a non localizable hardcoded string.
|
||||
// And agents could be confused, assuming the email address == "(no nickname)"
|
||||
const char *email = (mCert->emailAddr) ? mCert->emailAddr : "(no email address)";
|
||||
_emailAddress = NS_ConvertUTF8toUCS2(email);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetEmailAddresses(PRUint32 *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;
|
||||
|
||||
PRUint32 iAddr;
|
||||
for (aAddr = CERT_GetFirstEmailAddress(mCert), iAddr = 0
|
||||
;
|
||||
aAddr
|
||||
;
|
||||
aAddr = CERT_GetNextEmailAddress(mCert, aAddr), ++iAddr)
|
||||
{
|
||||
(*aAddresses)[iAddr] = ToNewUnicode(NS_ConvertUTF8toUCS2(aAddr));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::ContainsEmailAddress(const nsAString &aEmailAddress, PRBool *result)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
NS_ENSURE_ARG(result);
|
||||
*result = PR_FALSE;
|
||||
|
||||
const char *aAddr = nsnull;
|
||||
for (aAddr = CERT_GetFirstEmailAddress(mCert)
|
||||
;
|
||||
aAddr
|
||||
;
|
||||
aAddr = CERT_GetNextEmailAddress(mCert, aAddr))
|
||||
{
|
||||
NS_ConvertUTF8toUCS2 certAddr(aAddr);
|
||||
ToLowerCase(certAddr);
|
||||
|
||||
nsAutoString testAddr(aEmailAddress);
|
||||
ToLowerCase(testAddr);
|
||||
|
||||
if (certAddr == testAddr)
|
||||
{
|
||||
*result = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertificate::GetCommonName(nsAString &aCommonName)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче