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
;