Back to index

lightning-sunbird  0.9+nobinonly
sslcon.c
Go to the documentation of this file.
00001 /* 
00002  * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is the Netscape security libraries.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either the GNU General Public License Version 2 or later (the "GPL"), or
00029  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040 /* $Id: sslcon.c,v 1.28.2.6 2006/11/14 01:12:08 wtchang%redhat.com Exp $ */
00041 
00042 #include "nssrenam.h"
00043 #include "cert.h"
00044 #include "secitem.h"
00045 #include "sechash.h"
00046 #include "cryptohi.h"              /* for SGN_ funcs */
00047 #include "keyhi.h"          /* for SECKEY_ high level functions. */
00048 #include "ssl.h"
00049 #include "sslimpl.h"
00050 #include "sslproto.h"
00051 #include "ssl3prot.h"
00052 #include "sslerr.h"
00053 #include "pk11func.h"
00054 #include "prinit.h"
00055 #include "prtime.h"  /* for PR_Now() */
00056 
00057 #define XXX
00058 static PRBool policyWasSet;
00059 
00060 /* This ordered list is indexed by (SSL_CK_xx * 3)   */
00061 /* Second and third bytes are MSB and LSB of master key length. */
00062 static const PRUint8 allCipherSuites[] = {
00063     0,                                    0,    0,
00064     SSL_CK_RC4_128_WITH_MD5,                     0x00, 0x80,
00065     SSL_CK_RC4_128_EXPORT40_WITH_MD5,            0x00, 0x80,
00066     SSL_CK_RC2_128_CBC_WITH_MD5,          0x00, 0x80,
00067     SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80,
00068     SSL_CK_IDEA_128_CBC_WITH_MD5,         0x00, 0x80,
00069     SSL_CK_DES_64_CBC_WITH_MD5,                  0x00, 0x40,
00070     SSL_CK_DES_192_EDE3_CBC_WITH_MD5,            0x00, 0xC0,
00071     0,                                    0,    0
00072 };
00073 
00074 #define ssl2_NUM_SUITES_IMPLEMENTED 6
00075 
00076 /* This list is sent back to the client when the client-hello message 
00077  * contains no overlapping ciphers, so the client can report what ciphers
00078  * are supported by the server.  Unlike allCipherSuites (above), this list
00079  * is sorted by descending preference, not by cipherSuite number. 
00080  */
00081 static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = {
00082     SSL_CK_RC4_128_WITH_MD5,                     0x00, 0x80,
00083     SSL_CK_RC2_128_CBC_WITH_MD5,          0x00, 0x80,
00084     SSL_CK_DES_192_EDE3_CBC_WITH_MD5,            0x00, 0xC0,
00085     SSL_CK_DES_64_CBC_WITH_MD5,                  0x00, 0x40,
00086     SSL_CK_RC4_128_EXPORT40_WITH_MD5,            0x00, 0x80,
00087     SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80
00088 };
00089 
00090 typedef struct ssl2SpecsStr {
00091     PRUint8           nkm; /* do this many hashes to generate key material. */
00092     PRUint8           nkd; /* size of readKey and writeKey in bytes. */
00093     PRUint8           blockSize;
00094     PRUint8           blockShift;
00095     CK_MECHANISM_TYPE mechanism;
00096     PRUint8           keyLen;      /* cipher symkey size in bytes. */
00097     PRUint8           pubLen;      /* publicly reveal this many bytes of key. */
00098     PRUint8           ivLen;       /* length of IV data at *ca.       */
00099 } ssl2Specs;
00100 
00101 static const ssl2Specs ssl_Specs[] = {
00102 /* NONE                                 */ 
00103                             {  0,  0, 0, 0, },
00104 /* SSL_CK_RC4_128_WITH_MD5         */ 
00105                             {  2, 16, 1, 0, CKM_RC4,       16,   0, 0, },
00106 /* SSL_CK_RC4_128_EXPORT40_WITH_MD5       */ 
00107                             {  2, 16, 1, 0, CKM_RC4,       16,  11, 0, },
00108 /* SSL_CK_RC2_128_CBC_WITH_MD5            */ 
00109                             {  2, 16, 8, 3, CKM_RC2_CBC,   16,   0, 8, },
00110 /* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5   */ 
00111                             {  2, 16, 8, 3, CKM_RC2_CBC,   16,  11, 8, },
00112 /* SSL_CK_IDEA_128_CBC_WITH_MD5           */ 
00113                             {  0,  0, 0, 0, },
00114 /* SSL_CK_DES_64_CBC_WITH_MD5             */ 
00115                             {  1,  8, 8, 3, CKM_DES_CBC,    8,   0, 8, },
00116 /* SSL_CK_DES_192_EDE3_CBC_WITH_MD5       */ 
00117                             {  3, 24, 8, 3, CKM_DES3_CBC,  24,   0, 8, },
00118 };
00119 
00120 #define SET_ERROR_CODE        /* reminder */
00121 #define TEST_FOR_FAILURE  /* reminder */
00122 
00123 /*
00124 ** Put a string tag in the library so that we can examine an executable
00125 ** and see what kind of security it supports.
00126 */
00127 const char *ssl_version = "SECURITY_VERSION:"
00128                      " +us"
00129                      " +export"
00130 #ifdef TRACE
00131                      " +trace"
00132 #endif
00133 #ifdef DEBUG
00134                      " +debug"
00135 #endif
00136                      ;
00137 
00138 const char * const ssl_cipherName[] = {
00139     "unknown",
00140     "RC4",
00141     "RC4-Export",
00142     "RC2-CBC",
00143     "RC2-CBC-Export",
00144     "IDEA-CBC",
00145     "DES-CBC",
00146     "DES-EDE3-CBC",
00147     "unknown",
00148     "unknown", /* was fortezza, NO LONGER USED */
00149 };
00150 
00151 
00152 /* bit-masks, showing which SSLv2 suites are allowed.
00153  * lsb corresponds to first cipher suite in allCipherSuites[].
00154  */
00155 static PRUint16      allowedByPolicy;          /* all off by default */
00156 static PRUint16      maybeAllowedByPolicy;     /* all off by default */
00157 static PRUint16      chosenPreference = 0xff;  /* all on  by default */
00158 
00159 /* bit values for the above two bit masks */
00160 #define SSL_CB_RC4_128_WITH_MD5              (1 << SSL_CK_RC4_128_WITH_MD5)
00161 #define SSL_CB_RC4_128_EXPORT40_WITH_MD5     (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5)
00162 #define SSL_CB_RC2_128_CBC_WITH_MD5          (1 << SSL_CK_RC2_128_CBC_WITH_MD5)
00163 #define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)
00164 #define SSL_CB_IDEA_128_CBC_WITH_MD5         (1 << SSL_CK_IDEA_128_CBC_WITH_MD5)
00165 #define SSL_CB_DES_64_CBC_WITH_MD5           (1 << SSL_CK_DES_64_CBC_WITH_MD5)
00166 #define SSL_CB_DES_192_EDE3_CBC_WITH_MD5     (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5)
00167 #define SSL_CB_IMPLEMENTED \
00168    (SSL_CB_RC4_128_WITH_MD5              | \
00169     SSL_CB_RC4_128_EXPORT40_WITH_MD5     | \
00170     SSL_CB_RC2_128_CBC_WITH_MD5          | \
00171     SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \
00172     SSL_CB_DES_64_CBC_WITH_MD5           | \
00173     SSL_CB_DES_192_EDE3_CBC_WITH_MD5)
00174 
00175 
00176 /* Construct a socket's list of cipher specs from the global default values.
00177  */
00178 static SECStatus
00179 ssl2_ConstructCipherSpecs(sslSocket *ss) 
00180 {
00181     PRUint8 *         cs           = NULL;
00182     unsigned int     allowed;
00183     unsigned int     count;
00184     int              ssl3_count    = 0;
00185     int              final_count;
00186     int              i;
00187     SECStatus               rv;
00188 
00189     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00190 
00191     count = 0;
00192     PORT_Assert(ss != 0);
00193     allowed = !ss->opt.enableSSL2 ? 0 :
00194        (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
00195     while (allowed) {
00196        if (allowed & 1) 
00197            ++count;
00198        allowed >>= 1;
00199     }
00200 
00201     /* Call ssl3_config_match_init() once here, 
00202      * instead of inside ssl3_ConstructV2CipherSpecsHack(),
00203      * because the latter gets called twice below, 
00204      * and then again in ssl2_BeginClientHandshake().
00205      */
00206     ssl3_config_match_init(ss);
00207 
00208     /* ask SSL3 how many cipher suites it has. */
00209     rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count);
00210     if (rv < 0) 
00211        return rv;
00212     count += ssl3_count;
00213 
00214     /* Allocate memory to hold cipher specs */
00215     if (count > 0)
00216        cs = (PRUint8*) PORT_Alloc(count * 3);
00217     else
00218        PORT_SetError(SSL_ERROR_SSL_DISABLED);
00219     if (cs == NULL)
00220        return SECFailure;
00221 
00222     if (ss->cipherSpecs != NULL) {
00223        PORT_Free(ss->cipherSpecs);
00224     }
00225     ss->cipherSpecs     = cs;
00226     ss->sizeCipherSpecs = count * 3;
00227 
00228     /* fill in cipher specs for SSL2 cipher suites */
00229     allowed = !ss->opt.enableSSL2 ? 0 :
00230        (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED);
00231     for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) {
00232        const PRUint8 * hs = implementedCipherSuites + i;
00233        int             ok = allowed & (1U << hs[0]);
00234        if (ok) {
00235            cs[0] = hs[0];
00236            cs[1] = hs[1];
00237            cs[2] = hs[2];
00238            cs += 3;
00239        }
00240     }
00241 
00242     /* now have SSL3 add its suites onto the end */
00243     rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
00244     
00245     /* adjust for any difference between first pass and second pass */
00246     ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
00247 
00248     return rv;
00249 }
00250 
00251 /* This function is called immediately after ssl2_ConstructCipherSpecs()
00252 ** at the beginning of a handshake.  It detects cases where a protocol
00253 ** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites
00254 ** for that protocol have been disabled.  If such cases, it clears the 
00255 ** enable bit for the protocol.  If no protocols remain enabled, or
00256 ** if no cipher suites are found, it sets the error code and returns
00257 ** SECFailure, otherwise it returns SECSuccess.
00258 */
00259 static SECStatus
00260 ssl2_CheckConfigSanity(sslSocket *ss)
00261 {
00262     unsigned int      allowed;
00263     int               ssl3CipherCount = 0;
00264     SECStatus         rv;
00265 
00266     /* count the SSL2 and SSL3 enabled ciphers.
00267      * if either is zero, clear the socket's enable for that protocol.
00268      */
00269     if (!ss->cipherSpecs)
00270        goto disabled;
00271 
00272     allowed = ss->allowedByPolicy & ss->chosenPreference;
00273     if (! allowed)
00274        ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
00275 
00276     /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */
00277     /* Ask how many ssl3 CipherSuites were enabled. */
00278     rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount);
00279     if (rv != SECSuccess || ssl3CipherCount <= 0) {
00280        ss->opt.enableSSL3 = PR_FALSE; /* not really enabled if no ciphers */
00281        ss->opt.enableTLS  = PR_FALSE;
00282     }
00283 
00284     if (!ss->opt.enableSSL2 && !ss->opt.enableSSL3 && !ss->opt.enableTLS) {
00285        SSL_DBG(("%d: SSL[%d]: Can't handshake! both v2 and v3 disabled.",
00286                SSL_GETPID(), ss->fd));
00287 disabled:
00288        PORT_SetError(SSL_ERROR_SSL_DISABLED);
00289        return SECFailure;
00290     }
00291     return SECSuccess;
00292 }
00293 
00294 /* 
00295  * Since this is a global (not per-socket) setting, we cannot use the
00296  * HandshakeLock to protect this.  Probably want a global lock.
00297  */
00298 SECStatus
00299 ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
00300 {
00301     PRUint32  bitMask;
00302     SECStatus rv       = SECSuccess;
00303 
00304     which &= 0x000f;
00305     bitMask = 1 << which;
00306 
00307     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
00308        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00309        return SECFailure;
00310     }
00311 
00312     if (policy == SSL_ALLOWED) {
00313        allowedByPolicy      |= bitMask;
00314        maybeAllowedByPolicy        |= bitMask;
00315     } else if (policy == SSL_RESTRICTED) {
00316        allowedByPolicy      &= ~bitMask;
00317        maybeAllowedByPolicy        |= bitMask;
00318     } else {
00319        allowedByPolicy      &= ~bitMask;
00320        maybeAllowedByPolicy        &= ~bitMask;
00321     }
00322     allowedByPolicy         &= SSL_CB_IMPLEMENTED;
00323     maybeAllowedByPolicy    &= SSL_CB_IMPLEMENTED;
00324 
00325     policyWasSet = PR_TRUE;
00326     return rv;
00327 }
00328 
00329 SECStatus
00330 ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
00331 {
00332     PRUint32     bitMask;
00333     PRInt32      policy;
00334 
00335     which &= 0x000f;
00336     bitMask = 1 << which;
00337 
00338     /* Caller assures oPolicy is not null. */
00339     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
00340        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00341        *oPolicy = SSL_NOT_ALLOWED;
00342        return SECFailure;
00343     }
00344 
00345     if (maybeAllowedByPolicy & bitMask) {
00346        policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
00347     } else {
00348        policy = SSL_NOT_ALLOWED;
00349     }
00350 
00351     *oPolicy = policy;
00352     return SECSuccess;
00353 }
00354 
00355 /* 
00356  * Since this is a global (not per-socket) setting, we cannot use the
00357  * HandshakeLock to protect this.  Probably want a global lock.
00358  * Called from SSL_CipherPrefSetDefault in sslsock.c
00359  * These changes have no effect on any sslSockets already created. 
00360  */
00361 SECStatus
00362 ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
00363 {
00364     PRUint32     bitMask;
00365     
00366     which &= 0x000f;
00367     bitMask = 1 << which;
00368 
00369     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
00370        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00371        return SECFailure;
00372     }
00373 
00374     if (enabled)
00375        chosenPreference |= bitMask;
00376     else
00377        chosenPreference &= ~bitMask;
00378     chosenPreference &= SSL_CB_IMPLEMENTED;
00379 
00380     return SECSuccess;
00381 }
00382 
00383 SECStatus 
00384 ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
00385 {
00386     PRBool       rv       = PR_FALSE;
00387     PRUint32     bitMask;
00388 
00389     which &= 0x000f;
00390     bitMask = 1 << which;
00391 
00392     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
00393        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00394        *enabled = PR_FALSE;
00395        return SECFailure;
00396     }
00397 
00398     rv = (PRBool)((chosenPreference & bitMask) != 0);
00399     *enabled = rv;
00400     return SECSuccess;
00401 }
00402 
00403 SECStatus 
00404 ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
00405 {
00406     PRUint32     bitMask;
00407     
00408     which &= 0x000f;
00409     bitMask = 1 << which;
00410 
00411     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
00412        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00413        return SECFailure;
00414     }
00415 
00416     if (enabled)
00417        ss->chosenPreference |= bitMask;
00418     else
00419        ss->chosenPreference &= ~bitMask;
00420     ss->chosenPreference &= SSL_CB_IMPLEMENTED;
00421 
00422     return SECSuccess;
00423 }
00424 
00425 SECStatus 
00426 ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
00427 {
00428     PRBool       rv       = PR_FALSE;
00429     PRUint32     bitMask;
00430 
00431     which &= 0x000f;
00432     bitMask = 1 << which;
00433 
00434     if (!(bitMask & SSL_CB_IMPLEMENTED)) {
00435        PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
00436        *enabled = PR_FALSE;
00437        return SECFailure;
00438     }
00439 
00440     rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
00441     *enabled = rv;
00442     return SECSuccess;
00443 }
00444 
00445 
00446 /* copy global default policy into socket. */
00447 void      
00448 ssl2_InitSocketPolicy(sslSocket *ss)
00449 {
00450     ss->allowedByPolicy            = allowedByPolicy;
00451     ss->maybeAllowedByPolicy       = maybeAllowedByPolicy;
00452     ss->chosenPreference    = chosenPreference;
00453 }
00454 
00455 
00456 /************************************************************************/
00457 
00458 /* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
00459  */
00460 static SECStatus
00461 ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, 
00462           int cipherChoice)
00463 {
00464     switch (cipherChoice) {
00465 
00466       case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
00467       case SSL_CK_RC2_128_CBC_WITH_MD5:
00468       case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
00469       case SSL_CK_RC4_128_WITH_MD5:
00470       case SSL_CK_DES_64_CBC_WITH_MD5:
00471       case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
00472        sec->hash = HASH_GetHashObject(HASH_AlgMD5);
00473        SECITEM_CopyItem(0, &sec->sendSecret, writeKey);
00474        SECITEM_CopyItem(0, &sec->rcvSecret, readKey);
00475        break;
00476 
00477       default:
00478        PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
00479        return SECFailure;
00480     }
00481     sec->hashcx = (*sec->hash->create)();
00482     if (sec->hashcx == NULL)
00483        return SECFailure;
00484     return SECSuccess;
00485 }
00486 
00487 /************************************************************************
00488  * All the Send functions below must acquire and release the socket's 
00489  * xmitBufLock.
00490  */
00491 
00492 /* Called from all the Send* functions below. */
00493 static SECStatus
00494 ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
00495 {
00496     SECStatus rv = SECSuccess;
00497 
00498     PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
00499 
00500     if (len < 128) {
00501        len = 128;
00502     }
00503     if (len > ss->sec.ci.sendBuf.space) {
00504        rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len);
00505        if (rv != SECSuccess) {
00506            SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
00507                    SSL_GETPID(), ss->fd, len));
00508            rv = SECFailure;
00509        }
00510     }
00511     return rv;
00512 }
00513 
00514 /* Called from:
00515  * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
00516  * ssl2_HandleRequestCertificate()     <- ssl2_HandleMessage() <- 
00517                                    ssl_Do1stHandshake()
00518  * ssl2_HandleMessage()                <- ssl_Do1stHandshake()
00519  * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()
00520                                      after ssl2_BeginClientHandshake()
00521  * ssl2_RestartHandshakeAfterCertReq() <- Called from certdlgs.c in nav.
00522  * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() 
00523                                      after ssl2_BeginServerHandshake()
00524  * 
00525  * Acquires and releases the socket's xmitBufLock.
00526  */    
00527 int
00528 ssl2_SendErrorMessage(sslSocket *ss, int error)
00529 {
00530     int rv;
00531     PRUint8 msg[SSL_HL_ERROR_HBYTES];
00532 
00533     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00534 
00535     msg[0] = SSL_MT_ERROR;
00536     msg[1] = MSB(error);
00537     msg[2] = LSB(error);
00538 
00539     ssl_GetXmitBufLock(ss);    /***************************************/
00540 
00541     SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
00542 
00543     ss->handshakeBegun = 1;
00544     rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0);
00545     if (rv >= 0) {
00546        rv = SECSuccess;
00547     }
00548     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00549     return rv;
00550 }
00551 
00552 /* Called from ssl2_TryToFinish().  
00553  * Acquires and releases the socket's xmitBufLock.
00554  */
00555 static SECStatus
00556 ssl2_SendClientFinishedMessage(sslSocket *ss)
00557 {
00558     SECStatus        rv    = SECSuccess;
00559     int              sent;
00560     PRUint8    msg[1 + SSL_CONNECTIONID_BYTES];
00561 
00562     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00563 
00564     ssl_GetXmitBufLock(ss);    /***************************************/
00565 
00566     if (ss->sec.ci.sentFinished == 0) {
00567        ss->sec.ci.sentFinished = 1;
00568 
00569        SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
00570                   SSL_GETPID(), ss->fd));
00571 
00572        msg[0] = SSL_MT_CLIENT_FINISHED;
00573        PORT_Memcpy(msg+1, ss->sec.ci.connectionID, 
00574                    sizeof(ss->sec.ci.connectionID));
00575 
00576        DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID)));
00577        sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0);
00578        rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
00579     }
00580     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00581     return rv;
00582 }
00583 
00584 /* Called from 
00585  * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
00586  * ssl2_HandleClientHelloMessage()  <- ssl_Do1stHandshake() 
00587                                       after ssl2_BeginServerHandshake()
00588  * Acquires and releases the socket's xmitBufLock.
00589  */
00590 static SECStatus
00591 ssl2_SendServerVerifyMessage(sslSocket *ss)
00592 {
00593     PRUint8 *        msg;
00594     int              sendLen;
00595     int              sent;
00596     SECStatus        rv;
00597 
00598     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00599 
00600     ssl_GetXmitBufLock(ss);    /***************************************/
00601 
00602     sendLen = 1 + SSL_CHALLENGE_BYTES;
00603     rv = ssl2_GetSendBuffer(ss, sendLen);
00604     if (rv != SECSuccess) {
00605        goto done;
00606     }
00607 
00608     msg = ss->sec.ci.sendBuf.buf;
00609     msg[0] = SSL_MT_SERVER_VERIFY;
00610     PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
00611 
00612     DUMP_MSG(29, (ss, msg, sendLen));
00613     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
00614 
00615     rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
00616 
00617 done:
00618     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00619     return rv;
00620 }
00621 
00622 /* Called from ssl2_TryToFinish(). 
00623  * Acquires and releases the socket's xmitBufLock.
00624  */
00625 static SECStatus
00626 ssl2_SendServerFinishedMessage(sslSocket *ss)
00627 {
00628     sslSessionID *   sid;
00629     PRUint8 *        msg;
00630     int              sendLen, sent;
00631     SECStatus        rv    = SECSuccess;
00632 
00633     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00634 
00635     ssl_GetXmitBufLock(ss);    /***************************************/
00636 
00637     if (ss->sec.ci.sentFinished == 0) {
00638        ss->sec.ci.sentFinished = 1;
00639        PORT_Assert(ss->sec.ci.sid != 0);
00640        sid = ss->sec.ci.sid;
00641 
00642        SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
00643                   SSL_GETPID(), ss->fd));
00644 
00645        sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
00646        rv = ssl2_GetSendBuffer(ss, sendLen);
00647        if (rv != SECSuccess) {
00648            goto done;
00649        }
00650 
00651        msg = ss->sec.ci.sendBuf.buf;
00652        msg[0] = SSL_MT_SERVER_FINISHED;
00653        PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,
00654                   sizeof(sid->u.ssl2.sessionID));
00655 
00656        DUMP_MSG(29, (ss, msg, sendLen));
00657        sent = (*ss->sec.send)(ss, msg, sendLen, 0);
00658 
00659        if (sent < 0) {
00660            /* If send failed, it is now a bogus  session-id */
00661            (*ss->sec.uncache)(sid);
00662            rv = (SECStatus)sent;
00663        } else if (!ss->opt.noCache) {
00664            /* Put the sid in session-id cache, (may already be there) */
00665            (*ss->sec.cache)(sid);
00666            rv = SECSuccess;
00667        }
00668        ssl_FreeSID(sid);
00669        ss->sec.ci.sid = 0;
00670     }
00671 done:
00672     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00673     return rv;
00674 }
00675 
00676 /* Called from ssl2_ClientSetupSessionCypher() <- 
00677  *                                        ssl2_HandleServerHelloMessage() 
00678  *                                           after ssl2_BeginClientHandshake()
00679  * Acquires and releases the socket's xmitBufLock.
00680  */
00681 static SECStatus
00682 ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
00683                     PRUint8 *ca, int caLen,
00684                     PRUint8 *ck, int ckLen,
00685                     PRUint8 *ek, int ekLen)
00686 {
00687     PRUint8 *        msg;
00688     int              sendLen;
00689     int              sent;
00690     SECStatus        rv;
00691 
00692     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00693 
00694     ssl_GetXmitBufLock(ss);    /***************************************/
00695 
00696     sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
00697     rv = ssl2_GetSendBuffer(ss, sendLen);
00698     if (rv != SECSuccess) 
00699        goto done;
00700 
00701     SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
00702               SSL_GETPID(), ss->fd));
00703 
00704     msg = ss->sec.ci.sendBuf.buf;
00705     msg[0] = SSL_MT_CLIENT_MASTER_KEY;
00706     msg[1] = cipher;
00707     msg[2] = MSB(keySize);
00708     msg[3] = LSB(keySize);
00709     msg[4] = MSB(ckLen);
00710     msg[5] = LSB(ckLen);
00711     msg[6] = MSB(ekLen);
00712     msg[7] = LSB(ekLen);
00713     msg[8] = MSB(caLen);
00714     msg[9] = LSB(caLen);
00715     PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
00716     PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);
00717     PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);
00718 
00719     DUMP_MSG(29, (ss, msg, sendLen));
00720     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
00721     rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
00722 done:
00723     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00724     return rv;
00725 }
00726 
00727 /* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage() 
00728  * Acquires and releases the socket's xmitBufLock.
00729  */
00730 static SECStatus
00731 ssl2_SendCertificateRequestMessage(sslSocket *ss)
00732 {
00733     PRUint8 *        msg;
00734     int              sent;
00735     int              sendLen;
00736     SECStatus        rv;
00737 
00738     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00739 
00740     ssl_GetXmitBufLock(ss);    /***************************************/
00741 
00742     sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
00743     rv = ssl2_GetSendBuffer(ss, sendLen);
00744     if (rv != SECSuccess) 
00745        goto done;
00746 
00747     SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
00748               SSL_GETPID(), ss->fd));
00749 
00750     /* Generate random challenge for client to encrypt */
00751     PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
00752 
00753     msg = ss->sec.ci.sendBuf.buf;
00754     msg[0] = SSL_MT_REQUEST_CERTIFICATE;
00755     msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
00756     PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, 
00757                 ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
00758 
00759     DUMP_MSG(29, (ss, msg, sendLen));
00760     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
00761     rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
00762 done:
00763     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00764     return rv;
00765 }
00766 
00767 /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
00768  *             ssl2_RestartHandshakeAfterCertReq() <- (application)
00769  * Acquires and releases the socket's xmitBufLock.
00770  */
00771 static int
00772 ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, 
00773                                     SECItem *encCode)
00774 {
00775     PRUint8 *msg;
00776     int rv, sendLen;
00777 
00778     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
00779 
00780     ssl_GetXmitBufLock(ss);    /***************************************/
00781 
00782     sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
00783     rv = ssl2_GetSendBuffer(ss, sendLen);
00784     if (rv) 
00785        goto done;
00786 
00787     SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
00788               SSL_GETPID(), ss->fd));
00789 
00790     msg = ss->sec.ci.sendBuf.buf;
00791     msg[0] = SSL_MT_CLIENT_CERTIFICATE;
00792     msg[1] = SSL_CT_X509_CERTIFICATE;
00793     msg[2] = MSB(cert->len);
00794     msg[3] = LSB(cert->len);
00795     msg[4] = MSB(encCode->len);
00796     msg[5] = LSB(encCode->len);
00797     PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
00798     PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
00799              encCode->data, encCode->len);
00800 
00801     DUMP_MSG(29, (ss, msg, sendLen));
00802     rv = (*ss->sec.send)(ss, msg, sendLen, 0);
00803     if (rv >= 0) {
00804        rv = SECSuccess;
00805     }
00806 done:
00807     ssl_ReleaseXmitBufLock(ss);    /***************************************/
00808     return rv;
00809 }
00810 
00811 /********************************************************************
00812 **  Send functions above this line must aquire & release the socket's   
00813 **     xmitBufLock.  
00814 ** All the ssl2_Send functions below this line are called vis ss->sec.send
00815 **     and require that the caller hold the xmitBufLock.
00816 */
00817 
00818 /*
00819 ** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
00820 */
00821 static SECStatus
00822 ssl2_CalcMAC(PRUint8             * result, 
00823             sslSecurityInfo     * sec,
00824             const PRUint8       * data, 
00825             unsigned int          dataLen,
00826             unsigned int          paddingLen)
00827 {
00828     const PRUint8 *      secret           = sec->sendSecret.data;
00829     unsigned int         secretLen = sec->sendSecret.len;
00830     unsigned long        sequenceNumber = sec->sendSequence;
00831     unsigned int         nout;
00832     PRUint8              seq[4];
00833     PRUint8              padding[32];/* XXX max blocksize? */
00834 
00835     if (!sec->hash || !sec->hash->length)
00836        return SECSuccess;
00837     if (!sec->hashcx)
00838        return SECFailure;
00839 
00840     /* Reset hash function */
00841     (*sec->hash->begin)(sec->hashcx);
00842 
00843     /* Feed hash the data */
00844     (*sec->hash->update)(sec->hashcx, secret, secretLen);
00845     (*sec->hash->update)(sec->hashcx, data, dataLen);
00846     PORT_Memset(padding, paddingLen, paddingLen);
00847     (*sec->hash->update)(sec->hashcx, padding, paddingLen);
00848 
00849     seq[0] = (PRUint8) (sequenceNumber >> 24);
00850     seq[1] = (PRUint8) (sequenceNumber >> 16);
00851     seq[2] = (PRUint8) (sequenceNumber >> 8);
00852     seq[3] = (PRUint8) (sequenceNumber);
00853 
00854     PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
00855     PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
00856     PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
00857     PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));
00858 
00859     (*sec->hash->update)(sec->hashcx, seq, 4);
00860 
00861     /* Get result */
00862     (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);
00863 
00864     return SECSuccess;
00865 }
00866 
00867 /*
00868 ** Maximum transmission amounts. These are tiny bit smaller than they
00869 ** need to be (they account for the MAC length plus some padding),
00870 ** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
00871 ** long. This gives an additional 9 bytes of slop to work within.
00872 */
00873 #define MAX_STREAM_CYPHER_LEN      0x7fe0
00874 #define MAX_BLOCK_CYPHER_LEN       0x3fe0
00875 
00876 /*
00877 ** Send some data in the clear. 
00878 ** Package up data with the length header and send it.
00879 **
00880 ** Return count of bytes succesfully written, or negative number (failure).
00881 */
00882 static PRInt32 
00883 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
00884 {
00885     PRUint8         * out;
00886     int               rv;
00887     int               amount;
00888     int               count = 0;
00889 
00890     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
00891 
00892     SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
00893                SSL_GETPID(), ss->fd, len));
00894     PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
00895 
00896     while (len) {
00897        amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
00898        if (amount + 2 > ss->sec.writeBuf.space) {
00899            rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2);
00900            if (rv != SECSuccess) {
00901               count = rv;
00902               break;
00903            }
00904        }
00905        out = ss->sec.writeBuf.buf;
00906 
00907        /*
00908        ** Construct message.
00909        */
00910        out[0] = 0x80 | MSB(amount);
00911        out[1] = LSB(amount);
00912        PORT_Memcpy(&out[2], in, amount);
00913 
00914        /* Now send the data */
00915        rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
00916        if (rv < 0) {
00917            if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
00918               rv = 0;
00919            } else {
00920               /* Return short write if some data already went out... */
00921               if (count == 0)
00922                   count = rv;
00923               break;
00924            }
00925        }
00926 
00927        if ((unsigned)rv < (amount + 2)) {
00928            /* Short write.  Save the data and return. */
00929            if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) 
00930                == SECFailure) {
00931               count = SECFailure;
00932            } else {
00933               count += amount;
00934               ss->sec.sendSequence++;
00935            }
00936            break;
00937        }
00938 
00939        ss->sec.sendSequence++;
00940        in    += amount;
00941        count += amount;
00942        len   -= amount;
00943     }
00944 
00945     return count;
00946 }
00947 
00948 /*
00949 ** Send some data, when using a stream cipher. Stream ciphers have a
00950 ** block size of 1. Package up the data with the length header
00951 ** and send it.
00952 */
00953 static PRInt32 
00954 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
00955 {
00956     PRUint8       *  out;
00957     int              rv;
00958     int              count  = 0;
00959 
00960     int              amount;
00961     PRUint8          macLen;
00962     int              nout;
00963     int              buflen;
00964 
00965     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
00966 
00967     SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
00968                SSL_GETPID(), ss->fd, len));
00969     PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
00970 
00971     while (len) {
00972        ssl_GetSpecReadLock(ss);  /*************************************/
00973 
00974        macLen = ss->sec.hash->length;
00975        amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
00976        buflen = amount + 2 + macLen;
00977        if (buflen > ss->sec.writeBuf.space) {
00978            rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
00979            if (rv != SECSuccess) {
00980               goto loser;
00981            }
00982        }
00983        out    = ss->sec.writeBuf.buf;
00984        nout   = amount + macLen;
00985        out[0] = 0x80 | MSB(nout);
00986        out[1] = LSB(nout);
00987 
00988        /* Calculate MAC */
00989        rv = ssl2_CalcMAC(out+2,           /* put MAC here */
00990                          &ss->sec, 
00991                         in, amount,              /* input addr & length */
00992                        0);                /* no padding */
00993        if (rv != SECSuccess) 
00994            goto loser;
00995 
00996        /* Encrypt MAC */
00997        rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen);
00998        if (rv) goto loser;
00999 
01000        /* Encrypt data from caller */
01001        rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount);
01002        if (rv) goto loser;
01003 
01004        ssl_ReleaseSpecReadLock(ss);  /*************************************/
01005 
01006        PRINT_BUF(50, (ss, "encrypted data:", out, buflen));
01007 
01008        rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
01009        if (rv < 0) {
01010            if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
01011               SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
01012                           "saving data", SSL_GETPID(), ss->fd));
01013               rv = 0;
01014            } else {
01015               SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
01016                           SSL_GETPID(), ss->fd, PORT_GetError()));
01017               /* Return short write if some data already went out... */
01018               if (count == 0)
01019                   count = rv;
01020               goto done;
01021            }
01022        }
01023 
01024        if ((unsigned)rv < buflen) {
01025            /* Short write.  Save the data and return. */
01026            if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) {
01027               count = SECFailure;
01028            } else {
01029               count += amount;
01030               ss->sec.sendSequence++;
01031            }
01032            goto done;
01033        }
01034 
01035        ss->sec.sendSequence++;
01036        in    += amount;
01037        count += amount;
01038        len   -= amount;
01039     }
01040 
01041 done:
01042     return count;
01043 
01044 loser:
01045     ssl_ReleaseSpecReadLock(ss);
01046     return SECFailure;
01047 }
01048 
01049 /*
01050 ** Send some data, when using a block cipher. Package up the data with
01051 ** the length header and send it.
01052 */
01053 /* XXX assumes blocksize is > 7 */
01054 static PRInt32
01055 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
01056 {
01057     PRUint8       *  out;              /* begining of output buffer.    */
01058     PRUint8       *  op;               /* next output byte goes here.   */
01059     int              rv;               /* value from funcs we called.   */
01060     int              count  = 0;        /* this function's return value. */
01061 
01062     unsigned int     hlen;             /* output record hdr len, 2 or 3 */
01063     unsigned int     macLen;                  /* MAC is this many bytes long.  */
01064     int              amount;                  /* of plaintext to go in record. */
01065     unsigned int     padding;                 /* add this many padding byte.   */
01066     int              nout;             /* ciphertext size after header. */
01067     int              buflen;                  /* size of generated record.     */
01068 
01069     PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
01070 
01071     SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
01072                SSL_GETPID(), ss->fd, len));
01073     PRINT_BUF(50, (ss, "clear data:", in, len));
01074 
01075     while (len) {
01076        ssl_GetSpecReadLock(ss);  /*************************************/
01077 
01078        macLen = ss->sec.hash->length;
01079        /* Figure out how much to send, including mac and padding */
01080        amount  = PR_MIN( len, MAX_BLOCK_CYPHER_LEN );
01081        nout    = amount + macLen;
01082        padding = nout & (ss->sec.blockSize - 1);
01083        if (padding) {
01084            hlen    = 3;
01085            padding = ss->sec.blockSize - padding;
01086            nout   += padding;
01087        } else {
01088            hlen = 2;
01089        }
01090        buflen = hlen + nout;
01091        if (buflen > ss->sec.writeBuf.space) {
01092            rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
01093            if (rv != SECSuccess) {
01094               goto loser;
01095            }
01096        }
01097        out = ss->sec.writeBuf.buf;
01098 
01099        /* Construct header */
01100        op = out;
01101        if (padding) {
01102            *op++ = MSB(nout);
01103            *op++ = LSB(nout);
01104            *op++ = padding;
01105        } else {
01106            *op++ = 0x80 | MSB(nout);
01107            *op++ = LSB(nout);
01108        }
01109 
01110        /* Calculate MAC */
01111        rv = ssl2_CalcMAC(op,              /* MAC goes here. */
01112                          &ss->sec, 
01113                         in, amount,       /* intput addr, len */
01114                        padding);
01115        if (rv != SECSuccess) 
01116            goto loser;
01117        op += macLen;
01118 
01119        /* Copy in the input data */
01120        /* XXX could eliminate the copy by folding it into the encryption */
01121        PORT_Memcpy(op, in, amount);
01122        op += amount;
01123        if (padding) {
01124            PORT_Memset(op, padding, padding);
01125            op += padding;
01126        }
01127 
01128        /* Encrypt result */
01129        rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen,
01130                       out+hlen, op - (out + hlen));
01131        if (rv) 
01132            goto loser;
01133 
01134        ssl_ReleaseSpecReadLock(ss);  /*************************************/
01135 
01136        PRINT_BUF(50, (ss, "final xmit data:", out, op - out));
01137 
01138        rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
01139        if (rv < 0) {
01140            if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
01141               rv = 0;
01142            } else {
01143               SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
01144                           SSL_GETPID(), ss->fd, PORT_GetError()));
01145               /* Return short write if some data already went out... */
01146               if (count == 0)
01147                   count = rv;
01148               goto done;
01149            }
01150        }
01151 
01152        if (rv < (op - out)) {
01153            /* Short write.  Save the data and return. */
01154            if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) {
01155               count = SECFailure;
01156            } else {
01157               count += amount;
01158               ss->sec.sendSequence++;
01159            }
01160            goto done;
01161        }
01162 
01163        ss->sec.sendSequence++;
01164        in    += amount;
01165        count += amount;
01166        len   -= amount;
01167     }
01168 
01169 done:
01170     return count;
01171 
01172 loser:
01173     ssl_ReleaseSpecReadLock(ss);
01174     return SECFailure;
01175 }
01176 
01177 /*
01178 ** Called from: ssl2_HandleServerHelloMessage,
01179 **              ssl2_HandleClientSessionKeyMessage,
01180 **              ssl2_RestartHandshakeAfterServerCert,
01181 **              ssl2_HandleClientHelloMessage,
01182 **              
01183 */
01184 static void
01185 ssl2_UseEncryptedSendFunc(sslSocket *ss)
01186 {
01187     ssl_GetXmitBufLock(ss);
01188     PORT_Assert(ss->sec.hashcx != 0);
01189 
01190     ss->gs.encrypted = 1;
01191     ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
01192     ssl_ReleaseXmitBufLock(ss);
01193 }
01194 
01195 /* Called while initializing socket in ssl_CreateSecurityInfo().
01196 ** This function allows us to keep the name of ssl2_SendClear static.
01197 */
01198 void
01199 ssl2_UseClearSendFunc(sslSocket *ss)
01200 {
01201     ss->sec.send = ssl2_SendClear;
01202 }
01203 
01204 /************************************************************************
01205 **                   END of Send functions.                          * 
01206 *************************************************************************/
01207 
01208 /***********************************************************************
01209  * For SSL3, this gathers in and handles records/messages until either 
01210  *     the handshake is complete or application data is available.
01211  *
01212  * For SSL2, this gathers in only the next SSLV2 record.
01213  *
01214  * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
01215  * Caller must hold handshake lock.
01216  * This function acquires and releases the RecvBufLock.
01217  *
01218  * returns SECSuccess for success.
01219  * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
01220  *     ssl3_GatherCompleteHandshake().
01221  * returns SECFailure on all other errors.
01222  *
01223  * The gather functions called by ssl_GatherRecord1stHandshake are expected 
01224  *     to return values interpreted as follows:
01225  *  1 : the function completed without error.
01226  *  0 : the function read EOF.
01227  * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
01228  * -2 : the function wants ssl_GatherRecord1stHandshake to be called again 
01229  *     immediately, by ssl_Do1stHandshake.
01230  *
01231  * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
01232  *
01233  * This function is called from ssl_Do1stHandshake().  
01234  * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
01235  *     ssl2_HandleMessage
01236  *     ssl2_HandleVerifyMessage
01237  *     ssl2_HandleServerHelloMessage
01238  *     ssl2_BeginClientHandshake   
01239  *     ssl2_HandleClientSessionKeyMessage
01240  *     ssl2_RestartHandshakeAfterCertReq 
01241  *     ssl3_RestartHandshakeAfterCertReq 
01242  *     ssl2_RestartHandshakeAfterServerCert 
01243  *     ssl3_RestartHandshakeAfterServerCert 
01244  *     ssl2_HandleClientHelloMessage
01245  *     ssl2_BeginServerHandshake
01246  */
01247 SECStatus
01248 ssl_GatherRecord1stHandshake(sslSocket *ss)
01249 {
01250     int rv;
01251 
01252     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01253 
01254     ssl_GetRecvBufLock(ss);
01255 
01256     if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
01257        /* Wait for handshake to complete, or application data to arrive.  */
01258        rv = ssl3_GatherCompleteHandshake(ss, 0);
01259     } else {
01260        /* See if we have a complete record */
01261        rv = ssl2_GatherRecord(ss, 0);
01262     }
01263     SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
01264                SSL_GETPID(), ss->fd, rv));
01265 
01266     ssl_ReleaseRecvBufLock(ss);
01267 
01268     if (rv <= 0) {
01269        if (rv == SECWouldBlock) {
01270            /* Progress is blocked waiting for callback completion.  */
01271            SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
01272                       SSL_GETPID(), ss->fd, ss->gs.remainder));
01273            return SECWouldBlock;
01274        }
01275        if (rv == 0) {
01276            /* EOF. Loser  */
01277            PORT_SetError(PR_END_OF_FILE_ERROR);
01278        }
01279        return SECFailure;   /* rv is < 0 here. */
01280     }
01281 
01282     SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
01283                SSL_GETPID(), ss->fd, ss->gs.recordLen));
01284 
01285     ss->handshake = 0;      /* makes ssl_Do1stHandshake call ss->nextHandshake.*/
01286     return SECSuccess;
01287 }
01288 
01289 /************************************************************************/
01290 
01291 /* Called from ssl2_ServerSetupSessionCypher()
01292  *             ssl2_ClientSetupSessionCypher()
01293  */
01294 static SECStatus
01295 ssl2_FillInSID(sslSessionID * sid, 
01296           int            cipher,
01297          PRUint8       *keyData, 
01298          int            keyLen,
01299          PRUint8       *ca, 
01300          int            caLen,
01301          int            keyBits, 
01302          int            secretKeyBits,
01303          SSLSignType    authAlgorithm,
01304          PRUint32       authKeyBits,
01305          SSLKEAType     keaType,
01306          PRUint32       keaKeyBits)
01307 {
01308     PORT_Assert(sid->references == 1);
01309     PORT_Assert(sid->cached == never_cached);
01310     PORT_Assert(sid->u.ssl2.masterKey.data == 0);
01311     PORT_Assert(sid->u.ssl2.cipherArg.data == 0);
01312 
01313     sid->version = SSL_LIBRARY_VERSION_2;
01314 
01315     sid->u.ssl2.cipherType = cipher;
01316     sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen);
01317     if (!sid->u.ssl2.masterKey.data) {
01318        return SECFailure;
01319     }
01320     PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
01321     sid->u.ssl2.masterKey.len = keyLen;
01322     sid->u.ssl2.keyBits       = keyBits;
01323     sid->u.ssl2.secretKeyBits = secretKeyBits;
01324     sid->authAlgorithm        = authAlgorithm;
01325     sid->authKeyBits          = authKeyBits;
01326     sid->keaType              = keaType;
01327     sid->keaKeyBits           = keaKeyBits;
01328     sid->lastAccessTime = sid->creationTime = ssl_Time();
01329     sid->expirationTime = sid->creationTime + ssl_sid_timeout;
01330 
01331     if (caLen) {
01332        sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen);
01333        if (!sid->u.ssl2.cipherArg.data) {
01334            return SECFailure;
01335        }
01336        sid->u.ssl2.cipherArg.len = caLen;
01337        PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
01338     }
01339     return SECSuccess;
01340 }
01341 
01342 /*
01343 ** Construct session keys given the masterKey (tied to the session-id),
01344 ** the client's challenge and the server's nonce.
01345 **
01346 ** Called from ssl2_CreateSessionCypher() <-
01347 */
01348 static SECStatus
01349 ssl2_ProduceKeys(sslSocket *    ss, 
01350             SECItem *      readKey, 
01351            SECItem *      writeKey,
01352            SECItem *      masterKey, 
01353            PRUint8 *      challenge,
01354            PRUint8 *      nonce, 
01355            int            cipherType)
01356 {
01357     PK11Context * cx        = 0;
01358     unsigned      nkm       = 0; /* number of hashes to generate key mat. */
01359     unsigned      nkd       = 0; /* size of readKey and writeKey. */
01360     unsigned      part;
01361     unsigned      i;
01362     unsigned      off;
01363     SECStatus     rv;
01364     PRUint8       countChar;
01365     PRUint8       km[3*16]; /* buffer for key material. */
01366 
01367     readKey->data = 0;
01368     writeKey->data = 0;
01369 
01370     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01371 
01372     rv = SECSuccess;
01373     cx = PK11_CreateDigestContext(SEC_OID_MD5);
01374     if (cx == NULL) {
01375        ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
01376        return SECFailure;
01377     }
01378 
01379     nkm = ssl_Specs[cipherType].nkm;
01380     nkd = ssl_Specs[cipherType].nkd;
01381 
01382     readKey->data = (PRUint8*) PORT_Alloc(nkd);
01383     if (!readKey->data) 
01384        goto loser;
01385     readKey->len = nkd;
01386 
01387     writeKey->data = (PRUint8*) PORT_Alloc(nkd);
01388     if (!writeKey->data) 
01389        goto loser;
01390     writeKey->len = nkd;
01391 
01392     /* Produce key material */
01393     countChar = '0';
01394     for (i = 0, off = 0; i < nkm; i++, off += 16) {
01395        rv  = PK11_DigestBegin(cx);
01396        rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
01397        rv |= PK11_DigestOp(cx, &countChar,      1);
01398        rv |= PK11_DigestOp(cx, challenge,       SSL_CHALLENGE_BYTES);
01399        rv |= PK11_DigestOp(cx, nonce,           SSL_CONNECTIONID_BYTES);
01400        rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH);
01401        if (rv != SECSuccess) {
01402            ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
01403            rv = SECFailure;
01404            goto loser;
01405        }
01406        countChar++;
01407     }
01408 
01409     /* Produce keys */
01410     PORT_Memcpy(readKey->data,  km,       nkd);
01411     PORT_Memcpy(writeKey->data, km + nkd, nkd);
01412 
01413 loser:
01414     PK11_DestroyContext(cx, PR_TRUE);
01415     return rv;
01416 }
01417 
01418 /* Called from ssl2_ServerSetupSessionCypher() 
01419 **                  <- ssl2_HandleClientSessionKeyMessage()
01420 **                          <- ssl2_HandleClientHelloMessage()
01421 ** and from    ssl2_ClientSetupSessionCypher() 
01422 **                  <- ssl2_HandleServerHelloMessage()
01423 */
01424 static SECStatus
01425 ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
01426 {
01427     SECItem         * rk = NULL;
01428     SECItem         * wk = NULL;
01429     SECItem *         param;
01430     SECStatus         rv;
01431     int               cipherType  = sid->u.ssl2.cipherType;
01432     PK11SlotInfo *    slot        = NULL;
01433     CK_MECHANISM_TYPE mechanism;
01434     SECItem           readKey;
01435     SECItem           writeKey;
01436 
01437     void *readcx = 0;
01438     void *writecx = 0;
01439     readKey.data = 0;
01440     writeKey.data = 0;
01441 
01442     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01443     if((ss->sec.ci.sid == 0))
01444        goto sec_loser;      /* don't crash if asserts are off */
01445 
01446     /* Trying to cut down on all these switch statements that should be tables.
01447      * So, test cipherType once, here, and then use tables below. 
01448      */
01449     switch (cipherType) {
01450     case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
01451     case SSL_CK_RC4_128_WITH_MD5:
01452     case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
01453     case SSL_CK_RC2_128_CBC_WITH_MD5:
01454     case SSL_CK_DES_64_CBC_WITH_MD5:
01455     case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
01456        break;
01457 
01458     default:
01459        SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
01460                SSL_GETPID(), ss->fd, cipherType));
01461        PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
01462        goto sec_loser;
01463     }
01464  
01465     rk = isClient ? &readKey  : &writeKey;
01466     wk = isClient ? &writeKey : &readKey;
01467 
01468     /* Produce the keys for this session */
01469     rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
01470                    ss->sec.ci.clientChallenge, ss->sec.ci.connectionID,
01471                    cipherType);
01472     if (rv != SECSuccess) 
01473        goto loser;
01474     PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
01475     PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));
01476 
01477     PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len);
01478     PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len);
01479     ss->sec.ci.keySize = readKey.len;
01480 
01481     /* Setup the MAC */
01482     rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType);
01483     if (rv != SECSuccess) 
01484        goto loser;
01485 
01486     /* First create the session key object */
01487     SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
01488            ssl_cipherName[cipherType]));
01489 
01490 
01491     mechanism  = ssl_Specs[cipherType].mechanism;
01492 
01493     /* set destructer before we call loser... */
01494     ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext;
01495     slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
01496     if (slot == NULL)
01497        goto loser;
01498 
01499     param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
01500     if (param == NULL)
01501        goto loser;
01502     readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
01503                                    CKA_DECRYPT, rk, param,
01504                                    ss->pkcs11PinArg);
01505     SECITEM_FreeItem(param, PR_TRUE);
01506     if (readcx == NULL)
01507        goto loser;
01508 
01509     /* build the client context */
01510     param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
01511     if (param == NULL)
01512        goto loser;
01513     writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
01514                                     CKA_ENCRYPT, wk, param,
01515                                     ss->pkcs11PinArg);
01516     SECITEM_FreeItem(param,PR_TRUE);
01517     if (writecx == NULL)
01518        goto loser;
01519     PK11_FreeSlot(slot);
01520 
01521     rv = SECSuccess;
01522     ss->sec.enc           = (SSLCipher) PK11_CipherOp;
01523     ss->sec.dec           = (SSLCipher) PK11_CipherOp;
01524     ss->sec.readcx        = (void *) readcx;
01525     ss->sec.writecx       = (void *) writecx;
01526     ss->sec.blockSize     = ssl_Specs[cipherType].blockSize;
01527     ss->sec.blockShift    = ssl_Specs[cipherType].blockShift;
01528     ss->sec.cipherType    = sid->u.ssl2.cipherType;
01529     ss->sec.keyBits       = sid->u.ssl2.keyBits;
01530     ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits;
01531     goto done;
01532 
01533   loser:
01534     if (ss->sec.destroy) {
01535        if (readcx)  (*ss->sec.destroy)(readcx, PR_TRUE);
01536        if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE);
01537     }
01538     ss->sec.destroy = NULL;
01539     if (slot) PK11_FreeSlot(slot);
01540 
01541   sec_loser:
01542     rv = SECFailure;
01543 
01544   done:
01545     if (rk) {
01546        SECITEM_ZfreeItem(rk, PR_FALSE);
01547     }
01548     if (wk) {
01549        SECITEM_ZfreeItem(wk, PR_FALSE);
01550     }
01551     return rv;
01552 }
01553 
01554 /*
01555 ** Setup the server ciphers given information from a CLIENT-MASTER-KEY
01556 ** message.
01557 **     "ss"      pointer to the ssl-socket object
01558 **     "cipher"  the cipher type to use
01559 **     "keyBits" the size of the final cipher key
01560 **     "ck"      the clear-key data
01561 **     "ckLen"   the number of bytes of clear-key data
01562 **     "ek"      the encrypted-key data
01563 **     "ekLen"   the number of bytes of encrypted-key data
01564 **     "ca"      the cipher-arg data
01565 **     "caLen"   the number of bytes of cipher-arg data
01566 **
01567 ** The MASTER-KEY is constructed by first decrypting the encrypted-key
01568 ** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
01569 ** concatenating the clear-key data with the SECRET-KEY-DATA. This code
01570 ** checks to make sure that the client didn't send us an improper amount
01571 ** of SECRET-KEY-DATA (it restricts the length of that data to match the
01572 ** spec).
01573 **
01574 ** Called from ssl2_HandleClientSessionKeyMessage().
01575 */
01576 static SECStatus
01577 ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
01578                       PRUint8 *ck, unsigned int ckLen,
01579                       PRUint8 *ek, unsigned int ekLen,
01580                       PRUint8 *ca, unsigned int caLen)
01581 {
01582     PRUint8           *kk = NULL;
01583     sslSessionID *    sid;
01584     PRUint8       *   kbuf = 0;    /* buffer for RSA decrypted data. */
01585     unsigned int      el1;  /* length of RSA decrypted data in kbuf */
01586     unsigned int      keySize;
01587     unsigned int      modulusLen;
01588     SECStatus         rv;
01589     PRUint8           mkbuf[SSL_MAX_MASTER_KEY_BYTES];
01590     sslServerCerts  * sc = ss->serverCerts + kt_rsa;
01591 
01592     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01593     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
01594     PORT_Assert((sc->SERVERKEY != 0));
01595     PORT_Assert((ss->sec.ci.sid != 0));
01596     sid = ss->sec.ci.sid;
01597 
01598     keySize = (keyBits + 7) >> 3;
01599     /* Is the message just way too big? */
01600     if (keySize > SSL_MAX_MASTER_KEY_BYTES) {
01601        /* bummer */
01602        SSL_DBG(("%d: SSL[%d]: keySize=%d ckLen=%d max session key size=%d",
01603                SSL_GETPID(), ss->fd, keySize, ckLen,
01604                SSL_MAX_MASTER_KEY_BYTES));
01605        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01606        goto loser;
01607     }
01608 
01609 
01610     /* Trying to cut down on all these switch statements that should be tables.
01611      * So, test cipherType once, here, and then use tables below. 
01612      */
01613     switch (cipher) {
01614     case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
01615     case SSL_CK_RC4_128_WITH_MD5:
01616     case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
01617     case SSL_CK_RC2_128_CBC_WITH_MD5:
01618     case SSL_CK_DES_64_CBC_WITH_MD5:
01619     case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
01620        break;
01621 
01622     default:
01623        SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
01624                SSL_GETPID(), ss->fd, cipher));
01625        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01626        goto loser;
01627     }
01628 
01629     /* For export ciphers, make sure they didn't send too much key data. */
01630     if (ckLen != ssl_Specs[cipher].pubLen) {
01631        SSL_DBG(("%d: SSL[%d]: odd secret key size, keySize=%d ckLen=%d!",
01632                SSL_GETPID(), ss->fd, keySize, ckLen));
01633        /* Somebody tried to sneak by a strange secret key */
01634        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01635        goto loser;
01636     }
01637 
01638     /* allocate the buffer to hold the decrypted portion of the key. */
01639     /* XXX Haven't done any range check on ekLen. */
01640     kbuf = (PRUint8*) PORT_Alloc(ekLen);
01641     if (!kbuf) {
01642        goto loser;
01643     }
01644 
01645     /*
01646     ** Decrypt encrypted half of the key. Note that encrypted half has
01647     ** been made to match the modulus size of our public key using
01648     ** PKCS#1. keySize is the real size of the data that is interesting.
01649     ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
01650     ** desired behavior here.
01651     */
01652     rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &el1, ekLen, ek, ekLen);
01653     if (rv != SECSuccess) 
01654        goto hide_loser;
01655 
01656     modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
01657     if (modulusLen == -1) {
01658        /* If the key was really bad, then PK11_pubDecryptRaw
01659         * would have failed, therefore the we must assume that the card
01660         * is just being a pain and not giving us the modulus... but it
01661         * should be the same size as the encrypted key length, so use it
01662         * and keep cranking */
01663        modulusLen = ekLen;
01664     }
01665     /* Is the length of the decrypted data (el1) the expected value? */
01666     if (modulusLen != el1) 
01667        goto hide_loser;
01668 
01669     /* Cheaply verify that PKCS#1 was used to format the encryption block */
01670     kk = kbuf + modulusLen - (keySize - ckLen);
01671     if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (kk[-1] != 0x00)) {
01672        /* Tsk tsk. */
01673        SSL_DBG(("%d: SSL[%d]: strange encryption block",
01674                SSL_GETPID(), ss->fd));
01675        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01676        goto hide_loser;
01677     }
01678 
01679     /* Make sure we're not subject to a version rollback attack. */
01680     if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
01681        PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
01682                            0x03, 0x03, 0x03, 0x03 };
01683        
01684        if (PORT_Memcmp(kk - 8 - 1, threes, 8) == 0) {
01685            PORT_SetError(SSL_ERROR_BAD_CLIENT);
01686            goto hide_loser;
01687        }
01688     }
01689     if (0) {
01690 hide_loser:
01691        /* Defense against the Bleichenbacher attack.
01692         * Provide the client with NO CLUES that the decrypted master key
01693         * was erroneous.  Don't send any error messages.
01694         * Instead, Generate a completely bogus master key .
01695         */
01696        PK11_GenerateRandom(kbuf, ekLen);
01697        if (!kk) {
01698            kk = kbuf + ekLen - (keySize-ckLen);
01699        }
01700     }
01701 
01702     /*
01703     ** Construct master key out of the pieces.
01704     */
01705     if (ckLen) {
01706        PORT_Memcpy(mkbuf, ck, ckLen);
01707     }
01708     PORT_Memcpy(mkbuf+ckLen, kk, keySize-ckLen);
01709 
01710     /* Fill in session-id */
01711     rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
01712                  keyBits, keyBits - (ckLen<<3),
01713                  ss->sec.authAlgorithm, ss->sec.authKeyBits,
01714                  ss->sec.keaType,       ss->sec.keaKeyBits);
01715     if (rv != SECSuccess) {
01716        goto loser;
01717     }
01718 
01719     /* Create session ciphers */
01720     rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
01721     if (rv != SECSuccess) {
01722        goto loser;
01723     }
01724 
01725     SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
01726               SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
01727               ckLen<<3, keySize<<3));
01728     rv = SECSuccess;
01729     goto done;
01730 
01731   loser:
01732     rv = SECFailure;
01733 
01734   done:
01735     PORT_Free(kbuf);
01736     return rv;
01737 }
01738 
01739 /************************************************************************/
01740 
01741 /*
01742 ** Rewrite the incoming cipher specs, comparing to list of specs we support,
01743 ** (ss->cipherSpecs) and eliminating anything we don't support
01744 **
01745 *  Note: Our list may contain SSL v3 ciphers.  
01746 *  We MUST NOT match on any of those.  
01747 *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
01748 *  in the first byte, and none of the SSLv2 ciphers do.
01749 *
01750 *  Called from ssl2_HandleClientHelloMessage().
01751 *  Returns the number of bytes of "qualified cipher specs", 
01752 *  which is typically a multiple of 3, but will be zero if there are none.
01753 */
01754 static int
01755 ssl2_QualifyCypherSpecs(sslSocket *ss, 
01756                         PRUint8 *  cs, /* cipher specs in client hello msg. */
01757                       int        csLen)
01758 {
01759     PRUint8 *    ms;
01760     PRUint8 *    hs;
01761     PRUint8 *    qs;
01762     int          mc;
01763     int          hc;
01764     PRUint8      qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
01765 
01766     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01767     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
01768 
01769     if (!ss->cipherSpecs) {
01770        SECStatus rv = ssl2_ConstructCipherSpecs(ss);
01771        if (rv != SECSuccess || !ss->cipherSpecs) 
01772            return 0;
01773     }
01774 
01775     PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
01776     qs = qualifiedSpecs;
01777     ms = ss->cipherSpecs;
01778     for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
01779        if (ms[0] == 0)
01780            continue;
01781        for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
01782            if ((hs[0] == ms[0]) &&
01783               (hs[1] == ms[1]) &&
01784               (hs[2] == ms[2])) {
01785               /* Copy this cipher spec into the "keep" section */
01786               qs[0] = hs[0];
01787               qs[1] = hs[1];
01788               qs[2] = hs[2];
01789               qs   += 3;
01790               break;
01791            }
01792        }
01793     }
01794     hc = qs - qualifiedSpecs;
01795     PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
01796     PORT_Memcpy(cs, qualifiedSpecs, hc);
01797     return hc;
01798 }
01799 
01800 /*
01801 ** Pick the best cipher we can find, given the array of server cipher
01802 ** specs.  Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
01803 ** If succesful, stores the master key size (bytes) in *pKeyLen.
01804 **
01805 ** This is correct only for the client side, but presently
01806 ** this function is only called from 
01807 **     ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
01808 **
01809 ** Note that most servers only return a single cipher suite in their 
01810 ** ServerHello messages.  So, the code below for finding the "best" cipher
01811 ** suite usually has only one choice.  The client and server should send 
01812 ** their cipher suite lists sorted in descending order by preference.
01813 */
01814 static int
01815 ssl2_ChooseSessionCypher(sslSocket *ss, 
01816                          int        hc,    /* number of cs's in hs. */
01817                        PRUint8 *  hs,    /* server hello's cipher suites. */
01818                        int *      pKeyLen) /* out: sym key size in bytes. */
01819 {
01820     PRUint8 *       ms;
01821     unsigned int    i;
01822     int             bestKeySize;
01823     int             bestRealKeySize;
01824     int             bestCypher;
01825     int             keySize;
01826     int             realKeySize;
01827     PRUint8 *       ohs               = hs;
01828     const PRUint8 * preferred;
01829     static const PRUint8 noneSuch[3] = { 0, 0, 0 };
01830 
01831     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01832     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
01833 
01834     if (!ss->cipherSpecs) {
01835        SECStatus rv = ssl2_ConstructCipherSpecs(ss);
01836        if (rv != SECSuccess || !ss->cipherSpecs) 
01837            goto loser;
01838     }
01839 
01840     if (!ss->preferredCipher) {
01841        unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
01842                               SSL_CB_IMPLEMENTED;
01843        if (allowed) {
01844            preferred = implementedCipherSuites;
01845            for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
01846               if (0 != (allowed & (1U << preferred[0]))) {
01847                   ss->preferredCipher = preferred;
01848                   break;
01849               }
01850               preferred += 3;
01851            }
01852        }
01853     }
01854     preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
01855     /*
01856     ** Scan list of ciphers recieved from peer and look for a match in
01857     ** our list.  
01858     *  Note: Our list may contain SSL v3 ciphers.  
01859     *  We MUST NOT match on any of those.  
01860     *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
01861     *  in the first byte, and none of the SSLv2 ciphers do.
01862     */
01863     bestKeySize = bestRealKeySize = 0;
01864     bestCypher = -1;
01865     while (--hc >= 0) {
01866        for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
01867            if ((hs[0] == preferred[0]) &&
01868               (hs[1] == preferred[1]) &&
01869               (hs[2] == preferred[2]) &&
01870                hs[0] != 0) {
01871               /* Pick this cipher immediately! */
01872               *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
01873               return hs[0];
01874            }
01875            if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
01876                 hs[0] != 0) {
01877               /* Found a match */
01878 
01879               /* Use secret keySize to determine which cipher is best */
01880               realKeySize = (hs[1] << 8) | hs[2];
01881               switch (hs[0]) {
01882                 case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
01883                 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
01884                   keySize = 40;
01885                   break;
01886                 default:
01887                   keySize = realKeySize;
01888                   break;
01889               }
01890               if (keySize > bestKeySize) {
01891                   bestCypher = hs[0];
01892                   bestKeySize = keySize;
01893                   bestRealKeySize = realKeySize;
01894               }
01895            }
01896        }
01897        hs += 3;
01898     }
01899     if (bestCypher < 0) {
01900        /*
01901        ** No overlap between server and client. Re-examine server list
01902        ** to see what kind of ciphers it does support so that we can set
01903        ** the error code appropriately.
01904        */
01905        if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
01906            (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
01907            PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
01908        } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
01909                  (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
01910            PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
01911        } else {
01912            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
01913        }
01914        SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
01915        goto loser;
01916     }
01917     *pKeyLen = (bestRealKeySize + 7) >> 3;
01918     return bestCypher;
01919 
01920   loser:
01921     return -1;
01922 }
01923 
01924 static SECStatus
01925 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
01926 {
01927     CERTCertificate *cert      = NULL;
01928     SECItem          certItem;
01929 
01930     certItem.data = certData;
01931     certItem.len  = certLen;
01932 
01933     /* decode the certificate */
01934     cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
01935                                PR_FALSE, PR_TRUE);
01936     
01937     if (cert == NULL) {
01938        SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
01939                SSL_GETPID(), ss->fd));
01940        PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
01941        return SECFailure;
01942     }
01943 
01944 #ifdef TRACE
01945     {
01946        if (ssl_trace >= 1) {
01947            char *issuer;
01948            char *subject;
01949            issuer = CERT_NameToAscii(&cert->issuer);
01950            subject = CERT_NameToAscii(&cert->subject);
01951            SSL_TRC(1,("%d: server certificate issuer: '%s'",
01952                      SSL_GETPID(), issuer ? issuer : "OOPS"));
01953            SSL_TRC(1,("%d: server name: '%s'",
01954                      SSL_GETPID(), subject ? subject : "OOPS"));
01955            PORT_Free(issuer);
01956            PORT_Free(subject);
01957        }
01958     }
01959 #endif
01960 
01961     ss->sec.peerCert = cert;
01962     return SECSuccess;
01963 }
01964 
01965 
01966 /*
01967  * Format one block of data for public/private key encryption using
01968  * the rules defined in PKCS #1. SSL2 does this itself to handle the
01969  * rollback detection.
01970  */
01971 #define RSA_BLOCK_MIN_PAD_LEN           8
01972 #define RSA_BLOCK_FIRST_OCTET           0x00
01973 #define RSA_BLOCK_AFTER_PAD_OCTET       0x00
01974 #define RSA_BLOCK_PUBLIC_OCTET            0x02
01975 unsigned char *
01976 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
01977 {
01978     unsigned char *block;
01979     unsigned char *bp;
01980     int padLen;
01981     SECStatus rv;
01982     int i;
01983 
01984     PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
01985     block = (unsigned char *) PORT_Alloc(modulusLen);
01986     if (block == NULL)
01987        return NULL;
01988 
01989     bp = block;
01990 
01991     /*
01992      * All RSA blocks start with two octets:
01993      * 0x00 || BlockType
01994      */
01995     *bp++ = RSA_BLOCK_FIRST_OCTET;
01996     *bp++ = RSA_BLOCK_PUBLIC_OCTET;
01997 
01998     /*
01999      * 0x00 || BT || Pad || 0x00 || ActualData
02000      *   1      1   padLen    1      data->len
02001      * Pad is all non-zero random bytes.
02002      */
02003     padLen = modulusLen - data->len - 3;
02004     PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
02005     rv = PK11_GenerateRandom(bp, padLen);
02006     if (rv == SECFailure) goto loser;
02007     /* replace all the 'zero' bytes */
02008     for (i = 0; i < padLen; i++) {
02009        while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
02010            rv = PK11_GenerateRandom(bp+i, 1);
02011            if (rv == SECFailure) goto loser;
02012        }
02013     }
02014     bp += padLen;
02015     *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
02016     PORT_Memcpy (bp, data->data, data->len);
02017 
02018     return block;
02019 loser:
02020     if (block) PORT_Free(block);
02021     return NULL;
02022 }
02023 
02024 /*
02025 ** Given the server's public key and cipher specs, generate a session key
02026 ** that is ready to use for encrypting/decrypting the byte stream. At
02027 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
02028 ** send it to the server.
02029 **
02030 ** Called from ssl2_HandleServerHelloMessage()
02031 */
02032 static SECStatus
02033 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
02034 {
02035     sslSessionID *    sid;
02036     PRUint8 *         ca;   /* points to iv data, or NULL if none. */
02037     PRUint8 *         ekbuf               = 0;
02038     CERTCertificate * cert         = 0;
02039     SECKEYPublicKey * serverKey    = 0;
02040     unsigned          modulusLen   = 0;
02041     SECStatus         rv;
02042     int               cipher;
02043     int               keyLen;      /* cipher symkey size in bytes. */
02044     int               ckLen;       /* publicly reveal this many bytes of key. */
02045     int               caLen;       /* length of IV data at *ca.       */
02046     int               nc;
02047 
02048     unsigned char *eblock;  /* holds unencrypted PKCS#1 formatted key. */
02049     SECItem           rek;  /* holds portion of symkey to be encrypted. */
02050 
02051     PRUint8           keyData[SSL_MAX_MASTER_KEY_BYTES];
02052     PRUint8           iv     [8];
02053 
02054     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02055 
02056     eblock = NULL;
02057 
02058     sid = ss->sec.ci.sid;
02059     PORT_Assert(sid != 0);
02060 
02061     cert = ss->sec.peerCert;
02062     
02063     serverKey = CERT_ExtractPublicKey(cert);
02064     if (!serverKey) {
02065        SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
02066                SSL_GETPID(), ss->fd, PORT_GetError()));
02067        PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
02068        rv = SECFailure;
02069        goto loser2;
02070     }
02071 
02072     ss->sec.authAlgorithm = ssl_sign_rsa;
02073     ss->sec.keaType       = ssl_kea_rsa;
02074     ss->sec.keaKeyBits    = \
02075     ss->sec.authKeyBits   = SECKEY_PublicKeyStrengthInBits(serverKey);
02076 
02077     /* Choose a compatible cipher with the server */
02078     nc = csLen / 3;
02079     cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
02080     if (cipher < 0) {
02081        /* ssl2_ChooseSessionCypher has set error code. */
02082        ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
02083        goto loser;
02084     }
02085 
02086     /* Generate the random keys */
02087     PK11_GenerateRandom(keyData, sizeof(keyData));
02088 
02089     /*
02090     ** Next, carve up the keys into clear and encrypted portions. The
02091     ** clear data is taken from the start of keyData and the encrypted
02092     ** portion from the remainder. Note that each of these portions is
02093     ** carved in half, one half for the read-key and one for the
02094     ** write-key.
02095     */
02096     ca = 0;
02097 
02098     /* We know that cipher is a legit value here, because 
02099      * ssl2_ChooseSessionCypher doesn't return bogus values.
02100      */
02101     ckLen = ssl_Specs[cipher].pubLen;     /* cleartext key length. */
02102     caLen = ssl_Specs[cipher].ivLen;      /* IV length.        */
02103     if (caLen) {
02104        PORT_Assert(sizeof iv >= caLen);
02105        PK11_GenerateRandom(iv, caLen);
02106        ca = iv;
02107     }
02108 
02109     /* Fill in session-id */
02110     rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
02111                  ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
02112                  ss->sec.authAlgorithm, ss->sec.authKeyBits,
02113                  ss->sec.keaType,       ss->sec.keaKeyBits);
02114     if (rv != SECSuccess) {
02115        goto loser;
02116     }
02117 
02118     SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
02119               SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
02120               ckLen<<3, keyLen<<3));
02121 
02122     /* Now setup read and write ciphers */
02123     rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
02124     if (rv != SECSuccess) {
02125        goto loser;
02126     }
02127 
02128     /*
02129     ** Fill in the encryption buffer with some random bytes. Then 
02130     ** copy in the portion of the session key we are encrypting.
02131     */
02132     modulusLen = SECKEY_PublicKeyStrength(serverKey);
02133     rek.data   = keyData + ckLen;
02134     rek.len    = keyLen  - ckLen;
02135     eblock = ssl_FormatSSL2Block(modulusLen, &rek);
02136     if (eblock == NULL) 
02137        goto loser;
02138 
02139     /* Set up the padding for version 2 rollback detection. */
02140     /* XXX We should really use defines here */
02141     if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
02142        PORT_Assert((modulusLen - rek.len) > 12);
02143        PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
02144     }
02145     ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
02146     if (!ekbuf) 
02147        goto loser;
02148     PRINT_BUF(10, (ss, "master key encryption block:",
02149                  eblock, modulusLen));
02150 
02151     /* Encrypt ekitem */
02152     rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
02153                                           ss->pkcs11PinArg);
02154     if (rv) 
02155        goto loser;
02156 
02157     /*  Now we have everything ready to send */
02158     rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
02159                             keyData, ckLen, ekbuf, modulusLen);
02160     if (rv != SECSuccess) {
02161        goto loser;
02162     }
02163     rv = SECSuccess;
02164     goto done;
02165 
02166   loser:
02167     rv = SECFailure;
02168 
02169   loser2:
02170   done:
02171     PORT_Memset(keyData, 0, sizeof(keyData));
02172     PORT_ZFree(ekbuf, modulusLen);
02173     PORT_ZFree(eblock, modulusLen);
02174     SECKEY_DestroyPublicKey(serverKey);
02175     return rv;
02176 }
02177 
02178 /************************************************************************/
02179 
02180 /* 
02181  * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
02182  * Caller holds recvBufLock and handshakeLock
02183  */
02184 static void
02185 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
02186 {
02187     sslSessionID *sid = ss->sec.ci.sid;
02188 
02189     /* Record entry in nonce cache */
02190     if (sid->peerCert == NULL) {
02191        PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
02192        sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
02193 
02194     }
02195     if (!ss->opt.noCache)
02196        (*ss->sec.cache)(sid);
02197 }
02198 
02199 /* Called from ssl2_HandleMessage() */
02200 static SECStatus
02201 ssl2_TriggerNextMessage(sslSocket *ss)
02202 {
02203     SECStatus        rv;
02204 
02205     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02206 
02207     if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
02208        !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
02209        ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
02210        rv = ssl2_SendCertificateRequestMessage(ss);
02211        return rv;
02212     }
02213     return SECSuccess;
02214 }
02215 
02216 /* See if it's time to send our finished message, or if the handshakes are
02217 ** complete.  Send finished message if appropriate.
02218 ** Returns SECSuccess unless anything goes wrong.
02219 **
02220 ** Called from ssl2_HandleMessage,
02221 **             ssl2_HandleVerifyMessage 
02222 **             ssl2_HandleServerHelloMessage
02223 **             ssl2_HandleClientSessionKeyMessage
02224 **             ssl2_RestartHandshakeAfterCertReq
02225 **             ssl2_RestartHandshakeAfterServerCert
02226 */
02227 static SECStatus
02228 ssl2_TryToFinish(sslSocket *ss)
02229 {
02230     SECStatus        rv;
02231     char             e, ef;
02232 
02233     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02234 
02235     e = ss->sec.ci.elements;
02236     ef = e | CIS_HAVE_FINISHED;
02237     if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
02238        if (ss->sec.isServer) {
02239            /* Send server finished message if we already didn't */
02240            rv = ssl2_SendServerFinishedMessage(ss);
02241        } else {
02242            /* Send client finished message if we already didn't */
02243            rv = ssl2_SendClientFinishedMessage(ss);
02244        }
02245        if (rv != SECSuccess) {
02246            return rv;
02247        }
02248        if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
02249            /* Totally finished */
02250            ss->handshake = 0;
02251            return SECSuccess;
02252        }
02253     }
02254     return SECSuccess;
02255 }
02256 
02257 /*
02258 ** Called from ssl2_HandleRequestCertificate
02259 **             ssl2_RestartHandshakeAfterCertReq
02260 */
02261 static SECStatus
02262 ssl2_SignResponse(sslSocket *ss,
02263             SECKEYPrivateKey *key,
02264             SECItem *response)
02265 {
02266     SGNContext *     sgn = NULL;
02267     PRUint8 *        challenge;
02268     unsigned int     len;
02269     SECStatus        rv            = SECFailure;
02270     
02271     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02272 
02273     challenge = ss->sec.ci.serverChallenge;
02274     len = ss->sec.ci.serverChallengeLen;
02275     
02276     /* Sign the expected data... */
02277     sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
02278     if (!sgn) 
02279        goto done;
02280     rv = SGN_Begin(sgn);
02281     if (rv != SECSuccess) 
02282        goto done;
02283     rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
02284     if (rv != SECSuccess) 
02285        goto done;
02286     rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
02287     if (rv != SECSuccess) 
02288        goto done;
02289     rv = SGN_Update(sgn, challenge, len);
02290     if (rv != SECSuccess) 
02291        goto done;
02292     rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, 
02293                          ss->sec.peerCert->derCert.len);
02294     if (rv != SECSuccess) 
02295        goto done;
02296     rv = SGN_End(sgn, response);
02297     if (rv != SECSuccess) 
02298        goto done;
02299 
02300 done:
02301     SGN_DestroyContext(sgn, PR_TRUE);
02302     return rv == SECSuccess ? SECSuccess : SECFailure;
02303 }
02304 
02305 /*
02306 ** Try to handle a request-certificate message. Get client's certificate
02307 ** and private key and sign a message for the server to see.
02308 ** Caller must hold handshakeLock 
02309 **
02310 ** Called from ssl2_HandleMessage().
02311 */
02312 static int
02313 ssl2_HandleRequestCertificate(sslSocket *ss)
02314 {
02315     CERTCertificate * cert  = NULL;       /* app-selected client cert. */
02316     SECKEYPrivateKey *key   = NULL;       /* priv key for cert. */
02317     SECStatus         rv;
02318     SECItem           response;
02319     int               ret   = 0;
02320     PRUint8           authType;
02321 
02322 
02323     /*
02324      * These things all need to be initialized before we can "goto loser".
02325      */
02326     response.data = NULL;
02327 
02328     /* get challenge info from connectionInfo */
02329     authType = ss->sec.ci.authType;
02330 
02331     if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
02332        SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
02333                   ss->fd, authType));
02334        goto no_cert_error;
02335     }
02336 
02337     /* Get certificate and private-key from client */
02338     if (!ss->getClientAuthData) {
02339        SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
02340                   SSL_GETPID(), ss->fd));
02341        goto no_cert_error;
02342     }
02343     ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
02344                                NULL, &cert, &key);
02345     if ( ret == SECWouldBlock ) {
02346        ssl_SetAlwaysBlock(ss);
02347        goto done;
02348     }
02349 
02350     if (ret) {
02351        goto no_cert_error;
02352     }
02353 
02354     /* check what the callback function returned */
02355     if ((!cert) || (!key)) {
02356         /* we are missing either the key or cert */
02357         if (cert) {
02358             /* got a cert, but no key - free it */
02359             CERT_DestroyCertificate(cert);
02360             cert = NULL;
02361         }
02362         if (key) {
02363             /* got a key, but no cert - free it */
02364             SECKEY_DestroyPrivateKey(key);
02365             key = NULL;
02366         }
02367         goto no_cert_error;
02368     }
02369 
02370     rv = ssl2_SignResponse(ss, key, &response);
02371     if ( rv != SECSuccess ) {
02372        ret = -1;
02373        goto loser;
02374     }
02375 
02376     /* Send response message */
02377     ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
02378 
02379     /* Now, remember the cert we sent. But first, forget any previous one. */
02380     if (ss->sec.localCert) {
02381        CERT_DestroyCertificate(ss->sec.localCert);
02382     }
02383     ss->sec.localCert = CERT_DupCertificate(cert);
02384     PORT_Assert(!ss->sec.ci.sid->localCert);
02385     if (ss->sec.ci.sid->localCert) {
02386        CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
02387     }
02388     ss->sec.ci.sid->localCert = cert;
02389     cert = NULL;
02390 
02391     goto done;
02392 
02393   no_cert_error:
02394     SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
02395               ss->fd, ret));
02396     ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
02397 
02398   loser:
02399   done:
02400     if ( cert ) {
02401        CERT_DestroyCertificate(cert);
02402     }
02403     if ( key ) {
02404        SECKEY_DestroyPrivateKey(key);
02405     }
02406     if ( response.data ) {
02407        PORT_Free(response.data);
02408     }
02409     
02410     return ret;
02411 }
02412 
02413 /*
02414 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
02415 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response
02416 ** are contained in the gathered input data.
02417 */
02418 static SECStatus
02419 ssl2_HandleClientCertificate(sslSocket *    ss, 
02420                              PRUint8        certType,   /* XXX unused */
02421                           PRUint8 *      cd, 
02422                           unsigned int   cdLen,
02423                           PRUint8 *      response,
02424                           unsigned int   responseLen)
02425 {
02426     CERTCertificate *cert   = NULL;
02427     SECKEYPublicKey *pubKey = NULL;
02428     VFYContext *     vfy    = NULL;
02429     SECItem *        derCert;
02430     SECStatus        rv            = SECFailure;
02431     SECItem          certItem;
02432     SECItem          rep;
02433 
02434     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02435     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
02436 
02437     /* Extract the certificate */
02438     certItem.data = cd;
02439     certItem.len  = cdLen;
02440 
02441     cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
02442                                PR_FALSE, PR_TRUE);
02443     if (cert == NULL) {
02444        goto loser;
02445     }
02446 
02447     /* save the certificate, since the auth routine will need it */
02448     ss->sec.peerCert = cert;
02449 
02450     /* Extract the public key */
02451     pubKey = CERT_ExtractPublicKey(cert);
02452     if (!pubKey) 
02453        goto loser;
02454     
02455     /* Verify the response data... */
02456     rep.data = response;
02457     rep.len = responseLen;
02458     /* SSL 2.0 only supports RSA certs, so we don't have to worry about
02459      * DSA here. */
02460     vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
02461                          ss->pkcs11PinArg);
02462     if (!vfy) 
02463        goto loser;
02464     rv = VFY_Begin(vfy);
02465     if (rv) 
02466        goto loser;
02467 
02468     rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
02469     if (rv) 
02470        goto loser;
02471     rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
02472     if (rv) 
02473        goto loser;
02474     rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
02475     if (rv) 
02476        goto loser;
02477 
02478     derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
02479     rv = VFY_Update(vfy, derCert->data, derCert->len);
02480     if (rv) 
02481        goto loser;
02482     rv = VFY_End(vfy);
02483     if (rv) 
02484        goto loser;
02485 
02486     /* Now ask the server application if it likes the certificate... */
02487     rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
02488                                        ss->fd, PR_TRUE, PR_TRUE);
02489     /* Hey, it liked it. */
02490     if (SECSuccess == rv) 
02491        goto done;
02492 
02493 loser:
02494     ss->sec.peerCert = NULL;
02495     CERT_DestroyCertificate(cert);
02496 
02497 done:
02498     VFY_DestroyContext(vfy, PR_TRUE);
02499     SECKEY_DestroyPublicKey(pubKey);
02500     return rv;
02501 }
02502 
02503 /*
02504 ** Handle remaining messages between client/server. Process finished
02505 ** messages from either side and any authentication requests.
02506 ** This should only be called for SSLv2 handshake messages, 
02507 ** not for application data records.
02508 ** Caller must hold handshake lock.
02509 **
02510 ** Called from ssl_Do1stHandshake().
02511 ** 
02512 */
02513 static SECStatus
02514 ssl2_HandleMessage(sslSocket *ss)
02515 {
02516     PRUint8 *        data;
02517     PRUint8 *        cid;
02518     unsigned         len, certType, certLen, responseLen;
02519     int              rv;
02520     int              rv2;
02521 
02522     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02523 
02524     ssl_GetRecvBufLock(ss);
02525 
02526     data = ss->gs.buf.buf + ss->gs.recordOffset;
02527 
02528     if (ss->gs.recordLen < 1) {
02529        goto bad_peer;
02530     }
02531     SSL_TRC(3, ("%d: SSL[%d]: received %d message",
02532               SSL_GETPID(), ss->fd, data[0]));
02533     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
02534 
02535     switch (data[0]) {
02536     case SSL_MT_CLIENT_FINISHED:
02537        if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
02538            SSL_DBG(("%d: SSL[%d]: dup client-finished message",
02539                    SSL_GETPID(), ss->fd));
02540            goto bad_peer;
02541        }
02542 
02543        /* See if nonce matches */
02544        len = ss->gs.recordLen - 1;
02545        cid = data + 1;
02546        if ((len != sizeof(ss->sec.ci.connectionID)) ||
02547            (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
02548            SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
02549            PRINT_BUF(5, (ss, "sent connection-id",
02550                        ss->sec.ci.connectionID, 
02551                        sizeof(ss->sec.ci.connectionID)));
02552            PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
02553            goto bad_peer;
02554        }
02555 
02556        SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
02557                   SSL_GETPID(), ss->fd, 
02558                   ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
02559        ss->sec.ci.elements |= CIS_HAVE_FINISHED;
02560        break;
02561 
02562     case SSL_MT_SERVER_FINISHED:
02563        if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
02564            SSL_DBG(("%d: SSL[%d]: dup server-finished message",
02565                    SSL_GETPID(), ss->fd));
02566            goto bad_peer;
02567        }
02568 
02569        if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
02570            SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
02571                    SSL_GETPID(), ss->fd, ss->gs.recordLen));
02572            goto bad_peer;
02573        }
02574        ssl2_ClientRegSessionID(ss, data+1);
02575        SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
02576                   SSL_GETPID(), ss->fd, 
02577                   ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
02578        ss->sec.ci.elements |= CIS_HAVE_FINISHED;
02579        break;
02580 
02581     case SSL_MT_REQUEST_CERTIFICATE:
02582        len = ss->gs.recordLen - 2;
02583        if ((len < SSL_MIN_CHALLENGE_BYTES) ||
02584            (len > SSL_MAX_CHALLENGE_BYTES)) {
02585            /* Bad challenge */
02586            SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
02587                    SSL_GETPID(), ss->fd, len));
02588            goto bad_peer;
02589        }
02590        
02591        /* save auth request info */
02592        ss->sec.ci.authType           = data[1];
02593        ss->sec.ci.serverChallengeLen = len;
02594        PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
02595        
02596        rv = ssl2_HandleRequestCertificate(ss);
02597        if (rv == SECWouldBlock) {
02598            SSL_TRC(3, ("%d: SSL[%d]: async cert request",
02599                      SSL_GETPID(), ss->fd));
02600            /* someone is handling this asynchronously */
02601            ssl_ReleaseRecvBufLock(ss);
02602            return SECWouldBlock;
02603        }
02604        if (rv) {
02605            SET_ERROR_CODE
02606            goto loser;
02607        }
02608        break;
02609 
02610     case SSL_MT_CLIENT_CERTIFICATE:
02611        if (!ss->authCertificate) {
02612            /* Server asked for authentication and can't handle it */
02613            PORT_SetError(SSL_ERROR_BAD_SERVER);
02614            goto loser;
02615        }
02616        if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
02617            SET_ERROR_CODE
02618            goto loser;
02619        }
02620        certType    = data[1];
02621        certLen     = (data[2] << 8) | data[3];
02622        responseLen = (data[4] << 8) | data[5];
02623        if (certType != SSL_CT_X509_CERTIFICATE) {
02624            PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
02625            goto loser;
02626        }
02627        if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES 
02628            > ss->gs.recordLen) {
02629            /* prevent overflow crash. */
02630            rv = SECFailure;
02631        } else
02632        rv = ssl2_HandleClientCertificate(ss, data[1],
02633               data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
02634               certLen,
02635               data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
02636               responseLen);
02637        if (rv) {
02638            rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
02639            SET_ERROR_CODE
02640            goto loser;
02641        }
02642        ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
02643        break;
02644 
02645     case SSL_MT_ERROR:
02646        rv = (data[1] << 8) | data[2];
02647        SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
02648                   SSL_GETPID(), ss->fd, rv));
02649 
02650        /* Convert protocol error number into API error number */
02651        switch (rv) {
02652          case SSL_PE_NO_CYPHERS:
02653            rv = SSL_ERROR_NO_CYPHER_OVERLAP;
02654            break;
02655          case SSL_PE_NO_CERTIFICATE:
02656            rv = SSL_ERROR_NO_CERTIFICATE;
02657            break;
02658          case SSL_PE_BAD_CERTIFICATE:
02659            rv = SSL_ERROR_BAD_CERTIFICATE;
02660            break;
02661          case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
02662            rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
02663            break;
02664          default:
02665            goto bad_peer;
02666        }
02667        /* XXX make certificate-request optionally fail... */
02668        PORT_SetError(rv);
02669        goto loser;
02670 
02671     default:
02672        SSL_DBG(("%d: SSL[%d]: unknown message %d",
02673                SSL_GETPID(), ss->fd, data[0]));
02674        goto loser;
02675     }
02676 
02677     SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
02678               SSL_GETPID(), ss->fd, data[0],
02679               ss->sec.ci.requiredElements, ss->sec.ci.elements));
02680 
02681     rv = ssl2_TryToFinish(ss);
02682     if (rv != SECSuccess) 
02683        goto loser;
02684 
02685     ss->gs.recordLen = 0;
02686     ssl_ReleaseRecvBufLock(ss);
02687 
02688     if (ss->handshake == 0) {
02689        return SECSuccess;
02690     }
02691 
02692     ss->handshake     = ssl_GatherRecord1stHandshake;
02693     ss->nextHandshake = ssl2_HandleMessage;
02694     return ssl2_TriggerNextMessage(ss);
02695 
02696   bad_peer:
02697     PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
02698     /* FALL THROUGH */
02699 
02700   loser:
02701     ssl_ReleaseRecvBufLock(ss);
02702     return SECFailure;
02703 }
02704 
02705 /************************************************************************/
02706 
02707 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage or 
02708 ** ssl2_RestartHandshakeAfterServerCert.
02709 */
02710 static SECStatus
02711 ssl2_HandleVerifyMessage(sslSocket *ss)
02712 {
02713     PRUint8 *        data;
02714     SECStatus        rv;
02715 
02716     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02717     ssl_GetRecvBufLock(ss);
02718 
02719     data = ss->gs.buf.buf + ss->gs.recordOffset;
02720     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
02721     if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
02722        (data[0] != SSL_MT_SERVER_VERIFY) ||
02723        PORT_Memcmp(data+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES)) {
02724        /* Bad server */
02725        PORT_SetError(SSL_ERROR_BAD_SERVER);
02726        goto loser;
02727     }
02728     ss->sec.ci.elements |= CIS_HAVE_VERIFY;
02729 
02730     SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
02731               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
02732               ss->sec.ci.elements));
02733 
02734     rv = ssl2_TryToFinish(ss);
02735     if (rv) 
02736        goto loser;
02737 
02738     ss->gs.recordLen = 0;
02739     ssl_ReleaseRecvBufLock(ss);
02740 
02741     if (ss->handshake == 0) {
02742        return SECSuccess;
02743     }
02744     ss->handshake         = ssl_GatherRecord1stHandshake;
02745     ss->nextHandshake     = ssl2_HandleMessage;
02746     return SECSuccess;
02747 
02748 
02749   loser:
02750     ssl_ReleaseRecvBufLock(ss);
02751     return SECFailure;
02752 }
02753 
02754 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
02755  * ICK! 
02756  * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
02757  */
02758 SECStatus
02759 ssl2_HandleServerHelloMessage(sslSocket *ss)
02760 {
02761     sslSessionID *   sid;
02762     PRUint8 *        cert;
02763     PRUint8 *        cs;
02764     PRUint8 *        data;
02765     SECStatus        rv; 
02766     int              needed, sidHit, certLen, csLen, cidLen, certType, err;
02767 
02768     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02769 
02770     if (!ss->opt.enableSSL2) {
02771        PORT_SetError(SSL_ERROR_SSL2_DISABLED);
02772        return SECFailure;
02773     }
02774 
02775     ssl_GetRecvBufLock(ss);
02776 
02777     PORT_Assert(ss->sec.ci.sid != 0);
02778     sid = ss->sec.ci.sid;
02779 
02780     data = ss->gs.buf.buf + ss->gs.recordOffset;
02781     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
02782 
02783     /* Make sure first message has some data and is the server hello message */
02784     if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES)
02785        || (data[0] != SSL_MT_SERVER_HELLO)) {
02786        if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
02787            err = (data[1] << 8) | data[2];
02788            if (err == SSL_PE_NO_CYPHERS) {
02789               PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
02790               goto loser;
02791            }
02792        }
02793        goto bad_server;
02794     }
02795 
02796     sidHit      = data[1];
02797     certType    = data[2];
02798     ss->version = (data[3] << 8) | data[4];
02799     certLen     = (data[5] << 8) | data[6];
02800     csLen       = (data[7] << 8) | data[8];
02801     cidLen      = (data[9] << 8) | data[10];
02802     cert        = data + SSL_HL_SERVER_HELLO_HBYTES;
02803     cs          = cert + certLen;
02804 
02805     SSL_TRC(5,
02806            ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
02807             SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
02808             csLen, cidLen));
02809     if (ss->version != SSL_LIBRARY_VERSION_2) {
02810         if (ss->version < SSL_LIBRARY_VERSION_2) {
02811          SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
02812                     SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
02813                     ss->version));
02814        } else {
02815          SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
02816                   SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
02817          /* server claims to be newer but does not follow protocol */
02818          PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
02819          goto loser;
02820        }
02821     }
02822 
02823     if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen 
02824                                                   > ss->gs.recordLen)
02825        || (csLen % 3) != 0   
02826        /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32  */
02827        ) {
02828        goto bad_server;
02829     }
02830 
02831     /* Save connection-id.
02832     ** This code only saves the first 16 byte of the connectionID.
02833     ** If the connectionID is shorter than 16 bytes, it is zero-padded.
02834     */
02835     if (cidLen < sizeof ss->sec.ci.connectionID)
02836        memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
02837     cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
02838     PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);
02839 
02840     /* See if session-id hit */
02841     needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
02842     if (sidHit) {
02843        if (certLen || csLen) {
02844            /* Uh oh - bogus server */
02845            SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
02846                    SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
02847            goto bad_server;
02848        }
02849 
02850        /* Total winner. */
02851        SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
02852                   "port=0x%04x",
02853                   SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
02854        ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
02855         ss->sec.authAlgorithm = sid->authAlgorithm;
02856        ss->sec.authKeyBits   = sid->authKeyBits;
02857        ss->sec.keaType       = sid->keaType;
02858        ss->sec.keaKeyBits    = sid->keaKeyBits;
02859        rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
02860        if (rv != SECSuccess) {
02861            goto loser;
02862        }
02863     } else {
02864        if (certType != SSL_CT_X509_CERTIFICATE) {
02865            PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
02866            goto loser;
02867        }
02868        if (csLen == 0) {
02869            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
02870            SSL_DBG(("%d: SSL[%d]: no cipher overlap",
02871                    SSL_GETPID(), ss->fd));
02872            goto loser;
02873        }
02874        if (certLen == 0) {
02875            SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
02876                    SSL_GETPID(), ss->fd, certLen, csLen));
02877            goto bad_server;
02878        }
02879 
02880        if (sid->cached != never_cached) {
02881            /* Forget our session-id - server didn't like it */
02882            SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
02883                      SSL_GETPID(), ss->fd));
02884            (*ss->sec.uncache)(sid);
02885            ssl_FreeSID(sid);
02886            ss->sec.ci.sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
02887            if (!sid) {
02888               goto loser;
02889            }
02890            sid->references = 1;
02891            sid->addr = ss->sec.ci.peer;
02892            sid->port = ss->sec.ci.port;
02893        }
02894 
02895        /* decode the server's certificate */
02896        rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
02897        if (rv != SECSuccess) {
02898            if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
02899               (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
02900            }
02901            goto loser;
02902        }
02903 
02904        /* Setup new session cipher */
02905        rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
02906        if (rv != SECSuccess) {
02907            if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
02908               (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
02909            }
02910            goto loser;
02911        }
02912     }
02913 
02914     /* Build up final list of required elements */
02915     ss->sec.ci.elements         = CIS_HAVE_MASTER_KEY;
02916     ss->sec.ci.requiredElements = needed;
02917 
02918   if (!sidHit) {
02919     /* verify the server's certificate. if sidHit, don't check signatures */
02920     rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd, 
02921                              (PRBool)(!sidHit), PR_FALSE);
02922     if (rv) {
02923        if (ss->handleBadCert) {
02924            rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
02925            if ( rv ) {
02926               if ( rv == SECWouldBlock ) {
02927                   /* someone will handle this connection asynchronously*/
02928 
02929                   SSL_DBG(("%d: SSL[%d]: go to async cert handler",
02930                           SSL_GETPID(), ss->fd));
02931                   ssl_ReleaseRecvBufLock(ss);
02932                   ssl_SetAlwaysBlock(ss);
02933                   return SECWouldBlock;
02934               }
02935               /* cert is bad */
02936               SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
02937                       SSL_GETPID(), ss->fd, PORT_GetError()));
02938               goto loser;
02939 
02940            }
02941            /* cert is good */
02942        } else {
02943            SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
02944                    SSL_GETPID(), ss->fd, PORT_GetError()));
02945            goto loser;
02946        }
02947     }
02948   }
02949     /*
02950     ** At this point we have a completed session key and our session
02951     ** cipher is setup and ready to go. Switch to encrypted write routine
02952     ** as all future message data is to be encrypted.
02953     */
02954     ssl2_UseEncryptedSendFunc(ss);
02955 
02956     rv = ssl2_TryToFinish(ss);
02957     if (rv != SECSuccess) 
02958        goto loser;
02959 
02960     ss->gs.recordLen = 0;
02961 
02962     ssl_ReleaseRecvBufLock(ss);
02963 
02964     if (ss->handshake == 0) {
02965        return SECSuccess;
02966     }
02967 
02968     SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
02969               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, 
02970               ss->sec.ci.elements));
02971     ss->handshake     = ssl_GatherRecord1stHandshake;
02972     ss->nextHandshake = ssl2_HandleVerifyMessage;
02973     return SECSuccess;
02974 
02975   bad_server:
02976     PORT_SetError(SSL_ERROR_BAD_SERVER);
02977     /* FALL THROUGH */
02978 
02979   loser:
02980     ssl_ReleaseRecvBufLock(ss);
02981     return SECFailure;
02982 }
02983 
02984 /* Sends out the initial client Hello message on the connection.
02985  * Acquires and releases the socket's xmitBufLock.
02986  */
02987 SECStatus
02988 ssl2_BeginClientHandshake(sslSocket *ss)
02989 {
02990     sslSessionID      *sid;
02991     PRUint8           *msg;
02992     PRUint8           *cp;
02993     PRUint8           *localCipherSpecs = NULL;
02994     unsigned int      localCipherSize;
02995     unsigned int      i;
02996     int               sendLen, sidLen = 0;
02997     SECStatus         rv;
02998 
02999     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
03000 
03001     ss->sec.isServer     = 0;
03002     ss->sec.sendSequence = 0;
03003     ss->sec.rcvSequence  = 0;
03004     ssl_ChooseSessionIDProcs(&ss->sec);
03005 
03006     if (!ss->cipherSpecs) {
03007        rv = ssl2_ConstructCipherSpecs(ss);
03008        if (rv != SECSuccess)
03009            goto loser;
03010     }
03011 
03012     /* count the SSL2 and SSL3 enabled ciphers.
03013      * if either is zero, clear the socket's enable for that protocol.
03014      */
03015     rv = ssl2_CheckConfigSanity(ss);
03016     if (rv != SECSuccess)
03017        goto loser;
03018 
03019     /* Get peer name of server */
03020     rv = ssl_GetPeerInfo(ss);
03021     if (rv < 0) {
03022 #ifdef HPUX11
03023         /*
03024          * On some HP-UX B.11.00 systems, getpeername() occasionally
03025          * fails with ENOTCONN after a successful completion of
03026          * non-blocking connect.  I found that if we do a write()
03027          * and then retry getpeername(), it will work.
03028          */
03029         if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
03030             char dummy;
03031             (void) PR_Write(ss->fd->lower, &dummy, 0);
03032             rv = ssl_GetPeerInfo(ss);
03033             if (rv < 0) {
03034                 goto loser;
03035             }
03036         }
03037 #else
03038        goto loser;
03039 #endif
03040     }
03041 
03042     SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
03043 
03044     /* Try to find server in our session-id cache */
03045     if (ss->opt.noCache) {
03046        sid = NULL;
03047     } else {
03048        sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, 
03049                            ss->url);
03050     }
03051     while (sid) {  /* this isn't really a loop */
03052        /* if we're not doing this SID's protocol any more, drop it. */
03053        if (((sid->version  < SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL2) ||
03054            ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL3) ||
03055            ((sid->version >  SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableTLS)) {
03056            ss->sec.uncache(sid);
03057            ssl_FreeSID(sid);
03058            sid = NULL;
03059            break;
03060        }
03061        if (ss->opt.enableSSL2 && sid->version < SSL_LIBRARY_VERSION_3_0) {
03062            /* If the cipher in this sid is not enabled, drop it. */
03063            for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
03064               if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
03065                   break;
03066            }
03067            if (i >= ss->sizeCipherSpecs) {
03068               ss->sec.uncache(sid);
03069               ssl_FreeSID(sid);
03070               sid = NULL;
03071               break;
03072            }
03073        }
03074        sidLen = sizeof(sid->u.ssl2.sessionID);
03075        PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
03076                     sidLen));
03077        ss->version = sid->version;
03078        PORT_Assert(!ss->sec.localCert);
03079        if (ss->sec.localCert) {
03080            CERT_DestroyCertificate(ss->sec.localCert);
03081        }
03082        ss->sec.localCert     = CERT_DupCertificate(sid->localCert);
03083        break;  /* this isn't really a loop */
03084     } 
03085     if (!sid) {
03086        sidLen = 0;
03087        sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
03088        if (!sid) {
03089            goto loser;
03090        }
03091        sid->references = 1;
03092        sid->cached     = never_cached;
03093        sid->addr       = ss->sec.ci.peer;
03094        sid->port       = ss->sec.ci.port;
03095        if (ss->peerID != NULL) {
03096            sid->peerID = PORT_Strdup(ss->peerID);
03097        }
03098        if (ss->url != NULL) {
03099            sid->urlSvrName = PORT_Strdup(ss->url);
03100        }
03101     }
03102     ss->sec.ci.sid = sid;
03103 
03104     PORT_Assert(sid != NULL);
03105 
03106     if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
03107         (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
03108 
03109        ss->gs.state      = GS_INIT;
03110        ss->handshake     = ssl_GatherRecord1stHandshake;
03111 
03112        /* ssl3_SendClientHello will override this if it succeeds. */
03113        ss->version       = SSL_LIBRARY_VERSION_3_0;
03114 
03115        ssl_GetXmitBufLock(ss);    /***************************************/
03116        ssl_GetSSL3HandshakeLock(ss);
03117        rv =  ssl3_SendClientHello(ss);
03118        ssl_ReleaseSSL3HandshakeLock(ss);
03119        ssl_ReleaseXmitBufLock(ss); /***************************************/
03120 
03121        return rv;
03122     }
03123 #if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B)
03124     /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
03125     ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
03126     if (ss->cipherSpecs != NULL) {
03127        PORT_Free(ss->cipherSpecs);
03128        ss->cipherSpecs     = NULL;
03129        ss->sizeCipherSpecs = 0;
03130     }
03131 #endif
03132 
03133     if (!ss->cipherSpecs) {
03134         rv = ssl2_ConstructCipherSpecs(ss);
03135        if (rv < 0) {
03136            return rv;
03137        }
03138     }
03139     localCipherSpecs = ss->cipherSpecs;
03140     localCipherSize  = ss->sizeCipherSpecs;
03141 
03142     sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + sidLen +
03143        SSL_CHALLENGE_BYTES;
03144 
03145     /* Generate challenge bytes for server */
03146     PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
03147 
03148     ssl_GetXmitBufLock(ss);    /***************************************/
03149 
03150     rv = ssl2_GetSendBuffer(ss, sendLen);
03151     if (rv) 
03152        goto unlock_loser;
03153 
03154     /* Construct client-hello message */
03155     cp = msg = ss->sec.ci.sendBuf.buf;
03156     msg[0] = SSL_MT_CLIENT_HELLO;
03157     if ( ss->opt.enableTLS ) {
03158        ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS;
03159     } else if ( ss->opt.enableSSL3 ) {
03160        ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_0;
03161     } else {
03162        ss->clientHelloVersion = SSL_LIBRARY_VERSION_2;
03163     }
03164     
03165     msg[1] = MSB(ss->clientHelloVersion);
03166     msg[2] = LSB(ss->clientHelloVersion);
03167     msg[3] = MSB(localCipherSize);
03168     msg[4] = LSB(localCipherSize);
03169     msg[5] = MSB(sidLen);
03170     msg[6] = LSB(sidLen);
03171     msg[7] = MSB(SSL_CHALLENGE_BYTES);
03172     msg[8] = LSB(SSL_CHALLENGE_BYTES);
03173     cp += SSL_HL_CLIENT_HELLO_HBYTES;
03174     PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
03175     cp += localCipherSize;
03176     if (sidLen) {
03177        PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
03178        cp += sidLen;
03179     }
03180     PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
03181 
03182     /* Send it to the server */
03183     DUMP_MSG(29, (ss, msg, sendLen));
03184     ss->handshakeBegun = 1;
03185     rv = (*ss->sec.send)(ss, msg, sendLen, 0);
03186 
03187     ssl_ReleaseXmitBufLock(ss);    /***************************************/
03188 
03189     if (rv < 0) {
03190        goto loser;
03191     }
03192 
03193     rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
03194     if (rv < 0) {
03195        goto loser;
03196     }
03197 
03198     /* Setup to receive servers hello message */
03199     ssl_GetRecvBufLock(ss);
03200     ss->gs.recordLen = 0;
03201     ssl_ReleaseRecvBufLock(ss);
03202 
03203     ss->handshake     = ssl_GatherRecord1stHandshake;
03204     ss->nextHandshake = ssl2_HandleServerHelloMessage;
03205     return SECSuccess;
03206 
03207 unlock_loser:
03208     ssl_ReleaseXmitBufLock(ss);
03209 loser:
03210     return SECFailure;
03211 }
03212 
03213 /************************************************************************/
03214 
03215 /* Handle the CLIENT-MASTER-KEY message. 
03216 ** Acquires and releases RecvBufLock.
03217 ** Called from ssl2_HandleClientHelloMessage(). 
03218 */
03219 static SECStatus
03220 ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
03221 {
03222     PRUint8 *        data;
03223     unsigned int     caLen;
03224     unsigned int     ckLen;
03225     unsigned int     ekLen;
03226     unsigned int     keySize;
03227     int              cipher;
03228     SECStatus        rv;
03229 
03230 
03231     ssl_GetRecvBufLock(ss);
03232 
03233     data = ss->gs.buf.buf + ss->gs.recordOffset;
03234     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
03235 
03236     if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
03237        || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
03238        goto bad_client;
03239     }
03240     cipher  = data[1];
03241     keySize = (data[2] << 8) | data[3];
03242     ckLen   = (data[4] << 8) | data[5];
03243     ekLen   = (data[6] << 8) | data[7];
03244     caLen   = (data[8] << 8) | data[9];
03245 
03246     SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keySize=%d ckLen=%d ekLen=%d caLen=%d",
03247               SSL_GETPID(), ss->fd, cipher, keySize, ckLen, ekLen, caLen));
03248 
03249     if (ss->gs.recordLen < 
03250            SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
03251        SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
03252                SSL_GETPID(), ss->fd, ss->gs.recordLen));
03253        goto bad_client;
03254     }
03255 
03256     /* Use info from client to setup session key */
03257     /* XXX should validate cipher&keySize are in our array */
03258     rv = ssl2_ServerSetupSessionCypher(ss, cipher, keySize,
03259               data + SSL_HL_CLIENT_MASTER_KEY_HBYTES,                 ckLen,
03260               data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen,         ekLen,
03261               data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
03262     ss->gs.recordLen = 0;   /* we're done with this record. */
03263 
03264     ssl_ReleaseRecvBufLock(ss);
03265 
03266     if (rv != SECSuccess) {
03267        goto loser;
03268     }
03269     ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
03270     ssl2_UseEncryptedSendFunc(ss);
03271 
03272     /* Send server verify message now that keys are established */
03273     rv = ssl2_SendServerVerifyMessage(ss);
03274     if (rv != SECSuccess) 
03275        goto loser;
03276 
03277     rv = ssl2_TryToFinish(ss);
03278     if (rv != SECSuccess) 
03279        goto loser;
03280     if (ss->handshake == 0) {
03281        return SECSuccess;
03282     }
03283 
03284     SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
03285               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
03286     ss->handshake         = ssl_GatherRecord1stHandshake;
03287     ss->nextHandshake     = ssl2_HandleMessage;
03288 
03289     return ssl2_TriggerNextMessage(ss);
03290 
03291 bad_client:
03292     ssl_ReleaseRecvBufLock(ss);
03293     PORT_SetError(SSL_ERROR_BAD_CLIENT);
03294     /* FALLTHROUGH */
03295 
03296 loser:
03297     return SECFailure;
03298 }
03299 
03300 /*
03301  * attempt to restart the handshake after asynchronously handling
03302  * a request for the client's certificate.
03303  *
03304  * inputs:  
03305  *     cert   Client cert chosen by application.
03306  *     key    Private key associated with cert.  
03307  *
03308  * XXX: need to make ssl2 and ssl3 versions of this function agree on whether
03309  *     they take the reference, or bump the ref count!
03310  *
03311  * Return value: XXX
03312  *
03313  * Caller holds 1stHandshakeLock.
03314  */
03315 int
03316 ssl2_RestartHandshakeAfterCertReq(sslSocket *          ss,
03317                               CERTCertificate *    cert, 
03318                               SECKEYPrivateKey *   key)
03319 {
03320     int              ret;
03321     SECStatus        rv          = SECSuccess;
03322     SECItem          response;
03323 
03324     if (ss->version >= SSL_LIBRARY_VERSION_3_0) 
03325        return SECFailure;
03326 
03327     response.data = NULL;
03328 
03329     /* generate error if no cert or key */
03330     if ( ( cert == NULL ) || ( key == NULL ) ) {
03331        goto no_cert;
03332     }
03333     
03334     /* generate signed response to the challenge */
03335     rv = ssl2_SignResponse(ss, key, &response);
03336     if ( rv != SECSuccess ) {
03337        goto no_cert;
03338     }
03339     
03340     /* Send response message */
03341     ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
03342     if (ret) {
03343        goto no_cert;
03344     }
03345 
03346     /* try to finish the handshake */
03347     ret = ssl2_TryToFinish(ss);
03348     if (ret) {
03349        goto loser;
03350     }
03351     
03352     /* done with handshake */
03353     if (ss->handshake == 0) {
03354        ret = SECSuccess;
03355        goto done;
03356     }
03357 
03358     /* continue handshake */
03359     ssl_GetRecvBufLock(ss);
03360     ss->gs.recordLen = 0;
03361     ssl_ReleaseRecvBufLock(ss);
03362 
03363     ss->handshake     = ssl_GatherRecord1stHandshake;
03364     ss->nextHandshake = ssl2_HandleMessage;
03365     ret = ssl2_TriggerNextMessage(ss);
03366     goto done;
03367     
03368 no_cert:
03369     /* no cert - send error */
03370     ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
03371     goto done;
03372     
03373 loser:
03374     ret = SECFailure;
03375 done:
03376     /* free allocated data */
03377     if ( response.data ) {
03378        PORT_Free(response.data);
03379     }
03380     
03381     return ret;
03382 }
03383 
03384 
03385 /* restart an SSL connection that we stopped to run certificate dialogs 
03386 ** XXX Need to document here how an application marks a cert to show that
03387 **     the application has accepted it (overridden CERT_VerifyCert).
03388  *
03389  * Return value: XXX
03390  *
03391  * Caller holds 1stHandshakeLock.
03392 */
03393 int
03394 ssl2_RestartHandshakeAfterServerCert(sslSocket *ss)
03395 {
03396     int rv    = SECSuccess;
03397 
03398     if (ss->version >= SSL_LIBRARY_VERSION_3_0) 
03399        return SECFailure;
03400 
03401     /* SSL 2
03402     ** At this point we have a completed session key and our session
03403     ** cipher is setup and ready to go. Switch to encrypted write routine
03404     ** as all future message data is to be encrypted.
03405     */
03406     ssl2_UseEncryptedSendFunc(ss);
03407 
03408     rv = ssl2_TryToFinish(ss);
03409     if (rv == SECSuccess && ss->handshake != NULL) {    
03410        /* handshake is not yet finished. */
03411 
03412        SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
03413               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
03414               ss->sec.ci.elements));
03415 
03416        ssl_GetRecvBufLock(ss);
03417        ss->gs.recordLen = 0;       /* mark it all used up. */
03418        ssl_ReleaseRecvBufLock(ss);
03419 
03420        ss->handshake     = ssl_GatherRecord1stHandshake;
03421        ss->nextHandshake = ssl2_HandleVerifyMessage;
03422     }
03423 
03424     return rv;
03425 }
03426 
03427 /*
03428 ** Handle the initial hello message from the client
03429 **
03430 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
03431 */
03432 SECStatus
03433 ssl2_HandleClientHelloMessage(sslSocket *ss)
03434 {
03435     sslSessionID    *sid;
03436     sslServerCerts * sc;
03437     CERTCertificate *serverCert;
03438     PRUint8         *msg;
03439     PRUint8         *data;
03440     PRUint8         *cs;
03441     PRUint8         *sd;
03442     PRUint8         *cert = NULL;
03443     PRUint8         *challenge;
03444     unsigned int    challengeLen;
03445     SECStatus       rv; 
03446     int             csLen;
03447     int             sendLen;
03448     int             sdLen;
03449     int             certLen;
03450     int             pid;
03451     int             sent;
03452     int             gotXmitBufLock = 0;
03453 #if defined(SOLARIS) && defined(i386)
03454     volatile PRUint8 hit;
03455 #else
03456     int             hit;
03457 #endif
03458     PRUint8         csImpl[sizeof implementedCipherSuites];
03459 
03460     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
03461 
03462     sc = ss->serverCerts + kt_rsa;
03463     serverCert = sc->serverCert;
03464 
03465     ssl_GetRecvBufLock(ss);
03466 
03467 
03468     data = ss->gs.buf.buf + ss->gs.recordOffset;
03469     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
03470 
03471     /* Make sure first message has some data and is the client hello message */
03472     if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
03473        || (data[0] != SSL_MT_CLIENT_HELLO)) {
03474        goto bad_client;
03475     }
03476 
03477     /* Get peer name of client */
03478     rv = ssl_GetPeerInfo(ss);
03479     if (rv != SECSuccess) {
03480        goto loser;
03481     }
03482 
03483     /* Examine version information */
03484     /*
03485      * See if this might be a V2 client hello asking to use the V3 protocol
03486      */
03487     if ((data[0] == SSL_MT_CLIENT_HELLO) && 
03488         (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && 
03489        (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
03490        rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
03491        if (rv != SECFailure) { /* Success */
03492            ss->handshake             = NULL;
03493            ss->nextHandshake         = ssl_GatherRecord1stHandshake;
03494            ss->securityHandshake     = NULL;
03495            ss->gs.state              = GS_INIT;
03496 
03497            /* ssl3_HandleV3ClientHello has set ss->version,
03498            ** and has gotten us a brand new sid.  
03499            */
03500            ss->sec.ci.sid->version  = ss->version;
03501        }
03502        ssl_ReleaseRecvBufLock(ss);
03503        return rv;
03504     }
03505     /* Previously, there was a test here to see if SSL2 was enabled.
03506     ** If not, an error code was set, and SECFailure was returned,
03507     ** without sending any error code to the other end of the connection.
03508     ** That test has been removed.  If SSL2 has been disabled, there
03509     ** should be no SSL2 ciphers enabled, and consequently, the code
03510     ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
03511     ** We now believe this is the correct thing to do, even when SSL2
03512     ** has been explicitly disabled by the application.
03513     */
03514 
03515     /* Extract info from message */
03516     ss->version = (data[1] << 8) | data[2];
03517 
03518     /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it.  */
03519     if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
03520        ss->version = SSL_LIBRARY_VERSION_2;
03521     }
03522     
03523     csLen        = (data[3] << 8) | data[4];
03524     sdLen        = (data[5] << 8) | data[6];
03525     challengeLen = (data[7] << 8) | data[8];
03526     cs           = data + SSL_HL_CLIENT_HELLO_HBYTES;
03527     sd           = cs + csLen;
03528     challenge    = sd + sdLen;
03529     PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
03530 
03531     if (!csLen || (csLen % 3) != 0 || 
03532         (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
03533        challengeLen < SSL_MIN_CHALLENGE_BYTES || 
03534        challengeLen > SSL_MAX_CHALLENGE_BYTES ||
03535         (unsigned)ss->gs.recordLen != 
03536             SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
03537        SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
03538                SSL_GETPID(), ss->fd, ss->gs.recordLen,
03539                SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
03540        goto bad_client;
03541     }
03542 
03543     SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
03544               SSL_GETPID(), ss->fd, ss->version));
03545     if (ss->version != SSL_LIBRARY_VERSION_2) {
03546        if (ss->version > SSL_LIBRARY_VERSION_2) {
03547            /*
03548            ** Newer client than us. Things are ok because new clients
03549            ** are required to be backwards compatible with old servers.
03550            ** Change version number to our version number so that client
03551            ** knows whats up.
03552            */
03553            ss->version = SSL_LIBRARY_VERSION_2;
03554        } else {
03555            SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
03556               SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
03557            PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
03558            goto loser;
03559        }
03560     }
03561 
03562     /* Qualify cipher specs before returning them to client */
03563     csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
03564     if (csLen == 0) {
03565        /* no overlap, send client our list of supported SSL v2 ciphers. */
03566         cs    = csImpl;
03567        csLen = sizeof implementedCipherSuites;
03568        PORT_Memcpy(cs, implementedCipherSuites, csLen);
03569        csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
03570        if (csLen == 0) {
03571          /* We don't support any SSL v2 ciphers! */
03572          ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
03573          PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
03574          goto loser;
03575        }
03576        /* Since this handhsake is going to fail, don't cache it. */
03577        ss->opt.noCache = 1; 
03578     }
03579 
03580     /* Squirrel away the challenge for later */
03581     PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);
03582 
03583     /* Examine message and see if session-id is good */
03584     ss->sec.ci.elements = 0;
03585     if (sdLen > 0 && !ss->opt.noCache) {
03586        SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
03587                   SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
03588                   ss->sec.ci.peer.pr_s6_addr32[1], 
03589                   ss->sec.ci.peer.pr_s6_addr32[2],
03590                   ss->sec.ci.peer.pr_s6_addr32[3]));
03591        sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
03592     } else {
03593        sid = NULL;
03594     }
03595     if (sid) {
03596        /* Got a good session-id. Short cut! */
03597        SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
03598                   SSL_GETPID(), ss->fd, ss->sec.ci.peer, 
03599                   ssl_Time() - sid->creationTime));
03600        PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
03601        ss->sec.ci.sid = sid;
03602        ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
03603        hit = 1;
03604        certLen = 0;
03605        csLen = 0;
03606 
03607         ss->sec.authAlgorithm = sid->authAlgorithm;
03608        ss->sec.authKeyBits   = sid->authKeyBits;
03609        ss->sec.keaType       = sid->keaType;
03610        ss->sec.keaKeyBits    = sid->keaKeyBits;
03611 
03612        rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
03613        if (rv != SECSuccess) {
03614            goto loser;
03615        }
03616     } else {
03617        SECItem * derCert   = &serverCert->derCert;
03618 
03619        SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
03620                   SSL_GETPID(), ss->fd));
03621        if (!serverCert) {
03622            SET_ERROR_CODE
03623            goto loser;
03624        }
03625        hit = 0;
03626        sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
03627        if (!sid) {
03628            goto loser;
03629        }
03630        sid->references = 1;
03631        sid->addr = ss->sec.ci.peer;
03632        sid->port = ss->sec.ci.port;
03633 
03634        /* Invent a session-id */
03635        ss->sec.ci.sid = sid;
03636        PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2);
03637 
03638        pid = SSL_GETPID();
03639        sid->u.ssl2.sessionID[0] = MSB(pid);
03640        sid->u.ssl2.sessionID[1] = LSB(pid);
03641        cert    = derCert->data;
03642        certLen = derCert->len;
03643 
03644        /* pretend that server sids remember the local cert. */
03645        PORT_Assert(!sid->localCert);
03646        if (sid->localCert) {
03647            CERT_DestroyCertificate(sid->localCert);
03648        }
03649        sid->localCert     = CERT_DupCertificate(serverCert);
03650 
03651        ss->sec.authAlgorithm = ssl_sign_rsa;
03652        ss->sec.keaType       = ssl_kea_rsa;
03653        ss->sec.keaKeyBits    = \
03654        ss->sec.authKeyBits   = ss->serverCerts[kt_rsa].serverKeyBits;
03655     }
03656 
03657     /* server sids don't remember the local cert, so whether we found
03658     ** a sid or not, just "remember" we used the rsa server cert.
03659     */
03660     if (ss->sec.localCert) {
03661        CERT_DestroyCertificate(ss->sec.localCert);
03662     }
03663     ss->sec.localCert     = CERT_DupCertificate(serverCert);
03664 
03665     /* Build up final list of required elements */
03666     ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
03667     if (ss->opt.requestCertificate) {
03668        ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
03669     }
03670     ss->sec.ci.sentElements = 0;
03671 
03672     /* Send hello message back to client */
03673     sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
03674            + SSL_CONNECTIONID_BYTES;
03675 
03676     ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
03677     rv = ssl2_GetSendBuffer(ss, sendLen);
03678     if (rv != SECSuccess) {
03679        goto loser;
03680     }
03681 
03682     SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
03683               SSL_GETPID(), ss->fd, sendLen));
03684 
03685     msg = ss->sec.ci.sendBuf.buf;
03686     msg[0] = SSL_MT_SERVER_HELLO;
03687     msg[1] = hit;
03688     msg[2] = SSL_CT_X509_CERTIFICATE;
03689     msg[3] = MSB(ss->version);
03690     msg[4] = LSB(ss->version);
03691     msg[5] = MSB(certLen);
03692     msg[6] = LSB(certLen);
03693     msg[7] = MSB(csLen);
03694     msg[8] = LSB(csLen);
03695     msg[9] = MSB(SSL_CONNECTIONID_BYTES);
03696     msg[10] = LSB(SSL_CONNECTIONID_BYTES);
03697     if (certLen) {
03698        PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
03699     }
03700     if (csLen) {
03701        PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
03702     }
03703     PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, 
03704                 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);
03705 
03706     DUMP_MSG(29, (ss, msg, sendLen));
03707 
03708     ss->handshakeBegun = 1;
03709     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
03710     if (sent < 0) {
03711        goto loser;
03712     }
03713     ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
03714 
03715     ss->gs.recordLen = 0;
03716     ss->handshake = ssl_GatherRecord1stHandshake;
03717     if (hit) {
03718        /* Old SID Session key is good. Go encrypted */
03719        ssl2_UseEncryptedSendFunc(ss);
03720 
03721        /* Send server verify message now that keys are established */
03722        rv = ssl2_SendServerVerifyMessage(ss);
03723        if (rv != SECSuccess) 
03724            goto loser;
03725 
03726        ss->nextHandshake = ssl2_HandleMessage;
03727        ssl_ReleaseRecvBufLock(ss);
03728        rv = ssl2_TriggerNextMessage(ss);
03729        return rv;
03730     }
03731     ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
03732     ssl_ReleaseRecvBufLock(ss);
03733     return SECSuccess;
03734 
03735   bad_client:
03736     PORT_SetError(SSL_ERROR_BAD_CLIENT);
03737     /* FALLTHROUGH */
03738 
03739   loser:
03740     if (gotXmitBufLock) {
03741        ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
03742     }
03743     SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
03744                SSL_GETPID(), ss->fd));
03745     ssl_ReleaseRecvBufLock(ss);
03746     return SECFailure;
03747 }
03748 
03749 SECStatus
03750 ssl2_BeginServerHandshake(sslSocket *ss)
03751 {
03752     SECStatus        rv;
03753     sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;
03754 
03755     ss->sec.isServer = 1;
03756     ssl_ChooseSessionIDProcs(&ss->sec);
03757     ss->sec.sendSequence = 0;
03758     ss->sec.rcvSequence = 0;
03759 
03760     /* don't turn on SSL2 if we don't have an RSA key and cert */
03761     if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || 
03762         !rsaAuth->serverCert) {
03763        ss->opt.enableSSL2 = PR_FALSE;
03764     }
03765 
03766     if (!ss->cipherSpecs) {
03767        rv = ssl2_ConstructCipherSpecs(ss);
03768        if (rv != SECSuccess)
03769            goto loser;
03770     }
03771 
03772     /* count the SSL2 and SSL3 enabled ciphers.
03773      * if either is zero, clear the socket's enable for that protocol.
03774      */
03775     rv = ssl2_CheckConfigSanity(ss);
03776     if (rv != SECSuccess)
03777        goto loser;
03778 
03779     /*
03780     ** Generate connection-id. Always do this, even if things fail
03781     ** immediately. This way the random number generator is always
03782     ** rolling around, every time we get a connection.
03783     */
03784     PK11_GenerateRandom(ss->sec.ci.connectionID, 
03785                         sizeof(ss->sec.ci.connectionID));
03786 
03787     ss->gs.recordLen = 0;
03788     ss->handshake     = ssl_GatherRecord1stHandshake;
03789     ss->nextHandshake = ssl2_HandleClientHelloMessage;
03790     return SECSuccess;
03791 
03792 loser:
03793     return SECFailure;
03794 }
03795 
03796 /* This function doesn't really belong in this file.
03797 ** It's here to keep AIX compilers from optimizing it away, 
03798 ** and not including it in the DSO.
03799 */
03800 
03801 #include "nss.h"
03802 extern const char __nss_ssl_rcsid[];
03803 extern const char __nss_ssl_sccsid[];
03804 
03805 PRBool
03806 NSSSSL_VersionCheck(const char *importedVersion)
03807 {
03808     /*
03809      * This is the secret handshake algorithm.
03810      *
03811      * This release has a simple version compatibility
03812      * check algorithm.  This release is not backward
03813      * compatible with previous major releases.  It is
03814      * not compatible with future major, minor, or
03815      * patch releases.
03816      */
03817     volatile char c; /* force a reference that won't get optimized away */
03818 
03819     c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; 
03820     return NSS_VersionCheck(importedVersion);
03821 }