]> git.saurik.com Git - apple/security.git/blobdiff - SecureTransport/sslChangeCipher.cpp
Security-54.1.3.tar.gz
[apple/security.git] / SecureTransport / sslChangeCipher.cpp
diff --git a/SecureTransport/sslChangeCipher.cpp b/SecureTransport/sslChangeCipher.cpp
new file mode 100644 (file)
index 0000000..391a8f2
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please obtain
+ * a copy of the License at http://www.apple.com/publicsource and read it before
+ * using this file.
+ * 
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
+ * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
+ * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
+ * specific language governing rights and limitations under the License.
+ */
+
+
+/*
+       File:           sslChangeCipher.cpp
+
+       Contains:       support for change cipher spec messages
+
+       Written by:     Doug Mitchell
+
+       Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
+
+*/
+
+#include "sslContext.h"
+#include "sslHandshake.h"
+#include "sslMemory.h"
+#include "sslAlertMessage.h"
+#include "sslDebug.h"
+
+#include <assert.h>
+#include <string.h>
+
+OSStatus
+SSLEncodeChangeCipherSpec(SSLRecord &rec, SSLContext *ctx)
+{   OSStatus          err;
+    
+    assert(ctx->writePending.ready);
+    
+    sslLogNegotiateDebug("===Sending changeCipherSpec msg");
+    rec.contentType = SSL_RecordTypeChangeCipher;
+       assert((ctx->negProtocolVersion == SSL_Version_3_0) ||
+                  (ctx->negProtocolVersion == TLS_Version_1_0));
+    rec.protocolVersion = ctx->negProtocolVersion;
+    rec.contents.length = 1;
+    if ((err = SSLAllocBuffer(rec.contents, 1, ctx)) != 0)
+        return err;
+    rec.contents.data[0] = 1;
+    
+    return noErr;
+}
+
+OSStatus
+SSLProcessChangeCipherSpec(SSLRecord rec, SSLContext *ctx)
+{   OSStatus          err;
+    
+    if (rec.contents.length != 1 || rec.contents.data[0] != 1)
+    {   SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+       sslErrorLog("***bad changeCipherSpec msg: length %d data 0x%x\n",
+               (unsigned)rec.contents.length, (unsigned)rec.contents.data[0]);
+        return errSSLProtocol;
+    }
+    
+    if (!ctx->readPending.ready || ctx->state != SSL_HdskStateChangeCipherSpec)
+    {   SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
+       sslErrorLog("***bad changeCipherSpec msg: readPending.ready %d state %d\n",
+               (unsigned)ctx->readPending.ready, (unsigned)ctx->state);
+        return errSSLProtocol;
+    }
+    
+    sslLogNegotiateDebug("===Processing changeCipherSpec msg");
+    
+    /* Install new cipher spec on read side */
+    if ((err = SSLDisposeCipherSuite(&ctx->readCipher, ctx)) != 0)
+    {   SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
+        return err;
+    }
+    ctx->readCipher = ctx->readPending;
+    ctx->readCipher.ready = 0;      /* Can't send data until Finished is sent */
+    SSLChangeHdskState(ctx, SSL_HdskStateFinished);
+    memset(&ctx->readPending, 0, sizeof(CipherContext));       /* Zero out old data */
+    return noErr;    
+}
+
+OSStatus
+SSLDisposeCipherSuite(CipherContext *cipher, SSLContext *ctx)
+{   OSStatus      err;
+    
+       /* symmetric key */
+    if (cipher->symKey)
+    {   if ((err = cipher->symCipher->finish(cipher, ctx)) != 0)
+            return err;
+        cipher->symKey = 0;
+    }
+    
+       /* per-record hash/hmac context */
+       ctx->sslTslCalls->freeMac(cipher);
+       
+    return noErr;
+}