Skip to content

Commit

Permalink
Expose API to generate a CSR in the Darwin framework. (#18672)
Browse files Browse the repository at this point in the history
There seem to be no OS-provided APIs for this on iOS, and a CSR is
needed to get a NOC issued by an external CA.
  • Loading branch information
bzbarsky-apple authored May 20, 2022
1 parent e6d1e8f commit 55ef609
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/darwin/Framework/CHIP/CHIPP256KeypairBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
if (![keypair respondsToSelector:@selector(ECDSA_sign_message_DER:)]
&& ![keypair respondsToSelector:@selector(ECDSA_sign_message_raw:)]) {
// Not a valid CHIPKeypair implementation.
NSLog(@"Keypair does not support message signing");
return CHIP_ERROR_INVALID_ARGUMENT;
}

Expand Down
16 changes: 16 additions & 0 deletions src/darwin/Framework/CHIP/MTRCertificates.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (BOOL)isCertificate:(NSData *)certificate1 equalTo:(NSData *)certificate2;

/**
* Generate a PKCS#10 certificate signing request from a CHIPKeypair. This can
* then be used to request an operational or ICA certificate from an external
* certificate authority.
*
* The CSR will have the subject OU DN set to 'CSA', because omitting all
* identifying information altogether often trips up CSR parsing code. The CA
* being used should expect this and ignore the request subject, producing a
* subject that matches the rules for Matter certificates.
*
* On failure returns nil and if "error" is not null sets *error to the relevant
* error.
*/
+ (nullable NSData *)generateCertificateSigningRequest:(id<CHIPKeypair>)keypair
error:(NSError * __autoreleasing _Nullable * _Nullable)error;

@end

NS_ASSUME_NONNULL_END
Expand Down
34 changes: 34 additions & 0 deletions src/darwin/Framework/CHIP/MTRCertificates.mm
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ + (nullable NSData *)generateOperationalCertificate:(id<CHIPKeypair>)signingKeyp

+ (BOOL)keypair:(id<CHIPKeypair>)keypair matchesCertificate:(NSData *)certificate
{
AutoPlatformMemory platformMemory;

P256PublicKey keypairPubKey;
CHIP_ERROR err = CHIPP256KeypairBridge::MatterPubKeyFromSecKeyRef(keypair.pubkey, &keypairPubKey);
if (err != CHIP_NO_ERROR) {
Expand All @@ -135,6 +137,8 @@ + (BOOL)keypair:(id<CHIPKeypair>)keypair matchesCertificate:(NSData *)certificat

+ (BOOL)isCertificate:(NSData *)certificate1 equalTo:(NSData *)certificate2
{
AutoPlatformMemory platformMemory;

P256PublicKey pubKey1;
CHIP_ERROR err = ExtractPubkeyFromX509Cert(AsByteSpan(certificate1), pubKey1);
if (err != CHIP_NO_ERROR) {
Expand Down Expand Up @@ -172,4 +176,34 @@ + (BOOL)isCertificate:(NSData *)certificate1 equalTo:(NSData *)certificate2
return subject1.IsEqual(subject2);
}

+ (nullable NSData *)generateCertificateSigningRequest:(id<CHIPKeypair>)keypair
error:(NSError * __autoreleasing _Nullable * _Nullable)error
{
AutoPlatformMemory platformMemory;

CHIPP256KeypairBridge keypairBridge;
CHIP_ERROR err = CHIP_NO_ERROR;
do {
err = keypairBridge.Init(keypair);
if (err != CHIP_NO_ERROR) {
break;
}
CHIPP256KeypairNativeBridge nativeKeypair(keypairBridge);

uint8_t buf[kMAX_CSR_Length];
MutableByteSpan csr(buf);
err = GenerateCertificateSigningRequest(&nativeKeypair, csr);
if (err != CHIP_NO_ERROR) {
break;
}

return AsData(csr);
} while (0);

if (error) {
*error = [CHIPError errorForCHIPErrorCode:err];
}
return nil;
}

@end
11 changes: 11 additions & 0 deletions src/darwin/Framework/CHIPTests/MatterCertificateTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,15 @@ - (void)testGenerateOperationalCertErrorCases
XCTAssertNil(operationalCert);
}

- (void)testGenerateCSR
{
__auto_type * testKeys = [[CHIPTestKeys alloc] init];
XCTAssertNotNil(testKeys);

__auto_type * csr = [MTRCertificates generateCertificateSigningRequest:testKeys error:nil];
XCTAssertNotNil(csr);

// Wish there was something we could test here about the CSR.
}

@end

0 comments on commit 55ef609

Please sign in to comment.