зеркало из https://github.com/mozilla/gecko-dev.git
Bug 682927 - Dis-trust DigiNotar root certificate, part 3; r=kaie,dveditz
This commit is contained in:
Родитель
2552ad09db
Коммит
2789fe6ab4
|
@ -1038,6 +1038,53 @@ 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.
|
||||
PRErrorCode
|
||||
PSM_SSL_BlacklistDigiNotar(CERTCertificate * serverCert,
|
||||
CERTCertList * serverCertChain)
|
||||
{
|
||||
PRBool isDigiNotarIssuedCert = PR_FALSE;
|
||||
|
||||
for (CERTCertListNode *node = CERT_LIST_HEAD(serverCertChain);
|
||||
!CERT_LIST_END(node, serverCertChain);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
if (!node->cert->issuerName)
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// By request of the Dutch government
|
||||
if (!strcmp(node->cert->issuerName,
|
||||
"CN=Staat der Nederlanden Root CA,O=Staat der Nederlanden,C=NL") &&
|
||||
CERT_LIST_END(CERT_LIST_NEXT(node), serverCertChain)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDigiNotarIssuedCert)
|
||||
return SEC_ERROR_UNTRUSTED_ISSUER; // user can override this
|
||||
else
|
||||
return 0; // No DigiNotor cert => carry on as normal
|
||||
}
|
||||
|
||||
|
||||
SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
|
||||
PRBool checksig, PRBool isServer) {
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
|
@ -1083,7 +1130,7 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SECStatus rv = PSM_SSL_PKIX_AuthCertificate(fd, serverCert, checksig, isServer);
|
||||
|
||||
// We want to remember the CA certs in the temp db, so that the application can find the
|
||||
|
@ -1099,14 +1146,28 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
|
|||
nsc = nsNSSCertificate::Create(serverCert);
|
||||
}
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
if (nsc) {
|
||||
PRBool dummyIsEV;
|
||||
nsc->GetIsExtendedValidation(&dummyIsEV); // the nsc object will cache the status
|
||||
}
|
||||
|
||||
CERTCertList *certList = CERT_GetCertChainFromCert(serverCert, PR_Now(), certUsageSSLCA);
|
||||
|
||||
nsCOMPtr<nsINSSComponent> nssComponent;
|
||||
|
||||
for (CERTCertListNode *node = CERT_LIST_HEAD(certList);
|
||||
|
@ -1142,6 +1203,9 @@ SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
|
|||
PR_FREEIF(nickname);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (certList) {
|
||||
CERT_DestroyCertList(certList);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,9 @@ void PR_CALLBACK HandshakeCallback(PRFileDesc *fd, void *client_data);
|
|||
SECStatus PR_CALLBACK AuthCertificateCallback(void* client_data, PRFileDesc* fd,
|
||||
PRBool checksig, PRBool isServer);
|
||||
|
||||
PRErrorCode PSM_SSL_BlacklistDigiNotar(CERTCertificate * serverCert,
|
||||
CERTCertList * serverCertChain);
|
||||
|
||||
SECStatus RegisterMyOCSPAIAInfoCallback();
|
||||
SECStatus UnregisterMyOCSPAIAInfoCallback();
|
||||
|
||||
|
|
|
@ -226,7 +226,8 @@ nsNSSSocketInfo::nsNSSSocketInfo()
|
|||
mAllowTLSIntoleranceTimeout(PR_TRUE),
|
||||
mRememberClientAuthCertificate(PR_FALSE),
|
||||
mHandshakeStartTime(0),
|
||||
mPort(0)
|
||||
mPort(0),
|
||||
mIsCertIssuerBlacklisted(PR_FALSE)
|
||||
{
|
||||
mThreadData = new nsSSLSocketThreadData;
|
||||
}
|
||||
|
@ -3440,6 +3441,10 @@ nsNSSBadCertHandler(void *arg, PRFileDesc *sslSocket)
|
|||
cvout, (void*)infoObject);
|
||||
}
|
||||
|
||||
if (infoObject->IsCertIssuerBlacklisted()) {
|
||||
collected_errors |= nsICertOverrideService::ERROR_UNTRUSTED;
|
||||
}
|
||||
|
||||
// We ignore the result code of the cert verification.
|
||||
// Either it is a failure, which is expected, and we'll process the
|
||||
// verify log below.
|
||||
|
|
|
@ -202,6 +202,12 @@ public:
|
|||
|
||||
PRStatus CloseSocketAndDestroy();
|
||||
|
||||
PRBool IsCertIssuerBlacklisted() const {
|
||||
return mIsCertIssuerBlacklisted;
|
||||
}
|
||||
void SetCertIssuerBlacklisted() {
|
||||
mIsCertIssuerBlacklisted = PR_TRUE;
|
||||
}
|
||||
protected:
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
PRFileDesc* mFd;
|
||||
|
@ -229,6 +235,7 @@ protected:
|
|||
PRIntervalTime mHandshakeStartTime;
|
||||
PRInt32 mPort;
|
||||
nsXPIDLCString mHostName;
|
||||
PRErrorCode mIsCertIssuerBlacklisted;
|
||||
|
||||
/* SSL Status */
|
||||
nsRefPtr<nsSSLStatus> mSSLStatus;
|
||||
|
|
Загрузка…
Ссылка в новой задаче