mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 683883 - Improve DigitNotarGate handling in PSM; r=rrelyea
This commit is contained in:
parent
71d64d5d55
commit
472f2f1189
@ -1038,9 +1038,43 @@ static struct nsSerialBinaryBlacklistEntry myUTNBlacklistEntries[] = {
|
||||
{ 0, 0 } // end marker
|
||||
};
|
||||
|
||||
// Bug 682927: Do not trust any DigiNotar-issued certificates.
|
||||
// We do this check after normal certificate validation because we do not
|
||||
// want to override a "revoked" OCSP response.
|
||||
// Call this if we have already decided that a cert should be treated as INVALID,
|
||||
// in order to check if we to worsen the error to REVOKED.
|
||||
PRErrorCode
|
||||
PSM_SSL_DigiNotarTreatAsRevoked(CERTCertificate * serverCert,
|
||||
CERTCertList * serverCertChain)
|
||||
{
|
||||
// If any involved cert was issued by DigiNotar,
|
||||
// and serverCert was issued after 01-JUL-2011,
|
||||
// then worsen the error to revoked.
|
||||
|
||||
PRTime cutoff = 0;
|
||||
PRStatus status = PR_ParseTimeString("01-JUL-2011 00:00", PR_TRUE, &cutoff);
|
||||
if (status != PR_SUCCESS) {
|
||||
NS_ASSERTION(status == PR_SUCCESS, "PR_ParseTimeString failed");
|
||||
// be safe, assume it's afterwards, keep going
|
||||
} else {
|
||||
PRTime notBefore = 0, notAfter = 0;
|
||||
if (CERT_GetCertTimes(serverCert, ¬Before, ¬After) == SECSuccess &&
|
||||
notBefore < cutoff) {
|
||||
// no worsening for certs issued before the cutoff date
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (CERTCertListNode *node = CERT_LIST_HEAD(serverCertChain);
|
||||
!CERT_LIST_END(node, serverCertChain);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
if (node->cert->issuerName &&
|
||||
strstr(node->cert->issuerName, "CN=DigiNotar")) {
|
||||
return SEC_ERROR_REVOKED_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Call this only if a cert has been reported by NSS as VALID
|
||||
PRErrorCode
|
||||
PSM_SSL_BlacklistDigiNotar(CERTCertificate * serverCert,
|
||||
CERTCertList * serverCertChain)
|
||||
@ -1053,28 +1087,30 @@ PSM_SSL_BlacklistDigiNotar(CERTCertificate * serverCert,
|
||||
if (!node->cert->issuerName)
|
||||
continue;
|
||||
|
||||
// If it's one of the "Staat der Nederlanden Root"s, then don't blacklist.
|
||||
// Compare names, and ensure it's a self-signed root.
|
||||
if ((!strcmp(node->cert->issuerName,
|
||||
"CN=Staat der Nederlanden Root CA,O=Staat der Nederlanden,C=NL") ||
|
||||
!strcmp(node->cert->issuerName,
|
||||
"CN=Staat der Nederlanden Root CA - G2,O=Staat der Nederlanden,C=NL")) &&
|
||||
SECITEM_ItemsAreEqual(&node->cert->derIssuer,&node->cert->derSubject)
|
||||
) {
|
||||
// keep as valid
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strstr(node->cert->issuerName, "CN=DigiNotar")) {
|
||||
isDigiNotarIssuedCert = PR_TRUE;
|
||||
// Do not let the user override the error if the cert was
|
||||
// chained from the "DigiNotar Root CA" cert and the cert was issued
|
||||
// within the time window in which we think the mis-issuance(s) occurred.
|
||||
if (strstr(node->cert->issuerName, "CN=DigiNotar Root CA")) {
|
||||
PRTime cutoff = 0, notBefore = 0, notAfter = 0;
|
||||
PRStatus status = PR_ParseTimeString("01-JUL-2011 00:00", PR_TRUE, &cutoff);
|
||||
NS_ASSERTION(status == PR_SUCCESS, "PR_ParseTimeString failed");
|
||||
if (status != PR_SUCCESS ||
|
||||
CERT_GetCertTimes(serverCert, ¬Before, ¬After) != SECSuccess ||
|
||||
notBefore >= cutoff) {
|
||||
return SEC_ERROR_REVOKED_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDigiNotarIssuedCert)
|
||||
return SEC_ERROR_UNTRUSTED_ISSUER; // user can override this
|
||||
else
|
||||
return 0; // No DigiNotor cert => carry on as normal
|
||||
if (isDigiNotarIssuedCert) {
|
||||
// let's see if we want to worsen the error code to revoked.
|
||||
PRErrorCode revoked_code = PSM_SSL_DigiNotarTreatAsRevoked(serverCert, serverCertChain);
|
||||
return (revoked_code != 0) ? revoked_code : SEC_ERROR_UNTRUSTED_ISSUER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1140,19 +1176,28 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
|
||||
}
|
||||
|
||||
CERTCertList *certList = nsnull;
|
||||
if (rv == SECSuccess) {
|
||||
certList = CERT_GetCertChainFromCert(serverCert, PR_Now(), certUsageSSLCA);
|
||||
if (!certList) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
PRErrorCode blacklistErrorCode = PSM_SSL_BlacklistDigiNotar(serverCert,
|
||||
certList);
|
||||
if (blacklistErrorCode != 0) {
|
||||
infoObject->SetCertIssuerBlacklisted();
|
||||
PORT_SetError(blacklistErrorCode);
|
||||
rv = SECFailure;
|
||||
certList = CERT_GetCertChainFromCert(serverCert, PR_Now(), certUsageSSLCA);
|
||||
if (!certList) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
PRErrorCode blacklistErrorCode;
|
||||
if (rv == SECSuccess) { // PSM_SSL_PKIX_AuthCertificate said "valid cert"
|
||||
blacklistErrorCode = PSM_SSL_BlacklistDigiNotar(serverCert, certList);
|
||||
} else { // PSM_SSL_PKIX_AuthCertificate said "invalid cert"
|
||||
PRErrorCode savedErrorCode = PORT_GetError();
|
||||
// Check if we want to worsen the error code to "revoked".
|
||||
blacklistErrorCode = PSM_SSL_DigiNotarTreatAsRevoked(serverCert, certList);
|
||||
if (blacklistErrorCode == 0) {
|
||||
// we don't worsen the code, let's keep the original error code from NSS
|
||||
PORT_SetError(savedErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
if (blacklistErrorCode != 0) {
|
||||
infoObject->SetCertIssuerBlacklisted();
|
||||
PORT_SetError(blacklistErrorCode);
|
||||
rv = SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
|
Loading…
Reference in New Issue
Block a user