📄 pkcs11ui.c
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * 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. *//* PKCS11 interface routines. Created by mwelch 1999 March 29 */#include "pkcs11ui.h"#include "pkcs11.h"#include "pk11func.h"#include "plstr.h"#include "secmod.h"#include "secmodti.h"#include "minihttp.h"#include "textgen.h"/* Utility */PK11SlotInfo *SSMPKCS11_FindSlotByID(SECMODModuleID modID, CK_SLOT_ID slotID){ SECMODModule *mod = NULL; PK11SlotInfo *slot = NULL; PRIntn i; mod = SECMOD_FindModuleByID(modID); if (mod) { for(i=0;i<mod->slotCount;i++) { if (mod->slots[i]->slotID == slotID) return mod->slots[i]; } } return NULL;}/* --------------------------------------------------------- PKCS11 module processing (list, add, delete) --------------------------------------------------------- */SSMStatusssmpkcs11_convert_module(SSMTextGenContext *cx, PRInt32 modIndex, SECMODModule *mod, char *fmt){ char *libraryDesc = NULL; char *dllName = NULL; char *version = NULL; char *tempStr = NULL; char *lib_ch = NULL; CK_INFO modInfo; SSMStatus rv = SSM_FAILURE; SECStatus srv; /* 65 is what's was used in the original UI. */ char buf[65]; char buf2[65]; srv = PK11_GetModInfo(mod, &modInfo); if (srv != SECSuccess) goto loser; /* we provide the space in (buf), so we don't deallocate lib_ch */ lib_ch = PK11_MakeString(NULL,buf2,(char *)modInfo.libraryDescription, sizeof(modInfo.libraryDescription)); if (mod->dllName) { dllName = mod->dllName; } else { rv = SSM_GetAndExpandText(cx, "text_pk11_no_dll", &dllName); if (rv != SSM_SUCCESS) goto loser; } PR_snprintf(buf, sizeof(buf), "%d.%d", modInfo.libraryVersion.major, modInfo.libraryVersion.minor); tempStr = PR_smprintf(fmt, modIndex, (long)mod->moduleID, lib_ch, mod->commonName, dllName, buf); if (tempStr == NULL) { rv = SSM_FAILURE; goto loser; } rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr); loser: if (dllName && dllName != mod->dllName) PR_Free(dllName); PR_FREEIF (tempStr); return rv;}/* PKCS11 module list keyword handler. Syntax: {_pk11modules <wrapper_key>}*/SSMStatusSSM_PKCS11ModulesKeywordHandler(SSMTextGenContext *cx){ SSMStatus rv = SSM_SUCCESS; char *wrapperKey = NULL; char *wrapperStr = NULL; SECMODModuleList *modList = SECMOD_GetDefaultModuleList(); SECMODModuleList *modWalk = NULL; SECMODListLock *modLock = SECMOD_GetDefaultModuleListLock(); PRBool gotLock = PR_FALSE; /* indicates whether we should release at end */ PRInt32 i=0; /* Check for parameter validity */ PR_ASSERT(cx); PR_ASSERT(cx->m_request); PR_ASSERT(cx->m_params); PR_ASSERT(cx->m_result); if (!cx || !cx->m_request || !cx->m_params || !cx->m_result) { rv = PR_INVALID_ARGUMENT_ERROR; goto real_loser; /* really bail here */ } if (SSM_Count(cx->m_params) != 1) { SSM_HTTPReportSpecificError(cx->m_request, "_certList: " "Incorrect number of parameters " "(%d supplied, 1 needed).\n", SSM_Count(cx->m_params)); goto user_loser; } /* Convert parameters to something we can use in finding certs. */ wrapperKey = (char *) SSM_At(cx->m_params, 0); PR_ASSERT(wrapperKey); /* Get the wrapper text. */ rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapperStr); if (rv != SSM_SUCCESS) goto real_loser; /* error string set by the called function */ /* Iterate over the PKCS11 modules. Put relevant info from each into its own copy of the wrapper text. */ SECMOD_GetReadLock(modLock); gotLock = PR_TRUE; modWalk = modList; while (modWalk) { rv = ssmpkcs11_convert_module(cx, i++, modWalk->module, wrapperStr); modWalk = modWalk->next; } goto done;user_loser: /* If we reach this point, something in the input is wrong, but we can still send something back to the client to indicate that a problem has occurred. */ /* If we can't do what we're about to do, really bail. */ if (!cx->m_request || !cx->m_request->errormsg) goto real_loser; /* Clear the string we were accumulating. */ SSMTextGen_UTF8StringClear(&cx->m_result); /* Use the result string given to us to explain what happened. */ SSM_ConcatenateUTF8String(&cx->m_result, cx->m_request->errormsg); /* Clear the result string, since we're sending this inline */ SSMTextGen_UTF8StringClear(&cx->m_request->errormsg); goto done;real_loser: /* If we reach this point, then it is so bad that we cannot send anything vaguely normal back to the client. Bail. */ if (rv == SSM_SUCCESS) rv = SSM_FAILURE;done: PR_FREEIF(wrapperStr); if (modLock && gotLock) SECMOD_ReleaseReadLock(modLock); return rv;}/* --------------------------------------------------------- PKCS11 slot code --------------------------------------------------------- */enum{ SSM_PK11STR_SLOT_LOGGED_IN = (long) 0, SSM_PK11STR_SLOT_NOT_LOGGED_IN, SSM_PK11STR_SLOT_NO_LOGIN_REQUIRED, SSM_PK11STR_SLOT_NOT_PRESENT, SSM_PK11STR_SLOT_UNINITIALIZED, SSM_PK11STR_SLOT_DISABLED, SSM_PK11STR_SLOT_READY, SSM_PK11STR_SLOT_STRING_COUNT};static char *slotStringKeys[] ={ "text_pk11_slot_logged_in", "text_pk11_slot_not_logged_in", "text_pk11_slot_no_login_required", "text_pk11_slot_not_present", "text_pk11_slot_uninitialized", "text_pk11_slot_disabled", "text_pk11_slot_ready"};static char **slotStrings = NULL;voidssmpkcs11_initialize_slot_labels(SSMTextGenContext *cx){ SSMStatus rv = SSM_SUCCESS; PRIntn i; slotStrings = (char **) PR_Calloc(SSM_PK11STR_SLOT_STRING_COUNT + 1, sizeof(char**)); PR_ASSERT(slotStrings); for(i=0;i<SSM_PK11STR_SLOT_STRING_COUNT;i++) { rv = SSM_FindUTF8StringInBundles(cx, slotStringKeys[i], &slotStrings[i]); PR_ASSERT(rv == SSM_SUCCESS); }}SSMStatusssmpkcs11_convert_slot(SSMTextGenContext *cx, PRInt32 slotIndex, PK11SlotInfo *slot, char *fmt, PRBool accumulate) /* accumulate in cx->m_result? */{ char *name = NULL; char *statusStr = NULL; char *serial = NULL; char *version = NULL; char *tempStr = NULL; char *name_ch = NULL; long status, slotID = 0, moduleID = 0; CK_TOKEN_INFO tokenInfo; SSMStatus rv = SSM_FAILURE; SECStatus srv = SECSuccess; /* 65 is what's was used in the original UI. */ char buf[65]; char empty[1] = { '\0' } ; if (!slotStrings) ssmpkcs11_initialize_slot_labels(cx); /* If we have a NULL slot, return blank information. */ if (!slot) { name = empty; statusStr = empty; serial = empty; version = empty; slotID = 0; goto show_stuff; } /* Get the slot name. Either the default name or the name of the token in the slot will be used. */ if (PK11_IsPresent(slot)) name = PK11_GetTokenName(slot); else name = PK11_GetSlotName(slot); /* Report the status of the slot. */ if (PK11_IsDisabled(slot)) status = SSM_PK11STR_SLOT_DISABLED; else if (!PK11_IsPresent(slot)) status = SSM_PK11STR_SLOT_NOT_PRESENT; else if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) status = SSM_PK11STR_SLOT_UNINITIALIZED; else if (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL)) status = SSM_PK11STR_SLOT_NOT_LOGGED_IN; else if (PK11_NeedLogin(slot)) status = SSM_PK11STR_SLOT_LOGGED_IN; else status = SSM_PK11STR_SLOT_READY; statusStr = slotStrings[status]; /* Get the serial number and version. */ /* This is how the old UI determines if there's a token in, so... */ if (PK11_IsPresent(slot)) srv = PK11_GetTokenInfo(slot, &tokenInfo); if (PK11_IsPresent(slot) && (srv == SECSuccess)) { /* Get serial number and version from the token info. */ serial = PK11_MakeString(NULL, NULL, (char*)tokenInfo.serialNumber, sizeof(tokenInfo.serialNumber)); PR_snprintf(buf, sizeof(buf), "%d.%d", tokenInfo.firmwareVersion.major, tokenInfo.firmwareVersion.minor); version = buf; } else { /* Get serial number and version from the slot info. */ CK_SLOT_INFO slotInfo; srv = PK11_GetSlotInfo(slot, &slotInfo); if (srv != SECSuccess) goto loser; serial = empty; PR_snprintf(buf, sizeof(buf), "%d.%d", slotInfo.firmwareVersion.major, slotInfo.firmwareVersion.minor); version = buf; } slotID = (long) (slot->slotID); moduleID = (long) (slot->module->moduleID); show_stuff: tempStr = PR_smprintf(fmt, slotIndex, slotID, moduleID, name, statusStr, serial, version); if (accumulate) { rv = SSM_ConcatenateUTF8String(&cx->m_result, tempStr); if (rv != SSM_SUCCESS) { goto loser; } } else rv = SSM_HTTPSendUTF8String(cx->m_request, tempStr); loser: /* The data that isn't freed is either because it's a member of the * data in a structure of the PK11 libraries or its a static local * variable. */ if (serial && serial != empty) PR_Free(serial); PR_FREEIF(tempStr); return rv;}/* PKCS11 slot list keyword handler. Syntax: {_pk11slots <moduleID>,<wrapper_key>}*/SSMStatusSSM_PKCS11SlotsKeywordHandler(SSMTextGenContext *cx){ SSMStatus rv = SSM_SUCCESS; SECMODModule *module = NULL; char *wrapperKey = NULL; char *moduleIDStr = NULL; char *modID_ch = NULL; long moduleID; char *wrapperStr = NULL; PRInt32 i=0; /* Check for parameter validity */ PR_ASSERT(cx); PR_ASSERT(cx->m_request); PR_ASSERT(cx->m_params); PR_ASSERT(cx->m_result); if (!cx || !cx->m_request || !cx->m_params || !cx->m_result) { rv = PR_INVALID_ARGUMENT_ERROR; goto real_loser; /* really bail here */ } if (SSM_Count(cx->m_params) != 2) { SSM_HTTPReportSpecificError(cx->m_request, "_certList: " "Incorrect number of parameters " "(%d supplied, 2 needed).\n", SSM_Count(cx->m_params)); goto user_loser; } /* Convert parameters to something we can use in finding certs. */ moduleIDStr = (char *) SSM_At(cx->m_params, 0); PR_ASSERT(moduleIDStr); wrapperKey = (char *) SSM_At(cx->m_params, 1); PR_ASSERT(wrapperKey); /* Find the module we're looking for based on the module ID. */ module = SECMOD_FindModuleByID((SECMODModuleID) moduleID); if (!module) goto user_loser; /* Get the wrapper text. */ rv = SSM_GetAndExpandTextKeyedByString(cx, wrapperKey, &wrapperStr); if (rv != SSM_SUCCESS) goto real_loser; /* error string set by the called function */ /* Iterate over the slots from this module. Put relevant info from each into its own copy of the wrapper text. */ for(i=0;i<module->slotCount;i++) { rv = ssmpkcs11_convert_slot(cx, i, module->slots[i], wrapperStr, PR_TRUE); if (rv != SSM_SUCCESS) goto user_loser; } goto done;user_loser: /* If we reach this point, something in the input is wrong, but we can still send something back to the client to indicate that a problem has occurred. */ /* If we can't do what we're about to do, really bail. */ if (!cx->m_request || !cx->m_request->errormsg) goto real_loser; /* Clear the string we were accumulating. */ SSMTextGen_UTF8StringClear(&cx->m_result); /* Use the result string given to us to explain what happened. */ SSM_ConcatenateUTF8String(&cx->m_result, cx->m_request->errormsg); /* Clear the result string, since we're sending this inline */ SSMTextGen_UTF8StringClear(&cx->m_request->errormsg); goto done;real_loser: /* If we reach this point, then it is so bad that we cannot send anything vaguely normal back to the client. Bail. */ if (rv == SSM_SUCCESS) rv = SSM_FAILURE;done: PR_FREEIF(wrapperStr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -