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