diff --git a/MQTTClient/MQTTClient.xcodeproj/project.pbxproj b/MQTTClient/MQTTClient.xcodeproj/project.pbxproj index 4cf85d40..556708a9 100644 --- a/MQTTClient/MQTTClient.xcodeproj/project.pbxproj +++ b/MQTTClient/MQTTClient.xcodeproj/project.pbxproj @@ -36,7 +36,6 @@ /* Begin PBXBuildFile section */ 840507C5193DCF2E002EBBD2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 840507C4193DCF2E002EBBD2 /* UIKit.framework */; }; 840715FA1BBE999700FBB3CB /* mosquitto.org.cer in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C91B49332700D81CC8 /* mosquitto.org.cer */; }; - 840715FB1BBE999700FBB3CB /* info@owntracks.org.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C51B4922E100D81CC8 /* info@owntracks.org.p12 */; }; 840715FC1BBE999700FBB3CB /* KreyChristoph.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C31B49110200D81CC8 /* KreyChristoph.p12 */; }; 840715FD1BBE999700FBB3CB /* server.der in Resources */ = {isa = PBXBuildFile; fileRef = C21D3CA71B1ED2F40012DD2F /* server.der */; }; 840715FE1BBE999700FBB3CB /* ADNNetServerTrustChain in Resources */ = {isa = PBXBuildFile; fileRef = C21D3C9D1B1EC4400012DD2F /* ADNNetServerTrustChain */; }; @@ -74,7 +73,6 @@ 8407163E1BBEF16E00FBB3CB /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8407163D1BBEF16E00FBB3CB /* CFNetwork.framework */; }; 840716401BBEF17600FBB3CB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8407163F1BBEF17600FBB3CB /* Foundation.framework */; }; 840716411BBEF18B00FBB3CB /* mosquitto.org.cer in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C91B49332700D81CC8 /* mosquitto.org.cer */; }; - 840716421BBEF18B00FBB3CB /* info@owntracks.org.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C51B4922E100D81CC8 /* info@owntracks.org.p12 */; }; 840716431BBEF18B00FBB3CB /* KreyChristoph.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C31B49110200D81CC8 /* KreyChristoph.p12 */; }; 840716441BBEF18B00FBB3CB /* server.der in Resources */ = {isa = PBXBuildFile; fileRef = C21D3CA71B1ED2F40012DD2F /* server.der */; }; 840716451BBEF18B00FBB3CB /* adn_0.cer in Resources */ = {isa = PBXBuildFile; fileRef = C21D3CA11B1EC63E0012DD2F /* adn_0.cer */; }; @@ -149,7 +147,6 @@ 8462436C1ABEAAF900B72519 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8462436B1ABEAAF900B72519 /* CoreData.framework */; }; 8462436D1ABEAB2900B72519 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8462436B1ABEAAF900B72519 /* CoreData.framework */; }; 8482D3C41B49110200D81CC8 /* KreyChristoph.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C31B49110200D81CC8 /* KreyChristoph.p12 */; }; - 8482D3C61B4922E200D81CC8 /* info@owntracks.org.p12 in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C51B4922E100D81CC8 /* info@owntracks.org.p12 */; }; 8482D3CA1B49332700D81CC8 /* mosquitto.org.cer in Resources */ = {isa = PBXBuildFile; fileRef = 8482D3C91B49332700D81CC8 /* mosquitto.org.cer */; }; 848BB8F3195FF7A2004FCAE2 /* MQTTClientOnlyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 848BB8F2195FF7A2004FCAE2 /* MQTTClientOnlyTests.m */; }; 84B1AFEE196C7AF60056B959 /* MultiThreadingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 84B1AFED196C7AF60056B959 /* MultiThreadingTests.m */; }; @@ -291,7 +288,6 @@ 846243681ABE9E5900B72519 /* MQTTPersistence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MQTTPersistence.m; sourceTree = ""; }; 8462436B1ABEAAF900B72519 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 8482D3C31B49110200D81CC8 /* KreyChristoph.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = KreyChristoph.p12; sourceTree = ""; }; - 8482D3C51B4922E100D81CC8 /* info@owntracks.org.p12 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "info@owntracks.org.p12"; sourceTree = ""; }; 8482D3C91B49332700D81CC8 /* mosquitto.org.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = mosquitto.org.cer; sourceTree = ""; }; 848BB8F2195FF7A2004FCAE2 /* MQTTClientOnlyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MQTTClientOnlyTests.m; sourceTree = ""; }; 84B1AFED196C7AF60056B959 /* MultiThreadingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MultiThreadingTests.m; sourceTree = ""; }; @@ -375,7 +371,6 @@ isa = PBXGroup; children = ( 8482D3C91B49332700D81CC8 /* mosquitto.org.cer */, - 8482D3C51B4922E100D81CC8 /* info@owntracks.org.p12 */, 8482D3C31B49110200D81CC8 /* KreyChristoph.p12 */, C21D3CA71B1ED2F40012DD2F /* server.der */, C21D3CA11B1EC63E0012DD2F /* adn_0.cer */, @@ -770,7 +765,6 @@ buildActionMask = 2147483647; files = ( 840716411BBEF18B00FBB3CB /* mosquitto.org.cer in Resources */, - 840716421BBEF18B00FBB3CB /* info@owntracks.org.p12 in Resources */, 840716431BBEF18B00FBB3CB /* KreyChristoph.p12 in Resources */, 840716441BBEF18B00FBB3CB /* server.der in Resources */, 840716451BBEF18B00FBB3CB /* adn_0.cer in Resources */, @@ -796,7 +790,6 @@ 840716081BBE99B000FBB3CB /* adn_1.cer in Resources */, 840716091BBE99B000FBB3CB /* adn_2.cer in Resources */, 840715FA1BBE999700FBB3CB /* mosquitto.org.cer in Resources */, - 840715FB1BBE999700FBB3CB /* info@owntracks.org.p12 in Resources */, 840715FC1BBE999700FBB3CB /* KreyChristoph.p12 in Resources */, 840715FD1BBE999700FBB3CB /* server.der in Resources */, 840715FE1BBE999700FBB3CB /* ADNNetServerTrustChain in Resources */, @@ -823,7 +816,6 @@ 8482D3CA1B49332700D81CC8 /* mosquitto.org.cer in Resources */, C21D3C9B1B1EC40A0012DD2F /* COMODO_RSA_Certification_Authority.cer in Resources */, C21D3C9C1B1EC40C0012DD2F /* COMODO_RSA_Domain_Validation_Secure_Server_CA.cer in Resources */, - 8482D3C61B4922E200D81CC8 /* info@owntracks.org.p12 in Resources */, 8482D3C41B49110200D81CC8 /* KreyChristoph.p12 in Resources */, C21D3C961B1EC4000012DD2F /* AltName.cer in Resources */, C21D3C971B1EC4010012DD2F /* NoDomains.cer in Resources */, @@ -1022,6 +1014,7 @@ buildSettings = { CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1041,6 +1034,7 @@ buildSettings = { CLANG_WARN_UNREACHABLE_CODE = YES; CODE_SIGN_IDENTITY = "-"; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1380,6 +1374,7 @@ 8407161C1BBEEF9C00FBB3CB /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 8407163A1BBEF13A00FBB3CB /* Build configuration list for PBXNativeTarget "MQTTClientOSXTests" */ = { isa = XCConfigurationList; @@ -1388,6 +1383,7 @@ 8407163C1BBEF13A00FBB3CB /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 8425D6DF1BBE8B45005AD733 /* Build configuration list for PBXNativeTarget "MQTTClientTV" */ = { isa = XCConfigurationList; diff --git a/MQTTClient/MQTTClient/MQTTSessionManager.h b/MQTTClient/MQTTClient/MQTTSessionManager.h index 3b2fab95..e5e328b8 100644 --- a/MQTTClient/MQTTClient/MQTTSessionManager.h +++ b/MQTTClient/MQTTClient/MQTTSessionManager.h @@ -11,6 +11,7 @@ #import #endif #import "MQTTSession.h" +#import "MQTTSSLSecurityPolicy.h" /** delegate gives your application access to received messages */ diff --git a/MQTTClient/MQTTClientTests/MQTTACLTests.m b/MQTTClient/MQTTClientTests/MQTTACLTests.m index be14ab1a..7844becb 100644 --- a/MQTTClient/MQTTClientTests/MQTTACLTests.m +++ b/MQTTClient/MQTTClientTests/MQTTACLTests.m @@ -51,7 +51,9 @@ - (void)test_connect_user_pwd_MQTT_3_1_2_19_MQTT_3_1_2_21 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssertEqual(self.event, MQTTSessionEventConnected, @"Not Connected %ld %@", (long)self.event, self.error); @@ -81,7 +83,9 @@ - (void)test_connect_user_no_pwd_MQTT_3_1_2_19_MQTT_3_1_2_20 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; @@ -112,7 +116,9 @@ - (void)test_connect_no_user_no_pwd_MQTT_3_1_2_18_MQTT_3_1_2_20 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; @@ -142,7 +148,9 @@ - (void)test_connect_no_user_but_pwd_MQTT_3_1_2_22 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; @@ -153,6 +161,46 @@ - (void)test_connect_no_user_but_pwd_MQTT_3_1_2_22 { #pragma mark helpers +- (NSArray *)clientCerts:(NSDictionary *)parameters { + NSArray *clientCerts = nil; + if (parameters[@"clientp12"] && parameters[@"clientp12pass"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTACLTests class]] pathForResource:parameters[@"clientp12"] + ofType:@"p12"]; + + clientCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; + if (!clientCerts) { + XCTFail(@"invalid p12 file"); + } + } + return clientCerts; +} + +- (MQTTSSLSecurityPolicy *)securityPolicy:(NSDictionary *)parameters { + MQTTSSLSecurityPolicy *securityPolicy = nil; + + if (parameters[@"serverCER"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTACLTests class]] pathForResource:parameters[@"serverCER"] + ofType:@"cer"]; + if (path) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + if (certificateData) { + securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; + securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; + securityPolicy.validatesCertificateChain = TRUE; + securityPolicy.allowInvalidCertificates = FALSE; + securityPolicy.validatesDomainName = TRUE; + } else { + XCTFail(@"error reading cer file"); + } + } else { + XCTFail(@"cer file not found"); + } + } + return securityPolicy; +} + - (void)received:(MQTTSession *)session type:(int)type qos:(MQTTQosLevel)qos retained:(BOOL)retained duped:(BOOL)duped mid:(UInt16)mid data:(NSData *)data { //NSLog(@"received:%d qos:%d retained:%d duped:%d mid:%d data:%@", type, qos, retained, duped, mid, data); self.type = type; diff --git a/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m b/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m index 2c294b0b..53196126 100644 --- a/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m +++ b/MQTTClient/MQTTClientTests/MQTTClientPublishTests.m @@ -409,6 +409,46 @@ - (void)testPublish_q2_dup_MQTT_3_3_1_2 * helpers */ +- (NSArray *)clientCerts:(NSDictionary *)parameters { + NSArray *clientCerts = nil; + if (parameters[@"clientp12"] && parameters[@"clientp12pass"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTClientPublishTests class]] pathForResource:parameters[@"clientp12"] + ofType:@"p12"]; + + clientCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; + if (!clientCerts) { + XCTFail(@"invalid p12 file"); + } + } + return clientCerts; +} + +- (MQTTSSLSecurityPolicy *)securityPolicy:(NSDictionary *)parameters { + MQTTSSLSecurityPolicy *securityPolicy = nil; + + if (parameters[@"serverCER"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTClientPublishTests class]] pathForResource:parameters[@"serverCER"] + ofType:@"cer"]; + if (path) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + if (certificateData) { + securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; + securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; + securityPolicy.validatesCertificateChain = TRUE; + securityPolicy.allowInvalidCertificates = FALSE; + securityPolicy.validatesDomainName = TRUE; + } else { + XCTFail(@"error reading cer file"); + } + } else { + XCTFail(@"cer file not found"); + } + } + return securityPolicy; +} + - (void)testPublishCloseExpected:(NSData *)data onTopic:(NSString *)topic retain:(BOOL)retain atLevel:(UInt8)qos { [self testPublishCore:data onTopic:topic retain:retain atLevel:qos]; @@ -507,7 +547,9 @@ - (void)connect:(NSDictionary *)parameters { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.delegate = self; self.session.persistence.persistent = PERSISTENT; diff --git a/MQTTClient/MQTTClientTests/MQTTClientSubscriptionTests.m b/MQTTClient/MQTTClientTests/MQTTClientSubscriptionTests.m index 73f08df9..f8e9b5b9 100644 --- a/MQTTClient/MQTTClientTests/MQTTClientSubscriptionTests.m +++ b/MQTTClient/MQTTClientTests/MQTTClientSubscriptionTests.m @@ -537,6 +537,47 @@ - (void)testMultiUnsubscribe_more * helpers */ + +- (NSArray *)clientCerts:(NSDictionary *)parameters { + NSArray *clientCerts = nil; + if (parameters[@"clientp12"] && parameters[@"clientp12pass"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTClientSubscriptionTests class]] pathForResource:parameters[@"clientp12"] + ofType:@"p12"]; + + clientCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; + if (!clientCerts) { + XCTFail(@"invalid p12 file"); + } + } + return clientCerts; +} + +- (MQTTSSLSecurityPolicy *)securityPolicy:(NSDictionary *)parameters { + MQTTSSLSecurityPolicy *securityPolicy = nil; + + if (parameters[@"serverCER"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTClientSubscriptionTests class]] pathForResource:parameters[@"serverCER"] + ofType:@"cer"]; + if (path) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + if (certificateData) { + securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; + securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; + securityPolicy.validatesCertificateChain = TRUE; + securityPolicy.allowInvalidCertificates = FALSE; + securityPolicy.validatesDomainName = TRUE; + } else { + XCTFail(@"error reading cer file"); + } + } else { + XCTFail(@"cer file not found"); + } + } + return securityPolicy; +} + - (void)testSubscribeSubackExpected:(NSString *)topic atLevel:(UInt8)qos { [self testSubscribe:topic atLevel:qos]; @@ -771,7 +812,9 @@ - (void)connect:(NSDictionary *)parameters { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.delegate = self; self.session.persistence.persistent = PERSISTENT; self.event = -1; diff --git a/MQTTClient/MQTTClientTests/MQTTClientTests.h b/MQTTClient/MQTTClientTests/MQTTClientTests.h index f7926a87..9dfe7e71 100644 --- a/MQTTClient/MQTTClientTests/MQTTClientTests.h +++ b/MQTTClient/MQTTClientTests/MQTTClientTests.h @@ -19,7 +19,7 @@ #define ALOT 1024 #define PERSISTENT false -//#define BROKERLIST @[@"local", @"localTls", @"localTlsCerts", @"mosquitto", @"mosquittoTls", @"mosquittoTlsCerts", @"eclipse", @"paho", @"pahotest", @"rabbitmq", @"hivemq", @"rsmb", @"mosca", @"m2m", @"vernemq", @"emqttd", @"moquette", @"activemq", @"apollo", @"cloudmqtt", @"hbmqtt"] +//#define BROKERLIST @[@"local", @"mosquitto", @"mosquittoTls", @"mosquittoTlsCerts", @"eclipse", @"paho", @"hivemq", @"m2m", @"rabbitmq"] #define BROKERLIST @[@"local"] #define BROKERS @{ \ @@ -32,40 +32,6 @@ @"timeout": @10 \ }, \ \ -@"moquette": @{ \ -@"host": @"localhost", \ -@"port": @1883, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"hbmqtt": @{ \ -@"host": @"localhost", \ -@"port": @1883, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"localTls": @{ \ -@"host": @"localhost", \ -@"port": @8883, \ -@"tls": @YES, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"localTlsCerts": @{ \ -@"host": @"localhost", \ -@"port": @8884, \ -@"tls": @YES, \ -@"protocollevel": @4, \ -@"timeout": @10, \ -@"clientp12": @"info@owntracks.org", \ -@"clientp12pass": @"12345678" \ -}, \ -\ @"mosquittoTls": @{ \ @"host": @"test.mosquitto.org", \ @"port": @8883, \ @@ -81,6 +47,7 @@ @"tls": @YES, \ @"protocollevel": @4, \ @"timeout": @10, \ +@"serverCER": @"mosquitto.org", \ @"clientp12": @"KreyChristoph", \ @"clientp12pass": @"abcde" \ }, \ @@ -131,74 +98,6 @@ @"tls": @NO, \ @"protocollevel": @3, \ @"timeout": @10 \ -}, \ -\ -@"activemq": @{ \ -@"host": @"localhost", \ -@"port": @1883, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"apollo": @{ \ -@"host": @"localhost", \ -@"port": @61613, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10, \ -@"user": @"admin", \ -@"pass": @"password" \ -}, \ -\ -@"pahotest": @{ \ -@"host": @"localhost", \ -@"port": @1884, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"rsmb": @{ \ -@"host": @"192.168.178.38", \ -@"port": @1884, \ -@"tls": @NO, \ -@"protocollevel": @3, \ -@"timeout": @10 \ -}, \ -\ -@"mosca": @{ \ -@"host": @"localhost", \ -@"port": @1885, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"vernemq": @{ \ -@"host": @"localhost", \ -@"port": @1886, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"emqttd": @{ \ -@"host": @"localhost", \ -@"port": @1887, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10 \ -}, \ -\ -@"cloudmqtt": @{ \ -@"host": @"mxx.cloudmqtt.com", \ -@"port": @10000, \ -@"tls": @NO, \ -@"protocollevel": @4, \ -@"timeout": @10, \ -@"user": @"xxxxxxxxx", \ -@"pass": @"xxxxxxxxxxx" \ } \ \ } diff --git a/MQTTClient/MQTTClientTests/MQTTClientTests.m b/MQTTClient/MQTTClientTests/MQTTClientTests.m index 40b99319..0a2feb68 100644 --- a/MQTTClient/MQTTClientTests/MQTTClientTests.m +++ b/MQTTClient/MQTTClientTests/MQTTClientTests.m @@ -39,13 +39,15 @@ - (void)test_init { for (NSString *broker in BROKERLIST) { NSLog(@"testing broker %@", broker); NSDictionary *parameters = BROKERS[broker]; - self.session = [[MQTTSession alloc] init]; - self.session.persistence.persistent = PERSISTENT; - self.session.userName = parameters[@"user"]; - self.session.password = parameters[@"pass"]; - [self connect:self.session parameters:parameters]; - XCTAssertEqual(self.event, MQTTSessionEventConnected, @"Not Connected %ld %@", (long)self.event, self.error); - [self shutdown:parameters]; + if (!parameters[@"serverCER"] && !parameters[@"clientp12"]) { + self.session = [[MQTTSession alloc] init]; + self.session.persistence.persistent = PERSISTENT; + self.session.userName = parameters[@"user"]; + self.session.password = parameters[@"pass"]; + [self connect:self.session parameters:parameters]; + XCTAssertEqual(self.event, MQTTSessionEventConnected, @"Not Connected %ld %@", (long)self.event, self.error); + [self shutdown:parameters]; + } } } @@ -65,7 +67,9 @@ - (void)test_init_zero_clientId_clean { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -105,7 +109,9 @@ - (void)test_init_zero_clientId_noclean_MQTT_3_1_3_8_MQTT_3_1_3_9 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -131,7 +137,9 @@ - (void)test_init_long_clientId { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); XCTAssertEqual(self.event, MQTTSessionEventConnected, @"Not Connected %ld %@", (long)self.event, self.error); @@ -155,7 +163,9 @@ - (void)test_init_no_clientId { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -180,7 +190,9 @@ - (void)test_connect_standard_port { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -193,16 +205,18 @@ - (void)test_connect_short { for (NSString *broker in BROKERLIST) { NSLog(@"testing broker %@", broker); NSDictionary *parameters = BROKERS[broker]; - self.session = [[MQTTSession alloc] initWithClientId:nil - userName:parameters[@"user"] - password:parameters[@"pass"] - keepAlive:60 - cleanSession:YES]; - self.session.persistence.persistent = TRUE; - [self connect:self.session parameters:parameters]; - XCTAssert(!self.timeout, @"timeout"); - XCTAssertEqual(self.event, MQTTSessionEventConnected, @"Not Connected %ld %@", (long)self.event, self.error); - [self shutdown:parameters]; + if (!parameters[@"serverCER"] && !parameters[@"clientp12"]) { + self.session = [[MQTTSession alloc] initWithClientId:nil + userName:parameters[@"user"] + password:parameters[@"pass"] + keepAlive:60 + cleanSession:YES]; + self.session.persistence.persistent = TRUE; + [self connect:self.session parameters:parameters]; + XCTAssert(!self.timeout, @"timeout"); + XCTAssertEqual(self.event, MQTTSessionEventConnected, @"Not Connected %ld %@", (long)self.event, self.error); + [self shutdown:parameters]; + } } } @@ -233,7 +247,9 @@ - (void)test_connect_will_non_retained_MQTT_3_1_2_8_MQTT_3_1_2_16 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; if (![subscribingSession connectAndWaitToHost:parameters[@"host"] port:[parameters[@"port"] intValue] usingSSL:[parameters[@"tls"] boolValue]]) { XCTFail(@"no connection for sub to %@", broker); @@ -252,7 +268,9 @@ - (void)test_connect_will_non_retained_MQTT_3_1_2_8_MQTT_3_1_2_16 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -286,7 +304,9 @@ - (void)test_disconnect_when_same_clientID_connects_MQTT_3_1_4_2 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -305,7 +325,9 @@ - (void)test_disconnect_when_same_clientID_connects_MQTT_3_1_4_2 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; if (![sameSession connectAndWaitToHost:parameters[@"host"] port:[parameters[@"port"] intValue] @@ -345,7 +367,9 @@ - (void)test_connect_will_retained_MQTT_3_1_2_8_MQTT_3_1_2_17 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; if (![subscribingSession connectAndWaitToHost:parameters[@"host"] port:[parameters[@"port"] intValue] usingSSL:[parameters[@"tls"] boolValue]]) { XCTFail(@"no connection for sub to %@", broker); @@ -364,7 +388,9 @@ - (void)test_connect_will_retained_MQTT_3_1_2_8_MQTT_3_1_2_17 { willRetainFlag:YES protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -396,7 +422,9 @@ - (void)test_connect_all_fields_MQTT_3_1_3_1 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -429,7 +457,9 @@ - (void)test_connect_other_protocollevel34__MQTT_3_1_2_1 { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] == 3 ? 4 : 3 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -463,7 +493,9 @@ - (void)test_connect_illegal_protocollevel5_MQTT_3_1_2_2_MQTT_3_2_2_5 { willRetainFlag:NO protocolLevel:5 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -496,7 +528,9 @@ - (void)test_connect_illegal_protocollevel0_and_protocolname_MQTT_3_1_2_1 { willRetainFlag:NO protocolLevel:0 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -527,7 +561,9 @@ - (void)test_ping { willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -624,7 +660,9 @@ - (void)test_dont_process_after_reject_MQTT_3_1_4_5 { willRetainFlag:NO protocolLevel:5 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; [self.session subscribeTopic:TOPIC]; @@ -637,6 +675,50 @@ - (void)test_dont_process_after_reject_MQTT_3_1_4_5 { } } +#define SYSTOPIC @"$SYS/#" + +- (void)test_systopic { + for (NSString *broker in BROKERLIST) { + NSLog(@"testing broker %@", broker); + NSDictionary *parameters = BROKERS[broker]; + self.session = [[MQTTSession alloc] initWithClientId:nil + userName:parameters[@"user"] + password:parameters[@"pass"] + keepAlive:60 + cleanSession:YES + will:NO + willTopic:nil + willMsg:nil + willQoS:0 + willRetainFlag:NO + protocolLevel:4 + runLoop:[NSRunLoop currentRunLoop] + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; + self.session.persistence.persistent = PERSISTENT; + [self connect:self.session parameters:parameters]; + XCTAssert(!self.timeout, @"timeout"); + XCTAssertEqual(self.event, MQTTSessionEventConnected, @"MQTTSessionEventConnected %@", self.error); + + [self.session subscribeToTopic:SYSTOPIC atLevel:MQTTQosLevelAtMostOnce]; + + self.timeout = FALSE; + [NSObject cancelPreviousPerformRequestsWithTarget:self]; + [self performSelector:@selector(ackTimeout:) + withObject:parameters[@"timeout"] + afterDelay:[parameters[@"timeout"] intValue]]; + + while (!self.timeout) { + NSLog(@"waiting for incoming %@ messages", SYSTOPIC); + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; + } + + [self shutdown:parameters]; + } +} + + #define PROCESSING_NUMBER 20 #define PROCESSING_INTERVAL 0.1 #define PROCESSING_TIMEOUT 30 @@ -657,7 +739,9 @@ - (void)test_throttling_incoming_q0 { willRetainFlag:NO protocolLevel:4 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -712,7 +796,9 @@ - (void)test_throttling_incoming_q1 { willRetainFlag:NO protocolLevel:4 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -767,7 +853,9 @@ - (void)test_throttling_incoming_q2 { willRetainFlag:NO protocolLevel:4 runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; XCTAssert(!self.timeout, @"timeout"); @@ -820,18 +908,6 @@ - (void)test_client_certificate { for (NSString *broker in BROKERLIST) { NSLog(@"testing broker %@", broker); NSDictionary *parameters = BROKERS[broker]; - if (!parameters[@"clientp12"]) continue; - if (!parameters[@"clientp12pass"]) continue; - - NSString *path = [[NSBundle bundleForClass:[MQTTClientTests class]] pathForResource:parameters[@"clientp12"] - ofType:@"p12"]; - - NSArray *myCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; - if (!myCerts) { - XCTFail(@"invalid p12 file"); - continue; - } - self.session = [[MQTTSession alloc] initWithClientId:nil userName:parameters[@"user"] password:parameters[@"pass"] @@ -845,8 +921,8 @@ - (void)test_client_certificate { protocolLevel:4 runLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes - securityPolicy:nil - certificates:myCerts]; + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; [self.session subscribeTopic:TOPIC]; @@ -865,26 +941,7 @@ - (void)test_pinned_certificate { for (NSString *broker in BROKERLIST) { NSLog(@"testing broker %@", broker); NSDictionary *parameters = BROKERS[broker]; - if (!parameters[@"serverCER"]) continue; - NSString *path = [[NSBundle bundleForClass:[MQTTClientTests class]] pathForResource:parameters[@"serverCER"] - ofType:@"cer"]; - if (!path) { - XCTFail(@"cer file not found"); - continue; - } - - NSData *certificateData = [NSData dataWithContentsOfFile:path]; - if (!certificateData) { - XCTFail(@"error reading cer file"); - continue; - } - - MQTTSSLSecurityPolicy *secpol = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; - secpol.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; - secpol.validatesCertificateChain = NO; - secpol.allowInvalidCertificates = TRUE; - self.session = [[MQTTSession alloc] initWithClientId:nil userName:parameters[@"user"] password:parameters[@"pass"] @@ -898,8 +955,8 @@ - (void)test_pinned_certificate { protocolLevel:4 runLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes - securityPolicy:secpol - certificates:nil]; + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.persistence.persistent = PERSISTENT; [self connect:self.session parameters:parameters]; [self.session subscribeTopic:TOPIC]; @@ -913,6 +970,46 @@ - (void)test_pinned_certificate { #pragma mark helpers +- (NSArray *)clientCerts:(NSDictionary *)parameters { + NSArray *clientCerts = nil; + if (parameters[@"clientp12"] && parameters[@"clientp12pass"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTClientTests class]] pathForResource:parameters[@"clientp12"] + ofType:@"p12"]; + + clientCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; + if (!clientCerts) { + XCTFail(@"invalid p12 file"); + } + } + return clientCerts; +} + +- (MQTTSSLSecurityPolicy *)securityPolicy:(NSDictionary *)parameters { + MQTTSSLSecurityPolicy *securityPolicy = nil; + + if (parameters[@"serverCER"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTClientTests class]] pathForResource:parameters[@"serverCER"] + ofType:@"cer"]; + if (path) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + if (certificateData) { + securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; + securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; + securityPolicy.validatesCertificateChain = FALSE; + securityPolicy.allowInvalidCertificates = TRUE; + securityPolicy.validatesDomainName = FALSE; + } else { + XCTFail(@"error reading cer file"); + } + } else { + XCTFail(@"cer file not found"); + } + } + return securityPolicy; +} + - (void)no_cleansession:(MQTTQosLevel)qos { for (NSString *broker in BROKERLIST) { NSLog(@"testing broker %@", broker); diff --git a/MQTTClient/MQTTClientTests/MQTTSessionManagerTests.m b/MQTTClient/MQTTClientTests/MQTTSessionManagerTests.m index e876ad58..e2e52eb4 100644 --- a/MQTTClient/MQTTClientTests/MQTTSessionManagerTests.m +++ b/MQTTClient/MQTTClientTests/MQTTSessionManagerTests.m @@ -65,7 +65,9 @@ - (void)testMQTTSessionManager:(BOOL)clean { willMsg:nil willQos:MQTTQosLevelAtMostOnce willRetainFlag:FALSE - withClientId:@"MQTTSessionManager"]; + withClientId:@"MQTTSessionManager" + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; while (self.step == -1 && manager.state != MQTTSessionManagerStateConnected) { NSLog(@"waiting for connect %d", manager.state); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; @@ -164,7 +166,9 @@ - (void)testMQTTSessionManagerPersistent { willMsg:nil willQos:MQTTQosLevelAtMostOnce willRetainFlag:FALSE - withClientId:@"MQTTSessionManager"]; + withClientId:@"MQTTSessionManager" + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; while (self.step == -1 && manager.state != MQTTSessionManagerStateConnected) { NSLog(@"waiting for connect %d", manager.state); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; @@ -215,5 +219,46 @@ - (void)testMQTTSessionManagerPersistent { } } +- (NSArray *)clientCerts:(NSDictionary *)parameters { + NSArray *clientCerts = nil; + if (parameters[@"clientp12"] && parameters[@"clientp12pass"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTSessionManagerTests class]] pathForResource:parameters[@"clientp12"] + ofType:@"p12"]; + + clientCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; + if (!clientCerts) { + XCTFail(@"invalid p12 file"); + } + } + return clientCerts; +} + +- (MQTTSSLSecurityPolicy *)securityPolicy:(NSDictionary *)parameters { + MQTTSSLSecurityPolicy *securityPolicy = nil; + + if (parameters[@"serverCER"]) { + + NSString *path = [[NSBundle bundleForClass:[MQTTSessionManagerTests class]] pathForResource:parameters[@"serverCER"] + ofType:@"cer"]; + if (path) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + if (certificateData) { + securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; + securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; + securityPolicy.validatesCertificateChain = TRUE; + securityPolicy.allowInvalidCertificates = FALSE; + securityPolicy.validatesDomainName = TRUE; + } else { + XCTFail(@"error reading cer file"); + } + } else { + XCTFail(@"cer file not found"); + } + } + return securityPolicy; +} + + @end diff --git a/MQTTClient/MQTTClientTests/MultiThreadingTests.m b/MQTTClient/MQTTClientTests/MultiThreadingTests.m index ceb11826..66f12356 100644 --- a/MQTTClient/MQTTClientTests/MultiThreadingTests.m +++ b/MQTTClient/MQTTClientTests/MultiThreadingTests.m @@ -35,7 +35,9 @@ - (id)setup:(NSDictionary *)parameters willRetainFlag:NO protocolLevel:[parameters[@"protocollevel"] intValue] runLoop:[NSRunLoop currentRunLoop] - forMode:NSRunLoopCommonModes]; + forMode:NSRunLoopCommonModes + securityPolicy:[self securityPolicy:parameters] + certificates:[self clientCerts:parameters]]; self.session.delegate = self; self.session.persistence.persistent = PERSISTENT; @@ -120,6 +122,42 @@ - (void)handleEvent:(MQTTSession *)session event:(MQTTSessionEvent)eventCode err self.error = error; } +- (NSArray *)clientCerts:(NSDictionary *)parameters { + NSArray *clientCerts = nil; + if (parameters[@"clientp12"] && parameters[@"clientp12pass"]) { + + NSString *path = [[NSBundle bundleForClass:[OneTest class]] pathForResource:parameters[@"clientp12"] + ofType:@"p12"]; + + clientCerts = [MQTTSession clientCertsFromP12:path passphrase:parameters[@"clientp12pass"]]; + } + return clientCerts; +} + +- (MQTTSSLSecurityPolicy *)securityPolicy:(NSDictionary *)parameters { + MQTTSSLSecurityPolicy *securityPolicy = nil; + + if (parameters[@"serverCER"]) { + + NSString *path = [[NSBundle bundleForClass:[OneTest class]] pathForResource:parameters[@"serverCER"] + ofType:@"cer"]; + if (path) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + if (certificateData) { + securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeCertificate]; + securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:certificateData, nil]; + securityPolicy.validatesCertificateChain = TRUE; + securityPolicy.allowInvalidCertificates = FALSE; + securityPolicy.validatesDomainName = TRUE; + } + } + } + return securityPolicy; +} + + + + @end @interface MultiThreadingTests : XCTestCase diff --git a/MQTTClient/MQTTClientTests/Resources/info@owntracks.org.p12 b/MQTTClient/MQTTClientTests/Resources/info@owntracks.org.p12 deleted file mode 100644 index 33fc003f..00000000 Binary files a/MQTTClient/MQTTClientTests/Resources/info@owntracks.org.p12 and /dev/null differ diff --git a/README.md b/README.md index dc176b63..fddb6b88 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ an Objective-C native MQTT Framework http://mqtt.org * ActiveMQ * Apollo * CloudMQTT +* aws ### Howto