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