|
23 | 23 |
|
24 | 24 | #include <lib/core/CHIPConfig.h>
|
25 | 25 | #include <lib/core/CHIPVendorIdentifiers.hpp>
|
| 26 | +#include <protocols/secure_channel/PASESession.h> // for chip::kTestControllerNodeId |
26 | 27 |
|
| 28 | +#import "CHIPCommandStorageDelegate.h" |
| 29 | +#import "CertificateIssuer.h" |
| 30 | +#import "ControllerStorage.h" |
27 | 31 | #include "MTRError_Utils.h"
|
28 | 32 |
|
29 | 33 | #include <map>
|
|
34 | 38 | std::map<std::string, MTRDeviceController *> CHIPCommandBridge::mControllers;
|
35 | 39 | dispatch_queue_t CHIPCommandBridge::mOTAProviderCallbackQueue;
|
36 | 40 | OTAProviderDelegate * CHIPCommandBridge::mOTADelegate;
|
| 41 | +bool CHIPCommandBridge::sUseSharedStorage = true; |
37 | 42 | constexpr char kTrustStorePathVariable[] = "PAA_TRUST_STORE_PATH";
|
38 | 43 |
|
39 |
| -CHIPToolKeypair * gNocSigner = [[CHIPToolKeypair alloc] init]; |
40 |
| - |
41 | 44 | CHIP_ERROR CHIPCommandBridge::Run()
|
42 | 45 | {
|
43 | 46 | // In interactive mode, we want to avoid memory accumulating in the main autorelease pool,
|
|
120 | 123 |
|
121 | 124 | CHIP_ERROR CHIPCommandBridge::MaybeSetUpStack()
|
122 | 125 | {
|
123 |
| - if (IsInteractive()) { |
124 |
| - return CHIP_NO_ERROR; |
125 |
| - } |
126 |
| - NSData * ipk; |
127 |
| - gNocSigner = [[CHIPToolKeypair alloc] init]; |
128 |
| - storage = [[CHIPToolPersistentStorageDelegate alloc] init]; |
| 126 | + VerifyOrReturnError(!IsInteractive(), CHIP_NO_ERROR); |
129 | 127 |
|
130 | 128 | mOTADelegate = [[OTAProviderDelegate alloc] init];
|
| 129 | + storage = [[CHIPToolPersistentStorageDelegate alloc] init]; |
131 | 130 |
|
132 |
| - auto factory = [MTRDeviceControllerFactory sharedInstance]; |
133 |
| - if (factory == nil) { |
134 |
| - ChipLogError(chipTool, "Controller factory is nil"); |
135 |
| - return CHIP_ERROR_INTERNAL; |
| 131 | + NSError * error; |
| 132 | + __auto_type * certificateIssuer = [CertificateIssuer sharedInstance]; |
| 133 | + [certificateIssuer startWithStorage:storage error:&error]; |
| 134 | + VerifyOrReturnError(nil == error, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Can not start the certificate issuer: %@", error)); |
| 135 | + |
| 136 | + NSArray<NSData *> * productAttestationAuthorityCertificates = nil; |
| 137 | + ReturnLogErrorOnFailure(GetPAACertsFromFolder(&productAttestationAuthorityCertificates)); |
| 138 | + if ([productAttestationAuthorityCertificates count] == 0) { |
| 139 | + productAttestationAuthorityCertificates = nil; |
136 | 140 | }
|
137 | 141 |
|
138 |
| - auto params = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; |
139 |
| - params.shouldStartServer = YES; |
140 |
| - params.otaProviderDelegate = mOTADelegate; |
141 |
| - NSArray<NSData *> * paaCertResults; |
142 |
| - ReturnLogErrorOnFailure(GetPAACertsFromFolder(&paaCertResults)); |
143 |
| - if ([paaCertResults count] > 0) { |
144 |
| - params.productAttestationAuthorityCertificates = paaCertResults; |
| 142 | + sUseSharedStorage = mCommissionerSharedStorage.ValueOr(true); |
| 143 | + if (sUseSharedStorage) { |
| 144 | + return SetUpStackWithSharedStorage(productAttestationAuthorityCertificates); |
145 | 145 | }
|
146 | 146 |
|
147 |
| - NSError * error; |
148 |
| - if ([factory startControllerFactory:params error:&error] == NO) { |
149 |
| - ChipLogError(chipTool, "Controller factory startup failed"); |
150 |
| - return MTRErrorToCHIPErrorCode(error); |
| 147 | + return SetUpStackWithPerControllerStorage(productAttestationAuthorityCertificates); |
| 148 | +} |
| 149 | + |
| 150 | +CHIP_ERROR CHIPCommandBridge::SetUpStackWithPerControllerStorage(NSArray<NSData *> * productAttestationAuthorityCertificates) |
| 151 | +{ |
| 152 | + __auto_type * certificateIssuer = [CertificateIssuer sharedInstance]; |
| 153 | + |
| 154 | + constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; |
| 155 | + std::string commissionerName = mCommissionerName.HasValue() ? mCommissionerName.Value() : kIdentityAlpha; |
| 156 | + for (size_t i = 0; i < ArraySize(identities); ++i) { |
| 157 | + __auto_type * uuidString = [NSString stringWithFormat:@"%@%@", @"8DCADB14-AF1F-45D0-B084-00000000000", @(i)]; |
| 158 | + __auto_type * controllerId = [[NSUUID alloc] initWithUUIDString:uuidString]; |
| 159 | + __auto_type * vendorId = @(mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1)); |
| 160 | + __auto_type * fabricId = @(i + 1); |
| 161 | + __auto_type * nodeId = @(chip::kTestControllerNodeId); |
| 162 | + |
| 163 | + if (commissionerName.compare(identities[i]) == 0 && mCommissionerNodeId.HasValue()) { |
| 164 | + nodeId = @(mCommissionerNodeId.Value()); |
| 165 | + } |
| 166 | + |
| 167 | + __auto_type * controllerStorage = [[ControllerStorage alloc] initWithControllerID:controllerId]; |
| 168 | + |
| 169 | + NSError * error; |
| 170 | + __auto_type * operationalKeypair = [certificateIssuer issueOperationalKeypairWithControllerStorage:controllerStorage error:&error]; |
| 171 | + __auto_type * operational = [certificateIssuer issueOperationalCertificateForNodeID:nodeId |
| 172 | + fabricID:fabricId |
| 173 | + publicKey:operationalKeypair.publicKey |
| 174 | + error:&error]; |
| 175 | + VerifyOrReturnError(nil == error, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Can not issue an operational certificate: %@", error)); |
| 176 | + |
| 177 | + __auto_type * controllerStorageQueue = dispatch_queue_create("com.chip.storage", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); |
| 178 | + __auto_type * params = [[MTRDeviceControllerExternalCertificateParameters alloc] initWithStorageDelegate:controllerStorage |
| 179 | + storageDelegateQueue:controllerStorageQueue |
| 180 | + uniqueIdentifier:controllerId |
| 181 | + ipk:certificateIssuer.ipk |
| 182 | + vendorID:vendorId |
| 183 | + operationalKeypair:operationalKeypair |
| 184 | + operationalCertificate:operational |
| 185 | + intermediateCertificate:nil |
| 186 | + rootCertificate:certificateIssuer.rootCertificate]; |
| 187 | + [params setOperationalCertificateIssuer:certificateIssuer queue:controllerStorageQueue]; |
| 188 | + params.productAttestationAuthorityCertificates = productAttestationAuthorityCertificates; |
| 189 | + |
| 190 | + __auto_type * controller = [[MTRDeviceController alloc] initWithParameters:params error:&error]; |
| 191 | + VerifyOrReturnError(nil != controller, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Controller startup failure: %@", error)); |
| 192 | + mControllers[identities[i]] = controller; |
151 | 193 | }
|
152 | 194 |
|
153 |
| - ReturnLogErrorOnFailure([gNocSigner createOrLoadKeys:storage]); |
| 195 | + return CHIP_NO_ERROR; |
| 196 | +} |
| 197 | + |
| 198 | +CHIP_ERROR CHIPCommandBridge::SetUpStackWithSharedStorage(NSArray<NSData *> * productAttestationAuthorityCertificates) |
| 199 | +{ |
| 200 | + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; |
| 201 | + VerifyOrReturnError(nil != factory, CHIP_ERROR_INTERNAL, ChipLogError(chipTool, "Controller factory is nil")); |
| 202 | + |
| 203 | + auto factoryParams = [[MTRDeviceControllerFactoryParams alloc] initWithStorage:storage]; |
| 204 | + factoryParams.shouldStartServer = YES; |
| 205 | + factoryParams.otaProviderDelegate = mOTADelegate; |
| 206 | + factoryParams.productAttestationAuthorityCertificates = productAttestationAuthorityCertificates; |
154 | 207 |
|
155 |
| - ipk = [gNocSigner getIPK]; |
| 208 | + NSError * error; |
| 209 | + auto started = [factory startControllerFactory:factoryParams error:&error]; |
| 210 | + VerifyOrReturnError(started, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Controller factory startup failed")); |
| 211 | + |
| 212 | + __auto_type * certificateIssuer = [CertificateIssuer sharedInstance]; |
156 | 213 |
|
157 | 214 | constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma };
|
158 | 215 | std::string commissionerName = mCommissionerName.HasValue() ? mCommissionerName.Value() : kIdentityAlpha;
|
159 | 216 | for (size_t i = 0; i < ArraySize(identities); ++i) {
|
160 |
| - auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithIPK:ipk fabricID:@(i + 1) nocSigner:gNocSigner]; |
161 |
| - |
| 217 | + __auto_type * fabricId = @(i + 1); |
| 218 | + __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:certificateIssuer.ipk |
| 219 | + fabricID:fabricId |
| 220 | + nocSigner:certificateIssuer.signingKey]; |
162 | 221 | if (commissionerName.compare(identities[i]) == 0 && mCommissionerNodeId.HasValue()) {
|
163 |
| - controllerParams.nodeId = @(mCommissionerNodeId.Value()); |
| 222 | + params.nodeId = @(mCommissionerNodeId.Value()); |
164 | 223 | }
|
165 |
| - // We're not sure whether we're creating a new fabric or using an |
166 |
| - // existing one, so just try both. |
167 |
| - auto controller = [factory createControllerOnExistingFabric:controllerParams error:&error]; |
| 224 | + |
| 225 | + // We're not sure whether we're creating a new fabric or using an existing one, so just try both. |
| 226 | + auto controller = [factory createControllerOnExistingFabric:params error:&error]; |
168 | 227 | if (controller == nil) {
|
169 | 228 | // Maybe we didn't have this fabric yet.
|
170 |
| - controllerParams.vendorID = @(mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1)); |
171 |
| - controller = [factory createControllerOnNewFabric:controllerParams error:&error]; |
| 229 | + params.vendorID = @(mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1)); |
| 230 | + controller = [factory createControllerOnNewFabric:params error:&error]; |
172 | 231 | }
|
173 |
| - if (controller == nil) { |
174 |
| - ChipLogError(chipTool, "Controller startup failure."); |
175 |
| - return MTRErrorToCHIPErrorCode(error); |
176 |
| - } |
177 |
| - |
| 232 | + VerifyOrReturnError(nil != controller, MTRErrorToCHIPErrorCode(error), ChipLogError(chipTool, "Controller startup failure: %@", error)); |
178 | 233 | mControllers[identities[i]] = controller;
|
179 | 234 | }
|
180 | 235 |
|
|
197 | 252 | kIdentityBeta, kIdentityGamma);
|
198 | 253 | chipDie();
|
199 | 254 | }
|
| 255 | + mCurrentIdentity = name; |
200 | 256 | mCurrentController = mControllers[name];
|
201 | 257 | }
|
202 | 258 |
|
203 | 259 | MTRDeviceController * CHIPCommandBridge::CurrentCommissioner() { return mCurrentController; }
|
204 | 260 |
|
| 261 | +NSNumber * CHIPCommandBridge::CurrentCommissionerFabricId() |
| 262 | +{ |
| 263 | + if (mCurrentIdentity.compare(kIdentityAlpha) == 0) { |
| 264 | + return @(1); |
| 265 | + } else if (mCurrentIdentity.compare(kIdentityBeta) == 0) { |
| 266 | + return @(2); |
| 267 | + } else if (mCurrentIdentity.compare(kIdentityGamma) == 0) { |
| 268 | + return @(3); |
| 269 | + } else { |
| 270 | + ChipLogError(chipTool, "Unknown commissioner name: %s. Supported names are [%s, %s, %s]", mCurrentIdentity.c_str(), kIdentityAlpha, |
| 271 | + kIdentityBeta, kIdentityGamma); |
| 272 | + chipDie(); |
| 273 | + } |
| 274 | + |
| 275 | + return @(0); // This should never happens. |
| 276 | +} |
| 277 | + |
205 | 278 | MTRDeviceController * CHIPCommandBridge::GetCommissioner(const char * identity) { return mControllers[identity]; }
|
206 | 279 |
|
207 | 280 | MTRBaseDevice * CHIPCommandBridge::BaseDeviceWithNodeId(chip::NodeId nodeId)
|
|
223 | 296 | {
|
224 | 297 | StopCommissioners();
|
225 | 298 |
|
226 |
| - auto factory = [MTRDeviceControllerFactory sharedInstance]; |
227 |
| - NSData * ipk = [gNocSigner getIPK]; |
| 299 | + if (sUseSharedStorage) { |
| 300 | + auto factory = [MTRDeviceControllerFactory sharedInstance]; |
228 | 301 |
|
229 |
| - constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; |
230 |
| - for (size_t i = 0; i < ArraySize(identities); ++i) { |
231 |
| - auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithIPK:ipk fabricID:@(i + 1) nocSigner:gNocSigner]; |
| 302 | + constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; |
| 303 | + for (size_t i = 0; i < ArraySize(identities); ++i) { |
| 304 | + __auto_type * certificateIssuer = [CertificateIssuer sharedInstance]; |
| 305 | + auto controllerParams = [[MTRDeviceControllerStartupParams alloc] initWithIPK:certificateIssuer.ipk fabricID:@(i + 1) nocSigner:certificateIssuer.signingKey]; |
232 | 306 |
|
233 |
| - auto controller = [factory createControllerOnExistingFabric:controllerParams error:nil]; |
234 |
| - mControllers[identities[i]] = controller; |
| 307 | + auto controller = [factory createControllerOnExistingFabric:controllerParams error:nil]; |
| 308 | + mControllers[identities[i]] = controller; |
| 309 | + } |
| 310 | + } else { |
| 311 | + NSArray<NSData *> * productAttestationAuthorityCertificates = nil; |
| 312 | + ReturnOnFailure(GetPAACertsFromFolder(&productAttestationAuthorityCertificates)); |
| 313 | + if ([productAttestationAuthorityCertificates count] == 0) { |
| 314 | + productAttestationAuthorityCertificates = nil; |
| 315 | + } |
| 316 | + |
| 317 | + ReturnOnFailure(SetUpStackWithPerControllerStorage(productAttestationAuthorityCertificates)); |
235 | 318 | }
|
236 | 319 | }
|
237 | 320 |
|
|
0 commit comments