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.7 2007/01/03 05:32:33 nelson%bolyard.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        unsigned 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 keyBits,
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(keyBits);
00708     msg[3] = LSB(keyBits);
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      *    dk   = NULL; /* decrypted master key */
01583     sslSessionID *    sid;
01584     sslServerCerts *  sc   = ss->serverCerts + kt_rsa;
01585     PRUint8       *   kbuf = 0;    /* buffer for RSA decrypted data. */
01586     unsigned int      ddLen;       /* length of RSA decrypted data in kbuf */
01587     unsigned int      keySize;
01588     unsigned int      dkLen;    /* decrypted key length in bytes */
01589     int               modulusLen;
01590     SECStatus         rv;
01591     PRUint16          allowed;  /* cipher kinds enabled and allowed by policy */
01592     PRUint8           mkbuf[SSL_MAX_MASTER_KEY_BYTES];
01593 
01594     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01595     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
01596     PORT_Assert((sc->SERVERKEY != 0));
01597     PORT_Assert((ss->sec.ci.sid != 0));
01598     sid = ss->sec.ci.sid;
01599 
01600     /* Trying to cut down on all these switch statements that should be tables.
01601      * So, test cipherType once, here, and then use tables below. 
01602      */
01603     switch (cipher) {
01604     case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
01605     case SSL_CK_RC4_128_WITH_MD5:
01606     case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
01607     case SSL_CK_RC2_128_CBC_WITH_MD5:
01608     case SSL_CK_DES_64_CBC_WITH_MD5:
01609     case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
01610        break;
01611 
01612     default:
01613        SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
01614                SSL_GETPID(), ss->fd, cipher));
01615        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01616        goto loser;
01617     }
01618 
01619     allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED;
01620     if (!(allowed & (1U << cipher))) {
01621        /* client chose a kind we don't allow! */
01622        SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d",
01623                SSL_GETPID(), ss->fd, cipher));
01624        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01625        goto loser;
01626     }
01627 
01628     keySize = ssl_Specs[cipher].keyLen;
01629     if (keyBits != keySize * BPB) {
01630        SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!",
01631                SSL_GETPID(), ss->fd, keyBits));
01632        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01633        goto loser;
01634     }
01635 
01636     if (ckLen != ssl_Specs[cipher].pubLen) {
01637        SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!",
01638                SSL_GETPID(), ss->fd, ckLen));
01639        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01640        goto loser;
01641     }
01642 
01643     if (caLen != ssl_Specs[cipher].ivLen) {
01644        SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!",
01645                SSL_GETPID(), ss->fd, caLen));
01646        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01647        goto loser;
01648     }
01649 
01650     modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
01651     if (modulusLen == -1) {
01652        /* If the key is bad, then PK11_PubDecryptRaw will fail below. */
01653        modulusLen = ekLen;
01654     }
01655     /* RSA modulus size presently limited to 8k bits maximum */
01656     if (ekLen > modulusLen || ekLen > 1024 || ekLen + ckLen < keySize) {
01657        SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
01658                SSL_GETPID(), ss->fd, ekLen));
01659        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01660        goto loser;
01661     }
01662 
01663     /* allocate the buffer to hold the decrypted portion of the key. */
01664     kbuf = (PRUint8*)PORT_Alloc(modulusLen);
01665     if (!kbuf) {
01666        goto loser;
01667     }
01668     dkLen = keySize - ckLen;
01669     dk    = kbuf + modulusLen - dkLen;
01670 
01671     /* Decrypt encrypted half of the key. 
01672     ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
01673     ** desired behavior here.
01674     */
01675     rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen);
01676     if (rv != SECSuccess) 
01677        goto hide_loser;
01678 
01679     /* Is the length of the decrypted data (ddLen) the expected value? */
01680     if (modulusLen != ddLen) 
01681        goto hide_loser;
01682 
01683     /* Cheaply verify that PKCS#1 was used to format the encryption block */
01684     if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) {
01685        SSL_DBG(("%d: SSL[%d]: strange encryption block",
01686                SSL_GETPID(), ss->fd));
01687        PORT_SetError(SSL_ERROR_BAD_CLIENT);
01688        goto hide_loser;
01689     }
01690 
01691     /* Make sure we're not subject to a version rollback attack. */
01692     if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
01693        static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
01694                                         0x03, 0x03, 0x03, 0x03 };
01695        
01696        if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) {
01697            PORT_SetError(SSL_ERROR_BAD_CLIENT);
01698            goto hide_loser;
01699        }
01700     }
01701     if (0) {
01702 hide_loser:
01703        /* Defense against the Bleichenbacher attack.
01704         * Provide the client with NO CLUES that the decrypted master key
01705         * was erroneous.  Don't send any error messages.
01706         * Instead, Generate a completely bogus master key .
01707         */
01708        PK11_GenerateRandom(dk, dkLen);
01709     }
01710 
01711     /*
01712     ** Construct master key out of the pieces.
01713     */
01714     if (ckLen) {
01715        PORT_Memcpy(mkbuf, ck, ckLen);
01716     }
01717     PORT_Memcpy(mkbuf + ckLen, dk, dkLen);
01718 
01719     /* Fill in session-id */
01720     rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
01721                  keyBits, keyBits - (ckLen<<3),
01722                  ss->sec.authAlgorithm, ss->sec.authKeyBits,
01723                  ss->sec.keaType,       ss->sec.keaKeyBits);
01724     if (rv != SECSuccess) {
01725        goto loser;
01726     }
01727 
01728     /* Create session ciphers */
01729     rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
01730     if (rv != SECSuccess) {
01731        goto loser;
01732     }
01733 
01734     SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
01735               SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
01736               ckLen<<3, keySize<<3));
01737     rv = SECSuccess;
01738     goto done;
01739 
01740   loser:
01741     rv = SECFailure;
01742 
01743   done:
01744     PORT_Free(kbuf);
01745     return rv;
01746 }
01747 
01748 /************************************************************************/
01749 
01750 /*
01751 ** Rewrite the incoming cipher specs, comparing to list of specs we support,
01752 ** (ss->cipherSpecs) and eliminating anything we don't support
01753 **
01754 *  Note: Our list may contain SSL v3 ciphers.  
01755 *  We MUST NOT match on any of those.  
01756 *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
01757 *  in the first byte, and none of the SSLv2 ciphers do.
01758 *
01759 *  Called from ssl2_HandleClientHelloMessage().
01760 *  Returns the number of bytes of "qualified cipher specs", 
01761 *  which is typically a multiple of 3, but will be zero if there are none.
01762 */
01763 static int
01764 ssl2_QualifyCypherSpecs(sslSocket *ss, 
01765                         PRUint8 *  cs, /* cipher specs in client hello msg. */
01766                       int        csLen)
01767 {
01768     PRUint8 *    ms;
01769     PRUint8 *    hs;
01770     PRUint8 *    qs;
01771     int          mc;
01772     int          hc;
01773     PRUint8      qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
01774 
01775     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01776     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
01777 
01778     if (!ss->cipherSpecs) {
01779        SECStatus rv = ssl2_ConstructCipherSpecs(ss);
01780        if (rv != SECSuccess || !ss->cipherSpecs) 
01781            return 0;
01782     }
01783 
01784     PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
01785     qs = qualifiedSpecs;
01786     ms = ss->cipherSpecs;
01787     for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
01788        if (ms[0] == 0)
01789            continue;
01790        for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
01791            if ((hs[0] == ms[0]) &&
01792               (hs[1] == ms[1]) &&
01793               (hs[2] == ms[2])) {
01794               /* Copy this cipher spec into the "keep" section */
01795               qs[0] = hs[0];
01796               qs[1] = hs[1];
01797               qs[2] = hs[2];
01798               qs   += 3;
01799               break;
01800            }
01801        }
01802     }
01803     hc = qs - qualifiedSpecs;
01804     PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
01805     PORT_Memcpy(cs, qualifiedSpecs, hc);
01806     return hc;
01807 }
01808 
01809 /*
01810 ** Pick the best cipher we can find, given the array of server cipher
01811 ** specs.  Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
01812 ** If succesful, stores the master key size (bytes) in *pKeyLen.
01813 **
01814 ** This is correct only for the client side, but presently
01815 ** this function is only called from 
01816 **     ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
01817 **
01818 ** Note that most servers only return a single cipher suite in their 
01819 ** ServerHello messages.  So, the code below for finding the "best" cipher
01820 ** suite usually has only one choice.  The client and server should send 
01821 ** their cipher suite lists sorted in descending order by preference.
01822 */
01823 static int
01824 ssl2_ChooseSessionCypher(sslSocket *ss, 
01825                          int        hc,    /* number of cs's in hs. */
01826                        PRUint8 *  hs,    /* server hello's cipher suites. */
01827                        int *      pKeyLen) /* out: sym key size in bytes. */
01828 {
01829     PRUint8 *       ms;
01830     unsigned int    i;
01831     int             bestKeySize;
01832     int             bestRealKeySize;
01833     int             bestCypher;
01834     int             keySize;
01835     int             realKeySize;
01836     PRUint8 *       ohs               = hs;
01837     const PRUint8 * preferred;
01838     static const PRUint8 noneSuch[3] = { 0, 0, 0 };
01839 
01840     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
01841     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
01842 
01843     if (!ss->cipherSpecs) {
01844        SECStatus rv = ssl2_ConstructCipherSpecs(ss);
01845        if (rv != SECSuccess || !ss->cipherSpecs) 
01846            goto loser;
01847     }
01848 
01849     if (!ss->preferredCipher) {
01850        unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
01851                               SSL_CB_IMPLEMENTED;
01852        if (allowed) {
01853            preferred = implementedCipherSuites;
01854            for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
01855               if (0 != (allowed & (1U << preferred[0]))) {
01856                   ss->preferredCipher = preferred;
01857                   break;
01858               }
01859               preferred += 3;
01860            }
01861        }
01862     }
01863     preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
01864     /*
01865     ** Scan list of ciphers recieved from peer and look for a match in
01866     ** our list.  
01867     *  Note: Our list may contain SSL v3 ciphers.  
01868     *  We MUST NOT match on any of those.  
01869     *  Fortunately, this is easy to detect because SSLv3 ciphers have zero
01870     *  in the first byte, and none of the SSLv2 ciphers do.
01871     */
01872     bestKeySize = bestRealKeySize = 0;
01873     bestCypher = -1;
01874     while (--hc >= 0) {
01875        for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
01876            if ((hs[0] == preferred[0]) &&
01877               (hs[1] == preferred[1]) &&
01878               (hs[2] == preferred[2]) &&
01879                hs[0] != 0) {
01880               /* Pick this cipher immediately! */
01881               *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
01882               return hs[0];
01883            }
01884            if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
01885                 hs[0] != 0) {
01886               /* Found a match */
01887 
01888               /* Use secret keySize to determine which cipher is best */
01889               realKeySize = (hs[1] << 8) | hs[2];
01890               switch (hs[0]) {
01891                 case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
01892                 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
01893                   keySize = 40;
01894                   break;
01895                 default:
01896                   keySize = realKeySize;
01897                   break;
01898               }
01899               if (keySize > bestKeySize) {
01900                   bestCypher = hs[0];
01901                   bestKeySize = keySize;
01902                   bestRealKeySize = realKeySize;
01903               }
01904            }
01905        }
01906        hs += 3;
01907     }
01908     if (bestCypher < 0) {
01909        /*
01910        ** No overlap between server and client. Re-examine server list
01911        ** to see what kind of ciphers it does support so that we can set
01912        ** the error code appropriately.
01913        */
01914        if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
01915            (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
01916            PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
01917        } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
01918                  (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
01919            PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
01920        } else {
01921            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
01922        }
01923        SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
01924        goto loser;
01925     }
01926     *pKeyLen = (bestRealKeySize + 7) >> 3;
01927     return bestCypher;
01928 
01929   loser:
01930     return -1;
01931 }
01932 
01933 static SECStatus
01934 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
01935 {
01936     CERTCertificate *cert      = NULL;
01937     SECItem          certItem;
01938 
01939     certItem.data = certData;
01940     certItem.len  = certLen;
01941 
01942     /* decode the certificate */
01943     cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
01944                                PR_FALSE, PR_TRUE);
01945     
01946     if (cert == NULL) {
01947        SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
01948                SSL_GETPID(), ss->fd));
01949        PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
01950        return SECFailure;
01951     }
01952 
01953 #ifdef TRACE
01954     {
01955        if (ssl_trace >= 1) {
01956            char *issuer;
01957            char *subject;
01958            issuer = CERT_NameToAscii(&cert->issuer);
01959            subject = CERT_NameToAscii(&cert->subject);
01960            SSL_TRC(1,("%d: server certificate issuer: '%s'",
01961                      SSL_GETPID(), issuer ? issuer : "OOPS"));
01962            SSL_TRC(1,("%d: server name: '%s'",
01963                      SSL_GETPID(), subject ? subject : "OOPS"));
01964            PORT_Free(issuer);
01965            PORT_Free(subject);
01966        }
01967     }
01968 #endif
01969 
01970     ss->sec.peerCert = cert;
01971     return SECSuccess;
01972 }
01973 
01974 
01975 /*
01976  * Format one block of data for public/private key encryption using
01977  * the rules defined in PKCS #1. SSL2 does this itself to handle the
01978  * rollback detection.
01979  */
01980 #define RSA_BLOCK_MIN_PAD_LEN           8
01981 #define RSA_BLOCK_FIRST_OCTET           0x00
01982 #define RSA_BLOCK_AFTER_PAD_OCTET       0x00
01983 #define RSA_BLOCK_PUBLIC_OCTET            0x02
01984 unsigned char *
01985 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
01986 {
01987     unsigned char *block;
01988     unsigned char *bp;
01989     int padLen;
01990     SECStatus rv;
01991     int i;
01992 
01993     if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) {
01994        PORT_SetError(SEC_ERROR_BAD_KEY);
01995        return NULL;
01996     }
01997     block = (unsigned char *) PORT_Alloc(modulusLen);
01998     if (block == NULL)
01999        return NULL;
02000 
02001     bp = block;
02002 
02003     /*
02004      * All RSA blocks start with two octets:
02005      * 0x00 || BlockType
02006      */
02007     *bp++ = RSA_BLOCK_FIRST_OCTET;
02008     *bp++ = RSA_BLOCK_PUBLIC_OCTET;
02009 
02010     /*
02011      * 0x00 || BT || Pad || 0x00 || ActualData
02012      *   1      1   padLen    1      data->len
02013      * Pad is all non-zero random bytes.
02014      */
02015     padLen = modulusLen - data->len - 3;
02016     PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
02017     rv = PK11_GenerateRandom(bp, padLen);
02018     if (rv == SECFailure) goto loser;
02019     /* replace all the 'zero' bytes */
02020     for (i = 0; i < padLen; i++) {
02021        while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
02022            rv = PK11_GenerateRandom(bp+i, 1);
02023            if (rv == SECFailure) goto loser;
02024        }
02025     }
02026     bp += padLen;
02027     *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
02028     PORT_Memcpy (bp, data->data, data->len);
02029 
02030     return block;
02031 loser:
02032     if (block) PORT_Free(block);
02033     return NULL;
02034 }
02035 
02036 /*
02037 ** Given the server's public key and cipher specs, generate a session key
02038 ** that is ready to use for encrypting/decrypting the byte stream. At
02039 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
02040 ** send it to the server.
02041 **
02042 ** Called from ssl2_HandleServerHelloMessage()
02043 */
02044 static SECStatus
02045 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
02046 {
02047     sslSessionID *    sid;
02048     PRUint8 *         ca;   /* points to iv data, or NULL if none. */
02049     PRUint8 *         ekbuf               = 0;
02050     CERTCertificate * cert         = 0;
02051     SECKEYPublicKey * serverKey    = 0;
02052     unsigned          modulusLen   = 0;
02053     SECStatus         rv;
02054     int               cipher;
02055     int               keyLen;      /* cipher symkey size in bytes. */
02056     int               ckLen;       /* publicly reveal this many bytes of key. */
02057     int               caLen;       /* length of IV data at *ca.       */
02058     int               nc;
02059 
02060     unsigned char *eblock;  /* holds unencrypted PKCS#1 formatted key. */
02061     SECItem           rek;  /* holds portion of symkey to be encrypted. */
02062 
02063     PRUint8           keyData[SSL_MAX_MASTER_KEY_BYTES];
02064     PRUint8           iv     [8];
02065 
02066     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02067 
02068     eblock = NULL;
02069 
02070     sid = ss->sec.ci.sid;
02071     PORT_Assert(sid != 0);
02072 
02073     cert = ss->sec.peerCert;
02074     
02075     serverKey = CERT_ExtractPublicKey(cert);
02076     if (!serverKey) {
02077        SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
02078                SSL_GETPID(), ss->fd, PORT_GetError()));
02079        PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
02080        rv = SECFailure;
02081        goto loser2;
02082     }
02083 
02084     ss->sec.authAlgorithm = ssl_sign_rsa;
02085     ss->sec.keaType       = ssl_kea_rsa;
02086     ss->sec.keaKeyBits    = \
02087     ss->sec.authKeyBits   = SECKEY_PublicKeyStrengthInBits(serverKey);
02088 
02089     /* Choose a compatible cipher with the server */
02090     nc = csLen / 3;
02091     cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
02092     if (cipher < 0) {
02093        /* ssl2_ChooseSessionCypher has set error code. */
02094        ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
02095        goto loser;
02096     }
02097 
02098     /* Generate the random keys */
02099     PK11_GenerateRandom(keyData, sizeof(keyData));
02100 
02101     /*
02102     ** Next, carve up the keys into clear and encrypted portions. The
02103     ** clear data is taken from the start of keyData and the encrypted
02104     ** portion from the remainder. Note that each of these portions is
02105     ** carved in half, one half for the read-key and one for the
02106     ** write-key.
02107     */
02108     ca = 0;
02109 
02110     /* We know that cipher is a legit value here, because 
02111      * ssl2_ChooseSessionCypher doesn't return bogus values.
02112      */
02113     ckLen = ssl_Specs[cipher].pubLen;     /* cleartext key length. */
02114     caLen = ssl_Specs[cipher].ivLen;      /* IV length.        */
02115     if (caLen) {
02116        PORT_Assert(sizeof iv >= caLen);
02117        PK11_GenerateRandom(iv, caLen);
02118        ca = iv;
02119     }
02120 
02121     /* Fill in session-id */
02122     rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
02123                  ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
02124                  ss->sec.authAlgorithm, ss->sec.authKeyBits,
02125                  ss->sec.keaType,       ss->sec.keaKeyBits);
02126     if (rv != SECSuccess) {
02127        goto loser;
02128     }
02129 
02130     SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
02131               SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
02132               ckLen<<3, keyLen<<3));
02133 
02134     /* Now setup read and write ciphers */
02135     rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
02136     if (rv != SECSuccess) {
02137        goto loser;
02138     }
02139 
02140     /*
02141     ** Fill in the encryption buffer with some random bytes. Then 
02142     ** copy in the portion of the session key we are encrypting.
02143     */
02144     modulusLen = SECKEY_PublicKeyStrength(serverKey);
02145     rek.data   = keyData + ckLen;
02146     rek.len    = keyLen  - ckLen;
02147     eblock = ssl_FormatSSL2Block(modulusLen, &rek);
02148     if (eblock == NULL) 
02149        goto loser;
02150 
02151     /* Set up the padding for version 2 rollback detection. */
02152     /* XXX We should really use defines here */
02153     if (ss->opt.enableSSL3 || ss->opt.enableTLS) {
02154        PORT_Assert((modulusLen - rek.len) > 12);
02155        PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
02156     }
02157     ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
02158     if (!ekbuf) 
02159        goto loser;
02160     PRINT_BUF(10, (ss, "master key encryption block:",
02161                  eblock, modulusLen));
02162 
02163     /* Encrypt ekitem */
02164     rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
02165                                           ss->pkcs11PinArg);
02166     if (rv) 
02167        goto loser;
02168 
02169     /*  Now we have everything ready to send */
02170     rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
02171                             keyData, ckLen, ekbuf, modulusLen);
02172     if (rv != SECSuccess) {
02173        goto loser;
02174     }
02175     rv = SECSuccess;
02176     goto done;
02177 
02178   loser:
02179     rv = SECFailure;
02180 
02181   loser2:
02182   done:
02183     PORT_Memset(keyData, 0, sizeof(keyData));
02184     PORT_ZFree(ekbuf, modulusLen);
02185     PORT_ZFree(eblock, modulusLen);
02186     SECKEY_DestroyPublicKey(serverKey);
02187     return rv;
02188 }
02189 
02190 /************************************************************************/
02191 
02192 /* 
02193  * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
02194  * Caller holds recvBufLock and handshakeLock
02195  */
02196 static void
02197 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
02198 {
02199     sslSessionID *sid = ss->sec.ci.sid;
02200 
02201     /* Record entry in nonce cache */
02202     if (sid->peerCert == NULL) {
02203        PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
02204        sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
02205 
02206     }
02207     if (!ss->opt.noCache)
02208        (*ss->sec.cache)(sid);
02209 }
02210 
02211 /* Called from ssl2_HandleMessage() */
02212 static SECStatus
02213 ssl2_TriggerNextMessage(sslSocket *ss)
02214 {
02215     SECStatus        rv;
02216 
02217     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02218 
02219     if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
02220        !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
02221        ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
02222        rv = ssl2_SendCertificateRequestMessage(ss);
02223        return rv;
02224     }
02225     return SECSuccess;
02226 }
02227 
02228 /* See if it's time to send our finished message, or if the handshakes are
02229 ** complete.  Send finished message if appropriate.
02230 ** Returns SECSuccess unless anything goes wrong.
02231 **
02232 ** Called from ssl2_HandleMessage,
02233 **             ssl2_HandleVerifyMessage 
02234 **             ssl2_HandleServerHelloMessage
02235 **             ssl2_HandleClientSessionKeyMessage
02236 **             ssl2_RestartHandshakeAfterCertReq
02237 **             ssl2_RestartHandshakeAfterServerCert
02238 */
02239 static SECStatus
02240 ssl2_TryToFinish(sslSocket *ss)
02241 {
02242     SECStatus        rv;
02243     char             e, ef;
02244 
02245     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02246 
02247     e = ss->sec.ci.elements;
02248     ef = e | CIS_HAVE_FINISHED;
02249     if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
02250        if (ss->sec.isServer) {
02251            /* Send server finished message if we already didn't */
02252            rv = ssl2_SendServerFinishedMessage(ss);
02253        } else {
02254            /* Send client finished message if we already didn't */
02255            rv = ssl2_SendClientFinishedMessage(ss);
02256        }
02257        if (rv != SECSuccess) {
02258            return rv;
02259        }
02260        if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
02261            /* Totally finished */
02262            ss->handshake = 0;
02263            return SECSuccess;
02264        }
02265     }
02266     return SECSuccess;
02267 }
02268 
02269 /*
02270 ** Called from ssl2_HandleRequestCertificate
02271 **             ssl2_RestartHandshakeAfterCertReq
02272 */
02273 static SECStatus
02274 ssl2_SignResponse(sslSocket *ss,
02275             SECKEYPrivateKey *key,
02276             SECItem *response)
02277 {
02278     SGNContext *     sgn = NULL;
02279     PRUint8 *        challenge;
02280     unsigned int     len;
02281     SECStatus        rv            = SECFailure;
02282     
02283     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02284 
02285     challenge = ss->sec.ci.serverChallenge;
02286     len = ss->sec.ci.serverChallengeLen;
02287     
02288     /* Sign the expected data... */
02289     sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
02290     if (!sgn) 
02291        goto done;
02292     rv = SGN_Begin(sgn);
02293     if (rv != SECSuccess) 
02294        goto done;
02295     rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
02296     if (rv != SECSuccess) 
02297        goto done;
02298     rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
02299     if (rv != SECSuccess) 
02300        goto done;
02301     rv = SGN_Update(sgn, challenge, len);
02302     if (rv != SECSuccess) 
02303        goto done;
02304     rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, 
02305                          ss->sec.peerCert->derCert.len);
02306     if (rv != SECSuccess) 
02307        goto done;
02308     rv = SGN_End(sgn, response);
02309     if (rv != SECSuccess) 
02310        goto done;
02311 
02312 done:
02313     SGN_DestroyContext(sgn, PR_TRUE);
02314     return rv == SECSuccess ? SECSuccess : SECFailure;
02315 }
02316 
02317 /*
02318 ** Try to handle a request-certificate message. Get client's certificate
02319 ** and private key and sign a message for the server to see.
02320 ** Caller must hold handshakeLock 
02321 **
02322 ** Called from ssl2_HandleMessage().
02323 */
02324 static int
02325 ssl2_HandleRequestCertificate(sslSocket *ss)
02326 {
02327     CERTCertificate * cert  = NULL;       /* app-selected client cert. */
02328     SECKEYPrivateKey *key   = NULL;       /* priv key for cert. */
02329     SECStatus         rv;
02330     SECItem           response;
02331     int               ret   = 0;
02332     PRUint8           authType;
02333 
02334 
02335     /*
02336      * These things all need to be initialized before we can "goto loser".
02337      */
02338     response.data = NULL;
02339 
02340     /* get challenge info from connectionInfo */
02341     authType = ss->sec.ci.authType;
02342 
02343     if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
02344        SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
02345                   ss->fd, authType));
02346        goto no_cert_error;
02347     }
02348 
02349     /* Get certificate and private-key from client */
02350     if (!ss->getClientAuthData) {
02351        SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
02352                   SSL_GETPID(), ss->fd));
02353        goto no_cert_error;
02354     }
02355     ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
02356                                NULL, &cert, &key);
02357     if ( ret == SECWouldBlock ) {
02358        ssl_SetAlwaysBlock(ss);
02359        goto done;
02360     }
02361 
02362     if (ret) {
02363        goto no_cert_error;
02364     }
02365 
02366     /* check what the callback function returned */
02367     if ((!cert) || (!key)) {
02368         /* we are missing either the key or cert */
02369         if (cert) {
02370             /* got a cert, but no key - free it */
02371             CERT_DestroyCertificate(cert);
02372             cert = NULL;
02373         }
02374         if (key) {
02375             /* got a key, but no cert - free it */
02376             SECKEY_DestroyPrivateKey(key);
02377             key = NULL;
02378         }
02379         goto no_cert_error;
02380     }
02381 
02382     rv = ssl2_SignResponse(ss, key, &response);
02383     if ( rv != SECSuccess ) {
02384        ret = -1;
02385        goto loser;
02386     }
02387 
02388     /* Send response message */
02389     ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
02390 
02391     /* Now, remember the cert we sent. But first, forget any previous one. */
02392     if (ss->sec.localCert) {
02393        CERT_DestroyCertificate(ss->sec.localCert);
02394     }
02395     ss->sec.localCert = CERT_DupCertificate(cert);
02396     PORT_Assert(!ss->sec.ci.sid->localCert);
02397     if (ss->sec.ci.sid->localCert) {
02398        CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
02399     }
02400     ss->sec.ci.sid->localCert = cert;
02401     cert = NULL;
02402 
02403     goto done;
02404 
02405   no_cert_error:
02406     SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
02407               ss->fd, ret));
02408     ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
02409 
02410   loser:
02411   done:
02412     if ( cert ) {
02413        CERT_DestroyCertificate(cert);
02414     }
02415     if ( key ) {
02416        SECKEY_DestroyPrivateKey(key);
02417     }
02418     if ( response.data ) {
02419        PORT_Free(response.data);
02420     }
02421     
02422     return ret;
02423 }
02424 
02425 /*
02426 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
02427 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response
02428 ** are contained in the gathered input data.
02429 */
02430 static SECStatus
02431 ssl2_HandleClientCertificate(sslSocket *    ss, 
02432                              PRUint8        certType,   /* XXX unused */
02433                           PRUint8 *      cd, 
02434                           unsigned int   cdLen,
02435                           PRUint8 *      response,
02436                           unsigned int   responseLen)
02437 {
02438     CERTCertificate *cert   = NULL;
02439     SECKEYPublicKey *pubKey = NULL;
02440     VFYContext *     vfy    = NULL;
02441     SECItem *        derCert;
02442     SECStatus        rv            = SECFailure;
02443     SECItem          certItem;
02444     SECItem          rep;
02445 
02446     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02447     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
02448 
02449     /* Extract the certificate */
02450     certItem.data = cd;
02451     certItem.len  = cdLen;
02452 
02453     cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
02454                                PR_FALSE, PR_TRUE);
02455     if (cert == NULL) {
02456        goto loser;
02457     }
02458 
02459     /* save the certificate, since the auth routine will need it */
02460     ss->sec.peerCert = cert;
02461 
02462     /* Extract the public key */
02463     pubKey = CERT_ExtractPublicKey(cert);
02464     if (!pubKey) 
02465        goto loser;
02466     
02467     /* Verify the response data... */
02468     rep.data = response;
02469     rep.len = responseLen;
02470     /* SSL 2.0 only supports RSA certs, so we don't have to worry about
02471      * DSA here. */
02472     vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
02473                          ss->pkcs11PinArg);
02474     if (!vfy) 
02475        goto loser;
02476     rv = VFY_Begin(vfy);
02477     if (rv) 
02478        goto loser;
02479 
02480     rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
02481     if (rv) 
02482        goto loser;
02483     rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
02484     if (rv) 
02485        goto loser;
02486     rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
02487     if (rv) 
02488        goto loser;
02489 
02490     derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
02491     rv = VFY_Update(vfy, derCert->data, derCert->len);
02492     if (rv) 
02493        goto loser;
02494     rv = VFY_End(vfy);
02495     if (rv) 
02496        goto loser;
02497 
02498     /* Now ask the server application if it likes the certificate... */
02499     rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
02500                                        ss->fd, PR_TRUE, PR_TRUE);
02501     /* Hey, it liked it. */
02502     if (SECSuccess == rv) 
02503        goto done;
02504 
02505 loser:
02506     ss->sec.peerCert = NULL;
02507     CERT_DestroyCertificate(cert);
02508 
02509 done:
02510     VFY_DestroyContext(vfy, PR_TRUE);
02511     SECKEY_DestroyPublicKey(pubKey);
02512     return rv;
02513 }
02514 
02515 /*
02516 ** Handle remaining messages between client/server. Process finished
02517 ** messages from either side and any authentication requests.
02518 ** This should only be called for SSLv2 handshake messages, 
02519 ** not for application data records.
02520 ** Caller must hold handshake lock.
02521 **
02522 ** Called from ssl_Do1stHandshake().
02523 ** 
02524 */
02525 static SECStatus
02526 ssl2_HandleMessage(sslSocket *ss)
02527 {
02528     PRUint8 *        data;
02529     PRUint8 *        cid;
02530     unsigned         len, certType, certLen, responseLen;
02531     int              rv;
02532     int              rv2;
02533 
02534     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02535 
02536     ssl_GetRecvBufLock(ss);
02537 
02538     data = ss->gs.buf.buf + ss->gs.recordOffset;
02539 
02540     if (ss->gs.recordLen < 1) {
02541        goto bad_peer;
02542     }
02543     SSL_TRC(3, ("%d: SSL[%d]: received %d message",
02544               SSL_GETPID(), ss->fd, data[0]));
02545     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
02546 
02547     switch (data[0]) {
02548     case SSL_MT_CLIENT_FINISHED:
02549        if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
02550            SSL_DBG(("%d: SSL[%d]: dup client-finished message",
02551                    SSL_GETPID(), ss->fd));
02552            goto bad_peer;
02553        }
02554 
02555        /* See if nonce matches */
02556        len = ss->gs.recordLen - 1;
02557        cid = data + 1;
02558        if ((len != sizeof(ss->sec.ci.connectionID)) ||
02559            (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
02560            SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
02561            PRINT_BUF(5, (ss, "sent connection-id",
02562                        ss->sec.ci.connectionID, 
02563                        sizeof(ss->sec.ci.connectionID)));
02564            PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
02565            goto bad_peer;
02566        }
02567 
02568        SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
02569                   SSL_GETPID(), ss->fd, 
02570                   ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
02571        ss->sec.ci.elements |= CIS_HAVE_FINISHED;
02572        break;
02573 
02574     case SSL_MT_SERVER_FINISHED:
02575        if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
02576            SSL_DBG(("%d: SSL[%d]: dup server-finished message",
02577                    SSL_GETPID(), ss->fd));
02578            goto bad_peer;
02579        }
02580 
02581        if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
02582            SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
02583                    SSL_GETPID(), ss->fd, ss->gs.recordLen));
02584            goto bad_peer;
02585        }
02586        ssl2_ClientRegSessionID(ss, data+1);
02587        SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
02588                   SSL_GETPID(), ss->fd, 
02589                   ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
02590        ss->sec.ci.elements |= CIS_HAVE_FINISHED;
02591        break;
02592 
02593     case SSL_MT_REQUEST_CERTIFICATE:
02594        len = ss->gs.recordLen - 2;
02595        if ((len < SSL_MIN_CHALLENGE_BYTES) ||
02596            (len > SSL_MAX_CHALLENGE_BYTES)) {
02597            /* Bad challenge */
02598            SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
02599                    SSL_GETPID(), ss->fd, len));
02600            goto bad_peer;
02601        }
02602        
02603        /* save auth request info */
02604        ss->sec.ci.authType           = data[1];
02605        ss->sec.ci.serverChallengeLen = len;
02606        PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
02607        
02608        rv = ssl2_HandleRequestCertificate(ss);
02609        if (rv == SECWouldBlock) {
02610            SSL_TRC(3, ("%d: SSL[%d]: async cert request",
02611                      SSL_GETPID(), ss->fd));
02612            /* someone is handling this asynchronously */
02613            ssl_ReleaseRecvBufLock(ss);
02614            return SECWouldBlock;
02615        }
02616        if (rv) {
02617            SET_ERROR_CODE
02618            goto loser;
02619        }
02620        break;
02621 
02622     case SSL_MT_CLIENT_CERTIFICATE:
02623        if (!ss->authCertificate) {
02624            /* Server asked for authentication and can't handle it */
02625            PORT_SetError(SSL_ERROR_BAD_SERVER);
02626            goto loser;
02627        }
02628        if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
02629            SET_ERROR_CODE
02630            goto loser;
02631        }
02632        certType    = data[1];
02633        certLen     = (data[2] << 8) | data[3];
02634        responseLen = (data[4] << 8) | data[5];
02635        if (certType != SSL_CT_X509_CERTIFICATE) {
02636            PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
02637            goto loser;
02638        }
02639        if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES 
02640            > ss->gs.recordLen) {
02641            /* prevent overflow crash. */
02642            rv = SECFailure;
02643        } else
02644        rv = ssl2_HandleClientCertificate(ss, data[1],
02645               data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
02646               certLen,
02647               data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
02648               responseLen);
02649        if (rv) {
02650            rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
02651            SET_ERROR_CODE
02652            goto loser;
02653        }
02654        ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
02655        break;
02656 
02657     case SSL_MT_ERROR:
02658        rv = (data[1] << 8) | data[2];
02659        SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
02660                   SSL_GETPID(), ss->fd, rv));
02661 
02662        /* Convert protocol error number into API error number */
02663        switch (rv) {
02664          case SSL_PE_NO_CYPHERS:
02665            rv = SSL_ERROR_NO_CYPHER_OVERLAP;
02666            break;
02667          case SSL_PE_NO_CERTIFICATE:
02668            rv = SSL_ERROR_NO_CERTIFICATE;
02669            break;
02670          case SSL_PE_BAD_CERTIFICATE:
02671            rv = SSL_ERROR_BAD_CERTIFICATE;
02672            break;
02673          case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
02674            rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
02675            break;
02676          default:
02677            goto bad_peer;
02678        }
02679        /* XXX make certificate-request optionally fail... */
02680        PORT_SetError(rv);
02681        goto loser;
02682 
02683     default:
02684        SSL_DBG(("%d: SSL[%d]: unknown message %d",
02685                SSL_GETPID(), ss->fd, data[0]));
02686        goto loser;
02687     }
02688 
02689     SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
02690               SSL_GETPID(), ss->fd, data[0],
02691               ss->sec.ci.requiredElements, ss->sec.ci.elements));
02692 
02693     rv = ssl2_TryToFinish(ss);
02694     if (rv != SECSuccess) 
02695        goto loser;
02696 
02697     ss->gs.recordLen = 0;
02698     ssl_ReleaseRecvBufLock(ss);
02699 
02700     if (ss->handshake == 0) {
02701        return SECSuccess;
02702     }
02703 
02704     ss->handshake     = ssl_GatherRecord1stHandshake;
02705     ss->nextHandshake = ssl2_HandleMessage;
02706     return ssl2_TriggerNextMessage(ss);
02707 
02708   bad_peer:
02709     PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
02710     /* FALL THROUGH */
02711 
02712   loser:
02713     ssl_ReleaseRecvBufLock(ss);
02714     return SECFailure;
02715 }
02716 
02717 /************************************************************************/
02718 
02719 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage or 
02720 ** ssl2_RestartHandshakeAfterServerCert.
02721 */
02722 static SECStatus
02723 ssl2_HandleVerifyMessage(sslSocket *ss)
02724 {
02725     PRUint8 *        data;
02726     SECStatus        rv;
02727 
02728     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02729     ssl_GetRecvBufLock(ss);
02730 
02731     data = ss->gs.buf.buf + ss->gs.recordOffset;
02732     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
02733     if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
02734        (data[0] != SSL_MT_SERVER_VERIFY) ||
02735        PORT_Memcmp(data+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES)) {
02736        /* Bad server */
02737        PORT_SetError(SSL_ERROR_BAD_SERVER);
02738        goto loser;
02739     }
02740     ss->sec.ci.elements |= CIS_HAVE_VERIFY;
02741 
02742     SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
02743               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
02744               ss->sec.ci.elements));
02745 
02746     rv = ssl2_TryToFinish(ss);
02747     if (rv) 
02748        goto loser;
02749 
02750     ss->gs.recordLen = 0;
02751     ssl_ReleaseRecvBufLock(ss);
02752 
02753     if (ss->handshake == 0) {
02754        return SECSuccess;
02755     }
02756     ss->handshake         = ssl_GatherRecord1stHandshake;
02757     ss->nextHandshake     = ssl2_HandleMessage;
02758     return SECSuccess;
02759 
02760 
02761   loser:
02762     ssl_ReleaseRecvBufLock(ss);
02763     return SECFailure;
02764 }
02765 
02766 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
02767  * ICK! 
02768  * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
02769  */
02770 SECStatus
02771 ssl2_HandleServerHelloMessage(sslSocket *ss)
02772 {
02773     sslSessionID *   sid;
02774     PRUint8 *        cert;
02775     PRUint8 *        cs;
02776     PRUint8 *        data;
02777     SECStatus        rv; 
02778     int              needed, sidHit, certLen, csLen, cidLen, certType, err;
02779 
02780     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
02781 
02782     if (!ss->opt.enableSSL2) {
02783        PORT_SetError(SSL_ERROR_SSL2_DISABLED);
02784        return SECFailure;
02785     }
02786 
02787     ssl_GetRecvBufLock(ss);
02788 
02789     PORT_Assert(ss->sec.ci.sid != 0);
02790     sid = ss->sec.ci.sid;
02791 
02792     data = ss->gs.buf.buf + ss->gs.recordOffset;
02793     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
02794 
02795     /* Make sure first message has some data and is the server hello message */
02796     if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES)
02797        || (data[0] != SSL_MT_SERVER_HELLO)) {
02798        if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
02799            err = (data[1] << 8) | data[2];
02800            if (err == SSL_PE_NO_CYPHERS) {
02801               PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
02802               goto loser;
02803            }
02804        }
02805        goto bad_server;
02806     }
02807 
02808     sidHit      = data[1];
02809     certType    = data[2];
02810     ss->version = (data[3] << 8) | data[4];
02811     certLen     = (data[5] << 8) | data[6];
02812     csLen       = (data[7] << 8) | data[8];
02813     cidLen      = (data[9] << 8) | data[10];
02814     cert        = data + SSL_HL_SERVER_HELLO_HBYTES;
02815     cs          = cert + certLen;
02816 
02817     SSL_TRC(5,
02818            ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
02819             SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
02820             csLen, cidLen));
02821     if (ss->version != SSL_LIBRARY_VERSION_2) {
02822         if (ss->version < SSL_LIBRARY_VERSION_2) {
02823          SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
02824                     SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
02825                     ss->version));
02826        } else {
02827          SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
02828                   SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
02829          /* server claims to be newer but does not follow protocol */
02830          PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
02831          goto loser;
02832        }
02833     }
02834 
02835     if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen 
02836                                                   > ss->gs.recordLen)
02837        || (csLen % 3) != 0   
02838        /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32  */
02839        ) {
02840        goto bad_server;
02841     }
02842 
02843     /* Save connection-id.
02844     ** This code only saves the first 16 byte of the connectionID.
02845     ** If the connectionID is shorter than 16 bytes, it is zero-padded.
02846     */
02847     if (cidLen < sizeof ss->sec.ci.connectionID)
02848        memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
02849     cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
02850     PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);
02851 
02852     /* See if session-id hit */
02853     needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
02854     if (sidHit) {
02855        if (certLen || csLen) {
02856            /* Uh oh - bogus server */
02857            SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
02858                    SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
02859            goto bad_server;
02860        }
02861 
02862        /* Total winner. */
02863        SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
02864                   "port=0x%04x",
02865                   SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
02866        ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
02867         ss->sec.authAlgorithm = sid->authAlgorithm;
02868        ss->sec.authKeyBits   = sid->authKeyBits;
02869        ss->sec.keaType       = sid->keaType;
02870        ss->sec.keaKeyBits    = sid->keaKeyBits;
02871        rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
02872        if (rv != SECSuccess) {
02873            goto loser;
02874        }
02875     } else {
02876        if (certType != SSL_CT_X509_CERTIFICATE) {
02877            PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
02878            goto loser;
02879        }
02880        if (csLen == 0) {
02881            PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
02882            SSL_DBG(("%d: SSL[%d]: no cipher overlap",
02883                    SSL_GETPID(), ss->fd));
02884            goto loser;
02885        }
02886        if (certLen == 0) {
02887            SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
02888                    SSL_GETPID(), ss->fd, certLen, csLen));
02889            goto bad_server;
02890        }
02891 
02892        if (sid->cached != never_cached) {
02893            /* Forget our session-id - server didn't like it */
02894            SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
02895                      SSL_GETPID(), ss->fd));
02896            (*ss->sec.uncache)(sid);
02897            ssl_FreeSID(sid);
02898            ss->sec.ci.sid = sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
02899            if (!sid) {
02900               goto loser;
02901            }
02902            sid->references = 1;
02903            sid->addr = ss->sec.ci.peer;
02904            sid->port = ss->sec.ci.port;
02905        }
02906 
02907        /* decode the server's certificate */
02908        rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
02909        if (rv != SECSuccess) {
02910            if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
02911               (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
02912            }
02913            goto loser;
02914        }
02915 
02916        /* Setup new session cipher */
02917        rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
02918        if (rv != SECSuccess) {
02919            if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
02920               (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
02921            }
02922            goto loser;
02923        }
02924     }
02925 
02926     /* Build up final list of required elements */
02927     ss->sec.ci.elements         = CIS_HAVE_MASTER_KEY;
02928     ss->sec.ci.requiredElements = needed;
02929 
02930   if (!sidHit) {
02931     /* verify the server's certificate. if sidHit, don't check signatures */
02932     rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd, 
02933                              (PRBool)(!sidHit), PR_FALSE);
02934     if (rv) {
02935        if (ss->handleBadCert) {
02936            rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
02937            if ( rv ) {
02938               if ( rv == SECWouldBlock ) {
02939                   /* someone will handle this connection asynchronously*/
02940 
02941                   SSL_DBG(("%d: SSL[%d]: go to async cert handler",
02942                           SSL_GETPID(), ss->fd));
02943                   ssl_ReleaseRecvBufLock(ss);
02944                   ssl_SetAlwaysBlock(ss);
02945                   return SECWouldBlock;
02946               }
02947               /* cert is bad */
02948               SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
02949                       SSL_GETPID(), ss->fd, PORT_GetError()));
02950               goto loser;
02951 
02952            }
02953            /* cert is good */
02954        } else {
02955            SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
02956                    SSL_GETPID(), ss->fd, PORT_GetError()));
02957            goto loser;
02958        }
02959     }
02960   }
02961     /*
02962     ** At this point we have a completed session key and our session
02963     ** cipher is setup and ready to go. Switch to encrypted write routine
02964     ** as all future message data is to be encrypted.
02965     */
02966     ssl2_UseEncryptedSendFunc(ss);
02967 
02968     rv = ssl2_TryToFinish(ss);
02969     if (rv != SECSuccess) 
02970        goto loser;
02971 
02972     ss->gs.recordLen = 0;
02973 
02974     ssl_ReleaseRecvBufLock(ss);
02975 
02976     if (ss->handshake == 0) {
02977        return SECSuccess;
02978     }
02979 
02980     SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
02981               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, 
02982               ss->sec.ci.elements));
02983     ss->handshake     = ssl_GatherRecord1stHandshake;
02984     ss->nextHandshake = ssl2_HandleVerifyMessage;
02985     return SECSuccess;
02986 
02987   bad_server:
02988     PORT_SetError(SSL_ERROR_BAD_SERVER);
02989     /* FALL THROUGH */
02990 
02991   loser:
02992     ssl_ReleaseRecvBufLock(ss);
02993     return SECFailure;
02994 }
02995 
02996 /* Sends out the initial client Hello message on the connection.
02997  * Acquires and releases the socket's xmitBufLock.
02998  */
02999 SECStatus
03000 ssl2_BeginClientHandshake(sslSocket *ss)
03001 {
03002     sslSessionID      *sid;
03003     PRUint8           *msg;
03004     PRUint8           *cp;
03005     PRUint8           *localCipherSpecs = NULL;
03006     unsigned int      localCipherSize;
03007     unsigned int      i;
03008     int               sendLen, sidLen = 0;
03009     SECStatus         rv;
03010 
03011     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
03012 
03013     ss->sec.isServer     = 0;
03014     ss->sec.sendSequence = 0;
03015     ss->sec.rcvSequence  = 0;
03016     ssl_ChooseSessionIDProcs(&ss->sec);
03017 
03018     if (!ss->cipherSpecs) {
03019        rv = ssl2_ConstructCipherSpecs(ss);
03020        if (rv != SECSuccess)
03021            goto loser;
03022     }
03023 
03024     /* count the SSL2 and SSL3 enabled ciphers.
03025      * if either is zero, clear the socket's enable for that protocol.
03026      */
03027     rv = ssl2_CheckConfigSanity(ss);
03028     if (rv != SECSuccess)
03029        goto loser;
03030 
03031     /* Get peer name of server */
03032     rv = ssl_GetPeerInfo(ss);
03033     if (rv < 0) {
03034 #ifdef HPUX11
03035         /*
03036          * On some HP-UX B.11.00 systems, getpeername() occasionally
03037          * fails with ENOTCONN after a successful completion of
03038          * non-blocking connect.  I found that if we do a write()
03039          * and then retry getpeername(), it will work.
03040          */
03041         if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
03042             char dummy;
03043             (void) PR_Write(ss->fd->lower, &dummy, 0);
03044             rv = ssl_GetPeerInfo(ss);
03045             if (rv < 0) {
03046                 goto loser;
03047             }
03048         }
03049 #else
03050        goto loser;
03051 #endif
03052     }
03053 
03054     SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
03055 
03056     /* Try to find server in our session-id cache */
03057     if (ss->opt.noCache) {
03058        sid = NULL;
03059     } else {
03060        sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, 
03061                            ss->url);
03062     }
03063     while (sid) {  /* this isn't really a loop */
03064        /* if we're not doing this SID's protocol any more, drop it. */
03065        if (((sid->version  < SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL2) ||
03066            ((sid->version == SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableSSL3) ||
03067            ((sid->version >  SSL_LIBRARY_VERSION_3_0) && !ss->opt.enableTLS)) {
03068            ss->sec.uncache(sid);
03069            ssl_FreeSID(sid);
03070            sid = NULL;
03071            break;
03072        }
03073        if (ss->opt.enableSSL2 && sid->version < SSL_LIBRARY_VERSION_3_0) {
03074            /* If the cipher in this sid is not enabled, drop it. */
03075            for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
03076               if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
03077                   break;
03078            }
03079            if (i >= ss->sizeCipherSpecs) {
03080               ss->sec.uncache(sid);
03081               ssl_FreeSID(sid);
03082               sid = NULL;
03083               break;
03084            }
03085        }
03086        sidLen = sizeof(sid->u.ssl2.sessionID);
03087        PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
03088                     sidLen));
03089        ss->version = sid->version;
03090        PORT_Assert(!ss->sec.localCert);
03091        if (ss->sec.localCert) {
03092            CERT_DestroyCertificate(ss->sec.localCert);
03093        }
03094        ss->sec.localCert     = CERT_DupCertificate(sid->localCert);
03095        break;  /* this isn't really a loop */
03096     } 
03097     if (!sid) {
03098        sidLen = 0;
03099        sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
03100        if (!sid) {
03101            goto loser;
03102        }
03103        sid->references = 1;
03104        sid->cached     = never_cached;
03105        sid->addr       = ss->sec.ci.peer;
03106        sid->port       = ss->sec.ci.port;
03107        if (ss->peerID != NULL) {
03108            sid->peerID = PORT_Strdup(ss->peerID);
03109        }
03110        if (ss->url != NULL) {
03111            sid->urlSvrName = PORT_Strdup(ss->url);
03112        }
03113     }
03114     ss->sec.ci.sid = sid;
03115 
03116     PORT_Assert(sid != NULL);
03117 
03118     if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
03119         (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
03120 
03121        ss->gs.state      = GS_INIT;
03122        ss->handshake     = ssl_GatherRecord1stHandshake;
03123 
03124        /* ssl3_SendClientHello will override this if it succeeds. */
03125        ss->version       = SSL_LIBRARY_VERSION_3_0;
03126 
03127        ssl_GetXmitBufLock(ss);    /***************************************/
03128        ssl_GetSSL3HandshakeLock(ss);
03129        rv =  ssl3_SendClientHello(ss);
03130        ssl_ReleaseSSL3HandshakeLock(ss);
03131        ssl_ReleaseXmitBufLock(ss); /***************************************/
03132 
03133        return rv;
03134     }
03135 #if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B)
03136     /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
03137     ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
03138     if (ss->cipherSpecs != NULL) {
03139        PORT_Free(ss->cipherSpecs);
03140        ss->cipherSpecs     = NULL;
03141        ss->sizeCipherSpecs = 0;
03142     }
03143 #endif
03144 
03145     if (!ss->cipherSpecs) {
03146         rv = ssl2_ConstructCipherSpecs(ss);
03147        if (rv < 0) {
03148            return rv;
03149        }
03150     }
03151     localCipherSpecs = ss->cipherSpecs;
03152     localCipherSize  = ss->sizeCipherSpecs;
03153 
03154     sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + sidLen +
03155        SSL_CHALLENGE_BYTES;
03156 
03157     /* Generate challenge bytes for server */
03158     PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
03159 
03160     ssl_GetXmitBufLock(ss);    /***************************************/
03161 
03162     rv = ssl2_GetSendBuffer(ss, sendLen);
03163     if (rv) 
03164        goto unlock_loser;
03165 
03166     /* Construct client-hello message */
03167     cp = msg = ss->sec.ci.sendBuf.buf;
03168     msg[0] = SSL_MT_CLIENT_HELLO;
03169     if ( ss->opt.enableTLS ) {
03170        ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_1_TLS;
03171     } else if ( ss->opt.enableSSL3 ) {
03172        ss->clientHelloVersion = SSL_LIBRARY_VERSION_3_0;
03173     } else {
03174        ss->clientHelloVersion = SSL_LIBRARY_VERSION_2;
03175     }
03176     
03177     msg[1] = MSB(ss->clientHelloVersion);
03178     msg[2] = LSB(ss->clientHelloVersion);
03179     msg[3] = MSB(localCipherSize);
03180     msg[4] = LSB(localCipherSize);
03181     msg[5] = MSB(sidLen);
03182     msg[6] = LSB(sidLen);
03183     msg[7] = MSB(SSL_CHALLENGE_BYTES);
03184     msg[8] = LSB(SSL_CHALLENGE_BYTES);
03185     cp += SSL_HL_CLIENT_HELLO_HBYTES;
03186     PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
03187     cp += localCipherSize;
03188     if (sidLen) {
03189        PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
03190        cp += sidLen;
03191     }
03192     PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
03193 
03194     /* Send it to the server */
03195     DUMP_MSG(29, (ss, msg, sendLen));
03196     ss->handshakeBegun = 1;
03197     rv = (*ss->sec.send)(ss, msg, sendLen, 0);
03198 
03199     ssl_ReleaseXmitBufLock(ss);    /***************************************/
03200 
03201     if (rv < 0) {
03202        goto loser;
03203     }
03204 
03205     rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
03206     if (rv < 0) {
03207        goto loser;
03208     }
03209 
03210     /* Setup to receive servers hello message */
03211     ssl_GetRecvBufLock(ss);
03212     ss->gs.recordLen = 0;
03213     ssl_ReleaseRecvBufLock(ss);
03214 
03215     ss->handshake     = ssl_GatherRecord1stHandshake;
03216     ss->nextHandshake = ssl2_HandleServerHelloMessage;
03217     return SECSuccess;
03218 
03219 unlock_loser:
03220     ssl_ReleaseXmitBufLock(ss);
03221 loser:
03222     return SECFailure;
03223 }
03224 
03225 /************************************************************************/
03226 
03227 /* Handle the CLIENT-MASTER-KEY message. 
03228 ** Acquires and releases RecvBufLock.
03229 ** Called from ssl2_HandleClientHelloMessage(). 
03230 */
03231 static SECStatus
03232 ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
03233 {
03234     PRUint8 *        data;
03235     unsigned int     caLen;
03236     unsigned int     ckLen;
03237     unsigned int     ekLen;
03238     unsigned int     keyBits;
03239     int              cipher;
03240     SECStatus        rv;
03241 
03242 
03243     ssl_GetRecvBufLock(ss);
03244 
03245     data = ss->gs.buf.buf + ss->gs.recordOffset;
03246     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
03247 
03248     if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
03249        || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
03250        goto bad_client;
03251     }
03252     cipher  = data[1];
03253     keyBits = (data[2] << 8) | data[3];
03254     ckLen   = (data[4] << 8) | data[5];
03255     ekLen   = (data[6] << 8) | data[7];
03256     caLen   = (data[8] << 8) | data[9];
03257 
03258     SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d",
03259               SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen));
03260 
03261     if (ss->gs.recordLen < 
03262            SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
03263        SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
03264                SSL_GETPID(), ss->fd, ss->gs.recordLen));
03265        goto bad_client;
03266     }
03267 
03268     /* Use info from client to setup session key */
03269     rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits,
03270               data + SSL_HL_CLIENT_MASTER_KEY_HBYTES,                 ckLen,
03271               data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen,         ekLen,
03272               data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
03273     ss->gs.recordLen = 0;   /* we're done with this record. */
03274 
03275     ssl_ReleaseRecvBufLock(ss);
03276 
03277     if (rv != SECSuccess) {
03278        goto loser;
03279     }
03280     ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
03281     ssl2_UseEncryptedSendFunc(ss);
03282 
03283     /* Send server verify message now that keys are established */
03284     rv = ssl2_SendServerVerifyMessage(ss);
03285     if (rv != SECSuccess) 
03286        goto loser;
03287 
03288     rv = ssl2_TryToFinish(ss);
03289     if (rv != SECSuccess) 
03290        goto loser;
03291     if (ss->handshake == 0) {
03292        return SECSuccess;
03293     }
03294 
03295     SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
03296               SSL_GETPID(), ss->fd, 
03297               ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
03298     ss->handshake         = ssl_GatherRecord1stHandshake;
03299     ss->nextHandshake     = ssl2_HandleMessage;
03300 
03301     return ssl2_TriggerNextMessage(ss);
03302 
03303 bad_client:
03304     ssl_ReleaseRecvBufLock(ss);
03305     PORT_SetError(SSL_ERROR_BAD_CLIENT);
03306     /* FALLTHROUGH */
03307 
03308 loser:
03309     return SECFailure;
03310 }
03311 
03312 /*
03313  * attempt to restart the handshake after asynchronously handling
03314  * a request for the client's certificate.
03315  *
03316  * inputs:  
03317  *     cert   Client cert chosen by application.
03318  *     key    Private key associated with cert.  
03319  *
03320  * XXX: need to make ssl2 and ssl3 versions of this function agree on whether
03321  *     they take the reference, or bump the ref count!
03322  *
03323  * Return value: XXX
03324  *
03325  * Caller holds 1stHandshakeLock.
03326  */
03327 int
03328 ssl2_RestartHandshakeAfterCertReq(sslSocket *          ss,
03329                               CERTCertificate *    cert, 
03330                               SECKEYPrivateKey *   key)
03331 {
03332     int              ret;
03333     SECStatus        rv          = SECSuccess;
03334     SECItem          response;
03335 
03336     if (ss->version >= SSL_LIBRARY_VERSION_3_0) 
03337        return SECFailure;
03338 
03339     response.data = NULL;
03340 
03341     /* generate error if no cert or key */
03342     if ( ( cert == NULL ) || ( key == NULL ) ) {
03343        goto no_cert;
03344     }
03345     
03346     /* generate signed response to the challenge */
03347     rv = ssl2_SignResponse(ss, key, &response);
03348     if ( rv != SECSuccess ) {
03349        goto no_cert;
03350     }
03351     
03352     /* Send response message */
03353     ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
03354     if (ret) {
03355        goto no_cert;
03356     }
03357 
03358     /* try to finish the handshake */
03359     ret = ssl2_TryToFinish(ss);
03360     if (ret) {
03361        goto loser;
03362     }
03363     
03364     /* done with handshake */
03365     if (ss->handshake == 0) {
03366        ret = SECSuccess;
03367        goto done;
03368     }
03369 
03370     /* continue handshake */
03371     ssl_GetRecvBufLock(ss);
03372     ss->gs.recordLen = 0;
03373     ssl_ReleaseRecvBufLock(ss);
03374 
03375     ss->handshake     = ssl_GatherRecord1stHandshake;
03376     ss->nextHandshake = ssl2_HandleMessage;
03377     ret = ssl2_TriggerNextMessage(ss);
03378     goto done;
03379     
03380 no_cert:
03381     /* no cert - send error */
03382     ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
03383     goto done;
03384     
03385 loser:
03386     ret = SECFailure;
03387 done:
03388     /* free allocated data */
03389     if ( response.data ) {
03390        PORT_Free(response.data);
03391     }
03392     
03393     return ret;
03394 }
03395 
03396 
03397 /* restart an SSL connection that we stopped to run certificate dialogs 
03398 ** XXX Need to document here how an application marks a cert to show that
03399 **     the application has accepted it (overridden CERT_VerifyCert).
03400  *
03401  * Return value: XXX
03402  *
03403  * Caller holds 1stHandshakeLock.
03404 */
03405 int
03406 ssl2_RestartHandshakeAfterServerCert(sslSocket *ss)
03407 {
03408     int rv    = SECSuccess;
03409 
03410     if (ss->version >= SSL_LIBRARY_VERSION_3_0) 
03411        return SECFailure;
03412 
03413     /* SSL 2
03414     ** At this point we have a completed session key and our session
03415     ** cipher is setup and ready to go. Switch to encrypted write routine
03416     ** as all future message data is to be encrypted.
03417     */
03418     ssl2_UseEncryptedSendFunc(ss);
03419 
03420     rv = ssl2_TryToFinish(ss);
03421     if (rv == SECSuccess && ss->handshake != NULL) {    
03422        /* handshake is not yet finished. */
03423 
03424        SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
03425               SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
03426               ss->sec.ci.elements));
03427 
03428        ssl_GetRecvBufLock(ss);
03429        ss->gs.recordLen = 0;       /* mark it all used up. */
03430        ssl_ReleaseRecvBufLock(ss);
03431 
03432        ss->handshake     = ssl_GatherRecord1stHandshake;
03433        ss->nextHandshake = ssl2_HandleVerifyMessage;
03434     }
03435 
03436     return rv;
03437 }
03438 
03439 /*
03440 ** Handle the initial hello message from the client
03441 **
03442 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
03443 */
03444 SECStatus
03445 ssl2_HandleClientHelloMessage(sslSocket *ss)
03446 {
03447     sslSessionID    *sid;
03448     sslServerCerts * sc;
03449     CERTCertificate *serverCert;
03450     PRUint8         *msg;
03451     PRUint8         *data;
03452     PRUint8         *cs;
03453     PRUint8         *sd;
03454     PRUint8         *cert = NULL;
03455     PRUint8         *challenge;
03456     unsigned int    challengeLen;
03457     SECStatus       rv; 
03458     int             csLen;
03459     int             sendLen;
03460     int             sdLen;
03461     int             certLen;
03462     int             pid;
03463     int             sent;
03464     int             gotXmitBufLock = 0;
03465 #if defined(SOLARIS) && defined(i386)
03466     volatile PRUint8 hit;
03467 #else
03468     int             hit;
03469 #endif
03470     PRUint8         csImpl[sizeof implementedCipherSuites];
03471 
03472     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
03473 
03474     sc = ss->serverCerts + kt_rsa;
03475     serverCert = sc->serverCert;
03476 
03477     ssl_GetRecvBufLock(ss);
03478 
03479 
03480     data = ss->gs.buf.buf + ss->gs.recordOffset;
03481     DUMP_MSG(29, (ss, data, ss->gs.recordLen));
03482 
03483     /* Make sure first message has some data and is the client hello message */
03484     if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
03485        || (data[0] != SSL_MT_CLIENT_HELLO)) {
03486        goto bad_client;
03487     }
03488 
03489     /* Get peer name of client */
03490     rv = ssl_GetPeerInfo(ss);
03491     if (rv != SECSuccess) {
03492        goto loser;
03493     }
03494 
03495     /* Examine version information */
03496     /*
03497      * See if this might be a V2 client hello asking to use the V3 protocol
03498      */
03499     if ((data[0] == SSL_MT_CLIENT_HELLO) && 
03500         (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && 
03501        (ss->opt.enableSSL3 || ss->opt.enableTLS)) {
03502        rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
03503        if (rv != SECFailure) { /* Success */
03504            ss->handshake             = NULL;
03505            ss->nextHandshake         = ssl_GatherRecord1stHandshake;
03506            ss->securityHandshake     = NULL;
03507            ss->gs.state              = GS_INIT;
03508 
03509            /* ssl3_HandleV3ClientHello has set ss->version,
03510            ** and has gotten us a brand new sid.  
03511            */
03512            ss->sec.ci.sid->version  = ss->version;
03513        }
03514        ssl_ReleaseRecvBufLock(ss);
03515        return rv;
03516     }
03517     /* Previously, there was a test here to see if SSL2 was enabled.
03518     ** If not, an error code was set, and SECFailure was returned,
03519     ** without sending any error code to the other end of the connection.
03520     ** That test has been removed.  If SSL2 has been disabled, there
03521     ** should be no SSL2 ciphers enabled, and consequently, the code
03522     ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
03523     ** We now believe this is the correct thing to do, even when SSL2
03524     ** has been explicitly disabled by the application.
03525     */
03526 
03527     /* Extract info from message */
03528     ss->version = (data[1] << 8) | data[2];
03529 
03530     /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it.  */
03531     if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
03532        ss->version = SSL_LIBRARY_VERSION_2;
03533     }
03534     
03535     csLen        = (data[3] << 8) | data[4];
03536     sdLen        = (data[5] << 8) | data[6];
03537     challengeLen = (data[7] << 8) | data[8];
03538     cs           = data + SSL_HL_CLIENT_HELLO_HBYTES;
03539     sd           = cs + csLen;
03540     challenge    = sd + sdLen;
03541     PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
03542 
03543     if (!csLen || (csLen % 3) != 0 || 
03544         (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
03545        challengeLen < SSL_MIN_CHALLENGE_BYTES || 
03546        challengeLen > SSL_MAX_CHALLENGE_BYTES ||
03547         (unsigned)ss->gs.recordLen != 
03548             SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
03549        SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
03550                SSL_GETPID(), ss->fd, ss->gs.recordLen,
03551                SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
03552        goto bad_client;
03553     }
03554 
03555     SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
03556               SSL_GETPID(), ss->fd, ss->version));
03557     if (ss->version != SSL_LIBRARY_VERSION_2) {
03558        if (ss->version > SSL_LIBRARY_VERSION_2) {
03559            /*
03560            ** Newer client than us. Things are ok because new clients
03561            ** are required to be backwards compatible with old servers.
03562            ** Change version number to our version number so that client
03563            ** knows whats up.
03564            */
03565            ss->version = SSL_LIBRARY_VERSION_2;
03566        } else {
03567            SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
03568               SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
03569            PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
03570            goto loser;
03571        }
03572     }
03573 
03574     /* Qualify cipher specs before returning them to client */
03575     csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
03576     if (csLen == 0) {
03577        /* no overlap, send client our list of supported SSL v2 ciphers. */
03578         cs    = csImpl;
03579        csLen = sizeof implementedCipherSuites;
03580        PORT_Memcpy(cs, implementedCipherSuites, csLen);
03581        csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
03582        if (csLen == 0) {
03583          /* We don't support any SSL v2 ciphers! */
03584          ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
03585          PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
03586          goto loser;
03587        }
03588        /* Since this handhsake is going to fail, don't cache it. */
03589        ss->opt.noCache = 1; 
03590     }
03591 
03592     /* Squirrel away the challenge for later */
03593     PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);
03594 
03595     /* Examine message and see if session-id is good */
03596     ss->sec.ci.elements = 0;
03597     if (sdLen > 0 && !ss->opt.noCache) {
03598        SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
03599                   SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
03600                   ss->sec.ci.peer.pr_s6_addr32[1], 
03601                   ss->sec.ci.peer.pr_s6_addr32[2],
03602                   ss->sec.ci.peer.pr_s6_addr32[3]));
03603        sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
03604     } else {
03605        sid = NULL;
03606     }
03607     if (sid) {
03608        /* Got a good session-id. Short cut! */
03609        SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
03610                   SSL_GETPID(), ss->fd, ss->sec.ci.peer, 
03611                   ssl_Time() - sid->creationTime));
03612        PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
03613        ss->sec.ci.sid = sid;
03614        ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
03615        hit = 1;
03616        certLen = 0;
03617        csLen = 0;
03618 
03619         ss->sec.authAlgorithm = sid->authAlgorithm;
03620        ss->sec.authKeyBits   = sid->authKeyBits;
03621        ss->sec.keaType       = sid->keaType;
03622        ss->sec.keaKeyBits    = sid->keaKeyBits;
03623 
03624        rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
03625        if (rv != SECSuccess) {
03626            goto loser;
03627        }
03628     } else {
03629        SECItem * derCert   = &serverCert->derCert;
03630 
03631        SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
03632                   SSL_GETPID(), ss->fd));
03633        if (!serverCert) {
03634            SET_ERROR_CODE
03635            goto loser;
03636        }
03637        hit = 0;
03638        sid = (sslSessionID*) PORT_ZAlloc(sizeof(sslSessionID));
03639        if (!sid) {
03640            goto loser;
03641        }
03642        sid->references = 1;
03643        sid->addr = ss->sec.ci.peer;
03644        sid->port = ss->sec.ci.port;
03645 
03646        /* Invent a session-id */
03647        ss->sec.ci.sid = sid;
03648        PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2);
03649 
03650        pid = SSL_GETPID();
03651        sid->u.ssl2.sessionID[0] = MSB(pid);
03652        sid->u.ssl2.sessionID[1] = LSB(pid);
03653        cert    = derCert->data;
03654        certLen = derCert->len;
03655 
03656        /* pretend that server sids remember the local cert. */
03657        PORT_Assert(!sid->localCert);
03658        if (sid->localCert) {
03659            CERT_DestroyCertificate(sid->localCert);
03660        }
03661        sid->localCert     = CERT_DupCertificate(serverCert);
03662 
03663        ss->sec.authAlgorithm = ssl_sign_rsa;
03664        ss->sec.keaType       = ssl_kea_rsa;
03665        ss->sec.keaKeyBits    = \
03666        ss->sec.authKeyBits   = ss->serverCerts[kt_rsa].serverKeyBits;
03667     }
03668 
03669     /* server sids don't remember the local cert, so whether we found
03670     ** a sid or not, just "remember" we used the rsa server cert.
03671     */
03672     if (ss->sec.localCert) {
03673        CERT_DestroyCertificate(ss->sec.localCert);
03674     }
03675     ss->sec.localCert     = CERT_DupCertificate(serverCert);
03676 
03677     /* Build up final list of required elements */
03678     ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
03679     if (ss->opt.requestCertificate) {
03680        ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
03681     }
03682     ss->sec.ci.sentElements = 0;
03683 
03684     /* Send hello message back to client */
03685     sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
03686            + SSL_CONNECTIONID_BYTES;
03687 
03688     ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
03689     rv = ssl2_GetSendBuffer(ss, sendLen);
03690     if (rv != SECSuccess) {
03691        goto loser;
03692     }
03693 
03694     SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
03695               SSL_GETPID(), ss->fd, sendLen));
03696 
03697     msg = ss->sec.ci.sendBuf.buf;
03698     msg[0] = SSL_MT_SERVER_HELLO;
03699     msg[1] = hit;
03700     msg[2] = SSL_CT_X509_CERTIFICATE;
03701     msg[3] = MSB(ss->version);
03702     msg[4] = LSB(ss->version);
03703     msg[5] = MSB(certLen);
03704     msg[6] = LSB(certLen);
03705     msg[7] = MSB(csLen);
03706     msg[8] = LSB(csLen);
03707     msg[9] = MSB(SSL_CONNECTIONID_BYTES);
03708     msg[10] = LSB(SSL_CONNECTIONID_BYTES);
03709     if (certLen) {
03710        PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
03711     }
03712     if (csLen) {
03713        PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
03714     }
03715     PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, 
03716                 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);
03717 
03718     DUMP_MSG(29, (ss, msg, sendLen));
03719 
03720     ss->handshakeBegun = 1;
03721     sent = (*ss->sec.send)(ss, msg, sendLen, 0);
03722     if (sent < 0) {
03723        goto loser;
03724     }
03725     ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
03726 
03727     ss->gs.recordLen = 0;
03728     ss->handshake = ssl_GatherRecord1stHandshake;
03729     if (hit) {
03730        /* Old SID Session key is good. Go encrypted */
03731        ssl2_UseEncryptedSendFunc(ss);
03732 
03733        /* Send server verify message now that keys are established */
03734        rv = ssl2_SendServerVerifyMessage(ss);
03735        if (rv != SECSuccess) 
03736            goto loser;
03737 
03738        ss->nextHandshake = ssl2_HandleMessage;
03739        ssl_ReleaseRecvBufLock(ss);
03740        rv = ssl2_TriggerNextMessage(ss);
03741        return rv;
03742     }
03743     ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
03744     ssl_ReleaseRecvBufLock(ss);
03745     return SECSuccess;
03746 
03747   bad_client:
03748     PORT_SetError(SSL_ERROR_BAD_CLIENT);
03749     /* FALLTHROUGH */
03750 
03751   loser:
03752     if (gotXmitBufLock) {
03753        ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
03754     }
03755     SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
03756                SSL_GETPID(), ss->fd));
03757     ssl_ReleaseRecvBufLock(ss);
03758     return SECFailure;
03759 }
03760 
03761 SECStatus
03762 ssl2_BeginServerHandshake(sslSocket *ss)
03763 {
03764     SECStatus        rv;
03765     sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;
03766 
03767     ss->sec.isServer = 1;
03768     ssl_ChooseSessionIDProcs(&ss->sec);
03769     ss->sec.sendSequence = 0;
03770     ss->sec.rcvSequence = 0;
03771 
03772     /* don't turn on SSL2 if we don't have an RSA key and cert */
03773     if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || 
03774         !rsaAuth->serverCert) {
03775        ss->opt.enableSSL2 = PR_FALSE;
03776     }
03777 
03778     if (!ss->cipherSpecs) {
03779        rv = ssl2_ConstructCipherSpecs(ss);
03780        if (rv != SECSuccess)
03781            goto loser;
03782     }
03783 
03784     /* count the SSL2 and SSL3 enabled ciphers.
03785      * if either is zero, clear the socket's enable for that protocol.
03786      */
03787     rv = ssl2_CheckConfigSanity(ss);
03788     if (rv != SECSuccess)
03789        goto loser;
03790 
03791     /*
03792     ** Generate connection-id. Always do this, even if things fail
03793     ** immediately. This way the random number generator is always
03794     ** rolling around, every time we get a connection.
03795     */
03796     PK11_GenerateRandom(ss->sec.ci.connectionID, 
03797                         sizeof(ss->sec.ci.connectionID));
03798 
03799     ss->gs.recordLen = 0;
03800     ss->handshake     = ssl_GatherRecord1stHandshake;
03801     ss->nextHandshake = ssl2_HandleClientHelloMessage;
03802     return SECSuccess;
03803 
03804 loser:
03805     return SECFailure;
03806 }
03807 
03808 /* This function doesn't really belong in this file.
03809 ** It's here to keep AIX compilers from optimizing it away, 
03810 ** and not including it in the DSO.
03811 */
03812 
03813 #include "nss.h"
03814 extern const char __nss_ssl_rcsid[];
03815 extern const char __nss_ssl_sccsid[];
03816 
03817 PRBool
03818 NSSSSL_VersionCheck(const char *importedVersion)
03819 {
03820     /*
03821      * This is the secret handshake algorithm.
03822      *
03823      * This release has a simple version compatibility
03824      * check algorithm.  This release is not backward
03825      * compatible with previous major releases.  It is
03826      * not compatible with future major, minor, or
03827      * patch releases.
03828      */
03829     volatile char c; /* force a reference that won't get optimized away */
03830 
03831     c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; 
03832     return NSS_VersionCheck(importedVersion);
03833 }