tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

VerifySSLServerCertChild.cpp (5185B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et tw=80 : */
      3 
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "VerifySSLServerCertChild.h"
      9 
     10 #include "CertVerifier.h"
     11 #include "mozilla/ipc/Endpoint.h"
     12 #include "mozilla/net/SocketProcessBackgroundChild.h"
     13 #include "mozilla/psm/PVerifySSLServerCertParent.h"
     14 #include "mozilla/psm/PVerifySSLServerCertChild.h"
     15 #include "nsNSSIOLayer.h"
     16 #include "nsSerializationHelper.h"
     17 
     18 #include "secerr.h"
     19 
     20 extern mozilla::LazyLogModule gPIPNSSLog;
     21 
     22 namespace mozilla {
     23 namespace psm {
     24 
     25 VerifySSLServerCertChild::VerifySSLServerCertChild(
     26    SSLServerCertVerificationResult* aResultTask,
     27    nsTArray<nsTArray<uint8_t>>&& aPeerCertChain, uint32_t aProviderFlags)
     28    : mResultTask(aResultTask),
     29      mPeerCertChain(std::move(aPeerCertChain)),
     30      mProviderFlags(aProviderFlags) {}
     31 
     32 ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifySSLServerCertFinished(
     33    nsTArray<ByteArray>&& aBuiltCertChain,
     34    const uint16_t& aCertTransparencyStatus, const EVStatus& aEVStatus,
     35    const bool& aSucceeded, int32_t aFinalError,
     36    const nsITransportSecurityInfo::OverridableErrorCategory&
     37        aOverridableErrorCategory,
     38    const bool& aIsBuiltCertChainRootBuiltInRoot,
     39    const bool& aMadeOCSPRequests) {
     40  MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
     41          ("[%p] VerifySSLServerCertChild::RecvOnVerifySSLServerCertFinished",
     42           this));
     43 
     44  nsTArray<nsTArray<uint8_t>> certBytesArray;
     45  for (auto& cert : aBuiltCertChain) {
     46    certBytesArray.AppendElement(std::move(cert.data()));
     47  }
     48 
     49  nsresult rv = mResultTask->Dispatch(
     50      std::move(certBytesArray), std::move(mPeerCertChain),
     51      aCertTransparencyStatus, aEVStatus, aSucceeded, aFinalError,
     52      aOverridableErrorCategory, aIsBuiltCertChainRootBuiltInRoot,
     53      mProviderFlags, aMadeOCSPRequests);
     54  if (NS_FAILED(rv)) {
     55    // We can't release this off the STS thread because some parts of it are
     56    // not threadsafe. Just leak mResultTask.
     57    mResultTask.forget().leak();
     58  }
     59  return IPC_OK();
     60 }
     61 
     62 SECStatus RemoteProcessCertVerification(
     63    nsTArray<nsTArray<uint8_t>>&& aPeerCertChain, const nsACString& aHostName,
     64    int32_t aPort, const OriginAttributes& aOriginAttributes,
     65    Maybe<nsTArray<uint8_t>>& aStapledOCSPResponse,
     66    Maybe<nsTArray<uint8_t>>& aSctsFromTLSExtension,
     67    Maybe<DelegatedCredentialInfo>& aDcInfo, uint32_t aProviderFlags,
     68    uint32_t aCertVerifierFlags, SSLServerCertVerificationResult* aResultTask) {
     69  if (!aResultTask) {
     70    PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
     71    return SECFailure;
     72  }
     73 
     74  nsTArray<ByteArray> peerCertBytes;
     75  for (auto& certBytes : aPeerCertChain) {
     76    peerCertBytes.AppendElement(ByteArray(certBytes));
     77  }
     78 
     79  Maybe<ByteArray> stapledOCSPResponse;
     80  if (aStapledOCSPResponse) {
     81    stapledOCSPResponse.emplace();
     82    stapledOCSPResponse->data().Assign(*aStapledOCSPResponse);
     83  }
     84 
     85  Maybe<ByteArray> sctsFromTLSExtension;
     86  if (aSctsFromTLSExtension) {
     87    sctsFromTLSExtension.emplace();
     88    sctsFromTLSExtension->data().Assign(*aSctsFromTLSExtension);
     89  }
     90 
     91  Maybe<DelegatedCredentialInfoArg> dcInfo;
     92  if (aDcInfo) {
     93    dcInfo.emplace();
     94    dcInfo.ref().scheme() = static_cast<uint32_t>(aDcInfo->scheme);
     95    dcInfo.ref().authKeyBits() = static_cast<uint32_t>(aDcInfo->authKeyBits);
     96  }
     97 
     98  ipc::Endpoint<PVerifySSLServerCertParent> parentEndpoint;
     99  ipc::Endpoint<PVerifySSLServerCertChild> childEndpoint;
    100  PVerifySSLServerCert::CreateEndpoints(&parentEndpoint, &childEndpoint);
    101 
    102  // Create a dedicated nsCString, so that our lambda below can take an
    103  // ownership stake in the underlying string buffer:
    104  nsCString hostName(aHostName);
    105 
    106  if (NS_FAILED(net::SocketProcessBackgroundChild::WithActor(
    107          "SendInitVerifySSLServerCert",
    108          [endpoint = std::move(parentEndpoint),
    109           peerCertBytes = std::move(peerCertBytes),
    110           hostName = std::move(hostName), port(aPort),
    111           originAttributes(aOriginAttributes),
    112           stapledOCSPResponse = std::move(stapledOCSPResponse),
    113           sctsFromTLSExtension = std::move(sctsFromTLSExtension),
    114           dcInfo = std::move(dcInfo), providerFlags(aProviderFlags),
    115           certVerifierFlags(aCertVerifierFlags)](
    116              net::SocketProcessBackgroundChild* aActor) mutable {
    117            (void)aActor->SendInitVerifySSLServerCert(
    118                std::move(endpoint), peerCertBytes, hostName, port,
    119                originAttributes, stapledOCSPResponse, sctsFromTLSExtension,
    120                dcInfo, providerFlags, certVerifierFlags);
    121          }))) {
    122    PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
    123    return SECFailure;
    124  }
    125 
    126  RefPtr<VerifySSLServerCertChild> authCert = new VerifySSLServerCertChild(
    127      aResultTask, std::move(aPeerCertChain), aProviderFlags);
    128  if (!childEndpoint.Bind(authCert)) {
    129    PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
    130    return SECFailure;
    131  }
    132 
    133  PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
    134  return SECWouldBlock;
    135 }
    136 
    137 }  // namespace psm
    138 }  // namespace mozilla