/*
 * vtables (and methods that call through them) for the 4 types of 
 * SSLSockets supported.  Only one type is still supported.
 * Various other functions.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "seccomon.h"
#include "cert.h"
#include "keyhi.h"
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "nspr.h"
#include "private/pprio.h"
#ifndef NO_PKCS11_BYPASS
#include "blapi.h"
#endif
#include "pk11pub.h"
#include "nss.h"

/* This is a bodge to allow this code to be compiled against older NSS headers
 * that don't contain the TLS 1.2 changes. */
#ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
#endif

#define SET_ERROR_CODE   /* reminder */

static const sslSocketOps ssl_default_ops = {	/* No SSL. */
    ssl_DefConnect,
    NULL,
    ssl_DefBind,
    ssl_DefListen,
    ssl_DefShutdown,
    ssl_DefClose,
    ssl_DefRecv,
    ssl_DefSend,
    ssl_DefRead,
    ssl_DefWrite,
    ssl_DefGetpeername,
    ssl_DefGetsockname
};

static const sslSocketOps ssl_secure_ops = {	/* SSL. */
    ssl_SecureConnect,
    NULL,
    ssl_DefBind,
    ssl_DefListen,
    ssl_SecureShutdown,
    ssl_SecureClose,
    ssl_SecureRecv,
    ssl_SecureSend,
    ssl_SecureRead,
    ssl_SecureWrite,
    ssl_DefGetpeername,
    ssl_DefGetsockname
};

/*
** default settings for socket enables
*/
static sslOptions ssl_defaults = {
    { siBuffer, NULL, 0 }, /* nextProtoNego */
    PR_TRUE, 	/* useSecurity        */
    PR_FALSE,	/* useSocks           */
    PR_FALSE,	/* requestCertificate */
    2,	        /* requireCertificate */
    PR_FALSE,	/* handshakeAsClient  */
    PR_FALSE,	/* handshakeAsServer  */
    PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
    PR_FALSE,	/* unusedBit9         */
    PR_FALSE, 	/* unusedBit10        */
    PR_FALSE,	/* noCache            */
    PR_FALSE,	/* fdx                */
    PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
    PR_TRUE,	/* detectRollBack     */
    PR_FALSE,   /* noStepDown         */
    PR_FALSE,   /* bypassPKCS11       */
    PR_FALSE,   /* noLocks            */
    PR_FALSE,   /* enableSessionTickets */
    PR_FALSE,   /* enableDeflate      */
    2,          /* enableRenegotiation (default: requires extension) */
    PR_FALSE,   /* requireSafeNegotiation */
    PR_FALSE,   /* enableFalseStart   */
    PR_TRUE,    /* cbcRandomIV        */
    PR_FALSE,   /* enableOCSPStapling */
    PR_TRUE,    /* enableNPN          */
    PR_FALSE,   /* enableALPN         */
    PR_FALSE,   /* enableSignedCertTimestamps */
    PR_FALSE    /* enableFallbackSCSV */
};

/*
 * default range of enabled SSL/TLS protocols
 */
static SSLVersionRange versions_defaults_stream = {
    SSL_LIBRARY_VERSION_3_0,
    SSL_LIBRARY_VERSION_TLS_1_0
};

static SSLVersionRange versions_defaults_datagram = {
    SSL_LIBRARY_VERSION_TLS_1_1,
    SSL_LIBRARY_VERSION_TLS_1_1
};

#define VERSIONS_DEFAULTS(variant) \
    (variant == ssl_variant_stream ? &versions_defaults_stream : \
                                     &versions_defaults_datagram)

sslSessionIDLookupFunc  ssl_sid_lookup;
sslSessionIDCacheFunc   ssl_sid_cache;
sslSessionIDUncacheFunc ssl_sid_uncache;

static PRBool ssl_inited = PR_FALSE;
static PRDescIdentity ssl_layer_id;

PRBool                  locksEverDisabled; 	/* implicitly PR_FALSE */
PRBool			ssl_force_locks;  	/* implicitly PR_FALSE */
int                     ssl_lock_readers	= 1;	/* default true. */
char                    ssl_debug;
char                    ssl_trace;
FILE *                  ssl_trace_iob;
FILE *                  ssl_keylog_iob;
char lockStatus[] = "Locks are ENABLED.  ";
#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */

/* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
static const PRUint16 srtpCiphers[] = {
    SRTP_AES128_CM_HMAC_SHA1_80,
    SRTP_AES128_CM_HMAC_SHA1_32,
    0
};

/* forward declarations. */
static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
static SECStatus  ssl_MakeLocks(sslSocket *ss);
static void       ssl_SetDefaultsFromEnvironment(void);
static PRStatus   ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, 
                                  PRDescIdentity id);

/************************************************************************/

/*
** Lookup a socket structure from a file descriptor.
** Only functions called through the PRIOMethods table should use this.
** Other app-callable functions should use ssl_FindSocket.
*/
static sslSocket *
ssl_GetPrivate(PRFileDesc *fd)
{
    sslSocket *ss;

    PORT_Assert(fd != NULL);
    PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
    PORT_Assert(fd->identity == ssl_layer_id);

    if (fd->methods->file_type != PR_DESC_LAYERED ||
        fd->identity != ssl_layer_id) {
	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
	return NULL;
    }

    ss = (sslSocket *)fd->secret;
    ss->fd = fd;
    return ss;
}

/* This function tries to find the SSL layer in the stack. 
 * It searches for the first SSL layer at or below the argument fd,
 * and failing that, it searches for the nearest SSL layer above the 
 * argument fd.  It returns the private sslSocket from the found layer.
 */
sslSocket *
ssl_FindSocket(PRFileDesc *fd)
{
    PRFileDesc *layer;
    sslSocket *ss;

    PORT_Assert(fd != NULL);
    PORT_Assert(ssl_layer_id != 0);

    layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
    if (layer == NULL) {
	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
	return NULL;
    }

    ss = (sslSocket *)layer->secret;
    ss->fd = layer;
    return ss;
}

static sslSocket *
ssl_DupSocket(sslSocket *os)
{
    sslSocket *ss;
    SECStatus rv;

    ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
    if (ss) {
	ss->opt                = os->opt;
	ss->opt.useSocks       = PR_FALSE;
	ss->vrange             = os->vrange;

	ss->peerID             = !os->peerID ? NULL : PORT_Strdup(os->peerID);
	ss->url                = !os->url    ? NULL : PORT_Strdup(os->url);

	ss->ops      = os->ops;
	ss->rTimeout = os->rTimeout;
	ss->wTimeout = os->wTimeout;
	ss->cTimeout = os->cTimeout;
	ss->dbHandle = os->dbHandle;

	/* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
	ss->allowedByPolicy	= os->allowedByPolicy;
	ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
	ss->chosenPreference 	= os->chosenPreference;
	PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
	PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
		    sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
	ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;

	if (os->cipherSpecs) {
	    ss->cipherSpecs  = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
	    if (ss->cipherSpecs) 
	    	PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs, 
		            os->sizeCipherSpecs);
	    ss->sizeCipherSpecs    = os->sizeCipherSpecs;
	    ss->preferredCipher    = os->preferredCipher;
	} else {
	    ss->cipherSpecs        = NULL;  /* produced lazily */
	    ss->sizeCipherSpecs    = 0;
	    ss->preferredCipher    = NULL;
	}
	if (ss->opt.useSecurity) {
	    /* This int should be SSLKEAType, but CC on Irix complains,
	     * during the for loop.
	     */
	    int i;
	    sslServerCerts * oc = os->serverCerts;
	    sslServerCerts * sc = ss->serverCerts;
            
	    for (i=kt_null; i < kt_kea_size; i++, oc++, sc++) {
		if (oc->serverCert && oc->serverCertChain) {
		    sc->serverCert      = CERT_DupCertificate(oc->serverCert);
		    sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
		    if (!sc->serverCertChain) 
		    	goto loser;
		} else {
		    sc->serverCert      = NULL;
		    sc->serverCertChain = NULL;
		}
		sc->serverKeyPair = oc->serverKeyPair ?
				ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
		if (oc->serverKeyPair && !sc->serverKeyPair)
		    goto loser;
	        sc->serverKeyBits = oc->serverKeyBits;
		ss->certStatusArray[i] = !os->certStatusArray[i] ? NULL :
				SECITEM_DupArray(NULL, os->certStatusArray[i]);
	    }
	    ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
		                  ssl3_GetKeyPairRef(os->stepDownKeyPair);
	    ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
		                  ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
/*
 * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
 * XXX We should detect this, and not just march on with NULL pointers.
 */
	    ss->authCertificate       = os->authCertificate;
	    ss->authCertificateArg    = os->authCertificateArg;
	    ss->getClientAuthData     = os->getClientAuthData;
	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
#ifdef NSS_PLATFORM_CLIENT_AUTH
	    ss->getPlatformClientAuthData    = os->getPlatformClientAuthData;
	    ss->getPlatformClientAuthDataArg = os->getPlatformClientAuthDataArg;
#endif
            ss->sniSocketConfig       = os->sniSocketConfig;
            ss->sniSocketConfigArg    = os->sniSocketConfigArg;
	    ss->handleBadCert         = os->handleBadCert;
	    ss->badCertArg            = os->badCertArg;
	    ss->handshakeCallback     = os->handshakeCallback;
	    ss->handshakeCallbackData = os->handshakeCallbackData;
	    ss->canFalseStartCallback = os->canFalseStartCallback;
	    ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
	    ss->pkcs11PinArg          = os->pkcs11PinArg;
	    ss->getChannelID          = os->getChannelID;
	    ss->getChannelIDArg       = os->getChannelIDArg;
    
	    /* Create security data */
	    rv = ssl_CopySecurityInfo(ss, os);
	    if (rv != SECSuccess) {
		goto loser;
	    }
	}
    }
    return ss;

loser:
    ssl_FreeSocket(ss);
    return NULL;
}

static void
ssl_DestroyLocks(sslSocket *ss)
{
    /* Destroy locks. */
    if (ss->firstHandshakeLock) {
    	PZ_DestroyMonitor(ss->firstHandshakeLock);
	ss->firstHandshakeLock = NULL;
    }
    if (ss->ssl3HandshakeLock) {
    	PZ_DestroyMonitor(ss->ssl3HandshakeLock);
	ss->ssl3HandshakeLock = NULL;
    }
    if (ss->specLock) {
    	NSSRWLock_Destroy(ss->specLock);
	ss->specLock = NULL;
    }

    if (ss->recvLock) {
    	PZ_DestroyLock(ss->recvLock);
	ss->recvLock = NULL;
    }
    if (ss->sendLock) {
    	PZ_DestroyLock(ss->sendLock);
	ss->sendLock = NULL;
    }
    if (ss->xmitBufLock) {
    	PZ_DestroyMonitor(ss->xmitBufLock);
	ss->xmitBufLock = NULL;
    }
    if (ss->recvBufLock) {
    	PZ_DestroyMonitor(ss->recvBufLock);
	ss->recvBufLock = NULL;
    }
}

/* Caller holds any relevant locks */
static void
ssl_DestroySocketContents(sslSocket *ss)
{
    /* "i" should be of type SSLKEAType, but CC on IRIX complains during
     * the for loop.
     */
    int        i;

    /* Free up socket */
    ssl_DestroySecurityInfo(&ss->sec);

    ssl3_DestroySSL3Info(ss);

    PORT_Free(ss->saveBuf.buf);
    PORT_Free(ss->pendingBuf.buf);
    ssl_DestroyGather(&ss->gs);

    if (ss->peerID != NULL)
	PORT_Free(ss->peerID);
    if (ss->url != NULL)
	PORT_Free((void *)ss->url);	/* CONST */
    if (ss->cipherSpecs) {
	PORT_Free(ss->cipherSpecs);
	ss->cipherSpecs     = NULL;
	ss->sizeCipherSpecs = 0;
    }

    /* Clean up server configuration */
    for (i=kt_null; i < kt_kea_size; i++) {
	sslServerCerts * sc = ss->serverCerts + i;
	if (sc->serverCert != NULL)
	    CERT_DestroyCertificate(sc->serverCert);
	if (sc->serverCertChain != NULL)
	    CERT_DestroyCertificateList(sc->serverCertChain);
	if (sc->serverKeyPair != NULL)
	    ssl3_FreeKeyPair(sc->serverKeyPair);
	if (ss->certStatusArray[i] != NULL) {
	    SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
	    ss->certStatusArray[i] = NULL;
	}
    }
    if (ss->stepDownKeyPair) {
	ssl3_FreeKeyPair(ss->stepDownKeyPair);
	ss->stepDownKeyPair = NULL;
    }
    if (ss->ephemeralECDHKeyPair) {
	ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
	ss->ephemeralECDHKeyPair = NULL;
    }
    SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
    PORT_Assert(!ss->xtnData.sniNameArr);
    if (ss->xtnData.sniNameArr) {
        PORT_Free(ss->xtnData.sniNameArr);
        ss->xtnData.sniNameArr = NULL;
    }
}

/*
 * free an sslSocket struct, and all the stuff that hangs off of it
 */
void
ssl_FreeSocket(sslSocket *ss)
{
/* Get every lock you can imagine!
** Caller already holds these:
**  SSL_LOCK_READER(ss);
**  SSL_LOCK_WRITER(ss);
*/
    ssl_Get1stHandshakeLock(ss);
    ssl_GetRecvBufLock(ss);
    ssl_GetSSL3HandshakeLock(ss);
    ssl_GetXmitBufLock(ss);
    ssl_GetSpecWriteLock(ss);

    ssl_DestroySocketContents(ss);

    /* Release all the locks acquired above.  */
    SSL_UNLOCK_READER(ss);
    SSL_UNLOCK_WRITER(ss);
    ssl_Release1stHandshakeLock(ss);
    ssl_ReleaseRecvBufLock(ss);
    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_ReleaseXmitBufLock(ss);
    ssl_ReleaseSpecWriteLock(ss);

    ssl_DestroyLocks(ss);

#ifdef DEBUG
    PORT_Memset(ss, 0x1f, sizeof *ss);
#endif
    PORT_Free(ss);
    return;
}

/************************************************************************/
SECStatus 
ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
{
    PRFileDesc *       osfd = ss->fd->lower;
    SECStatus         rv = SECFailure;
    PRSocketOptionData opt;

    opt.option         = PR_SockOpt_NoDelay;
    opt.value.no_delay = (PRBool)!enabled;

    if (osfd->methods->setsocketoption) {
        rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
    } else {
        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    }

    return rv;
}

static void
ssl_ChooseOps(sslSocket *ss)
{
    ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
}

/* Called from SSL_Enable (immediately below) */
static SECStatus
PrepareSocket(sslSocket *ss)
{
    SECStatus     rv = SECSuccess;

    ssl_ChooseOps(ss);
    return rv;
}

SECStatus
SSL_Enable(PRFileDesc *fd, int which, PRBool on)
{
    return SSL_OptionSet(fd, which, on);
}

#ifndef NO_PKCS11_BYPASS
static const PRCallOnceType pristineCallOnce;
static PRCallOnceType setupBypassOnce;

static SECStatus SSL_BypassShutdown(void* appData, void* nssData)
{
    /* unload freeBL shared library from memory */
    BL_Unload();
    setupBypassOnce = pristineCallOnce;
    return SECSuccess;
}

static PRStatus SSL_BypassRegisterShutdown(void)
{
    SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL);
    PORT_Assert(SECSuccess == rv);
    return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE;
}
#endif

static PRStatus SSL_BypassSetup(void)
{
#ifdef NO_PKCS11_BYPASS
    /* Guarantee binary compatibility */
    return PR_SUCCESS;
#else
    return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown);
#endif
}

/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_TLS, on) described in
 * ssl.h in the section "SSL version range setting API".
 */
static void
ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
{
    if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
	if (on) {
	    vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
	    vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
	} /* else don't change anything */
	return;
    }

    if (on) {
	/* Expand the range of enabled version to include TLS 1.0 */
	vrange->min = PR_MIN(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
	vrange->max = PR_MAX(vrange->max, SSL_LIBRARY_VERSION_TLS_1_0);
    } else {
	/* Disable all TLS versions, leaving only SSL 3.0 if it was enabled */
	if (vrange->min == SSL_LIBRARY_VERSION_3_0) {
	    vrange->max = SSL_LIBRARY_VERSION_3_0;
	} else {
	    /* Only TLS was enabled, so now no versions are. */
	    vrange->min = SSL_LIBRARY_VERSION_NONE;
	    vrange->max = SSL_LIBRARY_VERSION_NONE;
	}
    }
}

/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_SSL3, on) described in
 * ssl.h in the section "SSL version range setting API".
 */
static void
ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
{
   if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
	if (on) {
	    vrange->min = SSL_LIBRARY_VERSION_3_0;
	    vrange->max = SSL_LIBRARY_VERSION_3_0;
	} /* else don't change anything */
	return;
    }

   if (on) {
	/* Expand the range of enabled versions to include SSL 3.0. We know
	 * SSL 3.0 or some version of TLS is already enabled at this point, so
	 * we don't need to change vrange->max.
	 */
	vrange->min = SSL_LIBRARY_VERSION_3_0;
   } else {
	/* Disable SSL 3.0, leaving TLS unaffected. */
	if (vrange->max > SSL_LIBRARY_VERSION_3_0) {
	    vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
	} else {
	    /* Only SSL 3.0 was enabled, so now no versions are. */
	    vrange->min = SSL_LIBRARY_VERSION_NONE;
	    vrange->max = SSL_LIBRARY_VERSION_NONE;
	}
    }
}

SECStatus
SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
{
    sslSocket *ss = ssl_FindSocket(fd);
    SECStatus  rv = SECSuccess;
    PRBool     holdingLocks;

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
	return SECFailure;
    }

    holdingLocks = (!ss->opt.noLocks);
    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    switch (which) {
      case SSL_SOCKS:
	ss->opt.useSocks = PR_FALSE;
	rv = PrepareSocket(ss);
	if (on) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    rv = SECFailure;
	}
	break;

      case SSL_SECURITY:
	ss->opt.useSecurity = on;
	rv = PrepareSocket(ss);
	break;

      case SSL_REQUEST_CERTIFICATE:
	ss->opt.requestCertificate = on;
	break;

      case SSL_REQUIRE_CERTIFICATE:
	ss->opt.requireCertificate = on;
	break;

      case SSL_HANDSHAKE_AS_CLIENT:
	if ( ss->opt.handshakeAsServer && on ) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    rv = SECFailure;
	    break;
	}
	ss->opt.handshakeAsClient = on;
	break;

      case SSL_HANDSHAKE_AS_SERVER:
	if ( ss->opt.handshakeAsClient && on ) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    rv = SECFailure;
	    break;
	}
	ss->opt.handshakeAsServer = on;
	break;

      case SSL_ENABLE_TLS:
        if (IS_DTLS(ss)) {
	    if (on) {
		PORT_SetError(SEC_ERROR_INVALID_ARGS);
		rv = SECFailure; /* not allowed */
	    }
	    break;
	}
	ssl_EnableTLS(&ss->vrange, on);
	ss->preferredCipher     = NULL;
	if (ss->cipherSpecs) {
	    PORT_Free(ss->cipherSpecs);
	    ss->cipherSpecs     = NULL;
	    ss->sizeCipherSpecs = 0;
	}
	break;

      case SSL_ENABLE_SSL3:
        if (IS_DTLS(ss)) {
	    if (on) {
		PORT_SetError(SEC_ERROR_INVALID_ARGS);
		rv = SECFailure; /* not allowed */
	    }
	    break;
	}
	ssl_EnableSSL3(&ss->vrange, on);
	ss->preferredCipher     = NULL;
	if (ss->cipherSpecs) {
	    PORT_Free(ss->cipherSpecs);
	    ss->cipherSpecs     = NULL;
	    ss->sizeCipherSpecs = 0;
	}
	break;

      case SSL_ENABLE_SSL2:
        if (IS_DTLS(ss)) {
	    if (on) {
		PORT_SetError(SEC_ERROR_INVALID_ARGS);
		rv = SECFailure; /* not allowed */
	    }
	    break;
	}
	ss->opt.enableSSL2       = on;
	if (on) {
	    ss->opt.v2CompatibleHello = on;
	}
	ss->preferredCipher     = NULL;
	if (ss->cipherSpecs) {
	    PORT_Free(ss->cipherSpecs);
	    ss->cipherSpecs     = NULL;
	    ss->sizeCipherSpecs = 0;
	}
	break;

      case SSL_NO_CACHE:
	ss->opt.noCache = on;
	break;

      case SSL_ENABLE_FDX:
	if (on && ss->opt.noLocks) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    rv = SECFailure;
	}
      	ss->opt.fdx = on;
	break;

      case SSL_V2_COMPATIBLE_HELLO:
        if (IS_DTLS(ss)) {
	    if (on) {
		PORT_SetError(SEC_ERROR_INVALID_ARGS);
		rv = SECFailure; /* not allowed */
	    }
	    break;
	}
      	ss->opt.v2CompatibleHello = on;
	if (!on) {
	    ss->opt.enableSSL2    = on;
	}
	break;

      case SSL_ROLLBACK_DETECTION:  
	ss->opt.detectRollBack = on;
        break;

      case SSL_NO_STEP_DOWN:        
	ss->opt.noStepDown     = on;         
	if (on) 
	    SSL_DisableExportCipherSuites(fd);
	break;

      case SSL_BYPASS_PKCS11:
	if (ss->handshakeBegun) {
	    PORT_SetError(PR_INVALID_STATE_ERROR);
	    rv = SECFailure;
	} else {
            if (PR_FALSE != on) {
                if (PR_SUCCESS == SSL_BypassSetup() ) {
#ifdef NO_PKCS11_BYPASS
                    ss->opt.bypassPKCS11 = PR_FALSE;
#else
                    ss->opt.bypassPKCS11 = on;
#endif
                } else {
                    rv = SECFailure;
                }
            } else {
                ss->opt.bypassPKCS11 = PR_FALSE;
            }
	}
	break;

      case SSL_NO_LOCKS:
	if (on && ss->opt.fdx) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    rv = SECFailure;
	}
	if (on && ssl_force_locks) 
	    on = PR_FALSE;	/* silent override */
	ss->opt.noLocks   = on;
	if (on) {
	    locksEverDisabled = PR_TRUE;
	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
	} else if (!holdingLocks) {
	    rv = ssl_MakeLocks(ss);
	    if (rv != SECSuccess) {
		ss->opt.noLocks   = PR_TRUE;
	    }
	}
	break;

      case SSL_ENABLE_SESSION_TICKETS:
	ss->opt.enableSessionTickets = on;
	break;

      case SSL_ENABLE_DEFLATE:
	ss->opt.enableDeflate = on;
	break;

      case SSL_ENABLE_RENEGOTIATION:
	ss->opt.enableRenegotiation = on;
	break;

      case SSL_REQUIRE_SAFE_NEGOTIATION:
	ss->opt.requireSafeNegotiation = on;
	break;

      case SSL_ENABLE_FALSE_START:
	ss->opt.enableFalseStart = on;
	break;

      case SSL_CBC_RANDOM_IV:
	ss->opt.cbcRandomIV = on;
	break;

      case SSL_ENABLE_OCSP_STAPLING:
       ss->opt.enableOCSPStapling = on;
       break;

      case SSL_ENABLE_NPN:
	ss->opt.enableNPN = on;
	break;

      case SSL_ENABLE_ALPN:
	ss->opt.enableALPN = on;
	break;

      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
	ss->opt.enableSignedCertTimestamps = on;
	break;

      case SSL_ENABLE_FALLBACK_SCSV:
       ss->opt.enableFallbackSCSV = on;
       break;

      default:
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	rv = SECFailure;
    }

    /* We can't use the macros for releasing the locks here,
     * because ss->opt.noLocks might have changed just above.
     * We must release these locks (monitors) here, if we aquired them above,
     * regardless of the current value of ss->opt.noLocks.
     */
    if (holdingLocks) {
	PZ_ExitMonitor((ss)->ssl3HandshakeLock);
	PZ_ExitMonitor((ss)->firstHandshakeLock);
    }

    return rv;
}

SECStatus
SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
{
    sslSocket *ss = ssl_FindSocket(fd);
    SECStatus  rv = SECSuccess;
    PRBool     on = PR_FALSE;

    if (!pOn) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
	*pOn = PR_FALSE;
	return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    switch (which) {
    case SSL_SOCKS:               on = PR_FALSE;               break;
    case SSL_SECURITY:            on = ss->opt.useSecurity;        break;
    case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
    case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
    case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient;  break;
    case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer;  break;
    case SSL_ENABLE_TLS:
	on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0;
	break;
    case SSL_ENABLE_SSL3:
	on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0;
	break;
    case SSL_ENABLE_SSL2:         on = ss->opt.enableSSL2;         break;
    case SSL_NO_CACHE:            on = ss->opt.noCache;            break;
    case SSL_ENABLE_FDX:          on = ss->opt.fdx;                break;
    case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello;  break;
    case SSL_ROLLBACK_DETECTION:  on = ss->opt.detectRollBack;     break;
    case SSL_NO_STEP_DOWN:        on = ss->opt.noStepDown;         break;
    case SSL_BYPASS_PKCS11:       on = ss->opt.bypassPKCS11;       break;
    case SSL_NO_LOCKS:            on = ss->opt.noLocks;            break;
    case SSL_ENABLE_SESSION_TICKETS:
	on = ss->opt.enableSessionTickets;
	break;
    case SSL_ENABLE_DEFLATE:      on = ss->opt.enableDeflate;      break;
    case SSL_ENABLE_RENEGOTIATION:     
                                  on = ss->opt.enableRenegotiation; break;
    case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                  on = ss->opt.requireSafeNegotiation; break;
    case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
    case SSL_CBC_RANDOM_IV:       on = ss->opt.cbcRandomIV;        break;
    case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
    case SSL_ENABLE_NPN:          on = ss->opt.enableNPN;          break;
    case SSL_ENABLE_ALPN:         on = ss->opt.enableALPN;         break;
    case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
	on = ss->opt.enableSignedCertTimestamps;
	break;
    case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;

    default:
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	rv = SECFailure;
    }

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    *pOn = on;
    return rv;
}

SECStatus
SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
{
    SECStatus  rv = SECSuccess;
    PRBool     on = PR_FALSE;

    if (!pOn) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    ssl_SetDefaultsFromEnvironment();

    switch (which) {
    case SSL_SOCKS:               on = PR_FALSE;                        break;
    case SSL_SECURITY:            on = ssl_defaults.useSecurity;        break;
    case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
    case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
    case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient;  break;
    case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer;  break;
    case SSL_ENABLE_TLS:
	on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
	break;
    case SSL_ENABLE_SSL3:
	on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
	break;
    case SSL_ENABLE_SSL2:         on = ssl_defaults.enableSSL2;         break;
    case SSL_NO_CACHE:            on = ssl_defaults.noCache;		break;
    case SSL_ENABLE_FDX:          on = ssl_defaults.fdx;                break;
    case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello;  break;
    case SSL_ROLLBACK_DETECTION:  on = ssl_defaults.detectRollBack;     break;
    case SSL_NO_STEP_DOWN:        on = ssl_defaults.noStepDown;         break;
    case SSL_BYPASS_PKCS11:       on = ssl_defaults.bypassPKCS11;       break;
    case SSL_NO_LOCKS:            on = ssl_defaults.noLocks;            break;
    case SSL_ENABLE_SESSION_TICKETS:
	on = ssl_defaults.enableSessionTickets;
	break;
    case SSL_ENABLE_DEFLATE:      on = ssl_defaults.enableDeflate;      break;
    case SSL_ENABLE_RENEGOTIATION:     
                                  on = ssl_defaults.enableRenegotiation; break;
    case SSL_REQUIRE_SAFE_NEGOTIATION: 
                                  on = ssl_defaults.requireSafeNegotiation; 
				  break;
    case SSL_ENABLE_FALSE_START:  on = ssl_defaults.enableFalseStart;   break;
    case SSL_CBC_RANDOM_IV:       on = ssl_defaults.cbcRandomIV;        break;
    case SSL_ENABLE_OCSP_STAPLING:
       on = ssl_defaults.enableOCSPStapling;
       break;
    case SSL_ENABLE_NPN:          on = ssl_defaults.enableNPN;          break;
    case SSL_ENABLE_ALPN:         on = ssl_defaults.enableALPN;         break;
    case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
	on = ssl_defaults.enableSignedCertTimestamps;
	break;
    case SSL_ENABLE_FALLBACK_SCSV:
	on = ssl_defaults.enableFallbackSCSV;
	break;

    default:
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	rv = SECFailure;
    }

    *pOn = on;
    return rv;
}

/* XXX Use Global Lock to protect this stuff. */
SECStatus
SSL_EnableDefault(int which, PRBool on)
{
    return SSL_OptionSetDefault(which, on);
}

SECStatus
SSL_OptionSetDefault(PRInt32 which, PRBool on)
{
    SECStatus status = ssl_Init();

    if (status != SECSuccess) {
	return status;
    }

    ssl_SetDefaultsFromEnvironment();

    switch (which) {
      case SSL_SOCKS:
	ssl_defaults.useSocks = PR_FALSE;
	if (on) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    return SECFailure;
	}
	break;

      case SSL_SECURITY:
	ssl_defaults.useSecurity = on;
	break;

      case SSL_REQUEST_CERTIFICATE:
	ssl_defaults.requestCertificate = on;
	break;

      case SSL_REQUIRE_CERTIFICATE:
	ssl_defaults.requireCertificate = on;
	break;

      case SSL_HANDSHAKE_AS_CLIENT:
	if ( ssl_defaults.handshakeAsServer && on ) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    return SECFailure;
	}
	ssl_defaults.handshakeAsClient = on;
	break;

      case SSL_HANDSHAKE_AS_SERVER:
	if ( ssl_defaults.handshakeAsClient && on ) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    return SECFailure;
	}
	ssl_defaults.handshakeAsServer = on;
	break;

      case SSL_ENABLE_TLS:
	ssl_EnableTLS(&versions_defaults_stream, on);
	break;

      case SSL_ENABLE_SSL3:
	ssl_EnableSSL3(&versions_defaults_stream, on);
	break;

      case SSL_ENABLE_SSL2:
	ssl_defaults.enableSSL2 = on;
	if (on) {
	    ssl_defaults.v2CompatibleHello = on;
	}
	break;

      case SSL_NO_CACHE:
	ssl_defaults.noCache = on;
	break;

      case SSL_ENABLE_FDX:
	if (on && ssl_defaults.noLocks) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    return SECFailure;
	}
      	ssl_defaults.fdx = on;
	break;

      case SSL_V2_COMPATIBLE_HELLO:
      	ssl_defaults.v2CompatibleHello = on;
	if (!on) {
	    ssl_defaults.enableSSL2    = on;
	}
	break;

      case SSL_ROLLBACK_DETECTION:  
	ssl_defaults.detectRollBack = on;
	break;

      case SSL_NO_STEP_DOWN:        
	ssl_defaults.noStepDown     = on;         
	if (on)
	    SSL_DisableDefaultExportCipherSuites();
	break;

      case SSL_BYPASS_PKCS11:
        if (PR_FALSE != on) {
            if (PR_SUCCESS == SSL_BypassSetup()) {
#ifdef NO_PKCS11_BYPASS
                ssl_defaults.bypassPKCS11   = PR_FALSE;
#else
                ssl_defaults.bypassPKCS11   = on;
#endif
            } else {
                return SECFailure;
            }
        } else {
            ssl_defaults.bypassPKCS11   = PR_FALSE;
        }
	break;

      case SSL_NO_LOCKS:
	if (on && ssl_defaults.fdx) {
	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
	    return SECFailure;
	}
	if (on && ssl_force_locks) 
	    on = PR_FALSE;		/* silent override */
	ssl_defaults.noLocks        = on;
	if (on) {
	    locksEverDisabled = PR_TRUE;
	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
	}
	break;

      case SSL_ENABLE_SESSION_TICKETS:
	ssl_defaults.enableSessionTickets = on;
	break;

      case SSL_ENABLE_DEFLATE:
	ssl_defaults.enableDeflate = on;
	break;

      case SSL_ENABLE_RENEGOTIATION:
	ssl_defaults.enableRenegotiation = on;
	break;

      case SSL_REQUIRE_SAFE_NEGOTIATION:
	ssl_defaults.requireSafeNegotiation = on;
	break;

      case SSL_ENABLE_FALSE_START:
	ssl_defaults.enableFalseStart = on;
	break;

      case SSL_CBC_RANDOM_IV:
	ssl_defaults.cbcRandomIV = on;
	break;

      case SSL_ENABLE_OCSP_STAPLING:
       ssl_defaults.enableOCSPStapling = on;
       break;

      case SSL_ENABLE_NPN:
	ssl_defaults.enableNPN = on;
	break;

      case SSL_ENABLE_ALPN:
	ssl_defaults.enableALPN = on;
	break;

      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
	ssl_defaults.enableSignedCertTimestamps = on;
	break;

      case SSL_ENABLE_FALLBACK_SCSV:
       ssl_defaults.enableFallbackSCSV = on;
       break;

      default:
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    return SECSuccess;
}

/* function tells us if the cipher suite is one that we no longer support. */
static PRBool 
ssl_IsRemovedCipherSuite(PRInt32 suite)
{
    switch (suite) {
    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
    case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
    	return PR_TRUE;
    default:
    	return PR_FALSE;
    }
}

/* Part of the public NSS API.
 * Since this is a global (not per-socket) setting, we cannot use the
 * HandshakeLock to protect this.  Probably want a global lock.
 */
SECStatus
SSL_SetPolicy(long which, int policy)
{
    if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
    	/* one of the two old FIPS ciphers */
	if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) 
	    which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
	else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
	    which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
    }
    if (ssl_IsRemovedCipherSuite(which))
    	return SECSuccess;
    return SSL_CipherPolicySet(which, policy);
}

SECStatus
SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
{
    SECStatus rv = ssl_Init();

    if (rv != SECSuccess) {
	return rv;
    }

    if (ssl_IsRemovedCipherSuite(which)) {
    	rv = SECSuccess;
    } else if (SSL_IS_SSL2_CIPHER(which)) {
	rv = ssl2_SetPolicy(which, policy);
    } else {
	rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
    }
    return rv;
}

SECStatus
SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
{
    SECStatus rv;

    if (!oPolicy) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (ssl_IsRemovedCipherSuite(which)) {
	*oPolicy = SSL_NOT_ALLOWED;
    	rv = SECSuccess;
    } else if (SSL_IS_SSL2_CIPHER(which)) {
	rv = ssl2_GetPolicy(which, oPolicy);
    } else {
	rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
    }
    return rv;
}

/* Part of the public NSS API.
 * Since this is a global (not per-socket) setting, we cannot use the
 * HandshakeLock to protect this.  Probably want a global lock.
 * These changes have no effect on any sslSockets already created. 
 */
SECStatus
SSL_EnableCipher(long which, PRBool enabled)
{
    if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
    	/* one of the two old FIPS ciphers */
	if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) 
	    which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
	else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
	    which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
    }
    if (ssl_IsRemovedCipherSuite(which))
    	return SECSuccess;
    return SSL_CipherPrefSetDefault(which, enabled);
}

SECStatus
SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
{
    SECStatus rv = ssl_Init();

    if (rv != SECSuccess) {
	return rv;
    }

    if (ssl_IsRemovedCipherSuite(which))
    	return SECSuccess;
    if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
    	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
	return SECFailure;
    }
    if (SSL_IS_SSL2_CIPHER(which)) {
	rv = ssl2_CipherPrefSetDefault(which, enabled);
    } else {
	rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
    }
    return rv;
}

SECStatus 
SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
{
    SECStatus  rv;
    
    if (!enabled) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (ssl_IsRemovedCipherSuite(which)) {
	*enabled = PR_FALSE;
    	rv = SECSuccess;
    } else if (SSL_IS_SSL2_CIPHER(which)) {
	rv = ssl2_CipherPrefGetDefault(which, enabled);
    } else {
	rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
    }
    return rv;
}

SECStatus
SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
{
    SECStatus rv;
    sslSocket *ss = ssl_FindSocket(fd);
    
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
	return SECFailure;
    }
    if (ssl_IsRemovedCipherSuite(which))
    	return SECSuccess;
    if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
    	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
	return SECFailure;
    }
    if (SSL_IS_SSL2_CIPHER(which)) {
	rv = ssl2_CipherPrefSet(ss, which, enabled);
    } else {
	rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
    }
    return rv;
}

SECStatus
SSL_CipherOrderSet(PRFileDesc *fd, const PRUint16 *ciphers, unsigned int len)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in CipherOrderSet", SSL_GETPID(),
		fd));
	return SECFailure;
    }
    return ssl3_CipherOrderSet(ss, ciphers, len);
}

SECStatus 
SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
{
    SECStatus  rv;
    sslSocket *ss = ssl_FindSocket(fd);
    
    if (!enabled) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
	*enabled = PR_FALSE;
	return SECFailure;
    }
    if (ssl_IsRemovedCipherSuite(which)) {
	*enabled = PR_FALSE;
    	rv = SECSuccess;
    } else if (SSL_IS_SSL2_CIPHER(which)) {
	rv = ssl2_CipherPrefGet(ss, which, enabled);
    } else {
	rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
    }
    return rv;
}

SECStatus
NSS_SetDomesticPolicy(void)
{
    SECStatus      status = SECSuccess;
    const PRUint16 *cipher;

    for (cipher = SSL_ImplementedCiphers; *cipher != 0; ++cipher) {
	status = SSL_SetPolicy(*cipher, SSL_ALLOWED);
	if (status != SECSuccess)
	    break;
    }
    return status;
}

SECStatus
NSS_SetExportPolicy(void)
{
    return NSS_SetDomesticPolicy();
}

SECStatus
NSS_SetFrancePolicy(void)
{
    return NSS_SetDomesticPolicy();
}

SECStatus
SSL_GetChannelBinding(PRFileDesc *fd,
		      SSLChannelBindingType binding_type,
		      unsigned char *out,
		      unsigned int *outLen,
		      unsigned int outLenMax) {
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelBinding",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    if (binding_type != SSL_CHANNEL_BINDING_TLS_UNIQUE) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
	return SECFailure;
    }

    return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
}


/* LOCKS ??? XXX */
static PRFileDesc *
ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
{
    sslSocket * ns = NULL;
    PRStatus    rv;
    PRNetAddr   addr;
    SECStatus	status = ssl_Init();

    if (status != SECSuccess) {
	return NULL;
    }

    if (model == NULL) {
	/* Just create a default socket if we're given NULL for the model */
	ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
    } else {
	sslSocket * ss = ssl_FindSocket(model);
	if (ss == NULL || ss->protocolVariant != variant) {
	    SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD", 
	    	      SSL_GETPID(), model));
	    return NULL;
	}
	ns = ssl_DupSocket(ss);
    }
    if (ns == NULL)
    	return NULL;

    rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
    if (rv != PR_SUCCESS) {
	ssl_FreeSocket(ns);
	SET_ERROR_CODE
	return NULL;
    }
    ns = ssl_FindSocket(fd);
    PORT_Assert(ns);
    if (ns)
	ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
    return fd;
}

PRFileDesc *
SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
{
    return ssl_ImportFD(model, fd, ssl_variant_stream);
}

PRFileDesc *
DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
{
    return ssl_ImportFD(model, fd, ssl_variant_datagram);
}

/* SSL_SetNextProtoCallback is used to select an application protocol
 * for ALPN and NPN.  For ALPN, this runs on the server; for NPN it
 * runs on the client. */
/* Note: The ALPN version doesn't allow for the use of a default, setting a
 * status of SSL_NEXT_PROTO_NO_OVERLAP is treated as a failure. */
SECStatus
SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
			 void *arg)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoCallback", SSL_GETPID(),
		 fd));
	return SECFailure;
    }

    ssl_GetSSL3HandshakeLock(ss);
    ss->nextProtoCallback = callback;
    ss->nextProtoArg = arg;
    ssl_ReleaseSSL3HandshakeLock(ss);

    return SECSuccess;
}

/* ssl_NextProtoNegoCallback is set as an ALPN/NPN callback when
 * SSL_SetNextProtoNego is used.
 */
static SECStatus
ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
			  const unsigned char *protos, unsigned int protos_len,
			  unsigned char *protoOut, unsigned int *protoOutLen,
			  unsigned int protoMaxLen)
{
    unsigned int i, j;
    const unsigned char *result;
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in ssl_NextProtoNegoCallback",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    /* For each protocol in server preference, see if we support it. */
    for (i = 0; i < protos_len; ) {
	for (j = 0; j < ss->opt.nextProtoNego.len; ) {
	    if (protos[i] == ss->opt.nextProtoNego.data[j] &&
		PORT_Memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
			     protos[i]) == 0) {
		/* We found a match. */
		ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
		result = &protos[i];
		goto found;
	    }
	    j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
	}
	i += 1 + (unsigned int)protos[i];
    }

    /* The other side supports the extension, and either doesn't have any
     * protocols configured, or none of its options match ours. In this case we
     * request our favoured protocol. */
    /* This will be treated as a failure for ALPN. */
    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
    result = ss->opt.nextProtoNego.data;

found:
    if (protoMaxLen < result[0]) {
	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
	return SECFailure;
    }
    memcpy(protoOut, result + 1, result[0]);
    *protoOutLen = result[0];
    return SECSuccess;
}

SECStatus
SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
		     unsigned int length)
{
    sslSocket *ss;
    SECStatus rv;
    SECItem dataItem = { siBuffer, (unsigned char *) data, length };

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
	return SECFailure;

    ssl_GetSSL3HandshakeLock(ss);
    SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
    rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem);
    ssl_ReleaseSSL3HandshakeLock(ss);

    if (rv != SECSuccess)
	return rv;

    return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL);
}

SECStatus
SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
		 unsigned int *bufLen, unsigned int bufLenMax)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
		 fd));
	return SECFailure;
    }

    if (!state || !buf || !bufLen) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    *state = ss->ssl3.nextProtoState;

    if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
	ss->ssl3.nextProto.data) {
	if (ss->ssl3.nextProto.len > bufLenMax) {
	    PORT_SetError(SEC_ERROR_OUTPUT_LEN);
	    return SECFailure;
	}
	PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len);
	*bufLen = ss->ssl3.nextProto.len;
    } else {
	*bufLen = 0;
    }

    return SECSuccess;
}

SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
			     const PRUint16 *ciphers,
			     unsigned int numCiphers)
{
    sslSocket *ss;
    unsigned int i;

    ss = ssl_FindSocket(fd);
    if (!ss || !IS_DTLS(ss)) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSRTPCiphers",
		 SSL_GETPID(), fd));
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    if (numCiphers > MAX_DTLS_SRTP_CIPHER_SUITES) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    ss->ssl3.dtlsSRTPCipherCount = 0;
    for (i = 0; i < numCiphers; i++) {
	const PRUint16 *srtpCipher = srtpCiphers;

	while (*srtpCipher) {
	    if (ciphers[i] == *srtpCipher)
		break;
	    srtpCipher++;
	}
	if (*srtpCipher) {
	    ss->ssl3.dtlsSRTPCiphers[ss->ssl3.dtlsSRTPCipherCount++] =
		ciphers[i];
	} else {
	    SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
		    "suite specified: 0x%04hx", SSL_GETPID(), fd,
		    ciphers[i]));
	}
    }

    if (ss->ssl3.dtlsSRTPCipherCount == 0) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    return SECSuccess;
}

SECStatus
SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
{
    sslSocket * ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSRTPCipher",
		 SSL_GETPID(), fd));
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    if (!ss->ssl3.dtlsSRTPCipherSuite) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    *cipher = ss->ssl3.dtlsSRTPCipherSuite;
    return SECSuccess;
}

PRFileDesc *
SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
{
    sslSocket * sm = NULL, *ss = NULL;
    int i;
    sslServerCerts * mc = NULL;
    sslServerCerts * sc = NULL;

    if (model == NULL) {
        PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
        return NULL;
    }
    sm = ssl_FindSocket(model);
    if (sm == NULL) {
        SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ReconfigFD", 
                 SSL_GETPID(), model));
        return NULL;
    }
    ss = ssl_FindSocket(fd);
    PORT_Assert(ss);
    if (ss == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    
    ss->opt  = sm->opt;
    ss->vrange = sm->vrange;
    PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
    PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
                sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
    ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;

    if (!ss->opt.useSecurity) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    /* This int should be SSLKEAType, but CC on Irix complains,
     * during the for loop.
     */
    for (i=kt_null; i < kt_kea_size; i++) {
        mc = &(sm->serverCerts[i]);
        sc = &(ss->serverCerts[i]);
        if (mc->serverCert && mc->serverCertChain) {
            if (sc->serverCert) {
                CERT_DestroyCertificate(sc->serverCert);
            }
            sc->serverCert      = CERT_DupCertificate(mc->serverCert);
            if (sc->serverCertChain) {
                CERT_DestroyCertificateList(sc->serverCertChain);
            }
            sc->serverCertChain = CERT_DupCertList(mc->serverCertChain);
            if (!sc->serverCertChain)
                goto loser;
	    if (sm->certStatusArray[i]) {
		if (ss->certStatusArray[i]) {
		    SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
		    ss->certStatusArray[i] = NULL;
		}
		ss->certStatusArray[i] = SECITEM_DupArray(NULL, sm->certStatusArray[i]);
		if (!ss->certStatusArray[i])
		    goto loser;
	    }
        }
        if (mc->serverKeyPair) {
            if (sc->serverKeyPair) {
                ssl3_FreeKeyPair(sc->serverKeyPair);
            }
            sc->serverKeyPair = ssl3_GetKeyPairRef(mc->serverKeyPair);
            sc->serverKeyBits = mc->serverKeyBits;
        }
    }
    if (sm->stepDownKeyPair) {
        if (ss->stepDownKeyPair) {
            ssl3_FreeKeyPair(ss->stepDownKeyPair);
        }
        ss->stepDownKeyPair = ssl3_GetKeyPairRef(sm->stepDownKeyPair);
    }
    if (sm->ephemeralECDHKeyPair) {
        if (ss->ephemeralECDHKeyPair) {
            ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
        }
        ss->ephemeralECDHKeyPair =
            ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
    }
    /* copy trust anchor names */
    if (sm->ssl3.ca_list) {
        if (ss->ssl3.ca_list) {
            CERT_FreeDistNames(ss->ssl3.ca_list);
        }
        ss->ssl3.ca_list = CERT_DupDistNames(sm->ssl3.ca_list);
        if (!ss->ssl3.ca_list) {
            goto loser;
        }
    }
    
    if (sm->authCertificate)
        ss->authCertificate       = sm->authCertificate;
    if (sm->authCertificateArg)
        ss->authCertificateArg    = sm->authCertificateArg;
    if (sm->getClientAuthData)
        ss->getClientAuthData     = sm->getClientAuthData;
    if (sm->getClientAuthDataArg)
        ss->getClientAuthDataArg  = sm->getClientAuthDataArg;
#ifdef NSS_PLATFORM_CLIENT_AUTH
    if (sm->getPlatformClientAuthData)
        ss->getPlatformClientAuthData    = sm->getPlatformClientAuthData;
    if (sm->getPlatformClientAuthDataArg)
        ss->getPlatformClientAuthDataArg = sm->getPlatformClientAuthDataArg;
#endif
    if (sm->sniSocketConfig)
        ss->sniSocketConfig       = sm->sniSocketConfig;
    if (sm->sniSocketConfigArg)
        ss->sniSocketConfigArg    = sm->sniSocketConfigArg;
    if (sm->handleBadCert)
        ss->handleBadCert         = sm->handleBadCert;
    if (sm->badCertArg)
        ss->badCertArg            = sm->badCertArg;
    if (sm->handshakeCallback)
        ss->handshakeCallback     = sm->handshakeCallback;
    if (sm->handshakeCallbackData)
        ss->handshakeCallbackData = sm->handshakeCallbackData;
    if (sm->pkcs11PinArg)
        ss->pkcs11PinArg          = sm->pkcs11PinArg;
    if (sm->getChannelID)
        ss->getChannelID          = sm->getChannelID;
    if (sm->getChannelIDArg)
        ss->getChannelIDArg       = sm->getChannelIDArg;
    return fd;
loser:
    return NULL;
}

PRBool
ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
			SSL3ProtocolVersion version)
{
    switch (protocolVariant) {
    case ssl_variant_stream:
	return (version >= SSL_LIBRARY_VERSION_3_0 &&
		version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
    case ssl_variant_datagram:
	return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
		version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
    default:
	/* Can't get here */
	PORT_Assert(PR_FALSE);
	return PR_FALSE;
    }
}

/* Returns PR_TRUE if the given version range is valid and
** fully supported; otherwise, returns PR_FALSE.
*/
static PRBool
ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
			 const SSLVersionRange *vrange)
{
    return vrange &&
	   vrange->min <= vrange->max &&
	   ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
	   ssl3_VersionIsSupported(protocolVariant, vrange->max);
}

SECStatus
SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
			     SSLVersionRange *vrange)
{
    if (!vrange) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    switch (protocolVariant) {
    case ssl_variant_stream:
	vrange->min = SSL_LIBRARY_VERSION_3_0;
	vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
	break;
    case ssl_variant_datagram:
	vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
	vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
	break;
    default:
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    return SECSuccess;
}

SECStatus
SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
			   SSLVersionRange *vrange)
{
    if ((protocolVariant != ssl_variant_stream &&
	 protocolVariant != ssl_variant_datagram) || !vrange) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    *vrange = *VERSIONS_DEFAULTS(protocolVariant);

    return SECSuccess;
}

SECStatus
SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
			   const SSLVersionRange *vrange)
{
    if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
	PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
	return SECFailure;
    }

    *VERSIONS_DEFAULTS(protocolVariant) = *vrange;

    return SECSuccess;
}

SECStatus
SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeGet",
		SSL_GETPID(), fd));
	return SECFailure;
    }

    if (!vrange) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    *vrange = ss->vrange;

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}

static PRCallOnceType checkTLS12TokenOnce;
static PRBool tls12TokenExists;

static PRStatus  
ssl_CheckTLS12Token(void)
{
    tls12TokenExists =
	PK11_TokenExists(CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256);
    return PR_SUCCESS;
}

static PRBool
ssl_TLS12TokenExists(void)
{
    (void) PR_CallOnce(&checkTLS12TokenOnce, ssl_CheckTLS12Token);
    return tls12TokenExists;
}

SECStatus
SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeSet",
		SSL_GETPID(), fd));
	return SECFailure;
    }

    if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
	PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
	return SECFailure;
    }

    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    ss->vrange = *vrange;
    /* If we don't have a sufficiently up-to-date softoken then we cannot do
     * TLS 1.2. */
    if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_2 &&
        !ssl_TLS12TokenExists()) {
	/* If the user requested a minimum version of 1.2, then we don't
	 * silently downgrade. */
	if (ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_2) {
	    ssl_ReleaseSSL3HandshakeLock(ss);
	    ssl_Release1stHandshakeLock(ss);
	    PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
	    return SECFailure;
	}
	ss->vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;
    }

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);

    return SECSuccess;
}

const SECItemArray *
SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
       SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerStapledOCSPResponses",
                SSL_GETPID(), fd));
       return NULL;
    }

    if (!ss->sec.ci.sid) {
       PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
       return NULL;
    }
    
    return &ss->sec.ci.sid->peerCertStatus;
}

const SECItem *
SSL_PeerSignedCertTimestamps(PRFileDesc *fd)
{
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
       SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerSignedCertTimestamps",
		SSL_GETPID(), fd));
       return NULL;
    }

    if (!ss->sec.ci.sid) {
       PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
       return NULL;
    }

    if (ss->sec.ci.sid->version < SSL_LIBRARY_VERSION_3_0) {
	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
	return NULL;
    }
    return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps;
}

SECStatus
SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
    sslSocket *ss = ssl_FindSocket(fd);

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_HandshakeResumedSession",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    *handshake_resumed = ss->ssl3.hs.isResuming;
    return SECSuccess;
}

const SECItem *
SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd)
{
  sslSocket *ss = ssl_FindSocket(fd);

  if (!ss) {
      SSL_DBG(("%d: SSL[%d]: bad socket in "
               "SSL_GetRequestedClientCertificateTypes", SSL_GETPID(), fd));
      return NULL;
  }

  return ss->requestedCertTypes;
}

/************************************************************************/
/* The following functions are the TOP LEVEL SSL functions.
** They all get called through the NSPRIOMethods table below.
*/

static PRFileDesc * PR_CALLBACK
ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
{
    sslSocket  *ss;
    sslSocket  *ns 	= NULL;
    PRFileDesc *newfd 	= NULL;
    PRFileDesc *osfd;
    PRStatus    status;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd));
	return NULL;
    }

    /* IF this is a listen socket, there shouldn't be any I/O going on */
    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);
    ssl_Get1stHandshakeLock(ss);
    ssl_GetSSL3HandshakeLock(ss);

    ss->cTimeout = timeout;

    osfd = ss->fd->lower;

    /* First accept connection */
    newfd = osfd->methods->accept(osfd, sockaddr, timeout);
    if (newfd == NULL) {
	SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d",
		 SSL_GETPID(), ss->fd, PORT_GetError()));
    } else {
	/* Create ssl module */
	ns = ssl_DupSocket(ss);
    }

    ssl_ReleaseSSL3HandshakeLock(ss);
    ssl_Release1stHandshakeLock(ss);
    SSL_UNLOCK_WRITER(ss);
    SSL_UNLOCK_READER(ss);			/* ss isn't used below here. */

    if (ns == NULL)
	goto loser;

    /* push ssl module onto the new socket */
    status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER);
    if (status != PR_SUCCESS)
	goto loser;

    /* Now start server connection handshake with client.
    ** Don't need locks here because nobody else has a reference to ns yet.
    */
    if ( ns->opt.useSecurity ) {
	if ( ns->opt.handshakeAsClient ) {
	    ns->handshake = ssl2_BeginClientHandshake;
	    ss->handshaking = sslHandshakingAsClient;
	} else {
	    ns->handshake = ssl2_BeginServerHandshake;
	    ss->handshaking = sslHandshakingAsServer;
	}
    }
    ns->TCPconnected = 1;
    return newfd;

loser:
    if (ns != NULL)
	ssl_FreeSocket(ns);
    if (newfd != NULL)
	PR_Close(newfd);
    return NULL;
}

static PRStatus PR_CALLBACK
ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
{
    sslSocket *ss;
    PRStatus   rv;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd));
	return PR_FAILURE;
    }

    /* IF this is a listen socket, there shouldn't be any I/O going on */
    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);

    ss->cTimeout = timeout;
    rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);

    SSL_UNLOCK_WRITER(ss);
    SSL_UNLOCK_READER(ss);

    return rv;
}

static PRStatus PR_CALLBACK
ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
{
    sslSocket * ss = ssl_GetPrivate(fd);
    PRStatus    rv;

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
	return PR_FAILURE;
    }
    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);

    rv = (PRStatus)(*ss->ops->bind)(ss, addr);

    SSL_UNLOCK_WRITER(ss);
    SSL_UNLOCK_READER(ss);
    return rv;
}

static PRStatus PR_CALLBACK
ssl_Listen(PRFileDesc *fd, PRIntn backlog)
{
    sslSocket * ss = ssl_GetPrivate(fd);
    PRStatus    rv;

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
	return PR_FAILURE;
    }
    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);

    rv = (PRStatus)(*ss->ops->listen)(ss, backlog);

    SSL_UNLOCK_WRITER(ss);
    SSL_UNLOCK_READER(ss);
    return rv;
}

static PRStatus PR_CALLBACK
ssl_Shutdown(PRFileDesc *fd, PRIntn how)
{
    sslSocket * ss = ssl_GetPrivate(fd);
    PRStatus    rv;

    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
	return PR_FAILURE;
    }
    if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
    	SSL_LOCK_READER(ss);
    }
    if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
    	SSL_LOCK_WRITER(ss);
    }

    rv = (PRStatus)(*ss->ops->shutdown)(ss, how);

    if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
    	SSL_UNLOCK_WRITER(ss);
    }
    if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
    	SSL_UNLOCK_READER(ss);
    }
    return rv;
}

static PRStatus PR_CALLBACK
ssl_Close(PRFileDesc *fd)
{
    sslSocket *ss;
    PRStatus   rv;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd));
	return PR_FAILURE;
    }

    /* There must not be any I/O going on */
    SSL_LOCK_READER(ss);
    SSL_LOCK_WRITER(ss);

    /* By the time this function returns, 
    ** ss is an invalid pointer, and the locks to which it points have 
    ** been unlocked and freed.  So, this is the ONE PLACE in all of SSL
    ** where the LOCK calls and the corresponding UNLOCK calls are not in
    ** the same function scope.  The unlock calls are in ssl_FreeSocket().
    */
    rv = (PRStatus)(*ss->ops->close)(ss);

    return rv;
}

static int PR_CALLBACK
ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
	 PRIntervalTime timeout)
{
    sslSocket *ss;
    int        rv;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd));
	return SECFailure;
    }
    SSL_LOCK_READER(ss);
    ss->rTimeout = timeout;
    if (!ss->opt.fdx)
	ss->wTimeout = timeout;
    rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
    SSL_UNLOCK_READER(ss);
    return rv;
}

static int PR_CALLBACK
ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
	 PRIntervalTime timeout)
{
    sslSocket *ss;
    int        rv;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd));
	return SECFailure;
    }
    SSL_LOCK_WRITER(ss);
    ss->wTimeout = timeout;
    if (!ss->opt.fdx)
	ss->rTimeout = timeout;
    rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
    SSL_UNLOCK_WRITER(ss);
    return rv;
}

static int PR_CALLBACK
ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
{
    sslSocket *ss;
    int        rv;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd));
	return SECFailure;
    }
    SSL_LOCK_READER(ss);
    ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
    if (!ss->opt.fdx)
	ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
    rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
    SSL_UNLOCK_READER(ss);
    return rv;
}

static int PR_CALLBACK
ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
{
    sslSocket *ss;
    int        rv;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd));
	return SECFailure;
    }
    SSL_LOCK_WRITER(ss);
    ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
    if (!ss->opt.fdx)
	ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
    rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
    SSL_UNLOCK_WRITER(ss);
    return rv;
}

static PRStatus PR_CALLBACK
ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
{
    sslSocket *ss;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd));
	return PR_FAILURE;
    }
    return (PRStatus)(*ss->ops->getpeername)(ss, addr);
}

/*
*/
SECStatus
ssl_GetPeerInfo(sslSocket *ss)
{
    PRFileDesc *      osfd;
    int               rv;
    PRNetAddr         sin;

    osfd = ss->fd->lower;

    PORT_Memset(&sin, 0, sizeof(sin));
    rv = osfd->methods->getpeername(osfd, &sin);
    if (rv < 0) {
	return SECFailure;
    }
    ss->TCPconnected = 1;
    if (sin.inet.family == PR_AF_INET) {
        PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ss->sec.ci.peer);
	ss->sec.ci.port = sin.inet.port;
    } else if (sin.ipv6.family == PR_AF_INET6) {
	ss->sec.ci.peer = sin.ipv6.ip;
	ss->sec.ci.port = sin.ipv6.port;
    } else {
	PORT_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR);
    	return SECFailure;
    }
    return SECSuccess;
}

static PRStatus PR_CALLBACK
ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
{
    sslSocket *ss;

    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd));
	return PR_FAILURE;
    }
    return (PRStatus)(*ss->ops->getsockname)(ss, name);
}

SECStatus
SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
			    SSLKEAType kea)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    if ( kea <= 0 || kea >= kt_kea_size) {
	SSL_DBG(("%d: SSL[%d]: invalid key in SSL_SetStapledOCSPResponses",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    if (ss->certStatusArray[kea]) {
        SECITEM_FreeArray(ss->certStatusArray[kea], PR_TRUE);
        ss->certStatusArray[kea] = NULL;
    }
    if (responses) {
	ss->certStatusArray[kea] = SECITEM_DupArray(NULL, responses);
    }
    return (ss->certStatusArray[kea] || !responses) ? SECSuccess : SECFailure;
}

SECStatus
SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
{
    sslSocket *ss;

    ss = ssl_FindSocket(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSockPeerID",
		 SSL_GETPID(), fd));
	return SECFailure;
    }

    if (ss->peerID) {
    	PORT_Free(ss->peerID);
	ss->peerID = NULL;
    }
    if (peerID)
	ss->peerID = PORT_Strdup(peerID);
    return (ss->peerID || !peerID) ? SECSuccess : SECFailure;
}

#define PR_POLL_RW (PR_POLL_WRITE | PR_POLL_READ)

static PRInt16 PR_CALLBACK
ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
{
    sslSocket *ss;
    PRInt16    new_flags = how_flags;	/* should select on these flags. */
    PRNetAddr  addr;

    *p_out_flags = 0;
    ss = ssl_GetPrivate(fd);
    if (!ss) {
	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll",
		 SSL_GETPID(), fd));
	return 0;	/* don't poll on this socket */
    }

    if (ss->opt.useSecurity && 
	ss->handshaking != sslHandshakingUndetermined &&
        !ss->firstHsDone &&
	(how_flags & PR_POLL_RW)) {
	if (!ss->TCPconnected) {
	    ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
	}
	/* If it's not connected, then presumably the application is polling
	** on read or write appropriately, so don't change it. 
	*/
	if (ss->TCPconnected) {
	    if (!ss->handshakeBegun) {
		/* If the handshake has not begun, poll on read or write 
		** based on the local application's role in the handshake,
		** not based on what the application requested.
		*/
		new_flags &= ~PR_POLL_RW;
		if (ss->handshaking == sslHandshakingAsClient) {
		    new_flags |= PR_POLL_WRITE;
		} else { /* handshaking as server */
		    new_flags |= PR_POLL_READ;
		}
	    } else 
	    /* First handshake is in progress */
	    if (ss->lastWriteBlocked) {
		if (new_flags & PR_POLL_READ) {
		    /* The caller is waiting for data to be received, 
		    ** but the initial handshake is blocked on write, or the 
		    ** client's first handshake record has not been written.
		    ** The code should select on write, not read.
		    */
		    new_flags ^=  PR_POLL_READ;	   /* don't select on read. */
		    new_flags |=  PR_POLL_WRITE;   /* do    select on write. */
		}
	    } else if (new_flags & PR_POLL_WRITE) {
		    /* The caller is trying to write, but the handshake is 
		    ** blocked waiting for data to read, and the first 
		    ** handshake has been sent.  So do NOT to poll on write
		    ** unless we did false start.
		    */
		    if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
			ss->ssl3.hs.canFalseStart)) {
			new_flags ^= PR_POLL_WRITE; /* don't select on write. */
		    }
		    new_flags |= PR_POLL_READ;      /* do    select on read. */
	    }
	}
    } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
	*p_out_flags = PR_POLL_READ;	/* it's ready already. */
	return new_flags;
    } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
	       (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
	new_flags |=  PR_POLL_WRITE;   /* also select on write. */
    }

    if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
	ss->ssl3.hs.restartTarget != NULL) {
	/* Read and write will block until the asynchronous callback completes
	 * (e.g. until SSL_AuthCertificateComplete is called), so don't tell
	 * the caller to poll the socket unless there is pending write data.
	 */
	if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) {
	    /* Ignore any newly-received data on the socket, but do wait for
	     * the socket to become writable again. Here, it is OK for an error
	     * to be detected, because our logic for sending pending write data
	     * will allow us to report the error to the caller without the risk
	     * of the application spinning.
	     */
	    new_flags &= (PR_POLL_WRITE | PR_POLL_EXCEPT);
	} else {
	    /* Unfortunately, clearing new_flags will make it impossible for
	     * the application to detect errors that it would otherwise be
	     * able to detect with PR_POLL_EXCEPT, until the asynchronous
	     * callback completes. However, we must clear all the flags to
	     * prevent the application from spinning (alternating between
	     * calling PR_Poll that would return PR_POLL_EXCEPT, and send/recv
	     * which won't actually report the I/O error while we are waiting
	     * for the asynchronous callback to complete).
	     */
	    new_flags = 0;
	}
    }

    if (new_flags && (fd->lower->methods->poll != NULL)) {
	PRInt16    lower_out_flags = 0;
	PRInt16    lower_new_flags;
        lower_new_flags = fd->lower->methods->poll(fd->lower, new_flags, 
					           &lower_out_flags);
	if ((lower_new_flags & lower_out_flags) && (how_flags != new_flags)) {
	    PRInt16 out_flags = lower_out_flags & ~PR_POLL_RW;
	    if (lower_out_flags & PR_POLL_READ) 
		out_flags |= PR_POLL_WRITE;
	    if (lower_out_flags & PR_POLL_WRITE) 
		out_flags |= PR_POLL_READ;
	    *p_out_flags = out_flags;
	    new_flags = how_flags;
	} else {
	    *p_out_flags = lower_out_flags;
	    new_flags    = lower_new_flags;
	}
    }

    return new_flags;
}

static PRInt32 PR_CALLBACK
ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
		 const void *headers, PRInt32 hlen,
		 PRTransmitFileFlags flags, PRIntervalTime timeout)
{
    PRSendFileData sfd;

    sfd.fd = fd;
    sfd.file_offset = 0;
    sfd.file_nbytes = 0;
    sfd.header = headers;
    sfd.hlen = hlen;
    sfd.trailer = NULL;
    sfd.tlen = 0;

    return sd->methods->sendfile(sd, &sfd, flags, timeout);
}


PRBool
ssl_FdIsBlocking(PRFileDesc *fd)
{
    PRSocketOptionData opt;
    PRStatus           status;

    opt.option             = PR_SockOpt_Nonblocking;
    opt.value.non_blocking = PR_FALSE;
    status = PR_GetSocketOption(fd, &opt);
    if (status != PR_SUCCESS)
	return PR_FALSE;
    return (PRBool)!opt.value.non_blocking;
}

PRBool
ssl_SocketIsBlocking(sslSocket *ss)
{
    return ssl_FdIsBlocking(ss->fd);
}

PRInt32  sslFirstBufSize = 8 * 1024;
PRInt32  sslCopyLimit    = 1024;

static PRInt32 PR_CALLBACK
ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors, 
           PRIntervalTime timeout)
{
    PRInt32            bufLen;
    PRInt32            left;
    PRInt32            rv;
    PRInt32            sent      =  0;
    const PRInt32      first_len = sslFirstBufSize;
    const PRInt32      limit     = sslCopyLimit;
    PRBool             blocking;
    PRIOVec            myIov	 = { 0, 0 };
    char               buf[MAX_FRAGMENT_LENGTH];

    if (vectors > PR_MAX_IOVECTOR_SIZE) {
    	PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
	return -1;
    }
    blocking = ssl_FdIsBlocking(fd);

#define K16 sizeof(buf)
#define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
#define GET_VECTOR   do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
#define HANDLE_ERR(rv, len) \
    if (rv != len) { \
	if (rv < 0) { \
	    if (!blocking \
		&& (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
		&& (sent > 0)) { \
		return sent; \
	    } else { \
		return -1; \
	    } \
	} \
	/* Only a nonblocking socket can have partial sends */ \
	PR_ASSERT(!blocking); \
	return sent + rv; \
    } 
#define SEND(bfr, len) \
    do { \
	rv = ssl_Send(fd, bfr, len, 0, timeout); \
	HANDLE_ERR(rv, len) \
	sent += len; \
    } while (0)

    /* Make sure the first write is at least 8 KB, if possible. */
    KILL_VECTORS
    if (!vectors)
	return ssl_Send(fd, 0, 0, 0, timeout);
    GET_VECTOR;
    if (!vectors) {
	return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
    }
    if (myIov.iov_len < first_len) {
	PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
	bufLen = myIov.iov_len;
	left = first_len - bufLen;
	while (vectors && left) {
	    int toCopy;
	    GET_VECTOR;
	    toCopy = PR_MIN(left, myIov.iov_len);
	    PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
	    bufLen         += toCopy;
	    left           -= toCopy;
	    myIov.iov_base += toCopy;
	    myIov.iov_len  -= toCopy;
	}
	SEND( buf, bufLen );
    }

    while (vectors || myIov.iov_len) {
	PRInt32   addLen;
	if (!myIov.iov_len) {
	    GET_VECTOR;
	}
	while (myIov.iov_len >= K16) {
	    SEND(myIov.iov_base, K16);
	    myIov.iov_base += K16;
	    myIov.iov_len  -= K16;
	}
	if (!myIov.iov_len)
	    continue;

	if (!vectors || myIov.iov_len > limit) {
	    addLen = 0;
	} else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
	    /* Addlen is already computed. */;
	} else if (vectors > 1 && 
	     iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
	     addLen = limit - myIov.iov_len;
	} else 
	    addLen = 0;

	if (!addLen) {
	    SEND( myIov.iov_base, myIov.iov_len );
	    myIov.iov_len = 0;
	    continue;
	}
	PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
	bufLen = myIov.iov_len;
	do {
	    GET_VECTOR;
	    PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
	    myIov.iov_base += addLen;
	    myIov.iov_len  -= addLen;
	    bufLen         += addLen;

	    left = PR_MIN( limit, K16 - bufLen);
	    if (!vectors 		/* no more left */
	    ||  myIov.iov_len > 0	/* we didn't use that one all up */
	    ||  bufLen >= K16		/* it's full. */
	    ) {
		addLen = 0;
	    } else if ((addLen = iov->iov_len % K16) <= left) {
		/* Addlen is already computed. */;
	    } else if (vectors > 1 && 
		 iov[1].iov_len % K16 + addLen <= left + limit) {
		 addLen = left;
	    } else 
		addLen = 0;

	} while (addLen);
	SEND( buf, bufLen );
    } 
    return sent;
}

/*
 * These functions aren't implemented.
 */

static PRInt32 PR_CALLBACK
ssl_Available(PRFileDesc *fd)
{
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return SECFailure;
}

static PRInt64 PR_CALLBACK
ssl_Available64(PRFileDesc *fd)
{
    PRInt64 res;

    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    LL_I2L(res, -1L);
    return res;
}

static PRStatus PR_CALLBACK
ssl_FSync(PRFileDesc *fd)
{
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
}

static PRInt32 PR_CALLBACK
ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return SECFailure;
}

static PRInt64 PR_CALLBACK
ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
    PRInt64 res;

    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    LL_I2L(res, -1L);
    return res;
}

static PRStatus PR_CALLBACK
ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
{
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
}

static PRStatus PR_CALLBACK
ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
{
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
}

static PRInt32 PR_CALLBACK
ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
	     PRNetAddr *addr, PRIntervalTime timeout)
{
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return SECFailure;
}

static PRInt32 PR_CALLBACK
ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
	   const PRNetAddr *addr, PRIntervalTime timeout)
{
    PORT_Assert(0);
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return SECFailure;
}

static const PRIOMethods ssl_methods = {
    PR_DESC_LAYERED,
    ssl_Close,           	/* close        */
    ssl_Read,            	/* read         */
    ssl_Write,           	/* write        */
    ssl_Available,       	/* available    */
    ssl_Available64,     	/* available64  */
    ssl_FSync,           	/* fsync        */
    ssl_Seek,            	/* seek         */
    ssl_Seek64,          	/* seek64       */
    ssl_FileInfo,        	/* fileInfo     */
    ssl_FileInfo64,      	/* fileInfo64   */
    ssl_WriteV,          	/* writev       */
    ssl_Connect,         	/* connect      */
    ssl_Accept,          	/* accept       */
    ssl_Bind,            	/* bind         */
    ssl_Listen,          	/* listen       */
    ssl_Shutdown,        	/* shutdown     */
    ssl_Recv,            	/* recv         */
    ssl_Send,            	/* send         */
    ssl_RecvFrom,        	/* recvfrom     */
    ssl_SendTo,          	/* sendto       */
    ssl_Poll,            	/* poll         */
    PR_EmulateAcceptRead,       /* acceptread   */
    ssl_TransmitFile,           /* transmitfile */
    ssl_GetSockName,     	/* getsockname  */
    ssl_GetPeerName,     	/* getpeername  */
    NULL,                	/* getsockopt   OBSOLETE */
    NULL,                	/* setsockopt   OBSOLETE */
    NULL,                	/* getsocketoption   */
    NULL,                	/* setsocketoption   */
    PR_EmulateSendFile, 	/* Send a (partial) file with header/trailer*/
    NULL,                	/* reserved for future use */
    NULL,                	/* reserved for future use */
    NULL,                	/* reserved for future use */
    NULL,                	/* reserved for future use */
    NULL                 	/* reserved for future use */
};


static PRIOMethods combined_methods;

static void
ssl_SetupIOMethods(void)
{
          PRIOMethods *new_methods  = &combined_methods;
    const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
    const PRIOMethods *my_methods   = &ssl_methods;

    *new_methods = *nspr_methods;

    new_methods->file_type         = my_methods->file_type;
    new_methods->close             = my_methods->close;
    new_methods->read              = my_methods->read;
    new_methods->write             = my_methods->write;
    new_methods->available         = my_methods->available;
    new_methods->available64       = my_methods->available64;
    new_methods->fsync             = my_methods->fsync;
    new_methods->seek              = my_methods->seek;
    new_methods->seek64            = my_methods->seek64;
    new_methods->fileInfo          = my_methods->fileInfo;
    new_methods->fileInfo64        = my_methods->fileInfo64;
    new_methods->writev            = my_methods->writev;
    new_methods->connect           = my_methods->connect;
    new_methods->accept            = my_methods->accept;
    new_methods->bind              = my_methods->bind;
    new_methods->listen            = my_methods->listen;
    new_methods->shutdown          = my_methods->shutdown;
    new_methods->recv              = my_methods->recv;
    new_methods->send              = my_methods->send;
    new_methods->recvfrom          = my_methods->recvfrom;
    new_methods->sendto            = my_methods->sendto;
    new_methods->poll              = my_methods->poll;
    new_methods->acceptread        = my_methods->acceptread;
    new_methods->transmitfile      = my_methods->transmitfile;
    new_methods->getsockname       = my_methods->getsockname;
    new_methods->getpeername       = my_methods->getpeername;
/*  new_methods->getsocketoption   = my_methods->getsocketoption;	*/
/*  new_methods->setsocketoption   = my_methods->setsocketoption;	*/
    new_methods->sendfile          = my_methods->sendfile;

}

static PRCallOnceType initIoLayerOnce;

static PRStatus  
ssl_InitIOLayer(void)
{
    ssl_layer_id = PR_GetUniqueIdentity("SSL");
    ssl_SetupIOMethods();
    ssl_inited = PR_TRUE;
    return PR_SUCCESS;
}

static PRStatus
ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
{
    PRFileDesc *layer	= NULL;
    PRStatus    status;

    if (!ssl_inited) {
	status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
	if (status != PR_SUCCESS)
	    goto loser;
    }

    if (ns == NULL)
	goto loser;

    layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
    if (layer == NULL)
	goto loser;
    layer->secret = (PRFilePrivate *)ns;

    /* Here, "stack" points to the PRFileDesc on the top of the stack.
    ** "layer" points to a new FD that is to be inserted into the stack.
    ** If layer is being pushed onto the top of the stack, then 
    ** PR_PushIOLayer switches the contents of stack and layer, and then
    ** puts stack on top of layer, so that after it is done, the top of 
    ** stack is the same "stack" as it was before, and layer is now the 
    ** FD for the former top of stack.
    ** After this call, stack always points to the top PRFD on the stack.
    ** If this function fails, the contents of stack and layer are as 
    ** they were before the call.
    */
    status = PR_PushIOLayer(stack, id, layer);
    if (status != PR_SUCCESS)
	goto loser;

    ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
    return PR_SUCCESS;

loser:
    if (layer) {
	layer->dtor(layer); /* free layer */
    }
    return PR_FAILURE;
}

/* if this fails, caller must destroy socket. */
static SECStatus
ssl_MakeLocks(sslSocket *ss)
{
    ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
    if (!ss->firstHandshakeLock) 
	goto loser;
    ss->ssl3HandshakeLock  = PZ_NewMonitor(nssILockSSL);
    if (!ss->ssl3HandshakeLock) 
	goto loser;
    ss->specLock           = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
    if (!ss->specLock) 
	goto loser;
    ss->recvBufLock        = PZ_NewMonitor(nssILockSSL);
    if (!ss->recvBufLock) 
	goto loser;
    ss->xmitBufLock        = PZ_NewMonitor(nssILockSSL);
    if (!ss->xmitBufLock) 
	goto loser;
    ss->writerThread       = NULL;
    if (ssl_lock_readers) {
	ss->recvLock       = PZ_NewLock(nssILockSSL);
	if (!ss->recvLock) 
	    goto loser;
	ss->sendLock       = PZ_NewLock(nssILockSSL);
	if (!ss->sendLock) 
	    goto loser;
    }
    return SECSuccess;
loser:
    ssl_DestroyLocks(ss);
    return SECFailure;
}

#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)
#define NSS_HAVE_GETENV 1
#endif

#define LOWER(x) (x | 0x20)  /* cheap ToLower function ignores LOCALE */

static void
ssl_SetDefaultsFromEnvironment(void)
{
#if defined( NSS_HAVE_GETENV )
    static int firsttime = 1;

    if (firsttime) {
	char * ev;
	firsttime = 0;
#ifdef DEBUG
	ev = getenv("SSLDEBUGFILE");
	if (ev && ev[0]) {
	    ssl_trace_iob = fopen(ev, "w");
	}
	if (!ssl_trace_iob) {
	    ssl_trace_iob = stderr;
	}
#ifdef TRACE
	ev = getenv("SSLTRACE");
	if (ev && ev[0]) {
	    ssl_trace = atoi(ev);
	    SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
	}
#endif /* TRACE */
	ev = getenv("SSLDEBUG");
	if (ev && ev[0]) {
	    ssl_debug = atoi(ev);
	    SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
	}
#endif /* DEBUG */
	ev = getenv("SSLKEYLOGFILE");
	if (ev && ev[0]) {
	    ssl_keylog_iob = fopen(ev, "a");
	    if (!ssl_keylog_iob) {
		SSL_TRACE(("SSL: failed to open key log file"));
	    } else {
		if (ftell(ssl_keylog_iob) == 0) {
		    fputs("# SSL/TLS secrets log file, generated by NSS\n",
			  ssl_keylog_iob);
		}
		SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
	    }
	}
#ifndef NO_PKCS11_BYPASS
	ev = getenv("SSLBYPASS");
	if (ev && ev[0]) {
	    ssl_defaults.bypassPKCS11 = (ev[0] == '1');
	    SSL_TRACE(("SSL: bypass default set to %d", \
		      ssl_defaults.bypassPKCS11));
	}
#endif /* NO_PKCS11_BYPASS */
	ev = getenv("SSLFORCELOCKS");
	if (ev && ev[0] == '1') {
	    ssl_force_locks = PR_TRUE;
	    ssl_defaults.noLocks = 0;
	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED.  ");
	    SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
	}
	ev = getenv("NSS_SSL_ENABLE_RENEGOTIATION");
	if (ev) {
	    if (ev[0] == '1' || LOWER(ev[0]) == 'u')
	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_UNRESTRICTED;
	    else if (ev[0] == '0' || LOWER(ev[0]) == 'n')
	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
	    else if (ev[0] == '2' || LOWER(ev[0]) == 'r')
		ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN;
	    else if (ev[0] == '3' || LOWER(ev[0]) == 't')
	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_TRANSITIONAL;
	    SSL_TRACE(("SSL: enableRenegotiation set to %d", 
	               ssl_defaults.enableRenegotiation));
	}
	ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
	if (ev && ev[0] == '1') {
	    ssl_defaults.requireSafeNegotiation = PR_TRUE;
	    SSL_TRACE(("SSL: requireSafeNegotiation set to %d", 
	                PR_TRUE));
	}
	ev = getenv("NSS_SSL_CBC_RANDOM_IV");
	if (ev && ev[0] == '0') {
	    ssl_defaults.cbcRandomIV = PR_FALSE;
	    SSL_TRACE(("SSL: cbcRandomIV set to 0"));
	}
    }
#endif /* NSS_HAVE_GETENV */
}

/*
** Create a newsocket structure for a file descriptor.
*/
static sslSocket *
ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
{
    sslSocket *ss;

    ssl_SetDefaultsFromEnvironment();

    if (ssl_force_locks)
	makeLocks = PR_TRUE;

    /* Make a new socket and get it ready */
    ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
    if (ss) {
        /* This should be of type SSLKEAType, but CC on IRIX
	 * complains during the for loop.
	 */
	int i;
	SECStatus status;
 
	ss->opt                = ssl_defaults;
	ss->opt.useSocks       = PR_FALSE;
	ss->opt.noLocks        = !makeLocks;
	ss->vrange             = *VERSIONS_DEFAULTS(protocolVariant);
	ss->protocolVariant    = protocolVariant;

	ss->peerID             = NULL;
	ss->rTimeout	       = PR_INTERVAL_NO_TIMEOUT;
	ss->wTimeout	       = PR_INTERVAL_NO_TIMEOUT;
	ss->cTimeout	       = PR_INTERVAL_NO_TIMEOUT;
	ss->cipherSpecs        = NULL;
        ss->sizeCipherSpecs    = 0;  /* produced lazily */
        ss->preferredCipher    = NULL;
        ss->url                = NULL;

	for (i=kt_null; i < kt_kea_size; i++) {
	    sslServerCerts * sc = ss->serverCerts + i;
	    sc->serverCert      = NULL;
	    sc->serverCertChain = NULL;
	    sc->serverKeyPair   = NULL;
	    sc->serverKeyBits   = 0;
	    ss->certStatusArray[i] = NULL;
	}
	ss->requestedCertTypes = NULL;
	ss->stepDownKeyPair    = NULL;
	ss->dbHandle           = CERT_GetDefaultCertDB();

	/* Provide default implementation of hooks */
	ss->authCertificate    = SSL_AuthCertificate;
	ss->authCertificateArg = (void *)ss->dbHandle;
        ss->sniSocketConfig    = NULL;
        ss->sniSocketConfigArg = NULL;
	ss->getClientAuthData  = NULL;
#ifdef NSS_PLATFORM_CLIENT_AUTH
	ss->getPlatformClientAuthData = NULL;
	ss->getPlatformClientAuthDataArg = NULL;
#endif   /* NSS_PLATFORM_CLIENT_AUTH */
	ss->handleBadCert      = NULL;
	ss->badCertArg         = NULL;
	ss->pkcs11PinArg       = NULL;
	ss->ephemeralECDHKeyPair = NULL;
	ss->getChannelID       = NULL;
	ss->getChannelIDArg    = NULL;

	ssl_ChooseOps(ss);
	ssl2_InitSocketPolicy(ss);
	ssl3_InitSocketPolicy(ss);
	PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);

	if (makeLocks) {
	    status = ssl_MakeLocks(ss);
	    if (status != SECSuccess)
		goto loser;
	}
	status = ssl_CreateSecurityInfo(ss);
	if (status != SECSuccess) 
	    goto loser;
	status = ssl_InitGather(&ss->gs);
	if (status != SECSuccess) {
loser:
	    ssl_DestroySocketContents(ss);
	    ssl_DestroyLocks(ss);
	    PORT_Free(ss);
	    ss = NULL;
	}
    }
    return ss;
}

