fortpk11.c

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

C
2,331
字号
/* * 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 implements PKCS 11 for FORTEZZA using MACI *   drivers.  Except for the Mac.  They only have CI libraries, so *   that's what we use there. * *   For more information about PKCS 11 See PKCS 11 Token Inteface Standard. * *   This implementations queries the MACI to figure out how  *    many slots exist on a given system.  There is an artificial boundary *    of 32 slots, because allocating slots dynamically caused memory *    problems in the client when first this module was first developed. *    Some how the heap was being corrupted and we couldn't find out where. *    Subsequent attempts to allocate dynamic memory caused no problem. * *   In this implementation, session objects are only visible to the session *   that created or generated them. */#include "fpkmem.h"#include "seccomon.h"#include "fpkcs11.h"#include "fpkcs11i.h"#include "cryptint.h"#include "pk11func.h"#include "fortsock.h"#include "fmutex.h"#ifdef notdef#include <ctype.h>#include <stdio.h>#endif#ifdef XP_MAC #ifndef __POWERPC__#include <A4Stuff.h>#endif/* This is not a 4.0 project, so I can't depend on * 4.0 defines, so instead I depend on CodeWarrior  * defines.  I define XP_MAC in fpkmem.h */#if __POWERPC__#elif __CFM68K__#else/* These include are taken fromn npmac.cpp which are used * by the plugin group to properly set-up a plug-in for  * dynamic loading on 68K. */#include <Quickdraw.h>/*** The Mixed Mode procInfos defined in npupp.h assume Think C-** style calling conventions.  These conventions are used by** Metrowerks with the exception of pointer return types, which** in Metrowerks 68K are returned in A0, instead of the standard** D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers,** Mixed Mode will return the values to a 68K plugin in D0, but ** a 68K plugin compiled by Metrowerks will expect the result in** A0.  The following pragma forces Metrowerks to use D0 instead.*/#ifdef __MWERKS__#ifndef powerc#pragma pointers_in_D0#endif#endif#ifdef __MWERKS__#ifndef powerc#pragma pointers_in_A0#endif#endif/* The following fix for static initializers fixes a previous** incompatibility with some parts of PowerPlant.*/#ifdef __MWERKS__#ifdef __cplusplus    extern "C" {#endif#ifndef powerc    extern void	__InitCode__(void);#else    extern void __sinit(void);#endif    extern void	__destroy_global_chain(void);#ifdef __cplusplus    }#endif /* __cplusplus */#endif /* __MWERKS__ */#endif#endiftypedef struct {   unsigned char *data;   int len;} CertItem;/* * ******************** Static data ******************************* *//* The next three strings must be exactly 32 characters long */static char *manufacturerID      = "Netscape Communications Corp    ";static char *libraryDescription  = "Communicator Fortezza Crypto Svc";typedef enum {DSA_KEY, KEA_KEY, V1_KEY, INVALID_KEY } PrivKeyType;static PK11Slot           fort11_slot[NUM_SLOTS];static FortezzaSocket     fortezzaSockets[NUM_SLOTS];static PRBool             init = PR_FALSE;static CK_ULONG           kNumSockets    = 0;#define __PASTE(x,y)    x##y  #undef CK_FUNC#undef CK_EXTERN#undef CK_NEED_ARG_LIST#undef _CK_RV#define fort11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen#define fort11_SlotFromSession  pk11_SlotFromSession#define fort11_isToken          pk11_isTokenstatic CK_FUNCTION_LIST fort11_funcList = {    { 2, 1 }, #undef CK_FUNC#undef CK_EXTERN#undef CK_NEED_ARG_LIST#undef _CK_RV #define CK_EXTERN#define CK_FUNC(name) name,#define _CK_RV #include "fpkcs11f.h" }; #undef CK_FUNC#undef CK_EXTERN#undef _CK_RV  #undef __PASTE#undef pk11_SlotFromSessionHandle#undef pk11_SlotFromID#define MAJOR_VERSION_MASK 0xFF00#define MINOR_VERSION_MASK 0x00FF/* Mechanisms */struct mechanismList {    CK_MECHANISM_TYPE	type;    CK_MECHANISM_INFO	domestic;    PRBool              privkey; };static struct mechanismList mechanisms[] = {     {CKM_DSA,              {512,1024,CKF_SIGN},                 PR_TRUE},     {CKM_SKIPJACK_KEY_GEN, {92, 92, CKF_GENERATE},              PR_TRUE},     {CKM_SKIPJACK_CBC64,   {92, 92, CKF_ENCRYPT | CKF_DECRYPT}, PR_TRUE},     {CKM_SKIPJACK_WRAP,    {92, 92, CKF_WRAP},                  PR_TRUE},     {CKM_KEA_KEY_DERIVE,   {128, 128, CKF_DERIVE},              PR_TRUE},};static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);/*************Static function prototypes********************************/static PRBool          fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type);static void            fort11_FreeAttribute(PK11Attribute *attribute);static void            fort11_DestroyAttribute(PK11Attribute *attribute);static PK11Object*     fort11_NewObject(PK11Slot *slot);static PK11FreeStatus  fort11_FreeObject(PK11Object *object);static CK_RV           fort11_AddAttributeType(PK11Object *object,					     CK_ATTRIBUTE_TYPE type,					     void *valPtr,					     CK_ULONG length);static void            fort11_AddSlotObject(PK11Slot *slot, PK11Object *object);static PK11Attribute*  fort11_FindAttribute(PK11Object *object,					  CK_ATTRIBUTE_TYPE type);static PK11Attribute*  fort11_NewAttribute(CK_ATTRIBUTE_TYPE type, 					 CK_VOID_PTR value, CK_ULONG len);static void            fort11_DeleteAttributeType(PK11Object *object,						CK_ATTRIBUTE_TYPE type);static void            fort11_AddAttribute(PK11Object *object,					 PK11Attribute *attribute);static void            fort11_AddObject(PK11Session *session, 				      PK11Object *object);static PK11Object *    fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle, 					     PK11Session *session);static void            fort11_DeleteObject(PK11Session *session,PK11Object *object);static CK_RV           fort11_DestroyObject(PK11Object *object);void   fort11_FreeSession(PK11Session *session);#define FIRST_SLOT_SESS_ID   0x00000100L#define ADD_NEXT_SESS_ID     0x00000100L#define SLOT_MASK            0x000000FFL#define FAILED CKR_FUNCTION_FAILEDstatic voidfort11_FreeFortezzaKey (void *inFortezzaKey) {    RemoveKey ((FortezzaKey*) inFortezzaKey);}static voidfort11_DestroySlotObjects (PK11Slot *slot, PK11Session *session) {    PK11Object *currObject, *nextObject, *oldObject;    int i;    for (i=0; i<HASH_SIZE; i++) {      currObject = slot->tokObjects[i];      slot->tokObjects[i] = NULL;      do {	  FMUTEX_Lock(slot->sessionLock);	  if (currObject) {	      nextObject = currObject->next;	      FMUTEX_Lock(currObject->refLock);	      currObject->refCount++;	      FMUTEX_Unlock(currObject->refLock);	      fort11_DeleteObject(session, currObject);	  }	  FMUTEX_Unlock(slot->sessionLock);	  if (currObject) {	      oldObject = currObject;	      currObject = nextObject;	      fort11_FreeObject(oldObject);	  }      } while (currObject != NULL);    }}static voidfort11_TokenRemoved(PK11Slot *slot, PK11Session *session) {    FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];    LogoutFromSocket (socket);    slot->isLoggedIn = PR_FALSE;    if (session && session->notify) {         /*If no session pointer exists, lots of leaked memory*/        session->notify (session->handle, CKN_SURRENDER,			 session->appData);	fort11_FreeSession(session); /* Release the reference held				      * by the slot with the session				      */    }    fort11_DestroySlotObjects(slot, session);    fort11_FreeSession(session); /* Release the reference held				  * by the slot with the session				  */    /* All keys will have been freed at this point so we can     * NULL out this pointer     */    socket->keys = NULL;}PRBoolfort11_FortezzaIsUserCert(unsigned char * label) {    if ( (!PORT_Memcmp(label, "KEAK", 4)) ||   /* v3 user certs */         (!PORT_Memcmp(label, "DSA1", 4)) ||	 (!PORT_Memcmp(label, "DSAI", 4)) ||         (!PORT_Memcmp(label, "DSAO", 4)) ||         (!PORT_Memcmp(label, "INKS", 4)) ||   /* v1 user certs */          (!PORT_Memcmp(label, "INKX", 4)) ||         (!PORT_Memcmp(label, "ONKS", 4)) ||         (!PORT_Memcmp(label, "ONKX", 4)) ||         (!PORT_Memcmp(label, "3IXS", 4)) ||   /* old v3 user certs */         (!PORT_Memcmp(label, "3OXS", 4)) ||         (!PORT_Memcmp(label, "3IKX", 4)) ) {           return PR_TRUE;    } else { return PR_FALSE; }    }static PRBoolfort11_FortezzaIsACert(unsigned char * label) {    if (label == NULL) return PR_FALSE;    if ( (!PORT_Memcmp(label, "DSA1", 4)) ||   /* v3 certs */         (!PORT_Memcmp(label, "DSAI", 4)) ||	 (!PORT_Memcmp(label, "DSAO", 4)) ||          (!PORT_Memcmp(label, "DSAX", 4)) ||         (!PORT_Memcmp(label, "KEAK", 4)) ||         (!PORT_Memcmp(label, "KEAX", 4)) ||         (!PORT_Memcmp(label, "CAX1", 4)) ||         (!PORT_Memcmp(label, "PCA1", 4)) ||         (!PORT_Memcmp(label, "PAA1", 4)) ||         (!PORT_Memcmp(label, "ICA1", 4)) ||         (!PORT_Memcmp(label, "3IXS", 4)) ||   /* old v3 certs */             (!PORT_Memcmp(label, "3OXS", 4)) ||             (!PORT_Memcmp(label, "3CAX", 4)) ||         (!PORT_Memcmp(label, "3IKX", 4)) ||         (!PORT_Memcmp(label, "3PCA", 4)) ||         (!PORT_Memcmp(label, "3PAA", 4)) ||         (!PORT_Memcmp(label, "3ICA", 4)) ||         (!PORT_Memcmp(label, "INKS", 4)) ||   /* v1 certs */             (!PORT_Memcmp(label, "INKX", 4)) ||         (!PORT_Memcmp(label, "ONKS", 4)) ||         (!PORT_Memcmp(label, "ONKX", 4)) ||         (!PORT_Memcmp(label, "RRXX", 4)) ||         (!PORT_Memcmp(label, "RTXX", 4)) ||         (!PORT_Memcmp(label, "LAXX", 4)) ) {           return PR_TRUE;    }     return PR_FALSE; } static int fort11_cert_length(unsigned char *buf, int length) {    unsigned char tag;    int used_length= 0;    int data_length;    tag = buf[used_length++];    /* blow out when we come to the end */    if (tag == 0) {	return 0;    }    data_length = buf[used_length++];    if (data_length&0x80) {	int  len_count = data_length & 0x7f;	data_length = 0;	while (len_count-- > 0) {	    data_length = (data_length << 8) | buf[used_length++];	}     }    if (data_length > (length-used_length) ) {	return length;    }    return (data_length + used_length);	}unsigned char *fort11_data_start(unsigned char *buf, int length, 				 int *data_length, PRBool includeTag) {    unsigned char tag;    int used_length= 0;    tag = buf[used_length++];    /* blow out when we come to the end */    if (tag == 0) {	return NULL;    }    *data_length = buf[used_length++];    if (*data_length&0x80) {	int  len_count = *data_length & 0x7f;	*data_length = 0;	while (len_count-- > 0) {	    *data_length = (*data_length << 8) | buf[used_length++];	}     }    if (*data_length > (length-used_length) ) {	*data_length = length-used_length;	return NULL;    }    if (includeTag) *data_length += used_length;    return (buf + (includeTag ? 0 : used_length));	}intfort11_GetCertFields(unsigned char *cert,int cert_length,CertItem *issuer,		     CertItem *serial,CertItem *subject){	unsigned char *buf;	int buf_length;	unsigned char *date;	int datelen;	/* get past the signature wrap */	buf = fort11_data_start(cert,cert_length,&buf_length,PR_FALSE);	if (buf == NULL) return FAILED;	/* get into the raw cert data */	buf = fort11_data_start(buf,buf_length,&buf_length,PR_FALSE);	if (buf == NULL) return FAILED;	/* skip past any optional version number */        if ((buf[0] & 0xa0) == 0xa0) {            date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);            if (date == NULL) return FAILED;            buf_length -= (date-buf) + datelen;            buf = date + datelen;        }        /* serial number */	serial->data = fort11_data_start(buf,buf_length,&serial->len,PR_FALSE);	if (serial->data == NULL) return FAILED;	buf_length -= (serial->data-buf) + serial->len;	buf = serial->data + serial->len;	/* skip the OID */	date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);	if (date == NULL) return FAILED;	buf_length -= (date-buf) + datelen;	buf = date + datelen;	/* issuer */	issuer->data = fort11_data_start(buf,buf_length,&issuer->len,PR_TRUE);	if (issuer->data == NULL) return FAILED;	buf_length -= (issuer->data-buf) + issuer->len;	buf = issuer->data + issuer->len;	/* skip the date */	date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);	if (date == NULL) return FAILED;	buf_length -= (date-buf) + datelen;	buf = date + datelen;	/*subject */	subject->data=fort11_data_start(buf,buf_length,&subject->len,PR_TRUE);	if (subject->data == NULL) return FAILED;	buf_length -= (subject->data-buf) + subject->len;	buf = subject->data +subject->len;	/*subject */	return CKR_OK;}

⌨️ 快捷键说明

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