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
60static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx);
61static size_t SSLEncodedDHKeyParamsLen(SSLContext *ctx);
62static 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
72static OSStatus SSLGenServerDHParamsAndKey(SSLContext *ctx);
73static OSStatus SSLEncodeDHKeyParams(SSLContext *ctx, uint8_t *charPtr);
74#endif
75static OSStatus SSLDecodeDHKeyParams(SSLContext *ctx, uint8_t **charPtr,
76	size_t length);
77#endif
78static OSStatus SSLDecodeECDHKeyParams(SSLContext *ctx, uint8_t **charPtr,
79	size_t length);
80
81#define DH_PARAM_DUMP		0
82#if 	DH_PARAM_DUMP
83
84static 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 */
119struct 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
142static OSStatus
143SSLEncodeRSAKeyParams(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
219static OSStatus
220SSLEncodeRSAPremasterSecret(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
242static OSStatus
243SSLSignServerKeyExchangeTls12(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
322fail:
323    SSLFreeBuffer(&signedHashes);
324    SSLFreeBuffer(&hashCtx);
325    return err;
326}
327
328static OSStatus
329SSLSignServerKeyExchange(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
397fail:
398    SSLFreeBuffer(&hashCtx);
399
400    return err;
401}
402
403static
404OSStatus 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
433static OSStatus
434SSLEncodeSignedServerKeyExchange(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
568fail:
569    SSLFreeBuffer(&exchangeParams);
570    SSLFreeBuffer(&signature);
571    return err;
572}
573
574static OSStatus
575SSLVerifySignedServerKeyExchange(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
646fail:
647    SSLFreeBuffer(&signedHashes);
648    SSLFreeBuffer(&hashCtx);
649    return err;
650
651}
652
653static OSStatus
654SSLVerifySignedServerKeyExchangeTls12(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
732fail:
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 */
743static OSStatus
744SSLDecodeSignedServerKeyExchange(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	}
879fail:
880    return err;
881}
882
883static OSStatus
884SSLDecodeRSAKeyExchange(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
1002static OSStatus
1003SSLEncodeRSAKeyExchange(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 */
1095static OSStatus
1096SSLGenServerDHParamsAndKey(
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 */
1162static size_t
1163SSLEncodedDHKeyParamsLen(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 */
1176static OSStatus
1177SSLEncodeDHKeyParams(
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 */
1214static OSStatus
1215SSLDecodeDHKeyParams(
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 */
1289static OSStatus
1290SSLGenClientDHKeyAndExchange(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);
1329out:
1330#endif
1331	return ortn;
1332}
1333
1334
1335static OSStatus
1336SSLEncodeDHanonServerKeyExchange(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
1366static OSStatus
1367SSLDecodeDHanonServerKeyExchange(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
1387static OSStatus
1388SSLDecodeDHClientKeyExchange(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
1431static OSStatus
1432SSLEncodeDHClientKeyExchange(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 */
1485static OSStatus
1486SSLGenClientECDHKeyAndExchange(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 */
1576static OSStatus
1577SSLDecodeECDHKeyParams(
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
1650static OSStatus
1651SSLEncodeECDHClientKeyExchange(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
1706static OSStatus
1707SSLDecodePSKClientKeyExchange(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
1751static OSStatus
1752SSLEncodePSKClientKeyExchange(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
1798OSStatus
1799SSLEncodeServerKeyExchange(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
1828OSStatus
1829SSLProcessServerKeyExchange(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
1860OSStatus
1861SSLEncodeKeyExchange(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
1903OSStatus
1904SSLProcessKeyExchange(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
1939OSStatus
1940SSLInitPendingCiphers(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
1965fail:
1966    SSLFreeBuffer(&key);
1967    return err;
1968}
1969