15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * vtables (and methods that call through them) for the 4 types of
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SSLSockets supported.  Only one type is still supported.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Various other functions.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This Source Code Form is subject to the terms of the Mozilla Public
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * License, v. 2.0. If a copy of the MPL was not distributed with this
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "seccomon.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cert.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "keyhi.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ssl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslimpl.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sslproto.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nspr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "private/pprio.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "blapi.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "pk11pub.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "nss.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)/* This is a bodge to allow this code to be compiled against older NSS headers
24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * that don't contain the TLS 1.2 changes. */
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24)
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SET_ERROR_CODE   /* reminder */
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const sslSocketOps ssl_default_ops = {	/* No SSL. */
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefConnect,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefBind,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefListen,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefShutdown,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefClose,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefRecv,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefSend,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefRead,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefWrite,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetpeername,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetsockname
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const sslSocketOps ssl_secure_ops = {	/* SSL. */
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureConnect,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefBind,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefListen,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureShutdown,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureClose,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureRecv,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureSend,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureRead,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureWrite,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetpeername,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetsockname
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** default settings for socket enables
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslOptions ssl_defaults = {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { siBuffer, NULL, 0 }, /* nextProtoNego */
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_TRUE, 	/* useSecurity        */
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* useSocks           */
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* requestCertificate */
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,	        /* requireCertificate */
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* handshakeAsClient  */
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* handshakeAsServer  */
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* unusedBit9         */
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE, 	/* unusedBit10        */
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* noCache            */
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* fdx                */
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_TRUE,	/* detectRollBack     */
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* noStepDown         */
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* bypassPKCS11       */
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* noLocks            */
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* enableSessionTickets */
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* enableDeflate      */
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,          /* enableRenegotiation (default: requires extension) */
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* requireSafeNegotiation */
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* enableFalseStart   */
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_TRUE,    /* cbcRandomIV        */
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PR_FALSE,   /* enableOCSPStapling */
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PR_TRUE,    /* enableNPN          */
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PR_FALSE,   /* enableALPN         */
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PR_FALSE,   /* enableSignedCertTimestamps */
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    PR_FALSE    /* enableFallbackSCSV */
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * default range of enabled SSL/TLS protocols
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SSLVersionRange versions_defaults_stream = {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_3_0,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_TLS_1_0
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SSLVersionRange versions_defaults_datagram = {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_TLS_1_1,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_TLS_1_1
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VERSIONS_DEFAULTS(variant) \
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (variant == ssl_variant_stream ? &versions_defaults_stream : \
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &versions_defaults_datagram)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionIDLookupFunc  ssl_sid_lookup;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionIDCacheFunc   ssl_sid_cache;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionIDUncacheFunc ssl_sid_uncache;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool ssl_inited = PR_FALSE;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRDescIdentity ssl_layer_id;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool                  locksEverDisabled; 	/* implicitly PR_FALSE */
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool			ssl_force_locks;  	/* implicitly PR_FALSE */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int                     ssl_lock_readers	= 1;	/* default true. */
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char                    ssl_debug;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char                    ssl_trace;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILE *                  ssl_trace_iob;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILE *                  ssl_keylog_iob;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char lockStatus[] = "Locks are ENABLED.  ";
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const PRUint16 srtpCiphers[] = {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SRTP_AES128_CM_HMAC_SHA1_80,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SRTP_AES128_CM_HMAC_SHA1_32,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward declarations. */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus  ssl_MakeLocks(sslSocket *ss);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void       ssl_SetDefaultsFromEnvironment(void);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus   ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  PRDescIdentity id);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Lookup a socket structure from a file descriptor.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Only functions called through the PRIOMethods table should use this.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Other app-callable functions should use ssl_FindSocket.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSocket *
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetPrivate(PRFileDesc *fd)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd != NULL);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd->identity == ssl_layer_id);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fd->methods->file_type != PR_DESC_LAYERED ||
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fd->identity != ssl_layer_id) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = (sslSocket *)fd->secret;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->fd = fd;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function tries to find the SSL layer in the stack.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It searches for the first SSL layer at or below the argument fd,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and failing that, it searches for the nearest SSL layer above the
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * argument fd.  It returns the private sslSocket from the found layer.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSocket *
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FindSocket(PRFileDesc *fd)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *layer;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd != NULL);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ssl_layer_id != 0);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (layer == NULL) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = (sslSocket *)layer->secret;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->fd = layer;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static sslSocket *
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DupSocket(sslSocket *os)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt                = os->opt;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSocks       = PR_FALSE;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->vrange             = os->vrange;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->peerID             = !os->peerID ? NULL : PORT_Strdup(os->peerID);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->url                = !os->url    ? NULL : PORT_Strdup(os->url);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ops      = os->ops;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->rTimeout = os->rTimeout;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->wTimeout = os->wTimeout;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cTimeout = os->cTimeout;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->dbHandle = os->dbHandle;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->allowedByPolicy	= os->allowedByPolicy;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->chosenPreference 	= os->chosenPreference;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (os->cipherSpecs) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs  = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->cipherSpecs)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		            os->sizeCipherSpecs);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs    = os->sizeCipherSpecs;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->preferredCipher    = os->preferredCipher;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs        = NULL;  /* produced lazily */
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs    = 0;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->preferredCipher    = NULL;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.useSecurity) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* This int should be SSLKEAType, but CC on Irix complains,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * during the for loop.
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int i;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sslServerCerts * oc = os->serverCerts;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sslServerCerts * sc = ss->serverCerts;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i=kt_null; i < kt_kea_size; i++, oc++, sc++) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (oc->serverCert && oc->serverCertChain) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCert      = CERT_DupCertificate(oc->serverCert);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!sc->serverCertChain)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    	goto loser;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCert      = NULL;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCertChain = NULL;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sc->serverKeyPair = oc->serverKeyPair ?
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (oc->serverKeyPair && !sc->serverKeyPair)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto loser;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        sc->serverKeyBits = oc->serverKeyBits;
260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		ss->certStatusArray[i] = !os->certStatusArray[i] ? NULL :
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)				SECITEM_DupArray(NULL, os->certStatusArray[i]);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                  ssl3_GetKeyPairRef(os->stepDownKeyPair);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                  ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XXX We should detect this, and not just march on with NULL pointers.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->authCertificate       = os->authCertificate;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->authCertificateArg    = os->authCertificateArg;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getClientAuthData     = os->getClientAuthData;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getPlatformClientAuthData    = os->getPlatformClientAuthData;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getPlatformClientAuthDataArg = os->getPlatformClientAuthDataArg;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ss->sniSocketConfig       = os->sniSocketConfig;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ss->sniSocketConfigArg    = os->sniSocketConfigArg;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handleBadCert         = os->handleBadCert;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->badCertArg            = os->badCertArg;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handshakeCallback     = os->handshakeCallback;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handshakeCallbackData = os->handshakeCallbackData;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    ss->canFalseStartCallback = os->canFalseStartCallback;
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	    ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->pkcs11PinArg          = os->pkcs11PinArg;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getChannelID          = os->getChannelID;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getChannelIDArg       = os->getChannelIDArg;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Create security data */
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl_CopySecurityInfo(ss, os);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FreeSocket(ss);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DestroyLocks(sslSocket *ss)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Destroy locks. */
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->firstHandshakeLock) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->firstHandshakeLock);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->firstHandshakeLock = NULL;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3HandshakeLock) {
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->ssl3HandshakeLock);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3HandshakeLock = NULL;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->specLock) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	NSSRWLock_Destroy(ss->specLock);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->specLock = NULL;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->recvLock) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyLock(ss->recvLock);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->recvLock = NULL;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->sendLock) {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyLock(ss->sendLock);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sendLock = NULL;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->xmitBufLock) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->xmitBufLock);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xmitBufLock = NULL;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->recvBufLock) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->recvBufLock);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->recvBufLock = NULL;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Caller holds any relevant locks */
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DestroySocketContents(sslSocket *ss)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* "i" should be of type SSLKEAType, but CC on IRIX complains during
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the for loop.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        i;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Free up socket */
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DestroySecurityInfo(&ss->sec);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl3_DestroySSL3Info(ss);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(ss->saveBuf.buf);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(ss->pendingBuf.buf);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DestroyGather(&ss->gs);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->peerID != NULL)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free(ss->peerID);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->url != NULL)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free((void *)ss->url);	/* CONST */
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->cipherSpecs) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free(ss->cipherSpecs);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cipherSpecs     = NULL;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sizeCipherSpecs = 0;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Clean up server configuration */
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i=kt_null; i < kt_kea_size; i++) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslServerCerts * sc = ss->serverCerts + i;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sc->serverCert != NULL)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CERT_DestroyCertificate(sc->serverCert);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sc->serverCertChain != NULL)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CERT_DestroyCertificateList(sc->serverCertChain);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sc->serverKeyPair != NULL)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_FreeKeyPair(sc->serverKeyPair);
377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	if (ss->certStatusArray[i] != NULL) {
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    ss->certStatusArray[i] = NULL;
380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->stepDownKeyPair) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_FreeKeyPair(ss->stepDownKeyPair);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->stepDownKeyPair = NULL;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ephemeralECDHKeyPair) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ephemeralECDHKeyPair = NULL;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(!ss->xtnData.sniNameArr);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->xtnData.sniNameArr) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_Free(ss->xtnData.sniNameArr);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->xtnData.sniNameArr = NULL;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * free an sslSocket struct, and all the stuff that hangs off of it
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FreeSocket(sslSocket *ss)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Get every lock you can imagine!
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Caller already holds these:
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  SSL_LOCK_READER(ss);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  SSL_LOCK_WRITER(ss);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetRecvBufLock(ss);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetXmitBufLock(ss);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSpecWriteLock(ss);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_DestroySocketContents(ss);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Release all the locks acquired above.  */
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SSL_UNLOCK_READER(ss);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseRecvBufLock(ss);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseXmitBufLock(ss);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseSpecWriteLock(ss);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_DestroyLocks(ss);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef DEBUG
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PORT_Memset(ss, 0x1f, sizeof *ss);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PORT_Free(ss);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *       osfd = ss->fd->lower;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus         rv = SECFailure;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRSocketOptionData opt;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.option         = PR_SockOpt_NoDelay;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.value.no_delay = (PRBool)!enabled;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (osfd->methods->setsocketoption) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ChooseOps(sslSocket *ss)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called from SSL_Enable (immediately below) */
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrepareSocket(sslSocket *ss)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus     rv = SECSuccess;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ChooseOps(ss);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_Enable(PRFileDesc *fd, int which, PRBool on)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_OptionSet(fd, which, on);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const PRCallOnceType pristineCallOnce;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType setupBypassOnce;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus SSL_BypassShutdown(void* appData, void* nssData)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* unload freeBL shared library from memory */
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BL_Unload();
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setupBypassOnce = pristineCallOnce;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus SSL_BypassRegisterShutdown(void)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(SECSuccess == rv);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus SSL_BypassSetup(void)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* Guarantee binary compatibility */
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PR_SUCCESS;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_TLS, on) described in
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ssl.h in the section "SSL version range setting API".
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} /* else don't change anything */
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (on) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Expand the range of enabled version to include TLS 1.0 */
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = PR_MIN(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->max = PR_MAX(vrange->max, SSL_LIBRARY_VERSION_TLS_1_0);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Disable all TLS versions, leaving only SSL 3.0 if it was enabled */
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (vrange->min == SSL_LIBRARY_VERSION_3_0) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_3_0;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Only TLS was enabled, so now no versions are. */
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_NONE;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_NONE;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_SSL3, on) described in
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ssl.h in the section "SSL version range setting API".
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_3_0;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_3_0;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} /* else don't change anything */
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (on) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Expand the range of enabled versions to include SSL 3.0. We know
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * SSL 3.0 or some version of TLS is already enabled at this point, so
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * we don't need to change vrange->max.
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = SSL_LIBRARY_VERSION_3_0;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   } else {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Disable SSL 3.0, leaving TLS unaffected. */
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (vrange->max > SSL_LIBRARY_VERSION_3_0) {
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Only SSL 3.0 was enabled, so now no versions are. */
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_NONE;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_NONE;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv = SECSuccess;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool     holdingLocks;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    holdingLocks = (!ss->opt.noLocks);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SOCKS:
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSocks = PR_FALSE;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PrepareSocket(ss);
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SECURITY:
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSecurity = on;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PrepareSocket(ss);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUEST_CERTIFICATE:
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.requestCertificate = on;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_CERTIFICATE:
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.requireCertificate = on;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_CLIENT:
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ss->opt.handshakeAsServer && on ) {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.handshakeAsClient = on;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_SERVER:
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ss->opt.handshakeAsClient && on ) {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.handshakeAsServer = on;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_TLS:
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableTLS(&ss->vrange, on);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->preferredCipher     = NULL;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->cipherSpecs) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss->cipherSpecs);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs     = NULL;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs = 0;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL3:
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableSSL3(&ss->vrange, on);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->preferredCipher     = NULL;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->cipherSpecs) {
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss->cipherSpecs);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs     = NULL;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs = 0;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL2:
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableSSL2       = on;
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->opt.v2CompatibleHello = on;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->preferredCipher     = NULL;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->cipherSpecs) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss->cipherSpecs);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs     = NULL;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs = 0;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_CACHE:
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noCache = on;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FDX:
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ss->opt.noLocks) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ss->opt.fdx = on;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_V2_COMPATIBLE_HELLO:
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ss->opt.v2CompatibleHello = on;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!on) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->opt.enableSSL2    = on;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ROLLBACK_DETECTION:
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.detectRollBack = on;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_STEP_DOWN:
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noStepDown     = on;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DisableExportCipherSuites(fd);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_BYPASS_PKCS11:
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->handshakeBegun) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(PR_INVALID_STATE_ERROR);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (PR_FALSE != on) {
7227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                if (PR_SUCCESS == SSL_BypassSetup() ) {
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
724868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    ss->opt.bypassPKCS11 = PR_FALSE;
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    ss->opt.bypassPKCS11 = on;
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    rv = SECFailure;
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                ss->opt.bypassPKCS11 = PR_FALSE;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_LOCKS:
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ss->opt.fdx) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_force_locks)
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    on = PR_FALSE;	/* silent override */
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noLocks   = on;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    locksEverDisabled = PR_TRUE;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (!holdingLocks) {
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl_MakeLocks(ss);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->opt.noLocks   = PR_TRUE;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SESSION_TICKETS:
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableSessionTickets = on;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_DEFLATE:
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableDeflate = on;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_RENEGOTIATION:
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableRenegotiation = on;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_SAFE_NEGOTIATION:
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.requireSafeNegotiation = on;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FALSE_START:
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableFalseStart = on;
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_CBC_RANDOM_IV:
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.cbcRandomIV = on;
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_OCSP_STAPLING:
781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ss->opt.enableOCSPStapling = on;
782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       break;
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case SSL_ENABLE_NPN:
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ss->opt.enableNPN = on;
7865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case SSL_ENABLE_ALPN:
7895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ss->opt.enableALPN = on;
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ss->opt.enableSignedCertTimestamps = on;
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
795f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
796a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case SSL_ENABLE_FALLBACK_SCSV:
797a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       ss->opt.enableFallbackSCSV = on;
798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       break;
799a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* We can't use the macros for releasing the locks here,
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * because ss->opt.noLocks might have changed just above.
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * We must release these locks (monitors) here, if we aquired them above,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * regardless of the current value of ss->opt.noLocks.
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (holdingLocks) {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PZ_ExitMonitor((ss)->ssl3HandshakeLock);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PZ_ExitMonitor((ss)->firstHandshakeLock);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv = SECSuccess;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool     on = PR_FALSE;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pOn) {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*pOn = PR_FALSE;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SOCKS:               on = PR_FALSE;               break;
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SECURITY:            on = ss->opt.useSecurity;        break;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient;  break;
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer;  break;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_TLS:
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL3:
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL2:         on = ss->opt.enableSSL2;         break;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_CACHE:            on = ss->opt.noCache;            break;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FDX:          on = ss->opt.fdx;                break;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello;  break;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ROLLBACK_DETECTION:  on = ss->opt.detectRollBack;     break;
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_STEP_DOWN:        on = ss->opt.noStepDown;         break;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_BYPASS_PKCS11:       on = ss->opt.bypassPKCS11;       break;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_LOCKS:            on = ss->opt.noLocks;            break;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SESSION_TICKETS:
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ss->opt.enableSessionTickets;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_DEFLATE:      on = ss->opt.enableDeflate;      break;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_RENEGOTIATION:
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ss->opt.enableRenegotiation; break;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_SAFE_NEGOTIATION:
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ss->opt.requireSafeNegotiation; break;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_CBC_RANDOM_IV:       on = ss->opt.cbcRandomIV;        break;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case SSL_ENABLE_NPN:          on = ss->opt.enableNPN;          break;
8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case SSL_ENABLE_ALPN:         on = ss->opt.enableALPN;         break;
872f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	on = ss->opt.enableSignedCertTimestamps;
8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
875a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *pOn = on;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv = SECSuccess;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool     on = PR_FALSE;
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pOn) {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetDefaultsFromEnvironment();
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SOCKS:               on = PR_FALSE;                        break;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SECURITY:            on = ssl_defaults.useSecurity;        break;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient;  break;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer;  break;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_TLS:
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL3:
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL2:         on = ssl_defaults.enableSSL2;         break;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_CACHE:            on = ssl_defaults.noCache;		break;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FDX:          on = ssl_defaults.fdx;                break;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello;  break;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ROLLBACK_DETECTION:  on = ssl_defaults.detectRollBack;     break;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_STEP_DOWN:        on = ssl_defaults.noStepDown;         break;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_BYPASS_PKCS11:       on = ssl_defaults.bypassPKCS11;       break;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_LOCKS:            on = ssl_defaults.noLocks;            break;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SESSION_TICKETS:
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ssl_defaults.enableSessionTickets;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_DEFLATE:      on = ssl_defaults.enableDeflate;      break;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_RENEGOTIATION:
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ssl_defaults.enableRenegotiation; break;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_SAFE_NEGOTIATION:
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ssl_defaults.requireSafeNegotiation;
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  break;
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FALSE_START:  on = ssl_defaults.enableFalseStart;   break;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_CBC_RANDOM_IV:       on = ssl_defaults.cbcRandomIV;        break;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_OCSP_STAPLING:
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       on = ssl_defaults.enableOCSPStapling;
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       break;
9375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case SSL_ENABLE_NPN:          on = ssl_defaults.enableNPN;          break;
9385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case SSL_ENABLE_ALPN:         on = ssl_defaults.enableALPN;         break;
939f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	on = ssl_defaults.enableSignedCertTimestamps;
9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
942a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case SSL_ENABLE_FALLBACK_SCSV:
9435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	on = ssl_defaults.enableFallbackSCSV;
9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *pOn = on;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* XXX Use Global Lock to protect this stuff. */
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_EnableDefault(int which, PRBool on)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_OptionSetDefault(which, on);
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionSetDefault(PRInt32 which, PRBool on)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus status = ssl_Init();
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != SECSuccess) {
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return status;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetDefaultsFromEnvironment();
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SOCKS:
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.useSocks = PR_FALSE;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SECURITY:
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.useSecurity = on;
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUEST_CERTIFICATE:
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.requestCertificate = on;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_CERTIFICATE:
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.requireCertificate = on;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_CLIENT:
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ssl_defaults.handshakeAsServer && on ) {
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.handshakeAsClient = on;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_SERVER:
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ssl_defaults.handshakeAsClient && on ) {
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.handshakeAsServer = on;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_TLS:
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableTLS(&versions_defaults_stream, on);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL3:
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableSSL3(&versions_defaults_stream, on);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL2:
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableSSL2 = on;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.v2CompatibleHello = on;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_CACHE:
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.noCache = on;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FDX:
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_defaults.noLocks) {
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ssl_defaults.fdx = on;
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_V2_COMPATIBLE_HELLO:
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ssl_defaults.v2CompatibleHello = on;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!on) {
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.enableSSL2    = on;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ROLLBACK_DETECTION:
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.detectRollBack = on;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_STEP_DOWN:
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.noStepDown     = on;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DisableDefaultExportCipherSuites();
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_BYPASS_PKCS11:
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (PR_FALSE != on) {
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (PR_SUCCESS == SSL_BypassSetup()) {
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                ssl_defaults.bypassPKCS11   = PR_FALSE;
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_defaults.bypassPKCS11   = on;
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return SECFailure;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl_defaults.bypassPKCS11   = PR_FALSE;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_LOCKS:
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_defaults.fdx) {
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_force_locks)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    on = PR_FALSE;		/* silent override */
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.noLocks        = on;
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    locksEverDisabled = PR_TRUE;
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SESSION_TICKETS:
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableSessionTickets = on;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_DEFLATE:
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableDeflate = on;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_RENEGOTIATION:
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableRenegotiation = on;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_SAFE_NEGOTIATION:
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.requireSafeNegotiation = on;
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FALSE_START:
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableFalseStart = on;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_CBC_RANDOM_IV:
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.cbcRandomIV = on;
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_OCSP_STAPLING:
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ssl_defaults.enableOCSPStapling = on;
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       break;
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case SSL_ENABLE_NPN:
11135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ssl_defaults.enableNPN = on;
11145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
11155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case SSL_ENABLE_ALPN:
11175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ssl_defaults.enableALPN = on;
11185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
11195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
11215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	ssl_defaults.enableSignedCertTimestamps = on;
11225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	break;
1123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      case SSL_ENABLE_FALLBACK_SCSV:
1125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       ssl_defaults.enableFallbackSCSV = on;
1126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       break;
1127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* function tells us if the cipher suite is one that we no longer support. */
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_IsRemovedCipherSuite(PRInt32 suite)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (suite) {
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return PR_TRUE;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return PR_FALSE;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Part of the public NSS API.
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since this is a global (not per-socket) setting, we cannot use the
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * HandshakeLock to protect this.  Probably want a global lock.
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetPolicy(long which, int policy)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	/* one of the two old FIPS ciphers */
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_CipherPolicySet(which, policy);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = ssl_Init();
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_SetPolicy(which, policy);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!oPolicy) {
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*oPolicy = SSL_NOT_ALLOWED;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_GetPolicy(which, oPolicy);
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Part of the public NSS API.
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since this is a global (not per-socket) setting, we cannot use the
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * HandshakeLock to protect this.  Probably want a global lock.
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These changes have no effect on any sslSockets already created.
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_EnableCipher(long which, PRBool enabled)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	/* one of the two old FIPS ciphers */
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_CipherPrefSetDefault(which, enabled);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = ssl_Init();
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SSL_IS_SSL2_CIPHER(which)) {
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefSetDefault(which, enabled);
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv;
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!enabled) {
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*enabled = PR_FALSE;
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefGetDefault(which, enabled);
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SSL_IS_SSL2_CIPHER(which)) {
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefSet(ss, which, enabled);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SECStatus
1295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SSL_CipherOrderSet(PRFileDesc *fd, const PRUint16 *ciphers, unsigned int len)
1296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){
1297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
1298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!ss) {
1300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in CipherOrderSet", SSL_GETPID(),
1301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		fd));
1302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)	return SECFailure;
1303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1304a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return ssl3_CipherOrderSet(ss, ciphers, len);
1305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv;
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!enabled) {
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*enabled = PR_FALSE;
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*enabled = PR_FALSE;
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefGet(ss, which, enabled);
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSS_SetDomesticPolicy(void)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus      status = SECSuccess;
13375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const PRUint16 *cipher;
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (cipher = SSL_ImplementedCiphers; *cipher != 0; ++cipher) {
13405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	status = SSL_SetPolicy(*cipher, SSL_ALLOWED);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != SECSuccess)
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSS_SetExportPolicy(void)
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NSS_SetDomesticPolicy();
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSS_SetFrancePolicy(void)
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NSS_SetDomesticPolicy();
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetChannelBinding(PRFileDesc *fd,
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      SSLChannelBindingType binding_type,
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      unsigned char *out,
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      unsigned int *outLen,
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      unsigned int outLenMax) {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelBinding",
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (binding_type != SSL_CHANNEL_BINDING_TLS_UNIQUE) {
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* LOCKS ??? XXX */
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRFileDesc *
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ns = NULL;
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    rv;
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRNetAddr   addr;
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus	status = ssl_Init();
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != SECSuccess) {
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (model == NULL) {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Just create a default socket if we're given NULL for the model */
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslSocket * ss = ssl_FindSocket(model);
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss == NULL || ss->protocolVariant != variant) {
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	      SSL_GETPID(), model));
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return NULL;
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns = ssl_DupSocket(ss);
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns == NULL)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return NULL;
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != PR_SUCCESS) {
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_FreeSocket(ns);
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ns = ssl_FindSocket(fd);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ns);
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fd;
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRFileDesc *
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_ImportFD(model, fd, ssl_variant_stream);
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRFileDesc *
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_ImportFD(model, fd, ssl_variant_datagram);
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 void *arg)
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoCallback", SSL_GETPID(),
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 fd));
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->nextProtoCallback = callback;
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->nextProtoArg = arg;
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SSL_SetNextProtoNego is used.
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  const unsigned char *protos, unsigned int protos_len,
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  unsigned char *protoOut, unsigned int *protoOutLen,
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  unsigned int protoMaxLen)
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int i, j;
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char *result;
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in ssl_NextProtoNegoCallback",
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (protos_len == 0) {
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* The server supports the extension, but doesn't have any protocols
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * configured. In this case we request our favoured protocol. */
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto pick_first;
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* For each protocol in server preference, see if we support it. */
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < protos_len; ) {
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (j = 0; j < ss->opt.nextProtoNego.len; ) {
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (protos[i] == ss->opt.nextProtoNego.data[j] &&
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_Memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     protos[i]) == 0) {
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* We found a match. */
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		result = &protos[i];
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto found;
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	i += 1 + (unsigned int)protos[i];
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pick_first:
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = ss->opt.nextProtoNego.data;
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found:
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (protoMaxLen < result[0]) {
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(protoOut, result + 1, result[0]);
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *protoOutLen = result[0];
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     unsigned int length)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem dataItem = { siBuffer, (unsigned char *) data, length };
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem);
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL);
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 unsigned int *bufLen, unsigned int bufLenMax)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 fd));
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!state || !buf || !bufLen) {
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *state = ss->ssl3.nextProtoState;
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.nextProto.data) {
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->ssl3.nextProto.len > bufLenMax) {
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_OUTPUT_LEN);
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len);
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*bufLen = ss->ssl3.nextProto.len;
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*bufLen = 0;
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     const PRUint16 *ciphers,
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     unsigned int numCiphers)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned int i;
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss || !IS_DTLS(ss)) {
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSRTPCiphers",
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (numCiphers > MAX_DTLS_SRTP_CIPHER_SUITES) {
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.dtlsSRTPCipherCount = 0;
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < numCiphers; i++) {
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const PRUint16 *srtpCipher = srtpCiphers;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (*srtpCipher) {
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ciphers[i] == *srtpCipher)
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    srtpCipher++;
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (*srtpCipher) {
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->ssl3.dtlsSRTPCiphers[ss->ssl3.dtlsSRTPCipherCount++] =
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ciphers[i];
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "suite specified: 0x%04hx", SSL_GETPID(), fd,
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ciphers[i]));
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3.dtlsSRTPCipherCount == 0) {
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ss;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSRTPCipher",
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->ssl3.dtlsSRTPCipherSuite) {
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *cipher = ss->ssl3.dtlsSRTPCipherSuite;
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRFileDesc *
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * sm = NULL, *ss = NULL;
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslServerCerts * mc = NULL;
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslServerCerts * sc = NULL;
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (model == NULL) {
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sm = ssl_FindSocket(model);
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm == NULL) {
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ReconfigFD",
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 SSL_GETPID(), model));
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ss);
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss == NULL) {
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_SetError(SEC_ERROR_INVALID_ARGS);
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->opt  = sm->opt;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->vrange = sm->vrange;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.useSecurity) {
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_SetError(SEC_ERROR_INVALID_ARGS);
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* This int should be SSLKEAType, but CC on Irix complains,
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * during the for loop.
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i=kt_null; i < kt_kea_size; i++) {
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mc = &(sm->serverCerts[i]);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sc = &(ss->serverCerts[i]);
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mc->serverCert && mc->serverCertChain) {
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sc->serverCert) {
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CERT_DestroyCertificate(sc->serverCert);
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverCert      = CERT_DupCertificate(mc->serverCert);
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sc->serverCertChain) {
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CERT_DestroyCertificateList(sc->serverCertChain);
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverCertChain = CERT_DupCertList(mc->serverCertChain);
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!sc->serverCertChain)
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                goto loser;
1695a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    if (sm->certStatusArray[i]) {
1696a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		if (ss->certStatusArray[i]) {
1697a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		    SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
1698a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		    ss->certStatusArray[i] = NULL;
1699a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		}
1700a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		ss->certStatusArray[i] = SECITEM_DupArray(NULL, sm->certStatusArray[i]);
1701a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		if (!ss->certStatusArray[i])
1702a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		    goto loser;
1703a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    }
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mc->serverKeyPair) {
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sc->serverKeyPair) {
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl3_FreeKeyPair(sc->serverKeyPair);
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverKeyPair = ssl3_GetKeyPairRef(mc->serverKeyPair);
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverKeyBits = mc->serverKeyBits;
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->stepDownKeyPair) {
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ss->stepDownKeyPair) {
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl3_FreeKeyPair(ss->stepDownKeyPair);
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->stepDownKeyPair = ssl3_GetKeyPairRef(sm->stepDownKeyPair);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->ephemeralECDHKeyPair) {
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ss->ephemeralECDHKeyPair) {
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->ephemeralECDHKeyPair =
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* copy trust anchor names */
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->ssl3.ca_list) {
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ss->ssl3.ca_list) {
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            CERT_FreeDistNames(ss->ssl3.ca_list);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->ssl3.ca_list = CERT_DupDistNames(sm->ssl3.ca_list);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ss->ssl3.ca_list) {
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            goto loser;
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->authCertificate)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->authCertificate       = sm->authCertificate;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->authCertificateArg)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->authCertificateArg    = sm->authCertificateArg;
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getClientAuthData)
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getClientAuthData     = sm->getClientAuthData;
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getClientAuthDataArg)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getClientAuthDataArg  = sm->getClientAuthDataArg;
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getPlatformClientAuthData)
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getPlatformClientAuthData    = sm->getPlatformClientAuthData;
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getPlatformClientAuthDataArg)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getPlatformClientAuthDataArg = sm->getPlatformClientAuthDataArg;
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->sniSocketConfig)
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfig       = sm->sniSocketConfig;
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->sniSocketConfigArg)
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfigArg    = sm->sniSocketConfigArg;
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->handleBadCert)
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->handleBadCert         = sm->handleBadCert;
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->badCertArg)
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->badCertArg            = sm->badCertArg;
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->handshakeCallback)
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->handshakeCallback     = sm->handshakeCallback;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->handshakeCallbackData)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->handshakeCallbackData = sm->handshakeCallbackData;
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->pkcs11PinArg)
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->pkcs11PinArg          = sm->pkcs11PinArg;
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getChannelID)
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getChannelID          = sm->getChannelID;
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getChannelIDArg)
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getChannelIDArg       = sm->getChannelIDArg;
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fd;
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL3ProtocolVersion version)
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (protocolVariant) {
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_stream:
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (version >= SSL_LIBRARY_VERSION_3_0 &&
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_datagram:
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Can't get here */
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(PR_FALSE);
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FALSE;
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns PR_TRUE if the given version range is valid and
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fully supported; otherwise, returns PR_FALSE.
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 const SSLVersionRange *vrange)
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return vrange &&
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   vrange->min <= vrange->max &&
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ssl3_VersionIsSupported(protocolVariant, vrange->max);
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     SSLVersionRange *vrange)
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vrange) {
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (protocolVariant) {
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_stream:
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = SSL_LIBRARY_VERSION_3_0;
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_datagram:
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   SSLVersionRange *vrange)
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((protocolVariant != ssl_variant_stream &&
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 protocolVariant != ssl_variant_datagram) || !vrange) {
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *vrange = *VERSIONS_DEFAULTS(protocolVariant);
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   const SSLVersionRange *vrange)
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *VERSIONS_DEFAULTS(protocolVariant) = *vrange;
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeGet",
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), fd));
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vrange) {
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *vrange = ss->vrange;
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1887868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRCallOnceType checkTLS12TokenOnce;
1888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRBool tls12TokenExists;
1889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRStatus
1891868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl_CheckTLS12Token(void)
1892868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
1893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    tls12TokenExists =
1894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PK11_TokenExists(CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256);
1895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return PR_SUCCESS;
1896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRBool
1899868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl_TLS12TokenExists(void)
1900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
1901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    (void) PR_CallOnce(&checkTLS12TokenOnce, ssl_CheckTLS12Token);
1902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return tls12TokenExists;
1903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1904868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeSet",
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), fd));
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->vrange = *vrange;
1925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* If we don't have a sufficiently up-to-date softoken then we cannot do
1926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     * TLS 1.2. */
1927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_2 &&
1928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        !ssl_TLS12TokenExists()) {
1929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	/* If the user requested a minimum version of 1.2, then we don't
1930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	 * silently downgrade. */
1931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_2) {
1932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    ssl_ReleaseSSL3HandshakeLock(ss);
1933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    ssl_Release1stHandshakeLock(ss);
1934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
1935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    return SECFailure;
1936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	}
1937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;
1938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const SECItemArray *
1947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
1948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
1952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerStapledOCSPResponses",
1953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                SSL_GETPID(), fd));
1954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return NULL;
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!ss->sec.ci.sid) {
1958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
1959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return NULL;
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return &ss->sec.ci.sid->peerCertStatus;
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const SECItem *
1966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SSL_PeerSignedCertTimestamps(PRFileDesc *fd)
1967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){
1968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
1969f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1970f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ss) {
1971f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerSignedCertTimestamps",
1972f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)		SSL_GETPID(), fd));
1973f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       return NULL;
1974f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1975f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1976f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!ss->sec.ci.sid) {
1977f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
1978f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       return NULL;
1979f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1980f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1981f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (ss->sec.ci.sid->version < SSL_LIBRARY_VERSION_3_0) {
1982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
1983f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)	return NULL;
1984f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1985f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return &ss->sec.ci.sid->u.ssl3.signedCertTimestamps;
1986f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1987f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_HandshakeResumedSession",
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *handshake_resumed = ss->ssl3.hs.isResuming;
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SECItem *
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd)
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sslSocket *ss = ssl_FindSocket(fd);
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ss) {
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSL_DBG(("%d: SSL[%d]: bad socket in "
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "SSL_GetRequestedClientCertificateTypes", SSL_GETPID(), fd));
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ss->requestedCertTypes;
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The following functions are the TOP LEVEL SSL functions.
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** They all get called through the NSPRIOMethods table below.
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRFileDesc * PR_CALLBACK
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket  *ss;
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket  *ns 	= NULL;
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *newfd 	= NULL;
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *osfd;
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    status;
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd));
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* IF this is a listen socket, there shouldn't be any I/O going on */
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->cTimeout = timeout;
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    osfd = ss->fd->lower;
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* First accept connection */
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newfd = osfd->methods->accept(osfd, sockaddr, timeout);
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (newfd == NULL) {
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d",
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), ss->fd, PORT_GetError()));
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Create ssl module */
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns = ssl_DupSocket(ss);
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_READER(ss);			/* ss isn't used below here. */
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns == NULL)
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* push ssl module onto the new socket */
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER);
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != PR_SUCCESS)
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Now start server connection handshake with client.
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** Don't need locks here because nobody else has a reference to ns yet.
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ( ns->opt.useSecurity ) {
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ns->opt.handshakeAsClient ) {
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ns->handshake = ssl2_BeginClientHandshake;
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handshaking = sslHandshakingAsClient;
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ns->handshake = ssl2_BeginServerHandshake;
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handshaking = sslHandshakingAsServer;
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ns->TCPconnected = 1;
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return newfd;
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns != NULL)
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_FreeSocket(ns);
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (newfd != NULL)
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PR_Close(newfd);
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus   rv;
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd));
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* IF this is a listen socket, there shouldn't be any I/O going on */
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->cTimeout = timeout;
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_READER(ss);
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ss = ssl_GetPrivate(fd);
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    rv;
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (PRStatus)(*ss->ops->bind)(ss, addr);
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_READER(ss);
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Listen(PRFileDesc *fd, PRIntn backlog)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ss = ssl_GetPrivate(fd);
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    rv;
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (PRStatus)(*ss->ops->listen)(ss, backlog);
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_READER(ss);
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Shutdown(PRFileDesc *fd, PRIntn how)
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ss = ssl_GetPrivate(fd);
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    rv;
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SSL_LOCK_READER(ss);
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SSL_LOCK_WRITER(ss);
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (PRStatus)(*ss->ops->shutdown)(ss, how);
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SSL_UNLOCK_WRITER(ss);
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	SSL_UNLOCK_READER(ss);
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Close(PRFileDesc *fd)
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus   rv;
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd));
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* There must not be any I/O going on */
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* By the time this function returns,
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** ss is an invalid pointer, and the locks to which it points have
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** been unlocked and freed.  So, this is the ONE PLACE in all of SSL
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** where the LOCK calls and the corresponding UNLOCK calls are not in
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** the same function scope.  The unlock calls are in ssl_FreeSocket().
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (PRStatus)(*ss->ops->close)(ss);
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int PR_CALLBACK
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 PRIntervalTime timeout)
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        rv;
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd));
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->rTimeout = timeout;
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.fdx)
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->wTimeout = timeout;
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_READER(ss);
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int PR_CALLBACK
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 PRIntervalTime timeout)
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        rv;
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd));
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->wTimeout = timeout;
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.fdx)
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->rTimeout = timeout;
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int PR_CALLBACK
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        rv;
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd));
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_READER(ss);
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.fdx)
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_READER(ss);
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int PR_CALLBACK
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        rv;
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd));
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LOCK_WRITER(ss);
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.fdx)
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd));
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (PRStatus)(*ss->ops->getpeername)(ss, addr);
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetPeerInfo(sslSocket *ss)
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *      osfd;
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int               rv;
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRNetAddr         sin;
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    osfd = ss->fd->lower;
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memset(&sin, 0, sizeof(sin));
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = osfd->methods->getpeername(osfd, &sin);
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv < 0) {
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->TCPconnected = 1;
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sin.inet.family == PR_AF_INET) {
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ss->sec.ci.peer);
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sec.ci.port = sin.inet.port;
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (sin.ipv6.family == PR_AF_INET6) {
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sec.ci.peer = sin.ipv6.ip;
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sec.ci.port = sin.ipv6.port;
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR);
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECFailure;
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd));
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FAILURE;
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (PRStatus)(*ss->ops->getsockname)(ss, name);
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
2351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
2352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)			    SSLKEAType kea)
2353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
2354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    sslSocket *ss;
2355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ss = ssl_FindSocket(fd);
2357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!ss) {
2358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
2359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)		 SSL_GETPID(), fd));
2360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	return SECFailure;
2361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if ( kea <= 0 || kea >= kt_kea_size) {
2364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: invalid key in SSL_SetStapledOCSPResponses",
2365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		 SSL_GETPID(), fd));
2366a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	return SECFailure;
2367a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
2368a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (ss->certStatusArray[kea]) {
2370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        SECITEM_FreeArray(ss->certStatusArray[kea], PR_TRUE);
2371a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        ss->certStatusArray[kea] = NULL;
2372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (responses) {
2374a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	ss->certStatusArray[kea] = SECITEM_DupArray(NULL, responses);
2375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
2376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return (ss->certStatusArray[kea] || !responses) ? SECSuccess : SECFailure;
2377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
2378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SECStatus
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
2386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSockPeerID",
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->peerID) {
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_Free(ss->peerID);
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->peerID = NULL;
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (peerID)
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->peerID = PORT_Strdup(peerID);
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (ss->peerID || !peerID) ? SECSuccess : SECFailure;
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PR_POLL_RW (PR_POLL_WRITE | PR_POLL_READ)
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt16 PR_CALLBACK
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt16    new_flags = how_flags;	/* should select on these flags. */
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRNetAddr  addr;
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *p_out_flags = 0;
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_GetPrivate(fd);
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll",
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return 0;	/* don't poll on this socket */
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->opt.useSecurity &&
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->handshaking != sslHandshakingUndetermined &&
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !ss->firstHsDone &&
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(how_flags & PR_POLL_RW)) {
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->TCPconnected) {
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* If it's not connected, then presumably the application is polling
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	** on read or write appropriately, so don't change it.
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->TCPconnected) {
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!ss->handshakeBegun) {
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* If the handshake has not begun, poll on read or write
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		** based on the local application's role in the handshake,
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		** not based on what the application requested.
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*/
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		new_flags &= ~PR_POLL_RW;
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ss->handshaking == sslHandshakingAsClient) {
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    new_flags |= PR_POLL_WRITE;
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else { /* handshaking as server */
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    new_flags |= PR_POLL_READ;
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* First handshake is in progress */
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->lastWriteBlocked) {
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (new_flags & PR_POLL_READ) {
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* The caller is waiting for data to be received,
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ** but the initial handshake is blocked on write, or the
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ** client's first handshake record has not been written.
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ** The code should select on write, not read.
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    */
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    new_flags ^=  PR_POLL_READ;	   /* don't select on read. */
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    new_flags |=  PR_POLL_WRITE;   /* do    select on write. */
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (new_flags & PR_POLL_WRITE) {
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* The caller is trying to write, but the handshake is
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ** blocked waiting for data to read, and the first
24544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)		    ** handshake has been sent.  So do NOT to poll on write
24554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)		    ** unless we did false start.
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    */
24574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)		    if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
24584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)			ss->ssl3.hs.canFalseStart)) {
24594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)			new_flags ^= PR_POLL_WRITE; /* don't select on write. */
24604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)		    }
24614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)		    new_flags |= PR_POLL_READ;      /* do    select on read. */
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*p_out_flags = PR_POLL_READ;	/* it's ready already. */
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return new_flags;
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	new_flags |=  PR_POLL_WRITE;   /* also select on write. */
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.hs.restartTarget != NULL) {
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read and write will block until the asynchronous callback completes
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * (e.g. until SSL_AuthCertificateComplete is called), so don't tell
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * the caller to poll the socket unless there is pending write data.
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) {
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Ignore any newly-received data on the socket, but do wait for
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * the socket to become writable again. Here, it is OK for an error
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * to be detected, because our logic for sending pending write data
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * will allow us to report the error to the caller without the risk
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * of the application spinning.
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags &= (PR_POLL_WRITE | PR_POLL_EXCEPT);
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Unfortunately, clearing new_flags will make it impossible for
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * the application to detect errors that it would otherwise be
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * able to detect with PR_POLL_EXCEPT, until the asynchronous
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * callback completes. However, we must clear all the flags to
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * prevent the application from spinning (alternating between
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * calling PR_Poll that would return PR_POLL_EXCEPT, and send/recv
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * which won't actually report the I/O error while we are waiting
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * for the asynchronous callback to complete).
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags = 0;
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (new_flags && (fd->lower->methods->poll != NULL)) {
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt16    lower_out_flags = 0;
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt16    lower_new_flags;
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lower_new_flags = fd->lower->methods->poll(fd->lower, new_flags,
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					           &lower_out_flags);
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((lower_new_flags & lower_out_flags) && (how_flags != new_flags)) {
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRInt16 out_flags = lower_out_flags & ~PR_POLL_RW;
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (lower_out_flags & PR_POLL_READ)
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		out_flags |= PR_POLL_WRITE;
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (lower_out_flags & PR_POLL_WRITE)
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		out_flags |= PR_POLL_READ;
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *p_out_flags = out_flags;
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags = how_flags;
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *p_out_flags = lower_out_flags;
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags    = lower_new_flags;
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new_flags;
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 const void *headers, PRInt32 hlen,
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 PRTransmitFileFlags flags, PRIntervalTime timeout)
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRSendFileData sfd;
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.fd = fd;
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.file_offset = 0;
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.file_nbytes = 0;
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.header = headers;
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.hlen = hlen;
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.trailer = NULL;
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.tlen = 0;
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sd->methods->sendfile(sd, &sfd, flags, timeout);
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FdIsBlocking(PRFileDesc *fd)
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRSocketOptionData opt;
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus           status;
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.option             = PR_SockOpt_Nonblocking;
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.value.non_blocking = PR_FALSE;
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = PR_GetSocketOption(fd, &opt);
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != PR_SUCCESS)
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FALSE;
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (PRBool)!opt.value.non_blocking;
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SocketIsBlocking(sslSocket *ss)
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_FdIsBlocking(ss->fd);
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32  sslFirstBufSize = 8 * 1024;
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32  sslCopyLimit    = 1024;
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           PRIntervalTime timeout)
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            bufLen;
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            left;
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            rv;
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            sent      =  0;
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRInt32      first_len = sslFirstBufSize;
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRInt32      limit     = sslCopyLimit;
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool             blocking;
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRIOVec            myIov	 = { 0, 0 };
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char               buf[MAX_FRAGMENT_LENGTH];
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vectors > PR_MAX_IOVECTOR_SIZE) {
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return -1;
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blocking = ssl_FdIsBlocking(fd);
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define K16 sizeof(buf)
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GET_VECTOR   do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_ERR(rv, len) \
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != len) { \
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv < 0) { \
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!blocking \
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&& (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&& (sent > 0)) { \
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return sent; \
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else { \
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1; \
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } \
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} \
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Only a nonblocking socket can have partial sends */ \
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PR_ASSERT(!blocking); \
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return sent + rv; \
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEND(bfr, len) \
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do { \
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl_Send(fd, bfr, len, 0, timeout); \
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HANDLE_ERR(rv, len) \
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sent += len; \
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (0)
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Make sure the first write is at least 8 KB, if possible. */
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KILL_VECTORS
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vectors)
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ssl_Send(fd, 0, 0, 0, timeout);
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GET_VECTOR;
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vectors) {
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (myIov.iov_len < first_len) {
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bufLen = myIov.iov_len;
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	left = first_len - bufLen;
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (vectors && left) {
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int toCopy;
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    GET_VECTOR;
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    toCopy = PR_MIN(left, myIov.iov_len);
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bufLen         += toCopy;
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left           -= toCopy;
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_base += toCopy;
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len  -= toCopy;
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SEND( buf, bufLen );
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (vectors || myIov.iov_len) {
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt32   addLen;
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!myIov.iov_len) {
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    GET_VECTOR;
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (myIov.iov_len >= K16) {
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SEND(myIov.iov_base, K16);
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_base += K16;
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len  -= K16;
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!myIov.iov_len)
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!vectors || myIov.iov_len > limit) {
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    addLen = 0;
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Addlen is already computed. */;
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (vectors > 1 &&
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     addLen = limit - myIov.iov_len;
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    addLen = 0;
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!addLen) {
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SEND( myIov.iov_base, myIov.iov_len );
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len = 0;
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bufLen = myIov.iov_len;
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	do {
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    GET_VECTOR;
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_base += addLen;
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len  -= addLen;
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bufLen         += addLen;
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left = PR_MIN( limit, K16 - bufLen);
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!vectors 		/* no more left */
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ||  myIov.iov_len > 0	/* we didn't use that one all up */
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ||  bufLen >= K16		/* it's full. */
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ) {
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		addLen = 0;
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((addLen = iov->iov_len % K16) <= left) {
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Addlen is already computed. */;
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (vectors > 1 &&
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 iov[1].iov_len % K16 + addLen <= left + limit) {
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 addLen = left;
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		addLen = 0;
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} while (addLen);
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SEND( buf, bufLen );
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sent;
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These functions aren't implemented.
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Available(PRFileDesc *fd)
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt64 PR_CALLBACK
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Available64(PRFileDesc *fd)
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt64 res;
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_I2L(res, -1L);
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return res;
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FSync(PRFileDesc *fd)
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt64 PR_CALLBACK
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt64 res;
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_I2L(res, -1L);
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return res;
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     PRNetAddr *addr, PRIntervalTime timeout)
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   const PRNetAddr *addr, PRIntervalTime timeout)
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const PRIOMethods ssl_methods = {
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_DESC_LAYERED,
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Close,           	/* close        */
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Read,            	/* read         */
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Write,           	/* write        */
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Available,       	/* available    */
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Available64,     	/* available64  */
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FSync,           	/* fsync        */
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Seek,            	/* seek         */
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Seek64,          	/* seek64       */
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FileInfo,        	/* fileInfo     */
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FileInfo64,      	/* fileInfo64   */
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_WriteV,          	/* writev       */
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Connect,         	/* connect      */
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Accept,          	/* accept       */
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Bind,            	/* bind         */
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Listen,          	/* listen       */
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Shutdown,        	/* shutdown     */
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Recv,            	/* recv         */
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Send,            	/* send         */
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_RecvFrom,        	/* recvfrom     */
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SendTo,          	/* sendto       */
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Poll,            	/* poll         */
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_EmulateAcceptRead,       /* acceptread   */
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_TransmitFile,           /* transmitfile */
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSockName,     	/* getsockname  */
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetPeerName,     	/* getpeername  */
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* getsockopt   OBSOLETE */
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* setsockopt   OBSOLETE */
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* getsocketoption   */
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* setsocketoption   */
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_EmulateSendFile, 	/* Send a (partial) file with header/trailer*/
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL                 	/* reserved for future use */
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRIOMethods combined_methods;
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SetupIOMethods(void)
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PRIOMethods *new_methods  = &combined_methods;
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRIOMethods *my_methods   = &ssl_methods;
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *new_methods = *nspr_methods;
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->file_type         = my_methods->file_type;
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->close             = my_methods->close;
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->read              = my_methods->read;
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->write             = my_methods->write;
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->available         = my_methods->available;
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->available64       = my_methods->available64;
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->fsync             = my_methods->fsync;
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->seek              = my_methods->seek;
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->seek64            = my_methods->seek64;
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->fileInfo          = my_methods->fileInfo;
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->fileInfo64        = my_methods->fileInfo64;
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->writev            = my_methods->writev;
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->connect           = my_methods->connect;
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->accept            = my_methods->accept;
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->bind              = my_methods->bind;
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->listen            = my_methods->listen;
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->shutdown          = my_methods->shutdown;
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->recv              = my_methods->recv;
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->send              = my_methods->send;
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->recvfrom          = my_methods->recvfrom;
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->sendto            = my_methods->sendto;
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->poll              = my_methods->poll;
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->acceptread        = my_methods->acceptread;
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->transmitfile      = my_methods->transmitfile;
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->getsockname       = my_methods->getsockname;
28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->getpeername       = my_methods->getpeername;
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  new_methods->getsocketoption   = my_methods->getsocketoption;	*/
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  new_methods->setsocketoption   = my_methods->setsocketoption;	*/
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->sendfile          = my_methods->sendfile;
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType initIoLayerOnce;
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_InitIOLayer(void)
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_layer_id = PR_GetUniqueIdentity("SSL");
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetupIOMethods();
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_inited = PR_TRUE;
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *layer	= NULL;
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    status;
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl_inited) {
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != PR_SUCCESS)
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns == NULL)
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (layer == NULL)
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer->secret = (PRFilePrivate *)ns;
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Here, "stack" points to the PRFileDesc on the top of the stack.
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** "layer" points to a new FD that is to be inserted into the stack.
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If layer is being pushed onto the top of the stack, then
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** PR_PushIOLayer switches the contents of stack and layer, and then
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** puts stack on top of layer, so that after it is done, the top of
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** stack is the same "stack" as it was before, and layer is now the
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** FD for the former top of stack.
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** After this call, stack always points to the top PRFD on the stack.
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If this function fails, the contents of stack and layer are as
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** they were before the call.
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = PR_PushIOLayer(stack, id, layer);
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != PR_SUCCESS)
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (layer) {
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	layer->dtor(layer); /* free layer */
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* if this fails, caller must destroy socket. */
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_MakeLocks(sslSocket *ss)
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->firstHandshakeLock)
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3HandshakeLock  = PZ_NewMonitor(nssILockSSL);
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->ssl3HandshakeLock)
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->specLock           = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->specLock)
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->recvBufLock        = PZ_NewMonitor(nssILockSSL);
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->recvBufLock)
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xmitBufLock        = PZ_NewMonitor(nssILockSSL);
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->xmitBufLock)
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->writerThread       = NULL;
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_lock_readers) {
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->recvLock       = PZ_NewLock(nssILockSSL);
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->recvLock)
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sendLock       = PZ_NewLock(nssILockSSL);
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sendLock)
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DestroyLocks(ss);
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NSS_HAVE_GETENV 1
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOWER(x) (x | 0x20)  /* cheap ToLower function ignores LOCALE */
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SetDefaultsFromEnvironment(void)
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined( NSS_HAVE_GETENV )
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static int firsttime = 1;
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (firsttime) {
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char * ev;
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	firsttime = 0;
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLDEBUGFILE");
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_trace_iob = fopen(ev, "w");
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ssl_trace_iob) {
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_trace_iob = stderr;
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef TRACE
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLTRACE");
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_trace = atoi(ev);
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* TRACE */
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLDEBUG");
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_debug = atoi(ev);
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* DEBUG */
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLKEYLOGFILE");
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_keylog_iob = fopen(ev, "a");
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!ssl_keylog_iob) {
2986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)		SSL_TRACE(("SSL: failed to open key log file"));
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ftell(ssl_keylog_iob) == 0) {
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    fputs("# SSL/TLS secrets log file, generated by NSS\n",
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  ssl_keylog_iob);
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
29922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLBYPASS");
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.bypassPKCS11 = (ev[0] == '1');
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: bypass default set to %d", \
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      ssl_defaults.bypassPKCS11));
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif /* NO_PKCS11_BYPASS */
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLFORCELOCKS");
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0] == '1') {
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_force_locks = PR_TRUE;
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.noLocks = 0;
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED.  ");
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("NSS_SSL_ENABLE_RENEGOTIATION");
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev) {
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ev[0] == '1' || LOWER(ev[0]) == 'u')
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_UNRESTRICTED;
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (ev[0] == '0' || LOWER(ev[0]) == 'n')
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (ev[0] == '2' || LOWER(ev[0]) == 'r')
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN;
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (ev[0] == '3' || LOWER(ev[0]) == 't')
30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_TRANSITIONAL;
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: enableRenegotiation set to %d",
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	               ssl_defaults.enableRenegotiation));
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0] == '1') {
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.requireSafeNegotiation = PR_TRUE;
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: requireSafeNegotiation set to %d",
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                PR_TRUE));
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("NSS_SSL_CBC_RANDOM_IV");
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0] == '0') {
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.cbcRandomIV = PR_FALSE;
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: cbcRandomIV set to 0"));
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* NSS_HAVE_GETENV */
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Create a newsocket structure for a file descriptor.
30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSocket *
30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetDefaultsFromEnvironment();
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_force_locks)
30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	makeLocks = PR_TRUE;
30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Make a new socket and get it ready */
30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss) {
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* This should be of type SSLKEAType, but CC on IRIX
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * complains during the for loop.
30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus status;
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt                = ssl_defaults;
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSocks       = PR_FALSE;
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noLocks        = !makeLocks;
30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->vrange             = *VERSIONS_DEFAULTS(protocolVariant);
3064c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch	ss->protocolVariant    = protocolVariant;
30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->peerID             = NULL;
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->rTimeout	       = PR_INTERVAL_NO_TIMEOUT;
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->wTimeout	       = PR_INTERVAL_NO_TIMEOUT;
30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cTimeout	       = PR_INTERVAL_NO_TIMEOUT;
30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cipherSpecs        = NULL;
30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sizeCipherSpecs    = 0;  /* produced lazily */
30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->preferredCipher    = NULL;
30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->url                = NULL;
30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i=kt_null; i < kt_kea_size; i++) {
30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sslServerCerts * sc = ss->serverCerts + i;
30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverCert      = NULL;
30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverCertChain = NULL;
30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverKeyPair   = NULL;
30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverKeyBits   = 0;
3081a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    ss->certStatusArray[i] = NULL;
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->requestedCertTypes = NULL;
30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->stepDownKeyPair    = NULL;
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->dbHandle           = CERT_GetDefaultCertDB();
30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Provide default implementation of hooks */
30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->authCertificate    = SSL_AuthCertificate;
30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->authCertificateArg = (void *)ss->dbHandle;
30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfig    = NULL;
30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfigArg = NULL;
30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getClientAuthData  = NULL;
30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH
30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getPlatformClientAuthData = NULL;
30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getPlatformClientAuthDataArg = NULL;
30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif   /* NSS_PLATFORM_CLIENT_AUTH */
30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->handleBadCert      = NULL;
30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->badCertArg         = NULL;
30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->pkcs11PinArg       = NULL;
3100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	ss->ephemeralECDHKeyPair = NULL;
31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getChannelID       = NULL;
31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getChannelIDArg    = NULL;
31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_ChooseOps(ss);
31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl2_InitSocketPolicy(ss);
31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_InitSocketPolicy(ss);
31072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (makeLocks) {
31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    status = ssl_MakeLocks(ss);
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (status != SECSuccess)
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = ssl_CreateSecurityInfo(ss);
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != SECSuccess)
31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = ssl_InitGather(&ss->gs);
31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != SECSuccess) {
31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_DestroySocketContents(ss);
31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_DestroyLocks(ss);
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss);
31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss = NULL;
31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3129