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"
42 #include <utilities/SecCFRelease.h>
43 #include <corecrypto/ccdh_gp.h>
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"
52 #include <AssertMacros.h>
53 #include <Security/oidsalg.h>
57 #include <Security/SecRSAKey.h>
60 static OSStatus
SSLGenServerDHParamsAndKey(SSLContext
*ctx
);
61 static size_t SSLEncodedDHKeyParamsLen(SSLContext
*ctx
);
62 static OSStatus
SSLEncodeDHKeyParams(SSLContext
*ctx
, uint8_t *charPtr
);
65 #endif /* USE_CDSA_CRYPTO */
68 // 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 // 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 // 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
);
164 SSLFreeBuffer(&exponent
);
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
);
181 SSLFreeBuffer(&exponent
);
182 return errSecSuccess
;
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)) != 0) {
203 CFReleaseSafe(exponent
);
204 CFReleaseSafe(modulus
);
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
);
215 return errSecSuccess
;
220 SSLEncodeRSAPremasterSecret(SSLContext
*ctx
)
221 { SSLBuffer randData
;
224 if ((err
= SSLAllocBuffer(&ctx
->preMasterSecret
,
225 SSL_RSA_PREMASTER_SECRET_SIZE
)) != 0)
228 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
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)
235 return errSecSuccess
;
239 * Generate a server key exchange message signed by our RSA or DSA private key.
243 SSLSignServerKeyExchangeTls12(SSLContext
*ctx
, SSLSignatureAndHashAlgorithm sigAlg
, SSLBuffer exchangeParams
, SSLBuffer signature
, size_t *actSigLen
)
246 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
247 uint8_t hashes
[SSL_MAX_DIGEST_LEN
];
248 SSLBuffer signedHashes
;
250 size_t dataToSignLen
;
251 const HashReference
*hashRef
;
254 signedHashes
.data
= 0;
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
;
262 switch (sigAlg
.hash
) {
263 case SSL_HashAlgorithmSHA1
:
264 hashRef
= &SSLHashSHA1
;
265 algId
.algorithm
= CSSMOID_SHA1WithRSA
;
267 case SSL_HashAlgorithmSHA256
:
268 hashRef
= &SSLHashSHA256
;
269 algId
.algorithm
= CSSMOID_SHA256WithRSA
;
271 case SSL_HashAlgorithmSHA384
:
272 hashRef
= &SSLHashSHA384
;
273 algId
.algorithm
= CSSMOID_SHA384WithRSA
;
276 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg
.hash
);
277 return errSSLProtocol
;
282 dataToSignLen
= hashRef
->digestSize
;
283 hashOut
.data
= hashes
;
284 hashOut
.length
= hashRef
->digestSize
;
286 if ((err
= ReadyHash(hashRef
, &hashCtx
)) != 0)
288 if ((err
= hashRef
->update(&hashCtx
, &clientRandom
)) != 0)
290 if ((err
= hashRef
->update(&hashCtx
, &serverRandom
)) != 0)
292 if ((err
= hashRef
->update(&hashCtx
, &exchangeParams
)) != 0)
294 if ((err
= hashRef
->final(&hashCtx
, &hashOut
)) != 0)
297 if(sigAlg
.signature
==SSL_SignatureAlgorithmRSA
) {
298 err
= sslRsaSign(ctx
,
299 ctx
->signingPrivKeyRef
,
307 err
= sslRawSign(ctx
,
308 ctx
->signingPrivKeyRef
,
309 dataToSign
, // one or two hashes
317 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
318 "returned %d\n", (int)err
);
323 SSLFreeBuffer(&signedHashes
);
324 SSLFreeBuffer(&hashCtx
);
329 SSLSignServerKeyExchange(SSLContext
*ctx
, bool isRsa
, SSLBuffer exchangeParams
, SSLBuffer signature
, size_t *actSigLen
)
332 uint8_t hashes
[SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
];
333 SSLBuffer clientRandom
,serverRandom
,hashCtx
, hash
;
335 size_t dataToSignLen
;
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
;
346 /* skip this if signing with DSA */
348 dataToSignLen
= SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
;
349 hash
.data
= &hashes
[0];
350 hash
.length
= SSL_MD5_DIGEST_LEN
;
352 if ((err
= ReadyHash(&SSLHashMD5
, &hashCtx
)) != 0)
354 if ((err
= SSLHashMD5
.update(&hashCtx
, &clientRandom
)) != 0)
356 if ((err
= SSLHashMD5
.update(&hashCtx
, &serverRandom
)) != 0)
358 if ((err
= SSLHashMD5
.update(&hashCtx
, &exchangeParams
)) != 0)
360 if ((err
= SSLHashMD5
.final(&hashCtx
, &hash
)) != 0)
362 if ((err
= SSLFreeBuffer(&hashCtx
)) != 0)
366 /* DSA - just use the SHA1 hash */
367 dataToSign
= &hashes
[SSL_MD5_DIGEST_LEN
];
368 dataToSignLen
= SSL_SHA1_DIGEST_LEN
;
370 hash
.data
= &hashes
[SSL_MD5_DIGEST_LEN
];
371 hash
.length
= SSL_SHA1_DIGEST_LEN
;
372 if ((err
= ReadyHash(&SSLHashSHA1
, &hashCtx
)) != 0)
374 if ((err
= SSLHashSHA1
.update(&hashCtx
, &clientRandom
)) != 0)
376 if ((err
= SSLHashSHA1
.update(&hashCtx
, &serverRandom
)) != 0)
378 if ((err
= SSLHashSHA1
.update(&hashCtx
, &exchangeParams
)) != 0)
380 if ((err
= SSLHashSHA1
.final(&hashCtx
, &hash
)) != 0)
382 if ((err
= SSLFreeBuffer(&hashCtx
)) != 0)
386 err
= sslRawSign(ctx
,
387 ctx
->signingPrivKeyRef
,
388 dataToSign
, // one or two hashes
398 SSLFreeBuffer(&hashCtx
);
404 OSStatus
FindSigAlg(SSLContext
*ctx
,
405 SSLSignatureAndHashAlgorithm
*alg
)
409 assert(ctx
->protocolSide
== kSSLServerSide
);
410 assert(ctx
->negProtocolVersion
>= TLS_Version_1_2
);
411 assert(!ctx
->isDTLS
);
413 if((ctx
->numClientSigAlgs
==0) ||(ctx
->clientSigAlgs
==NULL
))
414 return errSSLInternal
;
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
)
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
;
429 // We could not find a supported signature and hash algorithm
430 return errSSLProtocol
;
434 SSLEncodeSignedServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
443 SSLBuffer exchangeParams
;
445 assert(ctx
->protocolSide
== kSSLServerSide
);
446 assert(ctx
->signingPubKey
!= NULL
);
447 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
448 exchangeParams
.data
= 0;
452 if(ctx
->negProtocolVersion
== DTLS_Version_1_0
) {
458 /* Set up parameter block to hash ==> exchangeParams */
459 switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
463 * Parameter block = encryption public key.
464 * If app hasn't supplied a separate encryption cert, abort.
466 if(ctx
->encryptPubKey
== NULL
) {
467 sslErrorLog("RSAServerKeyExchange: no encrypt cert\n");
468 return errSSLBadConfiguration
;
470 err
= SSLEncodeRSAKeyParams(&exchangeParams
,
471 ctx
->encryptPubKey
, ctx
);
477 case SSL_DHE_DSS_EXPORT
:
479 /* and fall through */
481 case SSL_DHE_RSA_EXPORT
:
484 * Parameter block = {prime, generator, public key}
485 * Obtain D-H parameters (if we don't have them) and a key pair.
487 err
= SSLGenServerDHParamsAndKey(ctx
);
491 size_t len
= SSLEncodedDHKeyParamsLen(ctx
);
492 err
= SSLAllocBuffer(&exchangeParams
, len
);
496 err
= SSLEncodeDHKeyParams(ctx
, exchangeParams
.data
);
500 #endif /* APPLE_DH */
503 /* shouldn't be here */
505 return errSSLInternal
;
508 SSLSignatureAndHashAlgorithm sigAlg
;
511 /* preallocate a buffer for signing */
512 err
= sslGetMaxSigSize(ctx
->signingPrivKeyRef
, &maxSigLen
);
516 err
= SSLAllocBuffer(&signature
, maxSigLen
);
521 outputLen
= exchangeParams
.length
+ 2;
523 if (sslVersionIsLikeTls12(ctx
))
525 err
=FindSigAlg(ctx
, &sigAlg
);
530 err
= SSLSignServerKeyExchangeTls12(ctx
, sigAlg
, exchangeParams
,
531 signature
, &actSigLen
);
533 err
= SSLSignServerKeyExchange(ctx
, isRsa
, exchangeParams
,
534 signature
, &actSigLen
);
540 assert(actSigLen
<= maxSigLen
);
542 outputLen
+= actSigLen
;
544 /* package it all up */
545 keyExch
->protocolVersion
= ctx
->negProtocolVersion
;
546 keyExch
->contentType
= SSL_RecordTypeHandshake
;
547 if ((err
= SSLAllocBuffer(&keyExch
->contents
, outputLen
+head
)) != 0)
550 charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExch
, SSL_HdskServerKeyExchange
, outputLen
);
552 memcpy(charPtr
, exchangeParams
.data
, exchangeParams
.length
);
553 charPtr
+= exchangeParams
.length
;
555 if (sslVersionIsLikeTls12(ctx
))
557 *charPtr
++=sigAlg
.hash
;
558 *charPtr
++=sigAlg
.signature
;
561 charPtr
= SSLEncodeInt(charPtr
, actSigLen
, 2);
562 memcpy(charPtr
, signature
.data
, actSigLen
);
563 assert((charPtr
+ actSigLen
) ==
564 (keyExch
->contents
.data
+ keyExch
->contents
.length
));
569 SSLFreeBuffer(&exchangeParams
);
570 SSLFreeBuffer(&signature
);
575 SSLVerifySignedServerKeyExchange(SSLContext
*ctx
, bool isRsa
, SSLBuffer signedParams
,
576 uint8_t *signature
, UInt16 signatureLen
)
579 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
580 uint8_t hashes
[SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
];
581 SSLBuffer signedHashes
;
583 size_t dataToSignLen
;
585 signedHashes
.data
= 0;
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
;
595 /* skip this if signing with DSA */
597 dataToSignLen
= SSL_SHA1_DIGEST_LEN
+ SSL_MD5_DIGEST_LEN
;
598 hashOut
.data
= hashes
;
599 hashOut
.length
= SSL_MD5_DIGEST_LEN
;
601 if ((err
= ReadyHash(&SSLHashMD5
, &hashCtx
)) != 0)
603 if ((err
= SSLHashMD5
.update(&hashCtx
, &clientRandom
)) != 0)
605 if ((err
= SSLHashMD5
.update(&hashCtx
, &serverRandom
)) != 0)
607 if ((err
= SSLHashMD5
.update(&hashCtx
, &signedParams
)) != 0)
609 if ((err
= SSLHashMD5
.final(&hashCtx
, &hashOut
)) != 0)
613 /* DSA, ECDSA - just use the SHA1 hash */
614 dataToSign
= &hashes
[SSL_MD5_DIGEST_LEN
];
615 dataToSignLen
= SSL_SHA1_DIGEST_LEN
;
618 hashOut
.data
= hashes
+ SSL_MD5_DIGEST_LEN
;
619 hashOut
.length
= SSL_SHA1_DIGEST_LEN
;
620 if ((err
= SSLFreeBuffer(&hashCtx
)) != 0)
623 if ((err
= ReadyHash(&SSLHashSHA1
, &hashCtx
)) != 0)
625 if ((err
= SSLHashSHA1
.update(&hashCtx
, &clientRandom
)) != 0)
627 if ((err
= SSLHashSHA1
.update(&hashCtx
, &serverRandom
)) != 0)
629 if ((err
= SSLHashSHA1
.update(&hashCtx
, &signedParams
)) != 0)
631 if ((err
= SSLHashSHA1
.final(&hashCtx
, &hashOut
)) != 0)
634 err
= sslRawVerify(ctx
,
636 dataToSign
, /* plaintext */
637 dataToSignLen
, /* plaintext length */
641 sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
642 "returned %d\n", (int)err
);
647 SSLFreeBuffer(&signedHashes
);
648 SSLFreeBuffer(&hashCtx
);
654 SSLVerifySignedServerKeyExchangeTls12(SSLContext
*ctx
, SSLSignatureAndHashAlgorithm sigAlg
, SSLBuffer signedParams
,
655 uint8_t *signature
, UInt16 signatureLen
)
658 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
659 uint8_t hashes
[SSL_MAX_DIGEST_LEN
];
660 SSLBuffer signedHashes
;
662 size_t dataToSignLen
;
663 const HashReference
*hashRef
;
666 signedHashes
.data
= 0;
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
;
674 switch (sigAlg
.hash
) {
675 case SSL_HashAlgorithmSHA1
:
676 hashRef
= &SSLHashSHA1
;
677 algId
.algorithm
= CSSMOID_SHA1WithRSA
;
679 case SSL_HashAlgorithmSHA256
:
680 hashRef
= &SSLHashSHA256
;
681 algId
.algorithm
= CSSMOID_SHA256WithRSA
;
683 case SSL_HashAlgorithmSHA384
:
684 hashRef
= &SSLHashSHA384
;
685 algId
.algorithm
= CSSMOID_SHA384WithRSA
;
688 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg
.hash
);
689 return errSSLProtocol
;
694 dataToSignLen
= hashRef
->digestSize
;
695 hashOut
.data
= hashes
;
696 hashOut
.length
= hashRef
->digestSize
;
698 if ((err
= ReadyHash(hashRef
, &hashCtx
)) != 0)
700 if ((err
= hashRef
->update(&hashCtx
, &clientRandom
)) != 0)
702 if ((err
= hashRef
->update(&hashCtx
, &serverRandom
)) != 0)
704 if ((err
= hashRef
->update(&hashCtx
, &signedParams
)) != 0)
706 if ((err
= hashRef
->final(&hashCtx
, &hashOut
)) != 0)
709 if(sigAlg
.signature
==SSL_SignatureAlgorithmRSA
) {
710 err
= sslRsaVerify(ctx
,
718 err
= sslRawVerify(ctx
,
720 dataToSign
, /* plaintext */
721 dataToSignLen
, /* plaintext length */
727 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
728 "returned %d\n", (int)err
);
733 SSLFreeBuffer(&signedHashes
);
734 SSLFreeBuffer(&hashCtx
);
740 * Decode and verify a server key exchange message signed by server's
744 SSLDecodeSignedServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
747 UInt16 modulusLen
= 0, exponentLen
= 0, signatureLen
;
748 uint8_t *modulus
= NULL
, *exponent
= NULL
, *signature
;
751 assert(ctx
->protocolSide
== kSSLClientSide
);
753 if (message
.length
< 2) {
754 sslErrorLog("SSLDecodeSignedServerKeyExchange: msg len error 1\n");
755 return errSSLProtocol
;
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
) {
764 modulusLen
= SSLDecodeInt(charPtr
, 2);
766 if((charPtr
+ modulusLen
) > endCp
) {
767 sslErrorLog("signedServerKeyExchange: msg len error 2\n");
768 return errSSLProtocol
;
771 charPtr
+= modulusLen
;
773 exponentLen
= SSLDecodeInt(charPtr
, 2);
775 if((charPtr
+ exponentLen
) > endCp
) {
776 sslErrorLog("signedServerKeyExchange: msg len error 3\n");
777 return errSSLProtocol
;
780 charPtr
+= exponentLen
;
784 case SSL_DHE_DSS_EXPORT
:
786 /* and fall through */
788 case SSL_DHE_RSA_EXPORT
:
789 err
= SSLDecodeDHKeyParams(ctx
, &charPtr
, message
.length
);
794 #endif /* APPLE_DH */
796 case SSL_ECDHE_ECDSA
:
798 /* and fall through */
800 err
= SSLDecodeECDHKeyParams(ctx
, &charPtr
, message
.length
);
807 return errSSLInternal
;
810 /* this is what's hashed */
811 SSLBuffer signedParams
;
812 signedParams
.data
= message
.data
;
813 signedParams
.length
= charPtr
- message
.data
;
815 SSLSignatureAndHashAlgorithm sigAlg
;
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
;
823 sigAlg
.hash
= *charPtr
++;
824 sigAlg
.signature
= *charPtr
++;
827 signatureLen
= SSLDecodeInt(charPtr
, 2);
829 if((charPtr
+ signatureLen
) != endCp
) {
830 sslErrorLog("signedServerKeyExchange: msg len error 4\n");
831 return errSSLProtocol
;
835 if (sslVersionIsLikeTls12(ctx
))
837 err
= SSLVerifySignedServerKeyExchangeTls12(ctx
, sigAlg
, signedParams
,
838 signature
, signatureLen
);
840 err
= SSLVerifySignedServerKeyExchange(ctx
, isRsa
, signedParams
,
841 signature
, signatureLen
);
847 /* Signature matches; now replace server key with new key (RSA only) */
848 switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
855 /* first free existing peerKey */
856 sslFreePubKey(&ctx
->peerPubKey
); /* no KCItem */
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
,
870 case SSL_DHE_RSA_EXPORT
:
872 case SSL_DHE_DSS_EXPORT
:
873 case SSL_ECDHE_ECDSA
:
875 break; /* handled above */
884 SSLDecodeRSAKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
886 size_t outputLen
, localKeyModulusLen
;
887 SSLProtocolVersion version
;
888 Boolean useEncryptKey
= false;
890 SSLPrivKey
*keyRef
= NULL
;
892 assert(ctx
->protocolSide
== kSSLServerSide
);
893 if (ctx
->encryptPrivKeyRef
) {
894 useEncryptKey
= true;
897 keyRef
= ctx
->encryptPrivKeyRef
;
898 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
901 keyRef
= ctx
->signingPrivKeyRef
;
902 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
905 localKeyModulusLen
= sslPrivKeyLengthInBytes(keyRef
);
906 if (localKeyModulusLen
== 0) {
907 sslErrorLog("SSLDecodeRSAKeyExchange: private key modulus is 0\n");
912 * We have to tolerate incoming key exchange msgs with and without the
913 * two-byte "encrypted length" field.
915 if (keyExchange
.length
== localKeyModulusLen
) {
916 /* no length encoded */
917 src
= keyExchange
.data
;
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;
925 sslErrorLog("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n",
926 (unsigned)localKeyModulusLen
, (unsigned)keyExchange
.length
);
927 return errSSLProtocol
;
929 err
= SSLAllocBuffer(&ctx
->preMasterSecret
, SSL_RSA_PREMASTER_SECRET_SIZE
);
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
947 * See http://eprint.iacr.org/2003/052/ for more info.
949 err
= sslRsaDecrypt(ctx
,
957 localKeyModulusLen
, // ciphertext len
958 ctx
->preMasterSecret
.data
,
959 SSL_RSA_PREMASTER_SECRET_SIZE
, // plaintext buf available
962 if(err
!= errSecSuccess
) {
963 /* possible Bleichenbacher attack */
964 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail");
966 else if(outputLen
!= SSL_RSA_PREMASTER_SECRET_SIZE
) {
967 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: premaster secret size error");
968 err
= errSSLProtocol
; // not passed back to caller
971 if(err
== errSecSuccess
) {
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.
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
;
985 if(err
!= errSecSuccess
) {
987 * Obfuscate failures for defense against Bleichenbacher and
988 * Klima-Pokorny-Rosa attacks.
990 SSLEncodeInt(ctx
->preMasterSecret
.data
, ctx
->negProtocolVersion
, 2);
992 tmpBuf
.data
= ctx
->preMasterSecret
.data
+ 2;
993 tmpBuf
.length
= SSL_RSA_PREMASTER_SECRET_SIZE
- 2;
994 /* must ignore failures here */
998 /* in any case, save premaster secret (good or bogus) and proceed */
999 return errSecSuccess
;
1003 SSLEncodeRSAKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1005 size_t outputLen
, peerKeyModulusLen
;
1008 bool encodeLen
= false;
1013 assert(ctx
->protocolSide
== kSSLClientSide
);
1014 if ((err
= SSLEncodeRSAPremasterSecret(ctx
)) != 0)
1017 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1018 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1019 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
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? */
1027 sslDebugLog("SSLEncodeRSAKeyExchange: peer key modulus length = %lu\n", peerKeyModulusLen
);
1029 msglen
= peerKeyModulusLen
;
1030 #if RSA_CLIENT_KEY_ADD_LENGTH
1031 if(ctx
->negProtocolVersion
>= TLS_Version_1_0
) {
1036 head
= SSLHandshakeHeaderSize(keyExchange
);
1037 bufLen
= msglen
+ head
;
1038 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,
1043 dst
= keyExchange
->contents
.data
+ head
;
1048 /* FIXME: can this line be removed? */
1049 p
= keyExchange
->contents
.data
;
1051 p
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, msglen
);
1054 /* the length of the encrypted pre_master_secret */
1055 SSLEncodeSize(keyExchange
->contents
.data
+ head
,
1056 peerKeyModulusLen
, 2);
1058 err
= sslRsaEncrypt(ctx
,
1065 ctx
->preMasterSecret
.data
,
1066 SSL_RSA_PREMASTER_SECRET_SIZE
,
1071 sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", (int)err
);
1075 assert(outputLen
== (encodeLen
? msglen
- 2 : msglen
));
1077 return errSecSuccess
;
1084 // MARK: Diffie-Hellman Key Exchange
1087 * Diffie-Hellman setup, server side. On successful return, the
1088 * following SSLContext members are valid:
1096 SSLGenServerDHParamsAndKey(
1100 assert(ctx
->protocolSide
== kSSLServerSide
);
1104 * Obtain D-H parameters if we don't have them.
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
);
1114 ccn_write_uint(n
, ccdh_gp_prime(gp
), s
, p
);
1115 ccn_write_uint(n
, ccdh_gp_g(gp
), s
, g
);
1117 const SSLBuffer prime
= {
1121 const SSLBuffer generator
= {
1126 ortn
=sslEncodeDhParams(&ctx
->dhParamsEncoded
, /* data mallocd and RETURNED PKCS-3 encoded */
1127 &prime
, /* Wire format */
1128 &generator
); /* Wire format */
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
));
1140 ortn
= sslDhGenerateKeyPair(ctx
,
1141 &ctx
->dhParamsEncoded
,
1142 ctx
->dhParamsPrime
.length
* 8,
1143 &pubKey
, ctx
->dhPrivate
);
1147 CSSM_TO_SSLBUF(&pubKey
.KeyData
, &ctx
->dhExchangePublic
);
1149 if (!ctx
->secDHContext
) {
1150 ortn
= sslDhCreateKey(ctx
);
1154 return sslDhGenerateKeyPair(ctx
);
1156 return errSecSuccess
;
1160 * size of DH param and public key, in wire format
1163 SSLEncodedDHKeyParamsLen(SSLContext
*ctx
)
1166 SSLBuffer generator
;
1168 sslDecodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1170 return (2+prime
.length
+2+generator
.length
+2+ctx
->dhExchangePublic
.length
);
1174 * Encode DH params and public key, in wire format, in caller-supplied buffer.
1177 SSLEncodeDHKeyParams(
1181 assert(ctx
->protocolSide
== kSSLServerSide
);
1182 assert(ctx
->dhParamsEncoded
.data
!= NULL
);
1183 assert(ctx
->dhExchangePublic
.data
!= NULL
);
1186 SSLBuffer generator
;
1188 sslDecodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1190 charPtr
= SSLEncodeInt(charPtr
, prime
.length
, 2);
1191 memcpy(charPtr
, prime
.data
, prime
.length
);
1192 charPtr
+= prime
.length
;
1194 charPtr
= SSLEncodeInt(charPtr
, generator
.length
, 2);
1195 memcpy(charPtr
, generator
.data
,
1197 charPtr
+= generator
.length
;
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
);
1204 dumpBuf("server prime", &prime
);
1205 dumpBuf("server generator", &generator
);
1206 dumpBuf("server pub key", &ctx
->dhExchangePublic
);
1208 return errSecSuccess
;
1212 * Decode DH params and server public key.
1215 SSLDecodeDHKeyParams(
1217 uint8_t **charPtr
, // IN/OUT
1220 OSStatus err
= errSecSuccess
;
1222 SSLBuffer generator
;
1224 assert(ctx
->protocolSide
== kSSLClientSide
);
1225 uint8_t *endCp
= *charPtr
+ length
;
1227 /* Allow reuse via renegotiation */
1228 SSLFreeBuffer(&ctx
->dhPeerPublic
);
1230 /* Prime, with a two-byte length */
1231 UInt32 len
= SSLDecodeInt(*charPtr
, 2);
1233 if((*charPtr
+ len
) > endCp
) {
1234 return errSSLProtocol
;
1237 prime
.data
= *charPtr
;
1242 /* Generator, with a two-byte length */
1243 len
= SSLDecodeInt(*charPtr
, 2);
1245 if((*charPtr
+ len
) > endCp
) {
1246 return errSSLProtocol
;
1249 generator
.data
= *charPtr
;
1250 generator
.length
= len
;
1254 sslEncodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1256 /* peer public key, with a two-byte length */
1257 len
= SSLDecodeInt(*charPtr
, 2);
1259 err
= SSLAllocBuffer(&ctx
->dhPeerPublic
, len
);
1263 memmove(ctx
->dhPeerPublic
.data
, *charPtr
, len
);
1266 dumpBuf("client peer pub", &ctx
->dhPeerPublic
);
1267 // dumpBuf("client prime", &ctx->dhParamsPrime);
1268 // dumpBuf("client generator", &ctx->dhParamsGenerator);
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
1279 * SSLContext members valid on entry:
1284 * SSLContext members valid on successful return:
1290 SSLGenClientDHKeyAndExchange(SSLContext
*ctx
)
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
;
1303 /* generate two keys */
1305 ctx
->dhPrivate
= (CSSM_KEY
*)sslMalloc(sizeof(CSSM_KEY
));
1306 ortn
= sslDhGenKeyPairClient(ctx
,
1307 &ctx
->dhParamsPrime
,
1308 &ctx
->dhParamsGenerator
,
1309 &pubKey
, ctx
->dhPrivate
);
1311 sslFree(ctx
->dhPrivate
);
1312 ctx
->dhPrivate
= NULL
;
1316 /* do the exchange, size of prime */
1317 ortn
= sslDhKeyExchange(ctx
, ctx
->dhParamsPrime
.length
* 8,
1318 &ctx
->preMasterSecret
);
1322 CSSM_TO_SSLBUF(&pubKey
.KeyData
, &ctx
->dhExchangePublic
);
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
);
1336 SSLEncodeDHanonServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
1338 OSStatus ortn
= errSecSuccess
;
1341 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1342 assert(ctx
->protocolSide
== kSSLServerSide
);
1345 * Obtain D-H parameters (if we don't have them) and a key pair.
1347 ortn
= SSLGenServerDHParamsAndKey(ctx
);
1352 size_t length
= SSLEncodedDHKeyParamsLen(ctx
);
1354 keyExch
->protocolVersion
= ctx
->negProtocolVersion
;
1355 keyExch
->contentType
= SSL_RecordTypeHandshake
;
1356 head
= SSLHandshakeHeaderSize(keyExch
);
1357 if ((ortn
= SSLAllocBuffer(&keyExch
->contents
, length
+head
)))
1360 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExch
, SSL_HdskServerKeyExchange
, length
);
1362 /* encode prime, generator, our public key */
1363 return SSLEncodeDHKeyParams(ctx
, charPtr
);
1367 SSLDecodeDHanonServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
1369 OSStatus err
= errSecSuccess
;
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
;
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
;
1388 SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1390 OSStatus ortn
= errSecSuccess
;
1391 unsigned int publicLen
;
1393 assert(ctx
->protocolSide
== kSSLServerSide
);
1394 if(ctx
->dhParamsEncoded
.data
== NULL
) {
1395 /* should never happen */
1397 return errSSLInternal
;
1400 /* this message simply contains the client's public DH key */
1401 uint8_t *charPtr
= keyExchange
.data
;
1402 publicLen
= SSLDecodeInt(charPtr
, 2);
1404 /* TODO : Check the len here ? Will fail in sslDhKeyExchange anyway */
1406 if((keyExchange.length != publicLen + 2) ||
1407 (publicLen > ctx->dhParamsPrime.length)) {
1408 return errSSLProtocol;
1411 SSLFreeBuffer(&ctx
->dhPeerPublic
); // allow reuse via renegotiation
1412 ortn
= SSLAllocBuffer(&ctx
->dhPeerPublic
, publicLen
);
1416 memmove(ctx
->dhPeerPublic
.data
, charPtr
, publicLen
);
1418 /* DH Key exchange, result --> premaster secret */
1419 SSLFreeBuffer(&ctx
->preMasterSecret
);
1421 ortn
= sslDhKeyExchange(ctx
, ctx
->dhParamsPrime
.length
* 8,
1422 &ctx
->preMasterSecret
);
1424 ortn
= sslDhKeyExchange(ctx
);
1426 dumpBuf("server peer pub", &ctx
->dhPeerPublic
);
1427 dumpBuf("server premaster", &ctx
->preMasterSecret
);
1432 SSLEncodeDHClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1437 assert(ctx
->protocolSide
== kSSLClientSide
);
1438 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1440 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1441 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
1443 if ((err
= SSLGenClientDHKeyAndExchange(ctx
)) != 0)
1446 outputLen
= ctx
->dhExchangePublic
.length
+ 2;
1447 head
= SSLHandshakeHeaderSize(keyExchange
);
1448 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,outputLen
+ head
)))
1451 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1453 charPtr
= SSLEncodeSize(charPtr
, ctx
->dhExchangePublic
.length
, 2);
1454 memcpy(charPtr
, ctx
->dhExchangePublic
.data
, ctx
->dhExchangePublic
.length
);
1456 dumpBuf("client pub key", &ctx
->dhExchangePublic
);
1457 dumpBuf("client premaster", &ctx
->preMasterSecret
);
1459 return errSecSuccess
;
1462 #endif /* APPLE_DH */
1465 // MARK: ECDSA Key Exchange
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
1473 * SSLContext members valid on entry:
1474 * if keyExchangeMethod == SSL_ECDHE_ECDSA or SSL_ECDHE_RSA:
1477 * if keyExchangeMethod == SSL_ECDH_ECDSA or SSL_ECDH_RSA:
1478 * peerPubKey, from which we infer ecdhPeerCurve
1480 * SSLContext members valid on successful return:
1482 * ecdhExchangePublic
1486 SSLGenClientECDHKeyAndExchange(SSLContext
*ctx
)
1490 assert(ctx
->protocolSide
== kSSLClientSide
);
1492 switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
1493 case SSL_ECDHE_ECDSA
:
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
;
1501 case SSL_ECDH_ECDSA
:
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
;
1510 /* The peer curve is in the key's CSSM_X509_ALGORITHM_IDENTIFIER... */
1511 ortn
= sslEcdsaPeerCurve(ctx
->peerPubKey
, &ctx
->ecdhPeerCurve
);
1515 sslEcdsaDebug("SSLGenClientECDHKeyAndExchange: derived peerCurve %u",
1516 (unsigned)ctx
->ecdhPeerCurve
);
1520 /* shouldn't be here */
1522 return errSSLInternal
;
1525 /* Generate our (ephemeral) pair, or extract it from our signing identity */
1526 if((ctx
->negAuthType
== SSLClientAuth_RSAFixedECDH
) ||
1527 (ctx
->negAuthType
== SSLClientAuth_ECDSAFixedECDH
)) {
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.
1533 assert(ctx
->signingPrivKeyRef
!= NULL
);
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
);
1542 ortn
= SecKeyGetCSPHandle(ctx
->signingPrivKeyRef
, &ctx
->ecdhPrivCspHand
);
1544 sslErrorLog("SSLGenClientECDHKeyAndExchange: SecKeyGetCSPHandle err %d\n",
1548 sslEcdsaDebug("+++ Extracted ECDH private key");
1551 /* generate a new pair */
1552 ortn
= sslEcdhGenerateKeyPair(ctx
, ctx
->ecdhPeerCurve
);
1557 sslEcdsaDebug("+++ Generated %u bit (%u byte) ECDH key pair",
1558 (unsigned)ctx
->ecdhPrivate
->KeyHeader
.LogicalKeySizeInBits
,
1559 (unsigned)((ctx
->ecdhPrivate
->KeyHeader
.LogicalKeySizeInBits
+ 7) / 8));
1564 /* do the exchange --> premaster secret */
1565 ortn
= sslEcdhKeyExchange(ctx
, &ctx
->preMasterSecret
);
1569 return errSecSuccess
;
1574 * Decode ECDH params and server public key.
1577 SSLDecodeECDHKeyParams(
1579 uint8_t **charPtr
, // IN/OUT
1582 OSStatus err
= errSecSuccess
;
1584 sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange");
1586 assert(ctx
->protocolSide
== kSSLClientSide
);
1587 uint8_t *endCp
= *charPtr
+ length
;
1589 /* Allow reuse via renegotiation */
1590 SSLFreeBuffer(&ctx
->ecdhPeerPublic
);
1592 /*** ECParameters - just a curveType and a named curve ***/
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
;
1601 if(*charPtr
> endCp
) {
1602 return errSSLProtocol
;
1605 /* two-byte curve */
1606 ctx
->ecdhPeerCurve
= SSLDecodeInt(*charPtr
, 2);
1608 if(*charPtr
> endCp
) {
1609 return errSSLProtocol
;
1611 switch(ctx
->ecdhPeerCurve
) {
1612 case SSL_Curve_secp256r1
:
1613 case SSL_Curve_secp384r1
:
1614 case SSL_Curve_secp521r1
:
1617 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curve (%u)\n",
1618 (unsigned)ctx
->ecdhPeerCurve
);
1619 return errSSLProtocol
;
1622 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: ecdhPeerCurve %u",
1623 (unsigned)ctx
->ecdhPeerCurve
);
1625 /*** peer public key as an ECPoint ***/
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...
1632 UInt32 len
= SSLDecodeInt(*charPtr
, 1);
1634 if((*charPtr
+ len
) > endCp
) {
1635 return errSSLProtocol
;
1637 err
= SSLAllocBuffer(&ctx
->ecdhPeerPublic
, len
);
1641 memmove(ctx
->ecdhPeerPublic
.data
, *charPtr
, len
);
1644 dumpBuf("client peer pub", &ctx
->ecdhPeerPublic
);
1651 SSLEncodeECDHClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1656 assert(ctx
->protocolSide
== kSSLClientSide
);
1657 if ((err
= SSLGenClientECDHKeyAndExchange(ctx
)) != 0)
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).
1665 bool emptyMsg
= false;
1666 switch(ctx
->negAuthType
) {
1667 case SSLClientAuth_RSAFixedECDH
:
1668 case SSLClientAuth_ECDSAFixedECDH
:
1678 outputLen
= ctx
->ecdhExchangePublic
.length
+ 1;
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
)))
1688 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1690 sslEcdsaDebug("+++ Sending EMPTY ECDH Client Key Exchange");
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");
1699 dumpBuf("client pub key", &ctx
->ecdhExchangePublic
);
1700 dumpBuf("client premaster", &ctx
->preMasterSecret
);
1701 return errSecSuccess
;
1707 SSLDecodePSKClientKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1709 OSStatus ortn
= errSecSuccess
;
1710 unsigned int identityLen
;
1712 assert(ctx
->protocolSide
== kSSLServerSide
);
1714 /* this message simply contains the client's PSK identity */
1715 uint8_t *charPtr
= keyExchange
.data
;
1716 identityLen
= SSLDecodeInt(charPtr
, 2);
1719 SSLFreeBuffer(&ctx
->pskIdentity
); // allow reuse via renegotiation
1720 ortn
= SSLAllocBuffer(&ctx
->pskIdentity
, identityLen
);
1724 memmove(ctx
->pskIdentity
.data
, charPtr
, identityLen
);
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. */
1731 size_t n
=ctx
->pskSharedSecret
.length
;
1733 if(n
==0) return errSSLBadConfiguration
;
1735 if ((ortn
= SSLAllocBuffer(&ctx
->preMasterSecret
, 2*(n
+2))) != 0)
1738 uint8_t *p
=ctx
->preMasterSecret
.data
;
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
);
1745 dumpBuf("server premaster (PSK)", &ctx
->preMasterSecret
);
1752 SSLEncodePSKClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1758 assert(ctx
->protocolSide
== kSSLClientSide
);
1760 outputLen
= ctx
->pskIdentity
.length
+2;
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
)))
1769 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1771 charPtr
= SSLEncodeSize(charPtr
, ctx
->pskIdentity
.length
, 2);
1772 memcpy(charPtr
, ctx
->pskIdentity
.data
, ctx
->pskIdentity
.length
);
1775 /* We better have a pskSharedSecret already */
1776 size_t n
=ctx
->pskSharedSecret
.length
;
1778 if(n
==0) return errSSLBadConfiguration
;
1780 if ((err
= SSLAllocBuffer(&ctx
->preMasterSecret
, 2*(n
+2))) != 0)
1783 uint8_t *p
=ctx
->preMasterSecret
.data
;
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
);
1790 dumpBuf("client premaster (PSK)", &ctx
->preMasterSecret
);
1792 return errSecSuccess
;
1797 // MARK: Public Functions
1799 SSLEncodeServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
1802 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
)
1804 case SSL_RSA_EXPORT
:
1807 case SSL_DHE_RSA_EXPORT
:
1809 case SSL_DHE_DSS_EXPORT
:
1810 #endif /* APPLE_DH */
1811 if ((err
= SSLEncodeSignedServerKeyExchange(keyExch
, ctx
)) != 0)
1816 case SSL_DH_anon_EXPORT
:
1817 if ((err
= SSLEncodeDHanonServerKeyExchange(keyExch
, ctx
)) != 0)
1822 return errSecUnimplemented
;
1825 return errSecSuccess
;
1829 SSLProcessServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
1833 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
1835 case SSL_RSA_EXPORT
:
1838 case SSL_DHE_RSA_EXPORT
:
1840 case SSL_DHE_DSS_EXPORT
:
1842 case SSL_ECDHE_ECDSA
:
1844 err
= SSLDecodeSignedServerKeyExchange(message
, ctx
);
1848 case SSL_DH_anon_EXPORT
:
1849 err
= SSLDecodeDHanonServerKeyExchange(message
, ctx
);
1853 err
= errSecUnimplemented
;
1861 SSLEncodeKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1864 assert(ctx
->protocolSide
== kSSLClientSide
);
1866 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
1868 case SSL_RSA_EXPORT
:
1869 sslDebugLog("SSLEncodeKeyExchange: RSA method\n");
1870 err
= SSLEncodeRSAKeyExchange(keyExchange
, ctx
);
1874 case SSL_DHE_RSA_EXPORT
:
1876 case SSL_DHE_DSS_EXPORT
:
1878 case SSL_DH_anon_EXPORT
:
1879 sslDebugLog("SSLEncodeKeyExchange: DH method\n");
1880 err
= SSLEncodeDHClientKeyExchange(keyExchange
, ctx
);
1883 case SSL_ECDH_ECDSA
:
1884 case SSL_ECDHE_ECDSA
:
1888 sslDebugLog("SSLEncodeKeyExchange: ECDH method\n");
1889 err
= SSLEncodeECDHClientKeyExchange(keyExchange
, ctx
);
1892 err
= SSLEncodePSKClientKeyExchange(keyExchange
, ctx
);
1895 sslErrorLog("SSLEncodeKeyExchange: unknown method (%d)\n",
1896 ctx
->selectedCipherSpecParams
.keyExchangeMethod
);
1897 err
= errSecUnimplemented
;
1904 SSLProcessKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1907 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
)
1909 case SSL_RSA_EXPORT
:
1910 if ((err
= SSLDecodeRSAKeyExchange(keyExchange
, ctx
)) != 0)
1916 case SSL_DHE_DSS_EXPORT
:
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)
1927 if ((err
= SSLDecodePSKClientKeyExchange(keyExchange
, ctx
)) != 0)
1931 sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n",
1932 ctx
->selectedCipherSpecParams
.keyExchangeMethod
);
1933 return errSecUnimplemented
;
1936 return errSecSuccess
;
1940 SSLInitPendingCiphers(SSLContext
*ctx
)
1945 err
= errSecSuccess
;
1948 keyDataLen
= ctx
->selectedCipherSpecParams
.macSize
+
1949 ctx
->selectedCipherSpecParams
.keySize
+
1950 ctx
->selectedCipherSpecParams
.ivSize
;
1951 keyDataLen
*= 2; /* two of everything */
1953 if ((err
= SSLAllocBuffer(&key
, keyDataLen
)))
1955 assert(ctx
->sslTslCalls
!= NULL
);
1956 if ((err
= ctx
->sslTslCalls
->generateKeyMaterial(key
, ctx
)) != 0)
1959 if((err
= ctx
->recFuncs
->initPendingCiphers(ctx
->recCtx
, ctx
->selectedCipher
, (ctx
->protocolSide
==kSSLServerSide
), key
)) != 0)
1962 ctx
->writePending_ready
= 1;
1963 ctx
->readPending_ready
= 1;
1966 SSLFreeBuffer(&key
);