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
)) != 0)
70 p
= SSLEncodeHandshakeHeader(ctx
, finished
, SSL_HdskFinished
, finishedSize
);
73 finishedMsg
.length
= finishedSize
;
75 isServerMsg
= (ctx
->protocolSide
== kSSLServerSide
) ? true : false;
76 err
= ctx
->sslTslCalls
->computeFinishedMac(ctx
, finishedMsg
, isServerMsg
);
81 /* Keep this around for secure renegotiation */
82 SSLFreeBuffer(&ctx
->ownVerifyData
);
83 return SSLCopyBuffer(&finishedMsg
, &ctx
->ownVerifyData
);
87 SSLProcessFinished(SSLBuffer message
, SSLContext
*ctx
)
89 SSLBuffer expectedFinished
;
91 unsigned finishedSize
;
93 switch(ctx
->negProtocolVersion
) {
97 case DTLS_Version_1_0
:
100 case TLS_Version_1_2
: /* TODO: Support variable finishedSize. */
105 return errSSLInternal
;
107 if (message
.length
!= finishedSize
) {
108 sslErrorLog("SSLProcessFinished: msg len error 1\n");
109 return errSSLProtocol
;
111 expectedFinished
.data
= 0;
112 if ((err
= SSLAllocBuffer(&expectedFinished
, finishedSize
)))
114 isServerMsg
= (ctx
->protocolSide
== kSSLServerSide
) ? false : true;
115 if ((err
= ctx
->sslTslCalls
->computeFinishedMac(ctx
, expectedFinished
, isServerMsg
)) != 0)
118 if (memcmp(expectedFinished
.data
, message
.data
, finishedSize
) != 0)
120 sslErrorLog("SSLProcessFinished: memcmp failure\n");
121 err
= errSSLProtocol
;
125 /* Keep this around for secure renegotiation */
126 SSLFreeBuffer(&ctx
->peerVerifyData
);
127 err
= SSLCopyBuffer(&expectedFinished
, &ctx
->peerVerifyData
);
130 SSLFreeBuffer(&expectedFinished
);
135 SSLEncodeServerHelloDone(SSLRecord
*helloDone
, SSLContext
*ctx
)
139 helloDone
->contentType
= SSL_RecordTypeHandshake
;
140 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
141 helloDone
->protocolVersion
= ctx
->negProtocolVersion
;
142 head
= SSLHandshakeHeaderSize(helloDone
);
143 if ((err
= SSLAllocBuffer(&helloDone
->contents
, head
)))
146 SSLEncodeHandshakeHeader(ctx
, helloDone
, SSL_HdskServerHelloDone
, 0); /* Message has 0 length */
148 return errSecSuccess
;
152 SSLProcessServerHelloDone(SSLBuffer message
, SSLContext
*ctx
)
153 { assert(ctx
->protocolSide
== kSSLClientSide
);
154 if (message
.length
!= 0) {
155 sslErrorLog("SSLProcessServerHelloDone: nonzero msg len\n");
156 return errSSLProtocol
;
158 return errSecSuccess
;