]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/lib/sslTransport.c
Security-57740.51.3.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / lib / sslTransport.c
1 /*
2 * Copyright (c) 1999-2001,2005-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * sslTransport.c - SSL transport layer
26 */
27
28 #include "ssl.h"
29 #include "sslMemory.h"
30 #include "sslContext.h"
31 #include "sslRecord.h"
32 #include "sslDebug.h"
33 #include "sslCipherSpecs.h"
34
35 #include <assert.h>
36 #include <string.h>
37
38 #include <utilities/SecIOFormat.h>
39 #include <utilities/SecCFWrappers.h>
40
41 #include <CommonCrypto/CommonDigest.h>
42 #include <Security/SecCertificatePriv.h>
43
44 #ifndef NDEBUG
45 static inline void sslIoTrace(
46 SSLContext *ctx,
47 const char *op,
48 size_t req,
49 size_t moved,
50 OSStatus stat)
51 {
52 sslLogRecordIo("[%p] ===%s: req %4lu moved %4lu status %d",
53 ctx, op, req, moved, (int)stat);
54 }
55 #else
56 #define sslIoTrace(ctx, op, req, moved, stat)
57 #endif /* NDEBUG */
58
59 extern int kSplitDefaultValue;
60
61 static OSStatus SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx);
62 static OSStatus SSLHandshakeProceed(SSLContext *ctx);
63
64 OSStatus
65 SSLWrite(
66 SSLContext *ctx,
67 const void * data,
68 size_t dataLength,
69 size_t *bytesWritten) /* RETURNED */
70 {
71 OSStatus err;
72 SSLRecord rec;
73 size_t dataLen, processed;
74
75 sslLogRecordIo("[%p] SSLWrite top", ctx);
76 if((ctx == NULL) || (bytesWritten == NULL)) {
77 return errSecParam;
78 }
79 dataLen = dataLength;
80 *bytesWritten = 0;
81
82 switch(ctx->state) {
83 case SSL_HdskStateGracefulClose:
84 err = errSSLClosedGraceful;
85 goto abort;
86 case SSL_HdskStateErrorClose:
87 err = errSSLClosedAbort;
88 goto abort;
89 case SSL_HdskStateReady:
90 break;
91 case SSL_HdskStateUninit:
92 /* not ready for I/O, and handshake not in progress */
93 sslIoTrace(ctx, "SSLWrite(1)", dataLength, 0, errSecBadReq);
94 return errSecBadReq;
95 default:
96 /* handshake in progress or done. Will call SSLHandshakeProceed below if necessary */
97 break;
98 }
99
100 /* First, we have to wait until the session is ready to send data,
101 so the encryption keys and such have been established. */
102 while (!(ctx->writeCipher_ready))
103 { if ((err = SSLHandshakeProceed(ctx)) != 0)
104 goto exit;
105 }
106
107 /* Attempt to empty the write queue before queueing more data */
108 if ((err = SSLServiceWriteQueue(ctx)) != 0)
109 goto abort;
110
111 processed = 0;
112
113 /* Skip empty writes, fragmentation is done at the coreTLS layer */
114 if(dataLen) {
115 rec.contentType = SSL_RecordTypeAppData;
116 rec.contents.data = ((uint8_t *)data) + processed;
117 rec.contents.length = dataLen;
118 if ((err = SSLWriteRecord(rec, ctx)) != 0)
119 goto exit;
120 processed += rec.contents.length;
121 }
122
123 /* All the data has been advanced to the write queue */
124 *bytesWritten = processed;
125 if ((err = SSLServiceWriteQueue(ctx)) == 0) {
126 err = errSecSuccess;
127 }
128 exit:
129 switch(err) {
130 case errSecSuccess:
131 case errSSLWouldBlock:
132 case errSSLUnexpectedRecord:
133 case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
134 case errSSLClientCertRequested:
135 case errSSLClientHelloReceived:
136 case errSSLClosedGraceful:
137 break;
138 default:
139 sslErrorLog("SSLWrite: going to state errorClose due to err %d\n",
140 (int)err);
141 SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
142 break;
143 }
144 abort:
145 sslIoTrace(ctx, "SSLWrite(2)", dataLength, *bytesWritten, err);
146 return err;
147 }
148
149 OSStatus
150 SSLRead (
151 SSLContext *ctx,
152 void * data,
153 size_t dataLength,
154 size_t *processed) /* RETURNED */
155 {
156 OSStatus err;
157 uint8_t *charPtr;
158 size_t bufSize, remaining, count;
159 SSLRecord rec;
160
161 sslLogRecordIo("[%p] SSLRead top (dataLength=%ld)", ctx, dataLength);
162 if((ctx == NULL) || (data == NULL) || (processed == NULL)) {
163 return errSecParam;
164 }
165 bufSize = dataLength;
166 *processed = 0; /* Initialize in case we return with errSSLWouldBlock */
167
168 readRetry:
169 /* first handle cases in which we know we're finished */
170 switch(ctx->state) {
171 case SSL_HdskStateGracefulClose:
172 err = errSSLClosedGraceful;
173 goto abort;
174 case SSL_HdskStateErrorClose:
175 err = errSSLClosedAbort;
176 goto abort;
177 case SSL_HdskStateNoNotifyClose:
178 err = errSSLClosedNoNotify;
179 goto abort;
180 default:
181 break;
182 }
183
184 /* First, we have to wait until the session is ready to receive data,
185 so the encryption keys and such have been established. */
186 while (ctx->readCipher_ready == 0) {
187 if ((err = SSLHandshakeProceed(ctx)) != 0) {
188 goto exit;
189 }
190 }
191
192 /* Need this to handle the case were SSLRead returned
193 errSSLClientHelloReceived as readCipher_ready is not set yet in that case */
194 if ((err = tls_handshake_continue(ctx->hdsk)) != 0)
195 return err;
196
197 /* Attempt to service the write queue */
198 if ((err = SSLServiceWriteQueue(ctx)) != 0) {
199 if (err != errSSLWouldBlock) {
200 goto exit;
201 }
202 }
203
204 remaining = bufSize;
205 charPtr = (uint8_t *)data;
206
207 /* If we have data in the buffer, use that first */
208 if (ctx->receivedDataBuffer.data)
209 {
210 count = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
211 if (count > bufSize)
212 count = bufSize;
213 memcpy(data, ctx->receivedDataBuffer.data + ctx->receivedDataPos, count);
214 remaining -= count;
215 charPtr += count;
216 *processed += count;
217 ctx->receivedDataPos += count;
218 }
219
220 assert(ctx->receivedDataPos <= ctx->receivedDataBuffer.length);
221 assert(*processed + remaining == bufSize);
222 assert(charPtr == ((uint8_t *)data) + *processed);
223
224 if (ctx->receivedDataBuffer.data != 0 &&
225 ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
226 {
227 SSLFreeBuffer(&ctx->receivedDataBuffer);
228 ctx->receivedDataBuffer.data = 0;
229 ctx->receivedDataPos = 0;
230 }
231
232 /*
233 * If we didnt fill up the users buffer, get some more data
234 */
235 if (remaining > 0 && ctx->state != SSL_HdskStateGracefulClose)
236 {
237 assert(ctx->receivedDataBuffer.data == 0);
238 if ((err = SSLReadRecord(&rec, ctx)) != 0) {
239 goto exit;
240 }
241 if (rec.contentType == SSL_RecordTypeAppData ||
242 rec.contentType == SSL_RecordTypeV2_0)
243 {
244 if (rec.contents.length <= remaining)
245 { /* Copy all we got in the user's buffer */
246 memcpy(charPtr, rec.contents.data, rec.contents.length);
247 *processed += rec.contents.length;
248 {
249 if ((err = SSLFreeRecord(rec, ctx))) {
250 goto exit;
251 }
252 }
253 }
254 else
255 { /* Copy what we can in the user's buffer, keep the rest for next SSLRead. */
256 memcpy(charPtr, rec.contents.data, remaining);
257 *processed += remaining;
258 ctx->receivedDataBuffer = rec.contents;
259 ctx->receivedDataPos = remaining;
260 }
261 }
262 else {
263 if ((err = SSLProcessProtocolMessage(&rec, ctx)) != 0) {
264 /* This may not make much sense, but this is required so that we
265 process the write queue. This replicate exactly the behavior
266 before the coreTLS adoption */
267 if(err == errSSLClosedGraceful) {
268 SSLClose(ctx);
269 } else {
270 goto exit;
271 }
272 }
273 if ((err = SSLFreeRecord(rec, ctx))) {
274 goto exit;
275 }
276 }
277 }
278
279 err = errSecSuccess;
280
281 exit:
282 /* test for renegotiate: loop until something useful happens */
283 if(((err == errSecSuccess) && (*processed == 0) && dataLength) || (err == errSSLUnexpectedRecord)) {
284 sslLogNegotiateDebug("SSLRead recursion");
285 goto readRetry;
286 }
287 /* shut down on serious errors */
288 switch(err) {
289 case errSecSuccess:
290 case errSSLWouldBlock:
291 case errSSLUnexpectedRecord:
292 case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
293 case errSSLClientCertRequested:
294 case errSSLClientHelloReceived:
295 case errSSLClosedGraceful:
296 case errSSLClosedNoNotify:
297 break;
298 default:
299 sslErrorLog("SSLRead: going to state errorClose due to err %d\n",
300 (int)err);
301 SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
302 break;
303 }
304 abort:
305 sslIoTrace(ctx, "SSLRead returns", dataLength, *processed, err);
306 return err;
307 }
308
309 #if SSL_DEBUG
310 #include "sslCrypto.h"
311 #endif
312
313
314
315 static void get_extended_peer_id(SSLContext *ctx, tls_buffer *extended_peer_id)
316 {
317 uint8_t md[CC_SHA256_DIGEST_LENGTH];
318 __block CC_SHA256_CTX hash_ctx;
319
320 CC_SHA256_Init(&hash_ctx);
321
322 CC_SHA256_Update(&hash_ctx, &ctx->allowAnyRoot, sizeof(ctx->allowAnyRoot));
323
324 #if !TARGET_OS_IPHONE
325 if(ctx->trustedLeafCerts) {
326 CFArrayForEach(ctx->trustedLeafCerts, ^(const void *value) {
327 SecCertificateRef cert = (SecCertificateRef) value;
328 CC_SHA256_Update(&hash_ctx, SecCertificateGetBytePtr(cert), (CC_LONG)SecCertificateGetLength(cert));
329 });
330 }
331 #endif
332
333 CC_SHA256_Update(&hash_ctx, &ctx->trustedCertsOnly, sizeof(ctx->trustedCertsOnly));
334
335
336 if(ctx->trustedCerts) {
337 CFArrayForEach(ctx->trustedCerts, ^(const void *value) {
338 SecCertificateRef cert = (SecCertificateRef) value;
339 CC_SHA256_Update(&hash_ctx, SecCertificateGetBytePtr(cert), (CC_LONG)SecCertificateGetLength(cert));
340 });
341 }
342
343 CC_SHA256_Final(md, &hash_ctx);
344
345 extended_peer_id->length = ctx->peerID.length + sizeof(md);
346 extended_peer_id->data = sslMalloc(extended_peer_id->length);
347 memcpy(extended_peer_id->data, ctx->peerID.data, ctx->peerID.length);
348 memcpy(extended_peer_id->data+ctx->peerID.length, md, sizeof(md));
349 }
350
351 /* Send the initial client hello */
352 static OSStatus
353 SSLHandshakeStart(SSLContext *ctx)
354 {
355 int err;
356 tls_buffer extended_peer_id;
357 get_extended_peer_id(ctx, &extended_peer_id);
358 err = tls_handshake_negotiate(ctx->hdsk, &extended_peer_id);
359 free(extended_peer_id.data);
360 if(err)
361 return err;
362
363 ctx->readCipher_ready = 0;
364 ctx->writeCipher_ready = 0;
365 SSLChangeHdskState(ctx, SSL_HdskStatePending);
366
367 return noErr;
368 }
369
370 OSStatus
371 SSLReHandshake(SSLContext *ctx)
372 {
373 if(ctx == NULL) {
374 return errSecParam;
375 }
376
377 if (ctx->state == SSL_HdskStateGracefulClose)
378 return errSSLClosedGraceful;
379 if (ctx->state == SSL_HdskStateErrorClose)
380 return errSSLClosedAbort;
381 if (ctx->state == SSL_HdskStatePending)
382 return errSecBadReq;
383
384 /* If we are the client, we start the negotiation */
385 if(ctx->protocolSide == kSSLClientSide) {
386 return SSLHandshakeStart(ctx);
387 } else {
388 return tls_handshake_request_renegotiation(ctx->hdsk);
389 }
390 }
391
392 OSStatus
393 SSLHandshake(SSLContext *ctx)
394 {
395 OSStatus err;
396
397 if(ctx == NULL) {
398 return errSecParam;
399 }
400 if (ctx->state == SSL_HdskStateGracefulClose)
401 return errSSLClosedGraceful;
402 if (ctx->state == SSL_HdskStateErrorClose)
403 return errSSLClosedAbort;
404
405 if(ctx->isDTLS && ctx->timeout_deadline) {
406 CFAbsoluteTime current = CFAbsoluteTimeGetCurrent();
407
408 if (ctx->timeout_deadline<current) {
409 sslDebugLog("%p, retransmition deadline expired\n", ctx);
410 err = tls_handshake_retransmit_timer_expired(ctx->hdsk);
411 if(err) {
412 return err;
413 }
414 }
415 }
416
417 /* Initial Client Hello */
418 if(ctx->state==SSL_HdskStateUninit) {
419 /* If we are the client, we start the negotiation */
420 if(ctx->protocolSide == kSSLClientSide) {
421 err = SSLHandshakeStart(ctx);
422 if(err) {
423 return err;
424 }
425 }
426 SSLChangeHdskState(ctx, SSL_HdskStatePending);
427 }
428
429 do {
430 err = SSLHandshakeProceed(ctx);
431 if((err != 0) && (err != errSSLUnexpectedRecord))
432 return err;
433 } while (ctx->readCipher_ready == 0 || ctx->writeCipher_ready == 0);
434
435 /* one more flush at completion of successful handshake */
436 if ((err = SSLServiceWriteQueue(ctx)) != 0) {
437 return err;
438 }
439
440 return errSecSuccess;
441 }
442
443 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
444
445 #include "SecADWrapper.h"
446
447 static void ad_log_SecureTransport_early_fail(long signature)
448 {
449 CFStringRef key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("com.apple.SecureTransport.early_fail.%ld"), signature);
450
451 if (key) {
452 SecADAddValueForScalarKey(key, 1);
453 CFRelease(key);
454 }
455 }
456
457 #endif
458
459
460 #if (!TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
461
462 #include <msgtracer_client.h>
463
464 static void mt_log_SecureTransport_early_fail(long signature)
465 {
466 char signature_string[16];
467
468 snprintf(signature_string, sizeof(signature_string), "%ld", signature);
469
470 msgtracer_log_with_keys("com.apple.SecureTransport.early_fail", ASL_LEVEL_NOTICE,
471 "com.apple.message.signature", signature_string,
472 "com.apple.message.summarize", "YES",
473 NULL);
474 }
475
476 #endif
477
478
479 static void log_SecureTransport_early_fail(long signature)
480 {
481 #if (!TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
482 mt_log_SecureTransport_early_fail(signature);
483 #endif
484
485 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
486 ad_log_SecureTransport_early_fail(signature);
487 #endif
488 }
489
490
491 static OSStatus
492 SSLHandshakeProceed(SSLContext *ctx)
493 {
494 OSStatus err;
495
496 if ((err = tls_handshake_continue(ctx->hdsk)) != 0)
497 return err;
498
499 if ((err = SSLServiceWriteQueue(ctx)) != 0)
500 return err;
501
502 SSLRecord rec;
503
504 err = SSLReadRecord(&rec, ctx);
505
506 if(!err) {
507 sslDebugLog("%p going to process a record (rec.len=%zd, ct=%d)\n", ctx, rec.contents.length, rec.contentType);
508 err = tls_handshake_process(ctx->hdsk, rec.contents, rec.contentType);
509 sslDebugLog("%p processed a record (rec.len=%zd, ct=%d, err=%d)\n", ctx, rec.contents.length, rec.contentType, (int)err);
510 SSLFreeRecord(rec, ctx);
511 } else if(err!=errSSLWouldBlock) {
512 sslDebugLog("%p Read error err=%d\n\n", ctx, (int)err);
513 }
514
515 if(ctx->protocolSide == kSSLClientSide &&
516 ctx->dheEnabled == false &&
517 !ctx->serverHelloReceived &&
518 err && err != errSSLWouldBlock)
519 {
520 log_SecureTransport_early_fail(err);
521 }
522
523 return err;
524 }
525
526 static OSStatus
527 SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx)
528 {
529 return tls_handshake_process(ctx->hdsk, rec->contents, rec->contentType);
530 }
531
532 OSStatus
533 SSLClose(SSLContext *ctx)
534 {
535 OSStatus err = errSecSuccess;
536
537 sslHdskStateDebug("SSLClose");
538 if(ctx == NULL) {
539 return errSecParam;
540 }
541
542 err = tls_handshake_close(ctx->hdsk);
543
544 if (err == 0)
545 err = SSLServiceWriteQueue(ctx);
546
547 SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
548 if (err == errSecIO)
549 err = errSecSuccess; /* Ignore errors related to closed streams */
550 return err;
551 }
552
553 /*
554 * Determine how much data the client can be guaranteed to
555 * obtain via SSLRead() without blocking or causing any low-level
556 * read operations to occur.
557 *
558 * Implemented here because the relevant info in SSLContext (receivedDataBuffer
559 * and receivedDataPos) are only used in this file.
560 */
561 OSStatus
562 SSLGetBufferedReadSize(SSLContextRef ctx,
563 size_t *bufSize) /* RETURNED */
564 {
565 if(ctx == NULL) {
566 return errSecParam;
567 }
568 if(ctx->receivedDataBuffer.data == NULL) {
569 *bufSize = 0;
570 }
571 else {
572 assert(ctx->receivedDataBuffer.length >= ctx->receivedDataPos);
573 *bufSize = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
574 }
575 return errSecSuccess;
576 }