| Index: nss/lib/certdb/stanpcertdb.c
|
| diff --git a/nss/lib/certdb/stanpcertdb.c b/nss/lib/certdb/stanpcertdb.c
|
| deleted file mode 100644
|
| index a65ad5cb84c5e08077154e36392649837ccb2b7b..0000000000000000000000000000000000000000
|
| --- a/nss/lib/certdb/stanpcertdb.c
|
| +++ /dev/null
|
| @@ -1,1041 +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, const 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(const 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;
|
| -
|
| - ret = STAN_ChangeCertTrust(cert, trust);
|
| - 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, PRTime 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,
|
| - const SECItem *name, PRTime 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)
|
| -{
|
| - PRTime oldtime;
|
| - PRTime 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;
|
| -}
|
|
|