forsock.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 816 行 · 第 1/2 页
C
816 行
/* * 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. */#include "fortsock.h"#include "fpkmem.h"#include "fmutex.h"#include <string.h>#include <stdlib.h>#define DEF_ENCRYPT_SIZE 0x8000static unsigned char Fortezza_mail_Rb[128] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,};int InitSocket (FortezzaSocket *inSocket, int inSlotID) { int ci_rv; CK_RV mrv; if (inSocket == NULL) return SOCKET_FAILURE; inSocket->isLoggedIn = PR_FALSE; inSocket->personalitiesLoaded = PR_FALSE; inSocket->isOpen = PR_FALSE; inSocket->personalityList = NULL; inSocket->keyRegisters = NULL; inSocket->keys = NULL; inSocket->numPersonalities = 0; inSocket->numKeyRegisters = 0; inSocket->hitCount = 0; inSocket->slotID = inSlotID; ci_rv = MACI_GetSessionID(&(inSocket->maciSession)); if (ci_rv != CI_OK) return SOCKET_FAILURE; ci_rv = MACI_Open (inSocket->maciSession, 0, inSlotID); if (ci_rv == CI_OK) { inSocket->isOpen = PR_TRUE; } else { MACI_Close (inSocket->maciSession, CI_NULL_FLAG, inSlotID); } if (FMUTEX_MutexEnabled()) { mrv = FMUTEX_Create(&inSocket->registersLock); if (mrv != CKR_OK) { inSocket->registersLock = NULL; } } else { inSocket->registersLock = NULL; } return SOCKET_SUCCESS;}int FreeSocket (FortezzaSocket *inSocket) { if (inSocket->registersLock) { FMUTEX_Destroy(inSocket->registersLock); } MACI_Close(inSocket->maciSession, CI_NULL_FLAG, inSocket->slotID); return SOCKET_SUCCESS;}int LoginToSocket (FortezzaSocket *inSocket, int inUserType, CI_PIN inPin) { int ci_rv, i; CI_STATUS ciStatus; CI_CONFIG ciConfig; FortezzaKey **oldRegisters, **newRegisters; int oldCount; HSESSION hs; if (inSocket == NULL || inSocket->isLoggedIn) return SOCKET_FAILURE; hs = inSocket->maciSession; ci_rv = MACI_Select (hs, inSocket->slotID); if (ci_rv != CI_OK) return ci_rv; ci_rv = MACI_CheckPIN(hs, inUserType, inPin); if (ci_rv != CI_OK) { return ci_rv; } ci_rv = MACI_GetStatus(hs, &ciStatus); if (ci_rv != CI_OK) { if (ci_rv == CI_FAIL) { ci_rv = CI_EXEC_FAIL; } return ci_rv; } ci_rv = MACI_GetConfiguration(hs, &ciConfig); if (ci_rv != CI_OK) { return ci_rv; } inSocket->isLoggedIn = PR_TRUE; inSocket->hasLoggedIn = PR_TRUE; PORT_Memcpy (inSocket->openCardSerial, ciStatus.SerialNumber, sizeof (CI_SERIAL_NUMBER)); inSocket->openCardState = ciStatus.CurrentState; inSocket->numPersonalities = ciStatus.CertificateCount; inSocket->numKeyRegisters = ciConfig.KeyRegisterCount; newRegisters = (FortezzaKey**)PORT_Alloc (sizeof(FortezzaKey)*ciConfig.KeyRegisterCount); FMUTEX_Lock(inSocket->registersLock); oldRegisters = inSocket->keyRegisters; oldCount = inSocket->numKeyRegisters; inSocket->keyRegisters = newRegisters; if (oldRegisters) { for (i=0; i<oldCount; i++) { if (oldRegisters[i]) { oldRegisters[i]->keyRegister = KeyNotLoaded; } oldRegisters[i] = NULL; } PORT_Free(oldRegisters); } if (inSocket->keyRegisters == NULL) { FMUTEX_Unlock(inSocket->registersLock); return SOCKET_FAILURE; } for (i=0; i<ciConfig.KeyRegisterCount; i++) { inSocket->keyRegisters[i] = NULL; } FMUTEX_Unlock(inSocket->registersLock); return SOCKET_SUCCESS;}int LogoutFromSocket (FortezzaSocket *inSocket) { if (inSocket == NULL) return SOCKET_FAILURE; inSocket->isLoggedIn = PR_FALSE; inSocket->hasLoggedIn = PR_FALSE; if (UnloadPersonalityList(inSocket) != SOCKET_SUCCESS) return SOCKET_FAILURE; return SOCKET_SUCCESS;}int FetchPersonalityList(FortezzaSocket *inSocket) { int rv; if (inSocket == NULL || inSocket->numPersonalities == 0) { return SOCKET_FAILURE; } rv = MACI_Select (inSocket->maciSession, inSocket->slotID); inSocket->personalityList = (CI_PERSON*)PORT_Alloc (sizeof(CI_PERSON)*inSocket->numPersonalities); if (inSocket->personalityList == NULL) { return SOCKET_FAILURE; } rv = MACI_GetPersonalityList(inSocket->maciSession, inSocket->numPersonalities, inSocket->personalityList); if (rv != CI_OK) { return SOCKET_FAILURE; } inSocket->personalitiesLoaded = PR_TRUE; return SOCKET_SUCCESS;}int UnloadPersonalityList(FortezzaSocket *inSocket) { if (inSocket == NULL) return SOCKET_FAILURE; inSocket->personalitiesLoaded = PR_FALSE; if (inSocket->personalityList) { PORT_Free(inSocket->personalityList); } inSocket->numPersonalities = 0; inSocket->personalityList = NULL; return SOCKET_SUCCESS;}PRBool SocketIsLoggedIn(CI_STATE status) { return (PRBool)((status == CI_READY) || (status == CI_STANDBY));}PRBool SocketStateUnchanged(FortezzaSocket* inSocket) { CI_STATUS ciStatus; int ciRV; ciRV = MACI_Select (inSocket->maciSession, inSocket->slotID); if (ciRV != CI_OK) return PR_FALSE; if (inSocket->hasLoggedIn && !inSocket->isLoggedIn) return PR_FALSE; /* User Logged out from the socket */ /* * Some vendor cards are slow. so if we think we are logged in, * and the card still thinks we're logged in, we must have the same * card. */ if (inSocket->isLoggedIn) { CI_STATE state; ciRV = MACI_GetState(inSocket->maciSession, &state); if (ciRV != CI_OK) return PR_FALSE; return SocketIsLoggedIn(state); } ciRV = MACI_GetStatus(inSocket->maciSession, &ciStatus); if(ciRV != CI_OK) { return PR_FALSE; } if (inSocket->isLoggedIn) { if (PORT_Memcmp(ciStatus.SerialNumber, inSocket->openCardSerial, sizeof (CI_SERIAL_NUMBER)) != 0) return PR_FALSE; /* Serial Number of card in slot has changed */ /* Probably means there is a new card */ } if (inSocket->isLoggedIn && !SocketIsLoggedIn(ciStatus.CurrentState)) return PR_FALSE; /* State of card changed. */ /* Probably re-inserted same card */ return PR_TRUE; /* No change in the state of the socket */}/* * can we regenerate this key on the fly? */static PRBoolFortezzaIsRegenerating(FortezzaKey *key) { /* TEK's are the only type of key that can't be regenerated */ if (key->keyType != TEK) return PR_TRUE; /* Client TEK's can never be regenerated */ if (key->keyData.tek.flags == CI_INITIATOR_FLAG) return PR_FALSE; /* Only Server TEK's that use the Mail protocol can be regenerated */ return ((PRBool)(memcmp(key->keyData.tek.Rb,Fortezza_mail_Rb, sizeof(key->keyData.tek.Rb)) == 0));}int GetBestKeyRegister(FortezzaSocket *inSocket) { int i, candidate = -1, candidate2 = 1; CK_ULONG minHitCount = 0xffffffff; CK_ULONG minRegHitCount = 0xffffffff; FortezzaKey **registers; registers = inSocket->keyRegisters; for (i=1; i< inSocket->numKeyRegisters; i++) { if (registers[i] == NULL) return i; } for (i=1; i < inSocket->numKeyRegisters; i++) { if (registers[i]->hitCount < minHitCount) { minHitCount = registers[i]->hitCount; candidate2 = i; } if (FortezzaIsRegenerating(registers[i]) && (registers[i]->hitCount < minRegHitCount)) { minRegHitCount = registers[i]->hitCount; candidate = i; } } if (candidate == -1) candidate = candidate2; return candidate;}int SetFortezzaKeyHandle (FortezzaKey *inKey, CK_OBJECT_HANDLE inHandle) { inKey->keyHandle = inHandle; return SOCKET_SUCCESS;}voidRemoveKey (FortezzaKey *inKey) { if (inKey != NULL && inKey->keySocket->keyRegisters != NULL) { if (inKey->keyRegister != KeyNotLoaded) { FortezzaKey **registers = inKey->keySocket->keyRegisters; registers[inKey->keyRegister] = NULL; MACI_DeleteKey(inKey->keySocket->maciSession, inKey->keyRegister); } PORT_Free(inKey); }}FortezzaKey *NewFortezzaKey(FortezzaSocket *inSocket, FortezzaKeyType inKeyType, CreateTEKInfo *TEKinfo, int inKeyRegister) { FortezzaKey *newKey, *oldKey; FortezzaKey **registers; HSESSION hs = inSocket->maciSession; int ciRV; newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey)); if (newKey == NULL) { return NULL; } newKey->keyHandle = 0; newKey->keyRegister = KeyNotLoaded; newKey->keyType = inKeyType; newKey->keySocket = inSocket; newKey->hitCount = 0; newKey->id = TEKinfo ? TEKinfo->personality : 0; if (inKeyType != Ks && inSocket->keyRegisters) { registers = inSocket->keyRegisters; oldKey = registers[inKeyRegister]; if (oldKey != NULL) { oldKey->keyRegister = KeyNotLoaded; } registers[inKeyRegister] = newKey; newKey->hitCount = inSocket->hitCount++; MACI_DeleteKey (hs, inKeyRegister); } newKey->keyRegister = inKeyRegister; MACI_Lock(hs, CI_BLOCK_LOCK_FLAG); switch (inKeyType) { case MEK: ciRV = MACI_GenerateMEK (hs, inKeyRegister, 0); if (ciRV != CI_OK) { RemoveKey(newKey); MACI_Unlock(hs); return NULL; } MACI_WrapKey(hs, 0, inKeyRegister, newKey->keyData.mek); break; case TEK: PORT_Memcpy (newKey->keyData.tek.Rb, TEKinfo->Rb, TEKinfo->randomLen); PORT_Memcpy (newKey->keyData.tek.Ra, TEKinfo->Ra, TEKinfo->randomLen); PORT_Memcpy (newKey->keyData.tek.pY, TEKinfo->pY, TEKinfo->YSize); newKey->keyData.tek.ySize = TEKinfo->YSize; newKey->keyData.tek.randomLen = TEKinfo->randomLen; newKey->keyData.tek.registerIndex = TEKinfo->personality; newKey->keyData.tek.flags = TEKinfo->flag; ciRV = MACI_SetPersonality(hs,TEKinfo->personality); if (ciRV != CI_OK) { RemoveKey(newKey); MACI_Unlock(hs); return NULL; } ciRV = MACI_GenerateTEK(hs, TEKinfo->flag, inKeyRegister, newKey->keyData.tek.Ra, TEKinfo->Rb, TEKinfo->YSize, TEKinfo->pY); if (ciRV != CI_OK) { RemoveKey(newKey); MACI_Unlock(hs); return NULL; } break; case Ks:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?