sslsecur.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,378 行 · 第 1/3 页

C
1,378
字号
    PORT_Assert((ss->socks != 0) && (ss->sec != 0));    /* First connect to socks daemon */    rv = ssl_SocksConnect(ss, sa);    if (rv < 0) {	return rv;    }    if ( ss->handshakeAsServer ) {	ss->securityHandshake = ssl2_BeginServerHandshake;    } else {	ss->securityHandshake = ssl2_BeginClientHandshake;    }        return 0;}PRFileDesc *ssl_SecureSocksAccept(sslSocket *ss, PRNetAddr *addr){#if 0    sslSocket *ns;    int rv;    PRFileDesc *newfd, *fd;    newfd = ssl_SocksAccept(ss, addr);    if (newfd == NULL) {	return newfd;    }    /* Create new socket */    ns = ssl_FindSocket(newfd);    PORT_Assert(ns != NULL);    /* Make an NSPR socket to give back to app */    fd = ssl_NewPRSocket(ns, newfd);    if (fd == NULL) {	ssl_FreeSocket(ns);	PR_Close(newfd);	return NULL;    }    if ( ns->handshakeAsClient ) {	ns->handshake = ssl2_BeginClientHandshake;    } else {	ns->handshake = ssl2_BeginServerHandshake;    }    return fd;#else    return NULL;#endif}intssl_SecureClose(sslSocket *ss){    int rv;    if (ss->version >= SSL_LIBRARY_VERSION_3_0 	&&    	ss->connected 				&& 	!(ss->shutdownHow & ssl_SHUTDOWN_SEND)	&&	(ss->ssl3 != NULL)) {	(void) SSL3_SendAlert(ss, alert_warning, close_notify);    }    rv = ssl_DefClose(ss);    return rv;}/* Caller handles all locking */intssl_SecureShutdown(sslSocket *ss, int nsprHow){    PRFileDesc *osfd = ss->fd->lower;    int 	rv;    PRIntn	sslHow	= nsprHow + 1;    if ((unsigned)nsprHow > PR_SHUTDOWN_BOTH) {	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);    	return PR_FAILURE;    }    if ((sslHow & ssl_SHUTDOWN_SEND) != 0 		&&	!(ss->shutdownHow & ssl_SHUTDOWN_SEND)		&&    	(ss->version >= SSL_LIBRARY_VERSION_3_0)	&&	ss->connected 					&& 	(ss->ssl3 != NULL)) {	(void) SSL3_SendAlert(ss, alert_warning, close_notify);    }    rv = osfd->methods->shutdown(osfd, nsprHow);    ss->shutdownHow |= sslHow;    return rv;}/************************************************************************/intssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags){    sslSecurityInfo *sec;    int              rv   = 0;    PORT_Assert(ss->sec != 0);    sec = ss->sec;    if (ss->shutdownHow & ssl_SHUTDOWN_RCV) {	PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);    	return PR_FAILURE;    }    if (flags & ~MSG_PEEK) {	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);    	return PR_FAILURE;    }    if (!ssl_SocketIsBlocking(ss) && !ss->fdx) {	ssl_GetXmitBufLock(ss);	if (ss->pendingBuf.len != 0) {	    rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend);	    if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) {		ssl_ReleaseXmitBufLock(ss);		return SECFailure;	    }	    /* XXX short write? */	}	ssl_ReleaseXmitBufLock(ss);    }        rv = 0;    /* If any of these is non-zero, the initial handshake is not done. */    if (!ss->connected) {	ssl_Get1stHandshakeLock(ss);	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {	    rv = ssl_Do1stHandshake(ss);	}	ssl_Release1stHandshakeLock(ss);    }    if (rv < 0) {	return rv;    }    if (len == 0) return 0;    rv = DoRecv(ss, (unsigned char*) buf, len, flags);    SSL_TRC(2, ("%d: SSL[%d]: recving %d bytes securely (errno=%d)",		SSL_GETPID(), ss->fd, rv, PORT_GetError()));    return rv;}intssl_SecureRead(sslSocket *ss, unsigned char *buf, int len){    return ssl_SecureRecv(ss, buf, len, 0);}intssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags){    sslSecurityInfo *sec;    int              rv		= 0;    PORT_Assert(ss->sec != 0);    sec = ss->sec;    if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {	PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);    	return PR_FAILURE;    }    if (flags) {	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);    	return PR_FAILURE;    }    ssl_GetXmitBufLock(ss);    if (ss->pendingBuf.len != 0) {	PORT_Assert(ss->pendingBuf.len > 0);	rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend);	if (ss->pendingBuf.len != 0) {	    PORT_Assert(ss->pendingBuf.len > 0);	    PORT_SetError(PR_WOULD_BLOCK_ERROR);	    rv = SECFailure;	}    }    ssl_ReleaseXmitBufLock(ss);    if (rv < 0) {	return rv;    }    /* If any of these is non-zero, the initial handshake is not done. */    if (!ss->connected) {	ssl_Get1stHandshakeLock(ss);	if (ss->handshake || ss->nextHandshake || ss->securityHandshake) {	    rv = ssl_Do1stHandshake(ss);	}	ssl_Release1stHandshakeLock(ss);    }    if (rv < 0) {	return rv;    }    /* Check for zero length writes after we do housekeeping so we make forward     * progress.     */    if (len == 0) return 0;    PORT_Assert(buf != NULL);        SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",		SSL_GETPID(), ss->fd, len));    /* Send out the data using one of these functions:     *	ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock,      *  ssl3_SendApplicationData     */    ssl_GetXmitBufLock(ss);    rv = (*sec->send)(ss, buf, len, flags);    ssl_ReleaseXmitBufLock(ss);    return rv;}intssl_SecureWrite(sslSocket *ss, const unsigned char *buf, int len){    return ssl_SecureSend(ss, buf, len, 0);}intSSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, void *arg){    sslSocket *ss;    int rv;        ss = ssl_FindSocket(fd);    if (!ss) {	SSL_DBG(("%d: SSL[%d]: bad socket in SSLBadCertHook",		 SSL_GETPID(), fd));	return SECFailure;    }    if ((rv = ssl_CreateSecurityInfo(ss)) != 0) {	return(rv);    }    ss->handleBadCert = f;    ss->badCertArg = arg;    return(0);}/* * Allow the application to pass the url or hostname into the SSL library * so that we can do some checking on it. */intSSL_SetURL(PRFileDesc *fd, const char *url){    sslSocket *   ss = ssl_FindSocket(fd);    int           rv = SECSuccess;    if (!ss) {	SSL_DBG(("%d: SSL[%d]: bad socket in SSLSetURL",		 SSL_GETPID(), fd));	return SECFailure;    }    ssl_Get1stHandshakeLock(ss);    ssl_GetSSL3HandshakeLock(ss);    if ( ss->url ) {	PORT_Free((void *)ss->url);	/* CONST */    }    ss->url = (const char *)PORT_Strdup(url);    if ( ss->url == NULL ) {	rv = SECFailure;    }    ssl_ReleaseSSL3HandshakeLock(ss);    ssl_Release1stHandshakeLock(ss);    return rv;}/*** Returns Negative number on error, zero or greater on success.** Returns the amount of data immediately available to be read.*/intSSL_DataPending(PRFileDesc *fd){    sslSocket *ss;    int        rv  = 0;    ss = ssl_FindSocket(fd);    if (ss && ss->useSecurity) {	ssl_Get1stHandshakeLock(ss);	ssl_GetSSL3HandshakeLock(ss);	/* Create ss->sec if it doesn't already exist. */	rv = ssl_CreateSecurityInfo(ss);	if (rv == SECSuccess) {	    ssl_GetRecvBufLock(ss);	    rv = ss->gather->writeOffset - ss->gather->readOffset;	    ssl_ReleaseRecvBufLock(ss);	}	ssl_ReleaseSSL3HandshakeLock(ss);	ssl_Release1stHandshakeLock(ss);    }    return rv;}intSSL_InvalidateSession(PRFileDesc *fd){    sslSocket *   ss = ssl_FindSocket(fd);    int           rv = SECFailure;    ssl_Get1stHandshakeLock(ss);    ssl_GetSSL3HandshakeLock(ss);    if (ss && ss->sec && ss->sec->ci.sid) {	ss->sec->uncache(ss->sec->ci.sid);	rv = SECSuccess;    }    ssl_ReleaseSSL3HandshakeLock(ss);    ssl_Release1stHandshakeLock(ss);    return rv;}SECItem *SSL_GetSessionID(PRFileDesc *fd){    sslSocket *    ss;    SECItem *      item = NULL;    sslSessionID * sid;    ss = ssl_FindSocket(fd);    ssl_Get1stHandshakeLock(ss);    ssl_GetSSL3HandshakeLock(ss);    if (ss && ss->useSecurity && ss->connected && ss->sec && ss->sec->ci.sid) {        sid = ss->sec->ci.sid;        item = (SECItem *)PORT_Alloc(sizeof(SECItem));        if (sid->version < SSL_LIBRARY_VERSION_3_0) {            item->len = SSL_SESSIONID_BYTES;            item->data = (unsigned char*)PORT_Alloc(item->len);            PORT_Memcpy(item->data, sid->u.ssl2.sessionID, item->len);        } else {            item->len = sid->u.ssl3.sessionIDLength;            item->data = (unsigned char*)PORT_Alloc(item->len);            PORT_Memcpy(item->data, sid->u.ssl3.sessionID, item->len);        }    }    ssl_ReleaseSSL3HandshakeLock(ss);    ssl_Release1stHandshakeLock(ss);    return item;}SECStatusSSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle){    sslSocket *    ss;    ss = ssl_FindSocket(fd);    if (!ss)    	return SECFailure;    if (!dbHandle) {    	PORT_SetError(SEC_ERROR_INVALID_ARGS);	return SECFailure;    }    ss->dbHandle = dbHandle;    return SECSuccess;}/* * attempt to restart the handshake after asynchronously handling * a request for the client's certificate. * * inputs:   *	cert	Client cert chosen by application. *		Note: ssl takes this reference, and does not bump the  *		reference count.  The caller should drop its reference *		without calling CERT_DestroyCert after calling this function. * *	key	Private key associated with cert.  This function makes a  *		copy of the private key, so the caller remains responsible  *		for destroying its copy after this function returns. * *	certChain  Chain of signers for cert.   *		Note: ssl takes this reference, and does not copy the chain. *		The caller should drop its reference without destroying the  *		chain.  SSL will free the chain when it is done with it. * * Return value: XXX * * XXX This code only works on the initial handshake on a connection, XXX *     It does not work on a subsequent handshake (redo). */intSSL_RestartHandshakeAfterCertReq(sslSocket *         ss,				CERTCertificate *    cert, 				SECKEYPrivateKey *   key,				CERTCertificateList *certChain){    int              ret;    ssl_Get1stHandshakeLock(ss);   /************************************/    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {	ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain);    } else {    	ret = ssl2_RestartHandshakeAfterCertReq(ss, cert, key);    }    ssl_Release1stHandshakeLock(ss);  /************************************/    return ret;}/* restart an SSL connection that we stopped to run certificate dialogs ** XXX	Need to document here how an application marks a cert to show that**	the application has accepted it (overridden CERT_VerifyCert). * * XXX This code only works on the initial handshake on a connection, XXX *     It does not work on a subsequent handshake (redo). * * Return value: XXX*/intSSL_RestartHandshakeAfterServerCert(sslSocket *ss){    int rv	= SECSuccess;    ssl_Get1stHandshakeLock(ss);     if (ss->version >= SSL_LIBRARY_VERSION_3_0) {	rv = ssl3_RestartHandshakeAfterServerCert(ss);    } else {	rv = ssl2_RestartHandshakeAfterServerCert(ss);    }    ssl_Release1stHandshakeLock(ss);    return rv;}

⌨️ 快捷键说明

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