]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ssl2Protocol.cpp
Security-54.1.3.tar.gz
[apple/security.git] / SecureTransport / ssl2Protocol.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: ssl2Protocol.cpp
21
22 Contains: Protocol engine for SSL 2
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "ssl.h"
31 #include "ssl2.h"
32 #include "sslRecord.h"
33 #include "sslMemory.h"
34 #include "sslContext.h"
35 #include "sslHandshake.h"
36 #include "sslSession.h"
37 #include "sslAlertMessage.h"
38 #include "sslDebug.h"
39 #include "appleCdsa.h"
40 #include "sslUtils.h"
41 #include "sslDigests.h"
42 #include <string.h>
43 #include <assert.h>
44
45 #ifndef NDEBUG
46
47 static char *sslHdskMsgToStr(SSL2MessageType msg)
48 {
49 static char badStr[100];
50
51 switch(msg) {
52 case SSL2_MsgError:
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";
72 default:
73 sprintf(badStr, "Unknown msg (%d(d)", msg);
74 return badStr;
75 }
76 }
77
78 static void logSsl2Msg(SSL2MessageType msg, char sent)
79 {
80 char *ms = sslHdskMsgToStr(msg);
81 sslHdskMsgDebug("...msg %s: %s", (sent ? "sent" : "recd"), ms);
82 }
83
84 #else
85
86 #define logSsl2Msg(m, s)
87
88 #endif /* NDEBUG */
89
90 OSStatus
91 SSL2ProcessMessage(SSLRecord &rec, SSLContext *ctx)
92 { OSStatus err = 0;
93 SSL2MessageType msg;
94 SSLBuffer contents;
95
96 if (rec.contents.length < 2)
97 return errSSLProtocol;
98
99 msg = (SSL2MessageType)rec.contents.data[0];
100 contents.data = rec.contents.data + 1;
101 contents.length = rec.contents.length - 1;
102
103 logSsl2Msg(msg, 0);
104
105 switch (msg)
106 { case SSL2_MsgError:
107 err = errSSLClosedAbort;
108 break;
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);
115 break;
116 case SSL2_MsgClientMasterKey:
117 if (ctx->state != SSL2_HdskStateClientMasterKey)
118 return errSSLProtocol;
119 err = SSL2ProcessClientMasterKey(contents, ctx);
120 break;
121 case SSL2_MsgClientFinished:
122 if (ctx->state != SSL2_HdskStateClientFinished)
123 return errSSLProtocol;
124 err = SSL2ProcessClientFinished(contents, ctx);
125 break;
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);
133 break;
134 case SSL2_MsgServerVerify:
135 if (ctx->state != SSL2_HdskStateServerVerify)
136 return errSSLProtocol;
137 err = SSL2ProcessServerVerify(contents, ctx);
138 break;
139 case SSL2_MsgServerFinished:
140 if (ctx->state != SSL2_HdskStateServerFinished) {
141 /* FIXME - this ifndef should not be necessary */
142 #ifndef NDEBUG
143 sslHdskStateDebug("SSL2_MsgServerFinished; state %s",
144 hdskStateToStr(ctx->state));
145 #endif
146 return errSSLProtocol;
147 }
148 err = SSL2ProcessServerFinished(contents, ctx);
149 break;
150 case SSL2_MsgRequestCert:
151 /* Don't process the request; we don't support client certification */
152 break;
153 case SSL2_MsgClientCert:
154 return errSSLProtocol;
155 break;
156 default:
157 return errSSLProtocol;
158 break;
159 }
160
161 if (err == 0)
162 {
163 /* FIXME - use requested or negotiated protocol version here? */
164 if ((msg == SSL2_MsgClientHello) &&
165 (ctx->negProtocolVersion >= SSL_Version_3_0))
166 { /* Promote this message to SSL 3 protocol */
167 if ((err = SSL3ReceiveSSL2ClientHello(rec, ctx)) != 0)
168 return err;
169 }
170 else
171 err = SSL2AdvanceHandshake(msg, ctx);
172 }
173 return err;
174 }
175
176 OSStatus
177 SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx)
178 { OSStatus err;
179
180 err = noErr;
181
182 switch (msg)
183 { case SSL2_MsgKickstart:
184 if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
185 ctx->negProtocolVersion == SSL_Version_Undetermined)
186 if ((err = SSLInitMessageHashes(ctx)) != 0)
187 return err;
188 if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientHello, ctx)) != 0)
189 return err;
190 switch (ctx->negProtocolVersion)
191 { case SSL_Version_Undetermined:
192 SSLChangeHdskState(ctx, SSL_HdskStateServerHelloUnknownVersion);
193 break;
194 case SSL_Version_3_0_With_2_0_Hello:
195 assert((ctx->reqProtocolVersion == SSL_Version_3_0) ||
196 (ctx->reqProtocolVersion == TLS_Version_1_0));
197 ctx->negProtocolVersion = ctx->reqProtocolVersion;
198 sslLogNegotiateDebug("===SSL client kickstart: negVersion "
199 "is %d_%d",
200 ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
201 SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
202 break;
203 case SSL_Version_2_0:
204 SSLChangeHdskState(ctx, SSL2_HdskStateServerHello);
205 break;
206 case SSL_Version_3_0_Only:
207 case SSL_Version_3_0:
208 case TLS_Version_1_0_Only:
209 case TLS_Version_1_0:
210 default:
211 assert("Bad protocol version for sending SSL 2 Client Hello");
212 break;
213 }
214 break;
215 case SSL2_MsgClientHello:
216 if ((err = SSL2CompareSessionIDs(ctx)) != 0)
217 return err;
218 if (ctx->ssl2SessionMatch == 0)
219 if ((err = SSL2GenerateSessionID(ctx)) != 0)
220 return err;
221 if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerHello, ctx)) != 0)
222 return err;
223 if (ctx->ssl2SessionMatch == 0)
224 { SSLChangeHdskState(ctx, SSL2_HdskStateClientMasterKey);
225 break;
226 }
227 sslLogResumSessDebug("===RESUMING SSL2 server-side session");
228 if ((err = SSL2InstallSessionKey(ctx)) != 0)
229 return err;
230 /* Fall through for matching session; lame, but true */
231 case SSL2_MsgClientMasterKey:
232 if ((err = SSL2InitCiphers(ctx)) != 0)
233 return err;
234 if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify, ctx)) != 0)
235 return err;
236 if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished, ctx)) != 0)
237 return err;
238 SSLChangeHdskState(ctx, SSL2_HdskStateClientFinished);
239 break;
240 case SSL2_MsgServerHello:
241 if (ctx->ssl2SessionMatch == 0)
242 { if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey, ctx)) != 0)
243 return err;
244 }
245 else
246 {
247 sslLogResumSessDebug("===RESUMING SSL2 client-side session");
248 if ((err = SSL2InstallSessionKey(ctx)) != 0)
249 return err;
250 }
251 if ((err = SSL2InitCiphers(ctx)) != 0)
252 return err;
253 if ((err = SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished, ctx)) != 0)
254 return err;
255 SSLChangeHdskState(ctx, SSL2_HdskStateServerVerify);
256 break;
257 case SSL2_MsgClientFinished:
258 /* Handshake is complete; turn ciphers on */
259 ctx->writeCipher.ready = 1;
260 ctx->readCipher.ready = 1;
261 /* original code never got out of SSL2_MsgClientFinished state */
262 assert(ctx->protocolSide == SSL_ServerSide);
263 SSLChangeHdskState(ctx, SSL2_HdskStateServerReady);
264 if (ctx->peerID.data != 0)
265 SSLAddSessionData(ctx);
266 break;
267 case SSL2_MsgServerVerify:
268 SSLChangeHdskState(ctx, SSL2_HdskStateServerFinished);
269 break;
270 case SSL2_MsgRequestCert:
271 if ((err = SSL2SendError(SSL2_ErrNoCert, ctx)) != 0)
272 return err;
273 break;
274 case SSL2_MsgServerFinished:
275 /* Handshake is complete; turn ciphers on */
276 ctx->writeCipher.ready = 1;
277 ctx->readCipher.ready = 1;
278 /* original code never got out of SSL2_MsgServerFinished state */
279 assert(ctx->protocolSide == SSL_ClientSide);
280 SSLChangeHdskState(ctx, SSL2_HdskStateClientReady);
281 if (ctx->peerID.data != 0)
282 SSLAddSessionData(ctx);
283 break;
284 case SSL2_MsgError:
285 case SSL2_MsgClientCert:
286 return errSSLProtocol;
287 break;
288 }
289
290 return noErr;
291 }
292
293 OSStatus
294 SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx)
295 { OSStatus err;
296 SSLRecord rec;
297
298 rec.contentType = SSL_RecordTypeV2_0;
299 rec.protocolVersion = SSL_Version_2_0;
300 if ((err = encodeFunc(rec.contents, ctx)) != 0)
301 return err;
302
303 logSsl2Msg((SSL2MessageType)rec.contents.data[0], 1);
304
305 assert(ctx->sslTslCalls != NULL);
306 if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
307 { SSLFreeBuffer(rec.contents, ctx);
308 return err;
309 }
310
311 if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
312 ctx->negProtocolVersion == SSL_Version_Undetermined)
313 if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
314 (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
315 return err;
316
317 err = SSLFreeBuffer(rec.contents, ctx);
318 return err;
319 }
320
321 OSStatus
322 SSL2CompareSessionIDs(SSLContext *ctx)
323 { OSStatus err;
324 SSLBuffer sessionIdentifier;
325
326 ctx->ssl2SessionMatch = 0;
327
328 if (ctx->resumableSession.data == 0)
329 return noErr;
330
331 if ((err = SSLRetrieveSessionID(ctx->resumableSession,
332 &sessionIdentifier, ctx)) != 0)
333 return err;
334
335 if (sessionIdentifier.length == ctx->sessionID.length &&
336 memcmp(sessionIdentifier.data, ctx->sessionID.data, sessionIdentifier.length) == 0)
337 ctx->ssl2SessionMatch = 1;
338
339 if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
340 return err;
341
342 return noErr;
343 }
344
345 OSStatus
346 SSL2InstallSessionKey(SSLContext *ctx)
347 { OSStatus err;
348
349 assert(ctx->ssl2SessionMatch != 0);
350 assert(ctx->resumableSession.data != 0);
351 if ((err = SSLInstallSessionFromData(ctx->resumableSession, ctx)) != 0)
352 return err;
353 return noErr;
354 }
355
356 OSStatus
357 SSL2GenerateSessionID(SSLContext *ctx)
358 { OSStatus err;
359
360 if ((err = SSLFreeBuffer(ctx->sessionID, ctx)) != 0)
361 return err;
362 if ((err = SSLAllocBuffer(ctx->sessionID, SSL_SESSION_ID_LEN, ctx)) != 0)
363 return err;
364 if ((err = sslRand(ctx, &ctx->sessionID)) != 0)
365 return err;
366 return noErr;
367 }
368
369 OSStatus
370 SSL2InitCiphers(SSLContext *ctx)
371 { OSStatus err;
372 int keyMaterialLen;
373 SSLBuffer keyData;
374 uint8 variantChar, *charPtr, *readKey, *writeKey, *iv;
375 SSLBuffer hashDigest, hashContext, masterKey, challenge, connectionID, variantData;
376
377 keyMaterialLen = 2 * ctx->selectedCipherSpec->cipher->keySize;
378 if ((err = SSLAllocBuffer(keyData, keyMaterialLen, ctx)) != 0)
379 return err;
380
381 /* Can't have % in assertion string... */
382 #if SSL_DEBUG
383 {
384 UInt32 keyModDigestSize = keyMaterialLen % SSLHashMD5.digestSize;
385 assert(keyModDigestSize == 0);
386 }
387 #endif
388
389 masterKey.data = ctx->masterSecret;
390 masterKey.length = ctx->selectedCipherSpec->cipher->keySize;
391 challenge.data = ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
392 ctx->ssl2ChallengeLength;
393 challenge.length = ctx->ssl2ChallengeLength;
394 connectionID.data = ctx->serverRandom;
395 connectionID.length = ctx->ssl2ConnectionIDLength;
396 variantData.data = &variantChar;
397 variantData.length = 1;
398 if ((err = SSLAllocBuffer(hashContext, SSLHashMD5.contextSize, ctx)) != 0)
399 { SSLFreeBuffer(keyData, ctx);
400 return err;
401 }
402
403 variantChar = 0x30; /* '0' */
404 charPtr = keyData.data;
405 while (keyMaterialLen)
406 { hashDigest.data = charPtr;
407 hashDigest.length = SSLHashMD5.digestSize;
408 if ((err = SSLHashMD5.init(hashContext, ctx)) != 0 ||
409 (err = SSLHashMD5.update(hashContext, masterKey)) != 0 ||
410 (err = SSLHashMD5.update(hashContext, variantData)) != 0 ||
411 (err = SSLHashMD5.update(hashContext, challenge)) != 0 ||
412 (err = SSLHashMD5.update(hashContext, connectionID)) != 0 ||
413 (err = SSLHashMD5.final(hashContext, hashDigest)) != 0)
414 { SSLFreeBuffer(keyData, ctx);
415 SSLFreeBuffer(hashContext, ctx);
416 return err;
417 }
418 charPtr += hashDigest.length;
419 ++variantChar;
420 keyMaterialLen -= hashDigest.length;
421 }
422
423 assert(charPtr == keyData.data + keyData.length);
424
425 if ((err = SSLFreeBuffer(hashContext, ctx)) != 0)
426 { SSLFreeBuffer(keyData, ctx);
427 return err;
428 }
429
430 ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm;
431 ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm;
432 ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
433 ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
434 ctx->readPending.sequenceNum = ctx->readCipher.sequenceNum;
435 ctx->writePending.sequenceNum = ctx->writeCipher.sequenceNum;
436
437 if (ctx->protocolSide == SSL_ServerSide)
438 { writeKey = keyData.data;
439 readKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
440 }
441 else
442 { readKey = keyData.data;
443 writeKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
444 }
445
446 iv = ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize;
447
448 if ((err = ctx->readPending.symCipher->initialize(readKey, iv,
449 &ctx->readPending, ctx)) != 0 ||
450 (err = ctx->writePending.symCipher->initialize(writeKey, iv,
451 &ctx->writePending, ctx)) != 0)
452 { SSLFreeBuffer(keyData, ctx);
453 return err;
454 }
455
456 /*
457 * HEY! macSecret is only 20 bytes. This blows up when key size
458 * is greater than 20, e.g., 3DES.
459 * I'll increase the size of macSecret to 24, 'cause it appears
460 * from the SSL v23 spec that the macSecret really the same size as
461 * CLIENT-WRITE-KEY and SERVER-READ-KEY (see 1.2 of the spec).
462 */
463 memcpy(ctx->readPending.macSecret, readKey, ctx->selectedCipherSpec->cipher->keySize);
464 memcpy(ctx->writePending.macSecret, writeKey, ctx->selectedCipherSpec->cipher->keySize);
465
466 if ((err = SSLFreeBuffer(keyData, ctx)) != 0)
467 return err;
468
469 ctx->readCipher = ctx->readPending;
470 ctx->writeCipher = ctx->writePending;
471 memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */
472 memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
473
474 return noErr;
475 }