1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ssl/sslsecur.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1591 @@ 1.4 +/* 1.5 + * Various SSL functions. 1.6 + * 1.7 + * This Source Code Form is subject to the terms of the Mozilla Public 1.8 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.9 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.10 +#include "cert.h" 1.11 +#include "secitem.h" 1.12 +#include "keyhi.h" 1.13 +#include "ssl.h" 1.14 +#include "sslimpl.h" 1.15 +#include "sslproto.h" 1.16 +#include "secoid.h" /* for SECOID_GetALgorithmTag */ 1.17 +#include "pk11func.h" /* for PK11_GenerateRandom */ 1.18 +#include "nss.h" /* for NSS_RegisterShutdown */ 1.19 +#include "prinit.h" /* for PR_CallOnceWithArg */ 1.20 + 1.21 +#define MAX_BLOCK_CYPHER_SIZE 32 1.22 + 1.23 +#define TEST_FOR_FAILURE /* reminder */ 1.24 +#define SET_ERROR_CODE /* reminder */ 1.25 + 1.26 +/* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock. 1.27 + * 1.28 + * Currently, the list of functions called through ss->handshake is: 1.29 + * 1.30 + * In sslsocks.c: 1.31 + * SocksGatherRecord 1.32 + * SocksHandleReply 1.33 + * SocksStartGather 1.34 + * 1.35 + * In sslcon.c: 1.36 + * ssl_GatherRecord1stHandshake 1.37 + * ssl2_HandleClientSessionKeyMessage 1.38 + * ssl2_HandleMessage 1.39 + * ssl2_HandleVerifyMessage 1.40 + * ssl2_BeginClientHandshake 1.41 + * ssl2_BeginServerHandshake 1.42 + * ssl2_HandleClientHelloMessage 1.43 + * ssl2_HandleServerHelloMessage 1.44 + * 1.45 + * The ss->handshake function returns SECWouldBlock under these conditions: 1.46 + * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in 1.47 + * the beginning of an SSL v3 hello message and returned SECWouldBlock 1.48 + * to switch to SSL v3 handshake processing. 1.49 + * 1.50 + * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming 1.51 + * v2 client hello msg, and called ssl3_HandleV2ClientHello which 1.52 + * returned SECWouldBlock. 1.53 + * 1.54 + * 3. SECWouldBlock was returned by one of the callback functions, via 1.55 + * one of these paths: 1.56 + * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> 1.57 + * ss->getClientAuthData() 1.58 + * 1.59 + * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert() 1.60 + * 1.61 + * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> 1.62 + * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> 1.63 + * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() -> 1.64 + * ss->handleBadCert() 1.65 + * 1.66 + * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> 1.67 + * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> 1.68 + * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() -> 1.69 + * ss->getClientAuthData() 1.70 + * 1.71 + * Called from: SSL_ForceHandshake (below), 1.72 + * ssl_SecureRecv (below) and 1.73 + * ssl_SecureSend (below) 1.74 + * from: WaitForResponse in sslsocks.c 1.75 + * ssl_SocksRecv in sslsocks.c 1.76 + * ssl_SocksSend in sslsocks.c 1.77 + * 1.78 + * Caller must hold the (write) handshakeLock. 1.79 + */ 1.80 +int 1.81 +ssl_Do1stHandshake(sslSocket *ss) 1.82 +{ 1.83 + int rv = SECSuccess; 1.84 + int loopCount = 0; 1.85 + 1.86 + do { 1.87 + PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.88 + PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); 1.89 + PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); 1.90 + PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); 1.91 + 1.92 + if (ss->handshake == 0) { 1.93 + /* Previous handshake finished. Switch to next one */ 1.94 + ss->handshake = ss->nextHandshake; 1.95 + ss->nextHandshake = 0; 1.96 + } 1.97 + if (ss->handshake == 0) { 1.98 + /* Previous handshake finished. Switch to security handshake */ 1.99 + ss->handshake = ss->securityHandshake; 1.100 + ss->securityHandshake = 0; 1.101 + } 1.102 + if (ss->handshake == 0) { 1.103 + /* for v3 this is done in ssl3_FinishHandshake */ 1.104 + if (!ss->firstHsDone && ss->version < SSL_LIBRARY_VERSION_3_0) { 1.105 + ssl_GetRecvBufLock(ss); 1.106 + ss->gs.recordLen = 0; 1.107 + ssl_FinishHandshake(ss); 1.108 + ssl_ReleaseRecvBufLock(ss); 1.109 + } 1.110 + break; 1.111 + } 1.112 + rv = (*ss->handshake)(ss); 1.113 + ++loopCount; 1.114 + /* This code must continue to loop on SECWouldBlock, 1.115 + * or any positive value. See XXX_1 comments. 1.116 + */ 1.117 + } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */ 1.118 + 1.119 + PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); 1.120 + PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); 1.121 + PORT_Assert(ss->opt.noLocks || !ssl_HaveSSL3HandshakeLock(ss)); 1.122 + 1.123 + if (rv == SECWouldBlock) { 1.124 + PORT_SetError(PR_WOULD_BLOCK_ERROR); 1.125 + rv = SECFailure; 1.126 + } 1.127 + return rv; 1.128 +} 1.129 + 1.130 +void 1.131 +ssl_FinishHandshake(sslSocket *ss) 1.132 +{ 1.133 + PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 1.134 + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 1.135 + 1.136 + SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", SSL_GETPID(), ss->fd)); 1.137 + 1.138 + ss->firstHsDone = PR_TRUE; 1.139 + ss->enoughFirstHsDone = PR_TRUE; 1.140 + ss->gs.writeOffset = 0; 1.141 + ss->gs.readOffset = 0; 1.142 + 1.143 + if (ss->handshakeCallback) { 1.144 + (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); 1.145 + } 1.146 +} 1.147 + 1.148 +/* 1.149 + * Handshake function that blocks. Used to force a 1.150 + * retry on a connection on the next read/write. 1.151 + */ 1.152 +static SECStatus 1.153 +ssl3_AlwaysBlock(sslSocket *ss) 1.154 +{ 1.155 + PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */ 1.156 + return SECWouldBlock; 1.157 +} 1.158 + 1.159 +/* 1.160 + * set the initial handshake state machine to block 1.161 + */ 1.162 +void 1.163 +ssl3_SetAlwaysBlock(sslSocket *ss) 1.164 +{ 1.165 + if (!ss->firstHsDone) { 1.166 + ss->handshake = ssl3_AlwaysBlock; 1.167 + ss->nextHandshake = 0; 1.168 + } 1.169 +} 1.170 + 1.171 +static SECStatus 1.172 +ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout) 1.173 +{ 1.174 + sslSocket *ss; 1.175 + 1.176 + ss = ssl_FindSocket(fd); 1.177 + if (!ss) { 1.178 + SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd)); 1.179 + return SECFailure; 1.180 + } 1.181 + SSL_LOCK_READER(ss); 1.182 + ss->rTimeout = timeout; 1.183 + if (ss->opt.fdx) { 1.184 + SSL_LOCK_WRITER(ss); 1.185 + } 1.186 + ss->wTimeout = timeout; 1.187 + if (ss->opt.fdx) { 1.188 + SSL_UNLOCK_WRITER(ss); 1.189 + } 1.190 + SSL_UNLOCK_READER(ss); 1.191 + return SECSuccess; 1.192 +} 1.193 + 1.194 +/* Acquires and releases HandshakeLock. 1.195 +*/ 1.196 +SECStatus 1.197 +SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) 1.198 +{ 1.199 + sslSocket *ss; 1.200 + SECStatus status; 1.201 + PRNetAddr addr; 1.202 + 1.203 + ss = ssl_FindSocket(s); 1.204 + if (!ss) { 1.205 + SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s)); 1.206 + return SECFailure; 1.207 + } 1.208 + 1.209 + /* Don't waste my time */ 1.210 + if (!ss->opt.useSecurity) 1.211 + return SECSuccess; 1.212 + 1.213 + SSL_LOCK_READER(ss); 1.214 + SSL_LOCK_WRITER(ss); 1.215 + 1.216 + /* Reset handshake state */ 1.217 + ssl_Get1stHandshakeLock(ss); 1.218 + 1.219 + ss->firstHsDone = PR_FALSE; 1.220 + ss->enoughFirstHsDone = PR_FALSE; 1.221 + if ( asServer ) { 1.222 + ss->handshake = ssl2_BeginServerHandshake; 1.223 + ss->handshaking = sslHandshakingAsServer; 1.224 + } else { 1.225 + ss->handshake = ssl2_BeginClientHandshake; 1.226 + ss->handshaking = sslHandshakingAsClient; 1.227 + } 1.228 + ss->nextHandshake = 0; 1.229 + ss->securityHandshake = 0; 1.230 + 1.231 + ssl_GetRecvBufLock(ss); 1.232 + status = ssl_InitGather(&ss->gs); 1.233 + ssl_ReleaseRecvBufLock(ss); 1.234 + 1.235 + ssl_GetSSL3HandshakeLock(ss); 1.236 + ss->ssl3.hs.canFalseStart = PR_FALSE; 1.237 + ss->ssl3.hs.restartTarget = NULL; 1.238 + 1.239 + /* 1.240 + ** Blow away old security state and get a fresh setup. 1.241 + */ 1.242 + ssl_GetXmitBufLock(ss); 1.243 + ssl_ResetSecurityInfo(&ss->sec, PR_TRUE); 1.244 + status = ssl_CreateSecurityInfo(ss); 1.245 + ssl_ReleaseXmitBufLock(ss); 1.246 + 1.247 + ssl_ReleaseSSL3HandshakeLock(ss); 1.248 + ssl_Release1stHandshakeLock(ss); 1.249 + 1.250 + if (!ss->TCPconnected) 1.251 + ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); 1.252 + 1.253 + SSL_UNLOCK_WRITER(ss); 1.254 + SSL_UNLOCK_READER(ss); 1.255 + 1.256 + return status; 1.257 +} 1.258 + 1.259 +/* For SSLv2, does nothing but return an error. 1.260 +** For SSLv3, flushes SID cache entry (if requested), 1.261 +** and then starts new client hello or hello request. 1.262 +** Acquires and releases HandshakeLock. 1.263 +*/ 1.264 +SECStatus 1.265 +SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache) 1.266 +{ 1.267 + sslSocket *ss; 1.268 + SECStatus rv; 1.269 + 1.270 + ss = ssl_FindSocket(fd); 1.271 + if (!ss) { 1.272 + SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd)); 1.273 + return SECFailure; 1.274 + } 1.275 + 1.276 + if (!ss->opt.useSecurity) 1.277 + return SECSuccess; 1.278 + 1.279 + ssl_Get1stHandshakeLock(ss); 1.280 + 1.281 + /* SSL v2 protocol does not support subsequent handshakes. */ 1.282 + if (ss->version < SSL_LIBRARY_VERSION_3_0) { 1.283 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); 1.284 + rv = SECFailure; 1.285 + } else { 1.286 + ssl_GetSSL3HandshakeLock(ss); 1.287 + rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */ 1.288 + ssl_ReleaseSSL3HandshakeLock(ss); 1.289 + } 1.290 + 1.291 + ssl_Release1stHandshakeLock(ss); 1.292 + 1.293 + return rv; 1.294 +} 1.295 + 1.296 +/* 1.297 +** Same as above, but with an I/O timeout. 1.298 + */ 1.299 +SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, 1.300 + PRBool flushCache, 1.301 + PRIntervalTime timeout) 1.302 +{ 1.303 + if (SECSuccess != ssl_SetTimeout(fd, timeout)) { 1.304 + return SECFailure; 1.305 + } 1.306 + return SSL_ReHandshake(fd, flushCache); 1.307 +} 1.308 + 1.309 +SECStatus 1.310 +SSL_RedoHandshake(PRFileDesc *fd) 1.311 +{ 1.312 + return SSL_ReHandshake(fd, PR_TRUE); 1.313 +} 1.314 + 1.315 +/* Register an application callback to be called when SSL handshake completes. 1.316 +** Acquires and releases HandshakeLock. 1.317 +*/ 1.318 +SECStatus 1.319 +SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb, 1.320 + void *client_data) 1.321 +{ 1.322 + sslSocket *ss; 1.323 + 1.324 + ss = ssl_FindSocket(fd); 1.325 + if (!ss) { 1.326 + SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback", 1.327 + SSL_GETPID(), fd)); 1.328 + return SECFailure; 1.329 + } 1.330 + 1.331 + if (!ss->opt.useSecurity) { 1.332 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.333 + return SECFailure; 1.334 + } 1.335 + 1.336 + ssl_Get1stHandshakeLock(ss); 1.337 + ssl_GetSSL3HandshakeLock(ss); 1.338 + 1.339 + ss->handshakeCallback = cb; 1.340 + ss->handshakeCallbackData = client_data; 1.341 + 1.342 + ssl_ReleaseSSL3HandshakeLock(ss); 1.343 + ssl_Release1stHandshakeLock(ss); 1.344 + 1.345 + return SECSuccess; 1.346 +} 1.347 + 1.348 +/* Register an application callback to be called when false start may happen. 1.349 +** Acquires and releases HandshakeLock. 1.350 +*/ 1.351 +SECStatus 1.352 +SSL_SetCanFalseStartCallback(PRFileDesc *fd, SSLCanFalseStartCallback cb, 1.353 + void *arg) 1.354 +{ 1.355 + sslSocket *ss; 1.356 + 1.357 + ss = ssl_FindSocket(fd); 1.358 + if (!ss) { 1.359 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetCanFalseStartCallback", 1.360 + SSL_GETPID(), fd)); 1.361 + return SECFailure; 1.362 + } 1.363 + 1.364 + if (!ss->opt.useSecurity) { 1.365 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.366 + return SECFailure; 1.367 + } 1.368 + 1.369 + ssl_Get1stHandshakeLock(ss); 1.370 + ssl_GetSSL3HandshakeLock(ss); 1.371 + 1.372 + ss->canFalseStartCallback = cb; 1.373 + ss->canFalseStartCallbackData = arg; 1.374 + 1.375 + ssl_ReleaseSSL3HandshakeLock(ss); 1.376 + ssl_Release1stHandshakeLock(ss); 1.377 + 1.378 + return SECSuccess; 1.379 +} 1.380 + 1.381 +SECStatus 1.382 +SSL_RecommendedCanFalseStart(PRFileDesc *fd, PRBool *canFalseStart) 1.383 +{ 1.384 + sslSocket *ss; 1.385 + 1.386 + *canFalseStart = PR_FALSE; 1.387 + ss = ssl_FindSocket(fd); 1.388 + if (!ss) { 1.389 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RecommendedCanFalseStart", 1.390 + SSL_GETPID(), fd)); 1.391 + return SECFailure; 1.392 + } 1.393 + 1.394 + if (!ss->ssl3.initialized) { 1.395 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.396 + return SECFailure; 1.397 + } 1.398 + 1.399 + if (ss->version < SSL_LIBRARY_VERSION_3_0) { 1.400 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); 1.401 + return SECFailure; 1.402 + } 1.403 + 1.404 + /* Require a forward-secret key exchange. */ 1.405 + *canFalseStart = ss->ssl3.hs.kea_def->kea == kea_dhe_dss || 1.406 + ss->ssl3.hs.kea_def->kea == kea_dhe_rsa || 1.407 + ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa || 1.408 + ss->ssl3.hs.kea_def->kea == kea_ecdhe_rsa; 1.409 + 1.410 + return SECSuccess; 1.411 +} 1.412 + 1.413 +/* Try to make progress on an SSL handshake by attempting to read the 1.414 +** next handshake from the peer, and sending any responses. 1.415 +** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot 1.416 +** read the next handshake from the underlying socket. 1.417 +** For SSLv2, returns when handshake is complete or fatal error occurs. 1.418 +** For SSLv3, returns when handshake is complete, or application data has 1.419 +** arrived that must be taken by application before handshake can continue, 1.420 +** or a fatal error occurs. 1.421 +** Application should use handshake completion callback to tell which. 1.422 +*/ 1.423 +SECStatus 1.424 +SSL_ForceHandshake(PRFileDesc *fd) 1.425 +{ 1.426 + sslSocket *ss; 1.427 + SECStatus rv = SECFailure; 1.428 + 1.429 + ss = ssl_FindSocket(fd); 1.430 + if (!ss) { 1.431 + SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake", 1.432 + SSL_GETPID(), fd)); 1.433 + return rv; 1.434 + } 1.435 + 1.436 + /* Don't waste my time */ 1.437 + if (!ss->opt.useSecurity) 1.438 + return SECSuccess; 1.439 + 1.440 + if (!ssl_SocketIsBlocking(ss)) { 1.441 + ssl_GetXmitBufLock(ss); 1.442 + if (ss->pendingBuf.len != 0) { 1.443 + int sent = ssl_SendSavedWriteData(ss); 1.444 + if ((sent < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { 1.445 + ssl_ReleaseXmitBufLock(ss); 1.446 + return SECFailure; 1.447 + } 1.448 + } 1.449 + ssl_ReleaseXmitBufLock(ss); 1.450 + } 1.451 + 1.452 + ssl_Get1stHandshakeLock(ss); 1.453 + 1.454 + if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 1.455 + int gatherResult; 1.456 + 1.457 + ssl_GetRecvBufLock(ss); 1.458 + gatherResult = ssl3_GatherCompleteHandshake(ss, 0); 1.459 + ssl_ReleaseRecvBufLock(ss); 1.460 + if (gatherResult > 0) { 1.461 + rv = SECSuccess; 1.462 + } else if (gatherResult == 0) { 1.463 + PORT_SetError(PR_END_OF_FILE_ERROR); 1.464 + } else if (gatherResult == SECWouldBlock) { 1.465 + PORT_SetError(PR_WOULD_BLOCK_ERROR); 1.466 + } 1.467 + } else if (!ss->firstHsDone) { 1.468 + rv = ssl_Do1stHandshake(ss); 1.469 + } else { 1.470 + /* tried to force handshake on an SSL 2 socket that has 1.471 + ** already completed the handshake. */ 1.472 + rv = SECSuccess; /* just pretend we did it. */ 1.473 + } 1.474 + 1.475 + ssl_Release1stHandshakeLock(ss); 1.476 + 1.477 + return rv; 1.478 +} 1.479 + 1.480 +/* 1.481 + ** Same as above, but with an I/O timeout. 1.482 + */ 1.483 +SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, 1.484 + PRIntervalTime timeout) 1.485 +{ 1.486 + if (SECSuccess != ssl_SetTimeout(fd, timeout)) { 1.487 + return SECFailure; 1.488 + } 1.489 + return SSL_ForceHandshake(fd); 1.490 +} 1.491 + 1.492 + 1.493 +/************************************************************************/ 1.494 + 1.495 +/* 1.496 +** Grow a buffer to hold newLen bytes of data. 1.497 +** Called for both recv buffers and xmit buffers. 1.498 +** Caller must hold xmitBufLock or recvBufLock, as appropriate. 1.499 +*/ 1.500 +SECStatus 1.501 +sslBuffer_Grow(sslBuffer *b, unsigned int newLen) 1.502 +{ 1.503 + newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); 1.504 + if (newLen > b->space) { 1.505 + unsigned char *newBuf; 1.506 + if (b->buf) { 1.507 + newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen); 1.508 + } else { 1.509 + newBuf = (unsigned char *) PORT_Alloc(newLen); 1.510 + } 1.511 + if (!newBuf) { 1.512 + return SECFailure; 1.513 + } 1.514 + SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", 1.515 + SSL_GETPID(), b->space, newLen)); 1.516 + b->buf = newBuf; 1.517 + b->space = newLen; 1.518 + } 1.519 + return SECSuccess; 1.520 +} 1.521 + 1.522 +SECStatus 1.523 +sslBuffer_Append(sslBuffer *b, const void * data, unsigned int len) 1.524 +{ 1.525 + unsigned int newLen = b->len + len; 1.526 + SECStatus rv; 1.527 + 1.528 + rv = sslBuffer_Grow(b, newLen); 1.529 + if (rv != SECSuccess) 1.530 + return rv; 1.531 + PORT_Memcpy(b->buf + b->len, data, len); 1.532 + b->len += len; 1.533 + return SECSuccess; 1.534 +} 1.535 + 1.536 +/* 1.537 +** Save away write data that is trying to be written before the security 1.538 +** handshake has been completed. When the handshake is completed, we will 1.539 +** flush this data out. 1.540 +** Caller must hold xmitBufLock 1.541 +*/ 1.542 +SECStatus 1.543 +ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) 1.544 +{ 1.545 + SECStatus rv; 1.546 + 1.547 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 1.548 + rv = sslBuffer_Append(&ss->pendingBuf, data, len); 1.549 + SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)", 1.550 + SSL_GETPID(), ss->fd, len, ss->pendingBuf.len)); 1.551 + return rv; 1.552 +} 1.553 + 1.554 +/* 1.555 +** Send saved write data. This will flush out data sent prior to a 1.556 +** complete security handshake. Hopefully there won't be too much of it. 1.557 +** Returns count of the bytes sent, NOT a SECStatus. 1.558 +** Caller must hold xmitBufLock 1.559 +*/ 1.560 +int 1.561 +ssl_SendSavedWriteData(sslSocket *ss) 1.562 +{ 1.563 + int rv = 0; 1.564 + 1.565 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 1.566 + if (ss->pendingBuf.len != 0) { 1.567 + SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", 1.568 + SSL_GETPID(), ss->fd, ss->pendingBuf.len)); 1.569 + rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); 1.570 + if (rv < 0) { 1.571 + return rv; 1.572 + } 1.573 + ss->pendingBuf.len -= rv; 1.574 + if (ss->pendingBuf.len > 0 && rv > 0) { 1.575 + /* UGH !! This shifts the whole buffer down by copying it */ 1.576 + PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, 1.577 + ss->pendingBuf.len); 1.578 + } 1.579 + } 1.580 + return rv; 1.581 +} 1.582 + 1.583 +/************************************************************************/ 1.584 + 1.585 +/* 1.586 +** Receive some application data on a socket. Reads SSL records from the input 1.587 +** stream, decrypts them and then copies them to the output buffer. 1.588 +** Called from ssl_SecureRecv() below. 1.589 +** 1.590 +** Caller does NOT hold 1stHandshakeLock because that handshake is over. 1.591 +** Caller doesn't call this until initial handshake is complete. 1.592 +** For SSLv2, there is no subsequent handshake. 1.593 +** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake 1.594 +** messages from a subsequent handshake. 1.595 +** 1.596 +** This code is similar to, and easily confused with, 1.597 +** ssl_GatherRecord1stHandshake() in sslcon.c 1.598 +*/ 1.599 +static int 1.600 +DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) 1.601 +{ 1.602 + int rv; 1.603 + int amount; 1.604 + int available; 1.605 + 1.606 + /* ssl3_GatherAppDataRecord may call ssl_FinishHandshake, which needs the 1.607 + * 1stHandshakeLock. */ 1.608 + ssl_Get1stHandshakeLock(ss); 1.609 + ssl_GetRecvBufLock(ss); 1.610 + 1.611 + available = ss->gs.writeOffset - ss->gs.readOffset; 1.612 + if (available == 0) { 1.613 + /* Get some more data */ 1.614 + if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 1.615 + /* Wait for application data to arrive. */ 1.616 + rv = ssl3_GatherAppDataRecord(ss, 0); 1.617 + } else { 1.618 + /* See if we have a complete record */ 1.619 + rv = ssl2_GatherRecord(ss, 0); 1.620 + } 1.621 + if (rv <= 0) { 1.622 + if (rv == 0) { 1.623 + /* EOF */ 1.624 + SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF", 1.625 + SSL_GETPID(), ss->fd)); 1.626 + goto done; 1.627 + } 1.628 + if ((rv != SECWouldBlock) && 1.629 + (PR_GetError() != PR_WOULD_BLOCK_ERROR)) { 1.630 + /* Some random error */ 1.631 + goto done; 1.632 + } 1.633 + 1.634 + /* 1.635 + ** Gather record is blocked waiting for more record data to 1.636 + ** arrive. Try to process what we have already received 1.637 + */ 1.638 + } else { 1.639 + /* Gather record has finished getting a complete record */ 1.640 + } 1.641 + 1.642 + /* See if any clear data is now available */ 1.643 + available = ss->gs.writeOffset - ss->gs.readOffset; 1.644 + if (available == 0) { 1.645 + /* 1.646 + ** No partial data is available. Force error code to 1.647 + ** EWOULDBLOCK so that caller will try again later. Note 1.648 + ** that the error code is probably EWOULDBLOCK already, 1.649 + ** but if it isn't (for example, if we received a zero 1.650 + ** length record) then this will force it to be correct. 1.651 + */ 1.652 + PORT_SetError(PR_WOULD_BLOCK_ERROR); 1.653 + rv = SECFailure; 1.654 + goto done; 1.655 + } 1.656 + SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d", 1.657 + SSL_GETPID(), ss->fd, available)); 1.658 + } 1.659 + 1.660 + /* Dole out clear data to reader */ 1.661 + amount = PR_MIN(len, available); 1.662 + PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); 1.663 + if (!(flags & PR_MSG_PEEK)) { 1.664 + ss->gs.readOffset += amount; 1.665 + } 1.666 + PORT_Assert(ss->gs.readOffset <= ss->gs.writeOffset); 1.667 + rv = amount; 1.668 + 1.669 + SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d", 1.670 + SSL_GETPID(), ss->fd, amount, available)); 1.671 + PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount)); 1.672 + 1.673 +done: 1.674 + ssl_ReleaseRecvBufLock(ss); 1.675 + ssl_Release1stHandshakeLock(ss); 1.676 + return rv; 1.677 +} 1.678 + 1.679 +/************************************************************************/ 1.680 + 1.681 +/* 1.682 +** Return SSLKEAType derived from cert's Public Key algorithm info. 1.683 +*/ 1.684 +SSLKEAType 1.685 +NSS_FindCertKEAType(CERTCertificate * cert) 1.686 +{ 1.687 + SSLKEAType keaType = kt_null; 1.688 + int tag; 1.689 + 1.690 + if (!cert) goto loser; 1.691 + 1.692 + tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); 1.693 + 1.694 + switch (tag) { 1.695 + case SEC_OID_X500_RSA_ENCRYPTION: 1.696 + case SEC_OID_PKCS1_RSA_ENCRYPTION: 1.697 + keaType = kt_rsa; 1.698 + break; 1.699 + case SEC_OID_X942_DIFFIE_HELMAN_KEY: 1.700 + keaType = kt_dh; 1.701 + break; 1.702 +#ifndef NSS_DISABLE_ECC 1.703 + case SEC_OID_ANSIX962_EC_PUBLIC_KEY: 1.704 + keaType = kt_ecdh; 1.705 + break; 1.706 +#endif /* NSS_DISABLE_ECC */ 1.707 + default: 1.708 + keaType = kt_null; 1.709 + } 1.710 + 1.711 + loser: 1.712 + 1.713 + return keaType; 1.714 +} 1.715 + 1.716 +static const PRCallOnceType pristineCallOnce; 1.717 +static PRCallOnceType setupServerCAListOnce; 1.718 + 1.719 +static SECStatus serverCAListShutdown(void* appData, void* nssData) 1.720 +{ 1.721 + PORT_Assert(ssl3_server_ca_list); 1.722 + if (ssl3_server_ca_list) { 1.723 + CERT_FreeDistNames(ssl3_server_ca_list); 1.724 + ssl3_server_ca_list = NULL; 1.725 + } 1.726 + setupServerCAListOnce = pristineCallOnce; 1.727 + return SECSuccess; 1.728 +} 1.729 + 1.730 +static PRStatus serverCAListSetup(void *arg) 1.731 +{ 1.732 + CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg; 1.733 + SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL); 1.734 + PORT_Assert(SECSuccess == rv); 1.735 + if (SECSuccess == rv) { 1.736 + ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle); 1.737 + return PR_SUCCESS; 1.738 + } 1.739 + return PR_FAILURE; 1.740 +} 1.741 + 1.742 +SECStatus 1.743 +ssl_ConfigSecureServer(sslSocket *ss, CERTCertificate *cert, 1.744 + const CERTCertificateList *certChain, 1.745 + ssl3KeyPair *keyPair, SSLKEAType kea) 1.746 +{ 1.747 + CERTCertificateList *localCertChain = NULL; 1.748 + sslServerCerts *sc = ss->serverCerts + kea; 1.749 + 1.750 + /* load the server certificate */ 1.751 + if (sc->serverCert != NULL) { 1.752 + CERT_DestroyCertificate(sc->serverCert); 1.753 + sc->serverCert = NULL; 1.754 + sc->serverKeyBits = 0; 1.755 + } 1.756 + /* load the server cert chain */ 1.757 + if (sc->serverCertChain != NULL) { 1.758 + CERT_DestroyCertificateList(sc->serverCertChain); 1.759 + sc->serverCertChain = NULL; 1.760 + } 1.761 + if (cert) { 1.762 + sc->serverCert = CERT_DupCertificate(cert); 1.763 + /* get the size of the cert's public key, and remember it */ 1.764 + sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey); 1.765 + if (!certChain) { 1.766 + localCertChain = 1.767 + CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer, 1.768 + PR_TRUE); 1.769 + if (!localCertChain) 1.770 + goto loser; 1.771 + } 1.772 + sc->serverCertChain = (certChain) ? CERT_DupCertList(certChain) : 1.773 + localCertChain; 1.774 + if (!sc->serverCertChain) { 1.775 + goto loser; 1.776 + } 1.777 + localCertChain = NULL; /* consumed */ 1.778 + } 1.779 + 1.780 + /* get keyPair */ 1.781 + if (sc->serverKeyPair != NULL) { 1.782 + ssl3_FreeKeyPair(sc->serverKeyPair); 1.783 + sc->serverKeyPair = NULL; 1.784 + } 1.785 + if (keyPair) { 1.786 + SECKEY_CacheStaticFlags(keyPair->privKey); 1.787 + sc->serverKeyPair = ssl3_GetKeyPairRef(keyPair); 1.788 + } 1.789 + if (kea == kt_rsa && cert && sc->serverKeyBits > 512 && 1.790 + !ss->opt.noStepDown && !ss->stepDownKeyPair) { 1.791 + if (ssl3_CreateRSAStepDownKeys(ss) != SECSuccess) { 1.792 + goto loser; 1.793 + } 1.794 + } 1.795 + return SECSuccess; 1.796 + 1.797 +loser: 1.798 + if (localCertChain) { 1.799 + CERT_DestroyCertificateList(localCertChain); 1.800 + } 1.801 + if (sc->serverCert != NULL) { 1.802 + CERT_DestroyCertificate(sc->serverCert); 1.803 + sc->serverCert = NULL; 1.804 + } 1.805 + if (sc->serverCertChain != NULL) { 1.806 + CERT_DestroyCertificateList(sc->serverCertChain); 1.807 + sc->serverCertChain = NULL; 1.808 + } 1.809 + if (sc->serverKeyPair != NULL) { 1.810 + ssl3_FreeKeyPair(sc->serverKeyPair); 1.811 + sc->serverKeyPair = NULL; 1.812 + } 1.813 + return SECFailure; 1.814 +} 1.815 + 1.816 +/* XXX need to protect the data that gets changed here.!! */ 1.817 + 1.818 +SECStatus 1.819 +SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, 1.820 + SECKEYPrivateKey *key, SSL3KEAType kea) 1.821 +{ 1.822 + 1.823 + return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea); 1.824 +} 1.825 + 1.826 +SECStatus 1.827 +SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert, 1.828 + const CERTCertificateList *certChainOpt, 1.829 + SECKEYPrivateKey *key, SSL3KEAType kea) 1.830 +{ 1.831 + sslSocket *ss; 1.832 + SECKEYPublicKey *pubKey = NULL; 1.833 + ssl3KeyPair *keyPair = NULL; 1.834 + SECStatus rv = SECFailure; 1.835 + 1.836 + ss = ssl_FindSocket(fd); 1.837 + if (!ss) { 1.838 + return SECFailure; 1.839 + } 1.840 + 1.841 + /* Both key and cert must have a value or be NULL */ 1.842 + /* Passing a value of NULL will turn off key exchange algorithms that were 1.843 + * previously turned on */ 1.844 + if (!cert != !key) { 1.845 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.846 + return SECFailure; 1.847 + } 1.848 + 1.849 + /* make sure the key exchange is recognized */ 1.850 + if ((kea >= kt_kea_size) || (kea < kt_null)) { 1.851 + PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 1.852 + return SECFailure; 1.853 + } 1.854 + 1.855 + if (kea != NSS_FindCertKEAType(cert)) { 1.856 + PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); 1.857 + return SECFailure; 1.858 + } 1.859 + 1.860 + if (cert) { 1.861 + /* get the size of the cert's public key, and remember it */ 1.862 + pubKey = CERT_ExtractPublicKey(cert); 1.863 + if (!pubKey) 1.864 + return SECFailure; 1.865 + } 1.866 + 1.867 + if (key) { 1.868 + SECKEYPrivateKey * keyCopy = NULL; 1.869 + CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM; 1.870 + 1.871 + if (key->pkcs11Slot) { 1.872 + PK11SlotInfo * bestSlot; 1.873 + bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); 1.874 + if (bestSlot) { 1.875 + keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); 1.876 + PK11_FreeSlot(bestSlot); 1.877 + } 1.878 + } 1.879 + if (keyCopy == NULL) 1.880 + keyMech = PK11_MapSignKeyType(key->keyType); 1.881 + if (keyMech != CKM_INVALID_MECHANISM) { 1.882 + PK11SlotInfo * bestSlot; 1.883 + /* XXX Maybe should be bestSlotMultiple? */ 1.884 + bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */); 1.885 + if (bestSlot) { 1.886 + keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); 1.887 + PK11_FreeSlot(bestSlot); 1.888 + } 1.889 + } 1.890 + if (keyCopy == NULL) 1.891 + keyCopy = SECKEY_CopyPrivateKey(key); 1.892 + if (keyCopy == NULL) 1.893 + goto loser; 1.894 + keyPair = ssl3_NewKeyPair(keyCopy, pubKey); 1.895 + if (keyPair == NULL) { 1.896 + SECKEY_DestroyPrivateKey(keyCopy); 1.897 + goto loser; 1.898 + } 1.899 + pubKey = NULL; /* adopted by serverKeyPair */ 1.900 + } 1.901 + if (ssl_ConfigSecureServer(ss, cert, certChainOpt, 1.902 + keyPair, kea) == SECFailure) { 1.903 + goto loser; 1.904 + } 1.905 + 1.906 + /* Only do this once because it's global. */ 1.907 + if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, 1.908 + &serverCAListSetup, 1.909 + (void *)(ss->dbHandle))) { 1.910 + rv = SECSuccess; 1.911 + } 1.912 + 1.913 +loser: 1.914 + if (keyPair) { 1.915 + ssl3_FreeKeyPair(keyPair); 1.916 + } 1.917 + if (pubKey) { 1.918 + SECKEY_DestroyPublicKey(pubKey); 1.919 + pubKey = NULL; 1.920 + } 1.921 + return rv; 1.922 +} 1.923 + 1.924 +/************************************************************************/ 1.925 + 1.926 +SECStatus 1.927 +ssl_CreateSecurityInfo(sslSocket *ss) 1.928 +{ 1.929 + SECStatus status; 1.930 + 1.931 + /* initialize sslv2 socket to send data in the clear. */ 1.932 + ssl2_UseClearSendFunc(ss); 1.933 + 1.934 + ss->sec.blockSize = 1; 1.935 + ss->sec.blockShift = 0; 1.936 + 1.937 + ssl_GetXmitBufLock(ss); 1.938 + status = sslBuffer_Grow(&ss->sec.writeBuf, 4096); 1.939 + ssl_ReleaseXmitBufLock(ss); 1.940 + 1.941 + return status; 1.942 +} 1.943 + 1.944 +SECStatus 1.945 +ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) 1.946 +{ 1.947 + ss->sec.send = os->sec.send; 1.948 + ss->sec.isServer = os->sec.isServer; 1.949 + ss->sec.keyBits = os->sec.keyBits; 1.950 + ss->sec.secretKeyBits = os->sec.secretKeyBits; 1.951 + 1.952 + ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert); 1.953 + if (os->sec.peerCert && !ss->sec.peerCert) 1.954 + goto loser; 1.955 + 1.956 + ss->sec.cache = os->sec.cache; 1.957 + ss->sec.uncache = os->sec.uncache; 1.958 + 1.959 + /* we don't dup the connection info. */ 1.960 + 1.961 + ss->sec.sendSequence = os->sec.sendSequence; 1.962 + ss->sec.rcvSequence = os->sec.rcvSequence; 1.963 + 1.964 + if (os->sec.hash && os->sec.hashcx) { 1.965 + ss->sec.hash = os->sec.hash; 1.966 + ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx); 1.967 + if (os->sec.hashcx && !ss->sec.hashcx) 1.968 + goto loser; 1.969 + } else { 1.970 + ss->sec.hash = NULL; 1.971 + ss->sec.hashcx = NULL; 1.972 + } 1.973 + 1.974 + SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret); 1.975 + if (os->sec.sendSecret.data && !ss->sec.sendSecret.data) 1.976 + goto loser; 1.977 + SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret); 1.978 + if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data) 1.979 + goto loser; 1.980 + 1.981 + /* XXX following code is wrong if either cx != 0 */ 1.982 + PORT_Assert(os->sec.readcx == 0); 1.983 + PORT_Assert(os->sec.writecx == 0); 1.984 + ss->sec.readcx = os->sec.readcx; 1.985 + ss->sec.writecx = os->sec.writecx; 1.986 + ss->sec.destroy = 0; 1.987 + 1.988 + ss->sec.enc = os->sec.enc; 1.989 + ss->sec.dec = os->sec.dec; 1.990 + 1.991 + ss->sec.blockShift = os->sec.blockShift; 1.992 + ss->sec.blockSize = os->sec.blockSize; 1.993 + 1.994 + return SECSuccess; 1.995 + 1.996 +loser: 1.997 + return SECFailure; 1.998 +} 1.999 + 1.1000 +/* Reset sec back to its initial state. 1.1001 +** Caller holds any relevant locks. 1.1002 +*/ 1.1003 +void 1.1004 +ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) 1.1005 +{ 1.1006 + /* Destroy MAC */ 1.1007 + if (sec->hash && sec->hashcx) { 1.1008 + (*sec->hash->destroy)(sec->hashcx, PR_TRUE); 1.1009 + sec->hashcx = NULL; 1.1010 + sec->hash = NULL; 1.1011 + } 1.1012 + SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); 1.1013 + SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); 1.1014 + 1.1015 + /* Destroy ciphers */ 1.1016 + if (sec->destroy) { 1.1017 + (*sec->destroy)(sec->readcx, PR_TRUE); 1.1018 + (*sec->destroy)(sec->writecx, PR_TRUE); 1.1019 + sec->readcx = NULL; 1.1020 + sec->writecx = NULL; 1.1021 + } else { 1.1022 + PORT_Assert(sec->readcx == 0); 1.1023 + PORT_Assert(sec->writecx == 0); 1.1024 + } 1.1025 + sec->readcx = 0; 1.1026 + sec->writecx = 0; 1.1027 + 1.1028 + if (sec->localCert) { 1.1029 + CERT_DestroyCertificate(sec->localCert); 1.1030 + sec->localCert = NULL; 1.1031 + } 1.1032 + if (sec->peerCert) { 1.1033 + CERT_DestroyCertificate(sec->peerCert); 1.1034 + sec->peerCert = NULL; 1.1035 + } 1.1036 + if (sec->peerKey) { 1.1037 + SECKEY_DestroyPublicKey(sec->peerKey); 1.1038 + sec->peerKey = NULL; 1.1039 + } 1.1040 + 1.1041 + /* cleanup the ci */ 1.1042 + if (sec->ci.sid != NULL) { 1.1043 + ssl_FreeSID(sec->ci.sid); 1.1044 + } 1.1045 + PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); 1.1046 + if (doMemset) { 1.1047 + memset(&sec->ci, 0, sizeof sec->ci); 1.1048 + } 1.1049 + 1.1050 +} 1.1051 + 1.1052 +/* 1.1053 +** Called from SSL_ResetHandshake (above), and 1.1054 +** from ssl_FreeSocket in sslsock.c 1.1055 +** Caller should hold relevant locks (e.g. XmitBufLock) 1.1056 +*/ 1.1057 +void 1.1058 +ssl_DestroySecurityInfo(sslSecurityInfo *sec) 1.1059 +{ 1.1060 + ssl_ResetSecurityInfo(sec, PR_FALSE); 1.1061 + 1.1062 + PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); 1.1063 + sec->writeBuf.buf = 0; 1.1064 + 1.1065 + memset(sec, 0, sizeof *sec); 1.1066 +} 1.1067 + 1.1068 +/************************************************************************/ 1.1069 + 1.1070 +int 1.1071 +ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa) 1.1072 +{ 1.1073 + PRFileDesc *osfd = ss->fd->lower; 1.1074 + int rv; 1.1075 + 1.1076 + if ( ss->opt.handshakeAsServer ) { 1.1077 + ss->securityHandshake = ssl2_BeginServerHandshake; 1.1078 + ss->handshaking = sslHandshakingAsServer; 1.1079 + } else { 1.1080 + ss->securityHandshake = ssl2_BeginClientHandshake; 1.1081 + ss->handshaking = sslHandshakingAsClient; 1.1082 + } 1.1083 + 1.1084 + /* connect to server */ 1.1085 + rv = osfd->methods->connect(osfd, sa, ss->cTimeout); 1.1086 + if (rv == PR_SUCCESS) { 1.1087 + ss->TCPconnected = 1; 1.1088 + } else { 1.1089 + int err = PR_GetError(); 1.1090 + SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d", 1.1091 + SSL_GETPID(), ss->fd, err)); 1.1092 + if (err == PR_IS_CONNECTED_ERROR) { 1.1093 + ss->TCPconnected = 1; 1.1094 + } 1.1095 + } 1.1096 + 1.1097 + SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d", 1.1098 + SSL_GETPID(), ss->fd, rv)); 1.1099 + return rv; 1.1100 +} 1.1101 + 1.1102 +/* 1.1103 + * The TLS 1.2 RFC 5246, Section 7.2.1 says: 1.1104 + * 1.1105 + * Unless some other fatal alert has been transmitted, each party is 1.1106 + * required to send a close_notify alert before closing the write side 1.1107 + * of the connection. The other party MUST respond with a close_notify 1.1108 + * alert of its own and close down the connection immediately, 1.1109 + * discarding any pending writes. It is not required for the initiator 1.1110 + * of the close to wait for the responding close_notify alert before 1.1111 + * closing the read side of the connection. 1.1112 + * 1.1113 + * The second sentence requires that we send a close_notify alert when we 1.1114 + * have received a close_notify alert. In practice, all SSL implementations 1.1115 + * close the socket immediately after sending a close_notify alert (which is 1.1116 + * allowed by the third sentence), so responding with a close_notify alert 1.1117 + * would result in a write failure with the ECONNRESET error. This is why 1.1118 + * we don't respond with a close_notify alert. 1.1119 + * 1.1120 + * Also, in the unlikely event that the TCP pipe is full and the peer stops 1.1121 + * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown 1.1122 + * may block indefinitely in blocking mode, and may fail (without retrying) 1.1123 + * in non-blocking mode. 1.1124 + */ 1.1125 + 1.1126 +int 1.1127 +ssl_SecureClose(sslSocket *ss) 1.1128 +{ 1.1129 + int rv; 1.1130 + 1.1131 + if (ss->version >= SSL_LIBRARY_VERSION_3_0 && 1.1132 + !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && 1.1133 + ss->firstHsDone && 1.1134 + !ss->recvdCloseNotify && 1.1135 + ss->ssl3.initialized) { 1.1136 + 1.1137 + /* We don't want the final alert to be Nagle delayed. */ 1.1138 + if (!ss->delayDisabled) { 1.1139 + ssl_EnableNagleDelay(ss, PR_FALSE); 1.1140 + ss->delayDisabled = 1; 1.1141 + } 1.1142 + 1.1143 + (void) SSL3_SendAlert(ss, alert_warning, close_notify); 1.1144 + } 1.1145 + rv = ssl_DefClose(ss); 1.1146 + return rv; 1.1147 +} 1.1148 + 1.1149 +/* Caller handles all locking */ 1.1150 +int 1.1151 +ssl_SecureShutdown(sslSocket *ss, int nsprHow) 1.1152 +{ 1.1153 + PRFileDesc *osfd = ss->fd->lower; 1.1154 + int rv; 1.1155 + PRIntn sslHow = nsprHow + 1; 1.1156 + 1.1157 + if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) { 1.1158 + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1.1159 + return PR_FAILURE; 1.1160 + } 1.1161 + 1.1162 + if ((sslHow & ssl_SHUTDOWN_SEND) != 0 && 1.1163 + ss->version >= SSL_LIBRARY_VERSION_3_0 && 1.1164 + !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && 1.1165 + ss->firstHsDone && 1.1166 + !ss->recvdCloseNotify && 1.1167 + ss->ssl3.initialized) { 1.1168 + 1.1169 + (void) SSL3_SendAlert(ss, alert_warning, close_notify); 1.1170 + } 1.1171 + 1.1172 + rv = osfd->methods->shutdown(osfd, nsprHow); 1.1173 + 1.1174 + ss->shutdownHow |= sslHow; 1.1175 + 1.1176 + return rv; 1.1177 +} 1.1178 + 1.1179 +/************************************************************************/ 1.1180 + 1.1181 + 1.1182 +int 1.1183 +ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) 1.1184 +{ 1.1185 + sslSecurityInfo *sec; 1.1186 + int rv = 0; 1.1187 + 1.1188 + sec = &ss->sec; 1.1189 + 1.1190 + if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { 1.1191 + PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); 1.1192 + return PR_FAILURE; 1.1193 + } 1.1194 + if (flags & ~PR_MSG_PEEK) { 1.1195 + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1.1196 + return PR_FAILURE; 1.1197 + } 1.1198 + 1.1199 + if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { 1.1200 + ssl_GetXmitBufLock(ss); 1.1201 + if (ss->pendingBuf.len != 0) { 1.1202 + rv = ssl_SendSavedWriteData(ss); 1.1203 + if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { 1.1204 + ssl_ReleaseXmitBufLock(ss); 1.1205 + return SECFailure; 1.1206 + } 1.1207 + } 1.1208 + ssl_ReleaseXmitBufLock(ss); 1.1209 + } 1.1210 + 1.1211 + rv = 0; 1.1212 + /* If any of these is non-zero, the initial handshake is not done. */ 1.1213 + if (!ss->firstHsDone) { 1.1214 + ssl_Get1stHandshakeLock(ss); 1.1215 + if (ss->handshake || ss->nextHandshake || ss->securityHandshake) { 1.1216 + rv = ssl_Do1stHandshake(ss); 1.1217 + } 1.1218 + ssl_Release1stHandshakeLock(ss); 1.1219 + } 1.1220 + if (rv < 0) { 1.1221 + return rv; 1.1222 + } 1.1223 + 1.1224 + if (len == 0) return 0; 1.1225 + 1.1226 + rv = DoRecv(ss, (unsigned char*) buf, len, flags); 1.1227 + SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)", 1.1228 + SSL_GETPID(), ss->fd, rv, PORT_GetError())); 1.1229 + return rv; 1.1230 +} 1.1231 + 1.1232 +int 1.1233 +ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) 1.1234 +{ 1.1235 + return ssl_SecureRecv(ss, buf, len, 0); 1.1236 +} 1.1237 + 1.1238 +/* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */ 1.1239 +int 1.1240 +ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) 1.1241 +{ 1.1242 + int rv = 0; 1.1243 + 1.1244 + SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", 1.1245 + SSL_GETPID(), ss->fd, len)); 1.1246 + 1.1247 + if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { 1.1248 + PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); 1.1249 + rv = PR_FAILURE; 1.1250 + goto done; 1.1251 + } 1.1252 + if (flags) { 1.1253 + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1.1254 + rv = PR_FAILURE; 1.1255 + goto done; 1.1256 + } 1.1257 + 1.1258 + ssl_GetXmitBufLock(ss); 1.1259 + if (ss->pendingBuf.len != 0) { 1.1260 + PORT_Assert(ss->pendingBuf.len > 0); 1.1261 + rv = ssl_SendSavedWriteData(ss); 1.1262 + if (rv >= 0 && ss->pendingBuf.len != 0) { 1.1263 + PORT_Assert(ss->pendingBuf.len > 0); 1.1264 + PORT_SetError(PR_WOULD_BLOCK_ERROR); 1.1265 + rv = SECFailure; 1.1266 + } 1.1267 + } 1.1268 + ssl_ReleaseXmitBufLock(ss); 1.1269 + if (rv < 0) { 1.1270 + goto done; 1.1271 + } 1.1272 + 1.1273 + if (len > 0) 1.1274 + ss->writerThread = PR_GetCurrentThread(); 1.1275 + /* If any of these is non-zero, the initial handshake is not done. */ 1.1276 + if (!ss->firstHsDone) { 1.1277 + PRBool falseStart = PR_FALSE; 1.1278 + ssl_Get1stHandshakeLock(ss); 1.1279 + if (ss->opt.enableFalseStart && 1.1280 + ss->version >= SSL_LIBRARY_VERSION_3_0) { 1.1281 + ssl_GetSSL3HandshakeLock(ss); 1.1282 + falseStart = ss->ssl3.hs.canFalseStart; 1.1283 + ssl_ReleaseSSL3HandshakeLock(ss); 1.1284 + } 1.1285 + if (!falseStart && 1.1286 + (ss->handshake || ss->nextHandshake || ss->securityHandshake)) { 1.1287 + rv = ssl_Do1stHandshake(ss); 1.1288 + } 1.1289 + ssl_Release1stHandshakeLock(ss); 1.1290 + } 1.1291 + if (rv < 0) { 1.1292 + ss->writerThread = NULL; 1.1293 + goto done; 1.1294 + } 1.1295 + 1.1296 + /* Check for zero length writes after we do housekeeping so we make forward 1.1297 + * progress. 1.1298 + */ 1.1299 + if (len == 0) { 1.1300 + rv = 0; 1.1301 + goto done; 1.1302 + } 1.1303 + PORT_Assert(buf != NULL); 1.1304 + if (!buf) { 1.1305 + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1.1306 + rv = PR_FAILURE; 1.1307 + goto done; 1.1308 + } 1.1309 + 1.1310 + if (!ss->firstHsDone) { 1.1311 + PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0); 1.1312 +#ifdef DEBUG 1.1313 + ssl_GetSSL3HandshakeLock(ss); 1.1314 + PORT_Assert(ss->ssl3.hs.canFalseStart); 1.1315 + ssl_ReleaseSSL3HandshakeLock(ss); 1.1316 +#endif 1.1317 + SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start", 1.1318 + SSL_GETPID(), ss->fd)); 1.1319 + } 1.1320 + 1.1321 + /* Send out the data using one of these functions: 1.1322 + * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, 1.1323 + * ssl3_SendApplicationData 1.1324 + */ 1.1325 + ssl_GetXmitBufLock(ss); 1.1326 + rv = (*ss->sec.send)(ss, buf, len, flags); 1.1327 + ssl_ReleaseXmitBufLock(ss); 1.1328 + ss->writerThread = NULL; 1.1329 +done: 1.1330 + if (rv < 0) { 1.1331 + SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d", 1.1332 + SSL_GETPID(), ss->fd, rv, PORT_GetError())); 1.1333 + } else { 1.1334 + SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count", 1.1335 + SSL_GETPID(), ss->fd, rv)); 1.1336 + } 1.1337 + return rv; 1.1338 +} 1.1339 + 1.1340 +int 1.1341 +ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len) 1.1342 +{ 1.1343 + return ssl_SecureSend(ss, buf, len, 0); 1.1344 +} 1.1345 + 1.1346 +SECStatus 1.1347 +SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) 1.1348 +{ 1.1349 + sslSocket *ss; 1.1350 + 1.1351 + ss = ssl_FindSocket(fd); 1.1352 + if (!ss) { 1.1353 + SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook", 1.1354 + SSL_GETPID(), fd)); 1.1355 + return SECFailure; 1.1356 + } 1.1357 + 1.1358 + ss->handleBadCert = f; 1.1359 + ss->badCertArg = arg; 1.1360 + 1.1361 + return SECSuccess; 1.1362 +} 1.1363 + 1.1364 +/* 1.1365 + * Allow the application to pass the url or hostname into the SSL library 1.1366 + * so that we can do some checking on it. It will be used for the value in 1.1367 + * SNI extension of client hello message. 1.1368 + */ 1.1369 +SECStatus 1.1370 +SSL_SetURL(PRFileDesc *fd, const char *url) 1.1371 +{ 1.1372 + sslSocket * ss = ssl_FindSocket(fd); 1.1373 + SECStatus rv = SECSuccess; 1.1374 + 1.1375 + if (!ss) { 1.1376 + SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL", 1.1377 + SSL_GETPID(), fd)); 1.1378 + return SECFailure; 1.1379 + } 1.1380 + ssl_Get1stHandshakeLock(ss); 1.1381 + ssl_GetSSL3HandshakeLock(ss); 1.1382 + 1.1383 + if ( ss->url ) { 1.1384 + PORT_Free((void *)ss->url); /* CONST */ 1.1385 + } 1.1386 + 1.1387 + ss->url = (const char *)PORT_Strdup(url); 1.1388 + if ( ss->url == NULL ) { 1.1389 + rv = SECFailure; 1.1390 + } 1.1391 + 1.1392 + ssl_ReleaseSSL3HandshakeLock(ss); 1.1393 + ssl_Release1stHandshakeLock(ss); 1.1394 + 1.1395 + return rv; 1.1396 +} 1.1397 + 1.1398 +/* 1.1399 + * Allow the application to pass the set of trust anchors 1.1400 + */ 1.1401 +SECStatus 1.1402 +SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *certList) 1.1403 +{ 1.1404 + sslSocket * ss = ssl_FindSocket(fd); 1.1405 + CERTDistNames *names = NULL; 1.1406 + 1.1407 + if (!certList) { 1.1408 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.1409 + return SECFailure; 1.1410 + } 1.1411 + if (!ss) { 1.1412 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTrustAnchors", 1.1413 + SSL_GETPID(), fd)); 1.1414 + return SECFailure; 1.1415 + } 1.1416 + 1.1417 + names = CERT_DistNamesFromCertList(certList); 1.1418 + if (names == NULL) { 1.1419 + return SECFailure; 1.1420 + } 1.1421 + ssl_Get1stHandshakeLock(ss); 1.1422 + ssl_GetSSL3HandshakeLock(ss); 1.1423 + if (ss->ssl3.ca_list) { 1.1424 + CERT_FreeDistNames(ss->ssl3.ca_list); 1.1425 + } 1.1426 + ss->ssl3.ca_list = names; 1.1427 + ssl_ReleaseSSL3HandshakeLock(ss); 1.1428 + ssl_Release1stHandshakeLock(ss); 1.1429 + 1.1430 + return SECSuccess; 1.1431 +} 1.1432 + 1.1433 +/* 1.1434 +** Returns Negative number on error, zero or greater on success. 1.1435 +** Returns the amount of data immediately available to be read. 1.1436 +*/ 1.1437 +int 1.1438 +SSL_DataPending(PRFileDesc *fd) 1.1439 +{ 1.1440 + sslSocket *ss; 1.1441 + int rv = 0; 1.1442 + 1.1443 + ss = ssl_FindSocket(fd); 1.1444 + 1.1445 + if (ss && ss->opt.useSecurity) { 1.1446 + ssl_GetRecvBufLock(ss); 1.1447 + rv = ss->gs.writeOffset - ss->gs.readOffset; 1.1448 + ssl_ReleaseRecvBufLock(ss); 1.1449 + } 1.1450 + 1.1451 + return rv; 1.1452 +} 1.1453 + 1.1454 +SECStatus 1.1455 +SSL_InvalidateSession(PRFileDesc *fd) 1.1456 +{ 1.1457 + sslSocket * ss = ssl_FindSocket(fd); 1.1458 + SECStatus rv = SECFailure; 1.1459 + 1.1460 + if (ss) { 1.1461 + ssl_Get1stHandshakeLock(ss); 1.1462 + ssl_GetSSL3HandshakeLock(ss); 1.1463 + 1.1464 + if (ss->sec.ci.sid && ss->sec.uncache) { 1.1465 + ss->sec.uncache(ss->sec.ci.sid); 1.1466 + rv = SECSuccess; 1.1467 + } 1.1468 + 1.1469 + ssl_ReleaseSSL3HandshakeLock(ss); 1.1470 + ssl_Release1stHandshakeLock(ss); 1.1471 + } 1.1472 + return rv; 1.1473 +} 1.1474 + 1.1475 +SECItem * 1.1476 +SSL_GetSessionID(PRFileDesc *fd) 1.1477 +{ 1.1478 + sslSocket * ss; 1.1479 + SECItem * item = NULL; 1.1480 + 1.1481 + ss = ssl_FindSocket(fd); 1.1482 + if (ss) { 1.1483 + ssl_Get1stHandshakeLock(ss); 1.1484 + ssl_GetSSL3HandshakeLock(ss); 1.1485 + 1.1486 + if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) { 1.1487 + item = (SECItem *)PORT_Alloc(sizeof(SECItem)); 1.1488 + if (item) { 1.1489 + sslSessionID * sid = ss->sec.ci.sid; 1.1490 + if (sid->version < SSL_LIBRARY_VERSION_3_0) { 1.1491 + item->len = SSL2_SESSIONID_BYTES; 1.1492 + item->data = (unsigned char*)PORT_Alloc(item->len); 1.1493 + PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); 1.1494 + } else { 1.1495 + item->len = sid->u.ssl3.sessionIDLength; 1.1496 + item->data = (unsigned char*)PORT_Alloc(item->len); 1.1497 + PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); 1.1498 + } 1.1499 + } 1.1500 + } 1.1501 + 1.1502 + ssl_ReleaseSSL3HandshakeLock(ss); 1.1503 + ssl_Release1stHandshakeLock(ss); 1.1504 + } 1.1505 + return item; 1.1506 +} 1.1507 + 1.1508 +SECStatus 1.1509 +SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) 1.1510 +{ 1.1511 + sslSocket * ss; 1.1512 + 1.1513 + ss = ssl_FindSocket(fd); 1.1514 + if (!ss) 1.1515 + return SECFailure; 1.1516 + if (!dbHandle) { 1.1517 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.1518 + return SECFailure; 1.1519 + } 1.1520 + ss->dbHandle = dbHandle; 1.1521 + return SECSuccess; 1.1522 +} 1.1523 + 1.1524 +/* DO NOT USE. This function was exported in ssl.def with the wrong signature; 1.1525 + * this implementation exists to maintain link-time compatibility. 1.1526 + */ 1.1527 +int 1.1528 +SSL_RestartHandshakeAfterCertReq(sslSocket * ss, 1.1529 + CERTCertificate * cert, 1.1530 + SECKEYPrivateKey * key, 1.1531 + CERTCertificateList *certChain) 1.1532 +{ 1.1533 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 1.1534 + return -1; 1.1535 +} 1.1536 + 1.1537 +/* DO NOT USE. This function was exported in ssl.def with the wrong signature; 1.1538 + * this implementation exists to maintain link-time compatibility. 1.1539 + */ 1.1540 +int 1.1541 +SSL_RestartHandshakeAfterServerCert(sslSocket * ss) 1.1542 +{ 1.1543 + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 1.1544 + return -1; 1.1545 +} 1.1546 + 1.1547 +/* See documentation in ssl.h */ 1.1548 +SECStatus 1.1549 +SSL_AuthCertificateComplete(PRFileDesc *fd, PRErrorCode error) 1.1550 +{ 1.1551 + SECStatus rv; 1.1552 + sslSocket *ss = ssl_FindSocket(fd); 1.1553 + 1.1554 + if (!ss) { 1.1555 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_AuthCertificateComplete", 1.1556 + SSL_GETPID(), fd)); 1.1557 + return SECFailure; 1.1558 + } 1.1559 + 1.1560 + ssl_Get1stHandshakeLock(ss); 1.1561 + 1.1562 + if (!ss->ssl3.initialized) { 1.1563 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.1564 + rv = SECFailure; 1.1565 + } else if (ss->version < SSL_LIBRARY_VERSION_3_0) { 1.1566 + PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); 1.1567 + rv = SECFailure; 1.1568 + } else { 1.1569 + rv = ssl3_AuthCertificateComplete(ss, error); 1.1570 + } 1.1571 + 1.1572 + ssl_Release1stHandshakeLock(ss); 1.1573 + 1.1574 + return rv; 1.1575 +} 1.1576 + 1.1577 +/* For more info see ssl.h */ 1.1578 +SECStatus 1.1579 +SSL_SNISocketConfigHook(PRFileDesc *fd, SSLSNISocketConfig func, 1.1580 + void *arg) 1.1581 +{ 1.1582 + sslSocket *ss; 1.1583 + 1.1584 + ss = ssl_FindSocket(fd); 1.1585 + if (!ss) { 1.1586 + SSL_DBG(("%d: SSL[%d]: bad socket in SNISocketConfigHook", 1.1587 + SSL_GETPID(), fd)); 1.1588 + return SECFailure; 1.1589 + } 1.1590 + 1.1591 + ss->sniSocketConfig = func; 1.1592 + ss->sniSocketConfigArg = arg; 1.1593 + return SECSuccess; 1.1594 +}