security/nss/lib/ssl/sslsock.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * vtables (and methods that call through them) for the 4 types of
michael@0 3 * SSLSockets supported. Only one type is still supported.
michael@0 4 * Various other functions.
michael@0 5 *
michael@0 6 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 7 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 9 #include "seccomon.h"
michael@0 10 #include "cert.h"
michael@0 11 #include "keyhi.h"
michael@0 12 #include "ssl.h"
michael@0 13 #include "sslimpl.h"
michael@0 14 #include "sslproto.h"
michael@0 15 #include "nspr.h"
michael@0 16 #include "private/pprio.h"
michael@0 17 #ifndef NO_PKCS11_BYPASS
michael@0 18 #include "blapi.h"
michael@0 19 #endif
michael@0 20 #include "nss.h"
michael@0 21
michael@0 22 #define SET_ERROR_CODE /* reminder */
michael@0 23
michael@0 24 static const sslSocketOps ssl_default_ops = { /* No SSL. */
michael@0 25 ssl_DefConnect,
michael@0 26 NULL,
michael@0 27 ssl_DefBind,
michael@0 28 ssl_DefListen,
michael@0 29 ssl_DefShutdown,
michael@0 30 ssl_DefClose,
michael@0 31 ssl_DefRecv,
michael@0 32 ssl_DefSend,
michael@0 33 ssl_DefRead,
michael@0 34 ssl_DefWrite,
michael@0 35 ssl_DefGetpeername,
michael@0 36 ssl_DefGetsockname
michael@0 37 };
michael@0 38
michael@0 39 static const sslSocketOps ssl_secure_ops = { /* SSL. */
michael@0 40 ssl_SecureConnect,
michael@0 41 NULL,
michael@0 42 ssl_DefBind,
michael@0 43 ssl_DefListen,
michael@0 44 ssl_SecureShutdown,
michael@0 45 ssl_SecureClose,
michael@0 46 ssl_SecureRecv,
michael@0 47 ssl_SecureSend,
michael@0 48 ssl_SecureRead,
michael@0 49 ssl_SecureWrite,
michael@0 50 ssl_DefGetpeername,
michael@0 51 ssl_DefGetsockname
michael@0 52 };
michael@0 53
michael@0 54 /*
michael@0 55 ** default settings for socket enables
michael@0 56 */
michael@0 57 static sslOptions ssl_defaults = {
michael@0 58 { siBuffer, NULL, 0 }, /* nextProtoNego */
michael@0 59 PR_TRUE, /* useSecurity */
michael@0 60 PR_FALSE, /* useSocks */
michael@0 61 PR_FALSE, /* requestCertificate */
michael@0 62 2, /* requireCertificate */
michael@0 63 PR_FALSE, /* handshakeAsClient */
michael@0 64 PR_FALSE, /* handshakeAsServer */
michael@0 65 PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */
michael@0 66 PR_FALSE, /* unusedBit9 */
michael@0 67 PR_FALSE, /* unusedBit10 */
michael@0 68 PR_FALSE, /* noCache */
michael@0 69 PR_FALSE, /* fdx */
michael@0 70 PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */
michael@0 71 PR_TRUE, /* detectRollBack */
michael@0 72 PR_FALSE, /* noStepDown */
michael@0 73 PR_FALSE, /* bypassPKCS11 */
michael@0 74 PR_FALSE, /* noLocks */
michael@0 75 PR_FALSE, /* enableSessionTickets */
michael@0 76 PR_FALSE, /* enableDeflate */
michael@0 77 2, /* enableRenegotiation (default: requires extension) */
michael@0 78 PR_FALSE, /* requireSafeNegotiation */
michael@0 79 PR_FALSE, /* enableFalseStart */
michael@0 80 PR_TRUE, /* cbcRandomIV */
michael@0 81 PR_FALSE, /* enableOCSPStapling */
michael@0 82 PR_TRUE, /* enableNPN */
michael@0 83 PR_FALSE, /* enableALPN */
michael@0 84 PR_FALSE, /* dummy */
michael@0 85 PR_FALSE /* enableFallbackSCSV */
michael@0 86 };
michael@0 87
michael@0 88 /*
michael@0 89 * default range of enabled SSL/TLS protocols
michael@0 90 */
michael@0 91 static SSLVersionRange versions_defaults_stream = {
michael@0 92 SSL_LIBRARY_VERSION_3_0,
michael@0 93 SSL_LIBRARY_VERSION_TLS_1_0
michael@0 94 };
michael@0 95
michael@0 96 static SSLVersionRange versions_defaults_datagram = {
michael@0 97 SSL_LIBRARY_VERSION_TLS_1_1,
michael@0 98 SSL_LIBRARY_VERSION_TLS_1_1
michael@0 99 };
michael@0 100
michael@0 101 #define VERSIONS_DEFAULTS(variant) \
michael@0 102 (variant == ssl_variant_stream ? &versions_defaults_stream : \
michael@0 103 &versions_defaults_datagram)
michael@0 104
michael@0 105 sslSessionIDLookupFunc ssl_sid_lookup;
michael@0 106 sslSessionIDCacheFunc ssl_sid_cache;
michael@0 107 sslSessionIDUncacheFunc ssl_sid_uncache;
michael@0 108
michael@0 109 static PRBool ssl_inited = PR_FALSE;
michael@0 110 static PRDescIdentity ssl_layer_id;
michael@0 111
michael@0 112 PRBool locksEverDisabled; /* implicitly PR_FALSE */
michael@0 113 PRBool ssl_force_locks; /* implicitly PR_FALSE */
michael@0 114 int ssl_lock_readers = 1; /* default true. */
michael@0 115 char ssl_debug;
michael@0 116 char ssl_trace;
michael@0 117 FILE * ssl_trace_iob;
michael@0 118 FILE * ssl_keylog_iob;
michael@0 119 char lockStatus[] = "Locks are ENABLED. ";
michael@0 120 #define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
michael@0 121
michael@0 122 /* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
michael@0 123 static const PRUint16 srtpCiphers[] = {
michael@0 124 SRTP_AES128_CM_HMAC_SHA1_80,
michael@0 125 SRTP_AES128_CM_HMAC_SHA1_32,
michael@0 126 0
michael@0 127 };
michael@0 128
michael@0 129 /* forward declarations. */
michael@0 130 static sslSocket *ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant variant);
michael@0 131 static SECStatus ssl_MakeLocks(sslSocket *ss);
michael@0 132 static void ssl_SetDefaultsFromEnvironment(void);
michael@0 133 static PRStatus ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,
michael@0 134 PRDescIdentity id);
michael@0 135
michael@0 136 /************************************************************************/
michael@0 137
michael@0 138 /*
michael@0 139 ** Lookup a socket structure from a file descriptor.
michael@0 140 ** Only functions called through the PRIOMethods table should use this.
michael@0 141 ** Other app-callable functions should use ssl_FindSocket.
michael@0 142 */
michael@0 143 static sslSocket *
michael@0 144 ssl_GetPrivate(PRFileDesc *fd)
michael@0 145 {
michael@0 146 sslSocket *ss;
michael@0 147
michael@0 148 PORT_Assert(fd != NULL);
michael@0 149 PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);
michael@0 150 PORT_Assert(fd->identity == ssl_layer_id);
michael@0 151
michael@0 152 if (fd->methods->file_type != PR_DESC_LAYERED ||
michael@0 153 fd->identity != ssl_layer_id) {
michael@0 154 PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
michael@0 155 return NULL;
michael@0 156 }
michael@0 157
michael@0 158 ss = (sslSocket *)fd->secret;
michael@0 159 /* Set ss->fd lazily. We can't rely on the value of ss->fd set by
michael@0 160 * ssl_PushIOLayer because another PR_PushIOLayer call will switch the
michael@0 161 * contents of the PRFileDesc pointed by ss->fd and the new layer.
michael@0 162 * See bug 807250.
michael@0 163 */
michael@0 164 ss->fd = fd;
michael@0 165 return ss;
michael@0 166 }
michael@0 167
michael@0 168 /* This function tries to find the SSL layer in the stack.
michael@0 169 * It searches for the first SSL layer at or below the argument fd,
michael@0 170 * and failing that, it searches for the nearest SSL layer above the
michael@0 171 * argument fd. It returns the private sslSocket from the found layer.
michael@0 172 */
michael@0 173 sslSocket *
michael@0 174 ssl_FindSocket(PRFileDesc *fd)
michael@0 175 {
michael@0 176 PRFileDesc *layer;
michael@0 177 sslSocket *ss;
michael@0 178
michael@0 179 PORT_Assert(fd != NULL);
michael@0 180 PORT_Assert(ssl_layer_id != 0);
michael@0 181
michael@0 182 layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);
michael@0 183 if (layer == NULL) {
michael@0 184 PORT_SetError(PR_BAD_DESCRIPTOR_ERROR);
michael@0 185 return NULL;
michael@0 186 }
michael@0 187
michael@0 188 ss = (sslSocket *)layer->secret;
michael@0 189 /* Set ss->fd lazily. We can't rely on the value of ss->fd set by
michael@0 190 * ssl_PushIOLayer because another PR_PushIOLayer call will switch the
michael@0 191 * contents of the PRFileDesc pointed by ss->fd and the new layer.
michael@0 192 * See bug 807250.
michael@0 193 */
michael@0 194 ss->fd = layer;
michael@0 195 return ss;
michael@0 196 }
michael@0 197
michael@0 198 static sslSocket *
michael@0 199 ssl_DupSocket(sslSocket *os)
michael@0 200 {
michael@0 201 sslSocket *ss;
michael@0 202 SECStatus rv;
michael@0 203
michael@0 204 ss = ssl_NewSocket((PRBool)(!os->opt.noLocks), os->protocolVariant);
michael@0 205 if (ss) {
michael@0 206 ss->opt = os->opt;
michael@0 207 ss->opt.useSocks = PR_FALSE;
michael@0 208 ss->vrange = os->vrange;
michael@0 209
michael@0 210 ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID);
michael@0 211 ss->url = !os->url ? NULL : PORT_Strdup(os->url);
michael@0 212
michael@0 213 ss->ops = os->ops;
michael@0 214 ss->rTimeout = os->rTimeout;
michael@0 215 ss->wTimeout = os->wTimeout;
michael@0 216 ss->cTimeout = os->cTimeout;
michael@0 217 ss->dbHandle = os->dbHandle;
michael@0 218
michael@0 219 /* copy ssl2&3 policy & prefs, even if it's not selected (yet) */
michael@0 220 ss->allowedByPolicy = os->allowedByPolicy;
michael@0 221 ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;
michael@0 222 ss->chosenPreference = os->chosenPreference;
michael@0 223 PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);
michael@0 224 PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, os->ssl3.dtlsSRTPCiphers,
michael@0 225 sizeof(PRUint16) * os->ssl3.dtlsSRTPCipherCount);
michael@0 226 ss->ssl3.dtlsSRTPCipherCount = os->ssl3.dtlsSRTPCipherCount;
michael@0 227
michael@0 228 if (os->cipherSpecs) {
michael@0 229 ss->cipherSpecs = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);
michael@0 230 if (ss->cipherSpecs)
michael@0 231 PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs,
michael@0 232 os->sizeCipherSpecs);
michael@0 233 ss->sizeCipherSpecs = os->sizeCipherSpecs;
michael@0 234 ss->preferredCipher = os->preferredCipher;
michael@0 235 } else {
michael@0 236 ss->cipherSpecs = NULL; /* produced lazily */
michael@0 237 ss->sizeCipherSpecs = 0;
michael@0 238 ss->preferredCipher = NULL;
michael@0 239 }
michael@0 240 if (ss->opt.useSecurity) {
michael@0 241 /* This int should be SSLKEAType, but CC on Irix complains,
michael@0 242 * during the for loop.
michael@0 243 */
michael@0 244 int i;
michael@0 245 sslServerCerts * oc = os->serverCerts;
michael@0 246 sslServerCerts * sc = ss->serverCerts;
michael@0 247
michael@0 248 for (i=kt_null; i < kt_kea_size; i++, oc++, sc++) {
michael@0 249 if (oc->serverCert && oc->serverCertChain) {
michael@0 250 sc->serverCert = CERT_DupCertificate(oc->serverCert);
michael@0 251 sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
michael@0 252 if (!sc->serverCertChain)
michael@0 253 goto loser;
michael@0 254 } else {
michael@0 255 sc->serverCert = NULL;
michael@0 256 sc->serverCertChain = NULL;
michael@0 257 }
michael@0 258 sc->serverKeyPair = oc->serverKeyPair ?
michael@0 259 ssl3_GetKeyPairRef(oc->serverKeyPair) : NULL;
michael@0 260 if (oc->serverKeyPair && !sc->serverKeyPair)
michael@0 261 goto loser;
michael@0 262 sc->serverKeyBits = oc->serverKeyBits;
michael@0 263 ss->certStatusArray[i] = !os->certStatusArray[i] ? NULL :
michael@0 264 SECITEM_DupArray(NULL, os->certStatusArray[i]);
michael@0 265 }
michael@0 266 ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :
michael@0 267 ssl3_GetKeyPairRef(os->stepDownKeyPair);
michael@0 268 ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL :
michael@0 269 ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair);
michael@0 270 /*
michael@0 271 * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL.
michael@0 272 * XXX We should detect this, and not just march on with NULL pointers.
michael@0 273 */
michael@0 274 ss->authCertificate = os->authCertificate;
michael@0 275 ss->authCertificateArg = os->authCertificateArg;
michael@0 276 ss->getClientAuthData = os->getClientAuthData;
michael@0 277 ss->getClientAuthDataArg = os->getClientAuthDataArg;
michael@0 278 ss->sniSocketConfig = os->sniSocketConfig;
michael@0 279 ss->sniSocketConfigArg = os->sniSocketConfigArg;
michael@0 280 ss->handleBadCert = os->handleBadCert;
michael@0 281 ss->badCertArg = os->badCertArg;
michael@0 282 ss->handshakeCallback = os->handshakeCallback;
michael@0 283 ss->handshakeCallbackData = os->handshakeCallbackData;
michael@0 284 ss->canFalseStartCallback = os->canFalseStartCallback;
michael@0 285 ss->canFalseStartCallbackData = os->canFalseStartCallbackData;
michael@0 286 ss->pkcs11PinArg = os->pkcs11PinArg;
michael@0 287
michael@0 288 /* Create security data */
michael@0 289 rv = ssl_CopySecurityInfo(ss, os);
michael@0 290 if (rv != SECSuccess) {
michael@0 291 goto loser;
michael@0 292 }
michael@0 293 }
michael@0 294 }
michael@0 295 return ss;
michael@0 296
michael@0 297 loser:
michael@0 298 ssl_FreeSocket(ss);
michael@0 299 return NULL;
michael@0 300 }
michael@0 301
michael@0 302 static void
michael@0 303 ssl_DestroyLocks(sslSocket *ss)
michael@0 304 {
michael@0 305 /* Destroy locks. */
michael@0 306 if (ss->firstHandshakeLock) {
michael@0 307 PZ_DestroyMonitor(ss->firstHandshakeLock);
michael@0 308 ss->firstHandshakeLock = NULL;
michael@0 309 }
michael@0 310 if (ss->ssl3HandshakeLock) {
michael@0 311 PZ_DestroyMonitor(ss->ssl3HandshakeLock);
michael@0 312 ss->ssl3HandshakeLock = NULL;
michael@0 313 }
michael@0 314 if (ss->specLock) {
michael@0 315 NSSRWLock_Destroy(ss->specLock);
michael@0 316 ss->specLock = NULL;
michael@0 317 }
michael@0 318
michael@0 319 if (ss->recvLock) {
michael@0 320 PZ_DestroyLock(ss->recvLock);
michael@0 321 ss->recvLock = NULL;
michael@0 322 }
michael@0 323 if (ss->sendLock) {
michael@0 324 PZ_DestroyLock(ss->sendLock);
michael@0 325 ss->sendLock = NULL;
michael@0 326 }
michael@0 327 if (ss->xmitBufLock) {
michael@0 328 PZ_DestroyMonitor(ss->xmitBufLock);
michael@0 329 ss->xmitBufLock = NULL;
michael@0 330 }
michael@0 331 if (ss->recvBufLock) {
michael@0 332 PZ_DestroyMonitor(ss->recvBufLock);
michael@0 333 ss->recvBufLock = NULL;
michael@0 334 }
michael@0 335 }
michael@0 336
michael@0 337 /* Caller holds any relevant locks */
michael@0 338 static void
michael@0 339 ssl_DestroySocketContents(sslSocket *ss)
michael@0 340 {
michael@0 341 /* "i" should be of type SSLKEAType, but CC on IRIX complains during
michael@0 342 * the for loop.
michael@0 343 */
michael@0 344 int i;
michael@0 345
michael@0 346 /* Free up socket */
michael@0 347 ssl_DestroySecurityInfo(&ss->sec);
michael@0 348
michael@0 349 ssl3_DestroySSL3Info(ss);
michael@0 350
michael@0 351 PORT_Free(ss->saveBuf.buf);
michael@0 352 PORT_Free(ss->pendingBuf.buf);
michael@0 353 ssl_DestroyGather(&ss->gs);
michael@0 354
michael@0 355 if (ss->peerID != NULL)
michael@0 356 PORT_Free(ss->peerID);
michael@0 357 if (ss->url != NULL)
michael@0 358 PORT_Free((void *)ss->url); /* CONST */
michael@0 359 if (ss->cipherSpecs) {
michael@0 360 PORT_Free(ss->cipherSpecs);
michael@0 361 ss->cipherSpecs = NULL;
michael@0 362 ss->sizeCipherSpecs = 0;
michael@0 363 }
michael@0 364
michael@0 365 /* Clean up server configuration */
michael@0 366 for (i=kt_null; i < kt_kea_size; i++) {
michael@0 367 sslServerCerts * sc = ss->serverCerts + i;
michael@0 368 if (sc->serverCert != NULL)
michael@0 369 CERT_DestroyCertificate(sc->serverCert);
michael@0 370 if (sc->serverCertChain != NULL)
michael@0 371 CERT_DestroyCertificateList(sc->serverCertChain);
michael@0 372 if (sc->serverKeyPair != NULL)
michael@0 373 ssl3_FreeKeyPair(sc->serverKeyPair);
michael@0 374 if (ss->certStatusArray[i] != NULL) {
michael@0 375 SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
michael@0 376 ss->certStatusArray[i] = NULL;
michael@0 377 }
michael@0 378 }
michael@0 379 if (ss->stepDownKeyPair) {
michael@0 380 ssl3_FreeKeyPair(ss->stepDownKeyPair);
michael@0 381 ss->stepDownKeyPair = NULL;
michael@0 382 }
michael@0 383 if (ss->ephemeralECDHKeyPair) {
michael@0 384 ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
michael@0 385 ss->ephemeralECDHKeyPair = NULL;
michael@0 386 }
michael@0 387 SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
michael@0 388 PORT_Assert(!ss->xtnData.sniNameArr);
michael@0 389 if (ss->xtnData.sniNameArr) {
michael@0 390 PORT_Free(ss->xtnData.sniNameArr);
michael@0 391 ss->xtnData.sniNameArr = NULL;
michael@0 392 }
michael@0 393 }
michael@0 394
michael@0 395 /*
michael@0 396 * free an sslSocket struct, and all the stuff that hangs off of it
michael@0 397 */
michael@0 398 void
michael@0 399 ssl_FreeSocket(sslSocket *ss)
michael@0 400 {
michael@0 401 /* Get every lock you can imagine!
michael@0 402 ** Caller already holds these:
michael@0 403 ** SSL_LOCK_READER(ss);
michael@0 404 ** SSL_LOCK_WRITER(ss);
michael@0 405 */
michael@0 406 ssl_Get1stHandshakeLock(ss);
michael@0 407 ssl_GetRecvBufLock(ss);
michael@0 408 ssl_GetSSL3HandshakeLock(ss);
michael@0 409 ssl_GetXmitBufLock(ss);
michael@0 410 ssl_GetSpecWriteLock(ss);
michael@0 411
michael@0 412 ssl_DestroySocketContents(ss);
michael@0 413
michael@0 414 /* Release all the locks acquired above. */
michael@0 415 SSL_UNLOCK_READER(ss);
michael@0 416 SSL_UNLOCK_WRITER(ss);
michael@0 417 ssl_Release1stHandshakeLock(ss);
michael@0 418 ssl_ReleaseRecvBufLock(ss);
michael@0 419 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 420 ssl_ReleaseXmitBufLock(ss);
michael@0 421 ssl_ReleaseSpecWriteLock(ss);
michael@0 422
michael@0 423 ssl_DestroyLocks(ss);
michael@0 424
michael@0 425 #ifdef DEBUG
michael@0 426 PORT_Memset(ss, 0x1f, sizeof *ss);
michael@0 427 #endif
michael@0 428 PORT_Free(ss);
michael@0 429 return;
michael@0 430 }
michael@0 431
michael@0 432 /************************************************************************/
michael@0 433 SECStatus
michael@0 434 ssl_EnableNagleDelay(sslSocket *ss, PRBool enabled)
michael@0 435 {
michael@0 436 PRFileDesc * osfd = ss->fd->lower;
michael@0 437 SECStatus rv = SECFailure;
michael@0 438 PRSocketOptionData opt;
michael@0 439
michael@0 440 opt.option = PR_SockOpt_NoDelay;
michael@0 441 opt.value.no_delay = (PRBool)!enabled;
michael@0 442
michael@0 443 if (osfd->methods->setsocketoption) {
michael@0 444 rv = (SECStatus) osfd->methods->setsocketoption(osfd, &opt);
michael@0 445 } else {
michael@0 446 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 447 }
michael@0 448
michael@0 449 return rv;
michael@0 450 }
michael@0 451
michael@0 452 static void
michael@0 453 ssl_ChooseOps(sslSocket *ss)
michael@0 454 {
michael@0 455 ss->ops = ss->opt.useSecurity ? &ssl_secure_ops : &ssl_default_ops;
michael@0 456 }
michael@0 457
michael@0 458 /* Called from SSL_Enable (immediately below) */
michael@0 459 static SECStatus
michael@0 460 PrepareSocket(sslSocket *ss)
michael@0 461 {
michael@0 462 SECStatus rv = SECSuccess;
michael@0 463
michael@0 464 ssl_ChooseOps(ss);
michael@0 465 return rv;
michael@0 466 }
michael@0 467
michael@0 468 SECStatus
michael@0 469 SSL_Enable(PRFileDesc *fd, int which, PRBool on)
michael@0 470 {
michael@0 471 return SSL_OptionSet(fd, which, on);
michael@0 472 }
michael@0 473
michael@0 474 #ifndef NO_PKCS11_BYPASS
michael@0 475 static const PRCallOnceType pristineCallOnce;
michael@0 476 static PRCallOnceType setupBypassOnce;
michael@0 477
michael@0 478 static SECStatus SSL_BypassShutdown(void* appData, void* nssData)
michael@0 479 {
michael@0 480 /* unload freeBL shared library from memory */
michael@0 481 BL_Unload();
michael@0 482 setupBypassOnce = pristineCallOnce;
michael@0 483 return SECSuccess;
michael@0 484 }
michael@0 485
michael@0 486 static PRStatus SSL_BypassRegisterShutdown(void)
michael@0 487 {
michael@0 488 SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL);
michael@0 489 PORT_Assert(SECSuccess == rv);
michael@0 490 return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE;
michael@0 491 }
michael@0 492 #endif
michael@0 493
michael@0 494 static PRStatus SSL_BypassSetup(void)
michael@0 495 {
michael@0 496 #ifdef NO_PKCS11_BYPASS
michael@0 497 /* Guarantee binary compatibility */
michael@0 498 return PR_SUCCESS;
michael@0 499 #else
michael@0 500 return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown);
michael@0 501 #endif
michael@0 502 }
michael@0 503
michael@0 504 /* Implements the semantics for SSL_OptionSet(SSL_ENABLE_TLS, on) described in
michael@0 505 * ssl.h in the section "SSL version range setting API".
michael@0 506 */
michael@0 507 static void
michael@0 508 ssl_EnableTLS(SSLVersionRange *vrange, PRBool on)
michael@0 509 {
michael@0 510 if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
michael@0 511 if (on) {
michael@0 512 vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
michael@0 513 vrange->max = SSL_LIBRARY_VERSION_TLS_1_0;
michael@0 514 } /* else don't change anything */
michael@0 515 return;
michael@0 516 }
michael@0 517
michael@0 518 if (on) {
michael@0 519 /* Expand the range of enabled version to include TLS 1.0 */
michael@0 520 vrange->min = PR_MIN(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
michael@0 521 vrange->max = PR_MAX(vrange->max, SSL_LIBRARY_VERSION_TLS_1_0);
michael@0 522 } else {
michael@0 523 /* Disable all TLS versions, leaving only SSL 3.0 if it was enabled */
michael@0 524 if (vrange->min == SSL_LIBRARY_VERSION_3_0) {
michael@0 525 vrange->max = SSL_LIBRARY_VERSION_3_0;
michael@0 526 } else {
michael@0 527 /* Only TLS was enabled, so now no versions are. */
michael@0 528 vrange->min = SSL_LIBRARY_VERSION_NONE;
michael@0 529 vrange->max = SSL_LIBRARY_VERSION_NONE;
michael@0 530 }
michael@0 531 }
michael@0 532 }
michael@0 533
michael@0 534 /* Implements the semantics for SSL_OptionSet(SSL_ENABLE_SSL3, on) described in
michael@0 535 * ssl.h in the section "SSL version range setting API".
michael@0 536 */
michael@0 537 static void
michael@0 538 ssl_EnableSSL3(SSLVersionRange *vrange, PRBool on)
michael@0 539 {
michael@0 540 if (SSL3_ALL_VERSIONS_DISABLED(vrange)) {
michael@0 541 if (on) {
michael@0 542 vrange->min = SSL_LIBRARY_VERSION_3_0;
michael@0 543 vrange->max = SSL_LIBRARY_VERSION_3_0;
michael@0 544 } /* else don't change anything */
michael@0 545 return;
michael@0 546 }
michael@0 547
michael@0 548 if (on) {
michael@0 549 /* Expand the range of enabled versions to include SSL 3.0. We know
michael@0 550 * SSL 3.0 or some version of TLS is already enabled at this point, so
michael@0 551 * we don't need to change vrange->max.
michael@0 552 */
michael@0 553 vrange->min = SSL_LIBRARY_VERSION_3_0;
michael@0 554 } else {
michael@0 555 /* Disable SSL 3.0, leaving TLS unaffected. */
michael@0 556 if (vrange->max > SSL_LIBRARY_VERSION_3_0) {
michael@0 557 vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
michael@0 558 } else {
michael@0 559 /* Only SSL 3.0 was enabled, so now no versions are. */
michael@0 560 vrange->min = SSL_LIBRARY_VERSION_NONE;
michael@0 561 vrange->max = SSL_LIBRARY_VERSION_NONE;
michael@0 562 }
michael@0 563 }
michael@0 564 }
michael@0 565
michael@0 566 SECStatus
michael@0 567 SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on)
michael@0 568 {
michael@0 569 sslSocket *ss = ssl_FindSocket(fd);
michael@0 570 SECStatus rv = SECSuccess;
michael@0 571 PRBool holdingLocks;
michael@0 572
michael@0 573 if (!ss) {
michael@0 574 SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
michael@0 575 return SECFailure;
michael@0 576 }
michael@0 577
michael@0 578 holdingLocks = (!ss->opt.noLocks);
michael@0 579 ssl_Get1stHandshakeLock(ss);
michael@0 580 ssl_GetSSL3HandshakeLock(ss);
michael@0 581
michael@0 582 switch (which) {
michael@0 583 case SSL_SOCKS:
michael@0 584 ss->opt.useSocks = PR_FALSE;
michael@0 585 rv = PrepareSocket(ss);
michael@0 586 if (on) {
michael@0 587 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 588 rv = SECFailure;
michael@0 589 }
michael@0 590 break;
michael@0 591
michael@0 592 case SSL_SECURITY:
michael@0 593 ss->opt.useSecurity = on;
michael@0 594 rv = PrepareSocket(ss);
michael@0 595 break;
michael@0 596
michael@0 597 case SSL_REQUEST_CERTIFICATE:
michael@0 598 ss->opt.requestCertificate = on;
michael@0 599 break;
michael@0 600
michael@0 601 case SSL_REQUIRE_CERTIFICATE:
michael@0 602 ss->opt.requireCertificate = on;
michael@0 603 break;
michael@0 604
michael@0 605 case SSL_HANDSHAKE_AS_CLIENT:
michael@0 606 if ( ss->opt.handshakeAsServer && on ) {
michael@0 607 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 608 rv = SECFailure;
michael@0 609 break;
michael@0 610 }
michael@0 611 ss->opt.handshakeAsClient = on;
michael@0 612 break;
michael@0 613
michael@0 614 case SSL_HANDSHAKE_AS_SERVER:
michael@0 615 if ( ss->opt.handshakeAsClient && on ) {
michael@0 616 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 617 rv = SECFailure;
michael@0 618 break;
michael@0 619 }
michael@0 620 ss->opt.handshakeAsServer = on;
michael@0 621 break;
michael@0 622
michael@0 623 case SSL_ENABLE_TLS:
michael@0 624 if (IS_DTLS(ss)) {
michael@0 625 if (on) {
michael@0 626 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 627 rv = SECFailure; /* not allowed */
michael@0 628 }
michael@0 629 break;
michael@0 630 }
michael@0 631 ssl_EnableTLS(&ss->vrange, on);
michael@0 632 ss->preferredCipher = NULL;
michael@0 633 if (ss->cipherSpecs) {
michael@0 634 PORT_Free(ss->cipherSpecs);
michael@0 635 ss->cipherSpecs = NULL;
michael@0 636 ss->sizeCipherSpecs = 0;
michael@0 637 }
michael@0 638 break;
michael@0 639
michael@0 640 case SSL_ENABLE_SSL3:
michael@0 641 if (IS_DTLS(ss)) {
michael@0 642 if (on) {
michael@0 643 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 644 rv = SECFailure; /* not allowed */
michael@0 645 }
michael@0 646 break;
michael@0 647 }
michael@0 648 ssl_EnableSSL3(&ss->vrange, on);
michael@0 649 ss->preferredCipher = NULL;
michael@0 650 if (ss->cipherSpecs) {
michael@0 651 PORT_Free(ss->cipherSpecs);
michael@0 652 ss->cipherSpecs = NULL;
michael@0 653 ss->sizeCipherSpecs = 0;
michael@0 654 }
michael@0 655 break;
michael@0 656
michael@0 657 case SSL_ENABLE_SSL2:
michael@0 658 if (IS_DTLS(ss)) {
michael@0 659 if (on) {
michael@0 660 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 661 rv = SECFailure; /* not allowed */
michael@0 662 }
michael@0 663 break;
michael@0 664 }
michael@0 665 ss->opt.enableSSL2 = on;
michael@0 666 if (on) {
michael@0 667 ss->opt.v2CompatibleHello = on;
michael@0 668 }
michael@0 669 ss->preferredCipher = NULL;
michael@0 670 if (ss->cipherSpecs) {
michael@0 671 PORT_Free(ss->cipherSpecs);
michael@0 672 ss->cipherSpecs = NULL;
michael@0 673 ss->sizeCipherSpecs = 0;
michael@0 674 }
michael@0 675 break;
michael@0 676
michael@0 677 case SSL_NO_CACHE:
michael@0 678 ss->opt.noCache = on;
michael@0 679 break;
michael@0 680
michael@0 681 case SSL_ENABLE_FDX:
michael@0 682 if (on && ss->opt.noLocks) {
michael@0 683 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 684 rv = SECFailure;
michael@0 685 }
michael@0 686 ss->opt.fdx = on;
michael@0 687 break;
michael@0 688
michael@0 689 case SSL_V2_COMPATIBLE_HELLO:
michael@0 690 if (IS_DTLS(ss)) {
michael@0 691 if (on) {
michael@0 692 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 693 rv = SECFailure; /* not allowed */
michael@0 694 }
michael@0 695 break;
michael@0 696 }
michael@0 697 ss->opt.v2CompatibleHello = on;
michael@0 698 if (!on) {
michael@0 699 ss->opt.enableSSL2 = on;
michael@0 700 }
michael@0 701 break;
michael@0 702
michael@0 703 case SSL_ROLLBACK_DETECTION:
michael@0 704 ss->opt.detectRollBack = on;
michael@0 705 break;
michael@0 706
michael@0 707 case SSL_NO_STEP_DOWN:
michael@0 708 ss->opt.noStepDown = on;
michael@0 709 if (on)
michael@0 710 SSL_DisableExportCipherSuites(fd);
michael@0 711 break;
michael@0 712
michael@0 713 case SSL_BYPASS_PKCS11:
michael@0 714 if (ss->handshakeBegun) {
michael@0 715 PORT_SetError(PR_INVALID_STATE_ERROR);
michael@0 716 rv = SECFailure;
michael@0 717 } else {
michael@0 718 if (PR_FALSE != on) {
michael@0 719 if (PR_SUCCESS == SSL_BypassSetup() ) {
michael@0 720 #ifdef NO_PKCS11_BYPASS
michael@0 721 ss->opt.bypassPKCS11 = PR_FALSE;
michael@0 722 #else
michael@0 723 ss->opt.bypassPKCS11 = on;
michael@0 724 #endif
michael@0 725 } else {
michael@0 726 rv = SECFailure;
michael@0 727 }
michael@0 728 } else {
michael@0 729 ss->opt.bypassPKCS11 = PR_FALSE;
michael@0 730 }
michael@0 731 }
michael@0 732 break;
michael@0 733
michael@0 734 case SSL_NO_LOCKS:
michael@0 735 if (on && ss->opt.fdx) {
michael@0 736 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 737 rv = SECFailure;
michael@0 738 }
michael@0 739 if (on && ssl_force_locks)
michael@0 740 on = PR_FALSE; /* silent override */
michael@0 741 ss->opt.noLocks = on;
michael@0 742 if (on) {
michael@0 743 locksEverDisabled = PR_TRUE;
michael@0 744 strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
michael@0 745 } else if (!holdingLocks) {
michael@0 746 rv = ssl_MakeLocks(ss);
michael@0 747 if (rv != SECSuccess) {
michael@0 748 ss->opt.noLocks = PR_TRUE;
michael@0 749 }
michael@0 750 }
michael@0 751 break;
michael@0 752
michael@0 753 case SSL_ENABLE_SESSION_TICKETS:
michael@0 754 ss->opt.enableSessionTickets = on;
michael@0 755 break;
michael@0 756
michael@0 757 case SSL_ENABLE_DEFLATE:
michael@0 758 ss->opt.enableDeflate = on;
michael@0 759 break;
michael@0 760
michael@0 761 case SSL_ENABLE_RENEGOTIATION:
michael@0 762 ss->opt.enableRenegotiation = on;
michael@0 763 break;
michael@0 764
michael@0 765 case SSL_REQUIRE_SAFE_NEGOTIATION:
michael@0 766 ss->opt.requireSafeNegotiation = on;
michael@0 767 break;
michael@0 768
michael@0 769 case SSL_ENABLE_FALSE_START:
michael@0 770 ss->opt.enableFalseStart = on;
michael@0 771 break;
michael@0 772
michael@0 773 case SSL_CBC_RANDOM_IV:
michael@0 774 ss->opt.cbcRandomIV = on;
michael@0 775 break;
michael@0 776
michael@0 777 case SSL_ENABLE_OCSP_STAPLING:
michael@0 778 ss->opt.enableOCSPStapling = on;
michael@0 779 break;
michael@0 780
michael@0 781 case SSL_ENABLE_NPN:
michael@0 782 ss->opt.enableNPN = on;
michael@0 783 break;
michael@0 784
michael@0 785 case SSL_ENABLE_ALPN:
michael@0 786 ss->opt.enableALPN = on;
michael@0 787 break;
michael@0 788
michael@0 789 case SSL_ENABLE_FALLBACK_SCSV:
michael@0 790 ss->opt.enableFallbackSCSV = on;
michael@0 791 break;
michael@0 792
michael@0 793 default:
michael@0 794 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 795 rv = SECFailure;
michael@0 796 }
michael@0 797
michael@0 798 /* We can't use the macros for releasing the locks here,
michael@0 799 * because ss->opt.noLocks might have changed just above.
michael@0 800 * We must release these locks (monitors) here, if we aquired them above,
michael@0 801 * regardless of the current value of ss->opt.noLocks.
michael@0 802 */
michael@0 803 if (holdingLocks) {
michael@0 804 PZ_ExitMonitor((ss)->ssl3HandshakeLock);
michael@0 805 PZ_ExitMonitor((ss)->firstHandshakeLock);
michael@0 806 }
michael@0 807
michael@0 808 return rv;
michael@0 809 }
michael@0 810
michael@0 811 SECStatus
michael@0 812 SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn)
michael@0 813 {
michael@0 814 sslSocket *ss = ssl_FindSocket(fd);
michael@0 815 SECStatus rv = SECSuccess;
michael@0 816 PRBool on = PR_FALSE;
michael@0 817
michael@0 818 if (!pOn) {
michael@0 819 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 820 return SECFailure;
michael@0 821 }
michael@0 822 if (!ss) {
michael@0 823 SSL_DBG(("%d: SSL[%d]: bad socket in Enable", SSL_GETPID(), fd));
michael@0 824 *pOn = PR_FALSE;
michael@0 825 return SECFailure;
michael@0 826 }
michael@0 827
michael@0 828 ssl_Get1stHandshakeLock(ss);
michael@0 829 ssl_GetSSL3HandshakeLock(ss);
michael@0 830
michael@0 831 switch (which) {
michael@0 832 case SSL_SOCKS: on = PR_FALSE; break;
michael@0 833 case SSL_SECURITY: on = ss->opt.useSecurity; break;
michael@0 834 case SSL_REQUEST_CERTIFICATE: on = ss->opt.requestCertificate; break;
michael@0 835 case SSL_REQUIRE_CERTIFICATE: on = ss->opt.requireCertificate; break;
michael@0 836 case SSL_HANDSHAKE_AS_CLIENT: on = ss->opt.handshakeAsClient; break;
michael@0 837 case SSL_HANDSHAKE_AS_SERVER: on = ss->opt.handshakeAsServer; break;
michael@0 838 case SSL_ENABLE_TLS:
michael@0 839 on = ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_0;
michael@0 840 break;
michael@0 841 case SSL_ENABLE_SSL3:
michael@0 842 on = ss->vrange.min == SSL_LIBRARY_VERSION_3_0;
michael@0 843 break;
michael@0 844 case SSL_ENABLE_SSL2: on = ss->opt.enableSSL2; break;
michael@0 845 case SSL_NO_CACHE: on = ss->opt.noCache; break;
michael@0 846 case SSL_ENABLE_FDX: on = ss->opt.fdx; break;
michael@0 847 case SSL_V2_COMPATIBLE_HELLO: on = ss->opt.v2CompatibleHello; break;
michael@0 848 case SSL_ROLLBACK_DETECTION: on = ss->opt.detectRollBack; break;
michael@0 849 case SSL_NO_STEP_DOWN: on = ss->opt.noStepDown; break;
michael@0 850 case SSL_BYPASS_PKCS11: on = ss->opt.bypassPKCS11; break;
michael@0 851 case SSL_NO_LOCKS: on = ss->opt.noLocks; break;
michael@0 852 case SSL_ENABLE_SESSION_TICKETS:
michael@0 853 on = ss->opt.enableSessionTickets;
michael@0 854 break;
michael@0 855 case SSL_ENABLE_DEFLATE: on = ss->opt.enableDeflate; break;
michael@0 856 case SSL_ENABLE_RENEGOTIATION:
michael@0 857 on = ss->opt.enableRenegotiation; break;
michael@0 858 case SSL_REQUIRE_SAFE_NEGOTIATION:
michael@0 859 on = ss->opt.requireSafeNegotiation; break;
michael@0 860 case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break;
michael@0 861 case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break;
michael@0 862 case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break;
michael@0 863 case SSL_ENABLE_NPN: on = ss->opt.enableNPN; break;
michael@0 864 case SSL_ENABLE_ALPN: on = ss->opt.enableALPN; break;
michael@0 865 case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
michael@0 866
michael@0 867 default:
michael@0 868 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 869 rv = SECFailure;
michael@0 870 }
michael@0 871
michael@0 872 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 873 ssl_Release1stHandshakeLock(ss);
michael@0 874
michael@0 875 *pOn = on;
michael@0 876 return rv;
michael@0 877 }
michael@0 878
michael@0 879 SECStatus
michael@0 880 SSL_OptionGetDefault(PRInt32 which, PRBool *pOn)
michael@0 881 {
michael@0 882 SECStatus rv = SECSuccess;
michael@0 883 PRBool on = PR_FALSE;
michael@0 884
michael@0 885 if (!pOn) {
michael@0 886 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 887 return SECFailure;
michael@0 888 }
michael@0 889
michael@0 890 ssl_SetDefaultsFromEnvironment();
michael@0 891
michael@0 892 switch (which) {
michael@0 893 case SSL_SOCKS: on = PR_FALSE; break;
michael@0 894 case SSL_SECURITY: on = ssl_defaults.useSecurity; break;
michael@0 895 case SSL_REQUEST_CERTIFICATE: on = ssl_defaults.requestCertificate; break;
michael@0 896 case SSL_REQUIRE_CERTIFICATE: on = ssl_defaults.requireCertificate; break;
michael@0 897 case SSL_HANDSHAKE_AS_CLIENT: on = ssl_defaults.handshakeAsClient; break;
michael@0 898 case SSL_HANDSHAKE_AS_SERVER: on = ssl_defaults.handshakeAsServer; break;
michael@0 899 case SSL_ENABLE_TLS:
michael@0 900 on = versions_defaults_stream.max >= SSL_LIBRARY_VERSION_TLS_1_0;
michael@0 901 break;
michael@0 902 case SSL_ENABLE_SSL3:
michael@0 903 on = versions_defaults_stream.min == SSL_LIBRARY_VERSION_3_0;
michael@0 904 break;
michael@0 905 case SSL_ENABLE_SSL2: on = ssl_defaults.enableSSL2; break;
michael@0 906 case SSL_NO_CACHE: on = ssl_defaults.noCache; break;
michael@0 907 case SSL_ENABLE_FDX: on = ssl_defaults.fdx; break;
michael@0 908 case SSL_V2_COMPATIBLE_HELLO: on = ssl_defaults.v2CompatibleHello; break;
michael@0 909 case SSL_ROLLBACK_DETECTION: on = ssl_defaults.detectRollBack; break;
michael@0 910 case SSL_NO_STEP_DOWN: on = ssl_defaults.noStepDown; break;
michael@0 911 case SSL_BYPASS_PKCS11: on = ssl_defaults.bypassPKCS11; break;
michael@0 912 case SSL_NO_LOCKS: on = ssl_defaults.noLocks; break;
michael@0 913 case SSL_ENABLE_SESSION_TICKETS:
michael@0 914 on = ssl_defaults.enableSessionTickets;
michael@0 915 break;
michael@0 916 case SSL_ENABLE_DEFLATE: on = ssl_defaults.enableDeflate; break;
michael@0 917 case SSL_ENABLE_RENEGOTIATION:
michael@0 918 on = ssl_defaults.enableRenegotiation; break;
michael@0 919 case SSL_REQUIRE_SAFE_NEGOTIATION:
michael@0 920 on = ssl_defaults.requireSafeNegotiation;
michael@0 921 break;
michael@0 922 case SSL_ENABLE_FALSE_START: on = ssl_defaults.enableFalseStart; break;
michael@0 923 case SSL_CBC_RANDOM_IV: on = ssl_defaults.cbcRandomIV; break;
michael@0 924 case SSL_ENABLE_OCSP_STAPLING:
michael@0 925 on = ssl_defaults.enableOCSPStapling;
michael@0 926 break;
michael@0 927 case SSL_ENABLE_NPN: on = ssl_defaults.enableNPN; break;
michael@0 928 case SSL_ENABLE_ALPN: on = ssl_defaults.enableALPN; break;
michael@0 929 case SSL_ENABLE_FALLBACK_SCSV:
michael@0 930 on = ssl_defaults.enableFallbackSCSV;
michael@0 931 break;
michael@0 932
michael@0 933 default:
michael@0 934 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 935 rv = SECFailure;
michael@0 936 }
michael@0 937
michael@0 938 *pOn = on;
michael@0 939 return rv;
michael@0 940 }
michael@0 941
michael@0 942 /* XXX Use Global Lock to protect this stuff. */
michael@0 943 SECStatus
michael@0 944 SSL_EnableDefault(int which, PRBool on)
michael@0 945 {
michael@0 946 return SSL_OptionSetDefault(which, on);
michael@0 947 }
michael@0 948
michael@0 949 SECStatus
michael@0 950 SSL_OptionSetDefault(PRInt32 which, PRBool on)
michael@0 951 {
michael@0 952 SECStatus status = ssl_Init();
michael@0 953
michael@0 954 if (status != SECSuccess) {
michael@0 955 return status;
michael@0 956 }
michael@0 957
michael@0 958 ssl_SetDefaultsFromEnvironment();
michael@0 959
michael@0 960 switch (which) {
michael@0 961 case SSL_SOCKS:
michael@0 962 ssl_defaults.useSocks = PR_FALSE;
michael@0 963 if (on) {
michael@0 964 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 965 return SECFailure;
michael@0 966 }
michael@0 967 break;
michael@0 968
michael@0 969 case SSL_SECURITY:
michael@0 970 ssl_defaults.useSecurity = on;
michael@0 971 break;
michael@0 972
michael@0 973 case SSL_REQUEST_CERTIFICATE:
michael@0 974 ssl_defaults.requestCertificate = on;
michael@0 975 break;
michael@0 976
michael@0 977 case SSL_REQUIRE_CERTIFICATE:
michael@0 978 ssl_defaults.requireCertificate = on;
michael@0 979 break;
michael@0 980
michael@0 981 case SSL_HANDSHAKE_AS_CLIENT:
michael@0 982 if ( ssl_defaults.handshakeAsServer && on ) {
michael@0 983 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 984 return SECFailure;
michael@0 985 }
michael@0 986 ssl_defaults.handshakeAsClient = on;
michael@0 987 break;
michael@0 988
michael@0 989 case SSL_HANDSHAKE_AS_SERVER:
michael@0 990 if ( ssl_defaults.handshakeAsClient && on ) {
michael@0 991 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 992 return SECFailure;
michael@0 993 }
michael@0 994 ssl_defaults.handshakeAsServer = on;
michael@0 995 break;
michael@0 996
michael@0 997 case SSL_ENABLE_TLS:
michael@0 998 ssl_EnableTLS(&versions_defaults_stream, on);
michael@0 999 break;
michael@0 1000
michael@0 1001 case SSL_ENABLE_SSL3:
michael@0 1002 ssl_EnableSSL3(&versions_defaults_stream, on);
michael@0 1003 break;
michael@0 1004
michael@0 1005 case SSL_ENABLE_SSL2:
michael@0 1006 ssl_defaults.enableSSL2 = on;
michael@0 1007 if (on) {
michael@0 1008 ssl_defaults.v2CompatibleHello = on;
michael@0 1009 }
michael@0 1010 break;
michael@0 1011
michael@0 1012 case SSL_NO_CACHE:
michael@0 1013 ssl_defaults.noCache = on;
michael@0 1014 break;
michael@0 1015
michael@0 1016 case SSL_ENABLE_FDX:
michael@0 1017 if (on && ssl_defaults.noLocks) {
michael@0 1018 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1019 return SECFailure;
michael@0 1020 }
michael@0 1021 ssl_defaults.fdx = on;
michael@0 1022 break;
michael@0 1023
michael@0 1024 case SSL_V2_COMPATIBLE_HELLO:
michael@0 1025 ssl_defaults.v2CompatibleHello = on;
michael@0 1026 if (!on) {
michael@0 1027 ssl_defaults.enableSSL2 = on;
michael@0 1028 }
michael@0 1029 break;
michael@0 1030
michael@0 1031 case SSL_ROLLBACK_DETECTION:
michael@0 1032 ssl_defaults.detectRollBack = on;
michael@0 1033 break;
michael@0 1034
michael@0 1035 case SSL_NO_STEP_DOWN:
michael@0 1036 ssl_defaults.noStepDown = on;
michael@0 1037 if (on)
michael@0 1038 SSL_DisableDefaultExportCipherSuites();
michael@0 1039 break;
michael@0 1040
michael@0 1041 case SSL_BYPASS_PKCS11:
michael@0 1042 if (PR_FALSE != on) {
michael@0 1043 if (PR_SUCCESS == SSL_BypassSetup()) {
michael@0 1044 #ifdef NO_PKCS11_BYPASS
michael@0 1045 ssl_defaults.bypassPKCS11 = PR_FALSE;
michael@0 1046 #else
michael@0 1047 ssl_defaults.bypassPKCS11 = on;
michael@0 1048 #endif
michael@0 1049 } else {
michael@0 1050 return SECFailure;
michael@0 1051 }
michael@0 1052 } else {
michael@0 1053 ssl_defaults.bypassPKCS11 = PR_FALSE;
michael@0 1054 }
michael@0 1055 break;
michael@0 1056
michael@0 1057 case SSL_NO_LOCKS:
michael@0 1058 if (on && ssl_defaults.fdx) {
michael@0 1059 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1060 return SECFailure;
michael@0 1061 }
michael@0 1062 if (on && ssl_force_locks)
michael@0 1063 on = PR_FALSE; /* silent override */
michael@0 1064 ssl_defaults.noLocks = on;
michael@0 1065 if (on) {
michael@0 1066 locksEverDisabled = PR_TRUE;
michael@0 1067 strcpy(lockStatus + LOCKSTATUS_OFFSET, "DISABLED.");
michael@0 1068 }
michael@0 1069 break;
michael@0 1070
michael@0 1071 case SSL_ENABLE_SESSION_TICKETS:
michael@0 1072 ssl_defaults.enableSessionTickets = on;
michael@0 1073 break;
michael@0 1074
michael@0 1075 case SSL_ENABLE_DEFLATE:
michael@0 1076 ssl_defaults.enableDeflate = on;
michael@0 1077 break;
michael@0 1078
michael@0 1079 case SSL_ENABLE_RENEGOTIATION:
michael@0 1080 ssl_defaults.enableRenegotiation = on;
michael@0 1081 break;
michael@0 1082
michael@0 1083 case SSL_REQUIRE_SAFE_NEGOTIATION:
michael@0 1084 ssl_defaults.requireSafeNegotiation = on;
michael@0 1085 break;
michael@0 1086
michael@0 1087 case SSL_ENABLE_FALSE_START:
michael@0 1088 ssl_defaults.enableFalseStart = on;
michael@0 1089 break;
michael@0 1090
michael@0 1091 case SSL_CBC_RANDOM_IV:
michael@0 1092 ssl_defaults.cbcRandomIV = on;
michael@0 1093 break;
michael@0 1094
michael@0 1095 case SSL_ENABLE_OCSP_STAPLING:
michael@0 1096 ssl_defaults.enableOCSPStapling = on;
michael@0 1097 break;
michael@0 1098
michael@0 1099 case SSL_ENABLE_NPN:
michael@0 1100 ssl_defaults.enableNPN = on;
michael@0 1101 break;
michael@0 1102
michael@0 1103 case SSL_ENABLE_ALPN:
michael@0 1104 ssl_defaults.enableALPN = on;
michael@0 1105 break;
michael@0 1106
michael@0 1107 case SSL_ENABLE_FALLBACK_SCSV:
michael@0 1108 ssl_defaults.enableFallbackSCSV = on;
michael@0 1109 break;
michael@0 1110
michael@0 1111 default:
michael@0 1112 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1113 return SECFailure;
michael@0 1114 }
michael@0 1115 return SECSuccess;
michael@0 1116 }
michael@0 1117
michael@0 1118 /* function tells us if the cipher suite is one that we no longer support. */
michael@0 1119 static PRBool
michael@0 1120 ssl_IsRemovedCipherSuite(PRInt32 suite)
michael@0 1121 {
michael@0 1122 switch (suite) {
michael@0 1123 case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
michael@0 1124 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
michael@0 1125 case SSL_FORTEZZA_DMS_WITH_RC4_128_SHA:
michael@0 1126 return PR_TRUE;
michael@0 1127 default:
michael@0 1128 return PR_FALSE;
michael@0 1129 }
michael@0 1130 }
michael@0 1131
michael@0 1132 /* Part of the public NSS API.
michael@0 1133 * Since this is a global (not per-socket) setting, we cannot use the
michael@0 1134 * HandshakeLock to protect this. Probably want a global lock.
michael@0 1135 */
michael@0 1136 SECStatus
michael@0 1137 SSL_SetPolicy(long which, int policy)
michael@0 1138 {
michael@0 1139 if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
michael@0 1140 /* one of the two old FIPS ciphers */
michael@0 1141 if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
michael@0 1142 which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
michael@0 1143 else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
michael@0 1144 which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
michael@0 1145 }
michael@0 1146 if (ssl_IsRemovedCipherSuite(which))
michael@0 1147 return SECSuccess;
michael@0 1148 return SSL_CipherPolicySet(which, policy);
michael@0 1149 }
michael@0 1150
michael@0 1151 SECStatus
michael@0 1152 SSL_CipherPolicySet(PRInt32 which, PRInt32 policy)
michael@0 1153 {
michael@0 1154 SECStatus rv = ssl_Init();
michael@0 1155
michael@0 1156 if (rv != SECSuccess) {
michael@0 1157 return rv;
michael@0 1158 }
michael@0 1159
michael@0 1160 if (ssl_IsRemovedCipherSuite(which)) {
michael@0 1161 rv = SECSuccess;
michael@0 1162 } else if (SSL_IS_SSL2_CIPHER(which)) {
michael@0 1163 rv = ssl2_SetPolicy(which, policy);
michael@0 1164 } else {
michael@0 1165 rv = ssl3_SetPolicy((ssl3CipherSuite)which, policy);
michael@0 1166 }
michael@0 1167 return rv;
michael@0 1168 }
michael@0 1169
michael@0 1170 SECStatus
michael@0 1171 SSL_CipherPolicyGet(PRInt32 which, PRInt32 *oPolicy)
michael@0 1172 {
michael@0 1173 SECStatus rv;
michael@0 1174
michael@0 1175 if (!oPolicy) {
michael@0 1176 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1177 return SECFailure;
michael@0 1178 }
michael@0 1179 if (ssl_IsRemovedCipherSuite(which)) {
michael@0 1180 *oPolicy = SSL_NOT_ALLOWED;
michael@0 1181 rv = SECSuccess;
michael@0 1182 } else if (SSL_IS_SSL2_CIPHER(which)) {
michael@0 1183 rv = ssl2_GetPolicy(which, oPolicy);
michael@0 1184 } else {
michael@0 1185 rv = ssl3_GetPolicy((ssl3CipherSuite)which, oPolicy);
michael@0 1186 }
michael@0 1187 return rv;
michael@0 1188 }
michael@0 1189
michael@0 1190 /* Part of the public NSS API.
michael@0 1191 * Since this is a global (not per-socket) setting, we cannot use the
michael@0 1192 * HandshakeLock to protect this. Probably want a global lock.
michael@0 1193 * These changes have no effect on any sslSockets already created.
michael@0 1194 */
michael@0 1195 SECStatus
michael@0 1196 SSL_EnableCipher(long which, PRBool enabled)
michael@0 1197 {
michael@0 1198 if ((which & 0xfffe) == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA) {
michael@0 1199 /* one of the two old FIPS ciphers */
michael@0 1200 if (which == SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA)
michael@0 1201 which = SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA;
michael@0 1202 else if (which == SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA)
michael@0 1203 which = SSL_RSA_FIPS_WITH_DES_CBC_SHA;
michael@0 1204 }
michael@0 1205 if (ssl_IsRemovedCipherSuite(which))
michael@0 1206 return SECSuccess;
michael@0 1207 return SSL_CipherPrefSetDefault(which, enabled);
michael@0 1208 }
michael@0 1209
michael@0 1210 SECStatus
michael@0 1211 SSL_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
michael@0 1212 {
michael@0 1213 SECStatus rv = ssl_Init();
michael@0 1214
michael@0 1215 if (rv != SECSuccess) {
michael@0 1216 return rv;
michael@0 1217 }
michael@0 1218
michael@0 1219 if (ssl_IsRemovedCipherSuite(which))
michael@0 1220 return SECSuccess;
michael@0 1221 if (enabled && ssl_defaults.noStepDown && SSL_IsExportCipherSuite(which)) {
michael@0 1222 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
michael@0 1223 return SECFailure;
michael@0 1224 }
michael@0 1225 if (SSL_IS_SSL2_CIPHER(which)) {
michael@0 1226 rv = ssl2_CipherPrefSetDefault(which, enabled);
michael@0 1227 } else {
michael@0 1228 rv = ssl3_CipherPrefSetDefault((ssl3CipherSuite)which, enabled);
michael@0 1229 }
michael@0 1230 return rv;
michael@0 1231 }
michael@0 1232
michael@0 1233 SECStatus
michael@0 1234 SSL_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
michael@0 1235 {
michael@0 1236 SECStatus rv;
michael@0 1237
michael@0 1238 if (!enabled) {
michael@0 1239 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1240 return SECFailure;
michael@0 1241 }
michael@0 1242 if (ssl_IsRemovedCipherSuite(which)) {
michael@0 1243 *enabled = PR_FALSE;
michael@0 1244 rv = SECSuccess;
michael@0 1245 } else if (SSL_IS_SSL2_CIPHER(which)) {
michael@0 1246 rv = ssl2_CipherPrefGetDefault(which, enabled);
michael@0 1247 } else {
michael@0 1248 rv = ssl3_CipherPrefGetDefault((ssl3CipherSuite)which, enabled);
michael@0 1249 }
michael@0 1250 return rv;
michael@0 1251 }
michael@0 1252
michael@0 1253 SECStatus
michael@0 1254 SSL_CipherPrefSet(PRFileDesc *fd, PRInt32 which, PRBool enabled)
michael@0 1255 {
michael@0 1256 SECStatus rv;
michael@0 1257 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1258
michael@0 1259 if (!ss) {
michael@0 1260 SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefSet", SSL_GETPID(), fd));
michael@0 1261 return SECFailure;
michael@0 1262 }
michael@0 1263 if (ssl_IsRemovedCipherSuite(which))
michael@0 1264 return SECSuccess;
michael@0 1265 if (enabled && ss->opt.noStepDown && SSL_IsExportCipherSuite(which)) {
michael@0 1266 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
michael@0 1267 return SECFailure;
michael@0 1268 }
michael@0 1269 if (SSL_IS_SSL2_CIPHER(which)) {
michael@0 1270 rv = ssl2_CipherPrefSet(ss, which, enabled);
michael@0 1271 } else {
michael@0 1272 rv = ssl3_CipherPrefSet(ss, (ssl3CipherSuite)which, enabled);
michael@0 1273 }
michael@0 1274 return rv;
michael@0 1275 }
michael@0 1276
michael@0 1277 SECStatus
michael@0 1278 SSL_CipherPrefGet(PRFileDesc *fd, PRInt32 which, PRBool *enabled)
michael@0 1279 {
michael@0 1280 SECStatus rv;
michael@0 1281 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1282
michael@0 1283 if (!enabled) {
michael@0 1284 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1285 return SECFailure;
michael@0 1286 }
michael@0 1287 if (!ss) {
michael@0 1288 SSL_DBG(("%d: SSL[%d]: bad socket in CipherPrefGet", SSL_GETPID(), fd));
michael@0 1289 *enabled = PR_FALSE;
michael@0 1290 return SECFailure;
michael@0 1291 }
michael@0 1292 if (ssl_IsRemovedCipherSuite(which)) {
michael@0 1293 *enabled = PR_FALSE;
michael@0 1294 rv = SECSuccess;
michael@0 1295 } else if (SSL_IS_SSL2_CIPHER(which)) {
michael@0 1296 rv = ssl2_CipherPrefGet(ss, which, enabled);
michael@0 1297 } else {
michael@0 1298 rv = ssl3_CipherPrefGet(ss, (ssl3CipherSuite)which, enabled);
michael@0 1299 }
michael@0 1300 return rv;
michael@0 1301 }
michael@0 1302
michael@0 1303 SECStatus
michael@0 1304 NSS_SetDomesticPolicy(void)
michael@0 1305 {
michael@0 1306 SECStatus status = SECSuccess;
michael@0 1307 const PRUint16 *cipher;
michael@0 1308
michael@0 1309 for (cipher = SSL_ImplementedCiphers; *cipher != 0; ++cipher) {
michael@0 1310 status = SSL_SetPolicy(*cipher, SSL_ALLOWED);
michael@0 1311 if (status != SECSuccess)
michael@0 1312 break;
michael@0 1313 }
michael@0 1314 return status;
michael@0 1315 }
michael@0 1316
michael@0 1317 SECStatus
michael@0 1318 NSS_SetExportPolicy(void)
michael@0 1319 {
michael@0 1320 return NSS_SetDomesticPolicy();
michael@0 1321 }
michael@0 1322
michael@0 1323 SECStatus
michael@0 1324 NSS_SetFrancePolicy(void)
michael@0 1325 {
michael@0 1326 return NSS_SetDomesticPolicy();
michael@0 1327 }
michael@0 1328
michael@0 1329
michael@0 1330
michael@0 1331 /* LOCKS ??? XXX */
michael@0 1332 static PRFileDesc *
michael@0 1333 ssl_ImportFD(PRFileDesc *model, PRFileDesc *fd, SSLProtocolVariant variant)
michael@0 1334 {
michael@0 1335 sslSocket * ns = NULL;
michael@0 1336 PRStatus rv;
michael@0 1337 PRNetAddr addr;
michael@0 1338 SECStatus status = ssl_Init();
michael@0 1339
michael@0 1340 if (status != SECSuccess) {
michael@0 1341 return NULL;
michael@0 1342 }
michael@0 1343
michael@0 1344 if (model == NULL) {
michael@0 1345 /* Just create a default socket if we're given NULL for the model */
michael@0 1346 ns = ssl_NewSocket((PRBool)(!ssl_defaults.noLocks), variant);
michael@0 1347 } else {
michael@0 1348 sslSocket * ss = ssl_FindSocket(model);
michael@0 1349 if (ss == NULL || ss->protocolVariant != variant) {
michael@0 1350 SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ImportFD",
michael@0 1351 SSL_GETPID(), model));
michael@0 1352 return NULL;
michael@0 1353 }
michael@0 1354 ns = ssl_DupSocket(ss);
michael@0 1355 }
michael@0 1356 if (ns == NULL)
michael@0 1357 return NULL;
michael@0 1358
michael@0 1359 rv = ssl_PushIOLayer(ns, fd, PR_TOP_IO_LAYER);
michael@0 1360 if (rv != PR_SUCCESS) {
michael@0 1361 ssl_FreeSocket(ns);
michael@0 1362 SET_ERROR_CODE
michael@0 1363 return NULL;
michael@0 1364 }
michael@0 1365 #if defined(DEBUG) || defined(FORCE_PR_ASSERT)
michael@0 1366 {
michael@0 1367 sslSocket * ss = ssl_FindSocket(fd);
michael@0 1368 PORT_Assert(ss == ns);
michael@0 1369 }
michael@0 1370 #endif
michael@0 1371 ns->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ns, &addr));
michael@0 1372 return fd;
michael@0 1373 }
michael@0 1374
michael@0 1375 PRFileDesc *
michael@0 1376 SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
michael@0 1377 {
michael@0 1378 return ssl_ImportFD(model, fd, ssl_variant_stream);
michael@0 1379 }
michael@0 1380
michael@0 1381 PRFileDesc *
michael@0 1382 DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
michael@0 1383 {
michael@0 1384 return ssl_ImportFD(model, fd, ssl_variant_datagram);
michael@0 1385 }
michael@0 1386
michael@0 1387 /* SSL_SetNextProtoCallback is used to select an application protocol
michael@0 1388 * for ALPN and NPN. For ALPN, this runs on the server; for NPN it
michael@0 1389 * runs on the client. */
michael@0 1390 /* Note: The ALPN version doesn't allow for the use of a default, setting a
michael@0 1391 * status of SSL_NEXT_PROTO_NO_OVERLAP is treated as a failure. */
michael@0 1392 SECStatus
michael@0 1393 SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
michael@0 1394 void *arg)
michael@0 1395 {
michael@0 1396 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1397
michael@0 1398 if (!ss) {
michael@0 1399 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoCallback", SSL_GETPID(),
michael@0 1400 fd));
michael@0 1401 return SECFailure;
michael@0 1402 }
michael@0 1403
michael@0 1404 ssl_GetSSL3HandshakeLock(ss);
michael@0 1405 ss->nextProtoCallback = callback;
michael@0 1406 ss->nextProtoArg = arg;
michael@0 1407 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 1408
michael@0 1409 return SECSuccess;
michael@0 1410 }
michael@0 1411
michael@0 1412 /* ssl_NextProtoNegoCallback is set as an ALPN/NPN callback when
michael@0 1413 * SSL_SetNextProtoNego is used.
michael@0 1414 */
michael@0 1415 static SECStatus
michael@0 1416 ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
michael@0 1417 const unsigned char *protos, unsigned int protos_len,
michael@0 1418 unsigned char *protoOut, unsigned int *protoOutLen,
michael@0 1419 unsigned int protoMaxLen)
michael@0 1420 {
michael@0 1421 unsigned int i, j;
michael@0 1422 const unsigned char *result;
michael@0 1423 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1424
michael@0 1425 if (!ss) {
michael@0 1426 SSL_DBG(("%d: SSL[%d]: bad socket in ssl_NextProtoNegoCallback",
michael@0 1427 SSL_GETPID(), fd));
michael@0 1428 return SECFailure;
michael@0 1429 }
michael@0 1430
michael@0 1431 /* For each protocol in server preference, see if we support it. */
michael@0 1432 for (i = 0; i < protos_len; ) {
michael@0 1433 for (j = 0; j < ss->opt.nextProtoNego.len; ) {
michael@0 1434 if (protos[i] == ss->opt.nextProtoNego.data[j] &&
michael@0 1435 PORT_Memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
michael@0 1436 protos[i]) == 0) {
michael@0 1437 /* We found a match. */
michael@0 1438 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
michael@0 1439 result = &protos[i];
michael@0 1440 goto found;
michael@0 1441 }
michael@0 1442 j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
michael@0 1443 }
michael@0 1444 i += 1 + (unsigned int)protos[i];
michael@0 1445 }
michael@0 1446
michael@0 1447 /* The other side supports the extension, and either doesn't have any
michael@0 1448 * protocols configured, or none of its options match ours. In this case we
michael@0 1449 * request our favoured protocol. */
michael@0 1450 /* This will be treated as a failure for ALPN. */
michael@0 1451 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
michael@0 1452 result = ss->opt.nextProtoNego.data;
michael@0 1453
michael@0 1454 found:
michael@0 1455 if (protoMaxLen < result[0]) {
michael@0 1456 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
michael@0 1457 return SECFailure;
michael@0 1458 }
michael@0 1459 memcpy(protoOut, result + 1, result[0]);
michael@0 1460 *protoOutLen = result[0];
michael@0 1461 return SECSuccess;
michael@0 1462 }
michael@0 1463
michael@0 1464 SECStatus
michael@0 1465 SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
michael@0 1466 unsigned int length)
michael@0 1467 {
michael@0 1468 sslSocket *ss;
michael@0 1469 SECStatus rv;
michael@0 1470 SECItem dataItem = { siBuffer, (unsigned char *) data, length };
michael@0 1471
michael@0 1472 ss = ssl_FindSocket(fd);
michael@0 1473 if (!ss) {
michael@0 1474 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
michael@0 1475 SSL_GETPID(), fd));
michael@0 1476 return SECFailure;
michael@0 1477 }
michael@0 1478
michael@0 1479 if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
michael@0 1480 return SECFailure;
michael@0 1481
michael@0 1482 ssl_GetSSL3HandshakeLock(ss);
michael@0 1483 SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
michael@0 1484 rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem);
michael@0 1485 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 1486
michael@0 1487 if (rv != SECSuccess)
michael@0 1488 return rv;
michael@0 1489
michael@0 1490 return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL);
michael@0 1491 }
michael@0 1492
michael@0 1493 SECStatus
michael@0 1494 SSL_GetNextProto(PRFileDesc *fd, SSLNextProtoState *state, unsigned char *buf,
michael@0 1495 unsigned int *bufLen, unsigned int bufLenMax)
michael@0 1496 {
michael@0 1497 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1498
michael@0 1499 if (!ss) {
michael@0 1500 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
michael@0 1501 fd));
michael@0 1502 return SECFailure;
michael@0 1503 }
michael@0 1504
michael@0 1505 if (!state || !buf || !bufLen) {
michael@0 1506 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1507 return SECFailure;
michael@0 1508 }
michael@0 1509
michael@0 1510 *state = ss->ssl3.nextProtoState;
michael@0 1511
michael@0 1512 if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
michael@0 1513 ss->ssl3.nextProto.data) {
michael@0 1514 if (ss->ssl3.nextProto.len > bufLenMax) {
michael@0 1515 PORT_SetError(SEC_ERROR_OUTPUT_LEN);
michael@0 1516 return SECFailure;
michael@0 1517 }
michael@0 1518 PORT_Memcpy(buf, ss->ssl3.nextProto.data, ss->ssl3.nextProto.len);
michael@0 1519 *bufLen = ss->ssl3.nextProto.len;
michael@0 1520 } else {
michael@0 1521 *bufLen = 0;
michael@0 1522 }
michael@0 1523
michael@0 1524 return SECSuccess;
michael@0 1525 }
michael@0 1526
michael@0 1527 SECStatus SSL_SetSRTPCiphers(PRFileDesc *fd,
michael@0 1528 const PRUint16 *ciphers,
michael@0 1529 unsigned int numCiphers)
michael@0 1530 {
michael@0 1531 sslSocket *ss;
michael@0 1532 unsigned int i;
michael@0 1533
michael@0 1534 ss = ssl_FindSocket(fd);
michael@0 1535 if (!ss || !IS_DTLS(ss)) {
michael@0 1536 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSRTPCiphers",
michael@0 1537 SSL_GETPID(), fd));
michael@0 1538 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1539 return SECFailure;
michael@0 1540 }
michael@0 1541
michael@0 1542 if (numCiphers > MAX_DTLS_SRTP_CIPHER_SUITES) {
michael@0 1543 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1544 return SECFailure;
michael@0 1545 }
michael@0 1546
michael@0 1547 ss->ssl3.dtlsSRTPCipherCount = 0;
michael@0 1548 for (i = 0; i < numCiphers; i++) {
michael@0 1549 const PRUint16 *srtpCipher = srtpCiphers;
michael@0 1550
michael@0 1551 while (*srtpCipher) {
michael@0 1552 if (ciphers[i] == *srtpCipher)
michael@0 1553 break;
michael@0 1554 srtpCipher++;
michael@0 1555 }
michael@0 1556 if (*srtpCipher) {
michael@0 1557 ss->ssl3.dtlsSRTPCiphers[ss->ssl3.dtlsSRTPCipherCount++] =
michael@0 1558 ciphers[i];
michael@0 1559 } else {
michael@0 1560 SSL_DBG(("%d: SSL[%d]: invalid or unimplemented SRTP cipher "
michael@0 1561 "suite specified: 0x%04hx", SSL_GETPID(), fd,
michael@0 1562 ciphers[i]));
michael@0 1563 }
michael@0 1564 }
michael@0 1565
michael@0 1566 if (ss->ssl3.dtlsSRTPCipherCount == 0) {
michael@0 1567 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1568 return SECFailure;
michael@0 1569 }
michael@0 1570
michael@0 1571 return SECSuccess;
michael@0 1572 }
michael@0 1573
michael@0 1574 SECStatus
michael@0 1575 SSL_GetSRTPCipher(PRFileDesc *fd, PRUint16 *cipher)
michael@0 1576 {
michael@0 1577 sslSocket * ss;
michael@0 1578
michael@0 1579 ss = ssl_FindSocket(fd);
michael@0 1580 if (!ss) {
michael@0 1581 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetSRTPCipher",
michael@0 1582 SSL_GETPID(), fd));
michael@0 1583 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1584 return SECFailure;
michael@0 1585 }
michael@0 1586
michael@0 1587 if (!ss->ssl3.dtlsSRTPCipherSuite) {
michael@0 1588 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1589 return SECFailure;
michael@0 1590 }
michael@0 1591
michael@0 1592 *cipher = ss->ssl3.dtlsSRTPCipherSuite;
michael@0 1593 return SECSuccess;
michael@0 1594 }
michael@0 1595
michael@0 1596 PRFileDesc *
michael@0 1597 SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
michael@0 1598 {
michael@0 1599 sslSocket * sm = NULL, *ss = NULL;
michael@0 1600 int i;
michael@0 1601 sslServerCerts * mc = NULL;
michael@0 1602 sslServerCerts * sc = NULL;
michael@0 1603
michael@0 1604 if (model == NULL) {
michael@0 1605 PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
michael@0 1606 return NULL;
michael@0 1607 }
michael@0 1608 sm = ssl_FindSocket(model);
michael@0 1609 if (sm == NULL) {
michael@0 1610 SSL_DBG(("%d: SSL[%d]: bad model socket in ssl_ReconfigFD",
michael@0 1611 SSL_GETPID(), model));
michael@0 1612 return NULL;
michael@0 1613 }
michael@0 1614 ss = ssl_FindSocket(fd);
michael@0 1615 PORT_Assert(ss);
michael@0 1616 if (ss == NULL) {
michael@0 1617 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1618 return NULL;
michael@0 1619 }
michael@0 1620
michael@0 1621 ss->opt = sm->opt;
michael@0 1622 ss->vrange = sm->vrange;
michael@0 1623 PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
michael@0 1624 PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
michael@0 1625 sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
michael@0 1626 ss->ssl3.dtlsSRTPCipherCount = sm->ssl3.dtlsSRTPCipherCount;
michael@0 1627
michael@0 1628 if (!ss->opt.useSecurity) {
michael@0 1629 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1630 return NULL;
michael@0 1631 }
michael@0 1632 /* This int should be SSLKEAType, but CC on Irix complains,
michael@0 1633 * during the for loop.
michael@0 1634 */
michael@0 1635 for (i=kt_null; i < kt_kea_size; i++) {
michael@0 1636 mc = &(sm->serverCerts[i]);
michael@0 1637 sc = &(ss->serverCerts[i]);
michael@0 1638 if (mc->serverCert && mc->serverCertChain) {
michael@0 1639 if (sc->serverCert) {
michael@0 1640 CERT_DestroyCertificate(sc->serverCert);
michael@0 1641 }
michael@0 1642 sc->serverCert = CERT_DupCertificate(mc->serverCert);
michael@0 1643 if (sc->serverCertChain) {
michael@0 1644 CERT_DestroyCertificateList(sc->serverCertChain);
michael@0 1645 }
michael@0 1646 sc->serverCertChain = CERT_DupCertList(mc->serverCertChain);
michael@0 1647 if (!sc->serverCertChain)
michael@0 1648 goto loser;
michael@0 1649 if (sm->certStatusArray[i]) {
michael@0 1650 if (ss->certStatusArray[i]) {
michael@0 1651 SECITEM_FreeArray(ss->certStatusArray[i], PR_TRUE);
michael@0 1652 ss->certStatusArray[i] = NULL;
michael@0 1653 }
michael@0 1654 ss->certStatusArray[i] = SECITEM_DupArray(NULL, sm->certStatusArray[i]);
michael@0 1655 if (!ss->certStatusArray[i])
michael@0 1656 goto loser;
michael@0 1657 }
michael@0 1658 }
michael@0 1659 if (mc->serverKeyPair) {
michael@0 1660 if (sc->serverKeyPair) {
michael@0 1661 ssl3_FreeKeyPair(sc->serverKeyPair);
michael@0 1662 }
michael@0 1663 sc->serverKeyPair = ssl3_GetKeyPairRef(mc->serverKeyPair);
michael@0 1664 sc->serverKeyBits = mc->serverKeyBits;
michael@0 1665 }
michael@0 1666 }
michael@0 1667 if (sm->stepDownKeyPair) {
michael@0 1668 if (ss->stepDownKeyPair) {
michael@0 1669 ssl3_FreeKeyPair(ss->stepDownKeyPair);
michael@0 1670 }
michael@0 1671 ss->stepDownKeyPair = ssl3_GetKeyPairRef(sm->stepDownKeyPair);
michael@0 1672 }
michael@0 1673 if (sm->ephemeralECDHKeyPair) {
michael@0 1674 if (ss->ephemeralECDHKeyPair) {
michael@0 1675 ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
michael@0 1676 }
michael@0 1677 ss->ephemeralECDHKeyPair =
michael@0 1678 ssl3_GetKeyPairRef(sm->ephemeralECDHKeyPair);
michael@0 1679 }
michael@0 1680 /* copy trust anchor names */
michael@0 1681 if (sm->ssl3.ca_list) {
michael@0 1682 if (ss->ssl3.ca_list) {
michael@0 1683 CERT_FreeDistNames(ss->ssl3.ca_list);
michael@0 1684 }
michael@0 1685 ss->ssl3.ca_list = CERT_DupDistNames(sm->ssl3.ca_list);
michael@0 1686 if (!ss->ssl3.ca_list) {
michael@0 1687 goto loser;
michael@0 1688 }
michael@0 1689 }
michael@0 1690
michael@0 1691 if (sm->authCertificate)
michael@0 1692 ss->authCertificate = sm->authCertificate;
michael@0 1693 if (sm->authCertificateArg)
michael@0 1694 ss->authCertificateArg = sm->authCertificateArg;
michael@0 1695 if (sm->getClientAuthData)
michael@0 1696 ss->getClientAuthData = sm->getClientAuthData;
michael@0 1697 if (sm->getClientAuthDataArg)
michael@0 1698 ss->getClientAuthDataArg = sm->getClientAuthDataArg;
michael@0 1699 if (sm->sniSocketConfig)
michael@0 1700 ss->sniSocketConfig = sm->sniSocketConfig;
michael@0 1701 if (sm->sniSocketConfigArg)
michael@0 1702 ss->sniSocketConfigArg = sm->sniSocketConfigArg;
michael@0 1703 if (sm->handleBadCert)
michael@0 1704 ss->handleBadCert = sm->handleBadCert;
michael@0 1705 if (sm->badCertArg)
michael@0 1706 ss->badCertArg = sm->badCertArg;
michael@0 1707 if (sm->handshakeCallback)
michael@0 1708 ss->handshakeCallback = sm->handshakeCallback;
michael@0 1709 if (sm->handshakeCallbackData)
michael@0 1710 ss->handshakeCallbackData = sm->handshakeCallbackData;
michael@0 1711 if (sm->pkcs11PinArg)
michael@0 1712 ss->pkcs11PinArg = sm->pkcs11PinArg;
michael@0 1713 return fd;
michael@0 1714 loser:
michael@0 1715 return NULL;
michael@0 1716 }
michael@0 1717
michael@0 1718 PRBool
michael@0 1719 ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
michael@0 1720 SSL3ProtocolVersion version)
michael@0 1721 {
michael@0 1722 switch (protocolVariant) {
michael@0 1723 case ssl_variant_stream:
michael@0 1724 return (version >= SSL_LIBRARY_VERSION_3_0 &&
michael@0 1725 version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
michael@0 1726 case ssl_variant_datagram:
michael@0 1727 return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
michael@0 1728 version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
michael@0 1729 default:
michael@0 1730 /* Can't get here */
michael@0 1731 PORT_Assert(PR_FALSE);
michael@0 1732 return PR_FALSE;
michael@0 1733 }
michael@0 1734 }
michael@0 1735
michael@0 1736 /* Returns PR_TRUE if the given version range is valid and
michael@0 1737 ** fully supported; otherwise, returns PR_FALSE.
michael@0 1738 */
michael@0 1739 static PRBool
michael@0 1740 ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
michael@0 1741 const SSLVersionRange *vrange)
michael@0 1742 {
michael@0 1743 return vrange &&
michael@0 1744 vrange->min <= vrange->max &&
michael@0 1745 ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
michael@0 1746 ssl3_VersionIsSupported(protocolVariant, vrange->max);
michael@0 1747 }
michael@0 1748
michael@0 1749 SECStatus
michael@0 1750 SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
michael@0 1751 SSLVersionRange *vrange)
michael@0 1752 {
michael@0 1753 if (!vrange) {
michael@0 1754 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1755 return SECFailure;
michael@0 1756 }
michael@0 1757
michael@0 1758 switch (protocolVariant) {
michael@0 1759 case ssl_variant_stream:
michael@0 1760 vrange->min = SSL_LIBRARY_VERSION_3_0;
michael@0 1761 vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
michael@0 1762 break;
michael@0 1763 case ssl_variant_datagram:
michael@0 1764 vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
michael@0 1765 vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
michael@0 1766 break;
michael@0 1767 default:
michael@0 1768 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1769 return SECFailure;
michael@0 1770 }
michael@0 1771
michael@0 1772 return SECSuccess;
michael@0 1773 }
michael@0 1774
michael@0 1775 SECStatus
michael@0 1776 SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
michael@0 1777 SSLVersionRange *vrange)
michael@0 1778 {
michael@0 1779 if ((protocolVariant != ssl_variant_stream &&
michael@0 1780 protocolVariant != ssl_variant_datagram) || !vrange) {
michael@0 1781 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1782 return SECFailure;
michael@0 1783 }
michael@0 1784
michael@0 1785 *vrange = *VERSIONS_DEFAULTS(protocolVariant);
michael@0 1786
michael@0 1787 return SECSuccess;
michael@0 1788 }
michael@0 1789
michael@0 1790 SECStatus
michael@0 1791 SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
michael@0 1792 const SSLVersionRange *vrange)
michael@0 1793 {
michael@0 1794 if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
michael@0 1795 PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
michael@0 1796 return SECFailure;
michael@0 1797 }
michael@0 1798
michael@0 1799 *VERSIONS_DEFAULTS(protocolVariant) = *vrange;
michael@0 1800
michael@0 1801 return SECSuccess;
michael@0 1802 }
michael@0 1803
michael@0 1804 SECStatus
michael@0 1805 SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
michael@0 1806 {
michael@0 1807 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1808
michael@0 1809 if (!ss) {
michael@0 1810 SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeGet",
michael@0 1811 SSL_GETPID(), fd));
michael@0 1812 return SECFailure;
michael@0 1813 }
michael@0 1814
michael@0 1815 if (!vrange) {
michael@0 1816 PORT_SetError(SEC_ERROR_INVALID_ARGS);
michael@0 1817 return SECFailure;
michael@0 1818 }
michael@0 1819
michael@0 1820 ssl_Get1stHandshakeLock(ss);
michael@0 1821 ssl_GetSSL3HandshakeLock(ss);
michael@0 1822
michael@0 1823 *vrange = ss->vrange;
michael@0 1824
michael@0 1825 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 1826 ssl_Release1stHandshakeLock(ss);
michael@0 1827
michael@0 1828 return SECSuccess;
michael@0 1829 }
michael@0 1830
michael@0 1831 SECStatus
michael@0 1832 SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
michael@0 1833 {
michael@0 1834 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1835
michael@0 1836 if (!ss) {
michael@0 1837 SSL_DBG(("%d: SSL[%d]: bad socket in SSL3_VersionRangeSet",
michael@0 1838 SSL_GETPID(), fd));
michael@0 1839 return SECFailure;
michael@0 1840 }
michael@0 1841
michael@0 1842 if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
michael@0 1843 PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
michael@0 1844 return SECFailure;
michael@0 1845 }
michael@0 1846
michael@0 1847 ssl_Get1stHandshakeLock(ss);
michael@0 1848 ssl_GetSSL3HandshakeLock(ss);
michael@0 1849
michael@0 1850 ss->vrange = *vrange;
michael@0 1851
michael@0 1852 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 1853 ssl_Release1stHandshakeLock(ss);
michael@0 1854
michael@0 1855 return SECSuccess;
michael@0 1856 }
michael@0 1857
michael@0 1858 const SECItemArray *
michael@0 1859 SSL_PeerStapledOCSPResponses(PRFileDesc *fd)
michael@0 1860 {
michael@0 1861 sslSocket *ss = ssl_FindSocket(fd);
michael@0 1862
michael@0 1863 if (!ss) {
michael@0 1864 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_PeerStapledOCSPResponses",
michael@0 1865 SSL_GETPID(), fd));
michael@0 1866 return NULL;
michael@0 1867 }
michael@0 1868
michael@0 1869 if (!ss->sec.ci.sid) {
michael@0 1870 PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
michael@0 1871 return NULL;
michael@0 1872 }
michael@0 1873
michael@0 1874 return &ss->sec.ci.sid->peerCertStatus;
michael@0 1875 }
michael@0 1876
michael@0 1877 /************************************************************************/
michael@0 1878 /* The following functions are the TOP LEVEL SSL functions.
michael@0 1879 ** They all get called through the NSPRIOMethods table below.
michael@0 1880 */
michael@0 1881
michael@0 1882 static PRFileDesc * PR_CALLBACK
michael@0 1883 ssl_Accept(PRFileDesc *fd, PRNetAddr *sockaddr, PRIntervalTime timeout)
michael@0 1884 {
michael@0 1885 sslSocket *ss;
michael@0 1886 sslSocket *ns = NULL;
michael@0 1887 PRFileDesc *newfd = NULL;
michael@0 1888 PRFileDesc *osfd;
michael@0 1889 PRStatus status;
michael@0 1890
michael@0 1891 ss = ssl_GetPrivate(fd);
michael@0 1892 if (!ss) {
michael@0 1893 SSL_DBG(("%d: SSL[%d]: bad socket in accept", SSL_GETPID(), fd));
michael@0 1894 return NULL;
michael@0 1895 }
michael@0 1896
michael@0 1897 /* IF this is a listen socket, there shouldn't be any I/O going on */
michael@0 1898 SSL_LOCK_READER(ss);
michael@0 1899 SSL_LOCK_WRITER(ss);
michael@0 1900 ssl_Get1stHandshakeLock(ss);
michael@0 1901 ssl_GetSSL3HandshakeLock(ss);
michael@0 1902
michael@0 1903 ss->cTimeout = timeout;
michael@0 1904
michael@0 1905 osfd = ss->fd->lower;
michael@0 1906
michael@0 1907 /* First accept connection */
michael@0 1908 newfd = osfd->methods->accept(osfd, sockaddr, timeout);
michael@0 1909 if (newfd == NULL) {
michael@0 1910 SSL_DBG(("%d: SSL[%d]: accept failed, errno=%d",
michael@0 1911 SSL_GETPID(), ss->fd, PORT_GetError()));
michael@0 1912 } else {
michael@0 1913 /* Create ssl module */
michael@0 1914 ns = ssl_DupSocket(ss);
michael@0 1915 }
michael@0 1916
michael@0 1917 ssl_ReleaseSSL3HandshakeLock(ss);
michael@0 1918 ssl_Release1stHandshakeLock(ss);
michael@0 1919 SSL_UNLOCK_WRITER(ss);
michael@0 1920 SSL_UNLOCK_READER(ss); /* ss isn't used below here. */
michael@0 1921
michael@0 1922 if (ns == NULL)
michael@0 1923 goto loser;
michael@0 1924
michael@0 1925 /* push ssl module onto the new socket */
michael@0 1926 status = ssl_PushIOLayer(ns, newfd, PR_TOP_IO_LAYER);
michael@0 1927 if (status != PR_SUCCESS)
michael@0 1928 goto loser;
michael@0 1929
michael@0 1930 /* Now start server connection handshake with client.
michael@0 1931 ** Don't need locks here because nobody else has a reference to ns yet.
michael@0 1932 */
michael@0 1933 if ( ns->opt.useSecurity ) {
michael@0 1934 if ( ns->opt.handshakeAsClient ) {
michael@0 1935 ns->handshake = ssl2_BeginClientHandshake;
michael@0 1936 ss->handshaking = sslHandshakingAsClient;
michael@0 1937 } else {
michael@0 1938 ns->handshake = ssl2_BeginServerHandshake;
michael@0 1939 ss->handshaking = sslHandshakingAsServer;
michael@0 1940 }
michael@0 1941 }
michael@0 1942 ns->TCPconnected = 1;
michael@0 1943 return newfd;
michael@0 1944
michael@0 1945 loser:
michael@0 1946 if (ns != NULL)
michael@0 1947 ssl_FreeSocket(ns);
michael@0 1948 if (newfd != NULL)
michael@0 1949 PR_Close(newfd);
michael@0 1950 return NULL;
michael@0 1951 }
michael@0 1952
michael@0 1953 static PRStatus PR_CALLBACK
michael@0 1954 ssl_Connect(PRFileDesc *fd, const PRNetAddr *sockaddr, PRIntervalTime timeout)
michael@0 1955 {
michael@0 1956 sslSocket *ss;
michael@0 1957 PRStatus rv;
michael@0 1958
michael@0 1959 ss = ssl_GetPrivate(fd);
michael@0 1960 if (!ss) {
michael@0 1961 SSL_DBG(("%d: SSL[%d]: bad socket in connect", SSL_GETPID(), fd));
michael@0 1962 return PR_FAILURE;
michael@0 1963 }
michael@0 1964
michael@0 1965 /* IF this is a listen socket, there shouldn't be any I/O going on */
michael@0 1966 SSL_LOCK_READER(ss);
michael@0 1967 SSL_LOCK_WRITER(ss);
michael@0 1968
michael@0 1969 ss->cTimeout = timeout;
michael@0 1970 rv = (PRStatus)(*ss->ops->connect)(ss, sockaddr);
michael@0 1971
michael@0 1972 SSL_UNLOCK_WRITER(ss);
michael@0 1973 SSL_UNLOCK_READER(ss);
michael@0 1974
michael@0 1975 return rv;
michael@0 1976 }
michael@0 1977
michael@0 1978 static PRStatus PR_CALLBACK
michael@0 1979 ssl_Bind(PRFileDesc *fd, const PRNetAddr *addr)
michael@0 1980 {
michael@0 1981 sslSocket * ss = ssl_GetPrivate(fd);
michael@0 1982 PRStatus rv;
michael@0 1983
michael@0 1984 if (!ss) {
michael@0 1985 SSL_DBG(("%d: SSL[%d]: bad socket in bind", SSL_GETPID(), fd));
michael@0 1986 return PR_FAILURE;
michael@0 1987 }
michael@0 1988 SSL_LOCK_READER(ss);
michael@0 1989 SSL_LOCK_WRITER(ss);
michael@0 1990
michael@0 1991 rv = (PRStatus)(*ss->ops->bind)(ss, addr);
michael@0 1992
michael@0 1993 SSL_UNLOCK_WRITER(ss);
michael@0 1994 SSL_UNLOCK_READER(ss);
michael@0 1995 return rv;
michael@0 1996 }
michael@0 1997
michael@0 1998 static PRStatus PR_CALLBACK
michael@0 1999 ssl_Listen(PRFileDesc *fd, PRIntn backlog)
michael@0 2000 {
michael@0 2001 sslSocket * ss = ssl_GetPrivate(fd);
michael@0 2002 PRStatus rv;
michael@0 2003
michael@0 2004 if (!ss) {
michael@0 2005 SSL_DBG(("%d: SSL[%d]: bad socket in listen", SSL_GETPID(), fd));
michael@0 2006 return PR_FAILURE;
michael@0 2007 }
michael@0 2008 SSL_LOCK_READER(ss);
michael@0 2009 SSL_LOCK_WRITER(ss);
michael@0 2010
michael@0 2011 rv = (PRStatus)(*ss->ops->listen)(ss, backlog);
michael@0 2012
michael@0 2013 SSL_UNLOCK_WRITER(ss);
michael@0 2014 SSL_UNLOCK_READER(ss);
michael@0 2015 return rv;
michael@0 2016 }
michael@0 2017
michael@0 2018 static PRStatus PR_CALLBACK
michael@0 2019 ssl_Shutdown(PRFileDesc *fd, PRIntn how)
michael@0 2020 {
michael@0 2021 sslSocket * ss = ssl_GetPrivate(fd);
michael@0 2022 PRStatus rv;
michael@0 2023
michael@0 2024 if (!ss) {
michael@0 2025 SSL_DBG(("%d: SSL[%d]: bad socket in shutdown", SSL_GETPID(), fd));
michael@0 2026 return PR_FAILURE;
michael@0 2027 }
michael@0 2028 if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
michael@0 2029 SSL_LOCK_READER(ss);
michael@0 2030 }
michael@0 2031 if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
michael@0 2032 SSL_LOCK_WRITER(ss);
michael@0 2033 }
michael@0 2034
michael@0 2035 rv = (PRStatus)(*ss->ops->shutdown)(ss, how);
michael@0 2036
michael@0 2037 if (how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH) {
michael@0 2038 SSL_UNLOCK_WRITER(ss);
michael@0 2039 }
michael@0 2040 if (how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH) {
michael@0 2041 SSL_UNLOCK_READER(ss);
michael@0 2042 }
michael@0 2043 return rv;
michael@0 2044 }
michael@0 2045
michael@0 2046 static PRStatus PR_CALLBACK
michael@0 2047 ssl_Close(PRFileDesc *fd)
michael@0 2048 {
michael@0 2049 sslSocket *ss;
michael@0 2050 PRStatus rv;
michael@0 2051
michael@0 2052 ss = ssl_GetPrivate(fd);
michael@0 2053 if (!ss) {
michael@0 2054 SSL_DBG(("%d: SSL[%d]: bad socket in close", SSL_GETPID(), fd));
michael@0 2055 return PR_FAILURE;
michael@0 2056 }
michael@0 2057
michael@0 2058 /* There must not be any I/O going on */
michael@0 2059 SSL_LOCK_READER(ss);
michael@0 2060 SSL_LOCK_WRITER(ss);
michael@0 2061
michael@0 2062 /* By the time this function returns,
michael@0 2063 ** ss is an invalid pointer, and the locks to which it points have
michael@0 2064 ** been unlocked and freed. So, this is the ONE PLACE in all of SSL
michael@0 2065 ** where the LOCK calls and the corresponding UNLOCK calls are not in
michael@0 2066 ** the same function scope. The unlock calls are in ssl_FreeSocket().
michael@0 2067 */
michael@0 2068 rv = (PRStatus)(*ss->ops->close)(ss);
michael@0 2069
michael@0 2070 return rv;
michael@0 2071 }
michael@0 2072
michael@0 2073 static int PR_CALLBACK
michael@0 2074 ssl_Recv(PRFileDesc *fd, void *buf, PRInt32 len, PRIntn flags,
michael@0 2075 PRIntervalTime timeout)
michael@0 2076 {
michael@0 2077 sslSocket *ss;
michael@0 2078 int rv;
michael@0 2079
michael@0 2080 ss = ssl_GetPrivate(fd);
michael@0 2081 if (!ss) {
michael@0 2082 SSL_DBG(("%d: SSL[%d]: bad socket in recv", SSL_GETPID(), fd));
michael@0 2083 return SECFailure;
michael@0 2084 }
michael@0 2085 SSL_LOCK_READER(ss);
michael@0 2086 ss->rTimeout = timeout;
michael@0 2087 if (!ss->opt.fdx)
michael@0 2088 ss->wTimeout = timeout;
michael@0 2089 rv = (*ss->ops->recv)(ss, (unsigned char*)buf, len, flags);
michael@0 2090 SSL_UNLOCK_READER(ss);
michael@0 2091 return rv;
michael@0 2092 }
michael@0 2093
michael@0 2094 static int PR_CALLBACK
michael@0 2095 ssl_Send(PRFileDesc *fd, const void *buf, PRInt32 len, PRIntn flags,
michael@0 2096 PRIntervalTime timeout)
michael@0 2097 {
michael@0 2098 sslSocket *ss;
michael@0 2099 int rv;
michael@0 2100
michael@0 2101 ss = ssl_GetPrivate(fd);
michael@0 2102 if (!ss) {
michael@0 2103 SSL_DBG(("%d: SSL[%d]: bad socket in send", SSL_GETPID(), fd));
michael@0 2104 return SECFailure;
michael@0 2105 }
michael@0 2106 SSL_LOCK_WRITER(ss);
michael@0 2107 ss->wTimeout = timeout;
michael@0 2108 if (!ss->opt.fdx)
michael@0 2109 ss->rTimeout = timeout;
michael@0 2110 rv = (*ss->ops->send)(ss, (const unsigned char*)buf, len, flags);
michael@0 2111 SSL_UNLOCK_WRITER(ss);
michael@0 2112 return rv;
michael@0 2113 }
michael@0 2114
michael@0 2115 static int PR_CALLBACK
michael@0 2116 ssl_Read(PRFileDesc *fd, void *buf, PRInt32 len)
michael@0 2117 {
michael@0 2118 sslSocket *ss;
michael@0 2119 int rv;
michael@0 2120
michael@0 2121 ss = ssl_GetPrivate(fd);
michael@0 2122 if (!ss) {
michael@0 2123 SSL_DBG(("%d: SSL[%d]: bad socket in read", SSL_GETPID(), fd));
michael@0 2124 return SECFailure;
michael@0 2125 }
michael@0 2126 SSL_LOCK_READER(ss);
michael@0 2127 ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2128 if (!ss->opt.fdx)
michael@0 2129 ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2130 rv = (*ss->ops->read)(ss, (unsigned char*)buf, len);
michael@0 2131 SSL_UNLOCK_READER(ss);
michael@0 2132 return rv;
michael@0 2133 }
michael@0 2134
michael@0 2135 static int PR_CALLBACK
michael@0 2136 ssl_Write(PRFileDesc *fd, const void *buf, PRInt32 len)
michael@0 2137 {
michael@0 2138 sslSocket *ss;
michael@0 2139 int rv;
michael@0 2140
michael@0 2141 ss = ssl_GetPrivate(fd);
michael@0 2142 if (!ss) {
michael@0 2143 SSL_DBG(("%d: SSL[%d]: bad socket in write", SSL_GETPID(), fd));
michael@0 2144 return SECFailure;
michael@0 2145 }
michael@0 2146 SSL_LOCK_WRITER(ss);
michael@0 2147 ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2148 if (!ss->opt.fdx)
michael@0 2149 ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2150 rv = (*ss->ops->write)(ss, (const unsigned char*)buf, len);
michael@0 2151 SSL_UNLOCK_WRITER(ss);
michael@0 2152 return rv;
michael@0 2153 }
michael@0 2154
michael@0 2155 static PRStatus PR_CALLBACK
michael@0 2156 ssl_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
michael@0 2157 {
michael@0 2158 sslSocket *ss;
michael@0 2159
michael@0 2160 ss = ssl_GetPrivate(fd);
michael@0 2161 if (!ss) {
michael@0 2162 SSL_DBG(("%d: SSL[%d]: bad socket in getpeername", SSL_GETPID(), fd));
michael@0 2163 return PR_FAILURE;
michael@0 2164 }
michael@0 2165 return (PRStatus)(*ss->ops->getpeername)(ss, addr);
michael@0 2166 }
michael@0 2167
michael@0 2168 /*
michael@0 2169 */
michael@0 2170 SECStatus
michael@0 2171 ssl_GetPeerInfo(sslSocket *ss)
michael@0 2172 {
michael@0 2173 PRFileDesc * osfd;
michael@0 2174 int rv;
michael@0 2175 PRNetAddr sin;
michael@0 2176
michael@0 2177 osfd = ss->fd->lower;
michael@0 2178
michael@0 2179 PORT_Memset(&sin, 0, sizeof(sin));
michael@0 2180 rv = osfd->methods->getpeername(osfd, &sin);
michael@0 2181 if (rv < 0) {
michael@0 2182 return SECFailure;
michael@0 2183 }
michael@0 2184 ss->TCPconnected = 1;
michael@0 2185 if (sin.inet.family == PR_AF_INET) {
michael@0 2186 PR_ConvertIPv4AddrToIPv6(sin.inet.ip, &ss->sec.ci.peer);
michael@0 2187 ss->sec.ci.port = sin.inet.port;
michael@0 2188 } else if (sin.ipv6.family == PR_AF_INET6) {
michael@0 2189 ss->sec.ci.peer = sin.ipv6.ip;
michael@0 2190 ss->sec.ci.port = sin.ipv6.port;
michael@0 2191 } else {
michael@0 2192 PORT_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR);
michael@0 2193 return SECFailure;
michael@0 2194 }
michael@0 2195 return SECSuccess;
michael@0 2196 }
michael@0 2197
michael@0 2198 static PRStatus PR_CALLBACK
michael@0 2199 ssl_GetSockName(PRFileDesc *fd, PRNetAddr *name)
michael@0 2200 {
michael@0 2201 sslSocket *ss;
michael@0 2202
michael@0 2203 ss = ssl_GetPrivate(fd);
michael@0 2204 if (!ss) {
michael@0 2205 SSL_DBG(("%d: SSL[%d]: bad socket in getsockname", SSL_GETPID(), fd));
michael@0 2206 return PR_FAILURE;
michael@0 2207 }
michael@0 2208 return (PRStatus)(*ss->ops->getsockname)(ss, name);
michael@0 2209 }
michael@0 2210
michael@0 2211 SECStatus
michael@0 2212 SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
michael@0 2213 SSLKEAType kea)
michael@0 2214 {
michael@0 2215 sslSocket *ss;
michael@0 2216
michael@0 2217 ss = ssl_FindSocket(fd);
michael@0 2218 if (!ss) {
michael@0 2219 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
michael@0 2220 SSL_GETPID(), fd));
michael@0 2221 return SECFailure;
michael@0 2222 }
michael@0 2223
michael@0 2224 if ( kea <= 0 || kea >= kt_kea_size) {
michael@0 2225 SSL_DBG(("%d: SSL[%d]: invalid key in SSL_SetStapledOCSPResponses",
michael@0 2226 SSL_GETPID(), fd));
michael@0 2227 return SECFailure;
michael@0 2228 }
michael@0 2229
michael@0 2230 if (ss->certStatusArray[kea]) {
michael@0 2231 SECITEM_FreeArray(ss->certStatusArray[kea], PR_TRUE);
michael@0 2232 ss->certStatusArray[kea] = NULL;
michael@0 2233 }
michael@0 2234 if (responses) {
michael@0 2235 ss->certStatusArray[kea] = SECITEM_DupArray(NULL, responses);
michael@0 2236 }
michael@0 2237 return (ss->certStatusArray[kea] || !responses) ? SECSuccess : SECFailure;
michael@0 2238 }
michael@0 2239
michael@0 2240 SECStatus
michael@0 2241 SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID)
michael@0 2242 {
michael@0 2243 sslSocket *ss;
michael@0 2244
michael@0 2245 ss = ssl_FindSocket(fd);
michael@0 2246 if (!ss) {
michael@0 2247 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSockPeerID",
michael@0 2248 SSL_GETPID(), fd));
michael@0 2249 return SECFailure;
michael@0 2250 }
michael@0 2251
michael@0 2252 if (ss->peerID) {
michael@0 2253 PORT_Free(ss->peerID);
michael@0 2254 ss->peerID = NULL;
michael@0 2255 }
michael@0 2256 if (peerID)
michael@0 2257 ss->peerID = PORT_Strdup(peerID);
michael@0 2258 return (ss->peerID || !peerID) ? SECSuccess : SECFailure;
michael@0 2259 }
michael@0 2260
michael@0 2261 #define PR_POLL_RW (PR_POLL_WRITE | PR_POLL_READ)
michael@0 2262
michael@0 2263 static PRInt16 PR_CALLBACK
michael@0 2264 ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
michael@0 2265 {
michael@0 2266 sslSocket *ss;
michael@0 2267 PRInt16 new_flags = how_flags; /* should select on these flags. */
michael@0 2268 PRNetAddr addr;
michael@0 2269
michael@0 2270 *p_out_flags = 0;
michael@0 2271 ss = ssl_GetPrivate(fd);
michael@0 2272 if (!ss) {
michael@0 2273 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_Poll",
michael@0 2274 SSL_GETPID(), fd));
michael@0 2275 return 0; /* don't poll on this socket */
michael@0 2276 }
michael@0 2277
michael@0 2278 if (ss->opt.useSecurity &&
michael@0 2279 ss->handshaking != sslHandshakingUndetermined &&
michael@0 2280 !ss->firstHsDone &&
michael@0 2281 (how_flags & PR_POLL_RW)) {
michael@0 2282 if (!ss->TCPconnected) {
michael@0 2283 ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr));
michael@0 2284 }
michael@0 2285 /* If it's not connected, then presumably the application is polling
michael@0 2286 ** on read or write appropriately, so don't change it.
michael@0 2287 */
michael@0 2288 if (ss->TCPconnected) {
michael@0 2289 if (!ss->handshakeBegun) {
michael@0 2290 /* If the handshake has not begun, poll on read or write
michael@0 2291 ** based on the local application's role in the handshake,
michael@0 2292 ** not based on what the application requested.
michael@0 2293 */
michael@0 2294 new_flags &= ~PR_POLL_RW;
michael@0 2295 if (ss->handshaking == sslHandshakingAsClient) {
michael@0 2296 new_flags |= PR_POLL_WRITE;
michael@0 2297 } else { /* handshaking as server */
michael@0 2298 new_flags |= PR_POLL_READ;
michael@0 2299 }
michael@0 2300 } else
michael@0 2301 /* First handshake is in progress */
michael@0 2302 if (ss->lastWriteBlocked) {
michael@0 2303 if (new_flags & PR_POLL_READ) {
michael@0 2304 /* The caller is waiting for data to be received,
michael@0 2305 ** but the initial handshake is blocked on write, or the
michael@0 2306 ** client's first handshake record has not been written.
michael@0 2307 ** The code should select on write, not read.
michael@0 2308 */
michael@0 2309 new_flags ^= PR_POLL_READ; /* don't select on read. */
michael@0 2310 new_flags |= PR_POLL_WRITE; /* do select on write. */
michael@0 2311 }
michael@0 2312 } else if (new_flags & PR_POLL_WRITE) {
michael@0 2313 /* The caller is trying to write, but the handshake is
michael@0 2314 ** blocked waiting for data to read, and the first
michael@0 2315 ** handshake has been sent. So do NOT to poll on write
michael@0 2316 ** unless we did false start.
michael@0 2317 */
michael@0 2318 if (!(ss->version >= SSL_LIBRARY_VERSION_3_0 &&
michael@0 2319 ss->ssl3.hs.canFalseStart)) {
michael@0 2320 new_flags ^= PR_POLL_WRITE; /* don't select on write. */
michael@0 2321 }
michael@0 2322 new_flags |= PR_POLL_READ; /* do select on read. */
michael@0 2323 }
michael@0 2324 }
michael@0 2325 } else if ((new_flags & PR_POLL_READ) && (SSL_DataPending(fd) > 0)) {
michael@0 2326 *p_out_flags = PR_POLL_READ; /* it's ready already. */
michael@0 2327 return new_flags;
michael@0 2328 } else if ((ss->lastWriteBlocked) && (how_flags & PR_POLL_READ) &&
michael@0 2329 (ss->pendingBuf.len != 0)) { /* write data waiting to be sent */
michael@0 2330 new_flags |= PR_POLL_WRITE; /* also select on write. */
michael@0 2331 }
michael@0 2332
michael@0 2333 if (ss->version >= SSL_LIBRARY_VERSION_3_0 &&
michael@0 2334 ss->ssl3.hs.restartTarget != NULL) {
michael@0 2335 /* Read and write will block until the asynchronous callback completes
michael@0 2336 * (e.g. until SSL_AuthCertificateComplete is called), so don't tell
michael@0 2337 * the caller to poll the socket unless there is pending write data.
michael@0 2338 */
michael@0 2339 if (ss->lastWriteBlocked && ss->pendingBuf.len != 0) {
michael@0 2340 /* Ignore any newly-received data on the socket, but do wait for
michael@0 2341 * the socket to become writable again. Here, it is OK for an error
michael@0 2342 * to be detected, because our logic for sending pending write data
michael@0 2343 * will allow us to report the error to the caller without the risk
michael@0 2344 * of the application spinning.
michael@0 2345 */
michael@0 2346 new_flags &= (PR_POLL_WRITE | PR_POLL_EXCEPT);
michael@0 2347 } else {
michael@0 2348 /* Unfortunately, clearing new_flags will make it impossible for
michael@0 2349 * the application to detect errors that it would otherwise be
michael@0 2350 * able to detect with PR_POLL_EXCEPT, until the asynchronous
michael@0 2351 * callback completes. However, we must clear all the flags to
michael@0 2352 * prevent the application from spinning (alternating between
michael@0 2353 * calling PR_Poll that would return PR_POLL_EXCEPT, and send/recv
michael@0 2354 * which won't actually report the I/O error while we are waiting
michael@0 2355 * for the asynchronous callback to complete).
michael@0 2356 */
michael@0 2357 new_flags = 0;
michael@0 2358 }
michael@0 2359 }
michael@0 2360
michael@0 2361 if (new_flags && (fd->lower->methods->poll != NULL)) {
michael@0 2362 PRInt16 lower_out_flags = 0;
michael@0 2363 PRInt16 lower_new_flags;
michael@0 2364 lower_new_flags = fd->lower->methods->poll(fd->lower, new_flags,
michael@0 2365 &lower_out_flags);
michael@0 2366 if ((lower_new_flags & lower_out_flags) && (how_flags != new_flags)) {
michael@0 2367 PRInt16 out_flags = lower_out_flags & ~PR_POLL_RW;
michael@0 2368 if (lower_out_flags & PR_POLL_READ)
michael@0 2369 out_flags |= PR_POLL_WRITE;
michael@0 2370 if (lower_out_flags & PR_POLL_WRITE)
michael@0 2371 out_flags |= PR_POLL_READ;
michael@0 2372 *p_out_flags = out_flags;
michael@0 2373 new_flags = how_flags;
michael@0 2374 } else {
michael@0 2375 *p_out_flags = lower_out_flags;
michael@0 2376 new_flags = lower_new_flags;
michael@0 2377 }
michael@0 2378 }
michael@0 2379
michael@0 2380 return new_flags;
michael@0 2381 }
michael@0 2382
michael@0 2383 static PRInt32 PR_CALLBACK
michael@0 2384 ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd,
michael@0 2385 const void *headers, PRInt32 hlen,
michael@0 2386 PRTransmitFileFlags flags, PRIntervalTime timeout)
michael@0 2387 {
michael@0 2388 PRSendFileData sfd;
michael@0 2389
michael@0 2390 sfd.fd = fd;
michael@0 2391 sfd.file_offset = 0;
michael@0 2392 sfd.file_nbytes = 0;
michael@0 2393 sfd.header = headers;
michael@0 2394 sfd.hlen = hlen;
michael@0 2395 sfd.trailer = NULL;
michael@0 2396 sfd.tlen = 0;
michael@0 2397
michael@0 2398 return sd->methods->sendfile(sd, &sfd, flags, timeout);
michael@0 2399 }
michael@0 2400
michael@0 2401
michael@0 2402 PRBool
michael@0 2403 ssl_FdIsBlocking(PRFileDesc *fd)
michael@0 2404 {
michael@0 2405 PRSocketOptionData opt;
michael@0 2406 PRStatus status;
michael@0 2407
michael@0 2408 opt.option = PR_SockOpt_Nonblocking;
michael@0 2409 opt.value.non_blocking = PR_FALSE;
michael@0 2410 status = PR_GetSocketOption(fd, &opt);
michael@0 2411 if (status != PR_SUCCESS)
michael@0 2412 return PR_FALSE;
michael@0 2413 return (PRBool)!opt.value.non_blocking;
michael@0 2414 }
michael@0 2415
michael@0 2416 PRBool
michael@0 2417 ssl_SocketIsBlocking(sslSocket *ss)
michael@0 2418 {
michael@0 2419 return ssl_FdIsBlocking(ss->fd);
michael@0 2420 }
michael@0 2421
michael@0 2422 PRInt32 sslFirstBufSize = 8 * 1024;
michael@0 2423 PRInt32 sslCopyLimit = 1024;
michael@0 2424
michael@0 2425 static PRInt32 PR_CALLBACK
michael@0 2426 ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors,
michael@0 2427 PRIntervalTime timeout)
michael@0 2428 {
michael@0 2429 PRInt32 i;
michael@0 2430 PRInt32 bufLen;
michael@0 2431 PRInt32 left;
michael@0 2432 PRInt32 rv;
michael@0 2433 PRInt32 sent = 0;
michael@0 2434 const PRInt32 first_len = sslFirstBufSize;
michael@0 2435 const PRInt32 limit = sslCopyLimit;
michael@0 2436 PRBool blocking;
michael@0 2437 PRIOVec myIov = { 0, 0 };
michael@0 2438 char buf[MAX_FRAGMENT_LENGTH];
michael@0 2439
michael@0 2440 if (vectors < 0) {
michael@0 2441 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
michael@0 2442 return -1;
michael@0 2443 }
michael@0 2444 if (vectors > PR_MAX_IOVECTOR_SIZE) {
michael@0 2445 PORT_SetError(PR_BUFFER_OVERFLOW_ERROR);
michael@0 2446 return -1;
michael@0 2447 }
michael@0 2448 for (i = 0; i < vectors; i++) {
michael@0 2449 if (iov[i].iov_len < 0) {
michael@0 2450 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
michael@0 2451 return -1;
michael@0 2452 }
michael@0 2453 }
michael@0 2454 blocking = ssl_FdIsBlocking(fd);
michael@0 2455
michael@0 2456 #define K16 sizeof(buf)
michael@0 2457 #define KILL_VECTORS while (vectors && !iov->iov_len) { ++iov; --vectors; }
michael@0 2458 #define GET_VECTOR do { myIov = *iov++; --vectors; KILL_VECTORS } while (0)
michael@0 2459 #define HANDLE_ERR(rv, len) \
michael@0 2460 if (rv != len) { \
michael@0 2461 if (rv < 0) { \
michael@0 2462 if (!blocking \
michael@0 2463 && (PR_GetError() == PR_WOULD_BLOCK_ERROR) \
michael@0 2464 && (sent > 0)) { \
michael@0 2465 return sent; \
michael@0 2466 } else { \
michael@0 2467 return -1; \
michael@0 2468 } \
michael@0 2469 } \
michael@0 2470 /* Only a nonblocking socket can have partial sends */ \
michael@0 2471 PR_ASSERT(!blocking); \
michael@0 2472 return sent + rv; \
michael@0 2473 }
michael@0 2474 #define SEND(bfr, len) \
michael@0 2475 do { \
michael@0 2476 rv = ssl_Send(fd, bfr, len, 0, timeout); \
michael@0 2477 HANDLE_ERR(rv, len) \
michael@0 2478 sent += len; \
michael@0 2479 } while (0)
michael@0 2480
michael@0 2481 /* Make sure the first write is at least 8 KB, if possible. */
michael@0 2482 KILL_VECTORS
michael@0 2483 if (!vectors)
michael@0 2484 return ssl_Send(fd, 0, 0, 0, timeout);
michael@0 2485 GET_VECTOR;
michael@0 2486 if (!vectors) {
michael@0 2487 return ssl_Send(fd, myIov.iov_base, myIov.iov_len, 0, timeout);
michael@0 2488 }
michael@0 2489 if (myIov.iov_len < first_len) {
michael@0 2490 PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
michael@0 2491 bufLen = myIov.iov_len;
michael@0 2492 left = first_len - bufLen;
michael@0 2493 while (vectors && left) {
michael@0 2494 int toCopy;
michael@0 2495 GET_VECTOR;
michael@0 2496 toCopy = PR_MIN(left, myIov.iov_len);
michael@0 2497 PORT_Memcpy(buf + bufLen, myIov.iov_base, toCopy);
michael@0 2498 bufLen += toCopy;
michael@0 2499 left -= toCopy;
michael@0 2500 myIov.iov_base += toCopy;
michael@0 2501 myIov.iov_len -= toCopy;
michael@0 2502 }
michael@0 2503 SEND( buf, bufLen );
michael@0 2504 }
michael@0 2505
michael@0 2506 while (vectors || myIov.iov_len) {
michael@0 2507 PRInt32 addLen;
michael@0 2508 if (!myIov.iov_len) {
michael@0 2509 GET_VECTOR;
michael@0 2510 }
michael@0 2511 while (myIov.iov_len >= K16) {
michael@0 2512 SEND(myIov.iov_base, K16);
michael@0 2513 myIov.iov_base += K16;
michael@0 2514 myIov.iov_len -= K16;
michael@0 2515 }
michael@0 2516 if (!myIov.iov_len)
michael@0 2517 continue;
michael@0 2518
michael@0 2519 if (!vectors || myIov.iov_len > limit) {
michael@0 2520 addLen = 0;
michael@0 2521 } else if ((addLen = iov->iov_len % K16) + myIov.iov_len <= limit) {
michael@0 2522 /* Addlen is already computed. */;
michael@0 2523 } else if (vectors > 1 &&
michael@0 2524 iov[1].iov_len % K16 + addLen + myIov.iov_len <= 2 * limit) {
michael@0 2525 addLen = limit - myIov.iov_len;
michael@0 2526 } else
michael@0 2527 addLen = 0;
michael@0 2528
michael@0 2529 if (!addLen) {
michael@0 2530 SEND( myIov.iov_base, myIov.iov_len );
michael@0 2531 myIov.iov_len = 0;
michael@0 2532 continue;
michael@0 2533 }
michael@0 2534 PORT_Memcpy(buf, myIov.iov_base, myIov.iov_len);
michael@0 2535 bufLen = myIov.iov_len;
michael@0 2536 do {
michael@0 2537 GET_VECTOR;
michael@0 2538 PORT_Memcpy(buf + bufLen, myIov.iov_base, addLen);
michael@0 2539 myIov.iov_base += addLen;
michael@0 2540 myIov.iov_len -= addLen;
michael@0 2541 bufLen += addLen;
michael@0 2542
michael@0 2543 left = PR_MIN( limit, K16 - bufLen);
michael@0 2544 if (!vectors /* no more left */
michael@0 2545 || myIov.iov_len > 0 /* we didn't use that one all up */
michael@0 2546 || bufLen >= K16 /* it's full. */
michael@0 2547 ) {
michael@0 2548 addLen = 0;
michael@0 2549 } else if ((addLen = iov->iov_len % K16) <= left) {
michael@0 2550 /* Addlen is already computed. */;
michael@0 2551 } else if (vectors > 1 &&
michael@0 2552 iov[1].iov_len % K16 + addLen <= left + limit) {
michael@0 2553 addLen = left;
michael@0 2554 } else
michael@0 2555 addLen = 0;
michael@0 2556
michael@0 2557 } while (addLen);
michael@0 2558 SEND( buf, bufLen );
michael@0 2559 }
michael@0 2560 return sent;
michael@0 2561 }
michael@0 2562
michael@0 2563 /*
michael@0 2564 * These functions aren't implemented.
michael@0 2565 */
michael@0 2566
michael@0 2567 static PRInt32 PR_CALLBACK
michael@0 2568 ssl_Available(PRFileDesc *fd)
michael@0 2569 {
michael@0 2570 PORT_Assert(0);
michael@0 2571 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2572 return SECFailure;
michael@0 2573 }
michael@0 2574
michael@0 2575 static PRInt64 PR_CALLBACK
michael@0 2576 ssl_Available64(PRFileDesc *fd)
michael@0 2577 {
michael@0 2578 PRInt64 res;
michael@0 2579
michael@0 2580 PORT_Assert(0);
michael@0 2581 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2582 LL_I2L(res, -1L);
michael@0 2583 return res;
michael@0 2584 }
michael@0 2585
michael@0 2586 static PRStatus PR_CALLBACK
michael@0 2587 ssl_FSync(PRFileDesc *fd)
michael@0 2588 {
michael@0 2589 PORT_Assert(0);
michael@0 2590 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2591 return PR_FAILURE;
michael@0 2592 }
michael@0 2593
michael@0 2594 static PRInt32 PR_CALLBACK
michael@0 2595 ssl_Seek(PRFileDesc *fd, PRInt32 offset, PRSeekWhence how) {
michael@0 2596 PORT_Assert(0);
michael@0 2597 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2598 return SECFailure;
michael@0 2599 }
michael@0 2600
michael@0 2601 static PRInt64 PR_CALLBACK
michael@0 2602 ssl_Seek64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence how) {
michael@0 2603 PRInt64 res;
michael@0 2604
michael@0 2605 PORT_Assert(0);
michael@0 2606 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2607 LL_I2L(res, -1L);
michael@0 2608 return res;
michael@0 2609 }
michael@0 2610
michael@0 2611 static PRStatus PR_CALLBACK
michael@0 2612 ssl_FileInfo(PRFileDesc *fd, PRFileInfo *info)
michael@0 2613 {
michael@0 2614 PORT_Assert(0);
michael@0 2615 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2616 return PR_FAILURE;
michael@0 2617 }
michael@0 2618
michael@0 2619 static PRStatus PR_CALLBACK
michael@0 2620 ssl_FileInfo64(PRFileDesc *fd, PRFileInfo64 *info)
michael@0 2621 {
michael@0 2622 PORT_Assert(0);
michael@0 2623 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2624 return PR_FAILURE;
michael@0 2625 }
michael@0 2626
michael@0 2627 static PRInt32 PR_CALLBACK
michael@0 2628 ssl_RecvFrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
michael@0 2629 PRNetAddr *addr, PRIntervalTime timeout)
michael@0 2630 {
michael@0 2631 PORT_Assert(0);
michael@0 2632 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2633 return SECFailure;
michael@0 2634 }
michael@0 2635
michael@0 2636 static PRInt32 PR_CALLBACK
michael@0 2637 ssl_SendTo(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
michael@0 2638 const PRNetAddr *addr, PRIntervalTime timeout)
michael@0 2639 {
michael@0 2640 PORT_Assert(0);
michael@0 2641 PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
michael@0 2642 return SECFailure;
michael@0 2643 }
michael@0 2644
michael@0 2645 static const PRIOMethods ssl_methods = {
michael@0 2646 PR_DESC_LAYERED,
michael@0 2647 ssl_Close, /* close */
michael@0 2648 ssl_Read, /* read */
michael@0 2649 ssl_Write, /* write */
michael@0 2650 ssl_Available, /* available */
michael@0 2651 ssl_Available64, /* available64 */
michael@0 2652 ssl_FSync, /* fsync */
michael@0 2653 ssl_Seek, /* seek */
michael@0 2654 ssl_Seek64, /* seek64 */
michael@0 2655 ssl_FileInfo, /* fileInfo */
michael@0 2656 ssl_FileInfo64, /* fileInfo64 */
michael@0 2657 ssl_WriteV, /* writev */
michael@0 2658 ssl_Connect, /* connect */
michael@0 2659 ssl_Accept, /* accept */
michael@0 2660 ssl_Bind, /* bind */
michael@0 2661 ssl_Listen, /* listen */
michael@0 2662 ssl_Shutdown, /* shutdown */
michael@0 2663 ssl_Recv, /* recv */
michael@0 2664 ssl_Send, /* send */
michael@0 2665 ssl_RecvFrom, /* recvfrom */
michael@0 2666 ssl_SendTo, /* sendto */
michael@0 2667 ssl_Poll, /* poll */
michael@0 2668 PR_EmulateAcceptRead, /* acceptread */
michael@0 2669 ssl_TransmitFile, /* transmitfile */
michael@0 2670 ssl_GetSockName, /* getsockname */
michael@0 2671 ssl_GetPeerName, /* getpeername */
michael@0 2672 NULL, /* getsockopt OBSOLETE */
michael@0 2673 NULL, /* setsockopt OBSOLETE */
michael@0 2674 NULL, /* getsocketoption */
michael@0 2675 NULL, /* setsocketoption */
michael@0 2676 PR_EmulateSendFile, /* Send a (partial) file with header/trailer*/
michael@0 2677 NULL, /* reserved for future use */
michael@0 2678 NULL, /* reserved for future use */
michael@0 2679 NULL, /* reserved for future use */
michael@0 2680 NULL, /* reserved for future use */
michael@0 2681 NULL /* reserved for future use */
michael@0 2682 };
michael@0 2683
michael@0 2684
michael@0 2685 static PRIOMethods combined_methods;
michael@0 2686
michael@0 2687 static void
michael@0 2688 ssl_SetupIOMethods(void)
michael@0 2689 {
michael@0 2690 PRIOMethods *new_methods = &combined_methods;
michael@0 2691 const PRIOMethods *nspr_methods = PR_GetDefaultIOMethods();
michael@0 2692 const PRIOMethods *my_methods = &ssl_methods;
michael@0 2693
michael@0 2694 *new_methods = *nspr_methods;
michael@0 2695
michael@0 2696 new_methods->file_type = my_methods->file_type;
michael@0 2697 new_methods->close = my_methods->close;
michael@0 2698 new_methods->read = my_methods->read;
michael@0 2699 new_methods->write = my_methods->write;
michael@0 2700 new_methods->available = my_methods->available;
michael@0 2701 new_methods->available64 = my_methods->available64;
michael@0 2702 new_methods->fsync = my_methods->fsync;
michael@0 2703 new_methods->seek = my_methods->seek;
michael@0 2704 new_methods->seek64 = my_methods->seek64;
michael@0 2705 new_methods->fileInfo = my_methods->fileInfo;
michael@0 2706 new_methods->fileInfo64 = my_methods->fileInfo64;
michael@0 2707 new_methods->writev = my_methods->writev;
michael@0 2708 new_methods->connect = my_methods->connect;
michael@0 2709 new_methods->accept = my_methods->accept;
michael@0 2710 new_methods->bind = my_methods->bind;
michael@0 2711 new_methods->listen = my_methods->listen;
michael@0 2712 new_methods->shutdown = my_methods->shutdown;
michael@0 2713 new_methods->recv = my_methods->recv;
michael@0 2714 new_methods->send = my_methods->send;
michael@0 2715 new_methods->recvfrom = my_methods->recvfrom;
michael@0 2716 new_methods->sendto = my_methods->sendto;
michael@0 2717 new_methods->poll = my_methods->poll;
michael@0 2718 new_methods->acceptread = my_methods->acceptread;
michael@0 2719 new_methods->transmitfile = my_methods->transmitfile;
michael@0 2720 new_methods->getsockname = my_methods->getsockname;
michael@0 2721 new_methods->getpeername = my_methods->getpeername;
michael@0 2722 /* new_methods->getsocketoption = my_methods->getsocketoption; */
michael@0 2723 /* new_methods->setsocketoption = my_methods->setsocketoption; */
michael@0 2724 new_methods->sendfile = my_methods->sendfile;
michael@0 2725
michael@0 2726 }
michael@0 2727
michael@0 2728 static PRCallOnceType initIoLayerOnce;
michael@0 2729
michael@0 2730 static PRStatus
michael@0 2731 ssl_InitIOLayer(void)
michael@0 2732 {
michael@0 2733 ssl_layer_id = PR_GetUniqueIdentity("SSL");
michael@0 2734 ssl_SetupIOMethods();
michael@0 2735 ssl_inited = PR_TRUE;
michael@0 2736 return PR_SUCCESS;
michael@0 2737 }
michael@0 2738
michael@0 2739 static PRStatus
michael@0 2740 ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
michael@0 2741 {
michael@0 2742 PRFileDesc *layer = NULL;
michael@0 2743 PRStatus status;
michael@0 2744
michael@0 2745 if (!ssl_inited) {
michael@0 2746 status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
michael@0 2747 if (status != PR_SUCCESS)
michael@0 2748 goto loser;
michael@0 2749 }
michael@0 2750
michael@0 2751 if (ns == NULL)
michael@0 2752 goto loser;
michael@0 2753
michael@0 2754 layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
michael@0 2755 if (layer == NULL)
michael@0 2756 goto loser;
michael@0 2757 layer->secret = (PRFilePrivate *)ns;
michael@0 2758
michael@0 2759 /* Here, "stack" points to the PRFileDesc on the top of the stack.
michael@0 2760 ** "layer" points to a new FD that is to be inserted into the stack.
michael@0 2761 ** If layer is being pushed onto the top of the stack, then
michael@0 2762 ** PR_PushIOLayer switches the contents of stack and layer, and then
michael@0 2763 ** puts stack on top of layer, so that after it is done, the top of
michael@0 2764 ** stack is the same "stack" as it was before, and layer is now the
michael@0 2765 ** FD for the former top of stack.
michael@0 2766 ** After this call, stack always points to the top PRFD on the stack.
michael@0 2767 ** If this function fails, the contents of stack and layer are as
michael@0 2768 ** they were before the call.
michael@0 2769 */
michael@0 2770 status = PR_PushIOLayer(stack, id, layer);
michael@0 2771 if (status != PR_SUCCESS)
michael@0 2772 goto loser;
michael@0 2773
michael@0 2774 ns->fd = (id == PR_TOP_IO_LAYER) ? stack : layer;
michael@0 2775 return PR_SUCCESS;
michael@0 2776
michael@0 2777 loser:
michael@0 2778 if (layer) {
michael@0 2779 layer->dtor(layer); /* free layer */
michael@0 2780 }
michael@0 2781 return PR_FAILURE;
michael@0 2782 }
michael@0 2783
michael@0 2784 /* if this fails, caller must destroy socket. */
michael@0 2785 static SECStatus
michael@0 2786 ssl_MakeLocks(sslSocket *ss)
michael@0 2787 {
michael@0 2788 ss->firstHandshakeLock = PZ_NewMonitor(nssILockSSL);
michael@0 2789 if (!ss->firstHandshakeLock)
michael@0 2790 goto loser;
michael@0 2791 ss->ssl3HandshakeLock = PZ_NewMonitor(nssILockSSL);
michael@0 2792 if (!ss->ssl3HandshakeLock)
michael@0 2793 goto loser;
michael@0 2794 ss->specLock = NSSRWLock_New(SSL_LOCK_RANK_SPEC, NULL);
michael@0 2795 if (!ss->specLock)
michael@0 2796 goto loser;
michael@0 2797 ss->recvBufLock = PZ_NewMonitor(nssILockSSL);
michael@0 2798 if (!ss->recvBufLock)
michael@0 2799 goto loser;
michael@0 2800 ss->xmitBufLock = PZ_NewMonitor(nssILockSSL);
michael@0 2801 if (!ss->xmitBufLock)
michael@0 2802 goto loser;
michael@0 2803 ss->writerThread = NULL;
michael@0 2804 if (ssl_lock_readers) {
michael@0 2805 ss->recvLock = PZ_NewLock(nssILockSSL);
michael@0 2806 if (!ss->recvLock)
michael@0 2807 goto loser;
michael@0 2808 ss->sendLock = PZ_NewLock(nssILockSSL);
michael@0 2809 if (!ss->sendLock)
michael@0 2810 goto loser;
michael@0 2811 }
michael@0 2812 return SECSuccess;
michael@0 2813 loser:
michael@0 2814 ssl_DestroyLocks(ss);
michael@0 2815 return SECFailure;
michael@0 2816 }
michael@0 2817
michael@0 2818 #if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_BEOS)
michael@0 2819 #define NSS_HAVE_GETENV 1
michael@0 2820 #endif
michael@0 2821
michael@0 2822 #define LOWER(x) (x | 0x20) /* cheap ToLower function ignores LOCALE */
michael@0 2823
michael@0 2824 static void
michael@0 2825 ssl_SetDefaultsFromEnvironment(void)
michael@0 2826 {
michael@0 2827 #if defined( NSS_HAVE_GETENV )
michael@0 2828 static int firsttime = 1;
michael@0 2829
michael@0 2830 if (firsttime) {
michael@0 2831 char * ev;
michael@0 2832 firsttime = 0;
michael@0 2833 #ifdef DEBUG
michael@0 2834 ev = getenv("SSLDEBUGFILE");
michael@0 2835 if (ev && ev[0]) {
michael@0 2836 ssl_trace_iob = fopen(ev, "w");
michael@0 2837 }
michael@0 2838 if (!ssl_trace_iob) {
michael@0 2839 ssl_trace_iob = stderr;
michael@0 2840 }
michael@0 2841 #ifdef TRACE
michael@0 2842 ev = getenv("SSLTRACE");
michael@0 2843 if (ev && ev[0]) {
michael@0 2844 ssl_trace = atoi(ev);
michael@0 2845 SSL_TRACE(("SSL: tracing set to %d", ssl_trace));
michael@0 2846 }
michael@0 2847 #endif /* TRACE */
michael@0 2848 ev = getenv("SSLDEBUG");
michael@0 2849 if (ev && ev[0]) {
michael@0 2850 ssl_debug = atoi(ev);
michael@0 2851 SSL_TRACE(("SSL: debugging set to %d", ssl_debug));
michael@0 2852 }
michael@0 2853 #endif /* DEBUG */
michael@0 2854 ev = getenv("SSLKEYLOGFILE");
michael@0 2855 if (ev && ev[0]) {
michael@0 2856 ssl_keylog_iob = fopen(ev, "a");
michael@0 2857 if (!ssl_keylog_iob) {
michael@0 2858 SSL_TRACE(("SSL: failed to open key log file"));
michael@0 2859 } else {
michael@0 2860 if (ftell(ssl_keylog_iob) == 0) {
michael@0 2861 fputs("# SSL/TLS secrets log file, generated by NSS\n",
michael@0 2862 ssl_keylog_iob);
michael@0 2863 }
michael@0 2864 SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
michael@0 2865 }
michael@0 2866 }
michael@0 2867 #ifndef NO_PKCS11_BYPASS
michael@0 2868 ev = getenv("SSLBYPASS");
michael@0 2869 if (ev && ev[0]) {
michael@0 2870 ssl_defaults.bypassPKCS11 = (ev[0] == '1');
michael@0 2871 SSL_TRACE(("SSL: bypass default set to %d", \
michael@0 2872 ssl_defaults.bypassPKCS11));
michael@0 2873 }
michael@0 2874 #endif /* NO_PKCS11_BYPASS */
michael@0 2875 ev = getenv("SSLFORCELOCKS");
michael@0 2876 if (ev && ev[0] == '1') {
michael@0 2877 ssl_force_locks = PR_TRUE;
michael@0 2878 ssl_defaults.noLocks = 0;
michael@0 2879 strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED. ");
michael@0 2880 SSL_TRACE(("SSL: force_locks set to %d", ssl_force_locks));
michael@0 2881 }
michael@0 2882 ev = getenv("NSS_SSL_ENABLE_RENEGOTIATION");
michael@0 2883 if (ev) {
michael@0 2884 if (ev[0] == '1' || LOWER(ev[0]) == 'u')
michael@0 2885 ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_UNRESTRICTED;
michael@0 2886 else if (ev[0] == '0' || LOWER(ev[0]) == 'n')
michael@0 2887 ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_NEVER;
michael@0 2888 else if (ev[0] == '2' || LOWER(ev[0]) == 'r')
michael@0 2889 ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_REQUIRES_XTN;
michael@0 2890 else if (ev[0] == '3' || LOWER(ev[0]) == 't')
michael@0 2891 ssl_defaults.enableRenegotiation = SSL_RENEGOTIATE_TRANSITIONAL;
michael@0 2892 SSL_TRACE(("SSL: enableRenegotiation set to %d",
michael@0 2893 ssl_defaults.enableRenegotiation));
michael@0 2894 }
michael@0 2895 ev = getenv("NSS_SSL_REQUIRE_SAFE_NEGOTIATION");
michael@0 2896 if (ev && ev[0] == '1') {
michael@0 2897 ssl_defaults.requireSafeNegotiation = PR_TRUE;
michael@0 2898 SSL_TRACE(("SSL: requireSafeNegotiation set to %d",
michael@0 2899 PR_TRUE));
michael@0 2900 }
michael@0 2901 ev = getenv("NSS_SSL_CBC_RANDOM_IV");
michael@0 2902 if (ev && ev[0] == '0') {
michael@0 2903 ssl_defaults.cbcRandomIV = PR_FALSE;
michael@0 2904 SSL_TRACE(("SSL: cbcRandomIV set to 0"));
michael@0 2905 }
michael@0 2906 }
michael@0 2907 #endif /* NSS_HAVE_GETENV */
michael@0 2908 }
michael@0 2909
michael@0 2910 /*
michael@0 2911 ** Create a newsocket structure for a file descriptor.
michael@0 2912 */
michael@0 2913 static sslSocket *
michael@0 2914 ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
michael@0 2915 {
michael@0 2916 sslSocket *ss;
michael@0 2917
michael@0 2918 ssl_SetDefaultsFromEnvironment();
michael@0 2919
michael@0 2920 if (ssl_force_locks)
michael@0 2921 makeLocks = PR_TRUE;
michael@0 2922
michael@0 2923 /* Make a new socket and get it ready */
michael@0 2924 ss = (sslSocket*) PORT_ZAlloc(sizeof(sslSocket));
michael@0 2925 if (ss) {
michael@0 2926 /* This should be of type SSLKEAType, but CC on IRIX
michael@0 2927 * complains during the for loop.
michael@0 2928 */
michael@0 2929 int i;
michael@0 2930 SECStatus status;
michael@0 2931
michael@0 2932 ss->opt = ssl_defaults;
michael@0 2933 ss->opt.useSocks = PR_FALSE;
michael@0 2934 ss->opt.noLocks = !makeLocks;
michael@0 2935 ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
michael@0 2936 ss->protocolVariant = protocolVariant;
michael@0 2937
michael@0 2938 ss->peerID = NULL;
michael@0 2939 ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2940 ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2941 ss->cTimeout = PR_INTERVAL_NO_TIMEOUT;
michael@0 2942 ss->cipherSpecs = NULL;
michael@0 2943 ss->sizeCipherSpecs = 0; /* produced lazily */
michael@0 2944 ss->preferredCipher = NULL;
michael@0 2945 ss->url = NULL;
michael@0 2946
michael@0 2947 for (i=kt_null; i < kt_kea_size; i++) {
michael@0 2948 sslServerCerts * sc = ss->serverCerts + i;
michael@0 2949 sc->serverCert = NULL;
michael@0 2950 sc->serverCertChain = NULL;
michael@0 2951 sc->serverKeyPair = NULL;
michael@0 2952 sc->serverKeyBits = 0;
michael@0 2953 ss->certStatusArray[i] = NULL;
michael@0 2954 }
michael@0 2955 ss->stepDownKeyPair = NULL;
michael@0 2956 ss->dbHandle = CERT_GetDefaultCertDB();
michael@0 2957
michael@0 2958 /* Provide default implementation of hooks */
michael@0 2959 ss->authCertificate = SSL_AuthCertificate;
michael@0 2960 ss->authCertificateArg = (void *)ss->dbHandle;
michael@0 2961 ss->sniSocketConfig = NULL;
michael@0 2962 ss->sniSocketConfigArg = NULL;
michael@0 2963 ss->getClientAuthData = NULL;
michael@0 2964 ss->handleBadCert = NULL;
michael@0 2965 ss->badCertArg = NULL;
michael@0 2966 ss->pkcs11PinArg = NULL;
michael@0 2967 ss->ephemeralECDHKeyPair = NULL;
michael@0 2968
michael@0 2969 ssl_ChooseOps(ss);
michael@0 2970 ssl2_InitSocketPolicy(ss);
michael@0 2971 ssl3_InitSocketPolicy(ss);
michael@0 2972 PR_INIT_CLIST(&ss->ssl3.hs.lastMessageFlight);
michael@0 2973
michael@0 2974 if (makeLocks) {
michael@0 2975 status = ssl_MakeLocks(ss);
michael@0 2976 if (status != SECSuccess)
michael@0 2977 goto loser;
michael@0 2978 }
michael@0 2979 status = ssl_CreateSecurityInfo(ss);
michael@0 2980 if (status != SECSuccess)
michael@0 2981 goto loser;
michael@0 2982 status = ssl_InitGather(&ss->gs);
michael@0 2983 if (status != SECSuccess) {
michael@0 2984 loser:
michael@0 2985 ssl_DestroySocketContents(ss);
michael@0 2986 ssl_DestroyLocks(ss);
michael@0 2987 PORT_Free(ss);
michael@0 2988 ss = NULL;
michael@0 2989 }
michael@0 2990 }
michael@0 2991 return ss;
michael@0 2992 }

mercurial