2 * Copyright (c) 1999-2001,2005-2007,2010-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * sslHandshakeFinish.c - Finished and server hello done messages.
28 #include "sslContext.h"
29 #include "sslHandshake.h"
30 #include "sslMemory.h"
33 #include "sslDigests.h"
39 SSLEncodeFinishedMessage(SSLRecord
*finished
, SSLContext
*ctx
)
41 SSLBuffer finishedMsg
;
43 unsigned finishedSize
;
47 /* size and version depend on negotiatedProtocol */
48 switch(ctx
->negProtocolVersion
) {
52 case DTLS_Version_1_0
:
55 case TLS_Version_1_2
: /* TODO: Support variable finishedSize. */
60 return errSSLInternal
;
62 finished
->protocolVersion
= ctx
->negProtocolVersion
;
64 finished
->contentType
= SSL_RecordTypeHandshake
;
65 /* msg = type + 3 bytes len + finishedSize */
66 head
= SSLHandshakeHeaderSize(finished
);
67 if ((err
= SSLAllocBuffer(&finished
->contents
, finishedSize
+ head
,
71 p
= SSLEncodeHandshakeHeader(ctx
, finished
, SSL_HdskFinished
, finishedSize
);
74 finishedMsg
.length
= finishedSize
;
76 isServerMsg
= (ctx
->protocolSide
== kSSLServerSide
) ? true : false;
77 err
= ctx
->sslTslCalls
->computeFinishedMac(ctx
, finishedMsg
, isServerMsg
);
82 /* Keep this around for secure renegotiation */
83 SSLFreeBuffer(&ctx
->ownVerifyData
, ctx
);
84 return SSLCopyBuffer(&finishedMsg
, &ctx
->ownVerifyData
);
88 SSLProcessFinished(SSLBuffer message
, SSLContext
*ctx
)
90 SSLBuffer expectedFinished
;
92 unsigned finishedSize
;
94 switch(ctx
->negProtocolVersion
) {
98 case DTLS_Version_1_0
:
100 case TLS_Version_1_1
:
101 case TLS_Version_1_2
: /* TODO: Support variable finishedSize. */
106 return errSSLInternal
;
108 if (message
.length
!= finishedSize
) {
109 sslErrorLog("SSLProcessFinished: msg len error 1\n");
110 return errSSLProtocol
;
112 expectedFinished
.data
= 0;
113 if ((err
= SSLAllocBuffer(&expectedFinished
, finishedSize
, ctx
)) != 0)
115 isServerMsg
= (ctx
->protocolSide
== kSSLServerSide
) ? false : true;
116 if ((err
= ctx
->sslTslCalls
->computeFinishedMac(ctx
, expectedFinished
, isServerMsg
)) != 0)
119 if (memcmp(expectedFinished
.data
, message
.data
, finishedSize
) != 0)
121 sslErrorLog("SSLProcessFinished: memcmp failure\n");
122 err
= errSSLProtocol
;
126 /* Keep this around for secure renegotiation */
127 SSLFreeBuffer(&ctx
->peerVerifyData
, ctx
);
128 err
= SSLCopyBuffer(&expectedFinished
, &ctx
->peerVerifyData
);
131 SSLFreeBuffer(&expectedFinished
, ctx
);
136 SSLEncodeServerHelloDone(SSLRecord
*helloDone
, SSLContext
*ctx
)
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)
147 SSLEncodeHandshakeHeader(ctx
, helloDone
, SSL_HdskServerHelloDone
, 0); /* Message has 0 length */
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
;