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