]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ssl2mesg.c
9be54b22e3d0986dbefc236e093a40bfe19748d0
[apple/security.git] / SecureTransport / ssl2mesg.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: ssl2mesg.c
21
22 SSLRef 3.0 Final -- 11/19/96
23
24 Copyright (c)1996 by Netscape Communications Corp.
25
26 By retrieving this software you are bound by the licensing terms
27 disclosed in the file "LICENSE.txt". Please read it, and if you don't
28 accept the terms, delete this software.
29
30 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
31 View, California <http://home.netscape.com/> and Consensus Development
32 Corporation of Berkeley, California <http://www.consensus.com/>.
33
34 *********************************************************************
35
36 File: ssl2mesg.c Message encoding and decoding functions for SSL 2
37
38 The necessary message encoding and decoding for all SSL 2 handshake
39 messages.
40
41 ****************************************************************** */
42
43 #ifndef _SSL_H_
44 #include "ssl.h"
45 #endif
46
47 #ifndef _SSL2_H_
48 #include "ssl2.h"
49 #endif
50
51 #ifndef _SSLREC_H_
52 #include "sslrec.h"
53 #endif
54
55 #ifndef _SSLALLOC_H_
56 #include "sslalloc.h"
57 #endif
58
59 #ifndef _SSLCTX_H_
60 #include "sslctx.h"
61 #endif
62
63 #ifndef _SSLALERT_H_
64 #include "sslalert.h"
65 #endif
66
67 #ifndef _SSLHDSHK_H_
68 #include "sslhdshk.h"
69 #endif
70
71 #ifndef _SSLSESS_H_
72 #include "sslsess.h"
73 #endif
74
75 #ifndef _SSL_DEBUG_H_
76 #include "sslDebug.h"
77 #endif
78
79 #ifndef _CIPHER_SPECS_H_
80 #include "cipherSpecs.h"
81 #endif
82
83 #ifndef _APPLE_CDSA_H_
84 #include "appleCdsa.h"
85 #endif
86
87 #ifndef _SSLUTIL_H_
88 #include "sslutil.h"
89 #endif
90
91 #include <string.h>
92 #include <assert.h>
93
94 SSLErr
95 SSL2ProcessClientHello(SSLBuffer msg, SSLContext *ctx)
96 { SSLErr err;
97 UInt8 *progress, *cipherList;
98 int i, j, cipherKindCount, sessionIDLen, challengeLen;
99 SSL2CipherKind cipherKind;
100 SSLCipherSuite matchingCipher, selectedCipher;
101 SSLProtocolVersion version;
102
103 if (msg.length < 27) {
104 errorLog0("SSL2ProcessClientHello: msg len error 1\n");
105 return ERR(SSLProtocolErr);
106 }
107
108 progress = msg.data;
109
110 version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
111 if (version > ctx->maxProtocolVersion) {
112 version = ctx->maxProtocolVersion;
113 }
114 /* FIXME - I think this needs work for a SSL_Version_2_0 server, to ensure that
115 * the client isn't establishing a v3 session. */
116 if (ctx->negProtocolVersion == SSL_Version_Undetermined)
117 {
118 #if LOG_NEGOTIATE
119 dprintf1("===SSL2 server: negVersion was undetermined; is %s\n",
120 protocolVersStr(version));
121 #endif
122 ctx->negProtocolVersion = version;
123 if(version >= TLS_Version_1_0) {
124 ctx->sslTslCalls = &Tls1Callouts;
125 }
126 else {
127 /* default from context init */
128 assert(ctx->sslTslCalls == &Ssl3Callouts);
129 }
130 }
131 else if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
132 { if (version < SSL_Version_3_0) {
133 errorLog0("SSL2ProcessClientHello: version error\n");
134 return ERR(SSLProtocolErr);
135 }
136 /* FIXME - I don't think path is ever taken - we NEVER set any
137 * protocol var to SSL_Version_3_0_With_2_0_Hello... */
138 #if LOG_NEGOTIATE
139 dprintf0("===SSL2 server: negVersion was 3_0_With_2_0_Hello; is 3_0\n");
140 #endif
141 ctx->negProtocolVersion = version;
142 }
143
144 progress += 2;
145 cipherKindCount = SSLDecodeInt(progress, 2);
146 progress += 2;
147 if (cipherKindCount % 3 != 0) {
148 errorLog0("SSL2ProcessClientHello: cipherKindCount error\n");
149 return ERR(SSLProtocolErr);
150 }
151 cipherKindCount /= 3;
152 sessionIDLen = SSLDecodeInt(progress, 2);
153 progress += 2;
154 challengeLen = SSLDecodeInt(progress, 2);
155 progress += 2;
156
157 if (msg.length != 8 + 3*cipherKindCount + sessionIDLen + challengeLen ||
158 (sessionIDLen != 0 && sessionIDLen != 16) ||
159 challengeLen < 16 || challengeLen > 32 ) {
160 errorLog0("SSL2ProcessClientHello: msg len error 2\n");
161 return ERR(SSLProtocolErr);
162 }
163 cipherList = progress;
164 selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
165
166 if (ctx->negProtocolVersion >= SSL_Version_3_0) {
167 /* If we're negotiating an SSL 3.0 session, use SSL 3.0 suites first */
168 for (i = 0; i < cipherKindCount; i++) {
169 cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
170 progress += 3;
171 if (selectedCipher != SSL_NO_SUCH_CIPHERSUITE)
172 continue;
173 if ((((UInt32)cipherKind) & 0xFF0000) != 0)
174 continue; /* Skip SSL 2 suites */
175 matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
176 for (j = 0; j<ctx->numValidCipherSpecs; j++) {
177 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher) {
178 selectedCipher = matchingCipher;
179 break;
180 }
181 } /* searching thru all our valid ciphers */
182 } /* for each client cipher */
183 } /* v3 or greater */
184
185 if(selectedCipher == SSL_NO_SUCH_CIPHERSUITE) {
186 /* try again using SSL2 ciphers only */
187 progress = cipherList;
188 for (i = 0; i < cipherKindCount; i++) {
189 cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
190 progress += 3;
191 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) {
192 /* After we find one, just keep advancing progress past
193 * the unused ones */
194 if ((((UInt32)cipherKind) & 0xFF0000) != 0) {
195 /* If it's a real SSL2 spec, look for it in the list */
196 matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
197 for (j = 0; j < SSL2CipherMapCount; j++) {
198 if (cipherKind == SSL2CipherMap[j].cipherKind) {
199 matchingCipher = SSL2CipherMap[j].cipherSuite;
200 break;
201 }
202 }
203 } /* real 3-byte SSL2 suite */
204 else {
205 /* if the first byte is zero, it's an encoded SSL 3 CipherSuite */
206 matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
207 /*
208 * One more restriction - if we've negotiated a v2 session,
209 * ignore this matching cipher if it's not in the SSL2 map.
210 */
211 if(ctx->negProtocolVersion < SSL_Version_3_0) {
212 int isInMap = 0;
213 for (j = 0; j < SSL2CipherMapCount; j++) {
214 if (matchingCipher == SSL2CipherMap[j].cipherSuite) {
215 isInMap = 1;
216 break;
217 }
218 }
219 if(!isInMap) {
220 /* Sorry, no can do */
221 matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
222 }
223 } /* SSL2 check */
224 } /* two-byte suite */
225
226 /* now see if we are enabled for this cipher */
227 if (matchingCipher != SSL_NO_SUCH_CIPHERSUITE) {
228 for (j = 0; j < ctx->numValidCipherSpecs; j++) {
229 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher) {
230 selectedCipher = matchingCipher;
231 break;
232 }
233 }
234 }
235 } /* not ignoring this suite */
236 } /* for each suite in the hello msg */
237 } /* not found in SSL3 ciphersuites */
238
239 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
240 return ERR(SSLNegotiationErr);
241
242 ctx->selectedCipher = selectedCipher;
243 err = FindCipherSpec(ctx);
244 if(err != 0) {
245 return err;
246 }
247 if (sessionIDLen > 0 && ctx->peerID.data != 0)
248 { /* Don't die on error; just treat it as an uncacheable session */
249 ERR(err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx));
250 if (err == 0)
251 memcpy(ctx->sessionID.data, progress, sessionIDLen);
252 }
253 progress += sessionIDLen;
254
255 ctx->ssl2ChallengeLength = challengeLen;
256 memset(ctx->clientRandom, 0, SSL_CLIENT_SRVR_RAND_SIZE);
257 memcpy(ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - challengeLen,
258 progress, challengeLen);
259 progress += challengeLen;
260 CASSERT(progress == msg.data + msg.length);
261
262 return SSLNoErr;
263 }
264
265 /*
266 * The SSL v2 spec says that the challenge string sent by the client can be
267 * between 16 and 32 bytes. However all Netscape enterprise servers actually
268 * require a 16 byte challenge. Q.v. cdnow.com, store.apple.com.
269 * Unfortunately this means that when we're trying to do a
270 * SSL_Version_3_0_With_2_0_Hello negotiation, we have to limit ourself to
271 * a 16-byte clientRandom, which we have to concatenate to 16 bytes of
272 * zeroes if we end up with a 3.0 or 3.1 connection. Thus we lose 16 bytes
273 * of entropy.
274 */
275 #define SSL2_CHALLENGE_LEN 16
276
277 SSLErr
278 SSL2EncodeClientHello(SSLBuffer *msg, SSLContext *ctx)
279 { SSLErr err;
280 UInt8 *progress;
281 int i, j, useSSL3Ciphers, totalCipherCount;
282 int sessionIDLen;
283 UInt16 version;
284 SSLBuffer sessionIdentifier, randomData;
285
286 switch (ctx->negProtocolVersion)
287 { case SSL_Version_Undetermined:
288 case SSL_Version_3_0_With_2_0_Hello:
289 /* go for it, see if server can handle upgrading */
290 useSSL3Ciphers = 1;
291 /* could be SSLv3 or TLSv1 */
292 version = ctx->maxProtocolVersion;
293 break;
294 case SSL_Version_2_0:
295 useSSL3Ciphers = 0;
296 version = SSL_Version_2_0;
297 break;
298 case SSL_Version_3_0_Only:
299 case SSL_Version_3_0:
300 case TLS_Version_1_0_Only:
301 case TLS_Version_1_0:
302 default:
303 ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
304 break;
305 }
306 #if LOG_NEGOTIATE
307 dprintf1("===SSL client: proclaiming %s capable\n",
308 protocolVersStr((SSLProtocolVersion)version));
309 #endif
310
311 if (useSSL3Ciphers != 0)
312 totalCipherCount = ctx->numValidCipherSpecs;
313 else
314 totalCipherCount = 0;
315
316 for (i = 0; i < SSL2CipherMapCount; i++)
317 for (j = 0; j < ctx->numValidCipherSpecs; j++)
318 if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
319 { totalCipherCount++;
320 break;
321 }
322
323 sessionIDLen = 0;
324 sessionIdentifier.data = 0;
325 if (ctx->resumableSession.data != 0)
326 { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
327 return err;
328 sessionIDLen = sessionIdentifier.length;
329 }
330
331 /* msg length = 9 + 3 * totalCipherCount + sessionIDLen + 16 bytes of challenge
332 * Use exactly 16 bytes of challenge because Netscape products have a bug
333 * that requires this length
334 */
335 if (ERR(err = SSLAllocBuffer(msg, 9 + (3*totalCipherCount) + sessionIDLen +
336 SSL2_CHALLENGE_LEN, &ctx->sysCtx)) != 0)
337 { ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
338 return err;
339 }
340
341 progress = msg->data;
342 *progress++ = ssl2_mt_client_hello;
343 progress = SSLEncodeInt(progress, version, 2);
344 progress = SSLEncodeInt(progress, 3*totalCipherCount, 2);
345 progress = SSLEncodeInt(progress, sessionIDLen, 2);
346 progress = SSLEncodeInt(progress, SSL2_CHALLENGE_LEN, 2);
347
348 /* If we can send SSL3 ciphers, encode the two-byte cipher specs into three-byte
349 * CipherKinds which have a leading 0.
350 */
351 if (useSSL3Ciphers != 0)
352 for (i = 0; i < ctx->numValidCipherSpecs; i++)
353 progress = SSLEncodeInt(progress, ctx->validCipherSpecs[i].cipherSpec, 3);
354
355 /* Now send those SSL2 specs for which we have implementations */
356 for (i = 0; i < SSL2CipherMapCount; i++)
357 for (j = 0; j < ctx->numValidCipherSpecs; j++)
358 if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
359 { progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
360 break;
361 }
362
363 if (sessionIDLen > 0)
364 { memcpy(progress, sessionIdentifier.data, sessionIDLen);
365 progress += sessionIDLen;
366 ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
367 }
368
369 randomData.data = progress;
370 randomData.length = SSL2_CHALLENGE_LEN;
371 if ((err = sslRand(ctx, &randomData)) != 0)
372 { ERR(SSLFreeBuffer(msg, &ctx->sysCtx));
373 return err;
374 }
375 progress += SSL2_CHALLENGE_LEN;
376
377 /* Zero out the first 16 bytes of clientRandom, and store
378 * the challenge in the second 16 bytes */
379 #if (SSL2_CHALLENGE_LEN == SSL_CLIENT_SRVR_RAND_SIZE)
380 /* this path verified to fail with Netscape Enterprise servers 1/16/02 */
381 memcpy(ctx->clientRandom, randomData.data, SSL2_CHALLENGE_LEN);
382 #else
383 memset(ctx->clientRandom, 0, SSL_CLIENT_SRVR_RAND_SIZE - SSL2_CHALLENGE_LEN);
384 memcpy(ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE - SSL2_CHALLENGE_LEN,
385 randomData.data, SSL2_CHALLENGE_LEN);
386 #endif
387 ctx->ssl2ChallengeLength = SSL2_CHALLENGE_LEN;
388
389 CASSERT(progress == msg->data + msg->length);
390
391 return SSLNoErr;
392 }
393
394 SSLErr
395 SSL2ProcessClientMasterKey(SSLBuffer msg, SSLContext *ctx)
396 { SSLErr err;
397 SSL2CipherKind cipherKind;
398 SSLBuffer secretData;
399 int clearLength, encryptedLength, keyArgLength;
400 UInt32 secretLength, localKeyModulusLen;
401 UInt8 *progress;
402 const CSSM_KEY *decryptKey;
403 CSSM_CSP_HANDLE decryptCspHand;
404
405 if (msg.length < 9) {
406 errorLog0("SSL2ProcessClientMasterKey: msg.length error 1\n");
407 return ERR(SSLProtocolErr);
408 }
409 CASSERT(ctx->protocolSide == SSL_ServerSide);
410
411 progress = msg.data;
412 cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
413 progress += 3;
414 clearLength = SSLDecodeInt(progress, 2);
415 progress += 2;
416 encryptedLength = SSLDecodeInt(progress, 2);
417 progress += 2;
418 keyArgLength = SSLDecodeInt(progress, 2);
419 progress += 2;
420
421 if (msg.length != 9 + clearLength + encryptedLength + keyArgLength) {
422 errorLog0("SSL2ProcessClientMasterKey: msg.length error 2\n");
423 return ERR(SSLProtocolErr);
424 }
425
426 /* Master key == CLEAR_DATA || SECRET_DATA */
427 memcpy(ctx->masterSecret, progress, clearLength);
428 progress += clearLength;
429
430 /*
431 * Just as in SSL2EncodeServerHello, which key we use depends on the
432 * app's config.
433 */
434 if(ctx->encryptPrivKey) {
435 decryptKey = ctx->encryptPrivKey;
436 CASSERT(ctx->encryptKeyCsp != 0);
437 decryptCspHand = ctx->encryptKeyCsp;
438 }
439 else if(ctx->signingPrivKey) {
440 decryptKey = ctx->signingPrivKey;
441 CASSERT(ctx->signingKeyCsp != 0);
442 decryptCspHand = ctx->signingKeyCsp;
443 }
444 else {
445 /* really should not happen... */
446 errorLog0("SSL2ProcessClientMasterKey: No server key!\n");
447 return SSLBadStateErr;
448 }
449 localKeyModulusLen = sslKeyLengthInBytes(decryptKey);
450
451 if (encryptedLength != localKeyModulusLen) {
452 errorLog0("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
453 return ERR(SSLProtocolErr);
454 }
455
456 /* Allocate enough room to hold any decrypted value */
457 if (ERR(err = SSLAllocBuffer(&secretData, encryptedLength, &ctx->sysCtx)) != 0)
458 return err;
459
460 err = sslRsaDecrypt(ctx,
461 decryptKey,
462 decryptCspHand,
463 progress,
464 encryptedLength,
465 secretData.data,
466 encryptedLength, // same length for both...?
467 &secretLength);
468 if(err) {
469 SSLFreeBuffer(&secretData, &ctx->sysCtx);
470 return err;
471 }
472
473 progress += encryptedLength;
474
475 if (clearLength + secretLength != ctx->selectedCipherSpec->cipher->keySize) {
476 errorLog0("SSL2ProcessClientMasterKey: length error 3\n");
477 return ERR(SSLProtocolErr);
478 }
479 memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
480 if (ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx)) != 0)
481 return err;
482
483 if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize) {
484 errorLog0("SSL2ProcessClientMasterKey: length error 4\n");
485 return ERR(SSLProtocolErr);
486 }
487
488 /* Stash the IV after the master key in master secret storage */
489 memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, progress, keyArgLength);
490 progress += keyArgLength;
491 CASSERT(progress = msg.data + msg.length);
492
493 return SSLNoErr;
494 }
495
496 SSLErr
497 SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx)
498 { SSLErr err;
499 int length, i, clearLen;
500 UInt32 outputLen, peerKeyModulusLen;
501 SSLBuffer keyData;
502 UInt8 *progress;
503
504 peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
505
506 /* Length is 10 + clear key size + encrypted output size + iv size */
507 length = 10;
508 clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
509 length += clearLen;
510 length += peerKeyModulusLen;
511 length += ctx->selectedCipherSpec->cipher->ivSize;
512
513 if (ERR(err = SSLAllocBuffer(msg, length, &ctx->sysCtx)) != 0)
514 return err;
515 progress = msg->data;
516 *progress++ = ssl2_mt_client_master_key;
517 for (i = 0; i < SSL2CipherMapCount; i++)
518 if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
519 break;
520 CASSERT(i < SSL2CipherMapCount);
521 #if LOG_NEGOTIATE
522 dprintf1("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x\n",
523 SSL2CipherMap[i].cipherKind);
524 #endif
525 progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
526 progress = SSLEncodeInt(progress, clearLen, 2);
527 progress = SSLEncodeInt(progress, peerKeyModulusLen, 2);
528 progress = SSLEncodeInt(progress, ctx->selectedCipherSpec->cipher->ivSize, 2);
529
530 /* Generate the keying material; we need enough data for the key and IV */
531 keyData.data = ctx->masterSecret;
532 keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
533 CASSERT(keyData.length <= 48); /* Must be able to store it in the masterSecret array */
534 if ((err = sslRand(ctx, &keyData)) != 0)
535 return err;
536
537 memcpy(progress, ctx->masterSecret, clearLen);
538 progress += clearLen;
539
540 /* Replace this with code to do encryption at lower level & set PKCS1 padding
541 for rollback attack */
542
543 /*
544 * encrypt only the secret key portion of masterSecret, starting at
545 * clearLen bytes
546 */
547 err = sslRsaEncrypt(ctx,
548 ctx->peerPubKey,
549 ctx->peerPubKeyCsp, // XX - maybe cspHand
550 ctx->masterSecret + clearLen,
551 ctx->selectedCipherSpec->cipher->keySize - clearLen,
552 progress,
553 peerKeyModulusLen,
554 &outputLen);
555 if(err) {
556 return err;
557 }
558
559 progress += outputLen;
560
561 /* copy clear IV to msg buf */
562 memcpy(progress, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
563 ctx->selectedCipherSpec->cipher->ivSize);
564 progress += ctx->selectedCipherSpec->cipher->ivSize;
565
566 CASSERT(progress == msg->data + msg->length);
567
568 return SSLNoErr;
569 }
570
571 SSLErr
572 SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
573 { if (msg.length != ctx->sessionID.length) {
574 errorLog0("SSL2ProcessClientFinished: length error\n");
575 return ERR(SSLProtocolErr);
576 }
577 if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0) {
578 errorLog0("SSL2ProcessClientFinished: data compare error\n");
579 return ERR(SSLProtocolErr);
580 }
581 return SSLNoErr;
582 }
583
584 SSLErr
585 SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx)
586 { SSLErr err;
587
588 if (ERR(err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, &ctx->sysCtx)) != 0)
589 return err;
590 msg->data[0] = ssl2_mt_client_finished;
591 memcpy(msg->data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
592 return SSLNoErr;
593 }
594
595 SSLErr
596 SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
597 { SSLErr err;
598 SSL2CertTypeCode certType;
599 int sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
600 int i, j;
601 SSL2CipherKind cipherKind;
602 SSLCertificate *cert;
603 SSLCipherSuite matchingCipher = 0; // avoid compiler warning
604 SSLCipherSuite selectedCipher;
605 UInt8 *progress;
606 SSLProtocolVersion version;
607
608 if (msg.length < 10) {
609 errorLog0("SSL2ProcessServerHello: length error\n");
610 return ERR(SSLProtocolErr);
611 }
612 progress = msg.data;
613
614 sessionIDMatch = *progress++;
615 certType = (SSL2CertTypeCode)*progress++;
616 version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
617 progress += 2;
618 if (version != SSL_Version_2_0) {
619 errorLog0("SSL2ProcessServerHello: version error\n");
620 return ERR(SSLProtocolErr);
621 }
622 ctx->negProtocolVersion = version;
623 #if LOG_NEGOTIATE
624 dprintf0("===SSL2 client: negVersion is 2_0\n");
625 #endif
626 certLen = SSLDecodeInt(progress, 2);
627 progress += 2;
628 cipherSpecsLen = SSLDecodeInt(progress, 2);
629 progress += 2;
630 connectionIDLen = SSLDecodeInt(progress, 2);
631 progress += 2;
632
633 if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
634 (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
635 return ERR(SSLProtocolErr);
636 if (sessionIDMatch != 0)
637 { if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
638 return ERR(SSLProtocolErr);
639 ctx->ssl2SessionMatch = 1;
640
641 ctx->ssl2ConnectionIDLength = connectionIDLen;
642 memcpy(ctx->serverRandom, progress, connectionIDLen);
643 progress += connectionIDLen;
644 }
645 else
646 { if (certType != ssl2_ct_x509_certificate)
647 return ERR(SSLNegotiationErr);
648 cipherSpecsLen /= 3;
649
650 cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
651 if(cert == NULL) {
652 return SSLMemoryErr;
653 }
654 cert->next = 0;
655 if (ERR(err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
656 {
657 sslFree(cert);
658 return err;
659 }
660 memcpy(cert->derCert.data, progress, certLen);
661 progress += certLen;
662 ctx->peerCert = cert;
663 /* This cert never gets verified in original SSLRef3 code... */
664 if((err = sslVerifyCertChain(ctx, ctx->peerCert)) != 0) {
665 return err;
666 }
667 if((err = sslPubKeyFromCert(ctx,
668 &cert->derCert,
669 &ctx->peerPubKey,
670 &ctx->peerPubKeyCsp)) != 0)
671 return err;
672
673 selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
674 for (i = 0; i < cipherSpecsLen; i++)
675 { cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
676 progress += 3;
677 //dprintf1("ssl2: server supports cipherKind 0x%x\n", (UInt32)cipherKind);
678 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing progress past the unused ones */
679 { for (j = 0; j < SSL2CipherMapCount; j++)
680 if (cipherKind == SSL2CipherMap[j].cipherKind)
681 { matchingCipher = SSL2CipherMap[j].cipherSuite;
682 break;
683 }
684 for (j = 0; j < ctx->numValidCipherSpecs; j++)
685 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
686 { selectedCipher = matchingCipher;
687 break;
688 }
689 }
690 }
691 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
692 return ERR(SSLNegotiationErr);
693 #if LOG_NEGOTIATE
694 dprintf1("===SSL2 client: selectedCipher 0x%x\n",
695 (unsigned)selectedCipher);
696 #endif
697
698 ctx->selectedCipher = selectedCipher;
699 if (ERR(err = FindCipherSpec(ctx)) != 0) {
700 return err;
701 }
702 ctx->ssl2ConnectionIDLength = connectionIDLen;
703 memcpy(ctx->serverRandom, progress, connectionIDLen);
704 progress += connectionIDLen;
705 }
706
707 CASSERT(progress == msg.data + msg.length);
708
709 return SSLNoErr;
710 }
711
712 SSLErr
713 SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx)
714 { SSLErr err;
715 SSLCertificate *cert;
716 SSLBuffer randomData;
717 UInt8 *progress;
718 int i;
719
720 /* Create the connection ID */
721 ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
722 randomData.data = ctx->serverRandom;
723 randomData.length = ctx->ssl2ConnectionIDLength;
724 if ((err = sslRand(ctx, &randomData)) != 0)
725 return err;
726
727 if (ctx->ssl2SessionMatch != 0)
728 { if (ERR(err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
729 return err;
730 progress = msg->data;
731 *progress++ = ssl2_mt_server_hello;
732 *progress++ = ctx->ssl2SessionMatch;
733 *progress++ = 0; /* cert type */
734 progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
735 progress = SSLEncodeInt(progress, 0, 2); /* cert len */
736 progress = SSLEncodeInt(progress, 0, 2); /* cipherspecs len */
737 progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
738 memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
739 progress += ctx->ssl2ConnectionIDLength;
740 }
741 else
742 { /* First, find the last cert in the chain; it's the one we'll send */
743
744 /*
745 * Use encryptCert if we have it, but allow for the case of app
746 * specifying one cert which can encrypt and sign.
747 */
748 if(ctx->encryptCert != NULL) {
749 cert = ctx->encryptCert;
750 }
751 else if(ctx->localCert != NULL) {
752 cert = ctx->localCert;
753 }
754 else {
755 /* really should not happen... */
756 errorLog0("SSL2EncodeServerHello: No server cert!\n");
757 return SSLBadStateErr;
758 }
759
760 while (cert->next != 0)
761 cert = cert->next;
762
763 if (ERR(err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
764 return err;
765 progress = msg->data;
766 *progress++ = ssl2_mt_server_hello;
767 *progress++ = ctx->ssl2SessionMatch;
768 *progress++ = ssl2_ct_x509_certificate; /* cert type */
769 #if LOG_NEGOTIATE
770 dprintf1("===SSL2 server: sending vers info %s\n",
771 protocolVersStr((SSLProtocolVersion)ctx->negProtocolVersion));
772 #endif
773 progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
774 progress = SSLEncodeInt(progress, cert->derCert.length, 2);
775 progress = SSLEncodeInt(progress, 3, 2); /* cipherspecs len */
776 progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
777 memcpy(progress, cert->derCert.data, cert->derCert.length);
778 progress += cert->derCert.length;
779 for (i = 0; i < SSL2CipherMapCount; i++)
780 if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
781 break;
782 CASSERT(i < SSL2CipherMapCount);
783 progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
784 dprintf1("ssl2: server specifying cipherKind 0x%lx\n",
785 (UInt32)SSL2CipherMap[i].cipherKind);
786 memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
787 progress += ctx->ssl2ConnectionIDLength;
788 }
789
790 CASSERT(progress == msg->data + msg->length);
791 return SSLNoErr;
792 }
793
794 SSLErr
795 SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
796 { if (msg.length != ctx->ssl2ChallengeLength)
797 return ERR(SSLProtocolErr);
798
799 if (memcmp(msg.data, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
800 ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength) != 0)
801 return ERR(SSLProtocolErr);
802
803 return SSLNoErr;
804 }
805
806 SSLErr
807 SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx)
808 { SSLErr err;
809
810 if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, &ctx->sysCtx)) != 0)
811 return err;
812
813 msg->data[0] = ssl2_mt_server_verify;
814 memcpy(msg->data+1, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
815 ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength);
816
817 return SSLNoErr;
818 }
819
820 SSLErr
821 SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
822 { SSLErr err;
823
824 if (ERR(err = SSLAllocBuffer(&ctx->sessionID, msg.length, &ctx->sysCtx)) != 0)
825 return err;
826 memcpy(ctx->sessionID.data, msg.data, msg.length);
827 return SSLNoErr;
828 }
829
830 SSLErr
831 SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx)
832 { SSLErr err;
833
834 if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
835 return err;
836
837 msg->data[0] = ssl2_mt_server_finished;
838 memcpy(msg->data+1, ctx->sessionID.data, ctx->sessionID.length);
839
840 return SSLNoErr;
841 }