Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2021-2022 Project CHIP Authors 4 : * All rights reserved. 5 : * 6 : * Licensed under the Apache License, Version 2.0 (the "License"); 7 : * you may not use this file except in compliance with the License. 8 : * You may obtain a copy of the License at 9 : * 10 : * http://www.apache.org/licenses/LICENSE-2.0 11 : * 12 : * Unless required by applicable law or agreed to in writing, software 13 : * distributed under the License is distributed on an "AS IS" BASIS, 14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 : * See the License for the specific language governing permissions and 16 : * limitations under the License. 17 : */ 18 : 19 : /** 20 : * @file 21 : * This file contains class definition of an example operational certificate 22 : * issuer for CHIP devices. The class can be used as a guideline on how to 23 : * construct your own certificate issuer. It can also be used in tests and tools 24 : * if a specific signing authority is not required. 25 : * 26 : * NOTE: This class stores the encryption key in clear storage. This is not suited 27 : * for production use. This should only be used in test tools. 28 : */ 29 : 30 : #pragma once 31 : 32 : #include <controller/OperationalCredentialsDelegate.h> 33 : #include <crypto/CHIPCryptoPAL.h> 34 : #include <lib/core/CASEAuthTag.h> 35 : #include <lib/core/CHIPError.h> 36 : #include <lib/core/CHIPPersistentStorageDelegate.h> 37 : #include <lib/support/CodeUtils.h> 38 : #include <lib/support/Span.h> 39 : 40 : namespace chip { 41 : namespace Controller { 42 : 43 : class DLL_EXPORT ExampleOperationalCredentialsIssuer : public OperationalCredentialsDelegate 44 : { 45 : public: 46 : // 47 : // Constructor to create an instance of this object that vends out operational credentials for a given fabric. 48 : // 49 : // An index should be provided to numerically identify this instance relative to others in a multi-fabric deployment. This is 50 : // needed given the interactions of this object with persistent storage. Consequently, the index is used to scope the entries 51 : // read/written to/from storage. 52 : // 53 : // It is recommended that this index track the fabric index within which this issuer is operating. 54 : // 55 : ExampleOperationalCredentialsIssuer(uint32_t index = 0) { mIndex = index; } 56 0 : ~ExampleOperationalCredentialsIssuer() override {} 57 : 58 : CHIP_ERROR GenerateNOCChain(const ByteSpan & csrElements, const ByteSpan & csrNonce, const ByteSpan & attestationSignature, 59 : const ByteSpan & attestationChallenge, const ByteSpan & DAC, const ByteSpan & PAI, 60 : Callback::Callback<OnNOCChainGeneration> * onCompletion) override; 61 : 62 0 : void SetNodeIdForNextNOCRequest(NodeId nodeId) override 63 : { 64 0 : mNextRequestedNodeId = nodeId; 65 0 : mNodeIdRequested = true; 66 0 : } 67 : 68 : void SetMaximallyLargeCertsUsed(bool areMaximallyLargeCertsUsed) { mUseMaximallySizedCerts = areMaximallyLargeCertsUsed; } 69 : 70 0 : void SetFabricIdForNextNOCRequest(FabricId fabricId) override { mNextFabricId = fabricId; } 71 : 72 : void SetCATValuesForNextNOCRequest(CATValues cats) { mNextCATs = cats; } 73 : 74 : /** 75 : * @brief Initialize the issuer with the keypair in the storage. 76 : * If the storage doesn't have one, it'll create one, and it to the storage. 77 : * 78 : * @param[in] storage A reference to the storage, where the keypair is stored. 79 : * The object of ExampleOperationalCredentialsIssuer doesn't hold 80 : * on the reference of storage. 81 : * 82 : * @return Returns a CHIP_ERROR on error, CHIP_NO_ERROR otherwise 83 : **/ 84 : [[deprecated("This class stores the encryption key in clear storage. Don't use it for production code.")]] CHIP_ERROR 85 : Initialize(PersistentStorageDelegate & storage); 86 : 87 : void SetIssuerId(uint32_t id) { mIssuerId = id; } 88 : 89 : void SetCurrentEpoch(uint32_t epoch) { mNow = epoch; } 90 : 91 : void SetCertificateValidityPeriod(uint32_t validity) { mValidity = validity; } 92 : 93 : /** 94 : * Generate a random operational node id. 95 : * 96 : * @param[out] aNodeId where to place the generated id. 97 : * 98 : * On error no guarantees are made about the state of aNodeId. 99 : */ 100 : static CHIP_ERROR GetRandomOperationalNodeId(NodeId * aNodeId); 101 : 102 : /** 103 : * This is a utility method that generates a operational certificate chain for the given public key. 104 : * This method is expected to be called once all the checks (e.g. device attestation, CSR verification etc) 105 : * have been completed, or not required (e.g. for self trusted devices such as commissioner apps). 106 : */ 107 : CHIP_ERROR GenerateNOCChainAfterValidation(NodeId nodeId, FabricId fabricId, const CATValues & cats, 108 : const Crypto::P256PublicKey & pubkey, MutableByteSpan & rcac, MutableByteSpan & icac, 109 : MutableByteSpan & noc); 110 : 111 : private: 112 : Crypto::P256Keypair mIssuer; 113 : Crypto::P256Keypair mIntermediateIssuer; 114 : bool mInitialized = false; 115 : uint32_t mIssuerId = 1; 116 : uint32_t mIntermediateIssuerId = 2; 117 : uint32_t mNow = 0; 118 : 119 : // By default, let's set validity to 10 years 120 : uint32_t mValidity = 365 * 24 * 60 * 60 * 10; 121 : 122 : NodeId mNextAvailableNodeId = 1; 123 : PersistentStorageDelegate * mStorage = nullptr; 124 : bool mUseMaximallySizedCerts = false; 125 : 126 : NodeId mNextRequestedNodeId = 1; 127 : FabricId mNextFabricId = 1; 128 : CATValues mNextCATs = kUndefinedCATs; 129 : bool mNodeIdRequested = false; 130 : uint64_t mIndex = 0; 131 : }; 132 : 133 : } // namespace Controller 134 : } // namespace chip