nsNSSCallbacks.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299
  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. #include "nsNSSCallbacks.h"
  7. #include "PSMRunnable.h"
  8. #include "ScopedNSSTypes.h"
  9. #include "SharedCertVerifier.h"
  10. #include "SharedSSLState.h"
  11. #include "mozilla/ArrayUtils.h"
  12. #include "mozilla/Assertions.h"
  13. #include "mozilla/Casting.h"
  14. #include "mozilla/RefPtr.h"
  15. #include "mozilla/TimeStamp.h"
  16. #include "mozilla/Unused.h"
  17. #include "nsContentUtils.h"
  18. #include "nsICertOverrideService.h"
  19. #include "nsIHttpChannelInternal.h"
  20. #include "nsIPrompt.h"
  21. #include "nsISupportsPriority.h"
  22. #include "nsITokenDialogs.h"
  23. #include "nsIUploadChannel.h"
  24. #include "nsIWebProgressListener.h"
  25. #include "nsNSSCertificate.h"
  26. #include "nsNSSComponent.h"
  27. #include "nsNSSIOLayer.h"
  28. #include "nsNetUtil.h"
  29. #include "nsProtectedAuthThread.h"
  30. #include "nsProxyRelease.h"
  31. #include "pkix/pkixtypes.h"
  32. #include "ssl.h"
  33. #include "sslproto.h"
  34. using namespace mozilla;
  35. using namespace mozilla::psm;
  36. extern LazyLogModule gPIPNSSLog;
  37. namespace {
  38. // Bits in bit mask for SSL_REASONS_FOR_NOT_FALSE_STARTING telemetry probe
  39. // These bits are numbered so that the least subtle issues have higher values.
  40. // This should make it easier for us to interpret the results.
  41. const uint32_t NPN_NOT_NEGOTIATED = 64;
  42. const uint32_t POSSIBLE_VERSION_DOWNGRADE = 4;
  43. const uint32_t POSSIBLE_CIPHER_SUITE_DOWNGRADE = 2;
  44. const uint32_t KEA_NOT_SUPPORTED = 1;
  45. } // namespace
  46. class nsHTTPDownloadEvent : public Runnable {
  47. public:
  48. nsHTTPDownloadEvent();
  49. ~nsHTTPDownloadEvent();
  50. NS_IMETHOD Run();
  51. nsNSSHttpRequestSession *mRequestSession;
  52. RefPtr<nsHTTPListener> mListener;
  53. bool mResponsibleForDoneSignal;
  54. TimeStamp mStartTime;
  55. };
  56. nsHTTPDownloadEvent::nsHTTPDownloadEvent()
  57. :mResponsibleForDoneSignal(true)
  58. {
  59. }
  60. nsHTTPDownloadEvent::~nsHTTPDownloadEvent()
  61. {
  62. if (mResponsibleForDoneSignal && mListener)
  63. mListener->send_done_signal();
  64. mRequestSession->Release();
  65. }
  66. NS_IMETHODIMP
  67. nsHTTPDownloadEvent::Run()
  68. {
  69. if (!mListener)
  70. return NS_OK;
  71. nsresult rv;
  72. nsCOMPtr<nsIIOService> ios = do_GetIOService();
  73. NS_ENSURE_STATE(ios);
  74. nsCOMPtr<nsIChannel> chan;
  75. ios->NewChannel2(mRequestSession->mURL,
  76. nullptr,
  77. nullptr,
  78. nullptr, // aLoadingNode
  79. nsContentUtils::GetSystemPrincipal(),
  80. nullptr, // aTriggeringPrincipal
  81. nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
  82. nsIContentPolicy::TYPE_OTHER,
  83. getter_AddRefs(chan));
  84. NS_ENSURE_STATE(chan);
  85. // Security operations scheduled through normal HTTP channels are given
  86. // high priority to accommodate real time OCSP transactions.
  87. nsCOMPtr<nsISupportsPriority> priorityChannel = do_QueryInterface(chan);
  88. if (priorityChannel)
  89. priorityChannel->AdjustPriority(nsISupportsPriority::PRIORITY_HIGHEST);
  90. chan->SetLoadFlags(nsIRequest::LOAD_ANONYMOUS |
  91. nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
  92. // For OCSP requests, only the first party domain aspect of origin attributes
  93. // is used. This means that OCSP requests are shared across different
  94. // containers.
  95. if (mRequestSession->mOriginAttributes != NeckoOriginAttributes()) {
  96. NeckoOriginAttributes attrs;
  97. attrs.mFirstPartyDomain =
  98. mRequestSession->mOriginAttributes.mFirstPartyDomain;
  99. nsCOMPtr<nsILoadInfo> loadInfo = chan->GetLoadInfo();
  100. if (loadInfo) {
  101. rv = loadInfo->SetOriginAttributes(attrs);
  102. NS_ENSURE_SUCCESS(rv, rv);
  103. }
  104. }
  105. // Create a loadgroup for this new channel. This way if the channel
  106. // is redirected, we'll have a way to cancel the resulting channel.
  107. nsCOMPtr<nsILoadGroup> lg = do_CreateInstance(NS_LOADGROUP_CONTRACTID);
  108. chan->SetLoadGroup(lg);
  109. if (mRequestSession->mHasPostData)
  110. {
  111. nsCOMPtr<nsIInputStream> uploadStream;
  112. rv = NS_NewPostDataStream(getter_AddRefs(uploadStream),
  113. false,
  114. mRequestSession->mPostData);
  115. NS_ENSURE_SUCCESS(rv, rv);
  116. nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(chan));
  117. NS_ENSURE_STATE(uploadChannel);
  118. rv = uploadChannel->SetUploadStream(uploadStream,
  119. mRequestSession->mPostContentType,
  120. -1);
  121. NS_ENSURE_SUCCESS(rv, rv);
  122. }
  123. // Do not use SPDY for internal security operations. It could result
  124. // in the silent upgrade to ssl, which in turn could require an SSL
  125. // operation to fulfill something like an OCSP fetch, which is an
  126. // endless loop.
  127. nsCOMPtr<nsIHttpChannelInternal> internalChannel = do_QueryInterface(chan);
  128. if (internalChannel) {
  129. rv = internalChannel->SetAllowSpdy(false);
  130. NS_ENSURE_SUCCESS(rv, rv);
  131. }
  132. nsCOMPtr<nsIHttpChannel> hchan = do_QueryInterface(chan);
  133. NS_ENSURE_STATE(hchan);
  134. rv = hchan->SetAllowSTS(false);
  135. NS_ENSURE_SUCCESS(rv, rv);
  136. rv = hchan->SetRequestMethod(mRequestSession->mRequestMethod);
  137. NS_ENSURE_SUCCESS(rv, rv);
  138. mResponsibleForDoneSignal = false;
  139. mListener->mResponsibleForDoneSignal = true;
  140. mListener->mLoadGroup = lg.get();
  141. NS_ADDREF(mListener->mLoadGroup);
  142. mListener->mLoadGroupOwnerThread = PR_GetCurrentThread();
  143. rv = NS_NewStreamLoader(getter_AddRefs(mListener->mLoader),
  144. mListener);
  145. if (NS_SUCCEEDED(rv)) {
  146. mStartTime = TimeStamp::Now();
  147. rv = hchan->AsyncOpen2(mListener->mLoader);
  148. }
  149. if (NS_FAILED(rv)) {
  150. mListener->mResponsibleForDoneSignal = false;
  151. mResponsibleForDoneSignal = true;
  152. NS_RELEASE(mListener->mLoadGroup);
  153. mListener->mLoadGroup = nullptr;
  154. mListener->mLoadGroupOwnerThread = nullptr;
  155. }
  156. return NS_OK;
  157. }
  158. struct nsCancelHTTPDownloadEvent : Runnable {
  159. RefPtr<nsHTTPListener> mListener;
  160. NS_IMETHOD Run() override {
  161. mListener->FreeLoadGroup(true);
  162. mListener = nullptr;
  163. return NS_OK;
  164. }
  165. };
  166. mozilla::pkix::Result
  167. nsNSSHttpServerSession::createSessionFcn(const char* host,
  168. uint16_t portnum,
  169. /*out*/ nsNSSHttpServerSession** pSession)
  170. {
  171. if (!host || !pSession) {
  172. return Result::FATAL_ERROR_INVALID_ARGS;
  173. }
  174. nsNSSHttpServerSession* hss = new nsNSSHttpServerSession;
  175. if (!hss) {
  176. return Result::FATAL_ERROR_NO_MEMORY;
  177. }
  178. hss->mHost = host;
  179. hss->mPort = portnum;
  180. *pSession = hss;
  181. return Success;
  182. }
  183. mozilla::pkix::Result
  184. nsNSSHttpRequestSession::createFcn(const nsNSSHttpServerSession* session,
  185. const char* http_protocol_variant,
  186. const char* path_and_query_string,
  187. const char* http_request_method,
  188. const NeckoOriginAttributes& origin_attributes,
  189. const PRIntervalTime timeout,
  190. /*out*/ nsNSSHttpRequestSession** pRequest)
  191. {
  192. if (!session || !http_protocol_variant || !path_and_query_string ||
  193. !http_request_method || !pRequest) {
  194. return Result::FATAL_ERROR_INVALID_ARGS;
  195. }
  196. nsNSSHttpRequestSession* rs = new nsNSSHttpRequestSession;
  197. if (!rs) {
  198. return Result::FATAL_ERROR_NO_MEMORY;
  199. }
  200. rs->mTimeoutInterval = timeout;
  201. // Use a maximum timeout value of 10 seconds because of bug 404059.
  202. // FIXME: Use a better approach once 406120 is ready.
  203. uint32_t maxBug404059Timeout = PR_TicksPerSecond() * 10;
  204. if (timeout > maxBug404059Timeout) {
  205. rs->mTimeoutInterval = maxBug404059Timeout;
  206. }
  207. rs->mURL.Assign(http_protocol_variant);
  208. rs->mURL.AppendLiteral("://");
  209. rs->mURL.Append(session->mHost);
  210. rs->mURL.Append(':');
  211. rs->mURL.AppendInt(session->mPort);
  212. rs->mURL.Append(path_and_query_string);
  213. rs->mOriginAttributes = origin_attributes;
  214. rs->mRequestMethod = http_request_method;
  215. *pRequest = rs;
  216. return Success;
  217. }
  218. mozilla::pkix::Result
  219. nsNSSHttpRequestSession::setPostDataFcn(const char* http_data,
  220. const uint32_t http_data_len,
  221. const char* http_content_type)
  222. {
  223. mHasPostData = true;
  224. mPostData.Assign(http_data, http_data_len);
  225. mPostContentType.Assign(http_content_type);
  226. return Success;
  227. }
  228. mozilla::pkix::Result
  229. nsNSSHttpRequestSession::trySendAndReceiveFcn(PRPollDesc** pPollDesc,
  230. uint16_t* http_response_code,
  231. const char** http_response_content_type,
  232. const char** http_response_headers,
  233. const char** http_response_data,
  234. uint32_t* http_response_data_len)
  235. {
  236. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  237. ("nsNSSHttpRequestSession::trySendAndReceiveFcn to %s\n", mURL.get()));
  238. bool onSTSThread;
  239. nsresult nrv;
  240. nsCOMPtr<nsIEventTarget> sts
  241. = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &nrv);
  242. if (NS_FAILED(nrv)) {
  243. NS_ERROR("Could not get STS service");
  244. return Result::FATAL_ERROR_INVALID_STATE;
  245. }
  246. nrv = sts->IsOnCurrentThread(&onSTSThread);
  247. if (NS_FAILED(nrv)) {
  248. NS_ERROR("IsOnCurrentThread failed");
  249. return Result::FATAL_ERROR_INVALID_STATE;
  250. }
  251. if (onSTSThread) {
  252. NS_ERROR("nsNSSHttpRequestSession::trySendAndReceiveFcn called on socket "
  253. "thread; this will not work.");
  254. return Result::FATAL_ERROR_INVALID_STATE;
  255. }
  256. const int max_retries = 2;
  257. int retry_count = 0;
  258. bool retryable_error = false;
  259. Result rv = Result::ERROR_UNKNOWN_ERROR;
  260. do
  261. {
  262. if (retry_count > 0)
  263. {
  264. if (retryable_error)
  265. {
  266. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  267. ("nsNSSHttpRequestSession::trySendAndReceiveFcn - sleeping and retrying: %d of %d\n",
  268. retry_count, max_retries));
  269. }
  270. PR_Sleep( PR_MillisecondsToInterval(300) * retry_count );
  271. }
  272. ++retry_count;
  273. retryable_error = false;
  274. rv =
  275. internal_send_receive_attempt(retryable_error, pPollDesc, http_response_code,
  276. http_response_content_type, http_response_headers,
  277. http_response_data, http_response_data_len);
  278. }
  279. while (retryable_error &&
  280. retry_count < max_retries);
  281. if (retry_count > 1)
  282. {
  283. if (retryable_error)
  284. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  285. ("nsNSSHttpRequestSession::trySendAndReceiveFcn - still failing, giving up...\n"));
  286. else
  287. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  288. ("nsNSSHttpRequestSession::trySendAndReceiveFcn - success at attempt %d\n",
  289. retry_count));
  290. }
  291. return rv;
  292. }
  293. void
  294. nsNSSHttpRequestSession::AddRef()
  295. {
  296. ++mRefCount;
  297. }
  298. void
  299. nsNSSHttpRequestSession::Release()
  300. {
  301. int32_t newRefCount = --mRefCount;
  302. if (!newRefCount) {
  303. delete this;
  304. }
  305. }
  306. mozilla::pkix::Result
  307. nsNSSHttpRequestSession::internal_send_receive_attempt(bool &retryable_error,
  308. PRPollDesc **pPollDesc,
  309. uint16_t *http_response_code,
  310. const char **http_response_content_type,
  311. const char **http_response_headers,
  312. const char **http_response_data,
  313. uint32_t *http_response_data_len)
  314. {
  315. if (pPollDesc) *pPollDesc = nullptr;
  316. if (http_response_code) *http_response_code = 0;
  317. if (http_response_content_type) *http_response_content_type = 0;
  318. if (http_response_headers) *http_response_headers = 0;
  319. if (http_response_data) *http_response_data = 0;
  320. uint32_t acceptableResultSize = 0;
  321. if (http_response_data_len)
  322. {
  323. acceptableResultSize = *http_response_data_len;
  324. *http_response_data_len = 0;
  325. }
  326. if (!mListener) {
  327. return Result::FATAL_ERROR_INVALID_STATE;
  328. }
  329. Mutex& waitLock = mListener->mLock;
  330. CondVar& waitCondition = mListener->mCondition;
  331. volatile bool &waitFlag = mListener->mWaitFlag;
  332. waitFlag = true;
  333. RefPtr<nsHTTPDownloadEvent> event(new nsHTTPDownloadEvent);
  334. if (!event) {
  335. return Result::FATAL_ERROR_NO_MEMORY;
  336. }
  337. event->mListener = mListener;
  338. this->AddRef();
  339. event->mRequestSession = this;
  340. nsresult rv = NS_DispatchToMainThread(event);
  341. if (NS_FAILED(rv)) {
  342. event->mResponsibleForDoneSignal = false;
  343. return Result::FATAL_ERROR_LIBRARY_FAILURE;
  344. }
  345. bool request_canceled = false;
  346. {
  347. MutexAutoLock locker(waitLock);
  348. const PRIntervalTime start_time = PR_IntervalNow();
  349. PRIntervalTime wait_interval;
  350. bool running_on_main_thread = NS_IsMainThread();
  351. if (running_on_main_thread)
  352. {
  353. // The result of running this on the main thread
  354. // is a series of small timeouts mixed with spinning the
  355. // event loop - this is always dangerous as there is so much main
  356. // thread code that does not expect to be called re-entrantly. Your
  357. // app really shouldn't do that.
  358. NS_WARNING("Security network blocking I/O on Main Thread");
  359. // let's process events quickly
  360. wait_interval = PR_MicrosecondsToInterval(50);
  361. }
  362. else
  363. {
  364. // On a secondary thread, it's fine to wait some more for
  365. // for the condition variable.
  366. wait_interval = PR_MillisecondsToInterval(250);
  367. }
  368. while (waitFlag)
  369. {
  370. if (running_on_main_thread)
  371. {
  372. // Networking runs on the main thread, which we happen to block here.
  373. // Processing events will allow the OCSP networking to run while we
  374. // are waiting. Thanks a lot to Darin Fisher for rewriting the
  375. // thread manager. Thanks a lot to Christian Biesinger who
  376. // made me aware of this possibility. (kaie)
  377. MutexAutoUnlock unlock(waitLock);
  378. NS_ProcessNextEvent(nullptr);
  379. }
  380. waitCondition.Wait(wait_interval);
  381. if (!waitFlag)
  382. break;
  383. if (!request_canceled)
  384. {
  385. bool timeout =
  386. (PRIntervalTime)(PR_IntervalNow() - start_time) > mTimeoutInterval;
  387. if (timeout)
  388. {
  389. request_canceled = true;
  390. RefPtr<nsCancelHTTPDownloadEvent> cancelevent(
  391. new nsCancelHTTPDownloadEvent);
  392. cancelevent->mListener = mListener;
  393. rv = NS_DispatchToMainThread(cancelevent);
  394. if (NS_FAILED(rv)) {
  395. NS_WARNING("cannot post cancel event");
  396. }
  397. break;
  398. }
  399. }
  400. }
  401. }
  402. if (request_canceled) {
  403. return Result::ERROR_OCSP_SERVER_ERROR;
  404. }
  405. if (NS_FAILED(mListener->mResultCode)) {
  406. if (mListener->mResultCode == NS_ERROR_CONNECTION_REFUSED ||
  407. mListener->mResultCode == NS_ERROR_NET_RESET) {
  408. retryable_error = true;
  409. }
  410. return Result::ERROR_OCSP_SERVER_ERROR;
  411. }
  412. if (http_response_code)
  413. *http_response_code = mListener->mHttpResponseCode;
  414. if (mListener->mHttpRequestSucceeded && http_response_data &&
  415. http_response_data_len) {
  416. *http_response_data_len = mListener->mResultLen;
  417. // acceptableResultSize == 0 means: any size is acceptable
  418. if (acceptableResultSize != 0 &&
  419. acceptableResultSize < mListener->mResultLen) {
  420. return Result::ERROR_OCSP_SERVER_ERROR;
  421. }
  422. // Return data by reference, result data will be valid until "this" gets
  423. // destroyed.
  424. *http_response_data = (const char*)mListener->mResultData;
  425. }
  426. if (mListener->mHttpRequestSucceeded && http_response_content_type) {
  427. if (mListener->mHttpResponseContentType.Length()) {
  428. *http_response_content_type = mListener->mHttpResponseContentType.get();
  429. }
  430. }
  431. return Success;
  432. }
  433. nsNSSHttpRequestSession::nsNSSHttpRequestSession()
  434. : mRefCount(1),
  435. mHasPostData(false),
  436. mTimeoutInterval(0),
  437. mListener(new nsHTTPListener)
  438. {
  439. }
  440. nsNSSHttpRequestSession::~nsNSSHttpRequestSession()
  441. {
  442. }
  443. nsHTTPListener::nsHTTPListener()
  444. : mResultData(nullptr),
  445. mResultLen(0),
  446. mLock("nsHTTPListener.mLock"),
  447. mCondition(mLock, "nsHTTPListener.mCondition"),
  448. mWaitFlag(true),
  449. mResponsibleForDoneSignal(false),
  450. mLoadGroup(nullptr),
  451. mLoadGroupOwnerThread(nullptr)
  452. {
  453. }
  454. nsHTTPListener::~nsHTTPListener()
  455. {
  456. if (mResponsibleForDoneSignal)
  457. send_done_signal();
  458. if (mResultData) {
  459. free(const_cast<uint8_t *>(mResultData));
  460. }
  461. if (mLoader) {
  462. NS_ReleaseOnMainThread(mLoader.forget());
  463. }
  464. }
  465. NS_IMPL_ISUPPORTS(nsHTTPListener, nsIStreamLoaderObserver)
  466. void
  467. nsHTTPListener::FreeLoadGroup(bool aCancelLoad)
  468. {
  469. nsILoadGroup *lg = nullptr;
  470. MutexAutoLock locker(mLock);
  471. if (mLoadGroup) {
  472. if (mLoadGroupOwnerThread != PR_GetCurrentThread()) {
  473. NS_ASSERTION(false,
  474. "attempt to access nsHTTPDownloadEvent::mLoadGroup on multiple threads, leaking it!");
  475. }
  476. else {
  477. lg = mLoadGroup;
  478. mLoadGroup = nullptr;
  479. }
  480. }
  481. if (lg) {
  482. if (aCancelLoad) {
  483. lg->Cancel(NS_ERROR_ABORT);
  484. }
  485. NS_RELEASE(lg);
  486. }
  487. }
  488. NS_IMETHODIMP
  489. nsHTTPListener::OnStreamComplete(nsIStreamLoader* aLoader,
  490. nsISupports* aContext,
  491. nsresult aStatus,
  492. uint32_t stringLen,
  493. const uint8_t* string)
  494. {
  495. mResultCode = aStatus;
  496. FreeLoadGroup(false);
  497. nsCOMPtr<nsIRequest> req;
  498. nsCOMPtr<nsIHttpChannel> hchan;
  499. nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
  500. if (NS_FAILED(aStatus))
  501. {
  502. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  503. ("nsHTTPListener::OnStreamComplete status failed %d", aStatus));
  504. }
  505. if (NS_SUCCEEDED(rv))
  506. hchan = do_QueryInterface(req, &rv);
  507. if (NS_SUCCEEDED(rv))
  508. {
  509. rv = hchan->GetRequestSucceeded(&mHttpRequestSucceeded);
  510. if (NS_FAILED(rv))
  511. mHttpRequestSucceeded = false;
  512. mResultLen = stringLen;
  513. mResultData = string; // take ownership of allocation
  514. aStatus = NS_SUCCESS_ADOPTED_DATA;
  515. unsigned int rcode;
  516. rv = hchan->GetResponseStatus(&rcode);
  517. if (NS_FAILED(rv))
  518. mHttpResponseCode = 500;
  519. else
  520. mHttpResponseCode = rcode;
  521. hchan->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"),
  522. mHttpResponseContentType);
  523. }
  524. if (mResponsibleForDoneSignal)
  525. send_done_signal();
  526. return aStatus;
  527. }
  528. void nsHTTPListener::send_done_signal()
  529. {
  530. mResponsibleForDoneSignal = false;
  531. {
  532. MutexAutoLock locker(mLock);
  533. mWaitFlag = false;
  534. mCondition.NotifyAll();
  535. }
  536. }
  537. static char*
  538. ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIInterfaceRequestor *ir)
  539. {
  540. if (!NS_IsMainThread()) {
  541. NS_ERROR("ShowProtectedAuthPrompt called off the main thread");
  542. return nullptr;
  543. }
  544. char* protAuthRetVal = nullptr;
  545. // Get protected auth dialogs
  546. nsCOMPtr<nsITokenDialogs> dialogs;
  547. nsresult nsrv = getNSSDialogs(getter_AddRefs(dialogs),
  548. NS_GET_IID(nsITokenDialogs),
  549. NS_TOKENDIALOGS_CONTRACTID);
  550. if (NS_SUCCEEDED(nsrv))
  551. {
  552. nsProtectedAuthThread* protectedAuthRunnable = new nsProtectedAuthThread();
  553. if (protectedAuthRunnable)
  554. {
  555. NS_ADDREF(protectedAuthRunnable);
  556. protectedAuthRunnable->SetParams(slot);
  557. nsCOMPtr<nsIProtectedAuthThread> runnable = do_QueryInterface(protectedAuthRunnable);
  558. if (runnable)
  559. {
  560. nsrv = dialogs->DisplayProtectedAuth(ir, runnable);
  561. // We call join on the thread,
  562. // so we can be sure that no simultaneous access will happen.
  563. protectedAuthRunnable->Join();
  564. if (NS_SUCCEEDED(nsrv))
  565. {
  566. SECStatus rv = protectedAuthRunnable->GetResult();
  567. switch (rv)
  568. {
  569. case SECSuccess:
  570. protAuthRetVal = ToNewCString(nsDependentCString(PK11_PW_AUTHENTICATED));
  571. break;
  572. case SECWouldBlock:
  573. protAuthRetVal = ToNewCString(nsDependentCString(PK11_PW_RETRY));
  574. break;
  575. default:
  576. protAuthRetVal = nullptr;
  577. break;
  578. }
  579. }
  580. }
  581. NS_RELEASE(protectedAuthRunnable);
  582. }
  583. }
  584. return protAuthRetVal;
  585. }
  586. class PK11PasswordPromptRunnable : public SyncRunnableBase
  587. , public nsNSSShutDownObject
  588. {
  589. public:
  590. PK11PasswordPromptRunnable(PK11SlotInfo* slot,
  591. nsIInterfaceRequestor* ir)
  592. : mResult(nullptr),
  593. mSlot(slot),
  594. mIR(ir)
  595. {
  596. }
  597. virtual ~PK11PasswordPromptRunnable();
  598. // This doesn't own the PK11SlotInfo or any other NSS objects, so there's
  599. // nothing to release.
  600. virtual void virtualDestroyNSSReference() override {}
  601. char * mResult; // out
  602. virtual void RunOnTargetThread() override;
  603. private:
  604. PK11SlotInfo* const mSlot; // in
  605. nsIInterfaceRequestor* const mIR; // in
  606. };
  607. PK11PasswordPromptRunnable::~PK11PasswordPromptRunnable()
  608. {
  609. nsNSSShutDownPreventionLock locker;
  610. if (isAlreadyShutDown()) {
  611. return;
  612. }
  613. shutdown(ShutdownCalledFrom::Object);
  614. }
  615. void
  616. PK11PasswordPromptRunnable::RunOnTargetThread()
  617. {
  618. static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
  619. nsNSSShutDownPreventionLock locker;
  620. if (isAlreadyShutDown()) {
  621. return;
  622. }
  623. nsresult rv;
  624. nsCOMPtr<nsIPrompt> prompt;
  625. if (!mIR) {
  626. rv = nsNSSComponent::GetNewPrompter(getter_AddRefs(prompt));
  627. if (NS_FAILED(rv)) {
  628. return;
  629. }
  630. } else {
  631. prompt = do_GetInterface(mIR);
  632. MOZ_ASSERT(prompt, "Interface requestor should implement nsIPrompt");
  633. }
  634. if (!prompt) {
  635. return;
  636. }
  637. if (PK11_ProtectedAuthenticationPath(mSlot)) {
  638. mResult = ShowProtectedAuthPrompt(mSlot, mIR);
  639. return;
  640. }
  641. nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID));
  642. if (!nssComponent) {
  643. return;
  644. }
  645. NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(mSlot));
  646. const char16_t* formatStrings[] = {
  647. tokenName.get(),
  648. };
  649. nsAutoString promptString;
  650. rv = nssComponent->PIPBundleFormatStringFromName("CertPassPrompt",
  651. formatStrings,
  652. ArrayLength(formatStrings),
  653. promptString);
  654. if (NS_FAILED(rv)) {
  655. return;
  656. }
  657. nsXPIDLString password;
  658. // |checkState| is unused because |checkMsg| (the argument just before it) is
  659. // null, but XPConnect requires it to point to a valid bool nonetheless.
  660. bool checkState = false;
  661. bool userClickedOK = false;
  662. rv = prompt->PromptPassword(nullptr, promptString.get(),
  663. getter_Copies(password), nullptr, &checkState,
  664. &userClickedOK);
  665. if (NS_FAILED(rv) || !userClickedOK) {
  666. return;
  667. }
  668. mResult = ToNewUTF8String(password);
  669. }
  670. char*
  671. PK11PasswordPrompt(PK11SlotInfo* slot, PRBool /*retry*/, void* arg)
  672. {
  673. RefPtr<PK11PasswordPromptRunnable> runnable(
  674. new PK11PasswordPromptRunnable(slot,
  675. static_cast<nsIInterfaceRequestor*>(arg)));
  676. runnable->DispatchToMainThreadAndWait();
  677. return runnable->mResult;
  678. }
  679. static nsCString
  680. getKeaGroupName(uint32_t aKeaGroup)
  681. {
  682. nsCString groupName;
  683. switch (aKeaGroup) {
  684. case ssl_grp_ec_secp256r1:
  685. groupName = NS_LITERAL_CSTRING("P256");
  686. break;
  687. case ssl_grp_ec_secp384r1:
  688. groupName = NS_LITERAL_CSTRING("P384");
  689. break;
  690. case ssl_grp_ec_secp521r1:
  691. groupName = NS_LITERAL_CSTRING("P521");
  692. break;
  693. case ssl_grp_ec_curve25519:
  694. groupName = NS_LITERAL_CSTRING("x25519");
  695. break;
  696. case ssl_grp_ffdhe_2048:
  697. groupName = NS_LITERAL_CSTRING("FF 2048");
  698. break;
  699. case ssl_grp_ffdhe_3072:
  700. groupName = NS_LITERAL_CSTRING("FF 3072");
  701. break;
  702. case ssl_grp_none:
  703. groupName = NS_LITERAL_CSTRING("none");
  704. break;
  705. case ssl_grp_ffdhe_custom:
  706. groupName = NS_LITERAL_CSTRING("custom");
  707. break;
  708. // All other groups are not enabled in Firefox. See namedGroups in
  709. // nsNSSIOLayer.cpp.
  710. default:
  711. // This really shouldn't happen!
  712. MOZ_ASSERT_UNREACHABLE("Invalid key exchange group.");
  713. groupName = NS_LITERAL_CSTRING("unknown group");
  714. }
  715. return groupName;
  716. }
  717. static nsCString
  718. getSignatureName(uint32_t aSignatureScheme)
  719. {
  720. nsCString signatureName;
  721. switch (aSignatureScheme) {
  722. case ssl_sig_none:
  723. signatureName = NS_LITERAL_CSTRING("none");
  724. break;
  725. case ssl_sig_rsa_pkcs1_sha1:
  726. signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA1");
  727. break;
  728. case ssl_sig_rsa_pkcs1_sha256:
  729. signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA256");
  730. break;
  731. case ssl_sig_rsa_pkcs1_sha384:
  732. signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA384");
  733. break;
  734. case ssl_sig_rsa_pkcs1_sha512:
  735. signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA512");
  736. break;
  737. case ssl_sig_ecdsa_secp256r1_sha256:
  738. signatureName = NS_LITERAL_CSTRING("ECDSA-P256-SHA256");
  739. break;
  740. case ssl_sig_ecdsa_secp384r1_sha384:
  741. signatureName = NS_LITERAL_CSTRING("ECDSA-P384-SHA384");
  742. break;
  743. case ssl_sig_ecdsa_secp521r1_sha512:
  744. signatureName = NS_LITERAL_CSTRING("ECDSA-P521-SHA512");
  745. break;
  746. case ssl_sig_rsa_pss_sha256:
  747. signatureName = NS_LITERAL_CSTRING("RSA-PSS-SHA256");
  748. break;
  749. case ssl_sig_rsa_pss_sha384:
  750. signatureName = NS_LITERAL_CSTRING("RSA-PSS-SHA384");
  751. break;
  752. case ssl_sig_rsa_pss_sha512:
  753. signatureName = NS_LITERAL_CSTRING("RSA-PSS-SHA512");
  754. break;
  755. case ssl_sig_ecdsa_sha1:
  756. signatureName = NS_LITERAL_CSTRING("ECDSA-SHA1");
  757. break;
  758. case ssl_sig_rsa_pkcs1_sha1md5:
  759. signatureName = NS_LITERAL_CSTRING("RSA-PKCS1-SHA1MD5");
  760. break;
  761. // All other groups are not enabled in Firefox. See sEnabledSignatureSchemes
  762. // in nsNSSIOLayer.cpp.
  763. default:
  764. // This really shouldn't happen!
  765. MOZ_ASSERT_UNREACHABLE("Invalid signature scheme.");
  766. signatureName = NS_LITERAL_CSTRING("unknown signature");
  767. }
  768. return signatureName;
  769. }
  770. // call with shutdown prevention lock held
  771. static void
  772. PreliminaryHandshakeDone(PRFileDesc* fd)
  773. {
  774. nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
  775. if (!infoObject)
  776. return;
  777. SSLChannelInfo channelInfo;
  778. if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) {
  779. infoObject->SetSSLVersionUsed(channelInfo.protocolVersion);
  780. infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted);
  781. SSLCipherSuiteInfo cipherInfo;
  782. if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
  783. sizeof cipherInfo) == SECSuccess) {
  784. /* Set the SSL Status information */
  785. RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
  786. if (!status) {
  787. status = new nsSSLStatus();
  788. infoObject->SetSSLStatus(status);
  789. }
  790. status->mHaveCipherSuiteAndProtocol = true;
  791. status->mCipherSuite = channelInfo.cipherSuite;
  792. status->mProtocolVersion = channelInfo.protocolVersion & 0xFF;
  793. status->mKeaGroup.Assign(getKeaGroupName(channelInfo.keaGroup));
  794. status->mSignatureSchemeName.Assign(
  795. getSignatureName(channelInfo.signatureScheme));
  796. infoObject->SetKEAUsed(channelInfo.keaType);
  797. infoObject->SetKEAKeyBits(channelInfo.keaKeyBits);
  798. infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm);
  799. }
  800. }
  801. // Don't update NPN details on renegotiation.
  802. if (infoObject->IsPreliminaryHandshakeDone()) {
  803. return;
  804. }
  805. // Get the NPN value.
  806. SSLNextProtoState state;
  807. unsigned char npnbuf[256];
  808. unsigned int npnlen;
  809. if (SSL_GetNextProto(fd, &state, npnbuf, &npnlen,
  810. AssertedCast<unsigned int>(ArrayLength(npnbuf)))
  811. == SECSuccess) {
  812. if (state == SSL_NEXT_PROTO_NEGOTIATED ||
  813. state == SSL_NEXT_PROTO_SELECTED) {
  814. infoObject->SetNegotiatedNPN(BitwiseCast<char*, unsigned char*>(npnbuf),
  815. npnlen);
  816. } else {
  817. infoObject->SetNegotiatedNPN(nullptr, 0);
  818. }
  819. } else {
  820. infoObject->SetNegotiatedNPN(nullptr, 0);
  821. }
  822. infoObject->SetPreliminaryHandshakeDone();
  823. }
  824. SECStatus
  825. CanFalseStartCallback(PRFileDesc* fd, void* client_data, PRBool *canFalseStart)
  826. {
  827. *canFalseStart = false;
  828. nsNSSShutDownPreventionLock locker;
  829. nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
  830. if (!infoObject) {
  831. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  832. return SECFailure;
  833. }
  834. infoObject->SetFalseStartCallbackCalled();
  835. if (infoObject->isAlreadyShutDown()) {
  836. MOZ_CRASH("SSL socket used after NSS shut down");
  837. PR_SetError(PR_INVALID_STATE_ERROR, 0);
  838. return SECFailure;
  839. }
  840. PreliminaryHandshakeDone(fd);
  841. uint32_t reasonsForNotFalseStarting = 0;
  842. SSLChannelInfo channelInfo;
  843. if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) != SECSuccess) {
  844. return SECSuccess;
  845. }
  846. SSLCipherSuiteInfo cipherInfo;
  847. if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
  848. sizeof (cipherInfo)) != SECSuccess) {
  849. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
  850. " KEA %d\n", fd,
  851. static_cast<int32_t>(channelInfo.keaType)));
  852. return SECSuccess;
  853. }
  854. nsSSLIOLayerHelpers& helpers = infoObject->SharedState().IOLayerHelpers();
  855. // Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
  856. // TLS 1.3 and later. See Bug 861310 for all the details as to why.
  857. if (channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2) {
  858. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
  859. "SSL Version must be TLS 1.2, was %x\n", fd,
  860. static_cast<int32_t>(channelInfo.protocolVersion)));
  861. reasonsForNotFalseStarting |= POSSIBLE_VERSION_DOWNGRADE;
  862. }
  863. // See bug 952863 for why ECDHE is allowed, but DHE (and RSA) are not.
  864. if (channelInfo.keaType != ssl_kea_ecdh) {
  865. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
  866. "unsupported KEA %d\n", fd,
  867. static_cast<int32_t>(channelInfo.keaType)));
  868. reasonsForNotFalseStarting |= KEA_NOT_SUPPORTED;
  869. }
  870. // Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
  871. // mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
  872. // design. See bug 1109766 for more details.
  873. if (cipherInfo.macAlgorithm != ssl_mac_aead) {
  874. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  875. ("CanFalseStartCallback [%p] failed - non-AEAD cipher used, %d, "
  876. "is not supported with False Start.\n", fd,
  877. static_cast<int32_t>(cipherInfo.symCipher)));
  878. reasonsForNotFalseStarting |= POSSIBLE_CIPHER_SUITE_DOWNGRADE;
  879. }
  880. // XXX: An attacker can choose which protocols are advertised in the
  881. // NPN extension. TODO(Bug 861311): We should restrict the ability
  882. // of an attacker leverage this capability by restricting false start
  883. // to the same protocol we previously saw for the server, after the
  884. // first successful connection to the server.
  885. // Enforce NPN to do false start if policy requires it. Do this as an
  886. // indicator if server compatibility.
  887. if (helpers.mFalseStartRequireNPN) {
  888. nsAutoCString negotiatedNPN;
  889. if (NS_FAILED(infoObject->GetNegotiatedNPN(negotiatedNPN)) ||
  890. !negotiatedNPN.Length()) {
  891. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] failed - "
  892. "NPN cannot be verified\n", fd));
  893. reasonsForNotFalseStarting |= NPN_NOT_NEGOTIATED;
  894. }
  895. }
  896. if (reasonsForNotFalseStarting == 0) {
  897. *canFalseStart = PR_TRUE;
  898. infoObject->SetFalseStarted();
  899. infoObject->NoteTimeUntilReady();
  900. MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CanFalseStartCallback [%p] ok\n", fd));
  901. }
  902. return SECSuccess;
  903. }
  904. // In the case of session resumption, the AuthCertificate hook has been bypassed
  905. // (because we've previously successfully connected to our peer). That being the
  906. // case, we unfortunately don't know if the peer's server certificate verified
  907. // as extended validation or not. To address this, we attempt to build a
  908. // verified EV certificate chain here using as much of the original context as
  909. // possible (e.g. stapled OCSP responses, SCTs, the hostname, the first party
  910. // domain, etc.). Note that because we are on the socket thread, this must not
  911. // cause any network requests, hence the use of FLAG_LOCAL_ONLY.
  912. static void
  913. DetermineEVStatusAndSetNewCert(RefPtr<nsSSLStatus> sslStatus, PRFileDesc* fd,
  914. nsNSSSocketInfo* infoObject)
  915. {
  916. MOZ_ASSERT(sslStatus);
  917. MOZ_ASSERT(fd);
  918. MOZ_ASSERT(infoObject);
  919. if (!sslStatus || !fd || !infoObject) {
  920. return;
  921. }
  922. UniqueCERTCertificate cert(SSL_PeerCertificate(fd));
  923. MOZ_ASSERT(cert, "SSL_PeerCertificate failed in TLS handshake callback?");
  924. if (!cert) {
  925. return;
  926. }
  927. RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
  928. MOZ_ASSERT(certVerifier,
  929. "Certificate verifier uninitialized in TLS handshake callback?");
  930. if (!certVerifier) {
  931. return;
  932. }
  933. // We don't own these pointers.
  934. const SECItemArray* stapledOCSPResponses = SSL_PeerStapledOCSPResponses(fd);
  935. const SECItem* stapledOCSPResponse = nullptr;
  936. // we currently only support single stapled responses
  937. if (stapledOCSPResponses && stapledOCSPResponses->len == 1) {
  938. stapledOCSPResponse = &stapledOCSPResponses->items[0];
  939. }
  940. const SECItem* sctsFromTLSExtension = SSL_PeerSignedCertTimestamps(fd);
  941. if (sctsFromTLSExtension && sctsFromTLSExtension->len == 0) {
  942. // SSL_PeerSignedCertTimestamps returns null on error and empty item
  943. // when no extension was returned by the server. We always use null when
  944. // no extension was received (for whatever reason), ignoring errors.
  945. sctsFromTLSExtension = nullptr;
  946. }
  947. int flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY |
  948. mozilla::psm::CertVerifier::FLAG_MUST_BE_EV;
  949. if (!infoObject->SharedState().IsOCSPStaplingEnabled() ||
  950. !infoObject->SharedState().IsOCSPMustStapleEnabled()) {
  951. flags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST;
  952. }
  953. SECOidTag evOidPolicy;
  954. UniqueCERTCertList unusedBuiltChain;
  955. const bool saveIntermediates = false;
  956. mozilla::pkix::Result rv = certVerifier->VerifySSLServerCert(
  957. cert,
  958. stapledOCSPResponse,
  959. sctsFromTLSExtension,
  960. mozilla::pkix::Now(),
  961. infoObject,
  962. infoObject->GetHostNameRaw(),
  963. unusedBuiltChain,
  964. saveIntermediates,
  965. flags,
  966. infoObject->GetOriginAttributes(),
  967. &evOidPolicy);
  968. RefPtr<nsNSSCertificate> nssc(nsNSSCertificate::Create(cert.get()));
  969. if (rv == Success && evOidPolicy != SEC_OID_UNKNOWN) {
  970. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  971. ("HandshakeCallback using NEW cert %p (is EV)", nssc.get()));
  972. sslStatus->SetServerCert(nssc, EVStatus::EV);
  973. } else {
  974. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  975. ("HandshakeCallback using NEW cert %p (is not EV)", nssc.get()));
  976. sslStatus->SetServerCert(nssc, EVStatus::NotEV);
  977. }
  978. }
  979. void HandshakeCallback(PRFileDesc* fd, void* client_data) {
  980. nsNSSShutDownPreventionLock locker;
  981. SECStatus rv;
  982. nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
  983. // Do the bookkeeping that needs to be done after the
  984. // server's ServerHello...ServerHelloDone have been processed, but that doesn't
  985. // need the handshake to be completed.
  986. PreliminaryHandshakeDone(fd);
  987. nsSSLIOLayerHelpers& ioLayerHelpers
  988. = infoObject->SharedState().IOLayerHelpers();
  989. SSLVersionRange versions(infoObject->GetTLSVersionRange());
  990. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  991. ("[%p] HandshakeCallback: succeeded using TLS version range (0x%04x,0x%04x)\n",
  992. fd, static_cast<unsigned int>(versions.min),
  993. static_cast<unsigned int>(versions.max)));
  994. // If the handshake completed, then we know the site is TLS tolerant
  995. ioLayerHelpers.rememberTolerantAtVersion(infoObject->GetHostName(),
  996. infoObject->GetPort(),
  997. versions.max);
  998. SSLChannelInfo channelInfo;
  999. rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo));
  1000. MOZ_ASSERT(rv == SECSuccess);
  1001. if (rv == SECSuccess) {
  1002. SSLCipherSuiteInfo cipherInfo;
  1003. rv = SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
  1004. sizeof cipherInfo);
  1005. MOZ_ASSERT(rv == SECSuccess);
  1006. if (rv == SECSuccess) {
  1007. MOZ_ASSERT(infoObject->GetKEAUsed() == channelInfo.keaType);
  1008. if (infoObject->IsFullHandshake()) {
  1009. switch (channelInfo.keaType) {
  1010. case ssl_kea_rsa:
  1011. break;
  1012. case ssl_kea_dh:
  1013. break;
  1014. case ssl_kea_ecdh:
  1015. break;
  1016. default:
  1017. MOZ_CRASH("impossible KEA");
  1018. break;
  1019. }
  1020. // RSA key exchange doesn't use a signature for auth.
  1021. if (channelInfo.keaType != ssl_kea_rsa) {
  1022. switch (channelInfo.authType) {
  1023. case ssl_auth_rsa:
  1024. case ssl_auth_rsa_sign:
  1025. break;
  1026. case ssl_auth_ecdsa:
  1027. break;
  1028. default:
  1029. MOZ_CRASH("impossible auth algorithm");
  1030. break;
  1031. }
  1032. }
  1033. }
  1034. }
  1035. }
  1036. PRBool siteSupportsSafeRenego;
  1037. if (channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_3) {
  1038. rv = SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn,
  1039. &siteSupportsSafeRenego);
  1040. MOZ_ASSERT(rv == SECSuccess);
  1041. if (rv != SECSuccess) {
  1042. siteSupportsSafeRenego = false;
  1043. }
  1044. } else {
  1045. // TLS 1.3 dropped support for renegotiation.
  1046. siteSupportsSafeRenego = true;
  1047. }
  1048. bool renegotiationUnsafe = !siteSupportsSafeRenego &&
  1049. ioLayerHelpers.treatUnsafeNegotiationAsBroken();
  1050. /* Set the SSL Status information */
  1051. RefPtr<nsSSLStatus> status(infoObject->SSLStatus());
  1052. if (!status) {
  1053. status = new nsSSLStatus();
  1054. infoObject->SetSSLStatus(status);
  1055. }
  1056. RememberCertErrorsTable::GetInstance().LookupCertErrorBits(infoObject,
  1057. status);
  1058. uint32_t state;
  1059. if (renegotiationUnsafe) {
  1060. state = nsIWebProgressListener::STATE_IS_BROKEN;
  1061. } else {
  1062. state = nsIWebProgressListener::STATE_IS_SECURE |
  1063. nsIWebProgressListener::STATE_SECURE_HIGH;
  1064. }
  1065. if (status->HasServerCert()) {
  1066. MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
  1067. ("HandshakeCallback KEEPING existing cert\n"));
  1068. } else {
  1069. DetermineEVStatusAndSetNewCert(status, fd, infoObject);
  1070. }
  1071. bool domainMismatch;
  1072. bool untrusted;
  1073. bool notValidAtThisTime;
  1074. // These all return NS_OK, so don't even bother checking the return values.
  1075. Unused << status->GetIsDomainMismatch(&domainMismatch);
  1076. Unused << status->GetIsUntrusted(&untrusted);
  1077. Unused << status->GetIsNotValidAtThisTime(&notValidAtThisTime);
  1078. // If we're here, the TLS handshake has succeeded. Thus if any of these
  1079. // booleans are true, the user has added an override for a certificate error.
  1080. if (domainMismatch || untrusted || notValidAtThisTime) {
  1081. state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN;
  1082. }
  1083. infoObject->SetSecurityState(state);
  1084. // XXX Bug 883674: We shouldn't be formatting messages here in PSM; instead,
  1085. // we should set a flag on the channel that higher (UI) level code can check
  1086. // to log the warning. In particular, these warnings should go to the web
  1087. // console instead of to the error console. Also, the warning is not
  1088. // localized.
  1089. if (!siteSupportsSafeRenego) {
  1090. nsXPIDLCString hostName;
  1091. infoObject->GetHostName(getter_Copies(hostName));
  1092. nsAutoString msg;
  1093. msg.Append(NS_ConvertASCIItoUTF16(hostName));
  1094. msg.AppendLiteral(" : server does not support RFC 5746, see CVE-2009-3555");
  1095. nsContentUtils::LogSimpleConsoleError(msg, "SSL");
  1096. }
  1097. infoObject->NoteTimeUntilReady();
  1098. infoObject->SetHandshakeCompleted();
  1099. }