]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslChangeCipher.cpp
Security-177.tar.gz
[apple/security.git] / SecureTransport / sslChangeCipher.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 /*
20 File: sslChangeCipher.cpp
21
22 Contains: support for change cipher spec messages
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "sslContext.h"
31 #include "sslHandshake.h"
32 #include "sslMemory.h"
33 #include "sslAlertMessage.h"
34 #include "sslDebug.h"
35
36 #include <assert.h>
37 #include <string.h>
38
39 OSStatus
40 SSLEncodeChangeCipherSpec(SSLRecord &rec, SSLContext *ctx)
41 { OSStatus err;
42
43 assert(ctx->writePending.ready);
44
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)
52 return err;
53 rec.contents.data[0] = 1;
54
55 return noErr;
56 }
57
58 OSStatus
59 SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
60 { OSStatus err;
61
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;
67 }
68
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;
74 }
75
76 sslLogNegotiateDebug("===Processing changeCipherSpec msg");
77
78 /* Install new cipher spec on read side */
79 if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
80 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
81 return err;
82 }
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 */
87 return noErr;
88 }
89
90 OSStatus
91 SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx)
92 { OSStatus err;
93
94 /* symmetric key */
95 if (cipher->symKey)
96 { if ((err = cipher->symCipher->finish(cipher, ctx)) != 0)
97 return err;
98 cipher->symKey = 0;
99 }
100
101 /* per-record hash/hmac context */
102 ctx->sslTslCalls->freeMac(cipher);
103
104 return noErr;
105 }