swflib.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,029 行 · 第 1/2 页
C
1,029 行
return ret;}/* * return the bytes of a certificate. */intMACI_GetCertificate(HSESSION hSession, int certIndex, CI_CERTIFICATE CI_FAR cert){ int len; int ret; fortSlotEntry *certEntry = NULL; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; certEntry = fort_GetCertEntry(swtoken->config_file,certIndex); if (certEntry == NULL) return CI_INV_CERT_INDEX; len = certEntry->certificateData.dataEncryptedWithKs.len; PORT_Memset(cert,0,sizeof(CI_CERTIFICATE)); PORT_Memcpy(cert, certEntry->certificateData.dataEncryptedWithKs.data,len); /* Ks is always stored in keyReg[0] when we log in */ return fort_skipjackDecrypt(swtoken->keyReg[0].data, &certEntry->certificateData.dataIV.data[SKIPJACK_LEAF_SIZE], len,cert,cert);}/* * return out sofware configuration bytes. Those field not used by the PKCS #11 * module may not be filled in exactly. */#define NETSCAPE "Netscape Communications Corp "#define PRODUCT "Netscape Software FORTEZZA Lib "#define SOFTWARE "Software FORTEZZA Implementation"intMACI_GetConfiguration(HSESSION hSession, CI_CONFIG_PTR config){ config->LibraryVersion = 0x0100; config->ManufacturerVersion = 0x0100; PORT_Memcpy(config->ManufacturerName,NETSCAPE,sizeof(NETSCAPE)); PORT_Memcpy(config->ProductName,PRODUCT,sizeof(PRODUCT)); PORT_Memcpy(config->ProcessorType,SOFTWARE,sizeof(SOFTWARE)); config->UserRAMSize = 0; config->LargestBlockSize = 0x10000; config->KeyRegisterCount = KEY_REGISTERS; config->CertificateCount = swtoken ? fort_GetCertCount(swtoken->config_file): 0; config->CryptoCardFlag = 0; config->ICDVersion = 0; config->ManufacturerSWVer = 0x0100; config->DriverVersion = 0x0100; return CI_OK;}/* * return a list of all the personalities (up to the value 'EntryCount') */intMACI_GetPersonalityList(HSESSION hSession, int EntryCount, CI_PERSON CI_FAR personList[]){ int count; int i,ret; FORTSWFile *config_file = NULL; unsigned char tmp[32]; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; config_file = swtoken->config_file; /* search for the index */ count= fort_GetCertCount(config_file); /* don't return more than the user asked for */ if (count > EntryCount) count = EntryCount; for (i=0; i < count ;i ++) { int len, dataLen; personList[i].CertificateIndex = config_file->slotEntries[i]->certIndex; len = config_file->slotEntries[i]->certificateLabel. dataEncryptedWithKs.len; if (len > sizeof(tmp)) len = sizeof(tmp); PORT_Memset(personList[i].CertLabel, ' ', sizeof(personList[i].CertLabel)); PORT_Memcpy(tmp, config_file->slotEntries[i]-> certificateLabel.dataEncryptedWithKs.data, len); /* Ks is always stored in keyReg[0] when we log in */ ret = fort_skipjackDecrypt(swtoken->keyReg[0].data, &config_file->slotEntries[i]-> certificateLabel.dataIV.data[SKIPJACK_LEAF_SIZE],len, tmp,tmp); if (ret != CI_OK) return ret; dataLen = DER_GetInteger(&config_file->slotEntries[i]-> certificateLabel.length); if (dataLen > sizeof(tmp)) dataLen = sizeof(tmp); PORT_Memcpy(personList[i].CertLabel, tmp, dataLen); personList[i].CertLabel[32] = 0; personList[i].CertLabel[33] = 0; personList[i].CertLabel[34] = 0; personList[i].CertLabel[35] = 0; } return CI_OK;}/* * get a new session ID. This function is only to make the interface happy, * the PKCS #11 module only uses one session per token. */intMACI_GetSessionID(HSESSION *session){ *session = 1; return CI_OK;}/* * return the current card state. */intMACI_GetState(HSESSION hSession, CI_STATE_PTR state){ int ret; if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret; *state = fort_GetState(swtoken); return CI_OK;}/* * return the status. NOTE that KeyRegisterFlags and CertificateFlags are never * really used by the PKCS #11 module, so they are not implemented. */intMACI_GetStatus(HSESSION hSession, CI_STATUS_PTR status){ int ret; FORTSWFile *config_file = NULL; if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret; config_file = swtoken->config_file; status->CurrentSocket = 1; status->LockState = swtoken->lock; PORT_Memcpy(status->SerialNumber, config_file->serialID.data, config_file->serialID.len); status->CurrentState = fort_GetState(swtoken); status->DecryptionMode = CI_CBC64_MODE; status->EncryptionMode = CI_CBC64_MODE; status->CurrentPersonality = swtoken->certIndex; status->KeyRegisterCount = KEY_REGISTERS; /* our code doesn't use KeyRegisters, which is good, because there's not * enough of them .... */ PORT_Memset(status->KeyRegisterFlags,0,sizeof(status->KeyRegisterFlags)); status->CertificateCount = fort_GetCertCount(config_file); PORT_Memset(status->CertificateFlags,0,sizeof(status->CertificateFlags)); PORT_Memset(status->Flags,0,sizeof(status->Flags)); return CI_OK;}/* * add the time call because the PKCS #11 module calls it, but always pretend * the clock is bad, so it never uses the returned time. */intMACI_GetTime(HSESSION hSession, CI_TIME CI_FAR time){ return CI_BAD_CLOCK;}/* This function is copied from NSPR so that the PKCS #11 module can be * independent of NSPR */PRInt32 local_getFileInfo(const char *fn, PRFileInfo *info);/* * initialize the SW module, and return the number of slots we support (1). */intMACI_Initialize(int CI_FAR *count){ char *filename = NULL; SECItem file; FORTSignedSWFile *decode_file = NULL; PRFileInfo info; /*PRFileDesc *fd = NULL;*/ int fd = -1; PRStatus err; int ret = CI_OK; int fcount; file.data = NULL; file.len = 0; *count = 1; /* allocate swtoken structure */ swtoken = PORT_ZNew(FORTSWToken); if (swtoken == NULL) return CI_OUT_OF_MEMORY; filename = (char *)fort_LookupFORTEZZAInitFile(); if (filename == NULL) { ret = CI_BAD_READ; goto failed; } fd = open(filename,O_RDONLY|O_BINARY,0); if (fd < 0) { ret = CI_BAD_READ; goto failed; } err = local_getFileInfo(filename,&info); if ((err != 0) || (info.size == 0)) { ret = CI_BAD_READ; goto failed; } file.data = PORT_ZAlloc(info.size); if (file.data == NULL) { ret = CI_OUT_OF_MEMORY; goto failed; } fcount = read(fd,file.data,info.size); close(fd); fd = -1; if (fcount != (int)info.size) { ret = CI_BAD_READ; goto failed; } file.len = fcount; decode_file = FORT_GetSWFile(&file); if (decode_file == NULL) { ret = CI_BAD_READ; goto failed; } swtoken->config_file = &decode_file->file; RNG_SystemInfoForRNG(); RNG_FileForRNG(filename);failed: if (filename) PORT_Free(filename); if (fd != -1) close(fd); if (file.data) PORT_Free(file.data); if (ret != CI_OK) { if (decode_file) FORT_DestroySignedSWFile(decode_file); if (swtoken) PORT_Free(swtoken); swtoken = NULL; } return CI_OK;}/* * load an IV from an external source. We technically should check it with the * key we received. */intMACI_LoadIV(HSESSION session, CI_IV CI_FAR iv){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; PORT_Memcpy(swtoken->IV,&iv[SKIPJACK_LEAF_SIZE],SKIPJACK_BLOCK_SIZE); return CI_OK;}/* implement token lock (should call PR_Monitor here) */intMACI_Lock(HSESSION session, int flags){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; swtoken->lock = 1; return CI_OK;}/* open a token. For software there isn't much to do that hasn't already been * done by initialize. */intMACI_Open(HSESSION session, unsigned int flags, int socket){ if (socket != SOCKET_ID) return CI_NO_CARD; if (swtoken == NULL) return CI_NO_CARD; return CI_OK;}/* * Reset logs out the token... */intMACI_Reset(HSESSION session){ if (swtoken) fort_Logout(swtoken); return CI_OK;}/* * restore and encrypt/decrypt state. NOTE: there is no error checking in this * or the save function. */intMACI_Restore(HSESSION session, int type, CI_SAVE_DATA CI_FAR data){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; PORT_Memcpy(swtoken->IV,data, sizeof (swtoken->IV)); return CI_OK;}/* * save and encrypt/decrypt state. NOTE: there is no error checking in this * or the restore function. */intMACI_Save(HSESSION session, int type,CI_SAVE_DATA CI_FAR data){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; PORT_Memcpy(data,swtoken->IV, sizeof (swtoken->IV)); return CI_OK;}/* * picks a token to operate against. In our case there can be only one. */intMACI_Select(HSESSION session, int socket){ if (socket == SOCKET_ID) return CKR_OK; return CI_NO_CARD;}/* * set a register as the key to use for encrypt/decrypt operations. */intMACI_SetKey(HSESSION session, int index){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; if ((ret = fort_KeyOK(swtoken,index,PR_TRUE)) != CI_OK) return ret; swtoken->key = index; return CI_OK;}/* * only CBC64 is supported. Keep setmode for compatibility */intMACI_SetMode(HSESSION session, int type, int mode){ if (mode != CI_CBC64_MODE) return CI_INV_MODE; return CI_OK;}/* set the personality to use for sign/verify */intMACI_SetPersonality(HSESSION session, int cert){ int ret; fortSlotEntry *certEntry = NULL; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; certEntry = fort_GetCertEntry(swtoken->config_file,cert); if ((certEntry == NULL) || ((certEntry->exchangeKeyInformation == NULL) && (certEntry->signatureKeyInformation == NULL)) ) return CI_INV_CERT_INDEX; swtoken->certIndex = cert; return CI_OK;}/* DSA sign some data */intMACI_Sign(HSESSION session, CI_HASHVALUE CI_FAR hash, CI_SIGNATURE CI_FAR sig){ SECKEYLowPrivateKey *key = NULL; fortSlotEntry * certEntry = NULL; int ret = CI_OK; SECStatus rv; SECItem signItem; SECItem hashItem; unsigned char random[DSA_SUBPRIME_LEN]; /* standard checks */ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; /* make sure the personality is set */ if (swtoken->certIndex == 0) return CI_INV_STATE; /* get the current personality */ certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex); if (certEntry == NULL) return CI_INV_CERT_INDEX; /* extract the private key from the personality */ ret = CI_OK; key = fort_GetPrivKey(swtoken,dsaKey,certEntry); if (key == NULL) { ret = CI_NO_X; goto loser; } /* create a random value for the signature */ ret = fort_GenerateRandom(random, sizeof(random)); if (ret != CI_OK) goto loser; /* Sign with that private key */ signItem.data = sig; signItem.len = DSA_SIGNATURE_LEN; hashItem.data = hash; hashItem.len = SHA1_LENGTH; rv = DSA_SignDigestWithSeed(&key->u.dsa, &signItem, &hashItem, random); if (rv != SECSuccess) { ret = CI_EXEC_FAIL; } /* clean up */loser: if (key != NULL) SECKEY_LowDestroyPrivateKey(key); return ret;}/* * clean up after ourselves. */intMACI_Terminate(HSESSION session){ if (swtoken == NULL) return CI_OUT_OF_MEMORY; /* clear all the keys */ fort_Logout(swtoken); FORT_DestroySWFile(swtoken->config_file); PORT_Free(swtoken); swtoken = NULL; return CI_OK;}/* implement token unlock (should call PR_Monitor here) */intMACI_Unlock(HSESSION session){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; swtoken->lock = 0; return CI_OK;}/* * unwrap a key into our software token. NOTE: this function does not * verify that the wrapping key is Ks or a TEK. This is because our higher * level software doesn't try to wrap MEKs with MEKs. If this API was exposed * generically, then we would have to worry about things like this. */intMACI_UnwrapKey(HSESSION session, int wrapKey, int target, CI_KEY CI_FAR keyData){ int ret = CI_OK; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; if ((ret = fort_KeyOK(swtoken,target,PR_FALSE)) != CI_OK) return ret; if ((ret = fort_KeyOK(swtoken,wrapKey,PR_TRUE)) != CI_OK) return ret; ret = fort_skipjackUnwrap(swtoken->keyReg[wrapKey].data, sizeof(CI_KEY), keyData, swtoken->keyReg[target].data); if (ret != CI_OK) goto loser; swtoken->keyReg[target].present = PR_TRUE;loser: return ret;}/* * Wrap a key out of our software token. NOTE: this function does not * verify that the wrapping key is Ks or a TEK, or that the source key is * a MEK. This is because our higher level software doesn't try to wrap MEKs * with MEKs, or wrap out TEKS and Ks. If this API was exposed * generically, then we would have to worry about things like this. */intMACI_WrapKey(HSESSION session, int wrapKey, int source, CI_KEY CI_FAR keyData){ int ret; if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret; if ((ret = fort_KeyOK(swtoken,source,PR_TRUE)) != CI_OK) return ret; if ((ret = fort_KeyOK(swtoken,wrapKey,PR_TRUE)) != CI_OK) return ret; ret = fort_skipjackWrap(swtoken->keyReg[wrapKey].data, sizeof(CI_KEY), swtoken->keyReg[source].data,keyData); return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?