/** * Copyright (c) 2022-2023 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Utilities for working with Matter certificates. */ #import #import NS_ASSUME_NONNULL_BEGIN @protocol MTRKeypair; MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRCertificates : NSObject - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; /** * Create a root (self-signed) X.509 DER encoded certificate that has the * right fields to be a valid Matter root certificate. * * If issuerID is not nil, it's unsignedLongLongValue will be used for the * matter-rcac-id attribute in the subject distinguished name of the resulting * certificate. * * If issuerID is nil, a random value will be generated for matter-rcac-id. * * If fabricID is not nil, it will be included in the subject DN of the * certificate. In this case it must be a valid Matter fabric id. * * validityPeriod specifies when the certificate will be valid. Note that * there is currently no mechanism available in Matter to update or rotate * the root certificate of a fabric installed on a device. A certificate with * no expiration time can be created by specifying [NSDate distantFuture] for * the end of the period. * * On failure returns nil and if "error" is not null sets *error to the relevant * error. */ + (MTRCertificateDERBytes _Nullable)createRootCertificate:(id)keypair issuerID:(NSNumber * _Nullable)issuerID fabricID:(NSNumber * _Nullable)fabricID validityPeriod:(NSDateInterval *)validityPeriod error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.6), macos(13.5), watchos(9.6), tvos(16.6)); /** * As above, but defaults to no expiration time. */ + (MTRCertificateDERBytes _Nullable)createRootCertificate:(id)keypair issuerID:(NSNumber * _Nullable)issuerID fabricID:(NSNumber * _Nullable)fabricID error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Create an intermediate X.509 DER encoded certificate that has the * right fields to be a valid Matter intermediate certificate. * * If issuerID is not nil, it's unsignedLongLongValue will be used for the * matter-icac-id attribute in the subject distinguished name of the resulting * certificate. * * If issuerID is nil, a random value will be generated for matter-icac-id. * * If fabricID is not nil, it will be included in the subject DN of the * certificate. In this case it must be a valid Matter fabric id. * * validityPeriod specifies when the certificate will be valid. A certificate * with no expiration time can be created by specifying [NSDate distantFuture] * for the end of the period. * * On failure returns nil and if "error" is not null sets *error to the relevant * error. */ + (MTRCertificateDERBytes _Nullable)createIntermediateCertificate:(id)rootKeypair rootCertificate:(MTRCertificateDERBytes)rootCertificate intermediatePublicKey:(SecKeyRef)intermediatePublicKey issuerID:(NSNumber * _Nullable)issuerID fabricID:(NSNumber * _Nullable)fabricID validityPeriod:(NSDateInterval *)validityPeriod error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.6), macos(13.5), watchos(9.6), tvos(16.6)); /** * As above, but defaults to no expiration time. */ + (MTRCertificateDERBytes _Nullable)createIntermediateCertificate:(id)rootKeypair rootCertificate:(MTRCertificateDERBytes)rootCertificate intermediatePublicKey:(SecKeyRef)intermediatePublicKey issuerID:(NSNumber * _Nullable)issuerID fabricID:(NSNumber * _Nullable)fabricID error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Create an X.509 DER encoded certificate that has the * right fields to be a valid Matter operational certificate. * * signingKeypair and signingCertificate are the root or intermediate that is * signing the operational certificate. * * nodeID and fabricID are expected to be 64-bit unsigned integers. * * nodeID must be a valid Matter operational node id. * * fabricID must be a valid Matter fabric id. * * caseAuthenticatedTags may be nil to indicate no CASE Authenticated Tags * should be used. If caseAuthenticatedTags is not nil, it must contain at most * 3 numbers, which are expected to be 32-bit unsigned Case Authenticated Tag * values. * * validityPeriod specifies when the certificate will be valid. A certificate * with no expiration time can be created by specifying [NSDate distantFuture] * for the end of the period. * * On failure returns nil and if "error" is not null sets *error to the relevant * error. */ + (MTRCertificateDERBytes _Nullable)createOperationalCertificate:(id)signingKeypair signingCertificate:(MTRCertificateDERBytes)signingCertificate operationalPublicKey:(SecKeyRef)operationalPublicKey fabricID:(NSNumber *)fabricID nodeID:(NSNumber *)nodeID caseAuthenticatedTags:(NSSet * _Nullable)caseAuthenticatedTags validityPeriod:(NSDateInterval *)validityPeriod error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.6), macos(13.5), watchos(9.6), tvos(16.6)); /** * As above, but defaults to no expiration time. */ + (MTRCertificateDERBytes _Nullable)createOperationalCertificate:(id)signingKeypair signingCertificate:(MTRCertificateDERBytes)signingCertificate operationalPublicKey:(SecKeyRef)operationalPublicKey fabricID:(NSNumber *)fabricID nodeID:(NSNumber *)nodeID caseAuthenticatedTags:(NSSet * _Nullable)caseAuthenticatedTags error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * Check whether the given keypair's public key matches the given certificate's * public key. The certificate is expected to be an X.509 DER encoded * certificate. * * Will return NO on failures to extract public keys from the objects. */ + (BOOL)keypair:(id)keypair matchesCertificate:(NSData *)certificate; /** * Check whether two X.509 DER encoded certificates are equivalent, in the sense * of having the same public key and the same subject DN. Returns NO if public * keys or subject DNs cannot be extracted from the certificates. */ + (BOOL)isCertificate:(MTRCertificateDERBytes)certificate1 equalTo:(MTRCertificateDERBytes)certificate2; /** * Generate a PKCS#10 certificate signing request from a MTRKeypair. 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. */ + (MTRCSRDERBytes _Nullable)createCertificateSigningRequest:(id)keypair error:(NSError * __autoreleasing _Nullable * _Nullable)error; /** * Convert the given X.509v3 DER encoded certificate to the Matter certificate * format. * * Returns nil if the conversion fails (e.g. if the input data cannot be parsed * as a DER encoded X.509 certificate, or if the certificate cannot be * represented in the Matter certificate format). */ + (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_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); /** * 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)publicKeyFromCSR:(MTRCSRDERBytes)csr error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @end @interface MTRCertificates (Deprecated) + (nullable NSData *)generateRootCertificate:(id)keypair issuerId:(nullable NSNumber *)issuerId fabricId:(nullable NSNumber *)fabricId error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_DEPRECATED("Please use createRootCertificate:issuerID:fabricID:error:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); + (nullable NSData *)generateIntermediateCertificate:(id)rootKeypair rootCertificate:(NSData *)rootCertificate intermediatePublicKey:(SecKeyRef)intermediatePublicKey issuerId:(nullable NSNumber *)issuerId fabricId:(nullable NSNumber *)fabricId error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_DEPRECATED("Please use createIntermediateCertificate:rootCertificate:intermediatePublicKey:issuerID:fabricID:error:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); + (nullable NSData *)generateOperationalCertificate:(id)signingKeypair signingCertificate:(NSData *)signingCertificate operationalPublicKey:(SecKeyRef)operationalPublicKey fabricId:(NSNumber *)fabricId nodeId:(NSNumber *)nodeId caseAuthenticatedTags:(NSArray * _Nullable)caseAuthenticatedTags error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_DEPRECATED( "Plase use " "createOperationalCertificate:signingCertificate:operationalPublicKey:fabricID:nodeID:caseAuthenticatedTags:error:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); + (nullable NSData *)generateCertificateSigningRequest:(id)keypair error:(NSError * __autoreleasing _Nullable * _Nullable)error MTR_DEPRECATED("Please use createCertificateSigningRequest:error:", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); @end NS_ASSUME_NONNULL_END