]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslHandshakeFinish.c
Security-55178.0.1.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,
68 ctx)) != 0)
69 return err;
70
71 p = SSLEncodeHandshakeHeader(ctx, finished, SSL_HdskFinished, finishedSize);
72
73 finishedMsg.data = p;
74 finishedMsg.length = finishedSize;
75
76 isServerMsg = (ctx->protocolSide == kSSLServerSide) ? true : false;
77 err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg, isServerMsg);
78
79 if(err)
80 return err;
81
82 /* Keep this around for secure renegotiation */
83 SSLFreeBuffer(&ctx->ownVerifyData, ctx);
84 return SSLCopyBuffer(&finishedMsg, &ctx->ownVerifyData);
85 }
86
87 OSStatus
88 SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
89 { OSStatus err;
90 SSLBuffer expectedFinished;
91 Boolean isServerMsg;
92 unsigned finishedSize;
93
94 switch(ctx->negProtocolVersion) {
95 case SSL_Version_3_0:
96 finishedSize = 36;
97 break;
98 case DTLS_Version_1_0:
99 case TLS_Version_1_0:
100 case TLS_Version_1_1:
101 case TLS_Version_1_2: /* TODO: Support variable finishedSize. */
102 finishedSize = 12;
103 break;
104 default:
105 assert(0);
106 return errSSLInternal;
107 }
108 if (message.length != finishedSize) {
109 sslErrorLog("SSLProcessFinished: msg len error 1\n");
110 return errSSLProtocol;
111 }
112 expectedFinished.data = 0;
113 if ((err = SSLAllocBuffer(&expectedFinished, finishedSize, ctx)) != 0)
114 return err;
115 isServerMsg = (ctx->protocolSide == kSSLServerSide) ? false : true;
116 if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished, isServerMsg)) != 0)
117 goto fail;
118
119 if (memcmp(expectedFinished.data, message.data, finishedSize) != 0)
120 {
121 sslErrorLog("SSLProcessFinished: memcmp failure\n");
122 err = errSSLProtocol;
123 goto fail;
124 }
125
126 /* Keep this around for secure renegotiation */
127 SSLFreeBuffer(&ctx->peerVerifyData, ctx);
128 err = SSLCopyBuffer(&expectedFinished, &ctx->peerVerifyData);
129
130 fail:
131 SSLFreeBuffer(&expectedFinished, ctx);
132 return err;
133 }
134
135 OSStatus
136 SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx)
137 { OSStatus err;
138 int head;
139
140 helloDone->contentType = SSL_RecordTypeHandshake;
141 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
142 helloDone->protocolVersion = ctx->negProtocolVersion;
143 head = SSLHandshakeHeaderSize(helloDone);
144 if ((err = SSLAllocBuffer(&helloDone->contents, head, ctx)) != 0)
145 return err;
146
147 SSLEncodeHandshakeHeader(ctx, helloDone, SSL_HdskServerHelloDone, 0); /* Message has 0 length */
148
149 return noErr;
150 }
151
152 OSStatus
153 SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
154 { assert(ctx->protocolSide == kSSLClientSide);
155 if (message.length != 0) {
156 sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
157 return errSSLProtocol;
158 }
159 return noErr;
160 }