SSLServerCertVerification.cpp 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. *
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. // For connections that are not processed on the socket transport thread, we do
  7. // NOT use the async logic described below. Instead, we authenticate the
  8. // certificate on the thread that the connection's I/O happens on,
  9. // synchronously. This allows us to do certificate verification for blocking
  10. // (not non-blocking) sockets and sockets that have their I/O processed on a
  11. // thread other than the socket transport service thread. Also, we DO NOT
  12. // support blocking sockets on the socket transport service thread at all.
  13. //
  14. // During certificate authentication, we call CERT_PKIXVerifyCert or
  15. // CERT_VerifyCert. These functions may make zero or more HTTP requests
  16. // for OCSP responses, CRLs, intermediate certificates, etc. Our fetching logic
  17. // for these requests processes them on the socket transport service thread.
  18. //
  19. // If the connection for which we are verifying the certificate is happening
  20. // on the socket transport thread (the usually case, at least for HTTP), then
  21. // if our cert auth hook were to call the CERT_*Verify* functions directly,
  22. // there would be a deadlock: The CERT_*Verify* function would cause an event
  23. // to be asynchronously posted to the socket transport thread, and then it
  24. // would block the socket transport thread waiting to be notified of the HTTP
  25. // response. However, the HTTP request would never actually be processed
  26. // because the socket transport thread would be blocked and so it wouldn't be
  27. // able process HTTP requests. (i.e. Deadlock.)
  28. //
  29. // Consequently, when we are asked to verify a certificate on the socket
  30. // transport service thread, we must always call the CERT_*Verify* cert
  31. // functions on another thread. To accomplish this, our auth cert hook
  32. // dispatches a SSLServerCertVerificationJob to a pool of background threads,
  33. // and then immediately returns SECWouldBlock to libssl. These jobs are where
  34. // the CERT_*Verify* functions are actually called.
  35. //
  36. // When our auth cert hook returns SECWouldBlock, libssl will carry on the
  37. // handshake while we validate the certificate. This will free up the socket
  38. // transport thread so that HTTP requests--in particular, the OCSP/CRL/cert
  39. // requests needed for cert verification as mentioned above--can be processed.
  40. //
  41. // Once the CERT_*Verify* function returns, the cert verification job
  42. // dispatches a SSLServerCertVerificationResult to the socket transport thread;
  43. // the SSLServerCertVerificationResult will notify libssl that the certificate
  44. // authentication is complete. Once libssl is notified that the authentication
  45. // is complete, it will continue the SSL handshake (if it hasn't already
  46. // finished) and it will begin allowing us to send/receive data on the
  47. // connection.
  48. //
  49. // Timeline of events (for connections managed by the socket transport service):
  50. //
  51. // * libssl calls SSLServerCertVerificationJob::Dispatch on the socket
  52. // transport thread.
  53. // * SSLServerCertVerificationJob::Dispatch queues a job
  54. // (instance of SSLServerCertVerificationJob) to its background thread
  55. // pool and returns.
  56. // * One of the background threads calls CERT_*Verify*, which may enqueue
  57. // some HTTP request(s) onto the socket transport thread, and then
  58. // blocks that background thread waiting for the responses and/or timeouts
  59. // or errors for those requests.
  60. // * Once those HTTP responses have all come back or failed, the
  61. // CERT_*Verify* function returns a result indicating that the validation
  62. // succeeded or failed.
  63. // * If the validation succeeded, then a SSLServerCertVerificationResult
  64. // event is posted to the socket transport thread, and the cert
  65. // verification thread becomes free to verify other certificates.
  66. // * Otherwise, a CertErrorRunnable is posted to the socket transport thread
  67. // and then to the main thread (blocking both, see CertErrorRunnable) to
  68. // do cert override processing and bad cert listener notification. Then
  69. // the cert verification thread becomes free to verify other certificates.
  70. // * After processing cert overrides, the CertErrorRunnable will dispatch a
  71. // SSLServerCertVerificationResult event to the socket transport thread to
  72. // notify it of the result of the override processing; then it returns,
  73. // freeing up the main thread.
  74. // * The SSLServerCertVerificationResult event will either wake up the
  75. // socket (using SSL_RestartHandshakeAfterServerCert) if validation
  76. // succeeded or there was an error override, or it will set an error flag
  77. // so that the next I/O operation on the socket will fail, causing the
  78. // socket transport thread to close the connection.
  79. //
  80. // Cert override processing must happen on the main thread because it accesses
  81. // the nsICertOverrideService, and that service must be accessed on the main
  82. // thread because some extensions (Selenium, in particular) replace it with a
  83. // Javascript implementation, and chrome JS must always be run on the main
  84. // thread.
  85. //
  86. // SSLServerCertVerificationResult must be dispatched to the socket transport
  87. // thread because we must only call SSL_* functions on the socket transport
  88. // thread since they may do I/O, because many parts of nsNSSSocketInfo (the
  89. // subclass of TransportSecurityInfo used when validating certificates during
  90. // an SSL handshake) and the PSM NSS I/O layer are not thread-safe, and because
  91. // we need the event to interrupt the PR_Poll that may waiting for I/O on the
  92. // socket for which we are validating the cert.
  93. #include "SSLServerCertVerification.h"
  94. #include <cstring>
  95. #include "BRNameMatchingPolicy.h"
  96. #include "CertVerifier.h"
  97. #include "CryptoTask.h"
  98. #include "ExtendedValidation.h"
  99. #include "NSSCertDBTrustDomain.h"
  100. #include "PSMRunnable.h"
  101. #include "ScopedNSSTypes.h"
  102. #include "SharedCertVerifier.h"
  103. #include "SharedSSLState.h"
  104. #include "TransportSecurityInfo.h" // For RememberCertErrorsTable
  105. #include "cert.h"
  106. #include "mozilla/Assertions.h"
  107. #include "mozilla/Casting.h"
  108. #include "mozilla/Mutex.h"
  109. #include "mozilla/RefPtr.h"
  110. #include "mozilla/UniquePtr.h"
  111. #include "mozilla/Unused.h"
  112. #include "mozilla/net/DNS.h"
  113. #include "nsComponentManagerUtils.h"
  114. #include "nsContentUtils.h"
  115. #include "nsIBadCertListener2.h"
  116. #include "nsICertOverrideService.h"
  117. #include "nsISiteSecurityService.h"
  118. #include "nsISocketProvider.h"
  119. #include "nsIThreadPool.h"
  120. #include "nsNSSCertificate.h"
  121. #include "nsNSSComponent.h"
  122. #include "nsNSSIOLayer.h"
  123. #include "nsNSSShutDown.h"
  124. #include "nsSSLStatus.h"
  125. #include "nsServiceManagerUtils.h"
  126. #include "nsURLHelper.h"
  127. #include "nsXPCOMCIDInternal.h"
  128. #include "pkix/pkix.h"
  129. #include "pkix/pkixnss.h"
  130. #include "secerr.h"
  131. #include "secoidt.h"
  132. #include "secport.h"
  133. #include "ssl.h"
  134. #include "sslerr.h"
  135. extern mozilla::LazyLogModule gPIPNSSLog;
  136. using namespace mozilla::pkix;
  137. namespace mozilla { namespace psm {
  138. namespace {
  139. // do not use a nsCOMPtr to avoid static initializer/destructor
  140. nsIThreadPool* gCertVerificationThreadPool = nullptr;
  141. // We add a mutex to serialize PKCS11 database operations
  142. Mutex* gSSLVerificationPK11Mutex = nullptr;
  143. } // unnamed namespace
  144. // Called when the socket transport thread starts, to initialize the SSL cert
  145. // verification thread pool. By tying the thread pool startup/shutdown directly
  146. // to the STS thread's lifetime, we ensure that they are *always* available for
  147. // SSL connections and that there are no races during startup and especially
  148. // shutdown. (Previously, we have had multiple problems with races in PSM
  149. // background threads, and the race-prevention/shutdown logic used there is
  150. // brittle. Since this service is critical to things like downloading updates,
  151. // we take no chances.) Also, by doing things this way, we avoid the need for
  152. // locks, since gCertVerificationThreadPool is only ever accessed on the socket
  153. // transport thread.
  154. void
  155. InitializeSSLServerCertVerificationThreads()
  156. {
  157. gSSLVerificationPK11Mutex = new Mutex("SSLVerificationPK11Mutex");
  158. // TODO: tuning, make parameters preferences
  159. // XXX: instantiate nsThreadPool directly, to make this more bulletproof.
  160. // Currently, the nsThreadPool.h header isn't exported for us to do so.
  161. nsresult rv = CallCreateInstance(NS_THREADPOOL_CONTRACTID,
  162. &gCertVerificationThreadPool);
  163. if (NS_FAILED(rv)) {
  164. NS_WARNING("Failed to create SSL cert verification threads.");
  165. return;
  166. }
  167. (void) gCertVerificationThreadPool->SetIdleThreadLimit(5);
  168. (void) gCertVerificationThreadPool->SetIdleThreadTimeout(30 * 1000);
  169. (void) gCertVerificationThreadPool->SetThreadLimit(5);
  170. (void) gCertVerificationThreadPool->SetName(NS_LITERAL_CSTRING("SSL Cert"));
  171. }
  172. // Called when the socket transport thread finishes, to destroy the thread
  173. // pool. Since the socket transport service has stopped processing events, it
  174. // will not attempt any more SSL I/O operations, so it is clearly safe to shut
  175. // down the SSL cert verification infrastructure. Also, the STS will not
  176. // dispatch many SSL verification result events at this point, so any pending
  177. // cert verifications will (correctly) fail at the point they are dispatched.
  178. //
  179. // The other shutdown race condition that is possible is a race condition with
  180. // shutdown of the nsNSSComponent service. We use the
  181. // nsNSSShutdownPreventionLock where needed (not here) to prevent that.
  182. void StopSSLServerCertVerificationThreads()
  183. {
  184. if (gCertVerificationThreadPool) {
  185. gCertVerificationThreadPool->Shutdown();
  186. NS_RELEASE(gCertVerificationThreadPool);
  187. }
  188. if (gSSLVerificationPK11Mutex) {
  189. delete gSSLVerificationPK11Mutex;
  190. gSSLVerificationPK11Mutex = nullptr;
  191. }
  192. }
  193. namespace {
  194. void
  195. LogInvalidCertError(nsNSSSocketInfo* socketInfo,
  196. PRErrorCode errorCode,
  197. ::mozilla::psm::SSLErrorMessageType errorMessageType)
  198. {
  199. nsString message;
  200. socketInfo->GetErrorLogMessage(errorCode, errorMessageType, message);
  201. if (!message.IsEmpty()) {
  202. nsContentUtils::LogSimpleConsoleError(message, "SSL");
  203. }
  204. }
  205. // Dispatched to the STS thread to notify the infoObject of the verification
  206. // result.
  207. //
  208. // This will cause the PR_Poll in the STS thread to return, so things work
  209. // correctly even if the STS thread is blocked polling (only) on the file
  210. // descriptor that is waiting for this result.
  211. class SSLServerCertVerificationResult : public Runnable
  212. {
  213. public:
  214. NS_DECL_NSIRUNNABLE
  215. SSLServerCertVerificationResult(nsNSSSocketInfo* infoObject,
  216. PRErrorCode errorCode,
  217. SSLErrorMessageType errorMessageType =
  218. PlainErrorMessage);
  219. void Dispatch();
  220. private:
  221. const RefPtr<nsNSSSocketInfo> mInfoObject;
  222. public:
  223. const PRErrorCode mErrorCode;
  224. const SSLErrorMessageType mErrorMessageType;
  225. };
  226. class CertErrorRunnable : public SyncRunnableBase
  227. {
  228. public:
  229. CertErrorRunnable(const void* fdForLogging,
  230. nsIX509Cert* cert,
  231. nsNSSSocketInfo* infoObject,
  232. PRErrorCode defaultErrorCodeToReport,
  233. uint32_t collectedErrors,
  234. PRErrorCode errorCodeTrust,
  235. PRErrorCode errorCodeMismatch,
  236. PRErrorCode errorCodeTime,
  237. uint32_t providerFlags)
  238. : mFdForLogging(fdForLogging), mCert(cert), mInfoObject(infoObject),
  239. mDefaultErrorCodeToReport(defaultErrorCodeToReport),
  240. mCollectedErrors(collectedErrors),
  241. mErrorCodeTrust(errorCodeTrust),
  242. mErrorCodeMismatch(errorCodeMismatch),
  243. mErrorCodeTime(errorCodeTime),
  244. mProviderFlags(providerFlags)
  245. {
  246. }
  247. virtual void RunOnTargetThread();
  248. RefPtr<SSLServerCertVerificationResult> mResult; // out
  249. private:
  250. SSLServerCertVerificationResult* CheckCertOverrides();
  251. const void* const mFdForLogging; // may become an invalid pointer; do not dereference
  252. const nsCOMPtr<nsIX509Cert> mCert;
  253. const RefPtr<nsNSSSocketInfo> mInfoObject;
  254. const PRErrorCode mDefaultErrorCodeToReport;
  255. const uint32_t mCollectedErrors;
  256. const PRErrorCode mErrorCodeTrust;
  257. const PRErrorCode mErrorCodeMismatch;
  258. const PRErrorCode mErrorCodeTime;
  259. const uint32_t mProviderFlags;
  260. };
  261. SECStatus
  262. DetermineCertOverrideErrors(const UniqueCERTCertificate& cert,
  263. const char* hostName,
  264. PRTime now, PRErrorCode defaultErrorCodeToReport,
  265. /*out*/ uint32_t& collectedErrors,
  266. /*out*/ PRErrorCode& errorCodeTrust,
  267. /*out*/ PRErrorCode& errorCodeMismatch,
  268. /*out*/ PRErrorCode& errorCodeTime)
  269. {
  270. MOZ_ASSERT(cert);
  271. MOZ_ASSERT(hostName);
  272. MOZ_ASSERT(collectedErrors == 0);
  273. MOZ_ASSERT(errorCodeTrust == 0);
  274. MOZ_ASSERT(errorCodeMismatch == 0);
  275. MOZ_ASSERT(errorCodeTime == 0);
  276. // Assumes the error prioritization described in mozilla::pkix's
  277. // BuildForward function. Also assumes that CheckCertHostname was only
  278. // called if CertVerifier::VerifyCert succeeded.
  279. switch (defaultErrorCodeToReport) {
  280. case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
  281. case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
  282. case SEC_ERROR_UNKNOWN_ISSUER:
  283. case SEC_ERROR_CA_CERT_INVALID:
  284. case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY:
  285. case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE:
  286. case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA:
  287. case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE:
  288. case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME:
  289. {
  290. collectedErrors = nsICertOverrideService::ERROR_UNTRUSTED;
  291. errorCodeTrust = defaultErrorCodeToReport;
  292. SECCertTimeValidity validity = CERT_CheckCertValidTimes(cert.get(), now,
  293. false);
  294. if (validity == secCertTimeUndetermined) {
  295. // This only happens if cert is null. CERT_CheckCertValidTimes will
  296. // have set the error code to SEC_ERROR_INVALID_ARGS. We should really
  297. // be using mozilla::pkix here anyway.
  298. MOZ_ASSERT(PR_GetError() == SEC_ERROR_INVALID_ARGS);
  299. return SECFailure;
  300. }
  301. if (validity == secCertTimeExpired) {
  302. collectedErrors |= nsICertOverrideService::ERROR_TIME;
  303. errorCodeTime = SEC_ERROR_EXPIRED_CERTIFICATE;
  304. } else if (validity == secCertTimeNotValidYet) {
  305. collectedErrors |= nsICertOverrideService::ERROR_TIME;
  306. errorCodeTime =
  307. mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE;
  308. }
  309. break;
  310. }
  311. case SEC_ERROR_INVALID_TIME:
  312. case SEC_ERROR_EXPIRED_CERTIFICATE:
  313. case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE:
  314. collectedErrors = nsICertOverrideService::ERROR_TIME;
  315. errorCodeTime = defaultErrorCodeToReport;
  316. break;
  317. case SSL_ERROR_BAD_CERT_DOMAIN:
  318. collectedErrors = nsICertOverrideService::ERROR_MISMATCH;
  319. errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
  320. break;
  321. case 0:
  322. NS_ERROR("No error code set during certificate validation failure.");
  323. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  324. return SECFailure;
  325. default:
  326. PR_SetError(defaultErrorCodeToReport, 0);
  327. return SECFailure;
  328. }
  329. if (defaultErrorCodeToReport != SSL_ERROR_BAD_CERT_DOMAIN) {
  330. Input certInput;
  331. if (certInput.Init(cert->derCert.data, cert->derCert.len) != Success) {
  332. PR_SetError(SEC_ERROR_BAD_DER, 0);
  333. return SECFailure;
  334. }
  335. Input hostnameInput;
  336. Result result = hostnameInput.Init(
  337. BitwiseCast<const uint8_t*, const char*>(hostName),
  338. strlen(hostName));
  339. if (result != Success) {
  340. PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
  341. return SECFailure;
  342. }
  343. // Use a lax policy so as to not generate potentially spurious name
  344. // mismatch "hints".
  345. BRNameMatchingPolicy nameMatchingPolicy(
  346. BRNameMatchingPolicy::Mode::DoNotEnforce);
  347. // CheckCertHostname expects that its input represents a certificate that
  348. // has already been successfully validated by BuildCertChain. This is
  349. // obviously not the case, however, because we're in the error path of
  350. // certificate verification. Thus, this is problematic. In the future, it
  351. // would be nice to remove this optimistic additional error checking and
  352. // simply punt to the front-end, which can more easily (and safely) perform
  353. // extra checks to give the user hints as to why verification failed.
  354. result = CheckCertHostname(certInput, hostnameInput, nameMatchingPolicy);
  355. // Treat malformed name information as a domain mismatch.
  356. if (result == Result::ERROR_BAD_DER ||
  357. result == Result::ERROR_BAD_CERT_DOMAIN) {
  358. collectedErrors |= nsICertOverrideService::ERROR_MISMATCH;
  359. errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
  360. } else if (IsFatalError(result)) {
  361. // Because its input has not been validated by BuildCertChain,
  362. // CheckCertHostname can return an error that is less important than the
  363. // original certificate verification error. Only return an error result
  364. // from this function if we've encountered a fatal error.
  365. PR_SetError(MapResultToPRErrorCode(result), 0);
  366. return SECFailure;
  367. }
  368. }
  369. return SECSuccess;
  370. }
  371. SSLServerCertVerificationResult*
  372. CertErrorRunnable::CheckCertOverrides()
  373. {
  374. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("[%p][%p] top of CheckCertOverrides\n",
  375. mFdForLogging, this));
  376. // "Use" mFdForLogging in non-PR_LOGGING builds, too, to suppress
  377. // clang's -Wunused-private-field build warning for this variable:
  378. Unused << mFdForLogging;
  379. if (!NS_IsMainThread()) {
  380. NS_ERROR("CertErrorRunnable::CheckCertOverrides called off main thread");
  381. return new SSLServerCertVerificationResult(mInfoObject,
  382. mDefaultErrorCodeToReport);
  383. }
  384. int32_t port;
  385. mInfoObject->GetPort(&port);
  386. nsAutoCString hostWithPortString(mInfoObject->GetHostName());
  387. hostWithPortString.Append(':');
  388. hostWithPortString.AppendInt(port);
  389. uint32_t remaining_display_errors = mCollectedErrors;
  390. // If this is an HTTP Strict Transport Security host, don't allow overrides
  391. // RFC 6797 section 12.1.
  392. bool strictTransportSecurityEnabled = false;
  393. nsCOMPtr<nsISiteSecurityService> sss(do_GetService(NS_SSSERVICE_CONTRACTID));
  394. if (!sss) {
  395. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  396. ("[%p][%p] couldn't get nsISiteSecurityService to check for HSTS/HPKP\n",
  397. mFdForLogging, this));
  398. return new SSLServerCertVerificationResult(mInfoObject,
  399. mDefaultErrorCodeToReport);
  400. }
  401. nsresult nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HSTS,
  402. mInfoObject->GetHostNameRaw(),
  403. mProviderFlags,
  404. nullptr,
  405. &strictTransportSecurityEnabled);
  406. if (NS_FAILED(nsrv)) {
  407. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  408. ("[%p][%p] checking for HSTS failed\n", mFdForLogging, this));
  409. return new SSLServerCertVerificationResult(mInfoObject,
  410. mDefaultErrorCodeToReport);
  411. }
  412. if (!strictTransportSecurityEnabled) {
  413. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  414. ("[%p][%p] no HSTS - overrides allowed\n",
  415. mFdForLogging, this));
  416. nsCOMPtr<nsICertOverrideService> overrideService =
  417. do_GetService(NS_CERTOVERRIDE_CONTRACTID);
  418. // it is fine to continue without the nsICertOverrideService
  419. uint32_t overrideBits = 0;
  420. if (overrideService)
  421. {
  422. bool haveOverride;
  423. bool isTemporaryOverride; // we don't care
  424. const nsACString& hostString(mInfoObject->GetHostName());
  425. nsrv = overrideService->HasMatchingOverride(hostString, port,
  426. mCert,
  427. &overrideBits,
  428. &isTemporaryOverride,
  429. &haveOverride);
  430. if (NS_SUCCEEDED(nsrv) && haveOverride)
  431. {
  432. // remove the errors that are already overriden
  433. remaining_display_errors &= ~overrideBits;
  434. }
  435. }
  436. if (!remaining_display_errors) {
  437. // all errors are covered by override rules, so let's accept the cert
  438. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  439. ("[%p][%p] All errors covered by override rules\n",
  440. mFdForLogging, this));
  441. return new SSLServerCertVerificationResult(mInfoObject, 0);
  442. }
  443. } else {
  444. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  445. ("[%p][%p] HSTS - no overrides allowed\n",
  446. mFdForLogging, this));
  447. }
  448. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  449. ("[%p][%p] Certificate error was not overridden\n",
  450. mFdForLogging, this));
  451. // Ok, this is a full stop.
  452. // First, deliver the technical details of the broken SSL status.
  453. // Try to get a nsIBadCertListener2 implementation from the socket consumer.
  454. nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
  455. NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, mInfoObject));
  456. if (sslSocketControl) {
  457. nsCOMPtr<nsIInterfaceRequestor> cb;
  458. sslSocketControl->GetNotificationCallbacks(getter_AddRefs(cb));
  459. if (cb) {
  460. nsCOMPtr<nsIBadCertListener2> bcl = do_GetInterface(cb);
  461. if (bcl) {
  462. nsIInterfaceRequestor* csi
  463. = static_cast<nsIInterfaceRequestor*>(mInfoObject);
  464. bool suppressMessage = false; // obsolete, ignored
  465. nsrv = bcl->NotifyCertProblem(csi, mInfoObject->SSLStatus(),
  466. hostWithPortString, &suppressMessage);
  467. }
  468. }
  469. }
  470. // pick the error code to report by priority
  471. PRErrorCode errorCodeToReport = mErrorCodeTrust ? mErrorCodeTrust
  472. : mErrorCodeMismatch ? mErrorCodeMismatch
  473. : mErrorCodeTime ? mErrorCodeTime
  474. : mDefaultErrorCodeToReport;
  475. SSLServerCertVerificationResult* result =
  476. new SSLServerCertVerificationResult(mInfoObject,
  477. errorCodeToReport,
  478. OverridableCertErrorMessage);
  479. LogInvalidCertError(mInfoObject,
  480. result->mErrorCode,
  481. result->mErrorMessageType);
  482. return result;
  483. }
  484. void
  485. CertErrorRunnable::RunOnTargetThread()
  486. {
  487. MOZ_ASSERT(NS_IsMainThread());
  488. mResult = CheckCertOverrides();
  489. MOZ_ASSERT(mResult);
  490. }
  491. // Returns null with the error code (PR_GetError()) set if it does not create
  492. // the CertErrorRunnable.
  493. CertErrorRunnable*
  494. CreateCertErrorRunnable(CertVerifier& certVerifier,
  495. PRErrorCode defaultErrorCodeToReport,
  496. nsNSSSocketInfo* infoObject,
  497. const UniqueCERTCertificate& cert,
  498. const void* fdForLogging,
  499. uint32_t providerFlags,
  500. PRTime now)
  501. {
  502. MOZ_ASSERT(infoObject);
  503. MOZ_ASSERT(cert);
  504. uint32_t collected_errors = 0;
  505. PRErrorCode errorCodeTrust = 0;
  506. PRErrorCode errorCodeMismatch = 0;
  507. PRErrorCode errorCodeTime = 0;
  508. if (DetermineCertOverrideErrors(cert, infoObject->GetHostNameRaw(), now,
  509. defaultErrorCodeToReport, collected_errors,
  510. errorCodeTrust, errorCodeMismatch,
  511. errorCodeTime) != SECSuccess) {
  512. // Attempt to enforce that if DetermineCertOverrideErrors failed,
  513. // PR_SetError was set with a non-overridable error. This is because if we
  514. // return from CreateCertErrorRunnable without calling
  515. // infoObject->SetStatusErrorBits, we won't have the required information
  516. // to actually add a certificate error override. This results in a broken
  517. // UI which is annoying but not a security disaster.
  518. MOZ_ASSERT(!ErrorIsOverridable(PR_GetError()));
  519. return nullptr;
  520. }
  521. RefPtr<nsNSSCertificate> nssCert(nsNSSCertificate::Create(cert.get()));
  522. if (!nssCert) {
  523. NS_ERROR("nsNSSCertificate::Create failed");
  524. PR_SetError(SEC_ERROR_NO_MEMORY, 0);
  525. return nullptr;
  526. }
  527. if (!collected_errors) {
  528. // This will happen when CERT_*Verify* only returned error(s) that are
  529. // not on our whitelist of overridable certificate errors.
  530. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("[%p] !collected_errors: %d\n",
  531. fdForLogging, static_cast<int>(defaultErrorCodeToReport)));
  532. PR_SetError(defaultErrorCodeToReport, 0);
  533. return nullptr;
  534. }
  535. infoObject->SetStatusErrorBits(nssCert, collected_errors);
  536. return new CertErrorRunnable(fdForLogging,
  537. static_cast<nsIX509Cert*>(nssCert.get()),
  538. infoObject, defaultErrorCodeToReport,
  539. collected_errors, errorCodeTrust,
  540. errorCodeMismatch, errorCodeTime,
  541. providerFlags);
  542. }
  543. // When doing async cert processing, we dispatch one of these runnables to the
  544. // socket transport service thread, which blocks the socket transport
  545. // service thread while it waits for the inner CertErrorRunnable to execute
  546. // CheckCertOverrides on the main thread. CheckCertOverrides must block events
  547. // on both of these threads because it calls TransportSecurityInfo::GetInterface(),
  548. // which may call nsHttpConnection::GetInterface() through
  549. // TransportSecurityInfo::mCallbacks. nsHttpConnection::GetInterface must always
  550. // execute on the main thread, with the socket transport service thread
  551. // blocked.
  552. class CertErrorRunnableRunnable : public Runnable
  553. {
  554. public:
  555. explicit CertErrorRunnableRunnable(CertErrorRunnable* certErrorRunnable)
  556. : mCertErrorRunnable(certErrorRunnable)
  557. {
  558. }
  559. private:
  560. NS_IMETHOD Run() override
  561. {
  562. nsresult rv = mCertErrorRunnable->DispatchToMainThreadAndWait();
  563. // The result must run on the socket transport thread, which we are already
  564. // on, so we can just run it directly, instead of dispatching it.
  565. if (NS_SUCCEEDED(rv)) {
  566. rv = mCertErrorRunnable->mResult ? mCertErrorRunnable->mResult->Run()
  567. : NS_ERROR_UNEXPECTED;
  568. }
  569. return rv;
  570. }
  571. RefPtr<CertErrorRunnable> mCertErrorRunnable;
  572. };
  573. class SSLServerCertVerificationJob : public Runnable
  574. {
  575. public:
  576. // Must be called only on the socket transport thread
  577. static SECStatus Dispatch(const RefPtr<SharedCertVerifier>& certVerifier,
  578. const void* fdForLogging,
  579. nsNSSSocketInfo* infoObject,
  580. const UniqueCERTCertificate& serverCert,
  581. const UniqueCERTCertList& peerCertChain,
  582. const SECItem* stapledOCSPResponse,
  583. const SECItem* sctsFromTLSExtension,
  584. uint32_t providerFlags,
  585. Time time,
  586. PRTime prtime);
  587. private:
  588. NS_DECL_NSIRUNNABLE
  589. // Must be called only on the socket transport thread
  590. SSLServerCertVerificationJob(const RefPtr<SharedCertVerifier>& certVerifier,
  591. const void* fdForLogging,
  592. nsNSSSocketInfo* infoObject,
  593. const UniqueCERTCertificate& cert,
  594. UniqueCERTCertList peerCertChain,
  595. const SECItem* stapledOCSPResponse,
  596. const SECItem* sctsFromTLSExtension,
  597. uint32_t providerFlags,
  598. Time time,
  599. PRTime prtime);
  600. const RefPtr<SharedCertVerifier> mCertVerifier;
  601. const void* const mFdForLogging;
  602. const RefPtr<nsNSSSocketInfo> mInfoObject;
  603. const UniqueCERTCertificate mCert;
  604. UniqueCERTCertList mPeerCertChain;
  605. const uint32_t mProviderFlags;
  606. const Time mTime;
  607. const PRTime mPRTime;
  608. const TimeStamp mJobStartTime;
  609. const UniqueSECItem mStapledOCSPResponse;
  610. const UniqueSECItem mSCTsFromTLSExtension;
  611. };
  612. SSLServerCertVerificationJob::SSLServerCertVerificationJob(
  613. const RefPtr<SharedCertVerifier>& certVerifier, const void* fdForLogging,
  614. nsNSSSocketInfo* infoObject, const UniqueCERTCertificate& cert,
  615. UniqueCERTCertList peerCertChain, const SECItem* stapledOCSPResponse,
  616. const SECItem* sctsFromTLSExtension,
  617. uint32_t providerFlags, Time time, PRTime prtime)
  618. : mCertVerifier(certVerifier)
  619. , mFdForLogging(fdForLogging)
  620. , mInfoObject(infoObject)
  621. , mCert(CERT_DupCertificate(cert.get()))
  622. , mPeerCertChain(Move(peerCertChain))
  623. , mProviderFlags(providerFlags)
  624. , mTime(time)
  625. , mPRTime(prtime)
  626. , mJobStartTime(TimeStamp::Now())
  627. , mStapledOCSPResponse(SECITEM_DupItem(stapledOCSPResponse))
  628. , mSCTsFromTLSExtension(SECITEM_DupItem(sctsFromTLSExtension))
  629. {
  630. }
  631. // This function assumes that we will only use the SPDY connection coalescing
  632. // feature on connections where we have negotiated SPDY using NPN. If we ever
  633. // talk SPDY without having negotiated it with SPDY, this code will give wrong
  634. // and perhaps unsafe results.
  635. //
  636. // Returns SECSuccess on the initial handshake of all connections, on
  637. // renegotiations for any connections where we did not negotiate SPDY, or on any
  638. // SPDY connection where the server's certificate did not change.
  639. //
  640. // Prohibit changing the server cert only if we negotiated SPDY,
  641. // in order to support SPDY's cross-origin connection pooling.
  642. static SECStatus
  643. BlockServerCertChangeForSpdy(nsNSSSocketInfo* infoObject,
  644. const UniqueCERTCertificate& serverCert)
  645. {
  646. // Get the existing cert. If there isn't one, then there is
  647. // no cert change to worry about.
  648. nsCOMPtr<nsIX509Cert> cert;
  649. RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
  650. if (!status) {
  651. // If we didn't have a status, then this is the
  652. // first handshake on this connection, not a
  653. // renegotiation.
  654. return SECSuccess;
  655. }
  656. status->GetServerCert(getter_AddRefs(cert));
  657. if (!cert) {
  658. NS_NOTREACHED("every nsSSLStatus must have a cert"
  659. "that implements nsIX509Cert");
  660. PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
  661. return SECFailure;
  662. }
  663. // Filter out sockets that did not neogtiate SPDY via NPN
  664. nsAutoCString negotiatedNPN;
  665. nsresult rv = infoObject->GetNegotiatedNPN(negotiatedNPN);
  666. NS_ASSERTION(NS_SUCCEEDED(rv),
  667. "GetNegotiatedNPN() failed during renegotiation");
  668. if (NS_SUCCEEDED(rv) && !StringBeginsWith(negotiatedNPN,
  669. NS_LITERAL_CSTRING("spdy/"))) {
  670. return SECSuccess;
  671. }
  672. // If GetNegotiatedNPN() failed we will assume spdy for safety's safe
  673. if (NS_FAILED(rv)) {
  674. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  675. ("BlockServerCertChangeForSpdy failed GetNegotiatedNPN() call."
  676. " Assuming spdy.\n"));
  677. }
  678. // Check to see if the cert has actually changed
  679. UniqueCERTCertificate c(cert->GetCert());
  680. NS_ASSERTION(c, "very bad and hopefully impossible state");
  681. bool sameCert = CERT_CompareCerts(c.get(), serverCert.get());
  682. if (sameCert) {
  683. return SECSuccess;
  684. }
  685. // Report an error - changed cert is confirmed
  686. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  687. ("SPDY Refused to allow new cert during renegotiation\n"));
  688. PR_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, 0);
  689. return SECFailure;
  690. }
  691. // Note: Takes ownership of |peerCertChain| if SECSuccess is not returned.
  692. SECStatus
  693. AuthCertificate(CertVerifier& certVerifier,
  694. nsNSSSocketInfo* infoObject,
  695. const UniqueCERTCertificate& cert,
  696. UniqueCERTCertList& peerCertChain,
  697. const SECItem* stapledOCSPResponse,
  698. const SECItem* sctsFromTLSExtension,
  699. uint32_t providerFlags,
  700. Time time)
  701. {
  702. MOZ_ASSERT(infoObject);
  703. MOZ_ASSERT(cert);
  704. // We want to avoid storing any intermediate cert information when browsing
  705. // in private, transient contexts.
  706. bool saveIntermediates =
  707. !(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE);
  708. SECOidTag evOidPolicy;
  709. UniqueCERTCertList certList;
  710. CertVerifier::OCSPStaplingStatus ocspStaplingStatus =
  711. CertVerifier::OCSP_STAPLING_NEVER_CHECKED;
  712. KeySizeStatus keySizeStatus = KeySizeStatus::NeverChecked;
  713. SHA1ModeResult sha1ModeResult = SHA1ModeResult::NeverChecked;
  714. CertificateTransparencyInfo certificateTransparencyInfo;
  715. int flags = 0;
  716. if (!infoObject->SharedState().IsOCSPStaplingEnabled() ||
  717. !infoObject->SharedState().IsOCSPMustStapleEnabled()) {
  718. flags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST;
  719. }
  720. Result rv = certVerifier.VerifySSLServerCert(cert, stapledOCSPResponse,
  721. sctsFromTLSExtension, time,
  722. infoObject,
  723. infoObject->GetHostNameRaw(),
  724. certList, saveIntermediates,
  725. flags, infoObject->
  726. GetOriginAttributes(),
  727. &evOidPolicy,
  728. &ocspStaplingStatus,
  729. &keySizeStatus, &sha1ModeResult,
  730. &certificateTransparencyInfo);
  731. if (rv == Success) {
  732. // Certificate verification succeeded. Delete any potential record of
  733. // certificate error bits.
  734. RememberCertErrorsTable::GetInstance().RememberCertHasError(infoObject,
  735. nullptr,
  736. SECSuccess);
  737. // The connection may get terminated, for example, if the server requires
  738. // a client cert. Let's provide a minimal SSLStatus
  739. // to the caller that contains at least the cert and its status.
  740. RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
  741. if (!status) {
  742. status = new nsSSLStatus();
  743. infoObject->SetSSLStatus(status);
  744. }
  745. if (!status->HasServerCert()) {
  746. EVStatus evStatus;
  747. if (evOidPolicy == SEC_OID_UNKNOWN) {
  748. evStatus = EVStatus::NotEV;
  749. } else {
  750. evStatus = EVStatus::EV;
  751. }
  752. RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(cert.get());
  753. status->SetServerCert(nsc, evStatus);
  754. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  755. ("AuthCertificate setting NEW cert %p", nsc.get()));
  756. }
  757. status->SetCertificateTransparencyInfo(certificateTransparencyInfo);
  758. }
  759. if (rv != Success) {
  760. // Certificate validation failed; store the peer certificate chain on
  761. // infoObject so it can be used for error reporting.
  762. infoObject->SetFailedCertChain(Move(peerCertChain));
  763. PR_SetError(MapResultToPRErrorCode(rv), 0);
  764. }
  765. return rv == Success ? SECSuccess : SECFailure;
  766. }
  767. /*static*/ SECStatus
  768. SSLServerCertVerificationJob::Dispatch(
  769. const RefPtr<SharedCertVerifier>& certVerifier,
  770. const void* fdForLogging,
  771. nsNSSSocketInfo* infoObject,
  772. const UniqueCERTCertificate& serverCert,
  773. const UniqueCERTCertList& peerCertChain,
  774. const SECItem* stapledOCSPResponse,
  775. const SECItem* sctsFromTLSExtension,
  776. uint32_t providerFlags,
  777. Time time,
  778. PRTime prtime)
  779. {
  780. // Runs on the socket transport thread
  781. if (!certVerifier || !infoObject || !serverCert) {
  782. NS_ERROR("Invalid parameters for SSL server cert validation");
  783. PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
  784. return SECFailure;
  785. }
  786. // Copy the certificate list so the runnable can take ownership of it in the
  787. // constructor.
  788. // We can safely skip checking if NSS has already shut down here since we're
  789. // in the middle of verifying a certificate.
  790. nsNSSShutDownPreventionLock lock;
  791. UniqueCERTCertList peerCertChainCopy =
  792. nsNSSCertList::DupCertList(peerCertChain, lock);
  793. if (!peerCertChainCopy) {
  794. PR_SetError(SEC_ERROR_NO_MEMORY, 0);
  795. return SECFailure;
  796. }
  797. RefPtr<SSLServerCertVerificationJob> job(
  798. new SSLServerCertVerificationJob(certVerifier, fdForLogging, infoObject,
  799. serverCert, Move(peerCertChainCopy),
  800. stapledOCSPResponse, sctsFromTLSExtension,
  801. providerFlags, time, prtime));
  802. nsresult nrv;
  803. if (!gCertVerificationThreadPool) {
  804. nrv = NS_ERROR_NOT_INITIALIZED;
  805. } else {
  806. nrv = gCertVerificationThreadPool->Dispatch(job, NS_DISPATCH_NORMAL);
  807. }
  808. if (NS_FAILED(nrv)) {
  809. // We can't call SetCertVerificationResult here to change
  810. // mCertVerificationState because SetCertVerificationResult will call
  811. // libssl functions that acquire SSL locks that are already being held at
  812. // this point. infoObject->mCertVerificationState will be stuck at
  813. // waiting_for_cert_verification here, but that is OK because we already
  814. // have to be able to handle cases where we encounter non-cert errors while
  815. // in that state.
  816. PRErrorCode error = nrv == NS_ERROR_OUT_OF_MEMORY
  817. ? SEC_ERROR_NO_MEMORY
  818. : PR_INVALID_STATE_ERROR;
  819. PORT_SetError(error);
  820. return SECFailure;
  821. }
  822. PORT_SetError(PR_WOULD_BLOCK_ERROR);
  823. return SECWouldBlock;
  824. }
  825. NS_IMETHODIMP
  826. SSLServerCertVerificationJob::Run()
  827. {
  828. // Runs on a cert verification thread
  829. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  830. ("[%p] SSLServerCertVerificationJob::Run\n", mInfoObject.get()));
  831. PRErrorCode error;
  832. nsNSSShutDownPreventionLock nssShutdownPrevention;
  833. if (mInfoObject->isAlreadyShutDown()) {
  834. error = SEC_ERROR_USER_CANCELLED;
  835. } else {
  836. // Reset the error code here so we can detect if AuthCertificate fails to
  837. // set the error code if/when it fails.
  838. PR_SetError(0, 0);
  839. SECStatus rv = AuthCertificate(*mCertVerifier, mInfoObject, mCert,
  840. mPeerCertChain, mStapledOCSPResponse.get(),
  841. mSCTsFromTLSExtension.get(),
  842. mProviderFlags, mTime);
  843. MOZ_ASSERT(mPeerCertChain || rv != SECSuccess,
  844. "AuthCertificate() should take ownership of chain on failure");
  845. if (rv == SECSuccess) {
  846. RefPtr<SSLServerCertVerificationResult> restart(
  847. new SSLServerCertVerificationResult(mInfoObject, 0));
  848. restart->Dispatch();
  849. return NS_OK;
  850. }
  851. // Note: the interval is not calculated once as PR_GetError MUST be called
  852. // before any other function call
  853. error = PR_GetError();
  854. if (error != 0) {
  855. RefPtr<CertErrorRunnable> runnable(
  856. CreateCertErrorRunnable(*mCertVerifier, error, mInfoObject, mCert,
  857. mFdForLogging, mProviderFlags, mPRTime));
  858. if (!runnable) {
  859. // CreateCertErrorRunnable set a new error code
  860. error = PR_GetError();
  861. } else {
  862. // We must block the the socket transport service thread while the
  863. // main thread executes the CertErrorRunnable. The CertErrorRunnable
  864. // will dispatch the result asynchronously, so we don't have to block
  865. // this thread waiting for it.
  866. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  867. ("[%p][%p] Before dispatching CertErrorRunnable\n",
  868. mFdForLogging, runnable.get()));
  869. nsresult nrv;
  870. nsCOMPtr<nsIEventTarget> stsTarget
  871. = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &nrv);
  872. if (NS_SUCCEEDED(nrv)) {
  873. nrv = stsTarget->Dispatch(new CertErrorRunnableRunnable(runnable),
  874. NS_DISPATCH_NORMAL);
  875. }
  876. if (NS_SUCCEEDED(nrv)) {
  877. return NS_OK;
  878. }
  879. NS_ERROR("Failed to dispatch CertErrorRunnable");
  880. error = PR_INVALID_STATE_ERROR;
  881. }
  882. }
  883. }
  884. if (error == 0) {
  885. NS_NOTREACHED("no error set during certificate validation failure");
  886. error = PR_INVALID_STATE_ERROR;
  887. }
  888. RefPtr<SSLServerCertVerificationResult> failure(
  889. new SSLServerCertVerificationResult(mInfoObject, error));
  890. failure->Dispatch();
  891. return NS_OK;
  892. }
  893. } // unnamed namespace
  894. // Extracts whatever information we need out of fd (using SSL_*) and passes it
  895. // to SSLServerCertVerificationJob::Dispatch. SSLServerCertVerificationJob should
  896. // never do anything with fd except logging.
  897. SECStatus
  898. AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer)
  899. {
  900. RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
  901. if (!certVerifier) {
  902. PR_SetError(SEC_ERROR_NOT_INITIALIZED, 0);
  903. return SECFailure;
  904. }
  905. // Runs on the socket transport thread
  906. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  907. ("[%p] starting AuthCertificateHook\n", fd));
  908. // Modern libssl always passes PR_TRUE for checkSig, and we have no means of
  909. // doing verification without checking signatures.
  910. NS_ASSERTION(checkSig, "AuthCertificateHook: checkSig unexpectedly false");
  911. // PSM never causes libssl to call this function with PR_TRUE for isServer,
  912. // and many things in PSM assume that we are a client.
  913. NS_ASSERTION(!isServer, "AuthCertificateHook: isServer unexpectedly true");
  914. nsNSSSocketInfo* socketInfo = static_cast<nsNSSSocketInfo*>(arg);
  915. UniqueCERTCertificate serverCert(SSL_PeerCertificate(fd));
  916. if (!checkSig || isServer || !socketInfo || !serverCert) {
  917. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  918. return SECFailure;
  919. }
  920. // Get the peer certificate chain for error reporting
  921. UniqueCERTCertList peerCertChain(SSL_PeerCertificateChain(fd));
  922. if (!peerCertChain) {
  923. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  924. return SECFailure;
  925. }
  926. socketInfo->SetFullHandshake();
  927. Time now(Now());
  928. PRTime prnow(PR_Now());
  929. if (BlockServerCertChangeForSpdy(socketInfo, serverCert) != SECSuccess)
  930. return SECFailure;
  931. nsCOMPtr<nsISSLSocketControl> sslSocketControl = do_QueryInterface(
  932. NS_ISUPPORTS_CAST(nsITransportSecurityInfo*, socketInfo));
  933. if (sslSocketControl && sslSocketControl->GetBypassAuthentication()) {
  934. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  935. ("[%p] Bypass Auth in AuthCertificateHook\n", fd));
  936. return SECSuccess;
  937. }
  938. bool onSTSThread;
  939. nsresult nrv;
  940. nsCOMPtr<nsIEventTarget> sts
  941. = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &nrv);
  942. if (NS_SUCCEEDED(nrv)) {
  943. nrv = sts->IsOnCurrentThread(&onSTSThread);
  944. }
  945. if (NS_FAILED(nrv)) {
  946. NS_ERROR("Could not get STS service or IsOnCurrentThread failed");
  947. PR_SetError(PR_UNKNOWN_ERROR, 0);
  948. return SECFailure;
  949. }
  950. // SSL_PeerStapledOCSPResponses will never return a non-empty response if
  951. // OCSP stapling wasn't enabled because libssl wouldn't have let the server
  952. // return a stapled OCSP response.
  953. // We don't own these pointers.
  954. const SECItemArray* csa = SSL_PeerStapledOCSPResponses(fd);
  955. SECItem* stapledOCSPResponse = nullptr;
  956. // we currently only support single stapled responses
  957. if (csa && csa->len == 1) {
  958. stapledOCSPResponse = &csa->items[0];
  959. }
  960. const SECItem* sctsFromTLSExtension = SSL_PeerSignedCertTimestamps(fd);
  961. if (sctsFromTLSExtension && sctsFromTLSExtension->len == 0) {
  962. // SSL_PeerSignedCertTimestamps returns null on error and empty item
  963. // when no extension was returned by the server. We always use null when
  964. // no extension was received (for whatever reason), ignoring errors.
  965. sctsFromTLSExtension = nullptr;
  966. }
  967. uint32_t providerFlags = 0;
  968. socketInfo->GetProviderFlags(&providerFlags);
  969. if (onSTSThread) {
  970. // We *must* do certificate verification on a background thread because
  971. // we need the socket transport thread to be free for our OCSP requests,
  972. // and we *want* to do certificate verification on a background thread
  973. // because of the performance benefits of doing so.
  974. socketInfo->SetCertVerificationWaiting();
  975. SECStatus rv = SSLServerCertVerificationJob::Dispatch(
  976. certVerifier, static_cast<const void*>(fd), socketInfo,
  977. serverCert, peerCertChain, stapledOCSPResponse,
  978. sctsFromTLSExtension, providerFlags, now, prnow);
  979. return rv;
  980. }
  981. // We can't do certificate verification on a background thread, because the
  982. // thread doing the network I/O may not interrupt its network I/O on receipt
  983. // of our SSLServerCertVerificationResult event, and/or it might not even be
  984. // a non-blocking socket.
  985. SECStatus rv = AuthCertificate(*certVerifier, socketInfo, serverCert,
  986. peerCertChain, stapledOCSPResponse,
  987. sctsFromTLSExtension, providerFlags, now);
  988. MOZ_ASSERT(peerCertChain || rv != SECSuccess,
  989. "AuthCertificate() should take ownership of chain on failure");
  990. if (rv == SECSuccess) {
  991. return SECSuccess;
  992. }
  993. PRErrorCode error = PR_GetError();
  994. if (error != 0) {
  995. RefPtr<CertErrorRunnable> runnable(
  996. CreateCertErrorRunnable(*certVerifier, error, socketInfo, serverCert,
  997. static_cast<const void*>(fd), providerFlags,
  998. prnow));
  999. if (!runnable) {
  1000. // CreateCertErrorRunnable sets a new error code when it fails
  1001. error = PR_GetError();
  1002. } else {
  1003. // We have to return SECSuccess or SECFailure based on the result of the
  1004. // override processing, so we must block this thread waiting for it. The
  1005. // CertErrorRunnable will NOT dispatch the result at all, since we passed
  1006. // false for CreateCertErrorRunnable's async parameter
  1007. nrv = runnable->DispatchToMainThreadAndWait();
  1008. if (NS_FAILED(nrv)) {
  1009. NS_ERROR("Failed to dispatch CertErrorRunnable");
  1010. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  1011. return SECFailure;
  1012. }
  1013. if (!runnable->mResult) {
  1014. NS_ERROR("CertErrorRunnable did not set result");
  1015. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  1016. return SECFailure;
  1017. }
  1018. if (runnable->mResult->mErrorCode == 0) {
  1019. return SECSuccess; // cert error override occurred.
  1020. }
  1021. // We must call SetCanceled here to set the error message type
  1022. // in case it isn't PlainErrorMessage, which is what we would
  1023. // default to if we just called
  1024. // PR_SetError(runnable->mResult->mErrorCode, 0) and returned
  1025. // SECFailure without doing this.
  1026. socketInfo->SetCanceled(runnable->mResult->mErrorCode,
  1027. runnable->mResult->mErrorMessageType);
  1028. error = runnable->mResult->mErrorCode;
  1029. }
  1030. }
  1031. if (error == 0) {
  1032. NS_ERROR("error code not set");
  1033. error = PR_UNKNOWN_ERROR;
  1034. }
  1035. PR_SetError(error, 0);
  1036. return SECFailure;
  1037. }
  1038. SSLServerCertVerificationResult::SSLServerCertVerificationResult(
  1039. nsNSSSocketInfo* infoObject, PRErrorCode errorCode,
  1040. SSLErrorMessageType errorMessageType)
  1041. : mInfoObject(infoObject)
  1042. , mErrorCode(errorCode)
  1043. , mErrorMessageType(errorMessageType)
  1044. {
  1045. }
  1046. void
  1047. SSLServerCertVerificationResult::Dispatch()
  1048. {
  1049. nsresult rv;
  1050. nsCOMPtr<nsIEventTarget> stsTarget
  1051. = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
  1052. NS_ASSERTION(stsTarget,
  1053. "Failed to get socket transport service event target");
  1054. rv = stsTarget->Dispatch(this, NS_DISPATCH_NORMAL);
  1055. NS_ASSERTION(NS_SUCCEEDED(rv),
  1056. "Failed to dispatch SSLServerCertVerificationResult");
  1057. }
  1058. NS_IMETHODIMP
  1059. SSLServerCertVerificationResult::Run()
  1060. {
  1061. // XXX: This cast will be removed by the next patch
  1062. ((nsNSSSocketInfo*) mInfoObject.get())
  1063. ->SetCertVerificationResult(mErrorCode, mErrorMessageType);
  1064. return NS_OK;
  1065. }
  1066. } } // namespace mozilla::psm