/* Reset sec back to its initial state. ** Caller holds any relevant locks. */ void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) { if (sec->localCert) { CERT_DestroyCertificate(sec->localCert); sec->localCert = NULL; } if (sec->peerCert) { CERT_DestroyCertificate(sec->peerCert); sec->peerCert = NULL; } if (sec->peerKey) { SECKEY_DestroyPublicKey(sec->peerKey); sec->peerKey = NULL; } /* cleanup the ci */ if (sec->ci.sid != NULL) { ssl_FreeSID(sec->ci.sid); } PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); if (doMemset) { memset(&sec->ci, 0, sizeof sec->ci); } }
/* Reset sec back to its initial state. ** Caller holds any relevant locks. */ void ssl_ResetSecurityInfo(sslSecurityInfo *sec, PRBool doMemset) { /* Destroy MAC */ if (sec->hash && sec->hashcx) { (*sec->hash->destroy)(sec->hashcx, PR_TRUE); sec->hashcx = NULL; sec->hash = NULL; } SECITEM_ZfreeItem(&sec->sendSecret, PR_FALSE); SECITEM_ZfreeItem(&sec->rcvSecret, PR_FALSE); /* Destroy ciphers */ if (sec->destroy) { (*sec->destroy)(sec->readcx, PR_TRUE); (*sec->destroy)(sec->writecx, PR_TRUE); sec->readcx = NULL; sec->writecx = NULL; } else { PORT_Assert(sec->readcx == 0); PORT_Assert(sec->writecx == 0); } sec->readcx = 0; sec->writecx = 0; if (sec->localCert) { CERT_DestroyCertificate(sec->localCert); sec->localCert = NULL; } if (sec->peerCert) { CERT_DestroyCertificate(sec->peerCert); sec->peerCert = NULL; } if (sec->peerKey) { SECKEY_DestroyPublicKey(sec->peerKey); sec->peerKey = NULL; } /* cleanup the ci */ if (sec->ci.sid != NULL) { ssl_FreeSID(sec->ci.sid); } PORT_ZFree(sec->ci.sendBuf.buf, sec->ci.sendBuf.space); if (doMemset) { memset(&sec->ci, 0, sizeof sec->ci); } }
/* Sends out the initial client Hello message on the connection. * Acquires and releases the socket's xmitBufLock. */ SECStatus ssl_BeginClientHandshake(sslSocket *ss) { sslSessionID *sid; SECStatus rv; PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss)); ss->sec.isServer = PR_FALSE; ssl_ChooseSessionIDProcs(&ss->sec); rv = ssl_CheckConfigSanity(ss); if (rv != SECSuccess) goto loser; /* Get peer name of server */ rv = ssl_GetPeerInfo(ss); if (rv < 0) { #ifdef HPUX11 /* * On some HP-UX B.11.00 systems, getpeername() occasionally * fails with ENOTCONN after a successful completion of * non-blocking connect. I found that if we do a write() * and then retry getpeername(), it will work. */ if (PR_GetError() == PR_NOT_CONNECTED_ERROR) { char dummy; (void)PR_Write(ss->fd->lower, &dummy, 0); rv = ssl_GetPeerInfo(ss); if (rv < 0) { goto loser; } } #else goto loser; #endif } SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd)); /* Try to find server in our session-id cache */ if (ss->opt.noCache) { sid = NULL; } else { sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); } if (sid) { if (sid->version >= ss->vrange.min && sid->version <= ss->vrange.max) { PORT_Assert(!ss->sec.localCert); ss->sec.localCert = CERT_DupCertificate(sid->localCert); } else { ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } } if (!sid) { sid = PORT_ZNew(sslSessionID); if (!sid) { goto loser; } sid->references = 1; sid->cached = never_cached; sid->addr = ss->sec.ci.peer; sid->port = ss->sec.ci.port; if (ss->peerID != NULL) { sid->peerID = PORT_Strdup(ss->peerID); } if (ss->url != NULL) { sid->urlSvrName = PORT_Strdup(ss->url); } } ss->sec.ci.sid = sid; PORT_Assert(sid != NULL); ss->gs.state = GS_INIT; ss->handshake = ssl_GatherRecord1stHandshake; /* ssl3_SendClientHello will override this if it succeeds. */ ss->version = SSL_LIBRARY_VERSION_3_0; ssl_GetSSL3HandshakeLock(ss); ssl_GetXmitBufLock(ss); rv = ssl3_SendClientHello(ss, client_hello_initial); ssl_ReleaseXmitBufLock(ss); ssl_ReleaseSSL3HandshakeLock(ss); return rv; loser: return SECFailure; }