]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/sslKeyExchange.c
Security-55471.14.4.tar.gz
[apple/security.git] / libsecurity_ssl / lib / sslKeyExchange.c
1 /*
2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * sslKeyExchange.c - Support for key exchange and server key exchange
26 */
27
28 #include "ssl.h"
29 #include "sslContext.h"
30 #include "sslHandshake.h"
31 #include "sslMemory.h"
32 #include "sslDebug.h"
33 #include "sslUtils.h"
34 #include "sslCrypto.h"
35 #include "sslRand.h"
36 #include "sslDigests.h"
37
38 #include <assert.h>
39 #include <string.h>
40
41 #include <stdio.h>
42 #include <utilities/SecCFRelease.h>
43 #include <corecrypto/ccdh_gp.h>
44
45 #ifdef USE_CDSA_CRYPTO
46 //#include <utilities/globalizer.h>
47 //#include <utilities/threading.h>
48 #include <Security/cssmapi.h>
49 #include <Security/SecKeyPriv.h>
50 #include "ModuleAttacher.h"
51 #else
52 #include <AssertMacros.h>
53 #include <Security/oidsalg.h>
54 #if APPLE_DH
55
56 #if TARGET_OS_IPHONE
57 #include <Security/SecRSAKey.h>
58 #endif
59
60 static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx);
61 static size_t SSLEncodedDHKeyParamsLen(SSLContext *ctx);
62 static OSStatus SSLEncodeDHKeyParams(SSLContext *ctx, uint8_t *charPtr);
63
64 #endif /* APPLE_DH */
65 #endif /* USE_CDSA_CRYPTO */
66
67 // MARK: -
68 // MARK: Forward Static Declarations
69
70 #if APPLE_DH
71 #if USE_CDSA_CRYPTO
72 static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx);
73 static OSStatus SSLEncodeDHKeyParams(SSLContext *ctx, uint8_t *charPtr);
74 #endif
75 static OSStatus SSLDecodeDHKeyParams(SSLContext *ctx, uint8_t **charPtr,
76 size_t length);
77 #endif
78 static OSStatus SSLDecodeECDHKeyParams(SSLContext *ctx, uint8_t **charPtr,
79 size_t length);
80
81 #define DH_PARAM_DUMP 0
82 #if DH_PARAM_DUMP
83
84 static void dumpBuf(const char *name, SSLBuffer *buf)
85 {
86 printf("%s:\n", name);
87 uint8_t *cp = buf->data;
88 uint8_t *endCp = cp + buf->length;
89
90 do {
91 unsigned i;
92 for(i=0; i<16; i++) {
93 printf("%02x ", *cp++);
94 if(cp == endCp) {
95 break;
96 }
97 }
98 if(cp == endCp) {
99 break;
100 }
101 printf("\n");
102 } while(cp < endCp);
103 printf("\n");
104 }
105 #else
106 #define dumpBuf(n, b)
107 #endif /* DH_PARAM_DUMP */
108
109 #if APPLE_DH
110
111 // MARK: -
112 // MARK: Local Diffie-Hellman Parameter Generator
113
114 /*
115 * Process-wide server-supplied Diffie-Hellman parameters.
116 * This might be overridden by some API_supplied parameters
117 * in the future.
118 */
119 struct ServerDhParams
120 {
121 /* these two for sending over the wire */
122 SSLBuffer prime;
123 SSLBuffer generator;
124 /* this one for sending to the CSP at key gen time */
125 SSLBuffer paramBlock;
126 };
127
128
129 #endif /* APPLE_DH */
130
131 // MARK: -
132 // MARK: RSA Key Exchange
133
134 /*
135 * Client RSA Key Exchange msgs actually start with a two-byte
136 * length field, contrary to the first version of RFC 2246, dated
137 * January 1999. See RFC 2246, March 2002, section 7.4.7.1 for
138 * updated requirements.
139 */
140 #define RSA_CLIENT_KEY_ADD_LENGTH 1
141
142 static OSStatus
143 SSLEncodeRSAKeyParams(SSLBuffer *keyParams, SSLPubKey *key, SSLContext *ctx)
144 {
145 #if 0
146 SSLBuffer modulus, exponent;
147 uint8_t *charPtr;
148
149 #ifdef USE_CDSA_CRYPTO
150 if(err = attachToCsp(ctx)) {
151 return err;
152 }
153
154 /* Note currently ALL public keys are raw, obtained from the CL... */
155 assert((*key)->KeyHeader.BlobType == CSSM_KEYBLOB_RAW);
156 #endif /* USE_CDSA_CRYPTO */
157
158 err = sslGetPubKeyBits(ctx,
159 key,
160 &modulus,
161 &exponent);
162 if(err) {
163 SSLFreeBuffer(&modulus);
164 SSLFreeBuffer(&exponent);
165 return err;
166 }
167
168 if ((err = SSLAllocBuffer(keyParams,
169 modulus.length + exponent.length + 4, ctx)) != 0) {
170 return err;
171 }
172 charPtr = keyParams->data;
173 charPtr = SSLEncodeInt(charPtr, modulus.length, 2);
174 memcpy(charPtr, modulus.data, modulus.length);
175 charPtr += modulus.length;
176 charPtr = SSLEncodeInt(charPtr, exponent.length, 2);
177 memcpy(charPtr, exponent.data, exponent.length);
178
179 /* these were mallocd by sslGetPubKeyBits() */
180 SSLFreeBuffer(&modulus);
181 SSLFreeBuffer(&exponent);
182 return errSecSuccess;
183 #else
184 CFDataRef modulus = SecKeyCopyModulus(SECKEYREF(key));
185 if (!modulus) {
186 sslErrorLog("SSLEncodeRSAKeyParams: SecKeyCopyModulus failed\n");
187 return errSSLCrypto;
188 }
189 CFDataRef exponent = SecKeyCopyExponent(SECKEYREF(key));
190 if (!exponent) {
191 sslErrorLog("SSLEncodeRSAKeyParams: SecKeyCopyExponent failed\n");
192 CFRelease(modulus);
193 return errSSLCrypto;
194 }
195
196 CFIndex modulusLength = CFDataGetLength(modulus);
197 CFIndex exponentLength = CFDataGetLength(exponent);
198 sslDebugLog("SSLEncodeRSAKeyParams: modulus len=%ld, exponent len=%ld\n",
199 modulusLength, exponentLength);
200 OSStatus err;
201 if ((err = SSLAllocBuffer(keyParams,
202 modulusLength + exponentLength + 4)) != 0) {
203 CFReleaseSafe(exponent);
204 CFReleaseSafe(modulus);
205 return err;
206 }
207 uint8_t *charPtr = keyParams->data;
208 charPtr = SSLEncodeSize(charPtr, modulusLength, 2);
209 memcpy(charPtr, CFDataGetBytePtr(modulus), modulusLength);
210 charPtr += modulusLength;
211 charPtr = SSLEncodeSize(charPtr, exponentLength, 2);
212 memcpy(charPtr, CFDataGetBytePtr(exponent), exponentLength);
213 CFRelease(modulus);
214 CFRelease(exponent);
215 return errSecSuccess;
216 #endif
217 }
218
219 static OSStatus
220 SSLEncodeRSAPremasterSecret(SSLContext *ctx)
221 { SSLBuffer randData;
222 OSStatus err;
223
224 if ((err = SSLAllocBuffer(&ctx->preMasterSecret,
225 SSL_RSA_PREMASTER_SECRET_SIZE)) != 0)
226 return err;
227
228 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
229
230 SSLEncodeInt(ctx->preMasterSecret.data, ctx->clientReqProtocol, 2);
231 randData.data = ctx->preMasterSecret.data+2;
232 randData.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
233 if ((err = sslRand(&randData)) != 0)
234 return err;
235 return errSecSuccess;
236 }
237
238 /*
239 * Generate a server key exchange message signed by our RSA or DSA private key.
240 */
241
242 static OSStatus
243 SSLSignServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgorithm sigAlg, SSLBuffer exchangeParams, SSLBuffer signature, size_t *actSigLen)
244 {
245 OSStatus err;
246 SSLBuffer hashOut, hashCtx, clientRandom, serverRandom;
247 uint8_t hashes[SSL_MAX_DIGEST_LEN];
248 SSLBuffer signedHashes;
249 uint8_t *dataToSign;
250 size_t dataToSignLen;
251 const HashReference *hashRef;
252 SecAsn1AlgId algId;
253
254 signedHashes.data = 0;
255 hashCtx.data = 0;
256
257 clientRandom.data = ctx->clientRandom;
258 clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
259 serverRandom.data = ctx->serverRandom;
260 serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
261
262 switch (sigAlg.hash) {
263 case SSL_HashAlgorithmSHA1:
264 hashRef = &SSLHashSHA1;
265 algId.algorithm = CSSMOID_SHA1WithRSA;
266 break;
267 case SSL_HashAlgorithmSHA256:
268 hashRef = &SSLHashSHA256;
269 algId.algorithm = CSSMOID_SHA256WithRSA;
270 break;
271 case SSL_HashAlgorithmSHA384:
272 hashRef = &SSLHashSHA384;
273 algId.algorithm = CSSMOID_SHA384WithRSA;
274 break;
275 default:
276 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg.hash);
277 return errSSLProtocol;
278 }
279
280
281 dataToSign = hashes;
282 dataToSignLen = hashRef->digestSize;
283 hashOut.data = hashes;
284 hashOut.length = hashRef->digestSize;
285
286 if ((err = ReadyHash(hashRef, &hashCtx)) != 0)
287 goto fail;
288 if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0)
289 goto fail;
290 if ((err = hashRef->update(&hashCtx, &serverRandom)) != 0)
291 goto fail;
292 if ((err = hashRef->update(&hashCtx, &exchangeParams)) != 0)
293 goto fail;
294 if ((err = hashRef->final(&hashCtx, &hashOut)) != 0)
295 goto fail;
296
297 if(sigAlg.signature==SSL_SignatureAlgorithmRSA) {
298 err = sslRsaSign(ctx,
299 ctx->signingPrivKeyRef,
300 &algId,
301 dataToSign,
302 dataToSignLen,
303 signature.data,
304 signature.length,
305 actSigLen);
306 } else {
307 err = sslRawSign(ctx,
308 ctx->signingPrivKeyRef,
309 dataToSign, // one or two hashes
310 dataToSignLen,
311 signature.data,
312 signature.length,
313 actSigLen);
314 }
315
316 if(err) {
317 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
318 "returned %d\n", (int)err);
319 goto fail;
320 }
321
322 fail:
323 SSLFreeBuffer(&signedHashes);
324 SSLFreeBuffer(&hashCtx);
325 return err;
326 }
327
328 static OSStatus
329 SSLSignServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer exchangeParams, SSLBuffer signature, size_t *actSigLen)
330 {
331 OSStatus err;
332 uint8_t hashes[SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN];
333 SSLBuffer clientRandom,serverRandom,hashCtx, hash;
334 uint8_t *dataToSign;
335 size_t dataToSignLen;
336
337 hashCtx.data = 0;
338
339 /* cook up hash(es) for raw sign */
340 clientRandom.data = ctx->clientRandom;
341 clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
342 serverRandom.data = ctx->serverRandom;
343 serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
344
345 if(isRsa) {
346 /* skip this if signing with DSA */
347 dataToSign = hashes;
348 dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN;
349 hash.data = &hashes[0];
350 hash.length = SSL_MD5_DIGEST_LEN;
351
352 if ((err = ReadyHash(&SSLHashMD5, &hashCtx)) != 0)
353 goto fail;
354 if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
355 goto fail;
356 if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0)
357 goto fail;
358 if ((err = SSLHashMD5.update(&hashCtx, &exchangeParams)) != 0)
359 goto fail;
360 if ((err = SSLHashMD5.final(&hashCtx, &hash)) != 0)
361 goto fail;
362 if ((err = SSLFreeBuffer(&hashCtx)) != 0)
363 goto fail;
364 }
365 else {
366 /* DSA - just use the SHA1 hash */
367 dataToSign = &hashes[SSL_MD5_DIGEST_LEN];
368 dataToSignLen = SSL_SHA1_DIGEST_LEN;
369 }
370 hash.data = &hashes[SSL_MD5_DIGEST_LEN];
371 hash.length = SSL_SHA1_DIGEST_LEN;
372 if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
373 goto fail;
374 if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
375 goto fail;
376 if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
377 goto fail;
378 if ((err = SSLHashSHA1.update(&hashCtx, &exchangeParams)) != 0)
379 goto fail;
380 if ((err = SSLHashSHA1.final(&hashCtx, &hash)) != 0)
381 goto fail;
382 if ((err = SSLFreeBuffer(&hashCtx)) != 0)
383 goto fail;
384
385
386 err = sslRawSign(ctx,
387 ctx->signingPrivKeyRef,
388 dataToSign, // one or two hashes
389 dataToSignLen,
390 signature.data,
391 signature.length,
392 actSigLen);
393 if(err) {
394 goto fail;
395 }
396
397 fail:
398 SSLFreeBuffer(&hashCtx);
399
400 return err;
401 }
402
403 static
404 OSStatus FindSigAlg(SSLContext *ctx,
405 SSLSignatureAndHashAlgorithm *alg)
406 {
407 unsigned i;
408
409 assert(ctx->protocolSide == kSSLServerSide);
410 assert(ctx->negProtocolVersion >= TLS_Version_1_2);
411 assert(!ctx->isDTLS);
412
413 if((ctx->numClientSigAlgs==0) ||(ctx->clientSigAlgs==NULL))
414 return errSSLInternal;
415
416 //FIXME: Need a better way to select here
417 for(i=0; i<ctx->numClientSigAlgs; i++) {
418 alg->hash = ctx->clientSigAlgs[i].hash;
419 alg->signature = ctx->clientSigAlgs[i].signature;
420 //We only support RSA for certs on the server side - but we should test against the cert type
421 if(ctx->clientSigAlgs[i].signature != SSL_SignatureAlgorithmRSA)
422 continue;
423 //Let's only support SHA1 and SHA256. SHA384 does not work with 512 bits keys.
424 // We should actually test against what the cert can do.
425 if((alg->hash==SSL_HashAlgorithmSHA1) || (alg->hash==SSL_HashAlgorithmSHA256)) {
426 return errSecSuccess;
427 }
428 }
429 // We could not find a supported signature and hash algorithm
430 return errSSLProtocol;
431 }
432
433 static OSStatus
434 SSLEncodeSignedServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
435 { OSStatus err;
436 uint8_t *charPtr;
437 size_t outputLen;
438 bool isRsa = true;
439 size_t maxSigLen;
440 size_t actSigLen;
441 SSLBuffer signature;
442 int head = 4;
443 SSLBuffer exchangeParams;
444
445 assert(ctx->protocolSide == kSSLServerSide);
446 assert(ctx->signingPubKey != NULL);
447 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
448 exchangeParams.data = 0;
449 signature.data = 0;
450
451 #if ENABLE_DTLS
452 if(ctx->negProtocolVersion == DTLS_Version_1_0) {
453 head+=8;
454 }
455 #endif
456
457
458 /* Set up parameter block to hash ==> exchangeParams */
459 switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
460 case SSL_RSA:
461 case SSL_RSA_EXPORT:
462 /*
463 * Parameter block = encryption public key.
464 * If app hasn't supplied a separate encryption cert, abort.
465 */
466 if(ctx->encryptPubKey == NULL) {
467 sslErrorLog("RSAServerKeyExchange: no encrypt cert\n");
468 return errSSLBadConfiguration;
469 }
470 err = SSLEncodeRSAKeyParams(&exchangeParams,
471 ctx->encryptPubKey, ctx);
472 break;
473
474 #if APPLE_DH
475
476 case SSL_DHE_DSS:
477 case SSL_DHE_DSS_EXPORT:
478 isRsa = false;
479 /* and fall through */
480 case SSL_DHE_RSA:
481 case SSL_DHE_RSA_EXPORT:
482 {
483 /*
484 * Parameter block = {prime, generator, public key}
485 * Obtain D-H parameters (if we don't have them) and a key pair.
486 */
487 err = SSLGenServerDHParamsAndKey(ctx);
488 if(err) {
489 return err;
490 }
491 size_t len = SSLEncodedDHKeyParamsLen(ctx);
492 err = SSLAllocBuffer(&exchangeParams, len);
493 if(err) {
494 goto fail;
495 }
496 err = SSLEncodeDHKeyParams(ctx, exchangeParams.data);
497 break;
498 }
499
500 #endif /* APPLE_DH */
501
502 default:
503 /* shouldn't be here */
504 assert(0);
505 return errSSLInternal;
506 }
507
508 SSLSignatureAndHashAlgorithm sigAlg;
509
510
511 /* preallocate a buffer for signing */
512 err = sslGetMaxSigSize(ctx->signingPrivKeyRef, &maxSigLen);
513 if(err) {
514 goto fail;
515 }
516 err = SSLAllocBuffer(&signature, maxSigLen);
517 if(err) {
518 goto fail;
519 }
520
521 outputLen = exchangeParams.length + 2;
522
523 if (sslVersionIsLikeTls12(ctx))
524 {
525 err=FindSigAlg(ctx, &sigAlg);
526 if(err)
527 goto fail;
528
529 outputLen += 2;
530 err = SSLSignServerKeyExchangeTls12(ctx, sigAlg, exchangeParams,
531 signature, &actSigLen);
532 } else {
533 err = SSLSignServerKeyExchange(ctx, isRsa, exchangeParams,
534 signature, &actSigLen);
535 }
536
537 if(err)
538 goto fail;
539
540 assert(actSigLen <= maxSigLen);
541
542 outputLen += actSigLen;
543
544 /* package it all up */
545 keyExch->protocolVersion = ctx->negProtocolVersion;
546 keyExch->contentType = SSL_RecordTypeHandshake;
547 if ((err = SSLAllocBuffer(&keyExch->contents, outputLen+head)) != 0)
548 goto fail;
549
550 charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, outputLen);
551
552 memcpy(charPtr, exchangeParams.data, exchangeParams.length);
553 charPtr += exchangeParams.length;
554
555 if (sslVersionIsLikeTls12(ctx))
556 {
557 *charPtr++=sigAlg.hash;
558 *charPtr++=sigAlg.signature;
559 }
560
561 charPtr = SSLEncodeInt(charPtr, actSigLen, 2);
562 memcpy(charPtr, signature.data, actSigLen);
563 assert((charPtr + actSigLen) ==
564 (keyExch->contents.data + keyExch->contents.length));
565
566 err = errSecSuccess;
567
568 fail:
569 SSLFreeBuffer(&exchangeParams);
570 SSLFreeBuffer(&signature);
571 return err;
572 }
573
574 static OSStatus
575 SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
576 uint8_t *signature, UInt16 signatureLen)
577 {
578 OSStatus err;
579 SSLBuffer hashOut, hashCtx, clientRandom, serverRandom;
580 uint8_t hashes[SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN];
581 SSLBuffer signedHashes;
582 uint8_t *dataToSign;
583 size_t dataToSignLen;
584
585 signedHashes.data = 0;
586 hashCtx.data = 0;
587
588 clientRandom.data = ctx->clientRandom;
589 clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
590 serverRandom.data = ctx->serverRandom;
591 serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
592
593
594 if(isRsa) {
595 /* skip this if signing with DSA */
596 dataToSign = hashes;
597 dataToSignLen = SSL_SHA1_DIGEST_LEN + SSL_MD5_DIGEST_LEN;
598 hashOut.data = hashes;
599 hashOut.length = SSL_MD5_DIGEST_LEN;
600
601 if ((err = ReadyHash(&SSLHashMD5, &hashCtx)) != 0)
602 goto fail;
603 if ((err = SSLHashMD5.update(&hashCtx, &clientRandom)) != 0)
604 goto fail;
605 if ((err = SSLHashMD5.update(&hashCtx, &serverRandom)) != 0)
606 goto fail;
607 if ((err = SSLHashMD5.update(&hashCtx, &signedParams)) != 0)
608 goto fail;
609 if ((err = SSLHashMD5.final(&hashCtx, &hashOut)) != 0)
610 goto fail;
611 }
612 else {
613 /* DSA, ECDSA - just use the SHA1 hash */
614 dataToSign = &hashes[SSL_MD5_DIGEST_LEN];
615 dataToSignLen = SSL_SHA1_DIGEST_LEN;
616 }
617
618 hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
619 hashOut.length = SSL_SHA1_DIGEST_LEN;
620 if ((err = SSLFreeBuffer(&hashCtx)) != 0)
621 goto fail;
622
623 if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
624 goto fail;
625 if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
626 goto fail;
627 if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
628 goto fail;
629 if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
630 goto fail;
631 if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
632 goto fail;
633
634 err = sslRawVerify(ctx,
635 ctx->peerPubKey,
636 dataToSign, /* plaintext */
637 dataToSignLen, /* plaintext length */
638 signature,
639 signatureLen);
640 if(err) {
641 sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
642 "returned %d\n", (int)err);
643 goto fail;
644 }
645
646 fail:
647 SSLFreeBuffer(&signedHashes);
648 SSLFreeBuffer(&hashCtx);
649 return err;
650
651 }
652
653 static OSStatus
654 SSLVerifySignedServerKeyExchangeTls12(SSLContext *ctx, SSLSignatureAndHashAlgorithm sigAlg, SSLBuffer signedParams,
655 uint8_t *signature, UInt16 signatureLen)
656 {
657 OSStatus err;
658 SSLBuffer hashOut, hashCtx, clientRandom, serverRandom;
659 uint8_t hashes[SSL_MAX_DIGEST_LEN];
660 SSLBuffer signedHashes;
661 uint8_t *dataToSign;
662 size_t dataToSignLen;
663 const HashReference *hashRef;
664 SecAsn1AlgId algId;
665
666 signedHashes.data = 0;
667 hashCtx.data = 0;
668
669 clientRandom.data = ctx->clientRandom;
670 clientRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
671 serverRandom.data = ctx->serverRandom;
672 serverRandom.length = SSL_CLIENT_SRVR_RAND_SIZE;
673
674 switch (sigAlg.hash) {
675 case SSL_HashAlgorithmSHA1:
676 hashRef = &SSLHashSHA1;
677 algId.algorithm = CSSMOID_SHA1WithRSA;
678 break;
679 case SSL_HashAlgorithmSHA256:
680 hashRef = &SSLHashSHA256;
681 algId.algorithm = CSSMOID_SHA256WithRSA;
682 break;
683 case SSL_HashAlgorithmSHA384:
684 hashRef = &SSLHashSHA384;
685 algId.algorithm = CSSMOID_SHA384WithRSA;
686 break;
687 default:
688 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg.hash);
689 return errSSLProtocol;
690 }
691
692
693 dataToSign = hashes;
694 dataToSignLen = hashRef->digestSize;
695 hashOut.data = hashes;
696 hashOut.length = hashRef->digestSize;
697
698 if ((err = ReadyHash(hashRef, &hashCtx)) != 0)
699 goto fail;
700 if ((err = hashRef->update(&hashCtx, &clientRandom)) != 0)
701 goto fail;
702 if ((err = hashRef->update(&hashCtx, &serverRandom)) != 0)
703 goto fail;
704 if ((err = hashRef->update(&hashCtx, &signedParams)) != 0)
705 goto fail;
706 if ((err = hashRef->final(&hashCtx, &hashOut)) != 0)
707 goto fail;
708
709 if(sigAlg.signature==SSL_SignatureAlgorithmRSA) {
710 err = sslRsaVerify(ctx,
711 ctx->peerPubKey,
712 &algId,
713 dataToSign,
714 dataToSignLen,
715 signature,
716 signatureLen);
717 } else {
718 err = sslRawVerify(ctx,
719 ctx->peerPubKey,
720 dataToSign, /* plaintext */
721 dataToSignLen, /* plaintext length */
722 signature,
723 signatureLen);
724 }
725
726 if(err) {
727 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
728 "returned %d\n", (int)err);
729 goto fail;
730 }
731
732 fail:
733 SSLFreeBuffer(&signedHashes);
734 SSLFreeBuffer(&hashCtx);
735 return err;
736
737 }
738
739 /*
740 * Decode and verify a server key exchange message signed by server's
741 * public key.
742 */
743 static OSStatus
744 SSLDecodeSignedServerKeyExchange(SSLBuffer message, SSLContext *ctx)
745 {
746 OSStatus err;
747 UInt16 modulusLen = 0, exponentLen = 0, signatureLen;
748 uint8_t *modulus = NULL, *exponent = NULL, *signature;
749 bool isRsa = true;
750
751 assert(ctx->protocolSide == kSSLClientSide);
752
753 if (message.length < 2) {
754 sslErrorLog("SSLDecodeSignedServerKeyExchange: msg len error 1\n");
755 return errSSLProtocol;
756 }
757
758 /* first extract the key-exchange-method-specific parameters */
759 uint8_t *charPtr = message.data;
760 uint8_t *endCp = charPtr + message.length;
761 switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
762 case SSL_RSA:
763 case SSL_RSA_EXPORT:
764 modulusLen = SSLDecodeInt(charPtr, 2);
765 charPtr += 2;
766 if((charPtr + modulusLen) > endCp) {
767 sslErrorLog("signedServerKeyExchange: msg len error 2\n");
768 return errSSLProtocol;
769 }
770 modulus = charPtr;
771 charPtr += modulusLen;
772
773 exponentLen = SSLDecodeInt(charPtr, 2);
774 charPtr += 2;
775 if((charPtr + exponentLen) > endCp) {
776 sslErrorLog("signedServerKeyExchange: msg len error 3\n");
777 return errSSLProtocol;
778 }
779 exponent = charPtr;
780 charPtr += exponentLen;
781 break;
782 #if APPLE_DH
783 case SSL_DHE_DSS:
784 case SSL_DHE_DSS_EXPORT:
785 isRsa = false;
786 /* and fall through */
787 case SSL_DHE_RSA:
788 case SSL_DHE_RSA_EXPORT:
789 err = SSLDecodeDHKeyParams(ctx, &charPtr, message.length);
790 if(err) {
791 return err;
792 }
793 break;
794 #endif /* APPLE_DH */
795
796 case SSL_ECDHE_ECDSA:
797 isRsa = false;
798 /* and fall through */
799 case SSL_ECDHE_RSA:
800 err = SSLDecodeECDHKeyParams(ctx, &charPtr, message.length);
801 if(err) {
802 return err;
803 }
804 break;
805 default:
806 assert(0);
807 return errSSLInternal;
808 }
809
810 /* this is what's hashed */
811 SSLBuffer signedParams;
812 signedParams.data = message.data;
813 signedParams.length = charPtr - message.data;
814
815 SSLSignatureAndHashAlgorithm sigAlg;
816
817 if (sslVersionIsLikeTls12(ctx)) {
818 /* Parse the algorithm field added in TLS1.2 */
819 if((charPtr + 2) > endCp) {
820 sslErrorLog("signedServerKeyExchange: msg len error 499\n");
821 return errSSLProtocol;
822 }
823 sigAlg.hash = *charPtr++;
824 sigAlg.signature = *charPtr++;
825 }
826
827 signatureLen = SSLDecodeInt(charPtr, 2);
828 charPtr += 2;
829 if((charPtr + signatureLen) != endCp) {
830 sslErrorLog("signedServerKeyExchange: msg len error 4\n");
831 return errSSLProtocol;
832 }
833 signature = charPtr;
834
835 if (sslVersionIsLikeTls12(ctx))
836 {
837 err = SSLVerifySignedServerKeyExchangeTls12(ctx, sigAlg, signedParams,
838 signature, signatureLen);
839 } else {
840 err = SSLVerifySignedServerKeyExchange(ctx, isRsa, signedParams,
841 signature, signatureLen);
842 }
843
844 if(err)
845 goto fail;
846
847 /* Signature matches; now replace server key with new key (RSA only) */
848 switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
849 case SSL_RSA:
850 case SSL_RSA_EXPORT:
851 {
852 SSLBuffer modBuf;
853 SSLBuffer expBuf;
854
855 /* first free existing peerKey */
856 sslFreePubKey(&ctx->peerPubKey); /* no KCItem */
857
858 /* and cook up a new one from raw bits */
859 modBuf.data = modulus;
860 modBuf.length = modulusLen;
861 expBuf.data = exponent;
862 expBuf.length = exponentLen;
863 err = sslGetPubKeyFromBits(ctx,
864 &modBuf,
865 &expBuf,
866 &ctx->peerPubKey);
867 break;
868 }
869 case SSL_DHE_RSA:
870 case SSL_DHE_RSA_EXPORT:
871 case SSL_DHE_DSS:
872 case SSL_DHE_DSS_EXPORT:
873 case SSL_ECDHE_ECDSA:
874 case SSL_ECDHE_RSA:
875 break; /* handled above */
876 default:
877 assert(0);
878 }
879 fail:
880 return err;
881 }
882
883 static OSStatus
884 SSLDecodeRSAKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
885 { OSStatus err;
886 size_t outputLen, localKeyModulusLen;
887 SSLProtocolVersion version;
888 Boolean useEncryptKey = false;
889 uint8_t *src = NULL;
890 SSLPrivKey *keyRef = NULL;
891
892 assert(ctx->protocolSide == kSSLServerSide);
893 if (ctx->encryptPrivKeyRef) {
894 useEncryptKey = true;
895 }
896 if (useEncryptKey) {
897 keyRef = ctx->encryptPrivKeyRef;
898 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
899 }
900 else {
901 keyRef = ctx->signingPrivKeyRef;
902 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
903 }
904
905 localKeyModulusLen = sslPrivKeyLengthInBytes(keyRef);
906 if (localKeyModulusLen == 0) {
907 sslErrorLog("SSLDecodeRSAKeyExchange: private key modulus is 0\n");
908 return errSSLCrypto;
909 }
910
911 /*
912 * We have to tolerate incoming key exchange msgs with and without the
913 * two-byte "encrypted length" field.
914 */
915 if (keyExchange.length == localKeyModulusLen) {
916 /* no length encoded */
917 src = keyExchange.data;
918 }
919 else if((keyExchange.length == (localKeyModulusLen + 2)) &&
920 (ctx->negProtocolVersion >= TLS_Version_1_0)) {
921 /* TLS only - skip the length bytes */
922 src = keyExchange.data + 2;
923 }
924 else {
925 sslErrorLog("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n",
926 (unsigned)localKeyModulusLen, (unsigned)keyExchange.length);
927 return errSSLProtocol;
928 }
929 err = SSLAllocBuffer(&ctx->preMasterSecret, SSL_RSA_PREMASTER_SECRET_SIZE);
930 if(err != 0) {
931 return err;
932 }
933
934 /*
935 * From this point on, to defend against the Bleichenbacher attack
936 * and its Klima-Pokorny-Rosa variant, any errors we detect are *not*
937 * reported to the caller or the peer. If we detect any error during
938 * decryption (e.g., bad PKCS1 padding) or in the testing of the version
939 * number in the premaster secret, we proceed by generating a random
940 * premaster secret, with the correct version number, and tell our caller
941 * that everything is fine. This session will fail as soon as the
942 * finished messages are sent, since we will be using a bogus premaster
943 * secret (and hence bogus session and MAC keys). Meanwhile we have
944 * not provided any side channel information relating to the cause of
945 * the failure.
946 *
947 * See http://eprint.iacr.org/2003/052/ for more info.
948 */
949 err = sslRsaDecrypt(ctx,
950 keyRef,
951 #if USE_CDSA_CRYPTO
952 CSSM_PADDING_PKCS1,
953 #else
954 kSecPaddingPKCS1,
955 #endif
956 src,
957 localKeyModulusLen, // ciphertext len
958 ctx->preMasterSecret.data,
959 SSL_RSA_PREMASTER_SECRET_SIZE, // plaintext buf available
960 &outputLen);
961
962 if(err != errSecSuccess) {
963 /* possible Bleichenbacher attack */
964 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail");
965 }
966 else if(outputLen != SSL_RSA_PREMASTER_SECRET_SIZE) {
967 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: premaster secret size error");
968 err = errSSLProtocol; // not passed back to caller
969 }
970
971 if(err == errSecSuccess) {
972 /*
973 * Two legal values here - the one we actually negotiated (which is
974 * technically incorrect but not uncommon), and the one the client
975 * sent as its preferred version in the client hello msg.
976 */
977 version = (SSLProtocolVersion)SSLDecodeInt(ctx->preMasterSecret.data, 2);
978 if((version != ctx->negProtocolVersion) &&
979 (version != ctx->clientReqProtocol)) {
980 /* possible Klima-Pokorny-Rosa attack */
981 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: version error");
982 err = errSSLProtocol;
983 }
984 }
985 if(err != errSecSuccess) {
986 /*
987 * Obfuscate failures for defense against Bleichenbacher and
988 * Klima-Pokorny-Rosa attacks.
989 */
990 SSLEncodeInt(ctx->preMasterSecret.data, ctx->negProtocolVersion, 2);
991 SSLBuffer tmpBuf;
992 tmpBuf.data = ctx->preMasterSecret.data + 2;
993 tmpBuf.length = SSL_RSA_PREMASTER_SECRET_SIZE - 2;
994 /* must ignore failures here */
995 sslRand(&tmpBuf);
996 }
997
998 /* in any case, save premaster secret (good or bogus) and proceed */
999 return errSecSuccess;
1000 }
1001
1002 static OSStatus
1003 SSLEncodeRSAKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1004 { OSStatus err;
1005 size_t outputLen, peerKeyModulusLen;
1006 size_t bufLen;
1007 uint8_t *dst;
1008 bool encodeLen = false;
1009 uint8_t *p;
1010 int head;
1011 size_t msglen;
1012
1013 assert(ctx->protocolSide == kSSLClientSide);
1014 if ((err = SSLEncodeRSAPremasterSecret(ctx)) != 0)
1015 return err;
1016
1017 keyExchange->contentType = SSL_RecordTypeHandshake;
1018 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
1019 keyExchange->protocolVersion = ctx->negProtocolVersion;
1020
1021 peerKeyModulusLen = sslPubKeyLengthInBytes(ctx->peerPubKey);
1022 if (peerKeyModulusLen == 0) {
1023 sslErrorLog("SSLEncodeRSAKeyExchange: peer key modulus is 0\n");
1024 /* FIXME: we don't return an error here... is this condition ever expected? */
1025 }
1026 #if SSL_DEBUG
1027 sslDebugLog("SSLEncodeRSAKeyExchange: peer key modulus length = %lu\n", peerKeyModulusLen);
1028 #endif
1029 msglen = peerKeyModulusLen;
1030 #if RSA_CLIENT_KEY_ADD_LENGTH
1031 if(ctx->negProtocolVersion >= TLS_Version_1_0) {
1032 msglen += 2;
1033 encodeLen = true;
1034 }
1035 #endif
1036 head = SSLHandshakeHeaderSize(keyExchange);
1037 bufLen = msglen + head;
1038 if ((err = SSLAllocBuffer(&keyExchange->contents,
1039 bufLen)) != 0)
1040 {
1041 return err;
1042 }
1043 dst = keyExchange->contents.data + head;
1044 if(encodeLen) {
1045 dst += 2;
1046 }
1047
1048 /* FIXME: can this line be removed? */
1049 p = keyExchange->contents.data;
1050
1051 p = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, msglen);
1052
1053 if(encodeLen) {
1054 /* the length of the encrypted pre_master_secret */
1055 SSLEncodeSize(keyExchange->contents.data + head,
1056 peerKeyModulusLen, 2);
1057 }
1058 err = sslRsaEncrypt(ctx,
1059 ctx->peerPubKey,
1060 #if USE_CDSA_CRYPTO
1061 CSSM_PADDING_PKCS1,
1062 #else
1063 kSecPaddingPKCS1,
1064 #endif
1065 ctx->preMasterSecret.data,
1066 SSL_RSA_PREMASTER_SECRET_SIZE,
1067 dst,
1068 peerKeyModulusLen,
1069 &outputLen);
1070 if(err) {
1071 sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", (int)err);
1072 return err;
1073 }
1074
1075 assert(outputLen == (encodeLen ? msglen - 2 : msglen));
1076
1077 return errSecSuccess;
1078 }
1079
1080
1081 #if APPLE_DH
1082
1083 // MARK: -
1084 // MARK: Diffie-Hellman Key Exchange
1085
1086 /*
1087 * Diffie-Hellman setup, server side. On successful return, the
1088 * following SSLContext members are valid:
1089 *
1090 * dhParamsPrime
1091 * dhParamsGenerator
1092 * dhPrivate
1093 * dhExchangePublic
1094 */
1095 static OSStatus
1096 SSLGenServerDHParamsAndKey(
1097 SSLContext *ctx)
1098 {
1099 OSStatus ortn;
1100 assert(ctx->protocolSide == kSSLServerSide);
1101
1102
1103 /*
1104 * Obtain D-H parameters if we don't have them.
1105 */
1106 if(ctx->dhParamsEncoded.data == NULL) {
1107 /* TODO: Pick appropriate group based on cipher suite */
1108 ccdh_const_gp_t gp = ccdh_gp_rfc5114_MODP_2048_256();
1109 cc_size n = ccdh_gp_n(gp);
1110 size_t s = ccdh_gp_prime_size(gp);
1111 uint8_t p[s];
1112 uint8_t g[s];
1113
1114 ccn_write_uint(n, ccdh_gp_prime(gp), s, p);
1115 ccn_write_uint(n, ccdh_gp_g(gp), s, g);
1116
1117 const SSLBuffer prime = {
1118 .data = p,
1119 .length = s,
1120 };
1121 const SSLBuffer generator = {
1122 .data = g,
1123 .length = s,
1124 };
1125
1126 ortn=sslEncodeDhParams(&ctx->dhParamsEncoded, /* data mallocd and RETURNED PKCS-3 encoded */
1127 &prime, /* Wire format */
1128 &generator); /* Wire format */
1129
1130 if(ortn)
1131 return ortn;
1132 }
1133
1134 #if USE_CDSA_CRYPTO
1135 /* generate per-session D-H key pair */
1136 sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
1137 SSLFreeBuffer(&ctx->dhExchangePublic);
1138 ctx->dhPrivate = (CSSM_KEY *)sslMalloc(sizeof(CSSM_KEY));
1139 CSSM_KEY pubKey;
1140 ortn = sslDhGenerateKeyPair(ctx,
1141 &ctx->dhParamsEncoded,
1142 ctx->dhParamsPrime.length * 8,
1143 &pubKey, ctx->dhPrivate);
1144 if(ortn) {
1145 return ortn;
1146 }
1147 CSSM_TO_SSLBUF(&pubKey.KeyData, &ctx->dhExchangePublic);
1148 #else
1149 if (!ctx->secDHContext) {
1150 ortn = sslDhCreateKey(ctx);
1151 if(ortn)
1152 return ortn;
1153 }
1154 return sslDhGenerateKeyPair(ctx);
1155 #endif
1156 return errSecSuccess;
1157 }
1158
1159 /*
1160 * size of DH param and public key, in wire format
1161 */
1162 static size_t
1163 SSLEncodedDHKeyParamsLen(SSLContext *ctx)
1164 {
1165 SSLBuffer prime;
1166 SSLBuffer generator;
1167
1168 sslDecodeDhParams(&ctx->dhParamsEncoded, &prime, &generator);
1169
1170 return (2+prime.length+2+generator.length+2+ctx->dhExchangePublic.length);
1171 }
1172
1173 /*
1174 * Encode DH params and public key, in wire format, in caller-supplied buffer.
1175 */
1176 static OSStatus
1177 SSLEncodeDHKeyParams(
1178 SSLContext *ctx,
1179 uint8_t *charPtr)
1180 {
1181 assert(ctx->protocolSide == kSSLServerSide);
1182 assert(ctx->dhParamsEncoded.data != NULL);
1183 assert(ctx->dhExchangePublic.data != NULL);
1184
1185 SSLBuffer prime;
1186 SSLBuffer generator;
1187
1188 sslDecodeDhParams(&ctx->dhParamsEncoded, &prime, &generator);
1189
1190 charPtr = SSLEncodeInt(charPtr, prime.length, 2);
1191 memcpy(charPtr, prime.data, prime.length);
1192 charPtr += prime.length;
1193
1194 charPtr = SSLEncodeInt(charPtr, generator.length, 2);
1195 memcpy(charPtr, generator.data,
1196 generator.length);
1197 charPtr += generator.length;
1198
1199 /* TODO: hum.... sounds like this one should be in the SecDHContext */
1200 charPtr = SSLEncodeInt(charPtr, ctx->dhExchangePublic.length, 2);
1201 memcpy(charPtr, ctx->dhExchangePublic.data,
1202 ctx->dhExchangePublic.length);
1203
1204 dumpBuf("server prime", &prime);
1205 dumpBuf("server generator", &generator);
1206 dumpBuf("server pub key", &ctx->dhExchangePublic);
1207
1208 return errSecSuccess;
1209 }
1210
1211 /*
1212 * Decode DH params and server public key.
1213 */
1214 static OSStatus
1215 SSLDecodeDHKeyParams(
1216 SSLContext *ctx,
1217 uint8_t **charPtr, // IN/OUT
1218 size_t length)
1219 {
1220 OSStatus err = errSecSuccess;
1221 SSLBuffer prime;
1222 SSLBuffer generator;
1223
1224 assert(ctx->protocolSide == kSSLClientSide);
1225 uint8_t *endCp = *charPtr + length;
1226
1227 /* Allow reuse via renegotiation */
1228 SSLFreeBuffer(&ctx->dhPeerPublic);
1229
1230 /* Prime, with a two-byte length */
1231 UInt32 len = SSLDecodeInt(*charPtr, 2);
1232 (*charPtr) += 2;
1233 if((*charPtr + len) > endCp) {
1234 return errSSLProtocol;
1235 }
1236
1237 prime.data = *charPtr;
1238 prime.length = len;
1239
1240 (*charPtr) += len;
1241
1242 /* Generator, with a two-byte length */
1243 len = SSLDecodeInt(*charPtr, 2);
1244 (*charPtr) += 2;
1245 if((*charPtr + len) > endCp) {
1246 return errSSLProtocol;
1247 }
1248
1249 generator.data = *charPtr;
1250 generator.length = len;
1251
1252 (*charPtr) += len;
1253
1254 sslEncodeDhParams(&ctx->dhParamsEncoded, &prime, &generator);
1255
1256 /* peer public key, with a two-byte length */
1257 len = SSLDecodeInt(*charPtr, 2);
1258 (*charPtr) += 2;
1259 err = SSLAllocBuffer(&ctx->dhPeerPublic, len);
1260 if(err) {
1261 return err;
1262 }
1263 memmove(ctx->dhPeerPublic.data, *charPtr, len);
1264 (*charPtr) += len;
1265
1266 dumpBuf("client peer pub", &ctx->dhPeerPublic);
1267 // dumpBuf("client prime", &ctx->dhParamsPrime);
1268 // dumpBuf("client generator", &ctx->dhParamsGenerator);
1269
1270 return err;
1271 }
1272
1273 /*
1274 * Given the server's Diffie-Hellman parameters, generate our
1275 * own DH key pair, and perform key exchange using the server's
1276 * public key and our private key. The result is the premaster
1277 * secret.
1278 *
1279 * SSLContext members valid on entry:
1280 * dhParamsPrime
1281 * dhParamsGenerator
1282 * dhPeerPublic
1283 *
1284 * SSLContext members valid on successful return:
1285 * dhPrivate
1286 * dhExchangePublic
1287 * preMasterSecret
1288 */
1289 static OSStatus
1290 SSLGenClientDHKeyAndExchange(SSLContext *ctx)
1291 {
1292 OSStatus ortn;
1293
1294 #if USE_CDSA_CRYPTO
1295
1296 if((ctx->dhParamsPrime.data == NULL) ||
1297 (ctx->dhParamsGenerator.data == NULL) ||
1298 (ctx->dhPeerPublic.data == NULL)) {
1299 sslErrorLog("SSLGenClientDHKeyAndExchange: incomplete server params\n");
1300 return errSSLProtocol;
1301 }
1302
1303 /* generate two keys */
1304 CSSM_KEY pubKey;
1305 ctx->dhPrivate = (CSSM_KEY *)sslMalloc(sizeof(CSSM_KEY));
1306 ortn = sslDhGenKeyPairClient(ctx,
1307 &ctx->dhParamsPrime,
1308 &ctx->dhParamsGenerator,
1309 &pubKey, ctx->dhPrivate);
1310 if(ortn) {
1311 sslFree(ctx->dhPrivate);
1312 ctx->dhPrivate = NULL;
1313 return ortn;
1314 }
1315
1316 /* do the exchange, size of prime */
1317 ortn = sslDhKeyExchange(ctx, ctx->dhParamsPrime.length * 8,
1318 &ctx->preMasterSecret);
1319 if(ortn) {
1320 return ortn;
1321 }
1322 CSSM_TO_SSLBUF(&pubKey.KeyData, &ctx->dhExchangePublic);
1323 #else
1324 ortn=errSSLProtocol;
1325 require(ctx->dhParamsEncoded.data, out);
1326 require_noerr(ortn = sslDhCreateKey(ctx), out);
1327 require_noerr(ortn = sslDhGenerateKeyPair(ctx), out);
1328 require_noerr(ortn = sslDhKeyExchange(ctx), out);
1329 out:
1330 #endif
1331 return ortn;
1332 }
1333
1334
1335 static OSStatus
1336 SSLEncodeDHanonServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
1337 {
1338 OSStatus ortn = errSecSuccess;
1339 int head;
1340
1341 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
1342 assert(ctx->protocolSide == kSSLServerSide);
1343
1344 /*
1345 * Obtain D-H parameters (if we don't have them) and a key pair.
1346 */
1347 ortn = SSLGenServerDHParamsAndKey(ctx);
1348 if(ortn) {
1349 return ortn;
1350 }
1351
1352 size_t length = SSLEncodedDHKeyParamsLen(ctx);
1353
1354 keyExch->protocolVersion = ctx->negProtocolVersion;
1355 keyExch->contentType = SSL_RecordTypeHandshake;
1356 head = SSLHandshakeHeaderSize(keyExch);
1357 if ((ortn = SSLAllocBuffer(&keyExch->contents, length+head)))
1358 return ortn;
1359
1360 uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExch, SSL_HdskServerKeyExchange, length);
1361
1362 /* encode prime, generator, our public key */
1363 return SSLEncodeDHKeyParams(ctx, charPtr);
1364 }
1365
1366 static OSStatus
1367 SSLDecodeDHanonServerKeyExchange(SSLBuffer message, SSLContext *ctx)
1368 {
1369 OSStatus err = errSecSuccess;
1370
1371 assert(ctx->protocolSide == kSSLClientSide);
1372 if (message.length < 6) {
1373 sslErrorLog("SSLDecodeDHanonServerKeyExchange error: msg len %u\n",
1374 (unsigned)message.length);
1375 return errSSLProtocol;
1376 }
1377 uint8_t *charPtr = message.data;
1378 err = SSLDecodeDHKeyParams(ctx, &charPtr, message.length);
1379 if(err == errSecSuccess) {
1380 if((message.data + message.length) != charPtr) {
1381 err = errSSLProtocol;
1382 }
1383 }
1384 return err;
1385 }
1386
1387 static OSStatus
1388 SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
1389 {
1390 OSStatus ortn = errSecSuccess;
1391 unsigned int publicLen;
1392
1393 assert(ctx->protocolSide == kSSLServerSide);
1394 if(ctx->dhParamsEncoded.data == NULL) {
1395 /* should never happen */
1396 assert(0);
1397 return errSSLInternal;
1398 }
1399
1400 /* this message simply contains the client's public DH key */
1401 uint8_t *charPtr = keyExchange.data;
1402 publicLen = SSLDecodeInt(charPtr, 2);
1403 charPtr += 2;
1404 /* TODO : Check the len here ? Will fail in sslDhKeyExchange anyway */
1405 /*
1406 if((keyExchange.length != publicLen + 2) ||
1407 (publicLen > ctx->dhParamsPrime.length)) {
1408 return errSSLProtocol;
1409 }
1410 */
1411 SSLFreeBuffer(&ctx->dhPeerPublic); // allow reuse via renegotiation
1412 ortn = SSLAllocBuffer(&ctx->dhPeerPublic, publicLen);
1413 if(ortn) {
1414 return ortn;
1415 }
1416 memmove(ctx->dhPeerPublic.data, charPtr, publicLen);
1417
1418 /* DH Key exchange, result --> premaster secret */
1419 SSLFreeBuffer(&ctx->preMasterSecret);
1420 #if USE_CDSA_CRYPTO
1421 ortn = sslDhKeyExchange(ctx, ctx->dhParamsPrime.length * 8,
1422 &ctx->preMasterSecret);
1423 #else
1424 ortn = sslDhKeyExchange(ctx);
1425 #endif
1426 dumpBuf("server peer pub", &ctx->dhPeerPublic);
1427 dumpBuf("server premaster", &ctx->preMasterSecret);
1428 return ortn;
1429 }
1430
1431 static OSStatus
1432 SSLEncodeDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1433 { OSStatus err;
1434 size_t outputLen;
1435 int head;
1436
1437 assert(ctx->protocolSide == kSSLClientSide);
1438 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
1439
1440 keyExchange->contentType = SSL_RecordTypeHandshake;
1441 keyExchange->protocolVersion = ctx->negProtocolVersion;
1442
1443 if ((err = SSLGenClientDHKeyAndExchange(ctx)) != 0)
1444 return err;
1445
1446 outputLen = ctx->dhExchangePublic.length + 2;
1447 head = SSLHandshakeHeaderSize(keyExchange);
1448 if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head)))
1449 return err;
1450
1451 uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
1452
1453 charPtr = SSLEncodeSize(charPtr, ctx->dhExchangePublic.length, 2);
1454 memcpy(charPtr, ctx->dhExchangePublic.data, ctx->dhExchangePublic.length);
1455
1456 dumpBuf("client pub key", &ctx->dhExchangePublic);
1457 dumpBuf("client premaster", &ctx->preMasterSecret);
1458
1459 return errSecSuccess;
1460 }
1461
1462 #endif /* APPLE_DH */
1463
1464 // MARK: -
1465 // MARK: ECDSA Key Exchange
1466
1467 /*
1468 * Given the server's ECDH curve params and public key, generate our
1469 * own ECDH key pair, and perform key exchange using the server's
1470 * public key and our private key. The result is the premaster
1471 * secret.
1472 *
1473 * SSLContext members valid on entry:
1474 * if keyExchangeMethod == SSL_ECDHE_ECDSA or SSL_ECDHE_RSA:
1475 * ecdhPeerPublic
1476 * ecdhPeerCurve
1477 * if keyExchangeMethod == SSL_ECDH_ECDSA or SSL_ECDH_RSA:
1478 * peerPubKey, from which we infer ecdhPeerCurve
1479 *
1480 * SSLContext members valid on successful return:
1481 * ecdhPrivate
1482 * ecdhExchangePublic
1483 * preMasterSecret
1484 */
1485 static OSStatus
1486 SSLGenClientECDHKeyAndExchange(SSLContext *ctx)
1487 {
1488 OSStatus ortn;
1489
1490 assert(ctx->protocolSide == kSSLClientSide);
1491
1492 switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
1493 case SSL_ECDHE_ECDSA:
1494 case SSL_ECDHE_RSA:
1495 /* Server sent us an ephemeral key with peer curve specified */
1496 if(ctx->ecdhPeerPublic.data == NULL) {
1497 sslErrorLog("SSLGenClientECDHKeyAndExchange: incomplete server params\n");
1498 return errSSLProtocol;
1499 }
1500 break;
1501 case SSL_ECDH_ECDSA:
1502 case SSL_ECDH_RSA:
1503 {
1504 /* No server key exchange; we have to get the curve from the key */
1505 if(ctx->peerPubKey == NULL) {
1506 sslErrorLog("SSLGenClientECDHKeyAndExchange: no peer key\n");
1507 return errSSLInternal;
1508 }
1509
1510 /* The peer curve is in the key's CSSM_X509_ALGORITHM_IDENTIFIER... */
1511 ortn = sslEcdsaPeerCurve(ctx->peerPubKey, &ctx->ecdhPeerCurve);
1512 if(ortn) {
1513 return ortn;
1514 }
1515 sslEcdsaDebug("SSLGenClientECDHKeyAndExchange: derived peerCurve %u",
1516 (unsigned)ctx->ecdhPeerCurve);
1517 break;
1518 }
1519 default:
1520 /* shouldn't be here */
1521 assert(0);
1522 return errSSLInternal;
1523 }
1524
1525 /* Generate our (ephemeral) pair, or extract it from our signing identity */
1526 if((ctx->negAuthType == SSLClientAuth_RSAFixedECDH) ||
1527 (ctx->negAuthType == SSLClientAuth_ECDSAFixedECDH)) {
1528 /*
1529 * Client auth with a fixed ECDH key in the cert. Convert private key
1530 * from SecKeyRef to CSSM format. We don't need ecdhExchangePublic
1531 * because the server gets that from our cert.
1532 */
1533 assert(ctx->signingPrivKeyRef != NULL);
1534 #if USE_CDSA_CRYPTO
1535 //assert(ctx->cspHand != 0);
1536 sslFreeKey(ctx->cspHand, &ctx->ecdhPrivate, NULL);
1537 SSLFreeBuffer(&ctx->ecdhExchangePublic);
1538 ortn = SecKeyGetCSSMKey(ctx->signingPrivKeyRef, (const CSSM_KEY **)&ctx->ecdhPrivate);
1539 if(ortn) {
1540 return ortn;
1541 }
1542 ortn = SecKeyGetCSPHandle(ctx->signingPrivKeyRef, &ctx->ecdhPrivCspHand);
1543 if(ortn) {
1544 sslErrorLog("SSLGenClientECDHKeyAndExchange: SecKeyGetCSPHandle err %d\n",
1545 (int)ortn);
1546 }
1547 #endif
1548 sslEcdsaDebug("+++ Extracted ECDH private key");
1549 }
1550 else {
1551 /* generate a new pair */
1552 ortn = sslEcdhGenerateKeyPair(ctx, ctx->ecdhPeerCurve);
1553 if(ortn) {
1554 return ortn;
1555 }
1556 #if USE_CDSA_CRYPTO
1557 sslEcdsaDebug("+++ Generated %u bit (%u byte) ECDH key pair",
1558 (unsigned)ctx->ecdhPrivate->KeyHeader.LogicalKeySizeInBits,
1559 (unsigned)((ctx->ecdhPrivate->KeyHeader.LogicalKeySizeInBits + 7) / 8));
1560 #endif
1561 }
1562
1563
1564 /* do the exchange --> premaster secret */
1565 ortn = sslEcdhKeyExchange(ctx, &ctx->preMasterSecret);
1566 if(ortn) {
1567 return ortn;
1568 }
1569 return errSecSuccess;
1570 }
1571
1572
1573 /*
1574 * Decode ECDH params and server public key.
1575 */
1576 static OSStatus
1577 SSLDecodeECDHKeyParams(
1578 SSLContext *ctx,
1579 uint8_t **charPtr, // IN/OUT
1580 size_t length)
1581 {
1582 OSStatus err = errSecSuccess;
1583
1584 sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange");
1585
1586 assert(ctx->protocolSide == kSSLClientSide);
1587 uint8_t *endCp = *charPtr + length;
1588
1589 /* Allow reuse via renegotiation */
1590 SSLFreeBuffer(&ctx->ecdhPeerPublic);
1591
1592 /*** ECParameters - just a curveType and a named curve ***/
1593
1594 /* 1-byte curveType, we only allow one type */
1595 uint8_t curveType = **charPtr;
1596 if(curveType != SSL_CurveTypeNamed) {
1597 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curveType (%u)\n", (unsigned)curveType);
1598 return errSSLProtocol;
1599 }
1600 (*charPtr)++;
1601 if(*charPtr > endCp) {
1602 return errSSLProtocol;
1603 }
1604
1605 /* two-byte curve */
1606 ctx->ecdhPeerCurve = SSLDecodeInt(*charPtr, 2);
1607 (*charPtr) += 2;
1608 if(*charPtr > endCp) {
1609 return errSSLProtocol;
1610 }
1611 switch(ctx->ecdhPeerCurve) {
1612 case SSL_Curve_secp256r1:
1613 case SSL_Curve_secp384r1:
1614 case SSL_Curve_secp521r1:
1615 break;
1616 default:
1617 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curve (%u)\n",
1618 (unsigned)ctx->ecdhPeerCurve);
1619 return errSSLProtocol;
1620 }
1621
1622 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: ecdhPeerCurve %u",
1623 (unsigned)ctx->ecdhPeerCurve);
1624
1625 /*** peer public key as an ECPoint ***/
1626
1627 /*
1628 * The spec says the the max length of an ECPoint is 255 bytes, limiting
1629 * this whole mechanism to a max modulus size of 1020 bits, which I find
1630 * hard to believe...
1631 */
1632 UInt32 len = SSLDecodeInt(*charPtr, 1);
1633 (*charPtr)++;
1634 if((*charPtr + len) > endCp) {
1635 return errSSLProtocol;
1636 }
1637 err = SSLAllocBuffer(&ctx->ecdhPeerPublic, len);
1638 if(err) {
1639 return err;
1640 }
1641 memmove(ctx->ecdhPeerPublic.data, *charPtr, len);
1642 (*charPtr) += len;
1643
1644 dumpBuf("client peer pub", &ctx->ecdhPeerPublic);
1645
1646 return err;
1647 }
1648
1649
1650 static OSStatus
1651 SSLEncodeECDHClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1652 { OSStatus err;
1653 size_t outputLen;
1654 int head;
1655
1656 assert(ctx->protocolSide == kSSLClientSide);
1657 if ((err = SSLGenClientECDHKeyAndExchange(ctx)) != 0)
1658 return err;
1659
1660 /*
1661 * Per RFC 4492 5.7, if we're doing ECDSA_fixed_ECDH or RSA_fixed_ECDH
1662 * client auth, we still send this message, but it's empty (because the
1663 * server gets our public key from our cert).
1664 */
1665 bool emptyMsg = false;
1666 switch(ctx->negAuthType) {
1667 case SSLClientAuth_RSAFixedECDH:
1668 case SSLClientAuth_ECDSAFixedECDH:
1669 emptyMsg = true;
1670 break;
1671 default:
1672 break;
1673 }
1674 if(emptyMsg) {
1675 outputLen = 0;
1676 }
1677 else {
1678 outputLen = ctx->ecdhExchangePublic.length + 1;
1679 }
1680
1681 keyExchange->contentType = SSL_RecordTypeHandshake;
1682 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
1683 keyExchange->protocolVersion = ctx->negProtocolVersion;
1684 head = SSLHandshakeHeaderSize(keyExchange);
1685 if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head)))
1686 return err;
1687
1688 uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
1689 if(emptyMsg) {
1690 sslEcdsaDebug("+++ Sending EMPTY ECDH Client Key Exchange");
1691 }
1692 else {
1693 /* just a 1-byte length here... */
1694 charPtr = SSLEncodeSize(charPtr, ctx->ecdhExchangePublic.length, 1);
1695 memcpy(charPtr, ctx->ecdhExchangePublic.data, ctx->ecdhExchangePublic.length);
1696 sslEcdsaDebug("+++ Encoded ECDH Client Key Exchange");
1697 }
1698
1699 dumpBuf("client pub key", &ctx->ecdhExchangePublic);
1700 dumpBuf("client premaster", &ctx->preMasterSecret);
1701 return errSecSuccess;
1702 }
1703
1704
1705
1706 static OSStatus
1707 SSLDecodePSKClientKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
1708 {
1709 OSStatus ortn = errSecSuccess;
1710 unsigned int identityLen;
1711
1712 assert(ctx->protocolSide == kSSLServerSide);
1713
1714 /* this message simply contains the client's PSK identity */
1715 uint8_t *charPtr = keyExchange.data;
1716 identityLen = SSLDecodeInt(charPtr, 2);
1717 charPtr += 2;
1718
1719 SSLFreeBuffer(&ctx->pskIdentity); // allow reuse via renegotiation
1720 ortn = SSLAllocBuffer(&ctx->pskIdentity, identityLen);
1721 if(ortn) {
1722 return ortn;
1723 }
1724 memmove(ctx->pskIdentity.data, charPtr, identityLen);
1725
1726 /* TODO: At this point we know the identity of the PSK client,
1727 we should break out of the handshake, so we can select the appropriate
1728 PreShared secret. As this stands, the preshared secret needs to be known
1729 before the handshake starts. */
1730
1731 size_t n=ctx->pskSharedSecret.length;
1732
1733 if(n==0) return errSSLBadConfiguration;
1734
1735 if ((ortn = SSLAllocBuffer(&ctx->preMasterSecret, 2*(n+2))) != 0)
1736 return ortn;
1737
1738 uint8_t *p=ctx->preMasterSecret.data;
1739
1740 p = SSLEncodeInt(p, n, 2);
1741 memset(p, 0, n); p+=n;
1742 p = SSLEncodeInt(p, n, 2);
1743 memcpy(p, ctx->pskSharedSecret.data, n);
1744
1745 dumpBuf("server premaster (PSK)", &ctx->preMasterSecret);
1746
1747 return ortn;
1748 }
1749
1750
1751 static OSStatus
1752 SSLEncodePSKClientKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1753 {
1754 OSStatus err;
1755 size_t outputLen;
1756 int head;
1757
1758 assert(ctx->protocolSide == kSSLClientSide);
1759
1760 outputLen = ctx->pskIdentity.length+2;
1761
1762 keyExchange->contentType = SSL_RecordTypeHandshake;
1763 assert(ctx->negProtocolVersion >= SSL_Version_3_0);
1764 keyExchange->protocolVersion = ctx->negProtocolVersion;
1765 head = SSLHandshakeHeaderSize(keyExchange);
1766 if ((err = SSLAllocBuffer(&keyExchange->contents,outputLen + head)))
1767 return err;
1768
1769 uint8_t *charPtr = SSLEncodeHandshakeHeader(ctx, keyExchange, SSL_HdskClientKeyExchange, outputLen);
1770
1771 charPtr = SSLEncodeSize(charPtr, ctx->pskIdentity.length, 2);
1772 memcpy(charPtr, ctx->pskIdentity.data, ctx->pskIdentity.length);
1773
1774
1775 /* We better have a pskSharedSecret already */
1776 size_t n=ctx->pskSharedSecret.length;
1777
1778 if(n==0) return errSSLBadConfiguration;
1779
1780 if ((err = SSLAllocBuffer(&ctx->preMasterSecret, 2*(n+2))) != 0)
1781 return err;
1782
1783 uint8_t *p=ctx->preMasterSecret.data;
1784
1785 p = SSLEncodeInt(p, n, 2);
1786 memset(p, 0, n); p+=n;
1787 p = SSLEncodeInt(p, n, 2);
1788 memcpy(p, ctx->pskSharedSecret.data, n);
1789
1790 dumpBuf("client premaster (PSK)", &ctx->preMasterSecret);
1791
1792 return errSecSuccess;
1793 }
1794
1795
1796 // MARK: -
1797 // MARK: Public Functions
1798 OSStatus
1799 SSLEncodeServerKeyExchange(SSLRecord *keyExch, SSLContext *ctx)
1800 { OSStatus err;
1801
1802 switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
1803 { case SSL_RSA:
1804 case SSL_RSA_EXPORT:
1805 #if APPLE_DH
1806 case SSL_DHE_RSA:
1807 case SSL_DHE_RSA_EXPORT:
1808 case SSL_DHE_DSS:
1809 case SSL_DHE_DSS_EXPORT:
1810 #endif /* APPLE_DH */
1811 if ((err = SSLEncodeSignedServerKeyExchange(keyExch, ctx)) != 0)
1812 return err;
1813 break;
1814 #if APPLE_DH
1815 case SSL_DH_anon:
1816 case SSL_DH_anon_EXPORT:
1817 if ((err = SSLEncodeDHanonServerKeyExchange(keyExch, ctx)) != 0)
1818 return err;
1819 break;
1820 #endif
1821 default:
1822 return errSecUnimplemented;
1823 }
1824
1825 return errSecSuccess;
1826 }
1827
1828 OSStatus
1829 SSLProcessServerKeyExchange(SSLBuffer message, SSLContext *ctx)
1830 {
1831 OSStatus err;
1832
1833 switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
1834 case SSL_RSA:
1835 case SSL_RSA_EXPORT:
1836 #if APPLE_DH
1837 case SSL_DHE_RSA:
1838 case SSL_DHE_RSA_EXPORT:
1839 case SSL_DHE_DSS:
1840 case SSL_DHE_DSS_EXPORT:
1841 #endif
1842 case SSL_ECDHE_ECDSA:
1843 case SSL_ECDHE_RSA:
1844 err = SSLDecodeSignedServerKeyExchange(message, ctx);
1845 break;
1846 #if APPLE_DH
1847 case SSL_DH_anon:
1848 case SSL_DH_anon_EXPORT:
1849 err = SSLDecodeDHanonServerKeyExchange(message, ctx);
1850 break;
1851 #endif
1852 default:
1853 err = errSecUnimplemented;
1854 break;
1855 }
1856
1857 return err;
1858 }
1859
1860 OSStatus
1861 SSLEncodeKeyExchange(SSLRecord *keyExchange, SSLContext *ctx)
1862 { OSStatus err;
1863
1864 assert(ctx->protocolSide == kSSLClientSide);
1865
1866 switch (ctx->selectedCipherSpecParams.keyExchangeMethod) {
1867 case SSL_RSA:
1868 case SSL_RSA_EXPORT:
1869 sslDebugLog("SSLEncodeKeyExchange: RSA method\n");
1870 err = SSLEncodeRSAKeyExchange(keyExchange, ctx);
1871 break;
1872 #if APPLE_DH
1873 case SSL_DHE_RSA:
1874 case SSL_DHE_RSA_EXPORT:
1875 case SSL_DHE_DSS:
1876 case SSL_DHE_DSS_EXPORT:
1877 case SSL_DH_anon:
1878 case SSL_DH_anon_EXPORT:
1879 sslDebugLog("SSLEncodeKeyExchange: DH method\n");
1880 err = SSLEncodeDHClientKeyExchange(keyExchange, ctx);
1881 break;
1882 #endif
1883 case SSL_ECDH_ECDSA:
1884 case SSL_ECDHE_ECDSA:
1885 case SSL_ECDH_RSA:
1886 case SSL_ECDHE_RSA:
1887 case SSL_ECDH_anon:
1888 sslDebugLog("SSLEncodeKeyExchange: ECDH method\n");
1889 err = SSLEncodeECDHClientKeyExchange(keyExchange, ctx);
1890 break;
1891 case TLS_PSK:
1892 err = SSLEncodePSKClientKeyExchange(keyExchange, ctx);
1893 break;
1894 default:
1895 sslErrorLog("SSLEncodeKeyExchange: unknown method (%d)\n",
1896 ctx->selectedCipherSpecParams.keyExchangeMethod);
1897 err = errSecUnimplemented;
1898 }
1899
1900 return err;
1901 }
1902
1903 OSStatus
1904 SSLProcessKeyExchange(SSLBuffer keyExchange, SSLContext *ctx)
1905 { OSStatus err;
1906
1907 switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
1908 { case SSL_RSA:
1909 case SSL_RSA_EXPORT:
1910 if ((err = SSLDecodeRSAKeyExchange(keyExchange, ctx)) != 0)
1911 return err;
1912 break;
1913 #if APPLE_DH
1914 case SSL_DH_anon:
1915 case SSL_DHE_DSS:
1916 case SSL_DHE_DSS_EXPORT:
1917 case SSL_DHE_RSA:
1918 case SSL_DHE_RSA_EXPORT:
1919 case SSL_DH_anon_EXPORT:
1920 sslDebugLog("SSLProcessKeyExchange: processing DH key exchange (%d)\n",
1921 ctx->selectedCipherSpecParams.keyExchangeMethod);
1922 if ((err = SSLDecodeDHClientKeyExchange(keyExchange, ctx)) != 0)
1923 return err;
1924 break;
1925 #endif
1926 case TLS_PSK:
1927 if ((err = SSLDecodePSKClientKeyExchange(keyExchange, ctx)) != 0)
1928 return err;
1929 break;
1930 default:
1931 sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n",
1932 ctx->selectedCipherSpecParams.keyExchangeMethod);
1933 return errSecUnimplemented;
1934 }
1935
1936 return errSecSuccess;
1937 }
1938
1939 OSStatus
1940 SSLInitPendingCiphers(SSLContext *ctx)
1941 { OSStatus err;
1942 SSLBuffer key;
1943 int keyDataLen;
1944
1945 err = errSecSuccess;
1946 key.data = 0;
1947
1948 keyDataLen = ctx->selectedCipherSpecParams.macSize +
1949 ctx->selectedCipherSpecParams.keySize +
1950 ctx->selectedCipherSpecParams.ivSize;
1951 keyDataLen *= 2; /* two of everything */
1952
1953 if ((err = SSLAllocBuffer(&key, keyDataLen)))
1954 return err;
1955 assert(ctx->sslTslCalls != NULL);
1956 if ((err = ctx->sslTslCalls->generateKeyMaterial(key, ctx)) != 0)
1957 goto fail;
1958
1959 if((err = ctx->recFuncs->initPendingCiphers(ctx->recCtx, ctx->selectedCipher, (ctx->protocolSide==kSSLServerSide), key)) != 0)
1960 goto fail;
1961
1962 ctx->writePending_ready = 1;
1963 ctx->readPending_ready = 1;
1964
1965 fail:
1966 SSLFreeBuffer(&key);
1967 return err;
1968 }