1/* 2 * Copyright (c) 1999-2001,2005-2007,2010-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 * sslRecord.c - Encryption, decryption and MACing of data 26*/ 27 28#include <SecureTransport.h> 29#include "ssl.h" 30#include "sslRecord.h" 31#include "sslMemory.h" 32#include "sslContext.h" 33#include "sslAlertMessage.h" 34#include "sslDebug.h" 35#include "sslUtils.h" 36#include "sslDigests.h" 37#include "SSLRecordInternal.h" 38 39#include <string.h> 40#include <assert.h> 41 42#include <utilities/SecIOFormat.h> 43 44/* 45 * Lots of servers fail to provide closure alerts when they disconnect. 46 * For now we'll just accept it as long as it occurs on a clean record boundary 47 * (and the handshake is complete). 48 */ 49#define SSL_ALLOW_UNNOTICED_DISCONNECT 1 50 51 52static OSStatus errorTranslate(int recordErr) 53{ 54 switch(recordErr) { 55 case errSecSuccess: 56 return errSecSuccess; 57 case errSSLRecordInternal: 58 return errSSLInternal; 59 case errSSLRecordWouldBlock: 60 return errSSLWouldBlock; 61 case errSSLRecordProtocol: 62 return errSSLProtocol; 63 case errSSLRecordNegotiation: 64 return errSSLNegotiation; 65 case errSSLRecordClosedAbort: 66 return errSSLClosedAbort; 67 case errSSLRecordConnectionRefused: 68 return errSSLConnectionRefused; 69 case errSSLRecordDecryptionFail: 70 return errSSLDecryptionFail; 71 case errSSLRecordBadRecordMac: 72 return errSSLBadRecordMac; 73 case errSSLRecordRecordOverflow: 74 return errSSLRecordOverflow; 75 case errSSLRecordUnexpectedRecord: 76 return errSSLUnexpectedRecord; 77 default: 78 sslErrorLog("unknown error code returned in sslErrorTranslate: %d\n", recordErr); 79 return recordErr; 80 } 81} 82 83/* SSLWriteRecord 84 * Attempt to encrypt and queue an SSL record. 85 */ 86OSStatus 87SSLWriteRecord(SSLRecord rec, SSLContext *ctx) 88{ 89 OSStatus err; 90 91 err=errorTranslate(ctx->recFuncs->write(ctx->recCtx, rec)); 92 93 switch(err) { 94 case errSecSuccess: 95 break; 96 default: 97 sslErrorLog("unexpected error code returned in SSLWriteRecord: %d\n", (int)err); 98 break; 99 } 100 101 return err; 102} 103 104/* SSLFreeRecord 105 * Free a record returned by SSLReadRecord. 106 */ 107OSStatus 108SSLFreeRecord(SSLRecord rec, SSLContext *ctx) 109{ 110 return ctx->recFuncs->free(ctx->recCtx, rec); 111} 112 113/* SSLReadRecord 114 * Attempt to read & decrypt an SSL record. 115 * Record content should be freed using SSLFreeRecord 116 */ 117OSStatus 118SSLReadRecord(SSLRecord *rec, SSLContext *ctx) 119{ 120 return errorTranslate(ctx->recFuncs->read(ctx->recCtx, rec)); 121} 122 123OSStatus SSLServiceWriteQueue(SSLContext *ctx) 124{ 125 return errorTranslate(ctx->recFuncs->serviceWriteQueue(ctx->recCtx)); 126} 127