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