pcks#11 是一个公钥加密的规范,关于此规范的说明可以google到很多文档,后面有空在写文章总结
nss pcks#11接口调用说明参考链接 pcks#11
Impl for nss,本文主要介绍nss中的动态链接库softokn3.so关于pcks#11的实现部分。
编译nss 代码时,提供了一个测试命令shlibsign来测试pcks#11的实现。main的代码片段如下:
-
/* Get the platform-dependent library name of the
-
* NSS cryptographic module.
-
*/
-
libname = PR_GetLibraryName(NULL, "softokn3"); //这里通过nspr框架(这个框架见备注说明),加载softokn3的动态链接库
-
assert(libname != NULL);
-
lib = PR_LoadLibrary(libname);
-
assert(lib != NULL);
-
PR_FreeLibraryName(libname);
-
-
-
if (FIPSMODE) {
-
/* FIPSMODE == FC_GetFunctionList */
-
/* library path must be set to an already signed softokn3/freebl */
-
pC_GetFunctionList = (CK_C_GetFunctionList)
-
PR_FindFunctionSymbol(lib, "FC_GetFunctionList");
-
} else {
-
/* NON FIPS mode == C_GetFunctionList */
-
pC_GetFunctionList = (CK_C_GetFunctionList)
-
PR_FindFunctionSymbol(lib, "C_GetFunctionList"); //查找 C_GetFunctionList
-
}
-
assert(pC_GetFunctionList != NULL);
-
-
crv = (*pC_GetFunctionList)(&pFunctionList);
-
assert(crv == CKR_OK);
-
-
if (configDir) {
-
if (!dbPrefix) {
-
dbPrefix = PL_strdup("");
-
}
-
crv = softokn_Init(pFunctionList, configDir, dbPrefix);
-
if (crv != CKR_OK) {
-
logIt("Failed to use provided database directory "
-
"will just initialize the volatile certdb.\n");
-
crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */
-
}
-
} else {
-
crv = softokn_Init(pFunctionList, NULL, NULL); /* NoDB Init */
-
}
C_GetFunctionList的代码片段如下:
-
/* return the function list */
-
CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
-
{
-
CHECK_FORK();
-
-
*pFunctionList = (CK_FUNCTION_LIST_PTR) &sftk_funcList;//这里返回的是sftk_funclist,这里是个全局变量
-
return CKR_OK;
-
}
-
-
/* return the function list */
-
CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
-
{
-
CHECK_FORK();
-
-
return NSC_GetFunctionList(pFunctionList);
-
}
sftk_funcList的初始化代码如下:
-
/* build the crypto module table */
-
static const CK_FUNCTION_LIST sftk_funcList = {
-
{ 1, 10 },
-
-
#undef CK_PKCS11_FUNCTION_INFO
-
#undef CK_NEED_ARG_LIST
-
-
#define CK_PKCS11_FUNCTION_INFO(func) \
-
__PASTE(NS,func),
-
#include "pkcs11f.h" //这里的关键是引用了pkcs11f.h,并且重新定义了CK_PKCS11_FUNCTION_INFO宏,此宏相当于所有func前面增加NS
-
-
};
pcks11f.h的代码片段如下:
点击(此处)折叠或打开
-
/* C_Initialize initializes the PKCS #11 library. */
-
CK_PKCS11_FUNCTION_INFO(C_Initialize) //这里展开之后相当于变成了NSC_Initialize,说明所有的实现函数最终都是包含NSC前缀的
-
#ifdef CK_NEED_ARG_LIST
-
(
-
CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
-
* cast to CK_C_INITIALIZE_ARGS_PTR
-
* and dereferenced */
-
);
-
#endif
NSC_Initialize的实现代码如下:
-
CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
-
{
-
CK_RV crv;
-
-
sftk_ForkReset(pReserved, &crv);
-
-
if (nsc_init) {
-
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
-
}
-
crv = nsc_CommonInitialize(pReserved,PR_FALSE);
-
nsc_init = (PRBool) (crv == CKR_OK);
-
return crv;
-
}
找到了这种定义的逻辑,再分析这种代码应该就不难了,这里的代码定义的比较紧凑和巧妙,很多开源的框架,包括glibc都会使用到这种技巧,这是读起来或者用工具跟踪代码的时候比较麻烦。
阅读(608) | 评论(0) | 转发(0) |