sslsock.c revision c2db58bd994c04d98e4ee2cd7565b71548655fe3
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)struct cipherPolicyStr {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int		cipher;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char 	export;	/* policy value for export policy */
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	unsigned char 	france;	/* policy value for france policy */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct cipherPolicyStr cipherPolicy;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This table contains two preconfigured policies: Export and France.
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)** It is used only by the functions NSS_SetDomesticPolicy,
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)** NSS_SetExportPolicy, and NSS_SetFrancePolicy.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Order of entries is not important.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static cipherPolicy ssl_ciphers[] = {	   /*   Export           France   */
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_EN_RC4_128_WITH_MD5,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_EN_RC4_128_EXPORT40_WITH_MD5,	    SSL_ALLOWED,     SSL_ALLOWED },
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_EN_RC2_128_CBC_WITH_MD5,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,   SSL_ALLOWED,     SSL_ALLOWED },
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_EN_DES_64_CBC_WITH_MD5,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_EN_DES_192_EDE3_CBC_WITH_MD5,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_WITH_RC4_128_MD5,		    SSL_RESTRICTED,  SSL_NOT_ALLOWED },
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_WITH_RC4_128_SHA,		    SSL_RESTRICTED,  SSL_NOT_ALLOWED },
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_WITH_3DES_EDE_CBC_SHA,	    SSL_RESTRICTED,  SSL_NOT_ALLOWED },
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_FIPS_WITH_DES_CBC_SHA,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_WITH_DES_CBC_SHA,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_EXPORT_WITH_RC4_40_MD5,	    SSL_ALLOWED,     SSL_ALLOWED },
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,	    SSL_ALLOWED,     SSL_ALLOWED },
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_DHE_RSA_WITH_DES_CBC_SHA,           SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_DHE_DSS_WITH_DES_CBC_SHA,           SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_DSS_WITH_RC4_128_SHA,           SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  SSL_RSA_WITH_NULL_MD5,		    SSL_ALLOWED,     SSL_ALLOWED },
65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  SSL_RSA_WITH_NULL_SHA,		    SSL_ALLOWED,     SSL_ALLOWED },
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_RSA_WITH_NULL_SHA256,		    SSL_ALLOWED,     SSL_ALLOWED },
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_RSA_WITH_AES_128_CBC_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_WITH_AES_128_CBC_SHA,     	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_RSA_WITH_AES_128_CBC_SHA256,        SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_RSA_WITH_AES_256_CBC_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_WITH_AES_256_CBC_SHA,     	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_RSA_WITH_AES_256_CBC_SHA256,        SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, 	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, 	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_WITH_SEED_CBC_SHA,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,    SSL_ALLOWED,     SSL_NOT_ALLOWED },
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,     SSL_ALLOWED,     SSL_NOT_ALLOWED },
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_ENABLE_ECC
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_ECDSA_WITH_NULL_SHA,           SSL_ALLOWED,     SSL_ALLOWED },
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_ECDSA_WITH_RC4_128_SHA,        SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,   SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_ECDSA_WITH_NULL_SHA,          SSL_ALLOWED,     SSL_ALLOWED },
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,       SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,   SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,   SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_RSA_WITH_NULL_SHA,             SSL_ALLOWED,     SSL_ALLOWED },
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_RSA_WITH_RC4_128_SHA,          SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_RSA_WITH_NULL_SHA,            SSL_ALLOWED,     SSL_ALLOWED },
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_RSA_WITH_RC4_128_SHA,         SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,  SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,     SSL_NOT_ALLOWED, SSL_NOT_ALLOWED },
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* NSS_ENABLE_ECC */
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {  0,					    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const sslSocketOps ssl_default_ops = {	/* No SSL. */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefConnect,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefBind,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefListen,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefShutdown,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefClose,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefRecv,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefSend,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefRead,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefWrite,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetpeername,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetsockname
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const sslSocketOps ssl_secure_ops = {	/* SSL. */
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureConnect,
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefBind,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefListen,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureShutdown,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureClose,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureRecv,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureSend,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureRead,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SecureWrite,
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetpeername,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DefGetsockname
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** default settings for socket enables
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslOptions ssl_defaults = {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { siBuffer, NULL, 0 }, /* nextProtoNego */
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_TRUE, 	/* useSecurity        */
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* useSocks           */
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* requestCertificate */
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,	        /* requireCertificate */
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* handshakeAsClient  */
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* handshakeAsServer  */
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* enableSSL2         */ /* now defaults to off in NSS 3.13 */
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* unusedBit9         */
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE, 	/* unusedBit10        */
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* noCache            */
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* fdx                */
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,	/* v2CompatibleHello  */ /* now defaults to off in NSS 3.13 */
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_TRUE,	/* detectRollBack     */
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* noStepDown         */
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* bypassPKCS11       */
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* noLocks            */
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* enableSessionTickets */
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* enableDeflate      */
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    2,          /* enableRenegotiation (default: requires extension) */
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* requireSafeNegotiation */
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_FALSE,   /* enableFalseStart   */
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_TRUE,    /* cbcRandomIV        */
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PR_FALSE    /* enableOCSPStapling */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * default range of enabled SSL/TLS protocols
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SSLVersionRange versions_defaults_stream = {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_3_0,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_TLS_1_0
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SSLVersionRange versions_defaults_datagram = {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_TLS_1_1,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSL_LIBRARY_VERSION_TLS_1_1
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VERSIONS_DEFAULTS(variant) \
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (variant == ssl_variant_stream ? &versions_defaults_stream : \
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &versions_defaults_datagram)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionIDLookupFunc  ssl_sid_lookup;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionIDCacheFunc   ssl_sid_cache;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSessionIDUncacheFunc ssl_sid_uncache;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool ssl_inited = PR_FALSE;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRDescIdentity ssl_layer_id;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool                  locksEverDisabled; 	/* implicitly PR_FALSE */
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool			ssl_force_locks;  	/* implicitly PR_FALSE */
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int                     ssl_lock_readers	= 1;	/* default true. */
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char                    ssl_debug;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char                    ssl_trace;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILE *                  ssl_trace_iob;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILE *                  ssl_keylog_iob;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char lockStatus[] = "Locks are ENABLED.  ";
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const PRUint16 srtpCiphers[] = {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SRTP_AES128_CM_HMAC_SHA1_80,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SRTP_AES128_CM_HMAC_SHA1_32,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* forward declarations. */
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus  ssl_MakeLocks(sslSocket *ss);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void       ssl_SetDefaultsFromEnvironment(void);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus   ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  PRDescIdentity id);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Lookup a socket structure from a file descriptor.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Only functions called through the PRIOMethods table should use this.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Other app-callable functions should use ssl_FindSocket.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSocket *
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_GetPrivate(PRFileDesc *fd)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd != NULL);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd->identity == ssl_layer_id);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fd->methods->file_type != PR_DESC_LAYERED ||
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fd->identity != ssl_layer_id) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = (sslSocket *)fd->secret;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->fd = fd;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* This function tries to find the SSL layer in the stack.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * It searches for the first SSL layer at or below the argument fd,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and failing that, it searches for the nearest SSL layer above the
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * argument fd.  It returns the private sslSocket from the found layer.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sslSocket *
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FindSocket(PRFileDesc *fd)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *layer;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(fd != NULL);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ssl_layer_id != 0);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (layer == NULL) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = (sslSocket *)layer->secret;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->fd = layer;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static sslSocket *
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DupSocket(sslSocket *os)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt                = os->opt;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSocks       = PR_FALSE;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->vrange             = os->vrange;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->peerID             = !os->peerID ? NULL : PORT_Strdup(os->peerID);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->url                = !os->url    ? NULL : PORT_Strdup(os->url);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ops      = os->ops;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->rTimeout = os->rTimeout;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->wTimeout = os->wTimeout;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cTimeout = os->cTimeout;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->dbHandle = os->dbHandle;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->allowedByPolicy	= os->allowedByPolicy;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->chosenPreference 	= os->chosenPreference;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (os->cipherSpecs) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs  = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ss->cipherSpecs)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		            os->sizeCipherSpecs);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs    = os->sizeCipherSpecs;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->preferredCipher    = os->preferredCipher;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs        = NULL;  /* produced lazily */
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs    = 0;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->preferredCipher    = NULL;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->opt.useSecurity) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* This int should be SSLKEAType, but CC on Irix complains,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * during the for loop.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int i;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sslServerCerts * oc = os->serverCerts;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sslServerCerts * sc = ss->serverCerts;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i=kt_null; i < kt_kea_size; i++, oc++, sc++) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (oc->serverCert && oc->serverCertChain) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCert      = CERT_DupCertificate(oc->serverCert);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!sc->serverCertChain)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    	goto loser;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCert      = NULL;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    sc->serverCertChain = NULL;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		sc->serverKeyPair = oc->serverKeyPair ?
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (oc->serverKeyPair && !sc->serverKeyPair)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto loser;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        sc->serverKeyBits = oc->serverKeyBits;
338a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		ss->certStatusArray[i] = !os->certStatusArray[i] ? NULL :
339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)				SECITEM_DupArray(NULL, os->certStatusArray[i]);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                  ssl3_GetKeyPairRef(os->stepDownKeyPair);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                  ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XXX We should detect this, and not just march on with NULL pointers.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->authCertificate       = os->authCertificate;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->authCertificateArg    = os->authCertificateArg;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getClientAuthData     = os->getClientAuthData;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getPlatformClientAuthData    = os->getPlatformClientAuthData;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getPlatformClientAuthDataArg = os->getPlatformClientAuthDataArg;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ss->sniSocketConfig       = os->sniSocketConfig;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ss->sniSocketConfigArg    = os->sniSocketConfigArg;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handleBadCert         = os->handleBadCert;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->badCertArg            = os->badCertArg;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handshakeCallback     = os->handshakeCallback;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->handshakeCallbackData = os->handshakeCallbackData;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->pkcs11PinArg          = os->pkcs11PinArg;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getChannelID          = os->getChannelID;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->getChannelIDArg       = os->getChannelIDArg;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Create security data */
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl_CopySecurityInfo(ss, os);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FreeSocket(ss);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DestroyLocks(sslSocket *ss)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Destroy locks. */
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->firstHandshakeLock) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->firstHandshakeLock);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->firstHandshakeLock = NULL;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3HandshakeLock) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->ssl3HandshakeLock);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3HandshakeLock = NULL;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->specLock) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	NSSRWLock_Destroy(ss->specLock);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->specLock = NULL;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->recvLock) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyLock(ss->recvLock);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->recvLock = NULL;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->sendLock) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyLock(ss->sendLock);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sendLock = NULL;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->xmitBufLock) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->xmitBufLock);
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->xmitBufLock = NULL;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->recvBufLock) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PZ_DestroyMonitor(ss->recvBufLock);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->recvBufLock = NULL;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Caller holds any relevant locks */
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_DestroySocketContents(sslSocket *ss)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* "i" should be of type SSLKEAType, but CC on IRIX complains during
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the for loop.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        i;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Free up socket */
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DestroySecurityInfo(&ss->sec);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl3_DestroySSL3Info(ss);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(ss->saveBuf.buf);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Free(ss->pendingBuf.buf);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DestroyGather(&ss->gs);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->peerID != NULL)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free(ss->peerID);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->url != NULL)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free((void *)ss->url);	/* CONST */
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->cipherSpecs) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Free(ss->cipherSpecs);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cipherSpecs     = NULL;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sizeCipherSpecs = 0;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Clean up server configuration */
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i=kt_null; i < kt_kea_size; i++) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslServerCerts * sc = ss->serverCerts + i;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sc->serverCert != NULL)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CERT_DestroyCertificate(sc->serverCert);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sc->serverCertChain != NULL)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CERT_DestroyCertificateList(sc->serverCertChain);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (sc->serverKeyPair != NULL)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl3_FreeKeyPair(sc->serverKeyPair);
453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	if (ss->certStatusArray[i] != NULL) {
454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    ss->certStatusArray[i] = NULL;
456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->stepDownKeyPair) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_FreeKeyPair(ss->stepDownKeyPair);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->stepDownKeyPair = NULL;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ephemeralECDHKeyPair) {
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ephemeralECDHKeyPair = NULL;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(!ss->xtnData.sniNameArr);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->xtnData.sniNameArr) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_Free(ss->xtnData.sniNameArr);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->xtnData.sniNameArr = NULL;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * free an sslSocket struct, and all the stuff that hangs off of it
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FreeSocket(sslSocket *ss)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Get every lock you can imagine!
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Caller already holds these:
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  SSL_LOCK_READER(ss);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**  SSL_LOCK_WRITER(ss);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetRecvBufLock(ss);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetXmitBufLock(ss);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSpecWriteLock(ss);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_DestroySocketContents(ss);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Release all the locks acquired above.  */
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SSL_UNLOCK_READER(ss);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SSL_UNLOCK_WRITER(ss);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseRecvBufLock(ss);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseXmitBufLock(ss);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_ReleaseSpecWriteLock(ss);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ssl_DestroyLocks(ss);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef DEBUG
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PORT_Memset(ss, 0x1f, sizeof *ss);
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PORT_Free(ss);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************/
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *       osfd = ss->fd->lower;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus         rv = SECFailure;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRSocketOptionData opt;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.option         = PR_SockOpt_NoDelay;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.value.no_delay = (PRBool)!enabled;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (osfd->methods->setsocketoption) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ChooseOps(sslSocket *ss)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Called from SSL_Enable (immediately below) */
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrepareSocket(sslSocket *ss)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus     rv = SECSuccess;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ChooseOps(ss);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_Enable(PRFileDesc *fd, int which, PRBool on)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_OptionSet(fd, which, on);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const PRCallOnceType pristineCallOnce;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType setupBypassOnce;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus SSL_BypassShutdown(void* appData, void* nssData)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* unload freeBL shared library from memory */
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BL_Unload();
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    setupBypassOnce = pristineCallOnce;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus SSL_BypassRegisterShutdown(void)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(SECSuccess == rv);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus SSL_BypassSetup(void)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /* Guarantee binary compatibility */
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PR_SUCCESS;
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_TLS, on) described in
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ssl.h in the section "SSL version range setting API".
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} /* else don't change anything */
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (on) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Expand the range of enabled version to include TLS 1.0 */
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = PR_MIN(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->max = PR_MAX(vrange->max, SSL_LIBRARY_VERSION_TLS_1_0);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Disable all TLS versions, leaving only SSL 3.0 if it was enabled */
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (vrange->min == SSL_LIBRARY_VERSION_3_0) {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_3_0;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Only TLS was enabled, so now no versions are. */
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_NONE;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_NONE;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Implements the semantics for SSL_OptionSet(SSL_ENABLE_SSL3, on) described in
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ssl.h in the section "SSL version range setting API".
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_3_0;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_3_0;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} /* else don't change anything */
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   if (on) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Expand the range of enabled versions to include SSL 3.0. We know
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * SSL 3.0 or some version of TLS is already enabled at this point, so
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * we don't need to change vrange->max.
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = SSL_LIBRARY_VERSION_3_0;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   } else {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Disable SSL 3.0, leaving TLS unaffected. */
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (vrange->max > SSL_LIBRARY_VERSION_3_0) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Only SSL 3.0 was enabled, so now no versions are. */
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->min = SSL_LIBRARY_VERSION_NONE;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    vrange->max = SSL_LIBRARY_VERSION_NONE;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv = SECSuccess;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool     holdingLocks;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    holdingLocks = (!ss->opt.noLocks);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SOCKS:
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSocks = PR_FALSE;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PrepareSocket(ss);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SECURITY:
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSecurity = on;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = PrepareSocket(ss);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUEST_CERTIFICATE:
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.requestCertificate = on;
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_CERTIFICATE:
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.requireCertificate = on;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_CLIENT:
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ss->opt.handshakeAsServer && on ) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.handshakeAsClient = on;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_SERVER:
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ss->opt.handshakeAsClient && on ) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.handshakeAsServer = on;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_TLS:
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableTLS(&ss->vrange, on);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->preferredCipher     = NULL;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->cipherSpecs) {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss->cipherSpecs);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs     = NULL;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs = 0;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL3:
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableSSL3(&ss->vrange, on);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->preferredCipher     = NULL;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->cipherSpecs) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss->cipherSpecs);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs     = NULL;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs = 0;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL2:
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableSSL2       = on;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->opt.v2CompatibleHello = on;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->preferredCipher     = NULL;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->cipherSpecs) {
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss->cipherSpecs);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->cipherSpecs     = NULL;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->sizeCipherSpecs = 0;
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_CACHE:
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noCache = on;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FDX:
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ss->opt.noLocks) {
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ss->opt.fdx = on;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_V2_COMPATIBLE_HELLO:
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (IS_DTLS(ss)) {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (on) {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_SetError(SEC_ERROR_INVALID_ARGS);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		rv = SECFailure; /* not allowed */
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ss->opt.v2CompatibleHello = on;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!on) {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->opt.enableSSL2    = on;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ROLLBACK_DETECTION:
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.detectRollBack = on;
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_STEP_DOWN:
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noStepDown     = on;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DisableExportCipherSuites(fd);
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_BYPASS_PKCS11:
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->handshakeBegun) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(PR_INVALID_STATE_ERROR);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (PR_FALSE != on) {
7987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                if (PR_SUCCESS == SSL_BypassSetup() ) {
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    ss->opt.bypassPKCS11 = PR_FALSE;
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                    ss->opt.bypassPKCS11 = on;
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } else {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    rv = SECFailure;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                ss->opt.bypassPKCS11 = PR_FALSE;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_LOCKS:
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ss->opt.fdx) {
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = SECFailure;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_force_locks)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    on = PR_FALSE;	/* silent override */
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noLocks   = on;
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    locksEverDisabled = PR_TRUE;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (!holdingLocks) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    rv = ssl_MakeLocks(ss);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (rv != SECSuccess) {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->opt.noLocks   = PR_TRUE;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SESSION_TICKETS:
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableSessionTickets = on;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_DEFLATE:
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableDeflate = on;
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_RENEGOTIATION:
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableRenegotiation = on;
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_SAFE_NEGOTIATION:
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.requireSafeNegotiation = on;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FALSE_START:
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.enableFalseStart = on;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_CBC_RANDOM_IV:
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.cbcRandomIV = on;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_OCSP_STAPLING:
857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ss->opt.enableOCSPStapling = on;
858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       break;
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* We can't use the macros for releasing the locks here,
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * because ss->opt.noLocks might have changed just above.
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * We must release these locks (monitors) here, if we aquired them above,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * regardless of the current value of ss->opt.noLocks.
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (holdingLocks) {
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PZ_ExitMonitor((ss)->ssl3HandshakeLock);
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PZ_ExitMonitor((ss)->firstHandshakeLock);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv = SECSuccess;
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool     on = PR_FALSE;
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pOn) {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*pOn = PR_FALSE;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SOCKS:               on = PR_FALSE;               break;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SECURITY:            on = ss->opt.useSecurity;        break;
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient;  break;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer;  break;
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_TLS:
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL3:
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0;
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL2:         on = ss->opt.enableSSL2;         break;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_CACHE:            on = ss->opt.noCache;            break;
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FDX:          on = ss->opt.fdx;                break;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello;  break;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ROLLBACK_DETECTION:  on = ss->opt.detectRollBack;     break;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_STEP_DOWN:        on = ss->opt.noStepDown;         break;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_BYPASS_PKCS11:       on = ss->opt.bypassPKCS11;       break;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_LOCKS:            on = ss->opt.noLocks;            break;
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SESSION_TICKETS:
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ss->opt.enableSessionTickets;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_DEFLATE:      on = ss->opt.enableDeflate;      break;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_RENEGOTIATION:
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ss->opt.enableRenegotiation; break;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_SAFE_NEGOTIATION:
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ss->opt.requireSafeNegotiation; break;
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FALSE_START:  on = ss->opt.enableFalseStart;   break;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_CBC_RANDOM_IV:       on = ss->opt.cbcRandomIV;        break;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *pOn = on;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv = SECSuccess;
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool     on = PR_FALSE;
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pOn) {
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetDefaultsFromEnvironment();
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SOCKS:               on = PR_FALSE;                        break;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_SECURITY:            on = ssl_defaults.useSecurity;        break;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient;  break;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer;  break;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_TLS:
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL3:
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SSL2:         on = ssl_defaults.enableSSL2;         break;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_CACHE:            on = ssl_defaults.noCache;		break;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FDX:          on = ssl_defaults.fdx;                break;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello;  break;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ROLLBACK_DETECTION:  on = ssl_defaults.detectRollBack;     break;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_STEP_DOWN:        on = ssl_defaults.noStepDown;         break;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_BYPASS_PKCS11:       on = ssl_defaults.bypassPKCS11;       break;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_NO_LOCKS:            on = ssl_defaults.noLocks;            break;
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_SESSION_TICKETS:
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	on = ssl_defaults.enableSessionTickets;
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_DEFLATE:      on = ssl_defaults.enableDeflate;      break;
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_RENEGOTIATION:
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ssl_defaults.enableRenegotiation; break;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_REQUIRE_SAFE_NEGOTIATION:
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  on = ssl_defaults.requireSafeNegotiation;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				  break;
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_FALSE_START:  on = ssl_defaults.enableFalseStart;   break;
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_CBC_RANDOM_IV:       on = ssl_defaults.cbcRandomIV;        break;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_ENABLE_OCSP_STAPLING:
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       on = ssl_defaults.enableOCSPStapling;
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       break;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = SECFailure;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *pOn = on;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* XXX Use Global Lock to protect this stuff. */
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_EnableDefault(int which, PRBool on)
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_OptionSetDefault(which, on);
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_OptionSetDefault(PRInt32 which, PRBool on)
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus status = ssl_Init();
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != SECSuccess) {
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return status;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetDefaultsFromEnvironment();
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (which) {
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SOCKS:
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.useSocks = PR_FALSE;
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_SECURITY:
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.useSecurity = on;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUEST_CERTIFICATE:
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.requestCertificate = on;
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_CERTIFICATE:
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.requireCertificate = on;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_CLIENT:
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ssl_defaults.handshakeAsServer && on ) {
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.handshakeAsClient = on;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_HANDSHAKE_AS_SERVER:
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ( ssl_defaults.handshakeAsClient && on ) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.handshakeAsServer = on;
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_TLS:
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableTLS(&versions_defaults_stream, on);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL3:
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_EnableSSL3(&versions_defaults_stream, on);
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SSL2:
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableSSL2 = on;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.v2CompatibleHello = on;
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_CACHE:
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.noCache = on;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FDX:
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_defaults.noLocks) {
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ssl_defaults.fdx = on;
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_V2_COMPATIBLE_HELLO:
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      	ssl_defaults.v2CompatibleHello = on;
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!on) {
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.enableSSL2    = on;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ROLLBACK_DETECTION:
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.detectRollBack = on;
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_STEP_DOWN:
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.noStepDown     = on;
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DisableDefaultExportCipherSuites();
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_BYPASS_PKCS11:
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (PR_FALSE != on) {
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (PR_SUCCESS == SSL_BypassSetup()) {
11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef NO_PKCS11_BYPASS
11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                ssl_defaults.bypassPKCS11   = PR_FALSE;
11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_defaults.bypassPKCS11   = on;
11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } else {
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                return SECFailure;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl_defaults.bypassPKCS11   = PR_FALSE;
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_NO_LOCKS:
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_defaults.fdx) {
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_INVALID_ARGS);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on && ssl_force_locks)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    on = PR_FALSE;		/* silent override */
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.noLocks        = on;
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (on) {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    locksEverDisabled = PR_TRUE;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_SESSION_TICKETS:
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableSessionTickets = on;
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_DEFLATE:
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableDeflate = on;
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_RENEGOTIATION:
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableRenegotiation = on;
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_REQUIRE_SAFE_NEGOTIATION:
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.requireSafeNegotiation = on;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_FALSE_START:
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.enableFalseStart = on;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_CBC_RANDOM_IV:
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_defaults.cbcRandomIV = on;
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SSL_ENABLE_OCSP_STAPLING:
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       ssl_defaults.enableOCSPStapling = on;
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       break;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* function tells us if the cipher suite is one that we no longer support. */
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_IsRemovedCipherSuite(PRInt32 suite)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (suite) {
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return PR_TRUE;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return PR_FALSE;
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Part of the public NSS API.
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since this is a global (not per-socket) setting, we cannot use the
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * HandshakeLock to protect this.  Probably want a global lock.
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetPolicy(long which, int policy)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	/* one of the two old FIPS ciphers */
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_CipherPolicySet(which, policy);
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = ssl_Init();
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_SetPolicy(which, policy);
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!oPolicy) {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*oPolicy = SSL_NOT_ALLOWED;
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_GetPolicy(which, oPolicy);
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Part of the public NSS API.
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Since this is a global (not per-socket) setting, we cannot use the
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * HandshakeLock to protect this.  Probably want a global lock.
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These changes have no effect on any sslSockets already created.
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_EnableCipher(long which, PRBool enabled)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	/* one of the two old FIPS ciphers */
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_CipherPrefSetDefault(which, enabled);
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv = ssl_Init();
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess) {
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SSL_IS_SSL2_CIPHER(which)) {
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefSetDefault(which, enabled);
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv;
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!enabled) {
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*enabled = PR_FALSE;
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefGetDefault(which, enabled);
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which))
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return SECSuccess;
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SSL_IS_SSL2_CIPHER(which)) {
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefSet(ss, which, enabled);
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus  rv;
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!enabled) {
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*enabled = PR_FALSE;
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_IsRemovedCipherSuite(which)) {
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*enabled = PR_FALSE;
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	rv = SECSuccess;
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (SSL_IS_SSL2_CIPHER(which)) {
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl2_CipherPrefGet(ss, which, enabled);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSS_SetDomesticPolicy(void)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus      status = SECSuccess;
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cipherPolicy * policy;
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (policy = ssl_ciphers; policy->cipher != 0; ++policy) {
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = SSL_SetPolicy(policy->cipher, SSL_ALLOWED);
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != SECSuccess)
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return status;
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSS_SetExportPolicy(void)
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NSS_SetDomesticPolicy();
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSS_SetFrancePolicy(void)
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NSS_SetDomesticPolicy();
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetChannelBinding(PRFileDesc *fd,
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      SSLChannelBindingType binding_type,
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      unsigned char *out,
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      unsigned int *outLen,
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      unsigned int outLenMax) {
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelBinding",
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (binding_type != SSL_CHANNEL_BINDING_TLS_UNIQUE) {
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* LOCKS ??? XXX */
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRFileDesc *
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ns = NULL;
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    rv;
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRNetAddr   addr;
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus	status = ssl_Init();
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != SECSuccess) {
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (model == NULL) {
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Just create a default socket if we're given NULL for the model */
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sslSocket * ss = ssl_FindSocket(model);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss == NULL || ss->protocolVariant != variant) {
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	      SSL_GETPID(), model));
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return NULL;
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns = ssl_DupSocket(ss);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns == NULL)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return NULL;
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != PR_SUCCESS) {
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_FreeSocket(ns);
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SET_ERROR_CODE
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return NULL;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ns = ssl_FindSocket(fd);
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ns);
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fd;
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRFileDesc *
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_ImportFD(model, fd, ssl_variant_stream);
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRFileDesc *
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_ImportFD(model, fd, ssl_variant_datagram);
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 void *arg)
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoCallback", SSL_GETPID(),
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 fd));
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->nextProtoCallback = callback;
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->nextProtoArg = arg;
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SSL_SetNextProtoNego is used.
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  const unsigned char *protos, unsigned int protos_len,
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  unsigned char *protoOut, unsigned int *protoOutLen,
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  unsigned int protoMaxLen)
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    unsigned int i, j;
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const unsigned char *result;
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in ssl_NextProtoNegoCallback",
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (protos_len == 0) {
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* The server supports the extension, but doesn't have any protocols
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * configured. In this case we request our favoured protocol. */
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto pick_first;
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* For each protocol in server preference, see if we support it. */
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < protos_len; ) {
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (j = 0; j < ss->opt.nextProtoNego.len; ) {
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (protos[i] == ss->opt.nextProtoNego.data[j] &&
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PORT_Memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     protos[i]) == 0) {
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* We found a match. */
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		result = &protos[i];
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto found;
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	i += 1 + (unsigned int)protos[i];
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pick_first:
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = ss->opt.nextProtoNego.data;
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found:
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (protoMaxLen < result[0]) {
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(protoOut, result + 1, result[0]);
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *protoOutLen = result[0];
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     unsigned int length)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECStatus rv;
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECItem dataItem = { siBuffer, (unsigned char *) data, length };
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem);
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != SECSuccess)
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return rv;
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL);
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 unsigned int *bufLen, unsigned int bufLenMax)
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 fd));
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!state || !buf || !bufLen) {
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *state = ss->ssl3.nextProtoState;
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.nextProto.data) {
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->ssl3.nextProto.len > bufLenMax) {
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_SetError(SEC_ERROR_OUTPUT_LEN);
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return SECFailure;
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len);
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*bufLen = ss->ssl3.nextProto.len;
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*bufLen = 0;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     const PRUint16 *ciphers,
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     unsigned int numCiphers)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned int i;
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss || !IS_DTLS(ss)) {
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSRTPCiphers",
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (numCiphers > MAX_DTLS_SRTP_CIPHER_SUITES) {
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.dtlsSRTPCipherCount = 0;
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < numCiphers; i++) {
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const PRUint16 *srtpCipher = srtpCiphers;
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (*srtpCipher) {
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ciphers[i] == *srtpCipher)
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    srtpCipher++;
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (*srtpCipher) {
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss->ssl3.dtlsSRTPCiphers[ss->ssl3.dtlsSRTPCipherCount++] =
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ciphers[i];
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "suite specified: 0x%04hx", SSL_GETPID(), fd,
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ciphers[i]));
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->ssl3.dtlsSRTPCipherCount == 0) {
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * ss;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSRTPCipher",
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 SSL_GETPID(), fd));
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->ssl3.dtlsSRTPCipherSuite) {
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *cipher = ss->ssl3.dtlsSRTPCipherSuite;
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRFileDesc *
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_NOT_REACHED("not implemented");
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket * sm = NULL, *ss = NULL;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslServerCerts * mc = NULL;
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslServerCerts * sc = NULL;
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (model == NULL) {
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sm = ssl_FindSocket(model);
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm == NULL) {
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ReconfigFD",
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 SSL_GETPID(), model));
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = ssl_FindSocket(fd);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(ss);
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss == NULL) {
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_SetError(SEC_ERROR_INVALID_ARGS);
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->opt  = sm->opt;
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->vrange = sm->vrange;
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->opt.useSecurity) {
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PORT_SetError(SEC_ERROR_INVALID_ARGS);
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return NULL;
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* This int should be SSLKEAType, but CC on Irix complains,
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * during the for loop.
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i=kt_null; i < kt_kea_size; i++) {
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mc = &(sm->serverCerts[i]);
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sc = &(ss->serverCerts[i]);
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mc->serverCert && mc->serverCertChain) {
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sc->serverCert) {
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CERT_DestroyCertificate(sc->serverCert);
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverCert      = CERT_DupCertificate(mc->serverCert);
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sc->serverCertChain) {
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CERT_DestroyCertificateList(sc->serverCertChain);
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverCertChain = CERT_DupCertList(mc->serverCertChain);
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (!sc->serverCertChain)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                goto loser;
1717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    if (sm->certStatusArray[i]) {
1718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		if (ss->certStatusArray[i]) {
1719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		    SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
1720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		    ss->certStatusArray[i] = NULL;
1721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		}
1722a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		ss->certStatusArray[i] = SECITEM_DupArray(NULL, sm->certStatusArray[i]);
1723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		if (!ss->certStatusArray[i])
1724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)		    goto loser;
1725a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    }
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mc->serverKeyPair) {
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (sc->serverKeyPair) {
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl3_FreeKeyPair(sc->serverKeyPair);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverKeyPair = ssl3_GetKeyPairRef(mc->serverKeyPair);
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sc->serverKeyBits = mc->serverKeyBits;
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->stepDownKeyPair) {
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ss->stepDownKeyPair) {
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl3_FreeKeyPair(ss->stepDownKeyPair);
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->stepDownKeyPair = ssl3_GetKeyPairRef(sm->stepDownKeyPair);
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->ephemeralECDHKeyPair) {
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ss->ephemeralECDHKeyPair) {
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->ephemeralECDHKeyPair =
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* copy trust anchor names */
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->ssl3.ca_list) {
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ss->ssl3.ca_list) {
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            CERT_FreeDistNames(ss->ssl3.ca_list);
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->ssl3.ca_list = CERT_DupDistNames(sm->ssl3.ca_list);
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!ss->ssl3.ca_list) {
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            goto loser;
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->authCertificate)
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->authCertificate       = sm->authCertificate;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->authCertificateArg)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->authCertificateArg    = sm->authCertificateArg;
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getClientAuthData)
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getClientAuthData     = sm->getClientAuthData;
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getClientAuthDataArg)
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getClientAuthDataArg  = sm->getClientAuthDataArg;
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getPlatformClientAuthData)
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getPlatformClientAuthData    = sm->getPlatformClientAuthData;
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getPlatformClientAuthDataArg)
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getPlatformClientAuthDataArg = sm->getPlatformClientAuthDataArg;
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->sniSocketConfig)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfig       = sm->sniSocketConfig;
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->sniSocketConfigArg)
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfigArg    = sm->sniSocketConfigArg;
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->handleBadCert)
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->handleBadCert         = sm->handleBadCert;
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->badCertArg)
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->badCertArg            = sm->badCertArg;
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->handshakeCallback)
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->handshakeCallback     = sm->handshakeCallback;
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->handshakeCallbackData)
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->handshakeCallbackData = sm->handshakeCallbackData;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->pkcs11PinArg)
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->pkcs11PinArg          = sm->pkcs11PinArg;
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getChannelID)
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getChannelID          = sm->getChannelID;
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (sm->getChannelIDArg)
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->getChannelIDArg       = sm->getChannelIDArg;
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return fd;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			SSL3ProtocolVersion version)
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (protocolVariant) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_stream:
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (version >= SSL_LIBRARY_VERSION_3_0 &&
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_datagram:
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Can't get here */
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Assert(PR_FALSE);
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FALSE;
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Returns PR_TRUE if the given version range is valid and
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** fully supported; otherwise, returns PR_FALSE.
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRBool
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 const SSLVersionRange *vrange)
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return vrange &&
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   vrange->min <= vrange->max &&
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   ssl3_VersionIsSupported(protocolVariant, vrange->max);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     SSLVersionRange *vrange)
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vrange) {
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (protocolVariant) {
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_stream:
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = SSL_LIBRARY_VERSION_3_0;
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ssl_variant_datagram:
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	break;
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   SSLVersionRange *vrange)
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((protocolVariant != ssl_variant_stream &&
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 protocolVariant != ssl_variant_datagram) || !vrange) {
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *vrange = *VERSIONS_DEFAULTS(protocolVariant);
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   const SSLVersionRange *vrange)
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *VERSIONS_DEFAULTS(protocolVariant) = *vrange;
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeGet",
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), fd));
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vrange) {
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SEC_ERROR_INVALID_ARGS);
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *vrange = ss->vrange;
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRCallOnceType checkTLS12TokenOnce;
1911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRBool tls12TokenExists;
1912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRStatus
1914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl_CheckTLS12Token(void)
1915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
1916868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    tls12TokenExists =
1917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	PK11_TokenExists(CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256);
1918868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return PR_SUCCESS;
1919868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1920868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1921868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)static PRBool
1922868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)ssl_TLS12TokenExists(void)
1923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){
1924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    (void) PR_CallOnce(&checkTLS12TokenOnce, ssl_CheckTLS12Token);
1925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return tls12TokenExists;
1926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SECStatus
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeSet",
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SSL_GETPID(), fd));
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return SECFailure;
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Get1stHandshakeLock(ss);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSSL3HandshakeLock(ss);
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->vrange = *vrange;
1948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    /* If we don't have a sufficiently up-to-date softoken then we cannot do
1949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)     * TLS 1.2. */
1950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_2 &&
1951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        !ssl_TLS12TokenExists()) {
1952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	/* If the user requested a minimum version of 1.2, then we don't
1953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	 * silently downgrade. */
1954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	if (ss->vrange.min >= SSL_LIBRARY_VERSION_TLS_1_2) {
1955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    ssl_ReleaseSSL3HandshakeLock(ss);
1956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    ssl_Release1stHandshakeLock(ss);
1957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
1958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	    return SECFailure;
1959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	}
1960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)	ss->vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;
1961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_ReleaseSSL3HandshakeLock(ss);
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Release1stHandshakeLock(ss);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const SECItemArray *
1970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
1971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss = ssl_FindSocket(fd);
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss) {
1975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerStapledOCSPResponses",
1976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                SSL_GETPID(), fd));
1977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return NULL;
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!ss->sec.ci.sid) {
1981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
1982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       return NULL;
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return &ss->sec.ci.sid->peerCertStatus;
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (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
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ** handshake has been sent.  so do NOT to poll on write.
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    */
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    new_flags ^=  PR_POLL_WRITE;   /* don't select on write. */
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    new_flags |=  PR_POLL_READ;	   /* do    select on read. */
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*p_out_flags = PR_POLL_READ;	/* it's ready already. */
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return new_flags;
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	new_flags |=  PR_POLL_WRITE;   /* also select on write. */
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->ssl3.hs.restartTarget != NULL) {
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Read and write will block until the asynchronous callback completes
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * (e.g. until SSL_AuthCertificateComplete is called), so don't tell
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * the caller to poll the socket unless there is pending write data.
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) {
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Ignore any newly-received data on the socket, but do wait for
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * the socket to become writable again. Here, it is OK for an error
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * to be detected, because our logic for sending pending write data
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * will allow us to report the error to the caller without the risk
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * of the application spinning.
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags &= (PR_POLL_WRITE | PR_POLL_EXCEPT);
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Unfortunately, clearing new_flags will make it impossible for
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * the application to detect errors that it would otherwise be
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * able to detect with PR_POLL_EXCEPT, until the asynchronous
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * callback completes. However, we must clear all the flags to
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * prevent the application from spinning (alternating between
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * calling PR_Poll that would return PR_POLL_EXCEPT, and send/recv
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * which won't actually report the I/O error while we are waiting
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * for the asynchronous callback to complete).
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags = 0;
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (new_flags && (fd->lower->methods->poll != NULL)) {
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt16    lower_out_flags = 0;
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt16    lower_new_flags;
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lower_new_flags = fd->lower->methods->poll(fd->lower, new_flags,
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					           &lower_out_flags);
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((lower_new_flags & lower_out_flags) && (how_flags != new_flags)) {
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PRInt16 out_flags = lower_out_flags & ~PR_POLL_RW;
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (lower_out_flags & PR_POLL_READ)
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		out_flags |= PR_POLL_WRITE;
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (lower_out_flags & PR_POLL_WRITE)
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		out_flags |= PR_POLL_READ;
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *p_out_flags = out_flags;
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags = how_flags;
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *p_out_flags = lower_out_flags;
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    new_flags    = lower_new_flags;
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new_flags;
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 const void *headers, PRInt32 hlen,
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 PRTransmitFileFlags flags, PRIntervalTime timeout)
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRSendFileData sfd;
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.fd = fd;
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.file_offset = 0;
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.file_nbytes = 0;
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.header = headers;
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.hlen = hlen;
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.trailer = NULL;
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sfd.tlen = 0;
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sd->methods->sendfile(sd, &sfd, flags, timeout);
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FdIsBlocking(PRFileDesc *fd)
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRSocketOptionData opt;
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus           status;
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.option             = PR_SockOpt_Nonblocking;
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    opt.value.non_blocking = PR_FALSE;
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = PR_GetSocketOption(fd, &opt);
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != PR_SUCCESS)
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return PR_FALSE;
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (PRBool)!opt.value.non_blocking;
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRBool
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SocketIsBlocking(sslSocket *ss)
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ssl_FdIsBlocking(ss->fd);
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32  sslFirstBufSize = 8 * 1024;
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PRInt32  sslCopyLimit    = 1024;
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           PRIntervalTime timeout)
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            bufLen;
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            left;
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            rv;
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt32            sent      =  0;
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRInt32      first_len = sslFirstBufSize;
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRInt32      limit     = sslCopyLimit;
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRBool             blocking;
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRIOVec            myIov	 = { 0, 0 };
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char               buf[MAX_FRAGMENT_LENGTH];
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vectors > PR_MAX_IOVECTOR_SIZE) {
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return -1;
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    blocking = ssl_FdIsBlocking(fd);
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define K16 sizeof(buf)
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GET_VECTOR   do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_ERR(rv, len) \
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != len) { \
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (rv < 0) { \
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!blocking \
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&& (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		&& (sent > 0)) { \
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return sent; \
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else { \
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return -1; \
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } \
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} \
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Only a nonblocking socket can have partial sends */ \
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PR_ASSERT(!blocking); \
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return sent + rv; \
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SEND(bfr, len) \
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do { \
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	rv = ssl_Send(fd, bfr, len, 0, timeout); \
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	HANDLE_ERR(rv, len) \
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	sent += len; \
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (0)
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Make sure the first write is at least 8 KB, if possible. */
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KILL_VECTORS
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vectors)
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ssl_Send(fd, 0, 0, 0, timeout);
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GET_VECTOR;
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!vectors) {
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (myIov.iov_len < first_len) {
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bufLen = myIov.iov_len;
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	left = first_len - bufLen;
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (vectors && left) {
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    int toCopy;
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    GET_VECTOR;
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    toCopy = PR_MIN(left, myIov.iov_len);
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bufLen         += toCopy;
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left           -= toCopy;
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_base += toCopy;
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len  -= toCopy;
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SEND( buf, bufLen );
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (vectors || myIov.iov_len) {
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PRInt32   addLen;
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!myIov.iov_len) {
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    GET_VECTOR;
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (myIov.iov_len >= K16) {
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SEND(myIov.iov_base, K16);
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_base += K16;
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len  -= K16;
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!myIov.iov_len)
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!vectors || myIov.iov_len > limit) {
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    addLen = 0;
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Addlen is already computed. */;
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (vectors > 1 &&
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     addLen = limit - myIov.iov_len;
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    addLen = 0;
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!addLen) {
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SEND( myIov.iov_base, myIov.iov_len );
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len = 0;
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    continue;
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	bufLen = myIov.iov_len;
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	do {
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    GET_VECTOR;
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_base += addLen;
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    myIov.iov_len  -= addLen;
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bufLen         += addLen;
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    left = PR_MIN( limit, K16 - bufLen);
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!vectors 		/* no more left */
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ||  myIov.iov_len > 0	/* we didn't use that one all up */
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ||  bufLen >= K16		/* it's full. */
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ) {
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		addLen = 0;
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((addLen = iov->iov_len % K16) <= left) {
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Addlen is already computed. */;
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (vectors > 1 &&
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 iov[1].iov_len % K16 + addLen <= left + limit) {
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 addLen = left;
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		addLen = 0;
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} while (addLen);
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SEND( buf, bufLen );
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return sent;
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * These functions aren't implemented.
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Available(PRFileDesc *fd)
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt64 PR_CALLBACK
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Available64(PRFileDesc *fd)
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt64 res;
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_I2L(res, -1L);
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return res;
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FSync(PRFileDesc *fd)
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt64 PR_CALLBACK
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRInt64 res;
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LL_I2L(res, -1L);
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return res;
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus PR_CALLBACK
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     PRNetAddr *addr, PRIntervalTime timeout)
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRInt32 PR_CALLBACK
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   const PRNetAddr *addr, PRIntervalTime timeout)
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PORT_Assert(0);
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const PRIOMethods ssl_methods = {
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_DESC_LAYERED,
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Close,           	/* close        */
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Read,            	/* read         */
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Write,           	/* write        */
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Available,       	/* available    */
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Available64,     	/* available64  */
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FSync,           	/* fsync        */
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Seek,            	/* seek         */
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Seek64,          	/* seek64       */
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FileInfo,        	/* fileInfo     */
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_FileInfo64,      	/* fileInfo64   */
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_WriteV,          	/* writev       */
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Connect,         	/* connect      */
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Accept,          	/* accept       */
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Bind,            	/* bind         */
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Listen,          	/* listen       */
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Shutdown,        	/* shutdown     */
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Recv,            	/* recv         */
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Send,            	/* send         */
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_RecvFrom,        	/* recvfrom     */
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SendTo,          	/* sendto       */
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_Poll,            	/* poll         */
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_EmulateAcceptRead,       /* acceptread   */
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_TransmitFile,           /* transmitfile */
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetSockName,     	/* getsockname  */
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_GetPeerName,     	/* getpeername  */
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* getsockopt   OBSOLETE */
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* setsockopt   OBSOLETE */
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* getsocketoption   */
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* setsocketoption   */
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PR_EmulateSendFile, 	/* Send a (partial) file with header/trailer*/
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL,                	/* reserved for future use */
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL                 	/* reserved for future use */
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRIOMethods combined_methods;
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SetupIOMethods(void)
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          PRIOMethods *new_methods  = &combined_methods;
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PRIOMethods *my_methods   = &ssl_methods;
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *new_methods = *nspr_methods;
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->file_type         = my_methods->file_type;
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->close             = my_methods->close;
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->read              = my_methods->read;
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->write             = my_methods->write;
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->available         = my_methods->available;
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->available64       = my_methods->available64;
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->fsync             = my_methods->fsync;
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->seek              = my_methods->seek;
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->seek64            = my_methods->seek64;
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->fileInfo          = my_methods->fileInfo;
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->fileInfo64        = my_methods->fileInfo64;
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->writev            = my_methods->writev;
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->connect           = my_methods->connect;
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->accept            = my_methods->accept;
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->bind              = my_methods->bind;
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->listen            = my_methods->listen;
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->shutdown          = my_methods->shutdown;
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->recv              = my_methods->recv;
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->send              = my_methods->send;
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->recvfrom          = my_methods->recvfrom;
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->sendto            = my_methods->sendto;
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->poll              = my_methods->poll;
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->acceptread        = my_methods->acceptread;
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->transmitfile      = my_methods->transmitfile;
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->getsockname       = my_methods->getsockname;
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->getpeername       = my_methods->getpeername;
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  new_methods->getsocketoption   = my_methods->getsocketoption;	*/
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*  new_methods->setsocketoption   = my_methods->setsocketoption;	*/
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_methods->sendfile          = my_methods->sendfile;
28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRCallOnceType initIoLayerOnce;
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_InitIOLayer(void)
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_layer_id = PR_GetUniqueIdentity("SSL");
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetupIOMethods();
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_inited = PR_TRUE;
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PRStatus
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRFileDesc *layer	= NULL;
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PRStatus    status;
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ssl_inited) {
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != PR_SUCCESS)
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ns == NULL)
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (layer == NULL)
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer->secret = (PRFilePrivate *)ns;
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Here, "stack" points to the PRFileDesc on the top of the stack.
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** "layer" points to a new FD that is to be inserted into the stack.
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If layer is being pushed onto the top of the stack, then
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** PR_PushIOLayer switches the contents of stack and layer, and then
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** puts stack on top of layer, so that after it is done, the top of
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** stack is the same "stack" as it was before, and layer is now the
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** FD for the former top of stack.
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** After this call, stack always points to the top PRFD on the stack.
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If this function fails, the contents of stack and layer are as
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** they were before the call.
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status = PR_PushIOLayer(stack, id, layer);
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (status != PR_SUCCESS)
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_SUCCESS;
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (layer) {
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	layer->dtor(layer); /* free layer */
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PR_FAILURE;
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* if this fails, caller must destroy socket. */
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static SECStatus
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_MakeLocks(sslSocket *ss)
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->firstHandshakeLock)
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->ssl3HandshakeLock  = PZ_NewMonitor(nssILockSSL);
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->ssl3HandshakeLock)
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->specLock           = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->specLock)
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->recvBufLock        = PZ_NewMonitor(nssILockSSL);
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->recvBufLock)
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->xmitBufLock        = PZ_NewMonitor(nssILockSSL);
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ss->xmitBufLock)
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto loser;
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss->writerThread       = NULL;
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_lock_readers) {
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->recvLock       = PZ_NewLock(nssILockSSL);
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->recvLock)
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->sendLock       = PZ_NewLock(nssILockSSL);
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ss->sendLock)
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECSuccess;
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_DestroyLocks(ss);
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SECFailure;
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NSS_HAVE_GETENV 1
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LOWER(x) (x | 0x20)  /* cheap ToLower function ignores LOCALE */
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_SetDefaultsFromEnvironment(void)
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined( NSS_HAVE_GETENV )
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static int firsttime = 1;
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (firsttime) {
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	char * ev;
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	firsttime = 0;
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLDEBUGFILE");
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_trace_iob = fopen(ev, "w");
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!ssl_trace_iob) {
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_trace_iob = stderr;
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef TRACE
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLTRACE");
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_trace = atoi(ev);
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* TRACE */
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLDEBUG");
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_debug = atoi(ev);
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* DEBUG */
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLKEYLOGFILE");
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_keylog_iob = fopen(ev, "a");
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (!ssl_keylog_iob) {
2982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)		SSL_TRACE(("SSL: failed to open key log file"));
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (ftell(ssl_keylog_iob) == 0) {
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    fputs("# SSL/TLS secrets log file, generated by NSS\n",
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			  ssl_keylog_iob);
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
29882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)		SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NO_PKCS11_BYPASS
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLBYPASS");
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0]) {
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.bypassPKCS11 = (ev[0] == '1');
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: bypass default set to %d", \
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		      ssl_defaults.bypassPKCS11));
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif /* NO_PKCS11_BYPASS */
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("SSLFORCELOCKS");
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0] == '1') {
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_force_locks = PR_TRUE;
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.noLocks = 0;
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED.  ");
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("NSS_SSL_ENABLE_RENEGOTIATION");
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev) {
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ev[0] == '1' || LOWER(ev[0]) == 'u')
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_UNRESTRICTED;
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (ev[0] == '0' || LOWER(ev[0]) == 'n')
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (ev[0] == '2' || LOWER(ev[0]) == 'r')
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN;
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (ev[0] == '3' || LOWER(ev[0]) == 't')
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    	ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_TRANSITIONAL;
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: enableRenegotiation set to %d",
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	               ssl_defaults.enableRenegotiation));
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0] == '1') {
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.requireSafeNegotiation = PR_TRUE;
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: requireSafeNegotiation set to %d",
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                PR_TRUE));
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ev = getenv("NSS_SSL_CBC_RANDOM_IV");
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ev && ev[0] == '0') {
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_defaults.cbcRandomIV = PR_FALSE;
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SSL_TRACE(("SSL: cbcRandomIV set to 0"));
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* NSS_HAVE_GETENV */
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Create a newsocket structure for a file descriptor.
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sslSocket *
30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sslSocket *ss;
30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssl_SetDefaultsFromEnvironment();
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ssl_force_locks)
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	makeLocks = PR_TRUE;
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Make a new socket and get it ready */
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ss) {
30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* This should be of type SSLKEAType, but CC on IRIX
30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * complains during the for loop.
30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SECStatus status;
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt                = ssl_defaults;
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.useSocks       = PR_FALSE;
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->opt.noLocks        = !makeLocks;
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->vrange             = *VERSIONS_DEFAULTS(protocolVariant);
3060c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch	ss->protocolVariant    = protocolVariant;
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->peerID             = NULL;
30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->rTimeout	       = PR_INTERVAL_NO_TIMEOUT;
30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->wTimeout	       = PR_INTERVAL_NO_TIMEOUT;
30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cTimeout	       = PR_INTERVAL_NO_TIMEOUT;
30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->cipherSpecs        = NULL;
30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sizeCipherSpecs    = 0;  /* produced lazily */
30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->preferredCipher    = NULL;
30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->url                = NULL;
30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i=kt_null; i < kt_kea_size; i++) {
30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sslServerCerts * sc = ss->serverCerts + i;
30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverCert      = NULL;
30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverCertChain = NULL;
30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverKeyPair   = NULL;
30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sc->serverKeyBits   = 0;
3077a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)	    ss->certStatusArray[i] = NULL;
30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->requestedCertTypes = NULL;
30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->stepDownKeyPair    = NULL;
30815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->dbHandle           = CERT_GetDefaultCertDB();
30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Provide default implementation of hooks */
30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->authCertificate    = SSL_AuthCertificate;
30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->authCertificateArg = (void *)ss->dbHandle;
30865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfig    = NULL;
30875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ss->sniSocketConfigArg = NULL;
30885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getClientAuthData  = NULL;
30895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NSS_PLATFORM_CLIENT_AUTH
30905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getPlatformClientAuthData = NULL;
30915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getPlatformClientAuthDataArg = NULL;
30925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif   /* NSS_PLATFORM_CLIENT_AUTH */
30935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->handleBadCert      = NULL;
30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->badCertArg         = NULL;
30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->pkcs11PinArg       = NULL;
3096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)	ss->ephemeralECDHKeyPair = NULL;
30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getChannelID       = NULL;
30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ss->getChannelIDArg    = NULL;
30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl_ChooseOps(ss);
31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl2_InitSocketPolicy(ss);
31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ssl3_InitSocketPolicy(ss);
31032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)	PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (makeLocks) {
31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    status = ssl_MakeLocks(ss);
31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (status != SECSuccess)
31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto loser;
31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = ssl_CreateSecurityInfo(ss);
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != SECSuccess)
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto loser;
31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	status = ssl_InitGather(&ss->gs);
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (status != SECSuccess) {
31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)loser:
31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_DestroySocketContents(ss);
31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ssl_DestroyLocks(ss);
31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PORT_Free(ss);
31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ss = NULL;
31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ss;
31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125