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/BackgroundChild.h"
12 #include "mozilla/ipc/PBackgroundChild.h"
13 #include "nsNSSIOLayer.h"
14 #include "nsSerializationHelper.h"
15 
16 extern mozilla::LazyLogModule gPIPNSSLog;
17 
18 namespace mozilla {
19 namespace psm {
20 
VerifySSLServerCertChild(const UniqueCERTCertificate & aCert,SSLServerCertVerificationResult * aResultTask,nsTArray<nsTArray<uint8_t>> && aPeerCertChain,uint32_t aProviderFlags)21 VerifySSLServerCertChild::VerifySSLServerCertChild(
22     const UniqueCERTCertificate& aCert,
23     SSLServerCertVerificationResult* aResultTask,
24     nsTArray<nsTArray<uint8_t>>&& aPeerCertChain, uint32_t aProviderFlags)
25     : mCert(CERT_DupCertificate(aCert.get())),
26       mResultTask(aResultTask),
27       mPeerCertChain(std::move(aPeerCertChain)),
28       mProviderFlags(aProviderFlags) {}
29 
RecvOnVerifiedSSLServerCertSuccess(nsTArray<ByteArray> && aBuiltCertChain,const uint16_t & aCertTransparencyStatus,const uint8_t & aEVStatus,const bool & aIsBuiltCertChainRootBuiltInRoot)30 ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess(
31     nsTArray<ByteArray>&& aBuiltCertChain,
32     const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus,
33     const bool& aIsBuiltCertChainRootBuiltInRoot) {
34   MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
35           ("[%p] VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess",
36            this));
37 
38   RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(mCert.get());
39   nsTArray<nsTArray<uint8_t>> certBytesArray;
40   for (auto& cert : aBuiltCertChain) {
41     certBytesArray.AppendElement(std::move(cert.data()));
42   }
43 
44   mResultTask->Dispatch(nsc, std::move(certBytesArray),
45                         std::move(mPeerCertChain), aCertTransparencyStatus,
46                         static_cast<EVStatus>(aEVStatus), true, 0, 0,
47                         aIsBuiltCertChainRootBuiltInRoot, mProviderFlags);
48   return IPC_OK();
49 }
50 
RecvOnVerifiedSSLServerCertFailure(const uint32_t & aFinalError,const uint32_t & aCollectedErrors)51 ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertFailure(
52     const uint32_t& aFinalError, const uint32_t& aCollectedErrors) {
53   MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
54           ("[%p]VerifySSLServerCertChild::"
55            "RecvOnVerifiedSSLServerCertFailure - aFinalError=%u, "
56            "aCollectedErrors=%u",
57            this, aFinalError, aCollectedErrors));
58 
59   RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(mCert.get());
60   mResultTask->Dispatch(
61       nsc, nsTArray<nsTArray<uint8_t>>(), std::move(mPeerCertChain),
62       nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
63       EVStatus::NotEV, false, aFinalError, aCollectedErrors, false,
64       mProviderFlags);
65   return IPC_OK();
66 }
67 
RemoteProcessCertVerification(const UniqueCERTCertificate & aCert,nsTArray<nsTArray<uint8_t>> && aPeerCertChain,const nsACString & aHostName,int32_t aPort,const OriginAttributes & aOriginAttributes,Maybe<nsTArray<uint8_t>> & aStapledOCSPResponse,Maybe<nsTArray<uint8_t>> & aSctsFromTLSExtension,Maybe<DelegatedCredentialInfo> & aDcInfo,uint32_t aProviderFlags,uint32_t aCertVerifierFlags,SSLServerCertVerificationResult * aResultTask)68 SECStatus RemoteProcessCertVerification(
69     const UniqueCERTCertificate& aCert,
70     nsTArray<nsTArray<uint8_t>>&& aPeerCertChain, const nsACString& aHostName,
71     int32_t aPort, const OriginAttributes& aOriginAttributes,
72     Maybe<nsTArray<uint8_t>>& aStapledOCSPResponse,
73     Maybe<nsTArray<uint8_t>>& aSctsFromTLSExtension,
74     Maybe<DelegatedCredentialInfo>& aDcInfo, uint32_t aProviderFlags,
75     uint32_t aCertVerifierFlags, SSLServerCertVerificationResult* aResultTask) {
76   if (!aResultTask) {
77     PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
78     return SECFailure;
79   }
80 
81   const ByteArray serverCertSerialized =
82       CopyableTArray<uint8_t>{aCert->derCert.data, aCert->derCert.len};
83 
84   nsTArray<ByteArray> peerCertBytes;
85   for (auto& certBytes : aPeerCertChain) {
86     peerCertBytes.AppendElement(ByteArray(certBytes));
87   }
88 
89   Maybe<ByteArray> stapledOCSPResponse;
90   if (aStapledOCSPResponse) {
91     stapledOCSPResponse.emplace();
92     stapledOCSPResponse->data().Assign(*aStapledOCSPResponse);
93   }
94 
95   Maybe<ByteArray> sctsFromTLSExtension;
96   if (aSctsFromTLSExtension) {
97     sctsFromTLSExtension.emplace();
98     sctsFromTLSExtension->data().Assign(*aSctsFromTLSExtension);
99   }
100 
101   Maybe<DelegatedCredentialInfoArg> dcInfo;
102   if (aDcInfo) {
103     dcInfo.emplace();
104     dcInfo.ref().scheme() = static_cast<uint32_t>(aDcInfo->scheme);
105     dcInfo.ref().authKeyBits() = static_cast<uint32_t>(aDcInfo->authKeyBits);
106   }
107 
108   mozilla::ipc::PBackgroundChild* actorChild = mozilla::ipc::BackgroundChild::
109       GetOrCreateForSocketParentBridgeForCurrentThread();
110   if (!actorChild) {
111     PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
112     return SECFailure;
113   }
114 
115   RefPtr<VerifySSLServerCertChild> authCert = new VerifySSLServerCertChild(
116       aCert, aResultTask, std::move(aPeerCertChain), aProviderFlags);
117   if (!actorChild->SendPVerifySSLServerCertConstructor(
118           authCert, serverCertSerialized, peerCertBytes,
119           PromiseFlatCString(aHostName), aPort, aOriginAttributes,
120           stapledOCSPResponse, sctsFromTLSExtension, dcInfo, aProviderFlags,
121           aCertVerifierFlags)) {
122     PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
123     return SECFailure;
124   }
125 
126   PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
127   return SECWouldBlock;
128 }
129 
130 }  // namespace psm
131 }  // namespace mozilla
132