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
); 
  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 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer sessionData
) 
 202     int err 
= errSSLSessionNotFound
; 
 203     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 205     sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__
, myCtx
, sessionKey
.length
, sessionKey
.data
[0], sessionData
.length
); 
 208         err 
= tls_cache_save_session_data(myCtx
->cache
, &sessionKey
, &sessionData
, myCtx
->sessionCacheTimeout
); 
 214 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer 
*sessionData
) 
 216     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 217     int err 
= errSSLSessionNotFound
; 
 219     SSLFreeBuffer(&myCtx
->resumableSession
); 
 221         err 
= tls_cache_load_session_data(myCtx
->cache
, &sessionKey
, &myCtx
->resumableSession
); 
 223     sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx
, sessionKey
.length
, sessionData
->length
, err
); 
 224     *sessionData 
= myCtx
->resumableSession
; 
 230 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
) 
 232     int err 
= errSSLSessionNotFound
; 
 233     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 235     sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx
, sessionKey
.length
, sessionKey
.data
[0]); 
 237         err 
= tls_cache_delete_session_data(myCtx
->cache
, &sessionKey
); 
 243 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx
) 
 245     SSLContext 
*myCtx 
= (SSLContext 
*)ctx
; 
 246     sslDebugLog("%p\n", ctx
); 
 249         tls_cache_empty(myCtx
->cache
); 
 254 tls_handshake_callbacks_t tls_handshake_callbacks 
= { 
 255     .write 
= tls_handshake_write_callback
, 
 256     .message 
= tls_handshake_message_callback
, 
 257     .ready 
= tls_handshake_ready_callback
, 
 258     .set_retransmit_timer 
= tls_handshake_set_retransmit_timer_callback
, 
 259     .save_session_data 
= tls_handshake_save_session_data_callback
, 
 260     .load_session_data 
= tls_handshake_load_session_data_callback
, 
 261     .delete_session_data 
= tls_handshake_delete_session_data_callback
, 
 262     .delete_all_sessions 
= tls_handshake_delete_all_sessions_callback
, 
 263     .init_pending_cipher 
= tls_handshake_init_pending_cipher_callback
, 
 264     .advance_write_cipher 
= tls_handshake_advance_write_callback
, 
 265     .rollback_write_cipher 
= tls_handshake_rollback_write_callback
, 
 266     .advance_read_cipher 
= tls_handshake_advance_read_cipher_callback
, 
 267     .set_protocol_version 
= tls_handshake_set_protocol_version_callback
,