ObjFW  Check-in [fa9652e096]

Overview
Comment:OFOpenSSLTLSStream: Use more error codes
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: fa9652e096d17854e57a75489318e1a71831b30404910b722938cd581f80ca6b
User & Date: js on 2024-11-13 23:46:28
Other Links: manifest | tags
Context
2024-11-14
00:27
Port to latest devkitARM check-in: 23da92beab user: js tags: trunk
2024-11-13
23:46
OFOpenSSLTLSStream: Use more error codes check-in: fa9652e096 user: js tags: trunk
00:01
Fix compiling on Haiku r1beta5 check-in: b585f68973 user: js tags: trunk
Changes

Modified src/OFTLSStream.h from [80f6ab9958] to [c23d19a2a9].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 * @brief An enum representing an error of an OFTLSStream.
 */
typedef enum {
	/** @brief An unknown error. */
	OFTLSStreamErrorCodeUnknown,
	/** @brief Initialization of the TLS context failed. */
	OFTLSStreamErrorCodeInitializationFailed,
	/** @brief Verification of the certificate failed. */
	OFTLSStreamErrorCodeCertificateVerificationFailed,
	/** @brief The certificate has an untrusted or unknown issuer. */
	OFTLSStreamErrorCodeCertificateIssuerUntrusted,
	/** @brief The certificate is for a different name. */
	OFTLSStreamErrorCodeCertificateNameMismatch,
	/** @brief The certificate has expired or is not yet valid. */
	OFTLSStreamErrorCodeCertificatedExpired,







|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 * @brief An enum representing an error of an OFTLSStream.
 */
typedef enum {
	/** @brief An unknown error. */
	OFTLSStreamErrorCodeUnknown,
	/** @brief Initialization of the TLS context failed. */
	OFTLSStreamErrorCodeInitializationFailed,
	/** @brief Failed to verify certificate. */
	OFTLSStreamErrorCodeCertificateVerificationFailed,
	/** @brief The certificate has an untrusted or unknown issuer. */
	OFTLSStreamErrorCodeCertificateIssuerUntrusted,
	/** @brief The certificate is for a different name. */
	OFTLSStreamErrorCodeCertificateNameMismatch,
	/** @brief The certificate has expired or is not yet valid. */
	OFTLSStreamErrorCodeCertificatedExpired,

Modified src/OFTLSStream.m from [698fb25b59] to [78c4319f41].

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
OFString *
OFTLSStreamErrorCodeDescription(OFTLSStreamErrorCode errorCode)
{
	switch (errorCode) {
	case OFTLSStreamErrorCodeInitializationFailed:
		return @"Initialization of TLS context failed";
	case OFTLSStreamErrorCodeCertificateVerificationFailed:
		return @"Verification of the certificate failed";
	case OFTLSStreamErrorCodeCertificateIssuerUntrusted:
		return @"The certificate has an untrusted or unknown issuer";
	case OFTLSStreamErrorCodeCertificateNameMismatch:
		return @"The certificate is for a different name";
	case OFTLSStreamErrorCodeCertificatedExpired:
		return @"The certificate has expired or is not yet valid";
	case OFTLSStreamErrorCodeCertificateRevoked:







|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
OFString *
OFTLSStreamErrorCodeDescription(OFTLSStreamErrorCode errorCode)
{
	switch (errorCode) {
	case OFTLSStreamErrorCodeInitializationFailed:
		return @"Initialization of TLS context failed";
	case OFTLSStreamErrorCodeCertificateVerificationFailed:
		return @"Failed to verify certificate";
	case OFTLSStreamErrorCodeCertificateIssuerUntrusted:
		return @"The certificate has an untrusted or unknown issuer";
	case OFTLSStreamErrorCodeCertificateNameMismatch:
		return @"The certificate is for a different name";
	case OFTLSStreamErrorCodeCertificatedExpired:
		return @"The certificate has expired or is not yet valid";
	case OFTLSStreamErrorCodeCertificateRevoked:

Modified src/tls/OFOpenSSLTLSStream.m from [ca917e4347] to [eaf4116fbc].

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

#include "config.h"

#include <errno.h>

#import "OFOpenSSLTLSStream.h"
#import "OFData.h"



#import "OFAlreadyOpenException.h"
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFReadFailedException.h"
#import "OFTLSHandshakeFailedException.h"
#import "OFWriteFailedException.h"

#define bufferSize OFOpenSSLTLSStreamBufferSize

int _ObjFWTLS_reference;
static SSL_CTX *clientContext;







































@implementation OFOpenSSLTLSStream
+ (void)load
{
	if (OFTLSStreamImplementation == Nil)
		OFTLSStreamImplementation = self;
}







>
>












>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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

#include "config.h"

#include <errno.h>

#import "OFOpenSSLTLSStream.h"
#import "OFData.h"

#include <openssl/err.h>

#import "OFAlreadyOpenException.h"
#import "OFInitializationFailedException.h"
#import "OFNotOpenException.h"
#import "OFReadFailedException.h"
#import "OFTLSHandshakeFailedException.h"
#import "OFWriteFailedException.h"

#define bufferSize OFOpenSSLTLSStreamBufferSize

int _ObjFWTLS_reference;
static SSL_CTX *clientContext;

static OFTLSStreamErrorCode
verifyResultToErrorCode(const SSL *SSL_)
{
	switch (SSL_get_verify_result(SSL_)) {
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
	case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
	case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
	case X509_V_ERR_CERT_UNTRUSTED:
		return OFTLSStreamErrorCodeCertificateIssuerUntrusted;
	case X509_V_ERR_HOSTNAME_MISMATCH:
		return OFTLSStreamErrorCodeCertificateNameMismatch;
	case X509_V_ERR_CERT_NOT_YET_VALID:
	case X509_V_ERR_CERT_HAS_EXPIRED:
		return OFTLSStreamErrorCodeCertificatedExpired;
	case X509_V_ERR_CERT_REVOKED:
		return OFTLSStreamErrorCodeCertificateRevoked;
	}

	return OFTLSStreamErrorCodeCertificateVerificationFailed;
}

static OFTLSStreamErrorCode
errToErrorCode(const SSL *SSL_)
{
	unsigned long err = ERR_get_error();

	switch (ERR_GET_LIB(err)) {
	case ERR_LIB_SSL:
		switch (ERR_GET_REASON(err)) {
		case SSL_R_CERTIFICATE_VERIFY_FAILED:
			return verifyResultToErrorCode(SSL_);
		}
	}

	return OFTLSStreamErrorCodeUnknown;
}

@implementation OFOpenSSLTLSStream
+ (void)load
{
	if (OFTLSStreamImplementation == Nil)
		OFTLSStreamImplementation = self;
}
110
111
112
113
114
115
116

117
118
119
120
121
122
123
{
	int ret;
	size_t bytesRead;

	if (!_handshakeDone)
		@throw [OFNotOpenException exceptionWithObject: self];


	ret = SSL_read_ex(_SSL, buffer, length, &bytesRead);

	while (BIO_ctrl_pending(_writeBIO) > 0) {
		int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

		OFEnsure(tmp >= 0);








>







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
{
	int ret;
	size_t bytesRead;

	if (!_handshakeDone)
		@throw [OFNotOpenException exceptionWithObject: self];

	ERR_clear_error();
	ret = SSL_read_ex(_SSL, buffer, length, &bytesRead);

	while (BIO_ctrl_pending(_writeBIO) > 0) {
		int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

		OFEnsure(tmp >= 0);

141
142
143
144
145
146
147

148
149
150
151
152
153
154
				    (int)tmp) == (int)tmp);
			} @catch (OFReadFailedException *e) {
				if (e.errNo == EWOULDBLOCK || e.errNo != EAGAIN)
					return 0;
			}
		}


		ret = SSL_read_ex(_SSL, buffer, length, &bytesRead);

		while (BIO_ctrl_pending(_writeBIO) > 0) {
			int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

			OFEnsure(tmp >= 0);








>







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
				    (int)tmp) == (int)tmp);
			} @catch (OFReadFailedException *e) {
				if (e.errNo == EWOULDBLOCK || e.errNo != EAGAIN)
					return 0;
			}
		}

		ERR_clear_error();
		ret = SSL_read_ex(_SSL, buffer, length, &bytesRead);

		while (BIO_ctrl_pending(_writeBIO) > 0) {
			int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

			OFEnsure(tmp >= 0);

172
173
174
175
176
177
178


179
180
181
182
183
184
185
- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
	int ret;
	size_t bytesWritten;

	if (!_handshakeDone)
		@throw [OFNotOpenException exceptionWithObject: self];



	if ((ret = SSL_write_ex(_SSL, buffer, length, &bytesWritten)) != 1) {
		/* FIXME: Translate error to errNo */
		int errNo = 0;

		if (SSL_get_error(_SSL, ret) == SSL_ERROR_WANT_WRITE)
			return bytesWritten;







>
>







214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
- (size_t)lowlevelWriteBuffer: (const void *)buffer length: (size_t)length
{
	int ret;
	size_t bytesWritten;

	if (!_handshakeDone)
		@throw [OFNotOpenException exceptionWithObject: self];

	ERR_clear_error();

	if ((ret = SSL_write_ex(_SSL, buffer, length, &bytesWritten)) != 1) {
		/* FIXME: Translate error to errNo */
		int errNo = 0;

		if (SSL_get_error(_SSL, ret) == SSL_ERROR_WANT_WRITE)
			return bytesWritten;
268
269
270
271
272
273
274

275
276
277
278
279
280
281
		if (SSL_set1_host(_SSL, _host.UTF8String) != 1)
			@throw [OFTLSHandshakeFailedException
			    exceptionWithStream: self
					   host: host
				      errorCode: initFailedErrorCode];
	}


	status = SSL_do_handshake(_SSL);

	while (BIO_ctrl_pending(_writeBIO) > 0) {
		int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

		OFEnsure(tmp >= 0);








>







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
		if (SSL_set1_host(_SSL, _host.UTF8String) != 1)
			@throw [OFTLSHandshakeFailedException
			    exceptionWithStream: self
					   host: host
				      errorCode: initFailedErrorCode];
	}

	ERR_clear_error();
	status = SSL_do_handshake(_SSL);

	while (BIO_ctrl_pending(_writeBIO) > 0) {
		int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

		OFEnsure(tmp >= 0);

296
297
298
299
300
301
302






303
304
305
306
307
308
309
310
311
			return;
		case SSL_ERROR_WANT_WRITE:
			[_underlyingStream asyncWriteData: [OFData data]
					      runLoopMode: runLoopMode];
			[_delegate retain];
			objc_autoreleasePoolPop(pool);
			return;






		default:
			/* FIXME: Map to better errors */
			exception = [OFTLSHandshakeFailedException
			    exceptionWithStream: self
					   host: host
				      errorCode: OFTLSStreamErrorCodeUnknown];
			break;
		}
	}







>
>
>
>
>
>

<







341
342
343
344
345
346
347
348
349
350
351
352
353
354

355
356
357
358
359
360
361
			return;
		case SSL_ERROR_WANT_WRITE:
			[_underlyingStream asyncWriteData: [OFData data]
					      runLoopMode: runLoopMode];
			[_delegate retain];
			objc_autoreleasePoolPop(pool);
			return;
		case SSL_ERROR_SSL:
			exception = [OFTLSHandshakeFailedException
			    exceptionWithStream: self
					   host: host
				      errorCode: errToErrorCode(_SSL)];
			break;
		default:

			exception = [OFTLSHandshakeFailedException
			    exceptionWithStream: self
					   host: host
				      errorCode: OFTLSStreamErrorCodeUnknown];
			break;
		}
	}
329
330
331
332
333
334
335

336
337
338
339
340
341
342
		    OFTLSStreamErrorCodeUnknown;
		int status;

		OFEnsure(length <= INT_MAX);
		OFEnsure(BIO_write(_readBIO, buffer, (int)length) ==
		    (int)length);


		status = SSL_do_handshake(_SSL);

		while (BIO_ctrl_pending(_writeBIO) > 0) {
			int tmp = BIO_read(_writeBIO, buffer, bufferSize);

			OFEnsure(tmp >= 0);








>







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
		    OFTLSStreamErrorCodeUnknown;
		int status;

		OFEnsure(length <= INT_MAX);
		OFEnsure(BIO_write(_readBIO, buffer, (int)length) ==
		    (int)length);

		ERR_clear_error();
		status = SSL_do_handshake(_SSL);

		while (BIO_ctrl_pending(_writeBIO) > 0) {
			int tmp = BIO_read(_writeBIO, buffer, bufferSize);

			OFEnsure(tmp >= 0);

352
353
354
355
356
357
358






359
360
361
362
363
364
365
				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];
				break;
			}







>
>
>
>
>
>







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
				return true;
			case SSL_ERROR_WANT_WRITE:;
				OFRunLoopMode runLoopMode =
				    [OFRunLoop currentRunLoop].currentMode;
				[_underlyingStream asyncWriteData: [OFData data]
						      runLoopMode: runLoopMode];
				return false;
			case SSL_ERROR_SSL:
				exception = [OFTLSHandshakeFailedException
				    exceptionWithStream: self
						   host: _host
					      errorCode: errToErrorCode(_SSL)];
				break;
			default:
				exception = [OFTLSHandshakeFailedException
				    exceptionWithStream: self
						   host: _host
					      errorCode: unknownErrorCode];
				break;
			}
393
394
395
396
397
398
399

400
401
402
403
404
405
406

			OFEnsure(tmp >= 0);

			[_underlyingStream writeBuffer: _buffer length: tmp];
			[_underlyingStream flushWriteBuffer];
		}


		status = SSL_do_handshake(_SSL);

		while (BIO_ctrl_pending(_writeBIO) > 0) {
			int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

			OFEnsure(tmp >= 0);








>







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

			OFEnsure(tmp >= 0);

			[_underlyingStream writeBuffer: _buffer length: tmp];
			[_underlyingStream flushWriteBuffer];
		}

		ERR_clear_error();
		status = SSL_do_handshake(_SSL);

		while (BIO_ctrl_pending(_writeBIO) > 0) {
			int tmp = BIO_read(_writeBIO, _buffer, bufferSize);

			OFEnsure(tmp >= 0);

418
419
420
421
422
423
424






425
426
427
428
429
430
431
				[_underlyingStream
				    asyncReadIntoBuffer: _buffer
						 length: bufferSize
					    runLoopMode: runLoopMode];
				return nil;
			case SSL_ERROR_WANT_WRITE:
				return data;






			default:
				exception = [OFTLSHandshakeFailedException
				    exceptionWithStream: self
						   host: _host
					      errorCode: unknownErrorCode];
				break;
			}







>
>
>
>
>
>







476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
				[_underlyingStream
				    asyncReadIntoBuffer: _buffer
						 length: bufferSize
					    runLoopMode: runLoopMode];
				return nil;
			case SSL_ERROR_WANT_WRITE:
				return data;
			case SSL_ERROR_SSL:
				exception = [OFTLSHandshakeFailedException
				    exceptionWithStream: self
						   host: _host
					      errorCode: errToErrorCode(_SSL)];
				break;
			default:
				exception = [OFTLSHandshakeFailedException
				    exceptionWithStream: self
						   host: _host
					      errorCode: unknownErrorCode];
				break;
			}