Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Initial support for Mbed TLS Mbed TLS is never automatically picked as a TLS implementation and always needs to be manually enabled using --with-tls=mbedtls. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
11b2a175958b6486036d8c05bdb26ec0 |
| User & Date: | js 2024-01-06 00:52:48.942 |
References
|
2024-01-06
| ||
| 01:09 | • Fixed ticket [043f2b5021]: Support mbedTLS plus 4 other changes artifact: f54c29bc11 user: js | |
Context
|
2024-01-06
| ||
| 01:00 | Fix compilation of OFOpenSSLTLSStream check-in: 64d9603a4f user: js tags: trunk | |
| 00:52 | Initial support for Mbed TLS check-in: 11b2a17595 user: js tags: trunk | |
|
2024-01-04
| ||
| 19:05 | Add new signing key check-in: b4c4812b7b user: js tags: trunk | |
Changes
Changes to configure.ac.
| ︙ | ︙ | |||
1780 1781 1782 1783 1784 1785 1786 | ]) ;; esac AC_ARG_WITH(tls, AS_HELP_STRING([--with-tls], [ enable TLS support using the specified library | | > | 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 | ]) ;; esac AC_ARG_WITH(tls, AS_HELP_STRING([--with-tls], [ enable TLS support using the specified library (yes, openssl, gnutls, securetransport, mbedtls or no)])) AS_IF([test x"$with_tls" = x""], [with_tls="yes"]) tls_support="no" AS_IF([test x"$with_tls" = x"securetransport" \ -o x"$with_tls" = x"yes"], [ AC_CHECK_HEADERS(Security/SecureTransport.h, [ old_LIBS="$LIBS" |
| ︙ | ︙ | |||
1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 | AC_SUBST(OF_GNUTLS_TLS_STREAM_M, "OFGnuTLSTLSStream.m") ], [ dnl Disable default action-if-not-found, which exits dnl configure with an error. : ]) ]) AS_IF([test x"$tls_support" != x"no"], [ AC_SUBST(TLS, "tls") AC_SUBST(TLS_CPPFLAGS) AC_SUBST(TLS_LIBS) AC_DEFINE(HAVE_TLS_SUPPORT, 1, [Whether we have an implementation for TLS]) | > > > > > > > > > > > > > > > > > > > > > > | 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 | AC_SUBST(OF_GNUTLS_TLS_STREAM_M, "OFGnuTLSTLSStream.m") ], [ dnl Disable default action-if-not-found, which exits dnl configure with an error. : ]) ]) AS_IF([test x"$with_tls" = x"mbedtls"], [ AC_ARG_WITH(mbedtls-ca-path, AS_HELP_STRING([path to CA file for Mbed TLS])) AS_IF([test x"$with_mbedtls_ca_path" = x""], [ AC_MSG_ERROR([--mbedtls-ca-path needs to be specified!]) ]) AC_DEFINE_UNQUOTED(OF_MBEDTLS_CA_PATH, "$with_mbedtls_ca_path", [Path to CA file for Mbed TLS]) AC_CHECK_LIB(mbedtls, mbedtls_net_init, [ AC_CHECK_HEADER(mbedtls/ssl.h, [ tls_support="Mbed TLS" TLS_LIBS="-lmbedx509 -lmbedcrypto $TLS_LIBS" TLS_LIBS="-lmbedtls $TLS_LIBS" AC_SUBST(OF_MBEDTLS_TLS_STREAM_M, "OFMbedTLSTLSStream.m") ]) ], [], [-lmbedx509 -lmbedcrypto]) ]) AS_IF([test x"$tls_support" != x"no"], [ AC_SUBST(TLS, "tls") AC_SUBST(TLS_CPPFLAGS) AC_SUBST(TLS_LIBS) AC_DEFINE(HAVE_TLS_SUPPORT, 1, [Whether we have an implementation for TLS]) |
| ︙ | ︙ |
Changes to extra.mk.in.
| ︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | OFHTTP = @OFHTTP@ OFHTTP_LIBS = @OFHTTP_LIBS@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ OF_GNUTLS_TLS_STREAM_M = @OF_GNUTLS_TLS_STREAM_M@ OF_HTTP_CLIENT_TESTS_M = @OF_HTTP_CLIENT_TESTS_M@ OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@ OF_OPENSSL_TLS_STREAM_M = @OF_OPENSSL_TLS_STREAM_M@ OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@ OF_SECURE_TRANSPORT_TLS_STREAM_M = @OF_SECURE_TRANSPORT_TLS_STREAM_M@ OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@ OF_SUBPROCESS_M = @OF_SUBPROCESS_M@ REEXPORT_RUNTIME = @REEXPORT_RUNTIME@ REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@ | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | OFHTTP = @OFHTTP@ OFHTTP_LIBS = @OFHTTP_LIBS@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ OF_GNUTLS_TLS_STREAM_M = @OF_GNUTLS_TLS_STREAM_M@ OF_HTTP_CLIENT_TESTS_M = @OF_HTTP_CLIENT_TESTS_M@ OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@ OF_MBEDTLS_TLS_STREAM_M = @OF_MBEDTLS_TLS_STREAM_M@ OF_OPENSSL_TLS_STREAM_M = @OF_OPENSSL_TLS_STREAM_M@ OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@ OF_SECURE_TRANSPORT_TLS_STREAM_M = @OF_SECURE_TRANSPORT_TLS_STREAM_M@ OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@ OF_SUBPROCESS_M = @OF_SUBPROCESS_M@ REEXPORT_RUNTIME = @REEXPORT_RUNTIME@ REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@ |
| ︙ | ︙ |
Changes to src/OFTLSStream.h.
| ︙ | ︙ | |||
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
+ (instancetype)streamWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream;
/**
* @brief Initializes the TLS stream with the specified stream as its
* underlying stream.
*
* @param stream The stream to use as underlying stream. Must not be closed
* before the TLS stream is closed.
* @return An initialized TLS stream
*/
- (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream
OF_DESIGNATED_INITIALIZER;
| > > > | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
+ (instancetype)streamWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream;
/**
* @brief Initializes the TLS stream with the specified stream as its
* underlying stream.
*
* @note The delegate of the specified stream will be changed to the TLS
* stream. You must not change this before the TLS session is completed.
*
* @param stream The stream to use as underlying stream. Must not be closed
* before the TLS stream is closed.
* @return An initialized TLS stream
*/
- (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream
OF_DESIGNATED_INITIALIZER;
|
| ︙ | ︙ |
Changes to src/tls/Makefile.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
include ../../extra.mk
DISTCLEAN = Info.plist
SHARED_LIB = ${OBJFWTLS_SHARED_LIB}
STATIC_LIB = ${OBJFWTLS_STATIC_LIB}
FRAMEWORK = ${OBJFWTLS_FRAMEWORK}
LIB_MAJOR = ${OBJFWTLS_LIB_MAJOR}
LIB_MINOR = ${OBJFWTLS_LIB_MINOR}
LIB_PATCH = ${OBJFWTLS_LIB_PATCH}
INCLUDES := ObjFWTLS.h
SRCS = ${OF_GNUTLS_TLS_STREAM_M} \
${OF_OPENSSL_TLS_STREAM_M} \
${OF_SECURE_TRANSPORT_TLS_STREAM_M}
includesubdir = ObjFWTLS
include ../../buildsys.mk
| > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
include ../../extra.mk
DISTCLEAN = Info.plist
SHARED_LIB = ${OBJFWTLS_SHARED_LIB}
STATIC_LIB = ${OBJFWTLS_STATIC_LIB}
FRAMEWORK = ${OBJFWTLS_FRAMEWORK}
LIB_MAJOR = ${OBJFWTLS_LIB_MAJOR}
LIB_MINOR = ${OBJFWTLS_LIB_MINOR}
LIB_PATCH = ${OBJFWTLS_LIB_PATCH}
INCLUDES := ObjFWTLS.h
SRCS = ${OF_GNUTLS_TLS_STREAM_M} \
${OF_MBEDTLS_TLS_STREAM_M} \
${OF_OPENSSL_TLS_STREAM_M} \
${OF_SECURE_TRANSPORT_TLS_STREAM_M}
includesubdir = ObjFWTLS
include ../../buildsys.mk
|
| ︙ | ︙ |
Changes to src/tls/OFGnuTLSTLSStream.m.
| ︙ | ︙ | |||
123 124 125 126 127 128 129 | if (!_initialized) @throw [OFNotOpenException exceptionWithObject: self]; if (_handshakeDone) gnutls_bye(_session, GNUTLS_SHUT_WR); gnutls_deinit(_session); | | | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | if (!_initialized) @throw [OFNotOpenException exceptionWithObject: self]; if (_handshakeDone) gnutls_bye(_session, GNUTLS_SHUT_WR); gnutls_deinit(_session); _initialized = _handshakeDone = false; [_host release]; _host = nil; [super close]; } |
| ︙ | ︙ | |||
235 236 237 238 239 240 241 |
if (_verifiesCertificates)
gnutls_session_set_verify_cert(_session, _host.UTF8String, 0);
status = gnutls_handshake(_session);
if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) {
if (gnutls_record_get_direction(_session) == 1)
| | < | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
if (_verifiesCertificates)
gnutls_session_set_verify_cert(_session, _host.UTF8String, 0);
status = gnutls_handshake(_session);
if (status == GNUTLS_E_INTERRUPTED || status == GNUTLS_E_AGAIN) {
if (gnutls_record_get_direction(_session) == 1)
[_underlyingStream asyncWriteData: [OFData data]
runLoopMode: runLoopMode];
else
[_underlyingStream asyncReadIntoBuffer: (void *)""
length: 0
runLoopMode: runLoopMode];
[_delegate retain];
return;
|
| ︙ | ︙ | |||
266 267 268 269 270 271 272 | didPerformClientHandshakeWithHost: host exception: exception]; } - (bool)stream: (OFStream *)stream didReadIntoBuffer: (void *)buffer length: (size_t)length | | < < | | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
didPerformClientHandshakeWithHost: host
exception: exception];
}
- (bool)stream: (OFStream *)stream
didReadIntoBuffer: (void *)buffer
length: (size_t)length
exception: (id)exception
{
if (exception == nil) {
int status = gnutls_handshake(_session);
if (status == GNUTLS_E_INTERRUPTED ||
status == GNUTLS_E_AGAIN) {
if (gnutls_record_get_direction(_session) == 1) {
OFRunLoopMode runLoopMode =
[OFRunLoop currentRunLoop].currentMode;
[_underlyingStream asyncWriteData: [OFData data]
runLoopMode: runLoopMode];
return false;
} else
return true;
}
if (status == GNUTLS_E_SUCCESS)
|
| ︙ | ︙ |
Added src/tls/OFMbedTLSTLSStream.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/*
* Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#import "OFTLSStream.h"
#include <mbedtls/ssl.h>
OF_ASSUME_NONNULL_BEGIN
@interface OFMbedTLSTLSStream: OFTLSStream <OFStreamDelegate>
{
bool _initialized, _handshakeDone;
mbedtls_ssl_config _config;
mbedtls_ssl_context _SSL;
OFString *_host;
}
@end
OF_ASSUME_NONNULL_END
|
Added src/tls/OFMbedTLSTLSStream.m.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
/*
* Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This file is part of ObjFW. It may be distributed under the terms of the
* Q Public License 1.0, which can be found in the file LICENSE.QPL included in
* the packaging of this file.
*
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include "config.h"
#include <errno.h>
#import "OFMbedTLSTLSStream.h"
#import "OFData.h"
#import "OFAlreadyOpenException.h"
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFOutOfRangeException.h"
#import "OFReadFailedException.h"
#import "OFTLSHandshakeFailedException.h"
#import "OFWriteFailedException.h"
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
int _ObjFWTLS_reference;
static mbedtls_entropy_context entropy;
static mbedtls_ctr_drbg_context CTRDRBG;
static mbedtls_x509_crt CAChain;
@implementation OFMbedTLSTLSStream
static int
readFunc(void *ctx, unsigned char *buffer, size_t length)
{
OFMbedTLSTLSStream *stream = (OFMbedTLSTLSStream *)ctx;
@try {
length = [stream.underlyingStream readIntoBuffer: buffer
length: length];
} @catch (OFReadFailedException *e) {
return -1;
}
if (length == 0 && !stream.underlyingStream.atEndOfStream)
return MBEDTLS_ERR_SSL_WANT_READ;
if (length > INT_MAX)
@throw [OFOutOfRangeException exception];
return (int)length;
}
static int
writeFunc(void *ctx, const unsigned char *buffer, size_t length)
{
OFMbedTLSTLSStream *stream = (OFMbedTLSTLSStream *)ctx;
@try {
[stream.underlyingStream writeBuffer: buffer length: length];
} @catch (OFWriteFailedException *e) {
if (e.errNo == EWOULDBLOCK || e.errNo == EAGAIN) {
size_t bytesWritten = e.bytesWritten;
if (bytesWritten > INT_MAX)
@throw [OFOutOfRangeException exception];
return (bytesWritten > 0
? (int)bytesWritten : MBEDTLS_ERR_SSL_WANT_WRITE);
}
return -1;
}
if (length > INT_MAX)
@throw [OFOutOfRangeException exception];
return (int)length;
}
+ (void)load
{
if (OFTLSStreamImplementation == Nil)
OFTLSStreamImplementation = self;
}
+ (void)initialize
{
if (self != [OFMbedTLSTLSStream class])
return;
mbedtls_entropy_init(&entropy);
if (mbedtls_ctr_drbg_seed(&CTRDRBG, mbedtls_entropy_func, &entropy,
NULL, 0) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
mbedtls_x509_crt_init(&CAChain);
if (mbedtls_x509_crt_parse_file(&CAChain, OF_MBEDTLS_CA_PATH) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- (instancetype)initWithStream: (OFStream <OFReadyForReadingObserving,
OFReadyForWritingObserving> *)stream
{
self = [super initWithStream: stream];
@try {
_underlyingStream.delegate = self;
} @catch (id e) {
[self release];
@throw e;
}
return self;
}
- (void)dealloc
{
if (_initialized)
[self close];
[_host release];
[super dealloc];
}
- (void)close
{
if (!_initialized)
@throw [OFNotOpenException exceptionWithObject: self];
if (_handshakeDone)
mbedtls_ssl_close_notify(&_SSL);
mbedtls_ssl_free(&_SSL);
mbedtls_ssl_config_free(&_config);
_initialized = _handshakeDone = false;
[_host release];
_host = nil;
[super close];
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
int ret;
if (!_handshakeDone)
@throw [OFNotOpenException exceptionWithObject: self];
if ((ret = mbedtls_ssl_read(&_SSL, buffer, length)) < 0) {
/*
* The underlying stream might have had data ready, but not
* enough for MbedTLS to return decrypted data. This means the
* caller might have observed the TLS stream for reading, got a
* ready signal and read - and expects the read to succeed, not
* to fail with EWOULDBLOCK/EAGAIN, as it was signaled ready.
* Therefore, return 0, as we could read 0 decrypted bytes, but
* cleared the ready signal of the underlying stream.
*/
if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
ret == MBEDTLS_ERR_SSL_WANT_WRITE)
return 0;
/* FIXME: Translate error to errNo */
@throw [OFReadFailedException exceptionWithObject: self
requestedLength: length
errNo: 0];
}
return ret;
}
- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
int ret;
if (!_handshakeDone)
@throw [OFNotOpenException exceptionWithObject: self];
if ((ret = mbedtls_ssl_write(&_SSL, buffer, length)) < 0) {
if (ret == MBEDTLS_ERR_SSL_WANT_READ ||
ret == MBEDTLS_ERR_SSL_WANT_WRITE)
return 0;
/* FIXME: Translate error to errNo */
@throw [OFWriteFailedException exceptionWithObject: self
requestedLength: length
bytesWritten: ret
errNo: 0];
}
return ret;
}
- (bool)lowlevelHasDataInReadBuffer
{
return (_underlyingStream.hasDataInReadBuffer ||
mbedtls_ssl_get_bytes_avail(&_SSL));
}
- (void)asyncPerformClientHandshakeWithHost: (OFString *)host
runLoopMode: (OFRunLoopMode)runLoopMode
{
static const OFTLSStreamErrorCode initFailedErrorCode =
OFTLSStreamErrorCodeInitializationFailed;
id exception = nil;
int status;
if (_initialized)
@throw [OFAlreadyOpenException exceptionWithObject: self];
if (mbedtls_ssl_config_defaults(&_config, MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0)
@throw [OFTLSHandshakeFailedException
exceptionWithStream: self
host: host
errorCode: initFailedErrorCode];
mbedtls_ssl_conf_rng(&_config, mbedtls_ctr_drbg_random, &CTRDRBG);
mbedtls_ssl_conf_authmode(&_config, (_verifiesCertificates
? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE));
mbedtls_ssl_conf_ca_chain(&_config, &CAChain, NULL);
mbedtls_ssl_init(&_SSL);
if (mbedtls_ssl_setup(&_SSL, &_config) != 0)
@throw [OFTLSHandshakeFailedException
exceptionWithStream: self
host: host
errorCode: initFailedErrorCode];
mbedtls_ssl_set_bio(&_SSL, self, writeFunc, readFunc, NULL);
_host = [host copy];
if (mbedtls_ssl_set_hostname(&_SSL, _host.UTF8String) != 0)
@throw [OFTLSHandshakeFailedException
exceptionWithStream: self
host: host
errorCode: initFailedErrorCode];
status = mbedtls_ssl_handshake(&_SSL);
if (status == MBEDTLS_ERR_SSL_WANT_READ) {
[_underlyingStream asyncReadIntoBuffer: (void *)""
length: 0
runLoopMode: runLoopMode];
[_delegate retain];
return;
} else if (status == MBEDTLS_ERR_SSL_WANT_WRITE) {
[_underlyingStream asyncWriteData: [OFData data]
runLoopMode: runLoopMode];
[_delegate retain];
return;
}
if (status == 0)
_handshakeDone = true;
else
/* FIXME: Map to better errors */
exception = [OFTLSHandshakeFailedException
exceptionWithStream: self
host: host
errorCode: OFTLSStreamErrorCodeUnknown];
if ([_delegate respondsToSelector:
@selector(stream:didPerformClientHandshakeWithHost:exception:)])
[_delegate stream: self
didPerformClientHandshakeWithHost: host
exception: exception];
}
- (bool)stream: (OFStream *)stream
didReadIntoBuffer: (void *)buffer
length: (size_t)length
exception: (id)exception
{
if (exception == nil) {
int status = mbedtls_ssl_handshake_step(&_SSL);
if (status == MBEDTLS_ERR_SSL_WANT_READ)
return true;
else if (status == MBEDTLS_ERR_SSL_WANT_WRITE) {
OFRunLoopMode runLoopMode =
[OFRunLoop currentRunLoop].currentMode;
[_underlyingStream asyncWriteData: [OFData data]
runLoopMode: runLoopMode];
return false;
}
if (status == 0)
_handshakeDone = true;
else
exception = [OFTLSHandshakeFailedException
exceptionWithStream: self
host: _host
errorCode: OFTLSStreamErrorCodeUnknown];
}
if ([_delegate respondsToSelector:
@selector(stream:didPerformClientHandshakeWithHost:exception:)])
[_delegate stream: self
didPerformClientHandshakeWithHost: _host
exception: exception];
[_delegate release];
return false;
}
- (OFData *)stream: (OFStream *)stream
didWriteData: (OFData *)data
bytesWritten: (size_t)bytesWritten
exception: (id)exception
{
if (exception == nil) {
int status = mbedtls_ssl_handshake_step(&_SSL);
if (status == MBEDTLS_ERR_SSL_WANT_WRITE)
return data;
else if (status == MBEDTLS_ERR_SSL_WANT_READ) {
OFRunLoopMode runLoopMode =
[OFRunLoop currentRunLoop].currentMode;
[_underlyingStream asyncReadIntoBuffer: (void *)""
length: 0
runLoopMode: runLoopMode];
return nil;
}
if (status == 0)
_handshakeDone = true;
else
exception = [OFTLSHandshakeFailedException
exceptionWithStream: self
host: _host
errorCode: OFTLSStreamErrorCodeUnknown];
}
if ([_delegate respondsToSelector:
@selector(stream:didPerformClientHandshakeWithHost:exception:)])
[_delegate stream: self
didPerformClientHandshakeWithHost: _host
exception: exception];
[_delegate release];
return nil;
}
@end
|
Changes to src/tls/OFOpenSSLTLSStream.m.
| ︙ | ︙ | |||
90 91 92 93 94 95 96 97 98 99 100 101 102 103 | if (_handshakeDone) SSL_shutdown(_SSL); SSL_free(_SSL); _SSL = NULL; [_host release]; _host = nil; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length | > > | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | if (_handshakeDone) SSL_shutdown(_SSL); SSL_free(_SSL); _SSL = NULL; _handshakeDone = false; [_host release]; _host = nil; [super close]; } - (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length |
| ︙ | ︙ | |||
283 284 285 286 287 288 289 | case SSL_ERROR_WANT_READ: [_underlyingStream asyncReadIntoBuffer: _buffer length: bufferSize runLoopMode: runLoopMode]; [_delegate retain]; return; case SSL_ERROR_WANT_WRITE: | | < | | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | case SSL_ERROR_WANT_READ: [_underlyingStream asyncReadIntoBuffer: _buffer length: bufferSize runLoopMode: runLoopMode]; [_delegate retain]; return; case SSL_ERROR_WANT_WRITE: [_underlyingStream asyncWriteData: [OFData data] runLoopMode: runLoopMode]; [_delegate retain]; return; default: /* FIXME: Map to better errors */ exception = [OFTLSHandshakeFailedException exceptionWithStream: self host: host |
| ︙ | ︙ | |||
338 339 340 341 342 343 344 |
if (status == 1)
_handshakeDone = true;
else {
switch (SSL_get_error(_SSL, status)) {
case SSL_ERROR_WANT_READ:
return true;
case SSL_ERROR_WANT_WRITE:
| < | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
if (status == 1)
_handshakeDone = true;
else {
switch (SSL_get_error(_SSL, status)) {
case SSL_ERROR_WANT_READ:
return true;
case SSL_ERROR_WANT_WRITE:
OFRunLoopMode runLoopMode =
[OFRunLoop currentRunLoop].currentMode;
[_underlyingStream asyncWriteData: [OFData data]
runLoopMode: runLoopMode];
return false;
default:
exception = [OFTLSHandshakeFailedException
exceptionWithStream: self
host: _host
errorCode: unknownErrorCode];
|
| ︙ | ︙ |
Changes to src/tls/OFSecureTransportTLSStream.m.
| ︙ | ︙ | |||
123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
SSLClose(_context);
#ifdef HAVE_SSLCREATECONTEXT
CFRelease(_context);
#else
SSLDisposeContext(_context);
#endif
_context = NULL;
[super close];
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
OSStatus status;
| > | 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
SSLClose(_context);
#ifdef HAVE_SSLCREATECONTEXT
CFRelease(_context);
#else
SSLDisposeContext(_context);
#endif
_context = NULL;
_handshakeDone = false;
[super close];
}
- (size_t)lowlevelReadIntoBuffer: (void *)buffer length: (size_t)length
{
OSStatus status;
|
| ︙ | ︙ |