diff options
Diffstat (limited to 'security/nss/lib/certdb/stanpcertdb.c')
-rw-r--r-- | security/nss/lib/certdb/stanpcertdb.c | 1073 |
1 files changed, 0 insertions, 1073 deletions
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c deleted file mode 100644 index e3e954184..000000000 --- a/security/nss/lib/certdb/stanpcertdb.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "prtime.h" - -#include "cert.h" -#include "certi.h" -#include "certdb.h" -#include "secitem.h" -#include "secder.h" - -/* Call to PK11_FreeSlot below */ - -#include "secasn1.h" -#include "secerr.h" -#include "nssilock.h" -#include "prmon.h" -#include "base64.h" -#include "sechash.h" -#include "plhash.h" -#include "pk11func.h" /* sigh */ - -#include "nsspki.h" -#include "pki.h" -#include "pkim.h" -#include "pki3hack.h" -#include "ckhelper.h" -#include "base.h" -#include "pkistore.h" -#include "dev3hack.h" -#include "dev.h" - -PRBool -SEC_CertNicknameConflict(const char *nickname, SECItem *derSubject, - CERTCertDBHandle *handle) -{ - CERTCertificate *cert; - PRBool conflict = PR_FALSE; - - cert=CERT_FindCertByNickname(handle, nickname); - - if (!cert) { - return conflict; - } - - conflict = !SECITEM_ItemsAreEqual(derSubject,&cert->derSubject); - CERT_DestroyCertificate(cert); - return conflict; -} - -SECStatus -SEC_DeletePermCertificate(CERTCertificate *cert) -{ - PRStatus nssrv; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSCertificate *c = STAN_GetNSSCertificate(cert); - CERTCertTrust *certTrust; - - if (c == NULL) { - /* error code is set */ - return SECFailure; - } - - certTrust = nssTrust_GetCERTCertTrustForCert(c, cert); - if (certTrust) { - NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c); - if (nssTrust) { - nssrv = STAN_DeleteCertTrustMatchingSlot(c); - if (nssrv != PR_SUCCESS) { - CERT_MapStanError(); - } - /* This call always returns PR_SUCCESS! */ - (void) nssTrust_Destroy(nssTrust); - } - } - - /* get rid of the token instances */ - nssrv = NSSCertificate_DeleteStoredObject(c, NULL); - - /* get rid of the cache entry */ - nssTrustDomain_LockCertCache(td); - nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); - nssTrustDomain_UnlockCertCache(td); - - return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; -} - -SECStatus -CERT_GetCertTrust(CERTCertificate *cert, CERTCertTrust *trust) -{ - SECStatus rv; - CERT_LockCertTrust(cert); - if ( cert->trust == NULL ) { - rv = SECFailure; - } else { - *trust = *cert->trust; - rv = SECSuccess; - } - CERT_UnlockCertTrust(cert); - return(rv); -} - -extern const NSSError NSS_ERROR_NO_ERROR; -extern const NSSError NSS_ERROR_INTERNAL_ERROR; -extern const NSSError NSS_ERROR_NO_MEMORY; -extern const NSSError NSS_ERROR_INVALID_POINTER; -extern const NSSError NSS_ERROR_INVALID_ARENA; -extern const NSSError NSS_ERROR_INVALID_ARENA_MARK; -extern const NSSError NSS_ERROR_DUPLICATE_POINTER; -extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED; -extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY; -extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED; -extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD; -extern const NSSError NSS_ERROR_VALUE_TOO_LARGE; -extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE; -extern const NSSError NSS_ERROR_BUFFER_TOO_SHORT; -extern const NSSError NSS_ERROR_INVALID_ATOB_CONTEXT; -extern const NSSError NSS_ERROR_INVALID_BASE64; -extern const NSSError NSS_ERROR_INVALID_BTOA_CONTEXT; -extern const NSSError NSS_ERROR_INVALID_ITEM; -extern const NSSError NSS_ERROR_INVALID_STRING; -extern const NSSError NSS_ERROR_INVALID_ASN1ENCODER; -extern const NSSError NSS_ERROR_INVALID_ASN1DECODER; -extern const NSSError NSS_ERROR_INVALID_BER; -extern const NSSError NSS_ERROR_INVALID_ATAV; -extern const NSSError NSS_ERROR_INVALID_ARGUMENT; -extern const NSSError NSS_ERROR_INVALID_UTF8; -extern const NSSError NSS_ERROR_INVALID_NSSOID; -extern const NSSError NSS_ERROR_UNKNOWN_ATTRIBUTE; -extern const NSSError NSS_ERROR_NOT_FOUND; -extern const NSSError NSS_ERROR_INVALID_PASSWORD; -extern const NSSError NSS_ERROR_USER_CANCELED; -extern const NSSError NSS_ERROR_MAXIMUM_FOUND; -extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND; -extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE; -extern const NSSError NSS_ERROR_HASH_COLLISION; -extern const NSSError NSS_ERROR_DEVICE_ERROR; -extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; -extern const NSSError NSS_ERROR_BUSY; -extern const NSSError NSS_ERROR_ALREADY_INITIALIZED; -extern const NSSError NSS_ERROR_PKCS11; - - -/* Look at the stan error stack and map it to NSS 3 errors */ -#define STAN_MAP_ERROR(x,y) \ - else if (error == (x)) { \ - secError = y; \ - } \ - -/* - * map Stan errors into NSS errors - * This function examines the stan error stack and automatically sets - * PORT_SetError(); to the appropriate SEC_ERROR value. - */ -void -CERT_MapStanError() -{ - PRInt32 *errorStack; - NSSError error, prevError; - int secError; - int i; - - error = 0; - - errorStack = NSS_GetErrorStack(); - if (errorStack == 0) { - PORT_SetError(0); - return; - } - error = prevError = CKR_GENERAL_ERROR; - /* get the 'top 2' error codes from the stack */ - for (i=0; errorStack[i]; i++) { - prevError = error; - error = errorStack[i]; - } - if (error == NSS_ERROR_PKCS11) { - /* map it */ - secError = PK11_MapError(prevError); - } - STAN_MAP_ERROR(NSS_ERROR_NO_ERROR, 0) - STAN_MAP_ERROR(NSS_ERROR_NO_MEMORY, SEC_ERROR_NO_MEMORY) - STAN_MAP_ERROR(NSS_ERROR_INVALID_BASE64, SEC_ERROR_BAD_DATA) - STAN_MAP_ERROR(NSS_ERROR_INVALID_BER, SEC_ERROR_BAD_DER) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ATAV, SEC_ERROR_INVALID_AVA) - STAN_MAP_ERROR(NSS_ERROR_INVALID_PASSWORD,SEC_ERROR_BAD_PASSWORD) - STAN_MAP_ERROR(NSS_ERROR_BUSY, SEC_ERROR_BUSY) - STAN_MAP_ERROR(NSS_ERROR_DEVICE_ERROR, SEC_ERROR_IO) - STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND, - SEC_ERROR_UNKNOWN_ISSUER) - STAN_MAP_ERROR(NSS_ERROR_INVALID_CERTIFICATE, SEC_ERROR_CERT_NOT_VALID) - STAN_MAP_ERROR(NSS_ERROR_INVALID_UTF8, SEC_ERROR_BAD_DATA) - STAN_MAP_ERROR(NSS_ERROR_INVALID_NSSOID, SEC_ERROR_BAD_DATA) - - /* these are library failure for lack of a better error code */ - STAN_MAP_ERROR(NSS_ERROR_NOT_FOUND, SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_IN_CACHE, - SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_MAXIMUM_FOUND, SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_USER_CANCELED, SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_INITIALIZED, - SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_ALREADY_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD, - SEC_ERROR_LIBRARY_FAILURE) - STAN_MAP_ERROR(NSS_ERROR_HASH_COLLISION, SEC_ERROR_LIBRARY_FAILURE) - - STAN_MAP_ERROR(NSS_ERROR_INTERNAL_ERROR, SEC_ERROR_LIBRARY_FAILURE) - - /* these are all invalid arguments */ - STAN_MAP_ERROR(NSS_ERROR_INVALID_ARGUMENT, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_POINTER, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA_MARK, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_DUPLICATE_POINTER, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_POINTER_NOT_REGISTERED, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_EMPTY, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_VALUE_TOO_LARGE, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_UNSUPPORTED_TYPE, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_BUFFER_TOO_SHORT, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ATOB_CONTEXT, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_BTOA_CONTEXT, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ITEM, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_STRING, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1ENCODER, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1DECODER, SEC_ERROR_INVALID_ARGS) - STAN_MAP_ERROR(NSS_ERROR_UNKNOWN_ATTRIBUTE, SEC_ERROR_INVALID_ARGS) - else { - secError = SEC_ERROR_LIBRARY_FAILURE; - } - PORT_SetError(secError); -} - - - -SECStatus -CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert, - CERTCertTrust *trust) -{ - SECStatus rv = SECSuccess; - PRStatus ret; - - CERT_LockCertTrust(cert); - ret = STAN_ChangeCertTrust(cert, trust); - CERT_UnlockCertTrust(cert); - if (ret != PR_SUCCESS) { - rv = SECFailure; - CERT_MapStanError(); - } - return rv; -} - -extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; - -SECStatus -__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, - CERTCertTrust *trust) -{ - NSSUTF8 *stanNick; - PK11SlotInfo *slot; - NSSToken *internal; - NSSCryptoContext *context; - nssCryptokiObject *permInstance; - NSSCertificate *c = STAN_GetNSSCertificate(cert); - nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; - nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; - SECStatus rv; - PRStatus ret; - - if (c == NULL) { - CERT_MapStanError(); - return SECFailure; - } - - context = c->object.cryptoContext; - if (!context) { - PORT_SetError(SEC_ERROR_ADDING_CERT); - return SECFailure; /* wasn't a temp cert */ - } - stanNick = nssCertificate_GetNickname(c, NULL); - if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { - /* different: take the new nickname */ - cert->nickname = NULL; - nss_ZFreeIf(stanNick); - stanNick = NULL; - } - if (!stanNick && nickname) { - /* Either there was no nickname yet, or we have a new nickname */ - stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL); - } /* else: old stanNick is identical to new nickname */ - /* Delete the temp instance */ - nssCertificateStore_Lock(context->certStore, &lockTrace); - nssCertificateStore_RemoveCertLOCKED(context->certStore, c); - nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); - c->object.cryptoContext = NULL; - /* Import the perm instance onto the internal token */ - slot = PK11_GetInternalKeySlot(); - internal = PK11Slot_GetNSSToken(slot); - permInstance = nssToken_ImportCertificate(internal, NULL, - NSSCertificateType_PKIX, - &c->id, - stanNick, - &c->encoding, - &c->issuer, - &c->subject, - &c->serial, - cert->emailAddr, - PR_TRUE); - nss_ZFreeIf(stanNick); - stanNick = NULL; - PK11_FreeSlot(slot); - if (!permInstance) { - if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { - PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); - } - return SECFailure; - } - nssPKIObject_AddInstance(&c->object, permInstance); - nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); - /* reset the CERTCertificate fields */ - cert->nssCertificate = NULL; - cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */ - if (!cert) { - CERT_MapStanError(); - return SECFailure; - } - cert->istemp = PR_FALSE; - cert->isperm = PR_TRUE; - if (!trust) { - return SECSuccess; - } - ret = STAN_ChangeCertTrust(cert, trust); - rv = SECSuccess; - if (ret != PR_SUCCESS) { - rv = SECFailure; - CERT_MapStanError(); - } - return rv; -} - -SECStatus -CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, - CERTCertTrust *trust) -{ - return __CERT_AddTempCertToPerm(cert, nickname, trust); -} - -CERTCertificate * -CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER) -{ - NSSCertificate *c; - CERTCertificate *cc; - NSSCertificate *tempCert = NULL; - nssPKIObject *pkio; - NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); - NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); - if (!isperm) { - NSSDER encoding; - NSSITEM_FROM_SECITEM(&encoding, derCert); - /* First, see if it is already a temp cert */ - c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC, - &encoding); - if (!c) { - /* Then, see if it is already a perm cert */ - c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, - &encoding); - } - if (c) { - /* actually, that search ends up going by issuer/serial, - * so it is still possible to return a cert with the same - * issuer/serial but a different encoding, and we're - * going to reject that - */ - if (!nssItem_Equal(&c->encoding, &encoding, NULL)) { - nssCertificate_Destroy(c); - PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); - cc = NULL; - } else { - cc = STAN_GetCERTCertificateOrRelease(c); - if (cc == NULL) { - CERT_MapStanError(); - } - } - return cc; - } - } - pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor); - if (!pkio) { - CERT_MapStanError(); - return NULL; - } - c = nss_ZNEW(pkio->arena, NSSCertificate); - if (!c) { - CERT_MapStanError(); - nssPKIObject_Destroy(pkio); - return NULL; - } - c->object = *pkio; - if (copyDER) { - nssItem_Create(c->object.arena, &c->encoding, - derCert->len, derCert->data); - } else { - NSSITEM_FROM_SECITEM(&c->encoding, derCert); - } - /* Forces a decoding of the cert in order to obtain the parts used - * below - */ - /* 'c' is not adopted here, if we fail loser frees what has been - * allocated so far for 'c' */ - cc = STAN_GetCERTCertificate(c); - if (!cc) { - CERT_MapStanError(); - goto loser; - } - nssItem_Create(c->object.arena, - &c->issuer, cc->derIssuer.len, cc->derIssuer.data); - nssItem_Create(c->object.arena, - &c->subject, cc->derSubject.len, cc->derSubject.data); - if (PR_TRUE) { - /* CERTCertificate stores serial numbers decoded. I need the DER - * here. sigh. - */ - SECItem derSerial = { 0 }; - CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); - if (!derSerial.data) goto loser; - nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data); - PORT_Free(derSerial.data); - } - if (nickname) { - c->object.tempName = nssUTF8_Create(c->object.arena, - nssStringType_UTF8String, - (NSSUTF8 *)nickname, - PORT_Strlen(nickname)); - } - if (cc->emailAddr && cc->emailAddr[0]) { - c->email = nssUTF8_Create(c->object.arena, - nssStringType_PrintableString, - (NSSUTF8 *)cc->emailAddr, - PORT_Strlen(cc->emailAddr)); - } - - tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c); - if (!tempCert) { - CERT_MapStanError(); - goto loser; - } - /* destroy our copy */ - NSSCertificate_Destroy(c); - /* and use the stored entry */ - c = tempCert; - cc = STAN_GetCERTCertificateOrRelease(c); - if (!cc) { - /* STAN_GetCERTCertificateOrRelease destroys c on failure. */ - CERT_MapStanError(); - return NULL; - } - - cc->istemp = PR_TRUE; - cc->isperm = PR_FALSE; - return cc; -loser: - /* Perhaps this should be nssCertificate_Destroy(c) */ - nssPKIObject_Destroy(&c->object); - return NULL; -} - -/* This symbol is exported for backward compatibility. */ -CERTCertificate * -__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, - char *nickname, PRBool isperm, PRBool copyDER) -{ - return CERT_NewTempCertificate(handle, derCert, nickname, - isperm, copyDER); -} - -/* maybe all the wincx's should be some const for internal token login? */ -CERTCertificate * -CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndSN) -{ - PK11SlotInfo *slot; - CERTCertificate *cert; - - cert = PK11_FindCertByIssuerAndSN(&slot,issuerAndSN,NULL); - if (cert && slot) { - PK11_FreeSlot(slot); - } - - return cert; -} - -static NSSCertificate * -get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp) -{ - NSSUsage usage; - NSSCertificate *arr[3]; - if (!ct) { - return nssCertificate_AddRef(cp); - } else if (!cp) { - return nssCertificate_AddRef(ct); - } - arr[0] = ct; - arr[1] = cp; - arr[2] = NULL; - usage.anyUsage = PR_TRUE; - return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL); -} - -CERTCertificate * -CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name) -{ - NSSCertificate *cp, *ct, *c; - NSSDER subject; - NSSUsage usage; - NSSCryptoContext *cc; - NSSITEM_FROM_SECITEM(&subject, name); - usage.anyUsage = PR_TRUE; - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateBySubject(cc, &subject, - NULL, &usage, NULL); - cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject, - NULL, &usage, NULL); - c = get_best_temp_or_perm(ct, cp); - if (ct) { - CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); - } - if (cp) { - CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp)); - } - return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; -} - -CERTCertificate * -CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID) -{ - CERTCertList *list; - CERTCertificate *cert = NULL; - CERTCertListNode *node, *head; - - list = CERT_CreateSubjectCertList(NULL,handle,name,0,PR_FALSE); - if (list == NULL) return NULL; - - node = head = CERT_LIST_HEAD(list); - if (head) { - do { - if (node->cert && - SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID) ) { - cert = CERT_DupCertificate(node->cert); - goto done; - } - node = CERT_LIST_NEXT(node); - } while (node && head != node); - } - PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); -done: - if (list) { - CERT_DestroyCertList(list); - } - return cert; -} - -CERTCertificate * -CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname) -{ - NSSCryptoContext *cc; - NSSCertificate *c, *ct; - CERTCertificate *cert; - NSSUsage usage; - usage.anyUsage = PR_TRUE; - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname, - NULL, &usage, NULL); - cert = PK11_FindCertFromNickname(nickname, NULL); - c = NULL; - if (cert) { - c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); - CERT_DestroyCertificate(cert); - if (ct) { - CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); - } - } else { - c = ct; - } - return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; -} - -CERTCertificate * -CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert) -{ - NSSCryptoContext *cc; - NSSCertificate *c; - NSSDER encoding; - NSSITEM_FROM_SECITEM(&encoding, derCert); - cc = STAN_GetDefaultCryptoContext(); - c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding); - if (!c) { - c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, - &encoding); - if (!c) return NULL; - } - return STAN_GetCERTCertificateOrRelease(c); -} - -static CERTCertificate * -common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, - const char *name, - PRBool anyUsage, - SECCertUsage lookingForUsage) -{ - NSSCryptoContext *cc; - NSSCertificate *c, *ct; - CERTCertificate *cert = NULL; - NSSUsage usage; - CERTCertList *certlist; - - if (NULL == name) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - usage.anyUsage = anyUsage; - - if (!anyUsage) { - usage.nss3lookingForCA = PR_FALSE; - usage.nss3usage = lookingForUsage; - } - - cc = STAN_GetDefaultCryptoContext(); - ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, - NULL, &usage, NULL); - if (!ct && PORT_Strchr(name, '@') != NULL) { - char* lowercaseName = CERT_FixupEmailAddr(name); - if (lowercaseName) { - ct = NSSCryptoContext_FindBestCertificateByEmail(cc, lowercaseName, - NULL, &usage, NULL); - PORT_Free(lowercaseName); - } - } - - if (anyUsage) { - cert = PK11_FindCertFromNickname(name, NULL); - } - else { - if (ct) { - /* Does ct really have the required usage? */ - nssDecodedCert *dc; - dc = nssCertificate_GetDecoding(ct); - if (!dc->matchUsage(dc, &usage)) { - CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); - ct = NULL; - } - } - - certlist = PK11_FindCertsFromNickname(name, NULL); - if (certlist) { - SECStatus rv = CERT_FilterCertListByUsage(certlist, - lookingForUsage, - PR_FALSE); - if (SECSuccess == rv && - !CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) { - cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert); - } - CERT_DestroyCertList(certlist); - } - } - - if (cert) { - c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); - CERT_DestroyCertificate(cert); - if (ct) { - CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); - } - } else { - c = ct; - } - return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; -} - -CERTCertificate * -CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name) -{ - return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, - PR_TRUE, 0); -} - -CERTCertificate * -CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, - const char *name, - SECCertUsage lookingForUsage) -{ - return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, - PR_FALSE, - lookingForUsage); -} - -static void -add_to_subject_list(CERTCertList *certList, CERTCertificate *cert, - PRBool validOnly, int64 sorttime) -{ - SECStatus secrv; - if (!validOnly || - CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE) - == secCertTimeValid) { - secrv = CERT_AddCertToListSorted(certList, cert, - CERT_SortCBValidity, - (void *)&sorttime); - if (secrv != SECSuccess) { - CERT_DestroyCertificate(cert); - } - } else { - CERT_DestroyCertificate(cert); - } -} - -CERTCertList * -CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle, - SECItem *name, int64 sorttime, PRBool validOnly) -{ - NSSCryptoContext *cc; - NSSCertificate **tSubjectCerts, **pSubjectCerts; - NSSCertificate **ci; - CERTCertificate *cert; - NSSDER subject; - PRBool myList = PR_FALSE; - cc = STAN_GetDefaultCryptoContext(); - NSSITEM_FROM_SECITEM(&subject, name); - /* Collect both temp and perm certs for the subject */ - tSubjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc, - &subject, - NULL, - 0, - NULL); - pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle, - &subject, - NULL, - 0, - NULL); - if (!tSubjectCerts && !pSubjectCerts) { - return NULL; - } - if (certList == NULL) { - certList = CERT_NewCertList(); - myList = PR_TRUE; - if (!certList) goto loser; - } - /* Iterate over the matching temp certs. Add them to the list */ - ci = tSubjectCerts; - while (ci && *ci) { - cert = STAN_GetCERTCertificateOrRelease(*ci); - /* *ci may be invalid at this point, don't reference it again */ - if (cert) { - /* NOTE: add_to_subject_list adopts the incoming cert. */ - add_to_subject_list(certList, cert, validOnly, sorttime); - } - ci++; - } - /* Iterate over the matching perm certs. Add them to the list */ - ci = pSubjectCerts; - while (ci && *ci) { - cert = STAN_GetCERTCertificateOrRelease(*ci); - /* *ci may be invalid at this point, don't reference it again */ - if (cert) { - /* NOTE: add_to_subject_list adopts the incoming cert. */ - add_to_subject_list(certList, cert, validOnly, sorttime); - } - ci++; - } - /* all the references have been adopted or freed at this point, just - * free the arrays now */ - nss_ZFreeIf(tSubjectCerts); - nss_ZFreeIf(pSubjectCerts); - return certList; -loser: - /* need to free the references in tSubjectCerts and pSubjectCerts! */ - nssCertificateArray_Destroy(tSubjectCerts); - nssCertificateArray_Destroy(pSubjectCerts); - if (myList && certList != NULL) { - CERT_DestroyCertList(certList); - } - return NULL; -} - -void -CERT_DestroyCertificate(CERTCertificate *cert) -{ - if ( cert ) { - /* don't use STAN_GetNSSCertificate because we don't want to - * go to the trouble of translating the CERTCertificate into - * an NSSCertificate just to destroy it. If it hasn't been done - * yet, don't do it at all. - */ - NSSCertificate *tmp = cert->nssCertificate; - if (tmp) { - /* delete the NSSCertificate */ - NSSCertificate_Destroy(tmp); - } else if (cert->arena) { - PORT_FreeArena(cert->arena, PR_FALSE); - } - } - return; -} - -int -CERT_GetDBContentVersion(CERTCertDBHandle *handle) -{ - /* should read the DB content version from the pkcs #11 device */ - return 0; -} - -SECStatus -certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr, - SECItem *emailProfile, SECItem *profileTime) -{ - int64 oldtime; - int64 newtime; - SECStatus rv = SECFailure; - PRBool saveit; - SECItem oldprof, oldproftime; - SECItem *oldProfile = NULL; - SECItem *oldProfileTime = NULL; - PK11SlotInfo *slot = NULL; - NSSCertificate *c; - NSSCryptoContext *cc; - nssSMIMEProfile *stanProfile = NULL; - PRBool freeOldProfile = PR_FALSE; - - c = STAN_GetNSSCertificate(cert); - if (!c) return SECFailure; - cc = c->object.cryptoContext; - if (cc != NULL) { - stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); - if (stanProfile) { - PORT_Assert(stanProfile->profileData); - SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData); - oldProfile = &oldprof; - SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime); - oldProfileTime = &oldproftime; - } - } else { - oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr, - &cert->derSubject, &oldProfileTime); - freeOldProfile = PR_TRUE; - } - - saveit = PR_FALSE; - - /* both profileTime and emailProfile have to exist or not exist */ - if ( emailProfile == NULL ) { - profileTime = NULL; - } else if ( profileTime == NULL ) { - emailProfile = NULL; - } - - if ( oldProfileTime == NULL ) { - saveit = PR_TRUE; - } else { - /* there was already a profile for this email addr */ - if ( profileTime ) { - /* we have an old and new profile - save whichever is more recent*/ - if ( oldProfileTime->len == 0 ) { - /* always replace if old entry doesn't have a time */ - oldtime = LL_MININT; - } else { - rv = DER_UTCTimeToTime(&oldtime, oldProfileTime); - if ( rv != SECSuccess ) { - goto loser; - } - } - - rv = DER_UTCTimeToTime(&newtime, profileTime); - if ( rv != SECSuccess ) { - goto loser; - } - - if ( LL_CMP(newtime, >, oldtime ) ) { - /* this is a newer profile, save it and cert */ - saveit = PR_TRUE; - } - } else { - saveit = PR_TRUE; - } - } - - - if (saveit) { - if (cc) { - if (stanProfile) { - /* stanProfile is already stored in the crypto context, - * overwrite the data - */ - NSSArena *arena = stanProfile->object.arena; - stanProfile->profileTime = nssItem_Create(arena, - NULL, - profileTime->len, - profileTime->data); - stanProfile->profileData = nssItem_Create(arena, - NULL, - emailProfile->len, - emailProfile->data); - } else if (profileTime && emailProfile) { - PRStatus nssrv; - NSSItem profTime, profData; - NSSITEM_FROM_SECITEM(&profTime, profileTime); - NSSITEM_FROM_SECITEM(&profData, emailProfile); - stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData); - if (!stanProfile) goto loser; - nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile); - rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; - } - } else { - rv = PK11_SaveSMimeProfile(slot, (char *)emailAddr, - &cert->derSubject, emailProfile, profileTime); - } - } else { - rv = SECSuccess; - } - -loser: - if (oldProfile && freeOldProfile) { - SECITEM_FreeItem(oldProfile,PR_TRUE); - } - if (oldProfileTime && freeOldProfile) { - SECITEM_FreeItem(oldProfileTime,PR_TRUE); - } - if (stanProfile) { - nssSMIMEProfile_Destroy(stanProfile); - } - if (slot) { - PK11_FreeSlot(slot); - } - - return(rv); -} - -/* - * - * Manage S/MIME profiles - * - */ - -SECStatus -CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, - SECItem *profileTime) -{ - const char *emailAddr; - SECStatus rv; - - if (!cert) { - return SECFailure; - } - - if (cert->slot && !PK11_IsInternal(cert->slot)) { - /* this cert comes from an external source, we need to add it - to the cert db before creating an S/MIME profile */ - PK11SlotInfo* internalslot = PK11_GetInternalKeySlot(); - if (!internalslot) { - return SECFailure; - } - rv = PK11_ImportCert(internalslot, cert, - CK_INVALID_HANDLE, NULL, PR_FALSE); - - PK11_FreeSlot(internalslot); - if (rv != SECSuccess ) { - return SECFailure; - } - } - - if (cert->slot && cert->isperm && CERT_IsUserCert(cert) && - (!emailProfile || !emailProfile->len)) { - /* Don't clobber emailProfile for user certs. */ - return SECSuccess; - } - - for (emailAddr = CERT_GetFirstEmailAddress(cert); emailAddr != NULL; - emailAddr = CERT_GetNextEmailAddress(cert,emailAddr)) { - rv = certdb_SaveSingleProfile(cert,emailAddr,emailProfile,profileTime); - if (rv != SECSuccess) { - return SECFailure; - } - } - return SECSuccess; - -} - - -SECItem * -CERT_FindSMimeProfile(CERTCertificate *cert) -{ - PK11SlotInfo *slot = NULL; - NSSCertificate *c; - NSSCryptoContext *cc; - SECItem *rvItem = NULL; - - if (!cert || !cert->emailAddr || !cert->emailAddr[0]) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - c = STAN_GetNSSCertificate(cert); - if (!c) return NULL; - cc = c->object.cryptoContext; - if (cc != NULL) { - nssSMIMEProfile *stanProfile; - stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); - if (stanProfile) { - rvItem = SECITEM_AllocItem(NULL, NULL, - stanProfile->profileData->size); - if (rvItem) { - rvItem->data = stanProfile->profileData->data; - } - nssSMIMEProfile_Destroy(stanProfile); - } - return rvItem; - } - rvItem = - PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL); - if (slot) { - PK11_FreeSlot(slot); - } - return rvItem; -} - -/* - * deprecated functions that are now just stubs. - */ -/* - * Close the database - */ -void -__CERT_ClosePermCertDB(CERTCertDBHandle *handle) -{ - PORT_Assert("CERT_ClosePermCertDB is Deprecated" == NULL); - return; -} - -SECStatus -CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname, - PRBool readOnly) -{ - PORT_Assert("CERT_OpenCertDBFilename is Deprecated" == NULL); - PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); - return SECFailure; -} - -SECItem * -SECKEY_HashPassword(char *pw, SECItem *salt) -{ - PORT_Assert("SECKEY_HashPassword is Deprecated" == NULL); - PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); - return NULL; -} - -SECStatus -__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, - SECItem *derSubject, - void *cb, void *cbarg) -{ - PORT_Assert("CERT_TraversePermCertsForSubject is Deprecated" == NULL); - PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); - return SECFailure; -} - - -SECStatus -__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname, - void *cb, void *cbarg) -{ - PORT_Assert("CERT_TraversePermCertsForNickname is Deprecated" == NULL); - PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); - return SECFailure; -} - - - |