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 "appleSession.h"
31 #include <Security/SecCertificate.h>
32 #include <Security/SecCertificatePriv.h>
33 #include "utilities/SecCFRelease.h"
37 int tls_handshake_write_callback(tls_handshake_ctx_t ctx
, const SSLBuffer data
, uint8_t content_type
)
39 SSLContext
*myCtx
= (SSLContext
*)ctx
;
40 sslDebugLog("%p (rec.len=%zd, ct=%d, d[0]=%d)\n", myCtx
, data
.length
, content_type
, data
.data
[0]);
45 rec
.contentType
=content_type
;
47 return myCtx
->recFuncs
->write(myCtx
->recCtx
,rec
);
52 tls_handshake_message_callback(tls_handshake_ctx_t ctx
, tls_handshake_message_t event
)
54 SSLContext
*myCtx
= (SSLContext
*)ctx
;
55 const tls_buffer
*npn_data
;
57 sslDebugLog("%p, message = %d\n", ctx
, event
);
60 case tls_handshake_message_certificate_request
:
61 assert(myCtx
->protocolSide
== kSSLClientSide
);
62 // Need to call this here, in case SetCertificate was already called.
63 myCtx
->clientCertState
= kSSLClientCertRequested
;
64 myCtx
->clientAuthTypes
= tls_handshake_get_peer_acceptable_client_auth_type(myCtx
->hdsk
, &myCtx
->numAuthTypes
);
65 SSLUpdateNegotiatedClientAuthType(myCtx
);
66 if (myCtx
->breakOnCertRequest
&& (myCtx
->localCert
==NULL
))
68 myCtx
->signalCertRequest
= true;
69 return errSSLClientCertRequested
;
72 case tls_handshake_message_client_hello
:
73 myCtx
->peerSigAlgs
= tls_handshake_get_peer_signature_algorithms(myCtx
->hdsk
, &myCtx
->numPeerSigAlgs
);
75 case tls_handshake_message_server_hello
:
76 npn_data
= tls_handshake_get_peer_npn_data(myCtx
->hdsk
);
78 myCtx
->npnFunc(myCtx
, myCtx
->npnFuncInfo
, npn_data
->data
, npn_data
->length
);
79 myCtx
->peerSigAlgs
= tls_handshake_get_peer_signature_algorithms(myCtx
->hdsk
, &myCtx
->numPeerSigAlgs
);
81 case tls_handshake_message_certificate
:
82 return tls_verify_peer_cert(myCtx
);
83 case tls_handshake_message_NPN_encrypted_extension
:
84 npn_data
= tls_handshake_get_peer_npn_data(myCtx
->hdsk
);
86 myCtx
->npnFunc(myCtx
, myCtx
->npnFuncInfo
, npn_data
->data
, npn_data
->length
);
96 tls_handshake_ready_callback(tls_handshake_ctx_t ctx
, bool write
, bool ready
)
98 SSLContext
*myCtx
= (SSLContext
*)ctx
;
100 sslDebugLog("%p %s ready=%d\n", myCtx
, write
?"write":"read", ready
);
103 myCtx
->writeCipher_ready
=ready
?1:0;
105 myCtx
->readCipher_ready
=ready
?1:0;
107 SSLChangeHdskState(myCtx
, SSL_HdskStateReady
);
109 SSLChangeHdskState(myCtx
, SSL_HdskStatePending
);
115 tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx
, int attempt
)
117 SSLContext
*myCtx
= (SSLContext
*)ctx
;
119 sslDebugLog("%p attempt=%d\n", ctx
, attempt
);
122 myCtx
->timeout_deadline
= CFAbsoluteTimeGetCurrent()+((1<<(attempt
-1))*myCtx
->timeout_duration
);
124 myCtx
->timeout_deadline
= 0; // cancel the timeout
130 tls_handshake_init_pending_cipher_callback(tls_handshake_ctx_t ctx
,
131 uint16_t selectedCipher
,
135 sslDebugLog("%p, cipher=%04x, server=%d\n", ctx
, selectedCipher
, server
);
136 SSLContext
*myCtx
= (SSLContext
*)ctx
;
137 return myCtx
->recFuncs
->initPendingCiphers(myCtx
->recCtx
, selectedCipher
, server
, key
);
141 tls_handshake_advance_write_callback(tls_handshake_ctx_t ctx
)
143 SSLContext
*myCtx
= (SSLContext
*)ctx
;
144 sslDebugLog("%p\n", myCtx
);
145 //FIXME: need to filter on cipher too - require missing coretls ciphersuite header */
146 bool split
= (myCtx
->oneByteRecordEnable
&& (myCtx
->negProtocolVersion
<=TLS_Version_1_0
));
147 myCtx
->recFuncs
->setOption(myCtx
->recCtx
, kSSLRecordOptionSendOneByteRecord
, split
);
148 return myCtx
->recFuncs
->advanceWriteCipher(myCtx
->recCtx
);
152 int tls_handshake_rollback_write_callback(tls_handshake_ctx_t ctx
)
154 SSLContext
*myCtx
= (SSLContext
*)ctx
;
155 sslDebugLog("%p\n", myCtx
);
156 return myCtx
->recFuncs
->rollbackWriteCipher(myCtx
->recCtx
);
160 int tls_handshake_advance_read_cipher_callback(tls_handshake_ctx_t ctx
)
162 SSLContext
*myCtx
= (SSLContext
*)ctx
;
163 sslDebugLog("%p\n", myCtx
);
164 return myCtx
->recFuncs
->advanceReadCipher(myCtx
->recCtx
);
168 int tls_handshake_set_protocol_version_callback(tls_handshake_ctx_t ctx
,
169 tls_protocol_version protocolVersion
)
171 SSLContext
*myCtx
= (SSLContext
*)ctx
;
172 //printf("%s: %p, pv=%04x\n", __FUNCTION__, ctx, protocolVersion);
173 myCtx
->negProtocolVersion
= protocolVersion
;
174 return myCtx
->recFuncs
->setProtocolVersion(myCtx
->recCtx
, protocolVersion
);
178 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer sessionData
)
180 sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__
, (SSLContext
*)ctx
, sessionKey
.length
, sessionKey
.data
[0], sessionData
.length
);
181 return sslAddSession(sessionKey
, sessionData
, 0);
185 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer
*sessionData
)
187 SSLContext
*myCtx
= (SSLContext
*)ctx
;
190 SSLFreeBuffer(&myCtx
->resumableSession
);
191 err
= sslCopySession(sessionKey
, &myCtx
->resumableSession
);
193 sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx
, sessionKey
.length
, sessionData
->length
, err
);
195 *sessionData
= myCtx
->resumableSession
;
201 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
)
203 sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx
, sessionKey
.length
, sessionKey
.data
[0]);
204 return sslDeleteSession(sessionKey
);
208 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx
)
210 sslDebugLog("%p\n", ctx
);
212 return sslCleanupSession();
215 tls_handshake_callbacks_t tls_handshake_callbacks
= {
216 .write
= tls_handshake_write_callback
,
217 .message
= tls_handshake_message_callback
,
218 .ready
= tls_handshake_ready_callback
,
219 .set_retransmit_timer
= tls_handshake_set_retransmit_timer_callback
,
220 .save_session_data
= tls_handshake_save_session_data_callback
,
221 .load_session_data
= tls_handshake_load_session_data_callback
,
222 .delete_session_data
= tls_handshake_delete_session_data_callback
,
223 .delete_all_sessions
= tls_handshake_delete_all_sessions_callback
,
224 .init_pending_cipher
= tls_handshake_init_pending_cipher_callback
,
225 .advance_write_cipher
= tls_handshake_advance_write_callback
,
226 .rollback_write_cipher
= tls_handshake_rollback_write_callback
,
227 .advance_read_cipher
= tls_handshake_advance_read_cipher_callback
,
228 .set_protocol_version
= tls_handshake_set_protocol_version_callback
,