]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ssl2prot.c
9b20f24e82d0e1180d69eeea459f6404fb7d9a04
[apple/security.git] / SecureTransport / ssl2prot.c
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: ssl2prot.c
21
22 Contains: Protocol engine for SSL 2
23
24 Written by: Doug Mitchell, based on Netscape SSLRef 3.0
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29 /* *********************************************************************
30 File: ssl2prot.c
31
32 SSLRef 3.0 Final -- 11/19/96
33
34 Copyright (c)1996 by Netscape Communications Corp.
35
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
39
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
43
44 *********************************************************************
45
46 File: ssl2prot.c Protocol engine for SSL 2
47
48 This is the heart of the SSL 2 implementation, including the state
49 engine for proceeding through the handshake and the necessary code
50 for installing negotiated keys and algorithms.
51
52 ****************************************************************** */
53
54 #ifndef _SSL_H_
55 #include "ssl.h"
56 #endif
57
58 #ifndef _SSL2_H_
59 #include "ssl2.h"
60 #endif
61
62 #ifndef _SSLREC_H_
63 #include "sslrec.h"
64 #endif
65
66 #ifndef _SSLALLOC_H_
67 #include "sslalloc.h"
68 #endif
69
70 #ifndef _SSLCTX_H_
71 #include "sslctx.h"
72 #endif
73
74 #ifndef _SSLHDSHK_H_
75 #include "sslhdshk.h"
76 #endif
77
78 #ifndef _SSLSESS_H_
79 #include "sslsess.h"
80 #endif
81
82 #ifndef _SSLALERT_H_
83 #include "sslalert.h"
84 #endif
85
86 #ifndef _SSL_DEBUG_H_
87 #include "sslDebug.h"
88 #endif
89
90 #ifndef _APPLE_CDSA_H_
91 #include "appleCdsa.h"
92 #endif
93
94 #include "digests.h"
95 #include <string.h>
96 #include <assert.h>
97
98 #if LOG_HDSK_MSG
99
100 static char *sslHdskMsgToStr(SSL2MessageType msg)
101 {
102 static char badStr[100];
103
104 switch(msg) {
105 case ssl2_mt_error:
106 return "ssl2_mt_error";
107 case ssl2_mt_client_hello:
108 return "ssl2_mt_client_hello";
109 case ssl2_mt_client_master_key:
110 return "ssl2_mt_client_master_key";
111 case ssl2_mt_client_finished:
112 return "ssl2_mt_client_finished";
113 case ssl2_mt_server_hello:
114 return "ssl2_mt_server_hello";
115 case ssl2_mt_server_verify:
116 return "ssl2_mt_server_verify";
117 case ssl2_mt_server_finished:
118 return "ssl2_mt_server_finished";
119 case ssl2_mt_request_certificate:
120 return "ssl2_mt_request_certificate";
121 case ssl2_mt_client_certificate:
122 return "ssl2_mt_client_certificate";
123 case ssl2_mt_kickstart_handshake:
124 return "ssl2_mt_kickstart_handshake";
125 default:
126 sprintf(badStr, "Unknown msg (%d(d)", msg);
127 return badStr;
128 }
129 }
130
131 static void logSsl2Msg(SSL2MessageType msg, char sent)
132 {
133 char *ms = sslHdskMsgToStr(msg);
134 printf("...msg %s: %s\n", (sent ? "sent" : "recd"), ms);
135 }
136
137 #else /* SSL_DEBUG */
138
139 #define logSsl2Msg(m, s)
140
141 #endif
142
143 SSLErr
144 SSL2ProcessMessage(SSLRecord rec, SSLContext *ctx)
145 { SSLErr err = 0;
146 SSL2MessageType msg;
147 SSLBuffer contents;
148
149 if (rec.contents.length < 2)
150 return ERR(SSLProtocolErr);
151
152 msg = (SSL2MessageType)rec.contents.data[0];
153 contents.data = rec.contents.data + 1;
154 contents.length = rec.contents.length - 1;
155
156 logSsl2Msg(msg, 0);
157
158 switch (msg)
159 { case ssl2_mt_error:
160 err = SSLConnectionClosedError;
161 break;
162 case ssl2_mt_client_hello:
163 if (ctx->state != HandshakeServerUninit)
164 return ERR(SSLProtocolErr);
165 ERR(err = SSL2ProcessClientHello(contents, ctx));
166 if (err == SSLNegotiationErr)
167 ERR(SSL2SendError(ssl2_pe_no_cipher, ctx));
168 break;
169 case ssl2_mt_client_master_key:
170 if (ctx->state != HandshakeSSL2ClientMasterKey)
171 return ERR(SSLProtocolErr);
172 ERR(err = SSL2ProcessClientMasterKey(contents, ctx));
173 break;
174 case ssl2_mt_client_finished:
175 if (ctx->state != HandshakeSSL2ClientFinished)
176 return ERR(SSLProtocolErr);
177 ERR(err = SSL2ProcessClientFinished(contents, ctx));
178 break;
179 case ssl2_mt_server_hello:
180 if (ctx->state != HandshakeSSL2ServerHello &&
181 ctx->state != HandshakeServerHelloUnknownVersion)
182 return ERR(SSLProtocolErr);
183 ERR(err = SSL2ProcessServerHello(contents, ctx));
184 if (err == SSLNegotiationErr)
185 ERR(SSL2SendError(ssl2_pe_no_cipher, ctx));
186 break;
187 case ssl2_mt_server_verify:
188 if (ctx->state != HandshakeSSL2ServerVerify)
189 return ERR(SSLProtocolErr);
190 ERR(err = SSL2ProcessServerVerify(contents, ctx));
191 break;
192 case ssl2_mt_server_finished:
193 if (ctx->state != HandshakeSSL2ServerFinished) {
194 #if LOG_HDSK_STATE
195 errorLog1("ssl2_mt_server_finished; state %s\n",
196 hdskStateToStr(ctx->state));
197 #endif
198 return ERR(SSLProtocolErr);
199 }
200 ERR(err = SSL2ProcessServerFinished(contents, ctx));
201 break;
202 case ssl2_mt_request_certificate:
203 /* Don't process the request; we don't support client certification */
204 break;
205 case ssl2_mt_client_certificate:
206 return ERR(SSLProtocolErr);
207 break;
208 default:
209 DEBUGVAL1("Unknown message %d", msg);
210 return ERR(SSLProtocolErr);
211 break;
212 }
213
214 if (err == 0)
215 { /* FIXME - use requested or negotiated protocol version here? */
216 if (msg == ssl2_mt_client_hello && (ctx->negProtocolVersion >= SSL_Version_3_0))
217 { /* Promote this message to SSL 3 protocol */
218 if (ERR(err = SSL3ReceiveSSL2ClientHello(rec, ctx)) != 0)
219 return err;
220 }
221 else
222 ERR(err = SSL2AdvanceHandshake(msg, ctx));
223 }
224 return err;
225 }
226
227 SSLErr
228 SSL2AdvanceHandshake(SSL2MessageType msg, SSLContext *ctx)
229 { SSLErr err;
230
231 err = SSLNoErr;
232
233 switch (msg)
234 { case ssl2_mt_kickstart_handshake:
235 if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
236 ctx->negProtocolVersion == SSL_Version_Undetermined)
237 if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
238 return err;
239 if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientHello, ctx)) != 0)
240 return err;
241 switch (ctx->negProtocolVersion)
242 { case SSL_Version_Undetermined:
243 SSLChangeHdskState(ctx, HandshakeServerHelloUnknownVersion);
244 break;
245 case SSL_Version_3_0_With_2_0_Hello:
246 assert((ctx->reqProtocolVersion == SSL_Version_3_0) ||
247 (ctx->reqProtocolVersion == TLS_Version_1_0));
248 ctx->negProtocolVersion = ctx->reqProtocolVersion;
249 #if LOG_NEGOTIATE
250 dprintf2("===SSL client kickstart: negVersion is %d_%d\n",
251 ctx->negProtocolVersion >> 8, ctx->negProtocolVersion & 0xff);
252 #endif
253 SSLChangeHdskState(ctx, HandshakeServerHello);
254 break;
255 case SSL_Version_2_0:
256 SSLChangeHdskState(ctx, HandshakeSSL2ServerHello);
257 break;
258 case SSL_Version_3_0_Only:
259 case SSL_Version_3_0:
260 case TLS_Version_1_0_Only:
261 case TLS_Version_1_0:
262 default:
263 ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
264 break;
265 }
266 break;
267 case ssl2_mt_client_hello:
268 if (ERR(err = SSL2CompareSessionIDs(ctx)) != 0)
269 return err;
270 if (ctx->ssl2SessionMatch == 0)
271 if (ERR(err = SSL2GenerateSessionID(ctx)) != 0)
272 return err;
273 if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerHello, ctx)) != 0)
274 return err;
275 if (ctx->ssl2SessionMatch == 0)
276 { SSLChangeHdskState(ctx, HandshakeSSL2ClientMasterKey);
277 break;
278 }
279 SSLLogResumSess("===RESUMING SSL2 server-side session\n");
280 if (ERR(err = SSL2InstallSessionKey(ctx)) != 0)
281 return err;
282 /* Fall through for matching session; lame, but true */
283 case ssl2_mt_client_master_key:
284 if (ERR(err = SSL2InitCiphers(ctx)) != 0)
285 return err;
286 if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerVerify, ctx)) != 0)
287 return err;
288 if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeServerFinished, ctx)) != 0)
289 return err;
290 SSLChangeHdskState(ctx, HandshakeSSL2ClientFinished);
291 break;
292 case ssl2_mt_server_hello:
293 if (ctx->ssl2SessionMatch == 0)
294 { if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientMasterKey, ctx)) != 0)
295 return err;
296 }
297 else
298 {
299 SSLLogResumSess("===RESUMING SSL2 client-side session\n");
300 if (ERR(err = SSL2InstallSessionKey(ctx)) != 0)
301 return err;
302 }
303 if (ERR(err = SSL2InitCiphers(ctx)) != 0)
304 return err;
305 if (ERR(err = SSL2PrepareAndQueueMessage(SSL2EncodeClientFinished, ctx)) != 0)
306 return err;
307 SSLChangeHdskState(ctx, HandshakeSSL2ServerVerify);
308 break;
309 case ssl2_mt_client_finished:
310 /* Handshake is complete; turn ciphers on */
311 ctx->writeCipher.ready = 1;
312 ctx->readCipher.ready = 1;
313 /* original code never got out of ssl2_mt_client_finished state */
314 CASSERT(ctx->protocolSide == SSL_ServerSide);
315 SSLChangeHdskState(ctx, HandshakeServerReady);
316 if (ctx->peerID.data != 0)
317 ERR(SSLAddSessionData(ctx));
318 break;
319 case ssl2_mt_server_verify:
320 SSLChangeHdskState(ctx, HandshakeSSL2ServerFinished);
321 break;
322 case ssl2_mt_request_certificate:
323 if (ERR(err = SSL2SendError(ssl2_pe_no_certificate, ctx)) != 0)
324 return err;
325 break;
326 case ssl2_mt_server_finished:
327 /* Handshake is complete; turn ciphers on */
328 ctx->writeCipher.ready = 1;
329 ctx->readCipher.ready = 1;
330 /* original code never got out of ssl2_mt_server_finished state */
331 CASSERT(ctx->protocolSide == SSL_ClientSide);
332 SSLChangeHdskState(ctx, HandshakeClientReady);
333 if (ctx->peerID.data != 0)
334 ERR(SSLAddSessionData(ctx));
335 break;
336 case ssl2_mt_error:
337 case ssl2_mt_client_certificate:
338 return ERR(SSLProtocolErr);
339 break;
340 }
341
342 return SSLNoErr;
343 }
344
345 SSLErr
346 SSL2PrepareAndQueueMessage(EncodeSSL2MessageFunc encodeFunc, SSLContext *ctx)
347 { SSLErr err;
348 SSLRecord rec;
349
350 rec.contentType = SSL_version_2_0_record;
351 rec.protocolVersion = SSL_Version_2_0;
352 if (ERR(err = encodeFunc(&rec.contents, ctx)) != 0)
353 return err;
354
355 logSsl2Msg((SSL2MessageType)rec.contents.data[0], 1);
356
357 assert(ctx->sslTslCalls != NULL);
358 if (ERR(err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
359 { ERR(SSLFreeBuffer(&rec.contents, &ctx->sysCtx));
360 return err;
361 }
362
363 if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello ||
364 ctx->negProtocolVersion == SSL_Version_Undetermined)
365 if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
366 ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
367 return err;
368
369 ERR(err = SSLFreeBuffer(&rec.contents, &ctx->sysCtx));
370 return err;
371 }
372
373 SSLErr
374 SSL2CompareSessionIDs(SSLContext *ctx)
375 { SSLErr err;
376 SSLBuffer sessionIdentifier;
377
378 ctx->ssl2SessionMatch = 0;
379
380 if (ctx->resumableSession.data == 0)
381 return SSLNoErr;
382
383 if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession,
384 &sessionIdentifier, ctx)) != 0)
385 return err;
386
387 if (sessionIdentifier.length == ctx->sessionID.length &&
388 memcmp(sessionIdentifier.data, ctx->sessionID.data, sessionIdentifier.length) == 0)
389 ctx->ssl2SessionMatch = 1;
390
391 if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
392 return err;
393
394 return SSLNoErr;
395 }
396
397 SSLErr
398 SSL2InstallSessionKey(SSLContext *ctx)
399 { SSLErr err;
400
401 CASSERT(ctx->ssl2SessionMatch != 0);
402 CASSERT(ctx->resumableSession.data != 0);
403 if (ERR(err = SSLInstallSessionFromData(ctx->resumableSession, ctx)) != 0)
404 return err;
405 return SSLNoErr;
406 }
407
408 SSLErr
409 SSL2GenerateSessionID(SSLContext *ctx)
410 { SSLErr err;
411
412 if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
413 return err;
414 if (ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx)) != 0)
415 return err;
416 if ((err = sslRand(ctx, &ctx->sessionID)) != 0)
417 return err;
418 return SSLNoErr;
419 }
420
421 SSLErr
422 SSL2InitCiphers(SSLContext *ctx)
423 { SSLErr err;
424 int keyMaterialLen;
425 SSLBuffer keyData;
426 uint8 variantChar, *progress, *readKey, *writeKey, *iv;
427 SSLBuffer hashDigest, hashContext, masterKey, challenge, connectionID, variantData;
428
429 keyMaterialLen = 2 * ctx->selectedCipherSpec->cipher->keySize;
430 if (ERR(err = SSLAllocBuffer(&keyData, keyMaterialLen, &ctx->sysCtx)) != 0)
431 return err;
432
433 /* Can't have % in assertion string... */
434 #if SSL_DEBUG
435 {
436 UInt32 keyModDigestSize = keyMaterialLen % SSLHashMD5.digestSize;
437 CASSERT(keyModDigestSize == 0);
438 }
439 #endif
440
441 masterKey.data = ctx->masterSecret;
442 masterKey.length = ctx->selectedCipherSpec->cipher->keySize;
443 challenge.data = ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
444 ctx->ssl2ChallengeLength;
445 challenge.length = ctx->ssl2ChallengeLength;
446 connectionID.data = ctx->serverRandom;
447 connectionID.length = ctx->ssl2ConnectionIDLength;
448 variantData.data = &variantChar;
449 variantData.length = 1;
450 if (ERR(err = SSLAllocBuffer(&hashContext, SSLHashMD5.contextSize, &ctx->sysCtx)) != 0)
451 { ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
452 return err;
453 }
454
455 variantChar = 0x30; /* '0' */
456 progress = keyData.data;
457 while (keyMaterialLen)
458 { hashDigest.data = progress;
459 hashDigest.length = SSLHashMD5.digestSize;
460 if (ERR(err = SSLHashMD5.init(hashContext, ctx)) != 0 ||
461 ERR(err = SSLHashMD5.update(hashContext, masterKey)) != 0 ||
462 ERR(err = SSLHashMD5.update(hashContext, variantData)) != 0 ||
463 ERR(err = SSLHashMD5.update(hashContext, challenge)) != 0 ||
464 ERR(err = SSLHashMD5.update(hashContext, connectionID)) != 0 ||
465 ERR(err = SSLHashMD5.final(hashContext, hashDigest)) != 0)
466 { SSLFreeBuffer(&keyData, &ctx->sysCtx);
467 SSLFreeBuffer(&hashContext, &ctx->sysCtx);
468 return err;
469 }
470 progress += hashDigest.length;
471 ++variantChar;
472 keyMaterialLen -= hashDigest.length;
473 }
474
475 CASSERT(progress == keyData.data + keyData.length);
476
477 if (ERR(err = SSLFreeBuffer(&hashContext, &ctx->sysCtx)) != 0)
478 { ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
479 return err;
480 }
481
482 ctx->readPending.macRef = ctx->selectedCipherSpec->macAlgorithm;
483 ctx->writePending.macRef = ctx->selectedCipherSpec->macAlgorithm;
484 ctx->readPending.symCipher = ctx->selectedCipherSpec->cipher;
485 ctx->writePending.symCipher = ctx->selectedCipherSpec->cipher;
486 ctx->readPending.sequenceNum = ctx->readCipher.sequenceNum;
487 ctx->writePending.sequenceNum = ctx->writeCipher.sequenceNum;
488
489 if (ctx->protocolSide == SSL_ServerSide)
490 { writeKey = keyData.data;
491 readKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
492 }
493 else
494 { readKey = keyData.data;
495 writeKey = keyData.data + ctx->selectedCipherSpec->cipher->keySize;
496 }
497
498 iv = ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize;
499
500 /* APPLE_CDSA symmetric cipher changes....*/
501 if (ERR(err = ctx->readPending.symCipher->initialize(readKey, iv,
502 &ctx->readPending, ctx)) != 0 ||
503 ERR(err = ctx->writePending.symCipher->initialize(writeKey, iv,
504 &ctx->writePending, ctx)) != 0)
505 { ERR(SSLFreeBuffer(&keyData, &ctx->sysCtx));
506 return err;
507 }
508
509 /*
510 * HEY! macSecret is only 20 bytes. This blows up when key size
511 * is greater than 20, e.g., 3DES.
512 * I'll increase the size of macSecret to 24, 'cause it appears
513 * from the SSL v23 spec that the macSecret really the same size as
514 * CLIENT-WRITE-KEY and SERVER-READ-KEY (see 1.2 of the spec).
515 */
516 memcpy(ctx->readPending.macSecret, readKey, ctx->selectedCipherSpec->cipher->keySize);
517 memcpy(ctx->writePending.macSecret, writeKey, ctx->selectedCipherSpec->cipher->keySize);
518
519 if (ERR(err = SSLFreeBuffer(&keyData, &ctx->sysCtx)) != 0)
520 return err;
521
522 ctx->readCipher = ctx->readPending;
523 ctx->writeCipher = ctx->writePending;
524 memset(&ctx->readPending, 0, sizeof(CipherContext)); /* Zero out old data */
525 memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
526
527 return SSLNoErr;
528 }