]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_ssl/lib/sslTransport.c
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurity_ssl / lib / sslTransport.c
1 /*
2 * Copyright (c) 1999-2001,2005-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * sslTransport.c - SSL transport layer
26 */
27
28 #include "ssl.h"
29 #include "sslMemory.h"
30 #include "sslContext.h"
31 #include "sslRecord.h"
32 #include "sslAlertMessage.h"
33 #include "sslSession.h"
34 #include "sslDebug.h"
35 #include "sslCipherSpecs.h"
36 #include "sslUtils.h"
37
38 #include <assert.h>
39 #include <string.h>
40
41 #include <utilities/SecIOFormat.h>
42
43 #ifndef NDEBUG
44 static inline void sslIoTrace(
45 SSLContext *ctx,
46 const char *op,
47 size_t req,
48 size_t moved,
49 OSStatus stat)
50 {
51 sslLogRecordIo("[%p] ===%s: req %4lu moved %4lu status %d",
52 ctx, op, req, moved, (int)stat);
53 }
54 #else
55 #define sslIoTrace(ctx, op, req, moved, stat)
56 #endif /* NDEBUG */
57
58 extern int kSplitDefaultValue;
59
60 static OSStatus SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx);
61 static OSStatus SSLHandshakeProceed(SSLContext *ctx);
62 //static OSStatus SSLInitConnection(SSLContext *ctx);
63
64 OSStatus
65 SSLWrite(
66 SSLContext *ctx,
67 const void * data,
68 size_t dataLength,
69 size_t *bytesWritten) /* RETURNED */
70 {
71 OSStatus err;
72 SSLRecord rec;
73 size_t dataLen, processed;
74
75 sslLogRecordIo("[%p] SSLWrite top", ctx);
76 if((ctx == NULL) || (bytesWritten == NULL)) {
77 return errSecParam;
78 }
79 dataLen = dataLength;
80 processed = 0; /* Initialize in case we return with errSSLWouldBlock */
81 *bytesWritten = 0;
82
83 switch(ctx->state) {
84 case SSL_HdskStateGracefulClose:
85 err = errSSLClosedGraceful;
86 goto abort;
87 case SSL_HdskStateErrorClose:
88 err = errSSLClosedAbort;
89 goto abort;
90 case SSL_HdskStateReady:
91 break;
92 case SSL_HdskStateUninit:
93 /* not ready for I/O, and handshake not in progress */
94 sslIoTrace(ctx, "SSLWrite(1)", dataLength, 0, errSecBadReq);
95 return errSecBadReq;
96 default:
97 /* handshake in progress or done. Will call SSLHandshakeProceed below if necessary */
98 break;
99 }
100
101 /* First, we have to wait until the session is ready to send data,
102 so the encryption keys and such have been established. */
103 err = errSecSuccess;
104 while (!(ctx->writeCipher_ready))
105 { if ((err = SSLHandshakeProceed(ctx)) != 0)
106 goto exit;
107 }
108
109 /* Attempt to empty the write queue before queueing more data */
110 if ((err = SSLServiceWriteQueue(ctx)) != 0)
111 goto abort;
112
113 processed = 0;
114
115 /* Skip empty writes, fragmentation is done at the coreTLS layer */
116 if(dataLen) {
117 rec.contentType = SSL_RecordTypeAppData;
118 rec.protocolVersion = ctx->negProtocolVersion;
119 rec.contents.data = ((uint8_t *)data) + processed;
120 rec.contents.length = dataLen;
121 if ((err = SSLWriteRecord(rec, ctx)) != 0)
122 goto exit;
123 processed += rec.contents.length;
124 }
125
126 /* All the data has been advanced to the write queue */
127 *bytesWritten = processed;
128 if ((err = SSLServiceWriteQueue(ctx)) == 0) {
129 err = errSecSuccess;
130 }
131 exit:
132 switch(err) {
133 case errSecSuccess:
134 case errSSLWouldBlock:
135 case errSSLUnexpectedRecord:
136 case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
137 case errSSLClientCertRequested:
138 case errSSLClosedGraceful:
139 break;
140 default:
141 sslErrorLog("SSLWrite: going to state errorClose due to err %d\n",
142 (int)err);
143 SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
144 break;
145 }
146 abort:
147 sslIoTrace(ctx, "SSLWrite(2)", dataLength, *bytesWritten, err);
148 return err;
149 }
150
151 OSStatus
152 SSLRead (
153 SSLContext *ctx,
154 void * data,
155 size_t dataLength,
156 size_t *processed) /* RETURNED */
157 {
158 OSStatus err;
159 uint8_t *charPtr;
160 size_t bufSize, remaining, count;
161 SSLRecord rec;
162
163 sslLogRecordIo("[%p] SSLRead top (dataLength=%ld)", ctx, dataLength);
164 if((ctx == NULL) || (data == NULL) || (processed == NULL)) {
165 return errSecParam;
166 }
167 bufSize = dataLength;
168 *processed = 0; /* Initialize in case we return with errSSLWouldBlock */
169
170 readRetry:
171 /* first handle cases in which we know we're finished */
172 switch(ctx->state) {
173 case SSL_HdskStateGracefulClose:
174 err = errSSLClosedGraceful;
175 goto abort;
176 case SSL_HdskStateErrorClose:
177 err = errSSLClosedAbort;
178 goto abort;
179 case SSL_HdskStateNoNotifyClose:
180 err = errSSLClosedNoNotify;
181 goto abort;
182 default:
183 break;
184 }
185
186 /* First, we have to wait until the session is ready to receive data,
187 so the encryption keys and such have been established. */
188 err = errSecSuccess;
189 while (ctx->readCipher_ready == 0) {
190 if ((err = SSLHandshakeProceed(ctx)) != 0) {
191 goto exit;
192 }
193 }
194
195 /* Attempt to service the write queue */
196 if ((err = SSLServiceWriteQueue(ctx)) != 0) {
197 if (err != errSSLWouldBlock) {
198 goto exit;
199 }
200 err = errSecSuccess; /* Write blocking shouldn't stop attempts to read */
201 }
202
203 remaining = bufSize;
204 charPtr = (uint8_t *)data;
205 if (ctx->receivedDataBuffer.data)
206 { count = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
207 if (count > bufSize)
208 count = bufSize;
209 memcpy(data, ctx->receivedDataBuffer.data + ctx->receivedDataPos, count);
210 remaining -= count;
211 charPtr += count;
212 *processed += count;
213 ctx->receivedDataPos += count;
214 }
215
216 assert(ctx->receivedDataPos <= ctx->receivedDataBuffer.length);
217 assert(*processed + remaining == bufSize);
218 assert(charPtr == ((uint8_t *)data) + *processed);
219
220 if (ctx->receivedDataBuffer.data != 0 &&
221 ctx->receivedDataPos >= ctx->receivedDataBuffer.length)
222 { SSLFreeBuffer(&ctx->receivedDataBuffer);
223 ctx->receivedDataBuffer.data = 0;
224 ctx->receivedDataPos = 0;
225 }
226
227 /*
228 * This while statement causes a hang when using nonblocking low-level I/O!
229 while (remaining > 0 && ctx->state != SSL_HdskStateGracefulClose)
230 ..what we really have to do is just return as soon as we read one
231 record. A performance hit in the nonblocking case, but that is
232 the only way this code can work in both modes...
233 */
234 if (remaining > 0 && ctx->state != SSL_HdskStateGracefulClose)
235 { assert(ctx->receivedDataBuffer.data == 0);
236 if ((err = SSLReadRecord(&rec, ctx)) != 0) {
237 goto exit;
238 }
239 if (rec.contentType == SSL_RecordTypeAppData ||
240 rec.contentType == SSL_RecordTypeV2_0)
241 { if (rec.contents.length <= remaining)
242 { memcpy(charPtr, rec.contents.data, rec.contents.length);
243 remaining -= rec.contents.length;
244 charPtr += rec.contents.length;
245 *processed += rec.contents.length;
246 {
247 if ((err = SSLFreeRecord(rec, ctx))) {
248 goto exit;
249 }
250 }
251 }
252 else
253 { memcpy(charPtr, rec.contents.data, remaining);
254 charPtr += remaining;
255 *processed += remaining;
256 ctx->receivedDataBuffer = rec.contents;
257 ctx->receivedDataPos = remaining;
258 remaining = 0;
259 }
260 }
261 else {
262 if ((err = SSLProcessProtocolMessage(&rec, ctx)) != 0) {
263 /* This may not make much sense, but this is required so that we
264 process the write queue. This replicate exactly the behavior
265 before the coreTLS adoption */
266 if(err == errSSLClosedGraceful) {
267 err = SSLClose(ctx);
268 } else {
269 goto exit;
270 }
271 }
272 if ((err = SSLFreeRecord(rec, ctx))) {
273 goto exit;
274 }
275 }
276 }
277
278 err = errSecSuccess;
279
280 exit:
281 /* test for renegotiate: loop until something useful happens */
282 if(((err == errSecSuccess) && (*processed == 0) && dataLength) || (err == errSSLUnexpectedRecord)) {
283 sslLogNegotiateDebug("SSLRead recursion");
284 goto readRetry;
285 }
286 /* shut down on serious errors */
287 switch(err) {
288 case errSecSuccess:
289 case errSSLWouldBlock:
290 case errSSLUnexpectedRecord:
291 case errSSLServerAuthCompleted: /* == errSSLClientAuthCompleted */
292 case errSSLClientCertRequested:
293 case errSSLClosedGraceful:
294 case errSSLClosedNoNotify:
295 break;
296 default:
297 sslErrorLog("SSLRead: going to state errorClose due to err %d\n",
298 (int)err);
299 SSLChangeHdskState(ctx, SSL_HdskStateErrorClose);
300 break;
301 }
302 abort:
303 sslIoTrace(ctx, "SSLRead returns", dataLength, *processed, err);
304 return err;
305 }
306
307 #if SSL_DEBUG
308 #include "sslCrypto.h"
309 #endif
310
311 OSStatus
312 SSLHandshake(SSLContext *ctx)
313 {
314 OSStatus err;
315
316 if(ctx == NULL) {
317 return errSecParam;
318 }
319 if (ctx->state == SSL_HdskStateGracefulClose)
320 return errSSLClosedGraceful;
321 if (ctx->state == SSL_HdskStateErrorClose)
322 return errSSLClosedAbort;
323
324 if(ctx->validCipherSuites == NULL) {
325 /* build list of legal cipherSpecs */
326 err = sslBuildCipherSuiteArray(ctx);
327 if(err) {
328 return err;
329 }
330 }
331
332 err = errSecSuccess;
333
334 if(ctx->isDTLS && ctx->timeout_deadline) {
335 CFAbsoluteTime current = CFAbsoluteTimeGetCurrent();
336
337 if (ctx->timeout_deadline<current) {
338 sslDebugLog("%p, retransmition deadline expired\n", ctx);
339 err = tls_handshake_retransmit_timer_expired(ctx->hdsk);
340 if(err) {
341 return err;
342 }
343 }
344 }
345
346 while (ctx->readCipher_ready == 0 || ctx->writeCipher_ready == 0)
347 {
348 err = SSLHandshakeProceed(ctx);
349 if((err != 0) && (err != errSSLUnexpectedRecord))
350 return err;
351 }
352
353 /* one more flush at completion of successful handshake */
354 if ((err = SSLServiceWriteQueue(ctx)) != 0) {
355 return err;
356 }
357
358 return errSecSuccess;
359 }
360
361
362 static OSStatus
363 SSLHandshakeProceed(SSLContext *ctx)
364 {
365 OSStatus err;
366
367
368 if(ctx->state==SSL_HdskStateUninit) {
369 /* If we are the client, we start the negotiation */
370 if(ctx->protocolSide == kSSLClientSide) {
371 err = tls_handshake_negotiate(ctx->hdsk, &ctx->peerID);
372 if(err)
373 return err;
374 }
375 SSLChangeHdskState(ctx, SSL_HdskStatePending);
376 }
377
378 if ((err = tls_handshake_continue(ctx->hdsk)) != 0)
379 return err;
380
381 if ((err = SSLServiceWriteQueue(ctx)) != 0)
382 return err;
383
384 SSLRecord rec;
385
386 err = SSLReadRecord(&rec, ctx);
387
388 if(!err) {
389 sslDebugLog("%p going to process a record (rec.len=%zd, ct=%d)\n", ctx, rec.contents.length, rec.contentType);
390 err = tls_handshake_process(ctx->hdsk, rec.contents, rec.contentType);
391 sslDebugLog("%p processed a record (rec.len=%zd, ct=%d, err=%d)\n", ctx, rec.contents.length, rec.contentType, (int)err);
392 SSLFreeRecord(rec, ctx);
393 } else if(err!=errSSLWouldBlock) {
394 sslDebugLog("%p Read error err=%d\n\n", ctx, (int)err);
395 }
396
397 return err;
398 }
399
400 static OSStatus
401 SSLProcessProtocolMessage(SSLRecord *rec, SSLContext *ctx)
402 {
403 return tls_handshake_process(ctx->hdsk, rec->contents, rec->contentType);
404 }
405
406 OSStatus
407 SSLClose(SSLContext *ctx)
408 {
409 OSStatus err = errSecSuccess;
410
411 sslHdskStateDebug("SSLClose");
412 if(ctx == NULL) {
413 return errSecParam;
414 }
415
416 err = tls_handshake_close(ctx->hdsk);
417
418 if (err == 0)
419 err = SSLServiceWriteQueue(ctx);
420
421 SSLChangeHdskState(ctx, SSL_HdskStateGracefulClose);
422 if (err == errSecIO)
423 err = errSecSuccess; /* Ignore errors related to closed streams */
424 return err;
425 }
426
427 /*
428 * Determine how much data the client can be guaranteed to
429 * obtain via SSLRead() without blocking or causing any low-level
430 * read operations to occur.
431 *
432 * Implemented here because the relevant info in SSLContext (receivedDataBuffer
433 * and receivedDataPos) are only used in this file.
434 */
435 OSStatus
436 SSLGetBufferedReadSize(SSLContextRef ctx,
437 size_t *bufSize) /* RETURNED */
438 {
439 if(ctx == NULL) {
440 return errSecParam;
441 }
442 if(ctx->receivedDataBuffer.data == NULL) {
443 *bufSize = 0;
444 }
445 else {
446 assert(ctx->receivedDataBuffer.length >= ctx->receivedDataPos);
447 *bufSize = ctx->receivedDataBuffer.length - ctx->receivedDataPos;
448 }
449 return errSecSuccess;
450 }