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