Alternative approach to disabling certificate pinning

This commit is contained in:
Chris Ballinger 2019-05-15 20:06:12 -07:00
parent f2a5de13d5
commit e4a46fd74e
7 changed files with 34 additions and 45 deletions

View File

@ -107,8 +107,8 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
#pragma mark Private #pragma mark Private
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (OTRXMPPStream*) newStream { - (XMPPStream*) newStream {
return [[OTRXMPPStream alloc] init]; return [[XMPPStream alloc] init];
} }
- (void)setupStream - (void)setupStream
@ -121,7 +121,9 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
self.xmppStream.tag = self.account.uniqueId; self.xmppStream.tag = self.account.uniqueId;
self.xmppStream.startTLSPolicy = XMPPStreamStartTLSPolicyRequired; self.xmppStream.startTLSPolicy = XMPPStreamStartTLSPolicyRequired;
[self.certificatePinningModule activate:self.xmppStream]; if (self.account.certificatePinning) {
[self.certificatePinningModule activate:self.xmppStream];
}
_deliveryReceipts = [[XMPPMessageDeliveryReceipts alloc] init]; _deliveryReceipts = [[XMPPMessageDeliveryReceipts alloc] init];
// We want to check if OTR messages can be decrypted // We want to check if OTR messages can be decrypted
@ -458,9 +460,6 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
// myJID = @"user@gmail.com/xmppframework"; // myJID = @"user@gmail.com/xmppframework";
// myPassword = @""; // myPassword = @"";
NSError * error = nil; NSError * error = nil;
NSString * domainString = [self accountDomainWithError:error]; NSString * domainString = [self accountDomainWithError:error];
if (error) { if (error) {
@ -473,9 +472,6 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
[self.xmppStream setHostPort:self.account.port]; [self.xmppStream setHostPort:self.account.port];
[self.xmppStream setCertificatePinning:self.account.certificatePinning];
error = nil; error = nil;
if (![self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]) if (![self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error])
{ {
@ -786,7 +782,10 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
settings[GCDAsyncSocketSSLProtocolVersionMin] = @(kTLSProtocol1); settings[GCDAsyncSocketSSLProtocolVersionMin] = @(kTLSProtocol1);
settings[GCDAsyncSocketSSLCipherSuites] = [OTRUtilities cipherSuites]; settings[GCDAsyncSocketSSLCipherSuites] = [OTRUtilities cipherSuites];
settings[GCDAsyncSocketManuallyEvaluateTrust] = @(YES);
if (self.account.certificatePinning) {
settings[GCDAsyncSocketManuallyEvaluateTrust] = @(YES);
}
self.loginStatus = OTRLoginStatusSecuring; self.loginStatus = OTRLoginStatusSecuring;
} }
@ -816,8 +815,6 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
{ {
//DDLogWarn(@"%@: %@ %@", THIS_FILE, THIS_METHOD, error); //DDLogWarn(@"%@: %@ %@", THIS_FILE, THIS_METHOD, error);
self.loginStatus = OTRLoginStatusDisconnected;
if (error) if (error)
{ {
DDLogError(@"Disconnected from server %@ with error: %@", self.account.bareJID.domain, error); DDLogError(@"Disconnected from server %@ with error: %@", self.account.bareJID.domain, error);
@ -826,6 +823,8 @@ typedef NS_ENUM(NSInteger, XMPPClientState) {
DDLogError(@"Disconnected from server %@.", self.account.bareJID.domain); DDLogError(@"Disconnected from server %@.", self.account.bareJID.domain);
} }
self.loginStatus = OTRLoginStatusDisconnected;
//Reset buddy info to offline //Reset buddy info to offline
__block NSArray<OTRXMPPBuddy*> *allBuddies = nil; __block NSArray<OTRXMPPBuddy*> *allBuddies = nil;
__block NSArray<OTRXMPPRoom*> *allRooms = nil; __block NSArray<OTRXMPPRoom*> *allRooms = nil;

View File

@ -17,7 +17,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface OTRXMPPManager() <OTRCertificatePinningDelegate> @interface OTRXMPPManager() <OTRCertificatePinningDelegate>
@property (nonatomic, strong, readonly) OTRXMPPStream *xmppStream; @property (nonatomic, strong, readonly) XMPPStream *xmppStream;
@property (nonatomic, strong, readonly) XMPPReconnect *xmppReconnect; @property (nonatomic, strong, readonly) XMPPReconnect *xmppReconnect;
@property (nonatomic, strong, readonly) XMPPvCardTempModule *xmppvCardTempModule; @property (nonatomic, strong, readonly) XMPPvCardTempModule *xmppvCardTempModule;
@property (nonatomic, strong, readonly) XMPPvCardAvatarModule *xmppvCardAvatarModule; @property (nonatomic, strong, readonly) XMPPvCardAvatarModule *xmppvCardAvatarModule;
@ -57,7 +57,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void) connectUserInitiated:(BOOL)userInitiated; - (void) connectUserInitiated:(BOOL)userInitiated;
/** Return a newly allocated stream object. This is overridden in OTRXMPPTorManager to use ProxyXMPPStream instead of OTRXMPPStream */ /** Return a newly allocated stream object. This is overridden in OTRXMPPTorManager to use ProxyXMPPStream instead of OTRXMPPStream */
- (OTRXMPPStream*) newStream; - (XMPPStream*) newStream;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -9,10 +9,10 @@
@import Foundation; @import Foundation;
@import XMPPFramework; @import XMPPFramework;
@interface OTRXMPPStream : XMPPStream //@interface OTRXMPPStream : XMPPStream
//
@property (nonatomic, readonly) BOOL certificatePinning; //@property (nonatomic, readonly) BOOL certificatePinning;
//
- (void)setCertificatePinning:(BOOL)certificatePinning; //- (void)setCertificatePinning:(BOOL)certificatePinning;
//
@end //@end

View File

@ -7,12 +7,12 @@
// //
#import "OTRXMPPStream.h" #import "OTRXMPPStream.h"
//
@implementation OTRXMPPStream //@implementation OTRXMPPStream
//
- (void)setCertificatePinning:(BOOL)certificatePinning //- (void)setCertificatePinning:(BOOL)certificatePinning
{ //{
_certificatePinning = certificatePinning; // _certificatePinning = certificatePinning;
} //}
//
@end //@end

View File

@ -30,7 +30,7 @@
} }
/** Override XMPPStream with XMPPProxyStream */ /** Override XMPPStream with XMPPProxyStream */
- (OTRXMPPStream*) newStream { - (XMPPStream*) newStream {
return [[ProxyXMPPStream alloc] init]; return [[ProxyXMPPStream alloc] init];
} }

View File

@ -9,7 +9,7 @@
#import "OTRXMPPStream.h" #import "OTRXMPPStream.h"
@import ProxyKit; @import ProxyKit;
@interface ProxyXMPPStream : OTRXMPPStream @interface ProxyXMPPStream : XMPPStream
/** /**
* Sets SOCKS proxy host and port * Sets SOCKS proxy host and port

View File

@ -17,7 +17,6 @@
#import "OTRConstants.h" #import "OTRConstants.h"
#import "OTRLog.h" #import "OTRLog.h"
#import "OTRXMPPStream.h"
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -297,19 +296,15 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
**/ **/
#pragma - mark GCDAsyncSockeTDelegate Methods #pragma - mark GCDAsyncSockeTDelegate Methods
- (void)xmppStream:(OTRXMPPStream *)sender didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL))completionHandler - (void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL))completionHandler
{ {
BOOL certificatePinning = sender.certificatePinning;
NSString *hostName = sender.myJID.domain; NSString *hostName = sender.myJID.domain;
// We should have a hostName. If we don't, something is wrong. // We should have a hostName. If we don't, something is wrong.
NSParameterAssert(hostName.length > 0); NSParameterAssert(hostName.length > 0);
if (!hostName.length) { if (!hostName.length) {
completionHandler(NO); completionHandler(NO);
} }
BOOL trusted = NO; BOOL trusted = [self isValidPinnedTrust:trust withHostName:hostName];
if (certificatePinning) {
trusted = [self isValidPinnedTrust:trust withHostName:hostName];
}
if (!trusted) { if (!trusted) {
//Delegate firing off for user to verify with status //Delegate firing off for user to verify with status
SecTrustResultType result; SecTrustResultType result;
@ -317,16 +312,11 @@ static id AFPublicKeyForCertificate(NSData *certificate) {
SecTrustSetPolicies(trust, policy); SecTrustSetPolicies(trust, policy);
OSStatus status = SecTrustEvaluate(trust, &result); OSStatus status = SecTrustEvaluate(trust, &result);
CFRelease(policy); CFRelease(policy);
if (!certificatePinning && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) { if ([self.delegate respondsToSelector:@selector(newTrust:withHostName:systemTrustResult:)] && status == noErr) {
trusted = YES;
} else if ([self.delegate respondsToSelector:@selector(newTrust:withHostName:systemTrustResult:)] && status == noErr) {
[self.delegate newTrust:trust withHostName:hostName systemTrustResult:result]; [self.delegate newTrust:trust withHostName:hostName systemTrustResult:result];
} }
} }
completionHandler(trusted); completionHandler(trusted);
} }
@end @end