Line data Source code
1 : /*
2 : * Copyright (c) 2025 Project CHIP Authors
3 : * All rights reserved.
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #pragma once
19 :
20 : #include <cstdint>
21 : #include <string>
22 :
23 : #include <app-common/zap-generated/cluster-objects.h>
24 : #include <credentials/CHIPCert.h>
25 : #include <credentials/FabricTable.h>
26 : #include <credentials/jcm/TrustVerification.h>
27 : #include <crypto/CHIPCryptoPAL.h>
28 : #include <lib/core/CHIPCore.h>
29 : #include <lib/core/CHIPError.h>
30 : #include <lib/core/CHIPVendorIdentifiers.hpp>
31 : #include <lib/support/DLLUtil.h>
32 : #include <messaging/ExchangeMgr.h>
33 :
34 : #include <functional>
35 : #include <memory>
36 : #include <utility>
37 :
38 : namespace chip {
39 : namespace Credentials {
40 : namespace JCM {
41 :
42 : /**
43 : * A client that handles Vendor ID verification
44 : */
45 : class DLL_EXPORT VendorIdVerificationClient
46 : {
47 : public:
48 66 : VendorIdVerificationClient() = default;
49 33 : virtual ~VendorIdVerificationClient() = default;
50 :
51 : // We forbid moving or copying because they could cause old GuardWithLiveness callbacks to execute with a stale `this`.
52 : // VendorIdVerificationClients are not currently copied or moved, but this is a good defensive change.
53 : VendorIdVerificationClient(const VendorIdVerificationClient &) = delete;
54 : VendorIdVerificationClient & operator=(const VendorIdVerificationClient &) = delete;
55 : VendorIdVerificationClient(VendorIdVerificationClient &&) = delete;
56 : VendorIdVerificationClient & operator=(VendorIdVerificationClient &&) = delete;
57 :
58 : // Used to obtain SessionHandles from VerifyVendorId callers. SessionHandles cannot be stored, so we must retrieve them
59 : // dynamically with a callback.
60 : using SessionGetterFunc = std::function<Optional<SessionHandle>()>;
61 :
62 : CHIP_ERROR VerifyVendorId(Messaging::ExchangeManager * exchangeMgr, const SessionGetterFunc getSession,
63 : TrustVerificationInfo * info);
64 :
65 : protected:
66 : virtual CHIP_ERROR OnLookupOperationalTrustAnchor(VendorId vendorID, CertificateKeyId & subjectKeyId,
67 : ByteSpan & globallyTrustedRootSpan) = 0;
68 : virtual void OnVendorIdVerificationComplete(const CHIP_ERROR & err) = 0;
69 :
70 : /**
71 : * Liveness guard for async callbacks. Returns a function that only executes the input function if `this` is still in scope.
72 : *
73 : * Intended for async callbacks that might outlive `this`.
74 : *
75 : * @param [in] f The function to invoke if `this` is alive
76 : *
77 : * @return A new function, `f'`, which invokes `f` if and only if `this` is alive
78 : */
79 : template <typename F>
80 41 : auto GuardWithLiveness(F && f)
81 : {
82 41 : std::weak_ptr<int> weak = mLivenessToken;
83 87 : return [weak, f = std::forward<F>(f)](auto &&... args) {
84 : // If we're able to lock the pointer to the liveness token, `this` is still alive and the function is safe to execute.
85 42 : if (auto strong = weak.lock())
86 : {
87 19 : f(std::forward<decltype(args)>(args)...);
88 : }
89 41 : };
90 41 : }
91 :
92 : private:
93 : CHIP_ERROR VerifyNOCCertificateChain(const ByteSpan & nocSpan, const ByteSpan & icacSpan, const ByteSpan & rcacSpan);
94 :
95 : CHIP_ERROR
96 : Verify(TrustVerificationInfo * info, const ByteSpan clientChallengeSpan, ByteSpan attestationChallengeSpan,
97 : const app::Clusters::OperationalCredentials::Commands::SignVIDVerificationResponse::DecodableType responseData);
98 :
99 : /**
100 : * Token whose lifetime tracks this object; see GuardWithLiveness().
101 : */
102 33 : std::shared_ptr<int> mLivenessToken = std::make_shared<int>(0);
103 : };
104 :
105 : } // namespace JCM
106 : } // namespace Credentials
107 : } // namespace chip
|