2  * Copyright (c) 2013-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@ 
  26 #include "tlsCallbacks.h" 
  27 #include "sslContext.h" 
  28 #include "sslCrypto.h" 
  30 #include "sslMemory.h" 
  31 #include <Security/SecCertificate.h> 
  32 #include <Security/SecCertificatePriv.h> 
  33 #include "utilities/SecCFRelease.h" 
  35 #include <tls_helpers.h> 
  36 #include <tls_cache.h> 
  39 int tls_handshake_write_callback(tls_handshake_ctx_t ctx
, const SSLBuffer data
, uint8_t content_type
) 
  41     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
  42     sslDebugLog("%p (rec.len=%zd, ct=%d, d[0]=%d)\n", myCtx
, data
.length
, content_type
, data
.data
[0]); 
  47     rec
.contentType
=content_type
; 
  49     return myCtx
->recFuncs
->write(myCtx
->recCtx
,rec
); 
  54 tls_handshake_message_callback(tls_handshake_ctx_t ctx
, tls_handshake_message_t event
) 
  56     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
  57     const tls_buffer 
*npn_data
; 
  58     const tls_buffer 
*alpn_data
; 
  61     sslDebugLog("%p, message = %d\n", ctx
, event
); 
  64         case tls_handshake_message_certificate_request
: 
  65             assert(myCtx
->protocolSide 
== kSSLClientSide
); 
  66             // Need to call this here, in case SetCertificate was already called. 
  67             myCtx
->clientCertState 
= kSSLClientCertRequested
; 
  68             myCtx
->clientAuthTypes 
= tls_handshake_get_peer_acceptable_client_auth_type(myCtx
->hdsk
, &myCtx
->numAuthTypes
); 
  69             if (myCtx
->breakOnCertRequest 
&& (myCtx
->localCertArray
==NULL
)) { 
  70                 myCtx
->signalCertRequest 
= true; 
  71                 err 
= errSSLClientCertRequested
; 
  74         case tls_handshake_message_client_hello
: 
  75             myCtx
->peerSigAlgs 
= tls_handshake_get_peer_signature_algorithms(myCtx
->hdsk
, &myCtx
->numPeerSigAlgs
); 
  76             if (myCtx
->breakOnClientHello
) { 
  77                 err 
= errSSLClientHelloReceived
; 
  80         case tls_handshake_message_server_hello
: 
  81             myCtx
->serverHelloReceived 
= true; 
  82             alpn_data 
= tls_handshake_get_peer_alpn_data(myCtx
->hdsk
); 
  83             if (alpn_data 
&& myCtx
->alpnFunc 
!= NULL
) { 
  84                 myCtx
->alpnFunc(myCtx
, myCtx
->alpnFuncInfo
, alpn_data
->data
, alpn_data
->length
); 
  86                 npn_data 
= tls_handshake_get_peer_npn_data(myCtx
->hdsk
); 
  88                     myCtx
->npnFunc(myCtx
, myCtx
->npnFuncInfo
, npn_data
->data
, npn_data
->length
); 
  91             myCtx
->peerSigAlgs 
= tls_handshake_get_peer_signature_algorithms(myCtx
->hdsk
, &myCtx
->numPeerSigAlgs
); 
  93         case tls_handshake_message_certificate
: 
  94             /* For clients, we only check the cert when we receive the ServerHelloDone message. 
  95                For servers, we check the client's cert right here. For both we set the public key */ 
  96             err 
= tls_helper_set_peer_pubkey(myCtx
->hdsk
); 
  97             if(!err 
&& (myCtx
->protocolSide 
== kSSLServerSide
)) { 
  98                 err 
= tls_verify_peer_cert(myCtx
); 
 101         case tls_handshake_message_server_hello_done
: 
 102             err 
= tls_verify_peer_cert(myCtx
); 
 104         case tls_handshake_message_NPN_encrypted_extension
: 
 105             npn_data 
= tls_handshake_get_peer_npn_data(myCtx
->hdsk
); 
 107                 myCtx
->npnFunc(myCtx
, myCtx
->npnFuncInfo
, npn_data
->data
, npn_data
->length
); 
 109         case tls_handshake_message_certificate_status
: 
 119 tls_handshake_ready_callback(tls_handshake_ctx_t ctx
, bool write
, bool ready
) 
 121     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 123     sslDebugLog("%p %s ready=%d\n", myCtx
, write
?"write":"read", ready
); 
 126         myCtx
->writeCipher_ready
=ready
?1:0; 
 128         myCtx
->readCipher_ready
=ready
?1:0; 
 130             SSLChangeHdskState(myCtx
, SSL_HdskStateReady
); 
 132             SSLChangeHdskState(myCtx
, SSL_HdskStatePending
); 
 138 tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx
, int attempt
) 
 140     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 142     sslDebugLog("%p attempt=%d\n", ctx
, attempt
); 
 145         myCtx
->timeout_deadline 
= CFAbsoluteTimeGetCurrent()+((1<<(attempt
-1))*myCtx
->timeout_duration
); 
 147         myCtx
->timeout_deadline 
= 0; // cancel the timeout 
 153 tls_handshake_init_pending_cipher_callback(tls_handshake_ctx_t ctx
, 
 154                                                   uint16_t            selectedCipher
, 
 158     sslDebugLog("%p, cipher=%04x, server=%d\n", ctx
, selectedCipher
, server
); 
 159     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 160     return myCtx
->recFuncs
->initPendingCiphers(myCtx
->recCtx
, selectedCipher
, server
, key
); 
 164 tls_handshake_advance_write_callback(tls_handshake_ctx_t ctx
) 
 166     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 167     sslDebugLog("%p\n", myCtx
); 
 168     //FIXME: need to filter on cipher too - require missing coretls ciphersuite header */ 
 169     bool split 
= (myCtx
->oneByteRecordEnable 
&& (myCtx
->negProtocolVersion
<=TLS_Version_1_0
)); 
 170     myCtx
->recFuncs
->setOption(myCtx
->recCtx
, kSSLRecordOptionSendOneByteRecord
, split
); 
 171     return myCtx
->recFuncs
->advanceWriteCipher(myCtx
->recCtx
); 
 175 int tls_handshake_rollback_write_callback(tls_handshake_ctx_t ctx
) 
 177     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 178     sslDebugLog("%p\n", myCtx
); 
 179     return myCtx
->recFuncs
->rollbackWriteCipher(myCtx
->recCtx
); 
 183 int tls_handshake_advance_read_cipher_callback(tls_handshake_ctx_t ctx
) 
 185     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 186     sslDebugLog("%p\n", myCtx
); 
 187     return myCtx
->recFuncs
->advanceReadCipher(myCtx
->recCtx
); 
 191 int tls_handshake_set_protocol_version_callback(tls_handshake_ctx_t ctx
, 
 192                                       tls_protocol_version  protocolVersion
) 
 194     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 195     myCtx
->negProtocolVersion 
= protocolVersion
; 
 196     return myCtx
->recFuncs
->setProtocolVersion(myCtx
->recCtx
, protocolVersion
); 
 200 _buildConfigurationSpecificSessionCacheKey(SSLContext 
*myCtx
, SSLBuffer 
*sessionKey
, SSLBuffer 
*outputBuffer
) 
 202     SSLBuffer configurationBuffer
; 
 203     configurationBuffer
.data 
= NULL
; 
 204     configurationBuffer
.length 
= 0; 
 205     int err 
= SSLGetSessionConfigurationIdentifier(myCtx
, &configurationBuffer
); 
 206     if (err 
!= errSecSuccess
) { 
 210     outputBuffer
->length 
= configurationBuffer
.length 
+ sessionKey
->length
; 
 211     outputBuffer
->data 
= (uint8_t *) malloc(outputBuffer
->length
); 
 212     if (outputBuffer
->data 
== NULL
) { 
 213         free(configurationBuffer
.data
); 
 214         return errSecAllocate
; 
 217     memcpy(outputBuffer
->data
, configurationBuffer
.data
, configurationBuffer
.length
); 
 218     memcpy(outputBuffer
->data 
+ configurationBuffer
.length
, sessionKey
->data
, sessionKey
->length
); 
 220     free(configurationBuffer
.data
); 
 222     return errSecSuccess
; 
 226 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer sessionData
) 
 228     int err 
= errSSLSessionNotFound
; 
 229     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 231     if (myCtx
->cache 
== NULL
) { 
 232         return errSSLSessionNotFound
; 
 235     SSLBuffer configurationSpecificKey
; 
 236     configurationSpecificKey
.data 
= NULL
; 
 237     configurationSpecificKey
.length 
= 0; 
 238     err 
= _buildConfigurationSpecificSessionCacheKey(myCtx
, &sessionKey
, &configurationSpecificKey
); 
 239     if (err  
!= errSecSuccess
) { 
 243     sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__
, myCtx
, configurationSpecificKey
.length
, configurationSpecificKey
.data
[0], sessionData
.length
); 
 245     err 
= tls_cache_save_session_data(myCtx
->cache
, &configurationSpecificKey
, &sessionData
, myCtx
->sessionCacheTimeout
); 
 247     free(configurationSpecificKey
.data
); 
 253 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer 
*sessionData
) 
 255     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 256     int err 
= errSSLSessionNotFound
; 
 258     SSLFreeBuffer(&myCtx
->resumableSession
); 
 259     if (myCtx
->cache 
== NULL
) { 
 260         return errSSLSessionNotFound
; 
 263     SSLBuffer configurationSpecificKey
; 
 264     configurationSpecificKey
.data 
= NULL
; 
 265     configurationSpecificKey
.length 
= 0; 
 266     err 
= _buildConfigurationSpecificSessionCacheKey(myCtx
, &sessionKey
, &configurationSpecificKey
); 
 267     if (err  
!= errSecSuccess
) { 
 271     err 
= tls_cache_load_session_data(myCtx
->cache
, &configurationSpecificKey
, &myCtx
->resumableSession
); 
 272     sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx
, configurationSpecificKey
.length
, sessionData
->length
, err
); 
 273     *sessionData 
= myCtx
->resumableSession
; 
 275     free(configurationSpecificKey
.data
); 
 281 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
) 
 283     int err 
= errSSLSessionNotFound
; 
 284     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 286     sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx
, sessionKey
.length
, sessionKey
.data
[0]); 
 288         err 
= tls_cache_delete_session_data(myCtx
->cache
, &sessionKey
); 
 294 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx
) 
 296     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 297     sslDebugLog("%p\n", ctx
); 
 300         tls_cache_empty(myCtx
->cache
); 
 305 tls_handshake_callbacks_t tls_handshake_callbacks 
= { 
 306     .write 
= tls_handshake_write_callback
, 
 307     .message 
= tls_handshake_message_callback
, 
 308     .ready 
= tls_handshake_ready_callback
, 
 309     .set_retransmit_timer 
= tls_handshake_set_retransmit_timer_callback
, 
 310     .save_session_data 
= tls_handshake_save_session_data_callback
, 
 311     .load_session_data 
= tls_handshake_load_session_data_callback
, 
 312     .delete_session_data 
= tls_handshake_delete_session_data_callback
, 
 313     .delete_all_sessions 
= tls_handshake_delete_all_sessions_callback
, 
 314     .init_pending_cipher 
= tls_handshake_init_pending_cipher_callback
, 
 315     .advance_write_cipher 
= tls_handshake_advance_write_callback
, 
 316     .rollback_write_cipher 
= tls_handshake_rollback_write_callback
, 
 317     .advance_read_cipher 
= tls_handshake_advance_read_cipher_callback
, 
 318     .set_protocol_version 
= tls_handshake_set_protocol_version_callback
,