Index: src/SSLInvalidCertificateException.h ================================================================== --- src/SSLInvalidCertificateException.h +++ src/SSLInvalidCertificateException.h @@ -1,7 +1,8 @@ /* * Copyright (c) 2011, Florian Zeitz + * Copyright (c) 2013, Jonathan Schleifer * * https://webkeks.org/git/?p=objopenssl.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,11 +24,11 @@ #import #import @interface SSLInvalidCertificateException: OFException { - OFString *reason; + OFString *_reason; } #ifdef OF_HAVE_PROPERTIES @property (readonly, assign) OFString *reason; #endif Index: src/SSLInvalidCertificateException.m ================================================================== --- src/SSLInvalidCertificateException.m +++ src/SSLInvalidCertificateException.m @@ -1,7 +1,8 @@ /* * Copyright (c) 2011, Florian Zeitz + * Copyright (c) 2013, Jonathan Schleifer * * https://webkeks.org/git/?p=objopenssl.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,36 +20,38 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "SSLInvalidCertificateException.h" + +#import #import @implementation SSLInvalidCertificateException -+ exceptionWithClass: (Class)class_ - reason: (OFString*)reason_ -{ - return [[[self alloc] initWithClass: class_ - reason: reason_] autorelease]; -} - -- initWithClass: (Class)class_ ++ exceptionWithClass: (Class)class + reason: (OFString*)reason +{ + return [[[self alloc] initWithClass: class + reason: reason] autorelease]; +} + +- initWithClass: (Class)class { Class c = [self class]; [self release]; @throw [OFNotImplementedException exceptionWithClass: c selector: _cmd]; } -- initWithClass: (Class)class_ - reason: (OFString*)reason_ +- initWithClass: (Class)class + reason: (OFString*)reason { - self = [super initWithClass: class_]; + self = [super initWithClass: class]; @try { - reason = [reason_ copy]; + _reason = [reason copy]; } @catch (id e) { [self release]; @throw e; } @@ -55,26 +58,26 @@ return self; } - (void)dealloc { - [reason release]; + [_reason release]; [super dealloc]; } - (OFString*)description { - if (description != nil) - return description; + if (_description != nil) + return _description; - description = [[OFString alloc] initWithFormat: - @"Invalid certificate! Reason: %@", reason]; + _description = [[OFString alloc] initWithFormat: + @"Invalid certificate! Reason: %@", _reason]; - return description; + return _description; } - (OFString*)reason { - return reason; + OF_GETTER(_reason, NO) } @end Index: src/SSLSocket.h ================================================================== --- src/SSLSocket.h +++ src/SSLSocket.h @@ -27,19 +27,17 @@ @class X509Certificate; @interface SSLSocket: OFTCPSocket { - SSL *ssl; - OFString *privateKeyFile; - OFString *certificateFile; - BOOL requestsClientCertificates; + SSL *_SSL; + OFString *_privateKeyFile, *_certificateFile; + BOOL _requestsClientCertificates; } #ifdef OF_HAVE_PROPERTIES -@property (copy) OFString *privateKeyFile; -@property (copy) OFString *certificateFile; +@property (copy) OFString *privateKeyFile, *certificateFile; @property BOOL requestsClientCertificates; #endif - initWithSocket: (OFTCPSocket*)socket; - initWithSocket: (OFTCPSocket*)socket Index: src/SSLSocket.m ================================================================== --- src/SSLSocket.m +++ src/SSLSocket.m @@ -119,41 +119,42 @@ privateKeyFile: nil certificateFile: nil]; } - initWithSocket: (OFTCPSocket*)socket - privateKeyFile: (OFString*)privateKeyFile_ - certificateFile: (OFString*)certificateFile_ + privateKeyFile: (OFString*)privateKeyFile + certificateFile: (OFString*)certificateFile { self = [self init]; @try { /* FIXME: Also allow with accepted sockets */ - privateKeyFile = [privateKeyFile_ copy]; - certificateFile = [certificateFile_ copy]; - - sock = dup(socket->sock); - - if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { - close(sock); - sock = INVALID_SOCKET; + _privateKeyFile = [privateKeyFile copy]; + _certificateFile = [certificateFile copy]; + + _socket = dup(socket->_socket); + + if ((_SSL = SSL_new(ctx)) == NULL || + !SSL_set_fd(_SSL, _socket)) { + close(_socket); + _socket = INVALID_SOCKET; @throw [OFInitializationFailedException exceptionWithClass: [self class]]; } - SSL_set_connect_state(ssl); - - if ((privateKeyFile != nil && !SSL_use_PrivateKey_file(ssl, - [privateKeyFile cStringWithEncoding: - OF_STRING_ENCODING_NATIVE], SSL_FILETYPE_PEM)) || - (certificateFile != nil && !SSL_use_certificate_file(ssl, - [certificateFile cStringWithEncoding: - OF_STRING_ENCODING_NATIVE], SSL_FILETYPE_PEM)) || - SSL_connect(ssl) != 1) { - close(sock); - sock = INVALID_SOCKET; + SSL_set_connect_state(_SSL); + + if ((_privateKeyFile != nil && !SSL_use_PrivateKey_file(_SSL, + [_privateKeyFile cStringWithEncoding: + OF_STRING_ENCODING_NATIVE], SSL_FILETYPE_PEM)) || + (_certificateFile != nil && !SSL_use_certificate_file(_SSL, + [_certificateFile cStringWithEncoding: + OF_STRING_ENCODING_NATIVE], SSL_FILETYPE_PEM)) || + SSL_connect(_SSL) != 1) { + close(_socket); + _socket = INVALID_SOCKET; @throw [OFInitializationFailedException exceptionWithClass: [self class]]; } } @catch (id e) { [self release]; @@ -163,44 +164,44 @@ return self; } - (void)dealloc { - SSL *ssl_ = ssl; + SSL *SSL_ = _SSL; - [privateKeyFile release]; - [certificateFile release]; + [_privateKeyFile release]; + [_certificateFile release]; [super dealloc]; - if (ssl_ != NULL) - SSL_free(ssl_); + if (SSL_ != NULL) + SSL_free(SSL_); } - (void)connectToHost: (OFString*)host port: (uint16_t)port { [super connectToHost: host port: port]; - if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { + if ((_SSL = SSL_new(ctx)) == NULL || !SSL_set_fd(_SSL, _socket)) { [super close]; @throw [OFConnectionFailedException exceptionWithClass: [self class] socket: self host: host port: port]; } - SSL_set_connect_state(ssl); + SSL_set_connect_state(_SSL); - if ((privateKeyFile != nil && !SSL_use_PrivateKey_file(ssl, - [privateKeyFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - SSL_FILETYPE_PEM)) || (certificateFile != nil && - !SSL_use_certificate_file(ssl, [certificateFile + if ((_privateKeyFile != nil && !SSL_use_PrivateKey_file(_SSL, + [_privateKeyFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + SSL_FILETYPE_PEM)) || (_certificateFile != nil && + !SSL_use_certificate_file(_SSL, [_certificateFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - SSL_FILETYPE_PEM)) || SSL_connect(ssl) != 1) { + SSL_FILETYPE_PEM)) || SSL_connect(_SSL) != 1) { [super close]; @throw [OFConnectionFailedException exceptionWithClass: [self class] socket: self host: host @@ -208,49 +209,49 @@ } } - (SSLSocket*)accept { - SSLSocket *newSocket = (SSLSocket*)[super accept]; - - if ((newSocket->ssl = SSL_new(ctx)) == NULL || - !SSL_set_fd(newSocket->ssl, newSocket->sock)) { - /* We only want to close the OFTCPSocket */ - object_setClass(newSocket, [OFTCPSocket class]); - [newSocket close]; - object_setClass(newSocket, object_getClass(self)); - - @throw [OFAcceptFailedException exceptionWithClass: [self class] - socket: self]; - } - - if (requestsClientCertificates) - SSL_set_verify(newSocket->ssl, SSL_VERIFY_PEER, NULL); - - SSL_set_accept_state(newSocket->ssl); - - if (!SSL_use_PrivateKey_file(newSocket->ssl, [privateKeyFile - cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - SSL_FILETYPE_PEM) || !SSL_use_certificate_file(newSocket->ssl, - [certificateFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE], - SSL_FILETYPE_PEM) || SSL_accept(newSocket->ssl) != 1) { - /* We only want to close the OFTCPSocket */ - object_setClass(newSocket, [OFTCPSocket class]); - [newSocket close]; - object_setClass(newSocket, object_getClass(self)); - - @throw [OFAcceptFailedException exceptionWithClass: [self class] - socket: self]; - } - - return newSocket; -} - -- (void)close -{ - if (ssl != NULL) - SSL_shutdown(ssl); + SSLSocket *client = (SSLSocket*)[super accept]; + + if ((client->_SSL = SSL_new(ctx)) == NULL || + !SSL_set_fd(client->_SSL, client->_socket)) { + /* We only want to close the OFTCPSocket */ + object_setClass(client, [OFTCPSocket class]); + [client close]; + object_setClass(client, object_getClass(self)); + + @throw [OFAcceptFailedException exceptionWithClass: [self class] + socket: self]; + } + + if (_requestsClientCertificates) + SSL_set_verify(client->_SSL, SSL_VERIFY_PEER, NULL); + + SSL_set_accept_state(client->_SSL); + + if (!SSL_use_PrivateKey_file(client->_SSL, [_privateKeyFile + cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + SSL_FILETYPE_PEM) || !SSL_use_certificate_file(client->_SSL, + [_certificateFile cStringWithEncoding: OF_STRING_ENCODING_NATIVE], + SSL_FILETYPE_PEM) || SSL_accept(client->_SSL) != 1) { + /* We only want to close the OFTCPSocket */ + object_setClass(client, [OFTCPSocket class]); + [client close]; + object_setClass(client, object_getClass(self)); + + @throw [OFAcceptFailedException exceptionWithClass: [self class] + socket: self]; + } + + return client; +} + +- (void)close +{ + if (_SSL != NULL) + SSL_shutdown(_SSL); [super close]; } - (size_t)lowlevelReadIntoBuffer: (void*)buffer @@ -259,40 +260,40 @@ ssize_t ret; if (length > INT_MAX) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; - if (sock == INVALID_SOCKET) + if (_socket == INVALID_SOCKET) @throw [OFNotConnectedException exceptionWithClass: [self class] socket: self]; - if (atEndOfStream) { + if (_atEndOfStream) { OFReadFailedException *e; e = [OFReadFailedException exceptionWithClass: [self class] stream: self requestedLength: length]; #ifndef _WIN32 - e->errNo = ENOTCONN; + e->_errNo = ENOTCONN; #else - e->errNo = WSAENOTCONN; + e->_errNo = WSAENOTCONN; #endif @throw e; } - if ((ret = SSL_read(ssl, buffer, (int)length)) < 0) { - if (SSL_get_error(ssl, ret) == SSL_ERROR_WANT_READ) + if ((ret = SSL_read(_SSL, buffer, (int)length)) < 0) { + if (SSL_get_error(_SSL, ret) == SSL_ERROR_WANT_READ) return 0; @throw [OFReadFailedException exceptionWithClass: [self class] stream: self requestedLength: length]; } if (ret == 0) - atEndOfStream = YES; + _atEndOfStream = YES; return ret; } - (void)lowlevelWriteBuffer: (const void*)buffer @@ -299,72 +300,72 @@ length: (size_t)length { if (length > INT_MAX) @throw [OFOutOfRangeException exceptionWithClass: [self class]]; - if (sock == INVALID_SOCKET) + if (_socket == INVALID_SOCKET) @throw [OFNotConnectedException exceptionWithClass: [self class] socket: self]; - if (atEndOfStream) { + if (_atEndOfStream) { OFWriteFailedException *e; e = [OFWriteFailedException exceptionWithClass: [self class] stream: self requestedLength: length]; #ifndef _WIN32 - e->errNo = ENOTCONN; + e->_errNo = ENOTCONN; #else - e->errNo = WSAENOTCONN; + e->_errNo = WSAENOTCONN; #endif @throw e; } - if (SSL_write(ssl, buffer, (int)length) < length) + if (SSL_write(_SSL, buffer, (int)length) < length) @throw [OFWriteFailedException exceptionWithClass: [self class] stream: self requestedLength: length]; } - (size_t)pendingBytes { - if (ssl == NULL) + if (_SSL == NULL) return [super pendingBytes]; - return [super pendingBytes] + SSL_pending(ssl); + return [super pendingBytes] + SSL_pending(_SSL); } -- (void)setPrivateKeyFile: (OFString*)file +- (void)setPrivateKeyFile: (OFString*)privateKeyFile { - OF_SETTER(privateKeyFile, file, YES, YES) + OF_SETTER(_privateKeyFile, privateKeyFile, YES, YES) } - (OFString*)privateKeyFile { - OF_GETTER(privateKeyFile, YES) + OF_GETTER(_privateKeyFile, YES) } -- (void)setCertificateFile: (OFString*)file +- (void)setCertificateFile: (OFString*)certificateFile { - OF_SETTER(certificateFile, file, YES, YES) + OF_SETTER(_certificateFile, certificateFile, YES, YES) } - (OFString*)certificateFile { - OF_GETTER(certificateFile, YES) + OF_GETTER(_certificateFile, YES) } - (void)setRequestsClientCertificates: (BOOL)enabled { - requestsClientCertificates = enabled; + _requestsClientCertificates = enabled; } - (BOOL)requestsClientCertificates { - return requestsClientCertificates; + return _requestsClientCertificates; } - (OFDataArray*)channelBindingDataWithType: (OFString*)type { size_t length; @@ -374,19 +375,19 @@ if (![type isEqual: @"tls-unique"]) @throw [OFInvalidArgumentException exceptionWithClass: [self class] selector: _cmd]; - if (SSL_session_reused(ssl) ^ !listening) { + if (SSL_session_reused(_SSL) ^ !_listening) { /* * We are either client or the session has been resumed * => we have sent the finished message */ - length = SSL_get_finished(ssl, buffer, 64); + length = SSL_get_finished(_SSL, buffer, 64); } else { /* peer sent the finished message */ - length = SSL_get_peer_finished(ssl, buffer, 64); + length = SSL_get_peer_finished(_SSL, buffer, 64); } data = [OFDataArray dataArray]; [data addItems: buffer count: length]; @@ -394,11 +395,11 @@ return data; } - (X509Certificate*)peerCertificate { - X509 *certificate = SSL_get_peer_certificate(ssl); + X509 *certificate = SSL_get_peer_certificate(_SSL); if (!certificate) return nil; return [[[X509Certificate alloc] @@ -407,12 +408,12 @@ - (void)verifyPeerCertificate { unsigned long ret; - if (SSL_get_peer_certificate(ssl) != NULL) { - if ((ret = SSL_get_verify_result(ssl)) != X509_V_OK) { + if (SSL_get_peer_certificate(_SSL) != NULL) { + if ((ret = SSL_get_verify_result(_SSL)) != X509_V_OK) { const char *tmp = X509_verify_cert_error_string(ret); OFString *reason = [OFString stringWithUTF8String: tmp]; @throw [SSLInvalidCertificateException exceptionWithClass: [self class] reason: reason]; Index: src/X509Certificate.h ================================================================== --- src/X509Certificate.h +++ src/X509Certificate.h @@ -1,7 +1,8 @@ /* * Copyright (c) 2011, Florian Zeitz + * Copyright (c) 2013, Jonathan Schleifer * * https://webkeks.org/git/?p=objopenssl.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -40,22 +41,22 @@ #define OID_SRVName @"1.3.6.1.5.5.7.8.7" @interface X509OID: OFObject { - OFString *string; + OFString *_string; } -- initWithUTF8String: (const char*)str; +- initWithUTF8String: (const char*)string; @end @interface X509Certificate: OFObject { - X509 *crt; - OFDictionary *issuer; - OFDictionary *subject; - OFDictionary *subjectAlternativeName; + X509 *_certificate; + OFDictionary *_issuer; + OFDictionary *_subject; + OFDictionary *_subjectAlternativeName; } #ifdef OF_HAVE_PROPERTIES @property (readonly) OFDictionary *issuer, *subject, *subjectAlternativeName; #endif Index: src/X509Certificate.m ================================================================== --- src/X509Certificate.m +++ src/X509Certificate.m @@ -1,8 +1,8 @@ /* * Copyright (c) 2011, Florian Zeitz - * Copyright (c) 2011, Jonathan Schleifer + * Copyright (c) 2011, 2013, Jonathan Schleifer * * https://webkeks.org/git/?p=objopenssl.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -38,41 +38,41 @@ #import #import @implementation X509Certificate -- initWithFile: (OFString*)file +- initWithFile: (OFString*)path { self = [self init]; @try { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFFile *fd = [OFFile fileWithPath: file - mode: @"r"]; - OFDataArray *data = [fd readDataArrayTillEndOfStream]; - [fd close]; + OFDataArray *data = [OFDataArray + dataArrayWithContentsOfFile: path]; const unsigned char *dataCArray = [data items]; - crt = d2i_X509(NULL, &dataCArray, [data count]); - [pool release]; - if (crt == NULL) + + _certificate = d2i_X509(NULL, &dataCArray, [data count]); + if (_certificate == NULL) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; + + [pool release]; } @catch (id e) { [self release]; @throw e; } return self; } -- initWithX509Struct: (X509*)cert +- initWithX509Struct: (X509*)certificate { self = [self init]; @try { - crt = X509_dup(cert); - if (crt == NULL) + _certificate = X509_dup(certificate); + if (_certificate == NULL) @throw [OFInitializationFailedException exceptionWithClass: [self class]]; } @catch (id e) { [self release]; @throw e; @@ -81,16 +81,16 @@ return self; } - (void)dealloc { - [issuer release]; - [subject release]; - [subjectAlternativeName release]; + [_issuer release]; + [_subject release]; + [_subjectAlternativeName release]; - if (crt != NULL) - X509_free(crt); + if (_certificate != NULL) + X509_free(_certificate); [super dealloc]; } - (OFString*)description @@ -107,51 +107,52 @@ - (OFDictionary*)issuer { X509_NAME *name; - if (issuer != nil) - return [[issuer copy] autorelease]; + if (_issuer != nil) + return [[_issuer copy] autorelease]; - name = X509_get_issuer_name(crt); - issuer = [[self X509_dictionaryFromX509Name: name] retain]; + name = X509_get_issuer_name(_certificate); + _issuer = [[self X509_dictionaryFromX509Name: name] retain]; - return issuer; + return _issuer; } - (OFDictionary*)subject { X509_NAME *name; - if (subject != nil) - return [[subject copy] autorelease]; + if (_subject != nil) + return [[_subject copy] autorelease]; - name = X509_get_subject_name(crt); - subject = [[self X509_dictionaryFromX509Name: name] retain]; + name = X509_get_subject_name(_certificate); + _subject = [[self X509_dictionaryFromX509Name: name] retain]; - return subject; + return _subject; } - (OFDictionary*)subjectAlternativeName { OFAutoreleasePool *pool; OFMutableDictionary *ret; int i; - if (subjectAlternativeName != nil) - return [[subjectAlternativeName copy] autorelease]; + if (_subjectAlternativeName != nil) + return [[_subjectAlternativeName copy] autorelease]; ret = [OFMutableDictionary dictionary]; pool = [[OFAutoreleasePool alloc] init]; i = -1; - while ((i = X509_get_ext_by_NID(crt, NID_subject_alt_name, i)) != -1) { + while ((i = X509_get_ext_by_NID(_certificate, + NID_subject_alt_name, i)) != -1) { X509_EXTENSION *extension; STACK_OF(GENERAL_NAME) *values; int j, count; - if ((extension = X509_get_ext(crt, i)) == NULL) + if ((extension = X509_get_ext(_certificate, i)) == NULL) break; if ((values = X509V3_EXT_d2i(extension)) == NULL) break; @@ -246,11 +247,11 @@ } [pool release]; [ret makeImmutable]; - subjectAlternativeName = [ret retain]; + _subjectAlternativeName = [ret retain]; return ret; } - (BOOL)hasCommonNameMatchingDomain: (OFString*)domain @@ -432,16 +433,16 @@ return ret; } @end @implementation X509OID -- initWithUTF8String: (const char*) str +- initWithUTF8String: (const char*)string { self = [self init]; @try { - string = [[OFString alloc] initWithUTF8String: str]; + _string = [[OFString alloc] initWithUTF8String: string]; } @catch (id e) { [self release]; @throw e; } @@ -448,35 +449,35 @@ return self; } - (void)dealloc { - [string release]; + [_string release]; [super dealloc]; } - (OFString*)description { char tmp[1024]; - OBJ_obj2txt(tmp, sizeof(tmp), OBJ_txt2obj([string UTF8String], 1), 0); + OBJ_obj2txt(tmp, sizeof(tmp), OBJ_txt2obj([_string UTF8String], 1), 0); return [OFString stringWithUTF8String: tmp]; } - (BOOL)isEqual: (id)object { if (([object isKindOfClass: [OFString class]]) || ([object isKindOfClass: [X509OID class]])) - return [object isEqual: string]; + return [object isEqual: _string]; return NO; } - (uint32_t)hash { - return [string hash]; + return [_string hash]; } - copy { return [self retain]; } @end