Skip to content

Commit 55ef609

Browse files
Expose API to generate a CSR in the Darwin framework. (project-chip#18672)
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.
1 parent e6d1e8f commit 55ef609

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

src/darwin/Framework/CHIP/CHIPP256KeypairBridge.mm

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
if (![keypair respondsToSelector:@selector(ECDSA_sign_message_DER:)]
3232
&& ![keypair respondsToSelector:@selector(ECDSA_sign_message_raw:)]) {
3333
// Not a valid CHIPKeypair implementation.
34+
NSLog(@"Keypair does not support message signing");
3435
return CHIP_ERROR_INVALID_ARGUMENT;
3536
}
3637

src/darwin/Framework/CHIP/MTRCertificates.h

+16
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,22 @@ NS_ASSUME_NONNULL_BEGIN
111111
*/
112112
+ (BOOL)isCertificate:(NSData *)certificate1 equalTo:(NSData *)certificate2;
113113

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

116132
NS_ASSUME_NONNULL_END

src/darwin/Framework/CHIP/MTRCertificates.mm

+34
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ + (nullable NSData *)generateOperationalCertificate:(id<CHIPKeypair>)signingKeyp
114114

115115
+ (BOOL)keypair:(id<CHIPKeypair>)keypair matchesCertificate:(NSData *)certificate
116116
{
117+
AutoPlatformMemory platformMemory;
118+
117119
P256PublicKey keypairPubKey;
118120
CHIP_ERROR err = CHIPP256KeypairBridge::MatterPubKeyFromSecKeyRef(keypair.pubkey, &keypairPubKey);
119121
if (err != CHIP_NO_ERROR) {
@@ -135,6 +137,8 @@ + (BOOL)keypair:(id<CHIPKeypair>)keypair matchesCertificate:(NSData *)certificat
135137

136138
+ (BOOL)isCertificate:(NSData *)certificate1 equalTo:(NSData *)certificate2
137139
{
140+
AutoPlatformMemory platformMemory;
141+
138142
P256PublicKey pubKey1;
139143
CHIP_ERROR err = ExtractPubkeyFromX509Cert(AsByteSpan(certificate1), pubKey1);
140144
if (err != CHIP_NO_ERROR) {
@@ -172,4 +176,34 @@ + (BOOL)isCertificate:(NSData *)certificate1 equalTo:(NSData *)certificate2
172176
return subject1.IsEqual(subject2);
173177
}
174178

179+
+ (nullable NSData *)generateCertificateSigningRequest:(id<CHIPKeypair>)keypair
180+
error:(NSError * __autoreleasing _Nullable * _Nullable)error
181+
{
182+
AutoPlatformMemory platformMemory;
183+
184+
CHIPP256KeypairBridge keypairBridge;
185+
CHIP_ERROR err = CHIP_NO_ERROR;
186+
do {
187+
err = keypairBridge.Init(keypair);
188+
if (err != CHIP_NO_ERROR) {
189+
break;
190+
}
191+
CHIPP256KeypairNativeBridge nativeKeypair(keypairBridge);
192+
193+
uint8_t buf[kMAX_CSR_Length];
194+
MutableByteSpan csr(buf);
195+
err = GenerateCertificateSigningRequest(&nativeKeypair, csr);
196+
if (err != CHIP_NO_ERROR) {
197+
break;
198+
}
199+
200+
return AsData(csr);
201+
} while (0);
202+
203+
if (error) {
204+
*error = [CHIPError errorForCHIPErrorCode:err];
205+
}
206+
return nil;
207+
}
208+
175209
@end

src/darwin/Framework/CHIPTests/MatterCertificateTests.m

+11
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,15 @@ - (void)testGenerateOperationalCertErrorCases
192192
XCTAssertNil(operationalCert);
193193
}
194194

195+
- (void)testGenerateCSR
196+
{
197+
__auto_type * testKeys = [[CHIPTestKeys alloc] init];
198+
XCTAssertNotNil(testKeys);
199+
200+
__auto_type * csr = [MTRCertificates generateCertificateSigningRequest:testKeys error:nil];
201+
XCTAssertNotNil(csr);
202+
203+
// Wish there was something we could test here about the CSR.
204+
}
205+
195206
@end

0 commit comments

Comments
 (0)