[xulrunner/f14] Distrust a specific Certificate Authority
Jan Horak
xhorak at fedoraproject.org
Wed Aug 31 09:49:26 UTC 2011
commit e9fc6c0cdda62473cc2a107549f9bbff08250528
Author: Jan Horak <jhorak at redhat.com>
Date: Wed Aug 31 11:49:07 2011 +0200
Distrust a specific Certificate Authority
xulrunner-diginotar.patch | 278 +++++++++++++++++++++++++++++++++++++++++++++
xulrunner.spec | 7 +-
2 files changed, 284 insertions(+), 1 deletions(-)
---
diff --git a/xulrunner-diginotar.patch b/xulrunner-diginotar.patch
new file mode 100644
index 0000000..af69fd2
--- /dev/null
+++ b/xulrunner-diginotar.patch
@@ -0,0 +1,278 @@
+# HG changeset patch
+# User Brian Smith <bsmith at mozilla.com>
+# Date 1314714784 14400
+# Node ID b01c24423221e4e88447d24c17412fbba9913993
+# Parent cbe67e60d8c0f10dbc34768cac7e0b0821674dc2
+Bug 682927 - Dis-trust DigiNotar root certificate, part 3; r=kaie,dveditz a=me
+
+diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp
+--- a/security/manager/ssl/src/nsNSSCallbacks.cpp
++++ b/security/manager/ssl/src/nsNSSCallbacks.cpp
+@@ -997,16 +997,63 @@ static struct nsSerialBinaryBlacklistEnt
+ { 16, "\x3e\x75\xce\xd4\x6b\x69\x30\x21\x21\x88\x30\xae\x86\xa8\x2a\x71" },
+ { 17, "\x00\xe9\x02\x8b\x95\x78\xe4\x15\xdc\x1a\x71\x0a\x2b\x88\x15\x44\x47" },
+ { 17, "\x00\xd7\x55\x8f\xda\xf5\xf1\x10\x5b\xb2\x13\x28\x2b\x70\x77\x29\xa3" },
+ { 16, "\x04\x7e\xcb\xe9\xfc\xa5\x5f\x7b\xd0\x9e\xae\x36\xe1\x0c\xae\x1e" },
+ { 17, "\x00\xf5\xc8\x6a\xf3\x61\x62\xf1\x3a\x64\xf5\x4f\x6d\xc9\x58\x7c\x06" },
+ { 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;
+
+ CERTCertificate *serverCert = SSL_PeerCertificate(fd);
+ CERTCertificateCleaner serverCertCleaner(serverCert);
+
+ if (serverCert &&
+@@ -1059,24 +1106,38 @@ SECStatus PR_CALLBACK AuthCertificateCal
+ nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
+ nsRefPtr<nsSSLStatus> status = infoObject->SSLStatus();
+ nsRefPtr<nsNSSCertificate> nsc;
+
+ if (!status || !status->mServerCert) {
+ nsc = new nsNSSCertificate(serverCert);
+ }
+
++ 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 (SECSuccess == rv) {
+ 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);
+ !CERT_LIST_END(node, certList);
+ node = CERT_LIST_NEXT(node)) {
+
+ if (node->cert->slot) {
+ // This cert was found on a token, no need to remember it in the temp db.
+@@ -1102,16 +1163,19 @@ SECStatus PR_CALLBACK AuthCertificateCal
+ if (slot) {
+ PK11_ImportCert(slot, node->cert, CK_INVALID_HANDLE,
+ const_cast<char*>(nickname.get()), PR_FALSE);
+ PK11_FreeSlot(slot);
+ }
+ }
+ }
+
++ }
++
++ if (certList) {
+ CERT_DestroyCertList(certList);
+ }
+
+ // The connection may get terminated, for example, if the server requires
+ // a client cert. Let's provide a minimal SSLStatus
+ // to the caller that contains at least the cert and its status.
+ if (!status) {
+ status = new nsSSLStatus();
+diff --git a/security/manager/ssl/src/nsNSSCallbacks.h b/security/manager/ssl/src/nsNSSCallbacks.h
+--- a/security/manager/ssl/src/nsNSSCallbacks.h
++++ b/security/manager/ssl/src/nsNSSCallbacks.h
+@@ -48,16 +48,19 @@
+
+ char* PR_CALLBACK
+ PK11PasswordPrompt(PK11SlotInfo *slot, PRBool retry, void* arg);
+
+ 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();
+
+ class nsHTTPListener : public nsIStreamLoaderObserver
+ {
+ private:
+ // For XPCOM implementations that are not a base class for some other
+ // class, it is good practice to make the destructor non-virtual and
+diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp
+--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
++++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
+@@ -217,17 +217,18 @@ nsNSSSocketInfo::nsNSSSocketInfo()
+ mForSTARTTLS(PR_FALSE),
+ mHandshakePending(PR_TRUE),
+ mCanceled(PR_FALSE),
+ mHasCleartextPhase(PR_FALSE),
+ mHandshakeInProgress(PR_FALSE),
+ mAllowTLSIntoleranceTimeout(PR_TRUE),
+ mRememberClientAuthCertificate(PR_FALSE),
+ mHandshakeStartTime(0),
+- mPort(0)
++ mPort(0),
++ mIsCertIssuerBlacklisted(PR_FALSE)
+ {
+ mThreadData = new nsSSLSocketThreadData;
+ }
+
+ nsNSSSocketInfo::~nsNSSSocketInfo()
+ {
+ delete mThreadData;
+
+@@ -3300,16 +3301,20 @@ nsNSSBadCertHandler(void *arg, PRFileDes
+
+ verify_log->arena = log_arena;
+
+ srv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), peerCert,
+ PR_TRUE, certificateUsageSSLServer,
+ PR_Now(), (void*)infoObject,
+ verify_log, NULL);
+
++ 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.
+ // Or it is a success, then a domain mismatch is the only
+ // possible failure.
+
+ CERTVerifyLogNode *i_node;
+ for (i_node = verify_log->head; i_node; i_node = i_node->next)
+diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h
+--- a/security/manager/ssl/src/nsNSSIOLayer.h
++++ b/security/manager/ssl/src/nsNSSIOLayer.h
+@@ -196,16 +196,22 @@ public:
+
+ /* Set SSL Status values */
+ nsresult SetSSLStatus(nsSSLStatus *aSSLStatus);
+ nsSSLStatus* SSLStatus() { return mSSLStatus; }
+ PRBool hasCertErrors();
+
+ PRStatus CloseSocketAndDestroy();
+
++ PRBool IsCertIssuerBlacklisted() const {
++ return mIsCertIssuerBlacklisted;
++ }
++ void SetCertIssuerBlacklisted() {
++ mIsCertIssuerBlacklisted = PR_TRUE;
++ }
+ protected:
+ nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
+ PRFileDesc* mFd;
+ nsCOMPtr<nsIX509Cert> mCert;
+ nsCOMPtr<nsIX509Cert> mPreviousCert; // DocShellDependent
+ enum {
+ blocking_state_unknown, is_nonblocking_socket, is_blocking_socket
+ } mBlockingState;
+@@ -223,16 +229,17 @@ protected:
+ PRPackedBool mCanceled;
+ PRPackedBool mHasCleartextPhase;
+ PRPackedBool mHandshakeInProgress;
+ PRPackedBool mAllowTLSIntoleranceTimeout;
+ PRPackedBool mRememberClientAuthCertificate;
+ PRIntervalTime mHandshakeStartTime;
+ PRInt32 mPort;
+ nsXPIDLCString mHostName;
++ PRErrorCode mIsCertIssuerBlacklisted;
+
+ /* SSL Status */
+ nsRefPtr<nsSSLStatus> mSSLStatus;
+
+ nsresult ActivateSSL();
+
+ nsSSLSocketThreadData *mThreadData;
+
+diff --git a/security/manager/ssl/src/nsIdentityChecking.cpp b/security/manager/ssl/src/nsIdentityChecking.cpp
+--- a/security/manager/ssl/src/nsIdentityChecking.cpp
++++ b/security/manager/ssl/src/nsIdentityChecking.cpp
+@@ -118,28 +118,16 @@ static struct nsMyTrustedEVInfo myTruste
+ SEC_OID_UNKNOWN,
+ "5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6",
+ "MDsxGDAWBgNVBAoTD0N5YmVydHJ1c3QsIEluYzEfMB0GA1UEAxMWQ3liZXJ0cnVz"
+ "dCBHbG9iYWwgUm9vdA==",
+ "BAAAAAABD4WqLUg=",
+ nsnull
+ },
+ {
+- // E=info at diginotar.nl,CN=DigiNotar Root CA,O=DigiNotar,C=NL
+- "2.16.528.1.1001.1.1.1.12.6.1.1.1",
+- "DigiNotar EV OID",
+- SEC_OID_UNKNOWN,
+- "C0:60:ED:44:CB:D8:81:BD:0E:F8:6C:0B:A2:87:DD:CF:81:67:47:8C",
+- "MF8xCzAJBgNVBAYTAk5MMRIwEAYDVQQKEwlEaWdpTm90YXIxGjAYBgNVBAMTEURp"
+- "Z2lOb3RhciBSb290IENBMSAwHgYJKoZIhvcNAQkBFhFpbmZvQGRpZ2lub3Rhci5u"
+- "bA==",
+- "DHbanJEMTiye/hXQWJM8TA==",
+- nsnull
+- },
+- {
+ // CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH
+ "2.16.756.1.89.1.2.1.1",
+ "SwissSign EV OID",
+ SEC_OID_UNKNOWN,
+ "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
+ "MEUxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMT"
+ "FlN3aXNzU2lnbiBHb2xkIENBIC0gRzI=",
+ "ALtAHEP1Xk+w",
diff --git a/xulrunner.spec b/xulrunner.spec
index 25618d7..ad172f3 100644
--- a/xulrunner.spec
+++ b/xulrunner.spec
@@ -28,7 +28,7 @@
Summary: XUL Runtime for Gecko Applications
Name: xulrunner
Version: 1.9.2.20
-Release: 1%{?pretag}%{?dist}
+Release: 2%{?pretag}%{?dist}
URL: http://developer.mozilla.org/En/XULRunner
License: MPLv1.1 or GPLv2+ or LGPLv2+
Group: Applications/Internet
@@ -58,6 +58,7 @@ Patch24: crashreporter-remove-static.patch
# Upstream patches
Patch30: mozilla-513747.patch
+Patch31: xulrunner-diginotar.patch
# ---------------------------------------------------
@@ -159,6 +160,7 @@ sed -e 's/__RPM_VERSION_INTERNAL__/%{version_internal}/' %{P:%%PATCH0} \
%patch22 -p1 -b .static
%patch30 -p2 -b .513747
+%patch31 -p1 -b .diginotar
%{__rm} -f .mozconfig
%{__cp} %{SOURCE10} .mozconfig
@@ -472,6 +474,9 @@ fi
#---------------------------------------------------------------------
%changelog
+* Wed Aug 31 2011 Jan Horak <jhorak at redhat.com> - 1.9.2.20-2
+- Distrust a specific Certificate Authority
+
* Tue Aug 16 2011 Jan Horak <stransky at redhat.com> - 1.9.2.20-1
- Update to 1.9.2.20
More information about the scm-commits
mailing list