Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions AWSIoT/AWSIoTDataManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "AWSIoTDataService.h"
#import "AWSIoTService.h"
#import "AWSIoTMQTTTypes.h"
#import "AWSIoTKeychain.h"

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -471,6 +472,23 @@ DEPRECATED_MSG_ATTRIBUTE("Use `updateUserMetaData` for updating the user meta da
certificateId:(NSString *)certificateId
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback;

/**
Initialises the MQTT session and connects to AWS IoT using certificate-based mutual authentication

@param clientId The Client Identifier identifies the Client to the Server.
@param cleanSession specifies if the server should discard previous session information.
@param certificateId contains the ID of the certificate to use in the connection; must be in the keychain
@param keyAlgorithmType The algorithm of the key pair.
@param callback When new mqtt session status is received callback will be called with new connection status.\

@return true if initialise finished with success
*/
- (BOOL)connectWithClientId:(NSString *)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback;

/**
Initialises the MQTT session and connects to AWS IoT on port 443 using certificate-based mutual authentication
and ALPN (Application Layer Protocol Negotiation)
Expand All @@ -492,6 +510,25 @@ DEPRECATED_MSG_ATTRIBUTE("Use `updateUserMetaData` for updating the user meta da
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback
API_AVAILABLE(ios(11), macosx(10.13));

/**
Initialises the MQTT session and connects to AWS IoT on port 443 using certificate-based mutual authentication
and ALPN (Application Layer Protocol Negotiation)

@param clientId The Client Identifier identifies the Client to the Server.
@param cleanSession specifies if the server should discard previous session information.
@param certificateId contains the ID of the certificate to use in the connection; must be in the keychain.
@param keyAlgorithmType The algorithm of the key pair.
@param callback When new mqtt session status is received callback will be called with new connection status.

@return true if initialise finished with success
*/
- (BOOL)connectUsingALPNWithClientId:(NSString *)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback
API_AVAILABLE(ios(11), macosx(10.13));

/**
Initialises the MQTT session and connects to AWS IoT using WebSocket/SigV4 authentication. IAM
credentials are taken from the current service configuration.
Expand Down
76 changes: 76 additions & 0 deletions AWSIoT/AWSIoTDataManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,20 @@ - (BOOL)connectUsingALPNWithClientId:(NSString *)clientId
port:443];
}

- (BOOL)connectUsingALPNWithClientId:(NSString *)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback
{
return [self connectWithClientId:clientId
cleanSession:cleanSession
certificateId:certificateId
keyAlgorithmType:keyAlgorithmType
statusCallback:callback
port:443];
}

- (BOOL)connectWithClientId:(NSString*)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
Expand All @@ -435,6 +449,20 @@ - (BOOL)connectWithClientId:(NSString*)clientId
port:8883];
}

- (BOOL)connectWithClientId:(NSString*)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback
{
return [self connectWithClientId:clientId
cleanSession:cleanSession
certificateId:certificateId
keyAlgorithmType:keyAlgorithmType
statusCallback:callback
port:8883];
}

- (BOOL)connectWithClientId:(NSString*)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
Expand Down Expand Up @@ -481,6 +509,54 @@ - (BOOL)connectWithClientId:(NSString*)clientId
statusCallback:callback];
}

- (BOOL)connectWithClientId:(NSString*)clientId
cleanSession:(BOOL)cleanSession
certificateId:(NSString *)certificateId
keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback
port:(UInt32)port
{
AWSDDLogDebug(@"<<%@>>In connectWithClientID", [NSThread currentThread]);
AWSDDLogInfo(@"hostName: %@", self.IoTData.configuration.endpoint.hostName);
AWSDDLogInfo(@"URL: %@", self.IoTData.configuration.endpoint.URL);

if (clientId == nil || [clientId isEqualToString: @""]) {
return false;
}

if (certificateId == nil || [certificateId isEqualToString:@""]) {
return false;
}

if (_userDidIssueConnect) {
//User has already connected. Can't connect multiple times, return No.
return NO;
}

_userDidIssueConnect = YES;
_userDidIssueDisconnect = NO;

[self.mqttClient setBaseReconnectTime:self.mqttConfiguration.baseReconnectTimeInterval];
[self.mqttClient setMinimumConnectionTime:self.mqttConfiguration.minimumConnectionTimeInterval];
[self.mqttClient setMaximumReconnectTime:self.mqttConfiguration.maximumReconnectTimeInterval];
[self.mqttClient setAutoResubscribe:self.mqttConfiguration.autoResubscribe];
[self.mqttClient setPublishRetryThrottle:self.mqttConfiguration.publishRetryThrottle];
[self.mqttClient setAutoResubscribe:self.mqttConfiguration.autoResubscribe];

return [self.mqttClient connectWithClientId:clientId
toHost:self.IoTData.configuration.endpoint.hostName
port:port
cleanSession:cleanSession
certificateId:certificateId
keyAlgorithmType:keyAlgorithmType
keepAlive:self.mqttConfiguration.keepAliveTimeInterval
willTopic:self.mqttConfiguration.lastWillAndTestament.topic
willMsg:[self.mqttConfiguration.lastWillAndTestament.message dataUsingEncoding:NSUTF8StringEncoding]
willQoS:self.mqttConfiguration.lastWillAndTestament.qos
willRetainFlag:self.mqttConfiguration.lastWillAndTestament.willRetain
statusCallback:callback];
}

- (BOOL)connectUsingWebSocketWithClientId:(NSString *)clientId
cleanSession:(BOOL)cleanSession
statusCallback:(void (^)(AWSIoTMQTTStatus status))callback;
Expand Down
46 changes: 46 additions & 0 deletions AWSIoT/AWSIoTManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#import "AWSIoTService.h"
#import "AWSIoTKeyChainTypes.h"
#import "AWSIoTKeychain.h"

//CreateCertificateWithResponse
@interface AWSIoTCreateCertificateResponse : AWSModel
Expand Down Expand Up @@ -208,6 +209,23 @@
*/
+ (BOOL)importIdentityFromPKCS12Data:(NSData *)pkcs12Data passPhrase:(NSString *)passPhrase certificateId:(NSString *)certificateId;

/**
* Imports a complete identity from PKCS#12 data into the keychain, validating against a specific algorithm type.
*
* This function extracts the certificate, public key, and private key, then validates their internal consistency and
* matches them against the expected algorithm type provided by the caller.
* Supports RSA, EC, ECPrimeRandom key algorithms.
*
* @param pkcs12Data The identity data in PKCS#12 format.
* @param passPhrase The password for the PKCS#12 data.
* @param certificateId A unique identifier used to construct the final tags for the keychain items.
* @param keyAlgorithmType The expected algorithm of the key pair. The function will fail if the actual
* key type in the data does not match this parameter.
*
* @return `YES` if the entire identity was validated and imported successfully, `NO` otherwise.
*/
+ (BOOL)importIdentityFromPKCS12Data:(NSData *)pkcs12Data passPhrase:(NSString *)passPhrase certificateId:(NSString *)certificateId keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType;

/**
* Validates the certificate with the given identifier of certificate.
*
Expand All @@ -217,6 +235,20 @@
*/
+ (BOOL)isValidCertificate:(NSString *)certificateId;

/**
* Check if a valid certificate identity exists for a given certificateId and algorithm type.
*
* This function constructs the appropriate private key tag and certificate
* label based on the provided algorithm type and certificate ID, then calls a more detailed
* validation method to confirm the identity's presence and integrity in the keychain.
*
* @param certificateId The unique identifier used to construct the full keychain tags.
* @param keyAlgorithmType The algorithm of the key pair associated with the certificate.
*
* @return `YES` if a valid identity is found, `NO` otherwise.
*/
+ (BOOL)isValidCertificate:(NSString *)certificateId keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType;

/**
* Deletes keys and certificate
*
Expand All @@ -226,6 +258,20 @@

+ (BOOL)deleteCertificateWithCertificateId:(NSString*)certificateId NS_SWIFT_NAME(deleteCertificate(certificateId:));

/**
* Deletes a complete identity (certificate and key pair) from the keychain.
*
* This function constructs the necessary unique tags based on the certificate ID and algorithm type,
* and then attempts to remove both the certificate and its associated asymmetric key pair.
*
* @param certificateId The unique identifier for the identity to be deleted.
* @param keyAlgorithmType The algorithm of the key pair to be deleted.
*
* @return `YES` if all components were successfully deleted (or were already not present),
* `NO` if a critical deletion error occurred for any component.
*/
+ (BOOL)deleteCertificateWithCertificateIdAndKeyAlgorithmType:(NSString*)certificateId keyAlgorithmType:(KeyAlgorithmType)keyAlgorithmType NS_SWIFT_NAME(deleteCertificate(certificateId:keyAlgorithmType:));

+ (void)setKeyChainAccessibility:(AWSIoTKeyChainAccessibility)accessibility;

+ (NSString *)certTagWithCertificateId:(NSString *)certificateId;
Expand Down
Loading