]> git.saurik.com Git - apple/security.git/blob - SecureTransport/hdskfini.c
Security-29.tar.gz
[apple/security.git] / SecureTransport / hdskfini.c
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: hdskfini.c
21
22 Contains: Finished and server hello done messages.
23
24 Written by: Doug Mitchell, based on Netscape RSARef 3.0
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29 /* *********************************************************************
30 File: hdskfini.c
31
32 SSLRef 3.0 Final -- 11/19/96
33
34 Copyright (c)1996 by Netscape Communications Corp.
35
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
39
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
43
44 *********************************************************************
45
46 File: hdskfini.c Finished and server hello done messages
47
48 Support for encoding and decoding finished and server hello done
49 messgages. Also includes the necessary calculations for the Finished
50 message; note that the same function is used to calculate certificate
51 verify message hashes (without the 'SRVR' or 'CLNT' protocol side
52 identifier).
53
54 ****************************************************************** */
55
56 #ifndef _SSLCTX_H_
57 #include "sslctx.h"
58 #endif
59
60 #ifndef _SSLHDSHK_H_
61 #include "sslhdshk.h"
62 #endif
63
64 #ifndef _SSLALLOC_H_
65 #include "sslalloc.h"
66 #endif
67
68 #ifndef _SSL_DEBUG_H_
69 #include "sslDebug.h"
70 #endif
71
72 #ifndef _SSLUTIL_H_
73 #include "sslutil.h"
74 #endif
75
76 #ifndef _DIGESTS_H_
77 #include "digests.h"
78 #endif
79
80 #include <string.h>
81
82 SSLErr
83 SSLEncodeFinishedMessage(SSLRecord *finished, SSLContext *ctx)
84 { SSLErr err;
85 SSLBuffer finishedMsg, shaMsgState, md5MsgState;
86 UInt32 sideSenderValue;
87
88 shaMsgState.data = 0;
89 md5MsgState.data = 0;
90
91 finished->contentType = SSL_handshake;
92 finished->protocolVersion = SSL_Version_3_0;
93 if ((err = SSLAllocBuffer(&finished->contents, 40, &ctx->sysCtx)) != 0)
94 return err;
95
96 finished->contents.data[0] = SSL_finished;
97 SSLEncodeInt(finished->contents.data + 1, 36, 3);
98
99 finishedMsg.data = finished->contents.data+4;
100 finishedMsg.length = 36;
101
102 if ((err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
103 goto fail;
104 if ((err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
105 goto fail;
106 sideSenderValue = (ctx->protocolSide == SSL_ServerSide) ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client;
107 if ((err = SSLCalculateFinishedMessage(finishedMsg, shaMsgState, md5MsgState, sideSenderValue, ctx)) != 0)
108 goto fail;
109
110 fail:
111 SSLFreeBuffer(&shaMsgState, &ctx->sysCtx);
112 SSLFreeBuffer(&md5MsgState, &ctx->sysCtx);
113 return err;
114 }
115
116 SSLErr
117 SSLProcessFinished(SSLBuffer message, SSLContext *ctx)
118 { SSLErr err;
119 SSLBuffer expectedFinished, shaMsgState, md5MsgState;
120 UInt32 peerSenderValue;
121
122 if (message.length != 36) {
123 errorLog0("SSLProcessFinished: msg len error 1\n");
124 return SSLProtocolErr;
125 }
126 peerSenderValue = (ctx->protocolSide == SSL_ClientSide) ? SSL_Finished_Sender_Server : SSL_Finished_Sender_Client;
127 expectedFinished.data = 0;
128 if ((err = SSLAllocBuffer(&expectedFinished, 36, &ctx->sysCtx)) != 0)
129 return err;
130 shaMsgState.data = 0;
131 if ((err = CloneHashState(&SSLHashSHA1, ctx->shaState, &shaMsgState, ctx)) != 0)
132 goto fail;
133 md5MsgState.data = 0;
134 if ((err = CloneHashState(&SSLHashMD5, ctx->md5State, &md5MsgState, ctx)) != 0)
135 goto fail;
136 if ((err = SSLCalculateFinishedMessage(expectedFinished, shaMsgState, md5MsgState, peerSenderValue, ctx)) != 0)
137 goto fail;
138 DUMP_BUFFER_NAME("finished got", message);
139 DUMP_BUFFER_NAME("finished wanted", expectedFinished);
140 if (memcmp(expectedFinished.data, message.data, 36) != 0)
141 {
142 errorLog0("SSLProcessFinished: memcmp failure\n");
143 err = SSLProtocolErr;
144 goto fail;
145 }
146
147 fail:
148 SSLFreeBuffer(&expectedFinished, &ctx->sysCtx);
149 SSLFreeBuffer(&shaMsgState, &ctx->sysCtx);
150 SSLFreeBuffer(&md5MsgState, &ctx->sysCtx);
151 return err;
152 }
153
154 SSLErr
155 SSLCalculateFinishedMessage(SSLBuffer finished, SSLBuffer shaMsgState,
156 SSLBuffer md5MsgState, UInt32 senderID, SSLContext *ctx)
157 { SSLErr err;
158 SSLBuffer hash, input;
159 UInt8 sender[4], md5Inner[16], shaInner[20];
160
161 CASSERT(finished.length == 36);
162
163 if (senderID != 0)
164 { SSLEncodeInt(sender, senderID, 4);
165 input.data = sender;
166 input.length = 4;
167 if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
168 return err;
169 if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
170 return err;
171 }
172 input.data = ctx->masterSecret;
173 input.length = 48;
174 if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
175 return err;
176 if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
177 return err;
178 input.data = SSLMACPad1;
179 input.length = SSLHashMD5.macPadSize;
180 if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
181 return err;
182 input.length = SSLHashSHA1.macPadSize;
183 if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
184 return err;
185 hash.data = md5Inner;
186 hash.length = 16;
187 if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
188 return err;
189 hash.data = shaInner;
190 hash.length = 20;
191 if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
192 return err;
193 if ((err = SSLHashMD5.init(md5MsgState)) != 0)
194 return err;
195 if ((err = SSLHashSHA1.init(shaMsgState)) != 0)
196 return err;
197 input.data = ctx->masterSecret;
198 input.length = 48;
199 if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
200 return err;
201 if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
202 return err;
203 input.data = SSLMACPad2;
204 input.length = SSLHashMD5.macPadSize;
205 if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
206 return err;
207 input.length = SSLHashSHA1.macPadSize;
208 if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
209 return err;
210 input.data = md5Inner;
211 input.length = 16;
212 if ((err = SSLHashMD5.update(md5MsgState, input)) != 0)
213 return err;
214 hash.data = finished.data;
215 hash.length = 16;
216 if ((err = SSLHashMD5.final(md5MsgState, hash)) != 0)
217 return err;
218 input.data = shaInner;
219 input.length = 20;
220 if ((err = SSLHashSHA1.update(shaMsgState, input)) != 0)
221 return err;
222 hash.data = finished.data + 16;
223 hash.length = 20;
224 if ((err = SSLHashSHA1.final(shaMsgState, hash)) != 0)
225 return err;
226 return SSLNoErr;
227 }
228
229 SSLErr
230 SSLEncodeServerHelloDone(SSLRecord *helloDone, SSLContext *ctx)
231 { SSLErr err;
232
233 helloDone->contentType = SSL_handshake;
234 helloDone->protocolVersion = SSL_Version_3_0;
235 if ((err = SSLAllocBuffer(&helloDone->contents, 4, &ctx->sysCtx)) != 0)
236 return err;
237 helloDone->contents.data[0] = SSL_server_hello_done;
238 SSLEncodeInt(helloDone->contents.data+1, 0, 3); /* Message has 0 length */
239 return SSLNoErr;
240 }
241
242 SSLErr
243 SSLProcessServerHelloDone(SSLBuffer message, SSLContext *ctx)
244 { CASSERT(ctx->protocolSide == SSL_ClientSide);
245 if (message.length != 0) {
246 errorLog0("SSLProcessServerHelloDone: nonzero msg len\n");
247 return SSLProtocolErr;
248 }
249 return SSLNoErr;
250 }