Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -1,2 +1,45 @@ +LIB = objopenssl +LIB_MAJOR = 0 +LIB_MINOR = 0 + +CPPFLAGS += -Wall -g +LIBS += -lssl -lcrypto -lz + +includedir = ObjGnuOpenSSL +prefix ?= /usr/local +INSTALL ?= install + +LIB_PREFIX = `objfw-config --lib-prefix` +LIB_SUFFIX = `objfw-config --lib-suffix` +LIB_FILE = ${LIB_PREFIX}${LIB}${LIB_SUFFIX} + +.SILENT: + all: - objfw-compile --lib 0.0 -o objopenssl *.m -lssl -lcrypto -lz -g -Wall + objfw-compile --lib ${LIB_MAJOR}.${LIB_MINOR} ${CPPFLAGS} ${LIBS} \ + -o ${LIB} src/*.m + +install: install-lib install-headers + +install-lib: all + mkdir -p ${destdir}${prefix}/lib + export LIB_MAJOR=${LIB_MAJOR}; \ + export LIB_MINOR=${LIB_MINOR}; \ + echo "Installing ${LIB_FILE}..."; \ + ${INSTALL} -m 755 ${LIB_FILE} ${destdir}${prefix}/lib/${LIB_FILE} + +install-headers: + mkdir -p ${destdir}${prefix}/include/${includedir} + cd src && for i in *.h; do \ + echo "Installing $$i..."; \ + install -m 644 $$i \ + ${destdir}${prefix}/include/${includedir}/$$i; \ + done + +clean: + export LIB_MAJOR=${LIB_MAJOR}; \ + export LIB_MINOR=${LIB_MINOR}; \ + for i in src/*.o ${LIB_FILE}; do \ + echo "Deleting $$i..."; \ + rm -f $$i; \ + done DELETED SSLSocket.h Index: SSLSocket.h ================================================================== --- SSLSocket.h +++ /dev/null @@ -1,16 +0,0 @@ -#include - -#import - -@interface SSLSocket: OFTCPSocket -{ - SSL_CTX *ctx; - SSL *ssl; - BOOL handsShaken; -} - -- initWithSocket: (OFTCPSocket*)socket; - -/* Change the return type */ -- (SSLSocket*)accept; -@end DELETED SSLSocket.m Index: SSLSocket.m ================================================================== --- SSLSocket.m +++ /dev/null @@ -1,223 +0,0 @@ -#include -#include -#include - -#import - -#import "SSLSocket.h" - -#import -#import -#import -#import -#import -#import -#import - -#ifndef INVALID_SOCKET -# define INVALID_SOCKET -1 -#endif - -@implementation SSLSocket -+ (void)load -{ - of_http_request_tls_socket_class = self; -} - -+ (void)initialize -{ - if (self == [SSLSocket class]) - SSL_library_init(); -} - -- init -{ - self = [super init]; - - @try { - if ((ctx = SSL_CTX_new(SSLv23_method())) == NULL) - @throw [OFInitializationFailedException - newWithClass: isa]; - - if ((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & - SSL_OP_NO_SSLv2) == 0) - @throw [OFInitializationFailedException - newWithClass: isa]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- initWithSocket: (OFTCPSocket*)socket -{ - self = [self init]; - - @try { - sock = dup(socket->sock); - - if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { - close(sock); - sock = INVALID_SOCKET; - @throw [OFInitializationFailedException - newWithClass: isa]; - } - - SSL_set_connect_state(ssl); - - if (SSL_connect(ssl) != 1) { - close(sock); - sock = INVALID_SOCKET; - @throw [OFInitializationFailedException - newWithClass: isa]; - } - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (void)dealloc -{ - SSL_CTX *ctx_ = ctx; - SSL *ssl_ = ssl; - - [super dealloc]; - - if (ssl_ != NULL) - SSL_free(ssl_); - if (ctx_ != NULL) - SSL_CTX_free(ctx_); -} - -- (void)connectToHost: (OFString*)host - onPort: (uint16_t)port -{ - [super connectToHost: host - onPort: port]; - - if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { - [super close]; - @throw [OFConnectionFailedException newWithClass: isa - socket: self - host: host - port: port]; - } - - SSL_set_connect_state(ssl); - - if (SSL_connect(ssl) != 1) { - [super close]; - @throw [OFConnectionFailedException newWithClass: isa - socket: self - host: host - port: port]; - } -} - -- (SSLSocket*)accept -{ - SSLSocket *newsock = (SSLSocket*)[super accept]; - - if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { - [super close]; - @throw [OFAcceptFailedException newWithClass: isa - socket: self]; - } - - SSL_set_accept_state(ssl); - - if (SSL_connect(ssl) != 1) { - [super close]; - @throw [OFAcceptFailedException newWithClass: isa - socket: self]; - } - - return newsock; -} - -- (void)close -{ - SSL_shutdown(ssl); - - [super close]; -} - -- (size_t)_readNBytes: (size_t)size - intoBuffer: (char*)buf -{ - ssize_t ret; - - if (size > INT_MAX) - @throw [OFOutOfRangeException newWithClass: isa]; - - if (sock == INVALID_SOCKET) - @throw [OFNotConnectedException newWithClass: isa - socket: self]; - - if (eos) { - OFReadFailedException *e; - - e = [OFReadFailedException newWithClass: isa - stream: self - requestedSize: size]; -#ifndef _WIN32 - e->errNo = ENOTCONN; -#else - e->errNo = WSAENOTCONN; -#endif - - @throw e; - } - - if ((ret = SSL_read(ssl, buf, (int)size)) < 0) - @throw [OFReadFailedException newWithClass: isa - stream: self - requestedSize: size]; - - if (ret == 0) - eos = YES; - - return ret; -} - -- (size_t)_writeNBytes: (size_t)size - fromBuffer: (const char*)buf -{ - ssize_t ret; - - if (size > INT_MAX) - @throw [OFOutOfRangeException newWithClass: isa]; - - if (sock == INVALID_SOCKET) - @throw [OFNotConnectedException newWithClass: isa - socket: self]; - - if (eos) { - OFWriteFailedException *e; - - e = [OFWriteFailedException newWithClass: isa - stream: self - requestedSize: size]; - -#ifndef _WIN32 - e->errNo = ENOTCONN; -#else - e->errNo = WSAENOTCONN; -#endif - - @throw e; - } - - if ((ret = SSL_write(ssl, buf, (int)size)) < 1) - @throw [OFWriteFailedException newWithClass: isa - stream: self - requestedSize: size]; - - return ret; -} -@end ADDED src/SSLSocket.h Index: src/SSLSocket.h ================================================================== --- /dev/null +++ src/SSLSocket.h @@ -0,0 +1,16 @@ +#include + +#import + +@interface SSLSocket: OFTCPSocket +{ + SSL_CTX *ctx; + SSL *ssl; + BOOL handsShaken; +} + +- initWithSocket: (OFTCPSocket*)socket; + +/* Change the return type */ +- (SSLSocket*)accept; +@end ADDED src/SSLSocket.m Index: src/SSLSocket.m ================================================================== --- /dev/null +++ src/SSLSocket.m @@ -0,0 +1,223 @@ +#include +#include +#include + +#import + +#import "SSLSocket.h" + +#import +#import +#import +#import +#import +#import +#import + +#ifndef INVALID_SOCKET +# define INVALID_SOCKET -1 +#endif + +@implementation SSLSocket ++ (void)load +{ + of_http_request_tls_socket_class = self; +} + ++ (void)initialize +{ + if (self == [SSLSocket class]) + SSL_library_init(); +} + +- init +{ + self = [super init]; + + @try { + if ((ctx = SSL_CTX_new(SSLv23_method())) == NULL) + @throw [OFInitializationFailedException + newWithClass: isa]; + + if ((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & + SSL_OP_NO_SSLv2) == 0) + @throw [OFInitializationFailedException + newWithClass: isa]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- initWithSocket: (OFTCPSocket*)socket +{ + self = [self init]; + + @try { + sock = dup(socket->sock); + + if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { + close(sock); + sock = INVALID_SOCKET; + @throw [OFInitializationFailedException + newWithClass: isa]; + } + + SSL_set_connect_state(ssl); + + if (SSL_connect(ssl) != 1) { + close(sock); + sock = INVALID_SOCKET; + @throw [OFInitializationFailedException + newWithClass: isa]; + } + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + SSL_CTX *ctx_ = ctx; + SSL *ssl_ = ssl; + + [super dealloc]; + + if (ssl_ != NULL) + SSL_free(ssl_); + if (ctx_ != NULL) + SSL_CTX_free(ctx_); +} + +- (void)connectToHost: (OFString*)host + onPort: (uint16_t)port +{ + [super connectToHost: host + onPort: port]; + + if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { + [super close]; + @throw [OFConnectionFailedException newWithClass: isa + socket: self + host: host + port: port]; + } + + SSL_set_connect_state(ssl); + + if (SSL_connect(ssl) != 1) { + [super close]; + @throw [OFConnectionFailedException newWithClass: isa + socket: self + host: host + port: port]; + } +} + +- (SSLSocket*)accept +{ + SSLSocket *newsock = (SSLSocket*)[super accept]; + + if ((ssl = SSL_new(ctx)) == NULL || !SSL_set_fd(ssl, sock)) { + [super close]; + @throw [OFAcceptFailedException newWithClass: isa + socket: self]; + } + + SSL_set_accept_state(ssl); + + if (SSL_connect(ssl) != 1) { + [super close]; + @throw [OFAcceptFailedException newWithClass: isa + socket: self]; + } + + return newsock; +} + +- (void)close +{ + SSL_shutdown(ssl); + + [super close]; +} + +- (size_t)_readNBytes: (size_t)size + intoBuffer: (char*)buf +{ + ssize_t ret; + + if (size > INT_MAX) + @throw [OFOutOfRangeException newWithClass: isa]; + + if (sock == INVALID_SOCKET) + @throw [OFNotConnectedException newWithClass: isa + socket: self]; + + if (eos) { + OFReadFailedException *e; + + e = [OFReadFailedException newWithClass: isa + stream: self + requestedSize: size]; +#ifndef _WIN32 + e->errNo = ENOTCONN; +#else + e->errNo = WSAENOTCONN; +#endif + + @throw e; + } + + if ((ret = SSL_read(ssl, buf, (int)size)) < 0) + @throw [OFReadFailedException newWithClass: isa + stream: self + requestedSize: size]; + + if (ret == 0) + eos = YES; + + return ret; +} + +- (size_t)_writeNBytes: (size_t)size + fromBuffer: (const char*)buf +{ + ssize_t ret; + + if (size > INT_MAX) + @throw [OFOutOfRangeException newWithClass: isa]; + + if (sock == INVALID_SOCKET) + @throw [OFNotConnectedException newWithClass: isa + socket: self]; + + if (eos) { + OFWriteFailedException *e; + + e = [OFWriteFailedException newWithClass: isa + stream: self + requestedSize: size]; + +#ifndef _WIN32 + e->errNo = ENOTCONN; +#else + e->errNo = WSAENOTCONN; +#endif + + @throw e; + } + + if ((ret = SSL_write(ssl, buf, (int)size)) < 1) + @throw [OFWriteFailedException newWithClass: isa + stream: self + requestedSize: size]; + + return ret; +} +@end