diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index d86e9fd5598..64491b2c856 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -208,7 +208,7 @@ static const unsigned char parityTable[256] = { /* Mechanisms */ struct mechanismList { CK_MECHANISM_TYPE type; - CK_MECHANISM_INFO domestic; + CK_MECHANISM_INFO info; PRBool privkey; }; @@ -354,8 +354,8 @@ static const struct mechanismList mechanisms[] = { #endif #if NSS_SOFTOKEN_DOES_RC5 /* ------------------------- RC5 Operations --------------------------- */ - {CKM_RC5_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE}, - {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, + {CKM_RC5_KEY_GEN, {1, 32, CKF_GENERATE}, PR_TRUE}, + {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, {CKM_RC5_CBC, {1, 32, CKF_EN_DE_WR_UN}, PR_TRUE}, {CKM_RC5_MAC, {1, 32, CKF_SN_VR}, PR_TRUE}, {CKM_RC5_MAC_GENERAL, {1, 32, CKF_SN_VR}, PR_TRUE}, @@ -407,7 +407,7 @@ static const struct mechanismList mechanisms[] = { {CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE}, {CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {16,16, CKF_GENERATE}, PR_TRUE}, }; -static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); +static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]); static char * pk11_setStringName(const char *inString, char *buffer, int buffer_length) @@ -2835,20 +2835,20 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) { - int i; + CK_ULONG i; switch (slotID) { case NETSCAPE_SLOT_ID: *pulCount = mechanismCount; if (pMechanismList != NULL) { - for (i=0; i < (int) mechanismCount; i++) { + for (i=0; i < mechanismCount; i++) { pMechanismList[i] = mechanisms[i].type; } } break; default: *pulCount = 0; - for (i=0; i < (int) mechanismCount; i++) { + for (i=0; i < mechanismCount; i++) { if (mechanisms[i].privkey) { (*pulCount)++; if (pMechanismList != NULL) { @@ -2868,7 +2868,7 @@ CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo) { PRBool isPrivateKey; - int i; + CK_ULONG i; switch (slotID) { case NETSCAPE_SLOT_ID: @@ -2878,19 +2878,46 @@ CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, isPrivateKey = PR_TRUE; break; } - for (i=0; i < (int) mechanismCount; i++) { + for (i=0; i < mechanismCount; i++) { if (type == mechanisms[i].type) { if (isPrivateKey && !mechanisms[i].privkey) { return CKR_MECHANISM_INVALID; } - PORT_Memcpy(pInfo,&mechanisms[i].domestic, - sizeof(CK_MECHANISM_INFO)); + PORT_Memcpy(pInfo,&mechanisms[i].info, sizeof(CK_MECHANISM_INFO)); return CKR_OK; } } return CKR_MECHANISM_INVALID; } +CK_RV pk11_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op) +{ + CK_ULONG i; + CK_FLAGS flags; + + switch (op) { + case CKA_ENCRYPT: flags = CKF_ENCRYPT; break; + case CKA_DECRYPT: flags = CKF_DECRYPT; break; + case CKA_WRAP: flags = CKF_WRAP; break; + case CKA_UNWRAP: flags = CKF_UNWRAP; break; + case CKA_SIGN: flags = CKF_SIGN; break; + case CKA_SIGN_RECOVER: flags = CKF_SIGN_RECOVER; break; + case CKA_VERIFY: flags = CKF_VERIFY; break; + case CKA_VERIFY_RECOVER: flags = CKF_VERIFY_RECOVER; break; + case CKA_DERIVE: flags = CKF_DERIVE; break; + default: + return CKR_ARGUMENTS_BAD; + } + for (i=0; i < mechanismCount; i++) { + if (type == mechanisms[i].type) { + return (flags & mechanisms[i].info.flags) ? CKR_OK + : CKR_MECHANISM_INVALID; + } + } + return CKR_MECHANISM_INVALID; +} + + static SECStatus pk11_TurnOffUser(NSSLOWCERTCertificate *cert, SECItem *k, void *arg) { diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 19c5142b839..44f2f9e9796 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -402,8 +402,11 @@ pk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr, } /* NSC_CryptInit initializes an encryption/Decryption operation. */ -/* This function is used by NSC_EncryptInit and NSC_WrapKey. The only difference - * in their uses if whether or not etype is CKA_ENCRYPT or CKA_WRAP */ +/* This function is used by NSC_EncryptInit, NSC_DecryptInit, + * NSC_WrapKey, NSC_UnwrapKey, + * NSC_SignInit, NSC_VerifyInit (via pk11_InitCBCMac), + * The only difference in their uses is the value of etype. + */ static CK_RV pk11_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype, @@ -425,6 +428,10 @@ pk11_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, PRBool useNewKey=PR_FALSE; int t; + crv = pk11_MechAllowsOperation(pMechanism->mechanism, etype); + if (crv != CKR_OK) + return crv; + session = pk11_SessionFromHandle(hSession); if (session == NULL) return CKR_SESSION_HANDLE_INVALID; @@ -619,8 +626,8 @@ finish_des: } context->update = (PK11Cipher) (isEncrypt ? DES_Encrypt : DES_Decrypt); context->destroy = (PK11Destroy) DES_DestroyContext; - break; + case CKM_AES_CBC_PAD: context->doPad = PR_TRUE; context->blockSize = 16; @@ -3448,7 +3455,6 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, crv = CKR_KEY_TYPE_INCONSISTENT; break; } - crv = pk11_CryptInit(hSession, pMechanism, hWrappingKey, CKA_WRAP, PK11_ENCRYPT, PR_TRUE); if (crv != CKR_OK) { diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index ae92816b39c..fba6e8e04b4 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -622,6 +622,8 @@ extern SECStatus secmod_AddPermDB(const char *domain, const char *filename, const char *dbname, char *module, PRBool rw); extern SECStatus secmod_ReleasePermDBData(const char *domain, const char *filename, const char *dbname, char **specList, PRBool rw); +/* mechanism allows this operation */ +extern CK_RV pk11_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op); /* * OK there are now lots of options here, lets go through them all: *