]> git.saurik.com Git - apple/security.git/blob - SecureTransport/ssl2mesg.c
Security-29.tar.gz
[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
93 SSLErr
94 SSL2ProcessClientHello(SSLBuffer msg, SSLContext *ctx)
95 { SSLErr err;
96 UInt8 *progress, *cipherList;
97 int i, j, cipherKindCount, sessionIDLen, challengeLen;
98 SSL2CipherKind cipherKind;
99 SSLCipherSuite matchingCipher, selectedCipher;
100 SSLProtocolVersion version;
101
102 if (msg.length < 27) {
103 errorLog0("SSL2ProcessClientHello: msg len error 1\n");
104 return ERR(SSLProtocolErr);
105 }
106
107 progress = msg.data;
108
109 version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
110 /* FIXME - ensure client isn't slipping under a SSL_Version_3_0_Only spec... */
111 if (ctx->negProtocolVersion == SSL_Version_Undetermined)
112 { if (version > SSL_Version_3_0)
113 version = SSL_Version_3_0;
114 #if LOG_NEGOTIATE
115 dprintf1("===SSL2 server: negVersion was undetermined; is %s\n",
116 protocolVersStr(version));
117 #endif
118 ctx->negProtocolVersion = version;
119 }
120 else if (ctx->negProtocolVersion == SSL_Version_3_0_With_2_0_Hello)
121 { if (version < SSL_Version_3_0) {
122 errorLog0("SSL2ProcessClientHello: version error\n");
123 return ERR(SSLProtocolErr);
124 }
125 #if LOG_NEGOTIATE
126 dprintf0("===SSL2 server: negVersion was 3_0_With_2_0_Hello; is 3_0\n");
127 #endif
128 ctx->negProtocolVersion = SSL_Version_3_0;
129 }
130
131 progress += 2;
132 cipherKindCount = SSLDecodeInt(progress, 2);
133 progress += 2;
134 if (cipherKindCount % 3 != 0) {
135 errorLog0("SSL2ProcessClientHello: cipherKindCount error\n");
136 return ERR(SSLProtocolErr);
137 }
138 cipherKindCount /= 3;
139 sessionIDLen = SSLDecodeInt(progress, 2);
140 progress += 2;
141 challengeLen = SSLDecodeInt(progress, 2);
142 progress += 2;
143
144 if (msg.length != 8 + 3*cipherKindCount + sessionIDLen + challengeLen ||
145 (sessionIDLen != 0 && sessionIDLen != 16) ||
146 challengeLen < 16 || challengeLen > 32 ) {
147 errorLog0("SSL2ProcessClientHello: msg len error 2\n");
148 return ERR(SSLProtocolErr);
149 }
150 cipherList = progress;
151 selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
152
153 if (ctx->negProtocolVersion == SSL_Version_3_0) /* If we're negotiating an SSL 3.0 session, use SSL 3.0 suites first */
154 { for (i = 0; i < cipherKindCount; i++)
155 { cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
156 progress += 3;
157 if (selectedCipher != SSL_NO_SUCH_CIPHERSUITE)
158 continue;
159 if ((((UInt32)cipherKind) & 0xFF0000) != 0)
160 continue; /* Skip SSL 2 suites */
161 matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
162 for (j = 0; j<ctx->numValidCipherSpecs; j++)
163 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
164 { selectedCipher = matchingCipher;
165 break;
166 }
167 }
168 }
169
170 progress = cipherList;
171 for (i = 0; i < cipherKindCount; i++)
172 { cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
173 progress += 3;
174 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing progress past the unused ones */
175 { if ((((UInt32)cipherKind) & 0xFF0000) != 0) /* If it's a real SSL2 spec, look for it in the list */
176 { matchingCipher = SSL_NO_SUCH_CIPHERSUITE;
177 for (j = 0; j < SSL2CipherMapCount; j++)
178 if (cipherKind == SSL2CipherMap[j].cipherKind)
179 { matchingCipher = SSL2CipherMap[j].cipherSuite;
180 break;
181 }
182 }
183 else /* if the first byte is zero, it's an encoded SSL 3 CipherSuite */
184 matchingCipher = (SSLCipherSuite)((UInt32)cipherKind & 0x00FFFF);
185 if (matchingCipher != SSL_NO_SUCH_CIPHERSUITE)
186 for (j = 0; j < ctx->numValidCipherSpecs; j++)
187 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
188 { selectedCipher = matchingCipher;
189 break;
190 }
191 }
192 }
193 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
194 return ERR(SSLNegotiationErr);
195
196 ctx->selectedCipher = selectedCipher;
197 err = FindCipherSpec(ctx);
198 if(err != 0) {
199 return err;
200 }
201 if (sessionIDLen > 0 && ctx->peerID.data != 0)
202 { /* Don't die on error; just treat it as an uncacheable session */
203 ERR(err = SSLAllocBuffer(&ctx->sessionID, sessionIDLen, &ctx->sysCtx));
204 if (err == 0)
205 memcpy(ctx->sessionID.data, progress, sessionIDLen);
206 }
207 progress += sessionIDLen;
208
209 ctx->ssl2ChallengeLength = challengeLen;
210 memset(ctx->clientRandom, 0, 32);
211 memcpy(ctx->clientRandom+32 - challengeLen, progress, challengeLen);
212 progress += challengeLen;
213 CASSERT(progress == msg.data + msg.length);
214
215 return SSLNoErr;
216 }
217
218 SSLErr
219 SSL2EncodeClientHello(SSLBuffer *msg, SSLContext *ctx)
220 { SSLErr err;
221 UInt8 *progress;
222 int i, j, useSSL3Ciphers, totalCipherCount;
223 int sessionIDLen;
224 UInt16 version;
225 SSLBuffer sessionIdentifier, randomData;
226
227 switch (ctx->negProtocolVersion)
228 { case SSL_Version_Undetermined:
229 case SSL_Version_3_0_With_2_0_Hello:
230 /* go for it, see if server can handle upgrading */
231 useSSL3Ciphers = 1;
232 version = SSL_Version_3_0;
233 break;
234 case SSL_Version_2_0:
235 useSSL3Ciphers = 0;
236 version = SSL_Version_2_0;
237 break;
238 case SSL_Version_3_0_Only:
239 case SSL_Version_3_0:
240 default:
241 ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
242 break;
243 }
244 #if LOG_NEGOTIATE
245 dprintf1("===SSL client: proclaiming %s capable\n",
246 protocolVersStr((SSLProtocolVersion)version));
247 #endif
248
249 if (useSSL3Ciphers != 0)
250 totalCipherCount = ctx->numValidCipherSpecs;
251 else
252 totalCipherCount = 0;
253
254 for (i = 0; i < SSL2CipherMapCount; i++)
255 for (j = 0; j < ctx->numValidCipherSpecs; j++)
256 if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
257 { totalCipherCount++;
258 break;
259 }
260
261 sessionIDLen = 0;
262 sessionIdentifier.data = 0;
263 if (ctx->resumableSession.data != 0)
264 { if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
265 return err;
266 sessionIDLen = sessionIdentifier.length;
267 }
268
269 /* msg length = 9 + 3 * totalCipherCount + sessionIDLen + 16 bytes of challenge
270 * Use exactly 16 bytes of challenge because Netscape products have a bug
271 * that requires this length
272 */
273 if (ERR(err = SSLAllocBuffer(msg, 9 + (3*totalCipherCount) + sessionIDLen + 16, &ctx->sysCtx)) != 0)
274 { ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
275 return err;
276 }
277
278 progress = msg->data;
279 *progress++ = ssl2_mt_client_hello;
280 progress = SSLEncodeInt(progress, version, 2);
281 progress = SSLEncodeInt(progress, 3*totalCipherCount, 2);
282 progress = SSLEncodeInt(progress, sessionIDLen, 2);
283 progress = SSLEncodeInt(progress, 16, 2);
284
285 /* If we can send SSL3 ciphers, encode the two-byte cipher specs into three-byte
286 * CipherKinds which have a leading 0.
287 */
288 if (useSSL3Ciphers != 0)
289 for (i = 0; i < ctx->numValidCipherSpecs; i++)
290 progress = SSLEncodeInt(progress, ctx->validCipherSpecs[i].cipherSpec, 3);
291
292 /* Now send those SSL2 specs for which we have implementations */
293 for (i = 0; i < SSL2CipherMapCount; i++)
294 for (j = 0; j < ctx->numValidCipherSpecs; j++)
295 if (ctx->validCipherSpecs[j].cipherSpec == SSL2CipherMap[i].cipherSuite)
296 { progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
297 break;
298 }
299
300 if (sessionIDLen > 0)
301 { memcpy(progress, sessionIdentifier.data, sessionIDLen);
302 progress += sessionIDLen;
303 ERR(SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx));
304 }
305
306 randomData.data = progress;
307 randomData.length = 16;
308 #ifdef _APPLE_CDSA_
309 if ((err = sslRand(ctx, &randomData)) != 0)
310 #else
311 if (ERR(err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
312 #endif
313 { ERR(SSLFreeBuffer(msg, &ctx->sysCtx));
314 return err;
315 }
316 progress += 16;
317
318 /* Zero out the first 16 bytes of clientRandom, and store the challenge in the
319 second 16 bytes */
320 memset(ctx->clientRandom, 0, 16);
321 memcpy(ctx->clientRandom+16, randomData.data, 16);
322 ctx->ssl2ChallengeLength = 16;
323
324 CASSERT(progress == msg->data + msg->length);
325
326 return SSLNoErr;
327 }
328
329 SSLErr
330 SSL2ProcessClientMasterKey(SSLBuffer msg, SSLContext *ctx)
331 { SSLErr err;
332 SSL2CipherKind cipherKind;
333 SSLBuffer secretData;
334 int clearLength, encryptedLength, keyArgLength;
335 UInt32 secretLength, localKeyModulusLen;
336 UInt8 *progress;
337
338 if (msg.length < 9) {
339 errorLog0("SSL2ProcessClientMasterKey: msg.length error 1\n");
340 return ERR(SSLProtocolErr);
341 }
342 CASSERT(ctx->protocolSide == SSL_ServerSide);
343
344 progress = msg.data;
345 cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
346 progress += 3;
347 clearLength = SSLDecodeInt(progress, 2);
348 progress += 2;
349 encryptedLength = SSLDecodeInt(progress, 2);
350 progress += 2;
351 keyArgLength = SSLDecodeInt(progress, 2);
352 progress += 2;
353
354 if (msg.length != 9 + clearLength + encryptedLength + keyArgLength) {
355 errorLog0("SSL2ProcessClientMasterKey: msg.length error 2\n");
356 return ERR(SSLProtocolErr);
357 }
358
359 /* Master key == CLEAR_DATA || SECRET_DATA */
360 memcpy(ctx->masterSecret, progress, clearLength);
361 progress += clearLength;
362
363 #if RSAREF
364 localKeyModulusLen = (ctx->localKey.bits + 7)/8;
365 #elif BSAFE
366 { A_RSA_KEY *keyInfo;
367 int rsaResult;
368
369 if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->localKey, KI_RSAPublic)) != 0)
370 return SSLUnknownErr;
371 localKeyModulusLen = keyInfo->modulus.len;
372 }
373 #elif _APPLE_CDSA_
374 CASSERT(ctx->encryptPrivKey != NULL);
375 localKeyModulusLen = sslKeyLengthInBytes(ctx->encryptPrivKey);
376 #else
377 #error No Asymmetric crypto
378 #endif /* RSAREF / BSAFE */
379
380 if (encryptedLength != localKeyModulusLen) {
381 errorLog0("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
382 return ERR(SSLProtocolErr);
383 }
384
385 /* Allocate enough room to hold any decrypted value */
386 if (ERR(err = SSLAllocBuffer(&secretData, encryptedLength, &ctx->sysCtx)) != 0)
387 return err;
388
389 #if RSAREF
390 /* Replace this with code to do decryption at lower level & check PKCS1 padding
391 for rollback attack */
392 if ((RSAPrivateDecrypt(secretData.data, &secretLength, progress, encryptedLength, &ctx->localKey)) != 0)
393 { ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx));
394 return ERR(SSLUnknownErr);
395 }
396 #elif BSAFE
397 { B_ALGORITHM_OBJ rsa;
398 B_ALGORITHM_METHOD *chooser[] = { &AM_RSA_CRT_DECRYPT, 0 };
399 int rsaResult;
400 unsigned int decryptLen;
401
402 if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
403 return SSLUnknownErr;
404 if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
405 return SSLUnknownErr;
406 if ((rsaResult = B_DecryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
407 return SSLUnknownErr;
408 if ((rsaResult = B_DecryptUpdate(rsa, secretData.data, &decryptLen, encryptedLength,
409 progress, encryptedLength, 0, NO_SURR)) != 0)
410 return SSLUnknownErr;
411 secretLength = decryptLen;
412 if ((rsaResult = B_DecryptFinal(rsa, secretData.data+secretLength,
413 &decryptLen, encryptedLength-secretLength, 0, NO_SURR)) != 0)
414 return SSLUnknownErr;
415 secretLength += decryptLen;
416 B_DestroyAlgorithmObject(&rsa);
417 }
418 #elif _APPLE_CDSA_
419 /*
420 * note we use encryptPrivKey, not signingPrivKey - this really is
421 * a decrypt op. Servers have to be configured with valid encryption cert
422 * chain to work with SSL2.
423 */
424 err = sslRsaDecrypt(ctx,
425 ctx->encryptPrivKey,
426 ctx->encryptKeyCsp,
427 progress,
428 encryptedLength,
429 secretData.data,
430 encryptedLength, // same length for both...?
431 &secretLength);
432 if(err) {
433 SSLFreeBuffer(&secretData, &ctx->sysCtx);
434 return err;
435 }
436 #endif /* RSAREF / BSAFE */
437
438 progress += encryptedLength;
439
440 if (clearLength + secretLength != ctx->selectedCipherSpec->cipher->keySize) {
441 errorLog0("SSL2ProcessClientMasterKey: length error 3\n");
442 return ERR(SSLProtocolErr);
443 }
444 memcpy(ctx->masterSecret + clearLength, secretData.data, secretLength);
445 if (ERR(err = SSLFreeBuffer(&secretData, &ctx->sysCtx)) != 0)
446 return err;
447
448 if (keyArgLength != ctx->selectedCipherSpec->cipher->ivSize) {
449 errorLog0("SSL2ProcessClientMasterKey: length error 4\n");
450 return ERR(SSLProtocolErr);
451 }
452
453 /* Stash the IV after the master key in master secret storage */
454 memcpy(ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize, progress, keyArgLength);
455 progress += keyArgLength;
456 CASSERT(progress = msg.data + msg.length);
457
458 return SSLNoErr;
459 }
460
461 SSLErr
462 SSL2EncodeClientMasterKey(SSLBuffer *msg, SSLContext *ctx)
463 { SSLErr err;
464 int length, i, clearLen;
465 UInt32 outputLen, peerKeyModulusLen;
466 SSLBuffer keyData;
467 UInt8 *progress;
468 #ifndef _APPLE_CDSA_
469 SSLRandomCtx rsaRandom;
470 int rsaResult;
471 #endif
472
473 #if RSAREF
474 peerKeyModulusLen = (ctx->peerKey.bits + 7)/8;
475 #elif BSAFE
476 { A_RSA_KEY *keyInfo;
477 int rsaResult;
478
479 if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
480 return SSLUnknownErr;
481 peerKeyModulusLen = keyInfo->modulus.len;
482 }
483 #elif _APPLE_CDSA_
484 peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
485 #endif /* RSAREF / BSAFE */
486
487 /* Length is 10 + clear key size + encrypted output size + iv size */
488 length = 10;
489 clearLen = ctx->selectedCipherSpec->cipher->keySize - ctx->selectedCipherSpec->cipher->secretKeySize;
490 length += clearLen;
491 length += peerKeyModulusLen;
492 length += ctx->selectedCipherSpec->cipher->ivSize;
493
494 if (ERR(err = SSLAllocBuffer(msg, length, &ctx->sysCtx)) != 0)
495 return err;
496 progress = msg->data;
497 *progress++ = ssl2_mt_client_master_key;
498 for (i = 0; i < SSL2CipherMapCount; i++)
499 if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
500 break;
501 CASSERT(i < SSL2CipherMapCount);
502 #if LOG_NEGOTIATE
503 dprintf1("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x\n",
504 SSL2CipherMap[i].cipherKind);
505 #endif
506 progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
507 progress = SSLEncodeInt(progress, clearLen, 2);
508 progress = SSLEncodeInt(progress, peerKeyModulusLen, 2);
509 progress = SSLEncodeInt(progress, ctx->selectedCipherSpec->cipher->ivSize, 2);
510
511 /* Generate the keying material; we need enough data for the key and IV */
512 keyData.data = ctx->masterSecret;
513 keyData.length = ctx->selectedCipherSpec->cipher->keySize + ctx->selectedCipherSpec->cipher->ivSize;
514 CASSERT(keyData.length <= 48); /* Must be able to store it in the masterSecret array */
515 #ifdef _APPLE_CDSA_
516 if ((err = sslRand(ctx, &keyData)) != 0)
517 #else
518 if (ERR(err = ctx->sysCtx.random(keyData, ctx->sysCtx.randomRef)) != 0)
519 #endif
520 return err;
521
522 memcpy(progress, ctx->masterSecret, clearLen);
523 progress += clearLen;
524
525 #ifndef _APPLE_CDSA_
526 if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
527 return err;
528 #endif
529
530 /* Replace this with code to do encryption at lower level & set PKCS1 padding
531 for rollback attack */
532 #if RSAREF
533 if ((rsaResult = RSAPublicEncrypt(progress, &outputLen,
534 ctx->masterSecret + clearLen,
535 ctx->selectedCipherSpec->cipher->keySize - clearLen,
536 &ctx->peerKey,&rsaRandom)) != 0)
537 { R_RandomFinal(&rsaRandom);
538 return ERR(SSLUnknownErr);
539 }
540 #elif BSAFE
541 { B_ALGORITHM_OBJ rsa;
542 B_ALGORITHM_METHOD *chooser[] = { &AM_RSA_ENCRYPT, 0 };
543 unsigned int encryptedOut;
544
545 if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
546 return SSLUnknownErr;
547 if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
548 return SSLUnknownErr;
549 if ((rsaResult = B_EncryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
550 return SSLUnknownErr;
551 if ((rsaResult = B_EncryptUpdate(rsa, progress,
552 &encryptedOut, peerKeyModulusLen, ctx->masterSecret + clearLen,
553 ctx->selectedCipherSpec->cipher->keySize - clearLen,
554 rsaRandom, NO_SURR)) != 0)
555 return SSLUnknownErr;
556 outputLen = encryptedOut;
557 if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
558 &encryptedOut, peerKeyModulusLen-outputLen, rsaRandom, NO_SURR)) != 0)
559 return SSLUnknownErr;
560 outputLen += encryptedOut;
561 B_DestroyAlgorithmObject(&rsa);
562 }
563 #elif _APPLE_CDSA_
564 /*
565 * encrypt only the secret key portion of masterSecret, starting at
566 * clearLen bytes
567 */
568 err = sslRsaEncrypt(ctx,
569 ctx->peerPubKey,
570 ctx->peerPubKeyCsp, // XX - maybe cspHand
571 ctx->masterSecret + clearLen,
572 ctx->selectedCipherSpec->cipher->keySize - clearLen,
573 progress,
574 peerKeyModulusLen,
575 &outputLen);
576 if(err) {
577 return err;
578 }
579 #endif
580
581 progress += outputLen;
582
583 #if RSAREF
584 R_RandomFinal(&rsaRandom);
585 #elif BSAFE
586 B_DestroyAlgorithmObject(&rsaRandom);
587 #endif
588
589 /* copy clear IV to msg buf */
590 memcpy(progress, ctx->masterSecret + ctx->selectedCipherSpec->cipher->keySize,
591 ctx->selectedCipherSpec->cipher->ivSize);
592 progress += ctx->selectedCipherSpec->cipher->ivSize;
593
594 CASSERT(progress == msg->data + msg->length);
595
596 return SSLNoErr;
597 }
598
599 SSLErr
600 SSL2ProcessClientFinished(SSLBuffer msg, SSLContext *ctx)
601 { if (msg.length != ctx->sessionID.length) {
602 errorLog0("SSL2ProcessClientFinished: length error\n");
603 return ERR(SSLProtocolErr);
604 }
605 if (memcmp(msg.data, ctx->serverRandom, ctx->ssl2ConnectionIDLength) != 0) {
606 errorLog0("SSL2ProcessClientFinished: data compare error\n");
607 return ERR(SSLProtocolErr);
608 }
609 return SSLNoErr;
610 }
611
612 SSLErr
613 SSL2EncodeClientFinished(SSLBuffer *msg, SSLContext *ctx)
614 { SSLErr err;
615
616 if (ERR(err = SSLAllocBuffer(msg, ctx->ssl2ConnectionIDLength+1, &ctx->sysCtx)) != 0)
617 return err;
618 msg->data[0] = ssl2_mt_client_finished;
619 memcpy(msg->data+1, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
620 return SSLNoErr;
621 }
622
623 SSLErr
624 SSL2ProcessServerHello(SSLBuffer msg, SSLContext *ctx)
625 { SSLErr err;
626 SSL2CertTypeCode certType;
627 int sessionIDMatch, certLen, cipherSpecsLen, connectionIDLen;
628 int i, j;
629 SSL2CipherKind cipherKind;
630 #ifndef __APPLE__
631 SSLBuffer certBuf;
632 #endif
633 SSLCertificate *cert;
634 SSLCipherSuite matchingCipher = 0; // avoid compiler warning
635 SSLCipherSuite selectedCipher;
636 UInt8 *progress;
637 SSLProtocolVersion version;
638
639 if (msg.length < 10) {
640 errorLog0("SSL2ProcessServerHello: length error\n");
641 return ERR(SSLProtocolErr);
642 }
643 progress = msg.data;
644
645 sessionIDMatch = *progress++;
646 certType = (SSL2CertTypeCode)*progress++;
647 version = (SSLProtocolVersion)SSLDecodeInt(progress, 2);
648 progress += 2;
649 if (version != SSL_Version_2_0) {
650 errorLog0("SSL2ProcessServerHello: version error\n");
651 return ERR(SSLProtocolErr);
652 }
653 ctx->negProtocolVersion = version;
654 #if LOG_NEGOTIATE
655 dprintf0("===SSL2 client: negVersion is 2_0\n");
656 #endif
657 certLen = SSLDecodeInt(progress, 2);
658 progress += 2;
659 cipherSpecsLen = SSLDecodeInt(progress, 2);
660 progress += 2;
661 connectionIDLen = SSLDecodeInt(progress, 2);
662 progress += 2;
663
664 if (connectionIDLen < 16 || connectionIDLen > 32 || cipherSpecsLen % 3 != 0 ||
665 (msg.length != 10 + certLen + cipherSpecsLen + connectionIDLen) )
666 return ERR(SSLProtocolErr);
667 if (sessionIDMatch != 0)
668 { if (certLen != 0 || cipherSpecsLen != 0 /* || certType != 0 */ )
669 return ERR(SSLProtocolErr);
670 ctx->ssl2SessionMatch = 1;
671
672 ctx->ssl2ConnectionIDLength = connectionIDLen;
673 memcpy(ctx->serverRandom, progress, connectionIDLen);
674 progress += connectionIDLen;
675 }
676 else
677 { if (certType != ssl2_ct_x509_certificate)
678 return ERR(SSLNegotiationErr);
679 cipherSpecsLen /= 3;
680
681 #ifdef __APPLE__
682 cert = (SSLCertificate *)sslMalloc(sizeof(SSLCertificate));
683 if(cert == NULL) {
684 return SSLMemoryErr;
685 }
686 #else
687 if (ERR(err = SSLAllocBuffer(&certBuf, sizeof(SSLCertificate), &ctx->sysCtx)) != 0)
688 return err;
689 cert = (SSLCertificate*)certBuf.data;
690 #endif
691 cert->next = 0;
692 if (ERR(err = SSLAllocBuffer(&cert->derCert, certLen, &ctx->sysCtx)) != 0)
693 {
694 #ifdef __APPLE__
695 sslFree(cert);
696 #else
697 ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
698 #endif
699 return err;
700 }
701 memcpy(cert->derCert.data, progress, certLen);
702 progress += certLen;
703 #ifndef _APPLE_CDSA_
704 /* not necessary */
705 if (ERR(err = ASNParseX509Certificate(cert->derCert, &cert->cert, ctx)) != 0)
706 { ERR(SSLFreeBuffer(&cert->derCert, &ctx->sysCtx));
707 ERR(SSLFreeBuffer(&certBuf, &ctx->sysCtx));
708 return err;
709 }
710 #endif
711 ctx->peerCert = cert;
712 #ifdef _APPLE_CDSA_
713 /* This cert never gets verified in original SSLRef3 code... */
714 if((err = sslVerifyCertChain(ctx, ctx->peerCert)) != 0) {
715 return err;
716 }
717 if((err = sslPubKeyFromCert(ctx,
718 &cert->derCert,
719 &ctx->peerPubKey,
720 &ctx->peerPubKeyCsp)) != 0)
721 #else
722 if (ERR(err = X509ExtractPublicKey(&cert->cert.pubKey, &ctx->peerKey)) != 0)
723 #endif
724 return err;
725
726 selectedCipher = SSL_NO_SUCH_CIPHERSUITE;
727 for (i = 0; i < cipherSpecsLen; i++)
728 { cipherKind = (SSL2CipherKind)SSLDecodeInt(progress, 3);
729 progress += 3;
730 //dprintf1("ssl2: server supports cipherKind 0x%x\n", (UInt32)cipherKind);
731 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE) /* After we find one, just keep advancing progress past the unused ones */
732 { for (j = 0; j < SSL2CipherMapCount; j++)
733 if (cipherKind == SSL2CipherMap[j].cipherKind)
734 { matchingCipher = SSL2CipherMap[j].cipherSuite;
735 break;
736 }
737 for (j = 0; j < ctx->numValidCipherSpecs; j++)
738 if (ctx->validCipherSpecs[j].cipherSpec == matchingCipher)
739 { selectedCipher = matchingCipher;
740 break;
741 }
742 }
743 }
744 if (selectedCipher == SSL_NO_SUCH_CIPHERSUITE)
745 return ERR(SSLNegotiationErr);
746 #if LOG_NEGOTIATE
747 dprintf1("===SSL2 client: selectedCipher 0x%x\n",
748 selectedCipher);
749 #endif
750
751 ctx->selectedCipher = selectedCipher;
752 if (ERR(err = FindCipherSpec(ctx)) != 0) {
753 return err;
754 }
755 ctx->ssl2ConnectionIDLength = connectionIDLen;
756 memcpy(ctx->serverRandom, progress, connectionIDLen);
757 progress += connectionIDLen;
758 }
759
760 CASSERT(progress == msg.data + msg.length);
761
762 return SSLNoErr;
763 }
764
765 SSLErr
766 SSL2EncodeServerHello(SSLBuffer *msg, SSLContext *ctx)
767 { SSLErr err;
768 SSLCertificate *cert;
769 SSLBuffer randomData;
770 UInt8 *progress;
771 int i;
772
773 /* Create the connection ID */
774 ctx->ssl2ConnectionIDLength = SSL2_CONNECTION_ID_LENGTH;
775 randomData.data = ctx->serverRandom;
776 randomData.length = ctx->ssl2ConnectionIDLength;
777 #ifdef _APPLE_CDSA_
778 if ((err = sslRand(ctx, &randomData)) != 0)
779 #else
780 if (ERR(err = ctx->sysCtx.random(randomData, ctx->sysCtx.randomRef)) != 0)
781 #endif
782 return err;
783
784 if (ctx->ssl2SessionMatch != 0)
785 { if (ERR(err = SSLAllocBuffer(msg, 11 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
786 return err;
787 progress = msg->data;
788 *progress++ = ssl2_mt_server_hello;
789 *progress++ = ctx->ssl2SessionMatch;
790 *progress++ = 0; /* cert type */
791 progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
792 progress = SSLEncodeInt(progress, 0, 2); /* cert len */
793 progress = SSLEncodeInt(progress, 0, 2); /* cipherspecs len */
794 progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
795 memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
796 progress += ctx->ssl2ConnectionIDLength;
797 }
798 else
799 { /* First, find the last cert in the chain; it's the one we'll send */
800
801 #if _APPLE_CDSA_
802 /*
803 * For Apple, we require an encryptCert here - we'll be encrypting
804 * with it, after all.
805 */
806 if(ctx->encryptCert == NULL) {
807 errorLog0("SSL2EncodeServerHello: No encryptCert!\n");
808 return SSLBadStateErr;
809 }
810 cert = ctx->encryptCert;
811 #else
812 CASSERT(ctx->localCert != 0);
813 cert = ctx->localCert;
814 #endif _APPLE_CDSA_
815
816 while (cert->next != 0)
817 cert = cert->next;
818
819 if (ERR(err = SSLAllocBuffer(msg, 11 + cert->derCert.length + 3 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
820 return err;
821 progress = msg->data;
822 *progress++ = ssl2_mt_server_hello;
823 *progress++ = ctx->ssl2SessionMatch;
824 *progress++ = ssl2_ct_x509_certificate; /* cert type */
825 #if LOG_NEGOTIATE
826 dprintf1("===SSL2 server: sending vers info %s\n",
827 protocolVersStr((SSLProtocolVersion)ctx->negProtocolVersion));
828 #endif
829 progress = SSLEncodeInt(progress, ctx->negProtocolVersion, 2);
830 progress = SSLEncodeInt(progress, cert->derCert.length, 2);
831 progress = SSLEncodeInt(progress, 3, 2); /* cipherspecs len */
832 progress = SSLEncodeInt(progress, ctx->ssl2ConnectionIDLength, 2);
833 memcpy(progress, cert->derCert.data, cert->derCert.length);
834 progress += cert->derCert.length;
835 for (i = 0; i < SSL2CipherMapCount; i++)
836 if (ctx->selectedCipher == SSL2CipherMap[i].cipherSuite)
837 break;
838 CASSERT(i < SSL2CipherMapCount);
839 progress = SSLEncodeInt(progress, SSL2CipherMap[i].cipherKind, 3);
840 dprintf1("ssl2: server specifying cipherKind 0x%lx\n",
841 (UInt32)SSL2CipherMap[i].cipherKind);
842 memcpy(progress, ctx->serverRandom, ctx->ssl2ConnectionIDLength);
843 progress += ctx->ssl2ConnectionIDLength;
844 }
845
846 CASSERT(progress == msg->data + msg->length);
847 return SSLNoErr;
848 }
849
850 SSLErr
851 SSL2ProcessServerVerify(SSLBuffer msg, SSLContext *ctx)
852 { if (msg.length != ctx->ssl2ChallengeLength)
853 return ERR(SSLProtocolErr);
854
855 if (memcmp(msg.data, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
856 ctx->ssl2ChallengeLength) != 0)
857 return ERR(SSLProtocolErr);
858
859 return SSLNoErr;
860 }
861
862 SSLErr
863 SSL2EncodeServerVerify(SSLBuffer *msg, SSLContext *ctx)
864 { SSLErr err;
865
866 if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->ssl2ChallengeLength, &ctx->sysCtx)) != 0)
867 return err;
868
869 msg->data[0] = ssl2_mt_server_verify;
870 memcpy(msg->data+1, ctx->clientRandom + 32 - ctx->ssl2ChallengeLength,
871 ctx->ssl2ChallengeLength);
872
873 return SSLNoErr;
874 }
875
876 SSLErr
877 SSL2ProcessServerFinished(SSLBuffer msg, SSLContext *ctx)
878 { SSLErr err;
879
880 if (ERR(err = SSLAllocBuffer(&ctx->sessionID, msg.length, &ctx->sysCtx)) != 0)
881 return err;
882 memcpy(ctx->sessionID.data, msg.data, msg.length);
883 return SSLNoErr;
884 }
885
886 SSLErr
887 SSL2EncodeServerFinished(SSLBuffer *msg, SSLContext *ctx)
888 { SSLErr err;
889
890 if (ERR(err = SSLAllocBuffer(msg, 1 + ctx->sessionID.length, &ctx->sysCtx)) != 0)
891 return err;
892
893 msg->data[0] = ssl2_mt_server_finished;
894 memcpy(msg->data+1, ctx->sessionID.data, ctx->sessionID.length);
895
896 return SSLNoErr;
897 }