Modernize the code a little

This commit is contained in:
Jonathan Schleifer 2017-05-14 02:33:26 +02:00
parent c428df9b60
commit cd3d39a9c2
No known key found for this signature in database
GPG key ID: 28D65178B37F33E3
8 changed files with 125 additions and 51 deletions

View file

@ -22,6 +22,8 @@
#import <ObjFW/OFConnectionFailedException.h> #import <ObjFW/OFConnectionFailedException.h>
OF_ASSUME_NONNULL_BEGIN
@class SSLSocket; @class SSLSocket;
@interface SSLConnectionFailedException: OFConnectionFailedException @interface SSLConnectionFailedException: OFConnectionFailedException
@ -30,9 +32,16 @@
long _verifyResult; long _verifyResult;
} }
@property (readonly) unsigned long SSLError; @property (readonly, nonatomic) unsigned long SSLError;
@property (readonly) long verifyResult; @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 + (instancetype)exceptionWithHost: (OFString *)host
port: (uint16_t)port port: (uint16_t)port
socket: (SSLSocket *)socket socket: (SSLSocket *)socket
@ -42,6 +51,13 @@
socket: (SSLSocket *)socket socket: (SSLSocket *)socket
SSLError: (unsigned long)SSLError SSLError: (unsigned long)SSLError
verifyResult: (long)verifyResult; 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 - initWithHost: (OFString *)host
port: (uint16_t)port port: (uint16_t)port
socket: (SSLSocket *)socket socket: (SSLSocket *)socket
@ -50,5 +66,7 @@
port: (uint16_t)port port: (uint16_t)port
socket: (SSLSocket *)socket socket: (SSLSocket *)socket
SSLError: (unsigned long)SSLError SSLError: (unsigned long)SSLError
verifyResult: (long)verifyResult; verifyResult: (long)verifyResult OF_DESIGNATED_INITIALIZER;
@end @end
OF_ASSUME_NONNULL_END

View file

@ -42,6 +42,21 @@
@implementation SSLConnectionFailedException @implementation SSLConnectionFailedException
@synthesize SSLError = _SSLError, verifyResult = _verifyResult; @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 + (instancetype)exceptionWithHost: (OFString *)host
port: (uint16_t)port port: (uint16_t)port
socket: (SSLSocket *)socket socket: (SSLSocket *)socket
@ -67,18 +82,31 @@
verifyResult: verifyResult] autorelease]; 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 - initWithHost: (OFString *)host
port: (uint16_t)port port: (uint16_t)port
socket: (SSLSocket *)socket socket: (SSLSocket *)socket
SSLError: (unsigned long)SSLError SSLError: (unsigned long)SSLError
{ {
self = [super initWithHost: host return [self initWithHost: host
port: port port: port
socket: socket]; socket: socket
SSLError: SSLError
_SSLError = SSLError; verifyResult: 0];
return self;
} }
- initWithHost: (OFString *)host - initWithHost: (OFString *)host

View file

@ -24,6 +24,8 @@
#import <ObjFW/OFString.h> #import <ObjFW/OFString.h>
#import <ObjFW/OFException.h> #import <ObjFW/OFException.h>
OF_ASSUME_NONNULL_BEGIN
@interface SSLInvalidCertificateException: OFException @interface SSLInvalidCertificateException: OFException
{ {
OFString *_reason; OFString *_reason;
@ -31,6 +33,10 @@
@property (readonly, nonatomic) OFString *reason; @property (readonly, nonatomic) OFString *reason;
+ exceptionWithReason: (OFString *)reason; + (instancetype)exception;
- initWithReason: (OFString *)reason; + (instancetype)exceptionWithReason: (OFString *)reason;
- init OF_UNAVAILABLE;
- initWithReason: (OFString *)reason OF_DESIGNATED_INITIALIZER;
@end @end
OF_ASSUME_NONNULL_END

View file

@ -30,21 +30,19 @@
@implementation SSLInvalidCertificateException @implementation SSLInvalidCertificateException
@synthesize reason = _reason; @synthesize reason = _reason;
+ exceptionWithReason: (OFString *)reason + (instancetype)exception
{
OF_UNRECOGNIZED_SELECTOR
}
+ (instancetype)exceptionWithReason: (OFString *)reason
{ {
return [[[self alloc] initWithReason: reason] autorelease]; return [[[self alloc] initWithReason: reason] autorelease];
} }
- init - init
{ {
@try { OF_INVALID_INIT_METHOD
[self doesNotRecognizeSelector: _cmd];
} @catch (id e) {
[self release];
@throw e;
}
abort();
} }
- initWithReason: (OFString *)reason - initWithReason: (OFString *)reason

View file

@ -26,6 +26,8 @@
#import <ObjFW/OFTCPSocket.h> #import <ObjFW/OFTCPSocket.h>
#import <ObjFW/OFTLSSocket.h> #import <ObjFW/OFTLSSocket.h>
OF_ASSUME_NONNULL_BEGIN
@class X509Certificate; @class X509Certificate;
@interface SSLSocket: OFTCPSocket <OFTLSSocket> @interface SSLSocket: OFTCPSocket <OFTLSSocket>
@ -37,12 +39,14 @@
bool _requestClientCertificatesEnabled; bool _requestClientCertificatesEnabled;
} }
@property (getter=isRequestClientCertificatesEnabled) @property (nonatomic, getter=isRequestClientCertificatesEnabled)
bool requestClientCertificatesEnabled; bool requestClientCertificatesEnabled;
@property OF_NULLABLE_PROPERTY (readonly, nonatomic)
X509Certificate *peerCertificate;
- initWithSocket: (OFTCPSocket *)socket; - initWithSocket: (OFTCPSocket *)socket;
- (void)SSL_super_close;
- (OFDataArray *)channelBindingDataWithType: (OFString *)type; - (OFDataArray *)channelBindingDataWithType: (OFString *)type;
- (X509Certificate *)peerCertificate; - (nullable X509Certificate *)peerCertificate;
- (void)verifyPeerCertificate;
@end @end
OF_ASSUME_NONNULL_END

View file

@ -90,6 +90,10 @@ locking_callback(int mode, int n, const char *file, int line)
of_mutex_unlock(&ssl_mutexes[n]); of_mutex_unlock(&ssl_mutexes[n]);
} }
@interface SSLSocket ()
- (void)SSL_super_close;
@end
@implementation SSLSocket @implementation SSLSocket
@synthesize delegate = _delegate, certificateFile = _certificateFile; @synthesize delegate = _delegate, certificateFile = _certificateFile;
@synthesize privateKeyFile = _privateKeyFile; @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); X509 *certificate = SSL_get_peer_certificate(_SSL);
if (!certificate) if (certificate == NULL)
return nil; return nil;
return [[[X509Certificate alloc] return [[[X509Certificate alloc]

View file

@ -26,7 +26,7 @@
#import <ObjFW/OFObject.h> #import <ObjFW/OFObject.h>
#import <ObjFW/OFString.h> #import <ObjFW/OFString.h>
@class OFDictionary; OF_ASSUME_NONNULL_BEGIN
/* OIDs: */ /* OIDs: */
#define OID_commonName @"2.5.4.3" #define OID_commonName @"2.5.4.3"
@ -41,12 +41,15 @@
#define OID_SRVName @"1.3.6.1.5.5.7.8.7" #define OID_SRVName @"1.3.6.1.5.5.7.8.7"
@class OFDictionary;
@interface X509OID: OFObject <OFCopying> @interface X509OID: OFObject <OFCopying>
{ {
OFString *_string; OFString *_string;
} }
- initWithUTF8String: (const char *)string; - init OF_UNAVAILABLE;
- initWithUTF8String: (const char *)string OF_DESIGNATED_INITIALIZER;
@end @end
@interface X509Certificate: OFObject @interface X509Certificate: OFObject
@ -57,18 +60,17 @@
OFDictionary *_subjectAlternativeName; OFDictionary *_subjectAlternativeName;
} }
@property (readonly, nonatomic) OFDictionary *issuer;
@property (readonly, nonatomic) OFDictionary *subject;
@property (readonly, nonatomic) OFDictionary *subjectAlternateName;
- init OF_UNAVAILABLE;
- initWithFile: (OFString *)file; - initWithFile: (OFString *)file;
- initWithX509Struct: (X509 *)cert; - initWithX509Struct: (X509 *)cert;
- (OFDictionary *)issuer;
- (OFDictionary *)subject;
- (OFDictionary *)subjectAlternativeName;
- (bool)hasCommonNameMatchingDomain: (OFString *)domain; - (bool)hasCommonNameMatchingDomain: (OFString *)domain;
- (bool)hasDNSNameMatchingDomain: (OFString *)domain; - (bool)hasDNSNameMatchingDomain: (OFString *)domain;
- (bool)hasSRVNameMatchingDomain: (OFString *)domain - (bool)hasSRVNameMatchingDomain: (OFString *)domain
service: (OFString *)service; 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 @end
OF_ASSUME_NONNULL_END

View file

@ -48,10 +48,27 @@
#import <ObjFW/macros.h> #import <ObjFW/macros.h>
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 @implementation X509Certificate
- init
{
OF_INVALID_INIT_METHOD
}
- initWithFile: (OFString *)path - initWithFile: (OFString *)path
{ {
self = [self init]; self = [super init];
@try { @try {
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
@ -75,7 +92,7 @@
- initWithX509Struct: (X509 *)certificate - initWithX509Struct: (X509 *)certificate
{ {
self = [self init]; self = [super init];
@try { @try {
_certificate = X509_dup(certificate); _certificate = X509_dup(certificate);
@ -265,12 +282,9 @@
- (bool)hasCommonNameMatchingDomain: (OFString *)domain - (bool)hasCommonNameMatchingDomain: (OFString *)domain
{ {
OFString *name;
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; 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 if ([self X509_isAssertedDomain: name
equalDomain: domain]) { equalDomain: domain]) {
[pool release]; [pool release];
@ -284,13 +298,10 @@
- (bool)hasDNSNameMatchingDomain: (OFString *)domain - (bool)hasDNSNameMatchingDomain: (OFString *)domain
{ {
OFString *name;
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; 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 if ([self X509_isAssertedDomain: name
equalDomain: domain]) { equalDomain: domain]) {
[pool release]; [pool release];
@ -306,12 +317,10 @@
service: (OFString *)service service: (OFString *)service
{ {
size_t serviceLength; size_t serviceLength;
OFString *name;
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
OFDictionary *SANs = [self subjectAlternativeName]; OFDictionary *SANs = [self subjectAlternativeName];
OFList *assertedNames = [[SANs objectForKey: @"otherName"] OFList *assertedNames = [[SANs objectForKey: @"otherName"]
objectForKey: OID_SRVName]; objectForKey: OID_SRVName];
OFEnumerator *enumerator = [assertedNames objectEnumerator];
if (![service hasPrefix: @"_"]) if (![service hasPrefix: @"_"])
service = [service stringByPrependingString: @"_"]; service = [service stringByPrependingString: @"_"];
@ -319,7 +328,7 @@
service = [service stringByAppendingString: @"."]; service = [service stringByAppendingString: @"."];
serviceLength = [service length]; serviceLength = [service length];
while ((name = [enumerator nextObject]) != nil) { for (OFString *name in assertedNames) {
if ([name hasPrefix: service]) { if ([name hasPrefix: service]) {
OFString *asserted; OFString *asserted;
asserted = [name substringWithRange: of_range( asserted = [name substringWithRange: of_range(
@ -443,9 +452,14 @@
@end @end
@implementation X509OID @implementation X509OID
- init
{
OF_INVALID_INIT_METHOD
}
- initWithUTF8String: (const char *)string - initWithUTF8String: (const char *)string
{ {
self = [self init]; self = [super init];
@try { @try {
_string = [[OFString alloc] initWithUTF8String: string]; _string = [[OFString alloc] initWithUTF8String: string];