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.
20 File: sslHandshakeFinish.c
22 Contains: Finished and server hello done messages.
24 Written by: Doug Mitchell
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
30 #include "sslContext.h"
31 #include "sslHandshake.h"
32 #include "sslMemory.h"
35 #include "sslDigests.h"
41 SSLEncodeFinishedMessage(SSLRecord
&finished
, SSLContext
*ctx
)
43 SSLBuffer finishedMsg
, shaMsgState
, md5MsgState
;
45 unsigned finishedSize
;
50 /* size and version depend on negotiatedProtocol */
51 switch(ctx
->negProtocolVersion
) {
53 finished
.protocolVersion
= SSL_Version_3_0
;
57 finished
.protocolVersion
= TLS_Version_1_0
;
62 return errSSLInternal
;
64 finished
.contentType
= SSL_RecordTypeHandshake
;
65 /* msg = type + 3 bytes len + finishedSize */
66 if ((err
= SSLAllocBuffer(finished
.contents
, finishedSize
+ 4,
70 finished
.contents
.data
[0] = SSL_HdskFinished
;
71 SSLEncodeInt(finished
.contents
.data
+ 1, finishedSize
, 3);
73 finishedMsg
.data
= finished
.contents
.data
+ 4;
74 finishedMsg
.length
= finishedSize
;
76 if ((err
= CloneHashState(SSLHashSHA1
, ctx
->shaState
, shaMsgState
, ctx
)) != 0)
78 if ((err
= CloneHashState(SSLHashMD5
, ctx
->md5State
, md5MsgState
, ctx
)) != 0)
80 isServerMsg
= (ctx
->protocolSide
== SSL_ServerSide
) ? true : false;
81 if ((err
= ctx
->sslTslCalls
->computeFinishedMac(ctx
, finishedMsg
,
82 shaMsgState
, md5MsgState
, isServerMsg
)) != 0)
86 SSLFreeBuffer(shaMsgState
, ctx
);
87 SSLFreeBuffer(md5MsgState
, ctx
);
92 SSLProcessFinished(SSLBuffer message
, SSLContext
*ctx
)
94 SSLBuffer expectedFinished
, shaMsgState
, md5MsgState
;
96 unsigned finishedSize
;
98 switch(ctx
->negProtocolVersion
) {
102 case TLS_Version_1_0
:
107 return errSSLInternal
;
109 if (message
.length
!= finishedSize
) {
110 sslErrorLog("SSLProcessFinished: msg len error 1\n");
111 return errSSLProtocol
;
113 expectedFinished
.data
= 0;
114 if ((err
= SSLAllocBuffer(expectedFinished
, finishedSize
, ctx
)) != 0)
116 shaMsgState
.data
= 0;
117 if ((err
= CloneHashState(SSLHashSHA1
, ctx
->shaState
, shaMsgState
, ctx
)) != 0)
119 md5MsgState
.data
= 0;
120 if ((err
= CloneHashState(SSLHashMD5
, ctx
->md5State
, md5MsgState
, ctx
)) != 0)
122 isServerMsg
= (ctx
->protocolSide
== SSL_ServerSide
) ? false : true;
123 if ((err
= ctx
->sslTslCalls
->computeFinishedMac(ctx
, expectedFinished
,
124 shaMsgState
, md5MsgState
, isServerMsg
)) != 0)
127 if (memcmp(expectedFinished
.data
, message
.data
, finishedSize
) != 0)
129 sslErrorLog("SSLProcessFinished: memcmp failure\n");
130 err
= errSSLProtocol
;
135 SSLFreeBuffer(expectedFinished
, ctx
);
136 SSLFreeBuffer(shaMsgState
, ctx
);
137 SSLFreeBuffer(md5MsgState
, ctx
);
142 SSLEncodeServerHelloDone(SSLRecord
&helloDone
, SSLContext
*ctx
)
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)
151 helloDone
.contents
.data
[0] = SSL_HdskServerHelloDone
;
152 SSLEncodeInt(helloDone
.contents
.data
+1, 0, 3); /* Message has 0 length */
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
;