]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ssl2Message.cpp
061e3da57d30de1c51d6f7dd16e901f64a66e112
[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 *cssmKey;
334 SecKeyRef decryptKeyRef = NULL;
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->encryptPrivKeyRef) {
366 decryptKeyRef = ctx->encryptPrivKeyRef;
367 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
368 }
369 else if(ctx->signingPrivKeyRef) {
370 decryptKeyRef = ctx->signingPrivKeyRef;
371 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
372 }
373 else {
374 /* app configuration error */
375 sslErrorLog("SSL2ProcessClientMasterKey: No server key!\n");
376 return errSSLBadConfiguration;
377 }
378 err = SecKeyGetCSSMKey(decryptKeyRef, &cssmKey);
379 if(err) {
380 sslErrorLog("SSL2ProcessClientMasterKey: SecKeyGetCSSMKey err %d\n", (int)err);
381 return err;
382 }
383 localKeyModulusLen = sslKeyLengthInBytes(cssmKey);
384
385 if (encryptedLength != localKeyModulusLen) {
386 sslErrorLog("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
387 return errSSLProtocol;
388 }
389
390 /* Allocate enough room to hold any decrypted value */
391 if ((err = SSLAllocBuffer(secretData, encryptedLength, ctx)) != 0)
392 return err;
393
394 err = sslRsaDecrypt(ctx,
395 decryptKeyRef,
396 charPtr,
397 encryptedLength,
398 secretData.data,
399 encryptedLength, // same length for both...?
400 &secretLength);
401 if(err) {
402 SSLFreeBuffer(secretData, ctx);
403 return err;
404 }
405
406 charPtr += encryptedLength;
407
408 if (clearLength + secretLength != ctx->selectedCipherSpec->cipher->keySize) {
409 sslErrorLog("SSL2ProcessClientMasterKey: length error 3\n");
410 return errSSLProtocol;
411 }
412 memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
413 if ((err = SSLFreeBuffer(secretData, ctx)) != 0)
414 return err;
415
416 if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize) {
417 sslErrorLog("SSL2ProcessClientMasterKey: length error 4\n");
418 return errSSLProtocol;
419 }
420
421 /* Stash the IV after the master key in master secret storage */
422 memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, charPtr, keyArgLength);
423 charPtr += keyArgLength;
424 assert(charPtr = msg.data + msg.length);
425
426 return noErr;
427 }
428
429 OSStatus
430 SSL2EncodeClientMasterKey(SSLBuffer &msg, SSLContext *ctx)
431 { OSStatus err;
432 unsigned length, i, clearLen;
433 UInt32 outputLen, peerKeyModulusLen;
434 SSLBuffer keyData;
435 UInt8 *charPtr;
436
437 peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
438
439 /* Length is 10 + clear key size + encrypted output size + iv size */
440 length = 10;
441 clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
442 length += clearLen;
443 length += peerKeyModulusLen;
444 length += ctx->selectedCipherSpec->cipher->ivSize;
445
446 if ((err = SSLAllocBuffer(msg, length, ctx)) != 0)
447 return err;
448 charPtr = msg.data;
449 *charPtr++ = SSL2_MsgClientMasterKey;
450 for (i = 0; i < SSL2CipherMapCount; i++)
451 if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
452 break;
453 assert(i < SSL2CipherMapCount);
454 sslLogNegotiateDebug("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x",
455 SSL2CipherMap[i].cipherKind);
456 charPtr = SSLEncodeInt(charPtr, SSL2CipherMap[i].cipherKind, 3);
457 charPtr = SSLEncodeInt(charPtr, clearLen, 2);
458 charPtr = SSLEncodeInt(charPtr, peerKeyModulusLen, 2);
459 charPtr = SSLEncodeInt(charPtr, ctx->selectedCipherSpec->cipher->ivSize, 2);
460
461 /* Generate the keying material; we need enough data for the key and IV */
462 keyData.data = ctx->masterSecret;
463 keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
464 assert(keyData.length <= 48); /* Must be able to store it in the masterSecret array */
465 if ((err = sslRand(ctx, &keyData)) != 0)
466 return err;
467
468 memcpy(charPtr, ctx->masterSecret, clearLen);
469 charPtr += clearLen;
470
471 /* Replace this with code to do encryption at lower level & set PKCS1 padding
472 for rollback attack */
473
474 /*
475 * encrypt only the secret key portion of masterSecret, starting at
476 * clearLen bytes
477 */
478 err = sslRsaEncrypt(ctx,
479 ctx->peerPubKey,
480 ctx->peerPubKeyCsp, // XX - maybe cspHand
481 ctx->masterSecret + clearLen,
482 ctx->selectedCipherSpec->cipher->keySize - clearLen,
483 charPtr,
484 peerKeyModulusLen,
485 &outputLen);
486 if(err) {
487 return err;
488 }
489
490 charPtr += outputLen;
491
492 /* copy clear IV to msg buf */
493 memcpy(charPtr, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
494 ctx->selectedCipherSpec->cipher->ivSize);
495 charPtr += ctx->selectedCipherSpec->cipher->ivSize;
496
497 assert(charPtr == msg.data + msg.length);
498
499 return noErr;
500 }
501
502 OSStatus
503 SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
504 { if (msg.length != ctx->sessionID.length) {
505 sslErrorLog("SSL2ProcessClientFinished: length error\n");
506 return errSSLProtocol;
507 }
508 if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0) {
509 sslErrorLog("SSL2ProcessClientFinished: data compare error\n");
510 return errSSLProtocol;
511 }
512 return noErr;
513 }
514
515 OSStatus
516 SSL2EncodeClientFinished(SSLBuffer &msg, SSLContext *ctx)
517 { OSStatus err;
518
519 if ((err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, ctx)) != 0)
520 return err;
521 msg.data[0] = SSL2_MsgClientFinished;
522 memcpy(msg.data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
523 return noErr;
524 }
525
526 OSStatus
527 SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
528 { OSStatus err;
529 SSL2CertTypeCode certType;
530 unsigned sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
531 unsigned i, j;
532 SSL2CipherKind cipherKind;
533 SSLCertificate *cert;
534 SSLCipherSuite matchingCipher = 0; // avoid compiler warning
535 SSLCipherSuite selectedCipher;
536 UInt8 *charPtr;
537 SSLProtocolVersion version;
538
539 if (msg.length < 10) {
540 sslErrorLog("SSL2ProcessServerHello: length error\n");
541 return errSSLProtocol;
542 }
543 charPtr = msg.data;
544
545 sessionIDMatch = *charPtr++;
546 certType = (SSL2CertTypeCode)*charPtr++;
547 version = (SSLProtocolVersion)SSLDecodeInt(charPtr, 2);
548 charPtr += 2;
549 if (version != SSL_Version_2_0) {
550 sslErrorLog("SSL2ProcessServerHello: version error\n");
551 return errSSLProtocol;
552 }
553 ctx->negProtocolVersion = version;
554 sslLogNegotiateDebug("===SSL2 client: negVersion is 2_0");
555 certLen = SSLDecodeInt(charPtr, 2);
556 charPtr += 2;
557 cipherSpecsLen = SSLDecodeInt(charPtr, 2);
558 charPtr += 2;
559 connectionIDLen = SSLDecodeInt(charPtr, 2);
560 charPtr += 2;
561
562 if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
563 (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
564 return errSSLProtocol;
565 if (sessionIDMatch != 0)
566 { if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
567 return errSSLProtocol;
568 ctx->sessionMatch = 1;
569
570 ctx->ssl2ConnectionIDLength = connectionIDLen;
571 memcpy(ctx->serverRandom, charPtr, connectionIDLen);
572 charPtr += connectionIDLen;
573 }
574 else
575 { if (certType != SSL2_CertTypeX509)
576 return errSSLNegotiation;
577 cipherSpecsLen /= 3;
578
579 cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
580 if(cert == NULL) {
581 return memFullErr;
582 }
583 cert->next = 0;
584 if ((err = SSLAllocBuffer(cert->derCert, certLen, ctx)) != 0)
585 {
586 sslFree(cert);
587 return err;
588 }
589 memcpy(cert->derCert.data, charPtr, certLen);
590 charPtr += certLen;
591 ctx->peerCert = cert;
592 if((err = sslVerifyCertChain(ctx, *ctx->peerCert)) != 0) {
593 return err;
594 }
595 if((err = sslPubKeyFromCert(ctx,
596 cert->derCert,
597 &ctx->peerPubKey,
598 &ctx->peerPubKeyCsp)) != 0)
599 return err;
600
601 selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
602 for (i = 0; i < cipherSpecsLen; i++)
603 { cipherKind = (SSL2CipherKind)SSLDecodeInt(charPtr, 3);
604 charPtr += 3;
605 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing charPtr past the unused ones */
606 { for (j = 0; j < SSL2CipherMapCount; j++)
607 if (cipherKind == SSL2CipherMap[j].cipherKind)
608 { matchingCipher = SSL2CipherMap[j].cipherSuite;
609 break;
610 }
611 for (j = 0; j < ctx->numValidCipherSpecs; j++)
612 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
613 { selectedCipher = matchingCipher;
614 break;
615 }
616 }
617 }
618 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
619 return errSSLNegotiation;
620 sslLogNegotiateDebug("===SSL2 client: selectedCipher 0x%x",
621 (unsigned)selectedCipher);
622
623 ctx->selectedCipher = selectedCipher;
624 if ((err = FindCipherSpec(ctx)) != 0) {
625 return err;
626 }
627 ctx->ssl2ConnectionIDLength = connectionIDLen;
628 memcpy(ctx->serverRandom, charPtr, connectionIDLen);
629 charPtr += connectionIDLen;
630 }
631
632 assert(charPtr == msg.data + msg.length);
633
634 return noErr;
635 }
636
637 OSStatus
638 SSL2EncodeServerHello(SSLBuffer &msg, SSLContext *ctx)
639 { OSStatus err;
640 SSLCertificate *cert;
641 SSLBuffer randomData;
642 UInt8 *charPtr;
643 unsigned i;
644
645 /* Create the connection ID */
646 ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
647 randomData.data = ctx->serverRandom;
648 randomData.length = ctx->ssl2ConnectionIDLength;
649 if ((err = sslRand(ctx, &randomData)) != 0)
650 return err;
651
652 if (ctx->sessionMatch != 0)
653 { if ((err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, ctx)) != 0)
654 return err;
655 charPtr = msg.data;
656 *charPtr++ = SSL2_MsgServerHello;
657 *charPtr++ = ctx->sessionMatch;
658 *charPtr++ = 0; /* cert type */
659 charPtr = SSLEncodeInt(charPtr, ctx->negProtocolVersion, 2);
660 charPtr = SSLEncodeInt(charPtr, 0, 2); /* cert len */
661 charPtr = SSLEncodeInt(charPtr, 0, 2); /* cipherspecs len */
662 charPtr = SSLEncodeInt(charPtr, ctx->ssl2ConnectionIDLength, 2);
663 memcpy(charPtr, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
664 charPtr += ctx->ssl2ConnectionIDLength;
665 }
666 else
667 { /* First, find the last cert in the chain; it's the one we'll send */
668
669 /*
670 * Use encryptCert if we have it, but allow for the case of app
671 * specifying one cert which can encrypt and sign.
672 */
673 if(ctx->encryptCert != NULL) {
674 cert = ctx->encryptCert;
675 }
676 else if(ctx->localCert != NULL) {
677 cert = ctx->localCert;
678 }
679 else {
680 /* really should not happen... */
681 sslErrorLog("SSL2EncodeServerHello: No server cert!\n");
682 return badReqErr;
683 }
684
685 while (cert->next != 0)
686 cert = cert->next;
687
688 if ((err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, ctx)) != 0)
689 return err;
690 charPtr = msg.data;
691 *charPtr++ = SSL2_MsgServerHello;
692 *charPtr++ = ctx->sessionMatch;
693 *charPtr++ = SSL2_CertTypeX509; /* cert type */
694
695 #ifndef NDEBUG
696 sslLogNegotiateDebug("===SSL2 server: sending vers info %s",
697 protocolVersStr((SSLProtocolVersion)ctx->negProtocolVersion));
698 #endif
699
700 charPtr = SSLEncodeInt(charPtr, ctx->negProtocolVersion, 2);
701 charPtr = SSLEncodeInt(charPtr, cert->derCert.length, 2);
702 charPtr = SSLEncodeInt(charPtr, 3, 2); /* cipherspecs len */
703 charPtr = SSLEncodeInt(charPtr, ctx->ssl2ConnectionIDLength, 2);
704 memcpy(charPtr, cert->derCert.data, cert->derCert.length);
705 charPtr += cert->derCert.length;
706 for (i = 0; i < SSL2CipherMapCount; i++)
707 if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
708 break;
709 assert(i < SSL2CipherMapCount);
710 charPtr = SSLEncodeInt(charPtr, SSL2CipherMap[i].cipherKind, 3);
711 sslLogNegotiateDebug("ssl2: server specifying cipherKind 0x%lx",
712 (UInt32)SSL2CipherMap[i].cipherKind);
713 memcpy(charPtr, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
714 charPtr += ctx->ssl2ConnectionIDLength;
715 }
716
717 assert(charPtr == msg.data + msg.length);
718 return noErr;
719 }
720
721 OSStatus
722 SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
723 { if (msg.length != ctx->ssl2ChallengeLength)
724 return errSSLProtocol;
725
726 if (memcmp(msg.data, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
727 ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength) != 0)
728 return errSSLProtocol;
729
730 return noErr;
731 }
732
733 OSStatus
734 SSL2EncodeServerVerify(SSLBuffer &msg, SSLContext *ctx)
735 { OSStatus err;
736
737 if ((err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, ctx)) != 0)
738 return err;
739
740 msg.data[0] = SSL2_MsgServerVerify;
741 memcpy(msg.data+1, ctx->clientRandom + SSL_CLIENT_SRVR_RAND_SIZE -
742 ctx->ssl2ChallengeLength, ctx->ssl2ChallengeLength);
743
744 return noErr;
745 }
746
747 OSStatus
748 SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
749 { OSStatus err;
750
751 if ((err = SSLAllocBuffer(ctx->sessionID, msg.length, ctx)) != 0)
752 return err;
753 memcpy(ctx->sessionID.data, msg.data, msg.length);
754 return noErr;
755 }
756
757 OSStatus
758 SSL2EncodeServerFinished(SSLBuffer &msg, SSLContext *ctx)
759 { OSStatus err;
760
761 if ((err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, ctx)) != 0)
762 return err;
763
764 msg.data[0] = SSL2_MsgServerFinished;
765 memcpy(msg.data+1, ctx->sessionID.data, ctx->sessionID.length);
766
767 return noErr;
768 }