pk11db.c

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

C
650
字号
	(dest)[3] = (unsigned char) ((src)&0xff); \	(dest)[2] = (unsigned char) (((src) >> 8) & 0xff); \	(dest)[1] = (unsigned char) (((src) >> 16) & 0xff); \	(dest)[0] = (unsigned char) (((src) >> 24) & 0xff);#define SECMOD_GETSHORT(src) \	((unsigned short) (((src)[0] << 8) | (src)[1]))#define SECMOD_GETLONG(src) \	((unsigned long) (( (unsigned long) (src)[0] << 24) | \			( (unsigned long) (src)[1] << 16)  | \			( (unsigned long) (src)[2] << 8) | \			(unsigned long) (src)[3]))/* * build a data base entry from a module  */static SECStatus secmod_EncodeData(DBT *data, SECMODModule * module) {    secmodData *encoded;    secmodSlotData *slot;    unsigned char *dataPtr;    unsigned short len, len2 = 0,count = 0;    unsigned short offset;    int dataLen, i, si;    len = PORT_Strlen(module->commonName);    if (module->dllName) {    	len2 = PORT_Strlen(module->dllName);    }    if (module->slotCount != 0) {	for (i=0; i < module->slotCount; i++) {	    if (module->slots[i]->defaultFlags != 0) {		count++;	    }	}    } else {	count = module->slotInfoCount;    }    dataLen = sizeof(secmodData) + len + len2 + 2 +				 count*sizeof(secmodSlotData);    data->data = (unsigned char *)			PORT_Alloc(dataLen);    encoded = (secmodData *)data->data;    dataPtr = (unsigned char *) data->data;    data->size = dataLen;    if (encoded == NULL) return SECFailure;    encoded->major = SECMOD_DB_VERSION_MAJOR;    encoded->minor = SECMOD_DB_VERSION_MINOR;    encoded->internal = (unsigned char) (module->internal ? 1 : 0);    encoded->fips = (unsigned char) (module->isFIPS ? 1 : 0);    SECMOD_PUTLONG(encoded->ssl,module->ssl[0]);    SECMOD_PUTLONG(&encoded->ssl[4],module->ssl[1]);    offset = (unsigned long) &(((secmodData *)0)->names[0]);    SECMOD_PUTSHORT(encoded->nameStart,offset);    offset = offset +len + len2 + 4;    SECMOD_PUTSHORT(encoded->slotOffset,offset);    SECMOD_PUTSHORT(&dataPtr[offset],count);    slot = (secmodSlotData *)(dataPtr+offset+2);    SECMOD_PUTSHORT(encoded->names,len);    PORT_Memcpy(&encoded->names[2],module->commonName,len);    SECMOD_PUTSHORT(&encoded->names[len+2],len2);    if (len2) PORT_Memcpy(&encoded->names[len+4],module->dllName,len2);    if (module->slotCount) {      for (i=0,si=0; i < module->slotCount; i++) {	if (module->slots[i]->defaultFlags) {	    SECMOD_PUTLONG(slot[si].slotID, module->slots[i]->slotID);	    SECMOD_PUTLONG(slot[si].defaultFlags,					     module->slots[i]->defaultFlags);	    SECMOD_PUTLONG(slot[si].timeout,module->slots[i]->timeout);	    slot[si].askpw = module->slots[i]->askpw;	    slot[si].hasRootCerts = module->slots[i]->hasRootCerts;	    PORT_Memset(slot[si].reserved, 0, sizeof(slot[si].reserved));	    si++;	}      }    } else {	for (i=0; i < module->slotInfoCount; i++) {	    SECMOD_PUTLONG(slot[i].slotID, module->slotInfo[i].slotID);	    SECMOD_PUTLONG(slot[i].defaultFlags,					module->slotInfo[i].defaultFlags);	    SECMOD_PUTLONG(slot[i].timeout,module->slotInfo[i].timeout);	    slot[i].askpw = module->slotInfo[i].askpw;	    slot[i].hasRootCerts = module->slotInfo[i].hasRootCerts;	    PORT_Memset(slot[i].reserved, 0, sizeof(slot[i].reserved));	}    }    return SECSuccess;}static void secmod_FreeData(DBT *data) {    if (data->data) {	PORT_Free(data->data);    }}/* * build a module from the data base entry. */static SECMODModule *secmod_DecodeData(DBT *data) {    SECMODModule * module;    secmodData *encoded;    secmodSlotData *slots;    unsigned char *names;    unsigned short len,len1;    unsigned long slotCount;    unsigned short offset;    PRBool isOldVersion  = PR_FALSE;    int i;    encoded = (secmodData *)data->data;    names = (unsigned char *)data->data;    offset = SECMOD_GETSHORT(encoded->slotOffset);    slots = (secmodSlotData *) (names + offset + 2);    slotCount = SECMOD_GETSHORT(names + offset);    names += SECMOD_GETSHORT(encoded->nameStart);    module = SECMOD_NewModule();    if (module == NULL) return NULL;    module->internal = (encoded->internal != 0) ? PR_TRUE: PR_FALSE;    module->isFIPS = (encoded->fips != 0) ? PR_TRUE: PR_FALSE;    len = SECMOD_GETSHORT(names);    if (module->internal && (encoded->major == SECMOD_DB_NOUI_VERSION_MAJOR) && 	(encoded->minor <= SECMOD_DB_NOUI_VERSION_MINOR)) {	isOldVersion = PR_TRUE;    }    /* decode the common name */    module->commonName = (char*)PORT_ArenaAlloc(module->arena,len+1);    if (module->commonName == NULL) {	SECMOD_DestroyModule(module);	return NULL;    }    PORT_Memcpy(module->commonName,&names[2],len);    module->commonName[len] = 0;    /* decode the DLL name */    len1 = (names[len+2] << 8) | names[len+3];    if (len1) {	module->dllName = (char*)PORT_ArenaAlloc(module->arena,len1 + 1);	if (module->dllName == NULL) {	    SECMOD_DestroyModule(module);	    return NULL;	}	PORT_Memcpy(module->dllName,&names[len+4],len1);	module->dllName[len1] = 0;    }    module->slotInfoCount = slotCount;    module->slotInfo = (PK11PreSlotInfo *) PORT_ArenaAlloc(module->arena,				slotCount * sizeof(PK11PreSlotInfo));    for (i=0; i < (int) slotCount; i++) {	module->slotInfo[i].slotID = SECMOD_GETLONG(slots[i].slotID);	module->slotInfo[i].defaultFlags = 				SECMOD_GETLONG(slots[i].defaultFlags);	if (isOldVersion && module->internal && 				(module->slotInfo[i].slotID != 2)) {		module->slotInfo[i].defaultFlags |= internalFlags;	}	module->slotInfo[i].timeout = SECMOD_GETLONG(slots[i].timeout);	module->slotInfo[i].askpw = slots[i].askpw;	module->slotInfo[i].hasRootCerts = slots[i].hasRootCerts;	if (module->slotInfo[i].askpw == 0xff) {	   module->slotInfo[i].askpw = -1;	}    }    /* decode SSL cipher enable flags */    module->ssl[0] = SECMOD_GETLONG(encoded->ssl);    module->ssl[1] = SECMOD_GETLONG(&encoded->ssl[4]);    return (module);}/* * open the PKCS #11 data base. */static char *pkcs11dbName = NULL;void SECMOD_InitDB(char *dbname) {    pkcs11dbName = PORT_Strdup(dbname);}static DB *secmod_OpenDB(PRBool readOnly) {    DB *pkcs11db = NULL;    char *dbname;    if (pkcs11dbName == NULL) return NULL;    dbname = pkcs11dbName;       /* I'm sure we should do more checks here sometime... */    pkcs11db = dbopen(dbname, readOnly ? O_RDONLY : O_RDWR, 0600, DB_HASH, 0);    /* didn't exist? create it */    if (pkcs11db == NULL) {	 if (readOnly) return NULL;	 pkcs11db = dbopen( dbname,                             O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );	 if (pkcs11db) (* pkcs11db->sync)(pkcs11db, 0);    }    return pkcs11db;}static void secmod_CloseDB(DB *pkcs11db) {     (*pkcs11db->close)(pkcs11db);}/* * Read all the existing modules in */SECMODModuleList *SECMOD_ReadPermDB(void) {    DBT key,data;    int ret;    DB *pkcs11db = NULL;    SECMODModuleList *newmod = NULL,*mod = NULL;    pkcs11db = secmod_OpenDB(PR_TRUE);    if (pkcs11db == NULL) {	return NULL;    }    /* read and parse the file or data base */    ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST);    if (ret)  goto done;    do {        /* allocate space for modules */	newmod = SECMOD_NewModuleListElement();	if (newmod == NULL) break;	newmod->module = secmod_DecodeData(&data);	if (newmod->module == NULL) {	    SECMOD_DestroyModuleListElement(newmod);	    break;	}	newmod->next = mod;	mod = newmod;    } while ( (*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT) == 0);done:    secmod_CloseDB(pkcs11db);    return mod;}/* * Delete a module from the Data Base */SECStatusSECMOD_DeletePermDB(SECMODModule * module) {    DBT key;    SECStatus rv = SECFailure;    DB *pkcs11db = NULL;    int ret;    /* make sure we have a db handle */    pkcs11db = secmod_OpenDB(PR_FALSE);    if (pkcs11db == NULL) {	return SECFailure;    }    rv = secmod_MakeKey(&key,module);    if (rv != SECSuccess) goto done;    rv = SECFailure;    ret = (*pkcs11db->del)(pkcs11db, &key, 0);    secmod_FreeKey(&key);    if (ret != 0) goto done;    ret = (*pkcs11db->sync)(pkcs11db, 0);    if (ret == 0) rv = SECSuccess;done:    secmod_CloseDB(pkcs11db);    return rv;}/* * Add a module to the Data base  */SECStatusSECMOD_AddPermDB(SECMODModule *module) {    DBT key,data;    SECStatus rv = SECFailure;    DB *pkcs11db = NULL;    int ret;    /* make sure we have a db handle */    pkcs11db = secmod_OpenDB(PR_FALSE);    if (pkcs11db == NULL) {	return SECFailure;    }    rv = secmod_MakeKey(&key,module);    if (rv != SECSuccess) goto done;    rv = secmod_EncodeData(&data,module);    if (rv != SECSuccess) {	secmod_FreeKey(&key);	goto done;    }    rv = SECFailure;    ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0);    secmod_FreeKey(&key);    secmod_FreeData(&data);    if (ret != 0) goto done;    ret = (*pkcs11db->sync)(pkcs11db, 0);    if (ret == 0) rv = SECSuccess;done:    secmod_CloseDB(pkcs11db);    return rv;}

⌨️ 快捷键说明

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