Back to index

lightning-sunbird  0.9+nobinonly
sslsock.c
Go to the documentation of this file.
00001 /*
00002  * vtables (and methods that call through them) for the 4 types of 
00003  * SSLSockets supported.  Only one type is still supported.
00004  * Various other functions.
00005  *
00006  * ***** BEGIN LICENSE BLOCK *****
00007  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00008  *
00009  * The contents of this file are subject to the Mozilla Public License Version
00010  * 1.1 (the "License"); you may not use this file except in compliance with
00011  * the License. You may obtain a copy of the License at
00012  * http://www.mozilla.org/MPL/
00013  *
00014  * Software distributed under the License is distributed on an "AS IS" basis,
00015  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00016  * for the specific language governing rights and limitations under the
00017  * License.
00018  *
00019  * The Original Code is the Netscape security libraries.
00020  *
00021  * The Initial Developer of the Original Code is
00022  * Netscape Communications Corporation.
00023  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00024  * the Initial Developer. All Rights Reserved.
00025  *
00026  * Contributor(s):
00027  *   Dr Stephen Henson <stephen.henson@gemplus.com>
00028  *   Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
00029  *
00030  * Alternatively, the contents of this file may be used under the terms of
00031  * either the GNU General Public License Version 2 or later (the "GPL"), or
00032  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00033  * in which case the provisions of the GPL or the LGPL are applicable instead
00034  * of those above. If you wish to allow use of your version of this file only
00035  * under the terms of either the GPL or the LGPL, and not to allow others to
00036  * use your version of this file under the terms of the MPL, indicate your
00037  * decision by deleting the provisions above and replace them with the notice
00038  * and other provisions required by the GPL or the LGPL. If you do not delete
00039  * the provisions above, a recipient may use your version of this file under
00040  * the terms of any one of the MPL, the GPL or the LGPL.
00041  *
00042  * ***** END LICENSE BLOCK ***** */
00043 /* $Id: sslsock.c,v 1.44.2.6 2006/10/02 21:17:59 julien.pierre.bugs%sun.com Exp $ */
00044 #include "seccomon.h"
00045 #include "cert.h"
00046 #include "keyhi.h"
00047 #include "ssl.h"
00048 #include "sslimpl.h"
00049 #include "sslproto.h"
00050 #include "nspr.h"
00051 #include "private/pprio.h"
00052 #include "blapi.h"
00053 #include "nss.h"
00054 
00055 #define SET_ERROR_CODE   /* reminder */
00056 
00057 struct cipherPolicyStr {
00058        int           cipher;
00059        unsigned char        export;       /* policy value for export policy */
00060        unsigned char        france;       /* policy value for france policy */
00061 };
00062 
00063 typedef struct cipherPolicyStr cipherPolicy;
00064 
00065 /* This table contains two preconfigured policies: Export and France.
00066 ** It is used only by the functions SSL_SetDomesticPolicy, 
00067 ** SSL_SetExportPolicy, and SSL_SetFrancyPolicy.
00068 ** Order of entries is not important.
00069 */
00070 static cipherPolicy ssl_ciphers[] = {        /*   Export           France   */
00071  {  SSL_EN_RC4_128_WITH_MD5,                  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00072  {  SSL_EN_RC4_128_EXPORT40_WITH_MD5,         SSL_ALLOWED,     SSL_ALLOWED },
00073  {  SSL_EN_RC2_128_CBC_WITH_MD5,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00074  {  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,   SSL_ALLOWED,     SSL_ALLOWED },
00075  {  SSL_EN_DES_64_CBC_WITH_MD5,               SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00076  {  SSL_EN_DES_192_EDE3_CBC_WITH_MD5,         SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00077  {  SSL_RSA_WITH_RC4_128_MD5,                 SSL_RESTRICTED,  SSL_NOT_ALLOWED },
00078  {  SSL_RSA_WITH_RC4_128_SHA,                 SSL_RESTRICTED,  SSL_NOT_ALLOWED },
00079  {  SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00080  {  SSL_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_RESTRICTED,  SSL_NOT_ALLOWED },
00081  {  SSL_RSA_FIPS_WITH_DES_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00082  {  SSL_RSA_WITH_DES_CBC_SHA,                 SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00083  {  SSL_RSA_EXPORT_WITH_RC4_40_MD5,           SSL_ALLOWED,     SSL_ALLOWED },
00084  {  SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,       SSL_ALLOWED,     SSL_ALLOWED },
00085  {  SSL_DHE_RSA_WITH_DES_CBC_SHA,           SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00086  {  SSL_DHE_DSS_WITH_DES_CBC_SHA,           SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00087  {  SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00088  {  SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00089  {  TLS_DHE_DSS_WITH_RC4_128_SHA,           SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00090  {  SSL_RSA_WITH_NULL_SHA,             SSL_ALLOWED,     SSL_ALLOWED },
00091  {  SSL_RSA_WITH_NULL_MD5,             SSL_ALLOWED,     SSL_ALLOWED },
00092  {  TLS_DHE_DSS_WITH_AES_128_CBC_SHA,         SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00093  {  TLS_DHE_RSA_WITH_AES_128_CBC_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00094  {  TLS_RSA_WITH_AES_128_CBC_SHA,             SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00095  {  TLS_DHE_DSS_WITH_AES_256_CBC_SHA,         SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00096  {  TLS_DHE_RSA_WITH_AES_256_CBC_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00097  {  TLS_RSA_WITH_AES_256_CBC_SHA,             SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00098  {  TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,    SSL_ALLOWED,     SSL_NOT_ALLOWED },
00099  {  TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,     SSL_ALLOWED,     SSL_NOT_ALLOWED },
00100 #ifdef NSS_ENABLE_ECC
00101  {  TLS_ECDH_ECDSA_WITH_NULL_SHA,           SSL_ALLOWED,     SSL_ALLOWED },
00102  {  TLS_ECDH_ECDSA_WITH_RC4_128_SHA,        SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00103  {  TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,   SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00104  {  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00105  {  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00106  {  TLS_ECDHE_ECDSA_WITH_NULL_SHA,          SSL_ALLOWED,     SSL_ALLOWED },
00107  {  TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00108  {  TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00109  {  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,   SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00110  {  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,   SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00111  {  TLS_ECDH_RSA_WITH_NULL_SHA,             SSL_ALLOWED,     SSL_ALLOWED },
00112  {  TLS_ECDH_RSA_WITH_RC4_128_SHA,          SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00113  {  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00114  {  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00115  {  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00116  {  TLS_ECDHE_RSA_WITH_NULL_SHA,            SSL_ALLOWED,     SSL_ALLOWED },
00117  {  TLS_ECDHE_RSA_WITH_RC4_128_SHA,         SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00118  {  TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00119  {  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00120  {  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
00121 #endif /* NSS_ENABLE_ECC */
00122  {  0,                                 SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }
00123 };
00124 
00125 static const sslSocketOps ssl_default_ops = {    /* No SSL. */
00126     ssl_DefConnect,
00127     NULL,
00128     ssl_DefBind,
00129     ssl_DefListen,
00130     ssl_DefShutdown,
00131     ssl_DefClose,
00132     ssl_DefRecv,
00133     ssl_DefSend,
00134     ssl_DefRead,
00135     ssl_DefWrite,
00136     ssl_DefGetpeername,
00137     ssl_DefGetsockname
00138 };
00139 
00140 static const sslSocketOps ssl_secure_ops = {     /* SSL. */
00141     ssl_SecureConnect,
00142     NULL,
00143     ssl_DefBind,
00144     ssl_DefListen,
00145     ssl_SecureShutdown,
00146     ssl_SecureClose,
00147     ssl_SecureRecv,
00148     ssl_SecureSend,
00149     ssl_SecureRead,
00150     ssl_SecureWrite,
00151     ssl_DefGetpeername,
00152     ssl_DefGetsockname
00153 };
00154 
00155 /*
00156 ** default settings for socket enables
00157 */
00158 static sslOptions ssl_defaults = {
00159     PR_TRUE,  /* useSecurity        */
00160     PR_FALSE, /* useSocks           */
00161     PR_FALSE, /* requestCertificate */
00162     2,         /* requireCertificate */
00163     PR_FALSE, /* handshakeAsClient  */
00164     PR_FALSE, /* handshakeAsServer  */
00165     PR_TRUE,  /* enableSSL2         */
00166     PR_TRUE,  /* enableSSL3         */
00167     PR_TRUE,  /* enableTLS          */ /* now defaults to on in NSS 3.0 */
00168     PR_FALSE, /* noCache            */
00169     PR_FALSE, /* fdx                */
00170     PR_TRUE,  /* v2CompatibleHello  */
00171     PR_TRUE,  /* detectRollBack     */
00172     PR_FALSE,   /* noStepDown         */
00173     PR_FALSE,   /* bypassPKCS11       */
00174     PR_FALSE,   /* noLocks            */
00175 };
00176 
00177 sslSessionIDLookupFunc  ssl_sid_lookup;
00178 sslSessionIDCacheFunc   ssl_sid_cache;
00179 sslSessionIDUncacheFunc ssl_sid_uncache;
00180 
00181 static PRBool ssl_inited = PR_FALSE;
00182 static PRDescIdentity ssl_layer_id;
00183 
00184 PRBool                  locksEverDisabled;       /* implicitly PR_FALSE */
00185 PRBool               ssl_force_locks;     /* implicitly PR_FALSE */
00186 int                     ssl_lock_readers  = 1;   /* default true. */
00187 char                    ssl_debug;
00188 char                    ssl_trace;
00189 char lockStatus[] = "Locks are ENABLED.  ";
00190 #define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
00191 
00192 /* forward declarations. */
00193 static sslSocket *ssl_NewSocket(PRBool makeLocks);
00194 static SECStatus  ssl_MakeLocks(sslSocket *ss);
00195 static PRStatus   ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, 
00196                                   PRDescIdentity id);
00197 
00198 /************************************************************************/
00199 
00200 /*
00201 ** Lookup a socket structure from a file descriptor.
00202 ** Only functions called through the PRIOMethods table should use this.
00203 ** Other app-callable functions should use ssl_FindSocket.
00204 */
00205 static sslSocket *
00206 ssl_GetPrivate(PRFileDesc *fd)
00207 {
00208     sslSocket *ss;
00209 
00210     PORT_Assert(fd != NULL);
00211     PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
00212     PORT_Assert(fd->identity == ssl_layer_id);
00213 
00214     ss = (sslSocket *)fd->secret;
00215     ss->fd = fd;
00216     return ss;
00217 }
00218 
00219 sslSocket *
00220 ssl_FindSocket(PRFileDesc *fd)
00221 {
00222     PRFileDesc *layer;
00223     sslSocket *ss;
00224 
00225     PORT_Assert(fd != NULL);
00226     PORT_Assert(ssl_layer_id != 0);
00227 
00228     layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
00229     if (layer == NULL) {
00230        PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
00231        return NULL;
00232     }
00233 
00234     ss = (sslSocket *)layer->secret;
00235     ss->fd = layer;
00236     return ss;
00237 }
00238 
00239 sslSocket *
00240 ssl_DupSocket(sslSocket *os)
00241 {
00242     sslSocket *ss;
00243     SECStatus rv;
00244 
00245     ss = ssl_NewSocket((PRBool)(!os->opt.noLocks));
00246     if (ss) {
00247        ss->opt                = os->opt;
00248        ss->opt.useSocks       = PR_FALSE;
00249 
00250        ss->peerID             = !os->peerID ? NULL : PORT_Strdup(os->peerID);
00251        ss->url                = !os->url    ? NULL : PORT_Strdup(os->url);
00252 
00253        ss->ops      = os->ops;
00254        ss->rTimeout = os->rTimeout;
00255        ss->wTimeout = os->wTimeout;
00256        ss->cTimeout = os->cTimeout;
00257        ss->dbHandle = os->dbHandle;
00258 
00259        /* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
00260        ss->allowedByPolicy  = os->allowedByPolicy;
00261        ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
00262        ss->chosenPreference        = os->chosenPreference;
00263        PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
00264 
00265        if (os->cipherSpecs) {
00266            ss->cipherSpecs  = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
00267            if (ss->cipherSpecs) 
00268               PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs, 
00269                           os->sizeCipherSpecs);
00270            ss->sizeCipherSpecs    = os->sizeCipherSpecs;
00271            ss->preferredCipher    = os->preferredCipher;
00272        } else {
00273            ss->cipherSpecs        = NULL;  /* produced lazily */
00274            ss->sizeCipherSpecs    = 0;
00275            ss->preferredCipher    = NULL;
00276        }
00277        if (ss->opt.useSecurity) {
00278            /* This int should be SSLKEAType, but CC on Irix complains,
00279             * during the for loop.
00280             */
00281            int i;
00282            sslServerCerts * oc = os->serverCerts;
00283            sslServerCerts * sc = ss->serverCerts;
00284 
00285            for (i=kt_null; i < kt_kea_size; i++, oc++, sc++) {
00286               if (oc->serverCert && oc->serverCertChain) {
00287                   sc->serverCert      = CERT_DupCertificate(oc->serverCert);
00288                   sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
00289                   if (!sc->serverCertChain) 
00290                      goto loser;
00291               } else {
00292                   sc->serverCert      = NULL;
00293                   sc->serverCertChain = NULL;
00294               }
00295               sc->serverKeyPair = oc->serverKeyPair ?
00296                             ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
00297               if (oc->serverKeyPair && !sc->serverKeyPair)
00298                   goto loser;
00299                sc->serverKeyBits = oc->serverKeyBits;
00300            }
00301            ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
00302                                 ssl3_GetKeyPairRef(os->stepDownKeyPair);
00303            ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
00304                                 ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
00305 /*
00306  * XXX the preceeding CERT_ and SECKEY_ functions can fail and return NULL.
00307  * XXX We should detect this, and not just march on with NULL pointers.
00308  */
00309            ss->authCertificate       = os->authCertificate;
00310            ss->authCertificateArg    = os->authCertificateArg;
00311            ss->getClientAuthData     = os->getClientAuthData;
00312            ss->getClientAuthDataArg  = os->getClientAuthDataArg;
00313            ss->handleBadCert         = os->handleBadCert;
00314            ss->badCertArg            = os->badCertArg;
00315            ss->handshakeCallback     = os->handshakeCallback;
00316            ss->handshakeCallbackData = os->handshakeCallbackData;
00317            ss->pkcs11PinArg          = os->pkcs11PinArg;
00318     
00319            /* Create security data */
00320            rv = ssl_CopySecurityInfo(ss, os);
00321            if (rv != SECSuccess) {
00322               goto loser;
00323            }
00324        }
00325     }
00326     return ss;
00327 
00328 loser:
00329     ssl_FreeSocket(ss);
00330     return NULL;
00331 }
00332 
00333 static void
00334 ssl_DestroyLocks(sslSocket *ss)
00335 {
00336     /* Destroy locks. */
00337     if (ss->firstHandshakeLock) {
00338        PZ_DestroyMonitor(ss->firstHandshakeLock);
00339        ss->firstHandshakeLock = NULL;
00340     }
00341     if (ss->ssl3HandshakeLock) {
00342        PZ_DestroyMonitor(ss->ssl3HandshakeLock);
00343        ss->ssl3HandshakeLock = NULL;
00344     }
00345     if (ss->specLock) {
00346        NSSRWLock_Destroy(ss->specLock);
00347        ss->specLock = NULL;
00348     }
00349 
00350     if (ss->recvLock) {
00351        PZ_DestroyLock(ss->recvLock);
00352        ss->recvLock = NULL;
00353     }
00354     if (ss->sendLock) {
00355        PZ_DestroyLock(ss->sendLock);
00356        ss->sendLock = NULL;
00357     }
00358     if (ss->xmitBufLock) {
00359        PZ_DestroyMonitor(ss->xmitBufLock);
00360        ss->xmitBufLock = NULL;
00361     }
00362     if (ss->recvBufLock) {
00363        PZ_DestroyMonitor(ss->recvBufLock);
00364        ss->recvBufLock = NULL;
00365     }
00366 }
00367 
00368 /* Caller holds any relevant locks */
00369 static void
00370 ssl_DestroySocketContents(sslSocket *ss)
00371 {
00372     /* "i" should be of type SSLKEAType, but CC on IRIX complains during
00373      * the for loop.
00374      */
00375     int        i;
00376 
00377     /* Free up socket */
00378     ssl_DestroySecurityInfo(&ss->sec);
00379 
00380     ssl3_DestroySSL3Info(ss);
00381 
00382     PORT_Free(ss->saveBuf.buf);
00383     PORT_Free(ss->pendingBuf.buf);
00384     ssl_DestroyGather(&ss->gs);
00385 
00386     if (ss->peerID != NULL)
00387        PORT_Free(ss->peerID);
00388     if (ss->url != NULL)
00389        PORT_Free((void *)ss->url); /* CONST */
00390     if (ss->cipherSpecs) {
00391        PORT_Free(ss->cipherSpecs);
00392        ss->cipherSpecs     = NULL;
00393        ss->sizeCipherSpecs = 0;
00394     }
00395 
00396     /* Clean up server configuration */
00397     for (i=kt_null; i < kt_kea_size; i++) {
00398        sslServerCerts * sc = ss->serverCerts + i;
00399        if (sc->serverCert != NULL)
00400            CERT_DestroyCertificate(sc->serverCert);
00401        if (sc->serverCertChain != NULL)
00402            CERT_DestroyCertificateList(sc->serverCertChain);
00403        if (sc->serverKeyPair != NULL)
00404            ssl3_FreeKeyPair(sc->serverKeyPair);
00405     }
00406     if (ss->stepDownKeyPair) {
00407        ssl3_FreeKeyPair(ss->stepDownKeyPair);
00408        ss->stepDownKeyPair = NULL;
00409     }
00410     if (ss->ephemeralECDHKeyPair) {
00411        ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
00412        ss->ephemeralECDHKeyPair = NULL;
00413     }
00414 }
00415 
00416 /*
00417  * free an sslSocket struct, and all the stuff that hangs off of it
00418  */
00419 void
00420 ssl_FreeSocket(sslSocket *ss)
00421 {
00422 #ifdef DEBUG
00423     sslSocket *fs;
00424     sslSocket  lSock;
00425 #endif
00426 
00427 /* Get every lock you can imagine!
00428 ** Caller already holds these:
00429 **  SSL_LOCK_READER(ss);
00430 **  SSL_LOCK_WRITER(ss);
00431 */
00432     ssl_Get1stHandshakeLock(ss);
00433     ssl_GetRecvBufLock(ss);
00434     ssl_GetSSL3HandshakeLock(ss);
00435     ssl_GetXmitBufLock(ss);
00436     ssl_GetSpecWriteLock(ss);
00437 
00438 #ifdef DEBUG
00439     fs = &lSock;
00440     *fs = *ss;                            /* Copy the old socket structure, */
00441     PORT_Memset(ss, 0x1f, sizeof *ss);  /* then blast the old struct ASAP. */
00442 #else
00443 #define fs ss
00444 #endif
00445 
00446     ssl_DestroySocketContents(fs);
00447 
00448     /* Release all the locks acquired above.  */
00449     SSL_UNLOCK_READER(fs);
00450     SSL_UNLOCK_WRITER(fs);
00451     ssl_Release1stHandshakeLock(fs);
00452     ssl_ReleaseRecvBufLock(fs);
00453     ssl_ReleaseSSL3HandshakeLock(fs);
00454     ssl_ReleaseXmitBufLock(fs);
00455     ssl_ReleaseSpecWriteLock(fs);
00456 
00457     ssl_DestroyLocks(fs);
00458 
00459     PORT_Free(ss);   /* free the caller's copy, not ours. */
00460     return;
00461 }
00462 #undef fs
00463 
00464 /************************************************************************/
00465 SECStatus 
00466 ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
00467 {
00468     PRFileDesc *       osfd = ss->fd->lower;
00469     SECStatus         rv = SECFailure;
00470     PRSocketOptionData opt;
00471 
00472     opt.option         = PR_SockOpt_NoDelay;
00473     opt.value.no_delay = (PRBool)!enabled;
00474 
00475     if (osfd->methods->setsocketoption) {
00476         rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
00477     } else {
00478         PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
00479     }
00480 
00481     return rv;
00482 }
00483 
00484 static void
00485 ssl_ChooseOps(sslSocket *ss)
00486 {
00487     ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
00488 }
00489 
00490 /* Called from SSL_Enable (immediately below) */
00491 static SECStatus
00492 PrepareSocket(sslSocket *ss)
00493 {
00494     SECStatus     rv = SECSuccess;
00495 
00496     ssl_ChooseOps(ss);
00497     return rv;
00498 }
00499 
00500 SECStatus
00501 SSL_Enable(PRFileDesc *fd, int which, PRBool on)
00502 {
00503     return SSL_OptionSet(fd, which, on);
00504 }
00505 
00506 static const PRCallOnceType pristineCallOnce;
00507 static PRCallOnceType setupBypassOnce;
00508 
00509 static SECStatus SSL_BypassShutdown(void* appData, void* nssData)
00510 {
00511     /* unload freeBL shared library from memory */
00512     BL_Unload();
00513     setupBypassOnce = pristineCallOnce;
00514     return SECSuccess;
00515 }
00516 
00517 static PRStatus SSL_BypassRegisterShutdown(void)
00518 {
00519     SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL);
00520     PORT_Assert(SECSuccess == rv);
00521     return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE;
00522 }
00523 
00524 static PRStatus SSL_BypassSetup(void)
00525 {
00526     return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown);
00527 }
00528 
00529 SECStatus
00530 SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
00531 {
00532     sslSocket *ss = ssl_FindSocket(fd);
00533     SECStatus  rv = SECSuccess;
00534     PRBool     holdingLocks;
00535 
00536     if (!ss) {
00537        SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
00538        return SECFailure;
00539     }
00540 
00541     holdingLocks = (!ss->opt.noLocks);
00542     ssl_Get1stHandshakeLock(ss);
00543     ssl_GetSSL3HandshakeLock(ss);
00544 
00545     switch (which) {
00546       case SSL_SOCKS:
00547        ss->opt.useSocks = PR_FALSE;
00548        rv = PrepareSocket(ss);
00549        if (on) {
00550            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00551            rv = SECFailure;
00552        }
00553        break;
00554 
00555       case SSL_SECURITY:
00556        ss->opt.useSecurity = on;
00557        rv = PrepareSocket(ss);
00558        break;
00559 
00560       case SSL_REQUEST_CERTIFICATE:
00561        ss->opt.requestCertificate = on;
00562        break;
00563 
00564       case SSL_REQUIRE_CERTIFICATE:
00565        ss->opt.requireCertificate = on;
00566        break;
00567 
00568       case SSL_HANDSHAKE_AS_CLIENT:
00569        if ( ss->opt.handshakeAsServer && on ) {
00570            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00571            rv = SECFailure;
00572            break;
00573        }
00574        ss->opt.handshakeAsClient = on;
00575        break;
00576 
00577       case SSL_HANDSHAKE_AS_SERVER:
00578        if ( ss->opt.handshakeAsClient && on ) {
00579            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00580            rv = SECFailure;
00581            break;
00582        }
00583        ss->opt.handshakeAsServer = on;
00584        break;
00585 
00586       case SSL_ENABLE_TLS:
00587        ss->opt.enableTLS       = on;
00588        ss->preferredCipher     = NULL;
00589        if (ss->cipherSpecs) {
00590            PORT_Free(ss->cipherSpecs);
00591            ss->cipherSpecs     = NULL;
00592            ss->sizeCipherSpecs = 0;
00593        }
00594        break;
00595 
00596       case SSL_ENABLE_SSL3:
00597        ss->opt.enableSSL3      = on;
00598        ss->preferredCipher     = NULL;
00599        if (ss->cipherSpecs) {
00600            PORT_Free(ss->cipherSpecs);
00601            ss->cipherSpecs     = NULL;
00602            ss->sizeCipherSpecs = 0;
00603        }
00604        break;
00605 
00606       case SSL_ENABLE_SSL2:
00607        ss->opt.enableSSL2       = on;
00608        if (on) {
00609            ss->opt.v2CompatibleHello = on;
00610        }
00611        ss->preferredCipher     = NULL;
00612        if (ss->cipherSpecs) {
00613            PORT_Free(ss->cipherSpecs);
00614            ss->cipherSpecs     = NULL;
00615            ss->sizeCipherSpecs = 0;
00616        }
00617        break;
00618 
00619       case SSL_NO_CACHE:
00620        ss->opt.noCache = on;
00621        break;
00622 
00623       case SSL_ENABLE_FDX:
00624        if (on && ss->opt.noLocks) {
00625            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00626            rv = SECFailure;
00627        }
00628        ss->opt.fdx = on;
00629        break;
00630 
00631       case SSL_V2_COMPATIBLE_HELLO:
00632        ss->opt.v2CompatibleHello = on;
00633        if (!on) {
00634            ss->opt.enableSSL2    = on;
00635        }
00636        break;
00637 
00638       case SSL_ROLLBACK_DETECTION:  
00639        ss->opt.detectRollBack = on;
00640         break;
00641 
00642       case SSL_NO_STEP_DOWN:        
00643        ss->opt.noStepDown     = on;         
00644        if (on) 
00645            SSL_DisableExportCipherSuites(fd);
00646        break;
00647 
00648       case SSL_BYPASS_PKCS11:
00649        if (ss->handshakeBegun) {
00650            PORT_SetError(PR_INVALID_STATE_ERROR);
00651            rv = SECFailure;
00652        } else {
00653             if (PR_FALSE != on) {
00654                 if (PR_SUCCESS == SSL_BypassSetup() ) {
00655                     ss->opt.bypassPKCS11   = on;
00656                 } else {
00657                     rv = SECFailure;
00658                 }
00659             } else {
00660                 ss->opt.bypassPKCS11   = PR_FALSE;
00661             }
00662        }
00663        break;
00664 
00665       case SSL_NO_LOCKS:
00666        if (on && ss->opt.fdx) {
00667            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00668            rv = SECFailure;
00669        }
00670        if (on && ssl_force_locks) 
00671            on = PR_FALSE;   /* silent override */
00672        ss->opt.noLocks   = on;
00673        if (on) {
00674            locksEverDisabled = PR_TRUE;
00675            strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
00676        } else if (!holdingLocks) {
00677            rv = ssl_MakeLocks(ss);
00678            if (rv != SECSuccess) {
00679               ss->opt.noLocks   = PR_TRUE;
00680            }
00681        }
00682        break;
00683 
00684       default:
00685        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00686        rv = SECFailure;
00687     }
00688 
00689     /* We can't use the macros for releasing the locks here,
00690      * because ss->opt.noLocks might have changed just above.
00691      * We must release these locks (monitors) here, if we aquired them above,
00692      * regardless of the current value of ss->opt.noLocks.
00693      */
00694     if (holdingLocks) {
00695        PZ_ExitMonitor((ss)->ssl3HandshakeLock);
00696        PZ_ExitMonitor((ss)->firstHandshakeLock);
00697     }
00698 
00699     return rv;
00700 }
00701 
00702 SECStatus
00703 SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
00704 {
00705     sslSocket *ss = ssl_FindSocket(fd);
00706     SECStatus  rv = SECSuccess;
00707     PRBool     on = PR_FALSE;
00708 
00709     if (!pOn) {
00710        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00711        return SECFailure;
00712     }
00713     if (!ss) {
00714        SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
00715        *pOn = PR_FALSE;
00716        return SECFailure;
00717     }
00718 
00719     ssl_Get1stHandshakeLock(ss);
00720     ssl_GetSSL3HandshakeLock(ss);
00721 
00722     switch (which) {
00723     case SSL_SOCKS:               on = PR_FALSE;               break;
00724     case SSL_SECURITY:            on = ss->opt.useSecurity;        break;
00725     case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
00726     case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
00727     case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient;  break;
00728     case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer;  break;
00729     case SSL_ENABLE_TLS:          on = ss->opt.enableTLS;          break;
00730     case SSL_ENABLE_SSL3:         on = ss->opt.enableSSL3;         break;
00731     case SSL_ENABLE_SSL2:         on = ss->opt.enableSSL2;         break;
00732     case SSL_NO_CACHE:            on = ss->opt.noCache;            break;
00733     case SSL_ENABLE_FDX:          on = ss->opt.fdx;                break;
00734     case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello;  break;
00735     case SSL_ROLLBACK_DETECTION:  on = ss->opt.detectRollBack;     break;
00736     case SSL_NO_STEP_DOWN:        on = ss->opt.noStepDown;         break;
00737     case SSL_BYPASS_PKCS11:       on = ss->opt.bypassPKCS11;       break;
00738     case SSL_NO_LOCKS:            on = ss->opt.noLocks;            break;
00739 
00740     default:
00741        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00742        rv = SECFailure;
00743     }
00744 
00745     ssl_ReleaseSSL3HandshakeLock(ss);
00746     ssl_Release1stHandshakeLock(ss);
00747 
00748     *pOn = on;
00749     return rv;
00750 }
00751 
00752 SECStatus
00753 SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
00754 {
00755     SECStatus  rv = SECSuccess;
00756     PRBool     on = PR_FALSE;
00757 
00758     if (!pOn) {
00759        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00760        return SECFailure;
00761     }
00762 
00763     switch (which) {
00764     case SSL_SOCKS:               on = PR_FALSE;                        break;
00765     case SSL_SECURITY:            on = ssl_defaults.useSecurity;        break;
00766     case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
00767     case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
00768     case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient;  break;
00769     case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer;  break;
00770     case SSL_ENABLE_TLS:          on = ssl_defaults.enableTLS;          break;
00771     case SSL_ENABLE_SSL3:         on = ssl_defaults.enableSSL3;         break;
00772     case SSL_ENABLE_SSL2:         on = ssl_defaults.enableSSL2;         break;
00773     case SSL_NO_CACHE:            on = ssl_defaults.noCache;          break;
00774     case SSL_ENABLE_FDX:          on = ssl_defaults.fdx;                break;
00775     case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello;  break;
00776     case SSL_ROLLBACK_DETECTION:  on = ssl_defaults.detectRollBack;     break;
00777     case SSL_NO_STEP_DOWN:        on = ssl_defaults.noStepDown;         break;
00778     case SSL_BYPASS_PKCS11:       on = ssl_defaults.bypassPKCS11;       break;
00779     case SSL_NO_LOCKS:            on = ssl_defaults.noLocks;            break;
00780 
00781     default:
00782        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00783        rv = SECFailure;
00784     }
00785 
00786     *pOn = on;
00787     return rv;
00788 }
00789 
00790 /* XXX Use Global Lock to protect this stuff. */
00791 SECStatus
00792 SSL_EnableDefault(int which, PRBool on)
00793 {
00794     return SSL_OptionSetDefault(which, on);
00795 }
00796 
00797 SECStatus
00798 SSL_OptionSetDefault(PRInt32 which, PRBool on)
00799 {
00800     switch (which) {
00801       case SSL_SOCKS:
00802        ssl_defaults.useSocks = PR_FALSE;
00803        if (on) {
00804            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00805            return SECFailure;
00806        }
00807        break;
00808 
00809       case SSL_SECURITY:
00810        ssl_defaults.useSecurity = on;
00811        break;
00812 
00813       case SSL_REQUEST_CERTIFICATE:
00814        ssl_defaults.requestCertificate = on;
00815        break;
00816 
00817       case SSL_REQUIRE_CERTIFICATE:
00818        ssl_defaults.requireCertificate = on;
00819        break;
00820 
00821       case SSL_HANDSHAKE_AS_CLIENT:
00822        if ( ssl_defaults.handshakeAsServer && on ) {
00823            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00824            return SECFailure;
00825        }
00826        ssl_defaults.handshakeAsClient = on;
00827        break;
00828 
00829       case SSL_HANDSHAKE_AS_SERVER:
00830        if ( ssl_defaults.handshakeAsClient && on ) {
00831            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00832            return SECFailure;
00833        }
00834        ssl_defaults.handshakeAsServer = on;
00835        break;
00836 
00837       case SSL_ENABLE_TLS:
00838        ssl_defaults.enableTLS = on;
00839        break;
00840 
00841       case SSL_ENABLE_SSL3:
00842        ssl_defaults.enableSSL3 = on;
00843        break;
00844 
00845       case SSL_ENABLE_SSL2:
00846        ssl_defaults.enableSSL2 = on;
00847        if (on) {
00848            ssl_defaults.v2CompatibleHello = on;
00849        }
00850        break;
00851 
00852       case SSL_NO_CACHE:
00853        ssl_defaults.noCache = on;
00854        break;
00855 
00856       case SSL_ENABLE_FDX:
00857        if (on && ssl_defaults.noLocks) {
00858            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00859            return SECFailure;
00860        }
00861        ssl_defaults.fdx = on;
00862        break;
00863 
00864       case SSL_V2_COMPATIBLE_HELLO:
00865        ssl_defaults.v2CompatibleHello = on;
00866        if (!on) {
00867            ssl_defaults.enableSSL2    = on;
00868        }
00869        break;
00870 
00871       case SSL_ROLLBACK_DETECTION:  
00872        ssl_defaults.detectRollBack = on;
00873        break;
00874 
00875       case SSL_NO_STEP_DOWN:        
00876        ssl_defaults.noStepDown     = on;         
00877        if (on)
00878            SSL_DisableDefaultExportCipherSuites();
00879        break;
00880 
00881       case SSL_BYPASS_PKCS11:
00882         if (PR_FALSE != on) {
00883             if (PR_SUCCESS == SSL_BypassSetup()) {
00884                 ssl_defaults.bypassPKCS11   = on;
00885             } else {
00886                 return SECFailure;
00887             }
00888         } else {
00889             ssl_defaults.bypassPKCS11   = PR_FALSE;
00890         }
00891        break;
00892 
00893       case SSL_NO_LOCKS:
00894        if (on && ssl_defaults.fdx) {
00895            PORT_SetError(SEC_ERROR_INVALID_ARGS);
00896            return SECFailure;
00897        }
00898        if (on && ssl_force_locks) 
00899            on = PR_FALSE;          /* silent override */
00900        ssl_defaults.noLocks        = on;
00901        if (on) {
00902            locksEverDisabled = PR_TRUE;
00903            strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
00904        }
00905        break;
00906 
00907       default:
00908        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00909        return SECFailure;
00910     }
00911     return SECSuccess;
00912 }
00913 
00914 /* function tells us if the cipher suite is one that we no longer support. */
00915 static PRBool 
00916 ssl_IsRemovedCipherSuite(PRInt32 suite)
00917 {
00918     switch (suite) {
00919     case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
00920     case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
00921     case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
00922        return PR_TRUE;
00923     default:
00924        return PR_FALSE;
00925     }
00926 }
00927 
00928 /* Part of the public NSS API.
00929  * Since this is a global (not per-socket) setting, we cannot use the
00930  * HandshakeLock to protect this.  Probably want a global lock.
00931  */
00932 SECStatus
00933 SSL_SetPolicy(long which, int policy)
00934 {
00935     if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
00936        /* one of the two old FIPS ciphers */
00937        if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) 
00938            which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
00939        else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
00940            which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
00941     }
00942     if (ssl_IsRemovedCipherSuite(which))
00943        return SECSuccess;
00944     return SSL_CipherPolicySet(which, policy);
00945 }
00946 
00947 SECStatus
00948 SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
00949 {
00950     SECStatus rv;
00951 
00952     if (ssl_IsRemovedCipherSuite(which)) {
00953        rv = SECSuccess;
00954     } else if (SSL_IS_SSL2_CIPHER(which)) {
00955        rv = ssl2_SetPolicy(which, policy);
00956     } else {
00957        rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
00958     }
00959     return rv;
00960 }
00961 
00962 SECStatus
00963 SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
00964 {
00965     SECStatus rv;
00966 
00967     if (!oPolicy) {
00968        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00969        return SECFailure;
00970     }
00971     if (ssl_IsRemovedCipherSuite(which)) {
00972        *oPolicy = SSL_NOT_ALLOWED;
00973        rv = SECSuccess;
00974     } else if (SSL_IS_SSL2_CIPHER(which)) {
00975        rv = ssl2_GetPolicy(which, oPolicy);
00976     } else {
00977        rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
00978     }
00979     return rv;
00980 }
00981 
00982 /* Part of the public NSS API.
00983  * Since this is a global (not per-socket) setting, we cannot use the
00984  * HandshakeLock to protect this.  Probably want a global lock.
00985  * These changes have no effect on any sslSockets already created. 
00986  */
00987 SECStatus
00988 SSL_EnableCipher(long which, PRBool enabled)
00989 {
00990     if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
00991        /* one of the two old FIPS ciphers */
00992        if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) 
00993            which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
00994        else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
00995            which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
00996     }
00997     if (ssl_IsRemovedCipherSuite(which))
00998        return SECSuccess;
00999     return SSL_CipherPrefSetDefault(which, enabled);
01000 }
01001 
01002 SECStatus
01003 SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
01004 {
01005     SECStatus rv;
01006 
01007     if (ssl_IsRemovedCipherSuite(which))
01008        return SECSuccess;
01009     if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
01010        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
01011        return SECFailure;
01012     }
01013     if (SSL_IS_SSL2_CIPHER(which)) {
01014        rv = ssl2_CipherPrefSetDefault(which, enabled);
01015     } else {
01016        rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
01017     }
01018     return rv;
01019 }
01020 
01021 SECStatus 
01022 SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
01023 {
01024     SECStatus  rv;
01025     
01026     if (!enabled) {
01027        PORT_SetError(SEC_ERROR_INVALID_ARGS);
01028        return SECFailure;
01029     }
01030     if (ssl_IsRemovedCipherSuite(which)) {
01031        *enabled = PR_FALSE;
01032        rv = SECSuccess;
01033     } else if (SSL_IS_SSL2_CIPHER(which)) {
01034        rv = ssl2_CipherPrefGetDefault(which, enabled);
01035     } else {
01036        rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
01037     }
01038     return rv;
01039 }
01040 
01041 SECStatus
01042 SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
01043 {
01044     SECStatus rv;
01045     sslSocket *ss = ssl_FindSocket(fd);
01046     
01047     if (!ss) {
01048        SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
01049        return SECFailure;
01050     }
01051     if (ssl_IsRemovedCipherSuite(which))
01052        return SECSuccess;
01053     if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
01054        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
01055        return SECFailure;
01056     }
01057     if (SSL_IS_SSL2_CIPHER(which)) {
01058        rv = ssl2_CipherPrefSet(ss, which, enabled);
01059     } else {
01060        rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
01061     }
01062     return rv;
01063 }
01064 
01065 SECStatus 
01066 SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
01067 {
01068     SECStatus  rv;
01069     sslSocket *ss = ssl_FindSocket(fd);
01070     
01071     if (!enabled) {
01072        PORT_SetError(SEC_ERROR_INVALID_ARGS);
01073        return SECFailure;
01074     }
01075     if (!ss) {
01076        SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
01077        *enabled = PR_FALSE;
01078        return SECFailure;
01079     }
01080     if (ssl_IsRemovedCipherSuite(which)) {
01081        *enabled = PR_FALSE;
01082        rv = SECSuccess;
01083     } else if (SSL_IS_SSL2_CIPHER(which)) {
01084        rv = ssl2_CipherPrefGet(ss, which, enabled);
01085     } else {
01086        rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
01087     }
01088     return rv;
01089 }
01090 
01091 SECStatus
01092 NSS_SetDomesticPolicy(void)
01093 {
01094 #ifndef EXPORT_VERSION
01095     SECStatus      status = SECSuccess;
01096     cipherPolicy * policy;
01097 
01098     for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
01099        status = SSL_SetPolicy(policy->cipher, SSL_ALLOWED);
01100        if (status != SECSuccess)
01101            break;
01102     }
01103     return status;
01104 #else
01105     return NSS_SetExportPolicy();
01106 #endif
01107 }
01108 
01109 SECStatus
01110 NSS_SetExportPolicy(void)
01111 {
01112     SECStatus      status = SECSuccess;
01113     cipherPolicy * policy;
01114 
01115     for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
01116        status = SSL_SetPolicy(policy->cipher, policy->export);
01117        if (status != SECSuccess)
01118            break;
01119     }
01120     return status;
01121 }
01122 
01123 SECStatus
01124 NSS_SetFrancePolicy(void)
01125 {
01126     SECStatus      status = SECSuccess;
01127     cipherPolicy * policy;
01128 
01129     for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
01130        status = SSL_SetPolicy(policy->cipher, policy->france);
01131        if (status != SECSuccess)
01132            break;
01133     }
01134     return status;
01135 }
01136 
01137 
01138 
01139 /* LOCKS ??? XXX */
01140 PRFileDesc *
01141 SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
01142 {
01143     sslSocket * ns = NULL;
01144     PRStatus    rv;
01145     PRNetAddr   addr;
01146 
01147     if (model == NULL) {
01148        /* Just create a default socket if we're given NULL for the model */
01149        ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks));
01150     } else {
01151        sslSocket * ss = ssl_FindSocket(model);
01152        if (ss == NULL) {
01153            SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD", 
01154                     SSL_GETPID(), model));
01155            return NULL;
01156        }
01157        ns = ssl_DupSocket(ss);
01158     }
01159     if (ns == NULL)
01160        return NULL;
01161 
01162     rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
01163     if (rv != PR_SUCCESS) {
01164        ssl_FreeSocket(ns);
01165        SET_ERROR_CODE
01166        return NULL;
01167     }
01168 #ifdef _WIN32
01169     PR_Sleep(PR_INTERVAL_NO_WAIT);     /* workaround NT winsock connect bug. */
01170 #endif
01171     ns = ssl_FindSocket(fd);
01172     PORT_Assert(ns);
01173     if (ns)
01174        ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
01175     return fd;
01176 }
01177 
01178 /************************************************************************/
01179 /* The following functions are the TOP LEVEL SSL functions.
01180 ** They all get called through the NSPRIOMethods table below.
01181 */
01182 
01183 static PRFileDesc * PR_CALLBACK
01184 ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
01185 {
01186     sslSocket  *ss;
01187     sslSocket  *ns   = NULL;
01188     PRFileDesc *newfd       = NULL;
01189     PRFileDesc *osfd;
01190     PRStatus    status;
01191 
01192     ss = ssl_GetPrivate(fd);
01193     if (!ss) {
01194        SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd));
01195        return NULL;
01196     }
01197 
01198     /* IF this is a listen socket, there shouldn't be any I/O going on */
01199     SSL_LOCK_READER(ss);
01200     SSL_LOCK_WRITER(ss);
01201     ssl_Get1stHandshakeLock(ss);
01202     ssl_GetSSL3HandshakeLock(ss);
01203 
01204     ss->cTimeout = timeout;
01205 
01206     osfd = ss->fd->lower;
01207 
01208     /* First accept connection */
01209     newfd = osfd->methods->accept(osfd, sockaddr, timeout);
01210     if (newfd == NULL) {
01211        SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d",
01212                SSL_GETPID(), ss->fd, PORT_GetError()));
01213     } else {
01214        /* Create ssl module */
01215        ns = ssl_DupSocket(ss);
01216     }
01217 
01218     ssl_ReleaseSSL3HandshakeLock(ss);
01219     ssl_Release1stHandshakeLock(ss);
01220     SSL_UNLOCK_WRITER(ss);
01221     SSL_UNLOCK_READER(ss);                /* ss isn't used below here. */
01222 
01223     if (ns == NULL)
01224        goto loser;
01225 
01226     /* push ssl module onto the new socket */
01227     status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER);
01228     if (status != PR_SUCCESS)
01229        goto loser;
01230 
01231     /* Now start server connection handshake with client.
01232     ** Don't need locks here because nobody else has a reference to ns yet.
01233     */
01234     if ( ns->opt.useSecurity ) {
01235        if ( ns->opt.handshakeAsClient ) {
01236            ns->handshake = ssl2_BeginClientHandshake;
01237            ss->handshaking = sslHandshakingAsClient;
01238        } else {
01239            ns->handshake = ssl2_BeginServerHandshake;
01240            ss->handshaking = sslHandshakingAsServer;
01241        }
01242     }
01243     ns->TCPconnected = 1;
01244     return newfd;
01245 
01246 loser:
01247     if (ns != NULL)
01248        ssl_FreeSocket(ns);
01249     if (newfd != NULL)
01250        PR_Close(newfd);
01251     return NULL;
01252 }
01253 
01254 static PRStatus PR_CALLBACK
01255 ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
01256 {
01257     sslSocket *ss;
01258     PRStatus   rv;
01259 
01260     ss = ssl_GetPrivate(fd);
01261     if (!ss) {
01262        SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd));
01263        return PR_FAILURE;
01264     }
01265 
01266     /* IF this is a listen socket, there shouldn't be any I/O going on */
01267     SSL_LOCK_READER(ss);
01268     SSL_LOCK_WRITER(ss);
01269 
01270     ss->cTimeout = timeout;
01271     rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);
01272 #ifdef _WIN32
01273     PR_Sleep(PR_INTERVAL_NO_WAIT);     /* workaround NT winsock connect bug. */
01274 #endif
01275 
01276     SSL_UNLOCK_WRITER(ss);
01277     SSL_UNLOCK_READER(ss);
01278 
01279     return rv;
01280 }
01281 
01282 static PRStatus PR_CALLBACK
01283 ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
01284 {
01285     sslSocket * ss = ssl_GetPrivate(fd);
01286     PRStatus    rv;
01287 
01288     if (!ss) {
01289        SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
01290        return PR_FAILURE;
01291     }
01292     SSL_LOCK_READER(ss);
01293     SSL_LOCK_WRITER(ss);
01294 
01295     rv = (PRStatus)(*ss->ops->bind)(ss, addr);
01296 
01297     SSL_UNLOCK_WRITER(ss);
01298     SSL_UNLOCK_READER(ss);
01299     return rv;
01300 }
01301 
01302 static PRStatus PR_CALLBACK
01303 ssl_Listen(PRFileDesc *fd, PRIntn backlog)
01304 {
01305     sslSocket * ss = ssl_GetPrivate(fd);
01306     PRStatus    rv;
01307 
01308     if (!ss) {
01309        SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
01310        return PR_FAILURE;
01311     }
01312     SSL_LOCK_READER(ss);
01313     SSL_LOCK_WRITER(ss);
01314 
01315     rv = (PRStatus)(*ss->ops->listen)(ss, backlog);
01316 
01317     SSL_UNLOCK_WRITER(ss);
01318     SSL_UNLOCK_READER(ss);
01319     return rv;
01320 }
01321 
01322 static PRStatus PR_CALLBACK
01323 ssl_Shutdown(PRFileDesc *fd, PRIntn how)
01324 {
01325     sslSocket * ss = ssl_GetPrivate(fd);
01326     PRStatus    rv;
01327 
01328     if (!ss) {
01329        SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
01330        return PR_FAILURE;
01331     }
01332     if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
01333        SSL_LOCK_READER(ss);
01334     }
01335     if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
01336        SSL_LOCK_WRITER(ss);
01337     }
01338 
01339     rv = (PRStatus)(*ss->ops->shutdown)(ss, how);
01340 
01341     if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
01342        SSL_UNLOCK_WRITER(ss);
01343     }
01344     if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
01345        SSL_UNLOCK_READER(ss);
01346     }
01347     return rv;
01348 }
01349 
01350 static PRStatus PR_CALLBACK
01351 ssl_Close(PRFileDesc *fd)
01352 {
01353     sslSocket *ss;
01354     PRStatus   rv;
01355 
01356     ss = ssl_GetPrivate(fd);
01357     if (!ss) {
01358        SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd));
01359        return PR_FAILURE;
01360     }
01361 
01362     /* There must not be any I/O going on */
01363     SSL_LOCK_READER(ss);
01364     SSL_LOCK_WRITER(ss);
01365 
01366     /* By the time this function returns, 
01367     ** ss is an invalid pointer, and the locks to which it points have 
01368     ** been unlocked and freed.  So, this is the ONE PLACE in all of SSL
01369     ** where the LOCK calls and the corresponding UNLOCK calls are not in
01370     ** the same function scope.  The unlock calls are in ssl_FreeSocket().
01371     */
01372     rv = (PRStatus)(*ss->ops->close)(ss);
01373 
01374     return rv;
01375 }
01376 
01377 static int PR_CALLBACK
01378 ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
01379         PRIntervalTime timeout)
01380 {
01381     sslSocket *ss;
01382     int        rv;
01383 
01384     ss = ssl_GetPrivate(fd);
01385     if (!ss) {
01386        SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd));
01387        return SECFailure;
01388     }
01389     SSL_LOCK_READER(ss);
01390     ss->rTimeout = timeout;
01391     if (!ss->opt.fdx)
01392        ss->wTimeout = timeout;
01393     rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
01394     SSL_UNLOCK_READER(ss);
01395     return rv;
01396 }
01397 
01398 static int PR_CALLBACK
01399 ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
01400         PRIntervalTime timeout)
01401 {
01402     sslSocket *ss;
01403     int        rv;
01404 
01405     ss = ssl_GetPrivate(fd);
01406     if (!ss) {
01407        SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd));
01408        return SECFailure;
01409     }
01410     SSL_LOCK_WRITER(ss);
01411     ss->wTimeout = timeout;
01412     if (!ss->opt.fdx)
01413        ss->rTimeout = timeout;
01414     rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
01415     SSL_UNLOCK_WRITER(ss);
01416     return rv;
01417 }
01418 
01419 static int PR_CALLBACK
01420 ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
01421 {
01422     sslSocket *ss;
01423     int        rv;
01424 
01425     ss = ssl_GetPrivate(fd);
01426     if (!ss) {
01427        SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd));
01428        return SECFailure;
01429     }
01430     SSL_LOCK_READER(ss);
01431     ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
01432     if (!ss->opt.fdx)
01433        ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
01434     rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
01435     SSL_UNLOCK_READER(ss);
01436     return rv;
01437 }
01438 
01439 static int PR_CALLBACK
01440 ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
01441 {
01442     sslSocket *ss;
01443     int        rv;
01444 
01445     ss = ssl_GetPrivate(fd);
01446     if (!ss) {
01447        SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd));
01448        return SECFailure;
01449     }
01450     SSL_LOCK_WRITER(ss);
01451     ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
01452     if (!ss->opt.fdx)
01453        ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
01454     rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
01455     SSL_UNLOCK_WRITER(ss);
01456     return rv;
01457 }
01458 
01459 static PRStatus PR_CALLBACK
01460 ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
01461 {
01462     sslSocket *ss;
01463 
01464     ss = ssl_GetPrivate(fd);
01465     if (!ss) {
01466        SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd));
01467        return PR_FAILURE;
01468     }
01469     return (PRStatus)(*ss->ops->getpeername)(ss, addr);
01470 }
01471 
01472 /*
01473 */
01474 SECStatus
01475 ssl_GetPeerInfo(sslSocket *ss)
01476 {
01477     PRFileDesc *      osfd;
01478     int               rv;
01479     PRNetAddr         sin;
01480 
01481     osfd = ss->fd->lower;
01482 
01483     PORT_Memset(&sin, 0, sizeof(sin));
01484     rv = osfd->methods->getpeername(osfd, &sin);
01485     if (rv < 0) {
01486        return SECFailure;
01487     }
01488     ss->TCPconnected = 1;
01489     if (sin.inet.family == PR_AF_INET) {
01490         PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ss->sec.ci.peer);
01491        ss->sec.ci.port = sin.inet.port;
01492     } else if (sin.ipv6.family == PR_AF_INET6) {
01493        ss->sec.ci.peer = sin.ipv6.ip;
01494        ss->sec.ci.port = sin.ipv6.port;
01495     } else {
01496        PORT_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR);
01497        return SECFailure;
01498     }
01499     return SECSuccess;
01500 }
01501 
01502 static PRStatus PR_CALLBACK
01503 ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
01504 {
01505     sslSocket *ss;
01506 
01507     ss = ssl_GetPrivate(fd);
01508     if (!ss) {
01509        SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd));
01510        return PR_FAILURE;
01511     }
01512     return (PRStatus)(*ss->ops->getsockname)(ss, name);
01513 }
01514 
01515 SECStatus PR_CALLBACK
01516 SSL_SetSockPeerID(PRFileDesc *fd, char *peerID)
01517 {
01518     sslSocket *ss;
01519 
01520     ss = ssl_FindSocket(fd);
01521     if (!ss) {
01522        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCacheIndex",
01523                SSL_GETPID(), fd));
01524        return SECFailure;
01525     }
01526 
01527     ss->peerID = PORT_Strdup(peerID);
01528     return SECSuccess;
01529 }
01530 
01531 SECStatus PR_CALLBACK
01532 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout)
01533 {
01534     sslSocket *ss;
01535 
01536     ss = ssl_GetPrivate(fd);
01537     if (!ss) {
01538        SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd));
01539        return SECFailure;
01540     }
01541     SSL_LOCK_READER(ss);
01542     ss->rTimeout = timeout;
01543     if (ss->opt.fdx) {
01544         SSL_LOCK_WRITER(ss);
01545     }
01546     ss->wTimeout = timeout;
01547     if (ss->opt.fdx) {
01548         SSL_UNLOCK_WRITER(ss);
01549     }
01550     SSL_UNLOCK_READER(ss);
01551     return SECSuccess;
01552 }
01553 
01554 #define PR_POLL_RW (PR_POLL_WRITE | PR_POLL_READ)
01555 
01556 static PRInt16 PR_CALLBACK
01557 ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
01558 {
01559     sslSocket *ss;
01560     PRInt16    new_flags = how_flags;     /* should select on these flags. */
01561     PRNetAddr  addr;
01562 
01563     *p_out_flags = 0;
01564     ss = ssl_GetPrivate(fd);
01565     if (!ss) {
01566        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll",
01567                SSL_GETPID(), fd));
01568        return 0;     /* don't poll on this socket */
01569     }
01570 
01571     if (ss->opt.useSecurity && 
01572        ss->handshaking != sslHandshakingUndetermined &&
01573         !ss->firstHsDone &&
01574        (how_flags & PR_POLL_RW)) {
01575        if (!ss->TCPconnected) {
01576            ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
01577        }
01578        /* If it's not connected, then presumably the application is polling
01579        ** on read or write appropriately, so don't change it. 
01580        */
01581        if (ss->TCPconnected) {
01582            if (!ss->handshakeBegun) {
01583               /* If the handshake has not begun, poll on read or write 
01584               ** based on the local application's role in the handshake,
01585               ** not based on what the application requested.
01586               */
01587               new_flags &= ~PR_POLL_RW;
01588               if (ss->handshaking == sslHandshakingAsClient) {
01589                   new_flags |= PR_POLL_WRITE;
01590               } else { /* handshaking as server */
01591                   new_flags |= PR_POLL_READ;
01592               }
01593            } else 
01594            /* First handshake is in progress */
01595            if (ss->lastWriteBlocked) {
01596               if (new_flags & PR_POLL_READ) {
01597                   /* The caller is waiting for data to be received, 
01598                   ** but the initial handshake is blocked on write, or the 
01599                   ** client's first handshake record has not been written.
01600                   ** The code should select on write, not read.
01601                   */
01602                   new_flags ^=  PR_POLL_READ;       /* don't select on read. */
01603                   new_flags |=  PR_POLL_WRITE;   /* do    select on write. */
01604               }
01605            } else if (new_flags & PR_POLL_WRITE) {
01606                   /* The caller is trying to write, but the handshake is 
01607                   ** blocked waiting for data to read, and the first 
01608                   ** handshake has been sent.  so do NOT to poll on write.
01609                   */
01610                   new_flags ^=  PR_POLL_WRITE;   /* don't select on write. */
01611                   new_flags |=  PR_POLL_READ;       /* do    select on read. */
01612            }
01613        }
01614     } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
01615        *p_out_flags = PR_POLL_READ;       /* it's ready already. */
01616        return new_flags;
01617     } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
01618               (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
01619        new_flags |=  PR_POLL_WRITE;   /* also select on write. */
01620     } 
01621     if (new_flags && (fd->lower->methods->poll != NULL)) {
01622        PRInt16    lower_out_flags = 0;
01623        PRInt16    lower_new_flags;
01624         lower_new_flags = fd->lower->methods->poll(fd->lower, new_flags, 
01625                                               &lower_out_flags);
01626        if ((lower_new_flags & lower_out_flags) && (how_flags != new_flags)) {
01627            PRInt16 out_flags = lower_out_flags & ~PR_POLL_RW;
01628            if (lower_out_flags & PR_POLL_READ) 
01629               out_flags |= PR_POLL_WRITE;
01630            if (lower_out_flags & PR_POLL_WRITE) 
01631               out_flags |= PR_POLL_READ;
01632            *p_out_flags = out_flags;
01633            new_flags = how_flags;
01634        } else {
01635            *p_out_flags = lower_out_flags;
01636            new_flags    = lower_new_flags;
01637        }
01638     }
01639 
01640     return new_flags;
01641 }
01642 
01643 static PRInt32 PR_CALLBACK
01644 ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
01645                const void *headers, PRInt32 hlen,
01646                PRTransmitFileFlags flags, PRIntervalTime timeout)
01647 {
01648     PRSendFileData sfd;
01649 
01650     sfd.fd = fd;
01651     sfd.file_offset = 0;
01652     sfd.file_nbytes = 0;
01653     sfd.header = headers;
01654     sfd.hlen = hlen;
01655     sfd.trailer = NULL;
01656     sfd.tlen = 0;
01657 
01658     return sd->methods->sendfile(sd, &sfd, flags, timeout);
01659 }
01660 
01661 
01662 PRBool
01663 ssl_FdIsBlocking(PRFileDesc *fd)
01664 {
01665     PRSocketOptionData opt;
01666     PRStatus           status;
01667 
01668     opt.option             = PR_SockOpt_Nonblocking;
01669     opt.value.non_blocking = PR_FALSE;
01670     status = PR_GetSocketOption(fd, &opt);
01671     if (status != PR_SUCCESS)
01672        return PR_FALSE;
01673     return (PRBool)!opt.value.non_blocking;
01674 }
01675 
01676 PRBool
01677 ssl_SocketIsBlocking(sslSocket *ss)
01678 {
01679     return ssl_FdIsBlocking(ss->fd);
01680 }
01681 
01682 PRInt32  sslFirstBufSize = 8 * 1024;
01683 PRInt32  sslCopyLimit    = 1024;
01684 
01685 static PRInt32 PR_CALLBACK
01686 ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors, 
01687            PRIntervalTime timeout)
01688 {
01689     PRInt32            bufLen;
01690     PRInt32            left;
01691     PRInt32            rv;
01692     PRInt32            sent      =  0;
01693     const PRInt32      first_len = sslFirstBufSize;
01694     const PRInt32      limit     = sslCopyLimit;
01695     PRBool             blocking;
01696     PRIOVec            myIov        = { 0, 0 };
01697     char               buf[MAX_FRAGMENT_LENGTH];
01698 
01699     if (vectors > PR_MAX_IOVECTOR_SIZE) {
01700        PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
01701        return -1;
01702     }
01703     blocking = ssl_FdIsBlocking(fd);
01704 
01705 #define K16 sizeof(buf)
01706 #define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
01707 #define GET_VECTOR   do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
01708 #define HANDLE_ERR(rv, len) \
01709     if (rv != len) { \
01710        if (rv < 0) { \
01711            if (!blocking \
01712               && (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
01713               && (sent > 0)) { \
01714               return sent; \
01715            } else { \
01716               return -1; \
01717            } \
01718        } \
01719        /* Only a nonblocking socket can have partial sends */ \
01720        PR_ASSERT(!blocking); \
01721        return sent + rv; \
01722     } 
01723 #define SEND(bfr, len) \
01724     do { \
01725        rv = ssl_Send(fd, bfr, len, 0, timeout); \
01726        HANDLE_ERR(rv, len) \
01727        sent += len; \
01728     } while (0)
01729 
01730     /* Make sure the first write is at least 8 KB, if possible. */
01731     KILL_VECTORS
01732     if (!vectors)
01733        return ssl_Send(fd, 0, 0, 0, timeout);
01734     GET_VECTOR;
01735     if (!vectors) {
01736        return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
01737     }
01738     if (myIov.iov_len < first_len) {
01739        PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
01740        bufLen = myIov.iov_len;
01741        left = first_len - bufLen;
01742        while (vectors && left) {
01743            int toCopy;
01744            GET_VECTOR;
01745            toCopy = PR_MIN(left, myIov.iov_len);
01746            PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
01747            bufLen         += toCopy;
01748            left           -= toCopy;
01749            myIov.iov_base += toCopy;
01750            myIov.iov_len  -= toCopy;
01751        }
01752        SEND( buf, bufLen );
01753     }
01754 
01755     while (vectors || myIov.iov_len) {
01756        PRInt32   addLen;
01757        if (!myIov.iov_len) {
01758            GET_VECTOR;
01759        }
01760        while (myIov.iov_len >= K16) {
01761            SEND(myIov.iov_base, K16);
01762            myIov.iov_base += K16;
01763            myIov.iov_len  -= K16;
01764        }
01765        if (!myIov.iov_len)
01766            continue;
01767 
01768        if (!vectors || myIov.iov_len > limit) {
01769            addLen = 0;
01770        } else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
01771            /* Addlen is already computed. */;
01772        } else if (vectors > 1 && 
01773             iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
01774             addLen = limit - myIov.iov_len;
01775        } else 
01776            addLen = 0;
01777 
01778        if (!addLen) {
01779            SEND( myIov.iov_base, myIov.iov_len );
01780            myIov.iov_len = 0;
01781            continue;
01782        }
01783        PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
01784        bufLen = myIov.iov_len;
01785        do {
01786            GET_VECTOR;
01787            PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
01788            myIov.iov_base += addLen;
01789            myIov.iov_len  -= addLen;
01790            bufLen         += addLen;
01791 
01792            left = PR_MIN( limit, K16 - bufLen);
01793            if (!vectors            /* no more left */
01794            ||  myIov.iov_len > 0   /* we didn't use that one all up */
01795            ||  bufLen >= K16              /* it's full. */
01796            ) {
01797               addLen = 0;
01798            } else if ((addLen = iov->iov_len % K16) <= left) {
01799               /* Addlen is already computed. */;
01800            } else if (vectors > 1 && 
01801                iov[1].iov_len % K16 + addLen <= left + limit) {
01802                addLen = left;
01803            } else 
01804               addLen = 0;
01805 
01806        } while (addLen);
01807        SEND( buf, bufLen );
01808     } 
01809     return sent;
01810 }
01811 
01812 /*
01813  * These functions aren't implemented.
01814  */
01815 
01816 static PRInt32 PR_CALLBACK
01817 ssl_Available(PRFileDesc *fd)
01818 {
01819     PORT_Assert(0);
01820     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01821     return SECFailure;
01822 }
01823 
01824 static PRInt64 PR_CALLBACK
01825 ssl_Available64(PRFileDesc *fd)
01826 {
01827     PRInt64 res;
01828 
01829     PORT_Assert(0);
01830     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01831     LL_I2L(res, -1L);
01832     return res;
01833 }
01834 
01835 static PRStatus PR_CALLBACK
01836 ssl_FSync(PRFileDesc *fd)
01837 {
01838     PORT_Assert(0);
01839     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01840     return PR_FAILURE;
01841 }
01842 
01843 static PRInt32 PR_CALLBACK
01844 ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
01845     PORT_Assert(0);
01846     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01847     return SECFailure;
01848 }
01849 
01850 static PRInt64 PR_CALLBACK
01851 ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
01852     PRInt64 res;
01853 
01854     PORT_Assert(0);
01855     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01856     LL_I2L(res, -1L);
01857     return res;
01858 }
01859 
01860 static PRStatus PR_CALLBACK
01861 ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
01862 {
01863     PORT_Assert(0);
01864     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01865     return PR_FAILURE;
01866 }
01867 
01868 static PRStatus PR_CALLBACK
01869 ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
01870 {
01871     PORT_Assert(0);
01872     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01873     return PR_FAILURE;
01874 }
01875 
01876 static PRInt32 PR_CALLBACK
01877 ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
01878             PRNetAddr *addr, PRIntervalTime timeout)
01879 {
01880     PORT_Assert(0);
01881     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01882     return SECFailure;
01883 }
01884 
01885 static PRInt32 PR_CALLBACK
01886 ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
01887           const PRNetAddr *addr, PRIntervalTime timeout)
01888 {
01889     PORT_Assert(0);
01890     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
01891     return SECFailure;
01892 }
01893 
01894 static const PRIOMethods ssl_methods = {
01895     PR_DESC_LAYERED,
01896     ssl_Close,              /* close        */
01897     ssl_Read,               /* read         */
01898     ssl_Write,              /* write        */
01899     ssl_Available,          /* available    */
01900     ssl_Available64,        /* available64  */
01901     ssl_FSync,              /* fsync        */
01902     ssl_Seek,               /* seek         */
01903     ssl_Seek64,             /* seek64       */
01904     ssl_FileInfo,           /* fileInfo     */
01905     ssl_FileInfo64,         /* fileInfo64   */
01906     ssl_WriteV,             /* writev       */
01907     ssl_Connect,            /* connect      */
01908     ssl_Accept,             /* accept       */
01909     ssl_Bind,               /* bind         */
01910     ssl_Listen,             /* listen       */
01911     ssl_Shutdown,           /* shutdown     */
01912     ssl_Recv,               /* recv         */
01913     ssl_Send,               /* send         */
01914     ssl_RecvFrom,           /* recvfrom     */
01915     ssl_SendTo,             /* sendto       */
01916     ssl_Poll,               /* poll         */
01917     PR_EmulateAcceptRead,       /* acceptread   */
01918     ssl_TransmitFile,           /* transmitfile */
01919     ssl_GetSockName,        /* getsockname  */
01920     ssl_GetPeerName,        /* getpeername  */
01921     NULL,                   /* getsockopt   OBSOLETE */
01922     NULL,                   /* setsockopt   OBSOLETE */
01923     NULL,                   /* getsocketoption   */
01924     NULL,                   /* setsocketoption   */
01925     PR_EmulateSendFile,     /* Send a (partial) file with header/trailer*/
01926     NULL,                   /* reserved for future use */
01927     NULL,                   /* reserved for future use */
01928     NULL,                   /* reserved for future use */
01929     NULL,                   /* reserved for future use */
01930     NULL                    /* reserved for future use */
01931 };
01932 
01933 
01934 static PRIOMethods combined_methods;
01935 
01936 static void
01937 ssl_SetupIOMethods(void)
01938 {
01939           PRIOMethods *new_methods  = &combined_methods;
01940     const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
01941     const PRIOMethods *my_methods   = &ssl_methods;
01942 
01943     *new_methods = *nspr_methods;
01944 
01945     new_methods->file_type         = my_methods->file_type;
01946     new_methods->close             = my_methods->close;
01947     new_methods->read              = my_methods->read;
01948     new_methods->write             = my_methods->write;
01949     new_methods->available         = my_methods->available;
01950     new_methods->available64       = my_methods->available64;
01951     new_methods->fsync             = my_methods->fsync;
01952     new_methods->seek              = my_methods->seek;
01953     new_methods->seek64            = my_methods->seek64;
01954     new_methods->fileInfo          = my_methods->fileInfo;
01955     new_methods->fileInfo64        = my_methods->fileInfo64;
01956     new_methods->writev            = my_methods->writev;
01957     new_methods->connect           = my_methods->connect;
01958     new_methods->accept            = my_methods->accept;
01959     new_methods->bind              = my_methods->bind;
01960     new_methods->listen            = my_methods->listen;
01961     new_methods->shutdown          = my_methods->shutdown;
01962     new_methods->recv              = my_methods->recv;
01963     new_methods->send              = my_methods->send;
01964     new_methods->recvfrom          = my_methods->recvfrom;
01965     new_methods->sendto            = my_methods->sendto;
01966     new_methods->poll              = my_methods->poll;
01967     new_methods->acceptread        = my_methods->acceptread;
01968     new_methods->transmitfile      = my_methods->transmitfile;
01969     new_methods->getsockname       = my_methods->getsockname;
01970     new_methods->getpeername       = my_methods->getpeername;
01971 /*  new_methods->getsocketoption   = my_methods->getsocketoption;     */
01972 /*  new_methods->setsocketoption   = my_methods->setsocketoption;     */
01973     new_methods->sendfile          = my_methods->sendfile;
01974 
01975 }
01976 
01977 static PRCallOnceType initIoLayerOnce;
01978 
01979 static PRStatus  
01980 ssl_InitIOLayer(void)
01981 {
01982     ssl_layer_id = PR_GetUniqueIdentity("SSL");
01983     ssl_SetupIOMethods();
01984     ssl_inited = PR_TRUE;
01985     return PR_SUCCESS;
01986 }
01987 
01988 static PRStatus
01989 ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
01990 {
01991     PRFileDesc *layer       = NULL;
01992     PRStatus    status;
01993 
01994     if (!ssl_inited) {
01995        PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
01996     }
01997 
01998     if (ns == NULL)
01999        goto loser;
02000 
02001     layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
02002     if (layer == NULL)
02003        goto loser;
02004     layer->secret = (PRFilePrivate *)ns;
02005 
02006     /* Here, "stack" points to the PRFileDesc on the top of the stack.
02007     ** "layer" points to a new FD that is to be inserted into the stack.
02008     ** If layer is being pushed onto the top of the stack, then 
02009     ** PR_PushIOLayer switches the contents of stack and layer, and then
02010     ** puts stack on top of layer, so that after it is done, the top of 
02011     ** stack is the same "stack" as it was before, and layer is now the 
02012     ** FD for the former top of stack.
02013     ** After this call, stack always points to the top PRFD on the stack.
02014     ** If this function fails, the contents of stack and layer are as 
02015     ** they were before the call.
02016     */
02017     status = PR_PushIOLayer(stack, id, layer);
02018     if (status != PR_SUCCESS)
02019        goto loser;
02020 
02021     ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
02022     return PR_SUCCESS;
02023 
02024 loser:
02025     if (layer) {
02026        layer->dtor(layer); /* free layer */
02027     }
02028     return PR_FAILURE;
02029 }
02030 
02031 /* if this fails, caller must destroy socket. */
02032 static SECStatus
02033 ssl_MakeLocks(sslSocket *ss)
02034 {
02035     ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
02036     if (!ss->firstHandshakeLock) 
02037        goto loser;
02038     ss->ssl3HandshakeLock  = PZ_NewMonitor(nssILockSSL);
02039     if (!ss->ssl3HandshakeLock) 
02040        goto loser;
02041     ss->specLock           = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
02042     if (!ss->specLock) 
02043        goto loser;
02044     ss->recvBufLock        = PZ_NewMonitor(nssILockSSL);
02045     if (!ss->recvBufLock) 
02046        goto loser;
02047     ss->xmitBufLock        = PZ_NewMonitor(nssILockSSL);
02048     if (!ss->xmitBufLock) 
02049        goto loser;
02050     ss->writerThread       = NULL;
02051     if (ssl_lock_readers) {
02052        ss->recvLock       = PZ_NewLock(nssILockSSL);
02053        if (!ss->recvLock) 
02054            goto loser;
02055        ss->sendLock       = PZ_NewLock(nssILockSSL);
02056        if (!ss->sendLock) 
02057            goto loser;
02058     }
02059     return SECSuccess;
02060 loser:
02061     ssl_DestroyLocks(ss);
02062     return SECFailure;
02063 }
02064 
02065 #if (defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)) && !defined(_WIN32_WCE)
02066 #define NSS_HAVE_GETENV 1
02067 #endif
02068 
02069 /*
02070 ** Create a newsocket structure for a file descriptor.
02071 */
02072 static sslSocket *
02073 ssl_NewSocket(PRBool makeLocks)
02074 {
02075     sslSocket *ss;
02076 #if defined( NSS_HAVE_GETENV )
02077     static int firsttime = 1;
02078 
02079     if (firsttime) {
02080        char * ev;
02081        firsttime = 0;
02082 #ifdef DEBUG
02083 #ifdef TRACE
02084        ev = getenv("SSLTRACE");
02085        if (ev && ev[0]) {
02086            ssl_trace = atoi(ev);
02087            SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
02088        }
02089 #endif /* TRACE */
02090        ev = getenv("SSLDEBUG");
02091        if (ev && ev[0]) {
02092            ssl_debug = atoi(ev);
02093            SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
02094        }
02095 #endif /* DEBUG */
02096        ev = getenv("SSLBYPASS");
02097        if (ev && ev[0]) {
02098            ssl_defaults.bypassPKCS11 = (ev[0] == '1');
02099            SSL_TRACE(("SSL: bypass default set to %d", \
02100                     ssl_defaults.bypassPKCS11));
02101        }
02102        ev = getenv("SSLFORCELOCKS");
02103        if (ev && ev[0] == '1') {
02104            ssl_force_locks = PR_TRUE;
02105            ssl_defaults.noLocks = 0;
02106            strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED.  ");
02107            SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
02108        }
02109     }
02110 #endif /* NSS_HAVE_GETENV */
02111     if (ssl_force_locks)
02112        makeLocks = PR_TRUE;
02113 
02114     /* Make a new socket and get it ready */
02115     ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
02116     if (ss) {
02117         /* This should be of type SSLKEAType, but CC on IRIX
02118         * complains during the for loop.
02119         */
02120        int i;
02121        SECStatus status;
02122  
02123        ss->opt                = ssl_defaults;
02124        ss->opt.useSocks       = PR_FALSE;
02125        ss->opt.noLocks        = !makeLocks;
02126 
02127        ss->peerID             = NULL;
02128        ss->rTimeout         = PR_INTERVAL_NO_TIMEOUT;
02129        ss->wTimeout         = PR_INTERVAL_NO_TIMEOUT;
02130        ss->cTimeout         = PR_INTERVAL_NO_TIMEOUT;
02131        ss->cipherSpecs        = NULL;
02132         ss->sizeCipherSpecs    = 0;  /* produced lazily */
02133         ss->preferredCipher    = NULL;
02134         ss->url                = NULL;
02135 
02136        for (i=kt_null; i < kt_kea_size; i++) {
02137            sslServerCerts * sc = ss->serverCerts + i;
02138            sc->serverCert      = NULL;
02139            sc->serverCertChain = NULL;
02140            sc->serverKeyPair   = NULL;
02141            sc->serverKeyBits   = 0;
02142        }
02143        ss->stepDownKeyPair    = NULL;
02144        ss->dbHandle           = CERT_GetDefaultCertDB();
02145 
02146        /* Provide default implementation of hooks */
02147        ss->authCertificate    = SSL_AuthCertificate;
02148        ss->authCertificateArg = (void *)ss->dbHandle;
02149        ss->getClientAuthData  = NULL;
02150        ss->handleBadCert      = NULL;
02151        ss->badCertArg         = NULL;
02152        ss->pkcs11PinArg       = NULL;
02153 
02154        ssl_ChooseOps(ss);
02155        ssl2_InitSocketPolicy(ss);
02156        ssl3_InitSocketPolicy(ss);
02157 
02158        if (makeLocks) {
02159            status = ssl_MakeLocks(ss);
02160            if (status != SECSuccess)
02161               goto loser;
02162        }
02163        status = ssl_CreateSecurityInfo(ss);
02164        if (status != SECSuccess) 
02165            goto loser;
02166        status = ssl_InitGather(&ss->gs);
02167        if (status != SECSuccess) {
02168 loser:
02169            ssl_DestroySocketContents(ss);
02170            ssl_DestroyLocks(ss);
02171            PORT_Free(ss);
02172            ss = NULL;
02173        }
02174     }
02175     return ss;
02176 }
02177