/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set sw=2 ts=8 et tw=80 : */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "VerifySSLServerCertChild.h" #include "CertVerifier.h" #include "mozilla/ipc/Endpoint.h" #include "mozilla/net/SocketProcessBackgroundChild.h" #include "mozilla/psm/PVerifySSLServerCertParent.h" #include "mozilla/psm/PVerifySSLServerCertChild.h" #include "nsNSSIOLayer.h" #include "nsSerializationHelper.h" #include "secerr.h" extern mozilla::LazyLogModule gPIPNSSLog; namespace mozilla { namespace psm { VerifySSLServerCertChild::VerifySSLServerCertChild( SSLServerCertVerificationResult* aResultTask, nsTArray>&& aPeerCertChain, uint32_t aProviderFlags) : mResultTask(aResultTask), mPeerCertChain(std::move(aPeerCertChain)), mProviderFlags(aProviderFlags) {} ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess( nsTArray&& aBuiltCertChain, const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus, const bool& aIsBuiltCertChainRootBuiltInRoot, const bool& aMadeOCSPRequests) { MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("[%p] VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess", this)); nsTArray> certBytesArray; for (auto& cert : aBuiltCertChain) { certBytesArray.AppendElement(std::move(cert.data())); } mResultTask->Dispatch( std::move(certBytesArray), std::move(mPeerCertChain), aCertTransparencyStatus, static_cast(aEVStatus), true, 0, nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET, aIsBuiltCertChainRootBuiltInRoot, mProviderFlags, aMadeOCSPRequests); return IPC_OK(); } ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertFailure( const int32_t& aFinalError, const uint32_t& aOverridableErrorCategory, const bool& aMadeOCSPRequests) { mResultTask->Dispatch( nsTArray>(), std::move(mPeerCertChain), nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE, EVStatus::NotEV, false, aFinalError, static_cast( aOverridableErrorCategory), false, mProviderFlags, aMadeOCSPRequests); return IPC_OK(); } SECStatus RemoteProcessCertVerification( nsTArray>&& aPeerCertChain, const nsACString& aHostName, int32_t aPort, const OriginAttributes& aOriginAttributes, Maybe>& aStapledOCSPResponse, Maybe>& aSctsFromTLSExtension, Maybe& aDcInfo, uint32_t aProviderFlags, uint32_t aCertVerifierFlags, SSLServerCertVerificationResult* aResultTask) { if (!aResultTask) { PR_SetError(SEC_ERROR_INVALID_ARGS, 0); return SECFailure; } nsTArray peerCertBytes; for (auto& certBytes : aPeerCertChain) { peerCertBytes.AppendElement(ByteArray(certBytes)); } Maybe stapledOCSPResponse; if (aStapledOCSPResponse) { stapledOCSPResponse.emplace(); stapledOCSPResponse->data().Assign(*aStapledOCSPResponse); } Maybe sctsFromTLSExtension; if (aSctsFromTLSExtension) { sctsFromTLSExtension.emplace(); sctsFromTLSExtension->data().Assign(*aSctsFromTLSExtension); } Maybe dcInfo; if (aDcInfo) { dcInfo.emplace(); dcInfo.ref().scheme() = static_cast(aDcInfo->scheme); dcInfo.ref().authKeyBits() = static_cast(aDcInfo->authKeyBits); } ipc::Endpoint parentEndpoint; ipc::Endpoint childEndpoint; PVerifySSLServerCert::CreateEndpoints(&parentEndpoint, &childEndpoint); // Create a dedicated nsCString, so that our lambda below can take an // ownership stake in the underlying string buffer: nsCString hostName(aHostName); if (NS_FAILED(net::SocketProcessBackgroundChild::WithActor( "SendInitVerifySSLServerCert", [endpoint = std::move(parentEndpoint), peerCertBytes = std::move(peerCertBytes), hostName = std::move(hostName), port(aPort), originAttributes(aOriginAttributes), stapledOCSPResponse = std::move(stapledOCSPResponse), sctsFromTLSExtension = std::move(sctsFromTLSExtension), dcInfo = std::move(dcInfo), providerFlags(aProviderFlags), certVerifierFlags(aCertVerifierFlags)]( net::SocketProcessBackgroundChild* aActor) mutable { Unused << aActor->SendInitVerifySSLServerCert( std::move(endpoint), peerCertBytes, hostName, port, originAttributes, stapledOCSPResponse, sctsFromTLSExtension, dcInfo, providerFlags, certVerifierFlags); }))) { PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); return SECFailure; } RefPtr authCert = new VerifySSLServerCertChild( aResultTask, std::move(aPeerCertChain), aProviderFlags); if (!childEndpoint.Bind(authCert)) { PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); return SECFailure; } PR_SetError(PR_WOULD_BLOCK_ERROR, 0); return SECWouldBlock; } } // namespace psm } // namespace mozilla