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:           ssl2Protocol.cpp 
  22         Contains:       Protocol engine for SSL 2 
  24         Written by:     Doug Mitchell 
  26         Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved. 
  32 #include "sslRecord.h" 
  33 #include "sslMemory.h" 
  34 #include "sslContext.h" 
  35 #include "sslHandshake.h" 
  36 #include "sslSession.h" 
  37 #include "sslAlertMessage.h" 
  39 #include "appleCdsa.h" 
  41 #include "sslDigests.h" 
  47 static char *sslHdskMsgToStr(SSL2MessageType msg
) 
  49         static char badStr
[100]; 
  53                         return "SSL2_MsgError";  
  54                 case SSL2_MsgClientHello
: 
  55                         return "SSL2_MsgClientHello";    
  56                 case SSL2_MsgClientMasterKey
: 
  57                         return "SSL2_MsgClientMasterKey";        
  58                 case SSL2_MsgClientFinished
: 
  59                         return "SSL2_MsgClientFinished";         
  60                 case SSL2_MsgServerHello
: 
  61                         return "SSL2_MsgServerHello";    
  62                 case SSL2_MsgServerVerify
: 
  63                         return "SSL2_MsgServerVerify";   
  64                 case SSL2_MsgServerFinished
: 
  65                         return "SSL2_MsgServerFinished";         
  66                 case SSL2_MsgRequestCert
: 
  67                         return "SSL2_MsgRequestCert";    
  68                 case SSL2_MsgClientCert
: 
  69                         return "SSL2_MsgClientCert";     
  70                 case SSL2_MsgKickstart
: 
  71                         return "SSL2_MsgKickstart";      
  73                         sprintf(badStr
, "Unknown msg (%d(d)", msg
); 
  78 static void logSsl2Msg(SSL2MessageType msg
, char sent
) 
  80         char *ms 
= sslHdskMsgToStr(msg
); 
  81         sslHdskMsgDebug("...msg %s: %s", (sent 
? "sent" : "recd"), ms
); 
  86 #define logSsl2Msg(m, s) 
  91 SSL2ProcessMessage(SSLRecord 
&rec
, SSLContext 
*ctx
) 
  96     if (rec
.contents
.length 
< 2) 
  97         return errSSLProtocol
; 
  99     msg 
= (SSL2MessageType
)rec
.contents
.data
[0]; 
 100     contents
.data 
= rec
.contents
.data 
+ 1; 
 101     contents
.length 
= rec
.contents
.length 
- 1; 
 106     {   case SSL2_MsgError
: 
 107                 err 
= errSSLClosedAbort
; 
 109         case SSL2_MsgClientHello
: 
 110             if (ctx
->state 
!= SSL_HdskStateServerUninit
) 
 111                 return errSSLProtocol
; 
 112             err 
= SSL2ProcessClientHello(contents
, ctx
); 
 113             if (err 
== errSSLNegotiation
) 
 114                 SSL2SendError(SSL2_ErrNoCipher
, ctx
); 
 116         case SSL2_MsgClientMasterKey
: 
 117             if (ctx
->state 
!= SSL2_HdskStateClientMasterKey
) 
 118                 return errSSLProtocol
; 
 119             err 
= SSL2ProcessClientMasterKey(contents
, ctx
); 
 121         case SSL2_MsgClientFinished
: 
 122             if (ctx
->state 
!= SSL2_HdskStateClientFinished
) 
 123                 return errSSLProtocol
; 
 124             err 
= SSL2ProcessClientFinished(contents
, ctx
); 
 126         case SSL2_MsgServerHello
: 
 127             if (ctx
->state 
!= SSL2_HdskStateServerHello 
&& 
 128                 ctx
->state 
!= SSL_HdskStateServerHelloUnknownVersion
) 
 129                 return errSSLProtocol
; 
 130             err 
= SSL2ProcessServerHello(contents
, ctx
); 
 131             if (err 
== errSSLNegotiation
) 
 132                 SSL2SendError(SSL2_ErrNoCipher
, ctx
); 
 134         case SSL2_MsgServerVerify
: 
 135             if (ctx
->state 
!= SSL2_HdskStateServerVerify
) 
 136                 return errSSLProtocol
; 
 137             err 
= SSL2ProcessServerVerify(contents
, ctx
); 
 139         case SSL2_MsgServerFinished
: 
 140             if (ctx
->state 
!= SSL2_HdskStateServerFinished
) { 
 141                                 /* FIXME - this ifndef should not be necessary */ 
 143                                 sslHdskStateDebug("SSL2_MsgServerFinished; state %s", 
 144                         hdskStateToStr(ctx
->state
)); 
 146                 return errSSLProtocol
; 
 148             err 
= SSL2ProcessServerFinished(contents
, ctx
); 
 150         case SSL2_MsgRequestCert
: 
 151             /* Don't process the request; we don't support client certification */ 
 153         case SSL2_MsgClientCert
: 
 154             return errSSLProtocol
; 
 157             return errSSLProtocol
; 
 163         if ((msg 
== SSL2_MsgClientHello
) &&  
 164                     (ctx
->negProtocolVersion 
>= SSL_Version_3_0
)) 
 165         {   /* Promote this message to SSL 3 protocol */ 
 166             if ((err 
= SSL3ReceiveSSL2ClientHello(rec
, ctx
)) != 0) 
 170             err 
= SSL2AdvanceHandshake(msg
, ctx
); 
 176 SSL2AdvanceHandshake(SSL2MessageType msg
, SSLContext 
*ctx
) 
 182     {   case SSL2_MsgKickstart
: 
 183                         assert(ctx
->negProtocolVersion 
== SSL_Version_Undetermined
); 
 184                         assert(ctx
->versionSsl2Enable
); 
 185             if (ctx
->versionSsl3Enable 
|| ctx
->versionTls1Enable
) { 
 186                                 /* prepare for possible v3 upgrade */ 
 187                 if ((err 
= SSLInitMessageHashes(ctx
)) != 0) 
 190             if ((err 
= SSL2PrepareAndQueueMessage(SSL2EncodeClientHello
, ctx
)) != 0) 
 192             if (ctx
->versionSsl3Enable 
|| ctx
->versionTls1Enable
) { 
 193                                 SSLChangeHdskState(ctx
, SSL_HdskStateServerHelloUnknownVersion
); 
 197                                 SSLChangeHdskState(ctx
, SSL2_HdskStateServerHello
); 
 200         case SSL2_MsgClientHello
: 
 201             if ((err 
= SSL2CompareSessionIDs(ctx
)) != 0) 
 203             if (ctx
->sessionMatch 
== 0) 
 204                 if ((err 
= SSL2GenerateSessionID(ctx
)) != 0) 
 206             if ((err 
= SSL2PrepareAndQueueMessage(SSL2EncodeServerHello
, ctx
)) != 0) 
 208             if (ctx
->sessionMatch 
== 0) 
 209             {   SSLChangeHdskState(ctx
, SSL2_HdskStateClientMasterKey
); 
 212                         sslLogResumSessDebug("===RESUMING SSL2 server-side session"); 
 213             if ((err 
= SSL2InstallSessionKey(ctx
)) != 0) 
 215             /* Fall through for matching session; lame, but true */ 
 216         case SSL2_MsgClientMasterKey
: 
 217             if ((err 
= SSL2InitCiphers(ctx
)) != 0) 
 219             if ((err 
= SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify
, ctx
)) != 0) 
 221             if ((err 
= SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished
, ctx
)) != 0) 
 223             SSLChangeHdskState(ctx
, SSL2_HdskStateClientFinished
); 
 225         case SSL2_MsgServerHello
: 
 226             if (ctx
->sessionMatch 
== 0) 
 227             {   if ((err 
= SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey
, ctx
)) != 0) 
 232                                 sslLogResumSessDebug("===RESUMING SSL2 client-side session"); 
 233                                 if ((err 
= SSL2InstallSessionKey(ctx
)) != 0) 
 236             if ((err 
= SSL2InitCiphers(ctx
)) != 0) 
 238             if ((err 
= SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished
, ctx
)) != 0) 
 240             SSLChangeHdskState(ctx
, SSL2_HdskStateServerVerify
); 
 242         case SSL2_MsgClientFinished
: 
 243             /* Handshake is complete; turn ciphers on */ 
 244             ctx
->writeCipher
.ready 
= 1; 
 245             ctx
->readCipher
.ready 
= 1; 
 246             /* original code never got out of SSL2_MsgClientFinished state */ 
 247             assert(ctx
->protocolSide 
== SSL_ServerSide
); 
 248             SSLChangeHdskState(ctx
, SSL_HdskStateServerReady
); 
 249             if (ctx
->peerID
.data 
!= 0) 
 250                 SSLAddSessionData(ctx
); 
 252         case SSL2_MsgServerVerify
: 
 253             SSLChangeHdskState(ctx
, SSL2_HdskStateServerFinished
); 
 255         case SSL2_MsgRequestCert
: 
 256             if ((err 
= SSL2SendError(SSL2_ErrNoCert
, ctx
)) != 0) 
 259         case SSL2_MsgServerFinished
: 
 260             /* Handshake is complete; turn ciphers on */ 
 261             ctx
->writeCipher
.ready 
= 1; 
 262             ctx
->readCipher
.ready 
= 1; 
 263             /* original code never got out of SSL2_MsgServerFinished state */ 
 264             assert(ctx
->protocolSide 
== SSL_ClientSide
); 
 265             SSLChangeHdskState(ctx
, SSL_HdskStateClientReady
); 
 266             if (ctx
->peerID
.data 
!= 0) 
 267                 SSLAddSessionData(ctx
); 
 270         case SSL2_MsgClientCert
: 
 271             return errSSLProtocol
; 
 279 SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc
, SSLContext 
*ctx
) 
 283     rec
.contentType 
= SSL_RecordTypeV2_0
; 
 284     rec
.protocolVersion 
= SSL_Version_2_0
; 
 285     if ((err 
= encodeFunc(rec
.contents
, ctx
)) != 0) 
 288     logSsl2Msg((SSL2MessageType
)rec
.contents
.data
[0], 1); 
 290         assert(ctx
->sslTslCalls 
!= NULL
); 
 291         if ((err 
= ctx
->sslTslCalls
->writeRecord(rec
, ctx
)) != 0) 
 292     {   SSLFreeBuffer(rec
.contents
, ctx
); 
 296         assert((ctx
->negProtocolVersion 
== SSL_Version_Undetermined
) || 
 297                (ctx
->negProtocolVersion 
== SSL_Version_2_0
)); 
 298     if((ctx
->negProtocolVersion 
== SSL_Version_Undetermined
) && 
 299            (ctx
->versionSsl3Enable 
|| ctx
->versionTls1Enable
)) { 
 300                 /* prepare for possible V3/TLS1 upgrade */ 
 301         if ((err 
= SSLHashSHA1
.update(ctx
->shaState
, rec
.contents
)) != 0 || 
 302             (err 
= SSLHashMD5
.update(ctx
->md5State
, rec
.contents
)) != 0) 
 305     err 
= SSLFreeBuffer(rec
.contents
, ctx
); 
 310 SSL2CompareSessionIDs(SSLContext 
*ctx
) 
 312     SSLBuffer       sessionIdentifier
; 
 314     ctx
->sessionMatch 
= 0; 
 316     if (ctx
->resumableSession
.data 
== 0) 
 319     if ((err 
= SSLRetrieveSessionID(ctx
->resumableSession
, 
 320                                     &sessionIdentifier
, ctx
)) != 0) 
 323     if (sessionIdentifier
.length 
== ctx
->sessionID
.length 
&& 
 324         memcmp(sessionIdentifier
.data
, ctx
->sessionID
.data
, sessionIdentifier
.length
) == 0) 
 325         ctx
->sessionMatch 
= 1; 
 327     if ((err 
= SSLFreeBuffer(sessionIdentifier
, ctx
)) != 0) 
 334 SSL2InstallSessionKey(SSLContext 
*ctx
) 
 337     assert(ctx
->sessionMatch 
!= 0); 
 338     assert(ctx
->resumableSession
.data 
!= 0); 
 339     if ((err 
= SSLInstallSessionFromData(ctx
->resumableSession
, ctx
)) != 0) 
 345 SSL2GenerateSessionID(SSLContext 
*ctx
) 
 348     if ((err 
= SSLFreeBuffer(ctx
->sessionID
, ctx
)) != 0) 
 350     if ((err 
= SSLAllocBuffer(ctx
->sessionID
, SSL_SESSION_ID_LEN
, ctx
)) != 0) 
 352     if ((err 
= sslRand(ctx
, &ctx
->sessionID
)) != 0) 
 358 SSL2InitCiphers(SSLContext 
*ctx
) 
 362     uint8           variantChar
, *charPtr
, *readKey
, *writeKey
, *iv
; 
 363     SSLBuffer       hashDigest
, hashContext
, masterKey
, challenge
, connectionID
, variantData
; 
 365     keyMaterialLen 
= 2 * ctx
->selectedCipherSpec
->cipher
->keySize
; 
 366     if ((err 
= SSLAllocBuffer(keyData
, keyMaterialLen
, ctx
)) != 0) 
 369         /* Can't have % in assertion string... */ 
 372                 UInt32 keyModDigestSize 
= keyMaterialLen 
% SSLHashMD5
.digestSize
; 
 373                 assert(keyModDigestSize 
== 0); 
 377     masterKey
.data 
= ctx
->masterSecret
; 
 378     masterKey
.length 
= ctx
->selectedCipherSpec
->cipher
->keySize
; 
 379     challenge
.data 
= ctx
->clientRandom 
+ SSL_CLIENT_SRVR_RAND_SIZE 
-  
 380                         ctx
->ssl2ChallengeLength
; 
 381     challenge
.length 
= ctx
->ssl2ChallengeLength
; 
 382     connectionID
.data 
= ctx
->serverRandom
; 
 383     connectionID
.length 
= ctx
->ssl2ConnectionIDLength
; 
 384     variantData
.data 
= &variantChar
; 
 385     variantData
.length 
= 1; 
 386     if ((err 
= SSLAllocBuffer(hashContext
, SSLHashMD5
.contextSize
, ctx
)) != 0) 
 387     {   SSLFreeBuffer(keyData
, ctx
); 
 391     variantChar 
= 0x30;     /* '0' */ 
 392     charPtr 
= keyData
.data
; 
 393     while (keyMaterialLen
) 
 394     {   hashDigest
.data 
= charPtr
; 
 395         hashDigest
.length 
= SSLHashMD5
.digestSize
; 
 396         if ((err 
= SSLHashMD5
.init(hashContext
, ctx
)) != 0 || 
 397             (err 
= SSLHashMD5
.update(hashContext
, masterKey
)) != 0 || 
 398             (err 
= SSLHashMD5
.update(hashContext
, variantData
)) != 0 || 
 399             (err 
= SSLHashMD5
.update(hashContext
, challenge
)) != 0 || 
 400             (err 
= SSLHashMD5
.update(hashContext
, connectionID
)) != 0 || 
 401             (err 
= SSLHashMD5
.final(hashContext
, hashDigest
)) != 0) 
 402         {   SSLFreeBuffer(keyData
, ctx
); 
 403             SSLFreeBuffer(hashContext
, ctx
); 
 406         charPtr 
+= hashDigest
.length
; 
 408         keyMaterialLen 
-= hashDigest
.length
; 
 411     assert(charPtr 
== keyData
.data 
+ keyData
.length
); 
 413     if ((err 
= SSLFreeBuffer(hashContext
, ctx
)) != 0) 
 414     {   SSLFreeBuffer(keyData
, ctx
); 
 418     ctx
->readPending
.macRef 
= ctx
->selectedCipherSpec
->macAlgorithm
; 
 419     ctx
->writePending
.macRef 
= ctx
->selectedCipherSpec
->macAlgorithm
; 
 420     ctx
->readPending
.symCipher 
= ctx
->selectedCipherSpec
->cipher
; 
 421     ctx
->writePending
.symCipher 
= ctx
->selectedCipherSpec
->cipher
; 
 422     ctx
->readPending
.sequenceNum 
= ctx
->readCipher
.sequenceNum
; 
 423     ctx
->writePending
.sequenceNum 
= ctx
->writeCipher
.sequenceNum
; 
 425     if (ctx
->protocolSide 
== SSL_ServerSide
) 
 426     {   writeKey 
= keyData
.data
; 
 427         readKey 
= keyData
.data 
+ ctx
->selectedCipherSpec
->cipher
->keySize
; 
 430     {   readKey 
= keyData
.data
; 
 431         writeKey 
= keyData
.data 
+ ctx
->selectedCipherSpec
->cipher
->keySize
; 
 434     iv 
= ctx
->masterSecret 
+ ctx
->selectedCipherSpec
->cipher
->keySize
; 
 436     if ((err 
= ctx
->readPending
.symCipher
->initialize(readKey
, iv
, 
 437                             &ctx
->readPending
, ctx
)) != 0 || 
 438         (err 
= ctx
->writePending
.symCipher
->initialize(writeKey
, iv
, 
 439                             &ctx
->writePending
, ctx
)) != 0) 
 440     {   SSLFreeBuffer(keyData
, ctx
); 
 445          * HEY! macSecret is only 20 bytes. This blows up when key size 
 446          * is greater than 20, e.g., 3DES.  
 447          * I'll increase the size of macSecret to 24, 'cause it appears 
 448          * from the SSL v23 spec that the macSecret really the same size as 
 449          * CLIENT-WRITE-KEY and  SERVER-READ-KEY (see 1.2 of the spec). 
 451     memcpy(ctx
->readPending
.macSecret
, readKey
, ctx
->selectedCipherSpec
->cipher
->keySize
); 
 452     memcpy(ctx
->writePending
.macSecret
, writeKey
, ctx
->selectedCipherSpec
->cipher
->keySize
); 
 454     if ((err 
= SSLFreeBuffer(keyData
, ctx
)) != 0) 
 457     ctx
->readCipher 
= ctx
->readPending
; 
 458     ctx
->writeCipher 
= ctx
->writePending
; 
 459     memset(&ctx
->readPending
, 0, sizeof(CipherContext
));        /* Zero out old data */ 
 460     memset(&ctx
->writePending
, 0, sizeof(CipherContext
));       /* Zero out old data */