2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
22 Contains: Finished and server hello done messages.
24 Written by: Doug Mitchell, based on Netscape RSARef 3.0
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
29 /* *********************************************************************
32 SSLRef 3.0 Final -- 11/19/96
34 Copyright (c)1996 by Netscape Communications Corp.
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.
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/>.
44 *********************************************************************
46 File: hdskfini.c Finished and server hello done messages
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
54 ****************************************************************** */
83 SSLEncodeFinishedMessage(SSLRecord
*finished
, SSLContext
*ctx
)
85 SSLBuffer finishedMsg
, shaMsgState
, md5MsgState
;
86 UInt32 sideSenderValue
;
91 finished
->contentType
= SSL_handshake
;
92 finished
->protocolVersion
= SSL_Version_3_0
;
93 if ((err
= SSLAllocBuffer(&finished
->contents
, 40, &ctx
->sysCtx
)) != 0)
96 finished
->contents
.data
[0] = SSL_finished
;
97 SSLEncodeInt(finished
->contents
.data
+ 1, 36, 3);
99 finishedMsg
.data
= finished
->contents
.data
+4;
100 finishedMsg
.length
= 36;
102 if ((err
= CloneHashState(&SSLHashSHA1
, ctx
->shaState
, &shaMsgState
, ctx
)) != 0)
104 if ((err
= CloneHashState(&SSLHashMD5
, ctx
->md5State
, &md5MsgState
, ctx
)) != 0)
106 sideSenderValue
= (ctx
->protocolSide
== SSL_ServerSide
) ? SSL_Finished_Sender_Server
: SSL_Finished_Sender_Client
;
107 if ((err
= SSLCalculateFinishedMessage(finishedMsg
, shaMsgState
, md5MsgState
, sideSenderValue
, ctx
)) != 0)
111 SSLFreeBuffer(&shaMsgState
, &ctx
->sysCtx
);
112 SSLFreeBuffer(&md5MsgState
, &ctx
->sysCtx
);
117 SSLProcessFinished(SSLBuffer message
, SSLContext
*ctx
)
119 SSLBuffer expectedFinished
, shaMsgState
, md5MsgState
;
120 UInt32 peerSenderValue
;
122 if (message
.length
!= 36) {
123 errorLog0("SSLProcessFinished: msg len error 1\n");
124 return SSLProtocolErr
;
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)
130 shaMsgState
.data
= 0;
131 if ((err
= CloneHashState(&SSLHashSHA1
, ctx
->shaState
, &shaMsgState
, ctx
)) != 0)
133 md5MsgState
.data
= 0;
134 if ((err
= CloneHashState(&SSLHashMD5
, ctx
->md5State
, &md5MsgState
, ctx
)) != 0)
136 if ((err
= SSLCalculateFinishedMessage(expectedFinished
, shaMsgState
, md5MsgState
, peerSenderValue
, ctx
)) != 0)
138 DUMP_BUFFER_NAME("finished got", message
);
139 DUMP_BUFFER_NAME("finished wanted", expectedFinished
);
140 if (memcmp(expectedFinished
.data
, message
.data
, 36) != 0)
142 errorLog0("SSLProcessFinished: memcmp failure\n");
143 err
= SSLProtocolErr
;
148 SSLFreeBuffer(&expectedFinished
, &ctx
->sysCtx
);
149 SSLFreeBuffer(&shaMsgState
, &ctx
->sysCtx
);
150 SSLFreeBuffer(&md5MsgState
, &ctx
->sysCtx
);
155 SSLCalculateFinishedMessage(SSLBuffer finished
, SSLBuffer shaMsgState
,
156 SSLBuffer md5MsgState
, UInt32 senderID
, SSLContext
*ctx
)
158 SSLBuffer hash
, input
;
159 UInt8 sender
[4], md5Inner
[16], shaInner
[20];
161 CASSERT(finished
.length
== 36);
164 { SSLEncodeInt(sender
, senderID
, 4);
167 if ((err
= SSLHashMD5
.update(md5MsgState
, input
)) != 0)
169 if ((err
= SSLHashSHA1
.update(shaMsgState
, input
)) != 0)
172 input
.data
= ctx
->masterSecret
;
174 if ((err
= SSLHashMD5
.update(md5MsgState
, input
)) != 0)
176 if ((err
= SSLHashSHA1
.update(shaMsgState
, input
)) != 0)
178 input
.data
= SSLMACPad1
;
179 input
.length
= SSLHashMD5
.macPadSize
;
180 if ((err
= SSLHashMD5
.update(md5MsgState
, input
)) != 0)
182 input
.length
= SSLHashSHA1
.macPadSize
;
183 if ((err
= SSLHashSHA1
.update(shaMsgState
, input
)) != 0)
185 hash
.data
= md5Inner
;
187 if ((err
= SSLHashMD5
.final(md5MsgState
, hash
)) != 0)
189 hash
.data
= shaInner
;
191 if ((err
= SSLHashSHA1
.final(shaMsgState
, hash
)) != 0)
193 if ((err
= SSLHashMD5
.init(md5MsgState
)) != 0)
195 if ((err
= SSLHashSHA1
.init(shaMsgState
)) != 0)
197 input
.data
= ctx
->masterSecret
;
199 if ((err
= SSLHashMD5
.update(md5MsgState
, input
)) != 0)
201 if ((err
= SSLHashSHA1
.update(shaMsgState
, input
)) != 0)
203 input
.data
= SSLMACPad2
;
204 input
.length
= SSLHashMD5
.macPadSize
;
205 if ((err
= SSLHashMD5
.update(md5MsgState
, input
)) != 0)
207 input
.length
= SSLHashSHA1
.macPadSize
;
208 if ((err
= SSLHashSHA1
.update(shaMsgState
, input
)) != 0)
210 input
.data
= md5Inner
;
212 if ((err
= SSLHashMD5
.update(md5MsgState
, input
)) != 0)
214 hash
.data
= finished
.data
;
216 if ((err
= SSLHashMD5
.final(md5MsgState
, hash
)) != 0)
218 input
.data
= shaInner
;
220 if ((err
= SSLHashSHA1
.update(shaMsgState
, input
)) != 0)
222 hash
.data
= finished
.data
+ 16;
224 if ((err
= SSLHashSHA1
.final(shaMsgState
, hash
)) != 0)
230 SSLEncodeServerHelloDone(SSLRecord
*helloDone
, SSLContext
*ctx
)
233 helloDone
->contentType
= SSL_handshake
;
234 helloDone
->protocolVersion
= SSL_Version_3_0
;
235 if ((err
= SSLAllocBuffer(&helloDone
->contents
, 4, &ctx
->sysCtx
)) != 0)
237 helloDone
->contents
.data
[0] = SSL_server_hello_done
;
238 SSLEncodeInt(helloDone
->contents
.data
+1, 0, 3); /* Message has 0 length */
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
;