From c6851c933492056cdeba67703d1bd3e18f5714d4 Mon Sep 17 00:00:00 2001 From: "ian.mcgreer%sun.com" Date: Tue, 11 Dec 2001 20:28:38 +0000 Subject: [PATCH] first step towards separating token and session object searches as performance enhancement. Searches are still over both types until local cert and trust stores for crypto contexts are implemented. --- security/nss/lib/dev/ckhelper.c | 12 +- security/nss/lib/dev/ckhelper.h | 35 +- security/nss/lib/dev/dev.h | 20 +- security/nss/lib/dev/devobject.c | 481 +++++++++++++-------------- security/nss/lib/dev/devt.h | 15 +- security/nss/lib/pk11wrap/pk11cert.c | 28 +- security/nss/lib/pki/certdecode.c | 4 +- security/nss/lib/pki/certificate.c | 22 +- security/nss/lib/pki/cryptocontext.c | 4 +- security/nss/lib/pki/pki3hack.c | 54 ++- security/nss/lib/pki/pkim.h | 4 +- security/nss/lib/pki/pkit.h | 45 ++- security/nss/lib/pki/trustdomain.c | 26 +- 13 files changed, 383 insertions(+), 367 deletions(-) diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c index a6c6dad3c46..7d659bb0399 100644 --- a/security/nss/lib/dev/ckhelper.c +++ b/security/nss/lib/dev/ckhelper.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.12 $ $Date: 2001-12-07 01:35:53 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.13 $ $Date: 2001-12-11 20:28:33 $ $Name: $"; #endif /* DEBUG */ #ifndef DEV_H @@ -196,12 +196,14 @@ nssCKObject_IsAttributeTrue ) { CK_BBOOL bool; - CK_ATTRIBUTE attr = { 0, NULL, 0 }; + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE atemplate = { 0, NULL, 0 }; CK_RV ckrv; - attr.type = attribute; - NSS_CK_SET_ATTRIBUTE_VAR(&attr, 0, bool); + attr = &atemplate; + NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool); nssSession_EnterMonitor(session); - ckrv = CKAPI(slot)->C_GetAttributeValue(session->handle, object, &attr, 1); + ckrv = CKAPI(slot)->C_GetAttributeValue(session->handle, object, + &atemplate, 1); nssSession_ExitMonitor(session); if (ckrv != CKR_OK) { *rvStatus = PR_FAILURE; diff --git a/security/nss/lib/dev/ckhelper.h b/security/nss/lib/dev/ckhelper.h index 5c64e3e703f..21d5e829152 100644 --- a/security/nss/lib/dev/ckhelper.h +++ b/security/nss/lib/dev/ckhelper.h @@ -41,7 +41,7 @@ #define CKHELPER_H #ifdef DEBUG -static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.10 $ $Date: 2001-11-08 00:14:52 $ $Name: $"; +static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.11 $ $Date: 2001-12-11 20:28:33 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSCKT_H @@ -67,18 +67,31 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_cert; NSS_EXTERN_DATA const NSSItem g_ck_class_pubkey; NSS_EXTERN_DATA const NSSItem g_ck_class_privkey; -#define NSS_CK_SET_ATTRIBUTE_VAR(cktemplate, index, var) \ - (cktemplate)[index].pValue = (CK_VOID_PTR)&var; \ - (cktemplate)[index].ulValueLen = (CK_ULONG)sizeof(var) +#define NSS_CK_TEMPLATE_START(_template, attr, size) \ + attr = _template; \ + size = 0; -/* so, nssUTF8_Size or nssUTF8_Length? \0 or no? */ -#define NSS_CK_SET_ATTRIBUTE_UTF8(cktemplate, index, utf8) \ - (cktemplate)[index].pValue = (CK_VOID_PTR)utf8; \ - (cktemplate)[index].ulValueLen = (CK_ULONG)nssUTF8_Size(utf8, NULL); +#define NSS_CK_SET_ATTRIBUTE_ITEM(pattr, kind, item) \ + (pattr)->type = kind; \ + (pattr)->pValue = (CK_VOID_PTR)(item)->data; \ + (pattr)->ulValueLen = (CK_ULONG)(item)->size; \ + (pattr)++; -#define NSS_CK_SET_ATTRIBUTE_ITEM(cktemplate, index, item) \ - (cktemplate)[index].pValue = (CK_VOID_PTR)(item)->data; \ - (cktemplate)[index].ulValueLen = (CK_ULONG)(item)->size; +#define NSS_CK_SET_ATTRIBUTE_UTF8(pattr, kind, utf8) \ + (pattr)->type = kind; \ + (pattr)->pValue = (CK_VOID_PTR)utf8; \ + (pattr)->ulValueLen = (CK_ULONG)nssUTF8_Size(utf8, NULL); \ + (pattr)++; + +#define NSS_CK_SET_ATTRIBUTE_VAR(pattr, kind, var) \ + (pattr)->type = kind; \ + (pattr)->pValue = (CK_VOID_PTR)&var; \ + (pattr)->ulValueLen = (CK_ULONG)sizeof(var); \ + (pattr)++; + +#define NSS_CK_TEMPLATE_FINISH(_template, attr, size) \ + size = (attr) - (_template); \ + PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0])); /* NSS_CK_ATTRIBUTE_TO_ITEM(attrib, item) * diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h index af413ca7b9f..5e7ff5c84c6 100644 --- a/security/nss/lib/dev/dev.h +++ b/security/nss/lib/dev/dev.h @@ -35,7 +35,7 @@ #define DEV_H #ifdef DEBUG -static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.14 $ $Date: 2001-11-28 16:23:38 $ $Name: $"; +static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.15 $ $Date: 2001-12-11 20:28:33 $ $Name: $"; #endif /* DEBUG */ #ifndef DEVT_H @@ -250,8 +250,7 @@ nssToken_ImportCertificate NSSToken *tok, nssSession *sessionOpt, NSSCertificate *cert, - NSSTrustDomain *td, - NSSCryptoContext *cc + PRBool asTokenObject ); NSS_EXTERN PRStatus @@ -260,8 +259,7 @@ nssToken_ImportTrust NSSToken *tok, nssSession *sessionOpt, NSSTrust *trust, - NSSTrustDomain *trustDomain, - NSSCryptoContext *cryptoContext + PRBool asTokenObject ); NSS_EXTERN NSSPublicKey * @@ -292,7 +290,8 @@ nssToken_FindTrustForCert ( NSSToken *token, nssSession *sessionOpt, - NSSCertificate *c + NSSCertificate *c, + nssTokenSearchType searchType ); NSS_EXTERN PRStatus @@ -336,7 +335,8 @@ nssToken_FindCertificateByIssuerAndSerialNumber NSSToken *token, nssSession *sessionOpt, NSSDER *issuer, - NSSDER *serial + NSSDER *serial, + nssTokenSearchType searchType ); NSS_EXTERN NSSCertificate * @@ -344,7 +344,8 @@ nssToken_FindCertificateByEncodedCertificate ( NSSToken *token, nssSession *sessionOpt, - NSSBER *encodedCertificate + NSSBER *encodedCertificate, + nssTokenSearchType searchType ); NSS_EXTERN NSSTrust * @@ -352,7 +353,8 @@ nssToken_FindTrustForCert ( NSSToken *token, nssSession *session, - NSSCertificate *c + NSSCertificate *c, + nssTokenSearchType searchType ); NSS_EXTERN NSSItem * diff --git a/security/nss/lib/dev/devobject.c b/security/nss/lib/dev/devobject.c index e6e7157571f..cc28f3b1d3e 100644 --- a/security/nss/lib/dev/devobject.c +++ b/security/nss/lib/dev/devobject.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.4 $ $Date: 2001-12-07 01:35:53 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.5 $ $Date: 2001-12-11 20:28:33 $ $Name: $"; #endif /* DEBUG */ #ifndef DEV_H @@ -60,6 +60,11 @@ static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.4 $ $D #include "pkit.h" #endif /* PKIT_H */ +/* XXX */ +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + #ifdef NSS_3_4_CODE #include "pkim.h" /* for cert decoding */ #include "pk11func.h" /* for PK11_HasRootCerts */ @@ -267,59 +272,26 @@ loser: return PR_FAILURE; } -static PRStatus -add_object_instance +static nssCryptokiInstance * +create_cryptoki_instance ( - nssPKIObject *object, + NSSArena *arena, NSSToken *t, CK_OBJECT_HANDLE h, - NSSTrustDomain *td, - NSSCryptoContext *cc + PRBool isTokenObject ) { - nssPKIObjectInstance *oi; - oi = nss_ZNEW(object->arena, nssPKIObjectInstance); - if (!oi) { - return PR_FAILURE; + nssCryptokiInstance *instance; + instance = nss_ZNEW(arena, nssCryptokiInstance); + if (!instance) { + return NULL; } - oi->cryptoki.handle = h; - oi->cryptoki.token = t; - oi->trustDomain = td; - oi->cryptoContext = cc; - nssList_Add(object->instanceList, oi); - return PR_SUCCESS; + instance->handle = h; + instance->token = t; + instance->isTokenObject = isTokenObject; + return instance; } -#if 0 -#ifdef NSS_3_4_CODE -static void make_nss3_nickname(NSSCertificate *c) -{ - /* In NSS 3.4, the semantic is that nickname = token name + label */ - PRStatus utf8rv; - NSSUTF8 *tokenName; - NSSUTF8 *label; - char *fullname; - PRUint32 len, tlen; - tokenName = nssToken_GetName(c->token); - label = c->nickname ? c->nickname : c->email; - if (!label) return; - tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */ - tlen += 1; /* : */ - len = nssUTF8_Length(label, &utf8rv); /* label */ - len += 1; /* \0 */ - len += tlen; - fullname = nss_ZAlloc(c->arena, len); - utf8rv = nssUTF8_CopyIntoFixedBuffer(tokenName, fullname, tlen, ':'); - utf8rv = nssUTF8_CopyIntoFixedBuffer(label, fullname + tlen, - len - tlen, '\0'); - nss_ZFreeIf(c->nickname); - c->nickname = nssUTF8_Create(c->arena, - nssStringType_UTF8String, - fullname, len); -} -#endif -#endif - static NSSCertificateType nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) { @@ -344,7 +316,7 @@ get_token_cert ) { NSSCertificate *rvCert; - nssPKIObject *object; + struct nssPKIObjectBaseStr *object; /* XXX needs to go */ NSSArena *arena; nssSession *session; PRStatus nssrv; @@ -373,6 +345,8 @@ get_token_cert object->arena = arena; object->refCount = 1; object->instanceList = nssList_Create(arena, PR_TRUE); + /* XXX this is only valid if tokens are unique in trust domains... */ + object->trustDomain = token->trustDomain; if (!object->instanceList) { goto loser; } @@ -403,7 +377,6 @@ get_token_cert email = dc->getEmailAddress(dc); if (email) rvCert->email = nssUTF8_Duplicate(email, arena); } - /*make_nss3_nickname(rvCert);*/ #endif return rvCert; loser: @@ -417,45 +390,43 @@ nssToken_ImportCertificate NSSToken *tok, nssSession *sessionOpt, NSSCertificate *cert, - NSSTrustDomain *td, - NSSCryptoContext *cc + PRBool asTokenObject ) { + nssCryptokiInstance *instance; CK_CERTIFICATE_TYPE cert_type = CKC_X_509; CK_OBJECT_HANDLE handle; - CK_ATTRIBUTE cert_tmpl[] = { - { CKA_TOKEN, NULL, 0 }, - { CKA_CLASS, NULL, 0 }, - { CKA_CERTIFICATE_TYPE, NULL, 0 }, - { CKA_ID, NULL, 0 }, - { CKA_LABEL, NULL, 0 }, - { CKA_VALUE, NULL, 0 }, - { CKA_ISSUER, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0 } - }; - CK_ULONG ctsize = sizeof(cert_tmpl)/sizeof(cert_tmpl[0]); - if (td) { - /* trust domain == token object */ - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 0, &g_ck_true); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE cert_tmpl[9]; + CK_ULONG ctsize; + NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); + if (asTokenObject) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } else { - /* crypto context == session object */ - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 0, &g_ck_false); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 1, &g_ck_class_cert); - NSS_CK_SET_ATTRIBUTE_VAR( cert_tmpl, 2, cert_type); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 3, &cert->id); - NSS_CK_SET_ATTRIBUTE_UTF8(cert_tmpl, 4, cert->nickname); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 5, &cert->encoding); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 6, &cert->issuer); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 7, &cert->subject); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_tmpl, 8, &cert->serial); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, &cert->id); + NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, cert->nickname); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, &cert->encoding); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &cert->issuer); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, &cert->subject); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, &cert->serial); + NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); /* Import the certificate onto the token */ handle = import_object(tok, sessionOpt, cert_tmpl, ctsize); if (handle == CK_INVALID_HANDLE) { return PR_FAILURE; } - return add_object_instance(&cert->object, tok, handle, td, cc); + instance = create_cryptoki_instance(cert->object.arena, + tok, handle, asTokenObject); + if (!instance) { + /* XXX destroy object */ + return PR_FAILURE; + } + nssList_Add(cert->object.instanceList, instance); + return PR_SUCCESS; } static PRBool @@ -475,7 +446,7 @@ retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg) nssTokenCertSearch *search = (nssTokenCertSearch *)arg; NSSCertificate *cert = NULL; nssListIterator *instances; - nssPKIObjectInstance *oi; + nssCryptokiInstance *ci; CK_ATTRIBUTE issuersn_tmpl[] = { { CKA_ISSUER, NULL, 0 }, { CKA_SERIAL_NUMBER, NULL, 0 } @@ -494,11 +465,11 @@ retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg) found = PR_FALSE; if (cert) { instances = cert->object.instances; - for (oi = (nssPKIObjectInstance *)nssListIterator_Start(instances); - oi != (nssPKIObjectInstance *)NULL; - oi = (nssPKIObjectInstance *)nssListIterator_Next(instances)) + for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances); + ci != (nssCryptokiInstance *)NULL; + ci = (nssCryptokiInstance *)nssListIterator_Next(instances)) { - if (oi->cryptoki.handle == h && oi->cryptoki.token == t) { + if (ci->handle == h && ci->token == t) { found = PR_TRUE; break; } @@ -509,12 +480,16 @@ retrieve_cert(NSSToken *t, nssSession *session, CK_OBJECT_HANDLE h, void *arg) if (!cert) return PR_FAILURE; } if (!found) { - nssrv = add_object_instance(&cert->object, t, h, - search->trustDomain, - search->cryptoContext); - if (nssrv != PR_SUCCESS) { - return nssrv; + PRBool isTokenObject; + /* XXX this is incorrect if the search is over both types */ + isTokenObject = (search->searchType == nssTokenSearchType_TokenOnly) ? + PR_TRUE : PR_FALSE; + ci = create_cryptoki_instance(cert->object.arena, t, h, isTokenObject); + if (!ci) { + NSSCertificate_Destroy(cert); + return PR_FAILURE; } + nssList_Add(cert->object.instanceList, ci); } return (*search->callback)(cert, search->cbarg); } @@ -531,12 +506,18 @@ nssToken_TraverseCertificates ) { PRStatus nssrv; - /* this is really traversal - the template is all certs */ - CK_ATTRIBUTE cert_template[] = { - { CKA_CLASS, NULL, 0 } - }; - CK_ULONG ctsize = sizeof(cert_template) / sizeof(cert_template[0]); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE cert_template[2]; + CK_ULONG ctsize; + NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); + /* Set the search to token/session only if provided */ + if (search->searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (search->searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn); nssrv = traverse_objects_by_template(token, sessionOpt, cert_template, ctsize, @@ -554,18 +535,23 @@ nssToken_TraverseCertificatesBySubject ) { PRStatus nssrv; - CK_ATTRIBUTE subj_tmpl[] = - { - { CKA_CLASS, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 } - }; - CK_ULONG stsize = (CK_ULONG)(sizeof(subj_tmpl) / sizeof(subj_tmpl[0])); - NSS_CK_SET_ATTRIBUTE_ITEM(subj_tmpl, 0, &g_ck_class_cert); - NSS_CK_SET_ATTRIBUTE_ITEM(subj_tmpl, 1, subject); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE subj_template[3]; + CK_ULONG stsize; + NSS_CK_TEMPLATE_START(subj_template, attr, stsize); + /* Set the search to token/session only if provided */ + if (search->searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (search->searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject); + NSS_CK_TEMPLATE_FINISH(subj_template, attr, stsize); nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn); /* now traverse the token certs matching this template */ nssrv = traverse_objects_by_template(token, sessionOpt, - subj_tmpl, stsize, + subj_template, stsize, retrieve_cert, search); return nssrv; } @@ -580,20 +566,23 @@ nssToken_TraverseCertificatesByNickname ) { PRStatus nssrv; - CK_ATTRIBUTE nick_tmpl[] = - { - { CKA_CLASS, NULL, 0 }, - { CKA_LABEL, NULL, 0 } - }; - CK_ULONG ntsize = sizeof(nick_tmpl) / sizeof(nick_tmpl[0]); - /* set up the search template */ - NSS_CK_SET_ATTRIBUTE_ITEM(nick_tmpl, 0, &g_ck_class_cert); - nick_tmpl[1].pValue = (CK_VOID_PTR)name; - nick_tmpl[1].ulValueLen = (CK_ULONG)nssUTF8_Length(name, &nssrv); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE nick_template[3]; + CK_ULONG ntsize; + NSS_CK_TEMPLATE_START(nick_template, attr, ntsize); + /* Set the search to token/session only if provided */ + if (search->searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (search->searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, name); + NSS_CK_TEMPLATE_FINISH(nick_template, attr, ntsize); nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn); /* now traverse the token certs matching this template */ nssrv = traverse_objects_by_template(token, sessionOpt, - nick_tmpl, ntsize, + nick_template, ntsize, retrieve_cert, search); if (nssrv != PR_SUCCESS) { return nssrv; @@ -604,9 +593,9 @@ nssToken_TraverseCertificatesByNickname * leaving it in until I have surveyed more tokens to see if it needed. * well, its needed by the builtin token... */ - nick_tmpl[1].ulValueLen++; + nick_template[1].ulValueLen++; nssrv = traverse_objects_by_template(token, sessionOpt, - nick_tmpl, ntsize, + nick_template, ntsize, retrieve_cert, search); return nssrv; } @@ -621,20 +610,23 @@ nssToken_TraverseCertificatesByEmail ) { PRStatus nssrv; - CK_ATTRIBUTE email_tmpl[] = - { - { CKA_CLASS, NULL, 0 }, - { CKA_NETSCAPE_EMAIL, NULL, 0 } - }; - CK_ULONG etsize = sizeof(email_tmpl) / sizeof(email_tmpl[0]); - /* set up the search template */ - NSS_CK_SET_ATTRIBUTE_ITEM(email_tmpl, 0, &g_ck_class_cert); - email_tmpl[1].pValue = (CK_VOID_PTR)email; - email_tmpl[1].ulValueLen = (CK_ULONG)nssUTF8_Length(email, &nssrv); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE email_template[3]; + CK_ULONG etsize; + NSS_CK_TEMPLATE_START(email_template, attr, etsize); + /* Set the search to token/session only if provided */ + if (search->searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (search->searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_EMAIL, email); + NSS_CK_TEMPLATE_FINISH(email_template, attr, etsize); nssList_SetCompareFunction(search->cached, compare_cert_by_issuer_sn); /* now traverse the token certs matching this template */ nssrv = traverse_objects_by_template(token, sessionOpt, - email_tmpl, etsize, + email_template, etsize, retrieve_cert, search); if (nssrv != PR_SUCCESS) { return nssrv; @@ -659,25 +651,29 @@ nssToken_FindCertificateByIssuerAndSerialNumber NSSToken *token, nssSession *sessionOpt, NSSDER *issuer, - NSSDER *serial + NSSDER *serial, + nssTokenSearchType searchType ) { NSSCertificate *rvCert = NULL; nssSession *session; - PRBool tokenObject; PRStatus nssrv; - CK_ULONG ctsize; CK_OBJECT_HANDLE object; - CK_ATTRIBUTE cert_template[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_ISSUER, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0 } - }; - ctsize = sizeof(cert_template) / sizeof(cert_template[0]); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE cert_template[4]; + CK_ULONG ctsize; + NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); + /* Set the search to token/session only if provided */ + if (searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } /* Set the unique id */ - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, issuer); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, serial); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, issuer); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial); + NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ object = find_object_by_template(token, sessionOpt, cert_template, ctsize); if (object == CK_INVALID_HANDLE) { @@ -686,21 +682,18 @@ nssToken_FindCertificateByIssuerAndSerialNumber session = (sessionOpt) ? sessionOpt : token->defaultSession; rvCert = get_token_cert(token, sessionOpt, object); if (rvCert) { - NSSTrustDomain *td; - NSSCryptoContext *cc; - tokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN, - session, token->slot, - &nssrv); - if (tokenObject) { - td = token->trustDomain; - cc = NULL; - } else { - td = NULL; - cc = NULL; /* XXX how to recover the crypto context from - * the token? - */ + PRBool isTokenObject; + nssCryptokiInstance *instance; + isTokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN, + session, token->slot, + &nssrv); + instance = create_cryptoki_instance(rvCert->object.arena, + token, object, isTokenObject); + if (!instance) { + NSSCertificate_Destroy(rvCert); + return NULL; } - add_object_instance(&rvCert->object, token, object, td, cc); + nssList_Add(rvCert->object.instanceList, instance); } return rvCert; } @@ -710,22 +703,27 @@ nssToken_FindCertificateByEncodedCertificate ( NSSToken *token, nssSession *sessionOpt, - NSSBER *encodedCertificate + NSSBER *encodedCertificate, + nssTokenSearchType searchType ) { NSSCertificate *rvCert = NULL; nssSession *session; - PRBool tokenObject; PRStatus nssrv; - CK_ULONG ctsize; CK_OBJECT_HANDLE object; - CK_ATTRIBUTE cert_template[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_VALUE, NULL, 0 } - }; - ctsize = sizeof(cert_template) / sizeof(cert_template[0]); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, encodedCertificate); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE cert_template[3]; + CK_ULONG ctsize; + NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); + /* Set the search to token/session only if provided */ + if (searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, encodedCertificate); + NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize); /* get the object handle */ object = find_object_by_template(token, sessionOpt, cert_template, ctsize); if (object == CK_INVALID_HANDLE) { @@ -734,21 +732,18 @@ nssToken_FindCertificateByEncodedCertificate session = (sessionOpt) ? sessionOpt : token->defaultSession; rvCert = get_token_cert(token, sessionOpt, object); if (rvCert) { - NSSTrustDomain *td; - NSSCryptoContext *cc; - tokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN, - session, token->slot, - &nssrv); - if (tokenObject) { - td = token->trustDomain; - cc = NULL; - } else { - td = NULL; - cc = NULL; /* XXX how to recover the crypto context from - * the token? - */ + PRBool isTokenObject; + nssCryptokiInstance *instance; + isTokenObject = nssCKObject_IsAttributeTrue(object, CKA_TOKEN, + session, token->slot, + &nssrv); + instance = create_cryptoki_instance(rvCert->object.arena, + token, object, isTokenObject); + if (!instance) { + NSSCertificate_Destroy(rvCert); + return NULL; } - add_object_instance(&rvCert->object, token, object, td, cc); + nssList_Add(rvCert->object.instanceList, instance); } return rvCert; } @@ -779,26 +774,14 @@ nssToken_ImportTrust NSSToken *tok, nssSession *sessionOpt, NSSTrust *trust, - NSSTrustDomain *trustDomain, - NSSCryptoContext *cryptoContext + PRBool asTokenObject ) { - PRStatus nssrv; CK_OBJECT_HANDLE handle; CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST; - CK_ATTRIBUTE trust_tmpl[] = { - { CKA_TOKEN, NULL, 0 }, - { CKA_CLASS, NULL, 0 }, - { CKA_ISSUER, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0 }, - { CKA_CERT_SHA1_HASH, NULL, 0 }, - { CKA_CERT_MD5_HASH, NULL, 0 }, - { CKA_TRUST_SERVER_AUTH, NULL, 0 }, - { CKA_TRUST_CLIENT_AUTH, NULL, 0 }, - { CKA_TRUST_EMAIL_PROTECTION, NULL, 0 }, - { CKA_TRUST_CODE_SIGNING, NULL, 0 } - }; - CK_ULONG tsize = sizeof(trust_tmpl) / sizeof(trust_tmpl[0]); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE trust_tmpl[10]; + CK_ULONG tsize; PRUint8 sha1[20]; /* this is cheating... */ PRUint8 md5[16]; NSSItem sha1_result, md5_result; @@ -807,30 +790,37 @@ nssToken_ImportTrust md5_result.data = md5; md5_result.size = sizeof md5; sha1_hash(&c->encoding, &sha1_result); md5_hash(&c->encoding, &md5_result); - if (trustDomain) { - NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 0, &g_ck_true); + NSS_CK_TEMPLATE_START(trust_tmpl, attr, tsize); + if (asTokenObject) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); } else { - NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 0, &g_ck_false); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); } - NSS_CK_SET_ATTRIBUTE_VAR( trust_tmpl, 1, tobjc); - NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 2, &c->issuer); - NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 3, &c->serial); - NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 4, &sha1_result); - NSS_CK_SET_ATTRIBUTE_ITEM(trust_tmpl, 5, &md5_result); + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &c->issuer); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, &c->serial); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_MD5_HASH, &md5_result); /* now set the trust values */ - NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 6, trust->serverAuth); - NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 7, trust->clientAuth); - NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 8, trust->emailProtection); - NSS_CK_SET_ATTRIBUTE_VAR(trust_tmpl, 9, trust->codeSigning); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, trust->serverAuth); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, trust->clientAuth); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, trust->codeSigning); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, + trust->emailProtection); + NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); /* import the trust object onto the token */ handle = import_object(tok, NULL, trust_tmpl, tsize); if (handle != CK_INVALID_HANDLE) { - nssrv = add_object_instance(&trust->object, tok, handle, - trustDomain, cryptoContext); - } else { - nssrv = PR_FAILURE; - } - return nssrv; + nssCryptokiInstance *instance; + instance = create_cryptoki_instance(trust->object.arena, + tok, handle, asTokenObject); + if (!instance) { + return PR_FAILURE; + } + nssList_Add(trust->object.instanceList, instance); + return PR_SUCCESS; + } + return PR_FAILURE; } static CK_OBJECT_HANDLE @@ -838,34 +828,39 @@ get_cert_trust_handle ( NSSToken *token, nssSession *session, - NSSCertificate *c + NSSCertificate *c, + nssTokenSearchType searchType ) { CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST; - CK_ATTRIBUTE tobj_template[] = { - { CKA_CLASS, NULL, 0 }, - { CKA_CERT_SHA1_HASH, NULL, 0 }, - { CKA_ISSUER, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0 } - }; - CK_ULONG tobj_size = sizeof(tobj_template) / sizeof(tobj_template[0]); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE tobj_template[5]; + CK_ULONG tobj_size; PRUint8 sha1[20]; /* this is cheating... */ NSSItem sha1_result; sha1_result.data = sha1; sha1_result.size = sizeof sha1; sha1_hash(&c->encoding, &sha1_result); - NSS_CK_SET_ATTRIBUTE_VAR( tobj_template, 0, tobjc); - NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 1, &sha1_result); - NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 2, &c->issuer); - NSS_CK_SET_ATTRIBUTE_ITEM(tobj_template, 3, &c->serial); + NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); + if (searchType == nssTokenSearchType_SessionOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); + } else if (searchType == nssTokenSearchType_TokenOnly) { + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + } + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH, &sha1_result); +#ifdef NSS_3_4_CODE + if (!PK11_HasRootCerts(token->pk11slot)) { +#endif + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &c->issuer); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER , &c->serial); #ifdef NSS_3_4_CODE - if (PK11_HasRootCerts(token->pk11slot)) { - tobj_size -= 2; } /* * we need to arrange for the built-in token to lose the bottom 2 * attributes so that old built-in tokens will continue to work. */ #endif + NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); return find_object_by_template(token, session, tobj_template, tobj_size); } @@ -875,33 +870,36 @@ nssToken_FindTrustForCert ( NSSToken *token, nssSession *sessionOpt, - NSSCertificate *c + NSSCertificate *c, + nssTokenSearchType searchType ) { PRStatus nssrv; NSSTrust *rvTrust; nssSession *session; NSSArena *arena; - nssPKIObject *object; + struct nssPKIObjectBaseStr *object; + nssCryptokiInstance *instance; + PRBool isTokenObject; + CK_BBOOL isToken; CK_TRUST saTrust, caTrust, epTrust, csTrust; CK_OBJECT_HANDLE tobjID; - CK_ATTRIBUTE trust_template[] = { - { CKA_TRUST_SERVER_AUTH, NULL, 0 }, - { CKA_TRUST_CLIENT_AUTH, NULL, 0 }, - { CKA_TRUST_EMAIL_PROTECTION, NULL, 0 }, - { CKA_TRUST_CODE_SIGNING, NULL, 0 } - }; - CK_ULONG trust_size = sizeof(trust_template) / sizeof(trust_template[0]); + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE trust_template[5]; + CK_ULONG trust_size; session = (sessionOpt) ? sessionOpt : token->defaultSession; - tobjID = get_cert_trust_handle(token, session, c); + tobjID = get_cert_trust_handle(token, session, c, searchType); if (tobjID == CK_INVALID_HANDLE) { return NULL; } /* Then use the trust object to find the trust settings */ - NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 0, saTrust); - NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 1, caTrust); - NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 2, epTrust); - NSS_CK_SET_ATTRIBUTE_VAR(trust_template, 3, csTrust); + NSS_CK_TEMPLATE_START(trust_template, attr, trust_size); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH, saTrust); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH, caTrust); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust); + NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); + NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); nssrv = nssCKObject_GetAttributes(tobjID, trust_template, trust_size, NULL, session, token->slot); @@ -920,6 +918,8 @@ nssToken_FindTrustForCert object = &rvTrust->object; object->arena = arena; object->refCount = 1; + /* XXX this is only valid if tokens are unique in trust domains... */ + object->trustDomain = token->trustDomain; object->instanceList = nssList_Create(arena, PR_TRUE); if (!object->instanceList) { nssArena_Destroy(arena); @@ -930,10 +930,9 @@ nssToken_FindTrustForCert nssArena_Destroy(arena); return NULL; } - /* need to figure out trust domain and/or crypto context */ - nssrv = add_object_instance(object, token, tobjID, - token->trustDomain, NULL); - if (nssrv != PR_SUCCESS) { + isTokenObject = (isToken == CK_TRUE) ? PR_TRUE : PR_FALSE; + instance = create_cryptoki_instance(arena, token, tobjID, isTokenObject); + if (!instance) { nssArena_Destroy(arena); return NULL; } diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h index 09281d03204..c98b47aa355 100644 --- a/security/nss/lib/dev/devt.h +++ b/security/nss/lib/dev/devt.h @@ -35,7 +35,7 @@ #define DEVT_H #ifdef DEBUG -static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:39 $ $Name: $"; +static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.8 $ $Date: 2001-12-11 20:28:34 $ $Name: $"; #endif /* DEBUG */ /* @@ -167,17 +167,26 @@ struct nssCryptokiInstanceStr { CK_OBJECT_HANDLE handle; NSSToken *token; + PRBool isTokenObject; }; typedef struct nssTokenCertSearchStr nssTokenCertSearch; +typedef enum { + nssTokenSearchType_AllObjects = 0, + nssTokenSearchType_SessionOnly = 1, + nssTokenSearchType_TokenOnly = 2 +} nssTokenSearchType; + struct nssTokenCertSearchStr { + nssTokenSearchType searchType; PRStatus (* callback)(NSSCertificate *c, void *arg); void *cbarg; nssList *cached; - NSSTrustDomain *trustDomain; - NSSCryptoContext *cryptoContext; + /* TODO: add a cache query callback if the list would be large + * (traversal) + */ }; struct NSSAlgorithmAndParametersStr diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index a40493a076e..54c1f66aa4e 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -1200,8 +1200,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { search.callback = get_newest_cert; search.cbarg = (void *)&cert; search.cached = certList; - search.trustDomain = defaultTD; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* find best cert on token */ nssToken_TraverseCertificatesByNickname(token, NULL, (NSSUTF8 *)nickname, @@ -1292,8 +1291,7 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { search.callback = collect_certs; search.cbarg = nameList; search.cached = nameList; - search.trustDomain = defaultTD; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, nickname, &search); count = nssList_Count(nameList); @@ -1536,12 +1534,12 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, if (cert->slot == NULL) { cert->slot = PK11_ReferenceSlot(slot); if (cert->nssCertificate) { - nssPKIObjectInstance *instance; + nssCryptokiInstance *instance; NSSCertificate *c = cert->nssCertificate; - instance = nss_ZNEW(c->object.arena, nssPKIObjectInstance); - instance->cryptoki.token = slot->nssToken; - instance->cryptoki.handle = cert->pkcs11ID; - instance->trustDomain = cert->dbhandle; + instance = nss_ZNEW(c->object.arena, nssCryptokiInstance); + instance->token = slot->nssToken; + instance->handle = cert->pkcs11ID; + instance->isTokenObject = PR_TRUE; nssList_Add(c->object.instanceList, instance); } else { cert->nssCertificate = STAN_GetNSSCertificate(cert); @@ -2336,8 +2334,7 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, search.callback = convert_cert; search.cbarg = &pk11cb; search.cached = subjectList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; token = PK11Slot_GetNSSToken(slot); nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, &subject, &search); @@ -2407,8 +2404,7 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, search.callback = convert_cert; search.cbarg = &pk11cb; search.cached = nameList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; token = PK11Slot_GetNSSToken(slot); nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, nick, &search); @@ -2461,8 +2457,7 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot, search.callback = convert_cert; search.cbarg = &pk11cb; search.cached = certList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; tok = PK11Slot_GetNSSToken(slot); if (tok) { nssrv = nssToken_TraverseCertificates(tok, NULL, &search); @@ -2518,7 +2513,8 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert, tok = PK11Slot_GetNSSToken(slot); NSSITEM_FROM_SECITEM(&derCert, &cert->derCert); /* XXX login to slots */ - c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert); + c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, &derCert, + nssTokenSearchType_AllObjects); if (c) { rvCert = STAN_GetCERTCertificate(c); } diff --git a/security/nss/lib/pki/certdecode.c b/security/nss/lib/pki/certdecode.c index 540533afde7..71dd3759d46 100644 --- a/security/nss/lib/pki/certdecode.c +++ b/security/nss/lib/pki/certdecode.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.5 $ $Date: 2001-12-07 01:36:07 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.6 $ $Date: 2001-12-11 20:28:36 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIT_H @@ -49,7 +49,7 @@ static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.5 $ $ NSS_IMPLEMENT PRStatus nssPKIObject_Destroy ( - nssPKIObject *object + struct nssPKIObjectBaseStr *object ) { nssList_Destroy(object->instanceList); diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 4efc20adcfe..3f1b898266a 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.19 $ $Date: 2001-12-07 01:36:08 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.20 $ $Date: 2001-12-11 20:28:36 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -106,13 +106,13 @@ NSSCertificate_DeleteStoredObject */ /* XXX use callback to log in if neccessary */ PRStatus nssrv = PR_SUCCESS; - nssPKIObjectInstance *instance; + nssCryptokiInstance *instance; nssListIterator *instances = c->object.instances; - for (instance = (nssPKIObjectInstance *)nssListIterator_Start(instances); - instance != (nssPKIObjectInstance *)NULL; - instance = (nssPKIObjectInstance *)nssListIterator_Next(instances)) + for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); + instance != (nssCryptokiInstance *)NULL; + instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) { - nssrv = nssToken_DeleteStoredObject(&instance->cryptoki); + nssrv = nssToken_DeleteStoredObject(instance); if (nssrv != PR_SUCCESS) { break; } @@ -316,15 +316,7 @@ NSSCertificate_GetTrustDomain NSSCertificate *c ) { - PRStatus nssrv = PR_SUCCESS; - nssPKIObjectInstance *instance; - nssList *instances = c->object.instanceList; - nssrv = nssList_GetArray(instances, (void **)&instance, 1); - if (nssrv == PR_SUCCESS) { - return instance->trustDomain; - } else { - return (NSSTrustDomain *)NULL; - } + return c->object.trustDomain; } NSS_IMPLEMENT NSSToken * diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c index 2ec94bd7e9d..9710d08b64c 100644 --- a/security/nss/lib/pki/cryptocontext.c +++ b/security/nss/lib/pki/cryptocontext.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.6 $ $Date: 2001-11-29 19:34:06 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.7 $ $Date: 2001-12-11 20:28:37 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -125,7 +125,7 @@ NSSCryptoContext_ImportCertificate return PR_FAILURE; } #endif - return nssToken_ImportCertificate(token, session, c, NULL, cc); + return nssToken_ImportCertificate(token, session, c, PR_FALSE); } NSS_IMPLEMENT NSSCertificate * diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index eb68173f33d..4e83b4f0bcf 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.8 $ $Date: 2001-12-07 01:36:08 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.9 $ $Date: 2001-12-11 20:28:37 $ $Name: $"; #endif /* DEBUG */ /* @@ -396,7 +396,8 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) tok != (NSSToken *)NULL; tok = (NSSToken *)nssListIterator_Next(td->tokens)) { - tokenTrust = nssToken_FindTrustForCert(tok, NULL, c); + tokenTrust = nssToken_FindTrustForCert(tok, NULL, c, + nssTokenSearchType_AllObjects); if (tokenTrust) { if (t) { if (t->serverAuth == CKT_NETSCAPE_TRUST_UNKNOWN) { @@ -440,10 +441,10 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) return rvTrust; } -static nssPKIObjectInstance * +static nssCryptokiInstance * get_cert_instance(NSSCertificate *c) { - nssPKIObjectInstance *instance; + nssCryptokiInstance *instance; instance = NULL; nssList_GetArray(c->object.instanceList, (void **)&instance, 1); return instance; @@ -452,7 +453,7 @@ get_cert_instance(NSSCertificate *c) static void fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) { - nssPKIObjectInstance *instance = get_cert_instance(c); + nssCryptokiInstance *instance = get_cert_instance(c); /* fill other fields needed by NSS3 functions using CERTCertificate */ if (!cc->nickname && c->nickname) { PRStatus nssrv; @@ -462,16 +463,15 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) cc->nickname[len-1] = '\0'; } if (instance) { - nssCryptokiInstance *cryptoki = &instance->cryptoki; /* slot */ - cc->slot = cryptoki->token->pk11slot; + cc->slot = instance->token->pk11slot; /* pkcs11ID */ - cc->pkcs11ID = cryptoki->handle; + cc->pkcs11ID = instance->handle; /* trust */ cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); - /* database handle is now the trust domain */ - cc->dbhandle = instance->trustDomain; } + /* database handle is now the trust domain */ + cc->dbhandle = c->object.trustDomain; /* subjectList ? */ /* pointer back */ cc->nssCertificate = c; @@ -493,7 +493,6 @@ STAN_GetCERTCertificate(NSSCertificate *c) if (!cc->nssCertificate) { fill_CERTCertificateFields(c, cc); } else if (!cc->trust) { - nssPKIObjectInstance *instance = get_cert_instance(c); cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); } return cc; @@ -527,8 +526,7 @@ NSS_EXTERN NSSCertificate * STAN_GetNSSCertificate(CERTCertificate *cc) { NSSCertificate *c; - nssPKIObject *object; - nssPKIObjectInstance *instance; + nssCryptokiInstance *instance; NSSArena *arena; c = cc->nssCertificate; if (c) { @@ -545,13 +543,13 @@ STAN_GetNSSCertificate(CERTCertificate *cc) if (!c) { goto loser; } - object = &c->object; NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); c->type = NSSCertificateType_PKIX; - object->arena = arena; - object->refCount = 1; - object->instanceList = nssList_Create(arena, PR_TRUE); - object->instances = nssList_CreateIterator(object->instanceList); + c->object.arena = arena; + c->object.refCount = 1; + c->object.trustDomain = (NSSTrustDomain *)cc->dbhandle; + c->object.instanceList = nssList_Create(arena, PR_TRUE); + c->object.instances = nssList_CreateIterator(c->object.instanceList); nssItem_Create(arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); nssItem_Create(arena, @@ -577,13 +575,13 @@ STAN_GetNSSCertificate(CERTCertificate *cc) (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } - instance = nss_ZNEW(arena, nssPKIObjectInstance); - instance->trustDomain = (NSSTrustDomain *)cc->dbhandle; if (cc->slot) { - instance->cryptoki.token = PK11Slot_GetNSSToken(cc->slot); - instance->cryptoki.handle = cc->pkcs11ID; + instance = nss_ZNEW(arena, nssCryptokiInstance); + instance->token = PK11Slot_GetNSSToken(cc->slot); + instance->handle = cc->pkcs11ID; + instance->isTokenObject = PR_TRUE; + nssList_Add(c->object.instanceList, instance); } - nssList_Add(object->instanceList, instance); c->decoding = create_decoded_pkix_cert_from_nss3cert(arena, cc); cc->nssCertificate = c; return c; @@ -631,17 +629,14 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) moving_object = PR_FALSE; } if (tok) { - nssPKIObjectInstance *instance = get_cert_instance(c); if (moving_object) { /* this is kind of hacky. the softoken needs the cert * object in order to store trust. forcing it to be perm */ - nssrv = nssToken_ImportCertificate(tok, NULL, c, td, NULL); + nssrv = nssToken_ImportCertificate(tok, NULL, c, PR_TRUE); if (nssrv != PR_SUCCESS) return nssrv; } - nssrv = nssToken_ImportTrust(tok, NULL, &nssTrust, - instance->trustDomain, - instance->cryptoContext); + nssrv = nssToken_ImportTrust(tok, NULL, &nssTrust, PR_TRUE); } else { nssrv = PR_FAILURE; } @@ -728,8 +723,7 @@ nssTrustDomain_TraverseCertificates search.callback = callback; search.cbarg = arg; search.cached = certList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; token = (NSSToken *)nssListIterator_Next(td->tokens)) diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h index 695eb583000..34b74c0075f 100644 --- a/security/nss/lib/pki/pkim.h +++ b/security/nss/lib/pki/pkim.h @@ -35,7 +35,7 @@ #define PKIM_H #ifdef DEBUG -static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.10 $ $Date: 2001-12-07 01:36:08 $ $Name: $"; +static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.11 $ $Date: 2001-12-11 20:28:38 $ $Name: $"; #endif /* DEBUG */ #ifndef BASE_H @@ -261,7 +261,7 @@ nssDecodedCert_Destroy NSS_EXTERN PRStatus nssPKIObject_Destroy ( - nssPKIObject *object + struct nssPKIObjectBaseStr *object ); NSS_EXTERN NSSTime * diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h index b5236a2ebc0..c2095a1b517 100644 --- a/security/nss/lib/pki/pkit.h +++ b/security/nss/lib/pki/pkit.h @@ -35,7 +35,7 @@ #define PKIT_H #ifdef DEBUG -static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.7 $ $Date: 2001-11-28 16:23:44 $ $Name: $"; +static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.8 $ $Date: 2001-12-11 20:28:38 $ $Name: $"; #endif /* DEBUG */ /* @@ -73,28 +73,41 @@ PR_BEGIN_EXTERN_C typedef struct nssDecodedCertStr nssDecodedCert; -typedef struct nssPKIObjectInstanceStr nssPKIObjectInstance; +/* + * A note on ephemeral certs + * + * The key objects defined here can only be created on tokens, and can only + * exist on tokens. Therefore, any instance of a key object must have + * a corresponding cryptoki instance. OTOH, certificates created in + * crypto contexts need not be stored as session objects on the token. + * There are good performance reasons for not doing so. The certificate + * and trust objects have been defined with a cryptoContext field to + * allow for ephemeral certs, which may have a single instance in a crypto + * context along with any number (including zero) of cryptoki instances. + * Since contexts may not share objects, there can be only one context + * for each object. + */ -typedef struct nssPKIObjectStr nssPKIObject; - -struct nssPKIObjectInstanceStr +/* The common data from which all objects inherit */ +struct nssPKIObjectBaseStr { - nssCryptokiInstance cryptoki; - NSSTrustDomain *trustDomain; - NSSCryptoContext *cryptoContext; -}; - -struct nssPKIObjectStr -{ - PRInt32 refCount; + /* The arena for all object memory */ NSSArena *arena; - nssList *instanceList; /* list of nssPKIObjectInstance */ + /* Thread-safe reference counting */ + PZLock *lock; + PRInt32 refCount; + /* List of nssCryptokiInstance's of the object */ + nssList *instanceList; nssListIterator *instances; + /* The object must live in a trust domain */ + NSSTrustDomain *trustDomain; + /* The object may live in a crypto context */ + NSSCryptoContext *cryptoContext; }; struct NSSTrustStr { - struct nssPKIObjectStr object; + struct nssPKIObjectBaseStr object; NSSCertificate *certificate; nssTrustLevel serverAuth; nssTrustLevel clientAuth; @@ -104,7 +117,7 @@ struct NSSTrustStr struct NSSCertificateStr { - struct nssPKIObjectStr object; + struct nssPKIObjectBaseStr object; NSSCertificateType type; NSSItem id; NSSBER encoding; diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c index 2aed8a2c90a..038dfa779c9 100644 --- a/security/nss/lib/pki/trustdomain.c +++ b/security/nss/lib/pki/trustdomain.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.19 $ $Date: 2001-11-29 22:05:32 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.20 $ $Date: 2001-12-11 20:28:38 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -448,8 +448,7 @@ NSSTrustDomain_FindBestCertificateByNickname search.callback = get_best_cert; search.cbarg = &best; search.cached = nameList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* XXX */ /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; @@ -492,8 +491,7 @@ NSSTrustDomain_FindCertificatesByNickname search.callback = collect_certs; search.cbarg = &ca; search.cached = nameList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* XXX */ /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; @@ -544,7 +542,8 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok, NULL, issuer, - serialNumber); + serialNumber, + nssTokenSearchType_AllObjects); if (rvCert) { /* cache it */ nssTrustDomain_AddCertsToCache(td, &rvCert, 1); @@ -582,8 +581,7 @@ NSSTrustDomain_FindBestCertificateBySubject search.callback = get_best_cert; search.cbarg = &best; search.cached = subjectList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* XXX */ /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; @@ -626,8 +624,7 @@ NSSTrustDomain_FindCertificatesBySubject search.callback = collect_certs; search.cbarg = &ca; search.cached = subjectList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* XXX */ /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; @@ -701,7 +698,8 @@ NSSTrustDomain_FindCertificateByEncodedCertificate tok = (NSSToken *)nssListIterator_Next(td->tokens)) { rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL, - encodedCertificate); + encodedCertificate, + nssTokenSearchType_AllObjects); if (rvCert) { /* cache it */ nssTrustDomain_AddCertsToCache(td, &rvCert, 1); @@ -739,8 +737,7 @@ NSSTrustDomain_FindCertificateByEmail search.callback = get_best_cert; search.cbarg = &best; search.cached = emailList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* XXX */ /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL; @@ -895,8 +892,7 @@ NSSTrustDomain_TraverseCertificates search.callback = callback; search.cbarg = arg; search.cached = certList; - search.trustDomain = td; - search.cryptoContext = NULL; + search.searchType = nssTokenSearchType_AllObjects; /* traverse the tokens */ for (token = (NSSToken *)nssListIterator_Start(td->tokens); token != (NSSToken *)NULL;