Skip to content

Commit

Permalink
Add a method to Darwin SetupPayload to test whether a passcode is val…
Browse files Browse the repository at this point in the history
…id. (#37193)
  • Loading branch information
bzbarsky-apple authored Jan 24, 2025
1 parent 8a916c1 commit 281adfd
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/darwin/Framework/CHIP/MTRSetupPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
/**
* Generate a random Matter-valid setup PIN.
*/
+ (NSUInteger)generateRandomPIN;
+ (NSUInteger)generateRandomPIN MTR_NEWLY_DEPRECATED("Please use generateRandomSetupPasscode");

/**
* Generate a random Matter-valid setup passcode.
Expand Down Expand Up @@ -214,6 +214,12 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1))
*/
- (NSString * _Nullable)qrCodeString MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6));

/**
* Check whether the provided setup passcode (represented as an unsigned
* integer) is a valid setup passcode.
*/
+ (BOOL)isValidSetupPasscode:(NSNumber *)setupPasscode MTR_NEWLY_AVAILABLE;

@end

MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6))
Expand Down
11 changes: 11 additions & 0 deletions src/darwin/Framework/CHIP/MTRSetupPayload.mm
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,17 @@ - (nullable NSString *)qrCodeString
return [self qrCodeStringSkippingValidation:NO];
}

+ (BOOL)isValidSetupPasscode:(NSNumber *)setupPasscode
{
using namespace chip;

uint64_t passCode = setupPasscode.unsignedLongLongValue;
if (!CanCastTo<uint32_t>(passCode)) {
return NO;
}
return SetupPayload::IsValidSetupPIN(static_cast<uint32_t>(passCode));
}

- (nullable NSString *)qrCodeStringSkippingValidation:(BOOL)allowInvalid
{
chip::QRCodeSetupPayloadGenerator generator(_payload);
Expand Down
35 changes: 35 additions & 0 deletions src/darwin/Framework/CHIPTests/MTRSetupPayloadTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -439,4 +439,39 @@ - (void)testDescriptionShowsUnknownDiscoveryMethods
XCTAssertNotEqualObjects(a.description, b.description);
}

- (uint32)generateRepeatedDigitPasscode:(uint8_t)digit
{
// "digit" is expected to be a single digit. Generates a number that has
// that digit repeated 8 times.
uint32_t passcode = 0;
for (int i = 0; i < 8; ++i) {
passcode = passcode * 10 + digit;
}
return passcode;
}

- (void)testValidSetupPasscode
{
// First, check the repeated-digit cases.
for (uint8_t digit = 0; digit <= 9; ++digit) {
XCTAssertFalse([MTRSetupPayload isValidSetupPasscode:@([self generateRepeatedDigitPasscode:digit])]);
}

// Then the sequential special cases.
XCTAssertFalse([MTRSetupPayload isValidSetupPasscode:@(12345678)]);
XCTAssertFalse([MTRSetupPayload isValidSetupPasscode:@(87654321)]);

// Then the "too big" cases:
XCTAssertFalse([MTRSetupPayload isValidSetupPasscode:@(100000000)]);
XCTAssertFalse([MTRSetupPayload isValidSetupPasscode:@(1lu << 27)]);
XCTAssertFalse([MTRSetupPayload isValidSetupPasscode:@((1llu << 32) + 1)]);

// Now some tests for known-valid passcodes:
XCTAssertTrue([MTRSetupPayload isValidSetupPasscode:@(1)]);
XCTAssertTrue([MTRSetupPayload isValidSetupPasscode:@(78654321)]);

// And we should only generate valid ones.
XCTAssertTrue([MTRSetupPayload isValidSetupPasscode:[MTRSetupPayload generateRandomSetupPasscode]]);
}

@end

0 comments on commit 281adfd

Please sign in to comment.