⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslconn.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 C
📖 第 1 页 / 共 5 页
字号:
    while (conn->m_sockStat == NULL ||           conn->m_sockStat->m_cipherName == NULL) {        SSM_DEBUG("Oops, the security status has not been updated.  "                  "Waiting...\n");        SSM_WaitResource(SSMRESOURCE(conn), PR_INTERVAL_NO_TIMEOUT);    }    /* XXX is this really necessary? */    if (conn->m_sockStat == NULL) {        SSM_DEBUG("No socket status on dead socket.\n");        SSM_UnlockResource(SSMRESOURCE(conn));        goto loser;    }    /* it's probably OK to unlock it here */    SSM_UnlockResource(SSMRESOURCE(conn));    /* we have a socket status object. */    rv = SSMSSLSocketStatus_Pickle(&conn->m_sockStat->super, len, blob);    if (rv != PR_SUCCESS) {        SSM_DEBUG("Failed to pickle the socket status.\n");        goto loser;    }    /* get the security level */    *securityLevel = conn->m_sockStat->m_level;    return rv; loser:    if (rv == PR_SUCCESS) {        rv = PR_FAILURE;    }    return rv;}/* * Function: SSMStatus SSMSSLDataConnection_FormSubmitHandler() * Purpose: handles any UI form submission that has an SSMSSLDataConnection *          object as target * Expected request: * - command: "formsubmit_handler" * - baseRef: "formsubmit_dosubmit_js" * - target: an SSMSSLDataConnection object * - formName: "cert_selection" | "bad_server_cert" * Arguments and return values * - res: SSMSSLDataConnection object * - req: the HTTPRequest object to be processed * - returns: SSM_SUCCESS if successful; error otherwise * * Note: add more handling helper functions if there are other form *       submission scenarios */SSMStatus SSMSSLDataConnection_FormSubmitHandler(SSMResource* res,                                                 HTTPRequest* req){    SSMStatus rv;    char* tmpStr = NULL;    SSMSSLDataConnection* conn;    conn = (SSMSSLDataConnection*)res;        /* make sure you got the right baseRef */    rv = SSM_HTTPParamValue(req, "baseRef", &tmpStr);    if (rv != SSM_SUCCESS ||        PL_strcmp(tmpStr, "windowclose_doclose_js") != 0) {        goto loser;    }    /* differentiate among different form submission events by looking up     * formName, and dispatch the request to the appropriate handler      */    /* cleaning up (unlocking monitors, etc.) is handled by individual     * handlers, so just go to done     */    if (res->m_formName == NULL) {        goto loser;    }    if (PL_strcmp(res->m_formName, "cert_selection") == 0) {        rv = SSM_ClientAuthCertSelectionButtonHandler(req);        goto done;    }    else if (PL_strcmp(res->m_formName, "bad_server_cert") == 0) {        /* server auth failure other than unknown issuer case */        rv = SSM_ServerAuthFailureButtonHandler(req);        goto done;    }    else {        /* unknown form name; abort */        SSM_DEBUG("don't know how to handle this form.\n");        goto loser;    }loser:    if (rv == SSM_SUCCESS) {        rv = SSM_FAILURE;    }    SSM_LockResource(req->target);    conn->m_UIInfo.chosen = -1;    conn->m_UIInfo.trustBadServerCert = BSCA_NO;    conn->m_UIInfo.UICompleted = PR_TRUE;    SSM_NotifyResource(req->target);    SSM_UnlockResource(req->target);done:    return rv;}void SSMSSLDataConnection_InitializeUIInfo(SSMSSLUIInfo* info){    info->UICompleted = PR_FALSE;    info->numFilteredCerts = 0;    info->certNicknames = NULL;    info->chosen = -1;    /* negative value denotes no cert was chosen */    info->trustBadServerCert = BSCA_NO;}void SSMSSLDataConnection_DestroyUIInfo(SSMSSLUIInfo* info){    int i;    if (info->numFilteredCerts != 0) {        for (i = 0; i < info->numFilteredCerts; i++) {            PR_FREEIF(info->certNicknames[i]);        }        PR_FREEIF(info->certNicknames);    }}SSMStatus SSMSSLDataConnection_UpdateSecurityStatus(SSMSSLDataConnection* conn){    SSMStatus rv = PR_SUCCESS;	PR_ASSERT(conn != NULL);		SSM_LockResource(SSMRESOURCE(conn));    if (conn->m_sockStat == NULL) {        /* socket status has not been created.  The security status will         * be properly populated by creating the socket status.         */        SSMResourceID statRID;        SSM_CreateResource(SSM_RESTYPE_SSL_SOCKET_STATUS, conn->socketSSL,                            SSMRESOURCE(conn)->m_connection, &statRID,                            (SSMResource**)&conn->m_sockStat);		conn->m_sockStat->m_error = conn->m_sslServerError;    }    else {        /* just update the values */        rv = SSMSSLSocketStatus_UpdateSecurityStatus(conn->m_sockStat,                                                      conn->socketSSL);        if (rv != PR_SUCCESS) {            goto loser;        }    }loser:    /* in case we fail to update the security status, we still notify     * because we don't want to quit just because this failed...     */    SSM_NotifyResource(SSMRESOURCE(conn));    /* notify SSMSSLDataConnection_GetAttr() for the socket RID */	SSM_UnlockResource(SSMRESOURCE(conn));    return rv;}/* updates the error code in case of an exception: returns the current * error code (0 if no error)  */static SSMStatus SSMSSLDataConnection_UpdateErrorCode(SSMSSLDataConnection* conn){    PR_ASSERT(conn != NULL);    SSM_LockResource(SSMRESOURCE(conn));    if (conn->m_error == 0) {        /* update the error code only if it is not already set:         * otherwise preserve the initial error code         */        PRInt32 rv;        rv = PR_GetError();        if (rv != SEC_ERROR_LIBRARY_FAILURE) {            /* XXX sometimes NSS reports this error even when connection             *     terminates normally: will escape this error here so that             *     this is not reported erroneously             */            conn->m_error = rv;        }    }    SSM_UnlockResource(SSMRESOURCE(conn));    return conn->m_error;}/* functions for setting up and configuring SSL connection */SECStatus SSM_SetupSSLSocket(PRFileDesc* socket, PRFileDesc** sslsocket,                             CERTCertDBHandle* handle, char* hostname,                             void* wincx){    SECStatus rv = SECFailure;    /* check arguments */    if ((socket == NULL) || (sslsocket == NULL) || (handle == NULL) ||         (hostname == NULL) || (wincx == NULL)) {        goto loser;    }    *sslsocket = NULL;  	/* import the socket into SSL layer */    *sslsocket = SSL_ImportFD(NULL, socket);    if (*sslsocket == NULL) {        goto loser;    }    	/* set some SSL settings for the socket */    rv = SSL_Enable(*sslsocket, SSL_SECURITY, PR_TRUE);    if (rv != SECSuccess) {		goto loser;	}  	rv = SSL_Enable(*sslsocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE);    if (rv != SECSuccess) {		goto loser;	}	rv = SSL_Enable(*sslsocket, SSL_ENABLE_FDX, PR_TRUE);    if (rv != SECSuccess) {		goto loser;	}	  	/* set callbacks */  	/* client authentication */  	rv = SSL_GetClientAuthDataHook(*sslsocket,                                    (SSLGetClientAuthData)SSM_SSLGetClientAuthData,                                    NULL) == 0 ? SECSuccess : SECFailure;    if (rv  != SECSuccess) {		goto loser;	}    	/* server cert authentication */	rv = SSL_AuthCertificateHook(*sslsocket,                                 (SSLAuthCertificate)SSM_SSLAuthCertificate,                                 (void*)handle) == 0 ? SECSuccess : SECFailure;    if (rv != SECSuccess) {		goto loser;	}    	rv = SSL_BadCertHook(*sslsocket, (SSLBadCertHandler)SSM_SSLBadCertHandler,                          wincx) == 0 ? SECSuccess : SECFailure;    if (rv != SECSuccess) {  		goto loser;	}    rv = SSL_HandshakeCallback(*sslsocket,                                (SSLHandshakeCallback)SSM_SSLHandshakeCallback,                               wincx) == 0 ? SECSuccess : SECFailure;    if (rv != SECSuccess) {        goto loser;    }    SSM_DEBUG("setting PKCS11 pin arg.\n");    rv = SSL_SetPKCS11PinArg(*sslsocket, wincx) == 0 ? SECSuccess : SECFailure;    if (rv != SECSuccess) {        goto loser;    }    /* prepare against man-in-the-middle attacks */    rv = SSL_SetURL(*sslsocket, hostname) == 0 ? SECSuccess : SECFailure;    if (rv != SECSuccess) {        goto loser;    }  	return rv;loser:	if (*sslsocket == NULL) {		/* aborted before SSL_ImportFD() */		if (socket != NULL) {			PR_Close(socket);		}	}	else {		PR_Close(*sslsocket);        *sslsocket = NULL;	}	return rv;}SSMStatus SSM_GetSSLSocket(SSMSSLDataConnection* conn){    SECStatus secstatus = SECSuccess;    PRStatus prstatus = PR_SUCCESS;    PRFileDesc* socket = NULL;    PRSocketOptionData sockdata;    SSMControlConnection* ctrlconn;    PRNetAddr addr;    PRHostEnt hostentry;    char buffer[256];    SSM_DEBUG("SSM_GetSSLSocket entered.\n");	/* check argument first */	if (conn == NULL) {		return PR_FAILURE;	}	    /* Enter SSL lock. We will release once connection is set up.      * If GetSecurityStatus request comes in before we are done, it'll spin      * on the SSL lock. (This lock is not used anyplace else.)     */      /*PR_EnterMonitor(conn->sslLock);*/    /* set up SSL secure socket */    SSM_DEBUG("setting up secure socket.\n");    socket = PR_NewTCPSocket();    if (socket == NULL) {        goto loser;    }    /* make the socket blocking - default on some platforms is non-blocking */    sockdata.option = PR_SockOpt_Nonblocking;    sockdata.value.non_blocking = PR_FALSE;    if (PR_SetSocketOption(socket, &sockdata) != PR_SUCCESS) {        goto loser;    }    if (conn->isTLS != PR_TRUE) {        /* set up SSL secure socket */        SSM_DEBUG("setting up secure socket.\n");        ctrlconn = SSMCONTROLCONNECTION(conn);        secstatus = SSM_SetupSSLSocket(socket, &conn->socketSSL,                                       ctrlconn->m_certdb, conn->hostName,                                        (void*)conn);        if (secstatus != SECSuccess) {            goto loser;        }    }    else {        /* do not need to create a secure socket here */        conn->socketSSL = socket;    }	    /* prepare and setup network connection */    SSM_DEBUG("preparing and setting up network connection.\n");    if (PR_StringToNetAddr(conn->hostIP, &addr) != PR_SUCCESS) {        PRIntn hostIndex;        prstatus = PR_GetHostByName(conn->hostName, buffer, 256, &hostentry);	if (prstatus != PR_SUCCESS) {	    goto loser;	}  	SSM_DEBUG("SSL server port: %d / host: %s \n", conn->port, 		  conn->hostName);	do {	    hostIndex = PR_EnumerateHostEnt(0, &hostentry, 					    (PRUint16) conn->port, &addr);	    if (hostIndex < 0) {	        goto loser;	    }	} while (PR_Connect(conn->socketSSL, &addr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS		 && hostIndex > 0);	SSM_DEBUG("Connected to target.\n");    } else {        if (PR_InitializeNetAddr(PR_IpAddrNull, (PRUint16)conn->port, &addr) != PR_SUCCESS) {	    goto loser;	}	if (PR_Connect(conn->socketSSL, &addr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS) {	  goto loser;	}	SSM_DEBUG("SSL server port: %d / host: %s\n", conn->port, 		  conn->hostName);	SSM_DEBUG("connected using hostIP: %s\n", conn->hostIP);    }#ifdef _HACK_    /* ### mwelch Fix for NSPR20 connect problem under 95/NT. */    PR_Sleep(PR_INTERVAL_NO_WAIT);#endif    /* established SSL connection, ready to send data */    if ((conn->isTLS == PR_FALSE) && (conn->forceHandshake == PR_TRUE)) {        /* if the client wants a forced handshake (e.g. SSL/IMAP),          * do it here          */        SSM_DEBUG("forcing handshake.\n");        secstatus = (SSL_ForceHandshake(conn->socketSSL) == 0)? SECSuccess:SECFailure;        if (secstatus != SECSuccess) {            goto loser;        }    }    /*	if (conn->m_sockStat) {        SSM_FreeResource(&conn->m_sockStat->super);	}    SSM_CreateResource(SSM_RESTYPE_SSL_SOCKET_STATUS, conn->socketSSL,                        SSMRESOURCE(conn)->m_connection, &statRID,                        (SSMResource**)&conn->m_sockStat);    */		/* check everything is hunky-dorey */    /*	SSMSSLSocketStatus_Invariant(conn->m_sockStat); */    /* end of the block */    /* release SSL lock. SSL connection is established. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -