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 + -
显示快捷键?