X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/ed6778a32ecff23bc2dfb6ca452badd0c68774a0..563f4f96f568bcdc0a04a82f89cafe3bebbe43f1:/SecureTransport/ssl2Protocol.cpp diff --git a/SecureTransport/ssl2Protocol.cpp b/SecureTransport/ssl2Protocol.cpp deleted file mode 100644 index 93a008e7..00000000 --- a/SecureTransport/ssl2Protocol.cpp +++ /dev/null @@ -1,463 +0,0 @@ -/* - * 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: ssl2Protocol.cpp - - Contains: Protocol engine for SSL 2 - - Written by: Doug Mitchell - - Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved. - -*/ - -#include "ssl.h" -#include "ssl2.h" -#include "sslRecord.h" -#include "sslMemory.h" -#include "sslContext.h" -#include "sslHandshake.h" -#include "sslSession.h" -#include "sslAlertMessage.h" -#include "sslDebug.h" -#include "appleCdsa.h" -#include "sslUtils.h" -#include "sslDigests.h" -#include -#include - -#ifndef NDEBUG - -static char *sslHdskMsgToStr(SSL2MessageType msg) -{ - static char badStr[100]; - - switch(msg) { - case SSL2_MsgError: - return "SSL2_MsgError"; - case SSL2_MsgClientHello: - return "SSL2_MsgClientHello"; - case SSL2_MsgClientMasterKey: - return "SSL2_MsgClientMasterKey"; - case SSL2_MsgClientFinished: - return "SSL2_MsgClientFinished"; - case SSL2_MsgServerHello: - return "SSL2_MsgServerHello"; - case SSL2_MsgServerVerify: - return "SSL2_MsgServerVerify"; - case SSL2_MsgServerFinished: - return "SSL2_MsgServerFinished"; - case SSL2_MsgRequestCert: - return "SSL2_MsgRequestCert"; - case SSL2_MsgClientCert: - return "SSL2_MsgClientCert"; - case SSL2_MsgKickstart: - return "SSL2_MsgKickstart"; - default: - sprintf(badStr, "Unknown msg (%d(d)", msg); - return badStr; - } -} - -static void logSsl2Msg(SSL2MessageType msg, char sent) -{ - char *ms = sslHdskMsgToStr(msg); - sslHdskMsgDebug("...msg %s: %s", (sent ? "sent" : "recd"), ms); -} - -#else - -#define logSsl2Msg(m, s) - -#endif /* NDEBUG */ - -OSStatus -SSL2ProcessMessage(SSLRecord &rec, SSLContext *ctx) -{ OSStatus err = 0; - SSL2MessageType msg; - SSLBuffer contents; - - if (rec.contents.length < 2) - return errSSLProtocol; - - msg = (SSL2MessageType)rec.contents.data[0]; - contents.data = rec.contents.data + 1; - contents.length = rec.contents.length - 1; - - logSsl2Msg(msg, 0); - - switch (msg) - { case SSL2_MsgError: - err = errSSLClosedAbort; - break; - case SSL2_MsgClientHello: - if (ctx->state != SSL_HdskStateServerUninit) - return errSSLProtocol; - err = SSL2ProcessClientHello(contents, ctx); - if (err == errSSLNegotiation) - SSL2SendError(SSL2_ErrNoCipher, ctx); - break; - case SSL2_MsgClientMasterKey: - if (ctx->state != SSL2_HdskStateClientMasterKey) - return errSSLProtocol; - err = SSL2ProcessClientMasterKey(contents, ctx); - break; - case SSL2_MsgClientFinished: - if (ctx->state != SSL2_HdskStateClientFinished) - return errSSLProtocol; - err = SSL2ProcessClientFinished(contents, ctx); - break; - case SSL2_MsgServerHello: - if (ctx->state != SSL2_HdskStateServerHello && - ctx->state != SSL_HdskStateServerHelloUnknownVersion) - return errSSLProtocol; - err = SSL2ProcessServerHello(contents, ctx); - if (err == errSSLNegotiation) - SSL2SendError(SSL2_ErrNoCipher, ctx); - break; - case SSL2_MsgServerVerify: - if (ctx->state != SSL2_HdskStateServerVerify) - return errSSLProtocol; - err = SSL2ProcessServerVerify(contents, ctx); - break; - case SSL2_MsgServerFinished: - if (ctx->state != SSL2_HdskStateServerFinished) { - /* FIXME - this ifndef should not be necessary */ - #ifndef NDEBUG - sslHdskStateDebug("SSL2_MsgServerFinished; state %s", - hdskStateToStr(ctx->state)); - #endif - return errSSLProtocol; - } - err = SSL2ProcessServerFinished(contents, ctx); - break; - case SSL2_MsgRequestCert: - /* Don't process the request; we don't support client certification */ - break; - case SSL2_MsgClientCert: - return errSSLProtocol; - break; - default: - return errSSLProtocol; - break; - } - - if (err == 0) - { - if ((msg == SSL2_MsgClientHello) && - (ctx->negProtocolVersion >= SSL_Version_3_0)) - { /* Promote this message to SSL 3 protocol */ - if ((err = SSL3ReceiveSSL2ClientHello(rec, ctx)) != 0) - return err; - } - else - err = SSL2AdvanceHandshake(msg, ctx); - } - return err; -} - -OSStatus -SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx) -{ OSStatus err; - - err = noErr; - - switch (msg) - { case SSL2_MsgKickstart: - assert(ctx->negProtocolVersion == SSL_Version_Undetermined); - assert(ctx->versionSsl2Enable); - if (ctx->versionSsl3Enable || ctx->versionTls1Enable) { - /* prepare for possible v3 upgrade */ - if ((err = SSLInitMessageHashes(ctx)) != 0) - return err; - } - if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientHello, ctx)) != 0) - return err; - if (ctx->versionSsl3Enable || ctx->versionTls1Enable) { - SSLChangeHdskState(ctx, SSL_HdskStateServerHelloUnknownVersion); - } - else { - /* v2 only */ - SSLChangeHdskState(ctx, SSL2_HdskStateServerHello); - } - break; - case SSL2_MsgClientHello: - if ((err = SSL2CompareSessionIDs(ctx)) != 0) - return err; - if (ctx->sessionMatch == 0) - if ((err = SSL2GenerateSessionID(ctx)) != 0) - return err; - if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerHello, ctx)) != 0) - return err; - if (ctx->sessionMatch == 0) - { SSLChangeHdskState(ctx, SSL2_HdskStateClientMasterKey); - break; - } - sslLogResumSessDebug("===RESUMING SSL2 server-side session"); - if ((err = SSL2InstallSessionKey(ctx)) != 0) - return err; - /* Fall through for matching session; lame, but true */ - case SSL2_MsgClientMasterKey: - if ((err = SSL2InitCiphers(ctx)) != 0) - return err; - if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify, ctx)) != 0) - return err; - if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished, ctx)) != 0) - return err; - SSLChangeHdskState(ctx, SSL2_HdskStateClientFinished); - break; - case SSL2_MsgServerHello: - if (ctx->sessionMatch == 0) - { if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey, ctx)) != 0) - return err; - } - else - { - sslLogResumSessDebug("===RESUMING SSL2 client-side session"); - if ((err = SSL2InstallSessionKey(ctx)) != 0) - return err; - } - if ((err = SSL2InitCiphers(ctx)) != 0) - return err; - if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished, ctx)) != 0) - return err; - SSLChangeHdskState(ctx, SSL2_HdskStateServerVerify); - break; - case SSL2_MsgClientFinished: - /* Handshake is complete; turn ciphers on */ - ctx->writeCipher.ready = 1; - ctx->readCipher.ready = 1; - /* original code never got out of SSL2_MsgClientFinished state */ - assert(ctx->protocolSide == SSL_ServerSide); - SSLChangeHdskState(ctx, SSL_HdskStateServerReady); - if (ctx->peerID.data != 0) - SSLAddSessionData(ctx); - break; - case SSL2_MsgServerVerify: - SSLChangeHdskState(ctx, SSL2_HdskStateServerFinished); - break; - case SSL2_MsgRequestCert: - if ((err = SSL2SendError(SSL2_ErrNoCert, ctx)) != 0) - return err; - break; - case SSL2_MsgServerFinished: - /* Handshake is complete; turn ciphers on */ - ctx->writeCipher.ready = 1; - ctx->readCipher.ready = 1; - /* original code never got out of SSL2_MsgServerFinished state */ - assert(ctx->protocolSide == SSL_ClientSide); - SSLChangeHdskState(ctx, SSL_HdskStateClientReady); - if (ctx->peerID.data != 0) - SSLAddSessionData(ctx); - break; - case SSL2_MsgError: - case SSL2_MsgClientCert: - return errSSLProtocol; - break; - } - - return noErr; -} - -OSStatus -SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx) -{ OSStatus err; - SSLRecord rec; - - rec.contentType = SSL_RecordTypeV2_0; - rec.protocolVersion = SSL_Version_2_0; - if ((err = encodeFunc(rec.contents, ctx)) != 0) - return err; - - logSsl2Msg((SSL2MessageType)rec.contents.data[0], 1); - - assert(ctx->sslTslCalls != NULL); - if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0) - { SSLFreeBuffer(rec.contents, ctx); - return err; - } - - assert((ctx->negProtocolVersion == SSL_Version_Undetermined) || - (ctx->negProtocolVersion == SSL_Version_2_0)); - if((ctx->negProtocolVersion == SSL_Version_Undetermined) && - (ctx->versionSsl3Enable || ctx->versionTls1Enable)) { - /* prepare for possible V3/TLS1 upgrade */ - if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 || - (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0) - return err; - } - err = SSLFreeBuffer(rec.contents, ctx); - return err; -} - -OSStatus -SSL2CompareSessionIDs(SSLContext *ctx) -{ OSStatus err; - SSLBuffer sessionIdentifier; - - ctx->sessionMatch = 0; - - if (ctx->resumableSession.data == 0) - return noErr; - - if ((err = SSLRetrieveSessionID(ctx->resumableSession, - &sessionIdentifier, ctx)) != 0) - return err; - - if (sessionIdentifier.length == ctx->sessionID.length && - memcmp(sessionIdentifier.data, ctx->sessionID.data, sessionIdentifier.length) == 0) - ctx->sessionMatch = 1; - - if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0) - return err; - - return noErr; -} - -OSStatus -SSL2InstallSessionKey(SSLContext *ctx) -{ OSStatus err; - - assert(ctx->sessionMatch != 0); - assert(ctx->resumableSession.data != 0); - if ((err = SSLInstallSessionFromData(ctx->resumableSession, ctx)) != 0) - return err; - return noErr; -} - -OSStatus -SSL2GenerateSessionID(SSLContext *ctx) -{ OSStatus err; - - if ((err = SSLFreeBuffer(ctx->sessionID, ctx)) != 0) - return err; - if ((err = SSLAllocBuffer(ctx->sessionID, SSL_SESSION_ID_LEN, ctx)) != 0) - return err; - if ((err = sslRand(ctx, &ctx->sessionID)) != 0) - return err; - return noErr; -} - -OSStatus -SSL2InitCiphers(SSLContext *ctx) -{ OSStatus err; - int keyMaterialLen; - SSLBuffer keyData; - uint8 variantChar, *charPtr, *readKey, *writeKey, *iv; - SSLBuffer hashDigest, hashContext, masterKey, challenge, connectionID, variantData; - - keyMaterialLen = 2 * ctx->selectedCipherSpec->cipher->keySize; - if ((err = SSLAllocBuffer(keyData, keyMaterialLen, ctx)) != 0) - return err; - - /* Can't have % in assertion string... */ - #if SSL_DEBUG - { - UInt32 keyModDigestSize = keyMaterialLen % SSLHashMD5.digestSize; - assert(keyModDigestSize == 0); - } - #endif - - masterKey.data = ctx->masterSecret; - masterKey.length = ctx->selectedCipherSpec->cipher->keySize; - challenge.data = ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - - ctx->ssl2ChallengeLength; - challenge.length = ctx->ssl2ChallengeLength; - connectionID.data = ctx->serverRandom; - connectionID.length = ctx->ssl2ConnectionIDLength; - variantData.data = &variantChar; - variantData.length = 1; - if ((err = SSLAllocBuffer(hashContext, SSLHashMD5.contextSize, ctx)) != 0) - { SSLFreeBuffer(keyData, ctx); - return err; - } - - variantChar = 0x30; /* '0' */ - charPtr = keyData.data; - while (keyMaterialLen) - { hashDigest.data = charPtr; - hashDigest.length = SSLHashMD5.digestSize; - if ((err = SSLHashMD5.init(hashContext, ctx)) != 0 || - (err = SSLHashMD5.update(hashContext, masterKey)) != 0 || - (err = SSLHashMD5.update(hashContext, variantData)) != 0 || - (err = SSLHashMD5.update(hashContext, challenge)) != 0 || - (err = SSLHashMD5.update(hashContext, connectionID)) != 0 || - (err = SSLHashMD5.final(hashContext, hashDigest)) != 0) - { SSLFreeBuffer(keyData, ctx); - SSLFreeBuffer(hashContext, ctx); - return err; - } - charPtr += hashDigest.length; - ++variantChar; - keyMaterialLen -= hashDigest.length; - } - - assert(charPtr == keyData.data + keyData.length); - - if ((err = SSLFreeBuffer(hashContext, ctx)) != 0) - { SSLFreeBuffer(keyData, ctx); - return err; - } - - ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm; - ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm; - ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher; - ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher; - ctx->readPending.sequenceNum = ctx->readCipher.sequenceNum; - ctx->writePending.sequenceNum = ctx->writeCipher.sequenceNum; - - if (ctx->protocolSide == SSL_ServerSide) - { writeKey = keyData.data; - readKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize; - } - else - { readKey = keyData.data; - writeKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize; - } - - iv = ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize; - - if ((err = ctx->readPending.symCipher->initialize(readKey, iv, - &ctx->readPending, ctx)) != 0 || - (err = ctx->writePending.symCipher->initialize(writeKey, iv, - &ctx->writePending, ctx)) != 0) - { SSLFreeBuffer(keyData, ctx); - return err; - } - - /* - * HEY! macSecret is only 20 bytes. This blows up when key size - * is greater than 20, e.g., 3DES. - * I'll increase the size of macSecret to 24, 'cause it appears - * from the SSL v23 spec that the macSecret really the same size as - * CLIENT-WRITE-KEY and SERVER-READ-KEY (see 1.2 of the spec). - */ - memcpy(ctx->readPending.macSecret, readKey, ctx->selectedCipherSpec->cipher->keySize); - memcpy(ctx->writePending.macSecret, writeKey, ctx->selectedCipherSpec->cipher->keySize); - - if ((err = SSLFreeBuffer(keyData, ctx)) != 0) - return err; - - ctx->readCipher = ctx->readPending; - ctx->writeCipher = ctx->writePending; - memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */ - memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */ - - return noErr; -}