]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslHandshakeFinish.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / lib / sslHandshakeFinish.c
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
38 OSStatus
39 SSLEncodeFinishedMessage(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
86 OSStatus
87 SSLProcessFinished(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
129 fail:
130 SSLFreeBuffer(&expectedFinished);
131 return err;
132 }
133
134 OSStatus
135 SSLEncodeServerHelloDone(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
151 OSStatus
152 SSLProcessServerHelloDone(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 }