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: sslChangeCipher.cpp
22 Contains: support for change cipher spec 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"
33 #include "sslAlertMessage.h"
40 SSLEncodeChangeCipherSpec(SSLRecord
&rec
, SSLContext
*ctx
)
43 assert(ctx
->writePending
.ready
);
45 sslLogNegotiateDebug("===Sending changeCipherSpec msg");
46 rec
.contentType
= SSL_RecordTypeChangeCipher
;
47 assert((ctx
->negProtocolVersion
== SSL_Version_3_0
) ||
48 (ctx
->negProtocolVersion
== TLS_Version_1_0
));
49 rec
.protocolVersion
= ctx
->negProtocolVersion
;
50 rec
.contents
.length
= 1;
51 if ((err
= SSLAllocBuffer(rec
.contents
, 1, ctx
)) != 0)
53 rec
.contents
.data
[0] = 1;
59 SSLProcessChangeCipherSpec(SSLRecord rec
, SSLContext
*ctx
)
62 if (rec
.contents
.length
!= 1 || rec
.contents
.data
[0] != 1)
63 { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg
, ctx
);
64 sslErrorLog("***bad changeCipherSpec msg: length %d data 0x%x\n",
65 (unsigned)rec
.contents
.length
, (unsigned)rec
.contents
.data
[0]);
66 return errSSLProtocol
;
69 if (!ctx
->readPending
.ready
|| ctx
->state
!= SSL_HdskStateChangeCipherSpec
)
70 { SSLFatalSessionAlert(SSL_AlertUnexpectedMsg
, ctx
);
71 sslErrorLog("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
72 (unsigned)ctx
->readPending
.ready
, (unsigned)ctx
->state
);
73 return errSSLProtocol
;
76 sslLogNegotiateDebug("===Processing changeCipherSpec msg");
78 /* Install new cipher spec on read side */
79 if ((err
= SSLDisposeCipherSuite(&ctx
->readCipher
, ctx
)) != 0)
80 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
83 ctx
->readCipher
= ctx
->readPending
;
84 ctx
->readCipher
.ready
= 0; /* Can't send data until Finished is sent */
85 SSLChangeHdskState(ctx
, SSL_HdskStateFinished
);
86 memset(&ctx
->readPending
, 0, sizeof(CipherContext
)); /* Zero out old data */
91 SSLDisposeCipherSuite(CipherContext
*cipher
, SSLContext
*ctx
)
96 { if ((err
= cipher
->symCipher
->finish(cipher
, ctx
)) != 0)
101 /* per-record hash/hmac context */
102 ctx
->sslTslCalls
->freeMac(cipher
);