1 /* 2 * Various SSL functions. 3 * 4 * ***** BEGIN LICENSE BLOCK ***** 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 6 * 7 * The contents of this file are subject to the Mozilla Public License Version 8 * 1.1 (the "License"); you may not use this file except in compliance with 9 * the License. You may obtain a copy of the License at 10 * http://www.mozilla.org/MPL/ 11 * 12 * Software distributed under the License is distributed on an "AS IS" basis, 13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 14 * for the specific language governing rights and limitations under the 15 * License. 16 * 17 * The Original Code is the Netscape security libraries. 18 * 19 * The Initial Developer of the Original Code is 20 * Netscape Communications Corporation. 21 * Portions created by the Initial Developer are Copyright (C) 1994-2000 22 * the Initial Developer. All Rights Reserved. 23 * 24 * Contributor(s): 25 * Dr Vipul Gupta <vipul.gupta (at) sun.com>, Sun Microsystems Laboratories 26 * 27 * Alternatively, the contents of this file may be used under the terms of 28 * either the GNU General Public License Version 2 or later (the "GPL"), or 29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 30 * in which case the provisions of the GPL or the LGPL are applicable instead 31 * of those above. If you wish to allow use of your version of this file only 32 * under the terms of either the GPL or the LGPL, and not to allow others to 33 * use your version of this file under the terms of the MPL, indicate your 34 * decision by deleting the provisions above and replace them with the notice 35 * and other provisions required by the GPL or the LGPL. If you do not delete 36 * the provisions above, a recipient may use your version of this file under 37 * the terms of any one of the MPL, the GPL or the LGPL. 38 * 39 * ***** END LICENSE BLOCK ***** */ 40 /* $Id: sslsecur.c,v 1.42 2008/10/03 19:20:20 wtc%google.com Exp $ */ 41 #include "cert.h" 42 #include "secitem.h" 43 #include "keyhi.h" 44 #include "ssl.h" 45 #include "sslimpl.h" 46 #include "sslproto.h" 47 #include "secoid.h" /* for SECOID_GetALgorithmTag */ 48 #include "pk11func.h" /* for PK11_GenerateRandom */ 49 #include "nss.h" /* for NSS_RegisterShutdown */ 50 #include "prinit.h" /* for PR_CallOnceWithArg */ 51 52 #define MAX_BLOCK_CYPHER_SIZE 32 53 54 #define TEST_FOR_FAILURE /* reminder */ 55 #define SET_ERROR_CODE /* reminder */ 56 57 /* Returns a SECStatus: SECSuccess or SECFailure, NOT SECWouldBlock. 58 * 59 * Currently, the list of functions called through ss->handshake is: 60 * 61 * In sslsocks.c: 62 * SocksGatherRecord 63 * SocksHandleReply 64 * SocksStartGather 65 * 66 * In sslcon.c: 67 * ssl_GatherRecord1stHandshake 68 * ssl2_HandleClientSessionKeyMessage 69 * ssl2_HandleMessage 70 * ssl2_HandleVerifyMessage 71 * ssl2_BeginClientHandshake 72 * ssl2_BeginServerHandshake 73 * ssl2_HandleClientHelloMessage 74 * ssl2_HandleServerHelloMessage 75 * 76 * The ss->handshake function returns SECWouldBlock under these conditions: 77 * 1. ssl_GatherRecord1stHandshake called ssl2_GatherData which read in 78 * the beginning of an SSL v3 hello message and returned SECWouldBlock 79 * to switch to SSL v3 handshake processing. 80 * 81 * 2. ssl2_HandleClientHelloMessage discovered version 3.0 in the incoming 82 * v2 client hello msg, and called ssl3_HandleV2ClientHello which 83 * returned SECWouldBlock. 84 * 85 * 3. SECWouldBlock was returned by one of the callback functions, via 86 * one of these paths: 87 * - ssl2_HandleMessage() -> ssl2_HandleRequestCertificate() -> ss->getClientAuthData() 88 * 89 * - ssl2_HandleServerHelloMessage() -> ss->handleBadCert() 90 * 91 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> 92 * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> 93 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificate() -> 94 * ss->handleBadCert() 95 * 96 * - ssl_GatherRecord1stHandshake() -> ssl3_GatherCompleteHandshake() -> 97 * ssl3_HandleRecord() -> ssl3_HandleHandshake() -> 98 * ssl3_HandleHandshakeMessage() -> ssl3_HandleCertificateRequest() -> 99 * ss->getClientAuthData() 100 * 101 * Called from: SSL_ForceHandshake (below), 102 * ssl_SecureRecv (below) and 103 * ssl_SecureSend (below) 104 * from: WaitForResponse in sslsocks.c 105 * ssl_SocksRecv in sslsocks.c 106 * ssl_SocksSend in sslsocks.c 107 * 108 * Caller must hold the (write) handshakeLock. 109 */ 110 int 111 ssl_Do1stHandshake(sslSocket *ss) 112 { 113 int rv = SECSuccess; 114 int loopCount = 0; 115 116 do { 117 PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); 118 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); 119 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); 120 121 if (ss->handshake == 0) { 122 /* Previous handshake finished. Switch to next one */ 123 ss->handshake = ss->nextHandshake; 124 ss->nextHandshake = 0; 125 } 126 if (ss->handshake == 0) { 127 /* Previous handshake finished. Switch to security handshake */ 128 ss->handshake = ss->securityHandshake; 129 ss->securityHandshake = 0; 130 } 131 if (ss->handshake == 0) { 132 ssl_GetRecvBufLock(ss); 133 ss->gs.recordLen = 0; 134 ssl_ReleaseRecvBufLock(ss); 135 136 SSL_TRC(3, ("%d: SSL[%d]: handshake is completed", 137 SSL_GETPID(), ss->fd)); 138 /* call handshake callback for ssl v2 */ 139 /* for v3 this is done in ssl3_HandleFinished() */ 140 if ((ss->handshakeCallback != NULL) && /* has callback */ 141 (!ss->firstHsDone) && /* only first time */ 142 (ss->version < SSL_LIBRARY_VERSION_3_0)) { /* not ssl3 */ 143 ss->firstHsDone = PR_TRUE; 144 (ss->handshakeCallback)(ss->fd, ss->handshakeCallbackData); 145 } 146 ss->firstHsDone = PR_TRUE; 147 ss->gs.writeOffset = 0; 148 ss->gs.readOffset = 0; 149 break; 150 } 151 rv = (*ss->handshake)(ss); 152 ++loopCount; 153 /* This code must continue to loop on SECWouldBlock, 154 * or any positive value. See XXX_1 comments. 155 */ 156 } while (rv != SECFailure); /* was (rv >= 0); XXX_1 */ 157 158 PORT_Assert(ss->opt.noLocks || !ssl_HaveRecvBufLock(ss)); 159 PORT_Assert(ss->opt.noLocks || !ssl_HaveXmitBufLock(ss)); 160 161 if (rv == SECWouldBlock) { 162 PORT_SetError(PR_WOULD_BLOCK_ERROR); 163 rv = SECFailure; 164 } 165 return rv; 166 } 167 168 /* 169 * Handshake function that blocks. Used to force a 170 * retry on a connection on the next read/write. 171 */ 172 static SECStatus 173 AlwaysBlock(sslSocket *ss) 174 { 175 PORT_SetError(PR_WOULD_BLOCK_ERROR); /* perhaps redundant. */ 176 return SECWouldBlock; 177 } 178 179 /* 180 * set the initial handshake state machine to block 181 */ 182 void 183 ssl_SetAlwaysBlock(sslSocket *ss) 184 { 185 if (!ss->firstHsDone) { 186 ss->handshake = AlwaysBlock; 187 ss->nextHandshake = 0; 188 } 189 } 190 191 static SECStatus 192 ssl_SetTimeout(PRFileDesc *fd, PRIntervalTime timeout) 193 { 194 sslSocket *ss; 195 196 ss = ssl_FindSocket(fd); 197 if (!ss) { 198 SSL_DBG(("%d: SSL[%d]: bad socket in SetTimeout", SSL_GETPID(), fd)); 199 return SECFailure; 200 } 201 SSL_LOCK_READER(ss); 202 ss->rTimeout = timeout; 203 if (ss->opt.fdx) { 204 SSL_LOCK_WRITER(ss); 205 } 206 ss->wTimeout = timeout; 207 if (ss->opt.fdx) { 208 SSL_UNLOCK_WRITER(ss); 209 } 210 SSL_UNLOCK_READER(ss); 211 return SECSuccess; 212 } 213 214 /* Acquires and releases HandshakeLock. 215 */ 216 SECStatus 217 SSL_ResetHandshake(PRFileDesc *s, PRBool asServer) 218 { 219 sslSocket *ss; 220 SECStatus status; 221 PRNetAddr addr; 222 223 ss = ssl_FindSocket(s); 224 if (!ss) { 225 SSL_DBG(("%d: SSL[%d]: bad socket in ResetHandshake", SSL_GETPID(), s)); 226 return SECFailure; 227 } 228 229 /* Don't waste my time */ 230 if (!ss->opt.useSecurity) 231 return SECSuccess; 232 233 SSL_LOCK_READER(ss); 234 SSL_LOCK_WRITER(ss); 235 236 /* Reset handshake state */ 237 ssl_Get1stHandshakeLock(ss); 238 ssl_GetSSL3HandshakeLock(ss); 239 240 ss->firstHsDone = PR_FALSE; 241 if ( asServer ) { 242 ss->handshake = ssl2_BeginServerHandshake; 243 ss->handshaking = sslHandshakingAsServer; 244 } else { 245 ss->handshake = ssl2_BeginClientHandshake; 246 ss->handshaking = sslHandshakingAsClient; 247 } 248 ss->nextHandshake = 0; 249 ss->securityHandshake = 0; 250 251 ssl_GetRecvBufLock(ss); 252 status = ssl_InitGather(&ss->gs); 253 ssl_ReleaseRecvBufLock(ss); 254 255 /* 256 ** Blow away old security state and get a fresh setup. 257 */ 258 ssl_GetXmitBufLock(ss); 259 ssl_ResetSecurityInfo(&ss->sec, PR_TRUE); 260 status = ssl_CreateSecurityInfo(ss); 261 ssl_ReleaseXmitBufLock(ss); 262 263 ssl_ReleaseSSL3HandshakeLock(ss); 264 ssl_Release1stHandshakeLock(ss); 265 266 if (!ss->TCPconnected) 267 ss->TCPconnected = (PR_SUCCESS == ssl_DefGetpeername(ss, &addr)); 268 269 SSL_UNLOCK_WRITER(ss); 270 SSL_UNLOCK_READER(ss); 271 272 return status; 273 } 274 275 /* For SSLv2, does nothing but return an error. 276 ** For SSLv3, flushes SID cache entry (if requested), 277 ** and then starts new client hello or hello request. 278 ** Acquires and releases HandshakeLock. 279 */ 280 SECStatus 281 SSL_ReHandshake(PRFileDesc *fd, PRBool flushCache) 282 { 283 sslSocket *ss; 284 SECStatus rv; 285 286 ss = ssl_FindSocket(fd); 287 if (!ss) { 288 SSL_DBG(("%d: SSL[%d]: bad socket in RedoHandshake", SSL_GETPID(), fd)); 289 return SECFailure; 290 } 291 292 if (!ss->opt.useSecurity) 293 return SECSuccess; 294 295 ssl_Get1stHandshakeLock(ss); 296 297 /* SSL v2 protocol does not support subsequent handshakes. */ 298 if (ss->version < SSL_LIBRARY_VERSION_3_0) { 299 PORT_SetError(SEC_ERROR_INVALID_ARGS); 300 rv = SECFailure; 301 } else { 302 ssl_GetSSL3HandshakeLock(ss); 303 rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */ 304 ssl_ReleaseSSL3HandshakeLock(ss); 305 } 306 307 ssl_Release1stHandshakeLock(ss); 308 309 return rv; 310 } 311 312 /* 313 ** Same as above, but with an I/O timeout. 314 */ 315 SSL_IMPORT SECStatus SSL_ReHandshakeWithTimeout(PRFileDesc *fd, 316 PRBool flushCache, 317 PRIntervalTime timeout) 318 { 319 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { 320 return SECFailure; 321 } 322 return SSL_ReHandshake(fd, flushCache); 323 } 324 325 SECStatus 326 SSL_RedoHandshake(PRFileDesc *fd) 327 { 328 return SSL_ReHandshake(fd, PR_TRUE); 329 } 330 331 /* Register an application callback to be called when SSL handshake completes. 332 ** Acquires and releases HandshakeLock. 333 */ 334 SECStatus 335 SSL_HandshakeCallback(PRFileDesc *fd, SSLHandshakeCallback cb, 336 void *client_data) 337 { 338 sslSocket *ss; 339 340 ss = ssl_FindSocket(fd); 341 if (!ss) { 342 SSL_DBG(("%d: SSL[%d]: bad socket in HandshakeCallback", 343 SSL_GETPID(), fd)); 344 return SECFailure; 345 } 346 347 if (!ss->opt.useSecurity) { 348 PORT_SetError(SEC_ERROR_INVALID_ARGS); 349 return SECFailure; 350 } 351 352 ssl_Get1stHandshakeLock(ss); 353 ssl_GetSSL3HandshakeLock(ss); 354 355 ss->handshakeCallback = cb; 356 ss->handshakeCallbackData = client_data; 357 358 ssl_ReleaseSSL3HandshakeLock(ss); 359 ssl_Release1stHandshakeLock(ss); 360 361 return SECSuccess; 362 } 363 364 /* Try to make progress on an SSL handshake by attempting to read the 365 ** next handshake from the peer, and sending any responses. 366 ** For non-blocking sockets, returns PR_ERROR_WOULD_BLOCK if it cannot 367 ** read the next handshake from the underlying socket. 368 ** For SSLv2, returns when handshake is complete or fatal error occurs. 369 ** For SSLv3, returns when handshake is complete, or application data has 370 ** arrived that must be taken by application before handshake can continue, 371 ** or a fatal error occurs. 372 ** Application should use handshake completion callback to tell which. 373 */ 374 SECStatus 375 SSL_ForceHandshake(PRFileDesc *fd) 376 { 377 sslSocket *ss; 378 SECStatus rv = SECFailure; 379 380 ss = ssl_FindSocket(fd); 381 if (!ss) { 382 SSL_DBG(("%d: SSL[%d]: bad socket in ForceHandshake", 383 SSL_GETPID(), fd)); 384 return rv; 385 } 386 387 /* Don't waste my time */ 388 if (!ss->opt.useSecurity) 389 return SECSuccess; 390 391 ssl_Get1stHandshakeLock(ss); 392 393 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 394 int gatherResult; 395 396 ssl_GetRecvBufLock(ss); 397 gatherResult = ssl3_GatherCompleteHandshake(ss, 0); 398 ssl_ReleaseRecvBufLock(ss); 399 if (gatherResult > 0) { 400 rv = SECSuccess; 401 } else if (gatherResult == 0) { 402 PORT_SetError(PR_END_OF_FILE_ERROR); 403 } else if (gatherResult == SECWouldBlock) { 404 PORT_SetError(PR_WOULD_BLOCK_ERROR); 405 } 406 } else if (!ss->firstHsDone) { 407 rv = ssl_Do1stHandshake(ss); 408 } else { 409 /* tried to force handshake on an SSL 2 socket that has 410 ** already completed the handshake. */ 411 rv = SECSuccess; /* just pretend we did it. */ 412 } 413 414 ssl_Release1stHandshakeLock(ss); 415 416 return rv; 417 } 418 419 /* 420 ** Same as above, but with an I/O timeout. 421 */ 422 SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd, 423 PRIntervalTime timeout) 424 { 425 if (SECSuccess != ssl_SetTimeout(fd, timeout)) { 426 return SECFailure; 427 } 428 return SSL_ForceHandshake(fd); 429 } 430 431 432 /************************************************************************/ 433 434 /* 435 ** Grow a buffer to hold newLen bytes of data. 436 ** Called for both recv buffers and xmit buffers. 437 ** Caller must hold xmitBufLock or recvBufLock, as appropriate. 438 */ 439 SECStatus 440 sslBuffer_Grow(sslBuffer *b, unsigned int newLen) 441 { 442 newLen = PR_MAX(newLen, MAX_FRAGMENT_LENGTH + 2048); 443 if (newLen > b->space) { 444 unsigned char *newBuf; 445 if (b->buf) { 446 newBuf = (unsigned char *) PORT_Realloc(b->buf, newLen); 447 } else { 448 newBuf = (unsigned char *) PORT_Alloc(newLen); 449 } 450 if (!newBuf) { 451 return SECFailure; 452 } 453 SSL_TRC(10, ("%d: SSL: grow buffer from %d to %d", 454 SSL_GETPID(), b->space, newLen)); 455 b->buf = newBuf; 456 b->space = newLen; 457 } 458 return SECSuccess; 459 } 460 461 SECStatus 462 sslBuffer_Append(sslBuffer *b, const void * data, unsigned int len) 463 { 464 unsigned int newLen = b->len + len; 465 SECStatus rv; 466 467 rv = sslBuffer_Grow(b, newLen); 468 if (rv != SECSuccess) 469 return rv; 470 PORT_Memcpy(b->buf + b->len, data, len); 471 b->len += len; 472 return SECSuccess; 473 } 474 475 /* 476 ** Save away write data that is trying to be written before the security 477 ** handshake has been completed. When the handshake is completed, we will 478 ** flush this data out. 479 ** Caller must hold xmitBufLock 480 */ 481 SECStatus 482 ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) 483 { 484 SECStatus rv; 485 486 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 487 rv = sslBuffer_Append(&ss->pendingBuf, data, len); 488 SSL_TRC(5, ("%d: SSL[%d]: saving %u bytes of data (%u total saved so far)", 489 SSL_GETPID(), ss->fd, len, ss->pendingBuf.len)); 490 return rv; 491 } 492 493 /* 494 ** Send saved write data. This will flush out data sent prior to a 495 ** complete security handshake. Hopefully there won't be too much of it. 496 ** Returns count of the bytes sent, NOT a SECStatus. 497 ** Caller must hold xmitBufLock 498 */ 499 int 500 ssl_SendSavedWriteData(sslSocket *ss) 501 { 502 int rv = 0; 503 504 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 505 if (ss->pendingBuf.len != 0) { 506 SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", 507 SSL_GETPID(), ss->fd, ss->pendingBuf.len)); 508 rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); 509 if (rv < 0) { 510 return rv; 511 } 512 ss->pendingBuf.len -= rv; 513 if (ss->pendingBuf.len > 0 && rv > 0) { 514 /* UGH !! This shifts the whole buffer down by copying it */ 515 PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, 516 ss->pendingBuf.len); 517 } 518 } 519 return rv; 520 } 521 522 /************************************************************************/ 523 524 /* 525 ** Receive some application data on a socket. Reads SSL records from the input 526 ** stream, decrypts them and then copies them to the output buffer. 527 ** Called from ssl_SecureRecv() below. 528 ** 529 ** Caller does NOT hold 1stHandshakeLock because that handshake is over. 530 ** Caller doesn't call this until initial handshake is complete. 531 ** For SSLv2, there is no subsequent handshake. 532 ** For SSLv3, the call to ssl3_GatherAppDataRecord may encounter handshake 533 ** messages from a subsequent handshake. 534 ** 535 ** This code is similar to, and easily confused with, 536 ** ssl_GatherRecord1stHandshake() in sslcon.c 537 */ 538 static int 539 DoRecv(sslSocket *ss, unsigned char *out, int len, int flags) 540 { 541 int rv; 542 int amount; 543 int available; 544 545 ssl_GetRecvBufLock(ss); 546 547 available = ss->gs.writeOffset - ss->gs.readOffset; 548 if (available == 0) { 549 /* Get some more data */ 550 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 551 /* Wait for application data to arrive. */ 552 rv = ssl3_GatherAppDataRecord(ss, 0); 553 } else { 554 /* See if we have a complete record */ 555 rv = ssl2_GatherRecord(ss, 0); 556 } 557 if (rv <= 0) { 558 if (rv == 0) { 559 /* EOF */ 560 SSL_TRC(10, ("%d: SSL[%d]: ssl_recv EOF", 561 SSL_GETPID(), ss->fd)); 562 goto done; 563 } 564 if ((rv != SECWouldBlock) && 565 (PR_GetError() != PR_WOULD_BLOCK_ERROR)) { 566 /* Some random error */ 567 goto done; 568 } 569 570 /* 571 ** Gather record is blocked waiting for more record data to 572 ** arrive. Try to process what we have already received 573 */ 574 } else { 575 /* Gather record has finished getting a complete record */ 576 } 577 578 /* See if any clear data is now available */ 579 available = ss->gs.writeOffset - ss->gs.readOffset; 580 if (available == 0) { 581 /* 582 ** No partial data is available. Force error code to 583 ** EWOULDBLOCK so that caller will try again later. Note 584 ** that the error code is probably EWOULDBLOCK already, 585 ** but if it isn't (for example, if we received a zero 586 ** length record) then this will force it to be correct. 587 */ 588 PORT_SetError(PR_WOULD_BLOCK_ERROR); 589 rv = SECFailure; 590 goto done; 591 } 592 SSL_TRC(30, ("%d: SSL[%d]: partial data ready, available=%d", 593 SSL_GETPID(), ss->fd, available)); 594 } 595 596 /* Dole out clear data to reader */ 597 amount = PR_MIN(len, available); 598 PORT_Memcpy(out, ss->gs.buf.buf + ss->gs.readOffset, amount); 599 if (!(flags & PR_MSG_PEEK)) { 600 ss->gs.readOffset += amount; 601 } 602 rv = amount; 603 604 SSL_TRC(30, ("%d: SSL[%d]: amount=%d available=%d", 605 SSL_GETPID(), ss->fd, amount, available)); 606 PRINT_BUF(4, (ss, "DoRecv receiving plaintext:", out, amount)); 607 608 done: 609 ssl_ReleaseRecvBufLock(ss); 610 return rv; 611 } 612 613 /************************************************************************/ 614 615 SSLKEAType 616 ssl_FindCertKEAType(CERTCertificate * cert) 617 { 618 SSLKEAType keaType = kt_null; 619 int tag; 620 621 if (!cert) goto loser; 622 623 tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); 624 625 switch (tag) { 626 case SEC_OID_X500_RSA_ENCRYPTION: 627 case SEC_OID_PKCS1_RSA_ENCRYPTION: 628 keaType = kt_rsa; 629 break; 630 631 case SEC_OID_X942_DIFFIE_HELMAN_KEY: 632 keaType = kt_dh; 633 break; 634 #ifdef NSS_ENABLE_ECC 635 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: 636 keaType = kt_ecdh; 637 break; 638 #endif /* NSS_ENABLE_ECC */ 639 default: 640 keaType = kt_null; 641 } 642 643 loser: 644 645 return keaType; 646 647 } 648 649 static const PRCallOnceType pristineCallOnce; 650 static PRCallOnceType setupServerCAListOnce; 651 652 static SECStatus serverCAListShutdown(void* appData, void* nssData) 653 { 654 PORT_Assert(ssl3_server_ca_list); 655 if (ssl3_server_ca_list) { 656 CERT_FreeDistNames(ssl3_server_ca_list); 657 ssl3_server_ca_list = NULL; 658 } 659 setupServerCAListOnce = pristineCallOnce; 660 return SECSuccess; 661 } 662 663 static PRStatus serverCAListSetup(void *arg) 664 { 665 CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg; 666 SECStatus rv = NSS_RegisterShutdown(serverCAListShutdown, NULL); 667 PORT_Assert(SECSuccess == rv); 668 if (SECSuccess == rv) { 669 ssl3_server_ca_list = CERT_GetSSLCACerts(dbHandle); 670 return PR_SUCCESS; 671 } 672 return PR_FAILURE; 673 } 674 675 676 /* XXX need to protect the data that gets changed here.!! */ 677 678 SECStatus 679 SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, 680 SECKEYPrivateKey *key, SSL3KEAType kea) 681 { 682 SECStatus rv; 683 sslSocket *ss; 684 sslServerCerts *sc; 685 SECKEYPublicKey * pubKey = NULL; 686 687 ss = ssl_FindSocket(fd); 688 if (!ss) { 689 return SECFailure; 690 } 691 692 /* Both key and cert must have a value or be NULL */ 693 /* Passing a value of NULL will turn off key exchange algorithms that were 694 * previously turned on */ 695 if (!cert != !key) { 696 PORT_SetError(SEC_ERROR_INVALID_ARGS); 697 return SECFailure; 698 } 699 700 /* make sure the key exchange is recognized */ 701 if ((kea >= kt_kea_size) || (kea < kt_null)) { 702 PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); 703 return SECFailure; 704 } 705 706 if (kea != ssl_FindCertKEAType(cert)) { 707 PORT_SetError(SSL_ERROR_CERT_KEA_MISMATCH); 708 return SECFailure; 709 } 710 711 sc = ss->serverCerts + kea; 712 /* load the server certificate */ 713 if (sc->serverCert != NULL) { 714 CERT_DestroyCertificate(sc->serverCert); 715 sc->serverCert = NULL; 716 } 717 if (cert) { 718 sc->serverCert = CERT_DupCertificate(cert); 719 if (!sc->serverCert) 720 goto loser; 721 /* get the size of the cert's public key, and remember it */ 722 pubKey = CERT_ExtractPublicKey(cert); 723 if (!pubKey) 724 goto loser; 725 sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey); 726 } 727 728 729 /* load the server cert chain */ 730 if (sc->serverCertChain != NULL) { 731 CERT_DestroyCertificateList(sc->serverCertChain); 732 sc->serverCertChain = NULL; 733 } 734 if (cert) { 735 sc->serverCertChain = CERT_CertChainFromCert( 736 sc->serverCert, certUsageSSLServer, PR_TRUE); 737 if (sc->serverCertChain == NULL) 738 goto loser; 739 } 740 741 /* load the private key */ 742 if (sc->serverKeyPair != NULL) { 743 ssl3_FreeKeyPair(sc->serverKeyPair); 744 sc->serverKeyPair = NULL; 745 } 746 if (key) { 747 SECKEYPrivateKey * keyCopy = NULL; 748 CK_MECHANISM_TYPE keyMech = CKM_INVALID_MECHANISM; 749 750 if (key->pkcs11Slot) { 751 PK11SlotInfo * bestSlot; 752 bestSlot = PK11_ReferenceSlot(key->pkcs11Slot); 753 if (bestSlot) { 754 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); 755 PK11_FreeSlot(bestSlot); 756 } 757 } 758 if (keyCopy == NULL) 759 keyMech = PK11_MapSignKeyType(key->keyType); 760 if (keyMech != CKM_INVALID_MECHANISM) { 761 PK11SlotInfo * bestSlot; 762 /* XXX Maybe should be bestSlotMultiple? */ 763 bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */); 764 if (bestSlot) { 765 keyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key); 766 PK11_FreeSlot(bestSlot); 767 } 768 } 769 if (keyCopy == NULL) 770 keyCopy = SECKEY_CopyPrivateKey(key); 771 if (keyCopy == NULL) 772 goto loser; 773 SECKEY_CacheStaticFlags(keyCopy); 774 sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, pubKey); 775 if (sc->serverKeyPair == NULL) { 776 SECKEY_DestroyPrivateKey(keyCopy); 777 goto loser; 778 } 779 pubKey = NULL; /* adopted by serverKeyPair */ 780 } 781 782 if (kea == kt_rsa && cert && sc->serverKeyBits > 512) { 783 if (ss->opt.noStepDown) { 784 /* disable all export ciphersuites */ 785 } else { 786 rv = ssl3_CreateRSAStepDownKeys(ss); 787 if (rv != SECSuccess) { 788 return SECFailure; /* err set by ssl3_CreateRSAStepDownKeys */ 789 } 790 } 791 } 792 793 /* Only do this once because it's global. */ 794 if (PR_SUCCESS == PR_CallOnceWithArg(&setupServerCAListOnce, 795 &serverCAListSetup, 796 (void *)(ss->dbHandle))) { 797 return SECSuccess; 798 } 799 800 loser: 801 if (pubKey) { 802 SECKEY_DestroyPublicKey(pubKey); 803 pubKey = NULL; 804 } 805 if (sc->serverCert != NULL) { 806 CERT_DestroyCertificate(sc->serverCert); 807 sc->serverCert = NULL; 808 } 809 if (sc->serverCertChain != NULL) { 810 CERT_DestroyCertificateList(sc->serverCertChain); 811 sc->serverCertChain = NULL; 812 } 813 if (sc->serverKeyPair != NULL) { 814 ssl3_FreeKeyPair(sc->serverKeyPair); 815 sc->serverKeyPair = NULL; 816 } 817 return SECFailure; 818 } 819 820 /************************************************************************/ 821 822 SECStatus 823 ssl_CreateSecurityInfo(sslSocket *ss) 824 { 825 SECStatus status; 826 827 /* initialize sslv2 socket to send data in the clear. */ 828 ssl2_UseClearSendFunc(ss); 829 830 ss->sec.blockSize = 1; 831 ss->sec.blockShift = 0; 832 833 ssl_GetXmitBufLock(ss); 834 status = sslBuffer_Grow(&ss->sec.writeBuf, 4096); 835 ssl_ReleaseXmitBufLock(ss); 836 837 return status; 838 } 839 840 SECStatus 841 ssl_CopySecurityInfo(sslSocket *ss, sslSocket *os) 842 { 843 ss->sec.send = os->sec.send; 844 ss->sec.isServer = os->sec.isServer; 845 ss->sec.keyBits = os->sec.keyBits; 846 ss->sec.secretKeyBits = os->sec.secretKeyBits; 847 848 ss->sec.peerCert = CERT_DupCertificate(os->sec.peerCert); 849 if (os->sec.peerCert && !ss->sec.peerCert) 850 goto loser; 851 852 ss->sec.cache = os->sec.cache; 853 ss->sec.uncache = os->sec.uncache; 854 855 /* we don't dup the connection info. */ 856 857 ss->sec.sendSequence = os->sec.sendSequence; 858 ss->sec.rcvSequence = os->sec.rcvSequence; 859 860 if (os->sec.hash && os->sec.hashcx) { 861 ss->sec.hash = os->sec.hash; 862 ss->sec.hashcx = os->sec.hash->clone(os->sec.hashcx); 863 if (os->sec.hashcx && !ss->sec.hashcx) 864 goto loser; 865 } else { 866 ss->sec.hash = NULL; 867 ss->sec.hashcx = NULL; 868 } 869 870 SECITEM_CopyItem(0, &ss->sec.sendSecret, &os->sec.sendSecret); 871 if (os->sec.sendSecret.data && !ss->sec.sendSecret.data) 872 goto loser; 873 SECITEM_CopyItem(0, &ss->sec.rcvSecret, &os->sec.rcvSecret); 874 if (os->sec.rcvSecret.data && !ss->sec.rcvSecret.data) 875 goto loser; 876 877 /* XXX following code is wrong if either cx != 0 */ 878 PORT_Assert(os->sec.readcx == 0); 879 PORT_Assert(os->sec.writecx == 0); 880 ss->sec.readcx = os->sec.readcx; 881 ss->sec.writecx = os->sec.writecx; 882 ss->sec.destroy = 0; 883 884 ss->sec.enc = os->sec.enc; 885 ss->sec.dec = os->sec.dec; 886 887 ss->sec.blockShift = os->sec.blockShift; 888 ss->sec.blockSize = os->sec.blockSize; 889 890 return SECSuccess; 891 892 loser: 893 return SECFailure; 894 } 895 896 /* Reset sec back to its initial state. 897 ** Caller holds any relevant locks. 898 */ 899 void 900 ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) 901 { 902 /* Destroy MAC */ 903 if (sec->hash && sec->hashcx) { 904 (*sec->hash->destroy)(sec->hashcx, PR_TRUE); 905 sec->hashcx = NULL; 906 sec->hash = NULL; 907 } 908 SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); 909 SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); 910 911 /* Destroy ciphers */ 912 if (sec->destroy) { 913 (*sec->destroy)(sec->readcx, PR_TRUE); 914 (*sec->destroy)(sec->writecx, PR_TRUE); 915 sec->readcx = NULL; 916 sec->writecx = NULL; 917 } else { 918 PORT_Assert(sec->readcx == 0); 919 PORT_Assert(sec->writecx == 0); 920 } 921 sec->readcx = 0; 922 sec->writecx = 0; 923 924 if (sec->localCert) { 925 CERT_DestroyCertificate(sec->localCert); 926 sec->localCert = NULL; 927 } 928 if (sec->peerCert) { 929 CERT_DestroyCertificate(sec->peerCert); 930 sec->peerCert = NULL; 931 } 932 if (sec->peerKey) { 933 SECKEY_DestroyPublicKey(sec->peerKey); 934 sec->peerKey = NULL; 935 } 936 937 /* cleanup the ci */ 938 if (sec->ci.sid != NULL) { 939 ssl_FreeSID(sec->ci.sid); 940 } 941 PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); 942 if (doMemset) { 943 memset(&sec->ci, 0, sizeof sec->ci); 944 } 945 946 } 947 948 /* 949 ** Called from SSL_ResetHandshake (above), and 950 ** from ssl_FreeSocket in sslsock.c 951 ** Caller should hold relevant locks (e.g. XmitBufLock) 952 */ 953 void 954 ssl_DestroySecurityInfo(sslSecurityInfo *sec) 955 { 956 ssl_ResetSecurityInfo(sec, PR_FALSE); 957 958 PORT_ZFree(sec->writeBuf.buf, sec->writeBuf.space); 959 sec->writeBuf.buf = 0; 960 961 memset(sec, 0, sizeof *sec); 962 } 963 964 /************************************************************************/ 965 966 int 967 ssl_SecureConnect(sslSocket *ss, const PRNetAddr *sa) 968 { 969 PRFileDesc *osfd = ss->fd->lower; 970 int rv; 971 972 if ( ss->opt.handshakeAsServer ) { 973 ss->securityHandshake = ssl2_BeginServerHandshake; 974 ss->handshaking = sslHandshakingAsServer; 975 } else { 976 ss->securityHandshake = ssl2_BeginClientHandshake; 977 ss->handshaking = sslHandshakingAsClient; 978 } 979 980 /* connect to server */ 981 rv = osfd->methods->connect(osfd, sa, ss->cTimeout); 982 if (rv == PR_SUCCESS) { 983 ss->TCPconnected = 1; 984 } else { 985 int err = PR_GetError(); 986 SSL_DBG(("%d: SSL[%d]: connect failed, errno=%d", 987 SSL_GETPID(), ss->fd, err)); 988 if (err == PR_IS_CONNECTED_ERROR) { 989 ss->TCPconnected = 1; 990 } 991 } 992 993 SSL_TRC(5, ("%d: SSL[%d]: secure connect completed, rv == %d", 994 SSL_GETPID(), ss->fd, rv)); 995 return rv; 996 } 997 998 /* 999 * The TLS 1.2 RFC 5246, Section 7.2.1 says: 1000 * 1001 * Unless some other fatal alert has been transmitted, each party is 1002 * required to send a close_notify alert before closing the write side 1003 * of the connection. The other party MUST respond with a close_notify 1004 * alert of its own and close down the connection immediately, 1005 * discarding any pending writes. It is not required for the initiator 1006 * of the close to wait for the responding close_notify alert before 1007 * closing the read side of the connection. 1008 * 1009 * The second sentence requires that we send a close_notify alert when we 1010 * have received a close_notify alert. In practice, all SSL implementations 1011 * close the socket immediately after sending a close_notify alert (which is 1012 * allowed by the third sentence), so responding with a close_notify alert 1013 * would result in a write failure with the ECONNRESET error. This is why 1014 * we don't respond with a close_notify alert. 1015 * 1016 * Also, in the unlikely event that the TCP pipe is full and the peer stops 1017 * reading, the SSL3_SendAlert call in ssl_SecureClose and ssl_SecureShutdown 1018 * may block indefinitely in blocking mode, and may fail (without retrying) 1019 * in non-blocking mode. 1020 */ 1021 1022 int 1023 ssl_SecureClose(sslSocket *ss) 1024 { 1025 int rv; 1026 1027 if (ss->version >= SSL_LIBRARY_VERSION_3_0 && 1028 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && 1029 ss->firstHsDone && 1030 !ss->recvdCloseNotify && 1031 ss->ssl3.initialized) { 1032 1033 /* We don't want the final alert to be Nagle delayed. */ 1034 if (!ss->delayDisabled) { 1035 ssl_EnableNagleDelay(ss, PR_FALSE); 1036 ss->delayDisabled = 1; 1037 } 1038 1039 (void) SSL3_SendAlert(ss, alert_warning, close_notify); 1040 } 1041 rv = ssl_DefClose(ss); 1042 return rv; 1043 } 1044 1045 /* Caller handles all locking */ 1046 int 1047 ssl_SecureShutdown(sslSocket *ss, int nsprHow) 1048 { 1049 PRFileDesc *osfd = ss->fd->lower; 1050 int rv; 1051 PRIntn sslHow = nsprHow + 1; 1052 1053 if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) { 1054 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1055 return PR_FAILURE; 1056 } 1057 1058 if ((sslHow & ssl_SHUTDOWN_SEND) != 0 && 1059 ss->version >= SSL_LIBRARY_VERSION_3_0 && 1060 !(ss->shutdownHow & ssl_SHUTDOWN_SEND) && 1061 ss->firstHsDone && 1062 !ss->recvdCloseNotify && 1063 ss->ssl3.initialized) { 1064 1065 (void) SSL3_SendAlert(ss, alert_warning, close_notify); 1066 } 1067 1068 rv = osfd->methods->shutdown(osfd, nsprHow); 1069 1070 ss->shutdownHow |= sslHow; 1071 1072 return rv; 1073 } 1074 1075 /************************************************************************/ 1076 1077 1078 int 1079 ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) 1080 { 1081 sslSecurityInfo *sec; 1082 int rv = 0; 1083 1084 sec = &ss->sec; 1085 1086 if (ss->shutdownHow & ssl_SHUTDOWN_RCV) { 1087 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); 1088 return PR_FAILURE; 1089 } 1090 if (flags & ~PR_MSG_PEEK) { 1091 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1092 return PR_FAILURE; 1093 } 1094 1095 if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { 1096 ssl_GetXmitBufLock(ss); 1097 if (ss->pendingBuf.len != 0) { 1098 rv = ssl_SendSavedWriteData(ss); 1099 if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { 1100 ssl_ReleaseXmitBufLock(ss); 1101 return SECFailure; 1102 } 1103 /* XXX short write? */ 1104 } 1105 ssl_ReleaseXmitBufLock(ss); 1106 } 1107 1108 rv = 0; 1109 /* If any of these is non-zero, the initial handshake is not done. */ 1110 if (!ss->firstHsDone) { 1111 ssl_Get1stHandshakeLock(ss); 1112 if (ss->handshake || ss->nextHandshake || ss->securityHandshake) { 1113 rv = ssl_Do1stHandshake(ss); 1114 } 1115 ssl_Release1stHandshakeLock(ss); 1116 } 1117 if (rv < 0) { 1118 return rv; 1119 } 1120 1121 if (len == 0) return 0; 1122 1123 rv = DoRecv(ss, (unsigned char*) buf, len, flags); 1124 SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)", 1125 SSL_GETPID(), ss->fd, rv, PORT_GetError())); 1126 return rv; 1127 } 1128 1129 int 1130 ssl_SecureRead(sslSocket *ss, unsigned char *buf, int len) 1131 { 1132 return ssl_SecureRecv(ss, buf, len, 0); 1133 } 1134 1135 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */ 1136 int 1137 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) 1138 { 1139 int rv = 0; 1140 1141 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", 1142 SSL_GETPID(), ss->fd, len)); 1143 1144 if (ss->shutdownHow & ssl_SHUTDOWN_SEND) { 1145 PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR); 1146 rv = PR_FAILURE; 1147 goto done; 1148 } 1149 if (flags) { 1150 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1151 rv = PR_FAILURE; 1152 goto done; 1153 } 1154 1155 ssl_GetXmitBufLock(ss); 1156 if (ss->pendingBuf.len != 0) { 1157 PORT_Assert(ss->pendingBuf.len > 0); 1158 rv = ssl_SendSavedWriteData(ss); 1159 if (rv >= 0 && ss->pendingBuf.len != 0) { 1160 PORT_Assert(ss->pendingBuf.len > 0); 1161 PORT_SetError(PR_WOULD_BLOCK_ERROR); 1162 rv = SECFailure; 1163 } 1164 } 1165 ssl_ReleaseXmitBufLock(ss); 1166 if (rv < 0) { 1167 goto done; 1168 } 1169 1170 if (len > 0) 1171 ss->writerThread = PR_GetCurrentThread(); 1172 /* If any of these is non-zero, the initial handshake is not done. */ 1173 if (!ss->firstHsDone) { 1174 ssl_Get1stHandshakeLock(ss); 1175 if (ss->handshake || ss->nextHandshake || ss->securityHandshake) { 1176 rv = ssl_Do1stHandshake(ss); 1177 } 1178 ssl_Release1stHandshakeLock(ss); 1179 } 1180 if (rv < 0) { 1181 ss->writerThread = NULL; 1182 goto done; 1183 } 1184 1185 /* Check for zero length writes after we do housekeeping so we make forward 1186 * progress. 1187 */ 1188 if (len == 0) { 1189 rv = 0; 1190 goto done; 1191 } 1192 PORT_Assert(buf != NULL); 1193 if (!buf) { 1194 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 1195 rv = PR_FAILURE; 1196 goto done; 1197 } 1198 1199 /* Send out the data using one of these functions: 1200 * ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, 1201 * ssl3_SendApplicationData 1202 */ 1203 ssl_GetXmitBufLock(ss); 1204 rv = (*ss->sec.send)(ss, buf, len, flags); 1205 ssl_ReleaseXmitBufLock(ss); 1206 ss->writerThread = NULL; 1207 done: 1208 if (rv < 0) { 1209 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d", 1210 SSL_GETPID(), ss->fd, rv, PORT_GetError())); 1211 } else { 1212 SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count", 1213 SSL_GETPID(), ss->fd, rv)); 1214 } 1215 return rv; 1216 } 1217 1218 int 1219 ssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len) 1220 { 1221 return ssl_SecureSend(ss, buf, len, 0); 1222 } 1223 1224 SECStatus 1225 SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg) 1226 { 1227 sslSocket *ss; 1228 1229 ss = ssl_FindSocket(fd); 1230 if (!ss) { 1231 SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook", 1232 SSL_GETPID(), fd)); 1233 return SECFailure; 1234 } 1235 1236 ss->handleBadCert = f; 1237 ss->badCertArg = arg; 1238 1239 return SECSuccess; 1240 } 1241 1242 /* 1243 * Allow the application to pass the url or hostname into the SSL library 1244 * so that we can do some checking on it. 1245 */ 1246 SECStatus 1247 SSL_SetURL(PRFileDesc *fd, const char *url) 1248 { 1249 sslSocket * ss = ssl_FindSocket(fd); 1250 SECStatus rv = SECSuccess; 1251 1252 if (!ss) { 1253 SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL", 1254 SSL_GETPID(), fd)); 1255 return SECFailure; 1256 } 1257 ssl_Get1stHandshakeLock(ss); 1258 ssl_GetSSL3HandshakeLock(ss); 1259 1260 if ( ss->url ) { 1261 PORT_Free((void *)ss->url); /* CONST */ 1262 } 1263 1264 ss->url = (const char *)PORT_Strdup(url); 1265 if ( ss->url == NULL ) { 1266 rv = SECFailure; 1267 } 1268 1269 ssl_ReleaseSSL3HandshakeLock(ss); 1270 ssl_Release1stHandshakeLock(ss); 1271 1272 return rv; 1273 } 1274 1275 /* 1276 ** Returns Negative number on error, zero or greater on success. 1277 ** Returns the amount of data immediately available to be read. 1278 */ 1279 int 1280 SSL_DataPending(PRFileDesc *fd) 1281 { 1282 sslSocket *ss; 1283 int rv = 0; 1284 1285 ss = ssl_FindSocket(fd); 1286 1287 if (ss && ss->opt.useSecurity) { 1288 1289 ssl_Get1stHandshakeLock(ss); 1290 ssl_GetSSL3HandshakeLock(ss); 1291 1292 ssl_GetRecvBufLock(ss); 1293 rv = ss->gs.writeOffset - ss->gs.readOffset; 1294 ssl_ReleaseRecvBufLock(ss); 1295 1296 ssl_ReleaseSSL3HandshakeLock(ss); 1297 ssl_Release1stHandshakeLock(ss); 1298 } 1299 1300 return rv; 1301 } 1302 1303 SECStatus 1304 SSL_InvalidateSession(PRFileDesc *fd) 1305 { 1306 sslSocket * ss = ssl_FindSocket(fd); 1307 SECStatus rv = SECFailure; 1308 1309 if (ss) { 1310 ssl_Get1stHandshakeLock(ss); 1311 ssl_GetSSL3HandshakeLock(ss); 1312 1313 if (ss->sec.ci.sid) { 1314 ss->sec.uncache(ss->sec.ci.sid); 1315 rv = SECSuccess; 1316 } 1317 1318 ssl_ReleaseSSL3HandshakeLock(ss); 1319 ssl_Release1stHandshakeLock(ss); 1320 } 1321 return rv; 1322 } 1323 1324 SECItem * 1325 SSL_GetSessionID(PRFileDesc *fd) 1326 { 1327 sslSocket * ss; 1328 SECItem * item = NULL; 1329 1330 ss = ssl_FindSocket(fd); 1331 if (ss) { 1332 ssl_Get1stHandshakeLock(ss); 1333 ssl_GetSSL3HandshakeLock(ss); 1334 1335 if (ss->opt.useSecurity && ss->firstHsDone && ss->sec.ci.sid) { 1336 item = (SECItem *)PORT_Alloc(sizeof(SECItem)); 1337 if (item) { 1338 sslSessionID * sid = ss->sec.ci.sid; 1339 if (sid->version < SSL_LIBRARY_VERSION_3_0) { 1340 item->len = SSL2_SESSIONID_BYTES; 1341 item->data = (unsigned char*)PORT_Alloc(item->len); 1342 PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len); 1343 } else { 1344 item->len = sid->u.ssl3.sessionIDLength; 1345 item->data = (unsigned char*)PORT_Alloc(item->len); 1346 PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len); 1347 } 1348 } 1349 } 1350 1351 ssl_ReleaseSSL3HandshakeLock(ss); 1352 ssl_Release1stHandshakeLock(ss); 1353 } 1354 return item; 1355 } 1356 1357 SECStatus 1358 SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle) 1359 { 1360 sslSocket * ss; 1361 1362 ss = ssl_FindSocket(fd); 1363 if (!ss) 1364 return SECFailure; 1365 if (!dbHandle) { 1366 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1367 return SECFailure; 1368 } 1369 ss->dbHandle = dbHandle; 1370 return SECSuccess; 1371 } 1372 1373 /* 1374 * attempt to restart the handshake after asynchronously handling 1375 * a request for the client's certificate. 1376 * 1377 * inputs: 1378 * cert Client cert chosen by application. 1379 * Note: ssl takes this reference, and does not bump the 1380 * reference count. The caller should drop its reference 1381 * without calling CERT_DestroyCert after calling this function. 1382 * 1383 * key Private key associated with cert. This function makes a 1384 * copy of the private key, so the caller remains responsible 1385 * for destroying its copy after this function returns. 1386 * 1387 * certChain Chain of signers for cert. 1388 * Note: ssl takes this reference, and does not copy the chain. 1389 * The caller should drop its reference without destroying the 1390 * chain. SSL will free the chain when it is done with it. 1391 * 1392 * Return value: XXX 1393 * 1394 * XXX This code only works on the initial handshake on a connection, XXX 1395 * It does not work on a subsequent handshake (redo). 1396 */ 1397 int 1398 SSL_RestartHandshakeAfterCertReq(sslSocket * ss, 1399 CERTCertificate * cert, 1400 SECKEYPrivateKey * key, 1401 CERTCertificateList *certChain) 1402 { 1403 int ret; 1404 1405 ssl_Get1stHandshakeLock(ss); /************************************/ 1406 1407 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 1408 ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain); 1409 } else { 1410 ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key); 1411 } 1412 1413 ssl_Release1stHandshakeLock(ss); /************************************/ 1414 return ret; 1415 } 1416 1417 1418 /* restart an SSL connection that we stopped to run certificate dialogs 1419 ** XXX Need to document here how an application marks a cert to show that 1420 ** the application has accepted it (overridden CERT_VerifyCert). 1421 * 1422 * XXX This code only works on the initial handshake on a connection, XXX 1423 * It does not work on a subsequent handshake (redo). 1424 * 1425 * Return value: XXX 1426 */ 1427 int 1428 SSL_RestartHandshakeAfterServerCert(sslSocket *ss) 1429 { 1430 int rv = SECSuccess; 1431 1432 ssl_Get1stHandshakeLock(ss); 1433 1434 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { 1435 rv = ssl3_RestartHandshakeAfterServerCert(ss); 1436 } else { 1437 rv = ssl2_RestartHandshakeAfterServerCert(ss); 1438 } 1439 1440 ssl_Release1stHandshakeLock(ss); 1441 return rv; 1442 } 1443