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.
19 /* *********************************************************************
22 SSLRef 3.0 Final -- 11/19/96
24 Copyright (c)1996 by Netscape Communications Corp.
26 By retrieving this software you are bound by the licensing terms
27 disclosed in the file "LICENSE.txt". Please read it, and if you don't
28 accept the terms, delete this software.
30 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
31 View, California <http://home.netscape.com/> and Consensus Development
32 Corporation of Berkeley, California <http://www.consensus.com/>.
34 *********************************************************************
36 File: ssl2mesg.c Message encoding and decoding functions for SSL 2
38 The necessary message encoding and decoding for all SSL 2 handshake
41 ****************************************************************** */
79 #ifndef _CIPHER_SPECS_H_
80 #include "cipherSpecs.h"
83 #ifndef _APPLE_CDSA_H_
84 #include "appleCdsa.h"
94 SSL2ProcessClientHello(SSLBuffer msg
, SSLContext
*ctx
)
96 UInt8
*progress
, *cipherList
;
97 int i
, j
, cipherKindCount
, sessionIDLen
, challengeLen
;
98 SSL2CipherKind cipherKind
;
99 SSLCipherSuite matchingCipher
, selectedCipher
;
100 SSLProtocolVersion version
;
102 if (msg
.length
< 27) {
103 errorLog0("SSL2ProcessClientHello: msg len error 1\n");
104 return ERR(SSLProtocolErr
);
109 version
= (SSLProtocolVersion
)SSLDecodeInt(progress
, 2);
110 /* FIXME - ensure client isn't slipping under a SSL_Version_3_0_Only spec... */
111 if (ctx
->negProtocolVersion
== SSL_Version_Undetermined
)
112 { if (version
> SSL_Version_3_0
)
113 version
= SSL_Version_3_0
;
115 dprintf1("===SSL2 server: negVersion was undetermined; is %s\n",
116 protocolVersStr(version
));
118 ctx
->negProtocolVersion
= version
;
120 else if (ctx
->negProtocolVersion
== SSL_Version_3_0_With_2_0_Hello
)
121 { if (version
< SSL_Version_3_0
) {
122 errorLog0("SSL2ProcessClientHello: version error\n");
123 return ERR(SSLProtocolErr
);
126 dprintf0("===SSL2 server: negVersion was 3_0_With_2_0_Hello; is 3_0\n");
128 ctx
->negProtocolVersion
= SSL_Version_3_0
;
132 cipherKindCount
= SSLDecodeInt(progress
, 2);
134 if (cipherKindCount
% 3 != 0) {
135 errorLog0("SSL2ProcessClientHello: cipherKindCount error\n");
136 return ERR(SSLProtocolErr
);
138 cipherKindCount
/= 3;
139 sessionIDLen
= SSLDecodeInt(progress
, 2);
141 challengeLen
= SSLDecodeInt(progress
, 2);
144 if (msg
.length
!= 8 + 3*cipherKindCount
+ sessionIDLen
+ challengeLen
||
145 (sessionIDLen
!= 0 && sessionIDLen
!= 16) ||
146 challengeLen
< 16 || challengeLen
> 32 ) {
147 errorLog0("SSL2ProcessClientHello: msg len error 2\n");
148 return ERR(SSLProtocolErr
);
150 cipherList
= progress
;
151 selectedCipher
= SSL_NO_SUCH_CIPHERSUITE
;
153 if (ctx
->negProtocolVersion
== SSL_Version_3_0
) /* If we're negotiating an SSL 3.0 session, use SSL 3.0 suites first */
154 { for (i
= 0; i
< cipherKindCount
; i
++)
155 { cipherKind
= (SSL2CipherKind
)SSLDecodeInt(progress
, 3);
157 if (selectedCipher
!= SSL_NO_SUCH_CIPHERSUITE
)
159 if ((((UInt32
)cipherKind
) & 0xFF0000) != 0)
160 continue; /* Skip SSL 2 suites */
161 matchingCipher
= (SSLCipherSuite
)((UInt32
)cipherKind
& 0x00FFFF);
162 for (j
= 0; j
<ctx
->numValidCipherSpecs
; j
++)
163 if (ctx
->validCipherSpecs
[j
].cipherSpec
== matchingCipher
)
164 { selectedCipher
= matchingCipher
;
170 progress
= cipherList
;
171 for (i
= 0; i
< cipherKindCount
; i
++)
172 { cipherKind
= (SSL2CipherKind
)SSLDecodeInt(progress
, 3);
174 if (selectedCipher
== SSL_NO_SUCH_CIPHERSUITE
) /* After we find one, just keep advancing progress past the unused ones */
175 { if ((((UInt32
)cipherKind
) & 0xFF0000) != 0) /* If it's a real SSL2 spec, look for it in the list */
176 { matchingCipher
= SSL_NO_SUCH_CIPHERSUITE
;
177 for (j
= 0; j
< SSL2CipherMapCount
; j
++)
178 if (cipherKind
== SSL2CipherMap
[j
].cipherKind
)
179 { matchingCipher
= SSL2CipherMap
[j
].cipherSuite
;
183 else /* if the first byte is zero, it's an encoded SSL 3 CipherSuite */
184 matchingCipher
= (SSLCipherSuite
)((UInt32
)cipherKind
& 0x00FFFF);
185 if (matchingCipher
!= SSL_NO_SUCH_CIPHERSUITE
)
186 for (j
= 0; j
< ctx
->numValidCipherSpecs
; j
++)
187 if (ctx
->validCipherSpecs
[j
].cipherSpec
== matchingCipher
)
188 { selectedCipher
= matchingCipher
;
193 if (selectedCipher
== SSL_NO_SUCH_CIPHERSUITE
)
194 return ERR(SSLNegotiationErr
);
196 ctx
->selectedCipher
= selectedCipher
;
197 err
= FindCipherSpec(ctx
);
201 if (sessionIDLen
> 0 && ctx
->peerID
.data
!= 0)
202 { /* Don't die on error; just treat it as an uncacheable session */
203 ERR(err
= SSLAllocBuffer(&ctx
->sessionID
, sessionIDLen
, &ctx
->sysCtx
));
205 memcpy(ctx
->sessionID
.data
, progress
, sessionIDLen
);
207 progress
+= sessionIDLen
;
209 ctx
->ssl2ChallengeLength
= challengeLen
;
210 memset(ctx
->clientRandom
, 0, 32);
211 memcpy(ctx
->clientRandom
+32 - challengeLen
, progress
, challengeLen
);
212 progress
+= challengeLen
;
213 CASSERT(progress
== msg
.data
+ msg
.length
);
219 SSL2EncodeClientHello(SSLBuffer
*msg
, SSLContext
*ctx
)
222 int i
, j
, useSSL3Ciphers
, totalCipherCount
;
225 SSLBuffer sessionIdentifier
, randomData
;
227 switch (ctx
->negProtocolVersion
)
228 { case SSL_Version_Undetermined
:
229 case SSL_Version_3_0_With_2_0_Hello
:
230 /* go for it, see if server can handle upgrading */
232 version
= SSL_Version_3_0
;
234 case SSL_Version_2_0
:
236 version
= SSL_Version_2_0
;
238 case SSL_Version_3_0_Only
:
239 case SSL_Version_3_0
:
241 ASSERTMSG("Bad protocol version for sending SSL 2 Client Hello");
245 dprintf1("===SSL client: proclaiming %s capable\n",
246 protocolVersStr((SSLProtocolVersion
)version
));
249 if (useSSL3Ciphers
!= 0)
250 totalCipherCount
= ctx
->numValidCipherSpecs
;
252 totalCipherCount
= 0;
254 for (i
= 0; i
< SSL2CipherMapCount
; i
++)
255 for (j
= 0; j
< ctx
->numValidCipherSpecs
; j
++)
256 if (ctx
->validCipherSpecs
[j
].cipherSpec
== SSL2CipherMap
[i
].cipherSuite
)
257 { totalCipherCount
++;
262 sessionIdentifier
.data
= 0;
263 if (ctx
->resumableSession
.data
!= 0)
264 { if (ERR(err
= SSLRetrieveSessionIDIdentifier(ctx
->resumableSession
, &sessionIdentifier
, ctx
)) != 0)
266 sessionIDLen
= sessionIdentifier
.length
;
269 /* msg length = 9 + 3 * totalCipherCount + sessionIDLen + 16 bytes of challenge
270 * Use exactly 16 bytes of challenge because Netscape products have a bug
271 * that requires this length
273 if (ERR(err
= SSLAllocBuffer(msg
, 9 + (3*totalCipherCount
) + sessionIDLen
+ 16, &ctx
->sysCtx
)) != 0)
274 { ERR(SSLFreeBuffer(&sessionIdentifier
, &ctx
->sysCtx
));
278 progress
= msg
->data
;
279 *progress
++ = ssl2_mt_client_hello
;
280 progress
= SSLEncodeInt(progress
, version
, 2);
281 progress
= SSLEncodeInt(progress
, 3*totalCipherCount
, 2);
282 progress
= SSLEncodeInt(progress
, sessionIDLen
, 2);
283 progress
= SSLEncodeInt(progress
, 16, 2);
285 /* If we can send SSL3 ciphers, encode the two-byte cipher specs into three-byte
286 * CipherKinds which have a leading 0.
288 if (useSSL3Ciphers
!= 0)
289 for (i
= 0; i
< ctx
->numValidCipherSpecs
; i
++)
290 progress
= SSLEncodeInt(progress
, ctx
->validCipherSpecs
[i
].cipherSpec
, 3);
292 /* Now send those SSL2 specs for which we have implementations */
293 for (i
= 0; i
< SSL2CipherMapCount
; i
++)
294 for (j
= 0; j
< ctx
->numValidCipherSpecs
; j
++)
295 if (ctx
->validCipherSpecs
[j
].cipherSpec
== SSL2CipherMap
[i
].cipherSuite
)
296 { progress
= SSLEncodeInt(progress
, SSL2CipherMap
[i
].cipherKind
, 3);
300 if (sessionIDLen
> 0)
301 { memcpy(progress
, sessionIdentifier
.data
, sessionIDLen
);
302 progress
+= sessionIDLen
;
303 ERR(SSLFreeBuffer(&sessionIdentifier
, &ctx
->sysCtx
));
306 randomData
.data
= progress
;
307 randomData
.length
= 16;
309 if ((err
= sslRand(ctx
, &randomData
)) != 0)
311 if (ERR(err
= ctx
->sysCtx
.random(randomData
, ctx
->sysCtx
.randomRef
)) != 0)
313 { ERR(SSLFreeBuffer(msg
, &ctx
->sysCtx
));
318 /* Zero out the first 16 bytes of clientRandom, and store the challenge in the
320 memset(ctx
->clientRandom
, 0, 16);
321 memcpy(ctx
->clientRandom
+16, randomData
.data
, 16);
322 ctx
->ssl2ChallengeLength
= 16;
324 CASSERT(progress
== msg
->data
+ msg
->length
);
330 SSL2ProcessClientMasterKey(SSLBuffer msg
, SSLContext
*ctx
)
332 SSL2CipherKind cipherKind
;
333 SSLBuffer secretData
;
334 int clearLength
, encryptedLength
, keyArgLength
;
335 UInt32 secretLength
, localKeyModulusLen
;
338 if (msg
.length
< 9) {
339 errorLog0("SSL2ProcessClientMasterKey: msg.length error 1\n");
340 return ERR(SSLProtocolErr
);
342 CASSERT(ctx
->protocolSide
== SSL_ServerSide
);
345 cipherKind
= (SSL2CipherKind
)SSLDecodeInt(progress
, 3);
347 clearLength
= SSLDecodeInt(progress
, 2);
349 encryptedLength
= SSLDecodeInt(progress
, 2);
351 keyArgLength
= SSLDecodeInt(progress
, 2);
354 if (msg
.length
!= 9 + clearLength
+ encryptedLength
+ keyArgLength
) {
355 errorLog0("SSL2ProcessClientMasterKey: msg.length error 2\n");
356 return ERR(SSLProtocolErr
);
359 /* Master key == CLEAR_DATA || SECRET_DATA */
360 memcpy(ctx
->masterSecret
, progress
, clearLength
);
361 progress
+= clearLength
;
364 localKeyModulusLen
= (ctx
->localKey
.bits
+ 7)/8;
366 { A_RSA_KEY
*keyInfo
;
369 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, ctx
->localKey
, KI_RSAPublic
)) != 0)
370 return SSLUnknownErr
;
371 localKeyModulusLen
= keyInfo
->modulus
.len
;
374 CASSERT(ctx
->encryptPrivKey
!= NULL
);
375 localKeyModulusLen
= sslKeyLengthInBytes(ctx
->encryptPrivKey
);
377 #error No Asymmetric crypto
378 #endif /* RSAREF / BSAFE */
380 if (encryptedLength
!= localKeyModulusLen
) {
381 errorLog0("SSL2ProcessClientMasterKey: encryptedLength error 1\n");
382 return ERR(SSLProtocolErr
);
385 /* Allocate enough room to hold any decrypted value */
386 if (ERR(err
= SSLAllocBuffer(&secretData
, encryptedLength
, &ctx
->sysCtx
)) != 0)
390 /* Replace this with code to do decryption at lower level & check PKCS1 padding
391 for rollback attack */
392 if ((RSAPrivateDecrypt(secretData
.data
, &secretLength
, progress
, encryptedLength
, &ctx
->localKey
)) != 0)
393 { ERR(err
= SSLFreeBuffer(&secretData
, &ctx
->sysCtx
));
394 return ERR(SSLUnknownErr
);
397 { B_ALGORITHM_OBJ rsa
;
398 B_ALGORITHM_METHOD
*chooser
[] = { &AM_RSA_CRT_DECRYPT
, 0 };
400 unsigned int decryptLen
;
402 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
403 return SSLUnknownErr
;
404 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPrivate
, 0)) != 0)
405 return SSLUnknownErr
;
406 if ((rsaResult
= B_DecryptInit(rsa
, ctx
->localKey
, chooser
, NO_SURR
)) != 0)
407 return SSLUnknownErr
;
408 if ((rsaResult
= B_DecryptUpdate(rsa
, secretData
.data
, &decryptLen
, encryptedLength
,
409 progress
, encryptedLength
, 0, NO_SURR
)) != 0)
410 return SSLUnknownErr
;
411 secretLength
= decryptLen
;
412 if ((rsaResult
= B_DecryptFinal(rsa
, secretData
.data
+secretLength
,
413 &decryptLen
, encryptedLength
-secretLength
, 0, NO_SURR
)) != 0)
414 return SSLUnknownErr
;
415 secretLength
+= decryptLen
;
416 B_DestroyAlgorithmObject(&rsa
);
420 * note we use encryptPrivKey, not signingPrivKey - this really is
421 * a decrypt op. Servers have to be configured with valid encryption cert
422 * chain to work with SSL2.
424 err
= sslRsaDecrypt(ctx
,
430 encryptedLength
, // same length for both...?
433 SSLFreeBuffer(&secretData
, &ctx
->sysCtx
);
436 #endif /* RSAREF / BSAFE */
438 progress
+= encryptedLength
;
440 if (clearLength
+ secretLength
!= ctx
->selectedCipherSpec
->cipher
->keySize
) {
441 errorLog0("SSL2ProcessClientMasterKey: length error 3\n");
442 return ERR(SSLProtocolErr
);
444 memcpy(ctx
->masterSecret
+ clearLength
, secretData
.data
, secretLength
);
445 if (ERR(err
= SSLFreeBuffer(&secretData
, &ctx
->sysCtx
)) != 0)
448 if (keyArgLength
!= ctx
->selectedCipherSpec
->cipher
->ivSize
) {
449 errorLog0("SSL2ProcessClientMasterKey: length error 4\n");
450 return ERR(SSLProtocolErr
);
453 /* Stash the IV after the master key in master secret storage */
454 memcpy(ctx
->masterSecret
+ ctx
->selectedCipherSpec
->cipher
->keySize
, progress
, keyArgLength
);
455 progress
+= keyArgLength
;
456 CASSERT(progress
= msg
.data
+ msg
.length
);
462 SSL2EncodeClientMasterKey(SSLBuffer
*msg
, SSLContext
*ctx
)
464 int length
, i
, clearLen
;
465 UInt32 outputLen
, peerKeyModulusLen
;
469 SSLRandomCtx rsaRandom
;
474 peerKeyModulusLen
= (ctx
->peerKey
.bits
+ 7)/8;
476 { A_RSA_KEY
*keyInfo
;
479 if ((rsaResult
= B_GetKeyInfo((POINTER
*)&keyInfo
, ctx
->peerKey
, KI_RSAPublic
)) != 0)
480 return SSLUnknownErr
;
481 peerKeyModulusLen
= keyInfo
->modulus
.len
;
484 peerKeyModulusLen
= sslKeyLengthInBytes(ctx
->peerPubKey
);
485 #endif /* RSAREF / BSAFE */
487 /* Length is 10 + clear key size + encrypted output size + iv size */
489 clearLen
= ctx
->selectedCipherSpec
->cipher
->keySize
- ctx
->selectedCipherSpec
->cipher
->secretKeySize
;
491 length
+= peerKeyModulusLen
;
492 length
+= ctx
->selectedCipherSpec
->cipher
->ivSize
;
494 if (ERR(err
= SSLAllocBuffer(msg
, length
, &ctx
->sysCtx
)) != 0)
496 progress
= msg
->data
;
497 *progress
++ = ssl2_mt_client_master_key
;
498 for (i
= 0; i
< SSL2CipherMapCount
; i
++)
499 if (ctx
->selectedCipher
== SSL2CipherMap
[i
].cipherSuite
)
501 CASSERT(i
< SSL2CipherMapCount
);
503 dprintf1("===SSL2EncodeClientMasterKey: sending cipherKind 0x%x\n",
504 SSL2CipherMap
[i
].cipherKind
);
506 progress
= SSLEncodeInt(progress
, SSL2CipherMap
[i
].cipherKind
, 3);
507 progress
= SSLEncodeInt(progress
, clearLen
, 2);
508 progress
= SSLEncodeInt(progress
, peerKeyModulusLen
, 2);
509 progress
= SSLEncodeInt(progress
, ctx
->selectedCipherSpec
->cipher
->ivSize
, 2);
511 /* Generate the keying material; we need enough data for the key and IV */
512 keyData
.data
= ctx
->masterSecret
;
513 keyData
.length
= ctx
->selectedCipherSpec
->cipher
->keySize
+ ctx
->selectedCipherSpec
->cipher
->ivSize
;
514 CASSERT(keyData
.length
<= 48); /* Must be able to store it in the masterSecret array */
516 if ((err
= sslRand(ctx
, &keyData
)) != 0)
518 if (ERR(err
= ctx
->sysCtx
.random(keyData
, ctx
->sysCtx
.randomRef
)) != 0)
522 memcpy(progress
, ctx
->masterSecret
, clearLen
);
523 progress
+= clearLen
;
526 if (ERR(err
= ReadyRandom(&rsaRandom
, ctx
)) != 0)
530 /* Replace this with code to do encryption at lower level & set PKCS1 padding
531 for rollback attack */
533 if ((rsaResult
= RSAPublicEncrypt(progress
, &outputLen
,
534 ctx
->masterSecret
+ clearLen
,
535 ctx
->selectedCipherSpec
->cipher
->keySize
- clearLen
,
536 &ctx
->peerKey
,&rsaRandom
)) != 0)
537 { R_RandomFinal(&rsaRandom
);
538 return ERR(SSLUnknownErr
);
541 { B_ALGORITHM_OBJ rsa
;
542 B_ALGORITHM_METHOD
*chooser
[] = { &AM_RSA_ENCRYPT
, 0 };
543 unsigned int encryptedOut
;
545 if ((rsaResult
= B_CreateAlgorithmObject(&rsa
)) != 0)
546 return SSLUnknownErr
;
547 if ((rsaResult
= B_SetAlgorithmInfo(rsa
, AI_PKCS_RSAPublic
, 0)) != 0)
548 return SSLUnknownErr
;
549 if ((rsaResult
= B_EncryptInit(rsa
, ctx
->peerKey
, chooser
, NO_SURR
)) != 0)
550 return SSLUnknownErr
;
551 if ((rsaResult
= B_EncryptUpdate(rsa
, progress
,
552 &encryptedOut
, peerKeyModulusLen
, ctx
->masterSecret
+ clearLen
,
553 ctx
->selectedCipherSpec
->cipher
->keySize
- clearLen
,
554 rsaRandom
, NO_SURR
)) != 0)
555 return SSLUnknownErr
;
556 outputLen
= encryptedOut
;
557 if ((rsaResult
= B_EncryptFinal(rsa
, progress
+outputLen
,
558 &encryptedOut
, peerKeyModulusLen
-outputLen
, rsaRandom
, NO_SURR
)) != 0)
559 return SSLUnknownErr
;
560 outputLen
+= encryptedOut
;
561 B_DestroyAlgorithmObject(&rsa
);
565 * encrypt only the secret key portion of masterSecret, starting at
568 err
= sslRsaEncrypt(ctx
,
570 ctx
->peerPubKeyCsp
, // XX - maybe cspHand
571 ctx
->masterSecret
+ clearLen
,
572 ctx
->selectedCipherSpec
->cipher
->keySize
- clearLen
,
581 progress
+= outputLen
;
584 R_RandomFinal(&rsaRandom
);
586 B_DestroyAlgorithmObject(&rsaRandom
);
589 /* copy clear IV to msg buf */
590 memcpy(progress
, ctx
->masterSecret
+ ctx
->selectedCipherSpec
->cipher
->keySize
,
591 ctx
->selectedCipherSpec
->cipher
->ivSize
);
592 progress
+= ctx
->selectedCipherSpec
->cipher
->ivSize
;
594 CASSERT(progress
== msg
->data
+ msg
->length
);
600 SSL2ProcessClientFinished(SSLBuffer msg
, SSLContext
*ctx
)
601 { if (msg
.length
!= ctx
->sessionID
.length
) {
602 errorLog0("SSL2ProcessClientFinished: length error\n");
603 return ERR(SSLProtocolErr
);
605 if (memcmp(msg
.data
, ctx
->serverRandom
, ctx
->ssl2ConnectionIDLength
) != 0) {
606 errorLog0("SSL2ProcessClientFinished: data compare error\n");
607 return ERR(SSLProtocolErr
);
613 SSL2EncodeClientFinished(SSLBuffer
*msg
, SSLContext
*ctx
)
616 if (ERR(err
= SSLAllocBuffer(msg
, ctx
->ssl2ConnectionIDLength
+1, &ctx
->sysCtx
)) != 0)
618 msg
->data
[0] = ssl2_mt_client_finished
;
619 memcpy(msg
->data
+1, ctx
->serverRandom
, ctx
->ssl2ConnectionIDLength
);
624 SSL2ProcessServerHello(SSLBuffer msg
, SSLContext
*ctx
)
626 SSL2CertTypeCode certType
;
627 int sessionIDMatch
, certLen
, cipherSpecsLen
, connectionIDLen
;
629 SSL2CipherKind cipherKind
;
633 SSLCertificate
*cert
;
634 SSLCipherSuite matchingCipher
= 0; // avoid compiler warning
635 SSLCipherSuite selectedCipher
;
637 SSLProtocolVersion version
;
639 if (msg
.length
< 10) {
640 errorLog0("SSL2ProcessServerHello: length error\n");
641 return ERR(SSLProtocolErr
);
645 sessionIDMatch
= *progress
++;
646 certType
= (SSL2CertTypeCode
)*progress
++;
647 version
= (SSLProtocolVersion
)SSLDecodeInt(progress
, 2);
649 if (version
!= SSL_Version_2_0
) {
650 errorLog0("SSL2ProcessServerHello: version error\n");
651 return ERR(SSLProtocolErr
);
653 ctx
->negProtocolVersion
= version
;
655 dprintf0("===SSL2 client: negVersion is 2_0\n");
657 certLen
= SSLDecodeInt(progress
, 2);
659 cipherSpecsLen
= SSLDecodeInt(progress
, 2);
661 connectionIDLen
= SSLDecodeInt(progress
, 2);
664 if (connectionIDLen
< 16 || connectionIDLen
> 32 || cipherSpecsLen
% 3 != 0 ||
665 (msg
.length
!= 10 + certLen
+ cipherSpecsLen
+ connectionIDLen
) )
666 return ERR(SSLProtocolErr
);
667 if (sessionIDMatch
!= 0)
668 { if (certLen
!= 0 || cipherSpecsLen
!= 0 /* || certType != 0 */ )
669 return ERR(SSLProtocolErr
);
670 ctx
->ssl2SessionMatch
= 1;
672 ctx
->ssl2ConnectionIDLength
= connectionIDLen
;
673 memcpy(ctx
->serverRandom
, progress
, connectionIDLen
);
674 progress
+= connectionIDLen
;
677 { if (certType
!= ssl2_ct_x509_certificate
)
678 return ERR(SSLNegotiationErr
);
682 cert
= (SSLCertificate
*)sslMalloc(sizeof(SSLCertificate
));
687 if (ERR(err
= SSLAllocBuffer(&certBuf
, sizeof(SSLCertificate
), &ctx
->sysCtx
)) != 0)
689 cert
= (SSLCertificate
*)certBuf
.data
;
692 if (ERR(err
= SSLAllocBuffer(&cert
->derCert
, certLen
, &ctx
->sysCtx
)) != 0)
697 ERR(SSLFreeBuffer(&certBuf
, &ctx
->sysCtx
));
701 memcpy(cert
->derCert
.data
, progress
, certLen
);
705 if (ERR(err
= ASNParseX509Certificate(cert
->derCert
, &cert
->cert
, ctx
)) != 0)
706 { ERR(SSLFreeBuffer(&cert
->derCert
, &ctx
->sysCtx
));
707 ERR(SSLFreeBuffer(&certBuf
, &ctx
->sysCtx
));
711 ctx
->peerCert
= cert
;
713 /* This cert never gets verified in original SSLRef3 code... */
714 if((err
= sslVerifyCertChain(ctx
, ctx
->peerCert
)) != 0) {
717 if((err
= sslPubKeyFromCert(ctx
,
720 &ctx
->peerPubKeyCsp
)) != 0)
722 if (ERR(err
= X509ExtractPublicKey(&cert
->cert
.pubKey
, &ctx
->peerKey
)) != 0)
726 selectedCipher
= SSL_NO_SUCH_CIPHERSUITE
;
727 for (i
= 0; i
< cipherSpecsLen
; i
++)
728 { cipherKind
= (SSL2CipherKind
)SSLDecodeInt(progress
, 3);
730 //dprintf1("ssl2: server supports cipherKind 0x%x\n", (UInt32)cipherKind);
731 if (selectedCipher
== SSL_NO_SUCH_CIPHERSUITE
) /* After we find one, just keep advancing progress past the unused ones */
732 { for (j
= 0; j
< SSL2CipherMapCount
; j
++)
733 if (cipherKind
== SSL2CipherMap
[j
].cipherKind
)
734 { matchingCipher
= SSL2CipherMap
[j
].cipherSuite
;
737 for (j
= 0; j
< ctx
->numValidCipherSpecs
; j
++)
738 if (ctx
->validCipherSpecs
[j
].cipherSpec
== matchingCipher
)
739 { selectedCipher
= matchingCipher
;
744 if (selectedCipher
== SSL_NO_SUCH_CIPHERSUITE
)
745 return ERR(SSLNegotiationErr
);
747 dprintf1("===SSL2 client: selectedCipher 0x%x\n",
751 ctx
->selectedCipher
= selectedCipher
;
752 if (ERR(err
= FindCipherSpec(ctx
)) != 0) {
755 ctx
->ssl2ConnectionIDLength
= connectionIDLen
;
756 memcpy(ctx
->serverRandom
, progress
, connectionIDLen
);
757 progress
+= connectionIDLen
;
760 CASSERT(progress
== msg
.data
+ msg
.length
);
766 SSL2EncodeServerHello(SSLBuffer
*msg
, SSLContext
*ctx
)
768 SSLCertificate
*cert
;
769 SSLBuffer randomData
;
773 /* Create the connection ID */
774 ctx
->ssl2ConnectionIDLength
= SSL2_CONNECTION_ID_LENGTH
;
775 randomData
.data
= ctx
->serverRandom
;
776 randomData
.length
= ctx
->ssl2ConnectionIDLength
;
778 if ((err
= sslRand(ctx
, &randomData
)) != 0)
780 if (ERR(err
= ctx
->sysCtx
.random(randomData
, ctx
->sysCtx
.randomRef
)) != 0)
784 if (ctx
->ssl2SessionMatch
!= 0)
785 { if (ERR(err
= SSLAllocBuffer(msg
, 11 + ctx
->sessionID
.length
, &ctx
->sysCtx
)) != 0)
787 progress
= msg
->data
;
788 *progress
++ = ssl2_mt_server_hello
;
789 *progress
++ = ctx
->ssl2SessionMatch
;
790 *progress
++ = 0; /* cert type */
791 progress
= SSLEncodeInt(progress
, ctx
->negProtocolVersion
, 2);
792 progress
= SSLEncodeInt(progress
, 0, 2); /* cert len */
793 progress
= SSLEncodeInt(progress
, 0, 2); /* cipherspecs len */
794 progress
= SSLEncodeInt(progress
, ctx
->ssl2ConnectionIDLength
, 2);
795 memcpy(progress
, ctx
->serverRandom
, ctx
->ssl2ConnectionIDLength
);
796 progress
+= ctx
->ssl2ConnectionIDLength
;
799 { /* First, find the last cert in the chain; it's the one we'll send */
803 * For Apple, we require an encryptCert here - we'll be encrypting
804 * with it, after all.
806 if(ctx
->encryptCert
== NULL
) {
807 errorLog0("SSL2EncodeServerHello: No encryptCert!\n");
808 return SSLBadStateErr
;
810 cert
= ctx
->encryptCert
;
812 CASSERT(ctx
->localCert
!= 0);
813 cert
= ctx
->localCert
;
816 while (cert
->next
!= 0)
819 if (ERR(err
= SSLAllocBuffer(msg
, 11 + cert
->derCert
.length
+ 3 + ctx
->sessionID
.length
, &ctx
->sysCtx
)) != 0)
821 progress
= msg
->data
;
822 *progress
++ = ssl2_mt_server_hello
;
823 *progress
++ = ctx
->ssl2SessionMatch
;
824 *progress
++ = ssl2_ct_x509_certificate
; /* cert type */
826 dprintf1("===SSL2 server: sending vers info %s\n",
827 protocolVersStr((SSLProtocolVersion
)ctx
->negProtocolVersion
));
829 progress
= SSLEncodeInt(progress
, ctx
->negProtocolVersion
, 2);
830 progress
= SSLEncodeInt(progress
, cert
->derCert
.length
, 2);
831 progress
= SSLEncodeInt(progress
, 3, 2); /* cipherspecs len */
832 progress
= SSLEncodeInt(progress
, ctx
->ssl2ConnectionIDLength
, 2);
833 memcpy(progress
, cert
->derCert
.data
, cert
->derCert
.length
);
834 progress
+= cert
->derCert
.length
;
835 for (i
= 0; i
< SSL2CipherMapCount
; i
++)
836 if (ctx
->selectedCipher
== SSL2CipherMap
[i
].cipherSuite
)
838 CASSERT(i
< SSL2CipherMapCount
);
839 progress
= SSLEncodeInt(progress
, SSL2CipherMap
[i
].cipherKind
, 3);
840 dprintf1("ssl2: server specifying cipherKind 0x%lx\n",
841 (UInt32
)SSL2CipherMap
[i
].cipherKind
);
842 memcpy(progress
, ctx
->serverRandom
, ctx
->ssl2ConnectionIDLength
);
843 progress
+= ctx
->ssl2ConnectionIDLength
;
846 CASSERT(progress
== msg
->data
+ msg
->length
);
851 SSL2ProcessServerVerify(SSLBuffer msg
, SSLContext
*ctx
)
852 { if (msg
.length
!= ctx
->ssl2ChallengeLength
)
853 return ERR(SSLProtocolErr
);
855 if (memcmp(msg
.data
, ctx
->clientRandom
+ 32 - ctx
->ssl2ChallengeLength
,
856 ctx
->ssl2ChallengeLength
) != 0)
857 return ERR(SSLProtocolErr
);
863 SSL2EncodeServerVerify(SSLBuffer
*msg
, SSLContext
*ctx
)
866 if (ERR(err
= SSLAllocBuffer(msg
, 1 + ctx
->ssl2ChallengeLength
, &ctx
->sysCtx
)) != 0)
869 msg
->data
[0] = ssl2_mt_server_verify
;
870 memcpy(msg
->data
+1, ctx
->clientRandom
+ 32 - ctx
->ssl2ChallengeLength
,
871 ctx
->ssl2ChallengeLength
);
877 SSL2ProcessServerFinished(SSLBuffer msg
, SSLContext
*ctx
)
880 if (ERR(err
= SSLAllocBuffer(&ctx
->sessionID
, msg
.length
, &ctx
->sysCtx
)) != 0)
882 memcpy(ctx
->sessionID
.data
, msg
.data
, msg
.length
);
887 SSL2EncodeServerFinished(SSLBuffer
*msg
, SSLContext
*ctx
)
890 if (ERR(err
= SSLAllocBuffer(msg
, 1 + ctx
->sessionID
.length
, &ctx
->sysCtx
)) != 0)
893 msg
->data
[0] = ssl2_mt_server_finished
;
894 memcpy(msg
->data
+1, ctx
->sessionID
.data
, ctx
->sessionID
.length
);