︙ | | |
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
|
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
|
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
|
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
|
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
|
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
|
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:
/* FIXME: Map to better errors */
exception = [OFTLSHandshakeFailedException
exceptionWithStream: self
host: host
errorCode: OFTLSStreamErrorCodeUnknown];
break;
}
}
|
︙ | | |
329
330
331
332
333
334
335
336
337
338
339
340
341
342
|
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
|
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
|
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
|
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;
}
|
︙ | | |