PORT_Assert( ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ssl_HaveRecvBufLock(ss)   );
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss)   );
ssl2_HandleClientCertificate(sslSocket *    ss,                              PRUint8        certType,	/* XXX unused */			     PRUint8 *      cd, 			     unsigned int   cdLen,			     PRUint8 *      response,			     unsigned int   responseLen){    CERTCertificate *cert	= NULL;    SECKEYPublicKey *pubKey	= NULL;    VFYContext *     vfy	= NULL;    SECItem *        derCert;    SECStatus        rv		= SECFailure;    SECItem          certItem;    SECItem          rep;    PORT_Assert( ssl_Have1stHandshakeLock(ss) );    PORT_Assert( ssl_HaveRecvBufLock(ss)   );    /* Extract the certificate */    certItem.data = cd;    certItem.len  = cdLen;    cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,			 	   PR_FALSE, PR_TRUE);    if (cert == NULL) {	goto loser;    }    /* save the certificate, since the auth routine will need it */    ss->sec.peerCert = cert;    /* Extract the public key */    pubKey = CERT_ExtractPublicKey(cert);    if (!pubKey)     	goto loser;        /* Verify the response data... */    rep.data = response;    rep.len = responseLen;    /* SSL 2.0 only supports RSA certs, so we don't have to worry about     * DSA here. */    vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,			    ss->pkcs11PinArg);    if (!vfy)     	goto loser;    rv = VFY_Begin(vfy);    if (rv)     	goto loser;    rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);    if (rv)     	goto loser;    rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);    if (rv)     	goto loser;    rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);    if (rv)     	goto loser;    derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;    rv = VFY_Update(vfy, derCert->data, derCert->len);    if (rv)     	goto loser;    rv = VFY_End(vfy);    if (rv)     	goto loser;    /* Now ask the server application if it likes the certificate... */    rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,					    ss->fd, PR_TRUE, PR_TRUE);    /* Hey, it liked it. */    if (SECSuccess == rv) 	goto done;loser:    ss->sec.peerCert = NULL;    CERT_DestroyCertificate(cert);done:    VFY_DestroyContext(vfy, PR_TRUE);    SECKEY_DestroyPublicKey(pubKey);    return rv;}