Update NSS to 3.32.1-RTM

This commit is contained in:
wolfbeast 2018-02-06 11:46:26 +01:00 committed by Roy Tam
commit c91ef9012b
512 changed files with 83203 additions and 16839 deletions

View file

@ -114,7 +114,7 @@ nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
rvSlot->base.refCount = 1;
rvSlot->base.lock = PZ_NewLock(nssILockOther);
rvSlot->base.arena = arena;
rvSlot->pk11slot = nss3slot;
rvSlot->pk11slot = PK11_ReferenceSlot(nss3slot);
rvSlot->epv = nss3slot->functionList;
rvSlot->slotID = nss3slot->slotID;
/* Grab the slot name from the PKCS#11 fixed-length buffer */
@ -150,7 +150,7 @@ nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
return NULL;
}
rvToken->base.arena = arena;
rvToken->pk11slot = nss3slot;
rvToken->pk11slot = PK11_ReferenceSlot(nss3slot);
rvToken->epv = nss3slot->functionList;
rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
nss3slot->session,

View file

@ -886,6 +886,10 @@ PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
PORT_SetError(PK11_MapError(crv));
return -1;
}
if (theTemplate.pValue == NULL) {
PORT_SetError(PK11_MapError(CKR_ATTRIBUTE_VALUE_INVALID));
return -1;
}
length = theTemplate.ulValueLen;
if (*(unsigned char *)theTemplate.pValue == 0) {
length--;

View file

@ -704,9 +704,11 @@ PRBool
PK11_NeedPWInit()
{
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
PRBool ret = PK11_NeedPWInitForSlot(slot);
PK11_FreeSlot(slot);
PRBool ret = PR_FALSE;
if (slot) {
ret = PK11_NeedPWInitForSlot(slot);
PK11_FreeSlot(slot);
}
return ret;
}

View file

@ -34,6 +34,8 @@
#include "pkitm.h"
#include "pkistore.h" /* to remove temp cert */
#include "devt.h"
#include "ckhelper.h"
#include "pkcs11uri.h"
extern const NSSError NSS_ERROR_NOT_FOUND;
extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
@ -507,15 +509,231 @@ transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
nss_ZFreeIf(certs);
}
CERTCertificate *
PK11_FindCertFromNickname(const char *nickname, void *wincx)
static void
transfer_uri_certs_to_collection(nssList *certList, PK11URI *uri,
nssPKIObjectCollection *collection)
{
NSSCertificate **certs;
PRUint32 i, count;
NSSToken **tokens, **tp;
PK11SlotInfo *slot;
const char *id;
id = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_ID);
count = nssList_Count(certList);
if (count == 0) {
return;
}
certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
if (!certs) {
return;
}
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 && (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) {
for (tp = tokens; *tp; tp++) {
const char *value;
slot = (*tp)->pk11slot;
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_TOKEN);
if (value &&
!pk11_MatchString(value,
(char *)slot->tokenInfo.label,
sizeof(slot->tokenInfo.label))) {
continue;
}
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MANUFACTURER);
if (value &&
!pk11_MatchString(value,
(char *)slot->tokenInfo.manufacturerID,
sizeof(slot->tokenInfo.manufacturerID))) {
continue;
}
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MODEL);
if (value &&
!pk11_MatchString(value,
(char *)slot->tokenInfo.model,
sizeof(slot->tokenInfo.model))) {
continue;
}
nssPKIObjectCollection_AddObject(collection,
(nssPKIObject *)certs[i]);
break;
}
nssTokenArray_Destroy(tokens);
}
CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(certs[i]));
}
nss_ZFreeIf(certs);
}
static NSSCertificate **
find_certs_from_uri(const char *uriString, void *wincx)
{
PK11URI *uri = NULL;
CK_ATTRIBUTE attributes[10];
CK_ULONG nattributes = 0;
const char *label;
PK11SlotInfo *slotinfo;
nssCryptokiObject **instances;
PRStatus status;
CERTCertificate *rvCert = NULL;
nssPKIObjectCollection *collection = NULL;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
NSSCertificate **certs = NULL;
nssList *certList = NULL;
SECStatus rv;
CK_OBJECT_CLASS s_class = CKO_CERTIFICATE;
static const CK_BBOOL s_true = CK_TRUE;
NSSToken **tokens, **tok;
uri = PK11URI_ParseURI(uriString);
if (uri == NULL) {
goto loser;
}
collection = nssCertificateCollection_Create(defaultTD, NULL);
if (!collection) {
goto loser;
}
certList = nssList_Create(NULL, PR_FALSE);
if (!certList) {
goto loser;
}
label = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_OBJECT);
if (label) {
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
(const char *)label,
certList);
} else {
(void)nssTrustDomain_GetCertsFromCache(defaultTD, certList);
}
transfer_uri_certs_to_collection(certList, uri, collection);
/* add the CKA_CLASS and CKA_TOKEN attributes manually */
attributes[nattributes].type = CKA_CLASS;
attributes[nattributes].pValue = (void *)&s_class;
attributes[nattributes].ulValueLen = sizeof(s_class);
nattributes++;
attributes[nattributes].type = CKA_TOKEN;
attributes[nattributes].pValue = (void *)&s_true;
attributes[nattributes].ulValueLen = sizeof(s_true);
nattributes++;
if (label) {
attributes[nattributes].type = CKA_LABEL;
attributes[nattributes].pValue = (void *)label;
attributes[nattributes].ulValueLen = strlen(label);
nattributes++;
}
tokens = NSSTrustDomain_FindTokensByURI(defaultTD, uri);
for (tok = tokens; tok && *tok; tok++) {
if (nssToken_IsPresent(*tok)) {
slotinfo = (*tok)->pk11slot;
rv = pk11_AuthenticateUnfriendly(slotinfo, PR_TRUE, wincx);
if (rv != SECSuccess) {
continue;
}
instances = nssToken_FindObjectsByTemplate(*tok, NULL,
attributes,
nattributes,
0, &status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
}
nssToken_Destroy(*tok);
}
nss_ZFreeIf(tokens);
nssList_Destroy(certList);
certs = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL);
loser:
if (collection) {
nssPKIObjectCollection_Destroy(collection);
}
if (uri) {
PK11URI_DestroyURI(uri);
}
return certs;
}
CERTCertificate *
PK11_FindCertFromURI(const char *uri, void *wincx)
{
static const NSSUsage usage = { PR_TRUE /* ... */ };
NSSCertificate *cert = NULL;
NSSCertificate **certs = NULL;
static const NSSUsage usage = { PR_TRUE /* ... */ };
NSSToken *token;
CERTCertificate *rvCert = NULL;
certs = find_certs_from_uri(uri, wincx);
if (certs) {
cert = nssCertificateArray_FindBestCertificate(certs, NULL,
&usage, NULL);
if (cert) {
rvCert = STAN_GetCERTCertificateOrRelease(cert);
}
nssCertificateArray_Destroy(certs);
}
return rvCert;
}
CERTCertList *
PK11_FindCertsFromURI(const char *uri, void *wincx)
{
int i;
CERTCertList *certList = NULL;
NSSCertificate **foundCerts;
NSSCertificate *c;
foundCerts = find_certs_from_uri(uri, wincx);
if (foundCerts) {
PRTime now = PR_Now();
certList = CERT_NewCertList();
for (i = 0, c = *foundCerts; c; c = foundCerts[++i]) {
if (certList) {
CERTCertificate *certCert = STAN_GetCERTCertificateOrRelease(c);
/* c may be invalid after this, don't reference it */
if (certCert) {
/* CERT_AddCertToListSorted adopts certCert */
CERT_AddCertToListSorted(certList, certCert,
CERT_SortCBValidity, &now);
}
} else {
nssCertificate_Destroy(c);
}
}
if (certList && CERT_LIST_HEAD(certList) == NULL) {
CERT_DestroyCertList(certList);
certList = NULL;
}
/* all the certs have been adopted or freed, free the raw array */
nss_ZFreeIf(foundCerts);
}
return certList;
}
static NSSCertificate **
find_certs_from_nickname(const char *nickname, void *wincx)
{
PRStatus status;
NSSCertificate **certs = NULL;
NSSToken *token = NULL;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
PK11SlotInfo *slot = NULL;
SECStatus rv;
@ -523,6 +741,11 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx)
char *delimit = NULL;
char *tokenName;
if (!strncmp(nickname, "pkcs11:", strlen("pkcs11:"))) {
certs = find_certs_from_uri(nickname, wincx);
if (certs)
return certs;
}
nickCopy = PORT_Strdup(nickname);
if (!nickCopy) {
/* error code is set */
@ -543,6 +766,11 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx)
} else {
slot = PK11_GetInternalKeySlot();
token = PK11Slot_GetNSSToken(slot);
if (token) {
nssToken_AddRef(token);
} else {
PORT_SetError(SEC_ERROR_NO_TOKEN);
}
}
if (token) {
nssList *certList;
@ -600,29 +828,38 @@ PK11_FindCertFromNickname(const char *nickname, void *wincx)
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
if (certs) {
cert = nssCertificateArray_FindBestCertificate(certs, NULL,
&usage, NULL);
if (cert) {
rvCert = STAN_GetCERTCertificateOrRelease(cert);
}
nssCertificateArray_Destroy(certs);
}
nssList_Destroy(certList);
}
if (slot) {
PK11_FreeSlot(slot);
}
if (nickCopy)
PORT_Free(nickCopy);
return rvCert;
loser:
if (token) {
nssToken_Destroy(token);
}
if (slot) {
PK11_FreeSlot(slot);
}
if (nickCopy)
PORT_Free(nickCopy);
return NULL;
return certs;
}
CERTCertificate *
PK11_FindCertFromNickname(const char *nickname, void *wincx)
{
CERTCertificate *rvCert = NULL;
NSSCertificate *cert = NULL;
NSSCertificate **certs = NULL;
static const NSSUsage usage = { PR_TRUE /* ... */ };
certs = find_certs_from_nickname(nickname, wincx);
if (certs) {
cert = nssCertificateArray_FindBestCertificate(certs, NULL,
&usage, NULL);
if (cert) {
rvCert = STAN_GetCERTCertificateOrRelease(cert);
}
nssCertificateArray_Destroy(certs);
}
return rvCert;
}
/* Traverse slots callback */
@ -690,8 +927,7 @@ PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
}
/* empty list? */
if (CERT_LIST_HEAD(cbparam.certList) == NULL ||
CERT_LIST_END(CERT_LIST_HEAD(cbparam.certList), cbparam.certList)) {
if (CERT_LIST_EMPTY(cbparam.certList)) {
CERT_DestroyCertList(cbparam.certList);
cbparam.certList = NULL;
}
@ -703,111 +939,12 @@ PK11_FindCertsFromEmailAddress(const char *email, void *wincx)
CERTCertList *
PK11_FindCertsFromNickname(const char *nickname, void *wincx)
{
char *nickCopy;
char *delimit = NULL;
char *tokenName;
int i;
CERTCertList *certList = NULL;
nssPKIObjectCollection *collection = NULL;
NSSCertificate **foundCerts = NULL;
NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain();
NSSCertificate *c;
NSSToken *token;
PK11SlotInfo *slot;
SECStatus rv;
nickCopy = PORT_Strdup(nickname);
if (!nickCopy) {
/* error code is set */
return NULL;
}
if ((delimit = PORT_Strchr(nickCopy, ':')) != NULL) {
tokenName = nickCopy;
nickname = delimit + 1;
*delimit = '\0';
/* find token by name */
token = NSSTrustDomain_FindTokenByName(defaultTD, (NSSUTF8 *)tokenName);
if (token) {
slot = PK11_ReferenceSlot(token->pk11slot);
} else {
PORT_SetError(SEC_ERROR_NO_TOKEN);
slot = NULL;
}
*delimit = ':';
} else {
slot = PK11_GetInternalKeySlot();
token = PK11Slot_GetNSSToken(slot);
}
if (token) {
PRStatus status;
nssList *nameList;
nssCryptokiObject **instances;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
rv = pk11_AuthenticateUnfriendly(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
PK11_FreeSlot(slot);
if (nickCopy)
PORT_Free(nickCopy);
return NULL;
}
collection = nssCertificateCollection_Create(defaultTD, NULL);
if (!collection) {
PK11_FreeSlot(slot);
if (nickCopy)
PORT_Free(nickCopy);
return NULL;
}
nameList = nssList_Create(NULL, PR_FALSE);
if (!nameList) {
PK11_FreeSlot(slot);
if (nickCopy)
PORT_Free(nickCopy);
return NULL;
}
(void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
nickname,
nameList);
transfer_token_certs_to_collection(nameList, token, collection);
instances = nssToken_FindCertificatesByNickname(token,
NULL,
nickname,
tokenOnly,
0,
&status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
/* if it wasn't found, repeat the process for email address */
if (nssPKIObjectCollection_Count(collection) == 0 &&
PORT_Strchr(nickname, '@') != NULL) {
char *lowercaseName = CERT_FixupEmailAddr(nickname);
if (lowercaseName) {
(void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
lowercaseName,
nameList);
transfer_token_certs_to_collection(nameList, token, collection);
instances = nssToken_FindCertificatesByEmail(token,
NULL,
lowercaseName,
tokenOnly,
0,
&status);
nssPKIObjectCollection_AddInstances(collection, instances, 0);
nss_ZFreeIf(instances);
PORT_Free(lowercaseName);
}
}
nssList_Destroy(nameList);
foundCerts = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
nssPKIObjectCollection_Destroy(collection);
}
if (slot) {
PK11_FreeSlot(slot);
}
if (nickCopy)
PORT_Free(nickCopy);
foundCerts = find_certs_from_nickname(nickname, wincx);
if (foundCerts) {
PRTime now = PR_Now();
certList = CERT_NewCertList();
@ -824,10 +961,6 @@ PK11_FindCertsFromNickname(const char *nickname, void *wincx)
nssCertificate_Destroy(c);
}
}
if (certList && CERT_LIST_HEAD(certList) == NULL) {
CERT_DestroyCertList(certList);
certList = NULL;
}
/* all the certs have been adopted or freed, free the raw array */
nss_ZFreeIf(foundCerts);
}
@ -979,8 +1112,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace);
c->object.cryptoContext = NULL;
CERT_LockCertTempPerm(cert);
cert->istemp = PR_FALSE;
cert->isperm = PR_TRUE;
CERT_UnlockCertTempPerm(cert);
}
/* add the new instance to the cert, force an update of the

View file

@ -17,6 +17,10 @@
#include "secerr.h"
#include "prenv.h"
#include "utilparst.h"
#include "prio.h"
#include "prprf.h"
#include <stdio.h>
#include "prsystem.h"
#define DEBUG_MODULE 1
@ -350,6 +354,7 @@ SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod)
}
}
#ifndef NSS_TEST_BUILD
static const char *my_shlib_name =
SHLIB_PREFIX "nss" SHLIB_VERSION "." SHLIB_SUFFIX;
static const char *softoken_shlib_name =
@ -359,11 +364,6 @@ static PRCallOnceType loadSoftokenOnce;
static PRLibrary *softokenLib;
static PRInt32 softokenLoadCount;
#include "prio.h"
#include "prprf.h"
#include <stdio.h>
#include "prsystem.h"
/* This function must be run only once. */
/* determine if hybrid platform, then actually load the DSO. */
static PRStatus
@ -380,6 +380,10 @@ softoken_LoadDSO(void)
}
return PR_FAILURE;
}
#else
CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList);
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
#endif
/*
* load a new module into our address space and initialize it.
@ -398,8 +402,11 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
if (mod->loaded)
return SECSuccess;
/* intenal modules get loaded from their internal list */
/* internal modules get loaded from their internal list */
if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_TEST_BUILD
entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
#else
/*
* Loads softoken as a dynamic library,
* even though the rest of NSS assumes this as the "internal" module.
@ -420,10 +427,15 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
if (!entry)
return SECFailure;
#endif
if (mod->isModuleDB) {
mod->moduleDBFunc = (CK_C_GetFunctionList)
#ifdef NSS_TEST_BUILD
NSC_ModuleDBFunc;
#else
PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
#endif
}
if (mod->moduleDBOnly) {
@ -601,6 +613,7 @@ SECMOD_UnloadModule(SECMODModule *mod)
* if not, we should change this to SECFailure and move it above the
* mod->loaded = PR_FALSE; */
if (mod->internal && (mod->dllName == NULL)) {
#ifndef NSS_TEST_BUILD
if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) {
if (softokenLib) {
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
@ -616,6 +629,7 @@ SECMOD_UnloadModule(SECMODModule *mod)
}
loadSoftokenOnce = pristineCallOnce;
}
#endif
return SECSuccess;
}

View file

@ -612,6 +612,10 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE type, int size)
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_NETSCAPE_PBE_SHA1_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:

View file

@ -156,8 +156,8 @@ PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
* check to see if a bool has been set.
*/
CK_BBOOL
PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type, PRBool haslock)
pk11_HasAttributeSet_Lock(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type, PRBool haslock)
{
CK_BBOOL ckvalue = CK_FALSE;
CK_ATTRIBUTE theTemplate;
@ -181,6 +181,14 @@ PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
return ckvalue;
}
CK_BBOOL
PK11_HasAttributeSet(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type, PRBool haslock)
{
PR_ASSERT(haslock == PR_FALSE);
return pk11_HasAttributeSet_Lock(slot, id, type, PR_FALSE);
}
/*
* returns a full list of attributes. Allocate space for them. If an arena is
* provided, allocate space out of the arena.
@ -2020,6 +2028,9 @@ PK11_FindObjectsFromNickname(char *nickname, PK11SlotInfo **slotptr,
if ((delimit = PORT_Strchr(nickname, ':')) != NULL) {
int len = delimit - nickname;
tokenName = (char *)PORT_Alloc(len + 1);
if (!tokenName) {
return CK_INVALID_HANDLE;
}
PORT_Memcpy(tokenName, nickname, len);
tokenName[len] = 0;

View file

@ -4,6 +4,7 @@
#include "plarena.h"
#include "blapit.h"
#include "seccomon.h"
#include "secitem.h"
#include "secport.h"
@ -301,17 +302,49 @@ SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
return SEC_OID_UNKNOWN;
}
static PRBool
sec_pkcs5_is_algorithm_v2_aes_algorithm(SECOidTag algorithm)
{
switch (algorithm) {
case SEC_OID_AES_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:
return AES_192_KEY_LENGTH;
case SEC_OID_AES_256_CBC:
return AES_256_KEY_LENGTH;
default:
break;
}
return 0;
}
/*
* get the key length in bytes from a PKCS5 PBE
*/
int
sec_pkcs5v2_key_length(SECAlgorithmID *algid)
static int
sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId)
{
SECOidTag algorithm;
PLArenaPool *arena = NULL;
SEC_PKCS5PBEParameter p5_param;
SECStatus rv;
int length = -1;
SECOidTag cipherAlg = SEC_OID_UNKNOWN;
algorithm = SECOID_GetAlgorithmTag(algid);
/* sanity check, they should all be PBKDF2 here */
@ -330,8 +363,20 @@ sec_pkcs5v2_key_length(SECAlgorithmID *algid)
goto loser;
}
if (p5_param.keyLength.data != NULL) {
if (cipherAlgId)
cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId);
if (sec_pkcs5_is_algorithm_v2_aes_algorithm(cipherAlg)) {
length = sec_pkcs5v2_aes_key_length(cipherAlg);
} else if (p5_param.keyLength.data != NULL) {
length = DER_GetInteger(&p5_param.keyLength);
} else {
CK_MECHANISM_TYPE cipherMech;
cipherMech = PK11_AlgtagToMechanism(cipherAlg);
if (cipherMech == CKM_INVALID_MECHANISM) {
goto loser;
}
length = PK11_GetMaxKeyLength(cipherMech);
}
loser:
@ -375,14 +420,15 @@ SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
return 16;
case SEC_OID_PKCS5_PBKDF2:
return sec_pkcs5v2_key_length(algid);
return sec_pkcs5v2_key_length(algid, NULL);
case SEC_OID_PKCS5_PBES2:
case SEC_OID_PKCS5_PBMAC1: {
sec_pkcs5V2Parameter *pbeV2_param;
int length = -1;
pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid);
if (pbeV2_param != NULL) {
length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId);
length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId,
&pbeV2_param->cipherAlgId);
sec_pkcs5_v2_destroy_v2_param(pbeV2_param);
}
return length;
@ -614,6 +660,8 @@ 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 {
CK_MECHANISM_TYPE cryptoMech;
cryptoMech = PK11_AlgtagToMechanism(cipherAlgorithm);

View file

@ -64,6 +64,19 @@ struct SECKEYDHPrivateKeyStr {
};
typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;
/*
** Elliptic Curve Private Key structures
** <https://tools.ietf.org/html/rfc5915#section-3>
*/
struct SECKEYECPrivateKeyStr {
PLArenaPool *arena;
SECItem version;
SECItem curveOID; /* optional/ignored */
SECItem publicValue; /* required (for now) */
SECItem privateValue;
};
typedef struct SECKEYECPrivateKeyStr SECKEYECPrivateKey;
/*
** raw private key object
*/
@ -74,6 +87,7 @@ struct SECKEYRawPrivateKeyStr {
SECKEYRSAPrivateKey rsa;
SECKEYDSAPrivateKey dsa;
SECKEYDHPrivateKey dh;
SECKEYECPrivateKey ec;
} u;
};
typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
@ -139,6 +153,33 @@ const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) },
};
#ifndef NSS_DISABLE_ECC
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.ec.version) },
{ SEC_ASN1_OCTET_STRING,
offsetof(SECKEYRawPrivateKey, u.ec.privateValue) },
/* This value will always be ignored. u.ec.curveOID will always be
* overriden with the outer AlgorithmID.parameters. */
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
SEC_ASN1_XTRN | 0,
offsetof(SECKEYRawPrivateKey, u.ec.curveOID),
SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
/* The public value is optional per RFC, but required in NSS. We
* can't do scalar mult on ECs to get a raw point with PK11 APIs. */
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
SEC_ASN1_XTRN | 1,
offsetof(SECKEYRawPrivateKey, u.ec.publicValue),
SEC_ASN1_SUB(SEC_BitStringTemplate) },
{ 0 }
};
#endif /* NSS_DISABLE_ECC */
const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
@ -198,6 +239,15 @@ prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
key->u.dh.base.type = siUnsignedInteger;
}
static void
prepare_ec_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
{
key->u.ec.version.type = siUnsignedInteger;
key->u.ec.curveOID.type = siUnsignedInteger;
key->u.ec.privateValue.type = siUnsignedInteger;
key->u.ec.publicValue.type = siUnsignedInteger;
}
SECStatus
PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
SECItem *nickname, SECItem *publicValue, PRBool isPerm,
@ -432,7 +482,50 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
lpk->u.dh.privateValue.len);
attrs++;
break;
/* what about fortezza??? */
#ifndef NSS_DISABLE_ECC
case ecKey:
keyType = CKK_EC;
if (lpk->u.ec.publicValue.len == 0) {
goto loser;
}
if (PK11_IsInternal(slot)) {
PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
lpk->u.ec.publicValue.data,
lpk->u.ec.publicValue.len);
attrs++;
}
PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
: &ckfalse,
sizeof(CK_BBOOL));
attrs++;
PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
(keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
: &ckfalse,
sizeof(CK_BBOOL));
attrs++;
PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue
: &ckfalse,
sizeof(CK_BBOOL));
attrs++;
ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue);
if (ck_id == NULL) {
goto loser;
}
PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
attrs++;
signedattr = attrs;
/* curveOID always is a copy of AlgorithmID.parameters. */
PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data,
lpk->u.ec.curveOID.len);
attrs++;
PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data,
lpk->u.ec.privateValue.len);
attrs++;
PK11_SETATTRS(attrs, CKA_EC_POINT, lpk->u.ec.publicValue.data,
lpk->u.ec.publicValue.len);
attrs++;
break;
#endif /* NSS_DISABLE_ECC */
default:
PORT_SetError(SEC_ERROR_BAD_KEY);
goto loser;
@ -513,6 +606,15 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
paramDest = NULL;
lpk->keyType = dhKey;
break;
#ifndef NSS_DISABLE_ECC
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
prepare_ec_priv_key_export_for_asn1(lpk);
keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
paramTemplate = NULL;
paramDest = NULL;
lpk->keyType = ecKey;
break;
#endif /* NSS_DISABLE_ECC */
default:
keyTemplate = NULL;
@ -526,10 +628,25 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
}
/* decode the private key and any algorithm parameters */
rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
if (rv != SECSuccess) {
goto loser;
}
#ifndef NSS_DISABLE_ECC
if (lpk->keyType == ecKey) {
/* Convert length in bits to length in bytes. */
lpk->u.ec.publicValue.len >>= 3;
/* Always override curveOID, we're ignoring any given value. */
rv = SECITEM_CopyItem(arena, &lpk->u.ec.curveOID,
&pki->algorithm.parameters);
if (rv != SECSuccess) {
goto loser;
}
}
#endif /* NSS_DISABLE_ECC */
if (paramDest && paramTemplate) {
rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
&(pki->algorithm.parameters));

View file

@ -14,6 +14,7 @@
#include "seccomon.h"
#include "pkcs7t.h"
#include "cmsreclist.h"
#include "pkcs11uri.h"
/*
* These are the private NSS functions. They are not exported by nss.def, and
@ -39,12 +40,15 @@ int PK11_GetMaxKeyLength(CK_MECHANISM_TYPE type);
* Generic Slot Management
************************************************************/
CK_OBJECT_HANDLE PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject);
PRBool pk11_MatchUriTokenInfo(PK11SlotInfo *slot, PK11URI *uri);
SECStatus PK11_ReadAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type, PLArenaPool *arena, SECItem *result);
CK_ULONG PK11_ReadULongAttribute(PK11SlotInfo *slot, CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type);
char *PK11_MakeString(PLArenaPool *arena, char *space, char *staticSring,
int stringLen);
PRBool pk11_MatchString(const char *string,
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);
@ -106,6 +110,7 @@ CK_OBJECT_HANDLE PK11_FindObjectForCert(CERTCertificate *cert,
void *wincx, PK11SlotInfo **pSlot);
PK11SymKey *pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type,
CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey);
unsigned int pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType);
/**********************************************************************
* Certs
@ -118,10 +123,10 @@ CK_OBJECT_HANDLE *PK11_FindObjectsFromNickname(char *nickname,
void *wincx);
CK_OBJECT_HANDLE PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE peer,
CK_OBJECT_CLASS o_class);
CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot,
CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type,
PRBool haslock);
CK_BBOOL pk11_HasAttributeSet_Lock(PK11SlotInfo *slot,
CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type,
PRBool haslock);
CK_RV PK11_GetAttributes(PLArenaPool *arena, PK11SlotInfo *slot,
CK_OBJECT_HANDLE obj, CK_ATTRIBUTE *attr, int count);
int PK11_NumberCertsForCertSubject(CERTCertificate *cert);

View file

@ -76,6 +76,7 @@ PRBool PK11_IsReadOnly(PK11SlotInfo *slot);
PRBool PK11_IsInternal(PK11SlotInfo *slot);
PRBool PK11_IsInternalKeySlot(PK11SlotInfo *slot);
char *PK11_GetTokenName(PK11SlotInfo *slot);
char *PK11_GetTokenURI(PK11SlotInfo *slot);
char *PK11_GetSlotName(PK11SlotInfo *slot);
PRBool PK11_NeedLogin(PK11SlotInfo *slot);
PRBool PK11_IsFriendly(PK11SlotInfo *slot);
@ -135,6 +136,7 @@ PK11TokenStatus PK11_WaitForTokenEvent(PK11SlotInfo *slot, PK11TokenEvent event,
PRBool PK11_NeedPWInit(void);
PRBool PK11_TokenExists(CK_MECHANISM_TYPE);
SECStatus PK11_GetModInfo(SECMODModule *mod, CK_INFO *info);
char *PK11_GetModuleURI(SECMODModule *mod);
PRBool PK11_IsFIPS(void);
SECMODModule *PK11_GetModule(PK11SlotInfo *slot);
@ -642,6 +644,8 @@ SECStatus PK11_TraverseSlotCerts(
SECStatus (*callback)(CERTCertificate *, SECItem *, void *),
void *arg, void *wincx);
CERTCertificate *PK11_FindCertFromNickname(const char *nickname, void *wincx);
CERTCertificate *PK11_FindCertFromURI(const char *uri, void *wincx);
CERTCertList *PK11_FindCertsFromURI(const char *uri, void *wincx);
CERTCertList *PK11_FindCertsFromEmailAddress(const char *email, void *wincx);
CERTCertList *PK11_FindCertsFromNickname(const char *nickname, void *wincx);
CERTCertificate *PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey);
@ -686,6 +690,10 @@ CERTCertList *PK11_ListCerts(PK11CertListType type, void *pwarg);
CERTCertList *PK11_ListCertsInSlot(PK11SlotInfo *slot);
CERTSignedCrl *PK11_ImportCRL(PK11SlotInfo *slot, SECItem *derCRL, char *url,
int type, void *wincx, PRInt32 importOptions, PLArenaPool *arena, PRInt32 decodeOptions);
CK_BBOOL PK11_HasAttributeSet(PK11SlotInfo *slot,
CK_OBJECT_HANDLE id,
CK_ATTRIBUTE_TYPE type,
PRBool haslock /* must be set to PR_FALSE */);
/**********************************************************************
* Sign/Verify

View file

@ -18,6 +18,8 @@
#include "secerr.h"
#include "hasht.h"
static ECPointEncoding pk11_ECGetPubkeyEncoding(const SECKEYPublicKey *pubKey);
static void
pk11_EnterKeyMonitor(PK11SymKey *symKey)
{
@ -2005,7 +2007,7 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey,
/* old PKCS #11 spec was ambiguous on what needed to be passed,
* try this again with and encoded public key */
if (crv != CKR_OK) {
if (crv != CKR_OK && pk11_ECGetPubkeyEncoding(pubKey) != ECPoint_XOnly) {
SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
&pubKey->u.ec.publicValue,
SEC_ASN1_GET(SEC_OctetStringTemplate));
@ -2211,6 +2213,11 @@ pk11_PubDeriveECKeyWithKDF(
/* old PKCS #11 spec was ambiguous on what needed to be passed,
* try this again with an encoded public key */
if (crv != CKR_OK) {
/* For curves that only use X as public value and no encoding we don't
* have to try again. (Currently only Curve25519) */
if (pk11_ECGetPubkeyEncoding(pubKey) == ECPoint_XOnly) {
goto loser;
}
SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
&pubKey->u.ec.publicValue,
SEC_ASN1_GET(SEC_OctetStringTemplate));

View file

@ -18,6 +18,7 @@
#include "dev3hack.h"
#include "pkim.h"
#include "utilpars.h"
#include "pkcs11uri.h"
/*************************************************************
* local static and global data
@ -409,6 +410,7 @@ PK11_NewSlotInfo(SECMODModule *mod)
slot->slot_name[0] = 0;
slot->token_name[0] = 0;
PORT_Memset(slot->serial, ' ', sizeof(slot->serial));
PORT_Memset(&slot->tokenInfo, 0, sizeof(slot->tokenInfo));
slot->module = NULL;
slot->authTransact = 0;
slot->authTime = LL_ZERO;
@ -1076,6 +1078,29 @@ PK11_MakeString(PLArenaPool *arena, char *space,
return newString;
}
/*
* check if a null-terminated string matches with a PKCS11 Static Label
*/
PRBool
pk11_MatchString(const char *string,
const char *staticString, int staticStringLen)
{
int i;
for (i = (staticStringLen - 1); i >= 0; i--) {
if (staticString[i] != ' ')
break;
}
/* move i to point to the last space */
i++;
if (strlen(string) == i && memcmp(string, staticString, i) == 0) {
return PR_TRUE;
}
return PR_FALSE;
}
/*
* Reads in the slots mechanism list for later use
*/
@ -1140,7 +1165,6 @@ PK11_ReadMechanismList(PK11SlotInfo *slot)
SECStatus
PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
{
CK_TOKEN_INFO tokenInfo;
CK_RV crv;
SECStatus rv;
PRStatus status;
@ -1148,7 +1172,7 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
/* set the slot flags to the current token values */
if (!slot->isThreadSafe)
PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &tokenInfo);
crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &slot->tokenInfo);
if (!slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
@ -1159,13 +1183,13 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
/* set the slot flags to the current token values */
slot->series++; /* allow other objects to detect that the
* slot is different */
slot->flags = tokenInfo.flags;
slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE);
slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE);
slot->flags = slot->tokenInfo.flags;
slot->needLogin = ((slot->tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE);
slot->readOnly = ((slot->tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE);
slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
slot->hasRandom = ((slot->tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
slot->protectedAuthPath =
((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
((slot->tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
? PR_TRUE
: PR_FALSE);
slot->lastLoginCheck = 0;
@ -1176,15 +1200,15 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
slot->protectedAuthPath = PR_FALSE;
}
(void)PK11_MakeString(NULL, slot->token_name,
(char *)tokenInfo.label, sizeof(tokenInfo.label));
slot->minPassword = tokenInfo.ulMinPinLen;
slot->maxPassword = tokenInfo.ulMaxPinLen;
PORT_Memcpy(slot->serial, tokenInfo.serialNumber, sizeof(slot->serial));
(char *)slot->tokenInfo.label, sizeof(slot->tokenInfo.label));
slot->minPassword = slot->tokenInfo.ulMinPinLen;
slot->maxPassword = slot->tokenInfo.ulMaxPinLen;
PORT_Memcpy(slot->serial, slot->tokenInfo.serialNumber, sizeof(slot->serial));
nssToken_UpdateName(slot->nssToken);
slot->defRWSession = (PRBool)((!slot->readOnly) &&
(tokenInfo.ulMaxSessionCount == 1));
(slot->tokenInfo.ulMaxSessionCount == 1));
rv = PK11_ReadMechanismList(slot);
if (rv != SECSuccess)
return rv;
@ -1193,13 +1217,13 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
slot->RSAInfoFlags = 0;
/* initialize the maxKeyCount value */
if (tokenInfo.ulMaxSessionCount == 0) {
if (slot->tokenInfo.ulMaxSessionCount == 0) {
slot->maxKeyCount = 800; /* should be #define or a config param */
} else if (tokenInfo.ulMaxSessionCount < 20) {
} else if (slot->tokenInfo.ulMaxSessionCount < 20) {
/* don't have enough sessions to keep that many keys around */
slot->maxKeyCount = 0;
} else {
slot->maxKeyCount = tokenInfo.ulMaxSessionCount / 2;
slot->maxKeyCount = slot->tokenInfo.ulMaxSessionCount / 2;
}
/* Make sure our session handle is valid */
@ -1331,13 +1355,12 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
SECStatus
PK11_TokenRefresh(PK11SlotInfo *slot)
{
CK_TOKEN_INFO tokenInfo;
CK_RV crv;
/* set the slot flags to the current token values */
if (!slot->isThreadSafe)
PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &tokenInfo);
crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID, &slot->tokenInfo);
if (!slot->isThreadSafe)
PK11_ExitSlotMonitor(slot);
if (crv != CKR_OK) {
@ -1345,12 +1368,12 @@ PK11_TokenRefresh(PK11SlotInfo *slot)
return SECFailure;
}
slot->flags = tokenInfo.flags;
slot->needLogin = ((tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE);
slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE);
slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
slot->flags = slot->tokenInfo.flags;
slot->needLogin = ((slot->tokenInfo.flags & CKF_LOGIN_REQUIRED) ? PR_TRUE : PR_FALSE);
slot->readOnly = ((slot->tokenInfo.flags & CKF_WRITE_PROTECTED) ? PR_TRUE : PR_FALSE);
slot->hasRandom = ((slot->tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
slot->protectedAuthPath =
((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
((slot->tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
? PR_TRUE
: PR_FALSE);
/* on some platforms Active Card incorrectly sets the
@ -1665,6 +1688,63 @@ PK11_GetTokenName(PK11SlotInfo *slot)
return slot->token_name;
}
char *
PK11_GetTokenURI(PK11SlotInfo *slot)
{
PK11URI *uri;
char *ret = NULL;
char label[32 + 1], manufacturer[32 + 1], serial[16 + 1], model[16 + 1];
PK11URIAttribute attrs[4];
size_t nattrs = 0;
PK11_MakeString(NULL, label, (char *)slot->tokenInfo.label,
sizeof(slot->tokenInfo.label));
if (*label != '\0') {
attrs[nattrs].name = PK11URI_PATTR_TOKEN;
attrs[nattrs].value = label;
nattrs++;
}
PK11_MakeString(NULL, manufacturer, (char *)slot->tokenInfo.manufacturerID,
sizeof(slot->tokenInfo.manufacturerID));
if (*manufacturer != '\0') {
attrs[nattrs].name = PK11URI_PATTR_MANUFACTURER;
attrs[nattrs].value = manufacturer;
nattrs++;
}
PK11_MakeString(NULL, serial, (char *)slot->tokenInfo.serialNumber,
sizeof(slot->tokenInfo.serialNumber));
if (*serial != '\0') {
attrs[nattrs].name = PK11URI_PATTR_SERIAL;
attrs[nattrs].value = serial;
nattrs++;
}
PK11_MakeString(NULL, model, (char *)slot->tokenInfo.model,
sizeof(slot->tokenInfo.model));
if (*model != '\0') {
attrs[nattrs].name = PK11URI_PATTR_MODEL;
attrs[nattrs].value = model;
nattrs++;
}
uri = PK11URI_CreateURI(attrs, nattrs, NULL, 0);
if (uri == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
ret = PK11URI_FormatURI(NULL, uri);
PK11URI_DestroyURI(uri);
if (ret == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
}
return ret;
}
char *
PK11_GetSlotName(PK11SlotInfo *slot)
{
@ -1771,6 +1851,46 @@ PK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info)
return SECSuccess;
}
PRBool
pk11_MatchUriTokenInfo(PK11SlotInfo *slot, PK11URI *uri)
{
const char *value;
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_TOKEN);
if (value) {
if (!pk11_MatchString(value, (char *)slot->tokenInfo.label,
sizeof(slot->tokenInfo.label))) {
return PR_FALSE;
}
}
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MANUFACTURER);
if (value) {
if (!pk11_MatchString(value, (char *)slot->tokenInfo.manufacturerID,
sizeof(slot->tokenInfo.manufacturerID))) {
return PR_FALSE;
}
}
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_SERIAL);
if (value) {
if (!pk11_MatchString(value, (char *)slot->tokenInfo.serialNumber,
sizeof(slot->tokenInfo.serialNumber))) {
return PR_FALSE;
}
}
value = PK11URI_GetPathAttribute(uri, PK11URI_PATTR_MODEL);
if (value) {
if (!pk11_MatchString(value, (char *)slot->tokenInfo.model,
sizeof(slot->tokenInfo.model))) {
return PR_FALSE;
}
}
return PR_TRUE;
}
/* Find out if we need to initialize the user's pin */
PRBool
PK11_NeedUserInit(PK11SlotInfo *slot)
@ -2291,6 +2411,14 @@ PK11_GetMaxKeyLength(CK_MECHANISM_TYPE mechanism)
}
}
}
/* fallback to pk11_GetPredefinedKeyLength for fixed key size algorithms */
if (keyLength == 0) {
CK_KEY_TYPE keyType;
keyType = PK11_GetKeyType(mechanism, 0);
keyLength = pk11_GetPredefinedKeyLength(keyType);
}
if (le)
PK11_FreeSlotListElement(list, le);
if (freeit)
@ -2356,7 +2484,11 @@ PK11_RandomUpdate(void *data, size_t bytes)
if (!bestIsInternal) {
/* do internal slot, too. */
slot = PK11_GetInternalSlot(); /* can't fail */
slot = PK11_GetInternalSlot();
PORT_Assert(slot);
if (!slot) {
return SECFailure;
}
status = PK11_SeedRandom(slot, data, bytes);
PK11_FreeSlot(slot);
}

View file

@ -14,6 +14,7 @@
#include "secerr.h"
#include "dev.h"
#include "utilpars.h"
#include "pkcs11uri.h"
/* these are for displaying error messages */
@ -590,6 +591,58 @@ PK11_GetModInfo(SECMODModule *mod, CK_INFO *info)
return (crv == CKR_OK) ? SECSuccess : SECFailure;
}
char *
PK11_GetModuleURI(SECMODModule *mod)
{
CK_INFO info;
PK11URI *uri;
char *ret = NULL;
PK11URIAttribute attrs[3];
size_t nattrs = 0;
char libraryManufacturer[32 + 1], libraryDescription[32 + 1], libraryVersion[8];
if (PK11_GetModInfo(mod, &info) == SECFailure) {
return NULL;
}
PK11_MakeString(NULL, libraryManufacturer, (char *)info.manufacturerID,
sizeof(info.manufacturerID));
if (*libraryManufacturer != '\0') {
attrs[nattrs].name = PK11URI_PATTR_LIBRARY_MANUFACTURER;
attrs[nattrs].value = libraryManufacturer;
nattrs++;
}
PK11_MakeString(NULL, libraryDescription, (char *)info.libraryDescription,
sizeof(info.libraryDescription));
if (*libraryDescription != '\0') {
attrs[nattrs].name = PK11URI_PATTR_LIBRARY_DESCRIPTION;
attrs[nattrs].value = libraryDescription;
nattrs++;
}
PR_snprintf(libraryVersion, sizeof(libraryVersion), "%d.%d",
info.libraryVersion.major, info.libraryVersion.minor);
attrs[nattrs].name = PK11URI_PATTR_LIBRARY_VERSION;
attrs[nattrs].value = libraryVersion;
nattrs++;
uri = PK11URI_CreateURI(attrs, nattrs, NULL, 0);
if (uri == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
ret = PK11URI_FormatURI(NULL, uri);
PK11URI_DestroyURI(uri);
if (ret == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
return ret;
}
/* Determine if we have the FIP's module loaded as the default
* module to trigger other bogus FIPS requirements in PKCS #12 and
* SSL

View file

@ -7,35 +7,54 @@
],
'targets': [
{
'target_name': 'pk11wrap',
'target_name': 'pk11wrap_static',
'type': 'static_library',
'sources': [
'dev3hack.c',
'pk11akey.c',
'pk11auth.c',
'pk11cert.c',
'pk11cxt.c',
'pk11err.c',
'pk11kea.c',
'pk11list.c',
'pk11load.c',
'pk11mech.c',
'pk11merge.c',
'pk11nobj.c',
'pk11obj.c',
'pk11pars.c',
'pk11pbe.c',
'pk11pk12.c',
'pk11pqg.c',
'pk11sdr.c',
'pk11skey.c',
'pk11slot.c',
'pk11util.c'
'defines': [
'NSS_TEST_BUILD',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports'
]
}
'pk11wrap_base',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/lib/softoken/softoken.gyp:softokn_static',
],
},
{
'target_name': 'pk11wrap',
'type': 'static_library',
'dependencies': [
'pk11wrap_base',
'<(DEPTH)/exports.gyp:nss_exports',
],
},
{
'target_name': 'pk11wrap_base',
'type': 'none',
'direct_dependent_settings': {
'sources': [
'dev3hack.c',
'pk11akey.c',
'pk11auth.c',
'pk11cert.c',
'pk11cxt.c',
'pk11err.c',
'pk11kea.c',
'pk11list.c',
'pk11load.c',
'pk11mech.c',
'pk11merge.c',
'pk11nobj.c',
'pk11obj.c',
'pk11pars.c',
'pk11pbe.c',
'pk11pk12.c',
'pk11pqg.c',
'pk11sdr.c',
'pk11skey.c',
'pk11slot.c',
'pk11util.c'
],
},
},
],
'target_defaults': {
'defines': [
@ -48,4 +67,4 @@
'variables': {
'module': 'nss'
}
}
}

View file

@ -107,6 +107,8 @@ struct PK11SlotInfoStr {
unsigned int lastState;
/* for Stan */
NSSToken *nssToken;
/* the tokeninfo struct */
CK_TOKEN_INFO tokenInfo;
/* fast mechanism lookup */
char mechanismBits[256];
};