diff --git a/src/SSLConnectionFailedException.h b/src/SSLConnectionFailedException.h index 31aef4f..07d1fbc 100644 --- a/src/SSLConnectionFailedException.h +++ b/src/SSLConnectionFailedException.h @@ -22,6 +22,8 @@ #import +OF_ASSUME_NONNULL_BEGIN + @class SSLSocket; @interface SSLConnectionFailedException: OFConnectionFailedException @@ -30,9 +32,16 @@ long _verifyResult; } -@property (readonly) unsigned long SSLError; -@property (readonly) long verifyResult; +@property (readonly, nonatomic) unsigned long SSLError; +@property (readonly, nonatomic) long verifyResult; ++ (instancetype)exceptionWithHost: (OFString *)host + port: (uint16_t)port + socket: (id)socket OF_UNAVAILABLE; ++ (instancetype)exceptionWithHost: (OFString *)host + port: (uint16_t)port + socket: (id)socket + errNo: (int)errNo OF_UNAVAILABLE; + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (SSLSocket *)socket @@ -42,6 +51,13 @@ socket: (SSLSocket *)socket SSLError: (unsigned long)SSLError verifyResult: (long)verifyResult; +- initWithHost: (OFString *)host + port: (uint16_t)port + socket: (SSLSocket *)socket OF_UNAVAILABLE; +- initWithHost: (OFString *)host + port: (uint16_t)port + socket: (SSLSocket *)socket + errNo: (int)errNo OF_UNAVAILABLE; - initWithHost: (OFString *)host port: (uint16_t)port socket: (SSLSocket *)socket @@ -50,5 +66,7 @@ port: (uint16_t)port socket: (SSLSocket *)socket SSLError: (unsigned long)SSLError - verifyResult: (long)verifyResult; + verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER; @end + +OF_ASSUME_NONNULL_END diff --git a/src/SSLConnectionFailedException.m b/src/SSLConnectionFailedException.m index 2b78c57..545263f 100644 --- a/src/SSLConnectionFailedException.m +++ b/src/SSLConnectionFailedException.m @@ -42,6 +42,21 @@ @implementation SSLConnectionFailedException @synthesize SSLError = _SSLError, verifyResult = _verifyResult; ++ (instancetype)exceptionWithHost: (OFString *)host + port: (uint16_t)port + socket: (id)socket +{ + OF_UNRECOGNIZED_SELECTOR +} + ++ (instancetype)exceptionWithHost: (OFString *)host + port: (uint16_t)port + socket: (id)socket + errNo: (int)errNo +{ + OF_UNRECOGNIZED_SELECTOR +} + + (instancetype)exceptionWithHost: (OFString *)host port: (uint16_t)port socket: (SSLSocket *)socket @@ -67,18 +82,31 @@ verifyResult: verifyResult] autorelease]; } +- initWithHost: (OFString *)host + port: (uint16_t)port + socket: (id)socket +{ + OF_INVALID_INIT_METHOD +} + +- initWithHost: (OFString *)host + port: (uint16_t)port + socket: (id)socket + errNo: (int)errNo +{ + OF_INVALID_INIT_METHOD +} + - initWithHost: (OFString *)host port: (uint16_t)port socket: (SSLSocket *)socket SSLError: (unsigned long)SSLError { - self = [super initWithHost: host - port: port - socket: socket]; - - _SSLError = SSLError; - - return self; + return [self initWithHost: host + port: port + socket: socket + SSLError: SSLError + verifyResult: 0]; } - initWithHost: (OFString *)host diff --git a/src/SSLInvalidCertificateException.h b/src/SSLInvalidCertificateException.h index d551593..353608e 100644 --- a/src/SSLInvalidCertificateException.h +++ b/src/SSLInvalidCertificateException.h @@ -24,6 +24,8 @@ #import #import +OF_ASSUME_NONNULL_BEGIN + @interface SSLInvalidCertificateException: OFException { OFString *_reason; @@ -31,6 +33,10 @@ @property (readonly, nonatomic) OFString *reason; -+ exceptionWithReason: (OFString *)reason; -- initWithReason: (OFString *)reason; ++ (instancetype)exception; ++ (instancetype)exceptionWithReason: (OFString *)reason; +- init OF_UNAVAILABLE; +- initWithReason: (OFString *)reason OF_DESIGNATED_INITIALIZER; @end + +OF_ASSUME_NONNULL_END diff --git a/src/SSLInvalidCertificateException.m b/src/SSLInvalidCertificateException.m index 4a60a11..00f9a33 100644 --- a/src/SSLInvalidCertificateException.m +++ b/src/SSLInvalidCertificateException.m @@ -30,21 +30,19 @@ @implementation SSLInvalidCertificateException @synthesize reason = _reason; -+ exceptionWithReason: (OFString *)reason ++ (instancetype)exception +{ + OF_UNRECOGNIZED_SELECTOR +} + ++ (instancetype)exceptionWithReason: (OFString *)reason { return [[[self alloc] initWithReason: reason] autorelease]; } - init { - @try { - [self doesNotRecognizeSelector: _cmd]; - } @catch (id e) { - [self release]; - @throw e; - } - - abort(); + OF_INVALID_INIT_METHOD } - initWithReason: (OFString *)reason diff --git a/src/SSLSocket.h b/src/SSLSocket.h index be2939c..d439c0f 100644 --- a/src/SSLSocket.h +++ b/src/SSLSocket.h @@ -26,6 +26,8 @@ #import #import +OF_ASSUME_NONNULL_BEGIN + @class X509Certificate; @interface SSLSocket: OFTCPSocket @@ -37,12 +39,14 @@ bool _requestClientCertificatesEnabled; } -@property (getter=isRequestClientCertificatesEnabled) +@property (nonatomic, getter=isRequestClientCertificatesEnabled) bool requestClientCertificatesEnabled; +@property OF_NULLABLE_PROPERTY (readonly, nonatomic) + X509Certificate *peerCertificate; - initWithSocket: (OFTCPSocket *)socket; -- (void)SSL_super_close; - (OFDataArray *)channelBindingDataWithType: (OFString *)type; -- (X509Certificate *)peerCertificate; -- (void)verifyPeerCertificate; +- (nullable X509Certificate *)peerCertificate; @end + +OF_ASSUME_NONNULL_END diff --git a/src/SSLSocket.m b/src/SSLSocket.m index 49e86a0..ad1533b 100644 --- a/src/SSLSocket.m +++ b/src/SSLSocket.m @@ -90,6 +90,10 @@ locking_callback(int mode, int n, const char *file, int line) of_mutex_unlock(&ssl_mutexes[n]); } +@interface SSLSocket () +- (void)SSL_super_close; +@end + @implementation SSLSocket @synthesize delegate = _delegate, certificateFile = _certificateFile; @synthesize privateKeyFile = _privateKeyFile; @@ -444,7 +448,7 @@ locking_callback(int mode, int n, const char *file, int line) { X509 *certificate = SSL_get_peer_certificate(_SSL); - if (!certificate) + if (certificate == NULL) return nil; return [[[X509Certificate alloc] diff --git a/src/X509Certificate.h b/src/X509Certificate.h index 8df8ec3..73f8893 100644 --- a/src/X509Certificate.h +++ b/src/X509Certificate.h @@ -26,7 +26,7 @@ #import #import -@class OFDictionary; +OF_ASSUME_NONNULL_BEGIN /* OIDs: */ #define OID_commonName @"2.5.4.3" @@ -41,12 +41,15 @@ #define OID_SRVName @"1.3.6.1.5.5.7.8.7" +@class OFDictionary; + @interface X509OID: OFObject { OFString *_string; } -- initWithUTF8String: (const char *)string; +- init OF_UNAVAILABLE; +- initWithUTF8String: (const char *)string OF_DESIGNATED_INITIALIZER; @end @interface X509Certificate: OFObject @@ -57,18 +60,17 @@ OFDictionary *_subjectAlternativeName; } +@property (readonly, nonatomic) OFDictionary *issuer; +@property (readonly, nonatomic) OFDictionary *subject; +@property (readonly, nonatomic) OFDictionary *subjectAlternateName; + +- init OF_UNAVAILABLE; - initWithFile: (OFString *)file; - initWithX509Struct: (X509 *)cert; -- (OFDictionary *)issuer; -- (OFDictionary *)subject; -- (OFDictionary *)subjectAlternativeName; - (bool)hasCommonNameMatchingDomain: (OFString *)domain; - (bool)hasDNSNameMatchingDomain: (OFString *)domain; - (bool)hasSRVNameMatchingDomain: (OFString *)domain service: (OFString *)service; -- (bool)X509_isAssertedDomain: (OFString *)asserted - equalDomain: (OFString *)domain; -- (OFDictionary *)X509_dictionaryFromX509Name: (X509_NAME *)name; -- (X509OID *)X509_stringFromASN1Object: (ASN1_OBJECT *)obj; -- (OFString *)X509_stringFromASN1String: (ASN1_STRING *)str; @end + +OF_ASSUME_NONNULL_END diff --git a/src/X509Certificate.m b/src/X509Certificate.m index bebcaf2..dd9ba7c 100644 --- a/src/X509Certificate.m +++ b/src/X509Certificate.m @@ -48,10 +48,27 @@ #import +OF_ASSUME_NONNULL_BEGIN + +@interface X509Certificate () +- (bool)X509_isAssertedDomain: (OFString *)asserted + equalDomain: (OFString *)domain; +- (OFDictionary *)X509_dictionaryFromX509Name: (X509_NAME *)name; +- (X509OID *)X509_stringFromASN1Object: (ASN1_OBJECT *)obj; +- (OFString *)X509_stringFromASN1String: (ASN1_STRING *)str; +@end + +OF_ASSUME_NONNULL_END + @implementation X509Certificate +- init +{ + OF_INVALID_INIT_METHOD +} + - initWithFile: (OFString *)path { - self = [self init]; + self = [super init]; @try { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; @@ -75,7 +92,7 @@ - initWithX509Struct: (X509 *)certificate { - self = [self init]; + self = [super init]; @try { _certificate = X509_dup(certificate); @@ -265,12 +282,9 @@ - (bool)hasCommonNameMatchingDomain: (OFString *)domain { - OFString *name; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFList *CNs = [[self subject] objectForKey: OID_commonName]; - OFEnumerator *enumerator = [CNs objectEnumerator]; - while ((name = [enumerator nextObject]) != nil) { + for (OFString *name in [[self subject] objectForKey: OID_commonName]) { if ([self X509_isAssertedDomain: name equalDomain: domain]) { [pool release]; @@ -284,13 +298,10 @@ - (bool)hasDNSNameMatchingDomain: (OFString *)domain { - OFString *name; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFDictionary *SANs = [self subjectAlternativeName]; - OFList *assertedNames = [SANs objectForKey: @"dNSName"]; - OFEnumerator *enumerator = [assertedNames objectEnumerator]; - while ((name = [enumerator nextObject]) != nil) { + for (OFString *name in + [[self subjectAlternativeName] objectForKey: @"dNSName"]) { if ([self X509_isAssertedDomain: name equalDomain: domain]) { [pool release]; @@ -306,12 +317,10 @@ service: (OFString *)service { size_t serviceLength; - OFString *name; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFDictionary *SANs = [self subjectAlternativeName]; OFList *assertedNames = [[SANs objectForKey: @"otherName"] objectForKey: OID_SRVName]; - OFEnumerator *enumerator = [assertedNames objectEnumerator]; if (![service hasPrefix: @"_"]) service = [service stringByPrependingString: @"_"]; @@ -319,7 +328,7 @@ service = [service stringByAppendingString: @"."]; serviceLength = [service length]; - while ((name = [enumerator nextObject]) != nil) { + for (OFString *name in assertedNames) { if ([name hasPrefix: service]) { OFString *asserted; asserted = [name substringWithRange: of_range( @@ -443,9 +452,14 @@ @end @implementation X509OID +- init +{ + OF_INVALID_INIT_METHOD +} + - initWithUTF8String: (const char *)string { - self = [self init]; + self = [super init]; @try { _string = [[OFString alloc] initWithUTF8String: string];