]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslHandshakeFinish.cpp
Security-54.1.3.tar.gz
[apple/security.git] / SecureTransport / sslHandshakeFinish.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 File: sslHandshakeFinish.c
21
22 Contains: Finished and server hello done messages.
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "sslContext.h"
31 #include "sslHandshake.h"
32 #include "sslMemory.h"
33 #include "sslDebug.h"
34 #include "sslUtils.h"
35 #include "sslDigests.h"
36
37 #include <string.h>
38 #include <assert.h>
39
40 OSStatus
41 SSLEncodeFinishedMessage(SSLRecord &finished, SSLContext *ctx)
42 { OSStatus err;
43 SSLBuffer finishedMsg, shaMsgState, md5MsgState;
44 Boolean isServerMsg;
45 unsigned finishedSize;
46
47 shaMsgState.data = 0;
48 md5MsgState.data = 0;
49
50 /* size and version depend on negotiatedProtocol */
51 switch(ctx->negProtocolVersion) {
52 case SSL_Version_3_0:
53 finished.protocolVersion = SSL_Version_3_0;
54 finishedSize = 36;
55 break;
56 case TLS_Version_1_0:
57 finished.protocolVersion = TLS_Version_1_0;
58 finishedSize = 12;
59 break;
60 default:
61 assert(0);
62 return errSSLInternal;
63 }
64 finished.contentType = SSL_RecordTypeHandshake;
65 /* msg = type + 3 bytes len + finishedSize */
66 if ((err = SSLAllocBuffer(finished.contents, finishedSize + 4,
67 ctx)) != 0)
68 return err;
69
70 finished.contents.data[0] = SSL_HdskFinished;
71 SSLEncodeInt(finished.contents.data + 1, finishedSize, 3);
72
73 finishedMsg.data = finished.contents.data + 4;
74 finishedMsg.length = finishedSize;
75
76 if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
77 goto fail;
78 if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
79 goto fail;
80 isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? true : false;
81 if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, finishedMsg,
82 shaMsgState, md5MsgState, isServerMsg)) != 0)
83 goto fail;
84
85 fail:
86 SSLFreeBuffer(shaMsgState, ctx);
87 SSLFreeBuffer(md5MsgState, ctx);
88 return err;
89 }
90
91 OSStatus
92 SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
93 { OSStatus err;
94 SSLBuffer expectedFinished, shaMsgState, md5MsgState;
95 Boolean isServerMsg;
96 unsigned finishedSize;
97
98 switch(ctx->negProtocolVersion) {
99 case SSL_Version_3_0:
100 finishedSize = 36;
101 break;
102 case TLS_Version_1_0:
103 finishedSize = 12;
104 break;
105 default:
106 assert(0);
107 return errSSLInternal;
108 }
109 if (message.length != finishedSize) {
110 sslErrorLog("SSLProcessFinished: msg len error 1\n");
111 return errSSLProtocol;
112 }
113 expectedFinished.data = 0;
114 if ((err = SSLAllocBuffer(expectedFinished, finishedSize, ctx)) != 0)
115 return err;
116 shaMsgState.data = 0;
117 if ((err = CloneHashState(SSLHashSHA1, ctx->shaState, shaMsgState, ctx)) != 0)
118 goto fail;
119 md5MsgState.data = 0;
120 if ((err = CloneHashState(SSLHashMD5, ctx->md5State, md5MsgState, ctx)) != 0)
121 goto fail;
122 isServerMsg = (ctx->protocolSide == SSL_ServerSide) ? false : true;
123 if ((err = ctx->sslTslCalls->computeFinishedMac(ctx, expectedFinished,
124 shaMsgState, md5MsgState, isServerMsg)) != 0)
125 goto fail;
126
127 if (memcmp(expectedFinished.data, message.data, finishedSize) != 0)
128 {
129 sslErrorLog("SSLProcessFinished: memcmp failure\n");
130 err = errSSLProtocol;
131 goto fail;
132 }
133
134 fail:
135 SSLFreeBuffer(expectedFinished, ctx);
136 SSLFreeBuffer(shaMsgState, ctx);
137 SSLFreeBuffer(md5MsgState, ctx);
138 return err;
139 }
140
141 OSStatus
142 SSLEncodeServerHelloDone(SSLRecord &helloDone, SSLContext *ctx)
143 { OSStatus err;
144
145 helloDone.contentType = SSL_RecordTypeHandshake;
146 assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
147 (ctx->negProtocolVersion == TLS_Version_1_0));
148 helloDone.protocolVersion = ctx->negProtocolVersion;
149 if ((err = SSLAllocBuffer(helloDone.contents, 4, ctx)) != 0)
150 return err;
151 helloDone.contents.data[0] = SSL_HdskServerHelloDone;
152 SSLEncodeInt(helloDone.contents.data+1, 0, 3); /* Message has 0 length */
153 return noErr;
154 }
155
156 OSStatus
157 SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
158 { assert(ctx->protocolSide == SSL_ClientSide);
159 if (message.length != 0) {
160 sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
161 return errSSLProtocol;
162 }
163 return noErr;
164 }