From 6028a138e9150ce034acba3879e0410171f4f0e8 Mon Sep 17 00:00:00 2001 From: John Schanck Date: Thu, 28 Apr 2022 19:48:06 +0000 Subject: [PATCH] Bug 1691122 - Remove subject common name fallback support in CertVerifier. r=keeler,necko-reviewers,kershaw Differential Revision: https://phabricator.services.mozilla.com/D143808 --- build/pgo/certs/bug1665057cert.certspec | 1 + build/pgo/certs/bug1706126cert.certspec | 1 + build/pgo/certs/cert9.db | Bin 294912 -> 294912 bytes build/pgo/certs/key4.db | Bin 294912 -> 294912 bytes build/pgo/certs/mochitest.client | Bin 2448 -> 2448 bytes docshell/base/nsDocShell.cpp | 6 +- modules/libpref/init/all.js | 12 - netwerk/base/nsIOService.cpp | 4 +- .../certverifier/BRNameMatchingPolicy.cpp | 42 --- security/certverifier/BRNameMatchingPolicy.h | 57 ---- security/certverifier/CertVerifier.cpp | 8 +- security/certverifier/CertVerifier.h | 3 - security/certverifier/moz.build | 2 - security/ct/MultiLogCTVerifier.h | 2 +- security/manager/ssl/CommonSocketControl.cpp | 7 +- .../manager/ssl/ContentSignatureVerifier.cpp | 4 +- .../manager/ssl/SSLServerCertVerification.cpp | 7 +- security/manager/ssl/SharedCertVerifier.h | 5 +- security/manager/ssl/SharedSSLState.h | 5 - security/manager/ssl/nsNSSComponent.cpp | 22 +- ...seline_requirements_subject_common_name.js | 247 ++---------------- testing/tools/iceserver/iceserver.py | 3 + 22 files changed, 30 insertions(+), 408 deletions(-) delete mode 100644 security/certverifier/BRNameMatchingPolicy.cpp delete mode 100644 security/certverifier/BRNameMatchingPolicy.h diff --git a/build/pgo/certs/bug1665057cert.certspec b/build/pgo/certs/bug1665057cert.certspec index 358e31b0b302..ee338b8d1ab6 100644 --- a/build/pgo/certs/bug1665057cert.certspec +++ b/build/pgo/certs/bug1665057cert.certspec @@ -1,2 +1,3 @@ subject:www.suggestion-example.com +extension:subjectAlternativeName:www.suggestion-example.com issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization diff --git a/build/pgo/certs/bug1706126cert.certspec b/build/pgo/certs/bug1706126cert.certspec index 6f48648e76bc..5fd2d894ff5c 100644 --- a/build/pgo/certs/bug1706126cert.certspec +++ b/build/pgo/certs/bug1706126cert.certspec @@ -1,2 +1,3 @@ subject:www.redirect-example.com +extension:subjectAlternativeName:www.redirect-example.com issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization diff --git a/build/pgo/certs/cert9.db b/build/pgo/certs/cert9.db index 22e7226618bf77851e65c2a5bca4b53b4076d53a..d34eaa8cf98a6731727798d0f2d29089a3ce61f1 100644 GIT binary patch delta 4065 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 D#GY$E diff --git a/build/pgo/certs/key4.db b/build/pgo/certs/key4.db index 8caf40f1aa91f4d13e1237201a6d5e8146494cda..01bdc4afa518518adb38346c29fb0636b0e7ef85 100644 GIT binary patch literal 294912 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 diff --git a/build/pgo/certs/mochitest.client b/build/pgo/certs/mochitest.client index 7ac76facc6955ab0a87be2aef616d7d9b2f4cda0..5b038dc61079304832e101603f0c2adaaa2c1787 100644 GIT binary patch delta 2227 zcmV;k2u$~o6Oa>-U4M;e7sz?j~S z^Eu0q{|80a4NRcNaXvAL+kXaLI74k0%rU(GVUEeh6;&8!6MuDI)J^ynD@b7{o5gvY zZlTz3i7U|$CWkY|S%^kRHzHQ&+XEDuNrck`RdLP>>>G}7;w00ogg0f|d%LN3bGQBM z)sah{ii&XELwE5~JQ!YjaC}NZ!?=~97Rz<^#nu4Xvli|)usUY_;KJ1u!In`e@-*98 zvi2s#F{M!4z<)w2)?|#bu{z(OVxO}|NQqnxV{&6~Vh&=@dGb^e|n&s1OMrg^f?Xbf+*JH`@@{0<@`+zO&{MYRho{N<7B}Ax>vm~^y|z- ziFCBq8ocZ*!Nd2LH5-WS*Md}Wv1aaCL~b$V|8e?Vj4iJ;15txdRqb6l(K)lK73)t8UpwebG21ku;j5@2!FvRFij^5M`x1*N7#hw)8-y^6zn^_ zOL#*IO~K&^@>WhT+yEsN^CF~yT*+`>ha47etRbYcA-aPdHRyuxN*ZGbR!I`k&N3p zJ%2&0oq2|Fznh*|>$M5#6d`ryuy3_EwgZqD;0KrV0NI4`WMa{imL=Eg)X{F<#mO+- z-VHe#)Y`zPxF6w1yyQm}y%Ebl&0bQP2KRm1)q;u{1R?_hAY^1JAl9^;JgSmn=Ld4< zgtVE!J|Vsj-_$%=nrSY66ft;6mx$5i2p^fgFjv9s3mhonCHo0bAE{H0geoJE^kJfV zgif8XD3kRAMt>$(b{akNmlOg52ml0v1jr1qDluj_L=ue{i7?2H;VAysyEUs*^d5L{ z+t>hnv2Ywm8O3s!9asU)&n66tQ3|lg9p6ZWG-!nPDnl5QItYu!o1Q2q^ju1j*{iy=tiwvj_J1D#@x=?C=sX0vapkxXf< z(|BBloiKV0z<+-4mdKu$+dy|}E=5<%P=|QwR7R`PW*rhWDaZI^CD9sk+={!%5*iN> z2izPae19H)r_LxVG+xGKfu{++2ttr=3%^Q`eCp}=l39HnxOlD-4qvjJJ>97dT=GrrT}v42c(z7bR3dD>h#|DgWg84uF?;oL94 zVq&%)w4;bm_6;Sp-_=TOz}kSQ;StGgj`gdar=ftyZ>@Gy-E;ByT+Dp+NXIcM>fa9}jKCXY!}+-26##xs=BbIz^l! z`29C`FD!s4tNg++1Ns|)Ytqr3Hh&)}x`@d`Z=hj#Gn&yNFe)$<-NWmIZ=EA|w(nPP z9z3lk_2z>}>#s0%e@u7+1_l)L%$k8Ll2x8Me3NO1mn> znpHaLUwwI>*4c(CqiJD5!7Hrw(ivYOc^sIQoN55wlks0M?=s0?+am{hy?;R#hXs$0 zH(LpM1!T!|B-OYIa0J`FH(R|EW&a3?|YR1c# zoNv#u_**Sw)$aI{6A4=)?dg+tZS`Q@ij0B2RYPkC)(ob21PH1M6EyD;wb%jz2mpS_ BIm`e6 delta 2227 zcmV;k2u$~o6Oa>-U4O)&v3DHGS@{A22mpYB1Bl!KH_=m&jpztNCjSphQrE}yDu~$q zNEE8OoD6Nb6;<)2k*z=a7F7;m#TaTWCwwka5|OQ0l`y3?`?=5^D24 zv^#Tv-DGq9+agpB7^TDA;Vbt{k|xLQ$D)Njbf3Co@btWmO2N`{57#>H)ymmM5D?Ul zPG4CwmVz~g8-G6k;(q_6)o@6}p&G2oODd%OaG0+UnWR8R} zsg%N-9rWGKT;f8*%tb)*s?>0jY!Sk|6ZL=gsS3Bm#(#kizjs=NvPu!Cul8yINOT#b zybFs|pCz~&=hud<_BtxBHkG_4w^5I)Cs$TQTdEDXWqAO#O>jSm zS`roT4J|0x*;?T|ZNND^vVKAV{Dqbf@9oZa05_3h)lL=3yC-<}&*|os)+;02Uj7+h z;#BB%V1H#f-D6!m=T-+*Ve5a>HnRXYH~@;^UE!W39$Bl&DCn(;Bt6-ijCFdmDG>Nq zMS45zL?aEE(}7iLk!QZyCV_L^gBvLW&C`chTbu)lfX%!skvoXY;(JlB4JRvmW!rd| zS>#Si%(IRPb?#*K?h6O;ZY#n9U!*s?Ss7XqU4N8tHZt{m`R{#Q4tn2L-XvK_Q}d9{ z<{VDXpJPY;*mhd-dI)O|hwA?BJCAr)S5(Zad!Vf*@pefCbfI;3SkTWc*DlgwSx72< zi%k@Nlp{=Iq^Yx}g-Q^-j0oIO)7}OGI>!a9z$g;#2i!9d{G00wjs(@v1Uw=jF>m)z zD1Vn45BDiy`U130)W@TsARGH%>ZLR?m_0MV_rL2}aWzIQAtJea&yFVwke9{tROCIf z_%d(6gi3A94Cg@-Ac{N6)zjfMhf#06#!Pj?(P~Z%99L5eH}CVC*_5T;mnTDGA1-18 z^M>-vuTHVCg)?hvs5_$72fhbPEO10l8XuISOmfOPTWS*~5qi!;_ahBR>m2m4R{E_}lp@{Zx5MdtF!@zdZCrY!@*8Fb}p z?UuFjmZ7rteK}plg*T^lEMG1_LQ_BBlmB;ex0)p-ynj`%1~7-aKs3q2-#pQc=&~;$ zM>SEaKs4B~dCVN`AKnRv4TFpE?n;(a6R~HQNgn=TP+WWY_kmSjQ;`Y#vZsPrMJ>=Z zBB1TL4}xktlx8<}VGU zQbI~g5q~I2OiG?`F>+6x?GH8CcbD<8-C?M_B#>_4Hop^=pk_~{=A=j*dQ|{$c&J8p z@FCWWmr^mf?%O1!XRp^>fxsqS^wiJipida8l)B?X;CW!x(4~CO<>@wnN%sHMub79I z<}wMCVFVDE5}+^KP`sOGu&l>JN&r-7(oU3$b${g#%QU&}=06KkZi7MTP$42T6^48` zF!~d=mI?Mez*5ca2`DI3%)vL?d)*Jf1zkT=YYyW4(t|cp<)G(O!>GK&#z4X&gN2$n<0*|^PSd9fX3V4?my#s&Snd4jJz6K5O zMZ##QFejJ2X=FNfwut=#UwiY9ODpbukbmI4`(x$6N{a3@O~@~ZtgbI!%JO8G+Ip0j zr2uTC=v!6(d5t(-muRond9a3ag3VJ_Bl~Qt=dVr*)U7ae^8|U0M%{rGrJwE=c)XB( zw!z{;3^jk7?_mVHX}DDe*s0{~9x?#APO$ZMBN>#7!Wj2A2@>X|Ut^hNR94Gb22IUJ9Wd>gA$2jU`R%$v`R!sax8BhB@&P=Dx{WVxLh)s!? z#dWw%+DOvK;>O{V6A4=)U~3&89Vg-I$Ej(IzC+i1PEZBjs`m-(*6Ph2ml04 BJ9_{C diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index ccc12f6b5a8c..6f554d87958e 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -234,7 +234,6 @@ #include "nsXULAppAPI.h" #include "ThirdPartyUtil.h" -#include "BRNameMatchingPolicy.h" #include "GeckoProfiler.h" #include "mozilla/NullPrincipal.h" #include "Navigator.h" @@ -6090,10 +6089,7 @@ already_AddRefed nsDocShell::MaybeFixBadCertDomainErrorURI( // Check if adding a "www." prefix to the request's hostname will // cause the response's certificate to match. - mozilla::psm::BRNameMatchingPolicy nameMatchingPolicy( - mozilla::psm::BRNameMatchingPolicy::Mode::Enforce); - rv1 = mozilla::pkix::CheckCertHostname(serverCertInput, newHostInput, - nameMatchingPolicy); + rv1 = mozilla::pkix::CheckCertHostname(serverCertInput, newHostInput); if (rv1 != mozilla::pkix::Success) { return nullptr; } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index b3c73579429a..a078809d8122 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -111,18 +111,6 @@ pref("security.pki.sha1_enforcement_level", 3); // x_11_x: COSE is required, PKCS#7 disabled (fail when present) pref("security.signed_app_signatures.policy", 2); -// security.pki.name_matching_mode controls how the platform matches hostnames -// to name information in TLS certificates. The possible values are: -// 0: always fall back to the subject common name if necessary (as in, if the -// subject alternative name extension is either not present or does not -// contain any DNS names or IP addresses) -// 1: fall back to the subject common name for certificates valid before 23 -// August 2016 if necessary -// 2: fall back to the subject common name for certificates valid before 23 -// August 2015 if necessary -// 3: only use name information from the subject alternative name extension -pref("security.pki.name_matching_mode", 3); - // security.pki.netscape_step_up_policy controls how the platform handles the // id-Netscape-stepUp OID in extended key usage extensions of CA certificates. // 0: id-Netscape-stepUp is always considered equivalent to id-kp-serverAuth diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 035e3264c4f0..be0b39efee78 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -252,7 +252,6 @@ static const char* gCallbackSecurityPrefs[] = { "security.ssl.enable_ocsp_stapling", "security.ssl.enable_ocsp_must_staple", "security.pki.certificate_transparency.mode", - "security.pki.name_matching_mode", nullptr, }; @@ -407,8 +406,7 @@ void nsIOService::OnTLSPrefChange(const char* aPref, void* aSelf) { LOG(("HandleTLSPrefChange done")); } else if (pref.EqualsLiteral("security.ssl.enable_ocsp_stapling") || pref.EqualsLiteral("security.ssl.enable_ocsp_must_staple") || - pref.EqualsLiteral("security.pki.certificate_transparency.mode") || - pref.EqualsLiteral("security.pki.name_matching_mode")) { + pref.EqualsLiteral("security.pki.certificate_transparency.mode")) { SetValidationOptionsCommon(); } } diff --git a/security/certverifier/BRNameMatchingPolicy.cpp b/security/certverifier/BRNameMatchingPolicy.cpp deleted file mode 100644 index c70801adcd29..000000000000 --- a/security/certverifier/BRNameMatchingPolicy.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "BRNameMatchingPolicy.h" - -#include "mozilla/Assertions.h" - -using namespace mozilla::psm; -using namespace mozilla::pkix; - -Result BRNameMatchingPolicy::FallBackToCommonName( - Time notBefore, - /*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) { - // (new Date("2015-08-23T00:00:00Z")).getTime() / 1000 - static const Time AUGUST_23_2015 = TimeFromEpochInSeconds(1440288000); - // (new Date("2016-08-23T00:00:00Z")).getTime() / 1000 - static const Time AUGUST_23_2016 = TimeFromEpochInSeconds(1471910400); - switch (mMode) { - case Mode::Enforce: - fallBackToCommonName = FallBackToSearchWithinSubject::No; - break; - case Mode::EnforceAfter23August2015: - fallBackToCommonName = notBefore > AUGUST_23_2015 - ? FallBackToSearchWithinSubject::No - : FallBackToSearchWithinSubject::Yes; - break; - case Mode::EnforceAfter23August2016: - fallBackToCommonName = notBefore > AUGUST_23_2016 - ? FallBackToSearchWithinSubject::No - : FallBackToSearchWithinSubject::Yes; - break; - case Mode::DoNotEnforce: - fallBackToCommonName = FallBackToSearchWithinSubject::Yes; - break; - default: - MOZ_CRASH("Unexpected Mode"); - } - return Success; -} diff --git a/security/certverifier/BRNameMatchingPolicy.h b/security/certverifier/BRNameMatchingPolicy.h deleted file mode 100644 index 1f9910cee20a..000000000000 --- a/security/certverifier/BRNameMatchingPolicy.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef BRNameMatchingPolicy_h -#define BRNameMatchingPolicy_h - -#include "mozpkix/pkixtypes.h" - -namespace mozilla { -namespace psm { - -// According to the Baseline Requirements version 1.3.3 section 7.1.4.2.2.a, -// the requirements of the subject common name field are as follows: -// "If present, this field MUST contain a single IP address or Fully‐Qualified -// Domain Name that is one of the values contained in the Certificate’s -// subjectAltName extension". Consequently, since any name information present -// in the common name must be present in the subject alternative name extension, -// when performing name matching, it should not be necessary to fall back to the -// common name. Because this consequence has not commonly been enforced, this -// implementation provides a mechanism to start enforcing it gradually while -// maintaining some backwards compatibility. If configured with the mode -// "EnforceAfter23August2016", name matching will only fall back to using the -// subject common name for certificates where the notBefore field is before 23 -// August 2016. Similarly, the mode "EnforceAfter23August2015" is also -// available. This is to provide a balance between allowing preexisting -// long-lived certificates and detecting newly-issued problematic certificates. -// Note that this implementation does not actually directly enforce that if the -// subject common name is present, its value corresponds to a dNSName or -// iPAddress entry in the subject alternative name extension. - -class BRNameMatchingPolicy : public mozilla::pkix::NameMatchingPolicy { - public: - enum class Mode { - DoNotEnforce = 0, - EnforceAfter23August2016 = 1, - EnforceAfter23August2015 = 2, - Enforce = 3, - }; - - explicit BRNameMatchingPolicy(Mode mode) : mMode(mode) {} - - virtual mozilla::pkix::Result FallBackToCommonName( - mozilla::pkix::Time notBefore, - /*out*/ mozilla::pkix::FallBackToSearchWithinSubject& - fallBacktoCommonName) override; - - private: - Mode mMode; -}; - -} // namespace psm -} // namespace mozilla - -#endif // BRNameMatchingPolicy_h diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp index f2cb8b459fb1..dc8b5a41d370 100644 --- a/security/certverifier/CertVerifier.cpp +++ b/security/certverifier/CertVerifier.cpp @@ -105,7 +105,6 @@ CertVerifier::CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc, mozilla::TimeDuration ocspTimeoutSoft, mozilla::TimeDuration ocspTimeoutHard, uint32_t certShortLifetimeInDays, SHA1Mode sha1Mode, - BRNameMatchingPolicy::Mode nameMatchingMode, NetscapeStepUpPolicy netscapeStepUpPolicy, CertificateTransparencyMode ctMode, CRLiteMode crliteMode, @@ -116,7 +115,6 @@ CertVerifier::CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc, mOCSPTimeoutHard(ocspTimeoutHard), mCertShortLifetimeInDays(certShortLifetimeInDays), mSHA1Mode(sha1Mode), - mNameMatchingMode(nameMatchingMode), mNetscapeStepUpPolicy(netscapeStepUpPolicy), mCTMode(ctMode), mCRLiteMode(crliteMode) { @@ -990,11 +988,7 @@ Result CertVerifier::VerifySSLServerCert( return Result::FATAL_ERROR_INVALID_ARGS; } - BRNameMatchingPolicy nameMatchingPolicy( - isBuiltChainRootBuiltInRootLocal - ? mNameMatchingMode - : BRNameMatchingPolicy::Mode::DoNotEnforce); - rv = CheckCertHostname(peerCertInput, hostnameInput, nameMatchingPolicy); + rv = CheckCertHostname(peerCertInput, hostnameInput); if (rv != Success) { // Treat malformed name information as a domain mismatch. if (rv == Result::ERROR_BAD_DER) { diff --git a/security/certverifier/CertVerifier.h b/security/certverifier/CertVerifier.h index f3a9ba9db494..b69a4b209490 100644 --- a/security/certverifier/CertVerifier.h +++ b/security/certverifier/CertVerifier.h @@ -7,7 +7,6 @@ #ifndef CertVerifier_h #define CertVerifier_h -#include "BRNameMatchingPolicy.h" #include "CTPolicyEnforcer.h" #include "CTVerifyResult.h" #include "EnterpriseRoots.h" @@ -220,7 +219,6 @@ class CertVerifier { mozilla::TimeDuration ocspTimeoutSoft, mozilla::TimeDuration ocspTimeoutHard, uint32_t certShortLifetimeInDays, SHA1Mode sha1Mode, - BRNameMatchingPolicy::Mode nameMatchingMode, NetscapeStepUpPolicy netscapeStepUpPolicy, CertificateTransparencyMode ctMode, CRLiteMode crliteMode, const Vector& thirdPartyCerts); @@ -234,7 +232,6 @@ class CertVerifier { const mozilla::TimeDuration mOCSPTimeoutHard; const uint32_t mCertShortLifetimeInDays; const SHA1Mode mSHA1Mode; - const BRNameMatchingPolicy::Mode mNameMatchingMode; const NetscapeStepUpPolicy mNetscapeStepUpPolicy; const CertificateTransparencyMode mCTMode; const CRLiteMode mCRLiteMode; diff --git a/security/certverifier/moz.build b/security/certverifier/moz.build index 268618d1e430..bf9ac0a38cf5 100644 --- a/security/certverifier/moz.build +++ b/security/certverifier/moz.build @@ -8,13 +8,11 @@ with Files("**"): BUG_COMPONENT = ("Core", "Security: PSM") EXPORTS += [ - "BRNameMatchingPolicy.h", "CertVerifier.h", "OCSPCache.h", ] UNIFIED_SOURCES += [ - "BRNameMatchingPolicy.cpp", "CertVerifier.cpp", "NSSCertDBTrustDomain.cpp", "OCSPCache.cpp", diff --git a/security/ct/MultiLogCTVerifier.h b/security/ct/MultiLogCTVerifier.h index 8f3047df7f7f..983f96677b59 100644 --- a/security/ct/MultiLogCTVerifier.h +++ b/security/ct/MultiLogCTVerifier.h @@ -19,7 +19,7 @@ namespace mozilla { namespace ct { -void DecodeSCTs(Input encodedSctList, +void DecodeSCTs(pkix::Input encodedSctList, std::vector& decodedSCTs, size_t& decodingErrors); diff --git a/security/manager/ssl/CommonSocketControl.cpp b/security/manager/ssl/CommonSocketControl.cpp index bb6fd19e2f66..2623ad96201a 100644 --- a/security/manager/ssl/CommonSocketControl.cpp +++ b/security/manager/ssl/CommonSocketControl.cpp @@ -6,7 +6,6 @@ #include "CommonSocketControl.h" -#include "BRNameMatchingPolicy.h" #include "PublicKeyPinningService.h" #include "SharedCertVerifier.h" #include "nsNSSComponent.h" @@ -192,11 +191,7 @@ CommonSocketControl::IsAcceptableForHost(const nsACString& hostname, return NS_OK; } - mozilla::psm::BRNameMatchingPolicy nameMatchingPolicy( - mIsBuiltCertChainRootBuiltInRoot - ? mozilla::psm::PublicSSLState()->NameMatchingMode() - : mozilla::psm::BRNameMatchingPolicy::Mode::DoNotEnforce); - rv = CheckCertHostname(serverCertInput, hostnameInput, nameMatchingPolicy); + rv = CheckCertHostname(serverCertInput, hostnameInput); if (rv != Success) { return NS_OK; } diff --git a/security/manager/ssl/ContentSignatureVerifier.cpp b/security/manager/ssl/ContentSignatureVerifier.cpp index a0a8eecde6aa..688bad668444 100644 --- a/security/manager/ssl/ContentSignatureVerifier.cpp +++ b/security/manager/ssl/ContentSignatureVerifier.cpp @@ -6,7 +6,6 @@ #include "ContentSignatureVerifier.h" -#include "BRNameMatchingPolicy.h" #include "CryptoTask.h" #include "CSTrustDomain.h" #include "ScopedNSSTypes.h" @@ -279,8 +278,7 @@ static nsresult VerifyContentSignatureInternal( return NS_ERROR_FAILURE; } - BRNameMatchingPolicy nameMatchingPolicy(BRNameMatchingPolicy::Mode::Enforce); - result = CheckCertHostname(certInput, hostnameInput, nameMatchingPolicy); + result = CheckCertHostname(certInput, hostnameInput); if (result != Success) { // EE cert isnot valid for the given host name. aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err7; diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp index ba14c1ab4832..e6db9703a336 100644 --- a/security/manager/ssl/SSLServerCertVerification.cpp +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -95,7 +95,6 @@ #include -#include "BRNameMatchingPolicy.h" #include "CertVerifier.h" #include "CryptoTask.h" #include "ExtendedValidation.h" @@ -372,10 +371,6 @@ SECStatus DetermineCertOverrideErrors(const nsCOMPtr& cert, PR_SetError(SEC_ERROR_INVALID_ARGS, 0); return SECFailure; } - // Use a lax policy so as to not generate potentially spurious name - // mismatch "hints". - BRNameMatchingPolicy nameMatchingPolicy( - BRNameMatchingPolicy::Mode::DoNotEnforce); // CheckCertHostname expects that its input represents a certificate that // has already been successfully validated by BuildCertChain. This is // obviously not the case, however, because we're in the error path of @@ -383,7 +378,7 @@ SECStatus DetermineCertOverrideErrors(const nsCOMPtr& cert, // would be nice to remove this optimistic additional error checking and // simply punt to the front-end, which can more easily (and safely) perform // extra checks to give the user hints as to why verification failed. - result = CheckCertHostname(certInput, hostnameInput, nameMatchingPolicy); + result = CheckCertHostname(certInput, hostnameInput); // Treat malformed name information as a domain mismatch. if (result == Result::ERROR_BAD_DER || result == Result::ERROR_BAD_CERT_DOMAIN) { diff --git a/security/manager/ssl/SharedCertVerifier.h b/security/manager/ssl/SharedCertVerifier.h index 73ee1dbfa9d7..a48936a89395 100644 --- a/security/manager/ssl/SharedCertVerifier.h +++ b/security/manager/ssl/SharedCertVerifier.h @@ -24,14 +24,13 @@ class SharedCertVerifier : public mozilla::psm::CertVerifier { mozilla::TimeDuration ocspSoftTimeout, mozilla::TimeDuration ocspHardTimeout, uint32_t certShortLifetimeInDays, SHA1Mode sha1Mode, - BRNameMatchingPolicy::Mode nameMatchingMode, NetscapeStepUpPolicy netscapeStepUpPolicy, CertificateTransparencyMode ctMode, CRLiteMode crliteMode, const Vector& thirdPartyCerts) : mozilla::psm::CertVerifier(odc, osc, ocspSoftTimeout, ocspHardTimeout, certShortLifetimeInDays, sha1Mode, - nameMatchingMode, netscapeStepUpPolicy, - ctMode, crliteMode, thirdPartyCerts) {} + netscapeStepUpPolicy, ctMode, crliteMode, + thirdPartyCerts) {} }; } // namespace psm diff --git a/security/manager/ssl/SharedSSLState.h b/security/manager/ssl/SharedSSLState.h index b6597967f089..31562fc76bee 100644 --- a/security/manager/ssl/SharedSSLState.h +++ b/security/manager/ssl/SharedSSLState.h @@ -36,9 +36,6 @@ class SharedSSLState { void SetSignedCertTimestampsEnabled(bool signedCertTimestampsEnabled) { mSignedCertTimestampsEnabled = signedCertTimestampsEnabled; } - void SetNameMatchingMode(BRNameMatchingPolicy::Mode aMode) { - mNameMatchingMode = aMode; - } // The following methods may be called from any thread bool SocketCreated(); @@ -49,7 +46,6 @@ class SharedSSLState { bool IsSignedCertTimestampsEnabled() const { return mSignedCertTimestampsEnabled; } - BRNameMatchingPolicy::Mode NameMatchingMode() { return mNameMatchingMode; } private: ~SharedSSLState(); @@ -67,7 +63,6 @@ class SharedSSLState { bool mOCSPStaplingEnabled; bool mOCSPMustStapleEnabled; bool mSignedCertTimestampsEnabled; - BRNameMatchingPolicy::Mode mNameMatchingMode; }; SharedSSLState* PublicSSLState(); diff --git a/security/manager/ssl/nsNSSComponent.cpp b/security/manager/ssl/nsNSSComponent.cpp index 53eef93d0940..b2b076c01c1e 100644 --- a/security/manager/ssl/nsNSSComponent.cpp +++ b/security/manager/ssl/nsNSSComponent.cpp @@ -1340,23 +1340,6 @@ void SetValidationOptionsCommon() { ctMode != CertVerifier::CertificateTransparencyMode::Disabled; PublicSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled); PrivateSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled); - - BRNameMatchingPolicy::Mode nameMatchingMode = - static_cast(Preferences::GetInt( - "security.pki.name_matching_mode", - static_cast(BRNameMatchingPolicy::Mode::DoNotEnforce))); - switch (nameMatchingMode) { - case BRNameMatchingPolicy::Mode::Enforce: - case BRNameMatchingPolicy::Mode::EnforceAfter23August2015: - case BRNameMatchingPolicy::Mode::EnforceAfter23August2016: - case BRNameMatchingPolicy::Mode::DoNotEnforce: - break; - default: - nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce; - break; - } - PublicSSLState()->SetNameMatchingMode(nameMatchingMode); - PrivateSSLState()->SetNameMatchingMode(nameMatchingMode); } namespace { @@ -1558,8 +1541,7 @@ void nsNSSComponent::setValidationOptions( mDefaultCertVerifier = new SharedCertVerifier( odc, osc, softTimeout, hardTimeout, certShortLifetimeInDays, sha1Mode, - PublicSSLState()->NameMatchingMode(), netscapeStepUpPolicy, ctMode, - crliteMode, mEnterpriseCerts); + netscapeStepUpPolicy, ctMode, crliteMode, mEnterpriseCerts); } void nsNSSComponent::UpdateCertVerifierWithEnterpriseRoots() { @@ -1576,7 +1558,6 @@ void nsNSSComponent::UpdateCertVerifierWithEnterpriseRoots() { : CertVerifier::ocspRelaxed, oldCertVerifier->mOCSPTimeoutSoft, oldCertVerifier->mOCSPTimeoutHard, oldCertVerifier->mCertShortLifetimeInDays, oldCertVerifier->mSHA1Mode, - oldCertVerifier->mNameMatchingMode, oldCertVerifier->mNetscapeStepUpPolicy, oldCertVerifier->mCTMode, oldCertVerifier->mCRLiteMode, mEnterpriseCerts); } @@ -2384,7 +2365,6 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic, prefName.EqualsLiteral( "security.pki.certificate_transparency.mode") || prefName.EqualsLiteral("security.pki.sha1_enforcement_level") || - prefName.EqualsLiteral("security.pki.name_matching_mode") || prefName.EqualsLiteral("security.pki.netscape_step_up_policy") || prefName.EqualsLiteral( "security.OCSP.timeoutMilliseconds.soft") || diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js index 56de79ae7cd1..d33ad8b27505 100644 --- a/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js +++ b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js @@ -3,16 +3,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -// The preference security.pki.name_matching_mode controls whether or not -// mozilla::pkix will fall back to using a certificate's subject common name -// during name matching. If the Baseline Requirements are followed, fallback -// should not be necessary (because any name information in the subject common -// name should be present in the subject alternative name extension). Due to -// compatibility concerns, the platform can be configured to fall back for -// certificates that are valid before 23 August 2016. Note that for certificates -// issued by an imported root, the platform will fall back if necessary, -// regardless of the value of the preference. - "use strict"; do_get_profile(); // must be called before getting nsIX509CertDB @@ -48,8 +38,6 @@ function checkCertOn25August2016(cert, expectedResult) { add_task(async function() { registerCleanupFunction(() => { - Services.prefs.clearUserPref("security.pki.name_matching_mode"); - Services.prefs.clearUserPref("security.test.built_in_root_hash"); Services.prefs.clearUserPref("privacy.reduceTimerPrecision"); }); @@ -57,239 +45,34 @@ add_task(async function() { loadCertWithTrust("ca", "CTu,,"); - // When verifying a certificate, if the trust anchor is not a built-in root, - // name matching will fall back to using the subject common name if necessary - // (i.e. if there is no subject alternative name extension or it does not - // contain any dNSName or iPAddress entries). Thus, since imported roots are - // not in general treated as built-ins, these should all successfully verify - // regardless of the value of the pref. - Services.prefs.setIntPref("security.pki.name_matching_mode", 0); - info("current mode: always fall back, root not built-in"); + // At one time there was a preference security.pki.name_matching_mode that + // controlled whether or not mozilla::pkix would fall back to using a + // certificate's subject common name during name matching. This no longer + // exists, and certificates that previously required the fallback should fail + // to verify. + await checkCertOn25August2016( certFromFile("no-san-recent"), - PRErrorCodeSuccess + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + SSL_ERROR_BAD_CERT_DOMAIN ); - await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); await checkCertOn25August2016( certFromFile("no-san-older"), - PRErrorCodeSuccess + SSL_ERROR_BAD_CERT_DOMAIN ); await checkCertOn25August2016( certFromFile("san-contains-no-hostnames-recent"), - PRErrorCodeSuccess + SSL_ERROR_BAD_CERT_DOMAIN ); await checkCertOn25August2016( certFromFile("san-contains-no-hostnames-old"), - PRErrorCodeSuccess + SSL_ERROR_BAD_CERT_DOMAIN ); await checkCertOn25August2016( certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess + SSL_ERROR_BAD_CERT_DOMAIN ); - - Services.prefs.setIntPref("security.pki.name_matching_mode", 1); - info( - "current mode: fall back for notBefore < August 23, 2016, root " + - "not built-in" - ); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); - await checkCertOn25August2016( - certFromFile("no-san-older"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess - ); - - Services.prefs.setIntPref("security.pki.name_matching_mode", 2); - info( - "current mode: fall back for notBefore < August 23, 2015, root " + - "not built-in" - ); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); - await checkCertOn25August2016( - certFromFile("no-san-older"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess - ); - - Services.prefs.setIntPref("security.pki.name_matching_mode", 3); - info("current mode: never fall back, root not built-in"); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); - await checkCertOn25August2016( - certFromFile("no-san-older"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess - ); - - // In debug builds, we can treat an imported root as a built-in, and thus we - // can actually test the different values of the pref. - if (isDebugBuild) { - let root = certFromFile("ca"); - Services.prefs.setCharPref( - "security.test.built_in_root_hash", - root.sha256Fingerprint - ); - - // Always fall back if necessary. - Services.prefs.setIntPref("security.pki.name_matching_mode", 0); - info("current mode: always fall back, root built-in"); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("no-san-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("no-san-older"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess - ); - - // Only fall back if notBefore < 23 August 2016 - Services.prefs.setIntPref("security.pki.name_matching_mode", 1); - info( - "current mode: fall back for notBefore < August 23, 2016, root " + - "built-in" - ); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("no-san-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("no-san-older"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess - ); - - // Only fall back if notBefore < 23 August 2015 - Services.prefs.setIntPref("security.pki.name_matching_mode", 2); - info( - "current mode: fall back for notBefore < August 23, 2015, root " + - "built-in" - ); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("no-san-old"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("no-san-older"), - PRErrorCodeSuccess - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - PRErrorCodeSuccess - ); - - // Never fall back. - Services.prefs.setIntPref("security.pki.name_matching_mode", 3); - info("current mode: never fall back, root built-in"); - await checkCertOn25August2016( - certFromFile("no-san-recent"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("no-san-old"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("no-san-older"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-recent"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-old"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - await checkCertOn25August2016( - certFromFile("san-contains-no-hostnames-older"), - SSL_ERROR_BAD_CERT_DOMAIN - ); - } }); diff --git a/testing/tools/iceserver/iceserver.py b/testing/tools/iceserver/iceserver.py index a8a113a9d2c4..a909229a1705 100644 --- a/testing/tools/iceserver/iceserver.py +++ b/testing/tools/iceserver/iceserver.py @@ -882,6 +882,9 @@ def create_self_signed_cert(name): cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60) cert.set_issuer(cert.get_subject()) cert.set_pubkey(k) + cert.add_extensions( + [crypto.X509Extension(b"subjectAltName", False, f"DNS:{name}".encode())] + ) cert.sign(k, "sha1") open(CERT_FILE, "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))