diff --git a/src/darwin/Framework/CHIP/MTRCertificates.h b/src/darwin/Framework/CHIP/MTRCertificates.h index 57eac0239a069d..e18878f8773b57 100644 --- a/src/darwin/Framework/CHIP/MTRCertificates.h +++ b/src/darwin/Framework/CHIP/MTRCertificates.h @@ -141,6 +141,16 @@ NS_ASSUME_NONNULL_BEGIN */ + (MTRCertificateTLVBytes _Nullable)convertX509Certificate:(MTRCertificateDERBytes)x509Certificate; +/** + * Convert the given Matter TLV encoded certificate to the X.509v3 DER encoded + * format. + * + * Returns nil if the conversion fails (e.g. if the input data cannot be parsed + * as a Matter TLV encoded certificate, or if the certificate cannot be + * represented in the X.509v3 DER format). + */ ++ (MTRCertificateDERBytes _Nullable)convertMatterCertificate:(MTRCertificateTLVBytes)matterCertificate MTR_NEWLY_AVAILABLE; + @end @interface MTRCertificates (Deprecated) diff --git a/src/darwin/Framework/CHIP/MTRCertificates.mm b/src/darwin/Framework/CHIP/MTRCertificates.mm index 1996cbd10f1845..39735bd79d3771 100644 --- a/src/darwin/Framework/CHIP/MTRCertificates.mm +++ b/src/darwin/Framework/CHIP/MTRCertificates.mm @@ -214,6 +214,23 @@ + (MTRCertificateTLVBytes _Nullable)convertX509Certificate:(MTRCertificateDERByt return AsData(chipCertBytes); } ++ (MTRCertificateDERBytes _Nullable)convertMatterCertificate:(MTRCertificateTLVBytes)matterCertificate +{ + chip::ByteSpan tlvCertBytes = AsByteSpan(matterCertificate); + + uint8_t derCertBuffer[chip::Controller::kMaxCHIPDERCertLength]; + chip::MutableByteSpan derCertBytes(derCertBuffer); + + CHIP_ERROR errorCode = chip::Credentials::ConvertChipCertToX509Cert(tlvCertBytes, derCertBytes); + + if (errorCode != CHIP_NO_ERROR) { + MTR_LOG_ERROR("ConvertChipCertToX509Cert: %{public}s", chip::ErrorStr(errorCode)); + return nil; + } + + return AsData(derCertBytes); +} + @end @implementation MTRCertificates (Deprecated) diff --git a/src/darwin/Framework/CHIPTests/MTRCertificateTests.m b/src/darwin/Framework/CHIPTests/MTRCertificateTests.m index e42ea141a1c987..abb6007231ea60 100644 --- a/src/darwin/Framework/CHIPTests/MTRCertificateTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCertificateTests.m @@ -34,6 +34,15 @@ - (void)testGenerateRootCert __auto_type * rootCert = [MTRCertificates createRootCertificate:testKeys issuerID:nil fabricID:nil error:nil]; XCTAssertNotNil(rootCert); + + // Test round-trip through TLV format. + __auto_type * tlvCert = [MTRCertificates convertX509Certificate:rootCert]; + XCTAssertNotNil(tlvCert); + + __auto_type * derCert = [MTRCertificates convertMatterCertificate:tlvCert]; + XCTAssertNotNil(derCert); + + XCTAssertEqualObjects(rootCert, derCert); } - (void)testGenerateIntermediateCert @@ -54,6 +63,15 @@ - (void)testGenerateIntermediateCert fabricID:nil error:nil]; XCTAssertNotNil(intermediateCert); + + // Test round-trip through TLV format. + __auto_type * tlvCert = [MTRCertificates convertX509Certificate:intermediateCert]; + XCTAssertNotNil(tlvCert); + + __auto_type * derCert = [MTRCertificates convertMatterCertificate:tlvCert]; + XCTAssertNotNil(derCert); + + XCTAssertEqualObjects(intermediateCert, derCert); } - (void)testGenerateOperationalCertNoIntermediate @@ -81,6 +99,15 @@ - (void)testGenerateOperationalCertNoIntermediate caseAuthenticatedTags:cats error:nil]; XCTAssertNotNil(operationalCert); + + // Test round-trip through TLV format. + __auto_type * tlvCert = [MTRCertificates convertX509Certificate:operationalCert]; + XCTAssertNotNil(tlvCert); + + __auto_type * derCert = [MTRCertificates convertMatterCertificate:tlvCert]; + XCTAssertNotNil(derCert); + + XCTAssertEqualObjects(operationalCert, derCert); } - (void)testGenerateOperationalCertWithIntermediate @@ -113,6 +140,15 @@ - (void)testGenerateOperationalCertWithIntermediate caseAuthenticatedTags:nil error:nil]; XCTAssertNotNil(operationalCert); + + // Test round-trip through TLV format. + __auto_type * tlvCert = [MTRCertificates convertX509Certificate:operationalCert]; + XCTAssertNotNil(tlvCert); + + __auto_type * derCert = [MTRCertificates convertMatterCertificate:tlvCert]; + XCTAssertNotNil(derCert); + + XCTAssertEqualObjects(operationalCert, derCert); } - (void)testGenerateOperationalCertErrorCases