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