2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * sslKeyExchange.c - Support for key exchange and server key exchange
29 #include "sslContext.h"
30 #include "sslHandshake.h"
31 #include "sslMemory.h"
34 #include "sslCrypto.h"
36 #include "sslDigests.h"
43 #include <corecrypto/ccdh_gp.h>
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"
52 #include <Security/SecRSAKey.h>
53 #include <AssertMacros.h>
54 #include <Security/oidsalg.h>
58 static OSStatus
SSLGenServerDHParamsAndKey(SSLContext
*ctx
);
59 static size_t SSLEncodedDHKeyParamsLen(SSLContext
*ctx
);
60 static OSStatus
SSLEncodeDHKeyParams(SSLContext
*ctx
, uint8_t *charPtr
);
63 #endif /* USE_CDSA_CRYPTO */
68 #pragma mark Forward Static Declarations
72 static OSStatus
SSLGenServerDHParamsAndKey(SSLContext
*ctx
);
73 static OSStatus
SSLEncodeDHKeyParams(SSLContext
*ctx
, uint8_t *charPtr
);
75 static OSStatus
SSLDecodeDHKeyParams(SSLContext
*ctx
, uint8_t **charPtr
,
78 static OSStatus
SSLDecodeECDHKeyParams(SSLContext
*ctx
, uint8_t **charPtr
,
81 #define DH_PARAM_DUMP 0
84 static void dumpBuf(const char *name
, SSLBuffer
*buf
)
86 printf("%s:\n", name
);
87 uint8_t *cp
= buf
->data
;
88 uint8_t *endCp
= cp
+ buf
->length
;
93 printf("%02x ", *cp
++);
106 #define dumpBuf(n, b)
107 #endif /* DH_PARAM_DUMP */
112 #pragma mark Local Diffie-Hellman Parameter Generator
115 * Process-wide server-supplied Diffie-Hellman parameters.
116 * This might be overridden by some API_supplied parameters
119 struct ServerDhParams
121 /* these two for sending over the wire */
124 /* this one for sending to the CSP at key gen time */
125 SSLBuffer paramBlock
;
129 #endif /* APPLE_DH */
132 #pragma mark RSA Key Exchange
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.
140 #define RSA_CLIENT_KEY_ADD_LENGTH 1
143 SSLEncodeRSAKeyParams(SSLBuffer
*keyParams
, SSLPubKey
*key
, SSLContext
*ctx
)
146 SSLBuffer modulus
, exponent
;
149 #ifdef USE_CDSA_CRYPTO
150 if(err
= attachToCsp(ctx
)) {
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 */
158 err
= sslGetPubKeyBits(ctx
,
163 SSLFreeBuffer(&modulus
, ctx
);
164 SSLFreeBuffer(&exponent
, ctx
);
168 if ((err
= SSLAllocBuffer(keyParams
,
169 modulus
.length
+ exponent
.length
+ 4, ctx
)) != 0) {
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
);
179 /* these were mallocd by sslGetPubKeyBits() */
180 SSLFreeBuffer(&modulus
, ctx
);
181 SSLFreeBuffer(&exponent
, ctx
);
184 CFDataRef modulus
= SecKeyCopyModulus(SECKEYREF(key
));
186 sslErrorLog("SSLEncodeRSAKeyParams: SecKeyCopyModulus failed\n");
189 CFDataRef exponent
= SecKeyCopyExponent(SECKEYREF(key
));
191 sslErrorLog("SSLEncodeRSAKeyParams: SecKeyCopyExponent failed\n");
196 CFIndex modulusLength
= CFDataGetLength(modulus
);
197 CFIndex exponentLength
= CFDataGetLength(exponent
);
198 sslDebugLog("SSLEncodeRSAKeyParams: modulus len=%ld, exponent len=%ld\n",
199 modulusLength
, exponentLength
);
201 if ((err
= SSLAllocBuffer(keyParams
,
202 modulusLength
+ exponentLength
+ 4, ctx
)) != 0) {
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
);
218 SSLEncodeRSAPremasterSecret(SSLContext
*ctx
)
219 { SSLBuffer randData
;
221 SSLProtocolVersion maxVersion
;
223 if ((err
= SSLAllocBuffer(&ctx
->preMasterSecret
,
224 SSL_RSA_PREMASTER_SECRET_SIZE
, ctx
)) != 0)
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)
238 * Generate a server key exchange message signed by our RSA or DSA private key.
242 SSLSignServerKeyExchangeTls12(SSLContext
*ctx
, SSLSignatureAndHashAlgorithm sigAlg
, SSLBuffer exchangeParams
, SSLBuffer signature
, size_t *actSigLen
)
245 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
246 uint8_t hashes
[SSL_MAX_DIGEST_LEN
];
247 SSLBuffer signedHashes
;
249 size_t dataToSignLen
;
250 const HashReference
*hashRef
;
253 signedHashes
.data
= 0;
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
;
261 switch (sigAlg
.hash
) {
262 case SSL_HashAlgorithmSHA1
:
263 hashRef
= &SSLHashSHA1
;
264 algId
.algorithm
= CSSMOID_SHA1WithRSA
;
266 case SSL_HashAlgorithmSHA256
:
267 hashRef
= &SSLHashSHA256
;
268 algId
.algorithm
= CSSMOID_SHA256WithRSA
;
270 case SSL_HashAlgorithmSHA384
:
271 hashRef
= &SSLHashSHA384
;
272 algId
.algorithm
= CSSMOID_SHA384WithRSA
;
275 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg
.hash
);
276 return errSSLProtocol
;
281 dataToSignLen
= hashRef
->digestSize
;
282 hashOut
.data
= hashes
;
283 hashOut
.length
= hashRef
->digestSize
;
285 if ((err
= ReadyHash(hashRef
, &hashCtx
, ctx
)) != 0)
287 if ((err
= hashRef
->update(&hashCtx
, &clientRandom
)) != 0)
289 if ((err
= hashRef
->update(&hashCtx
, &serverRandom
)) != 0)
291 if ((err
= hashRef
->update(&hashCtx
, &exchangeParams
)) != 0)
293 if ((err
= hashRef
->final(&hashCtx
, &hashOut
)) != 0)
296 if(sigAlg
.signature
==SSL_SignatureAlgorithmRSA
) {
297 err
= sslRsaSign(ctx
,
298 ctx
->signingPrivKeyRef
,
306 err
= sslRawSign(ctx
,
307 ctx
->signingPrivKeyRef
,
308 dataToSign
, // one or two hashes
316 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
317 "returned %d\n", (int)err
);
322 SSLFreeBuffer(&signedHashes
, ctx
);
323 SSLFreeBuffer(&hashCtx
, ctx
);
328 SSLSignServerKeyExchange(SSLContext
*ctx
, bool isRsa
, SSLBuffer exchangeParams
, SSLBuffer signature
, size_t *actSigLen
)
331 uint8_t hashes
[SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
];
332 SSLBuffer clientRandom
,serverRandom
,hashCtx
, hash
;
334 size_t dataToSignLen
;
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
;
345 /* skip this if signing with DSA */
347 dataToSignLen
= SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
;
348 hash
.data
= &hashes
[0];
349 hash
.length
= SSL_MD5_DIGEST_LEN
;
351 if ((err
= ReadyHash(&SSLHashMD5
, &hashCtx
, ctx
)) != 0)
353 if ((err
= SSLHashMD5
.update(&hashCtx
, &clientRandom
)) != 0)
355 if ((err
= SSLHashMD5
.update(&hashCtx
, &serverRandom
)) != 0)
357 if ((err
= SSLHashMD5
.update(&hashCtx
, &exchangeParams
)) != 0)
359 if ((err
= SSLHashMD5
.final(&hashCtx
, &hash
)) != 0)
361 if ((err
= SSLFreeBuffer(&hashCtx
, ctx
)) != 0)
365 /* DSA - just use the SHA1 hash */
366 dataToSign
= &hashes
[SSL_MD5_DIGEST_LEN
];
367 dataToSignLen
= SSL_SHA1_DIGEST_LEN
;
369 hash
.data
= &hashes
[SSL_MD5_DIGEST_LEN
];
370 hash
.length
= SSL_SHA1_DIGEST_LEN
;
371 if ((err
= ReadyHash(&SSLHashSHA1
, &hashCtx
, ctx
)) != 0)
373 if ((err
= SSLHashSHA1
.update(&hashCtx
, &clientRandom
)) != 0)
375 if ((err
= SSLHashSHA1
.update(&hashCtx
, &serverRandom
)) != 0)
377 if ((err
= SSLHashSHA1
.update(&hashCtx
, &exchangeParams
)) != 0)
379 if ((err
= SSLHashSHA1
.final(&hashCtx
, &hash
)) != 0)
381 if ((err
= SSLFreeBuffer(&hashCtx
, ctx
)) != 0)
385 err
= sslRawSign(ctx
,
386 ctx
->signingPrivKeyRef
,
387 dataToSign
, // one or two hashes
397 SSLFreeBuffer(&hashCtx
, ctx
);
403 OSStatus
FindSigAlg(SSLContext
*ctx
,
404 SSLSignatureAndHashAlgorithm
*alg
)
408 assert(ctx
->protocolSide
== kSSLServerSide
);
409 assert(ctx
->negProtocolVersion
>= TLS_Version_1_2
);
410 assert(!ctx
->isDTLS
);
412 if((ctx
->numClientSigAlgs
==0) ||(ctx
->clientSigAlgs
==NULL
))
413 return errSSLInternal
;
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
)
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
)) {
428 // We could not find a supported signature and hash algorithm
429 return errSSLProtocol
;
433 SSLEncodeSignedServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
442 SSLBuffer exchangeParams
;
444 assert(ctx
->protocolSide
== kSSLServerSide
);
445 assert(ctx
->signingPubKey
!= NULL
);
446 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
447 exchangeParams
.data
= 0;
451 if(ctx
->negProtocolVersion
== DTLS_Version_1_0
) {
457 /* Set up parameter block to hash ==> exchangeParams */
458 switch(ctx
->selectedCipherSpec
.keyExchangeMethod
) {
462 * Parameter block = encryption public key.
463 * If app hasn't supplied a separate encryption cert, abort.
465 if(ctx
->encryptPubKey
== NULL
) {
466 sslErrorLog("RSAServerKeyExchange: no encrypt cert\n");
467 return errSSLBadConfiguration
;
469 err
= SSLEncodeRSAKeyParams(&exchangeParams
,
470 ctx
->encryptPubKey
, ctx
);
476 case SSL_DHE_DSS_EXPORT
:
478 /* and fall through */
480 case SSL_DHE_RSA_EXPORT
:
483 * Parameter block = {prime, generator, public key}
484 * Obtain D-H parameters (if we don't have them) and a key pair.
486 err
= SSLGenServerDHParamsAndKey(ctx
);
490 size_t len
= SSLEncodedDHKeyParamsLen(ctx
);
491 err
= SSLAllocBuffer(&exchangeParams
, len
, ctx
);
495 err
= SSLEncodeDHKeyParams(ctx
, exchangeParams
.data
);
499 #endif /* APPLE_DH */
502 /* shouldn't be here */
504 return errSSLInternal
;
507 SSLSignatureAndHashAlgorithm sigAlg
;
510 /* preallocate a buffer for signing */
511 err
= sslGetMaxSigSize(ctx
->signingPrivKeyRef
, &maxSigLen
);
515 err
= SSLAllocBuffer(&signature
, maxSigLen
, ctx
);
520 outputLen
= exchangeParams
.length
+ 2;
522 if (sslVersionIsLikeTls12(ctx
))
524 err
=FindSigAlg(ctx
, &sigAlg
);
529 err
= SSLSignServerKeyExchangeTls12(ctx
, sigAlg
, exchangeParams
,
530 signature
, &actSigLen
);
532 err
= SSLSignServerKeyExchange(ctx
, isRsa
, exchangeParams
,
533 signature
, &actSigLen
);
539 assert(actSigLen
<= maxSigLen
);
541 outputLen
+= actSigLen
;
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)
549 charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExch
, SSL_HdskServerKeyExchange
, outputLen
);
551 memcpy(charPtr
, exchangeParams
.data
, exchangeParams
.length
);
552 charPtr
+= exchangeParams
.length
;
554 if (sslVersionIsLikeTls12(ctx
))
556 *charPtr
++=sigAlg
.hash
;
557 *charPtr
++=sigAlg
.signature
;
560 charPtr
= SSLEncodeInt(charPtr
, actSigLen
, 2);
561 memcpy(charPtr
, signature
.data
, actSigLen
);
562 assert((charPtr
+ actSigLen
) ==
563 (keyExch
->contents
.data
+ keyExch
->contents
.length
));
568 SSLFreeBuffer(&exchangeParams
, ctx
);
569 SSLFreeBuffer(&signature
, ctx
);
574 SSLVerifySignedServerKeyExchange(SSLContext
*ctx
, bool isRsa
, SSLBuffer signedParams
,
575 uint8_t *signature
, UInt16 signatureLen
)
578 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
579 uint8_t hashes
[SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
];
580 SSLBuffer signedHashes
;
582 size_t dataToSignLen
;
584 signedHashes
.data
= 0;
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
;
594 /* skip this if signing with DSA */
596 dataToSignLen
= SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
;
597 hashOut
.data
= hashes
;
598 hashOut
.length
= SSL_MD5_DIGEST_LEN
;
600 if ((err
= ReadyHash(&SSLHashMD5
, &hashCtx
, ctx
)) != 0)
602 if ((err
= SSLHashMD5
.update(&hashCtx
, &clientRandom
)) != 0)
604 if ((err
= SSLHashMD5
.update(&hashCtx
, &serverRandom
)) != 0)
606 if ((err
= SSLHashMD5
.update(&hashCtx
, &signedParams
)) != 0)
608 if ((err
= SSLHashMD5
.final(&hashCtx
, &hashOut
)) != 0)
612 /* DSA, ECDSA - just use the SHA1 hash */
613 dataToSign
= &hashes
[SSL_MD5_DIGEST_LEN
];
614 dataToSignLen
= SSL_SHA1_DIGEST_LEN
;
617 hashOut
.data
= hashes
+ SSL_MD5_DIGEST_LEN
;
618 hashOut
.length
= SSL_SHA1_DIGEST_LEN
;
619 if ((err
= SSLFreeBuffer(&hashCtx
, ctx
)) != 0)
622 if ((err
= ReadyHash(&SSLHashSHA1
, &hashCtx
, ctx
)) != 0)
624 if ((err
= SSLHashSHA1
.update(&hashCtx
, &clientRandom
)) != 0)
626 if ((err
= SSLHashSHA1
.update(&hashCtx
, &serverRandom
)) != 0)
628 if ((err
= SSLHashSHA1
.update(&hashCtx
, &signedParams
)) != 0)
630 if ((err
= SSLHashSHA1
.final(&hashCtx
, &hashOut
)) != 0)
633 err
= sslRawVerify(ctx
,
635 dataToSign
, /* plaintext */
636 dataToSignLen
, /* plaintext length */
640 sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
641 "returned %d\n", (int)err
);
646 SSLFreeBuffer(&signedHashes
, ctx
);
647 SSLFreeBuffer(&hashCtx
, ctx
);
653 SSLVerifySignedServerKeyExchangeTls12(SSLContext
*ctx
, SSLSignatureAndHashAlgorithm sigAlg
, SSLBuffer signedParams
,
654 uint8_t *signature
, UInt16 signatureLen
)
657 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
658 uint8_t hashes
[SSL_MAX_DIGEST_LEN
];
659 SSLBuffer signedHashes
;
661 size_t dataToSignLen
;
662 const HashReference
*hashRef
;
665 signedHashes
.data
= 0;
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
;
673 switch (sigAlg
.hash
) {
674 case SSL_HashAlgorithmSHA1
:
675 hashRef
= &SSLHashSHA1
;
676 algId
.algorithm
= CSSMOID_SHA1WithRSA
;
678 case SSL_HashAlgorithmSHA256
:
679 hashRef
= &SSLHashSHA256
;
680 algId
.algorithm
= CSSMOID_SHA256WithRSA
;
682 case SSL_HashAlgorithmSHA384
:
683 hashRef
= &SSLHashSHA384
;
684 algId
.algorithm
= CSSMOID_SHA384WithRSA
;
687 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg
.hash
);
688 return errSSLProtocol
;
693 dataToSignLen
= hashRef
->digestSize
;
694 hashOut
.data
= hashes
;
695 hashOut
.length
= hashRef
->digestSize
;
697 if ((err
= ReadyHash(hashRef
, &hashCtx
, ctx
)) != 0)
699 if ((err
= hashRef
->update(&hashCtx
, &clientRandom
)) != 0)
701 if ((err
= hashRef
->update(&hashCtx
, &serverRandom
)) != 0)
703 if ((err
= hashRef
->update(&hashCtx
, &signedParams
)) != 0)
705 if ((err
= hashRef
->final(&hashCtx
, &hashOut
)) != 0)
708 if(sigAlg
.signature
==SSL_SignatureAlgorithmRSA
) {
709 err
= sslRsaVerify(ctx
,
717 err
= sslRawVerify(ctx
,
719 dataToSign
, /* plaintext */
720 dataToSignLen
, /* plaintext length */
726 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
727 "returned %d\n", (int)err
);
732 SSLFreeBuffer(&signedHashes
, ctx
);
733 SSLFreeBuffer(&hashCtx
, ctx
);
739 * Decode and verify a server key exchange message signed by server's
743 SSLDecodeSignedServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
746 UInt16 modulusLen
= 0, exponentLen
= 0, signatureLen
;
747 uint8_t *modulus
= NULL
, *exponent
= NULL
, *signature
;
750 assert(ctx
->protocolSide
== kSSLClientSide
);
752 if (message
.length
< 2) {
753 sslErrorLog("SSLDecodeSignedServerKeyExchange: msg len error 1\n");
754 return errSSLProtocol
;
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
) {
763 modulusLen
= SSLDecodeInt(charPtr
, 2);
765 if((charPtr
+ modulusLen
) > endCp
) {
766 sslErrorLog("signedServerKeyExchange: msg len error 2\n");
767 return errSSLProtocol
;
770 charPtr
+= modulusLen
;
772 exponentLen
= SSLDecodeInt(charPtr
, 2);
774 if((charPtr
+ exponentLen
) > endCp
) {
775 sslErrorLog("signedServerKeyExchange: msg len error 3\n");
776 return errSSLProtocol
;
779 charPtr
+= exponentLen
;
783 case SSL_DHE_DSS_EXPORT
:
785 /* and fall through */
787 case SSL_DHE_RSA_EXPORT
:
788 err
= SSLDecodeDHKeyParams(ctx
, &charPtr
, message
.length
);
793 #endif /* APPLE_DH */
795 case SSL_ECDHE_ECDSA
:
797 /* and fall through */
799 err
= SSLDecodeECDHKeyParams(ctx
, &charPtr
, message
.length
);
806 return errSSLInternal
;
809 /* this is what's hashed */
810 SSLBuffer signedParams
;
811 signedParams
.data
= message
.data
;
812 signedParams
.length
= charPtr
- message
.data
;
814 SSLSignatureAndHashAlgorithm sigAlg
;
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
;
822 sigAlg
.hash
= *charPtr
++;
823 sigAlg
.signature
= *charPtr
++;
826 signatureLen
= SSLDecodeInt(charPtr
, 2);
828 if((charPtr
+ signatureLen
) != endCp
) {
829 sslErrorLog("signedServerKeyExchange: msg len error 4\n");
830 return errSSLProtocol
;
834 if (sslVersionIsLikeTls12(ctx
))
836 err
= SSLVerifySignedServerKeyExchangeTls12(ctx
, sigAlg
, signedParams
,
837 signature
, signatureLen
);
839 err
= SSLVerifySignedServerKeyExchange(ctx
, isRsa
, signedParams
,
840 signature
, signatureLen
);
846 /* Signature matches; now replace server key with new key (RSA only) */
847 switch(ctx
->selectedCipherSpec
.keyExchangeMethod
) {
854 /* first free existing peerKey */
855 sslFreePubKey(&ctx
->peerPubKey
); /* no KCItem */
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
,
869 case SSL_DHE_RSA_EXPORT
:
871 case SSL_DHE_DSS_EXPORT
:
872 case SSL_ECDHE_ECDSA
:
874 break; /* handled above */
883 SSLDecodeRSAKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
885 size_t outputLen
, localKeyModulusLen
;
886 SSLProtocolVersion version
;
887 Boolean useEncryptKey
= false;
889 SSLPrivKey
*keyRef
= NULL
;
891 assert(ctx
->protocolSide
== kSSLServerSide
);
893 #if SSL_SERVER_KEYEXCH_HACK
895 * the way we work with Netscape.
896 * FIXME - maybe we should *require* an encryptPrivKey in this
899 if((ctx
->selectedCipherSpec
.keyExchangeMethod
== SSL_RSA_EXPORT
) &&
900 (ctx
->encryptPrivKey
!= NULL
)) {
901 useEncryptKey
= true;
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;
909 #endif /* SSL_SERVER_KEYEXCH_HACK */
911 keyRef
= ctx
->encryptPrivKeyRef
;
912 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
915 keyRef
= ctx
->signingPrivKeyRef
;
916 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
919 localKeyModulusLen
= sslPrivKeyLengthInBytes(keyRef
);
920 if (localKeyModulusLen
== 0) {
921 sslErrorLog("SSLDecodeRSAKeyExchange: private key modulus is 0\n");
926 * We have to tolerate incoming key exchange msgs with and without the
927 * two-byte "encrypted length" field.
929 if (keyExchange
.length
== localKeyModulusLen
) {
930 /* no length encoded */
931 src
= keyExchange
.data
;
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;
939 sslErrorLog("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n",
940 (unsigned)localKeyModulusLen
, (unsigned)keyExchange
.length
);
941 return errSSLProtocol
;
943 err
= SSLAllocBuffer(&ctx
->preMasterSecret
, SSL_RSA_PREMASTER_SECRET_SIZE
, ctx
);
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
961 * See http://eprint.iacr.org/2003/052/ for more info.
963 err
= sslRsaDecrypt(ctx
,
971 localKeyModulusLen
, // ciphertext len
972 ctx
->preMasterSecret
.data
,
973 SSL_RSA_PREMASTER_SECRET_SIZE
, // plaintext buf available
977 /* possible Bleichenbacher attack */
978 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail");
980 else if(outputLen
!= SSL_RSA_PREMASTER_SECRET_SIZE
) {
981 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: premaster secret size error");
982 err
= errSSLProtocol
; // not passed back to caller
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.
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
;
1001 * Obfuscate failures for defense against Bleichenbacher and
1002 * Klima-Pokorny-Rosa attacks.
1004 SSLEncodeInt(ctx
->preMasterSecret
.data
, ctx
->negProtocolVersion
, 2);
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
);
1012 /* in any case, save premaster secret (good or bogus) and proceed */
1017 SSLEncodeRSAKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1019 size_t outputLen
, peerKeyModulusLen
;
1022 bool encodeLen
= false;
1027 assert(ctx
->protocolSide
== kSSLClientSide
);
1028 if ((err
= SSLEncodeRSAPremasterSecret(ctx
)) != 0)
1031 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1032 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1033 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
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? */
1041 sslDebugLog("SSLEncodeRSAKeyExchange: peer key modulus length = %lu\n", peerKeyModulusLen
);
1043 msglen
= peerKeyModulusLen
;
1044 #if RSA_CLIENT_KEY_ADD_LENGTH
1045 if(ctx
->negProtocolVersion
>= TLS_Version_1_0
) {
1050 head
= SSLHandshakeHeaderSize(keyExchange
);
1051 bufLen
= msglen
+ head
;
1052 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,
1057 dst
= keyExchange
->contents
.data
+ head
;
1062 /* FIXME: can this line be removed? */
1063 p
= keyExchange
->contents
.data
;
1065 p
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, msglen
);
1068 /* the length of the encrypted pre_master_secret */
1069 SSLEncodeSize(keyExchange
->contents
.data
+ head
,
1070 peerKeyModulusLen
, 2);
1072 err
= sslRsaEncrypt(ctx
,
1079 ctx
->preMasterSecret
.data
,
1080 SSL_RSA_PREMASTER_SECRET_SIZE
,
1085 sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", err
);
1089 assert(outputLen
== (encodeLen
? msglen
- 2 : msglen
));
1098 #pragma mark Diffie-Hellman Key Exchange
1101 * Diffie-Hellman setup, server side. On successful return, the
1102 * following SSLContext members are valid:
1110 SSLGenServerDHParamsAndKey(
1114 assert(ctx
->protocolSide
== kSSLServerSide
);
1118 * Obtain D-H parameters if we don't have them.
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
);
1128 ccn_write_uint(n
, ccdh_gp_prime(gp
), s
, p
);
1129 ccn_write_uint(n
, ccdh_gp_g(gp
), s
, g
);
1131 const SSLBuffer prime
= {
1135 const SSLBuffer generator
= {
1140 ortn
=sslEncodeDhParams(&ctx
->dhParamsEncoded
, /* data mallocd and RETURNED PKCS-3 encoded */
1141 &prime
, /* Wire format */
1142 &generator
); /* Wire format */
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
));
1154 ortn
= sslDhGenerateKeyPair(ctx
,
1155 &ctx
->dhParamsEncoded
,
1156 ctx
->dhParamsPrime
.length
* 8,
1157 &pubKey
, ctx
->dhPrivate
);
1161 CSSM_TO_SSLBUF(&pubKey
.KeyData
, &ctx
->dhExchangePublic
);
1163 if (!ctx
->secDHContext
) {
1164 ortn
= sslDhCreateKey(ctx
);
1168 return sslDhGenerateKeyPair(ctx
);
1174 * size of DH param and public key, in wire format
1177 SSLEncodedDHKeyParamsLen(SSLContext
*ctx
)
1180 SSLBuffer generator
;
1182 sslDecodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1184 return (2+prime
.length
+2+generator
.length
+2+ctx
->dhExchangePublic
.length
);
1188 * Encode DH params and public key, in wire format, in caller-supplied buffer.
1191 SSLEncodeDHKeyParams(
1195 assert(ctx
->protocolSide
== kSSLServerSide
);
1196 assert(ctx
->dhParamsEncoded
.data
!= NULL
);
1197 assert(ctx
->dhExchangePublic
.data
!= NULL
);
1200 SSLBuffer generator
;
1202 sslDecodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1204 charPtr
= SSLEncodeInt(charPtr
, prime
.length
, 2);
1205 memcpy(charPtr
, prime
.data
, prime
.length
);
1206 charPtr
+= prime
.length
;
1208 charPtr
= SSLEncodeInt(charPtr
, generator
.length
, 2);
1209 memcpy(charPtr
, generator
.data
,
1211 charPtr
+= generator
.length
;
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
);
1218 dumpBuf("server prime", &prime
);
1219 dumpBuf("server generator", &generator
);
1220 dumpBuf("server pub key", &ctx
->dhExchangePublic
);
1226 * Decode DH params and server public key.
1229 SSLDecodeDHKeyParams(
1231 uint8_t **charPtr
, // IN/OUT
1234 OSStatus err
= noErr
;
1236 SSLBuffer generator
;
1238 assert(ctx
->protocolSide
== kSSLClientSide
);
1239 uint8_t *endCp
= *charPtr
+ length
;
1241 /* Allow reuse via renegotiation */
1242 SSLFreeBuffer(&ctx
->dhPeerPublic
, ctx
);
1244 /* Prime, with a two-byte length */
1245 UInt32 len
= SSLDecodeInt(*charPtr
, 2);
1247 if((*charPtr
+ len
) > endCp
) {
1248 return errSSLProtocol
;
1251 prime
.data
= *charPtr
;
1256 /* Generator, with a two-byte length */
1257 len
= SSLDecodeInt(*charPtr
, 2);
1259 if((*charPtr
+ len
) > endCp
) {
1260 return errSSLProtocol
;
1263 generator
.data
= *charPtr
;
1264 generator
.length
= len
;
1268 sslEncodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1270 /* peer public key, with a two-byte length */
1271 len
= SSLDecodeInt(*charPtr
, 2);
1273 err
= SSLAllocBuffer(&ctx
->dhPeerPublic
, len
, ctx
);
1277 memmove(ctx
->dhPeerPublic
.data
, *charPtr
, len
);
1280 dumpBuf("client peer pub", &ctx
->dhPeerPublic
);
1281 dumpBuf("client prime", &ctx
->dhParamsPrime
);
1282 dumpBuf("client generator", &ctx
->dhParamsGenerator
);
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
1293 * SSLContext members valid on entry:
1298 * SSLContext members valid on successful return:
1304 SSLGenClientDHKeyAndExchange(SSLContext
*ctx
)
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
;
1317 /* generate two keys */
1319 ctx
->dhPrivate
= (CSSM_KEY
*)sslMalloc(sizeof(CSSM_KEY
));
1320 ortn
= sslDhGenKeyPairClient(ctx
,
1321 &ctx
->dhParamsPrime
,
1322 &ctx
->dhParamsGenerator
,
1323 &pubKey
, ctx
->dhPrivate
);
1325 sslFree(ctx
->dhPrivate
);
1326 ctx
->dhPrivate
= NULL
;
1330 /* do the exchange, size of prime */
1331 ortn
= sslDhKeyExchange(ctx
, ctx
->dhParamsPrime
.length
* 8,
1332 &ctx
->preMasterSecret
);
1336 CSSM_TO_SSLBUF(&pubKey
.KeyData
, &ctx
->dhExchangePublic
);
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
);
1350 SSLEncodeDHanonServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
1352 OSStatus ortn
= noErr
;
1355 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1356 assert(ctx
->protocolSide
== kSSLServerSide
);
1359 * Obtain D-H parameters (if we don't have them) and a key pair.
1361 ortn
= SSLGenServerDHParamsAndKey(ctx
);
1366 size_t length
= SSLEncodedDHKeyParamsLen(ctx
);
1368 keyExch
->protocolVersion
= ctx
->negProtocolVersion
;
1369 keyExch
->contentType
= SSL_RecordTypeHandshake
;
1370 head
= SSLHandshakeHeaderSize(keyExch
);
1371 if ((ortn
= SSLAllocBuffer(&keyExch
->contents
, length
+head
, ctx
)) != 0)
1374 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExch
, SSL_HdskServerKeyExchange
, length
);
1376 /* encode prime, generator, our public key */
1377 return SSLEncodeDHKeyParams(ctx
, charPtr
);
1381 SSLDecodeDHanonServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
1383 OSStatus err
= noErr
;
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
;
1391 uint8_t *charPtr
= message
.data
;
1392 err
= SSLDecodeDHKeyParams(ctx
, &charPtr
, message
.length
);
1394 if((message
.data
+ message
.length
) != charPtr
) {
1395 err
= errSSLProtocol
;
1402 SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1404 OSStatus ortn
= noErr
;
1405 unsigned int publicLen
;
1407 assert(ctx
->protocolSide
== kSSLServerSide
);
1408 if(ctx
->dhParamsEncoded
.data
== NULL
) {
1409 /* should never happen */
1411 return errSSLInternal
;
1414 /* this message simply contains the client's public DH key */
1415 uint8_t *charPtr
= keyExchange
.data
;
1416 publicLen
= SSLDecodeInt(charPtr
, 2);
1418 /* TODO : Check the len here ? Will fail in sslDhKeyExchange anyway */
1420 if((keyExchange.length != publicLen + 2) ||
1421 (publicLen > ctx->dhParamsPrime.length)) {
1422 return errSSLProtocol;
1425 SSLFreeBuffer(&ctx
->dhPeerPublic
, ctx
); // allow reuse via renegotiation
1426 ortn
= SSLAllocBuffer(&ctx
->dhPeerPublic
, publicLen
, ctx
);
1430 memmove(ctx
->dhPeerPublic
.data
, charPtr
, publicLen
);
1432 /* DH Key exchange, result --> premaster secret */
1433 SSLFreeBuffer(&ctx
->preMasterSecret
, ctx
);
1435 ortn
= sslDhKeyExchange(ctx
, ctx
->dhParamsPrime
.length
* 8,
1436 &ctx
->preMasterSecret
);
1438 ortn
= sslDhKeyExchange(ctx
);
1440 dumpBuf("server peer pub", &ctx
->dhPeerPublic
);
1441 dumpBuf("server premaster", &ctx
->preMasterSecret
);
1446 SSLEncodeDHClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1451 assert(ctx
->protocolSide
== kSSLClientSide
);
1452 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1454 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1455 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
1457 if ((err
= SSLGenClientDHKeyAndExchange(ctx
)) != 0)
1460 outputLen
= ctx
->dhExchangePublic
.length
+ 2;
1461 head
= SSLHandshakeHeaderSize(keyExchange
);
1462 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,outputLen
+ head
,ctx
)) != 0)
1465 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1467 charPtr
= SSLEncodeSize(charPtr
, ctx
->dhExchangePublic
.length
, 2);
1468 memcpy(charPtr
, ctx
->dhExchangePublic
.data
, ctx
->dhExchangePublic
.length
);
1470 dumpBuf("client pub key", &ctx
->dhExchangePublic
);
1471 dumpBuf("client premaster", &ctx
->preMasterSecret
);
1476 #endif /* APPLE_DH */
1479 #pragma mark ECDSA Key Exchange
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
1487 * SSLContext members valid on entry:
1488 * if keyExchangeMethod == SSL_ECDHE_ECDSA or SSL_ECDHE_RSA:
1491 * if keyExchangeMethod == SSL_ECDH_ECDSA or SSL_ECDH_RSA:
1492 * peerPubKey, from which we infer ecdhPeerCurve
1494 * SSLContext members valid on successful return:
1496 * ecdhExchangePublic
1500 SSLGenClientECDHKeyAndExchange(SSLContext
*ctx
)
1504 assert(ctx
->protocolSide
== kSSLClientSide
);
1506 switch(ctx
->selectedCipherSpec
.keyExchangeMethod
) {
1507 case SSL_ECDHE_ECDSA
:
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
;
1515 case SSL_ECDH_ECDSA
:
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
;
1524 /* The peer curve is in the key's CSSM_X509_ALGORITHM_IDENTIFIER... */
1525 ortn
= sslEcdsaPeerCurve(ctx
->peerPubKey
, &ctx
->ecdhPeerCurve
);
1529 sslEcdsaDebug("SSLGenClientECDHKeyAndExchange: derived peerCurve %u",
1530 (unsigned)ctx
->ecdhPeerCurve
);
1534 /* shouldn't be here */
1536 return errSSLInternal
;
1539 /* Generate our (ephemeral) pair, or extract it from our signing identity */
1540 if((ctx
->negAuthType
== SSLClientAuth_RSAFixedECDH
) ||
1541 (ctx
->negAuthType
== SSLClientAuth_ECDSAFixedECDH
)) {
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.
1547 assert(ctx
->signingPrivKeyRef
!= NULL
);
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
);
1556 ortn
= SecKeyGetCSPHandle(ctx
->signingPrivKeyRef
, &ctx
->ecdhPrivCspHand
);
1558 sslErrorLog("SSLGenClientECDHKeyAndExchange: SecKeyGetCSPHandle err %d\n",
1562 sslEcdsaDebug("+++ Extracted ECDH private key");
1565 /* generate a new pair */
1566 ortn
= sslEcdhGenerateKeyPair(ctx
, ctx
->ecdhPeerCurve
);
1571 sslEcdsaDebug("+++ Generated %u bit (%u byte) ECDH key pair",
1572 (unsigned)ctx
->ecdhPrivate
->KeyHeader
.LogicalKeySizeInBits
,
1573 (unsigned)((ctx
->ecdhPrivate
->KeyHeader
.LogicalKeySizeInBits
+ 7) / 8));
1578 /* do the exchange --> premaster secret */
1579 ortn
= sslEcdhKeyExchange(ctx
, &ctx
->preMasterSecret
);
1588 * Decode ECDH params and server public key.
1591 SSLDecodeECDHKeyParams(
1593 uint8_t **charPtr
, // IN/OUT
1596 OSStatus err
= noErr
;
1598 sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange");
1600 assert(ctx
->protocolSide
== kSSLClientSide
);
1601 uint8_t *endCp
= *charPtr
+ length
;
1603 /* Allow reuse via renegotiation */
1604 SSLFreeBuffer(&ctx
->ecdhPeerPublic
, ctx
);
1606 /*** ECParameters - just a curveType and a named curve ***/
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
;
1615 if(*charPtr
> endCp
) {
1616 return errSSLProtocol
;
1619 /* two-byte curve */
1620 ctx
->ecdhPeerCurve
= SSLDecodeInt(*charPtr
, 2);
1622 if(*charPtr
> endCp
) {
1623 return errSSLProtocol
;
1625 switch(ctx
->ecdhPeerCurve
) {
1626 case SSL_Curve_secp256r1
:
1627 case SSL_Curve_secp384r1
:
1628 case SSL_Curve_secp521r1
:
1631 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curve (%u)\n",
1632 (unsigned)ctx
->ecdhPeerCurve
);
1633 return errSSLProtocol
;
1636 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: ecdhPeerCurve %u",
1637 (unsigned)ctx
->ecdhPeerCurve
);
1639 /*** peer public key as an ECPoint ***/
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...
1646 UInt32 len
= SSLDecodeInt(*charPtr
, 1);
1648 if((*charPtr
+ len
) > endCp
) {
1649 return errSSLProtocol
;
1651 err
= SSLAllocBuffer(&ctx
->ecdhPeerPublic
, len
, ctx
);
1655 memmove(ctx
->ecdhPeerPublic
.data
, *charPtr
, len
);
1658 dumpBuf("client peer pub", &ctx
->ecdhPeerPublic
);
1665 SSLEncodeECDHClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1670 assert(ctx
->protocolSide
== kSSLClientSide
);
1671 if ((err
= SSLGenClientECDHKeyAndExchange(ctx
)) != 0)
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).
1679 bool emptyMsg
= false;
1680 switch(ctx
->negAuthType
) {
1681 case SSLClientAuth_RSAFixedECDH
:
1682 case SSLClientAuth_ECDSAFixedECDH
:
1692 outputLen
= ctx
->ecdhExchangePublic
.length
+ 1;
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)
1702 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1704 sslEcdsaDebug("+++ Sending EMPTY ECDH Client Key Exchange");
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");
1713 dumpBuf("client pub key", &ctx
->ecdhExchangePublic
);
1714 dumpBuf("client premaster", &ctx
->preMasterSecret
);
1719 #pragma mark Public Functions
1721 SSLEncodeServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
1724 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
)
1726 case SSL_RSA_EXPORT
:
1729 case SSL_DHE_RSA_EXPORT
:
1731 case SSL_DHE_DSS_EXPORT
:
1732 #endif /* APPLE_DH */
1733 if ((err
= SSLEncodeSignedServerKeyExchange(keyExch
, ctx
)) != 0)
1738 case SSL_DH_anon_EXPORT
:
1739 if ((err
= SSLEncodeDHanonServerKeyExchange(keyExch
, ctx
)) != 0)
1751 SSLProcessServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
1755 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
) {
1757 case SSL_RSA_EXPORT
:
1760 case SSL_DHE_RSA_EXPORT
:
1762 case SSL_DHE_DSS_EXPORT
:
1764 case SSL_ECDHE_ECDSA
:
1766 err
= SSLDecodeSignedServerKeyExchange(message
, ctx
);
1770 case SSL_DH_anon_EXPORT
:
1771 err
= SSLDecodeDHanonServerKeyExchange(message
, ctx
);
1783 SSLEncodeKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1786 assert(ctx
->protocolSide
== kSSLClientSide
);
1788 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
) {
1790 case SSL_RSA_EXPORT
:
1791 sslDebugLog("SSLEncodeKeyExchange: RSA method\n");
1792 err
= SSLEncodeRSAKeyExchange(keyExchange
, ctx
);
1796 case SSL_DHE_RSA_EXPORT
:
1798 case SSL_DHE_DSS_EXPORT
:
1800 case SSL_DH_anon_EXPORT
:
1801 sslDebugLog("SSLEncodeKeyExchange: DH method\n");
1802 err
= SSLEncodeDHClientKeyExchange(keyExchange
, ctx
);
1805 case SSL_ECDH_ECDSA
:
1806 case SSL_ECDHE_ECDSA
:
1810 sslDebugLog("SSLEncodeKeyExchange: ECDH method\n");
1811 err
= SSLEncodeECDHClientKeyExchange(keyExchange
, ctx
);
1814 sslDebugLog("SSLEncodeKeyExchange: unknown method (%d)\n",
1815 ctx
->selectedCipherSpec
.keyExchangeMethod
);
1823 SSLProcessKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1826 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
)
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)
1837 case SSL_DHE_DSS_EXPORT
:
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)
1848 sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n",
1849 ctx
->selectedCipherSpec
.keyExchangeMethod
);
1857 SSLInitPendingCiphers(SSLContext
*ctx
)
1860 uint8_t *keyDataProgress
, *keyPtr
, *ivPtr
;
1862 CipherContext
*serverPending
, *clientPending
;
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
;
1871 if(ctx
->negProtocolVersion
== DTLS_Version_1_0
)
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);
1876 ctx
->writePending
.sequenceNum
.high
=0;
1877 ctx
->readPending
.sequenceNum
.high
=0;
1879 ctx
->readPending
.sequenceNum
.low
= 0;
1880 ctx
->writePending
.sequenceNum
.low
= 0;
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 */
1888 if ((err
= SSLAllocBuffer(&key
, keyDataLen
, ctx
)) != 0)
1890 assert(ctx
->sslTslCalls
!= NULL
);
1891 if ((err
= ctx
->sslTslCalls
->generateKeyMaterial(key
, ctx
)) != 0)
1894 if (ctx
->protocolSide
== kSSLServerSide
)
1895 { serverPending
= &ctx
->writePending
;
1896 clientPending
= &ctx
->readPending
;
1899 { serverPending
= &ctx
->readPending
;
1900 clientPending
= &ctx
->writePending
;
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
;
1911 /* init the reusable-per-record MAC contexts */
1912 err
= ctx
->sslTslCalls
->initMac(clientPending
, ctx
);
1916 err
= ctx
->sslTslCalls
->initMac(serverPending
, ctx
);
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
;
1933 ivPtr
= keyDataProgress
+ ctx
->selectedCipherSpec
.cipher
->secretKeySize
;
1936 if ((err
= ctx
->selectedCipherSpec
.cipher
->initialize(keyPtr
, ivPtr
,
1937 clientPending
, ctx
)) != 0)
1939 keyPtr
= keyDataProgress
;
1940 keyDataProgress
+= ctx
->selectedCipherSpec
.cipher
->secretKeySize
;
1941 /* Skip client write IV to get to server write IV */
1948 ivPtr
= keyDataProgress
+ ctx
->selectedCipherSpec
.cipher
->ivSize
;
1951 if ((err
= ctx
->selectedCipherSpec
.cipher
->initialize(keyPtr
, ivPtr
,
1952 serverPending
, ctx
)) != 0)
1956 uint8_t clientExportKey
[16], serverExportKey
[16],
1957 clientExportIV
[16], serverExportIV
[16];
1958 SSLBuffer clientWrite
, serverWrite
;
1959 SSLBuffer finalClientWrite
, finalServerWrite
;
1960 SSLBuffer finalClientIV
, finalServerIV
;
1962 assert(ctx
->selectedCipherSpec
.cipher
->keySize
<= 16);
1963 assert(ctx
->selectedCipherSpec
.cipher
->ivSize
<= 16);
1965 /* Inputs to generateExportKeyAndIv are clientRandom, serverRandom,
1966 * clientWriteKey, serverWriteKey. The first two are already present
1968 * Outputs are a key and IV for each of {server, client}.
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
;
1984 assert(ctx
->sslTslCalls
!= NULL
);
1985 err
= ctx
->sslTslCalls
->generateExportKeyAndIv(ctx
, clientWrite
, serverWrite
,
1986 finalClientWrite
, finalServerWrite
, finalClientIV
, finalServerIV
);
1990 if ((err
= ctx
->selectedCipherSpec
.cipher
->initialize(clientExportKey
,
1991 clientExportIV
, clientPending
, ctx
)) != 0)
1993 if ((err
= ctx
->selectedCipherSpec
.cipher
->initialize(serverExportKey
,
1994 serverExportIV
, serverPending
, ctx
)) != 0)
1998 /* Ciphers are ready for use */
1999 ctx
->writePending
.ready
= 1;
2000 ctx
->readPending
.ready
= 1;
2002 /* Ciphers get swapped by sending or receiving a change cipher spec message */
2006 SSLFreeBuffer(&key
, ctx
);