Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
pk11nobj.c File Reference
#include "secport.h"
#include "seccomon.h"
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#include "pkcs11.h"
#include "pk11func.h"
#include "cert.h"
#include "certi.h"
#include "secitem.h"
#include "sechash.h"
#include "secoid.h"
#include "certdb.h"
#include "secerr.h"
#include "sslerr.h"
#include "pki3hack.h"
#include "dev3hack.h"
#include "devm.h"
#include "pki.h"
#include "pkim.h"

Go to the source code of this file.

Classes

struct  crlOptionsStr

Defines

#define NSS_3_4_CODE

Typedefs

typedef struct crlOptionsStr

Functions

CK_TRUST pk11_GetTrustField (PK11SlotInfo *slot, PRArenaPool *arena, CK_OBJECT_HANDLE id, CK_ATTRIBUTE_TYPE type)
PRBool pk11_HandleTrustObject (PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust *trust)
static SECStatus pk11_CollectCrls (PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
SECStatus PK11_LookupCrls (CERTCrlHeadNode *nodes, int type, void *wincx)
static SECStatus pk11_RetrieveCrlsCallback (PK11SlotInfo *slot, CK_OBJECT_HANDLE crlID, void *arg)
SECStatus pk11_RetrieveCrls (CERTCrlHeadNode *nodes, SECItem *issuer, void *wincx)
SECItem * PK11_FindCrlByName (PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, SECItem *name, int type, char **url)
CK_OBJECT_HANDLE PK11_PutCrl (PK11SlotInfo *slot, SECItem *crl, SECItem *name, char *url, int type)
SECStatus SEC_DeletePermCRL (CERTSignedCrl *crl)
SECItem * PK11_FindSMimeProfile (PK11SlotInfo **slot, char *emailAddr, SECItem *name, SECItem **profileTime)
SECStatus PK11_SaveSMimeProfile (PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, SECItem *emailProfile, SECItem *profileTime)
CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot, char *url, CERTSignedCrl *newCrl, SECItem *derCrl, int type)
CERTSignedCrl * PK11_ImportCRL (PK11SlotInfo *slot, SECItem *derCRL, char *url, int type, void *wincx, PRInt32 importOptions, PRArenaPool *arena, PRInt32 decodeoptions)

Variables

const NSSError NSS_ERROR_NOT_FOUND

Class Documentation

struct crlOptionsStr

Definition at line 273 of file pk11nobj.c.

Class Members
PRInt32 decodeOptions
CERTCrlHeadNode * head

Define Documentation

Definition at line 59 of file pk11nobj.c.


Typedef Documentation

typedef struct crlOptionsStr

Definition at line 281 of file pk11nobj.c.


Function Documentation

CERTSignedCrl* crl_storeCRL ( PK11SlotInfo *  slot,
char *  url,
CERTSignedCrl *  newCrl,
SECItem *  derCrl,
int  type 
)

Definition at line 690 of file crl.c.

{
    CERTSignedCrl *oldCrl = NULL, *crl = NULL;
    PRBool deleteOldCrl = PR_FALSE;
    CK_OBJECT_HANDLE crlHandle = CK_INVALID_HANDLE;
    SECStatus rv;

    PORT_Assert(newCrl);
    PORT_Assert(derCrl);

    /* we can't use the cache here because we must look in the same
       token */
    rv = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type,
                                &oldCrl, CRL_DECODE_SKIP_ENTRIES);
    /* if there is an old crl on the token, make sure the one we are
       installing is newer. If not, exit out, otherwise delete the
       old crl.
     */
    if (oldCrl != NULL) {
       /* if it's already there, quietly continue */
       if (SECITEM_CompareItem(newCrl->derCrl, oldCrl->derCrl) 
                                          == SECEqual) {
           crl = newCrl;
           crl->slot = PK11_ReferenceSlot(slot);
           crl->pkcs11ID = oldCrl->pkcs11ID;
           goto done;
       }
        if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) {

            if (type == SEC_CRL_TYPE) {
                PORT_SetError(SEC_ERROR_OLD_CRL);
            } else {
                PORT_SetError(SEC_ERROR_OLD_KRL);
            }

            goto done;
        }

        if ((SECITEM_CompareItem(&newCrl->crl.derName,
                &oldCrl->crl.derName) != SECEqual) &&
            (type == SEC_KRL_TYPE) ) {

            PORT_SetError(SEC_ERROR_CKL_CONFLICT);
            goto done;
        }

        /* if we have a url in the database, use that one */
        if (oldCrl->url) {
           url = oldCrl->url;
        }

        /* really destroy this crl */
        /* first drum it out of the permanment Data base */
       deleteOldCrl = PR_TRUE;
    }

    /* invalidate CRL cache for this issuer */
    CERT_CRLCacheRefreshIssuer(NULL, &newCrl->crl.derName);
    /* Write the new entry into the data base */
    crlHandle = PK11_PutCrl(slot, derCrl, &newCrl->crl.derName, url, type);
    if (crlHandle != CK_INVALID_HANDLE) {
       crl = newCrl;
       crl->slot = PK11_ReferenceSlot(slot);
       crl->pkcs11ID = crlHandle;
       if (url) {
           crl->url = PORT_ArenaStrdup(crl->arena,url);
       }
    }

done:
    if (oldCrl) {
       if (deleteOldCrl && crlHandle != CK_INVALID_HANDLE) {
           SEC_DeletePermCRL(oldCrl);
       }
       SEC_DestroyCrl(oldCrl);
    }

    return crl;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus pk11_CollectCrls ( PK11SlotInfo *  slot,
CK_OBJECT_HANDLE  crlID,
void arg 
) [static]

Definition at line 180 of file pk11nobj.c.

{
    SECItem derCrl;
    CERTCrlHeadNode *head = (CERTCrlHeadNode *) arg;
    CERTCrlNode *new_node = NULL;
    CK_ATTRIBUTE fetchCrl[3] = {
        { CKA_VALUE, NULL, 0},
        { CKA_NETSCAPE_KRL, NULL, 0},
        { CKA_NETSCAPE_URL, NULL, 0},
    };
    const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
    CK_RV crv;
    SECStatus rv = SECFailure;

    crv = PK11_GetAttributes(head->arena,slot,crlID,fetchCrl,fetchCrlSize);
    if (CKR_OK != crv) {
       PORT_SetError(PK11_MapError(crv));
       goto loser;
    }

    if (!fetchCrl[1].pValue) {
       PORT_SetError(SEC_ERROR_CRL_INVALID);
       goto loser;
    }

    new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena, sizeof(CERTCrlNode));
    if (new_node == NULL) {
        goto loser;
    }

    if (*((CK_BBOOL *)fetchCrl[1].pValue))
        new_node->type = SEC_KRL_TYPE;
    else
        new_node->type = SEC_CRL_TYPE;

    derCrl.type = siBuffer;
    derCrl.data = (unsigned char *)fetchCrl[0].pValue;
    derCrl.len = fetchCrl[0].ulValueLen;
    new_node->crl=CERT_DecodeDERCrl(head->arena,&derCrl,new_node->type);
    if (new_node->crl == NULL) {
       goto loser;
    }

    if (fetchCrl[2].pValue) {
        int nnlen = fetchCrl[2].ulValueLen;
        new_node->crl->url  = (char *)PORT_ArenaAlloc(head->arena, nnlen+1);
        if ( !new_node->crl->url ) {
            goto loser;
        }
        PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
        new_node->crl->url[nnlen] = 0;
    } else {
        new_node->crl->url = NULL;
    }


    new_node->next = NULL;
    if (head->last) {
        head->last->next = new_node;
        head->last = new_node;
    } else {
        head->first = head->last = new_node;
    }
    rv = SECSuccess;

loser:
    return(rv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECItem* PK11_FindCrlByName ( PK11SlotInfo **  slot,
CK_OBJECT_HANDLE crlHandle,
SECItem *  name,
int  type,
char **  url 
)

Definition at line 431 of file pk11nobj.c.

{
    NSSCRL **crls, **crlp, *crl;
    NSSDER subject;
    SECItem *rvItem;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSITEM_FROM_SECITEM(&subject, name);
    if (*slot) {
       nssCryptokiObject **instances;
       nssPKIObjectCollection *collection;
       nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
       NSSToken *token = PK11Slot_GetNSSToken(*slot);
       collection = nssCRLCollection_Create(td, NULL);
       if (!collection) {
           return NULL;
       }
       instances = nssToken_FindCRLsBySubject(token, NULL, &subject, 
                                              tokenOnly, 0, NULL);
       nssPKIObjectCollection_AddInstances(collection, instances, 0);
       nss_ZFreeIf(instances);
       crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
       nssPKIObjectCollection_Destroy(collection);
    } else {
       crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
    }
    if ((!crls) || (*crls == NULL)) {
       if (crls) {
           nssCRLArray_Destroy(crls);
       }
       if (NSS_GetError() == NSS_ERROR_NOT_FOUND) {
           PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
       }
       return NULL;
    }
    crl = NULL;
    for (crlp = crls; *crlp; crlp++) {
       if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
           ((*crlp)->isKRL && type != SEC_CRL_TYPE)) 
       {
           crl = nssCRL_AddRef(*crlp);
           break;
       }
    }
    nssCRLArray_Destroy(crls);
    if (!crl) { 
       /* CRL collection was found, but no interesting CRL's were on it.
        * Not an error */
       PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
       return NULL;
    }
    if (crl->url) {
       *url = PORT_Strdup(crl->url);
       if (!*url) {
           nssCRL_Destroy(crl);
           return NULL;
       }
    } else {
       *url = NULL;
    }
    rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
    if (!rvItem) {
       PORT_Free(*url);
       nssCRL_Destroy(crl);
       return NULL;
    }
    memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
    *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
    *crlHandle = crl->object.instances[0]->handle;
    nssCRL_Destroy(crl);
    return rvItem;
}

Here is the call graph for this function:

SECItem* PK11_FindSMimeProfile ( PK11SlotInfo **  slot,
char *  emailAddr,
SECItem *  name,
SECItem **  profileTime 
)

Definition at line 564 of file pk11nobj.c.

{
    CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
    CK_ATTRIBUTE theTemplate[] = {
       { CKA_SUBJECT, NULL, 0 },
       { CKA_CLASS, NULL, 0 },
       { CKA_NETSCAPE_EMAIL, NULL, 0 },
    };
    CK_ATTRIBUTE smimeData[] =  {
       { CKA_SUBJECT, NULL, 0 },
       { CKA_VALUE, NULL, 0 },
    };
    /* if you change the array, change the variable below as well */
    int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
    CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
    CK_ATTRIBUTE *attrs = theTemplate;
    CK_RV crv;
    SECItem *emailProfile = NULL;

    if (!emailAddr || !emailAddr[0]) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return NULL;
    }

    PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
    PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
    PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, strlen(emailAddr)); 
                                                            attrs++;

    if (*slot) {
       smimeh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
    } else {
       PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
                                                 PR_FALSE,PR_TRUE,NULL);
       PK11SlotListElement *le;

       /* loop through all the slots */
       for (le = list->head; le; le = le->next) {
           smimeh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
           if (smimeh != CK_INVALID_HANDLE) {
              *slot = PK11_ReferenceSlot(le->slot);
              break;
           }
       }
       PK11_FreeSlotList(list);
    }
    
    if (smimeh == CK_INVALID_HANDLE) {
       PORT_SetError(SEC_ERROR_NO_KRL);
       return NULL;
    }

    if (profileTime) {
       PK11_SETATTRS(smimeData, CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0);
    } 
    
    crv = PK11_GetAttributes(NULL,*slot,smimeh,smimeData,2);
    if (crv != CKR_OK) {
       PORT_SetError(PK11_MapError (crv));
       goto loser;
    }

    if (!profileTime) {
       SECItem profileSubject;

       profileSubject.data = (unsigned char*) smimeData[0].pValue;
       profileSubject.len = smimeData[0].ulValueLen;
       if (!SECITEM_ItemsAreEqual(&profileSubject,name)) {
           goto loser;
       }
    }

    emailProfile = (SECItem *)PORT_ZAlloc(sizeof(SECItem));    
    if (emailProfile == NULL) {
       goto loser;
    }

    emailProfile->data = (unsigned char*) smimeData[1].pValue;
    emailProfile->len = smimeData[1].ulValueLen;

    if (profileTime) {
       *profileTime = (SECItem *)PORT_ZAlloc(sizeof(SECItem));    
       if (*profileTime) {
           (*profileTime)->data = (unsigned char*) smimeData[0].pValue;
           (*profileTime)->len = smimeData[0].ulValueLen;
       }
    }

loser:
    if (emailProfile == NULL) {
       if (smimeData[1].pValue) {
           PORT_Free(smimeData[1].pValue);
       }
    }
    if (profileTime == NULL || *profileTime == NULL) {
       if (smimeData[0].pValue) {
           PORT_Free(smimeData[0].pValue);
       }
    }
    return emailProfile;
}

Here is the call graph for this function:

CK_TRUST pk11_GetTrustField ( PK11SlotInfo *  slot,
PRArenaPool arena,
CK_OBJECT_HANDLE  id,
CK_ATTRIBUTE_TYPE  type 
)

Definition at line 71 of file pk11nobj.c.

{
  CK_TRUST rv = 0;
  SECItem item;

  item.data = NULL;
  item.len = 0;

  if( SECSuccess == PK11_ReadAttribute(slot, id, type, arena, &item) ) {
    PORT_Assert(item.len == sizeof(CK_TRUST));
    PORT_Memcpy(&rv, item.data, sizeof(CK_TRUST));
    /* Damn, is there an endian problem here? */
    return rv;
  }

  return 0;
}

Here is the call graph for this function:

PRBool pk11_HandleTrustObject ( PK11SlotInfo *  slot,
CERTCertificate *  cert,
CERTCertTrust *  trust 
)

Definition at line 91 of file pk11nobj.c.

{
  PRArenaPool *arena;

  CK_ATTRIBUTE tobjTemplate[] = {
    { CKA_CLASS, NULL, 0 },
    { CKA_CERT_SHA1_HASH, NULL, 0 },
  };

  CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST;
  CK_OBJECT_HANDLE tobjID;
  unsigned char sha1_hash[SHA1_LENGTH];

  CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;

  PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);

  PK11_SETATTRS(&tobjTemplate[0], CKA_CLASS, &tobjc, sizeof(tobjc));
  PK11_SETATTRS(&tobjTemplate[1], CKA_CERT_SHA1_HASH, sha1_hash, 
                SHA1_LENGTH);

  tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate, 
                                     sizeof(tobjTemplate)/sizeof(tobjTemplate[0]));
  if( CK_INVALID_HANDLE == tobjID ) {
    return PR_FALSE;
  }

  arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
  if( NULL == arena ) return PR_FALSE;

  /* Unfortunately, it seems that PK11_GetAttributes doesn't deal
   * well with nonexistant attributes.  I guess we have to check 
   * the trust info fields one at a time.
   */

  /* We could verify CKA_CERT_HASH here */

  /* We could verify CKA_EXPIRES here */


  /* "Purpose" trust information */
  serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
  clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
  codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
  emailProtection = pk11_GetTrustField(slot, arena, tobjID, 
                                          CKA_TRUST_EMAIL_PROTECTION);
  /* Here's where the fun logic happens.  We have to map back from the 
   * key usage, extended key usage, purpose, and possibly other trust values 
   * into the old trust-flags bits.  */

  /* First implementation: keep it simple for testing.  We can study what other
   * mappings would be appropriate and add them later.. fgmr 20000724 */

  if ( serverAuth ==  CKT_NETSCAPE_TRUSTED ) {
    trust->sslFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
  }

  if ( serverAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
    trust->sslFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | 
                                                 CERTDB_NS_TRUSTED_CA;
  }
  if ( clientAuth == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
    trust->sslFlags |=  CERTDB_TRUSTED_CLIENT_CA ;
  }

  if ( emailProtection == CKT_NETSCAPE_TRUSTED ) {
    trust->emailFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
  }

  if ( emailProtection == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
    trust->emailFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
  }

  if( codeSigning == CKT_NETSCAPE_TRUSTED ) {
    trust->objectSigningFlags |= CERTDB_VALID_PEER | CERTDB_TRUSTED;
  }

  if( codeSigning == CKT_NETSCAPE_TRUSTED_DELEGATOR ) {
    trust->objectSigningFlags |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA;
  }

  /* There's certainly a lot more logic that can go here.. */

  PORT_FreeArena(arena, PR_FALSE);

  return PR_TRUE;
}

Here is the call graph for this function:

CERTSignedCrl* PK11_ImportCRL ( PK11SlotInfo *  slot,
SECItem *  derCRL,
char *  url,
int  type,
void wincx,
PRInt32  importOptions,
PRArenaPool arena,
PRInt32  decodeoptions 
)

Definition at line 741 of file pk11nobj.c.

{
    CERTSignedCrl *newCrl, *crl;
    SECStatus rv;
    CERTCertificate *caCert = NULL;

    newCrl = crl = NULL;

    do {
        newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type,
                                            decodeoptions);
        if (newCrl == NULL) {
            if (type == SEC_CRL_TYPE) {
                /* only promote error when the error code is too generic */
                if (PORT_GetError () == SEC_ERROR_BAD_DER)
                    PORT_SetError(SEC_ERROR_CRL_INVALID);
               } else {
                PORT_SetError(SEC_ERROR_KRL_INVALID);
            }
            break;          
        }

        if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){
            CERTCertDBHandle* handle = CERT_GetDefaultCertDB();
            PR_ASSERT(handle != NULL);
            caCert = CERT_FindCertByName (handle,
                                          &newCrl->crl.derName);
            if (caCert == NULL) {
                PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);           
                break;
            }

            /* If caCert is a v3 certificate, make sure that it can be used for
               crl signing purpose */
            rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN);
            if (rv != SECSuccess) {
                break;
            }

            rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,
                                       PR_Now(), wincx);
            if (rv != SECSuccess) {
                if (type == SEC_CRL_TYPE) {
                    PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
                } else {
                    PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
                }
                break;
            }
        }

       crl = crl_storeCRL(slot, url, newCrl, derCRL, type);

    } while (0);

    if (crl == NULL) {
       SEC_DestroyCrl (newCrl);
    }
    if (caCert) {
        CERT_DestroyCertificate(caCert);
    }
    return (crl);
}

Here is the call graph for this function:

SECStatus PK11_LookupCrls ( CERTCrlHeadNode *  nodes,
int  type,
void wincx 
)

Definition at line 254 of file pk11nobj.c.

                                                               {
    pk11TraverseSlot creater;
    CK_ATTRIBUTE theTemplate[2];
    CK_ATTRIBUTE *attrs;
    CK_OBJECT_CLASS certClass = CKO_NETSCAPE_CRL;
    CK_BBOOL isKrl = CK_FALSE;

    attrs = theTemplate;
    PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
    if (type != -1) {
       isKrl = (CK_BBOOL) (type == SEC_KRL_TYPE);
        PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, &isKrl, sizeof(isKrl)); attrs++;
    }

    creater.callback = pk11_CollectCrls;
    creater.callbackArg = (void *) nodes;
    creater.findTemplate = theTemplate;
    creater.templateCount = (attrs - theTemplate);

    return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
}

Here is the call graph for this function:

CK_OBJECT_HANDLE PK11_PutCrl ( PK11SlotInfo *  slot,
SECItem *  crl,
SECItem *  name,
char *  url,
int  type 
)

Definition at line 505 of file pk11nobj.c.

{
    NSSItem derCRL, derSubject;
    NSSToken *token = PK11Slot_GetNSSToken(slot);
    nssCryptokiObject *object;
    PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
    CK_OBJECT_HANDLE rvH;

    NSSITEM_FROM_SECITEM(&derSubject, name);
    NSSITEM_FROM_SECITEM(&derCRL, crl);

    object = nssToken_ImportCRL(token, NULL, 
                                &derSubject, &derCRL, isKRL, url, PR_TRUE);

    if (object) {
       rvH = object->handle;
       nssCryptokiObject_Destroy(object);
    } else {
       rvH = CK_INVALID_HANDLE;
    }
    return rvH;
}

Here is the call graph for this function:

SECStatus pk11_RetrieveCrls ( CERTCrlHeadNode *  nodes,
SECItem *  issuer,
void wincx 
)

Definition at line 390 of file pk11nobj.c.

{
    pk11TraverseSlot creater;
    CK_ATTRIBUTE theTemplate[2];
    CK_ATTRIBUTE *attrs;
    CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
    crlOptions options;

    attrs = theTemplate;
    PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;

    options.head = nodes;

    /* - do a partial decoding - we don't need to decode the entries while
       fetching
       - don't copy the DER for optimal performance - CRL can be very large
       - have the CRL objects adopt the DER, so SEC_DestroyCrl will free it
       - keep bad CRL objects. The CRL cache is interested in them, for
         security purposes. Bad CRL objects are a sign of something amiss.
    */

    options.decodeOptions = CRL_DECODE_SKIP_ENTRIES | CRL_DECODE_DONT_COPY_DER |
                            CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_KEEP_BAD_CRL;
    if (issuer)
    {
        PK11_SETATTRS(attrs, CKA_SUBJECT, issuer->data, issuer->len); attrs++;
    }

    creater.callback = pk11_RetrieveCrlsCallback;
    creater.callbackArg = (void *) &options;
    creater.findTemplate = theTemplate;
    creater.templateCount = (attrs - theTemplate);

    return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx);
}

Here is the call graph for this function:

static SECStatus pk11_RetrieveCrlsCallback ( PK11SlotInfo *  slot,
CK_OBJECT_HANDLE  crlID,
void arg 
) [static]

Definition at line 284 of file pk11nobj.c.

{
    SECItem* derCrl = NULL;
    crlOptions* options = (crlOptions*) arg;
    CERTCrlHeadNode *head = options->head;
    CERTCrlNode *new_node = NULL;
    CK_ATTRIBUTE fetchCrl[3] = {
        { CKA_VALUE, NULL, 0},
        { CKA_NETSCAPE_KRL, NULL, 0},
        { CKA_NETSCAPE_URL, NULL, 0},
    };
    const int fetchCrlSize = sizeof(fetchCrl)/sizeof(fetchCrl[2]);
    CK_RV crv;
    SECStatus rv = SECFailure;
    PRBool adopted = PR_FALSE; /* whether the CRL adopted the DER memory
                                  successfully */
    int i;

    crv = PK11_GetAttributes(NULL,slot,crlID,fetchCrl,fetchCrlSize);
    if (CKR_OK != crv) {
       PORT_SetError(PK11_MapError(crv));
       goto loser;
    }

    if (!fetchCrl[1].pValue) {
        /* reject KRLs */
       PORT_SetError(SEC_ERROR_CRL_INVALID);
       goto loser;
    }

    new_node = (CERTCrlNode *)PORT_ArenaAlloc(head->arena,
                                              sizeof(CERTCrlNode));
    if (new_node == NULL) {
        goto loser;
    }

    new_node->type = SEC_CRL_TYPE;

    derCrl = SECITEM_AllocItem(NULL, NULL, 0);
    if (!derCrl) {
        goto loser;
    }
    derCrl->type = siBuffer;
    derCrl->data = (unsigned char *)fetchCrl[0].pValue;
    derCrl->len = fetchCrl[0].ulValueLen;
    new_node->crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl,new_node->type,
                                               options->decodeOptions);
    if (new_node->crl == NULL) {
       goto loser;
    }    
    adopted = PR_TRUE; /* now that the CRL has adopted the DER memory,
                          we won't need to free it upon exit */

    if (fetchCrl[2].pValue && fetchCrl[2].ulValueLen) {
        /* copy the URL if there is one */
        int nnlen = fetchCrl[2].ulValueLen;
        new_node->crl->url  = (char *)PORT_ArenaAlloc(new_node->crl->arena,
                                                      nnlen+1);
        if ( !new_node->crl->url ) {
            goto loser;
        }
        PORT_Memcpy(new_node->crl->url, fetchCrl[2].pValue, nnlen);
        new_node->crl->url[nnlen] = 0;
    } else {
        new_node->crl->url = NULL;
    }

    new_node->next = NULL;
    if (head->last) {
        head->last->next = new_node;
        head->last = new_node;
    } else {
        head->first = head->last = new_node;
    }
    rv = SECSuccess;
    new_node->crl->slot = PK11_ReferenceSlot(slot);
    new_node->crl->pkcs11ID = crlID;

loser:
    /* free attributes that weren't adopted by the CRL */
    for (i=1;i<fetchCrlSize;i++) {
        if (fetchCrl[i].pValue) {
            PORT_Free(fetchCrl[i].pValue);
        }
    }
    /* free the DER if the CRL object didn't adopt it */
    if (fetchCrl[0].pValue && PR_FALSE == adopted) {
        PORT_Free(fetchCrl[0].pValue);
    }
    if (derCrl && !adopted) {
        /* clear the data fields, which we already took care of above */
        derCrl->data = NULL;
        derCrl->len = 0;
        /* free the memory for the SECItem structure itself */
        SECITEM_FreeItem(derCrl, PR_TRUE);
    }
    return(rv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus PK11_SaveSMimeProfile ( PK11SlotInfo *  slot,
char *  emailAddr,
SECItem *  derSubj,
SECItem *  emailProfile,
SECItem *  profileTime 
)

Definition at line 669 of file pk11nobj.c.

{
    CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME;
    CK_BBOOL ck_true = CK_TRUE;
    CK_ATTRIBUTE theTemplate[] = {
       { CKA_CLASS, NULL, 0 },
       { CKA_TOKEN, NULL, 0 },
       { CKA_SUBJECT, NULL, 0 },
       { CKA_NETSCAPE_EMAIL, NULL, 0 },
       { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 },
       { CKA_VALUE, NULL, 0 }
    };
    /* if you change the array, change the variable below as well */
    int realSize = 0;
    CK_OBJECT_HANDLE smimeh = CK_INVALID_HANDLE;
    CK_ATTRIBUTE *attrs = theTemplate;
    CK_SESSION_HANDLE rwsession;
    PK11SlotInfo *free_slot = NULL;
    CK_RV crv;
#ifdef DEBUG
    int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
#endif

    PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++;
    PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true)); attrs++;
    PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++;
    PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, 
                            emailAddr, PORT_Strlen(emailAddr)+1); attrs++;
    if (profileTime) {
       PK11_SETATTRS(attrs, CKA_NETSCAPE_SMIME_TIMESTAMP, profileTime->data,
                                                   profileTime->len); attrs++;
       PK11_SETATTRS(attrs, CKA_VALUE,emailProfile->data,
                                                   emailProfile->len); attrs++;
    }
    realSize = attrs - theTemplate;
    PORT_Assert (realSize <= tsize);

    if (slot == NULL) {
       free_slot = slot = PK11_GetInternalKeySlot();
       /* we need to free the key slot in the end!!! */
    }

    rwsession = PK11_GetRWSession(slot);
    if (rwsession == CK_INVALID_SESSION) {
       PORT_SetError(SEC_ERROR_READ_ONLY);
       if (free_slot) {
           PK11_FreeSlot(free_slot);
       }
       return SECFailure;
    }

    crv = PK11_GETTAB(slot)->
                        C_CreateObject(rwsession,theTemplate,realSize,&smimeh);
    if (crv != CKR_OK) {
        PORT_SetError( PK11_MapError(crv) );
    }

    PK11_RestoreROSession(slot,rwsession);

    if (free_slot) {
       PK11_FreeSlot(free_slot);
    }
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus SEC_DeletePermCRL ( CERTSignedCrl *  crl)

Definition at line 534 of file pk11nobj.c.

{
    PRStatus status;
    NSSToken *token;
    nssCryptokiObject *object;
    PK11SlotInfo *slot = crl->slot;

    if (slot == NULL) {
        PORT_Assert(slot);
       /* shouldn't happen */
       PORT_SetError( SEC_ERROR_CRL_INVALID);
       return SECFailure;
    }
    token = PK11Slot_GetNSSToken(slot);

    object = nss_ZNEW(NULL, nssCryptokiObject);
    object->token = nssToken_AddRef(token);
    object->handle = crl->pkcs11ID;
    object->isTokenObject = PR_TRUE;

    status = nssToken_DeleteStoredObject(object);

    nssCryptokiObject_Destroy(object);
    return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 80 of file errorval.c.