diff --git a/src/darwin/Framework/CHIP/MTRCSRInfo.h b/src/darwin/Framework/CHIP/MTRCSRInfo.h index f90c108e239c88..99ba458d464828 100644 --- a/src/darwin/Framework/CHIP/MTRCSRInfo.h +++ b/src/darwin/Framework/CHIP/MTRCSRInfo.h @@ -19,8 +19,6 @@ #import -typedef NSData * MTRCSRDERBytes; - NS_ASSUME_NONNULL_BEGIN /** diff --git a/src/darwin/Framework/CHIP/MTRCertificates.h b/src/darwin/Framework/CHIP/MTRCertificates.h index e18878f8773b57..c236f2ea3ed21a 100644 --- a/src/darwin/Framework/CHIP/MTRCertificates.h +++ b/src/darwin/Framework/CHIP/MTRCertificates.h @@ -20,8 +20,7 @@ #import -typedef NSData * MTRCertificateDERBytes; -typedef NSData * MTRCertificateTLVBytes; +#import NS_ASSUME_NONNULL_BEGIN @@ -128,8 +127,8 @@ NS_ASSUME_NONNULL_BEGIN * On failure returns nil and if "error" is not null sets *error to the relevant * error. */ -+ (NSData * _Nullable)createCertificateSigningRequest:(id)keypair - error:(NSError * __autoreleasing _Nullable * _Nullable)error; ++ (MTRCSRDERBytes _Nullable)createCertificateSigningRequest:(id)keypair + error:(NSError * __autoreleasing _Nullable * _Nullable)error; /** * Convert the given X.509v3 DER encoded certificate to the Matter certificate @@ -151,6 +150,15 @@ NS_ASSUME_NONNULL_BEGIN */ + (MTRCertificateDERBytes _Nullable)convertMatterCertificate:(MTRCertificateTLVBytes)matterCertificate MTR_NEWLY_AVAILABLE; +/** + * Extract the public key from the given PKCS#10 certificate signing request. + * This is the public key that a certificate issued in response to the request + * would need to have. + */ ++ (NSData * _Nullable)extractPublicKeyFromCertificateSigningRequest:(MTRCSRDERBytes)certificateSigningRequest + error:(NSError * __autoreleasing _Nullable * _Nullable)error + MTR_NEWLY_AVAILABLE; + @end @interface MTRCertificates (Deprecated) diff --git a/src/darwin/Framework/CHIP/MTRCertificates.mm b/src/darwin/Framework/CHIP/MTRCertificates.mm index c1699d616c3706..bdf93d18fc9ebc 100644 --- a/src/darwin/Framework/CHIP/MTRCertificates.mm +++ b/src/darwin/Framework/CHIP/MTRCertificates.mm @@ -221,6 +221,24 @@ + (MTRCertificateDERBytes _Nullable)convertMatterCertificate:(MTRCertificateTLVB return AsData(derCertBytes); } ++ (NSData * _Nullable)extractPublicKeyFromCertificateSigningRequest:(MTRCSRDERBytes)certificateSigningRequest + error:(NSError * __autoreleasing _Nullable * _Nullable)error +{ + auto requestSpan = AsByteSpan(certificateSigningRequest); + P256PublicKey publicKey; + CHIP_ERROR err = VerifyCertificateSigningRequest(requestSpan.data(), requestSpan.size(), publicKey); + if (err != CHIP_NO_ERROR) { + MTR_LOG_ERROR("extractPublicKeyFromCertificateSigningRequest: %s", chip::ErrorStr(err)); + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + P256PublicKeySpan publicKeySpan(publicKey.ConstBytes()); + return AsData(publicKeySpan); +} + @end @implementation MTRCertificates (Deprecated) diff --git a/src/darwin/Framework/CHIP/MTRDefines.h b/src/darwin/Framework/CHIP/MTRDefines.h index 80bfaaf5ff875b..63a60fa1ffc333 100644 --- a/src/darwin/Framework/CHIP/MTRDefines.h +++ b/src/darwin/Framework/CHIP/MTRDefines.h @@ -26,3 +26,6 @@ #endif typedef NSData * MTRTLVBytes; +typedef NSData * MTRCSRDERBytes; +typedef NSData * MTRCertificateDERBytes; +typedef NSData * MTRCertificateTLVBytes; diff --git a/src/darwin/Framework/CHIPTests/MTRCertificateTests.m b/src/darwin/Framework/CHIPTests/MTRCertificateTests.m index abb6007231ea60..b445eb88cd130c 100644 --- a/src/darwin/Framework/CHIPTests/MTRCertificateTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCertificateTests.m @@ -284,7 +284,16 @@ - (void)testGenerateCSR __auto_type * csr = [MTRCertificates createCertificateSigningRequest:testKeys error:nil]; XCTAssertNotNil(csr); - // Wish there was something we could test here about the CSR. + __auto_type * publicKey = [MTRCertificates extractPublicKeyFromCertificateSigningRequest:csr error:nil]; + XCTAssertNotNil(publicKey); + + SecKeyRef originalKeyRef = [testKeys publicKey]; + XCTAssertTrue(originalKeyRef != NULL); + + NSData * originalPublicKey = (__bridge_transfer NSData *) SecKeyCopyExternalRepresentation(originalKeyRef, nil); + XCTAssertNotNil(originalPublicKey); + + XCTAssertEqualObjects(publicKey, originalPublicKey); } @end