PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) ); PORT_Assert( ssl_HaveXmitBufLock(ss));
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey){    PK11SymKey *	pms 		= NULL;    SECStatus           rv    		= SECFailure;    PRBool              isTLS;    CK_MECHANISM_TYPE	target;    SECKEYDHParams	dhParam;		/* DH parameters */    SECKEYPublicKey	*pubKey = NULL;		/* Ephemeral DH key */    SECKEYPrivateKey	*privKey = NULL;	/* Ephemeral DH key */    PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );    PORT_Assert( ssl_HaveXmitBufLock(ss));    isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);    /* Copy DH parameters from server key */    dhParam.prime.data = svrPubKey->u.dh.prime.data;    dhParam.prime.len = svrPubKey->u.dh.prime.len;    dhParam.base.data = svrPubKey->u.dh.base.data;    dhParam.base.len = svrPubKey->u.dh.base.len;    /* Generate ephemeral DH keypair */    privKey = SECKEY_CreateDHPrivateKey(&dhParam, &pubKey, NULL);    if (!privKey || !pubKey) {	    ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL);	    rv = SECFailure;	    goto loser;    }    PRINT_BUF(50, (ss, "DH public value:",					pubKey->u.dh.publicValue.data,					pubKey->u.dh.publicValue.len));    if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH;    else target = CKM_SSL3_MASTER_KEY_DERIVE_DH;    /* Determine the PMS */    pms = PK11_PubDerive(privKey, svrPubKey, PR_FALSE, NULL, NULL,			    CKM_DH_PKCS_DERIVE, target, CKA_DERIVE, 0, NULL);    if (pms == NULL) {	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);	goto loser;    }    SECKEY_DestroyPrivateKey(privKey);    privKey = NULL;    rv = ssl3_InitPendingCipherSpec(ss,  pms);    PK11_FreeSymKey(pms); pms = NULL;    if (rv != SECSuccess) {	ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);	goto loser;    }    rv = ssl3_AppendHandshakeHeader(ss, client_key_exchange, 					pubKey->u.dh.publicValue.len + 2);    if (rv != SECSuccess) {	goto loser;	/* err set by ssl3_AppendHandshake* */    }    rv = ssl3_AppendHandshakeVariable(ss, 					pubKey->u.dh.publicValue.data,					pubKey->u.dh.publicValue.len, 2);    SECKEY_DestroyPublicKey(pubKey);    pubKey = NULL;    if (rv != SECSuccess) {	goto loser;	/* err set by ssl3_AppendHandshake* */    }    rv = SECSuccess;loser:    if(pms) PK11_FreeSymKey(pms);    if(privKey) SECKEY_DestroyPrivateKey(privKey);    if(pubKey) SECKEY_DestroyPublicKey(pubKey);    return rv;}