2 * Copyright (c) 1999-2001,2005-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * sslTransport.c - SSL transport layer
29 #include "sslMemory.h"
30 #include "sslContext.h"
31 #include "sslRecord.h"
33 #include "sslCipherSpecs.h"
38 #include <utilities/SecIOFormat.h>
39 #include <utilities/SecCFWrappers.h>
41 #include <CommonCrypto/CommonDigest.h>
42 #include <Security/SecCertificatePriv.h>
45 static inline void sslIoTrace(
52 sslLogRecordIo("[%p] ===%s: req %4lu moved %4lu status %d",
53 ctx
, op
, req
, moved
, (int)stat
);
56 #define sslIoTrace(ctx, op, req, moved, stat)
59 extern int kSplitDefaultValue
;
61 static OSStatus
SSLProcessProtocolMessage(SSLRecord
*rec
, SSLContext
*ctx
);
62 static OSStatus
SSLHandshakeProceed(SSLContext
*ctx
);
69 size_t *bytesWritten
) /* RETURNED */
73 size_t dataLen
, processed
;
75 sslLogRecordIo("[%p] SSLWrite top", ctx
);
76 if((ctx
== NULL
) || (bytesWritten
== NULL
)) {
83 case SSL_HdskStateGracefulClose
:
84 err
= errSSLClosedGraceful
;
86 case SSL_HdskStateErrorClose
:
87 err
= errSSLClosedAbort
;
89 case SSL_HdskStateReady
:
91 case SSL_HdskStateUninit
:
92 /* not ready for I/O, and handshake not in progress */
93 sslIoTrace(ctx
, "SSLWrite(1)", dataLength
, 0, errSecBadReq
);
96 /* handshake in progress or done. Will call SSLHandshakeProceed below if necessary */
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)
107 /* Attempt to empty the write queue before queueing more data */
108 if ((err
= SSLServiceWriteQueue(ctx
)) != 0)
113 /* Skip empty writes, fragmentation is done at the coreTLS layer */
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)
120 processed
+= rec
.contents
.length
;
123 /* All the data has been advanced to the write queue */
124 *bytesWritten
= processed
;
125 if ((err
= SSLServiceWriteQueue(ctx
)) == 0) {
131 case errSSLWouldBlock
:
132 case errSSLUnexpectedRecord
:
133 case errSSLServerAuthCompleted
: /* == errSSLClientAuthCompleted */
134 case errSSLClientCertRequested
:
135 case errSSLClientHelloReceived
:
136 case errSSLClosedGraceful
:
139 sslErrorLog("SSLWrite: going to state errorClose due to err %d\n",
141 SSLChangeHdskState(ctx
, SSL_HdskStateErrorClose
);
145 sslIoTrace(ctx
, "SSLWrite(2)", dataLength
, *bytesWritten
, err
);
154 size_t *processed
) /* RETURNED */
158 size_t bufSize
, remaining
, count
;
161 sslLogRecordIo("[%p] SSLRead top (dataLength=%ld)", ctx
, dataLength
);
162 if((ctx
== NULL
) || (data
== NULL
) || (processed
== NULL
)) {
165 bufSize
= dataLength
;
166 *processed
= 0; /* Initialize in case we return with errSSLWouldBlock */
169 /* first handle cases in which we know we're finished */
171 case SSL_HdskStateGracefulClose
:
172 err
= errSSLClosedGraceful
;
174 case SSL_HdskStateErrorClose
:
175 err
= errSSLClosedAbort
;
177 case SSL_HdskStateNoNotifyClose
:
178 err
= errSSLClosedNoNotify
;
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) {
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)
197 /* Attempt to service the write queue */
198 if ((err
= SSLServiceWriteQueue(ctx
)) != 0) {
199 if (err
!= errSSLWouldBlock
) {
205 charPtr
= (uint8_t *)data
;
207 /* If we have data in the buffer, use that first */
208 if (ctx
->receivedDataBuffer
.data
)
210 count
= ctx
->receivedDataBuffer
.length
- ctx
->receivedDataPos
;
213 memcpy(data
, ctx
->receivedDataBuffer
.data
+ ctx
->receivedDataPos
, count
);
217 ctx
->receivedDataPos
+= count
;
220 assert(ctx
->receivedDataPos
<= ctx
->receivedDataBuffer
.length
);
221 assert(*processed
+ remaining
== bufSize
);
222 assert(charPtr
== ((uint8_t *)data
) + *processed
);
224 if (ctx
->receivedDataBuffer
.data
!= 0 &&
225 ctx
->receivedDataPos
>= ctx
->receivedDataBuffer
.length
)
227 SSLFreeBuffer(&ctx
->receivedDataBuffer
);
228 ctx
->receivedDataBuffer
.data
= 0;
229 ctx
->receivedDataPos
= 0;
233 * If we didnt fill up the users buffer, get some more data
235 if (remaining
> 0 && ctx
->state
!= SSL_HdskStateGracefulClose
)
237 assert(ctx
->receivedDataBuffer
.data
== 0);
238 if ((err
= SSLReadRecord(&rec
, ctx
)) != 0) {
241 if (rec
.contentType
== SSL_RecordTypeAppData
||
242 rec
.contentType
== SSL_RecordTypeV2_0
)
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
;
249 if ((err
= SSLFreeRecord(rec
, ctx
))) {
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
;
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
) {
273 if ((err
= SSLFreeRecord(rec
, ctx
))) {
282 /* test for renegotiate: loop until something useful happens */
283 if(((err
== errSecSuccess
) && (*processed
== 0) && dataLength
) || (err
== errSSLUnexpectedRecord
)) {
284 sslLogNegotiateDebug("SSLRead recursion");
287 /* shut down on serious errors */
290 case errSSLWouldBlock
:
291 case errSSLUnexpectedRecord
:
292 case errSSLServerAuthCompleted
: /* == errSSLClientAuthCompleted */
293 case errSSLClientCertRequested
:
294 case errSSLClientHelloReceived
:
295 case errSSLClosedGraceful
:
296 case errSSLClosedNoNotify
:
299 sslErrorLog("SSLRead: going to state errorClose due to err %d\n",
301 SSLChangeHdskState(ctx
, SSL_HdskStateErrorClose
);
305 sslIoTrace(ctx
, "SSLRead returns", dataLength
, *processed
, err
);
310 #include "sslCrypto.h"
315 static void get_extended_peer_id(SSLContext
*ctx
, tls_buffer
*extended_peer_id
)
317 uint8_t md
[CC_SHA256_DIGEST_LENGTH
];
318 __block CC_SHA256_CTX hash_ctx
;
320 CC_SHA256_Init(&hash_ctx
);
322 CC_SHA256_Update(&hash_ctx
, &ctx
->allowAnyRoot
, sizeof(ctx
->allowAnyRoot
));
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
));
333 CC_SHA256_Update(&hash_ctx
, &ctx
->trustedCertsOnly
, sizeof(ctx
->trustedCertsOnly
));
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
));
343 CC_SHA256_Final(md
, &hash_ctx
);
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
));
351 /* Send the initial client hello */
353 SSLHandshakeStart(SSLContext
*ctx
)
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
);
363 ctx
->readCipher_ready
= 0;
364 ctx
->writeCipher_ready
= 0;
365 SSLChangeHdskState(ctx
, SSL_HdskStatePending
);
371 SSLReHandshake(SSLContext
*ctx
)
377 if (ctx
->state
== SSL_HdskStateGracefulClose
)
378 return errSSLClosedGraceful
;
379 if (ctx
->state
== SSL_HdskStateErrorClose
)
380 return errSSLClosedAbort
;
381 if (ctx
->state
== SSL_HdskStatePending
)
384 /* If we are the client, we start the negotiation */
385 if(ctx
->protocolSide
== kSSLClientSide
) {
386 return SSLHandshakeStart(ctx
);
388 return tls_handshake_request_renegotiation(ctx
->hdsk
);
393 SSLHandshake(SSLContext
*ctx
)
400 if (ctx
->state
== SSL_HdskStateGracefulClose
)
401 return errSSLClosedGraceful
;
402 if (ctx
->state
== SSL_HdskStateErrorClose
)
403 return errSSLClosedAbort
;
405 if(ctx
->isDTLS
&& ctx
->timeout_deadline
) {
406 CFAbsoluteTime current
= CFAbsoluteTimeGetCurrent();
408 if (ctx
->timeout_deadline
<current
) {
409 sslDebugLog("%p, retransmition deadline expired\n", ctx
);
410 err
= tls_handshake_retransmit_timer_expired(ctx
->hdsk
);
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
);
426 SSLChangeHdskState(ctx
, SSL_HdskStatePending
);
430 err
= SSLHandshakeProceed(ctx
);
431 if((err
!= 0) && (err
!= errSSLUnexpectedRecord
))
433 } while (ctx
->readCipher_ready
== 0 || ctx
->writeCipher_ready
== 0);
435 /* one more flush at completion of successful handshake */
436 if ((err
= SSLServiceWriteQueue(ctx
)) != 0) {
440 return errSecSuccess
;
443 #if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR)
445 #include "SecADWrapper.h"
447 static void ad_log_SecureTransport_early_fail(long signature
)
449 CFStringRef key
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("com.apple.SecureTransport.early_fail.%ld"), signature
);
452 SecADAddValueForScalarKey(key
, 1);
460 #if (!TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
462 #include <msgtracer_client.h>
464 static void mt_log_SecureTransport_early_fail(long signature
)
466 char signature_string
[16];
468 snprintf(signature_string
, sizeof(signature_string
), "%ld", signature
);
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",
479 static void log_SecureTransport_early_fail(long signature
)
481 #if (!TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
482 mt_log_SecureTransport_early_fail(signature
);
485 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
486 ad_log_SecureTransport_early_fail(signature
);
492 SSLHandshakeProceed(SSLContext
*ctx
)
496 if ((err
= tls_handshake_continue(ctx
->hdsk
)) != 0)
499 if ((err
= SSLServiceWriteQueue(ctx
)) != 0)
504 err
= SSLReadRecord(&rec
, ctx
);
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
);
515 if(ctx
->protocolSide
== kSSLClientSide
&&
516 ctx
->dheEnabled
== false &&
517 !ctx
->serverHelloReceived
&&
518 err
&& err
!= errSSLWouldBlock
)
520 log_SecureTransport_early_fail(err
);
527 SSLProcessProtocolMessage(SSLRecord
*rec
, SSLContext
*ctx
)
529 return tls_handshake_process(ctx
->hdsk
, rec
->contents
, rec
->contentType
);
533 SSLClose(SSLContext
*ctx
)
535 OSStatus err
= errSecSuccess
;
537 sslHdskStateDebug("SSLClose");
542 err
= tls_handshake_close(ctx
->hdsk
);
545 err
= SSLServiceWriteQueue(ctx
);
547 SSLChangeHdskState(ctx
, SSL_HdskStateGracefulClose
);
549 err
= errSecSuccess
; /* Ignore errors related to closed streams */
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.
558 * Implemented here because the relevant info in SSLContext (receivedDataBuffer
559 * and receivedDataPos) are only used in this file.
562 SSLGetBufferedReadSize(SSLContextRef ctx
,
563 size_t *bufSize
) /* RETURNED */
568 if(ctx
->receivedDataBuffer
.data
== NULL
) {
572 assert(ctx
->receivedDataBuffer
.length
>= ctx
->receivedDataPos
);
573 *bufSize
= ctx
->receivedDataBuffer
.length
- ctx
->receivedDataPos
;
575 return errSecSuccess
;