sslsnce.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,927 行 · 第 1/4 页
C
1,927 行
PR_Lock(cacheLock);}static void unlock_cache(void){ PR_Unlock(cacheLock);}/*** Perform some mumbo jumbo on the ip-address and the session-id value to** compute a hash value.*/static PRUint32 Offset(const PRIPv6Addr *addr, unsigned char *s, unsigned nl){ PRUint32 rv; rv = addr->pr_s6_addr32[3] ^ (((PRUint32)s[0] << 24) | ((PRUint32)s[1] << 16) | (s[2] << 8) | s[nl-1]); return (rv % numSIDCacheEntries) * sizeof(SIDCacheEntry);}/*** Look something up in the cache. This will invalidate old entries** in the process. Caller has locked the cache!** Returns PR_TRUE if found a valid match. PR_FALSE otherwise.*/static PRBool FindSID(const PRIPv6Addr *addr, unsigned char *sessionID, unsigned sessionIDLength, SIDCacheEntry *sce){ PRUint32 offset; PRUint32 now; int rv;#ifdef XP_UNIX off_t off;#endif /* Read in cache entry after hashing ip address and session-id value */ offset = Offset(addr, sessionID, sessionIDLength); now = ssl_Time(); GET_SERVER_CACHE_READ_LOCK(SIDCacheFD, offset, sizeof *sce);#ifdef XP_UNIX off = lseek(SIDCacheFD, offset, SEEK_SET); rv = -1; if (off != offset) { if (off == -1) nss_MD_unix_map_lseek_error(errno); else PORT_SetError(PR_FILE_SEEK_ERROR); } else { rv = read(SIDCacheFD, sce, sizeof *sce); if (rv != sizeof *sce) { if (rv == -1) nss_MD_unix_map_read_error(errno); else PORT_SetError(PR_IO_ERROR); } }#else /* XP_WIN32 */ /* Use memory mapped I/O and just memcpy() the data */ CopyMemory(sce, &SIDCacheData[offset], sizeof *sce); rv = sizeof *sce;#endif /* XP_WIN32 */ RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *sce); if (rv != sizeof *sce) { IOError(rv, "server sid cache read"); return PR_FALSE; } if (!sce->u.ssl2.valid) { /* Entry is not valid */ PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND); return PR_FALSE; } if (((sce->u.ssl2.version < SSL_LIBRARY_VERSION_3_0) && (now > sce->time + ssl_sid_timeout)) || ((sce->u.ssl2.version >= SSL_LIBRARY_VERSION_3_0) && (now > sce->time + ssl3_sid_timeout))) { /* SessionID has timed out. Invalidate the entry. */ SSL_TRC(7, ("%d: timed out sid entry addr=%08x%08x%08x%08x now=%x time+=%x", myPid, sce->addr.pr_s6_addr32[0], sce->addr.pr_s6_addr32[1], sce->addr.pr_s6_addr32[2], sce->addr.pr_s6_addr32[3], now, sce->time + ssl_sid_timeout)); sce->u.ssl2.valid = 0; GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, offset, sizeof *sce);#ifdef XP_UNIX off = lseek(SIDCacheFD, offset, SEEK_SET); rv = -1; if (off != offset) { if (off == -1) nss_MD_unix_map_lseek_error(errno); else PORT_SetError(PR_IO_ERROR); } else { rv = write(SIDCacheFD, sce, sizeof *sce); if (rv != sizeof *sce) { if (rv == -1) nss_MD_unix_map_write_error(errno); else PORT_SetError(PR_IO_ERROR); IOError(rv, "timeout-write"); } }#else /* WIN32 */ /* Use memory mapped I/O and just memcpy() the data */ CopyMemory(&SIDCacheData[offset], sce, sizeof *sce); rv = sizeof *sce;#endif /* XP_UNIX */ RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof *sce); if (rv == sizeof *sce) PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND); return PR_FALSE; } /* ** Finally, examine specific session-id/addr data to see if the cache ** entry matches our addr+session-id value */ if (!memcmp(&sce->addr, addr, sizeof(PRIPv6Addr)) && (PORT_Memcmp(sce->u.ssl2.sessionID, sessionID, sessionIDLength) == 0)) { /* Found it */ return PR_TRUE; } PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND); return PR_FALSE;}/************************************************************************//* This is the primary function for finding entries in the server's sid cache. * Although it is static, this function is called via the global function * pointer ssl_sid_lookup. */static sslSessionID *ServerSessionIDLookup( const PRIPv6Addr *addr, unsigned char *sessionID, unsigned int sessionIDLength, CERTCertDBHandle * dbHandle){ SIDCacheEntry sce; sslSessionID *sid; sid = 0; lock_cache(); if (FindSID(addr, sessionID, sessionIDLength, &sce)) { /* Found it. Convert file format to internal format */ sid = ConvertToSID(&sce, dbHandle); } unlock_cache(); return sid;}/*** Place an sid into the cache, if it isn't already there. Note that if** some other server process has replaced a session-id cache entry that has** the same cache index as this sid, then all is ok. Somebody has to lose** when this condition occurs, so it might as well be this sid.*/static void ServerSessionIDCache(sslSessionID *sid){ SIDCacheEntry sce; PRUint32 offset;#ifdef XP_UNIX off_t off; int rv;#endif uint16 version = sid->version; if ((version >= SSL_LIBRARY_VERSION_3_0) && (sid->u.ssl3.sessionIDLength == 0)) { return; } if (sid->cached == never_cached || sid->cached == invalid_cache) { lock_cache(); sid->time = ssl_Time(); if (version < SSL_LIBRARY_VERSION_3_0) { SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipher=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], sid->time, sid->u.ssl2.cipherType)); PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID))); PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len)); PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len)); /* Write out new cache entry */ offset = Offset(&sid->addr, sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID)); } else { SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipherSuite=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], sid->time, sid->u.ssl3.cipherSuite)); PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength)); offset = Offset(&sid->addr, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength); } ConvertFromSID(&sce, sid); if (version >= SSL_LIBRARY_VERSION_3_0) { if (sid->peerCert == NULL) { sce.u.ssl3.certIndex = -1; } else { sce.u.ssl3.certIndex = (int16) ((offset / sizeof(SIDCacheEntry)) % numCertCacheEntries); } } GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, offset, sizeof sce);#ifdef XP_UNIX off = lseek(SIDCacheFD, offset, SEEK_SET); if (off != offset) { if (off == -1) nss_MD_unix_map_lseek_error(errno); else PORT_SetError(PR_IO_ERROR); } else { rv = write(SIDCacheFD, &sce, sizeof sce); if (rv != sizeof(sce)) { if (rv == -1) nss_MD_unix_map_write_error(errno); else PORT_SetError(PR_IO_ERROR); IOError(rv, "update-write"); } }#else /* WIN32 */ CopyMemory(&SIDCacheData[offset], &sce, sizeof sce);#endif /* XP_UNIX */ RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, offset, sizeof sce); if ((version >= SSL_LIBRARY_VERSION_3_0) && (sid->peerCert != NULL)) { CacheCert(sid->peerCert, &sce); } sid->cached = in_server_cache; unlock_cache(); }}static void ServerSessionIDUncache(sslSessionID *sid){ SIDCacheEntry sce; PRErrorCode err; int rv; if (sid == NULL) return; /* Uncaching a SID should never change the error code. ** So save it here and restore it before exiting. */ err = PR_GetError(); lock_cache(); if (sid->version < SSL_LIBRARY_VERSION_3_0) { SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x " "cipher=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], sid->time, sid->u.ssl2.cipherType)); PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID))); PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data, sid->u.ssl2.masterKey.len)); PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data, sid->u.ssl2.cipherArg.len)); rv = FindSID(&sid->addr, sid->u.ssl2.sessionID, sizeof(sid->u.ssl2.sessionID), &sce); } else { SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x " "cipherSuite=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2], sid->addr.pr_s6_addr32[3], sid->time, sid->u.ssl3.cipherSuite)); PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength)); rv = FindSID(&sid->addr, sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength, &sce); } if (rv) { Invalidate(&sce); } sid->cached = invalid_cache; unlock_cache(); PORT_SetError(err);}static SECStatusInitSessionIDCache(int maxCacheEntries, PRUint32 timeout, PRUint32 ssl3_timeout, const char *directory){ char *cfn;#ifdef XP_UNIX int rv; if (SIDCacheFD >= 0) { /* Already done */ return SECSuccess; }#else /* WIN32 */ if(SIDCacheFDMAP != INVALID_HANDLE_VALUE) { /* Already done */ return SECSuccess; }#endif /* XP_UNIX */ if (maxCacheEntries) { numSIDCacheEntries = maxCacheEntries; } sidCacheWrapOffset = numSIDCacheEntries * sizeof(SIDCacheEntry); sidCacheFileSize = sidCacheWrapOffset + (kt_kea_size * SSL_NUM_WRAP_MECHS * sizeof(SSLWrappedSymWrappingKey)); /* Create file names */ cfn = (char*) PORT_Alloc(PORT_Strlen(directory) + 100); if (!cfn) { return SECFailure; }#ifdef XP_UNIX sprintf(cfn, "%s/.sslsidc.%d", directory, getpid());#else /* XP_WIN32 */ sprintf(cfn, "%s\\ssl.sidc.%d.%d", directory, GetCurrentProcessId(), GetCurrentThreadId());#endif /* XP_WIN32 */ /* Create session-id cache file */#ifdef XP_UNIX do { (void) unlink(cfn); SIDCacheFD = open(cfn, O_EXCL|O_CREAT|O_RDWR, 0600); } while (SIDCacheFD < 0 && errno == EEXIST); if (SIDCacheFD < 0) { nss_MD_unix_map_open_error(errno); IOError(SIDCacheFD, "create"); goto loser; } rv = unlink(cfn); if (rv < 0) { nss_MD_unix_map_unlink_error(errno); IOError(rv, "unlink"); goto loser; }#else /* WIN32 */ SIDCacheFDMAP = CreateFileMapping(INVALID_HANDLE_VALUE, /* allocate in swap file */ &sidCacheFDMapAttributes, /* inheritable. */ PAGE_READWRITE, 0, /* size, high word. */ sidCacheFileSize, /* size, low word. */ NULL); /* no map name in FS */ if(! SIDCacheFDMAP) { nss_MD_win32_map_default_error(GetLastError()); goto loser; } SIDCacheData = (char *)MapViewOfFile(SIDCacheFDMAP, FILE_MAP_ALL_ACCESS, /* R/W */ 0, 0, /* offset */ sidCacheFileSize); /* size */ if (! SIDCacheData) { nss_MD_win32_map_default_error(GetLastError()); goto loser; }#endif /* XP_UNIX */ if (!cacheLock) nss_InitLock(&cacheLock); if (!cacheLock) { SET_ERROR_CODE goto loser; }#ifdef _WIN32 if (isMultiProcess && (SECSuccess != createServerCacheSemaphore())) { SET_ERROR_CODE goto loser; }#endif if (timeout) { if (timeout > 100) { timeout = 100; } if (timeout < 5) { timeout = 5; } ssl_sid_timeout = timeout; } if (ssl3_timeout) { if (ssl3_timeout > 86400L) { ssl3_timeout = 86400L; } if (ssl3_timeout < 5) { ssl3_timeout = 5; } ssl3_sid_timeout = ssl3_timeout; } GET_SERVER_CACHE_WRITE_LOCK(SIDCacheFD, 0, sidCacheFileSize);#ifdef XP_UNIX /* Initialize the files */ if (ZeroFile(SIDCacheFD, sidCacheFileSize)) { /* Bummer */ close(SIDCacheFD); SIDCacheFD = -1; goto loser; }#else /* XP_WIN32 */ ZeroMemory(SIDCacheData, sidCacheFileSize);#endif /* XP_UNIX */ RELEASE_SERVER_CACHE_LOCK(SIDCacheFD, 0, sidCacheFileSize); PORT_Free(cfn); return SECSuccess; loser:#ifdef _WIN32 if (svrCacheSem) destroyServerCacheSemaphore();#endif if (cacheLock) { PR_DestroyLock(cacheLock); cacheLock = NULL; } PORT_Free(cfn); return SECFailure;}static SECStatus InitCertCache(const char *directory){ char *cfn;#ifdef XP_UNIX int rv; if (certCacheFD >= 0) { /* Already done */ return SECSuccess; }#else /* WIN32 */ if(certCacheFDMAP != INVALID_HANDLE_VALUE) { /* Already done */ return SECSuccess; }#endif /* XP_UNIX */ numCertCacheEntries = sidCacheFileSize / sizeof(CertCacheEntry); if (numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) numCertCacheEntries = MIN_CERT_CACHE_ENTRIES; certCacheFileSize = numCertCacheEntries * sizeof(CertCacheEntry); /* Create file names */ cfn = (char*) PORT_Alloc(PORT_Strlen(directory) + 100); if (!cfn) { return SECFailure; }#ifdef XP_UNIX sprintf(cfn, "%s/.sslcertc.%d", directory, getpid());#else /* XP_WIN32 */ sprintf(cfn, "%s\\ssl.certc.%d.%d", directory, GetCurrentProcessId(), GetCurrentThreadId());#endif /* XP_WIN32 */ /* Create certificate cache file */#ifdef XP_UNIX
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?