swfutl.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 743 行 · 第 1/2 页

C
743
字号
/* * 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. *//* * This File includes utility functions used by cilib. and swfparse.c */#include "prtypes.h"#include "prsystem.h"#include "prio.h"#include "swforti.h"#include "keyt.h"/* #include "dh.h" */#include "maci.h"#include "secport.h"#include "secrng.h"#ifdef XP_OS2#include <stat.h> 	/* Needed for OS/2 emx */#endif#ifdef XP_WIN#include <windows.h>#include <winsock.h>#include <direct.h>#endif/* no platform seem to agree on where this function is defined */static char *local_index(char *source, char target) {   while ((*source != target) && (*source != 0)) {	*source++;   }   return (*source != 0) ? source : NULL;}/* * Check to see if the index is ok, and that key is appropriately present or * absent. */intfort_KeyOK(FORTSWToken *token, int index, PRBool isPresent){    if (index < 0) return CI_INV_KEY_INDEX;    if (index >= KEY_REGISTERS) return CI_INV_KEY_INDEX;    return (token->keyReg[index].present == isPresent) ? CI_OK : 			(isPresent ? CI_NO_KEY : CI_REG_IN_USE);}/* * clear out a key register */voidfort_ClearKey(FORTKeySlot *key){    key->present = PR_FALSE;    PORT_Memset(key->data, 0, sizeof (key->data));    return;}/* * clear out an Ra register */voidfort_ClearRaSlot(FORTRaRegisters *ra){    PORT_Memset(ra->public, 0, sizeof(ra->public));    PORT_Memset(ra->private, 0, sizeof(ra->private));    return;}/* * provide a helper function to do all the loggin out functions. * NOTE: Logining in only happens in MACI_CheckPIN */voidfort_Logout(FORTSWToken *token){    int i;    /* ditch all the stored keys */    for (i=0; i < KEY_REGISTERS; i++) {	fort_ClearKey(&token->keyReg[i]);    }    for (i=0; i < MAX_RA_SLOTS; i++) {	fort_ClearRaSlot(&token->RaValues[i]);    }    /* mark as logged out */    token->login = PR_FALSE;    token->certIndex = 0;    token->key = 0;    return;}/* * update the new IV value based on the current cipherText (should be the last  * block of the cipher text). */intfort_UpdateIV(unsigned char *cipherText, unsigned int size,unsigned char *IV){    if (size == 0) return CI_INV_SIZE;    if ((size & (SKIPJACK_BLOCK_SIZE-1)) != 0) return CI_INV_SIZE;    size -= SKIPJACK_BLOCK_SIZE;    PORT_Memcpy(IV,&cipherText[size],SKIPJACK_BLOCK_SIZE);    return CI_OK;}/* * verify that we have a card initialized, and if necessary, logged in. */intfort_CardExists(FORTSWToken *token,PRBool needLogin){    if (token == NULL ) return CI_LIB_NOT_INIT;     if (token->config_file == NULL) return CI_NO_CARD;    if (needLogin && !token->login) return CI_INV_STATE;    return CI_OK;}/* * walk down the cert slot entries, counting them. * return that count. */intfort_GetCertCount(FORTSWFile *file){    int i;    if (file->slotEntries == NULL) return 0;    for (i=0; file->slotEntries[i]; i++) 	/* no body */ ;    return i;}/* * copy an unsigned SECItem to a signed SecItem. (if the high bit is on, * pad with a leading 0. */SECStatusfort_CopyUnsigned(PRArenaPool *arena, SECItem *to, const SECItem *from){    int offset = 0;    if (from->data && from->len) {	if (from->data[0] & 0x80) offset = 1;	if ( arena ) {	    to->data = (unsigned char*) PORT_ArenaZAlloc(arena,							 from->len+offset);	} else {	    to->data = (unsigned char*) PORT_ZAlloc(from->len+offset);	}		if (!to->data) {	    return SECFailure;	}	PORT_Memcpy(to->data+offset, from->data, from->len);	to->len = from->len+offset;    } else {	to->data = 0;	to->len = 0;    }    return SECSuccess;}/* * NOTE: these keys do not have the public values, and cannot be used to * extract the public key from the private key. Since we never do this in * this code, and this function is static, we're reasonably safe (as long as * any of your callees do not try to extract the public value as well). * Also -- the token must be logged in before this function is called. */SECKEYLowPrivateKey *fort_GetPrivKey(FORTSWToken *token,KeyType keyType,fortSlotEntry *certEntry){    SECKEYLowPrivateKey *returnKey = NULL;    SECStatus rv = SECFailure;    PRArenaPool *poolp;    fortKeyInformation *keyInfo;    unsigned char *keyData;    int len, ret;    /* select the right keyinfo */    switch (keyType) {    case dsaKey:	keyInfo = certEntry->signatureKeyInformation;	if (keyInfo ==  NULL) keyInfo = certEntry->exchangeKeyInformation;	break;    case dhKey:	keyInfo = certEntry->exchangeKeyInformation;	if (keyInfo == NULL) keyInfo = certEntry->signatureKeyInformation;	break;    }    /* if we don't have any key information, blow out of here */    if (keyInfo == NULL) return NULL;    poolp = PORT_NewArena(2048);    if(!poolp) {	return NULL;    }    returnKey = (SECKEYLowPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(SECKEYLowPrivateKey));    if(!returnKey) {	rv = SECFailure;	goto loser;    }    returnKey->keyType = keyType;    returnKey->arena = poolp;    /*     * decrypt the private key     */    len = keyInfo->privateKeyWrappedWithKs.len;    keyData = PORT_ArenaZAlloc(poolp,len);    if (keyData == NULL) {	rv = SECFailure;	goto loser;    }    /* keys must be 160 bits (20 bytes) if that's not the case the Unwrap will     * fail.. */    ret = fort_skipjackUnwrap(token->keyReg[0].data, len, 			keyInfo->privateKeyWrappedWithKs.data, keyData);    if (ret != CI_OK) {	rv = SECFailure;	goto loser;    }    switch(keyType) {	case dsaKey:	    returnKey->u.dsa.privateValue.data = keyData;	    returnKey->u.dsa.privateValue.len = 20;	    returnKey->u.dsa.params.arena = poolp;	    rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.prime),					&(keyInfo->p));	    if(rv != SECSuccess) break;	    rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.subPrime),					&(keyInfo->q));	    if(rv != SECSuccess) break;	    rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.base),					&(keyInfo->g));	    if(rv != SECSuccess) break;	    break;	case dhKey:	    returnKey->u.dh.arena = poolp;	    returnKey->u.dh.privateValue.data = keyData;	    returnKey->u.dh.privateValue.len = 20;	    rv = fort_CopyUnsigned(poolp, &(returnKey->u.dh.prime),					&(keyInfo->p));	    if(rv != SECSuccess) break;	    rv = fort_CopyUnsigned(poolp, &(returnKey->u.dh.base),					&(keyInfo->g));	    if(rv != SECSuccess) break;	    rv = SECSuccess;	    break;	default:	    rv = SECFailure;    }loser:    if(rv != SECSuccess) {	PORT_FreeArena(poolp, PR_TRUE);	returnKey = NULL;    }    return returnKey;}/* * find a particulare certificate entry from the config * file. */fortSlotEntry *fort_GetCertEntry(FORTSWFile *file,int index){    /* search for the index */    int i,count= fort_GetCertCount(file);    /* make sure the given index exists & has key material */    for (i=0; i < count ;i ++) {	if (file->slotEntries[i]->certIndex == index) {	    return file->slotEntries[i];	}    }    return NULL;}/* * use the token to determine it's CI_State. */CI_STATEfort_GetState(FORTSWToken *token){    /* no file? then the token has not been initialized */    if (!token->config_file) {	return CI_UNINITIALIZED;    }    /* we're initialized, are we logged in (CI_USER_INITIALIZED is not logged     * in) */    if (!token->login) {	return CI_USER_INITIALIZED;    }    /* We're logged in, do we have a personality set */    if (token->certIndex) {	return CI_READY;    }    /* We're logged in, with no personality set */    return CI_STANDBY;}/* * find the private ra value for a given public Ra value. */fortRaPrivatePtrfort_LookupPrivR(FORTSWToken *token,CI_RA Ra){    int i;    /* probably a more efficient way of doing this would be to search first     * several entries before nextRa (or search backwards from next Ra)     */    for (i=0; i < MAX_RA_SLOTS; i++) {	if (PORT_Memcmp(token->RaValues[i].public,Ra,CI_RA_SIZE) == 0) {	    return token->RaValues[i].private;	}    }    return NULL;}/* * go add more noise to the random number generator */voidfort_AddNoise(void)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?