summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--automation/abi-check/expected-report-libnss3.so.txt13
-rw-r--r--automation/abi-check/expected-report-libsoftokn3.so.txt10
-rw-r--r--cmd/pk11mode/pk11mode.c2
-rw-r--r--lib/pk11wrap/pk11load.c65
-rw-r--r--lib/pk11wrap/secmodi.h2
-rw-r--r--lib/pk11wrap/secmodt.h1
-rw-r--r--lib/softoken/fipstokn.c365
-rw-r--r--lib/softoken/manifest.mn1
-rw-r--r--lib/softoken/pkcs11.c127
-rw-r--r--lib/softoken/pkcs11c.c55
-rw-r--r--lib/softoken/pkcs11i.h3
-rw-r--r--lib/softoken/sftkmessage.c166
-rw-r--r--lib/softoken/softoken.gyp1
-rw-r--r--lib/softoken/softoken.h17
-rw-r--r--lib/softoken/softokn.def11
-rw-r--r--lib/util/pkcs11.h6
-rw-r--r--lib/util/pkcs11f.h48
-rw-r--r--lib/util/pkcs11n.h10
-rw-r--r--nss/automation/abi-check/new-report-libnss3.so.txt13
-rw-r--r--nss/automation/abi-check/new-report-libsoftokn3.so.txt8
20 files changed, 870 insertions, 54 deletions
diff --git a/automation/abi-check/expected-report-libnss3.so.txt b/automation/abi-check/expected-report-libnss3.so.txt
index e69de29bb..edf5a1310 100644
--- a/automation/abi-check/expected-report-libnss3.so.txt
+++ b/automation/abi-check/expected-report-libnss3.so.txt
@@ -0,0 +1,13 @@
+
+1 function with some indirect sub-type change:
+
+ [C]'function SECStatus PK11_GetModInfo(SECMODModule*, CK_INFO*)' at pk11util.c:613:1 has some indirect sub-type changes:
+ parameter 1 of type 'SECMODModule*' has sub-type changes:
+ in pointed to type 'typedef SECMODModule' at secmodt.h:29:1:
+ underlying type 'struct SECMODModuleStr' at secmodt.h:44:1 changed:
+ type size changed from 1600 to 1664 (in bits)
+ 1 data member insertion:
+ 'CK_FLAGS SECMODModuleStr::flags', at offset 1600 (in bits) at secmodt.h:76:1
+ no data member change (1 filtered);
+
+
diff --git a/automation/abi-check/expected-report-libsoftokn3.so.txt b/automation/abi-check/expected-report-libsoftokn3.so.txt
index e69de29bb..b26ffd3e5 100644
--- a/automation/abi-check/expected-report-libsoftokn3.so.txt
+++ b/automation/abi-check/expected-report-libsoftokn3.so.txt
@@ -0,0 +1,10 @@
+
+6 Added functions:
+
+ 'function CK_RV C_GetInterface(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS)' {C_GetInterface@@NSS_3.52}
+ 'function CK_RV C_GetInterfaceList(CK_INTERFACE_PTR, CK_ULONG_PTR)' {C_GetInterfaceList@@NSS_3.52}
+ 'function CK_RV FC_GetInterface(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS)' {FC_GetInterface@@NSS_3.52}
+ 'function CK_RV FC_GetInterfaceList(CK_INTERFACE_PTR, CK_ULONG_PTR)' {FC_GetInterfaceList@@NSS_3.52}
+ 'function CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS)' {NSC_GetInterface@@NSS_3.52}
+ 'function CK_RV NSC_GetInterfaceList(CK_INTERFACE_PTR, CK_ULONG_PTR)' {NSC_GetInterfaceList@@NSS_3.52}
+
diff --git a/cmd/pk11mode/pk11mode.c b/cmd/pk11mode/pk11mode.c
index 16554536d..851d64f8f 100644
--- a/cmd/pk11mode/pk11mode.c
+++ b/cmd/pk11mode/pk11mode.c
@@ -16,7 +16,7 @@
#include <string.h>
#include <stdarg.h>
-#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
+#if defined(XP_UNIX) && defined(DO_FORK_CHECK)
#include <unistd.h>
#include <sys/wait.h>
#else
diff --git a/lib/pk11wrap/pk11load.c b/lib/pk11wrap/pk11load.c
index 7413429db..8e80fe7b3 100644
--- a/lib/pk11wrap/pk11load.c
+++ b/lib/pk11wrap/pk11load.c
@@ -380,7 +380,9 @@ softoken_LoadDSO(void)
return PR_FAILURE;
}
#else
-CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList);
+CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName,
+ CK_VERSION_PTR pVersion,
+ CK_INTERFACE_PTR_PTR *ppInterface, CK_FLAGS flags);
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
#endif
@@ -391,12 +393,18 @@ SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
PRLibrary *library = NULL;
- CK_C_GetFunctionList entry = NULL;
+ CK_C_GetInterface ientry = NULL;
+ CK_C_GetFunctionList fentry = NULL;
CK_INFO info;
CK_ULONG slotCount = 0;
SECStatus rv;
PRBool alreadyLoaded = PR_FALSE;
char *disableUnload = NULL;
+#ifndef NSS_STATIC_SOFTOKEN
+ const char *nss_interface;
+ const char *nss_function;
+#endif
+ CK_INTERFACE_PTR interface;
if (mod->loaded)
return SECSuccess;
@@ -404,7 +412,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/* internal modules get loaded from their internal list */
if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_STATIC_SOFTOKEN
- entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
+ ientry = (CK_C_GetInterface)NSC_GetInterface;
#else
/*
* Loads softoken as a dynamic library,
@@ -417,15 +425,22 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
PR_ATOMIC_INCREMENT(&softokenLoadCount);
if (mod->isFIPS) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "FC_GetFunctionList");
+ nss_interface = "FC_GetInterface";
+ nss_function = "FC_GetFunctionList";
} else {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
+ nss_interface = "NSC_GetInterface";
+ nss_function = "NSC_GetFunctionList";
}
- if (!entry)
- return SECFailure;
+ ientry = (CK_C_GetInterface)
+ PR_FindSymbol(softokenLib, nss_interface);
+ if (!ientry) {
+ fentry = (CK_C_GetFunctionList)
+ PR_FindSymbol(softokenLib, nss_function);
+ if (!fentry) {
+ return SECFailure;
+ }
+ }
#endif
if (mod->isModuleDB) {
@@ -461,8 +476,12 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
* now we need to get the entry point to find the function pointers
*/
if (!mod->moduleDBOnly) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(library, "C_GetFunctionList");
+ ientry = (CK_C_GetInterface)
+ PR_FindSymbol(library, "C_GetInterface");
+ if (!ientry) {
+ fentry = (CK_C_GetFunctionList)
+ PR_FindSymbol(library, "C_GetFunctionList");
+ }
}
if (mod->isModuleDB) {
mod->moduleDBFunc = (void *)
@@ -470,7 +489,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
}
if (mod->moduleDBFunc == NULL)
mod->isModuleDB = PR_FALSE;
- if (entry == NULL) {
+ if ((ientry == NULL) && (fentry == NULL)) {
if (mod->isModuleDB) {
mod->loaded = PR_TRUE;
mod->moduleDBOnly = PR_TRUE;
@@ -484,8 +503,22 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/*
* We need to get the function list
*/
- if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
- goto fail;
+ if (ientry) {
+ /* we first try to get a FORK_SAFE interface */
+ if ((*ientry)((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface,
+ CKF_INTERFACE_FORK_SAFE) != CKR_OK) {
+ /* one is not appearantly available, get a non-fork safe version */
+ if ((*ientry)((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface, 0) != CKR_OK) {
+ goto fail;
+ }
+ }
+ mod->functionList = interface->pFunctionList;
+ mod->flags = interface->flags;
+ } else {
+ if ((*fentry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
+ goto fail;
+ mod->flags = 0;
+ }
#ifdef DEBUG_MODULE
modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
@@ -513,10 +546,10 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/* check the version number */
if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK)
goto fail2;
- if (info.cryptokiVersion.major != 2)
+ if (info.cryptokiVersion.major < 2)
goto fail2;
/* all 2.0 are a priori *not* thread safe */
- if (info.cryptokiVersion.minor < 1) {
+ if ((info.cryptokiVersion.major == 2) && (info.cryptokiVersion.minor < 1)) {
if (!loadSingleThreadedModules) {
PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
goto fail2;
diff --git a/lib/pk11wrap/secmodi.h b/lib/pk11wrap/secmodi.h
index 634b241bd..a85f94cc2 100644
--- a/lib/pk11wrap/secmodi.h
+++ b/lib/pk11wrap/secmodi.h
@@ -94,7 +94,7 @@ CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot,
CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot,
CK_ATTRIBUTE *inTemplate, int tsize, int *objCount);
-#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_PTR)((x)->functionList))
+#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_3_0_PTR)((x)->functionList))
#define PK11_SETATTRS(x, id, v, l) \
(x)->type = (id); \
(x)->pValue = (v); \
diff --git a/lib/pk11wrap/secmodt.h b/lib/pk11wrap/secmodt.h
index 23abe307f..34fd4cce1 100644
--- a/lib/pk11wrap/secmodt.h
+++ b/lib/pk11wrap/secmodt.h
@@ -73,6 +73,7 @@ struct SECMODModuleStr {
unsigned long evControlMask; /* control the running and shutdown of slot
* events (SECMOD_WaitForAnyTokenEvent) */
CK_VERSION cryptokiVersion; /* version of this library */
+ CK_FLAGS flags; /* pkcs11 v3 flags */
};
/* evControlMask flags */
diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c
index 5d456716e..3fe1f0dcb 100644
--- a/lib/softoken/fipstokn.c
+++ b/lib/softoken/fipstokn.c
@@ -230,6 +230,8 @@ fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
+#define CK_PKCS11_3_0 1
+
#define CK_PKCS11_FUNCTION_INFO(name) CK_RV __PASTE(NS, name)
#define CK_NEED_ARG_LIST 1
@@ -245,11 +247,32 @@ fc_getAttribute(CK_ATTRIBUTE_PTR pTemplate,
#include "pkcs11f.h"
/* ------------- build the CK_CRYPTO_TABLE ------------------------- */
-static CK_FUNCTION_LIST sftk_fipsTable = {
- { 1, 10 },
+static CK_FUNCTION_LIST_3_0 sftk_fipsTable = {
+ { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(F, name) \
+ ,
+
+#include "pkcs11f.h"
+
+};
+
+/* forward declaration of special GetInfo functions */
+CK_RV FC_GetInfoV2(CK_INFO_PTR pInfo);
+CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo);
+
+static CK_FUNCTION_LIST sftk_fipsTable_v2 = {
+ { 2, 40 },
+#undef CK_PKCS11_3_0
+#define CK_PKCS11_2_0_ONLY 1
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
+#define C_GetInfo C_GetInfoV2
#define CK_PKCS11_FUNCTION_INFO(name) \
__PASTE(F, name) \
@@ -259,11 +282,24 @@ static CK_FUNCTION_LIST sftk_fipsTable = {
};
+#undef C_GetInfo
#undef CK_NEED_ARG_LIST
#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_PKCS11_2_0_ONLY
#undef __PASTE
+/*
+ * Array is orderd by default first
+ */
+static CK_INTERFACE fips_interfaces[] = {
+ { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable, NSS_INTERFACE_FLAGS },
+ { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_fipsTable_v2, NSS_INTERFACE_FLAGS },
+ { (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS }
+};
+/* must match the count of interfaces in fips_interfaces above*/
+#define FIPS_INTERFACE_COUNT 3
+
/* CKO_NOT_A_KEY can be any object class that's not a key object. */
#define CKO_NOT_A_KEY CKO_DATA
@@ -419,10 +455,51 @@ FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
CHECK_FORK();
- *pFunctionList = &sftk_fipsTable;
+ *pFunctionList = &sftk_fipsTable_v2;
return CKR_OK;
}
+CK_RV
+FC_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
+{
+ CK_ULONG count = *pulCount;
+ *pulCount = FIPS_INTERFACE_COUNT;
+ if (interfaces == NULL) {
+ return CKR_OK;
+ }
+ if (count < FIPS_INTERFACE_COUNT) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ PORT_Memcpy(interfaces, fips_interfaces, sizeof(fips_interfaces));
+ return CKR_OK;
+}
+
+/*
+ * Get the requested interface, use the fips_interfaces array so we can
+ * easily add new interfaces as they occur.
+ */
+CK_RV
+FC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
+ CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
+{
+ int i;
+ for (i = 0; i < FIPS_INTERFACE_COUNT; i++) {
+ CK_INTERFACE_PTR interface = &fips_interfaces[i];
+ if (pInterfaceName && PORT_Strcmp((char *)pInterfaceName, (char *)interface->pInterfaceName) != 0) {
+ continue;
+ }
+ if (pVersion && PORT_Memcmp(pVersion, (CK_VERSION *)interface->pFunctionList, sizeof(CK_VERSION)) != 0) {
+ continue;
+ }
+ if (flags & ((interface->flags & flags) != flags)) {
+ continue;
+ }
+ *ppInterface = interface;
+ return CKR_OK;
+ }
+ return CKR_ARGUMENTS_BAD;
+}
+
/* sigh global so pkcs11 can read it */
PRBool nsf_init = PR_FALSE;
@@ -510,6 +587,15 @@ FC_GetInfo(CK_INFO_PTR pInfo)
return NSC_GetInfo(pInfo);
}
+/* FC_GetInfo returns general information about PKCS #11. */
+CK_RV
+FC_GetInfoV2(CK_INFO_PTR pInfo)
+{
+ CHECK_FORK();
+
+ return NSC_GetInfoV2(pInfo);
+}
+
/* FC_GetSlotList obtains a list of slots in the system. */
CK_RV
FC_GetSlotList(CK_BBOOL tokenPresent,
@@ -540,7 +626,7 @@ FC_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
crv = NSC_GetTokenInfo(slotID, pInfo);
if (crv == CKR_OK) {
- /* use the global database to figure out if we are running in
+ /* use the global database to figure out if we are running in
* FIPS 140 Level 1 or Level 2 */
if (slotID == FIPS_SLOT_ID &&
(pInfo->flags & CKF_LOGIN_REQUIRED) == 0) {
@@ -718,6 +804,16 @@ FC_CloseAllSessions(CK_SLOT_ID slotID)
return NSC_CloseAllSessions(slotID);
}
+CK_RV
+FC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags)
+{
+ SFTK_FIPSFATALCHECK();
+
+ CHECK_FORK();
+
+ return NSC_SessionCancel(hSession, flags);
+}
+
/* FC_GetSessionInfo obtains information about the session. */
CK_RV
FC_GetSessionInfo(CK_SESSION_HANDLE hSession,
@@ -777,6 +873,36 @@ FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
return rv;
}
+CK_RV
+FC_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername,
+ CK_ULONG ulUsernameLen)
+{
+ CK_RV rv;
+ PRBool successful;
+ if (sftk_fatalError)
+ return CKR_DEVICE_ERROR;
+ rv = NSC_LoginUser(hSession, userType, pPin, ulPinLen,
+ pUsername, ulUsernameLen);
+ successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN);
+ if (successful)
+ isLoggedIn = PR_TRUE;
+ if (sftk_audit_enabled) {
+ char msg[128];
+ char user[61];
+ int len = PR_MIN(ulUsernameLen, sizeof(user) - 1);
+ PORT_Memcpy(user, pUsername, len);
+ user[len] = 0;
+ NSSAuditSeverity severity;
+ severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR;
+ PR_snprintf(msg, sizeof msg,
+ "C_LoginUser(hSession=0x%08lX, userType=%lu username=%s)=0x%08lX",
+ (PRUint32)hSession, (PRUint32)userType, user, (PRUint32)rv);
+ sftk_LogAuditMessage(severity, NSS_AUDIT_LOGIN, msg);
+ }
+ return rv;
+}
+
/* FC_Logout logs a user out from a token. */
CK_RV
FC_Logout(CK_SESSION_HANDLE hSession)
@@ -1691,3 +1817,234 @@ FC_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot,
return NSC_WaitForSlotEvent(flags, pSlot, pReserved);
}
+
+CK_RV
+FC_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+
+ rv = NSC_MessageEncryptInit(hSession, pMechanism, hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("MessageEncrypt", hSession, pMechanism, hKey, rv);
+ }
+ return rv;
+}
+
+CK_RV
+FC_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext,
+ CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext,
+ CK_ULONG_PTR pulCiphertextLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_EncryptMessage(hSession, pParameter, ulParameterLen,
+ pAssociatedData, ulAssociatedDataLen,
+ pPlaintext, ulPlaintextLen, pCiphertext,
+ pulCiphertextLen);
+}
+
+CK_RV
+FC_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_EncryptMessageBegin(hSession, pParameter, ulParameterLen,
+ pAssociatedData, ulAssociatedDataLen);
+}
+
+CK_RV
+FC_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart,
+ CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart,
+ CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_EncryptMessageNext(hSession, pParameter, ulParameterLen,
+ pPlaintextPart, ulPlaintextPartLen,
+ pCiphertextPart, pulCiphertextPartLen, flags);
+}
+
+CK_RV
+FC_MessageEncryptFinal(CK_SESSION_HANDLE hSession)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_MessageEncryptFinal(hSession);
+}
+
+CK_RV
+FC_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+
+ rv = NSC_MessageDecryptInit(hSession, pMechanism, hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("MessageDecrypt", hSession, pMechanism, hKey, rv);
+ }
+ return rv;
+}
+
+CK_RV
+FC_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext,
+ CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext,
+ CK_ULONG_PTR pulPlaintextLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_DecryptMessage(hSession, pParameter, ulParameterLen,
+ pAssociatedData, ulAssociatedDataLen,
+ pCiphertext, ulCiphertextLen, pPlaintext,
+ pulPlaintextLen);
+}
+
+CK_RV
+FC_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_DecryptMessageBegin(hSession, pParameter, ulParameterLen,
+ pAssociatedData, ulAssociatedDataLen);
+}
+
+CK_RV
+FC_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart,
+ CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart,
+ CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_DecryptMessageNext(hSession, pParameter, ulParameterLen,
+ pCiphertextPart, ulCiphertextPartLen,
+ pPlaintextPart, pulPlaintextPartLen, flags);
+}
+
+CK_RV
+FC_MessageDecryptFinal(CK_SESSION_HANDLE hSession)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_MessageDecryptFinal(hSession);
+}
+
+CK_RV
+FC_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+
+ rv = NSC_MessageSignInit(hSession, pMechanism, hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("MessageSign", hSession, pMechanism, hKey, rv);
+ }
+ return rv;
+}
+
+CK_RV
+FC_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_SignMessage(hSession, pParameter, ulParameterLen, pData,
+ ulDataLen, pSignature, pulSignatureLen);
+}
+
+CK_RV
+FC_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_SignMessageBegin(hSession, pParameter, ulParameterLen);
+}
+
+CK_RV
+FC_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_SignMessageNext(hSession, pParameter, ulParameterLen, pData,
+ ulDataLen, pSignature, pulSignatureLen);
+}
+
+CK_RV
+FC_MessageSignFinal(CK_SESSION_HANDLE hSession)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_MessageSignFinal(hSession);
+}
+
+CK_RV
+FC_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+
+ rv = NSC_MessageVerifyInit(hSession, pMechanism, hKey);
+ if (sftk_audit_enabled) {
+ sftk_AuditCryptInit("MessageVerify", hSession, pMechanism, hKey, rv);
+ }
+ return rv;
+}
+
+CK_RV
+FC_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_VerifyMessage(hSession, pParameter, ulParameterLen, pData,
+ ulDataLen, pSignature, ulSignatureLen);
+}
+
+CK_RV
+FC_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_VerifyMessageBegin(hSession, pParameter, ulParameterLen);
+}
+
+CK_RV
+FC_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_VerifyMessageNext(hSession, pParameter, ulParameterLen,
+ pData, ulDataLen, pSignature, ulSignatureLen);
+}
+
+CK_RV
+FC_MessageVerifyFinal(CK_SESSION_HANDLE hSession)
+{
+ SFTK_FIPSCHECK();
+ CHECK_FORK();
+ return NSC_MessageVerifyFinal(hSession);
+}
diff --git a/lib/softoken/manifest.mn b/lib/softoken/manifest.mn
index fed4e62ec..62c5d35cf 100644
--- a/lib/softoken/manifest.mn
+++ b/lib/softoken/manifest.mn
@@ -46,6 +46,7 @@ CSRCS = \
sftkdb.c \
sftkhmac.c \
sftkike.c \
+ sftkmessage.c \
sftkpars.c \
sftkpwd.c \
softkver.c \
diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c
index c0ece339f..e9d9c70c0 100644
--- a/lib/softoken/pkcs11.c
+++ b/lib/softoken/pkcs11.c
@@ -86,6 +86,7 @@ static PRUint32 minSessionObjectHandle = 1U;
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
+#define CK_PKCS11_3_0 1
#define CK_EXTERN extern
#define CK_PKCS11_FUNCTION_INFO(func) \
CK_RV __PASTE(NS, func)
@@ -94,8 +95,8 @@ static PRUint32 minSessionObjectHandle = 1U;
#include "pkcs11f.h"
/* build the crypto module table */
-static const CK_FUNCTION_LIST sftk_funcList = {
- { 1, 10 },
+static CK_FUNCTION_LIST_3_0 sftk_funcList = {
+ { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
@@ -107,11 +108,50 @@ static const CK_FUNCTION_LIST sftk_funcList = {
};
+/* need a special version of get info for version 2 which returns the version
+ * 2.4 version number */
+CK_RV NSC_GetInfoV2(CK_INFO_PTR pInfo);
+
+/* build the crypto module table */
+static CK_FUNCTION_LIST sftk_funcList_v2 = {
+ { 2, 40 },
+
+#undef CK_PKCS11_3_0
+#define CK_PKCS_11_2_0_ONLY 1
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+#define C_GetInfo C_GetInfoV2
+
+#define CK_PKCS11_FUNCTION_INFO(func) \
+ __PASTE(NS, func) \
+ ,
+#include "pkcs11f.h"
+
+};
+
+#undef C_GetInfo
+#undef CK_PKCS_11_2_0_ONLY
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
#undef __PASTE
+CK_NSS_MODULE_FUNCTIONS sftk_module_funcList = {
+ { 1, 0 },
+ NSC_ModuleDBFunc
+};
+
+/*
+ * Array is orderd by default first
+ */
+static CK_INTERFACE nss_interfaces[] = {
+ { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_funcList, NSS_INTERFACE_FLAGS },
+ { (CK_UTF8CHAR_PTR) "PKCS 11", &sftk_funcList_v2, NSS_INTERFACE_FLAGS },
+ { (CK_UTF8CHAR_PTR) "Vendor NSS Module Interface", &sftk_module_funcList, NSS_INTERFACE_FLAGS }
+};
+/* must match the count of interfaces in nss_interfaces above */
+#define NSS_INTERFACE_COUNT 3
+
/* List of DES Weak Keys */
typedef unsigned char desKey[8];
static const desKey sftk_desWeakTable[] = {
@@ -2405,7 +2445,7 @@ sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type)
CK_RV
NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
{
- *pFunctionList = (CK_FUNCTION_LIST_PTR)&sftk_funcList;
+ *pFunctionList = (CK_FUNCTION_LIST_PTR)&sftk_funcList_v2;
return CKR_OK;
}
@@ -2416,6 +2456,60 @@ C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
return NSC_GetFunctionList(pFunctionList);
}
+CK_RV
+NSC_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
+{
+ CK_ULONG count = *pulCount;
+ *pulCount = NSS_INTERFACE_COUNT;
+ if (interfaces == NULL) {
+ return CKR_OK;
+ }
+ if (count < NSS_INTERFACE_COUNT) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+ PORT_Memcpy(interfaces, nss_interfaces, sizeof(nss_interfaces));
+ return CKR_OK;
+}
+
+CK_RV
+C_GetInterfaceList(CK_INTERFACE_PTR interfaces, CK_ULONG_PTR pulCount)
+{
+ return NSC_GetInterfaceList(interfaces, pulCount);
+}
+
+/*
+ * Get the requested interface, use the nss_interfaces array so we can
+ * easily add new interfaces as they occur.
+ */
+CK_RV
+NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
+ CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
+{
+ int i;
+ for (i = 0; i < NSS_INTERFACE_COUNT; i++) {
+ CK_INTERFACE_PTR interface = &nss_interfaces[i];
+ if (pInterfaceName && PORT_Strcmp((char *)pInterfaceName, (char *)interface->pInterfaceName) != 0) {
+ continue;
+ }
+ if (pVersion && PORT_Memcmp(pVersion, (CK_VERSION *)interface->pFunctionList, sizeof(CK_VERSION)) != 0) {
+ continue;
+ }
+ if (flags & ((interface->flags & flags) != flags)) {
+ continue;
+ }
+ *ppInterface = interface;
+ return CKR_OK;
+ }
+ return CKR_ARGUMENTS_BAD;
+}
+
+CK_RV
+C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
+ CK_INTERFACE_PTR_PTR ppInterface, CK_FLAGS flags)
+{
+ return NSC_GetInterface(pInterfaceName, pVersion, ppInterface, flags);
+}
+
static PLHashNumber
sftk_HashNumber(const void *key)
{
@@ -3392,8 +3486,24 @@ NSC_GetInfo(CK_INFO_PTR pInfo)
CHECK_FORK();
+ pInfo->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR;
+ pInfo->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR;
+ PORT_Memcpy(pInfo->manufacturerID, manufacturerID, 32);
+ pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
+ pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
+ PORT_Memcpy(pInfo->libraryDescription, libraryDescription, 32);
+ pInfo->flags = 0;
+ return CKR_OK;
+}
+
+/* NSC_GetInfo returns general information about Cryptoki. */
+CK_RV
+NSC_GetInfoV2(CK_INFO_PTR pInfo)
+{
+ CHECK_FORK();
+
pInfo->cryptokiVersion.major = 2;
- pInfo->cryptokiVersion.minor = 20;
+ pInfo->cryptokiVersion.minor = 40;
PORT_Memcpy(pInfo->manufacturerID, manufacturerID, 32);
pInfo->libraryVersion.major = SOFTOKEN_VMAJOR;
pInfo->libraryVersion.minor = SOFTOKEN_VMINOR;
@@ -4254,6 +4364,15 @@ done:
return crv;
}
+CK_RV
+NSC_LoginUser(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pUsername,
+ CK_ULONG ulUsernameLen)
+{
+ /* softoken currently does not support additional users */
+ return CKR_OPERATION_NOT_INITIALIZED;
+}
+
/* NSC_Logout logs a user out from a token. */
CK_RV
NSC_Logout(CK_SESSION_HANDLE hSession)
diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c
index 99a9c6958..b46292b18 100644
--- a/lib/softoken/pkcs11c.c
+++ b/lib/softoken/pkcs11c.c
@@ -48,6 +48,8 @@
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
+#define CK_PKCS11_3_0 1
+
#define CK_EXTERN extern
#define CK_PKCS11_FUNCTION_INFO(func) \
CK_RV __PASTE(NS, func)
@@ -3090,6 +3092,59 @@ NSC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN);
}
+struct SFTK_SESSION_FLAGS {
+ CK_FLAGS flag;
+ SFTKContextType type;
+};
+
+const static struct SFTK_SESSION_FLAGS sftk_session_flags[] = {
+ { CKF_ENCRYPT, SFTK_ENCRYPT },
+ { CKF_DECRYPT, SFTK_DECRYPT },
+ { CKF_DIGEST, SFTK_HASH },
+ { CKF_SIGN, SFTK_SIGN },
+ { CKF_SIGN_RECOVER, SFTK_SIGN_RECOVER },
+ { CKF_VERIFY, SFTK_VERIFY },
+ { CKF_VERIFY_RECOVER, SFTK_VERIFY_RECOVER }
+
+};
+const static int sftk_flag_count = PR_ARRAY_SIZE(sftk_session_flags);
+
+/*
+ * Cancel one or more operations running on the existing session.
+ */
+CK_RV
+NSC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags)
+{
+ SFTKSession *session;
+ SFTKSessionContext *context;
+ CK_RV gcrv = CKR_OK;
+ CK_RV crv;
+ int i;
+
+ for (i = 0; i < sftk_flag_count; i++) {
+ if (flags & sftk_session_flags[i].flag) {
+ flags &= ~sftk_session_flags[i].flag;
+ crv = sftk_GetContext(hSession, &context, sftk_session_flags[i].type, PR_TRUE, &session);
+ if (crv != CKR_OK) {
+ gcrv = CKR_OPERATION_CANCEL_FAILED;
+ continue;
+ }
+ sftk_TerminateOp(session, sftk_session_flags[i].type, context);
+ }
+ }
+ if (flags & CKF_FIND_OBJECTS) {
+ flags &= ~CKF_FIND_OBJECTS;
+ crv = NSC_FindObjectsFinal(hSession);
+ if (crv != CKR_OK) {
+ gcrv = CKR_OPERATION_CANCEL_FAILED;
+ }
+ }
+ if (flags) {
+ gcrv = CKR_OPERATION_CANCEL_FAILED;
+ }
+ return gcrv;
+}
+
/* NSC_SignFinal finishes a multiple-part signature operation,
* returning the signature. */
CK_RV
diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h
index 93973bc54..5de51a2ea 100644
--- a/lib/softoken/pkcs11i.h
+++ b/lib/softoken/pkcs11i.h
@@ -676,6 +676,8 @@ struct sftk_MACCtxStr {
};
typedef struct sftk_MACCtxStr sftk_MACCtx;
+extern CK_NSS_MODULE_FUNCTIONS sftk_module_funcList;
+
SEC_BEGIN_PROTOS
/* shared functions between pkcs11.c and fipstokn.c */
@@ -888,6 +890,7 @@ CK_RV sftk_CheckCBCPadding(CK_BYTE_PTR pBuf, unsigned int bufLen,
/* NIST 800-108 (kbkdf.c) implementations */
extern CK_RV kbkdf_Dispatch(CK_MECHANISM_TYPE mech, CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, SFTKObject *base_key, SFTKObject *ret_key, CK_ULONG keySize);
+char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
SEC_END_PROTOS
diff --git a/lib/softoken/sftkmessage.c b/lib/softoken/sftkmessage.c
new file mode 100644
index 000000000..05af0ee51
--- /dev/null
+++ b/lib/softoken/sftkmessage.c
@@ -0,0 +1,166 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * This file implements PKCS 11 on top of our existing security modules
+ *
+ * Implement the PKCS #11 v3.0 Message interfaces
+ */
+#include "seccomon.h"
+#include "pkcs11.h"
+#include "pkcs11i.h"
+
+CK_RV
+NSC_MessageEncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_EncryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pPlaintext,
+ CK_ULONG ulPlaintextLen, CK_BYTE_PTR pCiphertext,
+ CK_ULONG_PTR pulCiphertextLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_EncryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_EncryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pPlaintextPart,
+ CK_ULONG ulPlaintextPartLen, CK_BYTE_PTR pCiphertextPart,
+ CK_ULONG_PTR pulCiphertextPartLen, CK_FLAGS flags)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageEncryptFinal(CK_SESSION_HANDLE hSession)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageDecryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_DecryptMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen, CK_BYTE_PTR pCiphertext,
+ CK_ULONG ulCiphertextLen, CK_BYTE_PTR pPlaintext,
+ CK_ULONG_PTR pulPlaintextLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_DecryptMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pAssociatedData,
+ CK_ULONG ulAssociatedDataLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_DecryptMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pCiphertextPart,
+ CK_ULONG ulCiphertextPartLen, CK_BYTE_PTR pPlaintextPart,
+ CK_ULONG_PTR pulPlaintextPartLen, CK_FLAGS flags)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageDecryptFinal(CK_SESSION_HANDLE hSession)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageSignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_SignMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_SignMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_SignMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageSignFinal(CK_SESSION_HANDLE hSession)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageVerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_VerifyMessage(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_VerifyMessageBegin(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_VerifyMessageNext(CK_SESSION_HANDLE hSession, CK_VOID_PTR pParameter,
+ CK_ULONG ulParameterLen, CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+NSC_MessageVerifyFinal(CK_SESSION_HANDLE hSession)
+{
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
diff --git a/lib/softoken/softoken.gyp b/lib/softoken/softoken.gyp
index 80fc7d75f..96942cd4a 100644
--- a/lib/softoken/softoken.gyp
+++ b/lib/softoken/softoken.gyp
@@ -59,6 +59,7 @@
'sftkdb.c',
'sftkhmac.c',
'sftkike.c',
+ 'sftkmessage.c',
'sftkpars.c',
'sftkpwd.c',
'softkver.c',
diff --git a/lib/softoken/softoken.h b/lib/softoken/softoken.h
index 4626e7849..30586fcf4 100644
--- a/lib/softoken/softoken.h
+++ b/lib/softoken/softoken.h
@@ -145,7 +145,9 @@ extern PRBool sftk_fatalError;
/*
** macros to check for forked child process after C_Initialize
*/
-#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
+/* for PKCS #11 3.0, default is NO_FORK_CHECK, if you want it, now you
+ * need to define DO_FORK_CHECK */
+#if defined(XP_UNIX) && defined(DO_FORK_CHECK)
#ifdef DEBUG
@@ -260,6 +262,19 @@ extern PRBool sftkForkCheckDisabled;
#endif
+/*
+ * If we were trying to be complete, we would have both FORK_SAFE
+ * and non-Fork safe interfaces here. That would require doubling
+ * the functions in our function list for both this and the FIPS
+ * interface. Since NSS now always asks for a FORK_SAFE interface,
+ * and can fall back to a non-FORK_SAFE interface, we set only
+ * export one set of interfaces here */
+#ifdef NO_FORK_CHECK
+#define NSS_INTERFACE_FLAGS CKF_INTERFACE_FORK_SAFE
+#else
+#define NSS_INTERFACE_FLAGS 0
+#endif
+
SEC_END_PROTOS
#endif /* _SOFTOKEN_H_ */
diff --git a/lib/softoken/softokn.def b/lib/softoken/softokn.def
index 0c71a1b4c..135755be6 100644
--- a/lib/softoken/softokn.def
+++ b/lib/softoken/softokn.def
@@ -26,3 +26,14 @@ NSC_ModuleDBFunc;
;+ local:
;+ *;
;+};
+;+NSS_3.52 { # NSS 3.52 release adds pkcs #11 v3.0
+;+ global:
+C_GetInterfaceList;
+FC_GetInterfaceList;
+NSC_GetInterfaceList;
+C_GetInterface;
+FC_GetInterface;
+NSC_GetInterface;
+;+ local:
+;+ *;
+;+};
diff --git a/lib/util/pkcs11.h b/lib/util/pkcs11.h
index 4b317bf35..77ec869aa 100644
--- a/lib/util/pkcs11.h
+++ b/lib/util/pkcs11.h
@@ -179,10 +179,10 @@ extern "C" {
#define __PASTE(x, y) x##y
-#ifndef CK_PKCS11_3
+#ifndef CK_PKCS11_3_0
/* remember that we set it so we can unset it at the end */
#define __NSS_CK_PKCS11_3_IMPLICIT 1
-#define CK_PKCS11_3 1
+#define CK_PKCS11_3_0 1
#endif
/* ==============================================================
@@ -259,7 +259,7 @@ struct CK_FUNCTION_LIST {
#undef CK_PKCS11_2_0_ONLY
#ifdef __NSS_CK_PKCS11_3_IMPLICIT
-#undef CK_PKCS11_3
+#undef CK_PKCS11_3_0
#undef __NSS_CK_PKCS11_3_IMPLICIT
#endif
diff --git a/lib/util/pkcs11f.h b/lib/util/pkcs11f.h
index a5492aef3..7d8705e1b 100644
--- a/lib/util/pkcs11f.h
+++ b/lib/util/pkcs11f.h
@@ -813,14 +813,14 @@ CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
#if defined(CK_PKCS11_3_0) && !defined(CK_PKCS11_2_0_ONLY)
CK_PKCS11_FUNCTION_INFO(C_GetInterfaceList)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_INTERFACE_PTR interfaces,
CK_ULONG_PTR pulCount);
#endif
CK_PKCS11_FUNCTION_INFO(C_GetInterface)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_UTF8CHAR_PTR pInterfaceName,
CK_VERSION_PTR pVersion,
@@ -829,7 +829,7 @@ CK_PKCS11_FUNCTION_INFO(C_GetInterface)
#endif
CK_PKCS11_FUNCTION_INFO(C_LoginUser)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_USER_TYPE userType,
@@ -840,14 +840,14 @@ CK_PKCS11_FUNCTION_INFO(C_LoginUser)
#endif
CK_PKCS11_FUNCTION_INFO(C_SessionCancel)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_FLAGS flags);
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageEncryptInit)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -855,7 +855,7 @@ CK_PKCS11_FUNCTION_INFO(C_MessageEncryptInit)
#endif
CK_PKCS11_FUNCTION_INFO(C_EncryptMessage)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -869,7 +869,7 @@ CK_PKCS11_FUNCTION_INFO(C_EncryptMessage)
#endif
CK_PKCS11_FUNCTION_INFO(C_EncryptMessageBegin)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -879,7 +879,7 @@ CK_PKCS11_FUNCTION_INFO(C_EncryptMessageBegin)
#endif
CK_PKCS11_FUNCTION_INFO(C_EncryptMessageNext)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -892,13 +892,13 @@ CK_PKCS11_FUNCTION_INFO(C_EncryptMessageNext)
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageEncryptFinal)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession);
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageDecryptInit)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -906,7 +906,7 @@ CK_PKCS11_FUNCTION_INFO(C_MessageDecryptInit)
#endif
CK_PKCS11_FUNCTION_INFO(C_DecryptMessage)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -920,7 +920,7 @@ CK_PKCS11_FUNCTION_INFO(C_DecryptMessage)
#endif
CK_PKCS11_FUNCTION_INFO(C_DecryptMessageBegin)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -930,7 +930,7 @@ CK_PKCS11_FUNCTION_INFO(C_DecryptMessageBegin)
#endif
CK_PKCS11_FUNCTION_INFO(C_DecryptMessageNext)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -943,13 +943,13 @@ CK_PKCS11_FUNCTION_INFO(C_DecryptMessageNext)
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageDecryptFinal)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession);
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageSignInit)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -957,7 +957,7 @@ CK_PKCS11_FUNCTION_INFO(C_MessageSignInit)
#endif
CK_PKCS11_FUNCTION_INFO(C_SignMessage)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -970,7 +970,7 @@ CK_PKCS11_FUNCTION_INFO(C_SignMessage)
#endif
CK_PKCS11_FUNCTION_INFO(C_SignMessageBegin)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -978,7 +978,7 @@ CK_PKCS11_FUNCTION_INFO(C_SignMessageBegin)
#endif
CK_PKCS11_FUNCTION_INFO(C_SignMessageNext)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -990,13 +990,13 @@ CK_PKCS11_FUNCTION_INFO(C_SignMessageNext)
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageSignFinal)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession);
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageVerifyInit)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
@@ -1004,7 +1004,7 @@ CK_PKCS11_FUNCTION_INFO(C_MessageVerifyInit)
#endif
CK_PKCS11_FUNCTION_INFO(C_VerifyMessage)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -1016,7 +1016,7 @@ CK_PKCS11_FUNCTION_INFO(C_VerifyMessage)
#endif
CK_PKCS11_FUNCTION_INFO(C_VerifyMessageBegin)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -1024,7 +1024,7 @@ CK_PKCS11_FUNCTION_INFO(C_VerifyMessageBegin)
#endif
CK_PKCS11_FUNCTION_INFO(C_VerifyMessageNext)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession,
CK_VOID_PTR pParameter,
@@ -1036,7 +1036,7 @@ CK_PKCS11_FUNCTION_INFO(C_VerifyMessageNext)
#endif
CK_PKCS11_FUNCTION_INFO(C_MessageVerifyFinal)
-#ifdef CK_NEED_ARGLIST
+#ifdef CK_NEED_ARG_LIST
(
CK_SESSION_HANDLE hSession);
#endif
diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h
index bee1f57f7..929e55b9e 100644
--- a/lib/util/pkcs11n.h
+++ b/lib/util/pkcs11n.h
@@ -555,6 +555,16 @@ typedef char **(PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
#define SFTK_MIN_FIPS_USER_SLOT_ID 101
#define SFTK_MAX_FIPS_USER_SLOT_ID 127
+/* Module Interface. This is the old NSS private module interface, now exported
+ * as a PKCS #11 v3 interface. It's interface name is
+ * "Vendor NSS Module Interface" */
+typedef char **(*CK_NSS_ModuleDBFunc)(unsigned long function,
+ char *parameters, void *args);
+typedef struct CK_NSS_MODULE_FUNCTIONS {
+ CK_VERSION version;
+ CK_NSS_ModuleDBFunc NSC_ModuleDBFunc;
+} CK_NSS_MODULE_FUNCTIONS;
+
/* There was an inconsistency between the spec and the header file in defining
* the CK_GCM_PARAMS structure. The authoritative reference is the header file,
* but NSS used the spec when adding it to its own header. In V3 we've
diff --git a/nss/automation/abi-check/new-report-libnss3.so.txt b/nss/automation/abi-check/new-report-libnss3.so.txt
new file mode 100644
index 000000000..edf5a1310
--- /dev/null
+++ b/nss/automation/abi-check/new-report-libnss3.so.txt
@@ -0,0 +1,13 @@
+
+1 function with some indirect sub-type change:
+
+ [C]'function SECStatus PK11_GetModInfo(SECMODModule*, CK_INFO*)' at pk11util.c:613:1 has some indirect sub-type changes:
+ parameter 1 of type 'SECMODModule*' has sub-type changes:
+ in pointed to type 'typedef SECMODModule' at secmodt.h:29:1:
+ underlying type 'struct SECMODModuleStr' at secmodt.h:44:1 changed:
+ type size changed from 1600 to 1664 (in bits)
+ 1 data member insertion:
+ 'CK_FLAGS SECMODModuleStr::flags', at offset 1600 (in bits) at secmodt.h:76:1
+ no data member change (1 filtered);
+
+
diff --git a/nss/automation/abi-check/new-report-libsoftokn3.so.txt b/nss/automation/abi-check/new-report-libsoftokn3.so.txt
new file mode 100644
index 000000000..1e825bede
--- /dev/null
+++ b/nss/automation/abi-check/new-report-libsoftokn3.so.txt
@@ -0,0 +1,8 @@
+
+4 Added functions:
+
+ 'function CK_RV FC_GetInterface(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS)' {FC_GetInterface@@NSS_3.52}
+ 'function CK_RV FC_GetInterfaceList(CK_INTERFACE_PTR, CK_ULONG_PTR)' {FC_GetInterfaceList@@NSS_3.52}
+ 'function CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR, CK_VERSION_PTR, CK_INTERFACE_PTR_PTR, CK_FLAGS)' {NSC_GetInterface@@NSS_3.52}
+ 'function CK_RV NSC_GetInterfaceList(CK_INTERFACE_PTR, CK_ULONG_PTR)' {NSC_GetInterfaceList@@NSS_3.52}
+