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