sslsock.c

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

C
1,856
字号
/* * vtables (and methods that call through them) for the 4 types of  * SSLSockets supported.  Only one type is still supported. * Various other functions. * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape security libraries. *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. * * $Id: sslsock.c,v 1.5 2000/09/12 20:15:43 jgmyers%netscape.com Exp $ */#include "seccomon.h"#include "cert.h"#include "keyhi.h"#include "ssl.h"#include "sslimpl.h"#include "sslproto.h"#include "nspr.h"#define SET_ERROR_CODE   /* reminder */struct cipherPolicyStr {	int		cipher;	unsigned char 	export;	/* policy value for export policy */	unsigned char 	france;	/* policy value for france policy */};typedef struct cipherPolicyStr cipherPolicy;/* this table reflects Netscape's browser policies. */static cipherPolicy ssl_ciphers[] = {	   /*   Export           France   */ {  SSL_EN_RC4_128_WITH_MD5,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_EN_RC4_128_EXPORT40_WITH_MD5,	    SSL_ALLOWED,     SSL_ALLOWED }, {  SSL_EN_RC2_128_CBC_WITH_MD5,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5,   SSL_ALLOWED,     SSL_ALLOWED }, {  SSL_EN_DES_64_CBC_WITH_MD5,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_EN_DES_192_EDE3_CBC_WITH_MD5,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_FORTEZZA_DMS_WITH_RC4_128_SHA,      SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_RSA_WITH_RC4_128_MD5,		    SSL_RESTRICTED,  SSL_NOT_ALLOWED }, {  SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_RSA_WITH_3DES_EDE_CBC_SHA,	    SSL_RESTRICTED,  SSL_NOT_ALLOWED }, {  SSL_RSA_FIPS_WITH_DES_CBC_SHA,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_RSA_WITH_DES_CBC_SHA,		    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_RSA_EXPORT_WITH_RC4_40_MD5,	    SSL_ALLOWED,     SSL_ALLOWED }, {  SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,	    SSL_ALLOWED,     SSL_ALLOWED }, {  SSL_FORTEZZA_DMS_WITH_NULL_SHA,	    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, {  SSL_RSA_WITH_NULL_MD5,		    SSL_ALLOWED,     SSL_ALLOWED }, {  TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,    SSL_ALLOWED,     SSL_NOT_ALLOWED }, {  TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,     SSL_ALLOWED,     SSL_NOT_ALLOWED }, {  0,					    SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }};staticsslSocketOps ssl_default_ops = {	/* No SSL, No Socks. */    ssl_DefConnect,    NULL,    ssl_DefBind,    ssl_DefListen,    ssl_DefShutdown,    ssl_DefClose,    ssl_DefRecv,    ssl_DefSend,    ssl_DefRead,    ssl_DefWrite,    ssl_DefGetpeername,    ssl_DefGetsockname};staticsslSocketOps ssl_socks_ops = {		/* No SSL, has socks. */    ssl_SocksConnect,    ssl_SocksAccept,    ssl_SocksBind,    ssl_SocksListen,    ssl_DefShutdown,    ssl_DefClose,    ssl_SocksRecv,    ssl_SocksSend,    ssl_SocksRead,    ssl_SocksWrite,    ssl_DefGetpeername,    ssl_SocksGetsockname};staticsslSocketOps ssl_secure_ops = {		/* SSL, no socks. */    ssl_SecureConnect,    NULL,    ssl_DefBind,    ssl_DefListen,    ssl_SecureShutdown,    ssl_SecureClose,    ssl_SecureRecv,    ssl_SecureSend,    ssl_SecureRead,    ssl_SecureWrite,    ssl_DefGetpeername,    ssl_DefGetsockname};staticsslSocketOps ssl_secure_socks_ops = {	/* Both SSL and Socks. */    ssl_SecureSocksConnect,    ssl_SecureSocksAccept,    ssl_SocksBind,    ssl_SocksListen,    ssl_SecureShutdown,    ssl_SecureClose,    ssl_SecureRecv,    ssl_SecureSend,    ssl_SecureRead,    ssl_SecureWrite,    ssl_DefGetpeername,    ssl_SocksGetsockname};/*** default settings for socket enables*/static sslOptions ssl_defaults = {    PR_TRUE, 	/* useSecurity        */    PR_FALSE,	/* useSocks           */    PR_FALSE,	/* requestCertificate */    2,	        /* requireCertificate */    PR_FALSE,	/* handshakeAsClient  */    PR_FALSE,	/* handshakeAsServer  */    PR_TRUE,	/* enableSSL2         */    PR_TRUE,	/* enableSSL3         */    PR_TRUE, 	/* enableTLS          */ /* now defaults to on in NSS 3.0 */    PR_FALSE,	/* noCache            */    PR_FALSE,	/* fdx                */    PR_TRUE,	/* v2CompatibleHello  */    PR_TRUE,	/* detectRollBack     */};sslSessionIDLookupFunc  ssl_sid_lookup;sslSessionIDCacheFunc   ssl_sid_cache;sslSessionIDUncacheFunc ssl_sid_uncache;static PRBool ssl_inited = PR_FALSE;static PRDescIdentity ssl_layer_id;int                     ssl_lock_readers	= 1;	/* default true. */char                    ssl_debug;char                    ssl_trace;/* forward declarations. */static sslSocket *ssl_NewSocket(void);static PRStatus   ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack,                                   PRDescIdentity id);/************************************************************************//*** Lookup a socket structure from a file descriptor.*/static sslSocket *ssl_GetPrivate(PRFileDesc *fd){    sslSocket *ss;    PORT_Assert(fd != NULL);    PORT_Assert(fd->methods->file_type == PR_DESC_LAYERED);    PORT_Assert(fd->identity == ssl_layer_id);    ss = (sslSocket *)fd->secret;    ss->fd = fd;    return ss;}sslSocket *ssl_FindSocket(PRFileDesc *fd){    PRFileDesc *layer;    sslSocket *ss;    PORT_Assert(fd != NULL);    PORT_Assert(ssl_layer_id != 0);    layer = PR_GetIdentitiesLayer(fd, ssl_layer_id);    if (layer == NULL)	return NULL;    ss = (sslSocket *)layer->secret;    ss->fd = layer;    return ss;}#if 0	/* dead code. */PRFileDesc *ssl_FindTop(sslSocket *ss){    PRFileDesc *fd = ss->fd;    while (fd->higher != NULL)	fd = fd->higher;    return fd;}#endifsslSocket *ssl_DupSocket(sslSocket *os){    sslSocket *ss;    SECStatus rv;    ss = ssl_NewSocket();    if (ss) {	ss->useSocks           = os->useSocks;	ss->useSecurity        = os->useSecurity;	ss->requestCertificate = os->requestCertificate;	ss->requireCertificate = os->requireCertificate;	ss->handshakeAsClient  = os->handshakeAsClient;	ss->handshakeAsServer  = os->handshakeAsServer;	ss->enableSSL2         = os->enableSSL2;	ss->enableSSL3         = os->enableSSL3;	ss->enableTLS          = os->enableTLS;	ss->noCache            = os->noCache;	ss->fdx                = os->fdx;	ss->v2CompatibleHello  = os->v2CompatibleHello;	ss->detectRollBack     = os->detectRollBack;	ss->peerID             = !os->peerID ? NULL : PORT_Strdup(os->peerID);	ss->url                = !os->url    ? NULL : PORT_Strdup(os->url);	ss->ops      = os->ops;	ss->peer     = os->peer;	ss->port     = os->port;	ss->rTimeout = os->rTimeout;	ss->wTimeout = os->wTimeout;	ss->cTimeout = os->cTimeout;	ss->dbHandle = os->dbHandle;	/* copy ssl2&3 policy & prefs, even if it's not selected (yet) */	ss->allowedByPolicy	= os->allowedByPolicy;	ss->maybeAllowedByPolicy= os->maybeAllowedByPolicy;	ss->chosenPreference 	= os->chosenPreference;	PORT_Memcpy(ss->cipherSuites, os->cipherSuites, sizeof os->cipherSuites);	if (os->cipherSpecs) {	    ss->cipherSpecs  = (unsigned char*)PORT_Alloc(os->sizeCipherSpecs);	    if (ss->cipherSpecs) 	    	PORT_Memcpy(ss->cipherSpecs, os->cipherSpecs, 		            os->sizeCipherSpecs);	    ss->sizeCipherSpecs    = os->sizeCipherSpecs;	    ss->preferredCipher    = os->preferredCipher;	} else {	    ss->cipherSpecs        = NULL;  /* produced lazily */	    ss->sizeCipherSpecs    = 0;	    ss->preferredCipher    = NULL;	}	if (ss->useSecurity) {	    /* This int should be SSLKEAType, but CC on Irix complains,	     * during the for loop.	     */	    int i;	    for (i=kt_null; i < kt_kea_size; i++) {		if (os->serverCert[i] && os->serverCertChain[i]) {		    ss->serverCert[i] = CERT_DupCertificate(os->serverCert[i]);		    ss->serverCertChain[i] = CERT_DupCertList(		                                       os->serverCertChain[i]);		} else {		    ss->serverCert[i]      = NULL;		    ss->serverCertChain[i] = NULL;		}		ss->serverKey[i] = os->serverKey[i] ?				SECKEY_CopyPrivateKey(os->serverKey[i]) : NULL;	    }	    ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL :		                  ssl3_GetKeyPairRef(os->stepDownKeyPair);/* * XXX the preceeding CERT_ and SECKEY_ functions can fail and return NULL. * XXX We should detect this, and not just march on with NULL pointers. */	    ss->authCertificate       = os->authCertificate;	    ss->authCertificateArg    = os->authCertificateArg;	    ss->getClientAuthData     = os->getClientAuthData;	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;	    ss->handleBadCert         = os->handleBadCert;	    ss->badCertArg            = os->badCertArg;	    ss->handshakeCallback     = os->handshakeCallback;	    ss->handshakeCallbackData = os->handshakeCallbackData;	    ss->pkcs11PinArg          = os->pkcs11PinArg;    	    /* Create security data */	    rv = ssl_CopySecurityInfo(ss, os);	    if (rv != SECSuccess) {		goto losage;	    }	}	if (ss->useSocks) {	    /* Create security data */	    rv = ssl_CopySocksInfo(ss, os);	    if (rv != SECSuccess) {		goto losage;	    }	}    }    return ss;  losage:    return NULL;}/* * free an sslSocket struct, and all the stuff that hangs off of it */voidssl_FreeSocket(sslSocket *ss){    /* "i" should be of type SSLKEAType, but CC on IRIX complains during     * the for loop.     */    int        i;    sslSocket *fs;    sslSocket  lSock;/* Get every lock you can imagine!** Caller already holds these:**  SSL_LOCK_READER(ss);**  SSL_LOCK_WRITER(ss);*/    ssl_Get1stHandshakeLock(ss);    ssl_GetRecvBufLock(ss);    ssl_GetSSL3HandshakeLock(ss);    ssl_GetXmitBufLock(ss);    ssl_GetSpecWriteLock(ss);#ifdef DEBUG    fs = &lSock;    *fs = *ss;				/* Copy the old socket structure, */    PORT_Memset(ss, 0x1f, sizeof *ss);  /* then blast the old struct ASAP. */#else    fs = ss;#endif    /* Free up socket */    ssl_DestroySocksInfo(fs->socks);    ssl_DestroySecurityInfo(fs->sec);    ssl3_DestroySSL3Info(fs->ssl3);    PORT_Free(fs->saveBuf.buf);    PORT_Free(fs->pendingBuf.buf);    if (fs->gather) {	ssl_DestroyGather(fs->gather);    }    if (fs->peerID != NULL)	PORT_Free(fs->peerID);    if (fs->url != NULL)	PORT_Free((void *)fs->url);	/* CONST */    /* Clean up server configuration */    for (i=kt_null; i < kt_kea_size; i++) {	if (fs->serverCert[i] != NULL)	    CERT_DestroyCertificate(fs->serverCert[i]);	if (fs->serverCertChain[i] != NULL)	    CERT_DestroyCertificateList(fs->serverCertChain[i]);	if (fs->serverKey[i] != NULL)	    SECKEY_DestroyPrivateKey(fs->serverKey[i]);    }    if (fs->stepDownKeyPair) {	ssl3_FreeKeyPair(fs->stepDownKeyPair);	fs->stepDownKeyPair = NULL;    }    /* Release all the locks acquired above.  */    SSL_UNLOCK_READER(fs);    SSL_UNLOCK_WRITER(fs);    ssl_Release1stHandshakeLock(fs);    ssl_ReleaseRecvBufLock(fs);    ssl_ReleaseSSL3HandshakeLock(fs);    ssl_ReleaseXmitBufLock(fs);    ssl_ReleaseSpecWriteLock(fs);    /* Destroy locks. */    if (fs->firstHandshakeLock) {    	PR_DestroyMonitor(fs->firstHandshakeLock);	fs->firstHandshakeLock = NULL;    }    if (fs->ssl3HandshakeLock) {    	PR_DestroyMonitor(fs->ssl3HandshakeLock);	fs->ssl3HandshakeLock = NULL;    }    if (fs->specLock) {    	NSSRWLock_Destroy(fs->specLock);	fs->specLock = NULL;    }    if (fs->recvLock) {    	PR_DestroyLock(fs->recvLock);	fs->recvLock = NULL;    }    if (fs->sendLock) {    	PR_DestroyLock(fs->sendLock);	fs->sendLock = NULL;    }    if (fs->xmitBufLock) {    	PR_DestroyMonitor(fs->xmitBufLock);	fs->xmitBufLock = NULL;    }    if (fs->recvBufLock) {    	PR_DestroyMonitor(fs->recvBufLock);	fs->recvBufLock = NULL;    }    if (fs->cipherSpecs) {	PORT_Free(fs->cipherSpecs);	fs->cipherSpecs     = NULL;	fs->sizeCipherSpecs = 0;    }    PORT_Free(ss);	/* free the caller's copy, not ours. */    return;}/************************************************************************/static voidssl_ChooseOps(sslSocket *ss){    if (ss->useSocks)  {    	ss->ops = ss->useSecurity ? &ssl_secure_socks_ops : &ssl_socks_ops ;    } else {    	ss->ops = ss->useSecurity ? &ssl_secure_ops       : &ssl_default_ops;    }}/* Called from SSL_Enable (immediately below) */static SECStatusPrepareSocket(sslSocket *ss){    SECStatus     rv = SECSuccess;    if (ss->useSocks) {

⌨️ 快捷键说明

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