re-introduce old nss im too tired for this

This commit is contained in:
wuggy 2026-06-30 06:37:32 +01:00
commit 3a838106b9
2871 changed files with 1374431 additions and 1762417 deletions

View file

@ -26,6 +26,8 @@ include $(CORE_DEPTH)/coreconf/config.mk
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
-include config.mk
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
@ -42,6 +44,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
export:: private_export
$(OBJDIR)/pk11load$(OBJ_SUFFIX): debug_module.c
@ -51,7 +54,8 @@ $(OBJDIR)/pk11load$(OBJ_SUFFIX): debug_module.c
ifeq ($(OS_TARGET)$(OS_RELEASE),AIX4.3)
ifeq ($(USE_64),1)
ifndef BUILD_OPT
$(OBJDIR)/pk11slot.o: pk11slot.c | $$(@D)/d
$(OBJDIR)/pk11slot.o: pk11slot.c
@$(MAKE_OBJDIR)
$(CC) -o $@ -c -O2 $(CFLAGS) $<
endif
endif

View file

@ -0,0 +1,15 @@
#
# 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/.
#
# Override TARGETS variable so that only static libraries
# are specifed as dependencies within rules.mk.
#
TARGETS = $(LIBRARY)
SHARED_LIBRARY =
IMPORT_LIBRARY =
PROGRAM =

File diff suppressed because it is too large Load diff

View file

@ -28,7 +28,7 @@ nssSession_ImportNSS3Session(NSSArena *arenaOpt,
PZLock *lock, PRBool rw)
{
nssSession *rvSession = NULL;
if (session != CK_INVALID_HANDLE) {
if (session != CK_INVALID_SESSION) {
rvSession = nss_ZNEW(arenaOpt, nssSession);
if (rvSession) {
rvSession->handle = session;

View file

@ -13,7 +13,6 @@
{
'files': [
'pk11func.h',
'pk11hpke.h',
'pk11pqg.h',
'pk11priv.h',
'pk11pub.h',
@ -27,8 +26,7 @@
{
'files': [
'dev3hack.h',
'secmodi.h',
'secmodti.h'
'secmodi.h'
],
'destination': '<(nss_private_dist_dir)/<(module)'
}

View file

@ -1,4 +1,4 @@
#
#
# 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/.
@ -9,7 +9,6 @@ EXPORTS = \
secmodt.h \
secpkcs5.h \
pk11func.h \
pk11hpke.h \
pk11pub.h \
pk11priv.h \
pk11sdr.h \
@ -18,7 +17,6 @@ EXPORTS = \
PRIVATE_EXPORTS = \
secmodi.h \
secmodti.h \
dev3hack.h \
$(NULL)
@ -31,7 +29,6 @@ CSRCS = \
pk11cert.c \
pk11cxt.c \
pk11err.c \
pk11hpke.c \
pk11kea.c \
pk11list.c \
pk11load.c \
@ -50,12 +47,11 @@ CSRCS = \
$(NULL)
LIBRARY_NAME = pk11wrap
SHARED_LIBRARY = $(NULL)
NSS_LIBRARY_VERSION = 3
LIBRARY_VERSION = 3
SOFTOKEN_LIBRARY_VERSION = 3
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" \
-DNSS_SHLIB_VERSION=\"$(NSS_LIBRARY_VERSION)\" \
-DSHLIB_VERSION=\"$(LIBRARY_VERSION)\" \
-DSOFTOKEN_SHLIB_VERSION=\"$(SOFTOKEN_LIBRARY_VERSION)\"
# only add module debugging in opt builds if DEBUG_PKCS11 is set

View file

@ -5,8 +5,6 @@
* This file contains functions to manage asymetric keys, (public and
* private keys).
*/
#include <stddef.h>
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
@ -232,7 +230,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
pk11_SignedToUnsigned(attrs);
}
}
rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE, theTemplate,
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
templateCount, isToken, &objectID);
if (ckaId) {
SECITEM_FreeItem(ckaId, PR_TRUE);
@ -1087,7 +1085,7 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot, SECKEYPrivateKey *privKey,
}
/* now Store the puppies */
rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE, privTemplate,
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate,
count, token, &objectID);
PORT_FreeArena(arena, PR_TRUE);
if (rv != SECSuccess) {
@ -1522,13 +1520,13 @@ PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
restore = PR_TRUE;
} else {
session_handle = slot->session;
if (session_handle != CK_INVALID_HANDLE)
if (session_handle != CK_INVALID_SESSION)
PK11_EnterSlotMonitor(slot);
restore = PR_FALSE;
haslock = PR_TRUE;
}
if (session_handle == CK_INVALID_HANDLE) {
if (session_handle == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return NULL;
}
@ -1903,12 +1901,12 @@ try_faulty_3des:
}
/* if we are unable to import the key and the pbeMechType is
* CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that
* CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that
* the encrypted blob was created with a buggy key generation method
* which is described in the PKCS 12 implementation notes. So we
* need to try importing via that method.
*/
if ((pbeMechType == CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) {
if ((pbeMechType == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) {
/* clean up after ourselves before redoing the key generation. */
PK11_FreeSymKey(key);
@ -1969,20 +1967,14 @@ PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx)
return pki;
}
/* V2 refers to PKCS #5 V2 here. If a PKCS #5 v1 or PKCS #12 pbe is passed
* for pbeTag, then encTag and hashTag are ignored. If pbe is an encryption
* algorithm, then PKCS #5 V2 is used with prfTag for the prf. If prfTag isn't
* supplied prf will be SEC_OID_HMAC_SHA1 */
SECKEYEncryptedPrivateKeyInfo *
PK11_ExportEncryptedPrivKeyInfoV2(
PK11_ExportEncryptedPrivKeyInfo(
PK11SlotInfo *slot, /* optional, encrypt key in this slot */
SECOidTag pbeAlg, /* PBE algorithm to encrypt the with key */
SECOidTag encAlg, /* Encryption algorithm to Encrypt the key with */
SECOidTag prfAlg, /* Hash algorithm for PRF */
SECOidTag algTag, /* encrypt key with this algorithm */
SECItem *pwitem, /* password for PBE encryption */
SECKEYPrivateKey *pk, /* encrypt this private key */
int iteration, /* interations for PBE alg */
void *pwArg) /* context for password callback */
void *wincx) /* context for password callback ? */
{
SECKEYEncryptedPrivateKeyInfo *epki = NULL;
PLArenaPool *arena = NULL;
@ -2003,7 +1995,7 @@ PK11_ExportEncryptedPrivKeyInfoV2(
return NULL;
}
algid = sec_pkcs5CreateAlgorithmID(pbeAlg, encAlg, prfAlg,
algid = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, SEC_OID_UNKNOWN,
&pbeAlgTag, 0, NULL, iteration);
if (algid == NULL) {
return NULL;
@ -2032,7 +2024,7 @@ PK11_ExportEncryptedPrivKeyInfoV2(
slot = pk->pkcs11Slot;
}
}
key = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE, pwArg);
key = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE, wincx);
if (key == NULL) {
rv = SECFailure;
goto loser;
@ -2126,46 +2118,6 @@ loser:
return epki;
}
SECKEYEncryptedPrivateKeyInfo *
PK11_ExportEncryptedPrivKeyInfo(
PK11SlotInfo *slot, /* optional, encrypt key in this slot */
SECOidTag algTag, /* PBE algorithm to encrypt the with key */
SECItem *pwitem, /* password for PBE encryption */
SECKEYPrivateKey *pk, /* encrypt this private key */
int iteration, /* interations for PBE alg */
void *pwArg) /* context for password callback */
{
return PK11_ExportEncryptedPrivKeyInfoV2(slot, algTag, SEC_OID_UNKNOWN,
SEC_OID_UNKNOWN, pwitem, pk,
iteration, pwArg);
}
/* V2 refers to PKCS #5 V2 here. If a PKCS #5 v1 or PKCS #12 pbe is passed
* for pbeTag, then encTag and hashTag are ignored. If pbe is an encryption
* algorithm, then PKCS #5 V2 is used with prfTag for the prf. If prfTag isn't
* supplied prf will be SEC_OID_HMAC_SHA1 */
SECKEYEncryptedPrivateKeyInfo *
PK11_ExportEncryptedPrivateKeyInfoV2(
PK11SlotInfo *slot, /* optional, encrypt key in this slot */
SECOidTag pbeAlg, /* PBE algorithm to encrypt the with key */
SECOidTag encAlg, /* Encryption algorithm to Encrypt the key with */
SECOidTag prfAlg, /* HMAC algorithm for PRF*/
SECItem *pwitem, /* password for PBE encryption */
CERTCertificate *cert, /* wrap priv key for this user cert */
int iteration, /* interations for PBE alg */
void *pwArg) /* context for password callback */
{
SECKEYEncryptedPrivateKeyInfo *epki = NULL;
SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, pwArg);
if (pk != NULL) {
epki = PK11_ExportEncryptedPrivKeyInfoV2(slot, pbeAlg, encAlg, prfAlg,
pwitem, pk, iteration,
pwArg);
SECKEY_DestroyPrivateKey(pk);
}
return epki;
}
SECKEYEncryptedPrivateKeyInfo *
PK11_ExportEncryptedPrivateKeyInfo(
PK11SlotInfo *slot, /* optional, encrypt key in this slot */
@ -2173,11 +2125,16 @@ PK11_ExportEncryptedPrivateKeyInfo(
SECItem *pwitem, /* password for PBE encryption */
CERTCertificate *cert, /* wrap priv key for this user cert */
int iteration, /* interations for PBE alg */
void *pwArg) /* context for password callback */
void *wincx) /* context for password callback ? */
{
return PK11_ExportEncryptedPrivateKeyInfoV2(slot, algTag, SEC_OID_UNKNOWN,
SEC_OID_UNKNOWN, pwitem, cert,
iteration, pwArg);
SECKEYEncryptedPrivateKeyInfo *epki = NULL;
SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
if (pk != NULL) {
epki = PK11_ExportEncryptedPrivKeyInfo(slot, algTag, pwitem, pk,
iteration, wincx);
SECKEY_DestroyPrivateKey(pk);
}
return epki;
}
SECItem *
@ -2314,7 +2271,7 @@ PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void *wincx)
PK11_Authenticate(slot, PR_TRUE, wincx);
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return NULL;
}
@ -2591,7 +2548,7 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
CK_ATTRIBUTE *attrs;
CK_BBOOL ckTrue = CK_TRUE;
CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY;
size_t tsize = 0;
unsigned int tsize = 0;
int objCount = 0;
CK_OBJECT_HANDLE *key_ids;
SECKEYPublicKeyList *keys;
@ -2639,7 +2596,7 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
CK_ATTRIBUTE *attrs;
CK_BBOOL ckTrue = CK_TRUE;
CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY;
size_t tsize = 0;
unsigned int tsize = 0;
int objCount = 0;
CK_OBJECT_HANDLE *key_ids;
SECKEYPrivateKeyList *keys;

View file

@ -105,7 +105,7 @@ pk11_CheckPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
if (retry++ == 0) {
rv = PK11_InitToken(slot, PR_FALSE);
if (rv == SECSuccess) {
if (slot->session != CK_INVALID_HANDLE) {
if (slot->session != CK_INVALID_SESSION) {
session = slot->session; /* we should have
* a new session now */
mustRetry = PR_TRUE;
@ -356,7 +356,7 @@ PK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return rv;
}
@ -417,7 +417,7 @@ PK11_VerifyPW(PK11SlotInfo *slot, char *pw)
SECStatus
PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
{
CK_SESSION_HANDLE rwsession = CK_INVALID_HANDLE;
CK_SESSION_HANDLE rwsession = CK_INVALID_SESSION;
CK_RV crv;
SECStatus rv = SECFailure;
int len;
@ -433,7 +433,7 @@ PK11_InitPin(PK11SlotInfo *slot, const char *ssopw, const char *userpw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
slot->lastLoginCheck = 0;
return rv;
@ -506,7 +506,7 @@ PK11_ChangePW(PK11SlotInfo *slot, const char *oldpw, const char *newpw)
/* get a rwsession */
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return rv;
}
@ -575,7 +575,7 @@ PK11_DoPassword(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
/*
* Central server type applications which control access to multiple
* client applications to single crypto devices need to virtuallize the
* slave applications to single crypto devices need to virtuallize the
* login state. This is done by a callback out of PK11_IsLoggedIn and
* here. If we are actually logged in, then we got here because the
* higher level code told us that the particular client application may
@ -796,7 +796,7 @@ PK11_IsLoggedIn(PK11SlotInfo *slot, void *wincx)
PK11_ExitSlotMonitor(slot);
/* if we can't get session info, something is really wrong */
if (crv != CKR_OK) {
slot->session = CK_INVALID_HANDLE;
slot->session = CK_INVALID_SESSION;
return PR_FALSE;
}

View file

@ -5,8 +5,6 @@
* This file manages PKCS #11 instances of certificates.
*/
#include <stddef.h>
#include "secport.h"
#include "seccomon.h"
#include "secmod.h"
@ -448,7 +446,7 @@ PK11_FindCertHandlesForKeyHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle,
idTemplate[0],
{ CKA_CLASS, &searchClass, sizeof(searchClass) }
};
const size_t searchAttrCount = sizeof(searchTemplate) / sizeof(searchTemplate[0]);
const int searchAttrCount = sizeof(searchTemplate) / sizeof(searchTemplate[0]);
CK_OBJECT_HANDLE *ids = pk11_FindObjectsByTemplate(slot, searchTemplate, searchAttrCount, certHandleCountOut);
PORT_DestroyCheapArena(&arena);
@ -616,8 +614,9 @@ transfer_uri_certs_to_collection(nssList *certList, PK11URI *uri,
PRUint32 i, count;
NSSToken **tokens, **tp;
PK11SlotInfo *slot;
const SECItem *id;
const char *id;
id = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_ID);
count = nssList_Count(certList);
if (count == 0) {
return;
@ -626,15 +625,14 @@ transfer_uri_certs_to_collection(nssList *certList, PK11URI *uri,
if (!certs) {
return;
}
id = PK11URI_GetPathAttributeItem(uri, PK11URI_PATTR_ID);
nssList_GetArray(certList, (void **)certs, count);
for (i = 0; i < count; i++) {
/*
* Filter the subject matched certs based on the
* CKA_ID from the URI
*/
if (id && (id->len != certs[i]->id.size ||
memcmp(id->data, certs[i]->id.data, certs[i]->id.size)))
* Filter the subject matched certs based on the
* CKA_ID from the URI
*/
if (id && (strlen(id) != certs[i]->id.size ||
memcmp(id, certs[i]->id.data, certs[i]->id.size)))
continue;
tokens = nssPKIObject_GetTokens(&certs[i]->object, NULL);
if (tokens) {
@ -666,14 +664,6 @@ transfer_uri_certs_to_collection(nssList *certList, PK11URI *uri,
continue;
}
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_SERIAL);
if (value &&
!pk11_MatchString(value,
(char *)slot->tokenInfo.serialNumber,
sizeof(slot->tokenInfo.serialNumber))) {
continue;
}
nssPKIObjectCollection_AddObject(collection,
(nssPKIObject *)certs[i]);
break;
@ -691,8 +681,7 @@ find_certs_from_uri(const char *uriString, void *wincx)
PK11URI *uri = NULL;
CK_ATTRIBUTE attributes[10];
CK_ULONG nattributes = 0;
const SECItem *id;
const char *label, *type;
const char *label;
PK11SlotInfo *slotinfo;
nssCryptokiObject **instances;
PRStatus status;
@ -719,16 +708,10 @@ find_certs_from_uri(const char *uriString, void *wincx)
goto loser;
}
/* if the "type" attribute is specified its value must be "cert" */
type = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_TYPE);
if (type && strcmp(type, "cert")) {
goto loser;
}
label = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_OBJECT);
if (label) {
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
label,
(const char *)label,
certList);
} else {
(void)nssTrustDomain_GetCertsFromCache(defaultTD, certList);
@ -754,14 +737,6 @@ find_certs_from_uri(const char *uriString, void *wincx)
nattributes++;
}
id = PK11URI_GetPathAttributeItem(uri, PK11URI_PATTR_ID);
if (id) {
attributes[nattributes].type = CKA_ID;
attributes[nattributes].pValue = (void *)id->data;
attributes[nattributes].ulValueLen = id->len;
nattributes++;
}
tokens = NSSTrustDomain_FindTokensByURI(defaultTD, uri);
for (tok = tokens; tok && *tok; tok++) {
if (nssToken_IsPresent(*tok)) {
@ -1283,6 +1258,29 @@ PK11_ImportDERCert(PK11SlotInfo *slot, SECItem *derCert,
return rv;
}
/*
* get a certificate handle, look at the cached handle first..
*/
CK_OBJECT_HANDLE
pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
CK_ATTRIBUTE *theTemplate, int tsize)
{
CK_OBJECT_HANDLE certh;
if (cert->slot == slot) {
certh = cert->pkcs11ID;
if ((certh == CK_INVALID_HANDLE) ||
(cert->series != slot->series)) {
certh = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
cert->pkcs11ID = certh;
cert->series = slot->series;
}
} else {
certh = pk11_FindObjectByTemplate(slot, theTemplate, tsize);
}
return certh;
}
/*
* return the private key From a given Cert
*/
@ -1291,12 +1289,33 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
void *wincx)
{
int err;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_VALUE, NULL, 0 },
{ CKA_CLASS, NULL, 0 }
};
/* if you change the array, change the variable below as well */
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_OBJECT_HANDLE certh;
CK_OBJECT_HANDLE keyh;
CK_ATTRIBUTE *attrs = theTemplate;
PRBool needLogin;
SECStatus rv;
certh = PK11_FindCertInSlot(slot, cert, wincx);
PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
cert->derCert.len);
attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
/*
* issue the find
*/
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
return NULL;
}
certh = pk11_getcerthandle(slot, cert, theTemplate, tsize);
if (certh == CK_INVALID_HANDLE) {
return NULL;
}
@ -1446,7 +1465,7 @@ PK11_ImportDERCertForKey(SECItem *derCert, char *nickname, void *wincx)
static CK_OBJECT_HANDLE
pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
CK_ATTRIBUTE *searchTemplate, size_t count, void *wincx)
CK_ATTRIBUTE *searchTemplate, int count, void *wincx)
{
PK11SlotList *list;
PK11SlotListElement *le;
@ -2031,7 +2050,7 @@ PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot)
{ CKA_CLASS, NULL, 0 },
{ CKA_VALUE, NULL, 0 },
};
const size_t templateSize = sizeof(searchTemplate) / sizeof(searchTemplate[0]);
int templateSize = sizeof(searchTemplate) / sizeof(searchTemplate[0]);
attr = searchTemplate;
PK11_SETATTRS(attr, CKA_CLASS, &certClass, sizeof(certClass));
@ -2039,7 +2058,8 @@ PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot)
PK11_SETATTRS(attr, CKA_VALUE, cert->derCert.data, cert->derCert.len);
if (cert->slot) {
certHandle = PK11_FindCertInSlot(cert->slot, cert, wincx);
certHandle = pk11_getcerthandle(cert->slot, cert, searchTemplate,
templateSize);
if (certHandle != CK_INVALID_HANDLE) {
*pSlot = PK11_ReferenceSlot(cert->slot);
return certHandle;
@ -2601,7 +2621,7 @@ PK11_FindBestKEAMatch(CERTCertificate *server, void *wincx)
rv = PK11_Authenticate(le->slot, PR_TRUE, wincx);
if (rv != SECSuccess)
continue;
if (le->slot->session == CK_INVALID_HANDLE) {
if (le->slot->session == CK_INVALID_SESSION) {
continue;
}
returnedCert = pk11_GetKEAMate(le->slot, server);
@ -2639,51 +2659,36 @@ PK11_GetKEAMatchedCerts(PK11SlotInfo *slot1, PK11SlotInfo *slot2,
return SECFailure;
}
/*
* return the private key From a given Cert
*/
CK_OBJECT_HANDLE
PK11_FindEncodedCertInSlot(PK11SlotInfo *slot, SECItem *derCert, void *wincx)
PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
{
if (!slot || !derCert) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_VALUE, NULL, 0 },
{ CKA_CLASS, NULL, 0 }
};
const size_t tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
/* if you change the array, change the variable below as well */
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_ATTRIBUTE *attrs = theTemplate;
SECStatus rv;
PK11_SETATTRS(attrs, CKA_VALUE, derCert->data, derCert->len);
PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
cert->derCert.len);
attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
SECStatus rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
/*
* issue the find
*/
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
return CK_INVALID_HANDLE;
}
return pk11_FindObjectByTemplate(slot, theTemplate, tsize);
}
CK_OBJECT_HANDLE
PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
{
CK_OBJECT_HANDLE certh;
if (cert->slot == slot) {
certh = cert->pkcs11ID;
if ((certh == CK_INVALID_HANDLE) ||
(cert->series != slot->series)) {
certh = PK11_FindEncodedCertInSlot(slot, &cert->derCert, wincx);
cert->pkcs11ID = certh;
cert->series = slot->series;
}
} else {
certh = PK11_FindEncodedCertInSlot(slot, &cert->derCert, wincx);
}
return certh;
return pk11_getcerthandle(slot, cert, theTemplate, tsize);
}
/* Looking for PK11_GetKeyIDFromCert?
@ -2811,12 +2816,30 @@ SECItem *
PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx)
{
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_VALUE, NULL, 0 },
{ CKA_CLASS, NULL, 0 }
};
/* if you change the array, change the variable below as well */
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_OBJECT_HANDLE certHandle;
CK_ATTRIBUTE *attrs = theTemplate;
PK11SlotInfo *slotRef = NULL;
SECItem *item;
SECStatus rv;
if (slot) {
certHandle = PK11_FindCertInSlot(slot, cert, wincx);
PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data,
cert->derCert.len);
attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass));
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
return NULL;
}
certHandle = pk11_getcerthandle(slot, cert, theTemplate, tsize);
} else {
certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef);
if (certHandle == CK_INVALID_HANDLE) {

View file

@ -17,8 +17,6 @@
#include "secoid.h"
#include "sechash.h"
#include "secerr.h"
#include "blapit.h"
#include "secport.h"
static const SECItem pk11_null_params = { 0 };
@ -125,7 +123,7 @@ SECStatus
pk11_restoreContext(PK11Context *context, void *space, unsigned long savedLength)
{
CK_RV crv;
CK_OBJECT_HANDLE objectID = context->objectID;
CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID : CK_INVALID_HANDLE;
PORT_Assert(space != NULL);
if (space == NULL) {
@ -142,54 +140,6 @@ pk11_restoreContext(PK11Context *context, void *space, unsigned long savedLength
SECStatus pk11_Finalize(PK11Context *context);
/*
* Initialize a Message function. Particular function is passed in as a
* function pointer. Since all C_Message*Init funcitons have the same
* prototype, we just pick one of the the prototypes to declare our init
* function.
*/
static CK_RV
pk11_contextInitMessage(PK11Context *context, CK_MECHANISM_PTR mech,
CK_C_MessageEncryptInit initFunc,
CK_FLAGS flags, CK_RV scrv)
{
PK11SlotInfo *slot = context->slot;
CK_VERSION version = slot->module->cryptokiVersion;
CK_RV crv = CKR_OK;
context->ivCounter = 0;
context->ivMaxCount = 0;
context->ivFixedBits = 0;
context->ivLen = 0;
context->ivGen = CKG_NO_GENERATE;
context->simulate_mechanism = (mech)->mechanism;
context->simulate_message = PR_FALSE;
/* check that we can do the Message interface. We need to check
* for either 1) are we using a PKCS #11 v3 interface and 2) is the
* Message flag set on the mechanism. If either is false we simulate
* the message interface for the Encrypt and Decrypt cases using the
* PKCS #11 V2 interface.
* Sign and verify do not have V2 interfaces, so we go ahead and fail
* if those cases */
if ((version.major >= 3) &&
PK11_DoesMechanismFlag(slot, (mech)->mechanism, flags)) {
PK11_EnterContextMonitor(context);
crv = (*initFunc)((context)->session, (mech), (context)->objectID);
PK11_ExitContextMonitor(context);
if ((crv == CKR_FUNCTION_NOT_SUPPORTED) ||
(crv == CKR_MECHANISM_INVALID)) {
/* we have a 3.0 interface, and the flag was set (or ignored)
* but the implementation was not there, use the V2 interface */
crv = (scrv);
context->simulate_message = PR_TRUE;
}
} else {
crv = (scrv);
context->simulate_message = PR_TRUE;
}
return crv;
}
/*
* Context initialization. Used by all flavors of CreateContext
*/
@ -197,74 +147,34 @@ static SECStatus
pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
{
CK_RV crv;
PK11SymKey *symKey = context->key;
SECStatus rv = SECSuccess;
context->simulate_message = PR_FALSE;
switch (context->operation) {
case CKA_ENCRYPT:
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, symKey->objectID);
break;
case CKA_DECRYPT:
PK11_EnterContextMonitor(context);
if (context->fortezzaHack) {
CK_ULONG count = 0;
/* generate the IV for fortezza */
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, context->objectID);
if (crv != CKR_OK) {
PK11_ExitContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, symKey->objectID);
if (crv != CKR_OK)
break;
}
PK11_GETTAB(context->slot)
->C_EncryptFinal(context->session,
NULL, &count);
}
crv = PK11_GETTAB(context->slot)->C_DecryptInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_DecryptInit(context->session, mech_info, symKey->objectID);
break;
case CKA_SIGN:
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, symKey->objectID);
break;
case CKA_VERIFY:
/* NOTE: we previously has this set to C_SignInit for Macing.
* It turns out now one could possibly use it that way, though,
* because PK11_HashOp() always called C_VerifyUpdate on CKA_VERIFY,
* which would have failed. So everyone just calls us with CKA_SIGN
* when Macing even when they are verifying, no need to 'do it
* for them'. It needs to be VerifyInit now so that we can do
* PKCS #11 hash/Verify combo operations. */
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_VerifyInit(context->session, mech_info, context->objectID);
PK11_ExitContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, symKey->objectID);
break;
case CKA_DIGEST:
PK11_EnterContextMonitor(context);
crv = PK11_GETTAB(context->slot)->C_DigestInit(context->session, mech_info);
PK11_ExitContextMonitor(context);
break;
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageEncryptInit,
CKF_MESSAGE_ENCRYPT, CKR_OK);
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageDecryptInit,
CKF_MESSAGE_DECRYPT, CKR_OK);
break;
case CKA_NSS_MESSAGE | CKA_SIGN:
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageSignInit,
CKF_MESSAGE_SIGN, CKR_FUNCTION_NOT_SUPPORTED);
break;
case CKA_NSS_MESSAGE | CKA_VERIFY:
crv = pk11_contextInitMessage(context, mech_info,
PK11_GETTAB(context->slot)->C_MessageVerifyInit,
CKF_MESSAGE_VERIFY, CKR_FUNCTION_NOT_SUPPORTED);
break;
default:
crv = CKR_OPERATION_NOT_INITIALIZED;
@ -276,95 +186,35 @@ pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info)
return SECFailure;
}
/* handle the case where the token is using the old NSS mechanism */
if (context->simulate_message &&
!PK11_DoesMechanism(context->slot, context->simulate_mechanism)) {
if ((context->simulate_mechanism == CKM_CHACHA20_POLY1305) &&
PK11_DoesMechanism(context->slot, CKM_NSS_CHACHA20_POLY1305)) {
context->simulate_mechanism = CKM_NSS_CHACHA20_POLY1305;
} else {
PORT_SetError(PK11_MapError(CKR_MECHANISM_INVALID));
return SECFailure;
}
}
/*
* handle session starvation case.. use our last session to multiplex
*/
if (!context->ownSession) {
PK11_EnterContextMonitor(context);
context->savedData = pk11_saveContext(context, context->savedData,
&context->savedLength);
if (context->savedData == NULL)
rv = SECFailure;
/* clear out out session for others to use */
pk11_Finalize(context);
PK11_ExitContextMonitor(context);
}
return rv;
}
/*
* Testing interfaces, not for general use. This function forces
* an AEAD context into simulation mode even though the target token
* can already do PKCS #11 v3.0 Message (i.e. softoken).
*/
SECStatus
_PK11_ContextSetAEADSimulation(PK11Context *context)
{
CK_RV crv;
/* only message encrypt and message decrypt contexts can be simulated */
if ((context->operation != (CKA_NSS_MESSAGE | CKA_ENCRYPT)) &&
(context->operation != (CKA_NSS_MESSAGE | CKA_DECRYPT))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* if we are already simulating, return */
if (context->simulate_message) {
return SECSuccess;
}
/* we need to shutdown the existing AEAD operation */
switch (context->operation) {
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
crv = PK11_GETTAB(context->slot)->C_MessageEncryptFinal(context->session);
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
crv = PK11_GETTAB(context->slot)->C_MessageDecryptFinal(context->session);
break;
default:
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return SECFailure;
}
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
context->simulate_message = PR_TRUE;
return SECSuccess;
}
PRBool
_PK11_ContextGetAEADSimulation(PK11Context *context)
{
return context->simulate_message;
}
/*
* Common Helper Function do come up with a new context.
*/
static PK11Context *
pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
PK11SymKey *symKey, CK_OBJECT_HANDLE objectID,
const SECItem *param, void *pwArg)
PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey,
SECItem *param)
{
CK_MECHANISM mech_info;
PK11Context *context;
SECStatus rv;
PORT_Assert(slot != NULL);
if (!slot || ((objectID == CK_INVALID_HANDLE) && ((operation != CKA_DIGEST) ||
(type == CKM_SKIPJACK_CBC64)))) {
if (!slot || (!symKey && ((operation != CKA_DIGEST) ||
(type == CKM_SKIPJACK_CBC64)))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
@ -382,23 +232,17 @@ pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
* of the connection.*/
context->fortezzaHack = PR_FALSE;
if (type == CKM_SKIPJACK_CBC64) {
if (symKey && (symKey->origin == PK11_OriginFortezzaHack)) {
if (symKey->origin == PK11_OriginFortezzaHack) {
context->fortezzaHack = PR_TRUE;
}
}
/* initialize the critical fields of the context */
context->operation = operation;
/* If we were given a symKey, keep our own reference to it so
* that the key doesn't disappear in the middle of the operation
* if the caller frees it. Public and Private keys are not reference
* counted, so the caller just has to keep his copies around until
* the operation completes */
context->key = symKey ? PK11_ReferenceSymKey(symKey) : NULL;
context->objectID = objectID;
context->slot = PK11_ReferenceSlot(slot);
context->session = pk11_GetNewSession(slot, &context->ownSession);
context->pwArg = pwArg;
context->cx = symKey ? symKey->cx : NULL;
/* get our session */
context->savedData = NULL;
@ -425,7 +269,9 @@ pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type,
mech_info.mechanism = type;
mech_info.pParameter = param->data;
mech_info.ulParameterLen = param->len;
PK11_EnterContextMonitor(context);
rv = pk11_context_init(context, &mech_info);
PK11_ExitContextMonitor(context);
if (rv != SECSuccess) {
PK11_DestroyContext(context, PR_TRUE);
@ -487,11 +333,11 @@ PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
/*
* Create a context from a key. We really should make sure we aren't using
* the same key in multiple sessions!
* the same key in multiple session!
*/
PK11Context *
PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
PK11SymKey *symKey, const SECItem *param)
PK11SymKey *symKey, SECItem *param)
{
PK11SymKey *newKey;
PK11Context *context;
@ -504,72 +350,13 @@ PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
symKey = newKey;
}
/* Context keeps its reference to the symKey, so it's safe to
* free our reference we we are through, even though we may have
* created the key using pk11_ForceSlot. */
/* Context Adopts the symKey.... */
context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey,
symKey->objectID, param, symKey->cx);
param);
PK11_FreeSymKey(symKey);
return context;
}
/* To support multipart public key operations (like hash/verify operations),
* we need to create contexts with public keys. */
PK11Context *
PK11_CreateContextByPubKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
SECKEYPublicKey *pubKey, const SECItem *param,
void *pwArg)
{
PK11SlotInfo *slot = pubKey->pkcs11Slot;
SECItem nullparam = { 0, 0, 0 };
/* if this slot doesn't support the mechanism, go to a slot that does */
/* public keys have all their data in the public key data structure,
* so there's no need to export the old key, just import this one. The
* import manages consistancy of the public key data structure */
if (slot == NULL || !PK11_DoesMechanism(slot, type)) {
CK_OBJECT_HANDLE objectID;
slot = PK11_GetBestSlot(type, NULL);
if (slot == NULL) {
return NULL;
}
objectID = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
PK11_FreeSlot(slot);
if (objectID == CK_INVALID_HANDLE) {
return NULL;
}
}
/* unlike symkeys, we accept a NULL parameter. map a null parameter
* to the empty parameter. This matches the semantics of
* PK11_VerifyWithMechanism */
return pk11_CreateNewContextInSlot(type, pubKey->pkcs11Slot, operation,
NULL, pubKey->pkcs11ID,
param ? param : &nullparam, pwArg);
}
/* To support multipart private key operations (like hash/sign operations),
* we need to create contexts with private keys. */
PK11Context *
PK11_CreateContextByPrivKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation,
SECKEYPrivateKey *privKey, const SECItem *param)
{
SECItem nullparam = { 0, 0, 0 };
/* Private keys are generally not movable. If the token the
* private key lives on can't do the operation, generally we are
* stuck anyway. So no need to try to manipulate the key into
* another token */
/* if this slot doesn't support the mechanism, go to a slot that does */
/* unlike symkeys, we accept a NULL parameter. map a null parameter
* to the empty parameter. This matches the semantics of
* PK11_SignWithMechanism */
return pk11_CreateNewContextInSlot(type, privKey->pkcs11Slot, operation,
NULL, privKey->pkcs11ID,
param ? param : &nullparam,
privKey->wincx);
}
/*
* Digest contexts don't need keys, but the do need to find a slot.
* Macing should use PK11_CreateContextBySymKey.
@ -595,8 +382,7 @@ PK11_CreateDigestContext(SECOidTag hashAlg)
param.len = 0;
param.type = 0;
context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL,
CK_INVALID_HANDLE, &param, NULL);
context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL, &param);
PK11_FreeSlot(slot);
return context;
}
@ -614,8 +400,7 @@ PK11_CloneContext(PK11Context *old)
unsigned long len;
newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation,
old->key, old->objectID, old->param,
old->pwArg);
old->key, old->param);
if (newcx == NULL)
return NULL;
@ -791,12 +576,12 @@ PK11_DigestBegin(PK11Context *cx)
*/
PK11_EnterContextMonitor(cx);
pk11_Finalize(cx);
PK11_ExitContextMonitor(cx);
mech_info.mechanism = cx->type;
mech_info.pParameter = cx->param->data;
mech_info.ulParameterLen = cx->param->len;
rv = pk11_context_init(cx, &mech_info);
PK11_ExitContextMonitor(cx);
if (rv != SECSuccess) {
return SECFailure;
@ -955,534 +740,6 @@ PK11_CipherOp(PK11Context *context, unsigned char *out, int *outlen,
return rv;
}
/*
* Simulate the IV generation that normally would happen in the token.
*
* This is a modifed copy of what is in freebl/gcm.c. We can't use the
* version in freebl because of layering, since freebl is inside the token
* boundary. These issues are traditionally handled by moving them to util,
* but we also have two different Random functions we have two switch between.
* Since this is primarily here for tokens that don't support the PKCS #11
* Message Interface, it's OK if they diverge a bit. Slight semantic
* differences from the freebl/gcm.c version shouldn't be much more than the
* sematic differences between freebl and other tokens which do implement the
* Message Interface. */
static SECStatus
pk11_GenerateIV(PK11Context *context, CK_GENERATOR_FUNCTION ivgen,
int fixedBits, unsigned char *iv, int ivLen)
{
unsigned int i;
unsigned int flexBits;
unsigned int ivOffset;
unsigned int ivNewCount;
unsigned char ivMask;
unsigned char ivSave;
SECStatus rv;
if (context->ivCounter != 0) {
/* If we've already generated a message, make sure all subsequent
* messages are using the same generator */
if ((context->ivGen != ivgen) ||
(context->ivFixedBits != fixedBits) ||
(context->ivLen != ivLen)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
} else {
/* remember these values */
context->ivGen = ivgen;
context->ivFixedBits = fixedBits;
context->ivLen = ivLen;
/* now calculate how may bits of IV we have to supply */
flexBits = ivLen * PR_BITS_PER_BYTE;
/* first make sure we aren't going to overflow */
if (flexBits < fixedBits) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
flexBits -= fixedBits;
/* if we are generating a random number reduce the acceptable bits to
* avoid birthday attacks */
if (ivgen == CKG_GENERATE_RANDOM) {
if (flexBits <= GCMIV_RANDOM_BIRTHDAY_BITS) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* see freebl/blapit.h for how GCMIV_RANDOM_BIRTHDAY_BITS is
* calculated. */
flexBits -= GCMIV_RANDOM_BIRTHDAY_BITS;
flexBits = flexBits >> 1;
}
if (flexBits == 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Turn those bits into the number of IV's we can safely return */
if (flexBits >= sizeof(context->ivMaxCount) * PR_BITS_PER_BYTE) {
context->ivMaxCount = PR_UINT64(0xffffffffffffffff);
} else {
context->ivMaxCount = (PR_UINT64(1) << flexBits);
}
}
/* no generate, accept the IV from the source */
if (ivgen == CKG_NO_GENERATE) {
context->ivCounter = 1;
return SECSuccess;
}
/* make sure we haven't exceeded the number of IVs we can return
* for this key, generator, and IV size */
if (context->ivCounter >= context->ivMaxCount) {
/* use a unique error from just bad user input */
PORT_SetError(SEC_ERROR_EXTRA_INPUT);
return SECFailure;
}
/* build to mask to handle the first byte of the IV */
ivOffset = fixedBits / PR_BITS_PER_BYTE;
ivMask = 0xff >> ((PR_BITS_PER_BYTE - (fixedBits & 7)) & 7);
ivNewCount = ivLen - ivOffset;
/* finally generate the IV */
switch (ivgen) {
case CKG_GENERATE: /* default to counter */
case CKG_GENERATE_COUNTER:
iv[ivOffset] = (iv[ivOffset] & ~ivMask) |
(PORT_GET_BYTE_BE(context->ivCounter, 0, ivNewCount) & ivMask);
for (i = 1; i < ivNewCount; i++) {
iv[ivOffset + i] =
PORT_GET_BYTE_BE(context->ivCounter, i, ivNewCount);
}
break;
case CKG_GENERATE_COUNTER_XOR:
iv[ivOffset] ^=
(PORT_GET_BYTE_BE(context->ivCounter, 0, ivNewCount) & ivMask);
for (i = 1; i < ivNewCount; i++) {
iv[ivOffset + i] ^=
PORT_GET_BYTE_BE(context->ivCounter, i, ivNewCount);
}
break;
case CKG_GENERATE_RANDOM:
ivSave = iv[ivOffset] & ~ivMask;
rv = PK11_GenerateRandom(iv + ivOffset, ivNewCount);
iv[ivOffset] = ivSave | (iv[ivOffset] & ivMask);
if (rv != SECSuccess) {
return rv;
}
break;
}
context->ivCounter++;
return SECSuccess;
}
/*
* PKCS #11 v2.40 did not have a message interface. If our module can't
* do the message interface use the old method of doing AEAD */
static SECStatus
pk11_AEADSimulateOp(PK11Context *context, void *params, int paramslen,
const unsigned char *aad, int aadlen,
unsigned char *out, int *outlen,
int maxout, const unsigned char *in, int inlen)
{
unsigned int length = maxout;
SECStatus rv = SECSuccess;
unsigned char *saveOut = out;
unsigned char *allocOut = NULL;
/*
* first we need to convert the single shot (v2.40) parameters into
* the message version of the parameters. This usually involves
* copying the Nonce or IV, setting the AAD from our parameter list
* and handling the tag differences */
CK_GCM_PARAMS_V3 gcm;
CK_GCM_MESSAGE_PARAMS *gcm_message;
CK_CCM_PARAMS ccm;
CK_CCM_MESSAGE_PARAMS *ccm_message;
CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha_poly;
CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *chacha_poly_message;
CK_NSS_AEAD_PARAMS nss_chacha_poly;
CK_MECHANISM_TYPE mechanism = context->simulate_mechanism;
SECItem sim_params = { 0, NULL, 0 };
unsigned char *tag = NULL;
unsigned int taglen;
PRBool encrypt;
*outlen = 0;
/* figure out if we are encrypting or decrypting, as tags are
* handled differently in both */
switch (context->operation) {
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
encrypt = PR_TRUE;
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
encrypt = PR_FALSE;
break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
switch (mechanism) {
case CKM_CHACHA20_POLY1305:
case CKM_SALSA20_POLY1305:
if (paramslen != sizeof(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
chacha_poly_message =
(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *)params;
chacha_poly.pNonce = chacha_poly_message->pNonce;
chacha_poly.ulNonceLen = chacha_poly_message->ulNonceLen;
chacha_poly.pAAD = (CK_BYTE_PTR)aad;
chacha_poly.ulAADLen = aadlen;
tag = chacha_poly_message->pTag;
taglen = 16;
sim_params.data = (unsigned char *)&chacha_poly;
sim_params.len = sizeof(chacha_poly);
/* SALSA20_POLY1305 and CHACHA20_POLY1305 do not generate the iv
* internally, don't simulate it either */
break;
case CKM_NSS_CHACHA20_POLY1305:
if (paramslen != sizeof(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
chacha_poly_message =
(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *)params;
tag = chacha_poly_message->pTag;
taglen = 16;
nss_chacha_poly.pNonce = chacha_poly_message->pNonce;
nss_chacha_poly.ulNonceLen = chacha_poly_message->ulNonceLen;
nss_chacha_poly.pAAD = (CK_BYTE_PTR)aad;
nss_chacha_poly.ulAADLen = aadlen;
nss_chacha_poly.ulTagLen = taglen;
sim_params.data = (unsigned char *)&nss_chacha_poly;
sim_params.len = sizeof(nss_chacha_poly);
/* CKM_NSS_CHACHA20_POLY1305 does not generate the iv
* internally, don't simulate it either */
break;
case CKM_AES_CCM:
if (paramslen != sizeof(CK_CCM_MESSAGE_PARAMS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
ccm_message = (CK_CCM_MESSAGE_PARAMS *)params;
ccm.ulDataLen = ccm_message->ulDataLen;
ccm.pNonce = ccm_message->pNonce;
ccm.ulNonceLen = ccm_message->ulNonceLen;
ccm.pAAD = (CK_BYTE_PTR)aad;
ccm.ulAADLen = aadlen;
ccm.ulMACLen = ccm_message->ulMACLen;
tag = ccm_message->pMAC;
taglen = ccm_message->ulMACLen;
sim_params.data = (unsigned char *)&ccm;
sim_params.len = sizeof(ccm);
if (encrypt) {
/* simulate generating the IV */
rv = pk11_GenerateIV(context, ccm_message->nonceGenerator,
ccm_message->ulNonceFixedBits,
ccm_message->pNonce,
ccm_message->ulNonceLen);
if (rv != SECSuccess) {
return rv;
}
}
break;
case CKM_AES_GCM:
if (paramslen != sizeof(CK_GCM_MESSAGE_PARAMS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
gcm_message = (CK_GCM_MESSAGE_PARAMS *)params;
gcm.pIv = gcm_message->pIv;
gcm.ulIvLen = gcm_message->ulIvLen;
gcm.ulIvBits = gcm.ulIvLen * PR_BITS_PER_BYTE;
gcm.pAAD = (CK_BYTE_PTR)aad;
gcm.ulAADLen = aadlen;
gcm.ulTagBits = gcm_message->ulTagBits;
tag = gcm_message->pTag;
taglen = (gcm_message->ulTagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
sim_params.data = (unsigned char *)&gcm;
sim_params.len = sizeof(gcm);
if (encrypt) {
/* simulate generating the IV */
rv = pk11_GenerateIV(context, gcm_message->ivGenerator,
gcm_message->ulIvFixedBits,
gcm_message->pIv, gcm_message->ulIvLen);
if (rv != SECSuccess) {
return rv;
}
}
break;
default:
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
}
/* now handle the tag. The message interface separates the tag from
* the data, while the single shot gets and puts the tag at the end of
* the encrypted data. */
if (!encrypt) {
/* In the decrypt case, if the tag is already at the end of the
* input buffer we are golden, otherwise we'll need a new input
* buffer and copy the tag at the end of it */
if (tag != in + inlen) {
allocOut = PORT_Alloc(inlen + taglen);
if (allocOut == NULL) {
return SECFailure;
}
PORT_Memcpy(allocOut, in, inlen);
PORT_Memcpy(allocOut + inlen, tag, taglen);
in = allocOut;
}
inlen = inlen + taglen;
} else {
/* if we end up allocating, we don't want to overrun this buffer,
* so we fail early here */
if (maxout < inlen) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* in the encrypt case, we are fine if maxout is big enough to hold
* the tag. We'll copy the tag after the operation */
if (maxout < inlen + taglen) {
allocOut = PORT_Alloc(inlen + taglen);
if (allocOut == NULL) {
return SECFailure;
}
out = allocOut;
length = maxout = inlen + taglen;
}
}
/* now do the operation */
if (encrypt) {
rv = PK11_Encrypt(context->key, mechanism, &sim_params, out, &length,
maxout, in, inlen);
} else {
rv = PK11_Decrypt(context->key, mechanism, &sim_params, out, &length,
maxout, in, inlen);
}
if (rv != SECSuccess) {
/* If the mechanism was CKM_AES_GCM, the module may have been
* following the same error as old versions of NSS. Retry with
* the CK_NSS_GCM_PARAMS */
if ((mechanism == CKM_AES_GCM) &&
(PORT_GetError() == SEC_ERROR_BAD_DATA)) {
CK_NSS_GCM_PARAMS gcm_nss;
gcm_message = (CK_GCM_MESSAGE_PARAMS *)params;
gcm_nss.pIv = gcm_message->pIv;
gcm_nss.ulIvLen = gcm_message->ulIvLen;
gcm_nss.pAAD = (CK_BYTE_PTR)aad;
gcm_nss.ulAADLen = aadlen;
gcm_nss.ulTagBits = gcm_message->ulTagBits;
sim_params.data = (unsigned char *)&gcm_nss;
sim_params.len = sizeof(gcm_nss);
if (encrypt) {
rv = PK11_Encrypt(context->key, mechanism, &sim_params, out,
&length, maxout, in, inlen);
} else {
rv = PK11_Decrypt(context->key, mechanism, &sim_params, out,
&length, maxout, in, inlen);
}
if (rv != SECSuccess) {
goto fail;
}
} else {
goto fail;
}
}
/* on encrypt, separate the output buffer from the tag */
if (encrypt) {
if ((length < taglen) || (length > inlen + taglen)) {
/* PKCS #11 module should not return a length smaller than
* taglen, or bigger than inlen+taglen */
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
goto fail;
}
length = length - taglen;
if (allocOut) {
/*
* If we used a temporary buffer, copy it out to the original
* buffer.
*/
PORT_Memcpy(saveOut, allocOut, length);
}
/* if the tag isn't in the right place, copy it out */
if (tag != out + length) {
PORT_Memcpy(tag, out + length, taglen);
}
}
*outlen = length;
rv = SECSuccess;
fail:
if (allocOut) {
PORT_Free(allocOut);
}
return rv;
}
/*
* Do an AEAD operation. This function optionally returns
* and IV on Encrypt for all mechanism. NSS knows which mechanisms
* generate IV's in the token and which don't. This allows the
* applications to make a single call without special handling for
* each AEAD mechanism (the special handling is all contained here.
*/
SECStatus
PK11_AEADOp(PK11Context *context, CK_GENERATOR_FUNCTION ivgen,
int fixedbits, unsigned char *iv, int ivlen,
const unsigned char *aad, int aadlen,
unsigned char *out, int *outlen,
int maxout, unsigned char *tag, int taglen,
const unsigned char *in, int inlen)
{
CK_GCM_MESSAGE_PARAMS gcm_message;
CK_CCM_MESSAGE_PARAMS ccm_message;
CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS chacha_poly_message;
void *params;
int paramslen;
SECStatus rv;
switch (context->simulate_mechanism) {
case CKM_CHACHA20_POLY1305:
case CKM_SALSA20_POLY1305:
case CKM_NSS_CHACHA20_POLY1305:
chacha_poly_message.pNonce = iv;
chacha_poly_message.ulNonceLen = ivlen;
chacha_poly_message.pTag = tag;
params = &chacha_poly_message;
paramslen = sizeof(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS);
/* SALSA20_POLY1305 and CHACHA20_POLY1305 do not generate the iv
* internally, Do it here. */
if (context->operation == (CKA_NSS_MESSAGE | CKA_ENCRYPT)) {
/* simulate generating the IV */
rv = pk11_GenerateIV(context, ivgen, fixedbits, iv, ivlen);
if (rv != SECSuccess) {
return rv;
}
}
break;
case CKM_AES_GCM:
gcm_message.pIv = iv;
gcm_message.ulIvLen = ivlen;
gcm_message.ivGenerator = ivgen;
gcm_message.ulIvFixedBits = fixedbits;
gcm_message.pTag = tag;
gcm_message.ulTagBits = taglen * 8;
params = &gcm_message;
paramslen = sizeof(CK_GCM_MESSAGE_PARAMS);
/* GCM generates IV internally */
break;
case CKM_AES_CCM:
ccm_message.ulDataLen = inlen;
ccm_message.pNonce = iv;
ccm_message.ulNonceLen = ivlen;
ccm_message.nonceGenerator = ivgen;
ccm_message.ulNonceFixedBits = fixedbits;
ccm_message.pMAC = tag;
ccm_message.ulMACLen = taglen;
params = &ccm_message;
paramslen = sizeof(CK_GCM_MESSAGE_PARAMS);
/* CCM generates IV internally */
break;
default:
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return SECFailure;
}
return PK11_AEADRawOp(context, params, paramslen, aad, aadlen, out, outlen,
maxout, in, inlen);
}
/* Do and AED operation. The application builds the params on it's own
* and passes them in. This allows applications direct access to the params
* so they can use mechanisms not yet understood by, NSS, or get semantics
* not suppied by PK11_AEAD. */
SECStatus
PK11_AEADRawOp(PK11Context *context, void *params, int paramslen,
const unsigned char *aad, int aadlen,
unsigned char *out, int *outlen,
int maxout, const unsigned char *in, int inlen)
{
CK_RV crv = CKR_OK;
CK_ULONG length = maxout;
SECStatus rv = SECSuccess;
PORT_Assert(outlen != NULL);
*outlen = 0;
if (((context->operation) & CKA_NSS_MESSAGE_MASK) != CKA_NSS_MESSAGE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/*
* The PKCS 11 module does not support the message interface, fall
* back to using single shot operation */
if (context->simulate_message) {
return pk11_AEADSimulateOp(context, params, paramslen, aad, aadlen,
out, outlen, maxout, in, inlen);
}
/* if we ran out of session, we need to restore our previously stored
* state.
*/
PK11_EnterContextMonitor(context);
if (!context->ownSession) {
rv = pk11_restoreContext(context, context->savedData,
context->savedLength);
if (rv != SECSuccess) {
PK11_ExitContextMonitor(context);
return rv;
}
}
switch (context->operation) {
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
length = maxout;
crv = PK11_GETTAB(context->slot)->C_EncryptMessage(context->session, params, paramslen, (CK_BYTE_PTR)aad, aadlen, (CK_BYTE_PTR)in, inlen, out, &length);
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
length = maxout;
crv = PK11_GETTAB(context->slot)->C_DecryptMessage(context->session, params, paramslen, (CK_BYTE_PTR)aad, aadlen, (CK_BYTE_PTR)in, inlen, out, &length);
break;
case CKA_NSS_MESSAGE | CKA_SIGN:
length = maxout;
crv = PK11_GETTAB(context->slot)->C_SignMessage(context->session, params, paramslen, (CK_BYTE_PTR)in, inlen, out, &length);
break;
case CKA_NSS_MESSAGE | CKA_VERIFY:
length = maxout; /* sig length */
crv = PK11_GETTAB(context->slot)->C_VerifyMessage(context->session, params, paramslen, (CK_BYTE_PTR)in, inlen, out /* sig */, length);
break;
default:
crv = CKR_OPERATION_NOT_INITIALIZED;
break;
}
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
rv = SECFailure;
} else {
*outlen = length;
}
/*
* handle session starvation case.. use our last session to multiplex
*/
if (!context->ownSession) {
context->savedData = pk11_saveContext(context, context->savedData,
&context->savedLength);
if (context->savedData == NULL)
rv = SECFailure;
/* clear out out session for others to use */
pk11_Finalize(context);
}
PK11_ExitContextMonitor(context);
return rv;
}
/*
* execute a digest/signature operation
*/
@ -1666,18 +923,6 @@ finalize:
case CKA_DIGEST:
crv = PK11_GETTAB(context->slot)->C_DigestFinal(context->session, buffer, &count);
break;
case CKA_NSS_MESSAGE | CKA_ENCRYPT:
crv = PK11_GETTAB(context->slot)->C_MessageEncryptFinal(context->session);
break;
case CKA_NSS_MESSAGE | CKA_DECRYPT:
crv = PK11_GETTAB(context->slot)->C_MessageDecryptFinal(context->session);
break;
case CKA_NSS_MESSAGE | CKA_SIGN:
crv = PK11_GETTAB(context->slot)->C_MessageSignFinal(context->session);
break;
case CKA_NSS_MESSAGE | CKA_VERIFY:
crv = PK11_GETTAB(context->slot)->C_MessageVerifyFinal(context->session);
break;
default:
crv = CKR_OPERATION_NOT_INITIALIZED;
break;
@ -1695,11 +940,6 @@ finalize:
return SECFailure;
}
/* Message interface does not need to allocate a final buffer */
if (((context->operation) & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
return SECSuccess;
}
/* try to finalize the session with a buffer */
if (buffer == NULL) {
if (count <= sizeof stackBuf) {
@ -1707,6 +947,7 @@ finalize:
} else {
buffer = PORT_Alloc(count);
if (buffer == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
}
}
@ -1731,13 +972,6 @@ PK11_DigestFinal(PK11Context *context, unsigned char *data,
CK_RV crv;
SECStatus rv;
/* message interface returns no data on Final, Should not use DigestFinal
* in this case */
if (((context->operation) & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* if we ran out of session, we need to restore our previously stored
* state.
*/
@ -1783,13 +1017,3 @@ PK11_DigestFinal(PK11Context *context, unsigned char *data,
*outLen = (unsigned int)len;
return SECSuccess;
}
PRBool
PK11_ContextGetFIPSStatus(PK11Context *context)
{
if (context->slot == NULL) {
return PR_FALSE;
}
return pk11slot_GetFIPSStatus(context->slot, context->session,
CK_INVALID_HANDLE, context->init ? CKT_NSS_SESSION_CHECK : CKT_NSS_SESSION_LAST_CHECK);
}

View file

@ -107,8 +107,8 @@ PK11_MapError(CK_RV rv)
MAPERROR(CKR_WRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_WRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_VENDOR_DEFINED, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_NSS_CERTDB_FAILED, SEC_ERROR_BAD_DATABASE)
MAPERROR(CKR_NSS_KEYDB_FAILED, SEC_ERROR_BAD_DATABASE)
MAPERROR(CKR_NETSCAPE_CERTDB_FAILED, SEC_ERROR_BAD_DATABASE)
MAPERROR(CKR_NETSCAPE_KEYDB_FAILED, SEC_ERROR_BAD_DATABASE)
MAPERROR(CKR_CANT_LOCK, SEC_ERROR_INCOMPATIBLE_PKCS11)
/* clang-format on */
@ -130,12 +130,12 @@ PK11_MapError(CK_RV rv)
#else
/* clang-format off */
/* clang-format off */
default :
break;
/* clang-format on */
}
return SEC_ERROR_UNKNOWN_PKCS11_ERROR;
/* clang-format on */
}
return SEC_ERROR_UNKNOWN_PKCS11_ERROR;
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,82 +0,0 @@
/* 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/. */
#ifndef _PK11_HPKE_H_
#define _PK11_HPKE_H_ 1
#include "blapit.h"
#include "seccomon.h"
#define CLEANUP \
PORT_Assert(rv == SECSuccess); \
cleanup
/* Error code must already be set. */
#define CHECK_RV(rv) \
if ((rv) != SECSuccess) { \
goto cleanup; \
}
/* Error code must already be set. */
#define CHECK_FAIL(cond) \
if ((cond)) { \
rv = SECFailure; \
goto cleanup; \
}
#define CHECK_FAIL_ERR(cond, err) \
if ((cond)) { \
PORT_SetError((err)); \
rv = SECFailure; \
goto cleanup; \
}
typedef enum {
HpkeModeBase = 0,
HpkeModePsk = 1,
} HpkeModeId;
/* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hpke-08#section-7.1 */
typedef enum {
HpkeDhKemX25519Sha256 = 0x20,
} HpkeKemId;
typedef enum {
HpkeKdfHkdfSha256 = 1,
HpkeKdfHkdfSha384 = 2,
HpkeKdfHkdfSha512 = 3,
} HpkeKdfId;
typedef enum {
HpkeAeadAes128Gcm = 1,
HpkeAeadAes256Gcm = 2,
HpkeAeadChaCha20Poly1305 = 3,
} HpkeAeadId;
typedef struct hpkeKemParamsStr {
HpkeKemId id;
unsigned int Nsk;
unsigned int Nsecret;
unsigned int Npk;
SECOidTag oidTag;
CK_MECHANISM_TYPE hashMech;
} hpkeKemParams;
typedef struct hpkeKdfParamsStr {
HpkeKdfId id;
unsigned int Nh;
CK_MECHANISM_TYPE mech;
} hpkeKdfParams;
typedef struct hpkeAeadParamsStr {
HpkeAeadId id;
unsigned int Nk;
unsigned int Nn;
unsigned int tagLen;
CK_MECHANISM_TYPE mech;
} hpkeAeadParams;
typedef struct HpkeContextStr HpkeContext;
#endif /* _PK11_HPKE_H_ */

View file

@ -6,8 +6,6 @@
* Interfaces.
*/
#include <stddef.h>
#include "seccomon.h"
#include "secmod.h"
#include "nssilock.h"
@ -31,7 +29,7 @@ pk11_FindRSAPubKey(PK11SlotInfo *slot)
CK_KEY_TYPE key_type = CKK_RSA;
CK_OBJECT_CLASS class_type = CKO_PUBLIC_KEY;
CK_ATTRIBUTE theTemplate[2];
size_t template_count = sizeof(theTemplate) / sizeof(theTemplate[0]);
int template_count = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_ATTRIBUTE *attrs = theTemplate;
PK11_SETATTRS(attrs, CKA_CLASS, &class_type, sizeof(class_type));
@ -78,14 +76,15 @@ pk11_KeyExchange(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
if (privKeyHandle == CK_INVALID_HANDLE) {
PK11RSAGenParams rsaParams;
if (symKeyLength > 120) /* bytes */ {
/* we'd have to generate an RSA key pair > 1024 bits long,
if (symKeyLength > 53) /* bytes */ {
/* we'd have to generate an RSA key pair > 512 bits long,
** and that's too costly. Don't even try.
*/
PORT_SetError(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY);
goto rsa_failed;
}
rsaParams.keySizeInBits = 1024;
rsaParams.keySizeInBits =
(symKeyLength > 21 || symKeyLength == 0) ? 512 : 256;
rsaParams.pe = 0x10001;
privKey = PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN,
&rsaParams, &pubKey, PR_FALSE, PR_TRUE, symKey->cx);

View file

@ -32,8 +32,8 @@ SECMOD_DestroyListLock(SECMODListLock *lock)
}
/*
* Lock the list for reading.
* Note: this uses a non-reentrant lock. Writers are given preference.
* Lock the List for Read: NOTE: this assumes the reading isn't so common
* the writing will be starved.
*/
void
SECMOD_GetReadLock(SECMODListLock *modLock)

View file

@ -6,7 +6,6 @@
* various PCKS #11 modules
*/
#define FORCE_PR_LOG 1
#include "base.h"
#include "seccomon.h"
#include "pkcs11.h"
#include "secmod.h"
@ -17,7 +16,7 @@
#include "nssilock.h"
#include "secerr.h"
#include "prenv.h"
#include "utilpars.h"
#include "utilparst.h"
#include "prio.h"
#include "prprf.h"
#include <stdio.h>
@ -276,8 +275,8 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
}
if (crv != CKR_OK) {
if (!mod->isThreadSafe ||
crv == CKR_NSS_CERTDB_FAILED ||
crv == CKR_NSS_KEYDB_FAILED) {
crv == CKR_NETSCAPE_CERTDB_FAILED ||
crv == CKR_NETSCAPE_KEYDB_FAILED) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
@ -356,7 +355,7 @@ SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod)
#ifndef NSS_STATIC_SOFTOKEN
static const char *my_shlib_name =
SHLIB_PREFIX "nss" NSS_SHLIB_VERSION "." SHLIB_SUFFIX;
SHLIB_PREFIX "nss" SHLIB_VERSION "." SHLIB_SUFFIX;
static const char *softoken_shlib_name =
SHLIB_PREFIX "softokn" SOFTOKEN_SHLIB_VERSION "." SHLIB_SUFFIX;
static const PRCallOnceType pristineCallOnce;
@ -381,9 +380,7 @@ softoken_LoadDSO(void)
return PR_FAILURE;
}
#else
CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName,
CK_VERSION_PTR pVersion,
CK_INTERFACE_PTR_PTR *ppInterface, CK_FLAGS flags);
CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList);
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
#endif
@ -394,28 +391,20 @@ SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
PRLibrary *library = NULL;
CK_C_GetInterface ientry = NULL;
CK_C_GetFunctionList fentry = NULL;
CK_C_GetFunctionList entry = 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;
mod->fipsIndicator = NULL;
/* internal modules get loaded from their internal list */
if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_STATIC_SOFTOKEN
ientry = (CK_C_GetInterface)NSC_GetInterface;
entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
#else
/*
* Loads softoken as a dynamic library,
@ -428,22 +417,15 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
PR_ATOMIC_INCREMENT(&softokenLoadCount);
if (mod->isFIPS) {
nss_interface = "FC_GetInterface";
nss_function = "FC_GetFunctionList";
entry = (CK_C_GetFunctionList)
PR_FindSymbol(softokenLib, "FC_GetFunctionList");
} else {
nss_interface = "NSC_GetInterface";
nss_function = "NSC_GetFunctionList";
entry = (CK_C_GetFunctionList)
PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
}
ientry = (CK_C_GetInterface)
PR_FindSymbol(softokenLib, nss_interface);
if (!ientry) {
fentry = (CK_C_GetFunctionList)
PR_FindSymbol(softokenLib, nss_function);
if (!fentry) {
return SECFailure;
}
}
if (!entry)
return SECFailure;
#endif
if (mod->isModuleDB) {
@ -465,27 +447,10 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
return SECFailure;
}
/* load the library. If this succeeds, then we have to remember to
/* load the library. If this succeeds, then we have to remember to
* unload the library if anything goes wrong from here on out...
*/
#if defined(_WIN32)
if (nssUTF8_Length(mod->dllName, NULL)) {
wchar_t *dllNameWide = _NSSUTIL_UTF8ToWide(mod->dllName);
if (dllNameWide) {
PRLibSpec libSpec;
libSpec.type = PR_LibSpec_PathnameU;
libSpec.value.pathname_u = dllNameWide;
library = PR_LoadLibraryWithFlags(libSpec, 0);
PORT_Free(dllNameWide);
}
}
if (library == NULL) {
// fallback to system code page
library = PR_LoadLibrary(mod->dllName);
}
#else
library = PR_LoadLibrary(mod->dllName);
#endif // defined(_WIN32)
mod->library = (void *)library;
if (library == NULL) {
@ -496,12 +461,8 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
* now we need to get the entry point to find the function pointers
*/
if (!mod->moduleDBOnly) {
ientry = (CK_C_GetInterface)
PR_FindSymbol(library, "C_GetInterface");
if (!ientry) {
fentry = (CK_C_GetFunctionList)
PR_FindSymbol(library, "C_GetFunctionList");
}
entry = (CK_C_GetFunctionList)
PR_FindSymbol(library, "C_GetFunctionList");
}
if (mod->isModuleDB) {
mod->moduleDBFunc = (void *)
@ -509,7 +470,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
}
if (mod->moduleDBFunc == NULL)
mod->isModuleDB = PR_FALSE;
if ((ientry == NULL) && (fentry == NULL)) {
if (entry == NULL) {
if (mod->isModuleDB) {
mod->loaded = PR_TRUE;
mod->moduleDBOnly = PR_TRUE;
@ -523,40 +484,18 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/*
* We need to get the function list
*/
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;
/* if we have a fips indicator, grab it */
if ((*ientry)((CK_UTF8CHAR_PTR) "Vendor NSS FIPS Interface", NULL,
&interface, 0) == CKR_OK) {
mod->fipsIndicator = ((CK_NSS_FIPS_FUNCTIONS *)(interface->pFunctionList))->NSC_NSSGetFIPSStatus;
}
} else {
if ((*fentry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
goto fail;
mod->flags = 0;
}
if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
goto fail;
#ifdef DEBUG_MODULE
modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
mod->functionList = (void *)nss_InsertDeviceLog(
(CK_FUNCTION_LIST_3_0_PTR)mod->functionList);
(CK_FUNCTION_LIST_PTR)mod->functionList);
}
#endif
/* This test operation makes sure our locking system is
* consistent even if we are using non-thread safe tokens by
* simulating unsafe tokens with safe ones. */
mod->isThreadSafe = !PR_GetEnvSecure("NSS_FORCE_TOKEN_LOCK");
mod->isThreadSafe = PR_TRUE;
/* Now we initialize the module */
rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
@ -574,10 +513,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.major == 2) && (info.cryptokiVersion.minor < 1)) {
if (info.cryptokiVersion.minor < 1) {
if (!loadSingleThreadedModules) {
PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
goto fail2;

View file

@ -32,8 +32,9 @@ typedef struct {
int iv;
} pk11MechanismData;
static pk11MechanismData pk11_default = { CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET,
CKM_FAKE_RANDOM, CKM_FAKE_RANDOM, 8, 8 };
static pk11MechanismData pk11_default =
{ CKM_GENERIC_SECRET_KEY_GEN, CKK_GENERIC_SECRET,
CKM_FAKE_RANDOM, CKM_FAKE_RANDOM, 8, 8 };
static pk11MechanismData *pk11_MechanismTable = NULL;
static int pk11_MechTableSize = 0;
static int pk11_MechEntrySize = 0;
@ -156,8 +157,6 @@ PK11_GetKeyMechanism(CK_KEY_TYPE type)
return CKM_CAMELLIA_CBC;
case CKK_NSS_CHACHA20:
return CKM_NSS_CHACHA20_POLY1305;
case CKK_CHACHA20:
return CKM_CHACHA20_POLY1305;
case CKK_AES:
return CKM_AES_CBC;
case CKK_DES:
@ -198,8 +197,6 @@ PK11_GetKeyMechanism(CK_KEY_TYPE type)
return CKM_KEA_KEY_DERIVE;
case CKK_EC: /* CKK_ECDSA is deprecated */
return CKM_ECDSA;
case CKK_HKDF:
return CKM_HKDF_DERIVE;
case CKK_GENERIC_SECRET:
default:
return CKM_SHA_1_HMAC;
@ -231,10 +228,6 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
case CKM_NSS_CHACHA20_KEY_GEN:
case CKM_NSS_CHACHA20_CTR:
return CKK_NSS_CHACHA20;
case CKM_CHACHA20_POLY1305:
case CKM_CHACHA20_KEY_GEN:
case CKM_CHACHA20:
return CKK_CHACHA20;
case CKM_AES_ECB:
case CKM_AES_CBC:
case CKM_AES_CCM:
@ -247,10 +240,8 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
case CKM_AES_CMAC_GENERAL:
case CKM_AES_CBC_PAD:
case CKM_AES_KEY_GEN:
case CKM_NSS_AES_KEY_WRAP:
case CKM_NSS_AES_KEY_WRAP_PAD:
case CKM_AES_KEY_WRAP:
case CKM_AES_KEY_WRAP_KWP:
case CKM_NETSCAPE_AES_KEY_WRAP:
case CKM_NETSCAPE_AES_KEY_WRAP_PAD:
case CKM_AES_XCBC_MAC:
case CKM_AES_XCBC_MAC_96:
return CKK_AES;
@ -388,10 +379,6 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, unsigned long len)
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return CKK_EC; /* CKK_ECDSA is deprecated */
case CKM_HKDF_KEY_GEN:
case CKM_HKDF_DERIVE:
case CKM_HKDF_DATA:
return CKK_HKDF;
case CKM_SSL3_PRE_MASTER_KEY_GEN:
case CKM_GENERIC_SECRET_KEY_GEN:
case CKM_SSL3_MASTER_KEY_DERIVE:
@ -460,9 +447,6 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_NSS_CHACHA20_POLY1305:
case CKM_NSS_CHACHA20_CTR:
return CKM_NSS_CHACHA20_KEY_GEN;
case CKM_CHACHA20_POLY1305:
case CKM_CHACHA20:
return CKM_CHACHA20_KEY_GEN;
case CKM_AES_ECB:
case CKM_AES_CBC:
case CKM_AES_CCM:
@ -633,20 +617,20 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_PBA_SHA1_WITH_SHA1_HMAC:
case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN:
case CKM_NSS_PBE_MD5_HMAC_KEY_GEN:
case CKM_NSS_PBE_MD2_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN:
case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN:
case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN:
case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN:
case CKM_NSS_PBE_SHA1_DES_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC4:
case CKM_NSS_PBE_SHA1_128_BIT_RC4:
case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_PBE_SHA1_RC2_40_CBC:
case CKM_PBE_SHA1_RC2_128_CBC:
case CKM_PBE_SHA1_RC4_40:
@ -709,11 +693,11 @@ PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
case CKM_CAST5_CBC_PAD:
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_NSS_PBE_SHA1_DES_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_PBE_SHA1_RC2_40_CBC:
case CKM_PBE_SHA1_RC2_128_CBC:
case CKM_PBE_SHA1_DES3_EDE_CBC:
@ -744,8 +728,8 @@ PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
case CKM_BATON_ECB96:
return 12;
case CKM_RC4:
case CKM_NSS_PBE_SHA1_40_BIT_RC4:
case CKM_NSS_PBE_SHA1_128_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
case CKM_PBE_SHA1_RC4_40:
case CKM_PBE_SHA1_RC4_128:
return 0;
@ -756,8 +740,6 @@ PK11_GetBlockSize(CK_MECHANISM_TYPE type, SECItem *params)
return -1; /* failure */
case CKM_NSS_CHACHA20_POLY1305:
case CKM_NSS_CHACHA20_CTR:
case CKM_CHACHA20_POLY1305:
case CKM_CHACHA20:
return 64;
default:
return pk11_lookup(type)->blockSize;
@ -796,11 +778,11 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type)
case CKM_IDEA_CBC:
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_NSS_PBE_SHA1_DES_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_PBE_SHA1_RC2_40_CBC:
case CKM_PBE_SHA1_RC2_128_CBC:
case CKM_PBE_SHA1_DES3_EDE_CBC:
@ -820,7 +802,6 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type)
return 8;
case CKM_AES_GCM:
case CKM_NSS_CHACHA20_POLY1305:
case CKM_CHACHA20_POLY1305:
return 12;
case CKM_SEED_CBC:
case CKM_SEED_CBC_PAD:
@ -829,7 +810,6 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type)
case CKM_AES_CBC:
case CKM_AES_CBC_PAD:
case CKM_NSS_CHACHA20_CTR:
case CKM_CHACHA20:
return 16;
case CKM_SKIPJACK_CBC64:
case CKM_SKIPJACK_ECB64:
@ -852,8 +832,8 @@ PK11_GetIVLength(CK_MECHANISM_TYPE type)
case CKM_RSA_PKCS:
case CKM_RSA_9796:
case CKM_RSA_X_509:
case CKM_NSS_PBE_SHA1_40_BIT_RC4:
case CKM_NSS_PBE_SHA1_128_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
case CKM_PBE_SHA1_RC4_40:
case CKM_PBE_SHA1_RC4_128:
return 0;
@ -1307,13 +1287,13 @@ PK11_ParamFromAlgid(SECAlgorithmID *algid)
break;
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_NSS_PBE_SHA1_DES_CBC:
case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC4:
case CKM_NSS_PBE_SHA1_128_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
case CKM_PBE_SHA1_DES2_EDE_CBC:
case CKM_PBE_SHA1_DES3_EDE_CBC:
case CKM_PBE_SHA1_RC2_40_CBC:
@ -1663,13 +1643,13 @@ PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
break;
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_NSS_PBE_SHA1_DES_CBC:
case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NSS_PBE_SHA1_40_BIT_RC4:
case CKM_NSS_PBE_SHA1_128_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
case CKM_PBE_SHA1_DES3_EDE_CBC:
case CKM_PBE_SHA1_DES2_EDE_CBC:
case CKM_PBE_SHA1_RC2_40_CBC:
@ -1860,11 +1840,11 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
switch (pPBEMechanism->mechanism) {
case CKM_PBE_MD2_DES_CBC:
case CKM_PBE_MD5_DES_CBC:
case CKM_NSS_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
pCryptoMechanism->mechanism = CKM_DES_CBC;
goto have_crypto_mechanism;
case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
case CKM_PBE_SHA1_DES3_EDE_CBC:
case CKM_PBE_SHA1_DES2_EDE_CBC:
pCryptoMechanism->mechanism = CKM_DES3_CBC;
@ -1878,19 +1858,19 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
(unsigned char *)(pPBEparams->pInitVector),
iv_len);
break;
case CKM_NSS_PBE_SHA1_40_BIT_RC4:
case CKM_NSS_PBE_SHA1_128_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
case CKM_PBE_SHA1_RC4_40:
case CKM_PBE_SHA1_RC4_128:
pCryptoMechanism->mechanism = CKM_RC4;
pCryptoMechanism->ulParameterLen = 0;
pCryptoMechanism->pParameter = CK_NULL_PTR;
break;
case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_PBE_SHA1_RC2_40_CBC:
rc2_key_len = 40;
goto have_key_len;
case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
rc2_key_len = 128;
have_key_len:
pCryptoMechanism->mechanism = CKM_RC2_CBC;

View file

@ -36,7 +36,7 @@ pk11_setAttributes(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_SESSION_HANDLE rwsession;
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
@ -93,7 +93,7 @@ pk11_copyAttributes(PLArenaPool *arena,
}
if (targetID == CK_INVALID_HANDLE) {
/* we need to create the object */
rv = PK11_CreateNewObject(targetSlot, CK_INVALID_HANDLE,
rv = PK11_CreateNewObject(targetSlot, CK_INVALID_SESSION,
copyTemplate, copyTemplateCount, PR_TRUE, &targetID);
} else {
/* update the existing object with the new attributes */
@ -464,7 +464,7 @@ pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
{ CKA_ID, NULL, 0 },
{ CKA_CLASS, NULL, 0 }
};
const CK_ULONG symTemplateCount = sizeof(symTemplate) / sizeof(symTemplate[0]);
CK_ULONG symTemplateCount = sizeof(symTemplate) / sizeof(symTemplate[0]);
CK_ATTRIBUTE symCopyTemplate[] = {
{ CKA_LABEL, NULL, 0 }
};

View file

@ -6,8 +6,6 @@
* etc).
*/
#include <stddef.h>
#include "secport.h"
#include "seccomon.h"
#include "secmod.h"
@ -63,7 +61,7 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
{ CKA_CERT_SHA1_HASH, NULL, 0 },
};
CK_OBJECT_CLASS tobjc = CKO_NSS_TRUST;
CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
CK_OBJECT_HANDLE tobjID;
unsigned char sha1_hash[SHA1_LENGTH];
@ -150,8 +148,8 @@ pk11_CollectCrls(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
CERTCrlNode *new_node = NULL;
CK_ATTRIBUTE fetchCrl[3] = {
{ CKA_VALUE, NULL, 0 },
{ CKA_NSS_KRL, NULL, 0 },
{ CKA_NSS_URL, NULL, 0 },
{ CKA_NETSCAPE_KRL, NULL, 0 },
{ CKA_NETSCAPE_URL, NULL, 0 },
};
const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
CK_RV crv;
@ -221,7 +219,7 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx)
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate[2];
CK_ATTRIBUTE *attrs;
CK_OBJECT_CLASS certClass = CKO_NSS_CRL;
CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
CK_BBOOL isKrl = CK_FALSE;
attrs = theTemplate;
@ -229,7 +227,7 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx)
attrs++;
if (type != -1) {
isKrl = (CK_BBOOL)(type == SEC_KRL_TYPE);
PK11_SETATTRS(attrs, CKA_NSS_KRL, &isKrl, sizeof(isKrl));
PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl));
attrs++;
}
@ -258,8 +256,8 @@ pk11_RetrieveCrlsCallback(PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID,
CERTCrlNode *new_node = NULL;
CK_ATTRIBUTE fetchCrl[3] = {
{ CKA_VALUE, NULL, 0 },
{ CKA_NSS_KRL, NULL, 0 },
{ CKA_NSS_URL, NULL, 0 },
{ CKA_NETSCAPE_KRL, NULL, 0 },
{ CKA_NETSCAPE_URL, NULL, 0 },
};
const int fetchCrlSize = sizeof(fetchCrl) / sizeof(fetchCrl[2]);
CK_RV crv;
@ -362,7 +360,7 @@ pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem *issuer,
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate[2];
CK_ATTRIBUTE *attrs;
CK_OBJECT_CLASS crlClass = CKO_NSS_CRL;
CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
crlOptions options;
attrs = theTemplate;
@ -557,18 +555,18 @@ SECItem *
PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
SECItem *name, SECItem **profileTime)
{
CK_OBJECT_CLASS smimeClass = CKO_NSS_SMIME;
CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_SUBJECT, NULL, 0 },
{ CKA_CLASS, NULL, 0 },
{ CKA_NSS_EMAIL, NULL, 0 },
{ CKA_NETSCAPE_EMAIL, NULL, 0 },
};
CK_ATTRIBUTE smimeData[] = {
{ CKA_SUBJECT, NULL, 0 },
{ CKA_VALUE, NULL, 0 },
};
/* if you change the array, change the variable below as well */
const size_t tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
CK_ATTRIBUTE *attrs = theTemplate;
CK_RV crv;
@ -583,7 +581,7 @@ PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
attrs++;
PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass));
attrs++;
PK11_SETATTRS(attrs, CKA_NSS_EMAIL, emailAddr, strlen(emailAddr));
PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr));
attrs++;
if (*slot) {
@ -613,7 +611,7 @@ PK11_FindSMimeProfile(PK11SlotInfo **slot, char *emailAddr,
}
if (profileTime) {
PK11_SETATTRS(smimeData, CKA_NSS_SMIME_TIMESTAMP, NULL, 0);
PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
}
crv = PK11_GetAttributes(NULL, *slot, smimeh, smimeData, 2);
@ -666,14 +664,14 @@ SECStatus
PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
SECItem *emailProfile, SECItem *profileTime)
{
CK_OBJECT_CLASS smimeClass = CKO_NSS_SMIME;
CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
CK_BBOOL ck_true = CK_TRUE;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_CLASS, NULL, 0 },
{ CKA_TOKEN, NULL, 0 },
{ CKA_SUBJECT, NULL, 0 },
{ CKA_NSS_EMAIL, NULL, 0 },
{ CKA_NSS_SMIME_TIMESTAMP, NULL, 0 },
{ CKA_NETSCAPE_EMAIL, NULL, 0 },
{ CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
{ CKA_VALUE, NULL, 0 }
};
/* if you change the array, change the variable below as well */
@ -693,11 +691,11 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
attrs++;
PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len);
attrs++;
PK11_SETATTRS(attrs, CKA_NSS_EMAIL,
PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL,
emailAddr, PORT_Strlen(emailAddr) + 1);
attrs++;
if (profileTime) {
PK11_SETATTRS(attrs, CKA_NSS_SMIME_TIMESTAMP, profileTime->data,
PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
profileTime->len);
attrs++;
PK11_SETATTRS(attrs, CKA_VALUE, emailProfile->data,
@ -713,7 +711,7 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj,
}
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_READ_ONLY);
if (free_slot) {
PK11_FreeSlot(free_slot);

View file

@ -5,7 +5,6 @@
* This file manages object type indepentent functions.
*/
#include <limits.h>
#include <stddef.h>
#include "seccomon.h"
#include "secmod.h"
@ -71,7 +70,7 @@ PK11_DestroyTokenObject(PK11SlotInfo *slot, CK_OBJECT_HANDLE object)
CK_SESSION_HANDLE rwsession;
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
@ -204,7 +203,7 @@ PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot,
/* make pedantic happy... note that it's only used arena != NULL */
void *mark = NULL;
CK_RV crv;
if (slot->session == CK_INVALID_HANDLE)
if (slot->session == CK_INVALID_SESSION)
return CKR_SESSION_HANDLE_INVALID;
/*
@ -318,7 +317,7 @@ PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
PK11_SETATTRS(&setTemplate, CKA_LABEL, (CK_CHAR *)nickname, len);
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
@ -395,12 +394,12 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
rwsession = session;
if (token) {
rwsession = PK11_GetRWSession(slot);
} else if (rwsession == CK_INVALID_HANDLE) {
} else if (rwsession == CK_INVALID_SESSION) {
rwsession = slot->session;
if (rwsession != CK_INVALID_HANDLE)
if (rwsession != CK_INVALID_SESSION)
PK11_EnterSlotMonitor(slot);
}
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
@ -413,7 +412,7 @@ PK11_CreateNewObject(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
}
if (token) {
PK11_RestoreROSession(slot, rwsession);
} else if (session == CK_INVALID_HANDLE) {
} else if (session == CK_INVALID_SESSION) {
PK11_ExitSlotMonitor(slot);
}
@ -841,11 +840,11 @@ PK11_SignWithMechanism(SECKEYPrivateKey *key, CK_MECHANISM_TYPE mechanism,
if (haslock)
PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner);
sig->len = len;
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
sig->len = len;
return SECSuccess;
}
@ -889,11 +888,11 @@ PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
if (haslock)
PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner);
sig->len = len;
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
sig->len = len;
return SECSuccess;
}
@ -1244,7 +1243,7 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
}
if (PK11_IsInternal(slot)) {
PK11_SETATTRS(attrs, CKA_NSS_DB, idValue->data,
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, idValue->data,
idValue->len);
attrs++;
}
@ -1276,13 +1275,13 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
rwsession = PK11_GetRWSession(slot);
} else {
rwsession = slot->session;
if (rwsession != CK_INVALID_HANDLE)
if (rwsession != CK_INVALID_SESSION)
PK11_EnterSlotMonitor(slot);
}
/* This is a lot a work to deal with fussy PKCS #11 modules
* that can't bother to return BAD_DATA when presented with an
* invalid session! */
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
goto loser;
}
@ -1693,12 +1692,18 @@ PK11_CreateManagedGenericObject(PK11SlotInfo *slot,
!token);
}
CK_OBJECT_HANDLE
PK11_GetObjectHandle(PK11ObjectType objType, void *objSpec,
PK11SlotInfo **slotp)
/*
* Change an attribute on a raw object
*/
SECStatus
PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
CK_ATTRIBUTE_TYPE attrType, SECItem *item)
{
CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE;
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
CK_ATTRIBUTE setTemplate;
CK_RV crv;
CK_SESSION_HANDLE rwsession;
switch (objType) {
case PK11_TypeGeneric:
@ -1722,42 +1727,16 @@ PK11_GetObjectHandle(PK11ObjectType objType, void *objSpec,
&slot);
break;
default:
PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
break;
}
if (slotp) {
*slotp = slot;
}
/* paranoia. If the object doesn't have a slot, then it's handle isn't
* valid either */
if (slot == NULL) {
handle = CK_INVALID_HANDLE;
}
return handle;
}
/*
* Change an attribute on a raw object
*/
SECStatus
PK11_WriteRawAttribute(PK11ObjectType objType, void *objSpec,
CK_ATTRIBUTE_TYPE attrType, SECItem *item)
{
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
CK_ATTRIBUTE setTemplate;
CK_RV crv;
CK_SESSION_HANDLE rwsession;
handle = PK11_GetObjectHandle(objType, objSpec, &slot);
if (handle == CK_INVALID_HANDLE) {
PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
return SECFailure;
}
PK11_SETATTRS(&setTemplate, attrType, (CK_CHAR *)item->data, item->len);
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
@ -1778,8 +1757,28 @@ PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
handle = PK11_GetObjectHandle(objType, objSpec, &slot);
if (handle == CK_INVALID_HANDLE) {
switch (objType) {
case PK11_TypeGeneric:
slot = ((PK11GenericObject *)objSpec)->slot;
handle = ((PK11GenericObject *)objSpec)->objectID;
break;
case PK11_TypePrivKey:
slot = ((SECKEYPrivateKey *)objSpec)->pkcs11Slot;
handle = ((SECKEYPrivateKey *)objSpec)->pkcs11ID;
break;
case PK11_TypePubKey:
slot = ((SECKEYPublicKey *)objSpec)->pkcs11Slot;
handle = ((SECKEYPublicKey *)objSpec)->pkcs11ID;
break;
case PK11_TypeSymKey:
slot = ((PK11SymKey *)objSpec)->slot;
handle = ((PK11SymKey *)objSpec)->objectID;
break;
case PK11_TypeCert: /* don't handle cert case for now */
default:
break;
}
if (slot == NULL) {
PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
return SECFailure;
}
@ -1787,31 +1786,11 @@ PK11_ReadRawAttribute(PK11ObjectType objType, void *objSpec,
return PK11_ReadAttribute(slot, handle, attrType, NULL, item);
}
SECStatus
PK11_ReadRawAttributes(PLArenaPool *arena, PK11ObjectType objType, void *objSpec,
CK_ATTRIBUTE *pTemplate, unsigned int count)
{
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
handle = PK11_GetObjectHandle(objType, objSpec, &slot);
if (handle == CK_INVALID_HANDLE) {
PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
return SECFailure;
}
CK_RV crv = PK11_GetAttributes(arena, slot, handle, pTemplate, count);
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
return SECSuccess;
}
/*
* return the object handle that matches the template
*/
CK_OBJECT_HANDLE
pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, size_t tsize)
pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, int tsize)
{
CK_OBJECT_HANDLE object;
CK_RV crv = CKR_SESSION_HANDLE_INVALID;
@ -1821,7 +1800,7 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, size_t
* issue the find
*/
PK11_EnterSlotMonitor(slot);
if (slot->session != CK_INVALID_HANDLE) {
if (slot->session != CK_INVALID_SESSION) {
crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
theTemplate, tsize);
}
@ -1850,7 +1829,7 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *theTemplate, size_t
*/
CK_OBJECT_HANDLE *
pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
size_t templCount, int *object_count)
int templCount, int *object_count)
{
CK_OBJECT_HANDLE *objID = NULL;
CK_ULONG returned_count = 0;
@ -1864,7 +1843,7 @@ pk11_FindObjectsByTemplate(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
if (haslock) {
PK11_EnterSlotMonitor(slot);
}
if (session != CK_INVALID_HANDLE) {
if (session != CK_INVALID_SESSION) {
crv = PK11_GETTAB(slot)->C_FindObjectsInit(session,
findTemplate, templCount);
}
@ -1945,7 +1924,7 @@ PK11_FindRawCertsWithSubject(PK11SlotInfo *slot, SECItem *derSubject,
{ CKA_CLASS, &cko_certificate, sizeof(cko_certificate) },
{ CKA_SUBJECT, derSubject->data, derSubject->len },
};
const size_t templateCount = sizeof(subjectTemplate) / sizeof(subjectTemplate[0]);
int templateCount = sizeof(subjectTemplate) / sizeof(subjectTemplate[0]);
int handleCount = 0;
CK_OBJECT_HANDLE *handles =
pk11_FindObjectsByTemplate(slot, subjectTemplate, templateCount,
@ -2025,7 +2004,7 @@ PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
};
/* if you change the array, change the variable below as well */
CK_ATTRIBUTE *keyclass = &theTemplate[1];
const size_t tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
int tsize = sizeof(theTemplate) / sizeof(theTemplate[0]);
/* if you change the array, change the variable below as well */
CK_OBJECT_HANDLE peerID;
PORTCheapArenaPool tmpArena;
@ -2074,7 +2053,7 @@ PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
CK_RV crv = CKR_SESSION_HANDLE_INVALID;
PK11_EnterSlotMonitor(slot);
if (slot->session != CK_INVALID_HANDLE) {
if (slot->session != CK_INVALID_SESSION) {
crv = PK11_GETTAB(slot)->C_FindObjectsInit(slot->session,
findTemplate, templCount);
}
@ -2179,7 +2158,7 @@ PK11_FindObjectsFromNickname(char *nickname, PK11SlotInfo **slotptr,
{ CKA_LABEL, NULL, 0 },
{ CKA_CLASS, NULL, 0 },
};
const size_t findCount = sizeof(findTemplate) / sizeof(findTemplate[0]);
int findCount = sizeof(findTemplate) / sizeof(findTemplate[0]);
SECStatus rv;
PK11_SETATTRS(&findTemplate[1], CKA_CLASS, &objclass, sizeof(objclass));
@ -2268,18 +2247,3 @@ pk11_GetLowLevelKeyFromHandle(PK11SlotInfo *slot, CK_OBJECT_HANDLE handle)
return item;
}
PRBool
PK11_ObjectGetFIPSStatus(PK11ObjectType objType, void *objSpec)
{
PK11SlotInfo *slot = NULL;
CK_OBJECT_HANDLE handle = 0;
handle = PK11_GetObjectHandle(objType, objSpec, &slot);
if (handle == CK_INVALID_HANDLE) {
PORT_SetError(SEC_ERROR_UNKNOWN_OBJECT_TYPE);
return PR_FALSE;
}
return pk11slot_GetFIPSStatus(slot, slot->session, handle,
CKT_NSS_OBJECT_CHECK);
}

View file

@ -127,10 +127,6 @@ secmod_NewModule(void)
*the other flags are set */
#define SECMOD_FLAG_INTERNAL_KEY_SLOT 0x02
/* private flags for policy check. */
#define SECMOD_FLAG_POLICY_CHECK_IDENTIFIER 0x01
#define SECMOD_FLAG_POLICY_CHECK_VALUE 0x02
/*
* for 3.4 we continue to use the old SECMODModule structure
*/
@ -162,17 +158,16 @@ SECMOD_CreateModule(const char *library, const char *moduleName,
* Disallow values are parsed first, then allow values, independent of the
* order they appear.
*
* flags: turn on the following flags:
* policy-lock: turn off the ability for applications to change policy with
* the call NSS_SetAlgorithmPolicy or the other system policy
* calls (SSL_SetPolicy, etc.)
* ssl-lock: turn off the ability to change the ssl defaults.
*
* The following only apply to ssl cipher suites (future smime)
*
* Future key words (not yet implemented):
* enable: turn on ciphersuites by default.
* disable: turn off ciphersuites by default without disallowing them by policy.
*
* flags: turn on the following flags:
* ssl-lock: turn off the ability for applications to change policy with
* the SSL_SetCipherPolicy (or SSL_SetPolicy).
* policy-lock: turn off the ability for applications to change policy with
* the call NSS_SetAlgorithmPolicy.
* ssl-default-lock: turn off the ability for applications to change cipher
* suite states with SSL_EnableCipher, SSL_DisableCipher.
*
*/
@ -328,21 +323,21 @@ static const oidValDef curveOptList[] = {
static const oidValDef hashOptList[] = {
/* Hashes */
{ CIPHER_NAME("MD2"), SEC_OID_MD2,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("MD4"), SEC_OID_MD4,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("MD5"), SEC_OID_MD5,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("SHA1"), SEC_OID_SHA1,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("SHA224"), SEC_OID_SHA224,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("SHA256"), SEC_OID_SHA256,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("SHA384"), SEC_OID_SHA384,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("SHA512"), SEC_OID_SHA512,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE }
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
};
static const oidValDef macOptList[] = {
@ -394,13 +389,7 @@ static const oidValDef kxOptList[] = {
static const oidValDef signOptList[] = {
/* Signatures */
{ CIPHER_NAME("DSA"), SEC_OID_ANSIX9_DSA_SIGNATURE,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
{ CIPHER_NAME("RSA-PKCS"), SEC_OID_PKCS1_RSA_ENCRYPTION,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
{ CIPHER_NAME("RSA-PSS"), SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
{ CIPHER_NAME("ECDSA"), SEC_OID_ANSIX962_EC_PUBLIC_KEY,
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_SIGNATURE },
NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
};
typedef struct {
@ -416,7 +405,7 @@ static const algListsDef algOptLists[] = {
{ macOptList, PR_ARRAY_SIZE(macOptList), "MAC", PR_FALSE },
{ cipherOptList, PR_ARRAY_SIZE(cipherOptList), "CIPHER", PR_FALSE },
{ kxOptList, PR_ARRAY_SIZE(kxOptList), "OTHER-KX", PR_FALSE },
{ signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_FALSE },
{ signOptList, PR_ARRAY_SIZE(signOptList), "OTHER-SIGN", PR_TRUE },
};
static const optionFreeDef sslOptList[] = {
@ -434,21 +423,12 @@ static const optionFreeDef sslOptList[] = {
{ CIPHER_NAME("DTLS1.3"), 0x304 },
};
static const optionFreeDef keySizeFlagsList[] = {
{ CIPHER_NAME("KEY-SIZE-SSL"), NSS_KEY_SIZE_POLICY_SSL_FLAG },
{ CIPHER_NAME("KEY-SIZE-SIGN"), NSS_KEY_SIZE_POLICY_SIGN_FLAG },
{ CIPHER_NAME("KEY-SIZE-VERIFY"), NSS_KEY_SIZE_POLICY_VERIFY_FLAG },
};
static const optionFreeDef freeOptList[] = {
/* Restrictions for asymetric keys */
{ CIPHER_NAME("RSA-MIN"), NSS_RSA_MIN_KEY_SIZE },
{ CIPHER_NAME("DH-MIN"), NSS_DH_MIN_KEY_SIZE },
{ CIPHER_NAME("DSA-MIN"), NSS_DSA_MIN_KEY_SIZE },
{ CIPHER_NAME("ECC-MIN"), NSS_ECC_MIN_KEY_SIZE },
/* what operations doe the key size apply to */
{ CIPHER_NAME("KEY-SIZE-FLAGS"), NSS_KEY_SIZE_POLICY_FLAGS },
/* constraints on SSL Protocols */
{ CIPHER_NAME("TLS-VERSION-MIN"), NSS_TLS_VERSION_MIN_POLICY },
{ CIPHER_NAME("TLS-VERSION-MAX"), NSS_TLS_VERSION_MAX_POLICY },
@ -463,19 +443,10 @@ static const policyFlagDef policyFlagList[] = {
/* add other key exhanges in the future */
{ CIPHER_NAME("KEY-EXCHANGE"), NSS_USE_ALG_IN_SSL_KX },
{ CIPHER_NAME("CERT-SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("CMS-SIGNATURE"), NSS_USE_ALG_IN_CMS_SIGNATURE },
{ CIPHER_NAME("ALL-SIGNATURE"), NSS_USE_ALG_IN_SIGNATURE },
/* sign turns off all signatures, but doesn't change the
* allowance for specific sigantures... for example:
* disallow=sha256/all allow=sha256/signature doesn't allow
* cert-sigantures, where disallow=sha256/all allow=sha256/all-signature
* does.
* however, disallow=sha356/signature and disallow=sha256/all-siganture are
* equivalent in effect */
{ CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_ANY_SIGNATURE },
/* enable/disable everything */
{ CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX |
NSS_USE_ALG_IN_SIGNATURE },
/* add other signatures in the future */
{ CIPHER_NAME("SIGNATURE"), NSS_USE_ALG_IN_CERT_SIGNATURE },
/* enable everything */
{ CIPHER_NAME("ALL"), NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX | NSS_USE_ALG_IN_CERT_SIGNATURE },
{ CIPHER_NAME("NONE"), 0 }
};
@ -509,7 +480,7 @@ secmod_ArgGetSubValue(const char *cipher, char sep1, char sep2,
static PRUint32
secmod_parsePolicyValue(const char *policyFlags, int policyLength,
PRBool printPolicyFeedback, PRUint32 policyCheckFlags)
PRBool printPolicyFeedback)
{
const char *flag, *currentString;
PRUint32 flags = 0;
@ -534,8 +505,7 @@ secmod_parsePolicyValue(const char *policyFlags, int policyLength,
break;
}
}
if (unknown && printPolicyFeedback &&
(policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE)) {
if (unknown && printPolicyFeedback) {
PR_SetEnv("NSS_POLICY_FAIL=1");
fprintf(stderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
policyLength, policyFlags, length, flag);
@ -557,7 +527,6 @@ secmod_getPolicyOptValue(const char *policyValue, int policyValueLength,
*result = val;
return SECSuccess;
}
/* handle any ssl strings */
for (i = 0; i < PR_ARRAY_SIZE(sslOptList); i++) {
if (policyValueLength == sslOptList[i].name_size &&
PORT_Strncasecmp(sslOptList[i].name, policyValue,
@ -566,108 +535,12 @@ secmod_getPolicyOptValue(const char *policyValue, int policyValueLength,
return SECSuccess;
}
}
/* handle key_size flags. Each flag represents a bit, which
* gets or'd together. They can be separated by , | or + */
val = 0;
while (*policyValue) {
PRBool found = PR_FALSE;
for (i = 0; i < PR_ARRAY_SIZE(keySizeFlagsList); i++) {
if (PORT_Strncasecmp(keySizeFlagsList[i].name, policyValue,
keySizeFlagsList[i].name_size) == 0) {
val |= keySizeFlagsList[i].option;
found = PR_TRUE;
policyValue += keySizeFlagsList[i].name_size;
break;
}
}
if (!found) {
return SECFailure;
}
if (*policyValue == ',' || *policyValue == '|' || *policyValue == '+') {
policyValue++;
}
}
*result = val;
return SECSuccess;
}
/* Policy operations:
* Disallow: operation is disallowed by policy. Implies disabled.
* Allow: operation is allowed by policy (but could be disabled).
* Disable: operation is turned off by default (but could be allowed).
* Enable: operation is enabled by default. Implies allowed.
*/
typedef enum {
NSS_DISALLOW,
NSS_ALLOW,
NSS_DISABLE,
NSS_ENABLE
} NSSPolicyOperation;
/* apply the operator specific policy */
SECStatus
secmod_setPolicyOperation(SECOidTag oid, NSSPolicyOperation operation,
PRUint32 value)
{
SECStatus rv = SECSuccess;
switch (operation) {
case NSS_DISALLOW:
/* clear the requested policy bits */
rv = NSS_SetAlgorithmPolicy(oid, 0, value);
break;
case NSS_ALLOW:
/* set the requested policy bits */
rv = NSS_SetAlgorithmPolicy(oid, value, 0);
break;
/* enable/disable only apply to SSL cipher suites (future S/MIME).
* Enable/disable is implemented by clearing the DEFAULT_NOT_VALID
* flag, then setting the NSS_USE_DEFAULT_SSL_ENABLE flag to the
* correct value. The ssl policy code will then sort out what to
* set based on ciphers and cipher suite values.*/
case NSS_DISABLE:
if (value & (NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX)) {
/* clear not valid and enable */
rv = NSS_SetAlgorithmPolicy(oid, 0,
NSS_USE_DEFAULT_NOT_VALID |
NSS_USE_DEFAULT_SSL_ENABLE);
}
break;
case NSS_ENABLE:
if (value & (NSS_USE_ALG_IN_SSL | NSS_USE_ALG_IN_SSL_KX)) {
/* set enable, clear not valid. NOTE: enable implies allow! */
rv = NSS_SetAlgorithmPolicy(oid, value | NSS_USE_DEFAULT_SSL_ENABLE,
NSS_USE_DEFAULT_NOT_VALID);
}
break;
default:
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
break;
}
return rv;
}
const char *
secmod_getOperationString(NSSPolicyOperation operation)
{
switch (operation) {
case NSS_DISALLOW:
return "disallow";
case NSS_ALLOW:
return "allow";
case NSS_DISABLE:
return "disable";
case NSS_ENABLE:
return "enable";
default:
break;
}
return "invalid";
return SECFailure;
}
static SECStatus
secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
PRBool printPolicyFeedback, PRUint32 policyCheckFlags)
secmod_applyCryptoPolicy(const char *policyString, PRBool allow,
PRBool printPolicyFeedback)
{
const char *cipher, *currentString;
unsigned i, j;
@ -695,15 +568,23 @@ secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
/* disable or enable all options by default */
PRUint32 value = 0;
if (newValue) {
value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1, printPolicyFeedback, policyCheckFlags);
value = secmod_parsePolicyValue(&cipher[3] + 1, length - 3 - 1, printPolicyFeedback);
}
for (i = 0; i < PR_ARRAY_SIZE(algOptLists); i++) {
const algListsDef *algOptList = &algOptLists[i];
for (j = 0; j < algOptList->entries; j++) {
PRUint32 enable, disable;
if (!newValue) {
value = algOptList->list[j].val;
}
secmod_setPolicyOperation(algOptList->list[j].oid, operation, value);
if (allow) {
enable = value;
disable = 0;
} else {
enable = 0;
disable = value;
}
NSS_SetAlgorithmPolicy(algOptList->list[j].oid, enable, disable);
}
}
continue;
@ -722,13 +603,20 @@ secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
if ((newOption || algOpt->name_size == length) &&
PORT_Strncasecmp(algOpt->name, cipher, name_size) == 0) {
PRUint32 value = algOpt->val;
PRUint32 enable, disable;
if (newOption) {
value = secmod_parsePolicyValue(&cipher[name_size] + 1,
length - name_size - 1,
printPolicyFeedback,
policyCheckFlags);
printPolicyFeedback);
}
rv = secmod_setPolicyOperation(algOptList->list[j].oid, operation, value);
if (allow) {
enable = value;
disable = 0;
} else {
enable = 0;
disable = value;
}
rv = NSS_SetAlgorithmPolicy(algOpt->oid, enable, disable);
if (rv != SECSuccess) {
/* could not enable option */
/* NSS_SetAlgorithPolicy should have set the error code */
@ -755,8 +643,7 @@ secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
rv = secmod_getPolicyOptValue(policyValue, policyValueLength,
&val);
if (rv != SECSuccess) {
if (printPolicyFeedback &&
(policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE)) {
if (printPolicyFeedback) {
PR_SetEnv("NSS_POLICY_FAIL=1");
fprintf(stderr, "NSS-POLICY-FAIL %.*s: unknown value: %.*s\n",
length, cipher, policyValueLength, policyValue);
@ -776,11 +663,10 @@ secmod_applyCryptoPolicy(const char *policyString, NSSPolicyOperation operation,
}
}
if (unknown && printPolicyFeedback &&
(policyCheckFlags & SECMOD_FLAG_POLICY_CHECK_IDENTIFIER)) {
if (unknown && printPolicyFeedback) {
PR_SetEnv("NSS_POLICY_FAIL=1");
fprintf(stderr, "NSS-POLICY-FAIL %s: unknown identifier: %.*s\n",
secmod_getOperationString(operation), length, cipher);
allow ? "allow" : "disallow", length, cipher);
}
}
return rv;
@ -823,8 +709,7 @@ secmod_sanityCheckCryptoPolicy(void)
anyEnabled = PR_TRUE;
fprintf(stderr, "NSS-POLICY-INFO: %s is enabled for SSL\n", algOpt->name);
}
if ((algOpt->val & NSS_USE_ALG_IN_CERT_SIGNATURE) &&
((value & NSS_USE_CERT_SIGNATURE_OK) == NSS_USE_CERT_SIGNATURE_OK)) {
if ((algOpt->val & NSS_USE_ALG_IN_CERT_SIGNATURE) && (value & NSS_USE_ALG_IN_CERT_SIGNATURE)) {
++num_sig_enabled;
anyEnabled = PR_TRUE;
fprintf(stderr, "NSS-POLICY-INFO: %s is enabled for CERT-SIGNATURE\n", algOpt->name);
@ -853,10 +738,9 @@ secmod_sanityCheckCryptoPolicy(void)
}
static SECStatus
secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback,
PRUint32 policyCheckFlags)
secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback)
{
char *args;
char *disallow, *allow;
SECStatus rv;
if (policyConfig == NULL) {
@ -868,53 +752,20 @@ secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback,
if (rv != SECSuccess) {
return rv;
}
args = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_DISALLOW, printPolicyFeedback,
policyCheckFlags);
if (args)
PORT_Free(args);
disallow = NSSUTIL_ArgGetParamValue("disallow", policyConfig);
rv = secmod_applyCryptoPolicy(disallow, PR_FALSE, printPolicyFeedback);
if (disallow)
PORT_Free(disallow);
if (rv != SECSuccess) {
return rv;
}
args = NSSUTIL_ArgGetParamValue("allow", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_ALLOW, printPolicyFeedback,
policyCheckFlags);
if (args)
PORT_Free(args);
allow = NSSUTIL_ArgGetParamValue("allow", policyConfig);
rv = secmod_applyCryptoPolicy(allow, PR_TRUE, printPolicyFeedback);
if (allow)
PORT_Free(allow);
if (rv != SECSuccess) {
return rv;
}
args = NSSUTIL_ArgGetParamValue("disable", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_DISABLE, printPolicyFeedback,
policyCheckFlags);
if (args)
PORT_Free(args);
if (rv != SECSuccess) {
return rv;
}
args = NSSUTIL_ArgGetParamValue("enable", policyConfig);
rv = secmod_applyCryptoPolicy(args, NSS_ENABLE, printPolicyFeedback,
policyCheckFlags);
if (args)
PORT_Free(args);
if (rv != SECSuccess) {
return rv;
}
/* this has to be last. Everything after this will be a noop */
if (NSSUTIL_ArgHasFlag("flags", "ssl-lock", policyConfig)) {
PRInt32 locks;
/* don't overwrite other (future) lock flags */
rv = NSS_OptionGet(NSS_DEFAULT_LOCKS, &locks);
if (rv == SECSuccess) {
rv = NSS_OptionSet(NSS_DEFAULT_LOCKS, locks | NSS_DEFAULT_SSL_LOCK);
}
if (rv != SECSuccess) {
return rv;
}
}
if (NSSUTIL_ArgHasFlag("flags", "policy-lock", policyConfig)) {
NSS_LockPolicy();
}
if (printPolicyFeedback) {
/* This helps to distinguish configurations that don't contain any
* policy config= statement. */
@ -925,22 +776,6 @@ secmod_parseCryptoPolicy(const char *policyConfig, PRBool printPolicyFeedback,
return rv;
}
static PRUint32
secmod_parsePolicyCheckFlags(const char *nss)
{
PRUint32 policyCheckFlags = 0;
if (NSSUTIL_ArgHasFlag("flags", "policyCheckIdentifier", nss)) {
policyCheckFlags |= SECMOD_FLAG_POLICY_CHECK_IDENTIFIER;
}
if (NSSUTIL_ArgHasFlag("flags", "policyCheckValue", nss)) {
policyCheckFlags |= SECMOD_FLAG_POLICY_CHECK_VALUE;
}
return policyCheckFlags;
}
/*
* for 3.4 we continue to use the old SECMODModule structure
*/
@ -952,10 +787,11 @@ SECMOD_CreateModuleEx(const char *library, const char *moduleName,
SECMODModule *mod;
SECStatus rv;
char *slotParams, *ciphers;
PRBool printPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
PRUint32 policyCheckFlags = secmod_parsePolicyCheckFlags(nss);
/* pk11pars.h still does not have const char * interfaces */
char *nssc = (char *)nss;
PRBool printPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nssc);
rv = secmod_parseCryptoPolicy(config, printPolicyFeedback, policyCheckFlags);
rv = secmod_parseCryptoPolicy(config, printPolicyFeedback);
/* do not load the module if policy parsing fails */
if (rv != SECSuccess) {
@ -979,27 +815,27 @@ SECMOD_CreateModuleEx(const char *library, const char *moduleName,
mod->libraryParams = PORT_ArenaStrdup(mod->arena, parameters);
}
mod->internal = NSSUTIL_ArgHasFlag("flags", "internal", nss);
mod->isFIPS = NSSUTIL_ArgHasFlag("flags", "FIPS", nss);
mod->internal = NSSUTIL_ArgHasFlag("flags", "internal", nssc);
mod->isFIPS = NSSUTIL_ArgHasFlag("flags", "FIPS", nssc);
/* if the system FIPS mode is enabled, force FIPS to be on */
if (SECMOD_GetSystemFIPSEnabled()) {
if (secmod_GetSystemFIPSEnabled()) {
mod->isFIPS = PR_TRUE;
}
mod->isCritical = NSSUTIL_ArgHasFlag("flags", "critical", nss);
slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
mod->isCritical = NSSUTIL_ArgHasFlag("flags", "critical", nssc);
slotParams = NSSUTIL_ArgGetParamValue("slotParams", nssc);
mod->slotInfo = NSSUTIL_ArgParseSlotInfo(mod->arena, slotParams,
&mod->slotInfoCount);
if (slotParams)
PORT_Free(slotParams);
/* new field */
mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nss,
mod->trustOrder = NSSUTIL_ArgReadLong("trustOrder", nssc,
NSSUTIL_DEFAULT_TRUST_ORDER, NULL);
/* new field */
mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder", nss,
mod->cipherOrder = NSSUTIL_ArgReadLong("cipherOrder", nssc,
NSSUTIL_DEFAULT_CIPHER_ORDER, NULL);
/* new field */
mod->isModuleDB = NSSUTIL_ArgHasFlag("flags", "moduleDB", nss);
mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags", "moduleDBOnly", nss);
mod->isModuleDB = NSSUTIL_ArgHasFlag("flags", "moduleDB", nssc);
mod->moduleDBOnly = NSSUTIL_ArgHasFlag("flags", "moduleDBOnly", nssc);
if (mod->moduleDBOnly)
mod->isModuleDB = PR_TRUE;
@ -1011,13 +847,13 @@ SECMOD_CreateModuleEx(const char *library, const char *moduleName,
* code checking if (mod->isModuleDB) will continue to work correctly. */
if (mod->isModuleDB) {
char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB;
if (NSSUTIL_ArgHasFlag("flags", "skipFirst", nss)) {
if (NSSUTIL_ArgHasFlag("flags", "skipFirst", nssc)) {
flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST;
}
if (NSSUTIL_ArgHasFlag("flags", "defaultModDB", nss)) {
if (NSSUTIL_ArgHasFlag("flags", "defaultModDB", nssc)) {
flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB;
}
if (NSSUTIL_ArgHasFlag("flags", "policyOnly", nss)) {
if (NSSUTIL_ArgHasFlag("flags", "policyOnly", nssc)) {
flags |= SECMOD_FLAG_MODULE_DB_POLICY_ONLY;
}
/* additional moduleDB flags could be added here in the future */
@ -1027,13 +863,13 @@ SECMOD_CreateModuleEx(const char *library, const char *moduleName,
if (mod->internal) {
char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL;
if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nss)) {
if (NSSUTIL_ArgHasFlag("flags", "internalKeySlot", nssc)) {
flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT;
}
mod->internal = (PRBool)flags;
}
ciphers = NSSUTIL_ArgGetParamValue("ciphers", nss);
ciphers = NSSUTIL_ArgGetParamValue("ciphers", nssc);
NSSUTIL_ArgParseCipherFlags(&mod->ssl[0], ciphers);
if (ciphers)
PORT_Free(ciphers);
@ -1098,8 +934,8 @@ secmod_SetInternalKeySlotFlag(SECMODModule *mod, PRBool val)
* try to expand the buffer with Realloc.
*/
static char *
secmod_doDescCopy(char *target, char **base, int *baseLen,
const char *desc, int descLen, char *value)
secmod_doDescCopy(char *target, int *targetLen, const char *desc,
int descLen, char *value)
{
int diff, esc_len;
@ -1108,14 +944,12 @@ secmod_doDescCopy(char *target, char **base, int *baseLen,
if (diff > 0) {
/* we need to escape... expand newSpecPtr as well to make sure
* we don't overflow it */
int offset = target - *base;
char *newPtr = PORT_Realloc(*base, *baseLen + diff);
char *newPtr = PORT_Realloc(target, *targetLen * diff);
if (!newPtr) {
return target; /* not enough space, just drop the whole copy */
}
*baseLen += diff;
target = newPtr + offset;
*base = newPtr;
*targetLen += diff;
target = newPtr;
value = NSSUTIL_Escape(value, '\"');
if (value == NULL) {
return target; /* couldn't escape value, just drop the copy */
@ -1211,60 +1045,54 @@ secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, target, "tokens=",
modulePrev = moduleSpec;
/* skip copying */)
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "cryptoTokenDescription=",
if (convert) { modulePrev = moduleSpec; })
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "cryptoSlotDescription=",
if (convert) { modulePrev = moduleSpec; })
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "dbTokenDescription=",
if (convert) {
modulePrev = moduleSpec;
if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_TOKEN_DESCRIPTION,
sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "dbSlotDescription=",
if (convert) {
modulePrev = moduleSpec; /* skip copying */
if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_SLOT_DESCRIPTION,
sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "FIPSTokenDescription=",
if (convert) {
modulePrev = moduleSpec; /* skip copying */
if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_TOKEN_DESCRIPTION,
sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(
moduleSpec, tmp, "FIPSSlotDescription=",
if (convert) {
modulePrev = moduleSpec; /* skip copying */
if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpec, &newSpecLen,
SECMOD_SLOT_DESCRIPTION,
sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
}
})
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=",
if (convert) { modulePrev = moduleSpec; });
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=",
if (convert) { modulePrev = moduleSpec; });
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=",
if (convert) {
modulePrev = moduleSpec;
if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
SECMOD_TOKEN_DESCRIPTION,
sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
}
});
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=",
if (convert) {
modulePrev = moduleSpec; /* skip copying */
if (!isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
SECMOD_SLOT_DESCRIPTION,
sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
}
});
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=",
if (convert) {
modulePrev = moduleSpec; /* skip copying */
if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
SECMOD_TOKEN_DESCRIPTION,
sizeof(SECMOD_TOKEN_DESCRIPTION) - 1,
tmp);
}
});
NSSUTIL_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=",
if (convert) {
modulePrev = moduleSpec; /* skip copying */
if (isFIPS) {
newSpecPtr = secmod_doDescCopy(newSpecPtr,
&newSpecLen,
SECMOD_SLOT_DESCRIPTION,
sizeof(SECMOD_SLOT_DESCRIPTION) - 1,
tmp);
}
});
NSSUTIL_HANDLE_FINAL_ARG(moduleSpec)
SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec);
}
@ -1969,7 +1797,6 @@ SECMOD_LoadModule(char *modulespec, SECMODModule *parent, PRBool recurse)
SECMODModule *oldModule = NULL;
SECStatus rv;
PRBool forwardPolicyFeedback = PR_FALSE;
PRUint32 forwardPolicyCheckFlags;
/* initialize the underlying module structures */
SECMOD_Init();
@ -1983,8 +1810,6 @@ SECMOD_LoadModule(char *modulespec, SECMODModule *parent, PRBool recurse)
module = SECMOD_CreateModuleEx(library, moduleName, parameters, nss, config);
forwardPolicyFeedback = NSSUTIL_ArgHasFlag("flags", "printPolicyFeedback", nss);
forwardPolicyCheckFlags = secmod_parsePolicyCheckFlags(nss);
if (library)
PORT_Free(library);
if (moduleName)
@ -2053,17 +1878,6 @@ SECMOD_LoadModule(char *modulespec, SECMODModule *parent, PRBool recurse)
/* Add printPolicyFeedback to the nss flags */
char *specWithForwards =
NSSUTIL_AddNSSFlagToModuleSpec(*index, "printPolicyFeedback");
char *tmp;
if (forwardPolicyCheckFlags & SECMOD_FLAG_POLICY_CHECK_IDENTIFIER) {
tmp = NSSUTIL_AddNSSFlagToModuleSpec(specWithForwards, "policyCheckIdentifier");
PORT_Free(specWithForwards);
specWithForwards = tmp;
}
if (forwardPolicyCheckFlags & SECMOD_FLAG_POLICY_CHECK_VALUE) {
tmp = NSSUTIL_AddNSSFlagToModuleSpec(specWithForwards, "policyCheckValue");
PORT_Free(specWithForwards);
specWithForwards = tmp;
}
child = SECMOD_LoadModule(specWithForwards, module, PR_TRUE);
PORT_Free(specWithForwards);
}

View file

@ -51,50 +51,54 @@ typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter;
* based upon the additions in PKCS 12. This should eventually be moved
* if RSA updates PKCS 5.
*/
const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SEC_PKCS5PBEParameter) },
{ SEC_ASN1_OCTET_STRING,
offsetof(SEC_PKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER,
offsetof(SEC_PKCS5PBEParameter, iteration) },
{ 0 }
};
const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
{
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SEC_PKCS5PBEParameter) },
{ SEC_ASN1_OCTET_STRING,
offsetof(SEC_PKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER,
offsetof(SEC_PKCS5PBEParameter, iteration) },
{ 0 }
};
const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
{ SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
{ 0 }
};
const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
{ SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
{ 0 }
};
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
/* SECOID_PKCS5_PBKDF2 */
const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
/* This is really a choice, but since we only understand this
const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
/* This is really a choice, but since we only understand this
* choice, just inline it */
{ SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
{ SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL,
offsetof(SEC_PKCS5PBEParameter, keyLength) },
{ SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL,
offsetof(SEC_PKCS5PBEParameter, pPrfAlgId),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ 0 }
};
{ SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
{ SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL,
offsetof(SEC_PKCS5PBEParameter, keyLength) },
{ SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL,
offsetof(SEC_PKCS5PBEParameter, pPrfAlgId),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ 0 }
};
/* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */
const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
offsetof(sec_pkcs5V2Parameter, cipherAlgId),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ 0 }
};
const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] =
{
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
offsetof(sec_pkcs5V2Parameter, cipherAlgId),
SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
{ 0 }
};
/*
* maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1
@ -298,45 +302,35 @@ SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
return SEC_OID_UNKNOWN;
}
/*
* Some oids encode the key size in the oid, while the actual PKCS
* PKCS #11 mechanism does not. In those cases we can't use
* the PKCS #11 automated key length code to select the key size.
*/
static int
sec_pkcs5v2_key_length_by_oid(SECOidTag algorithm)
static PRBool
sec_pkcs5_is_algorithm_v2_aes_algorithm(SECOidTag algorithm)
{
switch (algorithm) {
case SEC_OID_AES_128_CBC:
case SEC_OID_CAMELLIA_128_CBC:
case SEC_OID_AES_192_CBC:
case SEC_OID_AES_256_CBC:
return PR_TRUE;
default:
return PR_FALSE;
}
}
static int
sec_pkcs5v2_aes_key_length(SECOidTag algorithm)
{
switch (algorithm) {
/* The key length for the AES-CBC-Pad algorithms are
* determined from the undelying cipher algorithm. */
case SEC_OID_AES_128_CBC:
return AES_128_KEY_LENGTH;
case SEC_OID_AES_192_CBC:
case SEC_OID_CAMELLIA_192_CBC:
return AES_192_KEY_LENGTH;
case SEC_OID_AES_256_CBC:
case SEC_OID_CAMELLIA_256_CBC:
return AES_256_KEY_LENGTH;
default:
break;
}
return -1;
}
/* find the keylength from the algorithm id */
static int
sec_pkcs5v2_default_key_length(SECOidTag algorithm)
{
CK_MECHANISM_TYPE cryptoMech;
int key_length = sec_pkcs5v2_key_length_by_oid(algorithm);
if (key_length != -1) {
return key_length;
}
cryptoMech = PK11_AlgtagToMechanism(algorithm);
if (cryptoMech == CKM_INVALID_MECHANISM) {
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return -1;
}
return PK11_GetMaxKeyLength(cryptoMech);
return 0;
}
/*
@ -372,17 +366,34 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId)
if (cipherAlgId)
cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId);
if (p5_param.keyLength.data != NULL) {
/* if the length is given, accept that length. This
* will allow us to decode old NSS encrypted data
* where we used the MAX keysize for the algorithm,
* but put an incorrect header for a different keysize.
if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) {
/* Previously, the PKCS#12 files created with the old NSS
* releases encoded the maximum key size of AES (that is 32)
* in the keyLength field of PBKDF2-params. That resulted in
* always performing AES-256 even if AES-128-CBC or
* AES-192-CBC is specified in the encryptionScheme field of
* PBES2-params. This is wrong, but for compatibility reasons,
* check the keyLength field and use the value if it is 32.
*/
if (p5_param.keyLength.data != NULL) {
length = DER_GetInteger(&p5_param.keyLength);
}
/* If the keyLength field is present and contains a value
* other than 32, that means the file is created outside of
* NSS, which we don't care about. Note that the following
* also handles the case when the field is absent. */
if (length != 32) {
length = sec_pkcs5v2_aes_key_length(cipherAlg);
}
} else if (p5_param.keyLength.data != NULL) {
length = DER_GetInteger(&p5_param.keyLength);
} else {
/* if the keylength was not specified, figure it
* out from the oid */
length = sec_pkcs5v2_default_key_length(cipherAlg);
CK_MECHANISM_TYPE cipherMech;
cipherMech = PK11_AlgtagToMechanism(cipherAlg);
if (cipherMech == CKM_INVALID_MECHANISM) {
goto loser;
}
length = PK11_GetMaxKeyLength(cipherMech);
}
loser:
@ -666,10 +677,17 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
if (hashAlg != SEC_OID_UNKNOWN) {
keyLength = HASH_ResultLenByOidTag(hashAlg);
} else if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlgorithm)) {
keyLength = sec_pkcs5v2_aes_key_length(cipherAlgorithm);
} else {
keyLength = sec_pkcs5v2_default_key_length(cipherAlgorithm);
CK_MECHANISM_TYPE cryptoMech;
cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm);
if (cryptoMech == CKM_INVALID_MECHANISM) {
goto loser;
}
keyLength = PK11_GetMaxKeyLength(cryptoMech);
}
if (keyLength <= 0) {
if (keyLength == 0) {
goto loser;
}
}
@ -865,9 +883,7 @@ pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech)
pbeV2_params->ulPrfDataLen = 0;
pbeV2_params->saltSource = CKZ_SALT_SPECIFIED;
pSalt = ((CK_CHAR_PTR)pbeV2_params) + sizeof(CK_PKCS5_PBKD2_PARAMS);
if (salt->data) {
PORT_Memcpy(pSalt, salt->data, salt->len);
}
PORT_Memcpy(pSalt, salt->data, salt->len);
pbeV2_params->pSaltSourceData = pSalt;
pbeV2_params->ulSaltSourceDataLen = salt->len;
pbeV2_params->iterations = iterations;
@ -883,9 +899,7 @@ pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech)
pSalt = ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS);
pbe_params->pSalt = pSalt;
if (salt->data) {
PORT_Memcpy(pSalt, salt->data, salt->len);
}
PORT_Memcpy(pSalt, salt->data, salt->len);
pbe_params->ulSaltLen = salt->len;
if (iv_len) {
pbe_params->pInitVector =
@ -974,10 +988,10 @@ PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC;
break;
case SEC_OID_MD2:
mechanism = CKM_NSS_PBE_MD2_HMAC_KEY_GEN;
mechanism = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;
break;
case SEC_OID_MD5:
mechanism = CKM_NSS_PBE_MD5_HMAC_KEY_GEN;
mechanism = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;
break;
default:
break;
@ -1089,7 +1103,7 @@ SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
CK_MECHANISM_TYPE type;
SECItem *param = NULL;
SECItem *iv = NULL;
SECItem src = { siBuffer, NULL, 0 };
SECItem src;
int iv_len = 0;
PK11SymKey *symKey;
PK11SlotInfo *slot;
@ -1129,7 +1143,7 @@ SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
type = PK11_AlgtagToMechanism(pbeAlg);
param = PK11_ParamFromAlgid(algid);
if (param == NULL) {
goto loser;
goto done;
}
slot = PK11_GetInternalSlot();
symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL);
@ -1229,9 +1243,7 @@ PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations)
if (!pbe_params->pPassword) {
goto loser;
}
if (pwd->data) {
PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
}
PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len);
pbe_params->ulPasswordLen = pwd->len;
pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len);
@ -1351,8 +1363,8 @@ PK11SymKey *
PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech,
SECItem *pwitem, PRBool faulty3DES, void *wincx)
{
if (faulty3DES && (type == CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC)) {
type = CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC;
if (faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
}
return pk11_RawPBEKeyGenWithKeyType(slot, type, mech, -1, 0, pwitem, wincx);
}
@ -1409,8 +1421,8 @@ PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem,
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
goto loser;
}
if (faulty3DES && (type == CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC)) {
type = CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC;
if (faulty3DES && (type == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC)) {
type = CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC;
}
symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen,
pwitem, wincx);

View file

@ -11,8 +11,6 @@
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#include "secmodt.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "secitem.h"
@ -288,7 +286,7 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
PORT_FreeArena(temparena, PR_TRUE);
return rv;
}
if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
if (pki->privateKey.data == NULL) {
/* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
* is a zero-length octet string, free the arena and return a failure
* to avoid trying to zero the corresponding SECItem in
@ -413,7 +411,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
goto loser;
}
if (PK11_IsInternal(slot)) {
PK11_SETATTRS(attrs, CKA_NSS_DB,
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
publicValue->data, publicValue->len);
attrs++;
}
@ -452,7 +450,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
* this dh key. We have a netscape only CKA_ value to do this.
* Only send it to internal slots */
if (PK11_IsInternal(slot)) {
PK11_SETATTRS(attrs, CKA_NSS_DB,
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
publicValue->data, publicValue->len);
attrs++;
}
@ -485,7 +483,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
goto loser;
}
if (PK11_IsInternal(slot)) {
PK11_SETATTRS(attrs, CKA_NSS_DB,
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
lpk->u.ec.publicValue.data,
lpk->u.ec.publicValue.len);
attrs++;
@ -537,7 +535,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
}
}
rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE,
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
theTemplate, templateCount, isPerm, &objectID);
/* create and return a SECKEYPrivateKey */
@ -652,15 +650,12 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
isPrivate, keyUsage, privk, wincx);
if (rv != SECSuccess) {
goto loser;
}
PORT_FreeArena(arena, PR_TRUE);
return SECSuccess;
loser:
PORT_FreeArena(arena, PR_TRUE);
return SECFailure;
if (arena != NULL) {
PORT_FreeArena(arena, PR_TRUE);
}
return rv;
}
SECStatus
@ -707,112 +702,63 @@ PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
const unsigned char pkiVersion = 0;
/* RSAPrivateKey version (always zero) */
const unsigned char rsaVersion = 0;
/* ECPrivateKey version (always one) */
const unsigned char ecVersion = 1;
PLArenaPool *arena = NULL;
SECKEYRawPrivateKey rawKey;
SECKEYPrivateKeyInfo *pki;
SECItem *encoded;
const SEC_ASN1Template *keyTemplate;
SECStatus rv;
if (pk->keyType != rsaKey) {
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
goto loser;
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
goto loser;
}
memset(&rawKey, 0, sizeof(rawKey));
rawKey.keyType = pk->keyType;
rawKey.u.rsa.version.type = siUnsignedInteger;
rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
if (!rawKey.u.rsa.version.data) {
goto loser;
}
rawKey.u.rsa.version.data[0] = rsaVersion;
rawKey.u.rsa.version.len = 1;
/* Read the component attributes of the private key */
prepare_rsa_priv_key_export_for_asn1(&rawKey);
if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
!ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
&rawKey.u.rsa.publicExponent) ||
!ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
&rawKey.u.rsa.privateExponent) ||
!ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
!ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
!ReadAttribute(pk, CKA_EXPONENT_1, arena,
&rawKey.u.rsa.exponent1) ||
!ReadAttribute(pk, CKA_EXPONENT_2, arena,
&rawKey.u.rsa.exponent2) ||
!ReadAttribute(pk, CKA_COEFFICIENT, arena,
&rawKey.u.rsa.coefficient)) {
goto loser;
}
pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo);
if (!pki) {
goto loser;
}
switch (pk->keyType) {
case rsaKey: {
rawKey.u.rsa.version.type = siUnsignedInteger;
rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
if (!rawKey.u.rsa.version.data) {
goto loser;
}
rawKey.u.rsa.version.data[0] = rsaVersion;
rawKey.u.rsa.version.len = 1;
/* Read the component attributes of the private key */
prepare_rsa_priv_key_export_for_asn1(&rawKey);
if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
!ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
&rawKey.u.rsa.publicExponent) ||
!ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
&rawKey.u.rsa.privateExponent) ||
!ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
!ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
!ReadAttribute(pk, CKA_EXPONENT_1, arena,
&rawKey.u.rsa.exponent1) ||
!ReadAttribute(pk, CKA_EXPONENT_2, arena,
&rawKey.u.rsa.exponent2) ||
!ReadAttribute(pk, CKA_COEFFICIENT, arena,
&rawKey.u.rsa.coefficient)) {
goto loser;
}
keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
if (rv != SECSuccess) {
goto loser;
}
} break;
case ecKey: {
rawKey.u.ec.version.type = siUnsignedInteger;
rawKey.u.ec.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
if (!rawKey.u.ec.version.data) {
goto loser;
}
rawKey.u.ec.version.data[0] = ecVersion;
rawKey.u.ec.version.len = 1;
SECItem curveOID;
/* Read the component attributes of the private key */
prepare_ec_priv_key_export_for_asn1(&rawKey);
if (!ReadAttribute(pk, CKA_VALUE, arena,
&rawKey.u.ec.privateValue) ||
!ReadAttribute(pk, CKA_EC_PARAMS, arena, &curveOID)) {
goto loser;
}
if (!ReadAttribute(pk, CKA_EC_POINT, arena,
&rawKey.u.ec.publicValue)) {
SECKEYPublicKey *pubk = SECKEY_ConvertToPublicKey(pk);
if (pubk == NULL)
goto loser;
rv = SECITEM_CopyItem(arena, &rawKey.u.ec.publicValue, &pubk->u.ec.publicValue);
SECKEY_DestroyPublicKey(pubk);
if (rv != SECSuccess) {
goto loser;
}
}
keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
/* Convert length in bytes to length in bits. */
rawKey.u.ec.publicValue.len <<= 3;
rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_ANSIX962_EC_PUBLIC_KEY, &curveOID);
if (rv != SECSuccess) {
goto loser;
}
} break;
default: {
PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
goto loser;
}
}
encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey, keyTemplate);
encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey,
SECKEY_RSAPrivateKeyExportTemplate);
if (!encoded) {
goto loser;
}
rv = SECOID_SetAlgorithmID(arena, &pki->algorithm,
SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
if (rv != SECSuccess) {
goto loser;
}
pki->version.type = siUnsignedInteger;
pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
if (!pki->version.data) {

View file

@ -55,9 +55,9 @@ PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
{ CKA_BASE, NULL, 0 },
};
CK_ATTRIBUTE vTemplate[] = {
{ CKA_NSS_PQG_COUNTER, NULL, 0 },
{ CKA_NSS_PQG_SEED, NULL, 0 },
{ CKA_NSS_PQG_H, NULL, 0 },
{ CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
{ CKA_NETSCAPE_PQG_SEED, NULL, 0 },
{ CKA_NETSCAPE_PQG_H, NULL, 0 },
};
CK_ULONG primeBits = L;
CK_ULONG subPrimeBits = N;
@ -84,7 +84,7 @@ PK11_PQG_ParamGenV2(unsigned int L, unsigned int N,
attrs++;
}
if (seedBits != 0) {
PK11_SETATTRS(attrs, CKA_NSS_PQG_SEED_BITS,
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED_BITS,
&seedBits, sizeof(seedBits));
attrs++;
}
@ -266,13 +266,13 @@ PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
{ CKA_SUBPRIME, NULL, 0 },
{ CKA_BASE, NULL, 0 },
{ CKA_TOKEN, NULL, 0 },
{ CKA_NSS_PQG_COUNTER, NULL, 0 },
{ CKA_NSS_PQG_SEED, NULL, 0 },
{ CKA_NSS_PQG_H, NULL, 0 },
{ CKA_NETSCAPE_PQG_COUNTER, NULL, 0 },
{ CKA_NETSCAPE_PQG_SEED, NULL, 0 },
{ CKA_NETSCAPE_PQG_H, NULL, 0 },
};
CK_ATTRIBUTE *attrs;
CK_BBOOL ckfalse = CK_FALSE;
CK_OBJECT_CLASS class = CKO_DOMAIN_PARAMETERS;
CK_OBJECT_CLASS class = CKO_KG_PARAMETERS;
CK_KEY_TYPE keyType = CKK_DSA;
SECStatus rv = SECSuccess;
PK11SlotInfo *slot;
@ -301,15 +301,15 @@ PK11_PQG_VerifyParams(const PQGParams *params, const PQGVerify *vfy,
if (vfy) {
if (vfy->counter != -1) {
counter = vfy->counter;
PK11_SETATTRS(attrs, CKA_NSS_PQG_COUNTER,
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_COUNTER,
&counter, sizeof(counter));
attrs++;
}
PK11_SETATTRS(attrs, CKA_NSS_PQG_SEED,
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_SEED,
vfy->seed.data, vfy->seed.len);
attrs++;
if (vfy->h.len) {
PK11_SETATTRS(attrs, CKA_NSS_PQG_H,
PK11_SETATTRS(attrs, CKA_NETSCAPE_PQG_H,
vfy->h.data, vfy->h.len);
attrs++;
}

View file

@ -3,9 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _PK11PRIV_H_
#define _PK11PRIV_H_
#include <stddef.h>
#include "plarena.h"
#include "seccomon.h"
#include "secoidt.h"
@ -51,7 +48,7 @@ CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
char *PK11_MakeString(PLArenaPool *arena, char *space, char *staticSring,
int stringLen);
PRBool pk11_MatchString(const char *string,
const char *staticString, size_t staticStringLen);
const char *staticString, int staticStringLen);
int PK11_MapError(CK_RV error);
CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot);
void PK11_RestoreROSession(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession);
@ -101,7 +98,6 @@ void PK11_AddMechanismEntry(CK_MECHANISM_TYPE type, CK_KEY_TYPE key,
int ivLen, int blocksize);
CK_MECHANISM_TYPE PK11_GetKeyMechanism(CK_KEY_TYPE type);
CK_MECHANISM_TYPE PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size);
PRBool PK11_DoesMechanismFlag(PK11SlotInfo *, CK_MECHANISM_TYPE type, CK_FLAGS flags);
/**********************************************************************
* Symetric, Public, and Private Keys
@ -150,14 +146,6 @@ PK11Context *PK11_CreateContextByRawKey(PK11SlotInfo *slot,
CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation,
SECItem *key, SECItem *param, void *wincx);
PRBool PK11_HashOK(SECOidTag hashAlg);
/*
* Testing interfaces, not for general use. If your code isn't in
* gtests or cmd, stay away from these. This function forces
* an AEAD context into simulation mode even though the target token
* can already do PKCS #11 v3.0 Message (e.i. softoken).
*/
SECStatus _PK11_ContextSetAEADSimulation(PK11Context *context);
PRBool _PK11_ContextGetAEADSimulation(PK11Context *context);
/**********************************************************************
* Functions which are deprecated....
@ -200,11 +188,6 @@ SECStatus pk11_setGlobalOptions(PRBool noSingleThreadedModules,
/* return whether NSS is allowed to call C_Finalize */
PRBool pk11_getFinalizeModulesOption(void);
/* fetch the FIPS state from the fips indicator, public versions of
* this function operate on the slot, the context, and the object */
PRBool pk11slot_GetFIPSStatus(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE object, CK_ULONG operationType);
SEC_END_PROTOS
#endif

View file

@ -9,7 +9,6 @@
#include "secdert.h"
#include "keythi.h"
#include "certt.h"
#include "pk11hpke.h"
#include "pkcs11t.h"
#include "secmodt.h"
#include "seccomon.h"
@ -268,8 +267,6 @@ CK_MECHANISM_TYPE PK11_MapSignKeyType(KeyType keyType);
**********************************************************************/
void PK11_FreeSymKey(PK11SymKey *key);
PK11SymKey *PK11_ReferenceSymKey(PK11SymKey *symKey);
PK11SymKey *PK11_ImportDataKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin,
CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx);
PK11SymKey *PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx);
PK11SymKey *PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot,
@ -357,11 +354,6 @@ void *PK11_GetSymKeyUserData(PK11SymKey *symKey);
SECStatus PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
PK11SymKey *symKey, SECItem *wrappedKey);
SECStatus PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey,
CK_MECHANISM_TYPE mechType,
SECItem *param,
PK11SymKey *symKey,
SECItem *wrappedKey);
SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey);
/* move a key to 'slot' optionally set the key attributes according to either
@ -370,25 +362,6 @@ SECStatus PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *params,
* currently ignored */
PK11SymKey *PK11_MoveSymKey(PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation,
CK_FLAGS flags, PRBool perm, PK11SymKey *symKey);
/*
* To do joint operations, we often need two keys in the same slot.
* Usually the PKCS #11 wrappers handle this correctly (like for PK11_WrapKey),
* but sometimes the wrappers don't know about mechanism specific keys in
* the Mechanism params. This function makes sure the two keys are in the
* same slot by copying one or both of the keys into a common slot. This
* functions makes sure the slot can handle the target mechanism. If the copy
* is warranted, this function will prefer to move the movingKey first, then
* the preferedKey. If the keys are moved, the new keys are returned in
* newMovingKey and/or newPreferedKey. The application is responsible
* for freeing those keys one the operation is complete.
*/
SECStatus PK11_SymKeysToSameSlot(CK_MECHANISM_TYPE mech,
CK_ATTRIBUTE_TYPE preferedOperation,
CK_ATTRIBUTE_TYPE movingOperation,
PK11SymKey *preferedKey, PK11SymKey *movingKey,
PK11SymKey **newPreferedKey,
PK11SymKey **newMovingKey);
/*
* derive a new key from the base key.
* PK11_Derive returns a key which can do exactly one operation, and is
@ -456,13 +429,6 @@ PK11SymKey *PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
*/
PK11SymKey *PK11_PubUnwrapSymKey(SECKEYPrivateKey *key, SECItem *wrapppedKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize);
PK11SymKey *PK11_PubUnwrapSymKeyWithMechanism(SECKEYPrivateKey *key,
CK_MECHANISM_TYPE mechType,
SECItem *param,
SECItem *wrapppedKey,
CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation,
int keySize);
PK11SymKey *PK11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey,
SECItem *wrappedKey, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize,
@ -627,20 +593,10 @@ SECKEYPrivateKeyInfo *PK11_ExportPrivateKeyInfo(
CERTCertificate *cert, void *wincx);
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivKeyInfo(
PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
SECKEYPrivateKey *pk, int iteration, void *pwArg);
SECKEYPrivateKey *pk, int iteration, void *wincx);
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivateKeyInfo(
PK11SlotInfo *slot, SECOidTag algTag, SECItem *pwitem,
CERTCertificate *cert, int iteration, void *pwArg);
/* V2 refers to PKCS #5 V2 here. If a PKCS #5 v1 or PKCS #12 pbe is passed
* for pbeTag, then encTag and hashTag are ignored. If pbe is an encryption
* algorithm, then PKCS #5 V2 is used with prfTag for the prf. If prfTag isn't
* supplied prf will be SEC_OID_HMAC_SHA1 */
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivKeyInfoV2(
PK11SlotInfo *slot, SECOidTag pbeTag, SECOidTag encTag, SECOidTag prfTag,
SECItem *pwitem, SECKEYPrivateKey *pk, int iteration, void *pwArg);
SECKEYEncryptedPrivateKeyInfo *PK11_ExportEncryptedPrivateKeyInfoV2(
PK11SlotInfo *slot, SECOidTag pbeTag, SECOidTag encTag, SECOidTag prfTag,
SECItem *pwitem, CERTCertificate *cert, int iteration, void *pwArg);
CERTCertificate *cert, int iteration, void *wincx);
SECKEYPrivateKey *PK11_FindKeyByDERCert(PK11SlotInfo *slot,
CERTCertificate *cert, void *wincx);
SECKEYPublicKey *PK11_MakeKEAPubKey(unsigned char *data, int length);
@ -722,7 +678,6 @@ SECStatus PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
void *wincx);
CERTCertificate *PK11_FindBestKEAMatch(CERTCertificate *serverCert, void *wincx);
PRBool PK11_FortezzaHasKEA(CERTCertificate *cert);
CK_OBJECT_HANDLE PK11_FindEncodedCertInSlot(PK11SlotInfo *slot, SECItem *derCert, void *wincx);
CK_OBJECT_HANDLE PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert,
void *wincx);
CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert,
@ -739,49 +694,6 @@ CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot,
CK_ATTRIBUTE_TYPE type,
PRBool haslock /* must be set to PR_FALSE */);
/**********************************************************************
* Hybrid Public Key Encryption
**********************************************************************/
/* Some of the various HPKE arguments would ideally be const, but the
* underlying PK11 functions take them as non-const. To avoid lying to
* the application with a cast, this idiosyncrasy is exposed. */
SECStatus PK11_HPKE_ValidateParameters(HpkeKemId kemId, HpkeKdfId kdfId, HpkeAeadId aeadId);
HpkeContext *PK11_HPKE_NewContext(HpkeKemId kemId, HpkeKdfId kdfId, HpkeAeadId aeadId,
PK11SymKey *psk, const SECItem *pskId);
SECStatus PK11_HPKE_Deserialize(const HpkeContext *cx, const PRUint8 *enc,
unsigned int encLen, SECKEYPublicKey **outPubKey);
void PK11_HPKE_DestroyContext(HpkeContext *cx, PRBool freeit);
/* Serialize an initialized receiver context. This only retains the keys and
* associated information necessary to resume Export and Open operations after
* import. Serialization is currently supported for receiver contexts only.
* This is done for two reasons: 1) it avoids having to move the encryption
* sequence number outside of the token (or adding encryption context
* serialization support to softoken), and 2) we don't have to worry about IV
* reuse due to sequence number cloning.
*
* |wrapKey| is required when exporting in FIPS mode. If exported with a
* wrapping key, that same key must be provided to the import function,
* otherwise behavior is undefined.
*
* Even when exported with key wrap, HPKE expects the nonce to also be kept
* secret and that value is not protected by wrapKey. Applications are
* responsible for maintaining the confidentiality of the exported information.
*/
SECStatus PK11_HPKE_ExportContext(const HpkeContext *cx, PK11SymKey *wrapKey, SECItem **serialized);
SECStatus PK11_HPKE_ExportSecret(const HpkeContext *cx, const SECItem *info, unsigned int L,
PK11SymKey **outKey);
const SECItem *PK11_HPKE_GetEncapPubKey(const HpkeContext *cx);
HpkeContext *PK11_HPKE_ImportContext(const SECItem *serialized, PK11SymKey *wrapKey);
SECStatus PK11_HPKE_Open(HpkeContext *cx, const SECItem *aad, const SECItem *ct, SECItem **outPt);
SECStatus PK11_HPKE_Seal(HpkeContext *cx, const SECItem *aad, const SECItem *pt, SECItem **outCt);
SECStatus PK11_HPKE_Serialize(const SECKEYPublicKey *pk, PRUint8 *buf, unsigned int *len, unsigned int maxLen);
SECStatus PK11_HPKE_SetupS(HpkeContext *cx, const SECKEYPublicKey *pkE, SECKEYPrivateKey *skE,
SECKEYPublicKey *pkR, const SECItem *info);
SECStatus PK11_HPKE_SetupR(HpkeContext *cx, const SECKEYPublicKey *pkR, SECKEYPrivateKey *skR,
const SECItem *enc, const SECItem *info);
/**********************************************************************
* Sign/Verify
**********************************************************************/
@ -817,17 +729,7 @@ SECStatus PK11_VerifyWithMechanism(SECKEYPublicKey *key,
**********************************************************************/
void PK11_DestroyContext(PK11Context *context, PRBool freeit);
PK11Context *PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation,
PK11SymKey *symKey,
const SECItem *param);
PK11Context *PK11_CreateContextByPubKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation,
SECKEYPublicKey *pubKey,
const SECItem *param, void *pwArg);
PK11Context *PK11_CreateContextByPrivKey(CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation,
SECKEYPrivateKey *privKey,
const SECItem *param);
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey, SECItem *param);
PK11Context *PK11_CreateDigestContext(SECOidTag hashAlg);
PK11Context *PK11_CloneContext(PK11Context *old);
SECStatus PK11_DigestBegin(PK11Context *cx);
@ -841,19 +743,6 @@ SECStatus PK11_DigestOp(PK11Context *context, const unsigned char *in,
unsigned len);
SECStatus PK11_CipherOp(PK11Context *context, unsigned char *out, int *outlen,
int maxout, const unsigned char *in, int inlen);
/* application builds the mechanism specific params */
SECStatus PK11_AEADRawOp(PK11Context *context, void *params, int paramslen,
const unsigned char *aad, int aadlen,
unsigned char *out, int *outlen,
int maxout, const unsigned char *in, int inlen);
/* NSS builds the mechanism specific params */
SECStatus PK11_AEADOp(PK11Context *context, CK_GENERATOR_FUNCTION ivGen,
int fixedbits, unsigned char *iv, int ivlen,
const unsigned char *aad, int aadlen,
unsigned char *out, int *outlen,
int maxout, unsigned char *tag, int taglen,
const unsigned char *in, int inlen);
SECStatus PK11_Finalize(PK11Context *context);
SECStatus PK11_DigestFinal(PK11Context *context, unsigned char *data,
unsigned int *outLen, unsigned int length);
@ -974,13 +863,8 @@ PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot,
*/
SECStatus PK11_ReadRawAttribute(PK11ObjectType type, void *object,
CK_ATTRIBUTE_TYPE attr, SECItem *item);
SECStatus PK11_ReadRawAttributes(PLArenaPool *arena, PK11ObjectType type, void *object,
CK_ATTRIBUTE *pTemplate, unsigned int count);
SECStatus PK11_WriteRawAttribute(PK11ObjectType type, void *object,
CK_ATTRIBUTE_TYPE attr, SECItem *item);
/* get the PKCS #11 handle and slot for a generic object */
CK_OBJECT_HANDLE PK11_GetObjectHandle(PK11ObjectType objType, void *objSpec,
PK11SlotInfo **slotp);
/*
* PK11_GetAllSlotsForCert returns all the slots that a given certificate
@ -1020,35 +904,6 @@ PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key);
PRBool SECMOD_HasRootCerts(void);
/**********************************************************************
* Other Utilities
**********************************************************************/
/*
* Get the state of the system FIPS mode -
* NSS uses this to force FIPS mode if the system bit is on. This returns
* the system state independent of the database state and can be called
* before NSS initializes.
*/
int SECMOD_GetSystemFIPSEnabled(void);
/* FIPS indicator functions. Some operations are physically allowed, but
* are against the NSS FIPS security policy. This is because sometimes NSS
* functions are used in non-security contexts. You can call these functions
* to determine if you are operating inside or outside the the current vendor's
* FIPS Security Policy for NSS. NOTE: if the current version of NSS is not
* actually FIPS certified, then these functions will always return PR_FALSE */
/* This function tells if if the last single shot operation on the slot
* was inside or outside the FIPS security policy */
PRBool PK11_SlotGetLastFIPSStatus(PK11SlotInfo *slot);
/* This tells you if the current operation is within the FIPS security policy. If
* you have called finalize on the context, it tells you if the last operation
* was within the FIPS security policy */
PRBool PK11_ContextGetFIPSStatus(PK11Context *context);
/* This tells you if the requested object was created in accordance to the
* NSS FIPS security policy. */
PRBool PK11_ObjectGetFIPSStatus(PK11ObjectType objType, void *objSpec);
SEC_END_PROTOS
#endif

View file

@ -6,8 +6,6 @@
* Interfaces.
*/
#include <stddef.h>
#include "seccomon.h"
#include "secmod.h"
#include "nssilock.h"
@ -75,11 +73,11 @@ pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession)
* session could be invalid if the token has been removed or because
* we got it from the non-owner free list */
if ((symKey->series != slot->series) ||
(symKey->session == CK_INVALID_HANDLE)) {
(symKey->session == CK_INVALID_SESSION)) {
symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
}
PORT_Assert(symKey->session != CK_INVALID_HANDLE);
if (symKey->session != CK_INVALID_HANDLE)
PORT_Assert(symKey->session != CK_INVALID_SESSION);
if (symKey->session != CK_INVALID_SESSION)
return symKey;
PK11_FreeSymKey(symKey);
/* if we are here, we need a session, but couldn't get one, it's
@ -96,13 +94,13 @@ pk11_getKeyFromList(PK11SlotInfo *slot, PRBool needSession)
symKey->next = NULL;
if (needSession) {
symKey->session = pk11_GetNewSession(slot, &symKey->sessionOwner);
PORT_Assert(symKey->session != CK_INVALID_HANDLE);
if (symKey->session == CK_INVALID_HANDLE) {
PORT_Assert(symKey->session != CK_INVALID_SESSION);
if (symKey->session == CK_INVALID_SESSION) {
PK11_FreeSymKey(symKey);
symKey = NULL;
}
} else {
symKey->session = CK_INVALID_HANDLE;
symKey->session = CK_INVALID_SESSION;
}
return symKey;
}
@ -150,7 +148,7 @@ pk11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
/* if needSession was specified, make sure we have a valid session.
* callers which specify needSession as false should do their own
* check of the session before returning the symKey */
if (needSession && symKey->session == CK_INVALID_HANDLE) {
if (needSession && symKey->session == CK_INVALID_SESSION) {
PK11_FreeSymKey(symKey);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
@ -215,16 +213,16 @@ PK11_FreeSymKey(PK11SymKey *symKey)
* session must be valid.
* freeSymKeysHead contain a list of SymKey structures without
* valid session.
* session must be CK_INVALID_HANDLE.
* session must be CK_INVALID_SESSION.
* though sessionOwner is false, callers should not depend on
* this fact.
*/
if (symKey->sessionOwner) {
PORT_Assert(symKey->session != CK_INVALID_HANDLE);
PORT_Assert(symKey->session != CK_INVALID_SESSION);
symKey->next = slot->freeSymKeysWithSessionHead;
slot->freeSymKeysWithSessionHead = symKey;
} else {
symKey->session = CK_INVALID_HANDLE;
symKey->session = CK_INVALID_SESSION;
symKey->next = slot->freeSymKeysHead;
slot->freeSymKeysHead = symKey;
}
@ -347,8 +345,8 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
/* This is the only case where pk11_CreateSymKey does not explicitly
* check symKey->session. We need to assert here to make sure.
* the session isn't invalid. */
PORT_Assert(parent->session != CK_INVALID_HANDLE);
if (parent->session == CK_INVALID_HANDLE) {
PORT_Assert(parent->session != CK_INVALID_SESSION);
if (parent->session == CK_INVALID_SESSION) {
PK11_FreeSymKey(symKey);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
@ -368,7 +366,6 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
int series, void *wincx)
{
PK11SymKey *symKey = NULL;
CK_OBJECT_HANDLE keyHandle;
PK11_EnterSlotMonitor(slot);
if (slot->series != series ||
@ -381,10 +378,9 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
type = slot->wrapMechanism;
}
keyHandle = slot->refKeys[wrap];
PK11_ExitSlotMonitor(slot);
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
slot->wrapMechanism, keyHandle, PR_FALSE, wincx);
slot->wrapMechanism, slot->refKeys[wrap], PR_FALSE, wincx);
PK11_ExitSlotMonitor(slot);
return symKey;
}
@ -405,19 +401,15 @@ void
PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey)
{
PK11_EnterSlotMonitor(slot);
if (wrap >= 0) {
size_t uwrap = (size_t)wrap;
if (uwrap < PR_ARRAY_SIZE(slot->refKeys) &&
slot->refKeys[uwrap] == CK_INVALID_HANDLE) {
/* save the handle and mechanism for the wrapping key */
/* mark the key and session as not owned by us so they don't get
* freed when the key goes way... that lets us reuse the key
* later */
slot->refKeys[uwrap] = wrapKey->objectID;
wrapKey->owner = PR_FALSE;
wrapKey->sessionOwner = PR_FALSE;
slot->wrapMechanism = wrapKey->type;
}
if (wrap < PR_ARRAY_SIZE(slot->refKeys) &&
slot->refKeys[wrap] == CK_INVALID_HANDLE) {
/* save the handle and mechanism for the wrapping key */
/* mark the key and session as not owned by us so they don't get freed
* when the key goes way... that lets us reuse the key later */
slot->refKeys[wrap] = wrapKey->objectID;
wrapKey->owner = PR_FALSE;
wrapKey->sessionOwner = PR_FALSE;
slot->wrapMechanism = wrapKey->type;
}
PK11_ExitSlotMonitor(slot);
}
@ -485,15 +477,6 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_ATTRIBUTE keyTemplate[5];
CK_ATTRIBUTE *attrs = keyTemplate;
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
* it as a real attribute */
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
* etc. Strip out the real attribute here */
operation &= ~CKA_NSS_MESSAGE_MASK;
}
PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
attrs++;
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
@ -508,37 +491,10 @@ PK11_ImportSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
keyTemplate, templateCount, key, wincx);
return symKey;
}
/* Import a PKCS #11 data object and return it as a key. This key is
* only useful in a limited number of mechanisms, such as HKDF. */
PK11SymKey *
PK11_ImportDataKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin,
CK_ATTRIBUTE_TYPE operation, SECItem *key, void *wincx)
{
CK_OBJECT_CLASS ckoData = CKO_DATA;
CK_ATTRIBUTE template[2] = { { CKA_CLASS, (CK_BYTE_PTR)&ckoData, sizeof(ckoData) },
{ CKA_VALUE, (CK_BYTE_PTR)key->data, key->len } };
CK_OBJECT_HANDLE handle;
PK11GenericObject *genObject;
genObject = PK11_CreateGenericObject(slot, template, PR_ARRAY_SIZE(template), PR_FALSE);
if (genObject == NULL) {
return NULL;
}
handle = PK11_GetObjectHandle(PK11_TypeGeneric, genObject, NULL);
if (handle == CK_INVALID_HANDLE) {
return NULL;
}
/* A note about ownership of the PKCS #11 handle:
* PK11_CreateGenericObject() will not destroy the object it creates
* on Free, For that you want PK11_CreateManagedGenericObject().
* Below we import the handle into the symKey structure. We pass
* PR_TRUE as the owner so that the symKey will destroy the object
* once it's freed. This is way it's safe to free now. */
PK11_DestroyGenericObject(genObject);
return PK11_SymKeyFromHandle(slot, NULL, origin, type, handle, PR_TRUE, wincx);
}
/* turn key bits into an appropriate key object */
/*
* turn key bits into an appropriate key object
*/
PK11SymKey *
PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key,
@ -552,15 +508,6 @@ PK11_ImportSymKeyWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_ATTRIBUTE keyTemplate[MAX_TEMPL_ATTRS];
CK_ATTRIBUTE *attrs = keyTemplate;
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
* it as a real attribute */
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
* etc. Strip out the real attribute here */
operation &= ~CKA_NSS_MESSAGE_MASK;
}
PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
attrs++;
PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
@ -599,7 +546,7 @@ PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
CK_ATTRIBUTE *attrs;
CK_BBOOL ckTrue = CK_TRUE;
CK_OBJECT_CLASS keyclass = CKO_SECRET_KEY;
size_t tsize = 0;
int tsize = 0;
CK_OBJECT_HANDLE key_id;
attrs = findTemp;
@ -1210,10 +1157,10 @@ PK11_KeyGenWithTemplate(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
symKey->owner = PR_FALSE;
} else {
session = symKey->session;
if (session != CK_INVALID_HANDLE)
if (session != CK_INVALID_SESSION)
pk11_EnterKeyMonitor(symKey);
}
if (session == CK_INVALID_HANDLE) {
if (session == CK_INVALID_SESSION) {
PK11_FreeSymKey(symKey);
PORT_SetError(SEC_ERROR_BAD_DATA);
return NULL;
@ -1260,7 +1207,7 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
PK11_Authenticate(slot, PR_TRUE, wincx);
rwsession = PK11_GetRWSession(slot);
if (rwsession == CK_INVALID_HANDLE) {
if (rwsession == CK_INVALID_SESSION) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return NULL;
}
@ -1277,23 +1224,13 @@ PK11_ConvertSessionSymKeyToTokenSymKey(PK11SymKey *symk, void *wincx)
symk->type, newKeyID, PR_FALSE /*owner*/, NULL /*wincx*/);
}
/* This function does a straight public key wrap with the CKM_RSA_PKCS
* mechanism. */
/*
* This function does a straight public key wrap (which only RSA can do).
* Use PK11_PubGenKey and PK11_WrapSymKey to implement the FORTEZZA and
* Diffie-Hellman Ciphers. */
SECStatus
PK11_PubWrapSymKey(CK_MECHANISM_TYPE type, SECKEYPublicKey *pubKey,
PK11SymKey *symKey, SECItem *wrappedKey)
{
CK_MECHANISM_TYPE inferred = pk11_mapWrapKeyType(pubKey->keyType);
return PK11_PubWrapSymKeyWithMechanism(pubKey, inferred, NULL, symKey,
wrappedKey);
}
/* This function wraps a symmetric key with a public key, such as with the
* CKM_RSA_PKCS and CKM_RSA_PKCS_OAEP mechanisms. */
SECStatus
PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey,
CK_MECHANISM_TYPE mechType, SECItem *param,
PK11SymKey *symKey, SECItem *wrappedKey)
{
PK11SlotInfo *slot;
CK_ULONG len = wrappedKey->len;
@ -1310,7 +1247,7 @@ PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey,
}
/* if this slot doesn't support the mechanism, go to a slot that does */
newKey = pk11_ForceSlot(symKey, mechType, CKA_ENCRYPT);
newKey = pk11_ForceSlot(symKey, type, CKA_ENCRYPT);
if (newKey != NULL) {
symKey = newKey;
}
@ -1321,15 +1258,9 @@ PK11_PubWrapSymKeyWithMechanism(SECKEYPublicKey *pubKey,
}
slot = symKey->slot;
mechanism.mechanism = mechType;
if (param == NULL) {
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
} else {
mechanism.pParameter = param->data;
mechanism.ulParameterLen = param->len;
}
mechanism.mechanism = pk11_mapWrapKeyType(pubKey->keyType);
mechanism.pParameter = NULL;
mechanism.ulParameterLen = 0;
id = PK11_ImportPublicKey(slot, pubKey, PR_FALSE);
if (id == CK_INVALID_HANDLE) {
@ -1423,124 +1354,16 @@ pk11_HandWrap(PK11SymKey *wrappingKey, SECItem *param, CK_MECHANISM_TYPE type,
return SECSuccess;
}
/*
* helper function which moves two keys into a new slot based on the
* desired mechanism.
*/
static SECStatus
pk11_moveTwoKeys(CK_MECHANISM_TYPE mech,
CK_ATTRIBUTE_TYPE preferedOperation,
CK_ATTRIBUTE_TYPE movingOperation,
PK11SymKey *preferedKey, PK11SymKey *movingKey,
PK11SymKey **newPreferedKey, PK11SymKey **newMovingKey)
{
PK11SlotInfo *newSlot;
*newMovingKey = NULL;
*newPreferedKey = NULL;
newSlot = PK11_GetBestSlot(mech, preferedKey->cx);
if (newSlot == NULL) {
return SECFailure;
}
*newMovingKey = pk11_CopyToSlot(newSlot, movingKey->type,
movingOperation, movingKey);
if (*newMovingKey == NULL) {
goto loser;
}
*newPreferedKey = pk11_CopyToSlot(newSlot, preferedKey->type,
preferedOperation, preferedKey);
if (*newPreferedKey == NULL) {
goto loser;
}
PK11_FreeSlot(newSlot);
return SECSuccess;
loser:
PK11_FreeSlot(newSlot);
PK11_FreeSymKey(*newMovingKey);
PK11_FreeSymKey(*newPreferedKey);
*newMovingKey = NULL;
*newPreferedKey = NULL;
return SECFailure;
}
/*
* To do joint operations, we often need two keys in the same slot.
* Usually the PKCS #11 wrappers handle this correctly (like for PK11_WrapKey),
* but sometimes the wrappers don't know about mechanism specific keys in
* the Mechanism params. This function makes sure the two keys are in the
* same slot by copying one or both of the keys into a common slot. This
* functions makes sure the slot can handle the target mechanism. If the copy
* is warranted, this function will prefer to move the movingKey first, then
* the preferedKey. If the keys are moved, the new keys are returned in
* newMovingKey and/or newPreferedKey. The application is responsible
* for freeing those keys once the operation is complete.
*/
SECStatus
PK11_SymKeysToSameSlot(CK_MECHANISM_TYPE mech,
CK_ATTRIBUTE_TYPE preferedOperation,
CK_ATTRIBUTE_TYPE movingOperation,
PK11SymKey *preferedKey, PK11SymKey *movingKey,
PK11SymKey **newPreferedKey, PK11SymKey **newMovingKey)
{
/* usually don't return new keys */
*newMovingKey = NULL;
*newPreferedKey = NULL;
if (movingKey->slot == preferedKey->slot) {
/* this should be the most common case */
if ((preferedKey->slot != NULL) &&
PK11_DoesMechanism(preferedKey->slot, mech)) {
return SECSuccess;
}
/* we are in the same slot, but it doesn't do the operation,
* move both keys to an appropriate target slot */
return pk11_moveTwoKeys(mech, preferedOperation, movingOperation,
preferedKey, movingKey,
newPreferedKey, newMovingKey);
}
/* keys are in different slot, try moving the moving key to the prefered
* key's slot */
if ((preferedKey->slot != NULL) &&
PK11_DoesMechanism(preferedKey->slot, mech)) {
*newMovingKey = pk11_CopyToSlot(preferedKey->slot, movingKey->type,
movingOperation, movingKey);
if (*newMovingKey != NULL) {
return SECSuccess;
}
}
/* couldn't moving the moving key to the prefered slot, try moving
* the prefered key */
if ((movingKey->slot != NULL) &&
PK11_DoesMechanism(movingKey->slot, mech)) {
*newPreferedKey = pk11_CopyToSlot(movingKey->slot, preferedKey->type,
preferedOperation, preferedKey);
if (*newPreferedKey != NULL) {
return SECSuccess;
}
}
/* Neither succeeded, but that could be that they were not in slots that
* supported the operation, try moving both keys into a common slot that
* can do the operation. */
return pk11_moveTwoKeys(mech, preferedOperation, movingOperation,
preferedKey, movingKey,
newPreferedKey, newMovingKey);
}
/*
* This function does a symetric based wrap.
*/
SECStatus
PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
PK11SymKey *wrappingKey, PK11SymKey *symKey,
SECItem *wrappedKey)
PK11SymKey *wrappingKey, PK11SymKey *symKey, SECItem *wrappedKey)
{
PK11SlotInfo *slot;
CK_ULONG len = wrappedKey->len;
PK11SymKey *newSymKey = NULL;
PK11SymKey *newWrappingKey = NULL;
PK11SymKey *newKey = NULL;
SECItem *param_save = NULL;
CK_MECHANISM mechanism;
PRBool owner = PR_TRUE;
@ -1548,32 +1371,44 @@ PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
CK_RV crv;
SECStatus rv;
/* force the keys into same slot */
rv = PK11_SymKeysToSameSlot(type, CKA_ENCRYPT, CKA_WRAP,
symKey, wrappingKey,
&newSymKey, &newWrappingKey);
if (rv != SECSuccess) {
/* Couldn't move the keys as desired, try to hand unwrap if possible */
if (symKey->data.data == NULL) {
rv = PK11_ExtractKeyValue(symKey);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_NO_MODULE);
return SECFailure;
/* if this slot doesn't support the mechanism, go to a slot that does */
/* Force symKey and wrappingKey into the same slot */
if ((wrappingKey->slot == NULL) || (symKey->slot != wrappingKey->slot)) {
/* first try copying the wrapping Key to the symKey slot */
if (symKey->slot && PK11_DoesMechanism(symKey->slot, type)) {
newKey = pk11_CopyToSlot(symKey->slot, type, CKA_WRAP, wrappingKey);
}
/* Nope, try it the other way */
if (newKey == NULL) {
if (wrappingKey->slot) {
newKey = pk11_CopyToSlot(wrappingKey->slot,
symKey->type, CKA_ENCRYPT, symKey);
}
/* just not playing... one last thing, can we get symKey's data?
* If it's possible, we it should already be in the
* symKey->data.data pointer because pk11_CopyToSlot would have
* tried to put it there. */
if (newKey == NULL) {
/* Can't get symKey's data: Game Over */
if (symKey->data.data == NULL) {
PORT_SetError(SEC_ERROR_NO_MODULE);
return SECFailure;
}
if (param == NULL) {
param_save = param = PK11_ParamFromIV(type, NULL);
}
rv = pk11_HandWrap(wrappingKey, param, type,
&symKey->data, wrappedKey);
if (param_save)
SECITEM_FreeItem(param_save, PR_TRUE);
return rv;
}
/* we successfully moved the sym Key */
symKey = newKey;
} else {
/* we successfully moved the wrapping Key */
wrappingKey = newKey;
}
if (param == NULL) {
param_save = param = PK11_ParamFromIV(type, NULL);
}
rv = pk11_HandWrap(wrappingKey, param, type, &symKey->data, wrappedKey);
if (param_save)
SECITEM_FreeItem(param_save, PR_TRUE);
return rv;
}
if (newSymKey) {
symKey = newSymKey;
}
if (newWrappingKey) {
wrappingKey = newWrappingKey;
}
/* at this point both keys are in the same token */
@ -1617,8 +1452,8 @@ PK11_WrapSymKey(CK_MECHANISM_TYPE type, SECItem *param,
} else {
wrappedKey->len = len;
}
PK11_FreeSymKey(newSymKey);
PK11_FreeSymKey(newWrappingKey);
if (newKey)
PK11_FreeSymKey(newKey);
if (param_save)
SECITEM_FreeItem(param_save, PR_TRUE);
return rv;
@ -1697,14 +1532,6 @@ PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
* it as a real attribute */
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
* etc. Strip out the real attribute here */
operation &= ~CKA_NSS_MESSAGE_MASK;
}
/* first copy caller attributes in. */
for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
@ -1779,7 +1606,7 @@ PK11_DeriveWithTemplate(PK11SymKey *baseKey, CK_MECHANISM_TYPE derive,
pk11_EnterKeyMonitor(symKey);
session = symKey->session;
}
if (session == CK_INVALID_HANDLE) {
if (session == CK_INVALID_SESSION) {
if (!isPerm)
pk11_ExitKeyMonitor(symKey);
crv = CKR_SESSION_HANDLE_INVALID;
@ -1932,11 +1759,6 @@ pk11_ANSIX963Derive(PK11SymKey *sharedSecret,
else
SharedInfoLen = sharedData->len;
if (SharedInfoLen > PR_UINT32_MAX - 4) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
bufferLen = SharedInfoLen + 4;
/* Populate buffer with Counter || sharedData
@ -2094,15 +1916,6 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
return NULL;
}
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
* it as a real attribute */
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
* etc. Strip out the real attribute here */
operation &= ~CKA_NSS_MESSAGE_MASK;
}
symKey->origin = PK11_OriginDerive;
switch (privKey->keyType) {
@ -2376,14 +2189,6 @@ pk11_PubDeriveECKeyWithKDF(
if (symKey == NULL) {
return NULL;
}
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
* it as a real attribute */
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
* etc. Strip out the real attribute here */
operation &= ~CKA_NSS_MESSAGE_MASK;
}
symKey->origin = PK11_OriginDerive;
@ -2430,7 +2235,7 @@ pk11_PubDeriveECKeyWithKDF(
key_size = SHA512_LENGTH;
break;
default:
PORT_AssertNotReached("Invalid CKD");
PORT_Assert(!"Invalid CKD");
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
return NULL;
}
@ -2706,14 +2511,6 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
/* CKA_NSS_MESSAGE is a fake operation to distinguish between
* Normal Encrypt/Decrypt and MessageEncrypt/Decrypt. Don't try to set
* it as a real attribute */
if ((operation & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) {
/* Message is or'd with a real Attribute (CKA_ENCRYPT, CKA_DECRYPT),
* etc. Strip out the real attribute here */
operation &= ~CKA_NSS_MESSAGE_MASK;
}
/* first copy caller attributes in. */
for (templateCount = 0; templateCount < numAttrs; ++templateCount) {
@ -2822,8 +2619,8 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
pk11_EnterKeyMonitor(symKey);
rwsession = symKey->session;
}
PORT_Assert(rwsession != CK_INVALID_HANDLE);
if (rwsession == CK_INVALID_HANDLE)
PORT_Assert(rwsession != CK_INVALID_SESSION);
if (rwsession == CK_INVALID_SESSION)
crv = CKR_SESSION_HANDLE_INVALID;
else
crv = PK11_GETTAB(slot)->C_UnwrapKey(rwsession, &mechanism, wrappingKey,
@ -2831,7 +2628,7 @@ pk11_AnyUnwrapKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE wrappingKey,
keyTemplate, templateCount,
&symKey->objectID);
if (isPerm) {
if (rwsession != CK_INVALID_HANDLE)
if (rwsession != CK_INVALID_SESSION)
PK11_RestoreROSession(slot, rwsession);
} else {
pk11_ExitKeyMonitor(symKey);
@ -2906,33 +2703,20 @@ PK11_UnwrapSymKeyWithFlagsPerm(PK11SymKey *wrappingKey,
wrappingKey->cx, keyTemplate, templateCount, isPerm);
}
/* unwrap a symmetric key with a private key. Only supports CKM_RSA_PKCS. */
/* unwrap a symetric key with a private key. */
PK11SymKey *
PK11_PubUnwrapSymKey(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize)
{
CK_MECHANISM_TYPE wrapType = pk11_mapWrapKeyType(wrappingKey->keyType);
return PK11_PubUnwrapSymKeyWithMechanism(wrappingKey, wrapType, NULL,
wrappedKey, target, operation,
keySize);
}
/* unwrap a symmetric key with a private key with the given parameters. */
PK11SymKey *
PK11_PubUnwrapSymKeyWithMechanism(SECKEYPrivateKey *wrappingKey,
CK_MECHANISM_TYPE mechType, SECItem *param,
SECItem *wrappedKey, CK_MECHANISM_TYPE target,
CK_ATTRIBUTE_TYPE operation, int keySize)
{
PK11SlotInfo *slot = wrappingKey->pkcs11Slot;
if (SECKEY_HAS_ATTRIBUTE_SET(wrappingKey, CKA_PRIVATE)) {
PK11_HandlePasswordCheck(slot, wrappingKey->wincx);
}
return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID, mechType, param,
wrappedKey, target, operation, keySize,
return pk11_AnyUnwrapKey(slot, wrappingKey->pkcs11ID,
wrapType, NULL, wrappedKey, target, operation, keySize,
wrappingKey->wincx, NULL, 0, PR_FALSE);
}

View file

@ -4,9 +4,6 @@
/*
* Deal with PKCS #11 Slots.
*/
#include <stddef.h>
#include "seccomon.h"
#include "secmod.h"
#include "nssilock.h"
@ -198,7 +195,8 @@ PK11_AddSlotToList(PK11SlotList *list, PK11SlotInfo *slot, PRBool sorted)
PZ_Lock(list->lock);
element = list->head;
/* Insertion sort, with higher cipherOrders are sorted first in the list */
while (element && sorted && (element->slot->module->cipherOrder > le->slot->module->cipherOrder)) {
while (element && sorted && (element->slot->module->cipherOrder >
le->slot->module->cipherOrder)) {
element = element->next;
}
if (element) {
@ -404,7 +402,7 @@ PK11_NewSlotInfo(SECMODModule *mod)
slot->defRWSession = PR_FALSE;
slot->protectedAuthPath = PR_FALSE;
slot->flags = 0;
slot->session = CK_INVALID_HANDLE;
slot->session = CK_INVALID_SESSION;
slot->slotID = 0;
slot->defaultFlags = 0;
slot->refCount = 1;
@ -748,22 +746,22 @@ PK11_GetRWSession(PK11SlotInfo *slot)
haveMonitor = PR_TRUE;
}
if (slot->defRWSession) {
PORT_Assert(slot->session != CK_INVALID_HANDLE);
if (slot->session != CK_INVALID_HANDLE)
PORT_Assert(slot->session != CK_INVALID_SESSION);
if (slot->session != CK_INVALID_SESSION)
return slot->session;
}
crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
CKF_RW_SESSION | CKF_SERIAL_SESSION,
slot, pk11_notify, &rwsession);
PORT_Assert(rwsession != CK_INVALID_HANDLE || crv != CKR_OK);
if (crv != CKR_OK || rwsession == CK_INVALID_HANDLE) {
PORT_Assert(rwsession != CK_INVALID_SESSION || crv != CKR_OK);
if (crv != CKR_OK || rwsession == CK_INVALID_SESSION) {
if (crv == CKR_OK)
crv = CKR_DEVICE_ERROR;
if (haveMonitor)
PK11_ExitSlotMonitor(slot);
PORT_SetError(PK11_MapError(crv));
return CK_INVALID_HANDLE;
return CK_INVALID_SESSION;
}
if (slot->defRWSession) { /* we have the monitor */
slot->session = rwsession;
@ -776,7 +774,7 @@ PK11_RWSessionHasLock(PK11SlotInfo *slot, CK_SESSION_HANDLE session_handle)
{
PRBool hasLock;
hasLock = (PRBool)(!slot->isThreadSafe ||
(slot->defRWSession && slot->session != CK_INVALID_HANDLE));
(slot->defRWSession && slot->session != CK_INVALID_SESSION));
return hasLock;
}
@ -786,7 +784,7 @@ pk11_RWSessionIsDefault(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession)
PRBool isDefault;
isDefault = (PRBool)(slot->session == rwsession &&
slot->defRWSession &&
slot->session != CK_INVALID_HANDLE);
slot->session != CK_INVALID_SESSION);
return isDefault;
}
@ -798,8 +796,8 @@ pk11_RWSessionIsDefault(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession)
void
PK11_RestoreROSession(PK11SlotInfo *slot, CK_SESSION_HANDLE rwsession)
{
PORT_Assert(rwsession != CK_INVALID_HANDLE);
if (rwsession != CK_INVALID_HANDLE) {
PORT_Assert(rwsession != CK_INVALID_SESSION);
if (rwsession != CK_INVALID_SESSION) {
PRBool doExit = PK11_RWSessionHasLock(slot, rwsession);
if (!pk11_RWSessionIsDefault(slot, rwsession))
PK11_GETTAB(slot)
@ -1113,16 +1111,16 @@ PK11_MakeString(PLArenaPool *arena, char *space,
*/
PRBool
pk11_MatchString(const char *string,
const char *staticString, size_t staticStringLen)
const char *staticString, int staticStringLen)
{
size_t i = staticStringLen;
int i;
/* move i to point to the last space */
while (i > 0) {
if (staticString[i - 1] != ' ')
for (i = (staticStringLen - 1); i >= 0; i--) {
if (staticString[i] != ' ')
break;
i--;
}
/* move i to point to the last space */
i++;
if (strlen(string) == i && memcmp(string, staticString, i) == 0) {
return PR_TRUE;
@ -1193,7 +1191,7 @@ pk11_ReadProfileList(PK11SlotInfo *slot)
CK_ATTRIBUTE *attrs;
CK_BBOOL cktrue = CK_TRUE;
CK_OBJECT_CLASS oclass = CKO_PROFILE;
size_t tsize;
int tsize;
int objCount;
CK_OBJECT_HANDLE *handles = NULL;
int i;
@ -1330,7 +1328,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
}
/* Make sure our session handle is valid */
if (slot->session == CK_INVALID_HANDLE) {
if (slot->session == CK_INVALID_SESSION) {
/* we know we don't have a valid session, go get one */
CK_SESSION_HANDLE session;
@ -1366,7 +1364,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
slot, pk11_notify, &slot->session);
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
slot->session = CK_INVALID_HANDLE;
slot->session = CK_INVALID_SESSION;
if (!slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
return SECFailure;
@ -1382,9 +1380,10 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
if (status != PR_SUCCESS)
return SECFailure;
/* Not all tokens have profile objects or even recognize what profile
* objects are it's OK for pk11_ReadProfileList to fail */
(void)pk11_ReadProfileList(slot);
rv = pk11_ReadProfileList(slot);
if (rv != SECSuccess) {
return SECFailure;
}
if (!(slot->isInternal) && (slot->hasRandom)) {
/* if this slot has a random number generater, use it to add entropy
@ -1426,7 +1425,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
/* work around a problem in softoken where it incorrectly
* reports databases opened read only as read/write. */
if (slot->isInternal && !slot->readOnly) {
CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
CK_SESSION_HANDLE session = CK_INVALID_SESSION;
/* try to open a R/W session */
crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID,
@ -1498,8 +1497,8 @@ pk11_isRootSlot(PK11SlotInfo *slot)
{
CK_ATTRIBUTE findTemp[1];
CK_ATTRIBUTE *attrs;
CK_OBJECT_CLASS oclass = CKO_NSS_BUILTIN_ROOT_LIST;
size_t tsize;
CK_OBJECT_CLASS oclass = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
int tsize;
CK_OBJECT_HANDLE handle;
attrs = findTemp;
@ -1540,7 +1539,7 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
* from their slots, and won't unload and disappear
* until all their slots have been freed */
if (PK11_GetSlotInfo(slot, &slotInfo) != SECSuccess) {
if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID, &slotInfo) != CKR_OK) {
slot->disabled = PR_TRUE;
slot->reason = PK11_DIS_COULD_NOT_INIT_TOKEN;
return;
@ -1607,7 +1606,7 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
}
/* permanent slots are always present */
if (slot->isPerm && (slot->session != CK_INVALID_HANDLE)) {
if (slot->isPerm && (slot->session != CK_INVALID_SESSION)) {
return PR_TRUE;
}
@ -1619,45 +1618,44 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
}
/* removable slots have a flag that says they are present */
if (PK11_GetSlotInfo(slot, &slotInfo) != SECSuccess) {
if (!slot->isThreadSafe)
PK11_EnterSlotMonitor(slot);
if (PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID, &slotInfo) != CKR_OK) {
if (!slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
return PR_FALSE;
}
if ((slotInfo.flags & CKF_TOKEN_PRESENT) == 0) {
/* if the slot is no longer present, close the session */
if (slot->session != CK_INVALID_HANDLE) {
if (!slot->isThreadSafe) {
PK11_EnterSlotMonitor(slot);
}
if (slot->session != CK_INVALID_SESSION) {
PK11_GETTAB(slot)
->C_CloseSession(slot->session);
slot->session = CK_INVALID_HANDLE;
if (!slot->isThreadSafe) {
PK11_ExitSlotMonitor(slot);
}
slot->session = CK_INVALID_SESSION;
}
if (!slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
return PR_FALSE;
}
/* use the session Info to determine if the card has been removed and then
* re-inserted */
if (slot->session != CK_INVALID_HANDLE) {
if (slot->isThreadSafe) {
if (slot->session != CK_INVALID_SESSION) {
if (slot->isThreadSafe)
PK11_EnterSlotMonitor(slot);
}
crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session, &sessionInfo);
if (crv != CKR_OK) {
PK11_GETTAB(slot)
->C_CloseSession(slot->session);
slot->session = CK_INVALID_HANDLE;
slot->session = CK_INVALID_SESSION;
}
if (slot->isThreadSafe) {
if (slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
}
}
if (!slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
/* card has not been removed, current token info is correct */
if (slot->session != CK_INVALID_HANDLE)
if (slot->session != CK_INVALID_SESSION)
return PR_TRUE;
/* initialize the token info state */
@ -2132,19 +2130,6 @@ PK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type)
return PR_FALSE;
}
PRBool pk11_filterSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE mechanism,
CK_FLAGS mechanismInfoFlags, unsigned int keySize);
/*
* Check that the given mechanism has the appropriate flags. This function
* presumes that slot can already do the given mechanism.
*/
PRBool
PK11_DoesMechanismFlag(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_FLAGS flags)
{
return !pk11_filterSlot(slot, type, flags, 0);
}
/*
* Return true if a token that can do the desired mechanism exists.
* This allows us to have hardware tokens that can do function XYZ magically
@ -2632,7 +2617,7 @@ SECStatus
PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
{
unsigned char tokenName[32];
size_t tokenNameLen;
int tokenNameLen;
CK_RV crv;
/* reconstruct the token name */
@ -2653,7 +2638,7 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
/* first shutdown the token. Existing sessions will get closed here */
PK11_GETTAB(slot)
->C_CloseAllSessions(slot->slotID);
slot->session = CK_INVALID_HANDLE;
slot->session = CK_INVALID_SESSION;
/* now re-init the token */
crv = PK11_GETTAB(slot)->C_InitToken(slot->slotID,
@ -2706,39 +2691,6 @@ PK11Slot_GetNSSToken(PK11SlotInfo *sl)
return rv;
}
PRBool
pk11slot_GetFIPSStatus(PK11SlotInfo *slot, CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE object, CK_ULONG operationType)
{
SECMODModule *mod = slot->module;
CK_RV crv;
CK_ULONG fipsState = CKS_NSS_FIPS_NOT_OK;
/* handle the obvious conditions:
* 1) the module doesn't have a fipsIndicator - fips state must be false */
if (mod->fipsIndicator == NULL) {
return PR_FALSE;
}
/* 2) the session doesn't exist - fips state must be false */
if (session == CK_INVALID_HANDLE) {
return PR_FALSE;
}
/* go fetch the state */
crv = mod->fipsIndicator(session, object, operationType, &fipsState);
if (crv != CKR_OK) {
return PR_FALSE;
}
return (fipsState == CKS_NSS_FIPS_OK) ? PR_TRUE : PR_FALSE;
}
PRBool
PK11_SlotGetLastFIPSStatus(PK11SlotInfo *slot)
{
return pk11slot_GetFIPSStatus(slot, slot->session, CK_INVALID_HANDLE,
CKT_NSS_SESSION_LAST_CHECK);
}
/*
* wait for a token to change it's state. The application passes in the expected
* new state in event.

View file

@ -96,8 +96,8 @@ SECMOD_Shutdown()
return SECSuccess;
}
PRBool
SECMOD_GetSystemFIPSEnabled(void)
int
secmod_GetSystemFIPSEnabled(void)
{
#ifdef LINUX
#ifndef NSS_FIPS_DISABLED
@ -107,20 +107,20 @@ SECMOD_GetSystemFIPSEnabled(void)
f = fopen("/proc/sys/crypto/fips_enabled", "r");
if (!f) {
return PR_FALSE;
return 0;
}
size = fread(&d, 1, sizeof(d), f);
fclose(f);
if (size != sizeof(d)) {
return PR_FALSE;
return 0;
}
if (d == '1') {
return PR_TRUE;
return 1;
}
#endif
#endif
return PR_FALSE;
return 0;
}
/*
@ -452,13 +452,11 @@ SECMOD_DeleteModule(const char *name, int *type)
SECStatus
SECMOD_DeleteInternalModule(const char *name)
{
#ifndef NSS_FIPS_DISABLED
SECMODModuleList *mlp;
SECMODModuleList **mlpp;
#endif
SECStatus rv = SECFailure;
if (SECMOD_GetSystemFIPSEnabled() || pendingModule) {
if (secmod_GetSystemFIPSEnabled() || pendingModule) {
PORT_SetError(SEC_ERROR_MODULE_STUCK);
return rv;
}
@ -470,7 +468,8 @@ SECMOD_DeleteInternalModule(const char *name)
#ifdef NSS_FIPS_DISABLED
PORT_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR);
return rv;
#else
#endif
SECMOD_GetWriteLock(moduleLock);
for (mlpp = &modules, mlp = modules;
mlp != NULL; mlpp = &mlp->next, mlp = *mlpp) {
@ -542,7 +541,6 @@ SECMOD_DeleteInternalModule(const char *name)
internalModule = newModule; /* adopt the module */
}
return rv;
#endif
}
SECStatus
@ -993,7 +991,7 @@ SECMOD_CanDeleteInternalModule(void)
#ifdef NSS_FIPS_DISABLED
return PR_FALSE;
#else
return (PRBool)((pendingModule == NULL) && !SECMOD_GetSystemFIPSEnabled());
return (PRBool)((pendingModule == NULL) && !secmod_GetSystemFIPSEnabled());
#endif
}
@ -1004,8 +1002,6 @@ SECMOD_CanDeleteInternalModule(void)
* C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
* grow on the caller. It is permissible for the slots to increase between
* successive calls with NULL to get the size.
*
* Caller must not hold a module list read lock.
*/
SECStatus
SECMOD_UpdateSlotList(SECMODModule *mod)
@ -1348,27 +1344,14 @@ loser:
PRBool
SECMOD_HasRemovableSlots(SECMODModule *mod)
{
int i;
PRBool ret = PR_FALSE;
if (!moduleLock) {
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
return ret;
}
SECMOD_GetReadLock(moduleLock);
ret = SECMOD_LockedModuleHasRemovableSlots(mod);
SECMOD_ReleaseReadLock(moduleLock);
return ret;
}
PRBool
SECMOD_LockedModuleHasRemovableSlots(SECMODModule *mod)
{
int i;
PRBool ret;
if (mod->slotCount == 0) {
return PR_TRUE;
}
ret = PR_FALSE;
for (i = 0; i < mod->slotCount; i++) {
PK11SlotInfo *slot = mod->slots[i];
/* perm modules are not inserted or removed */
@ -1378,6 +1361,10 @@ SECMOD_LockedModuleHasRemovableSlots(SECMODModule *mod)
ret = PR_TRUE;
break;
}
if (mod->slotCount == 0) {
ret = PR_TRUE;
}
SECMOD_ReleaseReadLock(moduleLock);
return ret;
}
@ -1395,7 +1382,7 @@ secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass,
PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass));
attrs++;
PK11_SETATTRS(attrs, CKA_NSS_MODULE_SPEC, (unsigned char *)sendSpec,
PK11_SETATTRS(attrs, CKA_NETSCAPE_MODULE_SPEC, (unsigned char *)sendSpec,
strlen(sendSpec) + 1);
attrs++;
@ -1509,7 +1496,7 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
PORT_SetError(SEC_ERROR_NO_MEMORY);
return NULL;
}
rv = secmod_UserDBOp(slot, CKO_NSS_NEWSLOT, sendSpec);
rv = secmod_UserDBOp(slot, CKO_NETSCAPE_NEWSLOT, sendSpec);
PR_smprintf_free(sendSpec);
PK11_FreeSlot(slot);
if (rv != SECSuccess) {
@ -1651,7 +1638,7 @@ SECMOD_CloseUserDB(PK11SlotInfo *slot)
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
}
rv = secmod_UserDBOp(slot, CKO_NSS_DELSLOT, sendSpec);
rv = secmod_UserDBOp(slot, CKO_NETSCAPE_DELSLOT, sendSpec);
PR_smprintf_free(sendSpec);
/* if we are in the delay period for the "isPresent" call, reset
* the delay since we know things have probably changed... */

View file

@ -37,7 +37,6 @@
'pk11cert.c',
'pk11cxt.c',
'pk11err.c',
'pk11hpke.c',
'pk11kea.c',
'pk11list.c',
'pk11load.c',
@ -61,7 +60,7 @@
'defines': [
'SHLIB_SUFFIX=\"<(dll_suffix)\"',
'SHLIB_PREFIX=\"<(dll_prefix)\"',
'NSS_SHLIB_VERSION=\"3\"',
'SHLIB_VERSION=\"3\"',
'SOFTOKEN_SHLIB_VERSION=\"3\"'
]
},

View file

@ -143,31 +143,7 @@ extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags);
extern unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags);
extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags);
/*
* Check to see if the module has removable slots that we may need to
* watch for.
*
* NB: This function acquires the module list lock in order to access
* mod->slotCount and mod->slots. Deadlock can occur if the caller holds the
* module list lock. Callers that already hold the module list lock must use
* SECMOD_LockedModuleHasRemovableSlots instead.
*/
PRBool SECMOD_HasRemovableSlots(SECMODModule *mod);
/*
* Like SECMOD_HasRemovableSlots but this function does not acquire the module
* list lock.
*/
PRBool SECMOD_LockedModuleHasRemovableSlots(SECMODModule *mod);
/*
* this function waits for a token event on any slot of a given module
* This function should not be called from more than one thread of the
* same process (though other threads can make other library calls
* on this module while this call is blocked).
*
* Caller must not hold a module list read lock.
*/
PK11SlotInfo *SECMOD_WaitForAnyTokenEvent(SECMODModule *mod,
unsigned long flags, PRIntervalTime latency);
/*
@ -177,7 +153,6 @@ PK11SlotInfo *SECMOD_WaitForAnyTokenEvent(SECMODModule *mod,
* shutting down the module.
*/
SECStatus SECMOD_CancelWait(SECMODModule *mod);
/*
* check to see if the module has added new slots. PKCS 11 v2.20 allows for
* modules to add new slots, but never remove them. Slots not be added between
@ -185,8 +160,6 @@ SECStatus SECMOD_CancelWait(SECMODModule *mod);
* C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
* grow on the caller. It is permissible for the slots to increase between
* corresponding calls with NULL to get the size.
*
* Caller must not hold a module list read lock.
*/
SECStatus SECMOD_UpdateSlotList(SECMODModule *mod);
SEC_END_PROTOS

View file

@ -7,9 +7,6 @@
*/
#ifndef _SECMODI_H_
#define _SECMODI_H_ 1
#include <stddef.h>
#include "pkcs11.h"
#include "nssilock.h"
#include "secoidt.h"
@ -93,11 +90,11 @@ CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
CK_VOID_PTR pdata);
void pk11_SignedToUnsigned(CK_ATTRIBUTE *attrib);
CK_OBJECT_HANDLE pk11_FindObjectByTemplate(PK11SlotInfo *slot,
CK_ATTRIBUTE *inTemplate, size_t tsize);
CK_ATTRIBUTE *inTemplate, int tsize);
CK_OBJECT_HANDLE *pk11_FindObjectsByTemplate(PK11SlotInfo *slot,
CK_ATTRIBUTE *inTemplate, size_t tsize, int *objCount);
CK_ATTRIBUTE *inTemplate, int tsize, int *objCount);
#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_3_0_PTR)((x)->functionList))
#define PK11_GETTAB(x) ((CK_FUNCTION_LIST_PTR)((x)->functionList))
#define PK11_SETATTRS(x, id, v, l) \
(x)->type = (id); \
(x)->pValue = (v); \
@ -118,6 +115,13 @@ PK11SymKey *pk11_TokenKeyGenWithFlagsAndKeyType(PK11SlotInfo *slot,
CK_MECHANISM_TYPE pk11_GetPBECryptoMechanism(SECAlgorithmID *algid,
SECItem **param, SECItem *pwd, PRBool faulty3DES);
/* Get the state of the system FIPS mode */
/* NSS uses this to force FIPS mode if the system bit is on. Applications which
* use the SECMOD_CanDeleteInteral() to check to see if they can switch to or
* from FIPS mode will automatically be told that they can't swith out of FIPS
* mode */
int secmod_GetSystemFIPSEnabled();
extern void pk11sdr_Init(void);
extern void pk11sdr_Shutdown(void);

View file

@ -73,10 +73,6 @@ 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 */
/* Warning this could go way in future versions of NSS
* when FIPS indicators wind up in the functionList */
CK_NSS_GetFIPSStatus fipsIndicator;
};
/* evControlMask flags */

View file

@ -146,43 +146,27 @@ struct PK11SymKeyStr {
* if necessary. ... Not RefCounted.
*/
struct PK11ContextStr {
CK_ATTRIBUTE_TYPE operation; /* type of operation this context is
* doing (CKA_ENCRYPT, CKA_SIGN,
* CKA_HASH, etc.) */
PK11SymKey *key; /* symetric key for this context */
CK_OBJECT_HANDLE objectID; /* object handle to key */
PK11SlotInfo *slot; /* slot this context is using */
CK_SESSION_HANDLE session; /* session this context is using */
PZLock *sessionLock; /* lock before accessing a PKCS #11
* session */
PRBool ownSession; /* do we own the session? */
void *pwArg; /* applicaton specific passwd arg */
void *savedData; /* save data when we are
* multiplexing on a single context */
unsigned long savedLength; /* length of the saved context */
SECItem *param; /* mechanism parameters used to
* build this context */
PRBool init; /* this contexted been initialized? */
CK_MECHANISM_TYPE type; /* what is the PKCS #11 this context
* is representing (usually what
* algorithm is being used
* (CKM_RSA_PKCS, CKM_DES, CKM_SHA,
* etc. */
PRBool fortezzaHack; /* Fortezza SSL has some special
* non-standard semantics*/
PRBool simulate_message; /* We are initializing a message
* interface but the underlying
* PKCS #11 module does not support
* it. We simulate the interface with
* the PCKS #11 v2 interface */
CK_MECHANISM_TYPE simulate_mechanism; /* The mechanism we are simulating */
PRUint64 ivCounter; /* iv counter for simulated message */
PRUint64 ivMaxCount; /* total number of IVs valid for
* this key */
unsigned long ivLen; /* length of the iv in bytes */
unsigned int ivFixedBits; /* number of bits not generated
* for the iv */
CK_GENERATOR_FUNCTION ivGen; /* PKCS #11 iv generator value */
CK_ATTRIBUTE_TYPE operation; /* type of operation this context is doing
* (CKA_ENCRYPT, CKA_SIGN, CKA_HASH, etc. */
PK11SymKey *key; /* symetric key used in this context */
PK11SlotInfo *slot; /* slot this context is operationing on */
CK_SESSION_HANDLE session; /* session this context is using */
PZLock *sessionLock; /* lock before accessing a PKCS #11
* session */
PRBool ownSession; /* do we own the session? */
void *cx; /* window context in case we need to loggin*/
void *savedData; /* save data when we are multiplexing on a
* single context */
unsigned long savedLength; /* length of the saved context */
SECItem *param; /* mechanism parameters used to build this
context */
PRBool init; /* has this contexted been initialized */
CK_MECHANISM_TYPE type; /* what is the PKCS #11 this context is
* representing (usually what algorithm is
* being used (CKM_RSA_PKCS, CKM_DES,
* CKM_SHA, etc.*/
PRBool fortezzaHack; /* Fortezza SSL has some special
* non-standard semantics*/
};
/*