2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
22 Contains: Support for key exchange and server key exchange
24 Written by: Doug Mitchell, based on Netscape SSLRef 3.0
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
29 /* *********************************************************************
32 SSLRef 3.0 Final -- 11/19/96
34 Copyright (c)1996 by Netscape Communications Corp.
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
44 *********************************************************************
46 File: hdskkyex.c Support for key exchange and server key exchange
48 Encoding and decoding of key exchange and server key exchange
49 messages in both the Diffie-Hellman and RSA variants; also, includes
50 the necessary crypto library calls to support this negotiation.
52 ****************************************************************** */
74 #ifndef _APPLE_CDSA_H_
75 #include "appleCdsa.h"
86 * For this config, just for this file, we'll do this typedef....
88 typedef CSSM_KEY_PTR SSLRSAPrivateKey
;
91 static SSLErr
SSLEncodeRSAServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
);
92 static SSLErr
SSLEncodeRSAKeyParams(SSLBuffer
*keyParams
, SSLRSAPrivateKey
*key
, SSLContext
*ctx
);
93 static SSLErr
SSLProcessRSAServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
);
94 static SSLErr
SSLDecodeRSAKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
);
95 static SSLErr
SSLEncodeRSAKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
);
97 static SSLErr
SSLEncodeDHanonServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
);
98 static SSLErr
SSLEncodeDHanonKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
);
99 static SSLErr
SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
);
100 static SSLErr
SSLProcessDHanonServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
);
104 SSLEncodeServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
107 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
110 if (ERR(err
= SSLEncodeRSAServerKeyExchange(keyExch
, ctx
)) != 0)
115 if (ERR(err
= SSLEncodeDHanonServerKeyExchange(keyExch
, ctx
)) != 0)
120 return ERR(SSLUnsupportedErr
);
127 SSLEncodeRSAServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
131 UInt32 outputLen
, localKeyModulusLen
;
133 SSLBuffer exportKey
,clientRandom
,serverRandom
,hashCtx
, hash
;
139 /* we have a public key here... */
140 CASSERT(ctx
->encryptPubKey
!= NULL
);
141 CASSERT(ctx
->protocolSide
== SSL_ServerSide
);
143 if ((err
= SSLEncodeRSAKeyParams(&exportKey
, &ctx
->encryptPubKey
, ctx
)) != 0)
145 if (ERR(err
= SSLEncodeRSAKeyParams(&exportKey
, &ctx
->exportKey
, ctx
)) != 0)
150 localKeyModulusLen
= (ctx
->localKey
.bits
+ 7)/8;
152 { A_RSA_KEY
*keyInfo
;
155 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, ctx
->localKey
, KI_RSAPublic
)) != 0)
156 return SSLUnknownErr
;
157 localKeyModulusLen
= keyInfo
->modulus
.len
;
160 CASSERT(ctx
->signingPubKey
!= NULL
);
161 localKeyModulusLen
= sslKeyLengthInBytes(ctx
->signingPubKey
);
163 #error No Asymmetric crypto specified
164 #endif /* RSAREF / BSAFE */
166 length
= exportKey
.length
+ 2 + localKeyModulusLen
; /* RSA ouputs a block as long as the modulus */
168 keyExch
->protocolVersion
= SSL_Version_3_0
;
169 keyExch
->contentType
= SSL_handshake
;
170 if (ERR(err
= SSLAllocBuffer(&keyExch
->contents
, length
+4, &ctx
->sysCtx
)) != 0)
173 progress
= keyExch
->contents
.data
;
174 *progress
++ = SSL_server_key_exchange
;
175 progress
= SSLEncodeInt(progress
, length
, 3);
177 memcpy(progress
, exportKey
.data
, exportKey
.length
);
178 progress
+= exportKey
.length
;
180 clientRandom
.data
= ctx
->clientRandom
;
181 clientRandom
.length
= 32;
182 serverRandom
.data
= ctx
->serverRandom
;
183 serverRandom
.length
= 32;
185 hash
.data
= &hashes
[0];
187 if (ERR(err
= ReadyHash(&SSLHashMD5
, &hashCtx
, ctx
)) != 0)
189 if (ERR(err
= SSLHashMD5
.update(hashCtx
, clientRandom
)) != 0)
191 if (ERR(err
= SSLHashMD5
.update(hashCtx
, serverRandom
)) != 0)
193 if (ERR(err
= SSLHashMD5
.update(hashCtx
, exportKey
)) != 0)
195 if (ERR(err
= SSLHashMD5
.final(hashCtx
, hash
)) != 0)
197 if (ERR(err
= SSLFreeBuffer(&hashCtx
, &ctx
->sysCtx
)) != 0)
200 hash
.data
= &hashes
[16];
202 if (ERR(err
= ReadyHash(&SSLHashSHA1
, &hashCtx
, ctx
)) != 0)
204 if (ERR(err
= SSLHashSHA1
.update(hashCtx
, clientRandom
)) != 0)
206 if (ERR(err
= SSLHashSHA1
.update(hashCtx
, serverRandom
)) != 0)
208 if (ERR(err
= SSLHashSHA1
.update(hashCtx
, exportKey
)) != 0)
210 if (ERR(err
= SSLHashSHA1
.final(hashCtx
, hash
)) != 0)
212 if (ERR(err
= SSLFreeBuffer(&hashCtx
, &ctx
->sysCtx
)) != 0)
215 progress
= SSLEncodeInt(progress
, localKeyModulusLen
, 2);
217 if (RSAPrivateEncrypt(progress
, &outputLen
, hashes
, 36, &ctx
->localKey
) != 0) /* Sign the structure */
218 return ERR(SSLUnknownErr
);
220 { B_ALGORITHM_OBJ rsa
;
221 B_ALGORITHM_METHOD
*chooser
[] = { &AM_RSA_ENCRYPT
, &AM_RSA_CRT_ENCRYPT
, 0 };
225 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
226 return SSLUnknownErr
;
227 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPrivate
, 0)) != 0)
228 return SSLUnknownErr
;
229 if ((rsaResult
= B_EncryptInit(rsa
, ctx
->localKey
, chooser
, NO_SURR
)) != 0)
230 return SSLUnknownErr
;
231 if ((rsaResult
= B_EncryptUpdate(rsa
, progress
,
232 &encryptedOut
, localKeyModulusLen
, hashes
, 36, 0, NO_SURR
)) != 0)
233 return SSLUnknownErr
;
234 outputLen
= encryptedOut
;
235 if ((rsaResult
= B_EncryptFinal(rsa
, progress
+outputLen
,
236 &encryptedOut
, localKeyModulusLen
-outputLen
, 0, NO_SURR
)) != 0)
237 return SSLUnknownErr
;
238 outputLen
+= encryptedOut
;
239 B_DestroyAlgorithmObject(&rsa
);
242 err
= sslRsaRawSign(ctx
,
253 #endif /* RSAREF / BSAFE */
254 CASSERT(outputLen
== localKeyModulusLen
);
259 ERR(SSLFreeBuffer(&hashCtx
, &ctx
->sysCtx
));
260 ERR(SSLFreeBuffer(&exportKey
, &ctx
->sysCtx
));
266 SSLEncodeRSAKeyParams(SSLBuffer
*keyParams
, SSLRSAPrivateKey
*key
, SSLContext
*ctx
)
268 SSLBuffer modulus
, exponent
;
273 modulus
.length
= (key
->bits
+ 7) / 8;
274 modulus
.data
= key
->modulus
+ MAX_RSA_MODULUS_LEN
- modulus
.length
;
276 exponent
.length
= MAX_RSA_MODULUS_LEN
;
277 exponent
.data
= key
->publicExponent
; /* Point at first byte */
279 while (*exponent
.data
== 0)
284 { A_RSA_KEY
*keyInfo
;
287 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, *key
, KI_RSAPublic
)) != 0)
288 return SSLUnknownErr
;
289 modulus
.data
= keyInfo
->modulus
.data
;
290 modulus
.length
= keyInfo
->modulus
.len
;
291 exponent
.data
= keyInfo
->exponent
.data
;
292 exponent
.length
= keyInfo
->exponent
.len
;
295 err
= sslGetPubKeyBits(ctx
,
301 SSLFreeBuffer(&modulus
, &ctx
->sysCtx
);
302 SSLFreeBuffer(&exponent
, &ctx
->sysCtx
);
306 #error No assymetric crypto specified
307 #endif /* RSAREF / BSAFE */
309 if (ERR(err
= SSLAllocBuffer(keyParams
, modulus
.length
+ exponent
.length
+ 4, &ctx
->sysCtx
)) != 0)
311 progress
= keyParams
->data
;
312 progress
= SSLEncodeInt(progress
, modulus
.length
, 2);
313 memcpy(progress
, modulus
.data
, modulus
.length
);
314 progress
+= modulus
.length
;
315 progress
= SSLEncodeInt(progress
, exponent
.length
, 2);
316 memcpy(progress
, exponent
.data
, exponent
.length
);
319 /* these were mallocd by sslGetPubKeyBits() */
320 SSLFreeBuffer(&modulus
, &ctx
->sysCtx
);
321 SSLFreeBuffer(&exponent
, &ctx
->sysCtx
);
328 SSLEncodeDHanonServerKeyExchange(SSLRecord
*keyExch
, SSLContext
*ctx
)
336 length
= 6 + ctx
->dhAnonParams
.primeLen
+ ctx
->dhAnonParams
.generatorLen
+
337 ctx
->dhExchangePublic
.length
;
339 keyExch
->protocolVersion
= SSL_Version_3_0
;
340 keyExch
->contentType
= SSL_handshake
;
341 if (ERR(err
= SSLAllocBuffer(&keyExch
->contents
, length
+4, &ctx
->sysCtx
)) != 0)
344 progress
= keyExch
->contents
.data
;
345 *progress
++ = SSL_server_key_exchange
;
346 progress
= SSLEncodeInt(progress
, length
, 3);
348 progress
= SSLEncodeInt(progress
, ctx
->dhAnonParams
.primeLen
, 2);
349 memcpy(progress
, ctx
->dhAnonParams
.prime
, ctx
->dhAnonParams
.primeLen
);
350 progress
+= ctx
->dhAnonParams
.primeLen
;
352 progress
= SSLEncodeInt(progress
, ctx
->dhAnonParams
.generatorLen
, 2);
353 memcpy(progress
, ctx
->dhAnonParams
.generator
, ctx
->dhAnonParams
.generatorLen
);
354 progress
+= ctx
->dhAnonParams
.generatorLen
;
356 if (ERR(err
= SSLAllocBuffer(&ctx
->dhExchangePublic
, ctx
->peerDHParams
.primeLen
, &ctx
->sysCtx
)) != 0)
358 if (ERR(err
= SSLAllocBuffer(&ctx
->dhPrivate
, ctx
->dhExchangePublic
.length
- 16, &ctx
->sysCtx
)) != 0)
361 if (ERR(err
= ReadyRandom(&random
, ctx
)) != 0)
364 if ((rsaErr
= R_SetupDHAgreement(ctx
->dhExchangePublic
.data
, ctx
->dhPrivate
.data
,
365 ctx
->dhPrivate
.length
, &ctx
->dhAnonParams
, &random
)) != 0)
366 { err
= SSLUnknownErr
;
370 progress
= SSLEncodeInt(progress
, ctx
->dhExchangePublic
.length
, 2);
371 memcpy(progress
, ctx
->dhExchangePublic
.data
, ctx
->dhExchangePublic
.length
);
372 progress
+= ctx
->dhExchangePublic
.length
;
375 { A_DH_KEY_AGREE_PARAMS
*params
;
376 unsigned int outputLen
;
378 if ((rsaErr
= B_GetAlgorithmInfo((POINTER
*)¶ms
, ctx
->dhAnonParams
, AI_DHKeyAgree
)) != 0)
379 return SSLUnknownErr
;
380 if (ERR(err
= ReadyRandom(&random
, ctx
)) != 0)
382 if (ERR(err
= SSLAllocBuffer(&ctx
->dhExchangePublic
, 128, &ctx
->sysCtx
)) != 0)
384 if ((rsaErr
= B_KeyAgreePhase1(ctx
->dhAnonParams
, ctx
->dhExchangePublic
.data
,
385 &outputLen
, 128, random
, NO_SURR
)) != 0)
386 { err
= SSLUnknownErr
;
389 ctx
->dhExchangePublic
.length
= outputLen
;
391 length
= 6 + params
->prime
.len
+ params
->base
.len
+ ctx
->dhExchangePublic
.length
;
393 keyExch
->protocolVersion
= SSL_Version_3_0
;
394 keyExch
->contentType
= SSL_handshake
;
395 if (ERR(err
= SSLAllocBuffer(&keyExch
->contents
, length
+4, &ctx
->sysCtx
)) != 0)
398 progress
= keyExch
->contents
.data
;
399 *progress
++ = SSL_server_key_exchange
;
400 progress
= SSLEncodeInt(progress
, length
, 3);
402 progress
= SSLEncodeInt(progress
, params
->prime
.len
, 2);
403 memcpy(progress
, params
->prime
.data
, params
->prime
.len
);
404 progress
+= params
->prime
.len
;
406 progress
= SSLEncodeInt(progress
, params
->base
.len
, 2);
407 memcpy(progress
, params
->base
.data
, params
->base
.len
);
408 progress
+= params
->base
.len
;
410 progress
= SSLEncodeInt(progress
, ctx
->dhExchangePublic
.length
, 2);
411 memcpy(progress
, ctx
->dhExchangePublic
.data
, ctx
->dhExchangePublic
.length
);
412 progress
+= ctx
->dhExchangePublic
.length
;
414 #endif /* RSAREF / BSAFE */
416 ASSERT(progress
== keyExch
->contents
.data
+ keyExch
->contents
.length
);
421 #endif /* APPLE_DH */
424 SSLProcessServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
427 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
430 if (ERR(err
= SSLProcessRSAServerKeyExchange(message
, ctx
)) != 0)
435 if (ERR(err
= SSLProcessDHanonServerKeyExchange(message
, ctx
)) != 0)
440 return ERR(SSLUnsupportedErr
);
447 SSLProcessRSAServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
450 SSLBuffer tempPubKey
, hashOut
, hashCtx
, clientRandom
, serverRandom
;
451 UInt16 modulusLen
, exponentLen
, signatureLen
;
452 UInt8
*progress
, *modulus
, *exponent
, *signature
;
458 #endif /* _APPLE_CDSA_ */
459 SSLBuffer signedHashes
;
461 signedHashes
.data
= 0;
464 if (message
.length
< 2) {
465 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
466 return ERR(SSLProtocolErr
);
468 progress
= message
.data
;
469 modulusLen
= SSLDecodeInt(progress
, 2);
470 modulus
= progress
+ 2;
471 progress
+= 2+modulusLen
;
472 if (message
.length
< 4 + modulusLen
) {
473 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
474 return ERR(SSLProtocolErr
);
476 exponentLen
= SSLDecodeInt(progress
, 2);
477 exponent
= progress
+ 2;
478 progress
+= 2+exponentLen
;
479 if (message
.length
< 6 + modulusLen
+ exponentLen
) {
480 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 2\n");
481 return ERR(SSLProtocolErr
);
483 signatureLen
= SSLDecodeInt(progress
, 2);
484 signature
= progress
+ 2;
485 if (message
.length
!= 6 + modulusLen
+ exponentLen
+ signatureLen
) {
486 errorLog0("SSLProcessRSAServerKeyExchange: msg len error 3\n");
487 return ERR(SSLProtocolErr
);
491 { /* Allocate room for the signed hashes; RSA can encrypt data
492 as long as the modulus */
493 if (ERR(err
= SSLAllocBuffer(&signedHashes
, (ctx
->peerKey
.bits
+ 7)/8, &ctx
->sysCtx
)) != 0)
496 if ((RSAPublicDecrypt(signedHashes
.data
, &outputLen
, signature
, signatureLen
,
497 &ctx
->peerKey
)) != 0)
498 { ERR(err
= SSLUnknownErr
);
503 { B_ALGORITHM_OBJ rsa
;
504 B_ALGORITHM_METHOD
*chooser
[] = { &AM_MD2
, &AM_MD5
, &AM_RSA_DECRYPT
, 0 };
506 unsigned int decryptLen
;
508 /* Allocate room for the signed hashes; BSAFE makes sure we don't decode too much data */
509 if (ERR(err
= SSLAllocBuffer(&signedHashes
, 36, &ctx
->sysCtx
)) != 0)
512 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
513 return SSLUnknownErr
;
514 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPublic
, 0)) != 0)
515 return SSLUnknownErr
;
516 if ((rsaResult
= B_DecryptInit(rsa
, ctx
->peerKey
, chooser
, NO_SURR
)) != 0)
517 return SSLUnknownErr
;
518 if ((rsaResult
= B_DecryptUpdate(rsa
, signedHashes
.data
, &decryptLen
, 36,
519 signature
, signatureLen
, 0, NO_SURR
)) != 0)
520 return SSLUnknownErr
;
521 outputLen
= decryptLen
;
522 if ((rsaResult
= B_DecryptFinal(rsa
, signedHashes
.data
+outputLen
,
523 &decryptLen
, 36-outputLen
, 0, NO_SURR
)) != 0)
524 return SSLUnknownErr
;
525 outputLen
+= decryptLen
;
526 B_DestroyAlgorithmObject(&rsa
);
530 /* not yet - calculate the hashes and then do a sig verify */
533 #error No Asymmetric crypto module
538 { ERR(err
= SSLProtocolErr
);
543 clientRandom
.data
= ctx
->clientRandom
;
544 clientRandom
.length
= 32;
545 serverRandom
.data
= ctx
->serverRandom
;
546 serverRandom
.length
= 32;
547 tempPubKey
.data
= message
.data
;
548 tempPubKey
.length
= modulusLen
+ exponentLen
+ 4;
552 if (ERR(err
= ReadyHash(&SSLHashMD5
, &hashCtx
, ctx
)) != 0)
554 if (ERR(err
= SSLHashMD5
.update(hashCtx
, clientRandom
)) != 0)
556 if (ERR(err
= SSLHashMD5
.update(hashCtx
, serverRandom
)) != 0)
558 if (ERR(err
= SSLHashMD5
.update(hashCtx
, tempPubKey
)) != 0)
560 if (ERR(err
= SSLHashMD5
.final(hashCtx
, hashOut
)) != 0)
565 * SHA hash goes right after the MD5 hash
567 hashOut
.data
= hash
+ 16;
569 if ((memcmp(hash
, signedHashes
.data
, 16)) != 0)
570 { ERR(err
= SSLProtocolErr
);
573 #endif /* _APPLE_CDSA_ */
576 if (ERR(err
= SSLFreeBuffer(&hashCtx
, &ctx
->sysCtx
)) != 0)
579 if (ERR(err
= ReadyHash(&SSLHashSHA1
, &hashCtx
, ctx
)) != 0)
581 if (ERR(err
= SSLHashSHA1
.update(hashCtx
, clientRandom
)) != 0)
583 if (ERR(err
= SSLHashSHA1
.update(hashCtx
, serverRandom
)) != 0)
585 if (ERR(err
= SSLHashSHA1
.update(hashCtx
, tempPubKey
)) != 0)
587 if (ERR(err
= SSLHashSHA1
.final(hashCtx
, hashOut
)) != 0)
592 err
= sslRsaRawVerify(ctx
,
595 hash
, /* plaintext */
596 36, /* plaintext length */
600 errorLog1("SSLProcessRSAServerKeyExchange: sslRsaRawVerify returned %d\n",
605 #else /* old BSAFE/RSAREF */
607 if ((memcmp(hash
, signedHashes
.data
+ 16, 20)) != 0)
608 { ERR(err
= SSLProtocolErr
);
614 /* Signature matches; now replace server key with new key */
616 memset(&ctx
->peerKey
, 0, sizeof(R_RSA_PUBLIC_KEY
));
617 memcpy(ctx
->peerKey
.modulus
+ (MAX_RSA_MODULUS_LEN
- modulusLen
),
618 modulus
, modulusLen
);
619 memcpy(ctx
->peerKey
.exponent
+ (MAX_RSA_MODULUS_LEN
- exponentLen
),
620 exponent
, exponentLen
);
622 /* Adjust bit length for leading zeros in value; assume no more than 8 leading zero bits */
623 { unsigned int bitAdjust
;
633 ctx
->peerKey
.bits
= modulusLen
* 8 - bitAdjust
;
637 { A_RSA_KEY pubKeyInfo
;
640 pubKeyInfo
.modulus
.data
= modulus
;
641 pubKeyInfo
.modulus
.len
= modulusLen
;
642 pubKeyInfo
.exponent
.data
= exponent
;
643 pubKeyInfo
.exponent
.len
= exponentLen
;
645 if ((rsaErr
= B_CreateKeyObject(&ctx
->peerKey
)) != 0)
646 return SSLUnknownErr
;
647 if ((rsaErr
= B_SetKeyInfo(ctx
->peerKey
, KI_RSAPublic
, (POINTER
)&pubKeyInfo
)) != 0)
648 return SSLUnknownErr
;
656 /* first free existing peerKey */
657 sslFreeKey(ctx
->peerPubKeyCsp
,
659 NULL
); /* no KCItem */
661 /* and cook up a new one from raw bits */
662 modBuf
.data
= modulus
;
663 modBuf
.length
= modulusLen
;
664 expBuf
.data
= exponent
;
665 expBuf
.length
= exponentLen
;
666 err
= sslGetPubKeyFromBits(ctx
,
670 &ctx
->peerPubKeyCsp
);
673 #error No Assymmetric crypto module
674 #endif /* RSAREF / BSAFE */
676 ERR(SSLFreeBuffer(&signedHashes
, &ctx
->sysCtx
));
677 ERR(SSLFreeBuffer(&hashCtx
, &ctx
->sysCtx
));
683 SSLProcessDHanonServerKeyExchange(SSLBuffer message
, SSLContext
*ctx
)
686 unsigned int totalLength
;
688 if (message
.length
< 6) {
689 errorLog1("SSLProcessDHanonServerKeyExchange error: msg len %d\n",
691 return ERR(SSLProtocolErr
);
693 progress
= message
.data
;
698 UInt8
*prime
, *generator
, *publicVal
;
700 ctx
->peerDHParams
.primeLen
= SSLDecodeInt(progress
, 2);
703 progress
+= ctx
->peerDHParams
.primeLen
;
704 totalLength
+= ctx
->peerDHParams
.primeLen
;
705 if (message
.length
< 6 + totalLength
)
706 return ERR(SSLProtocolErr
);
708 ctx
->peerDHParams
.generatorLen
= SSLDecodeInt(progress
, 2);
710 generator
= progress
;
711 progress
+= ctx
->peerDHParams
.generatorLen
;
712 totalLength
+= ctx
->peerDHParams
.generatorLen
;
713 if (message
.length
< 6 + totalLength
)
714 return ERR(SSLProtocolErr
);
716 ctx
->dhPeerPublic
.length
= SSLDecodeInt(progress
, 2);
718 publicVal
= progress
;
719 progress
+= ctx
->dhPeerPublic
.length
;
720 totalLength
+= ctx
->dhPeerPublic
.length
;
721 if (message
.length
!= 6 + totalLength
)
722 return ERR(SSLProtocolErr
);
724 ASSERT(progress
== message
.data
+ message
.length
);
726 if (ERR(err
= SSLAllocBuffer(&alloc
, ctx
->peerDHParams
.primeLen
+
727 ctx
->peerDHParams
.generatorLen
, &ctx
->sysCtx
)) != 0)
730 ctx
->peerDHParams
.prime
= alloc
.data
;
731 memcpy(ctx
->peerDHParams
.prime
, prime
, ctx
->peerDHParams
.primeLen
);
732 ctx
->peerDHParams
.generator
= alloc
.data
+ ctx
->peerDHParams
.primeLen
;
733 memcpy(ctx
->peerDHParams
.generator
, generator
, ctx
->peerDHParams
.generatorLen
);
735 if (ERR(err
= SSLAllocBuffer(&ctx
->dhPeerPublic
,
736 ctx
->dhPeerPublic
.length
, &ctx
->sysCtx
)) != 0)
739 memcpy(ctx
->dhPeerPublic
.data
, publicVal
, ctx
->dhPeerPublic
.length
);
743 unsigned char *publicVal
;
744 A_DH_KEY_AGREE_PARAMS params
;
745 B_ALGORITHM_METHOD
*chooser
[] = { &AM_DH_KEY_AGREE
, 0 };
747 params
.prime
.len
= SSLDecodeInt(progress
, 2);
749 params
.prime
.data
= progress
;
750 progress
+= params
.prime
.len
;
751 totalLength
+= params
.prime
.len
;
752 if (message
.length
< 6 + totalLength
)
753 return ERR(SSLProtocolErr
);
755 params
.base
.len
= SSLDecodeInt(progress
, 2);
757 params
.base
.data
= progress
;
758 progress
+= params
.base
.len
;
759 totalLength
+= params
.base
.len
;
760 if (message
.length
< 6 + totalLength
)
761 return ERR(SSLProtocolErr
);
763 ctx
->dhPeerPublic
.length
= SSLDecodeInt(progress
, 2);
764 if (ERR(err
= SSLAllocBuffer(&ctx
->dhPeerPublic
, ctx
->dhPeerPublic
.length
, &ctx
->sysCtx
)) != 0)
768 publicVal
= progress
;
769 progress
+= ctx
->dhPeerPublic
.length
;
770 totalLength
+= ctx
->dhPeerPublic
.length
;
771 memcpy(ctx
->dhPeerPublic
.data
, publicVal
, ctx
->dhPeerPublic
.length
);
772 if (message
.length
!= 6 + totalLength
)
773 return ERR(SSLProtocolErr
);
775 params
.exponentBits
= 8 * ctx
->dhPeerPublic
.length
- 1;
777 if ((rsaErr
= B_CreateAlgorithmObject(&ctx
->peerDHParams
)) != 0)
778 return SSLUnknownErr
;
779 if ((rsaErr
= B_SetAlgorithmInfo(ctx
->peerDHParams
, AI_DHKeyAgree
, (POINTER
)¶ms
)) != 0)
780 return SSLUnknownErr
;
781 if ((rsaErr
= B_KeyAgreeInit(ctx
->peerDHParams
, (B_KEY_OBJ
) 0, chooser
, NO_SURR
)) != 0)
782 return SSLUnknownErr
;
792 SSLProcessKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
795 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
798 if (ERR(err
= SSLDecodeRSAKeyExchange(keyExchange
, ctx
)) != 0)
803 if (ERR(err
= SSLDecodeDHanonKeyExchange(keyExchange
, ctx
)) != 0)
808 return ERR(SSLUnsupportedErr
);
815 SSLDecodeRSAKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
818 UInt32 outputLen
, localKeyModulusLen
;
819 SSLRSAPrivateKey
*key
;
820 SSLProtocolVersion version
;
821 Boolean useEncryptKey
= false;
825 /* different key names, also need CSP handle */
826 CSSM_CSP_HANDLE cspHand
;
828 CASSERT(ctx
->protocolSide
== SSL_ServerSide
);
831 * FIXME - The original SSLRef looked at
832 * ctx->selectedCipherSpec->keyExchangeMethod to decide which
833 * key to use (exportKey or localKey). I really don't think we
834 * want to use that - it's constant. We need to look at
835 * whether the app specified encrypting certs, right?
837 #if SSL_SERVER_KEYEXCH_HACK
839 * the way we work with Netscape.
840 * FIXME - maybe we should *require* an encryptPrivKey in this
843 if((ctx
->selectedCipherSpec
->keyExchangeMethod
== SSL_RSA_EXPORT
) &&
844 (ctx
->encryptPrivKey
!= NULL
)) {
845 useEncryptKey
= true;
848 #else /* !SSL_SERVER_KEYEXCH_HACK */
849 /* The "correct" way, I think, which doesn't work with Netscape */
850 if (ctx
->encryptPrivKey
) {
851 useEncryptKey
= true;
853 #endif /* SSL_SERVER_KEYEXCH_HACK */
855 key
= &ctx
->encryptPrivKey
;
856 cspHand
= ctx
->encryptKeyCsp
;
859 key
= &ctx
->signingPrivKey
;
860 cspHand
= ctx
->signingKeyCsp
;
862 #else /* original SSLRef3 */
863 if (ctx
->selectedCipherSpec
->keyExchangeMethod
== SSL_RSA_EXPORT
)
864 key
= &ctx
->exportKey
;
866 key
= &ctx
->localKey
;
867 #endif /* _APPLE_CDSA_ */
871 localKeyModulusLen
= (key
->bits
+ 7)/8;
873 { A_RSA_KEY
*keyInfo
;
876 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, *key
, KI_RSAPublic
)) != 0)
877 return SSLUnknownErr
;
878 localKeyModulusLen
= keyInfo
->modulus
.len
;
881 localKeyModulusLen
= sslKeyLengthInBytes(*key
);
883 #error No assymetric crypto module
884 #endif /* RSAREF / BSAFE */
886 if (keyExchange
.length
!= localKeyModulusLen
) {
887 errorLog0("SSLDecodeRSAKeyExchange: length error\n");
888 return ERR(SSLProtocolErr
);
892 if (ERR(err
= SSLAllocBuffer(&result
, localKeyModulusLen
, &ctx
->sysCtx
)) != 0)
894 if ((RSAPrivateDecrypt(result
.data
, &outputLen
, keyExchange
.data
, keyExchange
.length
, key
)) != 0)
895 { ERR(err
= SSLUnknownErr
);
899 { B_ALGORITHM_OBJ rsa
;
900 B_ALGORITHM_METHOD
*chooser
[] = { &AM_RSA_DECRYPT
, &AM_RSA_CRT_DECRYPT
, 0 };
902 unsigned int decryptLen
;
904 /* Allocate room for the premaster secret; BSAFE makes sure we don't decode too much data */
905 if (ERR(err
= SSLAllocBuffer(&result
, 48, &ctx
->sysCtx
)) != 0)
908 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
909 return SSLUnknownErr
;
910 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPrivate
, 0)) != 0)
911 return SSLUnknownErr
;
914 * I think this is an SSLRef bug - we need to use the right key here,
915 * as the RSAREF case above does!
917 if ((rsaResult
= B_DecryptInit(rsa
, *key
, chooser
, NO_SURR
)) != 0)
918 return SSLUnknownErr
;
919 #else /* the SSLRef way */
920 if ((rsaResult
= B_DecryptInit(rsa
, ctx
->localKey
, chooser
, NO_SURR
)) != 0)
921 return SSLUnknownErr
;
922 #endif /* mac/SSLREF */
923 if ((rsaResult
= B_DecryptUpdate(rsa
, result
.data
, &decryptLen
, 48,
924 keyExchange
.data
, keyExchange
.length
, 0, NO_SURR
)) != 0)
925 return SSLUnknownErr
;
926 outputLen
= decryptLen
;
927 if ((rsaResult
= B_DecryptFinal(rsa
, result
.data
+outputLen
,
928 &decryptLen
, 48-outputLen
, 0, NO_SURR
)) != 0)
929 return SSLUnknownErr
;
930 outputLen
+= decryptLen
;
931 B_DestroyAlgorithmObject(&rsa
);
934 err
= sslRsaDecrypt(ctx
,
949 errorLog0("SSLDecodeRSAKeyExchange: outputLen error\n");
950 ERR(err
= SSLProtocolErr
);
953 result
.length
= outputLen
;
955 version
= (SSLProtocolVersion
)SSLDecodeInt(result
.data
, 2);
956 /* Modify this check to check against our maximum version with protocol revisions */
957 if (version
> ctx
->negProtocolVersion
&& version
< SSL_Version_3_0
) {
958 errorLog0("SSLDecodeRSAKeyExchange: version error\n");
959 ERR(err
= SSLProtocolErr
);
962 if (ERR(err
= SSLAllocBuffer(&ctx
->preMasterSecret
, 48, &ctx
->sysCtx
)) != 0)
964 memcpy(ctx
->preMasterSecret
.data
, result
.data
, 48);
968 ERR(SSLFreeBuffer(&result
, &ctx
->sysCtx
));
974 SSLDecodeDHanonKeyExchange(SSLBuffer keyExchange
, SSLContext
*ctx
)
976 unsigned int publicLen
;
979 publicLen
= SSLDecodeInt(keyExchange
.data
, 2);
982 if (keyExchange
.length
!= publicLen
+ 2 ||
983 publicLen
!= ctx
->dhAnonParams
.primeLen
)
984 return ERR(SSLProtocolErr
);
986 if (ERR(err
= SSLAllocBuffer(&ctx
->preMasterSecret
, ctx
->dhAnonParams
.primeLen
, &ctx
->sysCtx
)) != 0)
989 if ((rsaResult
= R_ComputeDHAgreedKey (ctx
->preMasterSecret
.data
, ctx
->dhPeerPublic
.data
,
990 ctx
->dhPrivate
.data
, ctx
->dhPrivate
.length
, &ctx
->dhAnonParams
)) != 0)
991 { err
= SSLUnknownErr
;
996 { unsigned int amount
;
997 if (keyExchange
.length
!= publicLen
+ 2)
998 return ERR(SSLProtocolErr
);
1000 if (ERR(err
= SSLAllocBuffer(&ctx
->preMasterSecret
, 128, &ctx
->sysCtx
)) != 0)
1003 if ((rsaResult
= B_KeyAgreePhase2(ctx
->dhAnonParams
, ctx
->preMasterSecret
.data
,
1004 &amount
, 128, keyExchange
.data
+2, publicLen
, NO_SURR
)) != 0)
1007 ctx
->preMasterSecret
.length
= amount
;
1013 #endif /* APPLE_DH */
1016 SSLEncodeKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1019 CASSERT(ctx
->protocolSide
== SSL_ClientSide
);
1021 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
1023 case SSL_RSA_EXPORT
:
1024 if (ERR(err
= SSLEncodeRSAKeyExchange(keyExchange
, ctx
)) != 0)
1029 if (ERR(err
= SSLEncodeDHanonKeyExchange(keyExchange
, ctx
)) != 0)
1034 return ERR(SSLUnsupportedErr
);
1041 SSLEncodeRSAKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1043 UInt32 outputLen
, peerKeyModulusLen
;
1045 SSLRandomCtx rsaRandom
;
1049 if (ERR(err
= SSLEncodeRSAPremasterSecret(ctx
)) != 0)
1053 if (ERR(err
= ReadyRandom(&rsaRandom
, ctx
)) != 0)
1057 keyExchange
->contentType
= SSL_handshake
;
1058 keyExchange
->protocolVersion
= SSL_Version_3_0
;
1061 peerKeyModulusLen
= (ctx
->peerKey
.bits
+ 7)/8;
1063 { A_RSA_KEY
*keyInfo
;
1065 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, ctx
->peerKey
, KI_RSAPublic
)) != 0)
1066 return SSLUnknownErr
;
1067 peerKeyModulusLen
= keyInfo
->modulus
.len
;
1070 peerKeyModulusLen
= sslKeyLengthInBytes(ctx
->peerPubKey
);
1072 #error No Assymetric Crypto
1073 #endif /* RSAREF / BSAFE */
1074 if (ERR(err
= SSLAllocBuffer(&keyExchange
->contents
,peerKeyModulusLen
+ 4,&ctx
->sysCtx
)) != 0)
1077 R_RandomFinal(&rsaRandom
);
1079 B_DestroyAlgorithmObject(&rsaRandom
);
1083 keyExchange
->contents
.data
[0] = SSL_client_key_exchange
;
1084 SSLEncodeInt(keyExchange
->contents
.data
+ 1, peerKeyModulusLen
, 3);
1086 if ((rsaResult
= RSAPublicEncrypt(keyExchange
->contents
.data
+4, &outputLen
,
1087 ctx
->preMasterSecret
.data
, 48,
1088 &ctx
->peerKey
,&rsaRandom
)) != 0)
1089 { R_RandomFinal(&rsaRandom
);
1090 return ERR(SSLUnknownErr
);
1093 R_RandomFinal(&rsaRandom
);
1096 { B_ALGORITHM_OBJ rsa
;
1097 B_ALGORITHM_METHOD
*chooser
[] = { &AM_RSA_ENCRYPT
, 0 };
1099 unsigned int encryptedOut
;
1101 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
1102 return SSLUnknownErr
;
1103 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPublic
, 0)) != 0)
1104 return SSLUnknownErr
;
1105 if ((rsaResult
= B_EncryptInit(rsa
, ctx
->peerKey
, chooser
, NO_SURR
)) != 0)
1106 return SSLUnknownErr
;
1107 if ((rsaResult
= B_EncryptUpdate(rsa
, keyExchange
->contents
.data
+4,
1108 &encryptedOut
, peerKeyModulusLen
, ctx
->preMasterSecret
.data
, 48, rsaRandom
, NO_SURR
)) != 0)
1109 return SSLUnknownErr
;
1110 outputLen
= encryptedOut
;
1111 if ((rsaResult
= B_EncryptFinal(rsa
, keyExchange
->contents
.data
+4+outputLen
,
1112 &encryptedOut
, peerKeyModulusLen
-outputLen
, rsaRandom
, NO_SURR
)) != 0)
1113 return SSLUnknownErr
;
1114 outputLen
+= encryptedOut
;
1115 B_DestroyAlgorithmObject(&rsa
);
1118 B_DestroyAlgorithmObject(&rsaRandom
);
1120 err
= sslRsaEncrypt(ctx
,
1122 /* FIXME - maybe this should be ctx->cspHand */
1124 ctx
->preMasterSecret
.data
,
1126 keyExchange
->contents
.data
+4,
1134 CASSERT(outputLen
+ 4 == keyExchange
->contents
.length
);
1141 SSLEncodeDHanonKeyExchange(SSLRecord
*keyExchange
, SSLContext
*ctx
)
1143 unsigned int outputLen
;
1145 if (ERR(err
= SSLEncodeDHPremasterSecret(ctx
)) != 0)
1148 outputLen
= ctx
->dhExchangePublic
.length
+ 2;
1150 keyExchange
->contentType
= SSL_handshake
;
1151 keyExchange
->protocolVersion
= SSL_Version_3_0
;
1153 if (ERR(err
= SSLAllocBuffer(&keyExchange
->contents
,outputLen
+ 4,&ctx
->sysCtx
)) != 0)
1156 keyExchange
->contents
.data
[0] = SSL_client_key_exchange
;
1157 SSLEncodeInt(keyExchange
->contents
.data
+1, ctx
->dhExchangePublic
.length
+2, 3);
1159 SSLEncodeInt(keyExchange
->contents
.data
+4, ctx
->dhExchangePublic
.length
, 2);
1160 memcpy(keyExchange
->contents
.data
+6, ctx
->dhExchangePublic
.data
, ctx
->dhExchangePublic
.length
);