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