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)
632 if ((err
= SSLHashSHA1
.final(&hashCtx
, &hashOut
)) != 0)
635 err
= sslRawVerify(ctx
,
637 dataToSign
, /* plaintext */
638 dataToSignLen
, /* plaintext length */
642 sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
643 "returned %d\n", (int)err
);
648 SSLFreeBuffer(&signedHashes
);
649 SSLFreeBuffer(&hashCtx
);
655 SSLVerifySignedServerKeyExchangeTls12(SSLContext
*ctx
, SSLSignatureAndHashAlgorithm sigAlg
, SSLBuffer signedParams
,
656 uint8_t *signature
, UInt16 signatureLen
)
659 SSLBuffer hashOut
, hashCtx
, clientRandom
, serverRandom
;
660 uint8_t hashes
[SSL_MAX_DIGEST_LEN
];
661 SSLBuffer signedHashes
;
663 size_t dataToSignLen
;
664 const HashReference
*hashRef
;
667 signedHashes
.data
= 0;
670 clientRandom
.data
= ctx
->clientRandom
;
671 clientRandom
.length
= SSL_CLIENT_SRVR_RAND_SIZE
;
672 serverRandom
.data
= ctx
->serverRandom
;
673 serverRandom
.length
= SSL_CLIENT_SRVR_RAND_SIZE
;
675 switch (sigAlg
.hash
) {
676 case SSL_HashAlgorithmSHA1
:
677 hashRef
= &SSLHashSHA1
;
678 algId
.algorithm
= CSSMOID_SHA1WithRSA
;
680 case SSL_HashAlgorithmSHA256
:
681 hashRef
= &SSLHashSHA256
;
682 algId
.algorithm
= CSSMOID_SHA256WithRSA
;
684 case SSL_HashAlgorithmSHA384
:
685 hashRef
= &SSLHashSHA384
;
686 algId
.algorithm
= CSSMOID_SHA384WithRSA
;
689 sslErrorLog("SSLVerifySignedServerKeyExchangeTls12: unsupported hash %d\n", sigAlg
.hash
);
690 return errSSLProtocol
;
695 dataToSignLen
= hashRef
->digestSize
;
696 hashOut
.data
= hashes
;
697 hashOut
.length
= hashRef
->digestSize
;
699 if ((err
= ReadyHash(hashRef
, &hashCtx
)) != 0)
701 if ((err
= hashRef
->update(&hashCtx
, &clientRandom
)) != 0)
703 if ((err
= hashRef
->update(&hashCtx
, &serverRandom
)) != 0)
705 if ((err
= hashRef
->update(&hashCtx
, &signedParams
)) != 0)
707 if ((err
= hashRef
->final(&hashCtx
, &hashOut
)) != 0)
710 if(sigAlg
.signature
==SSL_SignatureAlgorithmRSA
) {
711 err
= sslRsaVerify(ctx
,
719 err
= sslRawVerify(ctx
,
721 dataToSign
, /* plaintext */
722 dataToSignLen
, /* plaintext length */
728 sslErrorLog("SSLDecodeSignedServerKeyExchangeTls12: sslRawVerify "
729 "returned %d\n", (int)err
);
734 SSLFreeBuffer(&signedHashes
);
735 SSLFreeBuffer(&hashCtx
);
741 * Decode and verify a server key exchange message signed by server's
745 SSLDecodeSignedServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
748 UInt16 modulusLen
= 0, exponentLen
= 0, signatureLen
;
749 uint8_t *modulus
= NULL
, *exponent
= NULL
, *signature
;
752 assert(ctx
->protocolSide
== kSSLClientSide
);
754 if (message
.length
< 2) {
755 sslErrorLog("SSLDecodeSignedServerKeyExchange: msg len error 1\n");
756 return errSSLProtocol
;
759 /* first extract the key-exchange-method-specific parameters */
760 uint8_t *charPtr
= message
.data
;
761 uint8_t *endCp
= charPtr
+ message
.length
;
762 switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
765 modulusLen
= SSLDecodeInt(charPtr
, 2);
767 if((charPtr
+ modulusLen
) > endCp
) {
768 sslErrorLog("signedServerKeyExchange: msg len error 2\n");
769 return errSSLProtocol
;
772 charPtr
+= modulusLen
;
774 exponentLen
= SSLDecodeInt(charPtr
, 2);
776 if((charPtr
+ exponentLen
) > endCp
) {
777 sslErrorLog("signedServerKeyExchange: msg len error 3\n");
778 return errSSLProtocol
;
781 charPtr
+= exponentLen
;
785 case SSL_DHE_DSS_EXPORT
:
787 /* and fall through */
789 case SSL_DHE_RSA_EXPORT
:
790 err
= SSLDecodeDHKeyParams(ctx
, &charPtr
, message
.length
);
795 #endif /* APPLE_DH */
797 case SSL_ECDHE_ECDSA
:
799 /* and fall through */
801 err
= SSLDecodeECDHKeyParams(ctx
, &charPtr
, message
.length
);
808 return errSSLInternal
;
811 /* this is what's hashed */
812 SSLBuffer signedParams
;
813 signedParams
.data
= message
.data
;
814 signedParams
.length
= charPtr
- message
.data
;
816 SSLSignatureAndHashAlgorithm sigAlg
;
818 if (sslVersionIsLikeTls12(ctx
)) {
819 /* Parse the algorithm field added in TLS1.2 */
820 if((charPtr
+ 2) > endCp
) {
821 sslErrorLog("signedServerKeyExchange: msg len error 499\n");
822 return errSSLProtocol
;
824 sigAlg
.hash
= *charPtr
++;
825 sigAlg
.signature
= *charPtr
++;
828 signatureLen
= SSLDecodeInt(charPtr
, 2);
830 if((charPtr
+ signatureLen
) != endCp
) {
831 sslErrorLog("signedServerKeyExchange: msg len error 4\n");
832 return errSSLProtocol
;
836 if (sslVersionIsLikeTls12(ctx
))
838 err
= SSLVerifySignedServerKeyExchangeTls12(ctx
, sigAlg
, signedParams
,
839 signature
, signatureLen
);
841 err
= SSLVerifySignedServerKeyExchange(ctx
, isRsa
, signedParams
,
842 signature
, signatureLen
);
848 /* Signature matches; now replace server key with new key (RSA only) */
849 switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
856 /* first free existing peerKey */
857 sslFreePubKey(&ctx
->peerPubKey
); /* no KCItem */
859 /* and cook up a new one from raw bits */
860 modBuf
.data
= modulus
;
861 modBuf
.length
= modulusLen
;
862 expBuf
.data
= exponent
;
863 expBuf
.length
= exponentLen
;
864 err
= sslGetPubKeyFromBits(ctx
,
871 case SSL_DHE_RSA_EXPORT
:
873 case SSL_DHE_DSS_EXPORT
:
874 case SSL_ECDHE_ECDSA
:
876 break; /* handled above */
885 SSLDecodeRSAKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
887 size_t outputLen
, localKeyModulusLen
;
888 SSLProtocolVersion version
;
889 Boolean useEncryptKey
= false;
891 SSLPrivKey
*keyRef
= NULL
;
893 assert(ctx
->protocolSide
== kSSLServerSide
);
894 if (ctx
->encryptPrivKeyRef
) {
895 useEncryptKey
= true;
898 keyRef
= ctx
->encryptPrivKeyRef
;
899 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
902 keyRef
= ctx
->signingPrivKeyRef
;
903 /* FIXME: when 3420180 is implemented, pick appropriate creds here */
906 localKeyModulusLen
= sslPrivKeyLengthInBytes(keyRef
);
907 if (localKeyModulusLen
== 0) {
908 sslErrorLog("SSLDecodeRSAKeyExchange: private key modulus is 0\n");
913 * We have to tolerate incoming key exchange msgs with and without the
914 * two-byte "encrypted length" field.
916 if (keyExchange
.length
== localKeyModulusLen
) {
917 /* no length encoded */
918 src
= keyExchange
.data
;
920 else if((keyExchange
.length
== (localKeyModulusLen
+ 2)) &&
921 (ctx
->negProtocolVersion
>= TLS_Version_1_0
)) {
922 /* TLS only - skip the length bytes */
923 src
= keyExchange
.data
+ 2;
926 sslErrorLog("SSLDecodeRSAKeyExchange: length error (exp %u got %u)\n",
927 (unsigned)localKeyModulusLen
, (unsigned)keyExchange
.length
);
928 return errSSLProtocol
;
930 err
= SSLAllocBuffer(&ctx
->preMasterSecret
, SSL_RSA_PREMASTER_SECRET_SIZE
);
936 * From this point on, to defend against the Bleichenbacher attack
937 * and its Klima-Pokorny-Rosa variant, any errors we detect are *not*
938 * reported to the caller or the peer. If we detect any error during
939 * decryption (e.g., bad PKCS1 padding) or in the testing of the version
940 * number in the premaster secret, we proceed by generating a random
941 * premaster secret, with the correct version number, and tell our caller
942 * that everything is fine. This session will fail as soon as the
943 * finished messages are sent, since we will be using a bogus premaster
944 * secret (and hence bogus session and MAC keys). Meanwhile we have
945 * not provided any side channel information relating to the cause of
948 * See http://eprint.iacr.org/2003/052/ for more info.
950 err
= sslRsaDecrypt(ctx
,
958 localKeyModulusLen
, // ciphertext len
959 ctx
->preMasterSecret
.data
,
960 SSL_RSA_PREMASTER_SECRET_SIZE
, // plaintext buf available
963 if(err
!= errSecSuccess
) {
964 /* possible Bleichenbacher attack */
965 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: RSA decrypt fail");
967 else if(outputLen
!= SSL_RSA_PREMASTER_SECRET_SIZE
) {
968 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: premaster secret size error");
969 err
= errSSLProtocol
; // not passed back to caller
972 if(err
== errSecSuccess
) {
974 * Two legal values here - the one we actually negotiated (which is
975 * technically incorrect but not uncommon), and the one the client
976 * sent as its preferred version in the client hello msg.
978 version
= (SSLProtocolVersion
)SSLDecodeInt(ctx
->preMasterSecret
.data
, 2);
979 if((version
!= ctx
->negProtocolVersion
) &&
980 (version
!= ctx
->clientReqProtocol
)) {
981 /* possible Klima-Pokorny-Rosa attack */
982 sslLogNegotiateDebug("SSLDecodeRSAKeyExchange: version error");
983 err
= errSSLProtocol
;
986 if(err
!= errSecSuccess
) {
988 * Obfuscate failures for defense against Bleichenbacher and
989 * Klima-Pokorny-Rosa attacks.
991 SSLEncodeInt(ctx
->preMasterSecret
.data
, ctx
->negProtocolVersion
, 2);
993 tmpBuf
.data
= ctx
->preMasterSecret
.data
+ 2;
994 tmpBuf
.length
= SSL_RSA_PREMASTER_SECRET_SIZE
- 2;
995 /* must ignore failures here */
999 /* in any case, save premaster secret (good or bogus) and proceed */
1000 return errSecSuccess
;
1004 SSLEncodeRSAKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1006 size_t outputLen
, peerKeyModulusLen
;
1009 bool encodeLen
= false;
1014 assert(ctx
->protocolSide
== kSSLClientSide
);
1015 if ((err
= SSLEncodeRSAPremasterSecret(ctx
)) != 0)
1018 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1019 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1020 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
1022 peerKeyModulusLen
= sslPubKeyLengthInBytes(ctx
->peerPubKey
);
1023 if (peerKeyModulusLen
== 0) {
1024 sslErrorLog("SSLEncodeRSAKeyExchange: peer key modulus is 0\n");
1025 /* FIXME: we don't return an error here... is this condition ever expected? */
1028 sslDebugLog("SSLEncodeRSAKeyExchange: peer key modulus length = %lu\n", peerKeyModulusLen
);
1030 msglen
= peerKeyModulusLen
;
1031 #if RSA_CLIENT_KEY_ADD_LENGTH
1032 if(ctx
->negProtocolVersion
>= TLS_Version_1_0
) {
1037 head
= SSLHandshakeHeaderSize(keyExchange
);
1038 bufLen
= msglen
+ head
;
1039 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,
1044 dst
= keyExchange
->contents
.data
+ head
;
1049 /* FIXME: can this line be removed? */
1050 p
= keyExchange
->contents
.data
;
1052 p
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, msglen
);
1055 /* the length of the encrypted pre_master_secret */
1056 SSLEncodeSize(keyExchange
->contents
.data
+ head
,
1057 peerKeyModulusLen
, 2);
1059 err
= sslRsaEncrypt(ctx
,
1066 ctx
->preMasterSecret
.data
,
1067 SSL_RSA_PREMASTER_SECRET_SIZE
,
1072 sslErrorLog("SSLEncodeRSAKeyExchange: error %d\n", (int)err
);
1076 assert(outputLen
== (encodeLen
? msglen
- 2 : msglen
));
1078 return errSecSuccess
;
1085 // MARK: Diffie-Hellman Key Exchange
1088 * Diffie-Hellman setup, server side. On successful return, the
1089 * following SSLContext members are valid:
1097 SSLGenServerDHParamsAndKey(
1101 assert(ctx
->protocolSide
== kSSLServerSide
);
1105 * Obtain D-H parameters if we don't have them.
1107 if(ctx
->dhParamsEncoded
.data
== NULL
) {
1108 /* TODO: Pick appropriate group based on cipher suite */
1109 ccdh_const_gp_t gp
= ccdh_gp_rfc5114_MODP_2048_256();
1110 cc_size n
= ccdh_gp_n(gp
);
1111 size_t s
= ccdh_gp_prime_size(gp
);
1115 ccn_write_uint(n
, ccdh_gp_prime(gp
), s
, p
);
1116 ccn_write_uint(n
, ccdh_gp_g(gp
), s
, g
);
1118 const SSLBuffer prime
= {
1122 const SSLBuffer generator
= {
1127 ortn
=sslEncodeDhParams(&ctx
->dhParamsEncoded
, /* data mallocd and RETURNED PKCS-3 encoded */
1128 &prime
, /* Wire format */
1129 &generator
); /* Wire format */
1136 /* generate per-session D-H key pair */
1137 sslFreeKey(ctx
->cspHand
, &ctx
->dhPrivate
, NULL
);
1138 SSLFreeBuffer(&ctx
->dhExchangePublic
);
1139 ctx
->dhPrivate
= (CSSM_KEY
*)sslMalloc(sizeof(CSSM_KEY
));
1141 ortn
= sslDhGenerateKeyPair(ctx
,
1142 &ctx
->dhParamsEncoded
,
1143 ctx
->dhParamsPrime
.length
* 8,
1144 &pubKey
, ctx
->dhPrivate
);
1148 CSSM_TO_SSLBUF(&pubKey
.KeyData
, &ctx
->dhExchangePublic
);
1150 if (!ctx
->secDHContext
) {
1151 ortn
= sslDhCreateKey(ctx
);
1155 return sslDhGenerateKeyPair(ctx
);
1157 return errSecSuccess
;
1161 * size of DH param and public key, in wire format
1164 SSLEncodedDHKeyParamsLen(SSLContext
*ctx
)
1167 SSLBuffer generator
;
1169 sslDecodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1171 return (2+prime
.length
+2+generator
.length
+2+ctx
->dhExchangePublic
.length
);
1175 * Encode DH params and public key, in wire format, in caller-supplied buffer.
1178 SSLEncodeDHKeyParams(
1182 assert(ctx
->protocolSide
== kSSLServerSide
);
1183 assert(ctx
->dhParamsEncoded
.data
!= NULL
);
1184 assert(ctx
->dhExchangePublic
.data
!= NULL
);
1187 SSLBuffer generator
;
1189 sslDecodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1191 charPtr
= SSLEncodeInt(charPtr
, prime
.length
, 2);
1192 memcpy(charPtr
, prime
.data
, prime
.length
);
1193 charPtr
+= prime
.length
;
1195 charPtr
= SSLEncodeInt(charPtr
, generator
.length
, 2);
1196 memcpy(charPtr
, generator
.data
,
1198 charPtr
+= generator
.length
;
1200 /* TODO: hum.... sounds like this one should be in the SecDHContext */
1201 charPtr
= SSLEncodeInt(charPtr
, ctx
->dhExchangePublic
.length
, 2);
1202 memcpy(charPtr
, ctx
->dhExchangePublic
.data
,
1203 ctx
->dhExchangePublic
.length
);
1205 dumpBuf("server prime", &prime
);
1206 dumpBuf("server generator", &generator
);
1207 dumpBuf("server pub key", &ctx
->dhExchangePublic
);
1209 return errSecSuccess
;
1213 * Decode DH params and server public key.
1216 SSLDecodeDHKeyParams(
1218 uint8_t **charPtr
, // IN/OUT
1221 OSStatus err
= errSecSuccess
;
1223 SSLBuffer generator
;
1225 assert(ctx
->protocolSide
== kSSLClientSide
);
1226 uint8_t *endCp
= *charPtr
+ length
;
1228 /* Allow reuse via renegotiation */
1229 SSLFreeBuffer(&ctx
->dhPeerPublic
);
1231 /* Prime, with a two-byte length */
1232 UInt32 len
= SSLDecodeInt(*charPtr
, 2);
1234 if((*charPtr
+ len
) > endCp
) {
1235 return errSSLProtocol
;
1238 prime
.data
= *charPtr
;
1243 /* Generator, with a two-byte length */
1244 len
= SSLDecodeInt(*charPtr
, 2);
1246 if((*charPtr
+ len
) > endCp
) {
1247 return errSSLProtocol
;
1250 generator
.data
= *charPtr
;
1251 generator
.length
= len
;
1255 sslEncodeDhParams(&ctx
->dhParamsEncoded
, &prime
, &generator
);
1257 /* peer public key, with a two-byte length */
1258 len
= SSLDecodeInt(*charPtr
, 2);
1260 err
= SSLAllocBuffer(&ctx
->dhPeerPublic
, len
);
1264 memmove(ctx
->dhPeerPublic
.data
, *charPtr
, len
);
1267 dumpBuf("client peer pub", &ctx
->dhPeerPublic
);
1268 // dumpBuf("client prime", &ctx->dhParamsPrime);
1269 // dumpBuf("client generator", &ctx->dhParamsGenerator);
1275 * Given the server's Diffie-Hellman parameters, generate our
1276 * own DH key pair, and perform key exchange using the server's
1277 * public key and our private key. The result is the premaster
1280 * SSLContext members valid on entry:
1285 * SSLContext members valid on successful return:
1291 SSLGenClientDHKeyAndExchange(SSLContext
*ctx
)
1297 if((ctx
->dhParamsPrime
.data
== NULL
) ||
1298 (ctx
->dhParamsGenerator
.data
== NULL
) ||
1299 (ctx
->dhPeerPublic
.data
== NULL
)) {
1300 sslErrorLog("SSLGenClientDHKeyAndExchange: incomplete server params\n");
1301 return errSSLProtocol
;
1304 /* generate two keys */
1306 ctx
->dhPrivate
= (CSSM_KEY
*)sslMalloc(sizeof(CSSM_KEY
));
1307 ortn
= sslDhGenKeyPairClient(ctx
,
1308 &ctx
->dhParamsPrime
,
1309 &ctx
->dhParamsGenerator
,
1310 &pubKey
, ctx
->dhPrivate
);
1312 sslFree(ctx
->dhPrivate
);
1313 ctx
->dhPrivate
= NULL
;
1317 /* do the exchange, size of prime */
1318 ortn
= sslDhKeyExchange(ctx
, ctx
->dhParamsPrime
.length
* 8,
1319 &ctx
->preMasterSecret
);
1323 CSSM_TO_SSLBUF(&pubKey
.KeyData
, &ctx
->dhExchangePublic
);
1325 ortn
=errSSLProtocol
;
1326 require(ctx
->dhParamsEncoded
.data
, out
);
1327 require_noerr(ortn
= sslDhCreateKey(ctx
), out
);
1328 require_noerr(ortn
= sslDhGenerateKeyPair(ctx
), out
);
1329 require_noerr(ortn
= sslDhKeyExchange(ctx
), out
);
1337 SSLEncodeDHanonServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
1339 OSStatus ortn
= errSecSuccess
;
1342 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1343 assert(ctx
->protocolSide
== kSSLServerSide
);
1346 * Obtain D-H parameters (if we don't have them) and a key pair.
1348 ortn
= SSLGenServerDHParamsAndKey(ctx
);
1353 size_t length
= SSLEncodedDHKeyParamsLen(ctx
);
1355 keyExch
->protocolVersion
= ctx
->negProtocolVersion
;
1356 keyExch
->contentType
= SSL_RecordTypeHandshake
;
1357 head
= SSLHandshakeHeaderSize(keyExch
);
1358 if ((ortn
= SSLAllocBuffer(&keyExch
->contents
, length
+head
)))
1361 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExch
, SSL_HdskServerKeyExchange
, length
);
1363 /* encode prime, generator, our public key */
1364 return SSLEncodeDHKeyParams(ctx
, charPtr
);
1368 SSLDecodeDHanonServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
1370 OSStatus err
= errSecSuccess
;
1372 assert(ctx
->protocolSide
== kSSLClientSide
);
1373 if (message
.length
< 6) {
1374 sslErrorLog("SSLDecodeDHanonServerKeyExchange error: msg len %u\n",
1375 (unsigned)message
.length
);
1376 return errSSLProtocol
;
1378 uint8_t *charPtr
= message
.data
;
1379 err
= SSLDecodeDHKeyParams(ctx
, &charPtr
, message
.length
);
1380 if(err
== errSecSuccess
) {
1381 if((message
.data
+ message
.length
) != charPtr
) {
1382 err
= errSSLProtocol
;
1389 SSLDecodeDHClientKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1391 OSStatus ortn
= errSecSuccess
;
1392 unsigned int publicLen
;
1394 assert(ctx
->protocolSide
== kSSLServerSide
);
1395 if(ctx
->dhParamsEncoded
.data
== NULL
) {
1396 /* should never happen */
1398 return errSSLInternal
;
1401 /* this message simply contains the client's public DH key */
1402 uint8_t *charPtr
= keyExchange
.data
;
1403 publicLen
= SSLDecodeInt(charPtr
, 2);
1405 /* TODO : Check the len here ? Will fail in sslDhKeyExchange anyway */
1407 if((keyExchange.length != publicLen + 2) ||
1408 (publicLen > ctx->dhParamsPrime.length)) {
1409 return errSSLProtocol;
1412 SSLFreeBuffer(&ctx
->dhPeerPublic
); // allow reuse via renegotiation
1413 ortn
= SSLAllocBuffer(&ctx
->dhPeerPublic
, publicLen
);
1417 memmove(ctx
->dhPeerPublic
.data
, charPtr
, publicLen
);
1419 /* DH Key exchange, result --> premaster secret */
1420 SSLFreeBuffer(&ctx
->preMasterSecret
);
1422 ortn
= sslDhKeyExchange(ctx
, ctx
->dhParamsPrime
.length
* 8,
1423 &ctx
->preMasterSecret
);
1425 ortn
= sslDhKeyExchange(ctx
);
1427 dumpBuf("server peer pub", &ctx
->dhPeerPublic
);
1428 dumpBuf("server premaster", &ctx
->preMasterSecret
);
1433 SSLEncodeDHClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1438 assert(ctx
->protocolSide
== kSSLClientSide
);
1439 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1441 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1442 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
1444 if ((err
= SSLGenClientDHKeyAndExchange(ctx
)) != 0)
1447 outputLen
= ctx
->dhExchangePublic
.length
+ 2;
1448 head
= SSLHandshakeHeaderSize(keyExchange
);
1449 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,outputLen
+ head
)))
1452 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1454 charPtr
= SSLEncodeSize(charPtr
, ctx
->dhExchangePublic
.length
, 2);
1455 memcpy(charPtr
, ctx
->dhExchangePublic
.data
, ctx
->dhExchangePublic
.length
);
1457 dumpBuf("client pub key", &ctx
->dhExchangePublic
);
1458 dumpBuf("client premaster", &ctx
->preMasterSecret
);
1460 return errSecSuccess
;
1463 #endif /* APPLE_DH */
1466 // MARK: ECDSA Key Exchange
1469 * Given the server's ECDH curve params and public key, generate our
1470 * own ECDH key pair, and perform key exchange using the server's
1471 * public key and our private key. The result is the premaster
1474 * SSLContext members valid on entry:
1475 * if keyExchangeMethod == SSL_ECDHE_ECDSA or SSL_ECDHE_RSA:
1478 * if keyExchangeMethod == SSL_ECDH_ECDSA or SSL_ECDH_RSA:
1479 * peerPubKey, from which we infer ecdhPeerCurve
1481 * SSLContext members valid on successful return:
1483 * ecdhExchangePublic
1487 SSLGenClientECDHKeyAndExchange(SSLContext
*ctx
)
1491 assert(ctx
->protocolSide
== kSSLClientSide
);
1493 switch(ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
1494 case SSL_ECDHE_ECDSA
:
1496 /* Server sent us an ephemeral key with peer curve specified */
1497 if(ctx
->ecdhPeerPublic
.data
== NULL
) {
1498 sslErrorLog("SSLGenClientECDHKeyAndExchange: incomplete server params\n");
1499 return errSSLProtocol
;
1502 case SSL_ECDH_ECDSA
:
1505 /* No server key exchange; we have to get the curve from the key */
1506 if(ctx
->peerPubKey
== NULL
) {
1507 sslErrorLog("SSLGenClientECDHKeyAndExchange: no peer key\n");
1508 return errSSLInternal
;
1511 /* The peer curve is in the key's CSSM_X509_ALGORITHM_IDENTIFIER... */
1512 ortn
= sslEcdsaPeerCurve(ctx
->peerPubKey
, &ctx
->ecdhPeerCurve
);
1516 sslEcdsaDebug("SSLGenClientECDHKeyAndExchange: derived peerCurve %u",
1517 (unsigned)ctx
->ecdhPeerCurve
);
1521 /* shouldn't be here */
1523 return errSSLInternal
;
1526 /* Generate our (ephemeral) pair, or extract it from our signing identity */
1527 if((ctx
->negAuthType
== SSLClientAuth_RSAFixedECDH
) ||
1528 (ctx
->negAuthType
== SSLClientAuth_ECDSAFixedECDH
)) {
1530 * Client auth with a fixed ECDH key in the cert. Convert private key
1531 * from SecKeyRef to CSSM format. We don't need ecdhExchangePublic
1532 * because the server gets that from our cert.
1534 assert(ctx
->signingPrivKeyRef
!= NULL
);
1536 //assert(ctx->cspHand != 0);
1537 sslFreeKey(ctx
->cspHand
, &ctx
->ecdhPrivate
, NULL
);
1538 SSLFreeBuffer(&ctx
->ecdhExchangePublic
);
1539 ortn
= SecKeyGetCSSMKey(ctx
->signingPrivKeyRef
, (const CSSM_KEY
**)&ctx
->ecdhPrivate
);
1543 ortn
= SecKeyGetCSPHandle(ctx
->signingPrivKeyRef
, &ctx
->ecdhPrivCspHand
);
1545 sslErrorLog("SSLGenClientECDHKeyAndExchange: SecKeyGetCSPHandle err %d\n",
1549 sslEcdsaDebug("+++ Extracted ECDH private key");
1552 /* generate a new pair */
1553 ortn
= sslEcdhGenerateKeyPair(ctx
, ctx
->ecdhPeerCurve
);
1558 sslEcdsaDebug("+++ Generated %u bit (%u byte) ECDH key pair",
1559 (unsigned)ctx
->ecdhPrivate
->KeyHeader
.LogicalKeySizeInBits
,
1560 (unsigned)((ctx
->ecdhPrivate
->KeyHeader
.LogicalKeySizeInBits
+ 7) / 8));
1565 /* do the exchange --> premaster secret */
1566 ortn
= sslEcdhKeyExchange(ctx
, &ctx
->preMasterSecret
);
1570 return errSecSuccess
;
1575 * Decode ECDH params and server public key.
1578 SSLDecodeECDHKeyParams(
1580 uint8_t **charPtr
, // IN/OUT
1583 OSStatus err
= errSecSuccess
;
1585 sslEcdsaDebug("+++ Decoding ECDH Server Key Exchange");
1587 assert(ctx
->protocolSide
== kSSLClientSide
);
1588 uint8_t *endCp
= *charPtr
+ length
;
1590 /* Allow reuse via renegotiation */
1591 SSLFreeBuffer(&ctx
->ecdhPeerPublic
);
1593 /*** ECParameters - just a curveType and a named curve ***/
1595 /* 1-byte curveType, we only allow one type */
1596 uint8_t curveType
= **charPtr
;
1597 if(curveType
!= SSL_CurveTypeNamed
) {
1598 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curveType (%u)\n", (unsigned)curveType
);
1599 return errSSLProtocol
;
1602 if(*charPtr
> endCp
) {
1603 return errSSLProtocol
;
1606 /* two-byte curve */
1607 ctx
->ecdhPeerCurve
= SSLDecodeInt(*charPtr
, 2);
1609 if(*charPtr
> endCp
) {
1610 return errSSLProtocol
;
1612 switch(ctx
->ecdhPeerCurve
) {
1613 case SSL_Curve_secp256r1
:
1614 case SSL_Curve_secp384r1
:
1615 case SSL_Curve_secp521r1
:
1618 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: Bad curve (%u)\n",
1619 (unsigned)ctx
->ecdhPeerCurve
);
1620 return errSSLProtocol
;
1623 sslEcdsaDebug("+++ SSLDecodeECDHKeyParams: ecdhPeerCurve %u",
1624 (unsigned)ctx
->ecdhPeerCurve
);
1626 /*** peer public key as an ECPoint ***/
1629 * The spec says the the max length of an ECPoint is 255 bytes, limiting
1630 * this whole mechanism to a max modulus size of 1020 bits, which I find
1631 * hard to believe...
1633 UInt32 len
= SSLDecodeInt(*charPtr
, 1);
1635 if((*charPtr
+ len
) > endCp
) {
1636 return errSSLProtocol
;
1638 err
= SSLAllocBuffer(&ctx
->ecdhPeerPublic
, len
);
1642 memmove(ctx
->ecdhPeerPublic
.data
, *charPtr
, len
);
1645 dumpBuf("client peer pub", &ctx
->ecdhPeerPublic
);
1652 SSLEncodeECDHClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1657 assert(ctx
->protocolSide
== kSSLClientSide
);
1658 if ((err
= SSLGenClientECDHKeyAndExchange(ctx
)) != 0)
1662 * Per RFC 4492 5.7, if we're doing ECDSA_fixed_ECDH or RSA_fixed_ECDH
1663 * client auth, we still send this message, but it's empty (because the
1664 * server gets our public key from our cert).
1666 bool emptyMsg
= false;
1667 switch(ctx
->negAuthType
) {
1668 case SSLClientAuth_RSAFixedECDH
:
1669 case SSLClientAuth_ECDSAFixedECDH
:
1679 outputLen
= ctx
->ecdhExchangePublic
.length
+ 1;
1682 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1683 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1684 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
1685 head
= SSLHandshakeHeaderSize(keyExchange
);
1686 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,outputLen
+ head
)))
1689 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1691 sslEcdsaDebug("+++ Sending EMPTY ECDH Client Key Exchange");
1694 /* just a 1-byte length here... */
1695 charPtr
= SSLEncodeSize(charPtr
, ctx
->ecdhExchangePublic
.length
, 1);
1696 memcpy(charPtr
, ctx
->ecdhExchangePublic
.data
, ctx
->ecdhExchangePublic
.length
);
1697 sslEcdsaDebug("+++ Encoded ECDH Client Key Exchange");
1700 dumpBuf("client pub key", &ctx
->ecdhExchangePublic
);
1701 dumpBuf("client premaster", &ctx
->preMasterSecret
);
1702 return errSecSuccess
;
1708 SSLDecodePSKClientKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1710 OSStatus ortn
= errSecSuccess
;
1711 unsigned int identityLen
;
1713 assert(ctx
->protocolSide
== kSSLServerSide
);
1715 /* this message simply contains the client's PSK identity */
1716 uint8_t *charPtr
= keyExchange
.data
;
1717 identityLen
= SSLDecodeInt(charPtr
, 2);
1720 SSLFreeBuffer(&ctx
->pskIdentity
); // allow reuse via renegotiation
1721 ortn
= SSLAllocBuffer(&ctx
->pskIdentity
, identityLen
);
1725 memmove(ctx
->pskIdentity
.data
, charPtr
, identityLen
);
1727 /* TODO: At this point we know the identity of the PSK client,
1728 we should break out of the handshake, so we can select the appropriate
1729 PreShared secret. As this stands, the preshared secret needs to be known
1730 before the handshake starts. */
1732 size_t n
=ctx
->pskSharedSecret
.length
;
1734 if(n
==0) return errSSLBadConfiguration
;
1736 if ((ortn
= SSLAllocBuffer(&ctx
->preMasterSecret
, 2*(n
+2))) != 0)
1739 uint8_t *p
=ctx
->preMasterSecret
.data
;
1741 p
= SSLEncodeInt(p
, n
, 2);
1742 memset(p
, 0, n
); p
+=n
;
1743 p
= SSLEncodeInt(p
, n
, 2);
1744 memcpy(p
, ctx
->pskSharedSecret
.data
, n
);
1746 dumpBuf("server premaster (PSK)", &ctx
->preMasterSecret
);
1753 SSLEncodePSKClientKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1759 assert(ctx
->protocolSide
== kSSLClientSide
);
1761 outputLen
= ctx
->pskIdentity
.length
+2;
1763 keyExchange
->contentType
= SSL_RecordTypeHandshake
;
1764 assert(ctx
->negProtocolVersion
>= SSL_Version_3_0
);
1765 keyExchange
->protocolVersion
= ctx
->negProtocolVersion
;
1766 head
= SSLHandshakeHeaderSize(keyExchange
);
1767 if ((err
= SSLAllocBuffer(&keyExchange
->contents
,outputLen
+ head
)))
1770 uint8_t *charPtr
= SSLEncodeHandshakeHeader(ctx
, keyExchange
, SSL_HdskClientKeyExchange
, outputLen
);
1772 charPtr
= SSLEncodeSize(charPtr
, ctx
->pskIdentity
.length
, 2);
1773 memcpy(charPtr
, ctx
->pskIdentity
.data
, ctx
->pskIdentity
.length
);
1776 /* We better have a pskSharedSecret already */
1777 size_t n
=ctx
->pskSharedSecret
.length
;
1779 if(n
==0) return errSSLBadConfiguration
;
1781 if ((err
= SSLAllocBuffer(&ctx
->preMasterSecret
, 2*(n
+2))) != 0)
1784 uint8_t *p
=ctx
->preMasterSecret
.data
;
1786 p
= SSLEncodeInt(p
, n
, 2);
1787 memset(p
, 0, n
); p
+=n
;
1788 p
= SSLEncodeInt(p
, n
, 2);
1789 memcpy(p
, ctx
->pskSharedSecret
.data
, n
);
1791 dumpBuf("client premaster (PSK)", &ctx
->preMasterSecret
);
1793 return errSecSuccess
;
1798 // MARK: Public Functions
1800 SSLEncodeServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
1803 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
)
1805 case SSL_RSA_EXPORT
:
1808 case SSL_DHE_RSA_EXPORT
:
1810 case SSL_DHE_DSS_EXPORT
:
1811 #endif /* APPLE_DH */
1812 if ((err
= SSLEncodeSignedServerKeyExchange(keyExch
, ctx
)) != 0)
1817 case SSL_DH_anon_EXPORT
:
1818 if ((err
= SSLEncodeDHanonServerKeyExchange(keyExch
, ctx
)) != 0)
1823 return errSecUnimplemented
;
1826 return errSecSuccess
;
1830 SSLProcessServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
1834 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
1836 case SSL_RSA_EXPORT
:
1839 case SSL_DHE_RSA_EXPORT
:
1841 case SSL_DHE_DSS_EXPORT
:
1843 case SSL_ECDHE_ECDSA
:
1845 err
= SSLDecodeSignedServerKeyExchange(message
, ctx
);
1849 case SSL_DH_anon_EXPORT
:
1850 err
= SSLDecodeDHanonServerKeyExchange(message
, ctx
);
1854 err
= errSecUnimplemented
;
1862 SSLEncodeKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1865 assert(ctx
->protocolSide
== kSSLClientSide
);
1867 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
) {
1869 case SSL_RSA_EXPORT
:
1870 sslDebugLog("SSLEncodeKeyExchange: RSA method\n");
1871 err
= SSLEncodeRSAKeyExchange(keyExchange
, ctx
);
1875 case SSL_DHE_RSA_EXPORT
:
1877 case SSL_DHE_DSS_EXPORT
:
1879 case SSL_DH_anon_EXPORT
:
1880 sslDebugLog("SSLEncodeKeyExchange: DH method\n");
1881 err
= SSLEncodeDHClientKeyExchange(keyExchange
, ctx
);
1884 case SSL_ECDH_ECDSA
:
1885 case SSL_ECDHE_ECDSA
:
1889 sslDebugLog("SSLEncodeKeyExchange: ECDH method\n");
1890 err
= SSLEncodeECDHClientKeyExchange(keyExchange
, ctx
);
1893 err
= SSLEncodePSKClientKeyExchange(keyExchange
, ctx
);
1896 sslErrorLog("SSLEncodeKeyExchange: unknown method (%d)\n",
1897 ctx
->selectedCipherSpecParams
.keyExchangeMethod
);
1898 err
= errSecUnimplemented
;
1905 SSLProcessKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
1908 switch (ctx
->selectedCipherSpecParams
.keyExchangeMethod
)
1910 case SSL_RSA_EXPORT
:
1911 if ((err
= SSLDecodeRSAKeyExchange(keyExchange
, ctx
)) != 0)
1917 case SSL_DHE_DSS_EXPORT
:
1919 case SSL_DHE_RSA_EXPORT
:
1920 case SSL_DH_anon_EXPORT
:
1921 sslDebugLog("SSLProcessKeyExchange: processing DH key exchange (%d)\n",
1922 ctx
->selectedCipherSpecParams
.keyExchangeMethod
);
1923 if ((err
= SSLDecodeDHClientKeyExchange(keyExchange
, ctx
)) != 0)
1928 if ((err
= SSLDecodePSKClientKeyExchange(keyExchange
, ctx
)) != 0)
1932 sslErrorLog("SSLProcessKeyExchange: unknown keyExchangeMethod (%d)\n",
1933 ctx
->selectedCipherSpecParams
.keyExchangeMethod
);
1934 return errSecUnimplemented
;
1937 return errSecSuccess
;
1941 SSLInitPendingCiphers(SSLContext
*ctx
)
1946 err
= errSecSuccess
;
1949 keyDataLen
= ctx
->selectedCipherSpecParams
.macSize
+
1950 ctx
->selectedCipherSpecParams
.keySize
+
1951 ctx
->selectedCipherSpecParams
.ivSize
;
1952 keyDataLen
*= 2; /* two of everything */
1954 if ((err
= SSLAllocBuffer(&key
, keyDataLen
)))
1956 assert(ctx
->sslTslCalls
!= NULL
);
1957 if ((err
= ctx
->sslTslCalls
->generateKeyMaterial(key
, ctx
)) != 0)
1960 if((err
= ctx
->recFuncs
->initPendingCiphers(ctx
->recCtx
, ctx
->selectedCipher
, (ctx
->protocolSide
==kSSLServerSide
), key
)) != 0)
1963 ctx
->writePending_ready
= 1;
1964 ctx
->readPending_ready
= 1;
1967 SSLFreeBuffer(&key
);