1/* 2 * Copyright (c) 1999-2001,2005-2007,2010-2012 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 * sslHandshakeFinish.c - Finished and server hello done messages. 26 */ 27 28#include "sslContext.h" 29#include "sslHandshake.h" 30#include "sslMemory.h" 31#include "sslDebug.h" 32#include "sslUtils.h" 33#include "sslDigests.h" 34 35#include <string.h> 36#include <assert.h> 37 38OSStatus 39SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx) 40{ OSStatus err; 41 SSLBuffer finishedMsg; 42 Boolean isServerMsg; 43 unsigned finishedSize; 44 UInt8 *p; 45 int head; 46 47 /* size and version depend on negotiatedProtocol */ 48 switch(ctx->negProtocolVersion) { 49 case SSL_Version_3_0: 50 finishedSize = 36; 51 break; 52 case DTLS_Version_1_0: 53 case TLS_Version_1_0: 54 case TLS_Version_1_1: 55 case TLS_Version_1_2: /* TODO: Support variable finishedSize. */ 56 finishedSize = 12; 57 break; 58 default: 59 assert(0); 60 return errSSLInternal; 61 } 62 finished->protocolVersion = ctx->negProtocolVersion; 63 64 finished->contentType = SSL_RecordTypeHandshake; 65 /* msg = type + 3 bytes len + finishedSize */ 66 head = SSLHandshakeHeaderSize(finished); 67 if ((err = SSLAllocBuffer(&finished->contents, finishedSize + head)) != 0) 68 return err; 69 70 p = SSLEncodeHandshakeHeader(ctx, finished, SSL_HdskFinished, finishedSize); 71 72 finishedMsg.data = p; 73 finishedMsg.length = finishedSize; 74 75 isServerMsg = (ctx->protocolSide == kSSLServerSide) ? true : false; 76 err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg, isServerMsg); 77 78 if(err) 79 return err; 80 81 /* Keep this around for secure renegotiation */ 82 SSLFreeBuffer(&ctx->ownVerifyData); 83 return SSLCopyBuffer(&finishedMsg, &ctx->ownVerifyData); 84} 85 86OSStatus 87SSLProcessFinished(SSLBuffer message, SSLContext *ctx) 88{ OSStatus err; 89 SSLBuffer expectedFinished; 90 Boolean isServerMsg; 91 unsigned finishedSize; 92 93 switch(ctx->negProtocolVersion) { 94 case SSL_Version_3_0: 95 finishedSize = 36; 96 break; 97 case DTLS_Version_1_0: 98 case TLS_Version_1_0: 99 case TLS_Version_1_1: 100 case TLS_Version_1_2: /* TODO: Support variable finishedSize. */ 101 finishedSize = 12; 102 break; 103 default: 104 assert(0); 105 return errSSLInternal; 106 } 107 if (message.length != finishedSize) { 108 sslErrorLog("SSLProcessFinished: msg len error 1\n"); 109 return errSSLProtocol; 110 } 111 expectedFinished.data = 0; 112 if ((err = SSLAllocBuffer(&expectedFinished, finishedSize))) 113 return err; 114 isServerMsg = (ctx->protocolSide == kSSLServerSide) ? false : true; 115 if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished, isServerMsg)) != 0) 116 goto fail; 117 118 if (memcmp(expectedFinished.data, message.data, finishedSize) != 0) 119 { 120 sslErrorLog("SSLProcessFinished: memcmp failure\n"); 121 err = errSSLProtocol; 122 goto fail; 123 } 124 125 /* Keep this around for secure renegotiation */ 126 SSLFreeBuffer(&ctx->peerVerifyData); 127 err = SSLCopyBuffer(&expectedFinished, &ctx->peerVerifyData); 128 129fail: 130 SSLFreeBuffer(&expectedFinished); 131 return err; 132} 133 134OSStatus 135SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx) 136{ OSStatus err; 137 int head; 138 139 helloDone->contentType = SSL_RecordTypeHandshake; 140 assert(ctx->negProtocolVersion >= SSL_Version_3_0); 141 helloDone->protocolVersion = ctx->negProtocolVersion; 142 head = SSLHandshakeHeaderSize(helloDone); 143 if ((err = SSLAllocBuffer(&helloDone->contents, head))) 144 return err; 145 146 SSLEncodeHandshakeHeader(ctx, helloDone, SSL_HdskServerHelloDone, 0); /* Message has 0 length */ 147 148 return errSecSuccess; 149} 150 151OSStatus 152SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx) 153{ assert(ctx->protocolSide == kSSLClientSide); 154 if (message.length != 0) { 155 sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n"); 156 return errSSLProtocol; 157 } 158 return errSecSuccess; 159} 160