Modernize the code a little
This commit is contained in:
parent
c428df9b60
commit
cd3d39a9c2
8 changed files with 125 additions and 51 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Reference in a new issue