]> git.saurik.com Git - apple/security.git/blob - SecureTransport/hdskkyex.c
Security-30.1.tar.gz
[apple/security.git] / SecureTransport / hdskkyex.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: hdskkyex.c
21
22 Contains: Support for key exchange and server key exchange
23
24 Written by: Doug Mitchell, based on Netscape SSLRef 3.0
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29 /* *********************************************************************
30 File: hdskkyex.c
31
32 SSLRef 3.0 Final -- 11/19/96
33
34 Copyright (c)1996 by Netscape Communications Corp.
35
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
39
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
43
44 *********************************************************************
45
46 File: hdskkyex.c Support for key exchange and server key exchange
47
48 Encoding and decoding of key exchange and server key exchange
49 messages in both the Diffie-Hellman and RSA variants; also, includes
50 the necessary crypto library calls to support this negotiation.
51
52 ****************************************************************** */
53
54 #ifndef _SSLCTX_H_
55 #include "sslctx.h"
56 #endif
57
58 #ifndef _SSLHDSHK_H_
59 #include "sslhdshk.h"
60 #endif
61
62 #ifndef _SSLALLOC_H_
63 #include "sslalloc.h"
64 #endif
65
66 #ifndef _SSL_DEBUG_H_
67 #include "sslDebug.h"
68 #endif
69
70 #ifndef _SSLUTIL_H_
71 #include "sslutil.h"
72 #endif
73
74 #ifndef _APPLE_CDSA_H_
75 #include "appleCdsa.h"
76 #endif
77
78 #ifndef _DIGESTS_H_
79 #include "digests.h"
80 #endif
81
82 #include <string.h>
83
84 #if _APPLE_CDSA_
85 /*
86 * For this config, just for this file, we'll do this typedef....
87 */
88 typedef CSSM_KEY_PTR SSLRSAPrivateKey;
89 #endif
90
91 static SSLErr SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
92 static SSLErr SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx);
93 static SSLErr SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx);
94 static SSLErr SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
95 static SSLErr SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
96 #if APPLE_DH
97 static SSLErr SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx);
98 static SSLErr SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx);
99 static SSLErr SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx);
100 static SSLErr SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx);
101 #endif
102
103 SSLErr
104 SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
105 { SSLErr err;
106
107 switch (ctx->selectedCipherSpec->keyExchangeMethod)
108 { case SSL_RSA:
109 case SSL_RSA_EXPORT:
110 if (ERR(err = SSLEncodeRSAServerKeyExchange(keyExch, ctx)) != 0)
111 return err;
112 break;
113 #if APPLE_DH
114 case SSL_DH_anon:
115 if (ERR(err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0)
116 return err;
117 break;
118 #endif
119 default:
120 return ERR(SSLUnsupportedErr);
121 }
122
123 return SSLNoErr;
124 }
125
126 static SSLErr
127 SSLEncodeRSAServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
128 { SSLErr err;
129 UInt8 *progress;
130 int length;
131 UInt32 outputLen, localKeyModulusLen;
132 UInt8 hashes[36];
133 SSLBuffer exportKey,clientRandom,serverRandom,hashCtx, hash;
134
135 exportKey.data = 0;
136 hashCtx.data = 0;
137
138 #if _APPLE_CDSA_
139 /* we have a public key here... */
140 CASSERT(ctx->encryptPubKey != NULL);
141 CASSERT(ctx->protocolSide == SSL_ServerSide);
142
143 if ((err = SSLEncodeRSAKeyParams(&exportKey, &ctx->encryptPubKey, ctx)) != 0)
144 #else
145 if (ERR(err = SSLEncodeRSAKeyParams(&exportKey, &ctx->exportKey, ctx)) != 0)
146 #endif
147 goto fail;
148
149 #if RSAREF
150 localKeyModulusLen = (ctx->localKey.bits + 7)/8;
151 #elif BSAFE
152 { A_RSA_KEY *keyInfo;
153 int rsaResult;
154
155 if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->localKey, KI_RSAPublic)) != 0)
156 return SSLUnknownErr;
157 localKeyModulusLen = keyInfo->modulus.len;
158 }
159 #elif _APPLE_CDSA_
160 CASSERT(ctx->signingPubKey != NULL);
161 localKeyModulusLen = sslKeyLengthInBytes(ctx->signingPubKey);
162 #else
163 #error No Asymmetric crypto specified
164 #endif /* RSAREF / BSAFE */
165
166 length = exportKey.length + 2 + localKeyModulusLen; /* RSA ouputs a block as long as the modulus */
167
168 keyExch->protocolVersion = SSL_Version_3_0;
169 keyExch->contentType = SSL_handshake;
170 if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
171 goto fail;
172
173 progress = keyExch->contents.data;
174 *progress++ = SSL_server_key_exchange;
175 progress = SSLEncodeInt(progress, length, 3);
176
177 memcpy(progress, exportKey.data, exportKey.length);
178 progress += exportKey.length;
179
180 clientRandom.data = ctx->clientRandom;
181 clientRandom.length = 32;
182 serverRandom.data = ctx->serverRandom;
183 serverRandom.length = 32;
184
185 hash.data = &hashes[0];
186 hash.length = 16;
187 if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
188 goto fail;
189 if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
190 goto fail;
191 if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
192 goto fail;
193 if (ERR(err = SSLHashMD5.update(hashCtx, exportKey)) != 0)
194 goto fail;
195 if (ERR(err = SSLHashMD5.final(hashCtx, hash)) != 0)
196 goto fail;
197 if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
198 goto fail;
199
200 hash.data = &hashes[16];
201 hash.length = 20;
202 if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
203 goto fail;
204 if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
205 goto fail;
206 if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
207 goto fail;
208 if (ERR(err = SSLHashSHA1.update(hashCtx, exportKey)) != 0)
209 goto fail;
210 if (ERR(err = SSLHashSHA1.final(hashCtx, hash)) != 0)
211 goto fail;
212 if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
213 goto fail;
214
215 progress = SSLEncodeInt(progress, localKeyModulusLen, 2);
216 #if RSAREF
217 if (RSAPrivateEncrypt(progress, &outputLen, hashes, 36, &ctx->localKey) != 0) /* Sign the structure */
218 return ERR(SSLUnknownErr);
219 #elif BSAFE
220 { B_ALGORITHM_OBJ rsa;
221 B_ALGORITHM_METHOD *chooser[] = { &AM_RSA_ENCRYPT, &AM_RSA_CRT_ENCRYPT, 0 };
222 int rsaResult;
223 UInt32 encryptedOut;
224
225 if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
226 return SSLUnknownErr;
227 if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
228 return SSLUnknownErr;
229 if ((rsaResult = B_EncryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
230 return SSLUnknownErr;
231 if ((rsaResult = B_EncryptUpdate(rsa, progress,
232 &encryptedOut, localKeyModulusLen, hashes, 36, 0, NO_SURR)) != 0)
233 return SSLUnknownErr;
234 outputLen = encryptedOut;
235 if ((rsaResult = B_EncryptFinal(rsa, progress+outputLen,
236 &encryptedOut, localKeyModulusLen-outputLen, 0, NO_SURR)) != 0)
237 return SSLUnknownErr;
238 outputLen += encryptedOut;
239 B_DestroyAlgorithmObject(&rsa);
240 }
241 #elif _APPLE_CDSA_
242 err = sslRsaRawSign(ctx,
243 ctx->signingPrivKey,
244 ctx->signingKeyCsp,
245 hashes,
246 36,
247 progress,
248 length,
249 &outputLen);
250 if(err) {
251 goto fail;
252 }
253 #endif /* RSAREF / BSAFE */
254 CASSERT(outputLen == localKeyModulusLen);
255
256 err = SSLNoErr;
257
258 fail:
259 ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
260 ERR(SSLFreeBuffer(&exportKey, &ctx->sysCtx));
261
262 return err;
263 }
264
265 static SSLErr
266 SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLRSAPrivateKey *key, SSLContext *ctx)
267 { SSLErr err;
268 SSLBuffer modulus, exponent;
269 UInt8 *progress;
270
271 #if RSAREF
272 keyParams->data = 0;
273 modulus.length = (key->bits + 7) / 8;
274 modulus.data = key->modulus + MAX_RSA_MODULUS_LEN - modulus.length;
275
276 exponent.length = MAX_RSA_MODULUS_LEN;
277 exponent.data = key->publicExponent; /* Point at first byte */
278
279 while (*exponent.data == 0)
280 { ++exponent.data;
281 --exponent.length;
282 }
283 #elif BSAFE
284 { A_RSA_KEY *keyInfo;
285 int rsaResult;
286
287 if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, *key, KI_RSAPublic)) != 0)
288 return SSLUnknownErr;
289 modulus.data = keyInfo->modulus.data;
290 modulus.length = keyInfo->modulus.len;
291 exponent.data = keyInfo->exponent.data;
292 exponent.length = keyInfo->exponent.len;
293 }
294 #elif _APPLE_CDSA_
295 err = sslGetPubKeyBits(ctx,
296 *key,
297 ctx->encryptKeyCsp,
298 &modulus,
299 &exponent);
300 if(err) {
301 SSLFreeBuffer(&modulus, &ctx->sysCtx);
302 SSLFreeBuffer(&exponent, &ctx->sysCtx);
303 return err;
304 }
305 #else
306 #error No assymetric crypto specified
307 #endif /* RSAREF / BSAFE */
308
309 if (ERR(err = SSLAllocBuffer(keyParams, modulus.length + exponent.length + 4, &ctx->sysCtx)) != 0)
310 return err;
311 progress = keyParams->data;
312 progress = SSLEncodeInt(progress, modulus.length, 2);
313 memcpy(progress, modulus.data, modulus.length);
314 progress += modulus.length;
315 progress = SSLEncodeInt(progress, exponent.length, 2);
316 memcpy(progress, exponent.data, exponent.length);
317
318 #if _APPLE_CDSA_
319 /* these were mallocd by sslGetPubKeyBits() */
320 SSLFreeBuffer(&modulus, &ctx->sysCtx);
321 SSLFreeBuffer(&exponent, &ctx->sysCtx);
322 #endif
323 return SSLNoErr;
324 }
325
326 #if APPLE_DH
327 static SSLErr
328 SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
329 { SSLErr err;
330 UInt32 length;
331 UInt8 *progress;
332 SSLRandomCtx random;
333 int rsaErr;
334
335 #if RSAREF
336 length = 6 + ctx->dhAnonParams.primeLen + ctx->dhAnonParams.generatorLen +
337 ctx->dhExchangePublic.length;
338
339 keyExch->protocolVersion = SSL_Version_3_0;
340 keyExch->contentType = SSL_handshake;
341 if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
342 return err;
343
344 progress = keyExch->contents.data;
345 *progress++ = SSL_server_key_exchange;
346 progress = SSLEncodeInt(progress, length, 3);
347
348 progress = SSLEncodeInt(progress, ctx->dhAnonParams.primeLen, 2);
349 memcpy(progress, ctx->dhAnonParams.prime, ctx->dhAnonParams.primeLen);
350 progress += ctx->dhAnonParams.primeLen;
351
352 progress = SSLEncodeInt(progress, ctx->dhAnonParams.generatorLen, 2);
353 memcpy(progress, ctx->dhAnonParams.generator, ctx->dhAnonParams.generatorLen);
354 progress += ctx->dhAnonParams.generatorLen;
355
356 if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, ctx->peerDHParams.primeLen, &ctx->sysCtx)) != 0)
357 return err;
358 if (ERR(err = SSLAllocBuffer(&ctx->dhPrivate, ctx->dhExchangePublic.length - 16, &ctx->sysCtx)) != 0)
359 return err;
360
361 if (ERR(err = ReadyRandom(&random, ctx)) != 0)
362 return err;
363
364 if ((rsaErr = R_SetupDHAgreement(ctx->dhExchangePublic.data, ctx->dhPrivate.data,
365 ctx->dhPrivate.length, &ctx->dhAnonParams, &random)) != 0)
366 { err = SSLUnknownErr;
367 return err;
368 }
369
370 progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
371 memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
372 progress += ctx->dhExchangePublic.length;
373
374 #elif BSAFE
375 { A_DH_KEY_AGREE_PARAMS *params;
376 unsigned int outputLen;
377
378 if ((rsaErr = B_GetAlgorithmInfo((POINTER*)&params, ctx->dhAnonParams, AI_DHKeyAgree)) != 0)
379 return SSLUnknownErr;
380 if (ERR(err = ReadyRandom(&random, ctx)) != 0)
381 return err;
382 if (ERR(err = SSLAllocBuffer(&ctx->dhExchangePublic, 128, &ctx->sysCtx)) != 0)
383 return err;
384 if ((rsaErr = B_KeyAgreePhase1(ctx->dhAnonParams, ctx->dhExchangePublic.data,
385 &outputLen, 128, random, NO_SURR)) != 0)
386 { err = SSLUnknownErr;
387 return err;
388 }
389 ctx->dhExchangePublic.length = outputLen;
390
391 length = 6 + params->prime.len + params->base.len + ctx->dhExchangePublic.length;
392
393 keyExch->protocolVersion = SSL_Version_3_0;
394 keyExch->contentType = SSL_handshake;
395 if (ERR(err = SSLAllocBuffer(&keyExch->contents, length+4, &ctx->sysCtx)) != 0)
396 return err;
397
398 progress = keyExch->contents.data;
399 *progress++ = SSL_server_key_exchange;
400 progress = SSLEncodeInt(progress, length, 3);
401
402 progress = SSLEncodeInt(progress, params->prime.len, 2);
403 memcpy(progress, params->prime.data, params->prime.len);
404 progress += params->prime.len;
405
406 progress = SSLEncodeInt(progress, params->base.len, 2);
407 memcpy(progress, params->base.data, params->base.len);
408 progress += params->base.len;
409
410 progress = SSLEncodeInt(progress, ctx->dhExchangePublic.length, 2);
411 memcpy(progress, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
412 progress += ctx->dhExchangePublic.length;
413 }
414 #endif /* RSAREF / BSAFE */
415
416 ASSERT(progress == keyExch->contents.data + keyExch->contents.length);
417
418 return SSLNoErr;
419 }
420
421 #endif /* APPLE_DH */
422
423 SSLErr
424 SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
425 { SSLErr err;
426
427 switch (ctx->selectedCipherSpec->keyExchangeMethod)
428 { case SSL_RSA:
429 case SSL_RSA_EXPORT:
430 if (ERR(err = SSLProcessRSAServerKeyExchange(message, ctx)) != 0)
431 return err;
432 break;
433 #if APPLE_DH
434 case SSL_DH_anon:
435 if (ERR(err = SSLProcessDHanonServerKeyExchange(message, ctx)) != 0)
436 return err;
437 break;
438 #endif
439 default:
440 return ERR(SSLUnsupportedErr);
441 }
442
443 return SSLNoErr;
444 }
445
446 static SSLErr
447 SSLProcessRSAServerKeyExchange(SSLBuffer message, SSLContext *ctx)
448 {
449 SSLErr err;
450 SSLBuffer tempPubKey, hashOut, hashCtx, clientRandom, serverRandom;
451 UInt16 modulusLen, exponentLen, signatureLen;
452 UInt8 *progress, *modulus, *exponent, *signature;
453 #if _APPLE_CDSA_
454 UInt8 hash[36];
455 #else
456 UInt8 hash[20];
457 UInt32 outputLen;
458 #endif /* _APPLE_CDSA_ */
459 SSLBuffer signedHashes;
460
461 signedHashes.data = 0;
462 hashCtx.data = 0;
463
464 if (message.length < 2) {
465 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
466 return ERR(SSLProtocolErr);
467 }
468 progress = message.data;
469 modulusLen = SSLDecodeInt(progress, 2);
470 modulus = progress + 2;
471 progress += 2+modulusLen;
472 if (message.length < 4 + modulusLen) {
473 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
474 return ERR(SSLProtocolErr);
475 }
476 exponentLen = SSLDecodeInt(progress, 2);
477 exponent = progress + 2;
478 progress += 2+exponentLen;
479 if (message.length < 6 + modulusLen + exponentLen) {
480 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
481 return ERR(SSLProtocolErr);
482 }
483 signatureLen = SSLDecodeInt(progress, 2);
484 signature = progress + 2;
485 if (message.length != 6 + modulusLen + exponentLen + signatureLen) {
486 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 3\n");
487 return ERR(SSLProtocolErr);
488 }
489
490 #if RSAREF
491 { /* Allocate room for the signed hashes; RSA can encrypt data
492 as long as the modulus */
493 if (ERR(err = SSLAllocBuffer(&signedHashes, (ctx->peerKey.bits + 7)/8, &ctx->sysCtx)) != 0)
494 return err;
495
496 if ((RSAPublicDecrypt(signedHashes.data, &outputLen, signature, signatureLen,
497 &ctx->peerKey)) != 0)
498 { ERR(err = SSLUnknownErr);
499 goto fail;
500 }
501 }
502 #elif BSAFE
503 { B_ALGORITHM_OBJ rsa;
504 B_ALGORITHM_METHOD *chooser[] = { &AM_MD2, &AM_MD5, &AM_RSA_DECRYPT, 0 };
505 int rsaResult;
506 unsigned int decryptLen;
507
508 /* Allocate room for the signed hashes; BSAFE makes sure we don't decode too much data */
509 if (ERR(err = SSLAllocBuffer(&signedHashes, 36, &ctx->sysCtx)) != 0)
510 return err;
511
512 if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
513 return SSLUnknownErr;
514 if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
515 return SSLUnknownErr;
516 if ((rsaResult = B_DecryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
517 return SSLUnknownErr;
518 if ((rsaResult = B_DecryptUpdate(rsa, signedHashes.data, &decryptLen, 36,
519 signature, signatureLen, 0, NO_SURR)) != 0)
520 return SSLUnknownErr;
521 outputLen = decryptLen;
522 if ((rsaResult = B_DecryptFinal(rsa, signedHashes.data+outputLen,
523 &decryptLen, 36-outputLen, 0, NO_SURR)) != 0)
524 return SSLUnknownErr;
525 outputLen += decryptLen;
526 B_DestroyAlgorithmObject(&rsa);
527 }
528 #elif _APPLE_CDSA_
529
530 /* not yet - calculate the hashes and then do a sig verify */
531
532 #else
533 #error No Asymmetric crypto module
534 #endif
535
536 #ifndef _APPLE_CDSA_
537 if (outputLen != 36)
538 { ERR(err = SSLProtocolErr);
539 goto fail;
540 }
541 #endif
542
543 clientRandom.data = ctx->clientRandom;
544 clientRandom.length = 32;
545 serverRandom.data = ctx->serverRandom;
546 serverRandom.length = 32;
547 tempPubKey.data = message.data;
548 tempPubKey.length = modulusLen + exponentLen + 4;
549 hashOut.data = hash;
550
551 hashOut.length = 16;
552 if (ERR(err = ReadyHash(&SSLHashMD5, &hashCtx, ctx)) != 0)
553 goto fail;
554 if (ERR(err = SSLHashMD5.update(hashCtx, clientRandom)) != 0)
555 goto fail;
556 if (ERR(err = SSLHashMD5.update(hashCtx, serverRandom)) != 0)
557 goto fail;
558 if (ERR(err = SSLHashMD5.update(hashCtx, tempPubKey)) != 0)
559 goto fail;
560 if (ERR(err = SSLHashMD5.final(hashCtx, hashOut)) != 0)
561 goto fail;
562
563 #if _APPLE_CDSA_
564 /*
565 * SHA hash goes right after the MD5 hash
566 */
567 hashOut.data = hash + 16;
568 #else
569 if ((memcmp(hash, signedHashes.data, 16)) != 0)
570 { ERR(err = SSLProtocolErr);
571 goto fail;
572 }
573 #endif /* _APPLE_CDSA_ */
574
575 hashOut.length = 20;
576 if (ERR(err = SSLFreeBuffer(&hashCtx, &ctx->sysCtx)) != 0)
577 goto fail;
578
579 if (ERR(err = ReadyHash(&SSLHashSHA1, &hashCtx, ctx)) != 0)
580 goto fail;
581 if (ERR(err = SSLHashSHA1.update(hashCtx, clientRandom)) != 0)
582 goto fail;
583 if (ERR(err = SSLHashSHA1.update(hashCtx, serverRandom)) != 0)
584 goto fail;
585 if (ERR(err = SSLHashSHA1.update(hashCtx, tempPubKey)) != 0)
586 goto fail;
587 if (ERR(err = SSLHashSHA1.final(hashCtx, hashOut)) != 0)
588 goto fail;
589
590 #if _APPLE_CDSA_
591
592 err = sslRsaRawVerify(ctx,
593 ctx->peerPubKey,
594 ctx->peerPubKeyCsp,
595 hash, /* plaintext */
596 36, /* plaintext length */
597 signature,
598 signatureLen);
599 if(err) {
600 errorLog1("SSLProcessRSAServerKeyExchange: sslRsaRawVerify returned %d\n",
601 err);
602 goto fail;
603 }
604
605 #else /* old BSAFE/RSAREF */
606
607 if ((memcmp(hash, signedHashes.data + 16, 20)) != 0)
608 { ERR(err = SSLProtocolErr);
609 goto fail;
610 }
611
612 #endif
613
614 /* Signature matches; now replace server key with new key */
615 #if RSAREF
616 memset(&ctx->peerKey, 0, sizeof(R_RSA_PUBLIC_KEY));
617 memcpy(ctx->peerKey.modulus + (MAX_RSA_MODULUS_LEN - modulusLen),
618 modulus, modulusLen);
619 memcpy(ctx->peerKey.exponent + (MAX_RSA_MODULUS_LEN - exponentLen),
620 exponent, exponentLen);
621
622 /* Adjust bit length for leading zeros in value; assume no more than 8 leading zero bits */
623 { unsigned int bitAdjust;
624 UInt8 c;
625
626 c = modulus[0];
627
628 bitAdjust = 8;
629 while (c != 0)
630 { --bitAdjust;
631 c >>= 1;
632 }
633 ctx->peerKey.bits = modulusLen * 8 - bitAdjust;
634 }
635 err = SSLNoErr;
636 #elif BSAFE
637 { A_RSA_KEY pubKeyInfo;
638 int rsaErr;
639
640 pubKeyInfo.modulus.data = modulus;
641 pubKeyInfo.modulus.len = modulusLen;
642 pubKeyInfo.exponent.data = exponent;
643 pubKeyInfo.exponent.len = exponentLen;
644
645 if ((rsaErr = B_CreateKeyObject(&ctx->peerKey)) != 0)
646 return SSLUnknownErr;
647 if ((rsaErr = B_SetKeyInfo(ctx->peerKey, KI_RSAPublic, (POINTER)&pubKeyInfo)) != 0)
648 return SSLUnknownErr;
649 }
650 err = SSLNoErr;
651 #elif _APPLE_CDSA_
652 {
653 SSLBuffer modBuf;
654 SSLBuffer expBuf;
655
656 /* first free existing peerKey */
657 sslFreeKey(ctx->peerPubKeyCsp,
658 &ctx->peerPubKey,
659 NULL); /* no KCItem */
660
661 /* and cook up a new one from raw bits */
662 modBuf.data = modulus;
663 modBuf.length = modulusLen;
664 expBuf.data = exponent;
665 expBuf.length = exponentLen;
666 err = sslGetPubKeyFromBits(ctx,
667 &modBuf,
668 &expBuf,
669 &ctx->peerPubKey,
670 &ctx->peerPubKeyCsp);
671 }
672 #else
673 #error No Assymmetric crypto module
674 #endif /* RSAREF / BSAFE */
675 fail:
676 ERR(SSLFreeBuffer(&signedHashes, &ctx->sysCtx));
677 ERR(SSLFreeBuffer(&hashCtx, &ctx->sysCtx));
678 return err;
679 }
680
681 #if APPLE_DH
682 static SSLErr
683 SSLProcessDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
684 { SSLErr err;
685 UInt8 *progress;
686 unsigned int totalLength;
687
688 if (message.length < 6) {
689 errorLog1("SSLProcessDHanonServerKeyExchange error: msg len %d\n",
690 message.length);
691 return ERR(SSLProtocolErr);
692 }
693 progress = message.data;
694 totalLength = 0;
695
696 #if RSAREF
697 { SSLBuffer alloc;
698 UInt8 *prime, *generator, *publicVal;
699
700 ctx->peerDHParams.primeLen = SSLDecodeInt(progress, 2);
701 progress += 2;
702 prime = progress;
703 progress += ctx->peerDHParams.primeLen;
704 totalLength += ctx->peerDHParams.primeLen;
705 if (message.length < 6 + totalLength)
706 return ERR(SSLProtocolErr);
707
708 ctx->peerDHParams.generatorLen = SSLDecodeInt(progress, 2);
709 progress += 2;
710 generator = progress;
711 progress += ctx->peerDHParams.generatorLen;
712 totalLength += ctx->peerDHParams.generatorLen;
713 if (message.length < 6 + totalLength)
714 return ERR(SSLProtocolErr);
715
716 ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
717 progress += 2;
718 publicVal = progress;
719 progress += ctx->dhPeerPublic.length;
720 totalLength += ctx->dhPeerPublic.length;
721 if (message.length != 6 + totalLength)
722 return ERR(SSLProtocolErr);
723
724 ASSERT(progress == message.data + message.length);
725
726 if (ERR(err = SSLAllocBuffer(&alloc, ctx->peerDHParams.primeLen +
727 ctx->peerDHParams.generatorLen, &ctx->sysCtx)) != 0)
728 return err;
729
730 ctx->peerDHParams.prime = alloc.data;
731 memcpy(ctx->peerDHParams.prime, prime, ctx->peerDHParams.primeLen);
732 ctx->peerDHParams.generator = alloc.data + ctx->peerDHParams.primeLen;
733 memcpy(ctx->peerDHParams.generator, generator, ctx->peerDHParams.generatorLen);
734
735 if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic,
736 ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
737 return err;
738
739 memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
740 }
741 #elif BSAFE
742 { int rsaErr;
743 unsigned char *publicVal;
744 A_DH_KEY_AGREE_PARAMS params;
745 B_ALGORITHM_METHOD *chooser[] = { &AM_DH_KEY_AGREE, 0 };
746
747 params.prime.len = SSLDecodeInt(progress, 2);
748 progress += 2;
749 params.prime.data = progress;
750 progress += params.prime.len;
751 totalLength += params.prime.len;
752 if (message.length < 6 + totalLength)
753 return ERR(SSLProtocolErr);
754
755 params.base.len = SSLDecodeInt(progress, 2);
756 progress += 2;
757 params.base.data = progress;
758 progress += params.base.len;
759 totalLength += params.base.len;
760 if (message.length < 6 + totalLength)
761 return ERR(SSLProtocolErr);
762
763 ctx->dhPeerPublic.length = SSLDecodeInt(progress, 2);
764 if (ERR(err = SSLAllocBuffer(&ctx->dhPeerPublic, ctx->dhPeerPublic.length, &ctx->sysCtx)) != 0)
765 return err;
766
767 progress += 2;
768 publicVal = progress;
769 progress += ctx->dhPeerPublic.length;
770 totalLength += ctx->dhPeerPublic.length;
771 memcpy(ctx->dhPeerPublic.data, publicVal, ctx->dhPeerPublic.length);
772 if (message.length != 6 + totalLength)
773 return ERR(SSLProtocolErr);
774
775 params.exponentBits = 8 * ctx->dhPeerPublic.length - 1;
776
777 if ((rsaErr = B_CreateAlgorithmObject(&ctx->peerDHParams)) != 0)
778 return SSLUnknownErr;
779 if ((rsaErr = B_SetAlgorithmInfo(ctx->peerDHParams, AI_DHKeyAgree, (POINTER)&params)) != 0)
780 return SSLUnknownErr;
781 if ((rsaErr = B_KeyAgreeInit(ctx->peerDHParams, (B_KEY_OBJ) 0, chooser, NO_SURR)) != 0)
782 return SSLUnknownErr;
783 }
784 #endif
785
786 return SSLNoErr;
787 }
788
789 #endif
790
791 SSLErr
792 SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
793 { SSLErr err;
794
795 switch (ctx->selectedCipherSpec->keyExchangeMethod)
796 { case SSL_RSA:
797 case SSL_RSA_EXPORT:
798 if (ERR(err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
799 return err;
800 break;
801 #if APPLE_DH
802 case SSL_DH_anon:
803 if (ERR(err = SSLDecodeDHanonKeyExchange(keyExchange, ctx)) != 0)
804 return err;
805 break;
806 #endif
807 default:
808 return ERR(SSLUnsupportedErr);
809 }
810
811 return SSLNoErr;
812 }
813
814 static SSLErr
815 SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
816 { SSLErr err;
817 SSLBuffer result;
818 UInt32 outputLen, localKeyModulusLen;
819 SSLRSAPrivateKey *key;
820 SSLProtocolVersion version;
821 Boolean useEncryptKey = false;
822
823 #if _APPLE_CDSA_
824
825 /* different key names, also need CSP handle */
826 CSSM_CSP_HANDLE cspHand;
827
828 CASSERT(ctx->protocolSide == SSL_ServerSide);
829
830 /*
831 * FIXME - The original SSLRef looked at
832 * ctx->selectedCipherSpec->keyExchangeMethod to decide which
833 * key to use (exportKey or localKey). I really don't think we
834 * want to use that - it's constant. We need to look at
835 * whether the app specified encrypting certs, right?
836 */
837 #if SSL_SERVER_KEYEXCH_HACK
838 /*
839 * the way we work with Netscape.
840 * FIXME - maybe we should *require* an encryptPrivKey in this
841 * situation?
842 */
843 if((ctx->selectedCipherSpec->keyExchangeMethod == SSL_RSA_EXPORT) &&
844 (ctx->encryptPrivKey != NULL)) {
845 useEncryptKey = true;
846 }
847
848 #else /* !SSL_SERVER_KEYEXCH_HACK */
849 /* The "correct" way, I think, which doesn't work with Netscape */
850 if (ctx->encryptPrivKey) {
851 useEncryptKey = true;
852 }
853 #endif /* SSL_SERVER_KEYEXCH_HACK */
854 if (useEncryptKey) {
855 key = &ctx->encryptPrivKey;
856 cspHand = ctx->encryptKeyCsp;
857 }
858 else {
859 key = &ctx->signingPrivKey;
860 cspHand = ctx->signingKeyCsp;
861 }
862 #else /* original SSLRef3 */
863 if (ctx->selectedCipherSpec->keyExchangeMethod == SSL_RSA_EXPORT)
864 key = &ctx->exportKey;
865 else
866 key = &ctx->localKey;
867 #endif /* _APPLE_CDSA_ */
868 result.data = 0;
869
870 #if RSAREF
871 localKeyModulusLen = (key->bits + 7)/8;
872 #elif BSAFE
873 { A_RSA_KEY *keyInfo;
874 int rsaResult;
875
876 if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, *key, KI_RSAPublic)) != 0)
877 return SSLUnknownErr;
878 localKeyModulusLen = keyInfo->modulus.len;
879 }
880 #elif _APPLE_CDSA_
881 localKeyModulusLen = sslKeyLengthInBytes(*key);
882 #else
883 #error No assymetric crypto module
884 #endif /* RSAREF / BSAFE */
885
886 if (keyExchange.length != localKeyModulusLen) {
887 errorLog0("SSLDecodeRSAKeyExchange: length error\n");
888 return ERR(SSLProtocolErr);
889 }
890
891 #if RSAREF
892 if (ERR(err = SSLAllocBuffer(&result, localKeyModulusLen, &ctx->sysCtx)) != 0)
893 return err;
894 if ((RSAPrivateDecrypt(result.data, &outputLen, keyExchange.data, keyExchange.length, key)) != 0)
895 { ERR(err = SSLUnknownErr);
896 goto fail;
897 }
898 #elif BSAFE
899 { B_ALGORITHM_OBJ rsa;
900 B_ALGORITHM_METHOD *chooser[] = { &AM_RSA_DECRYPT, &AM_RSA_CRT_DECRYPT, 0 };
901 int rsaResult;
902 unsigned int decryptLen;
903
904 /* Allocate room for the premaster secret; BSAFE makes sure we don't decode too much data */
905 if (ERR(err = SSLAllocBuffer(&result, 48, &ctx->sysCtx)) != 0)
906 return err;
907
908 if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
909 return SSLUnknownErr;
910 if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPrivate, 0)) != 0)
911 return SSLUnknownErr;
912 #ifdef macintosh
913 /*
914 * I think this is an SSLRef bug - we need to use the right key here,
915 * as the RSAREF case above does!
916 */
917 if ((rsaResult = B_DecryptInit(rsa, *key, chooser, NO_SURR)) != 0)
918 return SSLUnknownErr;
919 #else /* the SSLRef way */
920 if ((rsaResult = B_DecryptInit(rsa, ctx->localKey, chooser, NO_SURR)) != 0)
921 return SSLUnknownErr;
922 #endif /* mac/SSLREF */
923 if ((rsaResult = B_DecryptUpdate(rsa, result.data, &decryptLen, 48,
924 keyExchange.data, keyExchange.length, 0, NO_SURR)) != 0)
925 return SSLUnknownErr;
926 outputLen = decryptLen;
927 if ((rsaResult = B_DecryptFinal(rsa, result.data+outputLen,
928 &decryptLen, 48-outputLen, 0, NO_SURR)) != 0)
929 return SSLUnknownErr;
930 outputLen += decryptLen;
931 B_DestroyAlgorithmObject(&rsa);
932 }
933 #elif _APPLE_CDSA_
934 err = sslRsaDecrypt(ctx,
935 *key,
936 cspHand,
937 keyExchange.data,
938 keyExchange.length,
939 result.data,
940 48,
941 &outputLen);
942 if(err) {
943 goto fail;
944 }
945 #endif
946
947 if (outputLen != 48)
948 {
949 errorLog0("SSLDecodeRSAKeyExchange: outputLen error\n");
950 ERR(err = SSLProtocolErr);
951 goto fail;
952 }
953 result.length = outputLen;
954
955 version = (SSLProtocolVersion)SSLDecodeInt(result.data, 2);
956 /* Modify this check to check against our maximum version with protocol revisions */
957 if (version > ctx->negProtocolVersion && version < SSL_Version_3_0) {
958 errorLog0("SSLDecodeRSAKeyExchange: version error\n");
959 ERR(err = SSLProtocolErr);
960 goto fail;
961 }
962 if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 48, &ctx->sysCtx)) != 0)
963 goto fail;
964 memcpy(ctx->preMasterSecret.data, result.data, 48);
965
966 err = SSLNoErr;
967 fail:
968 ERR(SSLFreeBuffer(&result, &ctx->sysCtx));
969 return err;
970 }
971
972 #if APPLE_DH
973 static SSLErr
974 SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
975 { SSLErr err;
976 unsigned int publicLen;
977 int rsaResult;
978
979 publicLen = SSLDecodeInt(keyExchange.data, 2);
980
981 #if RSAREF
982 if (keyExchange.length != publicLen + 2 ||
983 publicLen != ctx->dhAnonParams.primeLen)
984 return ERR(SSLProtocolErr);
985
986 if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, ctx->dhAnonParams.primeLen, &ctx->sysCtx)) != 0)
987 return err;
988
989 if ((rsaResult = R_ComputeDHAgreedKey (ctx->preMasterSecret.data, ctx->dhPeerPublic.data,
990 ctx->dhPrivate.data, ctx->dhPrivate.length, &ctx->dhAnonParams)) != 0)
991 { err = SSLUnknownErr;
992 return err;
993 }
994
995 #elif BSAFE
996 { unsigned int amount;
997 if (keyExchange.length != publicLen + 2)
998 return ERR(SSLProtocolErr);
999
1000 if (ERR(err = SSLAllocBuffer(&ctx->preMasterSecret, 128, &ctx->sysCtx)) != 0)
1001 return err;
1002
1003 if ((rsaResult = B_KeyAgreePhase2(ctx->dhAnonParams, ctx->preMasterSecret.data,
1004 &amount, 128, keyExchange.data+2, publicLen, NO_SURR)) != 0)
1005 return err;
1006
1007 ctx->preMasterSecret.length = amount;
1008 }
1009 #endif
1010
1011 return SSLNoErr;
1012 }
1013 #endif /* APPLE_DH */
1014
1015 SSLErr
1016 SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1017 { SSLErr err;
1018
1019 CASSERT(ctx->protocolSide == SSL_ClientSide);
1020
1021 switch (ctx->selectedCipherSpec->keyExchangeMethod)
1022 { case SSL_RSA:
1023 case SSL_RSA_EXPORT:
1024 if (ERR(err = SSLEncodeRSAKeyExchange(keyExchange, ctx)) != 0)
1025 return err;
1026 break;
1027 #if APPLE_DH
1028 case SSL_DH_anon:
1029 if (ERR(err = SSLEncodeDHanonKeyExchange(keyExchange, ctx)) != 0)
1030 return err;
1031 break;
1032 #endif
1033 default:
1034 return ERR(SSLUnsupportedErr);
1035 }
1036
1037 return SSLNoErr;
1038 }
1039
1040 static SSLErr
1041 SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1042 { SSLErr err;
1043 UInt32 outputLen, peerKeyModulusLen;
1044 #if !_APPLE_CDSA_
1045 SSLRandomCtx rsaRandom;
1046 int rsaResult;
1047 #endif
1048
1049 if (ERR(err = SSLEncodeRSAPremasterSecret(ctx)) != 0)
1050 return err;
1051
1052 #if !_APPLE_CDSA_
1053 if (ERR(err = ReadyRandom(&rsaRandom, ctx)) != 0)
1054 return err;
1055 #endif
1056
1057 keyExchange->contentType = SSL_handshake;
1058 keyExchange->protocolVersion = SSL_Version_3_0;
1059
1060 #if RSAREF
1061 peerKeyModulusLen = (ctx->peerKey.bits + 7)/8;
1062 #elif BSAFE
1063 { A_RSA_KEY *keyInfo;
1064
1065 if ((rsaResult = B_GetKeyInfo((POINTER*)&keyInfo, ctx->peerKey, KI_RSAPublic)) != 0)
1066 return SSLUnknownErr;
1067 peerKeyModulusLen = keyInfo->modulus.len;
1068 }
1069 #elif _APPLE_CDSA_
1070 peerKeyModulusLen = sslKeyLengthInBytes(ctx->peerPubKey);
1071 #else
1072 #error No Assymetric Crypto
1073 #endif /* RSAREF / BSAFE */
1074 if (ERR(err = SSLAllocBuffer(&keyExchange->contents,peerKeyModulusLen + 4,&ctx->sysCtx)) != 0)
1075 {
1076 #if RSAREF
1077 R_RandomFinal(&rsaRandom);
1078 #elif BSAFE
1079 B_DestroyAlgorithmObject(&rsaRandom);
1080 #endif
1081 return err;
1082 }
1083 keyExchange->contents.data[0] = SSL_client_key_exchange;
1084 SSLEncodeInt(keyExchange->contents.data + 1, peerKeyModulusLen, 3);
1085 #if RSAREF
1086 if ((rsaResult = RSAPublicEncrypt(keyExchange->contents.data+4, &outputLen,
1087 ctx->preMasterSecret.data, 48,
1088 &ctx->peerKey,&rsaRandom)) != 0)
1089 { R_RandomFinal(&rsaRandom);
1090 return ERR(SSLUnknownErr);
1091 }
1092
1093 R_RandomFinal(&rsaRandom);
1094
1095 #elif BSAFE
1096 { B_ALGORITHM_OBJ rsa;
1097 B_ALGORITHM_METHOD *chooser[] = { &AM_RSA_ENCRYPT, 0 };
1098 int rsaResult;
1099 unsigned int encryptedOut;
1100
1101 if ((rsaResult = B_CreateAlgorithmObject(&rsa)) != 0)
1102 return SSLUnknownErr;
1103 if ((rsaResult = B_SetAlgorithmInfo(rsa, AI_PKCS_RSAPublic, 0)) != 0)
1104 return SSLUnknownErr;
1105 if ((rsaResult = B_EncryptInit(rsa, ctx->peerKey, chooser, NO_SURR)) != 0)
1106 return SSLUnknownErr;
1107 if ((rsaResult = B_EncryptUpdate(rsa, keyExchange->contents.data+4,
1108 &encryptedOut, peerKeyModulusLen, ctx->preMasterSecret.data, 48, rsaRandom, NO_SURR)) != 0)
1109 return SSLUnknownErr;
1110 outputLen = encryptedOut;
1111 if ((rsaResult = B_EncryptFinal(rsa, keyExchange->contents.data+4+outputLen,
1112 &encryptedOut, peerKeyModulusLen-outputLen, rsaRandom, NO_SURR)) != 0)
1113 return SSLUnknownErr;
1114 outputLen += encryptedOut;
1115 B_DestroyAlgorithmObject(&rsa);
1116 }
1117
1118 B_DestroyAlgorithmObject(&rsaRandom);
1119 #elif _APPLE_CDSA_
1120 err = sslRsaEncrypt(ctx,
1121 ctx->peerPubKey,
1122 /* FIXME - maybe this should be ctx->cspHand */
1123 ctx->peerPubKeyCsp,
1124 ctx->preMasterSecret.data,
1125 48,
1126 keyExchange->contents.data+4,
1127 peerKeyModulusLen,
1128 &outputLen);
1129 if(err) {
1130 return err;
1131 }
1132 #endif
1133
1134 CASSERT(outputLen + 4 == keyExchange->contents.length);
1135
1136 return SSLNoErr;
1137 }
1138
1139 #if APPLE_DH
1140 static SSLErr
1141 SSLEncodeDHanonKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1142 { SSLErr err;
1143 unsigned int outputLen;
1144
1145 if (ERR(err = SSLEncodeDHPremasterSecret(ctx)) != 0)
1146 return err;
1147
1148 outputLen = ctx->dhExchangePublic.length + 2;
1149
1150 keyExchange->contentType = SSL_handshake;
1151 keyExchange->protocolVersion = SSL_Version_3_0;
1152
1153 if (ERR(err = SSLAllocBuffer(&keyExchange->contents,outputLen + 4,&ctx->sysCtx)) != 0)
1154 return err;
1155
1156 keyExchange->contents.data[0] = SSL_client_key_exchange;
1157 SSLEncodeInt(keyExchange->contents.data+1, ctx->dhExchangePublic.length+2, 3);
1158
1159 SSLEncodeInt(keyExchange->contents.data+4, ctx->dhExchangePublic.length, 2);
1160 memcpy(keyExchange->contents.data+6, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
1161
1162 return SSLNoErr;
1163 }
1164 #endif
1165