rv = PK11_DigestBegin(ss->ssl3->hs.md5); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); return rv; } rv = PK11_DigestBegin(ss->ssl3->hs.sha); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return rv; }
if (ss->opt.bypassPKCS11) { MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx); SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx); } else { rv = PK11_DigestBegin(ss->ssl3.hs.md5); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); return rv; } rv = PK11_DigestBegin(ss->ssl3.hs.sha); if (rv != SECSuccess) { ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE); return rv; } }
ssl3_SendClientHello(sslSocket *ss){    sslSessionID *   sid;    ssl3CipherSpec * cwSpec;    SECStatus        rv;    int              i;    int              length;    int              num_suites;    int              actual_count = 0;    SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(),		ss->fd));    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );    PORT_Assert( ssl_HaveXmitBufLock(ss) );    rv = ssl3_InitState(ss);    if (rv != SECSuccess) {	return rv;		/* ssl3_InitState has set the error code. */    }    SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",	    SSL_GETPID(), ss->fd ));    rv = PK11_DigestBegin(ss->ssl3->hs.md5);    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);	return rv;    }    rv = PK11_DigestBegin(ss->ssl3->hs.sha);    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);	return rv;    }    /* We ignore ss->sec.ci.sid here, and use ssl_Lookup because Lookup     * handles expired entries and other details.     * XXX If we've been called from ssl2_BeginClientHandshake, then     * this lookup is duplicative and wasteful.     */    sid = (ss->noCache) ? NULL	    : ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url);    /* We can't resume based on a different token. If the sid exists,     * make sure the token that holds the master secret still exists ...     * If we previously did client-auth, make sure that the token that holds     * the private key still exists, is logged in, hasn't been removed, etc.     */    if (sid) {	PK11SlotInfo *slot;	PRBool sidOK = PR_TRUE;	slot = (!sid->u.ssl3.masterValid) ? NULL :	                     SECMOD_LookupSlot(sid->u.ssl3.masterModuleID,	                                       sid->u.ssl3.masterSlotID);	if (slot == NULL) {	   sidOK = PR_FALSE;	} else {	    PK11SymKey *wrapKey = NULL;	    if (!PK11_IsPresent(slot) ||		((wrapKey = PK11_GetWrapKey(slot, sid->u.ssl3.masterWrapIndex,					    sid->u.ssl3.masterWrapMech,					    sid->u.ssl3.masterWrapSeries,					    ss->pkcs11PinArg)) == NULL) ) {		sidOK = PR_FALSE;	    }	    if (wrapKey) PK11_FreeSymKey(wrapKey);	    PK11_FreeSlot(slot);	    slot = NULL;	}	/* If we previously did client-auth, make sure that the token that	** holds the private key still exists, is logged in, hasn't been	** removed, etc.	*/	if (sidOK && !ssl3_ClientAuthTokenPresent(sid)) {	    sidOK = PR_FALSE;	}	if (!sidOK) {	    ++ssl3stats.sch_sid_cache_not_ok;	    (*ss->sec.uncache)(sid);	    ssl_FreeSID(sid);	    sid = NULL;	}    }    if (sid) {	++ssl3stats.sch_sid_cache_hits;	rv = ssl3_NegotiateVersion(ss, sid->version);	if (rv != SECSuccess)	    return rv;	/* error code was set */	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,		      sid->u.ssl3.sessionIDLength));	ss->ssl3->policy = sid->u.ssl3.policy;    } else {	++ssl3stats.sch_sid_cache_misses;	rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_3_1_TLS);	if (rv != SECSuccess)	    return rv;	/* error code was set */	sid = ssl3_NewSessionID(ss, PR_FALSE);	if (!sid) {	    return SECFailure;	/* memory error is set */        }    }    ssl_GetSpecWriteLock(ss);    cwSpec = ss->ssl3->cwSpec;    if (cwSpec->mac_def->mac == mac_null) {	/* SSL records are not being MACed. */	cwSpec->version = ss->version;    }    ssl_ReleaseSpecWriteLock(ss);    if (ss->sec.ci.sid != NULL) {	ssl_FreeSID(ss->sec.ci.sid);	/* decrement ref count, free if zero */    }    ss->sec.ci.sid = sid;    ss->sec.send = ssl3_SendApplicationData;    /* shouldn't get here if SSL3 is disabled, but ... */    PORT_Assert(ss->enableSSL3 || ss->enableTLS);    if (!ss->enableSSL3 && !ss->enableTLS) {	PORT_SetError(SSL_ERROR_SSL_DISABLED);    	return SECFailure;    }    /* how many suites does our PKCS11 support (regardless of policy)? */    num_suites = ssl3_config_match_init(ss);    if (!num_suites)    	return SECFailure;	/* ssl3_config_match_init has set error code. */    /* how many suites are permitted by policy and user preference? */    num_suites = count_cipher_suites(ss, ss->ssl3->policy, PR_TRUE);    if (!num_suites)    	return SECFailure;	/* count_cipher_suites has set error code. */    length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH +	1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) +	2 + num_suites*sizeof(ssl3CipherSuite) +	1 + compressionMethodsCount;    rv = ssl3_AppendHandshakeHeader(ss, client_hello, length);    if (rv != SECSuccess) {	return rv;	/* err set by ssl3_AppendHandshake* */    }    ss->clientHelloVersion = ss->version;    rv = ssl3_AppendHandshakeNumber(ss, ss->clientHelloVersion, 2);    if (rv != SECSuccess) {	return rv;	/* err set by ssl3_AppendHandshake* */    }    rv = ssl3_GetNewRandom(&ss->ssl3->hs.client_random);    if (rv != SECSuccess) {	return rv;	/* err set by GetNewRandom. */    }    rv = ssl3_AppendHandshake(ss, &ss->ssl3->hs.client_random,                              SSL3_RANDOM_LENGTH);    if (rv != SECSuccess) {	return rv;	/* err set by ssl3_AppendHandshake* */    }    if (sid)	rv = ssl3_AppendHandshakeVariable(	    ss, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, 1);    else	rv = ssl3_AppendHandshakeVariable(ss, NULL, 0, 1);    if (rv != SECSuccess) {	return rv;	/* err set by ssl3_AppendHandshake* */    }    rv = ssl3_AppendHandshakeNumber(ss, num_suites*sizeof(ssl3CipherSuite), 2);    if (rv != SECSuccess) {	return rv;	/* err set by ssl3_AppendHandshake* */    }    for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];	if (config_match(suite, ss->ssl3->policy, PR_TRUE)) {	    actual_count++;	    if (actual_count > num_suites) {		/* set error card removal/insertion error */		PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);		return SECFailure;	    }	    rv = ssl3_AppendHandshakeNumber(ss, suite->cipher_suite,					    sizeof(ssl3CipherSuite));	    if (rv != SECSuccess) {		return rv;	/* err set by ssl3_AppendHandshake* */	    }	}    }    /* if cards were removed or inserted between count_cipher_suites and     * generating our list, detect the error here rather than send it off to     * the server.. */    if (actual_count != num_suites) {	/* Card removal/insertion error */	PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);	return SECFailure;    }    rv = ssl3_AppendHandshakeNumber(ss, compressionMethodsCount, 1);    if (rv != SECSuccess) {	return rv;	/* err set by ssl3_AppendHandshake* */    }    for (i = 0; i < compressionMethodsCount; i++) {	rv = ssl3_AppendHandshakeNumber(ss, compressions[i], 1);	if (rv != SECSuccess) {	    return rv;	/* err set by ssl3_AppendHandshake* */	}    }    rv = ssl3_FlushHandshake(ss, 0);    if (rv != SECSuccess) {	return rv;	/* error code set by ssl3_FlushHandshake */    }    ss->ssl3->hs.ws = wait_server_hello;    return rv;}