From a95d4e2c73c48f5c6396cad7c0aa428736b404c1 Mon Sep 17 00:00:00 2001 From: Robert Relyea Date: Tue, 17 Mar 2020 17:04:52 -0700 Subject: [PATCH] Bug 1603628 Update NSS to handle PKCS #11 v3.0 r=ueno r=mt Update to PKCS #11 v3.0 part 2. Create the functions and switch to the C_Interface() function to fetch the PKCS #11 function table. Also PKCS #11 v3.0 uses a new fork safe interface. NSS can already handle the case if the PKCS #11 module happens to be fork safe (when asked by the application to refresh the tokens in the child process, NSS can detect that such a refresh is not necessary and continue. Softoken could also be put in fork_safe mode with an environment variable. With this patch it's the default, and NSS asks for the fork safe API by default. Technically softoken should implement the old non-fork safe interface when PKCS #11 v2.0 is called, but NSS no longer needs it, and doing so would double the number of PKCS #11 interfaces are needed. You can still compile with fork unsafe semantics, and the PKCS #11 V3.0 module will do the right thing and not include the fork safe flag. Firefox does not fork(), so for firefox this is simply code that is no longer compilied. We now use C_GetInterface, which allows us to specify what kind of interface we want (PKCS #11 v3.0, PKCS #11 v2.0, fork safe, etc.). Vendor specific functions can now be accessed through the C_GetInterface. If the C_GetInterface function does not exists, we fall bak to the old C_GetFunctionList. There are 24 new functions in PKCS #11 v3.0: C_GetInterfaceList - return a table of all the supported interfaces C_GetInterface - return a specific interface. You can specify interface name, version and flags separately. You can leave off any of these and you will get what the token thinks is the best match of the interfaces that meet the criteria. We do this in softoken by the order of the interface list. C_SessionCancel - Cancel one or more multipart operation C_LoginUser - Supply a user name to C_Login(). This function has no meaning for softoken, so it just returns CKR_OPERATION_NOT_INITIALIZED under the theory that if we in the future want to support usernames, the NSS db would need special initialization to make that happen. C_Message* and C_*Message* (20 functions in all) are the new AEAD interface (they are written generally so that it can be used for things other than AEAD). In this patch they are unimplemented (see the next patch). This patch adds regular (NSC_) and FIPS (FC_) versions of these functions. Also when creating the PKCS #11 v2.0 interface, we had to create a 2.0 specific version of C_GetInfo so that it can return a 2.40 in the CK_VERSION field rather than 3.00. We do this with #defines since all the function tables are generated automagically with pkcs11f.h. Differential Revision: https://phabricator.services.mozilla.com/D67240 --- .../abi-check/expected-report-libnss3.so.txt | 13 + .../expected-report-libsoftokn3.so.txt | 10 + cmd/pk11mode/pk11mode.c | 2 +- lib/pk11wrap/pk11load.c | 65 +++- lib/pk11wrap/secmodi.h | 2 +- lib/pk11wrap/secmodt.h | 1 + lib/softoken/fipstokn.c | 365 +++++++++++++++++- lib/softoken/manifest.mn | 1 + lib/softoken/pkcs11.c | 127 +++++- lib/softoken/pkcs11c.c | 55 +++ lib/softoken/pkcs11i.h | 3 + lib/softoken/sftkmessage.c | 166 ++++++++ lib/softoken/softoken.gyp | 1 + lib/softoken/softoken.h | 17 +- lib/softoken/softokn.def | 11 + lib/util/pkcs11.h | 6 +- lib/util/pkcs11f.h | 48 +-- lib/util/pkcs11n.h | 10 + .../abi-check/new-report-libnss3.so.txt | 13 + .../abi-check/new-report-libsoftokn3.so.txt | 8 + 20 files changed, 870 insertions(+), 54 deletions(-) create mode 100644 lib/softoken/sftkmessage.c create mode 100644 nss/automation/abi-check/new-report-libnss3.so.txt create mode 100644 nss/automation/abi-check/new-report-libsoftokn3.so.txt diff --git a/automation/abi-check/expected-report-libnss3.so.txt b/automation/abi-check/expected-report-libnss3.so.txt index e69de29bb2..edf5a13102 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 e69de29bb2..b26ffd3e5a 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 16554536d5..851d64f8fb 100644 --- a/cmd/pk11mode/pk11mode.c +++ b/cmd/pk11mode/pk11mode.c @@ -16,7 +16,7 @@ #include #include -#if defined(XP_UNIX) && !defined(NO_FORK_CHECK) +#if defined(XP_UNIX) && defined(DO_FORK_CHECK) #include #include #else diff --git a/lib/pk11wrap/pk11load.c b/lib/pk11wrap/pk11load.c index 7413429db1..8e80fe7b3a 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 634b241bdf..a85f94cc2d 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 23abe307f9..34fd4cce1d 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 5d456716e3..3fe1f0dcb6 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 fed4e62eca..62c5d35cfa 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 c0ece339f4..e9d9c70c08 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 @@ NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, 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 99a9c69583..b46292b183 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 93973bc54f..5de51a2ea1 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 0000000000..05af0ee513 --- /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 80fc7d75f1..96942cd4af 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 4626e78497..30586fcf4b 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 0c71a1b4c0..135755be6c 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 4b317bf353..77ec869aa4 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 a5492aef34..7d8705e1bb 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 bee1f57f77..929e55b9e6 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 0000000000..edf5a13102 --- /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 0000000000..1e825bedee --- /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} +