Bug 408432, Add Exception fails for certs with no DNS names (no CN, no SAN) r=rrelyea, blocking1.9=dsicore

This commit is contained in:
kaie@kuix.de 2008-01-14 08:04:00 -08:00
parent e277586d41
commit d2c25c96f2
3 changed files with 41 additions and 11 deletions

View File

@ -349,6 +349,7 @@ certErrorTrust_Untrusted=The certificate does not come from a trusted source.
certErrorMismatch=The certificate is not valid for the name %S.
certErrorMismatchSingle2=The certificate is only valid for %S.
certErrorMismatchMultiple=The certificate is only valid for the following names:
certErrorMismatchNoNames=The certificate is not valid for any server names.
certErrorExpired=The certificate expired on %S.
certErrorNotYetValid=The certificate will not be valid until %S.

View File

@ -1505,8 +1505,27 @@ char* nsNSSCertificate::defaultServerNickname(CERTCertificate* cert)
char* servername = nsnull;
servername = CERT_GetCommonName(&cert->subject);
if (servername == NULL) {
return nsnull;
if (!servername) {
// Certs without common names are strange, but they do exist...
// Let's try to use another string for the nickname
servername = CERT_GetOrgUnitName(&cert->subject);
if (!servername) {
servername = CERT_GetOrgName(&cert->subject);
if (!servername) {
servername = CERT_GetLocalityName(&cert->subject);
if (!servername) {
servername = CERT_GetStateName(&cert->subject);
if (!servername) {
servername = CERT_GetCountryName(&cert->subject);
if (!servername) {
// We tried hard, there is nothing more we can do.
// A cert without any names doesn't really make sense.
return nsnull;
}
}
}
}
}
}
count = 1;
@ -1523,7 +1542,7 @@ char* nsNSSCertificate::defaultServerNickname(CERTCertificate* cert)
conflict = SEC_CertNicknameConflict(nickname, &cert->derSubject,
cert->dbhandle);
if (conflict == PR_SUCCESS) {
if (!conflict) {
break;
}
PR_Free(nickname);

View File

@ -787,10 +787,10 @@ static PRBool
GetSubjectAltNames(CERTCertificate *nssCert,
nsINSSComponent *component,
nsString &allNames,
PRBool &multipleNames)
PRUint32 nameCount)
{
allNames.Truncate();
multipleNames = PR_FALSE;
nameCount = 0;
PRArenaPool *san_arena = nsnull;
SECItem altNameExtension = {siBuffer, NULL, 0 };
@ -819,7 +819,7 @@ GetSubjectAltNames(CERTCertificate *nssCert,
case certDNSName:
name.AssignASCII((char*)current->name.other.data, current->name.other.len);
if (!allNames.IsEmpty()) {
multipleNames = PR_TRUE;
++nameCount;
allNames.Append(NS_LITERAL_STRING(" , "));
}
allNames.Append(name);
@ -844,7 +844,7 @@ GetSubjectAltNames(CERTCertificate *nssCert,
}
if (!name.IsEmpty()) {
if (!allNames.IsEmpty()) {
multipleNames = PR_TRUE;
++nameCount;
allNames.Append(NS_LITERAL_STRING(" , "));
}
allNames.Append(name);
@ -893,11 +893,11 @@ AppendErrorTextMismatch(const nsString &host,
}
nsString allNames;
PRBool multipleNames = PR_FALSE;
PRUint32 nameCount = 0;
PRBool useSAN = PR_FALSE;
if (nssCert)
useSAN = GetSubjectAltNames(nssCert, component, allNames, multipleNames);
useSAN = GetSubjectAltNames(nssCert, component, allNames, nameCount);
if (!useSAN) {
char *certName = nsnull;
@ -908,12 +908,13 @@ AppendErrorTextMismatch(const nsString &host,
if (!certName)
certName = CERT_GetCommonName(&nssCert->subject);
if (certName) {
++nameCount;
allNames.AssignASCII(certName);
PORT_Free(certName);
}
}
if (multipleNames) {
if (nameCount > 1) {
nsString message;
rv = component->GetPIPNSSBundleString("certErrorMismatchMultiple",
message);
@ -924,7 +925,7 @@ AppendErrorTextMismatch(const nsString &host,
returnedMessage.Append(NS_LITERAL_STRING(" \n"));
}
}
else { // !multipleNames
else if (nameCount == 1) {
const PRUnichar *params[1];
params[0] = allNames.get();
@ -937,6 +938,15 @@ AppendErrorTextMismatch(const nsString &host,
returnedMessage.Append(NS_LITERAL_STRING("\n"));
}
}
else { // nameCount == 0
nsString message;
nsresult rv = component->GetPIPNSSBundleString("certErrorMismatchNoNames",
message);
if (NS_SUCCEEDED(rv)) {
returnedMessage.Append(message);
returnedMessage.Append(NS_LITERAL_STRING("\n"));
}
}
}
static void