Back to index

lightning-sunbird  0.9+nobinonly
Functions
cms.h File Reference
#include "seccomon.h"
#include "secoidt.h"
#include "certt.h"
#include "keyt.h"
#include "hasht.h"
#include "cmst.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

SEC_BEGIN_PROTOS
NSSCMSDecoderContext * 
NSS_CMSDecoder_Start (PRArenaPool *poolp, NSSCMSContentCallback cb, void *cb_arg, PK11PasswordFunc pwfn, void *pwfn_arg, NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg)
SECStatus NSS_CMSDecoder_Update (NSSCMSDecoderContext *p7dcx, const char *buf, unsigned long len)
void NSS_CMSDecoder_Cancel (NSSCMSDecoderContext *p7dcx)
NSSCMSMessage * NSS_CMSDecoder_Finish (NSSCMSDecoderContext *p7dcx)
NSSCMSMessage * NSS_CMSMessage_CreateFromDER (SECItem *DERmessage, NSSCMSContentCallback cb, void *cb_arg, PK11PasswordFunc pwfn, void *pwfn_arg, NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg)
NSSCMSEncoderContext * NSS_CMSEncoder_Start (NSSCMSMessage *cmsg, NSSCMSContentCallback outputfn, void *outputarg, SECItem *dest, PLArenaPool *destpoolp, PK11PasswordFunc pwfn, void *pwfn_arg, NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, SECAlgorithmID **detached_digestalgs, SECItem **detached_digests)
SECStatus NSS_CMSEncoder_Update (NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len)
SECStatus NSS_CMSEncoder_Cancel (NSSCMSEncoderContext *p7ecx)
SECStatus NSS_CMSEncoder_Finish (NSSCMSEncoderContext *p7ecx)
NSSCMSMessage * NSS_CMSMessage_Create (PLArenaPool *poolp)
void NSS_CMSMessage_SetEncodingParams (NSSCMSMessage *cmsg, PK11PasswordFunc pwfn, void *pwfn_arg, NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, SECAlgorithmID **detached_digestalgs, SECItem **detached_digests)
void NSS_CMSMessage_Destroy (NSSCMSMessage *cmsg)
NSSCMSMessage * NSS_CMSMessage_Copy (NSSCMSMessage *cmsg)
PLArenaPoolNSS_CMSMessage_GetArena (NSSCMSMessage *cmsg)
NSSCMSContentInfo * NSS_CMSMessage_GetContentInfo (NSSCMSMessage *cmsg)
SECItem * NSS_CMSMessage_GetContent (NSSCMSMessage *cmsg)
int NSS_CMSMessage_ContentLevelCount (NSSCMSMessage *cmsg)
NSSCMSContentInfo * NSS_CMSMessage_ContentLevel (NSSCMSMessage *cmsg, int n)
PRBool NSS_CMSMessage_ContainsCertsOrCrls (NSSCMSMessage *cmsg)
PRBool NSS_CMSMessage_IsEncrypted (NSSCMSMessage *cmsg)
PRBool NSS_CMSMessage_IsSigned (NSSCMSMessage *cmsg)
PRBool NSS_CMSMessage_IsContentEmpty (NSSCMSMessage *cmsg, unsigned int minLen)
void NSS_CMSContentInfo_Destroy (NSSCMSContentInfo *cinfo)
NSSCMSContentInfo * NSS_CMSContentInfo_GetChildContentInfo (NSSCMSContentInfo *cinfo)
SECStatus NSS_CMSContentInfo_SetContent (NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr)
SECStatus NSS_CMSContentInfo_SetContent_Data (NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
SECStatus NSS_CMSContentInfo_SetContent_SignedData (NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
SECStatus NSS_CMSContentInfo_SetContent_EnvelopedData (NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSContentInfo_SetContent_DigestedData (NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd)
SECStatus NSS_CMSContentInfo_SetContent_EncryptedData (NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd)
voidNSS_CMSContentInfo_GetContent (NSSCMSContentInfo *cinfo)
SECItem * NSS_CMSContentInfo_GetInnerContent (NSSCMSContentInfo *cinfo)
SECOidTag NSS_CMSContentInfo_GetContentTypeTag (NSSCMSContentInfo *cinfo)
SECItem * NSS_CMSContentInfo_GetContentTypeOID (NSSCMSContentInfo *cinfo)
SECOidTag NSS_CMSContentInfo_GetContentEncAlgTag (NSSCMSContentInfo *cinfo)
SECAlgorithmID * NSS_CMSContentInfo_GetContentEncAlg (NSSCMSContentInfo *cinfo)
SECStatus NSS_CMSContentInfo_SetContentEncAlg (PLArenaPool *poolp, NSSCMSContentInfo *cinfo, SECOidTag bulkalgtag, SECItem *parameters, int keysize)
SECStatus NSS_CMSContentInfo_SetContentEncAlgID (PLArenaPool *poolp, NSSCMSContentInfo *cinfo, SECAlgorithmID *algid, int keysize)
void NSS_CMSContentInfo_SetBulkKey (NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey)
PK11SymKey * NSS_CMSContentInfo_GetBulkKey (NSSCMSContentInfo *cinfo)
int NSS_CMSContentInfo_GetBulkKeySize (NSSCMSContentInfo *cinfo)
SECStatus NSS_CMSArray_SortByDER (void **objs, const SEC_ASN1Template *objtemplate, void **objs2)
int NSS_CMSUtil_DERCompare (void *a, void *b)
int NSS_CMSAlgArray_GetIndexByAlgID (SECAlgorithmID **algorithmArray, SECAlgorithmID *algid)
int NSS_CMSAlgArray_GetIndexByAlgTag (SECAlgorithmID **algorithmArray, SECOidTag algtag)
const SECHashObject * NSS_CMSUtil_GetHashObjByAlgID (SECAlgorithmID *algid)
SECOidTag NSS_CMSUtil_MakeSignatureAlgorithm (SECOidTag hashalg, SECOidTag encalg)
const SEC_ASN1TemplateNSS_CMSUtil_GetTemplateByTypeTag (SECOidTag type)
size_t NSS_CMSUtil_GetSizeByTypeTag (SECOidTag type)
NSSCMSContentInfo * NSS_CMSContent_GetContentInfo (void *msg, SECOidTag type)
const char * NSS_CMSUtil_VerificationStatusToString (NSSCMSVerificationStatus vs)
NSSCMSSignedData * NSS_CMSSignedData_Create (NSSCMSMessage *cmsg)
void NSS_CMSSignedData_Destroy (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_Encode_BeforeStart (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_Encode_BeforeData (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_Encode_AfterData (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_Decode_BeforeData (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_Decode_AfterData (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_Decode_AfterEnd (NSSCMSSignedData *sigd)
NSSCMSSignerInfo ** NSS_CMSSignedData_GetSignerInfos (NSSCMSSignedData *sigd)
int NSS_CMSSignedData_SignerInfoCount (NSSCMSSignedData *sigd)
NSSCMSSignerInfo * NSS_CMSSignedData_GetSignerInfo (NSSCMSSignedData *sigd, int i)
SECAlgorithmID ** NSS_CMSSignedData_GetDigestAlgs (NSSCMSSignedData *sigd)
NSSCMSContentInfo * NSS_CMSSignedData_GetContentInfo (NSSCMSSignedData *sigd)
SECItem ** NSS_CMSSignedData_GetCertificateList (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_ImportCerts (NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, SECCertUsage certusage, PRBool keepcerts)
PRBool NSS_CMSSignedData_HasDigests (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_VerifySignerInfo (NSSCMSSignedData *sigd, int i, CERTCertDBHandle *certdb, SECCertUsage certusage)
SECStatus NSS_CMSSignedData_VerifyCertsOnly (NSSCMSSignedData *sigd, CERTCertDBHandle *certdb, SECCertUsage usage)
SECStatus NSS_CMSSignedData_AddCertList (NSSCMSSignedData *sigd, CERTCertificateList *certlist)
SECStatus NSS_CMSSignedData_AddCertChain (NSSCMSSignedData *sigd, CERTCertificate *cert)
SECStatus NSS_CMSSignedData_AddCertificate (NSSCMSSignedData *sigd, CERTCertificate *cert)
PRBool NSS_CMSSignedData_ContainsCertsOrCrls (NSSCMSSignedData *sigd)
SECStatus NSS_CMSSignedData_AddSignerInfo (NSSCMSSignedData *sigd, NSSCMSSignerInfo *signerinfo)
SECStatus NSS_CMSSignedData_SetDigests (NSSCMSSignedData *sigd, SECAlgorithmID **digestalgs, SECItem **digests)
SECStatus NSS_CMSSignedData_SetDigestValue (NSSCMSSignedData *sigd, SECOidTag digestalgtag, SECItem *digestdata)
SECStatus NSS_CMSSignedData_AddDigest (PRArenaPool *poolp, NSSCMSSignedData *sigd, SECOidTag digestalgtag, SECItem *digest)
SECItem * NSS_CMSSignedData_GetDigestValue (NSSCMSSignedData *sigd, SECOidTag digestalgtag)
NSSCMSSignedData * NSS_CMSSignedData_CreateCertsOnly (NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain)
NSSCMSSignerInfo * NSS_CMSSignerInfo_Create (NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag)
NSSCMSSignerInfo * NSS_CMSSignerInfo_CreateWithSubjKeyID (NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
void NSS_CMSSignerInfo_Destroy (NSSCMSSignerInfo *si)
SECStatus NSS_CMSSignerInfo_Sign (NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType)
SECStatus NSS_CMSSignerInfo_VerifyCertificate (NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb, SECCertUsage certusage)
SECStatus NSS_CMSSignerInfo_Verify (NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType)
NSSCMSVerificationStatus NSS_CMSSignerInfo_GetVerificationStatus (NSSCMSSignerInfo *signerinfo)
SECOidData * NSS_CMSSignerInfo_GetDigestAlg (NSSCMSSignerInfo *signerinfo)
SECOidTag NSS_CMSSignerInfo_GetDigestAlgTag (NSSCMSSignerInfo *signerinfo)
int NSS_CMSSignerInfo_GetVersion (NSSCMSSignerInfo *signerinfo)
CERTCertificateList * NSS_CMSSignerInfo_GetCertList (NSSCMSSignerInfo *signerinfo)
SECStatus NSS_CMSSignerInfo_GetSigningTime (NSSCMSSignerInfo *sinfo, PRTime *stime)
CERTCertificate * NSS_CMSSignerInfo_GetSigningCertificate (NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb)
char * NSS_CMSSignerInfo_GetSignerCommonName (NSSCMSSignerInfo *sinfo)
char * NSS_CMSSignerInfo_GetSignerEmailAddress (NSSCMSSignerInfo *sinfo)
SECStatus NSS_CMSSignerInfo_AddAuthAttr (NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
SECStatus NSS_CMSSignerInfo_AddUnauthAttr (NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
SECStatus NSS_CMSSignerInfo_AddSigningTime (NSSCMSSignerInfo *signerinfo, PRTime t)
SECStatus NSS_CMSSignerInfo_AddSMIMECaps (NSSCMSSignerInfo *signerinfo)
SECStatus NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs (NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
SECStatus NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs (NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
SECStatus NSS_CMSSignerInfo_AddCounterSignature (NSSCMSSignerInfo *signerinfo, SECOidTag digestalg, CERTCertificate signingcert)
SECStatus NSS_SMIMESignerInfo_SaveSMIMEProfile (NSSCMSSignerInfo *signerinfo)
SECStatus NSS_CMSSignerInfo_IncludeCerts (NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage)
NSSCMSEnvelopedData * NSS_CMSEnvelopedData_Create (NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize)
void NSS_CMSEnvelopedData_Destroy (NSSCMSEnvelopedData *edp)
NSSCMSContentInfo * NSS_CMSEnvelopedData_GetContentInfo (NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSEnvelopedData_AddRecipient (NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip)
SECStatus NSS_CMSEnvelopedData_Encode_BeforeStart (NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSEnvelopedData_Encode_BeforeData (NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSEnvelopedData_Encode_AfterData (NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSEnvelopedData_Decode_BeforeData (NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSEnvelopedData_Decode_AfterData (NSSCMSEnvelopedData *envd)
SECStatus NSS_CMSEnvelopedData_Decode_AfterEnd (NSSCMSEnvelopedData *envd)
NSSCMSRecipientInfo * NSS_CMSRecipientInfo_Create (NSSCMSMessage *cmsg, CERTCertificate *cert)
NSSCMSRecipientInfo * NSS_CMSRecipientInfo_CreateWithSubjKeyID (NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey)
NSSCMSRecipientInfo * NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert (NSSCMSMessage *cmsg, CERTCertificate *cert)
NSSCMSRecipientInfo * NSS_CMSRecipientInfo_CreateNew (void *pwfn_arg)
NSSCMSRecipientInfo * NSS_CMSRecipientInfo_CreateFromDER (SECItem *input, void *pwfn_arg)
void NSS_CMSRecipientInfo_Destroy (NSSCMSRecipientInfo *ri)
SECStatus NSS_CMSRecipientInfo_GetCertAndKey (NSSCMSRecipientInfo *ri, CERTCertificate **retcert, SECKEYPrivateKey **retkey)
int NSS_CMSRecipientInfo_GetVersion (NSSCMSRecipientInfo *ri)
SECItem * NSS_CMSRecipientInfo_GetEncryptedKey (NSSCMSRecipientInfo *ri, int subIndex)
SECStatus NSS_CMSRecipientInfo_Encode (PRArenaPool *poolp, const NSSCMSRecipientInfo *src, SECItem *returned)
SECOidTag NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag (NSSCMSRecipientInfo *ri)
SECStatus NSS_CMSRecipientInfo_WrapBulkKey (NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, SECOidTag bulkalgtag)
PK11SymKey * NSS_CMSRecipientInfo_UnwrapBulkKey (NSSCMSRecipientInfo *ri, int subIndex, CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag)
NSSCMSEncryptedData * NSS_CMSEncryptedData_Create (NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize)
void NSS_CMSEncryptedData_Destroy (NSSCMSEncryptedData *encd)
NSSCMSContentInfo * NSS_CMSEncryptedData_GetContentInfo (NSSCMSEncryptedData *encd)
SECStatus NSS_CMSEncryptedData_Encode_BeforeStart (NSSCMSEncryptedData *encd)
SECStatus NSS_CMSEncryptedData_Encode_BeforeData (NSSCMSEncryptedData *encd)
SECStatus NSS_CMSEncryptedData_Encode_AfterData (NSSCMSEncryptedData *encd)
SECStatus NSS_CMSEncryptedData_Decode_BeforeData (NSSCMSEncryptedData *encd)
SECStatus NSS_CMSEncryptedData_Decode_AfterData (NSSCMSEncryptedData *encd)
SECStatus NSS_CMSEncryptedData_Decode_AfterEnd (NSSCMSEncryptedData *encd)
NSSCMSDigestedData * NSS_CMSDigestedData_Create (NSSCMSMessage *cmsg, SECAlgorithmID *digestalg)
void NSS_CMSDigestedData_Destroy (NSSCMSDigestedData *digd)
NSSCMSContentInfo * NSS_CMSDigestedData_GetContentInfo (NSSCMSDigestedData *digd)
SECStatus NSS_CMSDigestedData_Encode_BeforeStart (NSSCMSDigestedData *digd)
SECStatus NSS_CMSDigestedData_Encode_BeforeData (NSSCMSDigestedData *digd)
SECStatus NSS_CMSDigestedData_Encode_AfterData (NSSCMSDigestedData *digd)
SECStatus NSS_CMSDigestedData_Decode_BeforeData (NSSCMSDigestedData *digd)
SECStatus NSS_CMSDigestedData_Decode_AfterData (NSSCMSDigestedData *digd)
SECStatus NSS_CMSDigestedData_Decode_AfterEnd (NSSCMSDigestedData *digd)
NSSCMSDigestContext * NSS_CMSDigestContext_StartMultiple (SECAlgorithmID **digestalgs)
NSSCMSDigestContext * NSS_CMSDigestContext_StartSingle (SECAlgorithmID *digestalg)
void NSS_CMSDigestContext_Update (NSSCMSDigestContext *cmsdigcx, const unsigned char *data, int len)
void NSS_CMSDigestContext_Cancel (NSSCMSDigestContext *cmsdigcx)
SECStatus NSS_CMSDigestContext_FinishMultiple (NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp, SECItem ***digestsp)
SECStatus NSS_CMSDigestContext_FinishSingle (NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp, SECItem *digest)
SECStatus NSS_CMSDEREncode (NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut, PLArenaPool *arena)

Function Documentation

int NSS_CMSAlgArray_GetIndexByAlgID ( SECAlgorithmID **  algorithmArray,
SECAlgorithmID *  algid 
)

Definition at line 155 of file cmsutil.c.

{
    int i;

    if (algorithmArray == NULL || algorithmArray[0] == NULL)
       return -1;

    for (i = 0; algorithmArray[i] != NULL; i++) {
       if (SECOID_CompareAlgorithmID(algorithmArray[i], algid) == SECEqual)
           break;    /* bingo */
    }

    if (algorithmArray[i] == NULL)
       return -1;    /* not found */

    return i;
}

Here is the call graph for this function:

int NSS_CMSAlgArray_GetIndexByAlgTag ( SECAlgorithmID **  algorithmArray,
SECOidTag  algtag 
)

Definition at line 185 of file cmsutil.c.

{
    SECOidData *algid;
    int i = -1;

    if (algorithmArray == NULL || algorithmArray[0] == NULL)
       return i;

#ifdef ORDER_N_SQUARED
    for (i = 0; algorithmArray[i] != NULL; i++) {
       algid = SECOID_FindOID(&(algorithmArray[i]->algorithm));
       if (algid->offset == algtag)
           break;    /* bingo */
    }
#else
    algid = SECOID_FindOIDByTag(algtag);
    if (!algid) 
       return i;
    for (i = 0; algorithmArray[i] != NULL; i++) {
       if (SECITEM_ItemsAreEqual(&algorithmArray[i]->algorithm, &algid->oid))
           break;    /* bingo */
    }
#endif

    if (algorithmArray[i] == NULL)
       return -1;    /* not found */

    return i;
}

Here is the call graph for this function:

SECStatus NSS_CMSArray_SortByDER ( void **  objs,
const SEC_ASN1Template objtemplate,
void **  objs2 
)

Definition at line 65 of file cmsutil.c.

{
    PRArenaPool *poolp;
    int num_objs;
    SECItem **enc_objs;
    SECStatus rv = SECFailure;
    int i;

    if (objs == NULL)                                   /* already sorted */
       return SECSuccess;

    num_objs = NSS_CMSArray_Count((void **)objs);
    if (num_objs == 0 || num_objs == 1)          /* already sorted. */
       return SECSuccess;

    poolp = PORT_NewArena (1024);  /* arena for temporaries */
    if (poolp == NULL)
       return SECFailure;          /* no memory; nothing we can do... */

    /*
     * Allocate arrays to hold the individual encodings which we will use
     * for comparisons and the reordered attributes as they are sorted.
     */
    enc_objs = (SECItem **)PORT_ArenaZAlloc(poolp, (num_objs + 1) * sizeof(SECItem *));
    if (enc_objs == NULL)
       goto loser;

    /* DER encode each individual object. */
    for (i = 0; i < num_objs; i++) {
       enc_objs[i] = SEC_ASN1EncodeItem(poolp, NULL, objs[i], objtemplate);
       if (enc_objs[i] == NULL)
           goto loser;
    }
    enc_objs[num_objs] = NULL;

    /* now compare and sort objs by the order of enc_objs */
    NSS_CMSArray_Sort((void **)enc_objs, NSS_CMSUtil_DERCompare, objs, objs2);

    rv = SECSuccess;

loser:
    PORT_FreeArena (poolp, PR_FALSE);
    return rv;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSContent_GetContentInfo ( void msg,
SECOidTag  type 
)

Definition at line 336 of file cmsutil.c.

{
    NSSCMSContent c;
    NSSCMSContentInfo *cinfo = NULL;

    if (!msg)
       return cinfo;
    c.pointer = msg;
    switch (type) {
    case SEC_OID_PKCS7_SIGNED_DATA:
       cinfo = &(c.signedData->contentInfo);
       break;
    case SEC_OID_PKCS7_ENVELOPED_DATA:
       cinfo = &(c.envelopedData->contentInfo);
       break;
    case SEC_OID_PKCS7_ENCRYPTED_DATA:
       cinfo = &(c.encryptedData->contentInfo);
       break;
    case SEC_OID_PKCS7_DIGESTED_DATA:
       cinfo = &(c.digestedData->contentInfo);
       break;
    default:
       cinfo = NULL;
    }
    return cinfo;
}
void NSS_CMSContentInfo_Destroy ( NSSCMSContentInfo *  cinfo)

Definition at line 60 of file cmscinfo.c.

{
    SECOidTag kind;

    kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    switch (kind) {
    case SEC_OID_PKCS7_ENVELOPED_DATA:
       NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
       break;
      case SEC_OID_PKCS7_SIGNED_DATA:
       NSS_CMSSignedData_Destroy(cinfo->content.signedData);
       break;
      case SEC_OID_PKCS7_ENCRYPTED_DATA:
       NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
       break;
      case SEC_OID_PKCS7_DIGESTED_DATA:
       NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
       break;
      default:
       /* XXX Anything else that needs to be "manually" freed/destroyed? */
       break;
    }
    if (cinfo->digcx) {
       /* must destroy digest objects */
       NSS_CMSDigestContext_Cancel(cinfo->digcx);
       cinfo->digcx = NULL;
    }
    if (cinfo->bulkkey)
       PK11_FreeSymKey(cinfo->bulkkey);

    if (cinfo->ciphcx) {
       NSS_CMSCipherContext_Destroy(cinfo->ciphcx);
       cinfo->ciphcx = NULL;
    }
    
    /* we live in a pool, so no need to worry about storage */
}

Here is the call graph for this function:

PK11SymKey* NSS_CMSContentInfo_GetBulkKey ( NSSCMSContentInfo *  cinfo)

Definition at line 348 of file cmscinfo.c.

{
    if (cinfo->bulkkey == NULL)
       return NULL;

    return PK11_ReferenceSymKey(cinfo->bulkkey);
}

Here is the call graph for this function:

int NSS_CMSContentInfo_GetBulkKeySize ( NSSCMSContentInfo *  cinfo)

Definition at line 357 of file cmscinfo.c.

{
    return cinfo->keysize;
}
NSSCMSContentInfo* NSS_CMSContentInfo_GetChildContentInfo ( NSSCMSContentInfo *  cinfo)

Definition at line 102 of file cmscinfo.c.

{
    void * ptr                  = NULL;
    NSSCMSContentInfo * ccinfo  = NULL;
    SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    switch (tag) {
    case SEC_OID_PKCS7_SIGNED_DATA:
       ptr    = (void *)cinfo->content.signedData;
       ccinfo = &(cinfo->content.signedData->contentInfo);
       break;
    case SEC_OID_PKCS7_ENVELOPED_DATA:
       ptr    = (void *)cinfo->content.envelopedData;
       ccinfo = &(cinfo->content.envelopedData->contentInfo);
       break;
    case SEC_OID_PKCS7_DIGESTED_DATA:
       ptr    = (void *)cinfo->content.digestedData;
       ccinfo = &(cinfo->content.digestedData->contentInfo);
       break;
    case SEC_OID_PKCS7_ENCRYPTED_DATA:
       ptr    = (void *)cinfo->content.encryptedData;
       ccinfo = &(cinfo->content.encryptedData->contentInfo);
       break;
    case SEC_OID_PKCS7_DATA:
    default:
       break;
    }
    return (ptr ? ccinfo : NULL);
}

Here is the call graph for this function:

void* NSS_CMSContentInfo_GetContent ( NSSCMSContentInfo *  cinfo)

Definition at line 213 of file cmscinfo.c.

{
    SECOidTag tag = (cinfo && cinfo->contentTypeTag) 
                       ? cinfo->contentTypeTag->offset 
                       : SEC_OID_UNKNOWN;
    switch (tag) {
    case SEC_OID_PKCS7_DATA:
    case SEC_OID_PKCS7_SIGNED_DATA:
    case SEC_OID_PKCS7_ENVELOPED_DATA:
    case SEC_OID_PKCS7_DIGESTED_DATA:
    case SEC_OID_PKCS7_ENCRYPTED_DATA:
       return cinfo->content.pointer;
    default:
       return NULL;
    }
}
SECAlgorithmID* NSS_CMSContentInfo_GetContentEncAlg ( NSSCMSContentInfo *  cinfo)

Definition at line 308 of file cmscinfo.c.

{
    return &(cinfo->contentEncAlg);
}
SECOidTag NSS_CMSContentInfo_GetContentEncAlgTag ( NSSCMSContentInfo *  cinfo)

Definition at line 296 of file cmscinfo.c.

{
    if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
       cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));

    return cinfo->contentEncAlgTag;
}

Here is the call graph for this function:

SECItem* NSS_CMSContentInfo_GetContentTypeOID ( NSSCMSContentInfo *  cinfo)

Definition at line 280 of file cmscinfo.c.

{
    if (cinfo->contentTypeTag == NULL)
       cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));

    if (cinfo->contentTypeTag == NULL)
       return NULL;

    return &(cinfo->contentTypeTag->oid);
}

Here is the call graph for this function:

SECOidTag NSS_CMSContentInfo_GetContentTypeTag ( NSSCMSContentInfo *  cinfo)

Definition at line 268 of file cmscinfo.c.

{
    if (cinfo->contentTypeTag == NULL)
       cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));

    if (cinfo->contentTypeTag == NULL)
       return SEC_OID_UNKNOWN;

    return cinfo->contentTypeTag->offset;
}

Here is the call graph for this function:

SECItem* NSS_CMSContentInfo_GetInnerContent ( NSSCMSContentInfo *  cinfo)

Definition at line 236 of file cmscinfo.c.

{
    NSSCMSContentInfo *ccinfo;
    SECOidTag          tag;
    SECItem           *pItem = NULL;

    tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    switch (tag) {
    case SEC_OID_PKCS7_DATA:
       /* end of recursion - every message has to have a data cinfo */
       pItem = cinfo->content.data; 
       break;
    case SEC_OID_PKCS7_DIGESTED_DATA:
    case SEC_OID_PKCS7_ENCRYPTED_DATA:
    case SEC_OID_PKCS7_ENVELOPED_DATA:
    case SEC_OID_PKCS7_SIGNED_DATA:
       ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
       if (ccinfo != NULL)
           pItem = NSS_CMSContentInfo_GetContent(ccinfo);
       break;
    default:
       PORT_Assert(0);
       break;
    }
    return pItem;
}

Here is the call graph for this function:

void NSS_CMSContentInfo_SetBulkKey ( NSSCMSContentInfo *  cinfo,
PK11SymKey *  bulkkey 
)

Definition at line 341 of file cmscinfo.c.

{
    cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey);
    cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg));
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContent ( NSSCMSMessage *  cmsg,
NSSCMSContentInfo *  cinfo,
SECOidTag  type,
void ptr 
)

Definition at line 135 of file cmscinfo.c.

{
    SECStatus rv;

    cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
    if (cinfo->contentTypeTag == NULL)
       return SECFailure;
    
    /* do not copy the oid, just create a reference */
    rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
    if (rv != SECSuccess)
       return SECFailure;

    cinfo->content.pointer = ptr;

    if (type != SEC_OID_PKCS7_DATA) {
       /* as we always have some inner data,
        * we need to set it to something, just to fool the encoder enough to work on it
        * and get us into nss_cms_encoder_notify at that point */
       cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1);
       if (cinfo->rawContent == NULL) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           return SECFailure;
       }
    }

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContent_Data ( NSSCMSMessage *  cmsg,
NSSCMSContentInfo *  cinfo,
SECItem *  data,
PRBool  detached 
)

Definition at line 173 of file cmscinfo.c.

{
    if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess)
       return SECFailure;
    cinfo->rawContent = (detached) ? 
                         NULL : (data) ? 
                            data : SECITEM_AllocItem(cmsg->poolp, NULL, 1);
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContent_DigestedData ( NSSCMSMessage *  cmsg,
NSSCMSContentInfo *  cinfo,
NSSCMSDigestedData *  digd 
)

Definition at line 196 of file cmscinfo.c.

{
    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd);
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContent_EncryptedData ( NSSCMSMessage *  cmsg,
NSSCMSContentInfo *  cinfo,
NSSCMSEncryptedData *  encd 
)

Definition at line 202 of file cmscinfo.c.

{
    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd);
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContent_EnvelopedData ( NSSCMSMessage *  cmsg,
NSSCMSContentInfo *  cinfo,
NSSCMSEnvelopedData *  envd 
)

Definition at line 190 of file cmscinfo.c.

{
    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd);
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContent_SignedData ( NSSCMSMessage *  cmsg,
NSSCMSContentInfo *  cinfo,
NSSCMSSignedData *  sigd 
)

Definition at line 184 of file cmscinfo.c.

{
    return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd);
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContentEncAlg ( PLArenaPool poolp,
NSSCMSContentInfo *  cinfo,
SECOidTag  bulkalgtag,
SECItem *  parameters,
int  keysize 
)

Definition at line 314 of file cmscinfo.c.

{
    SECStatus rv;

    rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
    if (rv != SECSuccess)
       return SECFailure;
    cinfo->keysize = keysize;
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSContentInfo_SetContentEncAlgID ( PLArenaPool poolp,
NSSCMSContentInfo *  cinfo,
SECAlgorithmID *  algid,
int  keysize 
)

Definition at line 327 of file cmscinfo.c.

{
    SECStatus rv;

    rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
    if (rv != SECSuccess)
       return SECFailure;
    if (keysize >= 0)
       cinfo->keysize = keysize;
    return SECSuccess;
}

Here is the call graph for this function:

void NSS_CMSDecoder_Cancel ( NSSCMSDecoderContext *  p7dcx)

Definition at line 696 of file cmsdecode.c.

{
    /* XXXX what about inner decoders? running digests? decryption? */
    /* XXXX there's a leak here! */
    NSS_CMSMessage_Destroy(p7dcx->cmsg);
    (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
    PORT_Free(p7dcx);
}

Here is the call graph for this function:

NSSCMSMessage* NSS_CMSDecoder_Finish ( NSSCMSDecoderContext *  p7dcx)

Definition at line 709 of file cmsdecode.c.

{
    NSSCMSMessage *cmsg;

    cmsg = p7dcx->cmsg;

    if (p7dcx->dcx == NULL || 
        SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
       nss_cms_after_end(p7dcx) != SECSuccess)
    {
       NSS_CMSMessage_Destroy(cmsg);      /* get rid of pool if it's ours */
       cmsg = NULL;
    }

    PORT_Free(p7dcx);
    return cmsg;
}

Here is the call graph for this function:

SEC_BEGIN_PROTOS NSSCMSDecoderContext* NSS_CMSDecoder_Start ( PRArenaPool poolp,
NSSCMSContentCallback  cb,
void cb_arg,
PK11PasswordFunc  pwfn,
void pwfn_arg,
NSSCMSGetDecryptKeyCallback  decrypt_key_cb,
void decrypt_key_cb_arg 
)

Definition at line 620 of file cmsdecode.c.

{
    NSSCMSDecoderContext *p7dcx;
    NSSCMSMessage *cmsg;

    cmsg = NSS_CMSMessage_Create(poolp);
    if (cmsg == NULL)
       return NULL;

    NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, 
                                     decrypt_key_cb_arg, NULL, NULL);

    p7dcx = PORT_ZNew(NSSCMSDecoderContext);
    if (p7dcx == NULL) {
       NSS_CMSMessage_Destroy(cmsg);
       return NULL;
    }

    p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, NSSCMSMessageTemplate);
    if (p7dcx->dcx == NULL) {
       PORT_Free (p7dcx);
       NSS_CMSMessage_Destroy(cmsg);
       return NULL;
    }

    SEC_ASN1DecoderSetNotifyProc (p7dcx->dcx, nss_cms_decoder_notify, p7dcx);

    p7dcx->cmsg = cmsg;
    p7dcx->type = SEC_OID_UNKNOWN;

    p7dcx->cb = cb;
    p7dcx->cb_arg = cb_arg;

    return p7dcx;
}

Here is the call graph for this function:

SECStatus NSS_CMSDecoder_Update ( NSSCMSDecoderContext *  p7dcx,
const char *  buf,
unsigned long  len 
)

Definition at line 664 of file cmsdecode.c.

{
    SECStatus rv;
    if (p7dcx->dcx != NULL && p7dcx->error == 0) {      
       /* if error is set already, don't bother */
       rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
       if (rv != SECSuccess) {
           p7dcx->error = PORT_GetError();
           PORT_Assert (p7dcx->error);
           if (p7dcx->error == 0)
              p7dcx->error = -1;
       }
    }

    if (p7dcx->error == 0)
       return SECSuccess;

    /* there has been a problem, let's finish the decoder */
    if (p7dcx->dcx != NULL) {
       (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
       p7dcx->dcx = NULL;
    }
    PORT_SetError (p7dcx->error);

    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSDEREncode ( NSSCMSMessage *  cmsg,
SECItem *  input,
SECItem *  derOut,
PLArenaPool arena 
)

Definition at line 382 of file cmsutil.c.

{
    NSSCMSEncoderContext *ecx;
    SECStatus rv = SECSuccess;
    if (!cmsg || !derOut || !arena) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    ecx = NSS_CMSEncoder_Start(cmsg, 0, 0, derOut, arena, 0, 0, 0, 0, 0, 0);
    if (!ecx) {
       PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
       return SECFailure;
    }
    if (input) {
       rv = NSS_CMSEncoder_Update(ecx, (const char*)input->data, input->len);
       if (rv) {
           PORT_SetError(SEC_ERROR_BAD_DATA);
       }
    }
    rv |= NSS_CMSEncoder_Finish(ecx);
    if (rv) {
       PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    }
    return rv;
}

Here is the call graph for this function:

void NSS_CMSDigestContext_Cancel ( NSSCMSDigestContext *  cmsdigcx)

Definition at line 185 of file cmsdigest.c.

{
    int i;
    digestPair *pair = cmsdigcx->digPairs;

    for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
       if (pair->digcx) {
           (*pair->digobj->destroy)(pair->digcx, PR_TRUE);
#ifdef CMS_FIND_LEAK_MULTIPLE
           --global_num_digests;
#endif
       }
    }
#ifdef CMS_FIND_LEAK_MULTIPLE
    PORT_Assert(global_num_digests == 0 || !stop_on_err);
#endif
    PORT_FreeArena(cmsdigcx->pool, PR_FALSE);
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestContext_FinishMultiple ( NSSCMSDigestContext *  cmsdigcx,
PLArenaPool poolp,
SECItem ***  digestsp 
)

Definition at line 209 of file cmsdigest.c.

{
    SECItem **  digests = NULL;
    digestPair *pair;
    void *      mark;
    int         i;
    SECStatus   rv;

    /* no contents? do not finish digests */
    if (digestsp == NULL || !cmsdigcx->saw_contents) {
       rv = SECSuccess;
       goto cleanup;
    }

    mark = PORT_ArenaMark (poolp);

    /* allocate digest array & SECItems on arena */
    digests = PORT_ArenaNewArray( poolp, SECItem *, cmsdigcx->digcnt + 1);

    rv = ((digests == NULL) ? SECFailure : SECSuccess);
    pair = cmsdigcx->digPairs;
    for (i = 0; rv == SECSuccess && i < cmsdigcx->digcnt; i++, pair++) {
       SECItem digest;
       unsigned char hash[HASH_LENGTH_MAX];

       if (!pair->digcx) {
           digests[i] = NULL;
           continue;
       }

       digest.type = siBuffer;
       digest.data = hash;
       digest.len  = pair->digobj->length;
       (* pair->digobj->end)(pair->digcx, hash, &digest.len, digest.len);
       digests[i] = SECITEM_ArenaDupItem(poolp, &digest);
       if (!digests[i]) {
           rv = SECFailure;
       }
    }
    digests[i] = NULL;
    if (rv == SECSuccess) {
       PORT_ArenaUnmark(poolp, mark);
    } else
       PORT_ArenaRelease(poolp, mark);

cleanup:
    NSS_CMSDigestContext_Cancel(cmsdigcx);
    /* Don't change the caller's digests pointer if we have no digests.
    **  NSS_CMSSignedData_Encode_AfterData depends on this behavior.
    */
    if (rv == SECSuccess && digestsp && digests) {
       *digestsp = digests;
    }
    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestContext_FinishSingle ( NSSCMSDigestContext *  cmsdigcx,
PLArenaPool poolp,
SECItem *  digest 
)

Definition at line 272 of file cmsdigest.c.

{
    SECStatus rv = SECFailure;
    SECItem **dp;
    PLArenaPool *arena = NULL;

    if ((arena = PORT_NewArena(1024)) == NULL)
       goto loser;

    /* get the digests into arena, then copy the first digest into poolp */
    rv = NSS_CMSDigestContext_FinishMultiple(cmsdigcx, arena, &dp);
    if (rv == SECSuccess) {
       /* now copy it into poolp */
       rv = SECITEM_CopyItem(poolp, digest, dp[0]);
    }
loser:
    if (arena)
       PORT_FreeArena(arena, PR_FALSE);

    return rv;
}

Here is the call graph for this function:

NSSCMSDigestContext* NSS_CMSDigestContext_StartMultiple ( SECAlgorithmID **  digestalgs)

Definition at line 78 of file cmsdigest.c.

{
    PLArenaPool *        pool;
    NSSCMSDigestContext *cmsdigcx;
    int digcnt;
    int i;

#ifdef CMS_FIND_LEAK_MULTIPLE
    PORT_Assert(global_num_digests == 0 || !stop_on_err);
#endif

    digcnt = (digestalgs == NULL) ? 0 : NSS_CMSArray_Count((void **)digestalgs);
    /* It's OK if digcnt is zero.  We have to allow this for "certs only"
    ** messages.
    */
    pool = PORT_NewArena(2048);
    if (!pool)
       return NULL;

    cmsdigcx = PORT_ArenaNew(pool, NSSCMSDigestContext);
    if (cmsdigcx == NULL)
       goto loser;

    cmsdigcx->saw_contents = PR_FALSE;
    cmsdigcx->pool   = pool;
    cmsdigcx->digcnt = digcnt;

    cmsdigcx->digPairs = PORT_ArenaZNewArray(pool, digestPair, digcnt);
    if (cmsdigcx->digPairs == NULL) {
       goto loser;
    }

    /*
     * Create a digest object context for each algorithm.
     */
    for (i = 0; i < digcnt; i++) {
       const SECHashObject *digobj;
       void *digcx;

       digobj = NSS_CMSUtil_GetHashObjByAlgID(digestalgs[i]);
       /*
        * Skip any algorithm we do not even recognize; obviously,
        * this could be a problem, but if it is critical then the
        * result will just be that the signature does not verify.
        * We do not necessarily want to error out here, because
        * the particular algorithm may not actually be important,
        * but we cannot know that until later.
        */
       if (digobj == NULL)
           continue;

       digcx = (*digobj->create)();
       if (digcx != NULL) {
           (*digobj->begin) (digcx);
           cmsdigcx->digPairs[i].digobj = digobj;
           cmsdigcx->digPairs[i].digcx  = digcx;
#ifdef CMS_FIND_LEAK_MULTIPLE
           global_num_digests++;
#endif
       }
    }
    return cmsdigcx;

loser:
    /* no digest objects have been created, or need to be destroyed. */
    if (pool) {
       PORT_FreeArena(pool, PR_FALSE);
    }
    return NULL;
}

Here is the call graph for this function:

NSSCMSDigestContext* NSS_CMSDigestContext_StartSingle ( SECAlgorithmID *  digestalg)

Definition at line 154 of file cmsdigest.c.

{
    SECAlgorithmID *digestalgs[] = { NULL, NULL };             /* fake array */

    digestalgs[0] = digestalg;
    return NSS_CMSDigestContext_StartMultiple(digestalgs);
}

Here is the call graph for this function:

void NSS_CMSDigestContext_Update ( NSSCMSDigestContext *  cmsdigcx,
const unsigned char *  data,
int  len 
)

Definition at line 166 of file cmsdigest.c.

{
    int i;
    digestPair *pair = cmsdigcx->digPairs;

    cmsdigcx->saw_contents = PR_TRUE;

    for (i = 0; i < cmsdigcx->digcnt; i++, pair++) {
       if (pair->digcx) {
           (*pair->digobj->update)(pair->digcx, data, len);
       }
    }
}
NSSCMSDigestedData* NSS_CMSDigestedData_Create ( NSSCMSMessage *  cmsg,
SECAlgorithmID *  digestalg 
)

Definition at line 59 of file cmsdigdata.c.

{
    void *mark;
    NSSCMSDigestedData *digd;
    PLArenaPool *poolp;

    poolp = cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData));
    if (digd == NULL)
       goto loser;

    digd->cmsg = cmsg;

    if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess)
       goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return digd;

loser:
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestedData_Decode_AfterData ( NSSCMSDigestedData *  digd)

Definition at line 199 of file cmsdigdata.c.

{
    SECStatus rv = SECSuccess;
    /* did we have digest calculation going on? */
    if (digd->contentInfo.digcx) {
       rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx,
                                           digd->cmsg->poolp, 
                                          &(digd->cdigest));
       /* error has been set by NSS_CMSDigestContext_FinishSingle */
       digd->contentInfo.digcx = NULL;
    }

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestedData_Decode_AfterEnd ( NSSCMSDigestedData *  digd)

Definition at line 221 of file cmsdigdata.c.

{
    /* did we have digest calculation going on? */
    if (digd->cdigest.len != 0) {
       /* XXX comparision btw digest & cdigest */
       /* XXX set status */
       /* TODO!!!! */
    }

    return SECSuccess;
}
SECStatus NSS_CMSDigestedData_Decode_BeforeData ( NSSCMSDigestedData *  digd)

Definition at line 178 of file cmsdigdata.c.

{
    /* is there a digest algorithm yet? */
    if (digd->digestAlg.algorithm.len == 0)
       return SECFailure;

    digd->contentInfo.digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
    if (digd->contentInfo.digcx == NULL)
       return SECFailure;

    return SECSuccess;
}

Here is the call graph for this function:

void NSS_CMSDigestedData_Destroy ( NSSCMSDigestedData *  digd)

Definition at line 90 of file cmsdigdata.c.

{
    /* everything's in a pool, so don't worry about the storage */
    NSS_CMSContentInfo_Destroy(&(digd->contentInfo));
    return;
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestedData_Encode_AfterData ( NSSCMSDigestedData *  digd)

Definition at line 155 of file cmsdigdata.c.

{
    SECStatus rv = SECSuccess;
    /* did we have digest calculation going on? */
    if (digd->contentInfo.digcx) {
       rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.digcx,
                                           digd->cmsg->poolp, 
                                          &(digd->digest));
       /* error has been set by NSS_CMSDigestContext_FinishSingle */
       digd->contentInfo.digcx = NULL;
    }

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestedData_Encode_BeforeData ( NSSCMSDigestedData *  digd)

Definition at line 135 of file cmsdigdata.c.

{
    /* set up the digests */
    if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) {
       /* if digest is already there, do nothing */
       digd->contentInfo.digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
       if (digd->contentInfo.digcx == NULL)
           return SECFailure;
    }
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSDigestedData_Encode_BeforeStart ( NSSCMSDigestedData *  digd)

Definition at line 114 of file cmsdigdata.c.

{
    unsigned long version;
    SECItem *dummy;

    version = NSS_CMS_DIGESTED_DATA_VERSION_DATA;
    if (NSS_CMSContentInfo_GetContentTypeTag(&(digd->contentInfo)) != SEC_OID_PKCS7_DATA)
       version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP;

    dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version);
    return (dummy == NULL) ? SECFailure : SECSuccess;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSDigestedData_GetContentInfo ( NSSCMSDigestedData *  digd)

Definition at line 101 of file cmsdigdata.c.

{
    return &(digd->contentInfo);
}
SECStatus NSS_CMSEncoder_Cancel ( NSSCMSEncoderContext *  p7ecx)

Definition at line 650 of file cmsencode.c.

{
    SECStatus rv = SECFailure;

    /* XXX do this right! */

    /*
     * Finish any inner decoders before us so that all the encoded data is flushed
     * This basically finishes all the decoders from the innermost to the outermost.
     * Finishing an inner decoder may result in data being updated to the outer decoder
     * while we are already in NSS_CMSEncoder_Finish, but that's allright.
     */
    if (p7ecx->childp7ecx) {
       rv = NSS_CMSEncoder_Cancel(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
       /* remember rv for now */
    }

    /*
     * On the way back up, there will be no more data (if we had an
     * inner encoder, it is done now!)
     * Flush out any remaining data and/or finish digests.
     */
    rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
    if (rv != SECSuccess)
       goto loser;

    p7ecx->childp7ecx = NULL;

    /* kick the encoder back into working mode again.
     * We turn off streaming stuff (which will cause the encoder to continue
     * encoding happily, now that we have all the data (like digests) ready for it).
     */
    SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
    SEC_ASN1EncoderClearStreaming(p7ecx->ecx);

    /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */
    rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);

loser:
    SEC_ASN1EncoderFinish(p7ecx->ecx);
    PORT_Free (p7ecx);
    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncoder_Finish ( NSSCMSEncoderContext *  p7ecx)

Definition at line 700 of file cmsencode.c.

{
    SECStatus rv = SECFailure;
    NSSCMSContentInfo *cinfo;
    SECOidTag childtype;

    /*
     * Finish any inner decoders before us so that all the encoded data is flushed
     * This basically finishes all the decoders from the innermost to the outermost.
     * Finishing an inner decoder may result in data being updated to the outer decoder
     * while we are already in NSS_CMSEncoder_Finish, but that's allright.
     */
    if (p7ecx->childp7ecx) {
       rv = NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
       if (rv != SECSuccess)
           goto loser;
    }

    /*
     * On the way back up, there will be no more data (if we had an
     * inner encoder, it is done now!)
     * Flush out any remaining data and/or finish digests.
     */
    rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
    if (rv != SECSuccess)
       goto loser;

    p7ecx->childp7ecx = NULL;

    /* find out about our inner content type - must be data */
    cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
    childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    if (childtype == SEC_OID_PKCS7_DATA && cinfo->content.data == NULL) {
       SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
       /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */
       rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
    }

    SEC_ASN1EncoderClearStreaming(p7ecx->ecx);

    if (p7ecx->error)
       rv = SECFailure;

loser:
    SEC_ASN1EncoderFinish(p7ecx->ecx);
    PORT_Free (p7ecx);
    return rv;
}

Here is the call graph for this function:

NSSCMSEncoderContext* NSS_CMSEncoder_Start ( NSSCMSMessage *  cmsg,
NSSCMSContentCallback  outputfn,
void outputarg,
SECItem *  dest,
PLArenaPool destpoolp,
PK11PasswordFunc  pwfn,
void pwfn_arg,
NSSCMSGetDecryptKeyCallback  decrypt_key_cb,
void decrypt_key_cb_arg,
SECAlgorithmID **  detached_digestalgs,
SECItem **  detached_digests 
)

Definition at line 520 of file cmsencode.c.

{
    NSSCMSEncoderContext *p7ecx;
    SECStatus rv;
    NSSCMSContentInfo *cinfo;

    NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg,
                                   detached_digestalgs, detached_digests);

    p7ecx = (NSSCMSEncoderContext *)PORT_ZAlloc(sizeof(NSSCMSEncoderContext));
    if (p7ecx == NULL) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    p7ecx->cmsg = cmsg;
    p7ecx->output.outputfn = outputfn;
    p7ecx->output.outputarg = outputarg;
    p7ecx->output.dest = dest;
    p7ecx->output.destpoolp = destpoolp;
    p7ecx->type = SEC_OID_UNKNOWN;

    cinfo = NSS_CMSMessage_GetContentInfo(cmsg);

    switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
    case SEC_OID_PKCS7_SIGNED_DATA:
       rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData);
       break;
    case SEC_OID_PKCS7_ENVELOPED_DATA:
       rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData);
       break;
    case SEC_OID_PKCS7_DIGESTED_DATA:
       rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData);
       break;
    case SEC_OID_PKCS7_ENCRYPTED_DATA:
       rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData);
       break;
    default:
       rv = SECFailure;
       break;
    }
    if (rv != SECSuccess) {
       PORT_Free(p7ecx);
       return NULL;
    }

    /* Initialize the BER encoder.
     * Note that this will not encode anything until the first call to SEC_ASN1EncoderUpdate */
    p7ecx->ecx = SEC_ASN1EncoderStart(cmsg, NSSCMSMessageTemplate,
                                   nss_cms_encoder_out, &(p7ecx->output));
    if (p7ecx->ecx == NULL) {
       PORT_Free (p7ecx);
       return NULL;
    }
    p7ecx->ecxupdated = PR_FALSE;

    /*
     * Indicate that we are streaming.  We will be streaming until we
     * get past the contents bytes.
     */
    SEC_ASN1EncoderSetStreaming(p7ecx->ecx);

    /*
     * The notify function will watch for the contents field.
     */
    SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, nss_cms_encoder_notify, p7ecx);

    /* this will kick off the encoding process & encode everything up to the content bytes,
     * at which point the notify function sets streaming mode (and possibly creates
     * a child encoder). */
    if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) {
       PORT_Free (p7ecx);
       return NULL;
    }

    return p7ecx;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncoder_Update ( NSSCMSEncoderContext *  p7ecx,
const char *  data,
unsigned long  len 
)

Definition at line 614 of file cmsencode.c.

{
    SECStatus rv;
    NSSCMSContentInfo *cinfo;
    SECOidTag childtype;

    if (p7ecx->error)
       return SECFailure;

    /* hand data to the innermost decoder */
    if (p7ecx->childp7ecx) {
       /* recursion here */
       rv = NSS_CMSEncoder_Update(p7ecx->childp7ecx, data, len);
    } else {
       /* we are at innermost decoder */
       /* find out about our inner content type - must be data */
       cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
       childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
       if (childtype != SEC_OID_PKCS7_DATA)
           return SECFailure;
       /* and we must not have preset data */
       if (cinfo->content.data != NULL)
           return SECFailure;

       /*  hand it the data so it can encode it (let DER trickle up the chain) */
       rv = nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_TRUE);
    }
    return rv;
}

Here is the call graph for this function:

NSSCMSEncryptedData* NSS_CMSEncryptedData_Create ( NSSCMSMessage *  cmsg,
SECOidTag  algorithm,
int  keysize 
)

Definition at line 64 of file cmsencdata.c.

{
    void *mark;
    NSSCMSEncryptedData *encd;
    PLArenaPool *poolp;
    SECAlgorithmID *pbe_algid;
    SECStatus rv;

    poolp = cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    encd = (NSSCMSEncryptedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEncryptedData));
    if (encd == NULL)
       goto loser;

    encd->cmsg = cmsg;

    /* version is set in NSS_CMSEncryptedData_Encode_BeforeStart() */

    switch (algorithm) {
    /* XXX hmmm... hardcoded algorithms? */
    case SEC_OID_RC2_CBC:
    case SEC_OID_DES_EDE3_CBC:
    case SEC_OID_DES_CBC:
       rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(encd->contentInfo), algorithm, NULL, keysize);
       break;
    default:
       /* Assume password-based-encryption.  At least, try that. */
       pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, 1, NULL);
       if (pbe_algid == NULL) {
           rv = SECFailure;
           break;
       }
       rv = NSS_CMSContentInfo_SetContentEncAlgID(poolp, &(encd->contentInfo), pbe_algid, keysize);
       SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE);
       break;
    }
    if (rv != SECSuccess)
       goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return encd;

loser:
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncryptedData_Decode_AfterData ( NSSCMSEncryptedData *  encd)

Definition at line 262 of file cmsencdata.c.

{
    if (encd->contentInfo.ciphcx) {
       NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx);
       encd->contentInfo.ciphcx = NULL;
    }

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncryptedData_Decode_AfterEnd ( NSSCMSEncryptedData *  encd)

Definition at line 276 of file cmsencdata.c.

{
    /* apply final touches */
    return SECSuccess;
}
SECStatus NSS_CMSEncryptedData_Decode_BeforeData ( NSSCMSEncryptedData *  encd)

Definition at line 223 of file cmsencdata.c.

{
    PK11SymKey *bulkkey = NULL;
    NSSCMSContentInfo *cinfo;
    SECAlgorithmID *bulkalg;
    SECStatus rv = SECFailure;

    cinfo = &(encd->contentInfo);

    bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo);

    if (encd->cmsg->decrypt_key_cb == NULL)      /* no callback? no key../ */
       goto loser;

    bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, bulkalg);
    if (bulkkey == NULL)
       /* no success finding a bulk key */
       goto loser;

    NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);

    cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg);
    if (cinfo->ciphcx == NULL)
       goto loser;          /* error has been set by NSS_CMSCipherContext_StartDecrypt */


    /* we are done with (this) bulkkey now. */
    PK11_FreeSymKey(bulkkey);

    rv = SECSuccess;

loser:
    return rv;
}

Here is the call graph for this function:

void NSS_CMSEncryptedData_Destroy ( NSSCMSEncryptedData *  encd)

Definition at line 117 of file cmsencdata.c.

{
    /* everything's in a pool, so don't worry about the storage */
    NSS_CMSContentInfo_Destroy(&(encd->contentInfo));
    return;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncryptedData_Encode_AfterData ( NSSCMSEncryptedData *  encd)

Definition at line 207 of file cmsencdata.c.

{
    if (encd->contentInfo.ciphcx) {
       NSS_CMSCipherContext_Destroy(encd->contentInfo.ciphcx);
       encd->contentInfo.ciphcx = NULL;
    }

    /* nothing to do after data */
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncryptedData_Encode_BeforeData ( NSSCMSEncryptedData *  encd)

Definition at line 176 of file cmsencdata.c.

{
    NSSCMSContentInfo *cinfo;
    PK11SymKey *bulkkey;
    SECAlgorithmID *algid;

    cinfo = &(encd->contentInfo);

    /* find bulkkey and algorithm - must have been set by NSS_CMSEncryptedData_Encode_BeforeStart */
    bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
    if (bulkkey == NULL)
       return SECFailure;
    algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
    if (algid == NULL)
       return SECFailure;

    /* this may modify algid (with IVs generated in a token).
     * it is therefore essential that algid is a pointer to the "real" contentEncAlg,
     * not just to a copy */
    cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp, bulkkey, algid);
    PK11_FreeSymKey(bulkkey);
    if (cinfo->ciphcx == NULL)
       return SECFailure;

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSEncryptedData_Encode_BeforeStart ( NSSCMSEncryptedData *  encd)

Definition at line 142 of file cmsencdata.c.

{
    int version;
    PK11SymKey *bulkkey = NULL;
    SECItem *dummy;
    NSSCMSContentInfo *cinfo = &(encd->contentInfo);

    if (NSS_CMSArray_IsEmpty((void **)encd->unprotectedAttr))
       version = NSS_CMS_ENCRYPTED_DATA_VERSION;
    else
       version = NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR;
    
    dummy = SEC_ASN1EncodeInteger (encd->cmsg->poolp, &(encd->version), version);
    if (dummy == NULL)
       return SECFailure;

    /* now get content encryption key (bulk key) by using our cmsg callback */
    if (encd->cmsg->decrypt_key_cb)
       bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, 
                  NSS_CMSContentInfo_GetContentEncAlg(cinfo));
    if (bulkkey == NULL)
       return SECFailure;

    /* store the bulk key in the contentInfo so that the encoder can find it */
    NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
    PK11_FreeSymKey (bulkkey);

    return SECSuccess;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSEncryptedData_GetContentInfo ( NSSCMSEncryptedData *  encd)

Definition at line 128 of file cmsencdata.c.

{
    return &(encd->contentInfo);
}
SECStatus NSS_CMSEnvelopedData_AddRecipient ( NSSCMSEnvelopedData *  edp,
NSSCMSRecipientInfo *  rip 
)

Definition at line 127 of file cmsenvdata.c.

{
    void *mark;
    SECStatus rv;

    /* XXX compare pools, if not same, copy rip into edp's pool */

    PR_ASSERT(edp != NULL);
    PR_ASSERT(rip != NULL);

    mark = PORT_ArenaMark(edp->cmsg->poolp);

    rv = NSS_CMSArray_Add(edp->cmsg->poolp, (void ***)&(edp->recipientInfos), (void *)rip);
    if (rv != SECSuccess) {
       PORT_ArenaRelease(edp->cmsg->poolp, mark);
       return SECFailure;
    }

    PORT_ArenaUnmark (edp->cmsg->poolp, mark);
    return SECSuccess;
}

Here is the call graph for this function:

NSSCMSEnvelopedData* NSS_CMSEnvelopedData_Create ( NSSCMSMessage *  cmsg,
SECOidTag  algorithm,
int  keysize 
)

Definition at line 58 of file cmsenvdata.c.

{
    void *mark;
    NSSCMSEnvelopedData *envd;
    PLArenaPool *poolp;
    SECStatus rv;

    poolp = cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    envd = (NSSCMSEnvelopedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEnvelopedData));
    if (envd == NULL)
       goto loser;

    envd->cmsg = cmsg;

    /* version is set in NSS_CMSEnvelopedData_Encode_BeforeStart() */

    rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo), algorithm, NULL, keysize);
    if (rv != SECSuccess)
       goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return envd;

loser:
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

Here is the call graph for this function:

SECStatus NSS_CMSEnvelopedData_Decode_AfterData ( NSSCMSEnvelopedData *  envd)

Definition at line 402 of file cmsenvdata.c.

{
    if (envd && envd->contentInfo.ciphcx) {
       NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx);
       envd->contentInfo.ciphcx = NULL;
    }

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSEnvelopedData_Decode_AfterEnd ( NSSCMSEnvelopedData *  envd)

Definition at line 416 of file cmsenvdata.c.

{
    /* apply final touches */
    return SECSuccess;
}
SECStatus NSS_CMSEnvelopedData_Decode_BeforeData ( NSSCMSEnvelopedData *  envd)

Definition at line 315 of file cmsenvdata.c.

{
    NSSCMSRecipientInfo *ri;
    PK11SymKey *bulkkey = NULL;
    SECOidTag bulkalgtag;
    SECAlgorithmID *bulkalg;
    SECStatus rv = SECFailure;
    NSSCMSContentInfo *cinfo;
    NSSCMSRecipient **recipient_list = NULL;
    NSSCMSRecipient *recipient;
    int rlIndex;

    if (NSS_CMSArray_Count((void **)envd->recipientInfos) == 0) {
       PORT_SetError(SEC_ERROR_BAD_DATA);
#if 0
       PORT_SetErrorString("No recipient data in envelope.");
#endif
       goto loser;
    }

    /* look if one of OUR cert's issuerSN is on the list of recipients, and if so,  */
    /* get the cert and private key for it right away */
    recipient_list = nss_cms_recipient_list_create(envd->recipientInfos);
    if (recipient_list == NULL)
       goto loser;

    /* what about multiple recipientInfos that match?
     * especially if, for some reason, we could not produce a bulk key with the first match?!
     * we could loop & feed partial recipient_list to PK11_FindCertAndKeyByRecipientList...
     * maybe later... */
    rlIndex = PK11_FindCertAndKeyByRecipientListNew(recipient_list, envd->cmsg->pwfn_arg);

    /* if that fails, then we're not an intended recipient and cannot decrypt */
    if (rlIndex < 0) {
       PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT);
#if 0
       PORT_SetErrorString("Cannot decrypt data because proper key cannot be found.");
#endif
       goto loser;
    }

    recipient = recipient_list[rlIndex];
    if (!recipient->cert || !recipient->privkey) {
       /* XXX should set an error code ?!? */
       goto loser;
    }
    /* get a pointer to "our" recipientinfo */
    ri = envd->recipientInfos[recipient->riIndex];

    cinfo = &(envd->contentInfo);
    bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo);
    if (bulkalgtag == SEC_OID_UNKNOWN) {
       PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
    } else 
       bulkkey = 
           NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex,
                                              recipient->cert,
                                              recipient->privkey,
                                              bulkalgtag);
    if (bulkkey == NULL) {
       /* no success finding a bulk key */
       goto loser;
    }

    NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);

    bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo);

    cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg);
    if (cinfo->ciphcx == NULL)
       goto loser;          /* error has been set by NSS_CMSCipherContext_StartDecrypt */


    rv = SECSuccess;

loser:
    if (bulkkey)
       PK11_FreeSymKey(bulkkey);
    if (recipient_list != NULL)
       nss_cms_recipient_list_destroy(recipient_list);
    return rv;
}

Here is the call graph for this function:

void NSS_CMSEnvelopedData_Destroy ( NSSCMSEnvelopedData *  edp)

Definition at line 93 of file cmsenvdata.c.

{
    NSSCMSRecipientInfo **recipientinfos;
    NSSCMSRecipientInfo *ri;

    if (edp == NULL)
       return;

    recipientinfos = edp->recipientInfos;
    if (recipientinfos == NULL)
       return;

    while ((ri = *recipientinfos++) != NULL)
       NSS_CMSRecipientInfo_Destroy(ri);

   NSS_CMSContentInfo_Destroy(&(edp->contentInfo));

}

Here is the call graph for this function:

SECStatus NSS_CMSEnvelopedData_Encode_AfterData ( NSSCMSEnvelopedData *  envd)

Definition at line 299 of file cmsenvdata.c.

{
    if (envd->contentInfo.ciphcx) {
       NSS_CMSCipherContext_Destroy(envd->contentInfo.ciphcx);
       envd->contentInfo.ciphcx = NULL;
    }

    /* nothing else to do after data */
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSEnvelopedData_Encode_BeforeData ( NSSCMSEnvelopedData *  envd)

Definition at line 268 of file cmsenvdata.c.

{
    NSSCMSContentInfo *cinfo;
    PK11SymKey *bulkkey;
    SECAlgorithmID *algid;

    cinfo = &(envd->contentInfo);

    /* find bulkkey and algorithm - must have been set by NSS_CMSEnvelopedData_Encode_BeforeStart */
    bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
    if (bulkkey == NULL)
       return SECFailure;
    algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
    if (algid == NULL)
       return SECFailure;

    /* this may modify algid (with IVs generated in a token).
     * it is essential that algid is a pointer to the contentEncAlg data, not a
     * pointer to a copy! */
    cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid);
    PK11_FreeSymKey(bulkkey);
    if (cinfo->ciphcx == NULL)
       return SECFailure;

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSEnvelopedData_Encode_BeforeStart ( NSSCMSEnvelopedData *  envd)

Definition at line 162 of file cmsenvdata.c.

{
    int version;
    NSSCMSRecipientInfo **recipientinfos;
    NSSCMSContentInfo *cinfo;
    PK11SymKey *bulkkey = NULL;
    SECOidTag bulkalgtag;
    CK_MECHANISM_TYPE type;
    PK11SlotInfo *slot;
    SECStatus rv;
    SECItem *dummy;
    PLArenaPool *poolp;
    extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
    void *mark = NULL;
    int i;

    poolp = envd->cmsg->poolp;
    cinfo = &(envd->contentInfo);

    recipientinfos = envd->recipientInfos;
    if (recipientinfos == NULL) {
       PORT_SetError(SEC_ERROR_BAD_DATA);
#if 0
       PORT_SetErrorString("Cannot find recipientinfos to encode.");
#endif
       goto loser;
    }

    version = NSS_CMS_ENVELOPED_DATA_VERSION_REG;
    if (envd->originatorInfo != NULL || envd->unprotectedAttr != NULL) {
       version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
    } else {
       for (i = 0; recipientinfos[i] != NULL; i++) {
           if (NSS_CMSRecipientInfo_GetVersion(recipientinfos[i]) != 0) {
              version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
              break;
           }
       }
    }
    dummy = SEC_ASN1EncodeInteger(poolp, &(envd->version), version);
    if (dummy == NULL)
       goto loser;

    /* now we need to have a proper content encryption algorithm
     * on the SMIME level, we would figure one out by looking at SMIME capabilities
     * we cannot do that on our level, so if none is set already, we'll just go
     * with one of the mandatory algorithms (3DES) */
    if ((bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo)) == SEC_OID_UNKNOWN) {
       rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, cinfo, SEC_OID_DES_EDE3_CBC, NULL, 168);
       if (rv != SECSuccess)
           goto loser;
       bulkalgtag = SEC_OID_DES_EDE3_CBC;
    } 

    /* generate a random bulk key suitable for content encryption alg */
    type = PK11_AlgtagToMechanism(bulkalgtag);
    slot = PK11_GetBestSlot(type, envd->cmsg->pwfn_arg);
    if (slot == NULL)
       goto loser;   /* error has been set by PK11_GetBestSlot */

    /* this is expensive... */
    bulkkey = PK11_KeyGen(slot, type, NULL, NSS_CMSContentInfo_GetBulkKeySize(cinfo) / 8, envd->cmsg->pwfn_arg);
    PK11_FreeSlot(slot);
    if (bulkkey == NULL)
       goto loser;   /* error has been set by PK11_KeyGen */

    mark = PORT_ArenaMark(poolp);

    /* Encrypt the bulk key with the public key of each recipient.  */
    for (i = 0; recipientinfos[i] != NULL; i++) {
       rv = NSS_CMSRecipientInfo_WrapBulkKey(recipientinfos[i], bulkkey, bulkalgtag);
       if (rv != SECSuccess)
           goto loser;      /* error has been set by NSS_CMSRecipientInfo_EncryptBulkKey */
                     /* could be: alg not supported etc. */
    }

    /* the recipientinfos are all finished. now sort them by DER for SET OF encoding */
    rv = NSS_CMSArray_SortByDER((void **)envd->recipientInfos, NSSCMSRecipientInfoTemplate, NULL);
    if (rv != SECSuccess)
       goto loser;   /* error has been set by NSS_CMSArray_SortByDER */

    /* store the bulk key in the contentInfo so that the encoder can find it */
    NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);

    PORT_ArenaUnmark(poolp, mark);

    PK11_FreeSymKey(bulkkey);

    return SECSuccess;

loser:
    if (mark != NULL)
       PORT_ArenaRelease (poolp, mark);
    if (bulkkey)
       PK11_FreeSymKey(bulkkey);

    return SECFailure;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSEnvelopedData_GetContentInfo ( NSSCMSEnvelopedData *  envd)

Definition at line 116 of file cmsenvdata.c.

{
    return &(envd->contentInfo);
}
PRBool NSS_CMSMessage_ContainsCertsOrCrls ( NSSCMSMessage *  cmsg)

Definition at line 231 of file cmsmessage.c.

{
    NSSCMSContentInfo *cinfo;

    /* descend into CMS message */
    for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) {
       if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) != SEC_OID_PKCS7_SIGNED_DATA)
           continue; /* next level */
       
       if (NSS_CMSSignedData_ContainsCertsOrCrls(cinfo->content.signedData))
           return PR_TRUE;
    }
    return PR_FALSE;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSMessage_ContentLevel ( NSSCMSMessage *  cmsg,
int  n 
)

Definition at line 214 of file cmsmessage.c.

{
    int count = 0;
    NSSCMSContentInfo *cinfo;

    /* walk down the chain of contentinfos */
    for (cinfo = &(cmsg->contentInfo); cinfo != NULL && count < n; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo)) {
       count++;
    }

    return cinfo;
}

Here is the call graph for this function:

int NSS_CMSMessage_ContentLevelCount ( NSSCMSMessage *  cmsg)

Definition at line 195 of file cmsmessage.c.

{
    int count = 0;
    NSSCMSContentInfo *cinfo;

    /* walk down the chain of contentinfos */
    for (cinfo = &(cmsg->contentInfo); cinfo != NULL; ) {
       count++;
       cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
    }
    return count;
}

Here is the call graph for this function:

NSSCMSMessage* NSS_CMSMessage_Copy ( NSSCMSMessage *  cmsg)

Definition at line 146 of file cmsmessage.c.

{
    if (cmsg == NULL)
       return NULL;

    PORT_Assert (cmsg->refCount > 0);

    cmsg->refCount++; /* XXX chrisk thread safety? */
    return cmsg;
}
NSSCMSMessage* NSS_CMSMessage_Create ( PLArenaPool poolp)

Definition at line 58 of file cmsmessage.c.

{
    void *mark = NULL;
    NSSCMSMessage *cmsg;
    PRBool poolp_is_ours = PR_FALSE;

    if (poolp == NULL) {
       poolp = PORT_NewArena (1024);           /* XXX what is right value? */
       if (poolp == NULL)
           return NULL;
       poolp_is_ours = PR_TRUE;
    } 

    if (!poolp_is_ours)
       mark = PORT_ArenaMark(poolp);

    cmsg = (NSSCMSMessage *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSMessage));
    if (cmsg == NULL) {
       if (!poolp_is_ours) {
           if (mark) {
              PORT_ArenaRelease(poolp, mark);
           }
       } else
           PORT_FreeArena(poolp, PR_FALSE);
       return NULL;
    }

    cmsg->poolp = poolp;
    cmsg->poolp_is_ours = poolp_is_ours;
    cmsg->refCount = 1;

    if (mark)
       PORT_ArenaUnmark(poolp, mark);

    return cmsg;
}

Here is the call graph for this function:

NSSCMSMessage* NSS_CMSMessage_CreateFromDER ( SECItem *  DERmessage,
NSSCMSContentCallback  cb,
void cb_arg,
PK11PasswordFunc  pwfn,
void pwfn_arg,
NSSCMSGetDecryptKeyCallback  decrypt_key_cb,
void decrypt_key_cb_arg 
)

Definition at line 728 of file cmsdecode.c.

{
    NSSCMSDecoderContext *p7dcx;

    /* first arg(poolp) == NULL => create our own pool */
    p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg, 
                                 decrypt_key_cb, decrypt_key_cb_arg);
    NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len);
    return NSS_CMSDecoder_Finish(p7dcx);
}

Here is the call graph for this function:

void NSS_CMSMessage_Destroy ( NSSCMSMessage *  cmsg)

Definition at line 122 of file cmsmessage.c.

{
    PORT_Assert (cmsg->refCount > 0);
    if (cmsg->refCount <= 0)       /* oops */
       return;

    cmsg->refCount--;              /* thread safety? */
    if (cmsg->refCount > 0)
       return;

    NSS_CMSContentInfo_Destroy(&(cmsg->contentInfo));

    /* if poolp is not NULL, cmsg is the owner of its arena */
    if (cmsg->poolp_is_ours)
       PORT_FreeArena (cmsg->poolp, PR_FALSE);   /* XXX clear it? */
}

Here is the call graph for this function:

PLArenaPool* NSS_CMSMessage_GetArena ( NSSCMSMessage *  cmsg)

Definition at line 161 of file cmsmessage.c.

{
    return cmsg->poolp;
}
SECItem* NSS_CMSMessage_GetContent ( NSSCMSMessage *  cmsg)

Definition at line 181 of file cmsmessage.c.

{
    /* this is a shortcut */
    NSSCMSContentInfo * cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
    SECItem           * pItem = NSS_CMSContentInfo_GetInnerContent(cinfo);
    return pItem;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSMessage_GetContentInfo ( NSSCMSMessage *  cmsg)

Definition at line 170 of file cmsmessage.c.

{
    return &(cmsg->contentInfo);
}
PRBool NSS_CMSMessage_IsContentEmpty ( NSSCMSMessage *  cmsg,
unsigned int  minLen 
)

Definition at line 305 of file cmsmessage.c.

{
    SECItem *item = NULL;

    if (cmsg == NULL)
       return PR_TRUE;

    item = NSS_CMSContentInfo_GetContent(NSS_CMSMessage_GetContentInfo(cmsg));

    if (!item) {
       return PR_TRUE;
    } else if(item->len <= minLen) {
       return PR_TRUE;
    }

    return PR_FALSE;
}

Here is the call graph for this function:

PRBool NSS_CMSMessage_IsEncrypted ( NSSCMSMessage *  cmsg)

Definition at line 250 of file cmsmessage.c.

{
    NSSCMSContentInfo *cinfo;

    /* walk down the chain of contentinfos */
    for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo))
    {
       switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
       case SEC_OID_PKCS7_ENVELOPED_DATA:
       case SEC_OID_PKCS7_ENCRYPTED_DATA:
           return PR_TRUE;
       default:
           break;
       }
    }
    return PR_FALSE;
}

Here is the call graph for this function:

PRBool NSS_CMSMessage_IsSigned ( NSSCMSMessage *  cmsg)

Definition at line 279 of file cmsmessage.c.

{
    NSSCMSContentInfo *cinfo;

    /* walk down the chain of contentinfos */
    for (cinfo = &(cmsg->contentInfo); cinfo != NULL; cinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo))
    {
       switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
       case SEC_OID_PKCS7_SIGNED_DATA:
           if (!NSS_CMSArray_IsEmpty((void **)cinfo->content.signedData->signerInfos))
              return PR_TRUE;
           break;
       default:
           break;
       }
    }
    return PR_FALSE;
}

Here is the call graph for this function:

void NSS_CMSMessage_SetEncodingParams ( NSSCMSMessage *  cmsg,
PK11PasswordFunc  pwfn,
void pwfn_arg,
NSSCMSGetDecryptKeyCallback  decrypt_key_cb,
void decrypt_key_cb_arg,
SECAlgorithmID **  detached_digestalgs,
SECItem **  detached_digests 
)

Definition at line 104 of file cmsmessage.c.

{
    if (pwfn)
       PK11_SetPasswordFunc(pwfn);
    cmsg->pwfn_arg = pwfn_arg;
    cmsg->decrypt_key_cb = decrypt_key_cb;
    cmsg->decrypt_key_cb_arg = decrypt_key_cb_arg;
    cmsg->detached_digestalgs = detached_digestalgs;
    cmsg->detached_digests = detached_digests;
}

Here is the call graph for this function:

NSSCMSRecipientInfo* NSS_CMSRecipientInfo_Create ( NSSCMSMessage *  cmsg,
CERTCertificate *  cert 
)

Definition at line 301 of file cmsrecinfo.c.

Here is the call graph for this function:

NSSCMSRecipientInfo* NSS_CMSRecipientInfo_CreateFromDER ( SECItem *  input,
void pwfn_arg 
)

Definition at line 315 of file cmsrecinfo.c.

Here is the call graph for this function:

NSSCMSRecipientInfo* NSS_CMSRecipientInfo_CreateNew ( void pwfn_arg)

Definition at line 308 of file cmsrecinfo.c.

Here is the call graph for this function:

NSSCMSRecipientInfo* NSS_CMSRecipientInfo_CreateWithSubjKeyID ( NSSCMSMessage *  cmsg,
SECItem *  subjKeyID,
SECKEYPublicKey *  pubKey 
)

Definition at line 323 of file cmsrecinfo.c.

{
    return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID, 
                                       NULL, pubKey, subjKeyID, NULL, NULL);
}

Here is the call graph for this function:

NSSCMSRecipientInfo* NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert ( NSSCMSMessage *  cmsg,
CERTCertificate *  cert 
)

Definition at line 332 of file cmsrecinfo.c.

{
    SECKEYPublicKey *pubKey = NULL;
    SECItem subjKeyID = {siBuffer, NULL, 0};
    NSSCMSRecipientInfo *retVal = NULL;

    if (!cmsg || !cert) {
       return NULL;
    }
    pubKey = CERT_ExtractPublicKey(cert);
    if (!pubKey) {
       goto done;
    }
    if (CERT_FindSubjectKeyIDExtension(cert, &subjKeyID) != SECSuccess ||
        subjKeyID.data == NULL) {
       goto done;
    }
    retVal = NSS_CMSRecipientInfo_CreateWithSubjKeyID(cmsg, &subjKeyID, pubKey);
done:
    if (pubKey)
       SECKEY_DestroyPublicKey(pubKey);

    if (subjKeyID.data)
       SECITEM_FreeItem(&subjKeyID, PR_FALSE);

    return retVal;
}

Here is the call graph for this function:

void NSS_CMSRecipientInfo_Destroy ( NSSCMSRecipientInfo *  ri)

Definition at line 362 of file cmsrecinfo.c.

{
    if (!ri) {
        return;
    }
    /* version was allocated on the pool, so no need to destroy it */
    /* issuerAndSN was allocated on the pool, so no need to destroy it */
    if (ri->cert != NULL)
       CERT_DestroyCertificate(ri->cert);

    if (nss_cmsrecipientinfo_usessubjectkeyid(ri)) {
       NSSCMSKeyTransRecipientInfoEx *extra;
       extra = &ri->ri.keyTransRecipientInfoEx;
       if (extra->pubKey)
           SECKEY_DestroyPublicKey(extra->pubKey);
    }
    if (ri->cmsg && ri->cmsg->contentInfo.contentTypeTag == &fakeContent) {
       NSS_CMSMessage_Destroy(ri->cmsg);
    }

    /* we're done. */
}

Here is the call graph for this function:

SECStatus NSS_CMSRecipientInfo_Encode ( PRArenaPool poolp,
const NSSCMSRecipientInfo *  src,
SECItem *  returned 
)

Definition at line 701 of file cmsrecinfo.c.

{
    extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
    SECStatus rv = SECFailure;
    if (!src || !returned) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
    } else if (SEC_ASN1EncodeItem(poolp, returned, src,
        NSSCMSRecipientInfoTemplate))   {
        rv = SECSuccess;
    }
    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSRecipientInfo_GetCertAndKey ( NSSCMSRecipientInfo *  ri,
CERTCertificate **  retcert,
SECKEYPrivateKey **  retkey 
)

Definition at line 626 of file cmsrecinfo.c.

{
    CERTCertificate* cert = NULL;
    NSSCMSRecipient** recipients = NULL;
    NSSCMSRecipientInfo* recipientInfos[2];
    SECStatus rv = SECSuccess;
    SECKEYPrivateKey* key = NULL;

    if (!ri)
        return SECFailure;
    
    if (!retcert && !retkey) {
        /* nothing requested, nothing found, success */
        return SECSuccess;
    }

    if (retcert) {
        *retcert = NULL;
    }
    if (retkey) {
        *retkey = NULL;
    }

    if (ri->cert) {
        cert = CERT_DupCertificate(ri->cert);
        if (!cert) {
            rv = SECFailure;
        }
    }
    if (SECSuccess == rv && !cert) {
        /* we don't have the cert, we have to look for it */
        /* first build an NSS_CMSRecipient */
        recipientInfos[0] = ri;
        recipientInfos[1] = NULL;

        recipients = nss_cms_recipient_list_create(recipientInfos);
        if (recipients) {
            /* now look for the cert and key */
            if (0 == PK11_FindCertAndKeyByRecipientListNew(recipients,
                ri->cmsg->pwfn_arg)) {
                cert = CERT_DupCertificate(recipients[0]->cert);
                key = SECKEY_CopyPrivateKey(recipients[0]->privkey);
            } else {
                rv = SECFailure;
            }

            nss_cms_recipient_list_destroy(recipients);
        }
        else {
            rv = SECFailure;
        }            
    } else if (SECSuccess == rv && cert && retkey) {
        /* we have the cert, we just need the key now */
        key = PK11_FindPrivateKeyFromCert(cert->slot, cert, ri->cmsg->pwfn_arg);
    }
    if (retcert) {
        *retcert = cert;
    } else {
        if (cert) {
            CERT_DestroyCertificate(cert);
        }
    }
    if (retkey) {
        *retkey = key;
    } else {
        if (key) {
            SECKEY_DestroyPrivateKey(key);
        }
    }

    return rv;
}

Here is the call graph for this function:

SECItem* NSS_CMSRecipientInfo_GetEncryptedKey ( NSSCMSRecipientInfo *  ri,
int  subIndex 
)

Definition at line 417 of file cmsrecinfo.c.

{
    SECItem *enckey = NULL;

    switch (ri->recipientInfoType) {
    case NSSCMSRecipientInfoID_KeyTrans:
       /* ignore subIndex */
       enckey = &(ri->ri.keyTransRecipientInfo.encKey);
       break;
    case NSSCMSRecipientInfoID_KEK:
       /* ignore subIndex */
       enckey = &(ri->ri.kekRecipientInfo.encKey);
       break;
    case NSSCMSRecipientInfoID_KeyAgree:
       enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
       break;
    }
    return enckey;
}

Definition at line 439 of file cmsrecinfo.c.

{
    SECOidTag encalgtag = SEC_OID_UNKNOWN; /* an invalid encryption alg */

    switch (ri->recipientInfoType) {
    case NSSCMSRecipientInfoID_KeyTrans:
       encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg));
       break;
    case NSSCMSRecipientInfoID_KeyAgree:
       encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
       break;
    case NSSCMSRecipientInfoID_KEK:
       encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg));
       break;
    }
    return encalgtag;
}

Here is the call graph for this function:

int NSS_CMSRecipientInfo_GetVersion ( NSSCMSRecipientInfo *  ri)

Definition at line 386 of file cmsrecinfo.c.

{
    unsigned long version;
    SECItem *versionitem = NULL;

    switch (ri->recipientInfoType) {
    case NSSCMSRecipientInfoID_KeyTrans:
       /* ignore subIndex */
       versionitem = &(ri->ri.keyTransRecipientInfo.version);
       break;
    case NSSCMSRecipientInfoID_KEK:
       /* ignore subIndex */
       versionitem = &(ri->ri.kekRecipientInfo.version);
       break;
    case NSSCMSRecipientInfoID_KeyAgree:
       versionitem = &(ri->ri.keyAgreeRecipientInfo.version);
       break;
    }

    PORT_Assert(versionitem);
    if (versionitem == NULL) 
       return 0;

    /* always take apart the SECItem */
    if (SEC_ASN1DecodeInteger(versionitem, &version) != SECSuccess)
       return 0;
    else
       return (int)version;
}

Here is the call graph for this function:

PK11SymKey* NSS_CMSRecipientInfo_UnwrapBulkKey ( NSSCMSRecipientInfo *  ri,
int  subIndex,
CERTCertificate *  cert,
SECKEYPrivateKey *  privkey,
SECOidTag  bulkalgtag 
)

Definition at line 556 of file cmsrecinfo.c.

{
    PK11SymKey *bulkkey = NULL;
    SECAlgorithmID *encalg;
    SECOidTag encalgtag;
    SECItem *enckey;
    int error;

    ri->cert = CERT_DupCertificate(cert);
              /* mark the recipientInfo so we can find it later */

    switch (ri->recipientInfoType) {
    case NSSCMSRecipientInfoID_KeyTrans:
       encalg = &(ri->ri.keyTransRecipientInfo.keyEncAlg);
       encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg));
       enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */
       switch (encalgtag) {
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
           /* RSA encryption algorithm: */
           /* get the symmetric (bulk) key by unwrapping it using our private key */
           bulkkey = NSS_CMSUtil_DecryptSymKey_RSA(privkey, enckey, bulkalgtag);
           break;
       case SEC_OID_NETSCAPE_SMIME_KEA:
           /* FORTEZZA key exchange algorithm */
           /* the supplemental data is in the parameters of encalg */
           bulkkey = NSS_CMSUtil_DecryptSymKey_MISSI(privkey, enckey, encalg, bulkalgtag, ri->cmsg->pwfn_arg);
           break;
       default:
           error = SEC_ERROR_UNSUPPORTED_KEYALG;
           goto loser;
       }
       break;
    case NSSCMSRecipientInfoID_KeyAgree:
       encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg);
       encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
       enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
       switch (encalgtag) {
       case SEC_OID_X942_DIFFIE_HELMAN_KEY:
           /* Diffie-Helman key exchange */
           /* XXX not yet implemented */
           /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */
           /* we support ephemeral-static DH only, so if the recipientinfo */
           /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */
           /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */
           /* content encryption key using a Unwrap op */
           /* the derive operation has to generate the key using the algorithm in RFC2631 */
           error = SEC_ERROR_UNSUPPORTED_KEYALG;
           break;
       default:
           error = SEC_ERROR_UNSUPPORTED_KEYALG;
           goto loser;
       }
       break;
    case NSSCMSRecipientInfoID_KEK:
       encalg = &(ri->ri.kekRecipientInfo.keyEncAlg);
       encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.kekRecipientInfo.keyEncAlg));
       enckey = &(ri->ri.kekRecipientInfo.encKey);
       /* not supported yet */
       error = SEC_ERROR_UNSUPPORTED_KEYALG;
       goto loser;
       break;
    }
    /* XXXX continue here */
    return bulkkey;

loser:
    return NULL;
}

Here is the call graph for this function:

SECStatus NSS_CMSRecipientInfo_WrapBulkKey ( NSSCMSRecipientInfo *  ri,
PK11SymKey *  bulkkey,
SECOidTag  bulkalgtag 
)

Definition at line 458 of file cmsrecinfo.c.

{
    CERTCertificate *cert;
    SECOidTag certalgtag;
    SECStatus rv = SECSuccess;
    SECItem *params = NULL;
    NSSCMSRecipientEncryptedKey *rek;
    NSSCMSOriginatorIdentifierOrKey *oiok;
    CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL;
    PLArenaPool *poolp;
    NSSCMSKeyTransRecipientInfoEx *extra = NULL;
    PRBool usesSubjKeyID;

    poolp = ri->cmsg->poolp;
    cert = ri->cert;
    usesSubjKeyID = nss_cmsrecipientinfo_usessubjectkeyid(ri);
    if (cert) {
       spki = &cert->subjectPublicKeyInfo;
       certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm));
    } else if (usesSubjKeyID) {
       extra = &ri->ri.keyTransRecipientInfoEx;
       /* sanity check */
       PORT_Assert(extra->pubKey);
       if (!extra->pubKey) {
           PORT_SetError(SEC_ERROR_INVALID_ARGS);
           return SECFailure;
       }
       spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(extra->pubKey);
       certalgtag = SECOID_GetAlgorithmTag(&spki->algorithm);
    } else {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    /* XXX set ri->recipientInfoType to the proper value here */
    /* or should we look if it's been set already ? */

    certalgtag = SECOID_GetAlgorithmTag(&spki->algorithm);
    switch (certalgtag) {
    case SEC_OID_PKCS1_RSA_ENCRYPTION:
       /* wrap the symkey */
       if (cert) {
           rv = NSS_CMSUtil_EncryptSymKey_RSA(poolp, cert, bulkkey, 
                                &ri->ri.keyTransRecipientInfo.encKey);
           if (rv != SECSuccess)
              break;
       } else if (usesSubjKeyID) {
           PORT_Assert(extra != NULL);
           rv = NSS_CMSUtil_EncryptSymKey_RSAPubKey(poolp, extra->pubKey,
                                bulkkey, &ri->ri.keyTransRecipientInfo.encKey);
           if (rv != SECSuccess)
              break;
       }

       rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL);
       break;
    case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
       rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0];
       if (rek == NULL) {
           rv = SECFailure;
           break;
       }

       oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey);
       PORT_Assert(oiok->identifierType == NSSCMSOriginatorIDOrKey_OriginatorPublicKey);

       /* see RFC2630 12.3.1.1 */
       if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier,
                                SEC_OID_X942_DIFFIE_HELMAN_KEY, NULL) != SECSuccess) {
           rv = SECFailure;
           break;
       }

       /* this will generate a key pair, compute the shared secret, */
       /* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */
       /* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */
       rv = NSS_CMSUtil_EncryptSymKey_ESDH(poolp, cert, bulkkey,
                                   &rek->encKey,
                                   &ri->ri.keyAgreeRecipientInfo.ukm,
                                   &ri->ri.keyAgreeRecipientInfo.keyEncAlg,
                                   &oiok->id.originatorPublicKey.publicKey);

       break;
    default:
       /* other algorithms not supported yet */
       /* NOTE that we do not support any KEK algorithm */
       PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
       rv = SECFailure;
       break;
    }
    if (freeSpki)
       SECKEY_DestroySubjectPublicKeyInfo(freeSpki);

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_AddCertChain ( NSSCMSSignedData *  sigd,
CERTCertificate *  cert 
)

Definition at line 775 of file cmssigdata.c.

{
    CERTCertificateList *certlist;
    SECCertUsage usage;
    SECStatus rv;

    usage = certUsageEmailSigner;

    if (!sigd || !cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* do not include root */
    certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE);
    if (certlist == NULL)
       return SECFailure;

    rv = NSS_CMSSignedData_AddCertList(sigd, certlist);

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_AddCertificate ( NSSCMSSignedData *  sigd,
CERTCertificate *  cert 
)

Definition at line 815 of file cmssigdata.c.

{
    CERTCertificate *c;
    SECStatus rv;

    if (!sigd || !cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    c = CERT_DupCertificate(cert);
    rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certs), (void *)c);
    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_AddCertList ( NSSCMSSignedData *  sigd,
CERTCertificateList *  certlist 
)

Definition at line 756 of file cmssigdata.c.

{
    SECStatus rv;

    if (!sigd || !certlist) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* XXX memory?? a certlist has an arena of its own and is not refcounted!?!? */
    rv = NSS_CMSArray_Add(sigd->cmsg->poolp, (void ***)&(sigd->certLists), (void *)certlist);

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_AddDigest ( PRArenaPool poolp,
NSSCMSSignedData *  sigd,
SECOidTag  digestalgtag,
SECItem *  digest 
)

Definition at line 1015 of file cmssigdata.c.

{
    SECAlgorithmID *digestalg;
    void *mark;

    if (!sigd || !poolp) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    mark = PORT_ArenaMark(poolp);

    digestalg = PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
    if (digestalg == NULL)
       goto loser;

    if (SECOID_SetAlgorithmID (poolp, digestalg, digestalgtag, NULL) != SECSuccess) /* no params */
       goto loser;

    if (NSS_CMSArray_Add(poolp, (void ***)&(sigd->digestAlgorithms), (void *)digestalg) != SECSuccess ||
       /* even if digest is NULL, add dummy to have same-size array */
       NSS_CMSArray_Add(poolp, (void ***)&(sigd->digests), (void *)digest) != SECSuccess)
    {
       goto loser;
    }

    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_AddSignerInfo ( NSSCMSSignedData *  sigd,
NSSCMSSignerInfo *  signerinfo 
)

Definition at line 846 of file cmssigdata.c.

{
    void *mark;
    SECStatus rv;
    SECOidTag digestalgtag;
    PLArenaPool *poolp;

    if (!sigd || !signerinfo) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    poolp = sigd->cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    /* add signerinfo */
    rv = NSS_CMSArray_Add(poolp, (void ***)&(sigd->signerInfos), (void *)signerinfo);
    if (rv != SECSuccess)
       goto loser;

    /*
     * add empty digest
     * Empty because we don't have it yet. Either it gets created during encoding
     * (if the data is present) or has to be set externally.
     * XXX maybe pass it in optionally?
     */
    digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
    rv = NSS_CMSSignedData_SetDigestValue(sigd, digestalgtag, NULL);
    if (rv != SECSuccess)
       goto loser;

    /*
     * The last thing to get consistency would be adding the digest.
     */

    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease (poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

PRBool NSS_CMSSignedData_ContainsCertsOrCrls ( NSSCMSSignedData *  sigd)

Definition at line 831 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return PR_FALSE;
    }
    if (sigd->rawCerts != NULL && sigd->rawCerts[0] != NULL)
       return PR_TRUE;
    else if (sigd->crls != NULL && sigd->crls[0] != NULL)
       return PR_TRUE;
    else
       return PR_FALSE;
}

Here is the call graph for this function:

NSSCMSSignedData* NSS_CMSSignedData_Create ( NSSCMSMessage *  cmsg)

Definition at line 54 of file cmssigdata.c.

{
    void *mark;
    NSSCMSSignedData *sigd;
    PLArenaPool *poolp;

    if (!cmsg) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    poolp = cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    sigd = (NSSCMSSignedData *)PORT_ArenaZAlloc (poolp, sizeof(NSSCMSSignedData));
    if (sigd == NULL)
       goto loser;

    sigd->cmsg = cmsg;

    /* signerInfos, certs, certlists, crls are all empty */
    /* version is set in NSS_CMSSignedData_Finalize() */

    PORT_ArenaUnmark(poolp, mark);
    return sigd;

loser:
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

Here is the call graph for this function:

NSSCMSSignedData* NSS_CMSSignedData_CreateCertsOnly ( NSSCMSMessage *  cmsg,
CERTCertificate *  cert,
PRBool  include_chain 
)

Definition at line 1090 of file cmssigdata.c.

{
    NSSCMSSignedData *sigd;
    void *mark;
    PLArenaPool *poolp;
    SECStatus rv;

    if (!cmsg || !cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    poolp = cmsg->poolp;
    mark = PORT_ArenaMark(poolp);

    sigd = NSS_CMSSignedData_Create(cmsg);
    if (sigd == NULL)
       goto loser;

    /* no signerinfos, thus no digestAlgorithms */

    /* but certs */
    if (include_chain) {
       rv = NSS_CMSSignedData_AddCertChain(sigd, cert);
    } else {
       rv = NSS_CMSSignedData_AddCertificate(sigd, cert);
    }
    if (rv != SECSuccess)
       goto loser;

    /* RFC2630 5.2 sez:
     * In the degenerate case where there are no signers, the
     * EncapsulatedContentInfo value being "signed" is irrelevant.  In this
     * case, the content type within the EncapsulatedContentInfo value being
     * "signed" should be id-data (as defined in section 4), and the content
     * field of the EncapsulatedContentInfo value should be omitted.
     */
    rv = NSS_CMSContentInfo_SetContent_Data(cmsg, &(sigd->contentInfo), NULL, PR_TRUE);
    if (rv != SECSuccess)
       goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return sigd;

loser:
    if (sigd)
       NSS_CMSSignedData_Destroy(sigd);
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_Decode_AfterData ( NSSCMSSignedData *  sigd)

Definition at line 414 of file cmssigdata.c.

{
    SECStatus rv = SECSuccess;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* did we have digest calculation going on? */
    if (sigd->contentInfo.digcx) {
       rv = NSS_CMSDigestContext_FinishMultiple(sigd->contentInfo.digcx, 
                                   sigd->cmsg->poolp, &(sigd->digests));
       /* error set by NSS_CMSDigestContext_FinishMultiple */
       sigd->contentInfo.digcx = NULL;
    }
    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_Decode_AfterEnd ( NSSCMSSignedData *  sigd)

Definition at line 438 of file cmssigdata.c.

{
    NSSCMSSignerInfo **signerinfos = NULL;
    int i;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* set cmsg for all the signerinfos */
    signerinfos = sigd->signerInfos;

    /* set cmsg for all the signerinfos */
    if (signerinfos) {
       for (i = 0; signerinfos[i] != NULL; i++)
           signerinfos[i]->cmsg = sigd->cmsg;
    }

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_Decode_BeforeData ( NSSCMSSignedData *  sigd)

Definition at line 393 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    /* set up the digests */
    if (sigd->digestAlgorithms != NULL && sigd->digests == NULL) {
       /* if digests are already there, do nothing */
       sigd->contentInfo.digcx = NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
       if (sigd->contentInfo.digcx == NULL)
           return SECFailure;
    }
    return SECSuccess;
}

Here is the call graph for this function:

void NSS_CMSSignedData_Destroy ( NSSCMSSignedData *  sigd)

Definition at line 87 of file cmssigdata.c.

{
    CERTCertificate **certs, **tempCerts, *cert;
    CERTCertificateList **certlists, *certlist;
    NSSCMSSignerInfo **signerinfos, *si;

    if (sigd == NULL)
       return;

    certs = sigd->certs;
    tempCerts = sigd->tempCerts;
    certlists = sigd->certLists;
    signerinfos = sigd->signerInfos;

    if (certs != NULL) {
       while ((cert = *certs++) != NULL)
           CERT_DestroyCertificate (cert);
    }

    if (tempCerts != NULL) {
       while ((cert = *tempCerts++) != NULL)
           CERT_DestroyCertificate (cert);
    }

    if (certlists != NULL) {
       while ((certlist = *certlists++) != NULL)
           CERT_DestroyCertificateList (certlist);
    }

    if (signerinfos != NULL) {
       while ((si = *signerinfos++) != NULL)
           NSS_CMSSignerInfo_Destroy(si);
    }

    /* everything's in a pool, so don't worry about the storage */
   NSS_CMSContentInfo_Destroy(&(sigd->contentInfo));

}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_Encode_AfterData ( NSSCMSSignedData *  sigd)

Definition at line 247 of file cmssigdata.c.

{
    NSSCMSSignerInfo **signerinfos, *signerinfo;
    NSSCMSContentInfo *cinfo;
    SECOidTag digestalgtag;
    SECStatus ret = SECFailure;
    SECStatus rv;
    SECItem *contentType;
    int certcount;
    int i, ci, cli, n, rci, si;
    PLArenaPool *poolp;
    CERTCertificateList *certlist;
    extern const SEC_ASN1Template NSSCMSSignerInfoTemplate[];

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    poolp = sigd->cmsg->poolp;
    cinfo = &(sigd->contentInfo);

    /* did we have digest calculation going on? */
    if (cinfo->digcx) {
       rv = NSS_CMSDigestContext_FinishMultiple(cinfo->digcx, poolp, 
                                                &(sigd->digests));
       /* error has been set by NSS_CMSDigestContext_FinishMultiple */
       cinfo->digcx = NULL;
       if (rv != SECSuccess)
           goto loser;             
    }

    signerinfos = sigd->signerInfos;
    certcount = 0;

    /* prepare all the SignerInfos (there may be none) */
    for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) {
       signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i);

       /* find correct digest for this signerinfo */
       digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
       n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
       if (n < 0 || sigd->digests == NULL || sigd->digests[n] == NULL) {
           /* oops - digest not found */
           PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
           goto loser;
       }

       /* XXX if our content is anything else but data, we need to force the
        * presence of signed attributes (RFC2630 5.3 "signedAttributes is a
        * collection...") */

       /* pass contentType here as we want a contentType attribute */
       if ((contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo)) == NULL)
           goto loser;

       /* sign the thing */
       rv = NSS_CMSSignerInfo_Sign(signerinfo, sigd->digests[n], contentType);
       if (rv != SECSuccess)
           goto loser;

       /* while we're at it, count number of certs in certLists */
       certlist = NSS_CMSSignerInfo_GetCertList(signerinfo);
       if (certlist)
           certcount += certlist->len;
    }

    /* this is a SET OF, so we need to sort them guys */
    rv = NSS_CMSArray_SortByDER((void **)signerinfos, NSSCMSSignerInfoTemplate, NULL);
    if (rv != SECSuccess)
       goto loser;

    /*
     * now prepare certs & crls
     */

    /* count the rest of the certs */
    if (sigd->certs != NULL) {
       for (ci = 0; sigd->certs[ci] != NULL; ci++)
           certcount++;
    }

    if (sigd->certLists != NULL) {
       for (cli = 0; sigd->certLists[cli] != NULL; cli++)
           certcount += sigd->certLists[cli]->len;
    }

    if (certcount == 0) {
       sigd->rawCerts = NULL;
    } else {
       /*
        * Combine all of the certs and cert chains into rawcerts.
        * Note: certcount is an upper bound; we may not need that many slots
        * but we will allocate anyway to avoid having to do another pass.
        * (The temporary space saving is not worth it.)
        *
        * XXX ARGH - this NEEDS to be fixed. need to come up with a decent
        *  SetOfDERcertficates implementation
        */
       sigd->rawCerts = (SECItem **)PORT_ArenaAlloc(poolp, (certcount + 1) * sizeof(SECItem *));
       if (sigd->rawCerts == NULL)
           return SECFailure;

       /*
        * XXX Want to check for duplicates and not add *any* cert that is
        * already in the set.  This will be more important when we start
        * dealing with larger sets of certs, dual-key certs (signing and
        * encryption), etc.  For the time being we can slide by...
        *
        * XXX ARGH - this NEEDS to be fixed. need to come up with a decent
        *  SetOfDERcertficates implementation
        */
       rci = 0;
       if (signerinfos != NULL) {
           for (si = 0; signerinfos[si] != NULL; si++) {
              signerinfo = signerinfos[si];
              for (ci = 0; ci < signerinfo->certList->len; ci++)
                  sigd->rawCerts[rci++] = &(signerinfo->certList->certs[ci]);
           }
       }

       if (sigd->certs != NULL) {
           for (ci = 0; sigd->certs[ci] != NULL; ci++)
              sigd->rawCerts[rci++] = &(sigd->certs[ci]->derCert);
       }

       if (sigd->certLists != NULL) {
           for (cli = 0; sigd->certLists[cli] != NULL; cli++) {
              for (ci = 0; ci < sigd->certLists[cli]->len; ci++)
                  sigd->rawCerts[rci++] = &(sigd->certLists[cli]->certs[ci]);
           }
       }

       sigd->rawCerts[rci] = NULL;

       /* this is a SET OF, so we need to sort them guys - we have the DER already, though */
       NSS_CMSArray_Sort((void **)sigd->rawCerts, NSS_CMSUtil_DERCompare, NULL, NULL);
    }

    ret = SECSuccess;

loser:
    return ret;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_Encode_BeforeData ( NSSCMSSignedData *  sigd)

Definition at line 218 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    /* set up the digests */
    if (sigd->digests && sigd->digests[0]) {
       sigd->contentInfo.digcx = NULL; /* don't attempt to make new ones. */
    } else if (sigd->digestAlgorithms != NULL) {
       sigd->contentInfo.digcx = 
               NSS_CMSDigestContext_StartMultiple(sigd->digestAlgorithms);
       if (sigd->contentInfo.digcx == NULL)
           return SECFailure;
    }
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_Encode_BeforeStart ( NSSCMSSignedData *  sigd)

Definition at line 138 of file cmssigdata.c.

{
    NSSCMSSignerInfo *signerinfo;
    SECOidTag digestalgtag;
    SECItem *dummy;
    int version;
    SECStatus rv;
    PRBool haveDigests = PR_FALSE;
    int n, i;
    PLArenaPool *poolp;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    poolp = sigd->cmsg->poolp;

    /* we assume that we have precomputed digests if there is a list of algorithms, and */
    /* a chunk of data for each of those algorithms */
    if (sigd->digestAlgorithms != NULL && sigd->digests != NULL) {
       for (i=0; sigd->digestAlgorithms[i] != NULL; i++) {
           if (sigd->digests[i] == NULL)
              break;
       }
       if (sigd->digestAlgorithms[i] == NULL)    /* reached the end of the array? */
           haveDigests = PR_TRUE;         /* yes: we must have all the digests */
    }
           
    version = NSS_CMS_SIGNED_DATA_VERSION_BASIC;

    /* RFC2630 5.1 "version is the syntax version number..." */
    if (NSS_CMSContentInfo_GetContentTypeTag(&(sigd->contentInfo)) != SEC_OID_PKCS7_DATA)
       version = NSS_CMS_SIGNED_DATA_VERSION_EXT;

    /* prepare all the SignerInfos (there may be none) */
    for (i=0; i < NSS_CMSSignedData_SignerInfoCount(sigd); i++) {
       signerinfo = NSS_CMSSignedData_GetSignerInfo(sigd, i);

       /* RFC2630 5.1 "version is the syntax version number..." */
       if (NSS_CMSSignerInfo_GetVersion(signerinfo) != NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN)
           version = NSS_CMS_SIGNED_DATA_VERSION_EXT;
       
       /* collect digestAlgorithms from SignerInfos */
       /* (we need to know which algorithms we have when the content comes in) */
       /* do not overwrite any existing digestAlgorithms (and digest) */
       digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
       n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);
       if (n < 0 && haveDigests) {
           /* oops, there is a digestalg we do not have a digest for */
           /* but we were supposed to have all the digests already... */
           goto loser;
       } else if (n < 0) {
           /* add the digestAlgorithm & a NULL digest */
           rv = NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, NULL);
           if (rv != SECSuccess)
              goto loser;
       } else {
           /* found it, nothing to do */
       }
    }

    dummy = SEC_ASN1EncodeInteger(poolp, &(sigd->version), (long)version);
    if (dummy == NULL)
       return SECFailure;

    /* this is a SET OF, so we need to sort them guys */
    rv = NSS_CMSArray_SortByDER((void **)sigd->digestAlgorithms, 
                                SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
                            (void **)sigd->digests);
    if (rv != SECSuccess)
       return SECFailure;
    
    return SECSuccess;

loser:
    return SECFailure;
}

Here is the call graph for this function:

SECItem** NSS_CMSSignedData_GetCertificateList ( NSSCMSSignedData *  sigd)

Definition at line 523 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    return sigd->rawCerts;
}

Here is the call graph for this function:

NSSCMSContentInfo* NSS_CMSSignedData_GetContentInfo ( NSSCMSSignedData *  sigd)

Definition at line 510 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    return &(sigd->contentInfo);
}

Here is the call graph for this function:

SECAlgorithmID** NSS_CMSSignedData_GetDigestAlgs ( NSSCMSSignedData *  sigd)

Definition at line 497 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    return sigd->digestAlgorithms;
}

Here is the call graph for this function:

SECItem* NSS_CMSSignedData_GetDigestValue ( NSSCMSSignedData *  sigd,
SECOidTag  digestalgtag 
)

Definition at line 1054 of file cmssigdata.c.

{
    int n;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if (sigd->digestAlgorithms == NULL || sigd->digests == NULL) {
        PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
       return NULL;
    }

    n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);

    return (n < 0) ? NULL : sigd->digests[n];
}

Here is the call graph for this function:

NSSCMSSignerInfo* NSS_CMSSignedData_GetSignerInfo ( NSSCMSSignedData *  sigd,
int  i 
)

Definition at line 484 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    return sigd->signerInfos[i];
}

Here is the call graph for this function:

NSSCMSSignerInfo** NSS_CMSSignedData_GetSignerInfos ( NSSCMSSignedData *  sigd)

Definition at line 464 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }
    return sigd->signerInfos;
}

Here is the call graph for this function:

PRBool NSS_CMSSignedData_HasDigests ( NSSCMSSignedData *  sigd)

Definition at line 746 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return PR_FALSE;
    }
    return (sigd->digests != NULL);
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_ImportCerts ( NSSCMSSignedData *  sigd,
CERTCertDBHandle *  certdb,
SECCertUsage  certusage,
PRBool  keepcerts 
)

Definition at line 533 of file cmssigdata.c.

{
    int certcount;
    CERTCertificate **certArray = NULL;
    CERTCertList *certList = NULL;
    CERTCertListNode *node;
    SECStatus rv;
    SECItem **rawArray;
    int i;
    PRTime now;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    certcount = NSS_CMSArray_Count((void **)sigd->rawCerts);

    /* get the certs in the temp DB */
    rv = CERT_ImportCerts(certdb, certusage, certcount, sigd->rawCerts, 
                      &certArray, PR_FALSE, PR_FALSE, NULL);
    if (rv != SECSuccess) {
       goto loser;
    }

    /* save the certs so they don't get destroyed */
    for (i=0; i < certcount; i++) {
       CERTCertificate *cert = certArray[i];
       if (cert)
            NSS_CMSSignedData_AddTempCertificate(sigd, cert);
    }

    if (!keepcerts) {
       goto done;
    }

    /* build a CertList for filtering */
    certList = CERT_NewCertList();
    if (certList == NULL) {
       rv = SECFailure;
       goto loser;
    }
    for (i=0; i < certcount; i++) {
       CERTCertificate *cert = certArray[i];
       if (cert)
           cert = CERT_DupCertificate(cert);
       if (cert)
           CERT_AddCertToListTail(certList,cert);
    }

    /* filter out the certs we don't want */
    rv = CERT_FilterCertListByUsage(certList,certusage, PR_FALSE);
    if (rv != SECSuccess) {
       goto loser;
    }

    /* go down the remaining list of certs and verify that they have
     * valid chains, then import them.
     */
    now = PR_Now();
    for (node = CERT_LIST_HEAD(certList) ; !CERT_LIST_END(node,certList);
                                          node= CERT_LIST_NEXT(node)) {
       CERTCertificateList *certChain;

       if (CERT_VerifyCert(certdb, node->cert, 
              PR_TRUE, certusage, now, NULL, NULL) != SECSuccess) {
           continue;
       }

       certChain = CERT_CertChainFromCert(node->cert, certusage, PR_FALSE);
       if (!certChain) {
           continue;
       }

       /*
        * CertChain returns an array of SECItems, import expects an array of
        * SECItem pointers. Create the SECItem Pointers from the array of
        * SECItems.
        */
       rawArray = (SECItem **)PORT_Alloc(certChain->len*sizeof (SECItem *));
       if (!rawArray) {
           CERT_DestroyCertificateList(certChain);
           continue;
       }
       for (i=0; i < certChain->len; i++) {
           rawArray[i] = &certChain->certs[i];
       }
       (void )CERT_ImportCerts(certdb, certusage, certChain->len, 
                     rawArray,  NULL, keepcerts, PR_FALSE, NULL);
       PORT_Free(rawArray);
       CERT_DestroyCertificateList(certChain);
    }

    rv = SECSuccess;

    /* XXX CRL handling */

done:
    if (sigd->signerInfos != NULL) {
       /* fill in all signerinfo's certs */
       for (i = 0; sigd->signerInfos[i] != NULL; i++)
           (void)NSS_CMSSignerInfo_GetSigningCertificate(
                                          sigd->signerInfos[i], certdb);
    }

loser:
    /* now free everything */
    if (certArray) {
       CERT_DestroyCertArray(certArray,certcount);
    }
    if (certList) {
       CERT_DestroyCertList(certList);
    }

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_SetDigests ( NSSCMSSignedData *  sigd,
SECAlgorithmID **  digestalgs,
SECItem **  digests 
)

Definition at line 898 of file cmssigdata.c.

{
    int cnt, i, idx;

    if (!sigd || !digestalgs || !digests) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (sigd->digestAlgorithms == NULL) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    /* we assume that the digests array is just not there yet */
    PORT_Assert(sigd->digests == NULL);
    if (sigd->digests != NULL) {
       PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
       return SECFailure;
    }

    /* now allocate one (same size as digestAlgorithms) */
    cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms);
    sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *));
    if (sigd->digests == NULL) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }

    for (i = 0; sigd->digestAlgorithms[i] != NULL; i++) {
       /* try to find the sigd's i'th digest algorithm in the array we passed in */
       idx = NSS_CMSAlgArray_GetIndexByAlgID(digestalgs, sigd->digestAlgorithms[i]);
       if (idx < 0) {
           PORT_SetError(SEC_ERROR_DIGEST_NOT_FOUND);
           return SECFailure;
       }
       if (!digests[idx]) {
           /* We have no digest for this algorithm, probably because it is 
           ** unrecognized or unsupported.  We'll ignore this here.  If this 
           ** digest is needed later, an error will be be generated then.
           */
           continue;
       }

       /* found it - now set it */
       if ((sigd->digests[i] = SECITEM_AllocItem(sigd->cmsg->poolp, NULL, 0)) == NULL ||
           SECITEM_CopyItem(sigd->cmsg->poolp, sigd->digests[i], digests[idx]) != SECSuccess)
       {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           return SECFailure;
       }
    }
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_SetDigestValue ( NSSCMSSignedData *  sigd,
SECOidTag  digestalgtag,
SECItem *  digestdata 
)

Definition at line 956 of file cmssigdata.c.

{
    SECItem *digest = NULL;
    PLArenaPool *poolp;
    void *mark;
    int n, cnt;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    poolp = sigd->cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

   
    if (digestdata) {
        digest = (SECItem *) PORT_ArenaZAlloc(poolp,sizeof(SECItem));

       /* copy digestdata item to arena (in case we have it and are not only making room) */
       if (SECITEM_CopyItem(poolp, digest, digestdata) != SECSuccess)
           goto loser;
    }

    /* now allocate one (same size as digestAlgorithms) */
    if (sigd->digests == NULL) {
        cnt = NSS_CMSArray_Count((void **)sigd->digestAlgorithms);
        sigd->digests = PORT_ArenaZAlloc(sigd->cmsg->poolp, (cnt + 1) * sizeof(SECItem *));
        if (sigd->digests == NULL) {
               PORT_SetError(SEC_ERROR_NO_MEMORY);
               return SECFailure;
        }
    }

    n = -1;
    if (sigd->digestAlgorithms != NULL)
       n = NSS_CMSAlgArray_GetIndexByAlgTag(sigd->digestAlgorithms, digestalgtag);

    /* if not found, add a digest */
    if (n < 0) {
       if (NSS_CMSSignedData_AddDigest(poolp, sigd, digestalgtag, digest) != SECSuccess)
           goto loser;
    } else {
       /* replace NULL pointer with digest item (and leak previous value) */
       sigd->digests[n] = digest;
    }

    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

int NSS_CMSSignedData_SignerInfoCount ( NSSCMSSignedData *  sigd)

Definition at line 474 of file cmssigdata.c.

{
    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return 0;
    }
    return NSS_CMSArray_Count((void **)sigd->signerInfos);
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_VerifyCertsOnly ( NSSCMSSignedData *  sigd,
CERTCertDBHandle *  certdb,
SECCertUsage  usage 
)

Definition at line 707 of file cmssigdata.c.

{
    CERTCertificate *cert;
    SECStatus rv = SECSuccess;
    int i;
    int count;
    PRTime now;

    if (!sigd || !certdb || !sigd->rawCerts) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    count = NSS_CMSArray_Count((void**)sigd->rawCerts);
    now = PR_Now();
    for (i=0; i < count; i++) {
       if (sigd->certs && sigd->certs[i]) {
           cert = CERT_DupCertificate(sigd->certs[i]);
       } else {
           cert = CERT_FindCertByDERCert(certdb, sigd->rawCerts[i]);
           if (!cert) {
              rv = SECFailure;
              break;
           }
       }
       rv |= CERT_VerifyCert(certdb, cert, PR_TRUE, usage, now, 
                              NULL, NULL);
       CERT_DestroyCertificate(cert);
    }

    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignedData_VerifySignerInfo ( NSSCMSSignedData *  sigd,
int  i,
CERTCertDBHandle *  certdb,
SECCertUsage  certusage 
)

Definition at line 666 of file cmssigdata.c.

{
    NSSCMSSignerInfo *signerinfo;
    NSSCMSContentInfo *cinfo;
    SECOidData *algiddata;
    SECItem *contentType, *digest;
    SECOidTag oidTag;
    SECStatus rv;

    if (!sigd) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    cinfo = &(sigd->contentInfo);

    signerinfo = sigd->signerInfos[i];

    /* verify certificate */
    rv = NSS_CMSSignerInfo_VerifyCertificate(signerinfo, certdb, certusage);
    if (rv != SECSuccess)
       return rv; /* error is set */

    /* find digest and contentType for signerinfo */
    algiddata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
    oidTag = algiddata ? algiddata->offset : SEC_OID_UNKNOWN;
    digest = NSS_CMSSignedData_GetDigestValue(sigd, oidTag);
    /* NULL digest is acceptable. */
    contentType = NSS_CMSContentInfo_GetContentTypeOID(cinfo);
    /* NULL contentType is acceptable. */

    /* now verify signature */
    rv = NSS_CMSSignerInfo_Verify(signerinfo, digest, contentType);
    return rv;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_AddAuthAttr ( NSSCMSSignerInfo *  signerinfo,
NSSCMSAttribute *  attr 
)

Definition at line 698 of file cmssiginfo.c.

{
    return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr);
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_AddCounterSignature ( NSSCMSSignerInfo *  signerinfo,
SECOidTag  digestalg,
CERTCertificate  signingcert 
)

Definition at line 906 of file cmssiginfo.c.

{
    /* XXXX TBD XXXX */
    return SECFailure;
}
SECStatus NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs ( NSSCMSSignerInfo *  signerinfo,
CERTCertificate *  cert,
CERTCertDBHandle *  certdb 
)

Definition at line 855 of file cmssiginfo.c.

{
    NSSCMSAttribute *attr;
    SECItem *smimeekp = NULL;
    void *mark;
    PLArenaPool *poolp;

    /* verify this cert for encryption */
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
       return SECFailure;
    }

    poolp = signerinfo->cmsg->poolp;
    mark = PORT_ArenaMark(poolp);

    smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
    if (smimeekp == NULL)
       goto loser;

    /* create new signing time attribute */
    if (NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
       goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
       goto loser;

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
       goto loser;

    PORT_ArenaUnmark (poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease (poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_AddSigningTime ( NSSCMSSignerInfo *  signerinfo,
PRTime  t 
)

Definition at line 727 of file cmssiginfo.c.

{
    NSSCMSAttribute *attr;
    SECItem stime;
    void *mark;
    PLArenaPool *poolp;

    poolp = signerinfo->cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    /* create new signing time attribute */
    if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
       goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) {
       SECITEM_FreeItem (&stime, PR_FALSE);
       goto loser;
    }

    SECITEM_FreeItem (&stime, PR_FALSE);

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
       goto loser;

    PORT_ArenaUnmark (poolp, mark);

    return SECSuccess;

loser:
    PORT_ArenaRelease (poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_AddSMIMECaps ( NSSCMSSignerInfo *  signerinfo)

Definition at line 769 of file cmssiginfo.c.

{
    NSSCMSAttribute *attr;
    SECItem *smimecaps = NULL;
    void *mark;
    PLArenaPool *poolp;

    poolp = signerinfo->cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    smimecaps = SECITEM_AllocItem(poolp, NULL, 0);
    if (smimecaps == NULL)
       goto loser;

    /* create new signing time attribute */
    if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps,
                         PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess)
       goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)
       goto loser;

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
       goto loser;

    PORT_ArenaUnmark (poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease (poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs ( NSSCMSSignerInfo *  signerinfo,
CERTCertificate *  cert,
CERTCertDBHandle *  certdb 
)

Definition at line 810 of file cmssiginfo.c.

{
    NSSCMSAttribute *attr;
    SECItem *smimeekp = NULL;
    void *mark;
    PLArenaPool *poolp;

    /* verify this cert for encryption */
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
       return SECFailure;
    }

    poolp = signerinfo->cmsg->poolp;
    mark = PORT_ArenaMark(poolp);

    smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
    if (smimeekp == NULL)
       goto loser;

    /* create new signing time attribute */
    if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
       goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
       goto loser;

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
       goto loser;

    PORT_ArenaUnmark (poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease (poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_AddUnauthAttr ( NSSCMSSignerInfo *  signerinfo,
NSSCMSAttribute *  attr 
)

Definition at line 708 of file cmssiginfo.c.

{
    return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr);
}

Here is the call graph for this function:

NSSCMSSignerInfo* NSS_CMSSignerInfo_Create ( NSSCMSMessage *  cmsg,
CERTCertificate *  cert,
SECOidTag  digestalgtag 
)

Definition at line 75 of file cmssiginfo.c.

{
    return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_IssuerSN, cert, NULL, NULL, NULL, digestalgtag); 
}

Here is the call graph for this function:

NSSCMSSignerInfo* NSS_CMSSignerInfo_CreateWithSubjKeyID ( NSSCMSMessage *  cmsg,
SECItem *  subjKeyID,
SECKEYPublicKey *  pubKey,
SECKEYPrivateKey *  signingKey,
SECOidTag  digestalgtag 
)

Definition at line 68 of file cmssiginfo.c.

{
    return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_SubjectKeyID, NULL, subjKeyID, pubKey, signingKey, digestalgtag); 
}

Here is the call graph for this function:

void NSS_CMSSignerInfo_Destroy ( NSSCMSSignerInfo *  si)

Definition at line 153 of file cmssiginfo.c.

{
    if (si->cert != NULL)
       CERT_DestroyCertificate(si->cert);

    if (si->certList != NULL) 
       CERT_DestroyCertificateList(si->certList);

    /* XXX storage ??? */
}

Here is the call graph for this function:

CERTCertificateList* NSS_CMSSignerInfo_GetCertList ( NSSCMSSignerInfo *  signerinfo)

Definition at line 557 of file cmssiginfo.c.

{
    return signerinfo->certList;
}
SECOidData* NSS_CMSSignerInfo_GetDigestAlg ( NSSCMSSignerInfo *  signerinfo)

Definition at line 534 of file cmssiginfo.c.

{
    return SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
}

Here is the call graph for this function:

SECOidTag NSS_CMSSignerInfo_GetDigestAlgTag ( NSSCMSSignerInfo *  signerinfo)

Definition at line 540 of file cmssiginfo.c.

{
    SECOidData *algdata;

    if (!signerinfo) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SEC_OID_UNKNOWN;
    }

    algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
    if (algdata != NULL)
       return algdata->offset;
    else
       return SEC_OID_UNKNOWN;
}

Here is the call graph for this function:

char* NSS_CMSSignerInfo_GetSignerCommonName ( NSSCMSSignerInfo *  sinfo)

Definition at line 660 of file cmssiginfo.c.

{
    CERTCertificate *signercert;

    /* will fail if cert is not verified */
    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
       return NULL;

    return (CERT_GetCommonName(&signercert->subject));
}

Here is the call graph for this function:

char* NSS_CMSSignerInfo_GetSignerEmailAddress ( NSSCMSSignerInfo *  sinfo)

Definition at line 680 of file cmssiginfo.c.

{
    CERTCertificate *signercert;

    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
       return NULL;

    if (!signercert->emailAddr || !signercert->emailAddr[0])
       return NULL;

    return (PORT_Strdup(signercert->emailAddr));
}

Here is the call graph for this function:

CERTCertificate* NSS_CMSSignerInfo_GetSigningCertificate ( NSSCMSSignerInfo *  signerinfo,
CERTCertDBHandle *  certdb 
)

Definition at line 614 of file cmssiginfo.c.

{
    CERTCertificate *cert;
    NSSCMSSignerIdentifier *sid;

    if (signerinfo->cert != NULL)
       return signerinfo->cert;

    /* no certdb, and cert hasn't been set yet? */
    if (certdb == NULL)
       return NULL;

    /*
     * This cert will also need to be freed, but since we save it
     * in signerinfo for later, we do not want to destroy it when
     * we leave this function -- we let the clean-up of the entire
     * cinfo structure later do the destroy of this cert.
     */
    sid = &signerinfo->signerIdentifier;
    switch (sid->identifierType) {
    case NSSCMSSignerID_IssuerSN:
       cert = CERT_FindCertByIssuerAndSN(certdb, sid->id.issuerAndSN);
       break;
    case NSSCMSSignerID_SubjectKeyID:
       cert = CERT_FindCertBySubjectKeyID(certdb, sid->id.subjectKeyID);
       break;
    default:
       cert = NULL;
       break;
    }

    /* cert can be NULL at that point */
    signerinfo->cert = cert;       /* earmark it */

    return cert;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_GetSigningTime ( NSSCMSSignerInfo *  sinfo,
PRTime stime 
)

Definition at line 585 of file cmssiginfo.c.

{
    NSSCMSAttribute *attr;
    SECItem *value;

    if (sinfo == NULL)
       return SECFailure;

    if (sinfo->signingTime != 0) {
       *stime = sinfo->signingTime;       /* cached copy */
       return SECSuccess;
    }

    attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr, SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
    /* XXXX multi-valued attributes NIH */
    if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL)
       return SECFailure;
    if (DER_DecodeTimeChoice(stime, value) != SECSuccess)
       return SECFailure;
    sinfo->signingTime = *stime;   /* make cached copy */
    return SECSuccess;
}

Here is the call graph for this function:

Definition at line 528 of file cmssiginfo.c.

{
    return signerinfo->verificationStatus;
}
int NSS_CMSSignerInfo_GetVersion ( NSSCMSSignerInfo *  signerinfo)

Definition at line 563 of file cmssiginfo.c.

{
    unsigned long version;

    /* always take apart the SECItem */
    if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess)
       return 0;
    else
       return (int)version;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_IncludeCerts ( NSSCMSSignerInfo *  signerinfo,
NSSCMSCertChainMode  cm,
SECCertUsage  usage 
)

Definition at line 1009 of file cmssiginfo.c.

{
    if (signerinfo->cert == NULL)
       return SECFailure;

    /* don't leak if we get called twice */
    if (signerinfo->certList != NULL) {
       CERT_DestroyCertificateList(signerinfo->certList);
       signerinfo->certList = NULL;
    }

    switch (cm) {
    case NSSCMSCM_None:
       signerinfo->certList = NULL;
       break;
    case NSSCMSCM_CertOnly:
       signerinfo->certList = CERT_CertListFromCert(signerinfo->cert);
       break;
    case NSSCMSCM_CertChain:
       signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE);
       break;
    case NSSCMSCM_CertChainWithRoot:
       signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE);
       break;
    }

    if (cm != NSSCMSCM_None && signerinfo->certList == NULL)
       return SECFailure;
    
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_Sign ( NSSCMSSignerInfo *  signerinfo,
SECItem *  digest,
SECItem *  contentType 
)

Definition at line 169 of file cmssiginfo.c.

{
    CERTCertificate *cert;
    SECKEYPrivateKey *privkey = NULL;
    SECOidTag digestalgtag;
    SECOidTag pubkAlgTag;
    SECItem signature = { 0 };
    SECStatus rv;
    PLArenaPool *poolp, *tmppoolp;
    SECAlgorithmID *algID, freeAlgID;
    CERTSubjectPublicKeyInfo *spki;

    PORT_Assert (digest != NULL);

    poolp = signerinfo->cmsg->poolp;

    switch (signerinfo->signerIdentifier.identifierType) {
    case NSSCMSSignerID_IssuerSN:
        cert = signerinfo->cert;

        if ((privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg)) == NULL)
           goto loser;
        algID = &cert->subjectPublicKeyInfo.algorithm;
        break;
    case NSSCMSSignerID_SubjectKeyID:
        privkey = signerinfo->signingKey;
        signerinfo->signingKey = NULL;
        spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey);
        SECKEY_DestroyPublicKey(signerinfo->pubKey);
        signerinfo->pubKey = NULL;
        SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm);
        SECKEY_DestroySubjectPublicKeyInfo(spki); 
        algID = &freeAlgID;
        break;
    default:
        goto loser;
    }
    digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
    /*
     * XXX I think there should be a cert-level interface for this,
     * so that I do not have to know about subjectPublicKeyInfo...
     */
    pubkAlgTag = SECOID_GetAlgorithmTag(algID);
    if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) {
      SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
    }

    /* Fortezza MISSI have weird signature formats.  
     * Map them to standard DSA formats 
     */
    pubkAlgTag = PK11_FortezzaMapSig(pubkAlgTag);

    if (signerinfo->authAttr != NULL) {
       SECOidTag signAlgTag;
       SECItem encoded_attrs;

       /* find and fill in the message digest attribute. */
       rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), 
                              SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE);
       if (rv != SECSuccess)
           goto loser;

       if (contentType != NULL) {
           /* if the caller wants us to, find and fill in the content type attribute. */
           rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr), 
                           SEC_OID_PKCS9_CONTENT_TYPE, contentType, PR_FALSE);
           if (rv != SECSuccess)
              goto loser;
       }

       if ((tmppoolp = PORT_NewArena (1024)) == NULL) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }

       /*
        * Before encoding, reorder the attributes so that when they
        * are encoded, they will be conforming DER, which is required
        * to have a specific order and that is what must be used for
        * the hash/signature.  We do this here, rather than building
        * it into EncodeAttributes, because we do not want to do
        * such reordering on incoming messages (which also uses
        * EncodeAttributes) or our old signatures (and other "broken"
        * implementations) will not verify.  So, we want to guarantee
        * that we send out good DER encodings of attributes, but not
        * to expect to receive them.
        */
       if (NSS_CMSAttributeArray_Reorder(signerinfo->authAttr) != SECSuccess)
           goto loser;

       encoded_attrs.data = NULL;
       encoded_attrs.len = 0;
       if (NSS_CMSAttributeArray_Encode(tmppoolp, &(signerinfo->authAttr), 
                       &encoded_attrs) == NULL)
           goto loser;

       signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag);
       rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len, 
                         privkey, signAlgTag);
       PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
    } else {
       rv = SGN_Digest(privkey, digestalgtag, &signature, digest);
    }
    SECKEY_DestroyPrivateKey(privkey);
    privkey = NULL;

    if (rv != SECSuccess)
       goto loser;

    if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature) 
          != SECSuccess)
       goto loser;

    SECITEM_FreeItem(&signature, PR_FALSE);

    if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag, 
                              NULL) != SECSuccess)
       goto loser;

    return SECSuccess;

loser:
    if (signature.len != 0)
       SECITEM_FreeItem (&signature, PR_FALSE);
    if (privkey)
       SECKEY_DestroyPrivateKey(privkey);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_Verify ( NSSCMSSignerInfo *  signerinfo,
SECItem *  digest,
SECItem *  contentType 
)

Definition at line 341 of file cmssiginfo.c.

{
    SECKEYPublicKey *publickey = NULL;
    NSSCMSAttribute *attr;
    SECItem encoded_attrs;
    CERTCertificate *cert;
    NSSCMSVerificationStatus vs = NSSCMSVS_Unverified;
    PLArenaPool *poolp;
    SECOidTag    digestalgtag;
    SECOidTag    pubkAlgTag;
    SECOidTag    signAlgTag;

    if (signerinfo == NULL)
       return SECFailure;

    /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL 
    ** and cert has not been verified 
    */
    cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL);
    if (cert == NULL) {
       vs = NSSCMSVS_SigningCertNotFound;
       goto loser;
    }

    if ((publickey = CERT_ExtractPublicKey(cert)) == NULL) {
       vs = NSSCMSVS_ProcessingError;
       goto loser;
    }

    digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);

    /*
     * XXX This may not be the right set of algorithms to check.
     * I'd prefer to trust that just calling VFY_Verify{Data,Digest}
     * would do the right thing (and set an error if it could not);
     * then additional algorithms could be handled by that code
     * and we would Just Work.  So this check should just be removed,
     * but not until the VFY code is better at setting errors.
     */
    pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
    switch (pubkAlgTag) {
    case SEC_OID_PKCS1_RSA_ENCRYPTION:
    case SEC_OID_ANSIX9_DSA_SIGNATURE:
    case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST:
    case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
    case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
#ifdef NSS_ECC_MORE_THAN_SUITE_B
    case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
#endif
       /* ok */
       break;
    case SEC_OID_UNKNOWN:
       vs = NSSCMSVS_SignatureAlgorithmUnknown;
       goto loser;
    default:
       vs = NSSCMSVS_SignatureAlgorithmUnsupported;
       goto loser;
    }

    signAlgTag = NSS_CMSUtil_MakeSignatureAlgorithm(digestalgtag, pubkAlgTag);

    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
       if (contentType) {
           /*
            * Check content type
            *
            * RFC2630 sez that if there are any authenticated attributes,
            * then there must be one for content type which matches the
            * content type of the content being signed, and there must
            * be one for message digest which matches our message digest.
            * So check these things first.
            */
           attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                   SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
           if (attr == NULL) {
              vs = NSSCMSVS_MalformedSignature;
              goto loser;
           }
              
           if (NSS_CMSAttribute_CompareValue(attr, contentType) == PR_FALSE) {
              vs = NSSCMSVS_MalformedSignature;
              goto loser;
           }
       }

       /*
        * Check digest
        */
       attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, 
                                     SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE);
       if (attr == NULL) {
           vs = NSSCMSVS_MalformedSignature;
           goto loser;
       }
       if (!digest || 
           NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) {
           vs = NSSCMSVS_DigestMismatch;
           goto loser;
       }

       if ((poolp = PORT_NewArena (1024)) == NULL) {
           vs = NSSCMSVS_ProcessingError;
           goto loser;
       }

       /*
        * Check signature
        *
        * The signature is based on a digest of the DER-encoded authenticated
        * attributes.  So, first we encode and then we digest/verify.
        * we trust the decoder to have the attributes in the right (sorted) 
        * order
        */
       encoded_attrs.data = NULL;
       encoded_attrs.len = 0;

       if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr), 
                                        &encoded_attrs) == NULL ||
              encoded_attrs.data == NULL || encoded_attrs.len == 0) {
           vs = NSSCMSVS_ProcessingError;
           goto loser;
       }

       vs = (VFY_VerifyData (encoded_attrs.data, encoded_attrs.len,
                     publickey, &(signerinfo->encDigest), signAlgTag,
                     signerinfo->cmsg->pwfn_arg) != SECSuccess) 
                     ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;

       PORT_FreeArena(poolp, PR_FALSE);  /* awkward memory management :-( */

    } else {
       SECItem *sig;

       /* No authenticated attributes. 
       ** The signature is based on the plain message digest. 
       */
       sig = &(signerinfo->encDigest);
       if (sig->len == 0)
           goto loser;

       vs = (!digest || 
             VFY_VerifyDigest(digest, publickey, sig, signAlgTag,
                     signerinfo->cmsg->pwfn_arg) != SECSuccess) 
                     ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
    }

    if (vs == NSSCMSVS_BadSignature) {
       /*
        * XXX Change the generic error into our specific one, because
        * in that case we get a better explanation out of the Security
        * Advisor.  This is really a bug in our error strings (the
        * "generic" error has a lousy/wrong message associated with it
        * which assumes the signature verification was done for the
        * purposes of checking the issuer signature on a certificate)
        * but this is at least an easy workaround and/or in the
        * Security Advisor, which specifically checks for the error
        * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation
        * in that case but does not similarly check for
        * SEC_ERROR_BAD_SIGNATURE.  It probably should, but then would
        * probably say the wrong thing in the case that it *was* the
        * certificate signature check that failed during the cert
        * verification done above.  Our error handling is really a mess.
        */
       if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE)
           PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
    }

    if (publickey != NULL)
       SECKEY_DestroyPublicKey (publickey);

    signerinfo->verificationStatus = vs;

    return (vs == NSSCMSVS_GoodSignature) ? SECSuccess : SECFailure;

loser:
    if (publickey != NULL)
       SECKEY_DestroyPublicKey (publickey);

    signerinfo->verificationStatus = vs;

    PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
    return SECFailure;
}

Here is the call graph for this function:

SECStatus NSS_CMSSignerInfo_VerifyCertificate ( NSSCMSSignerInfo *  signerinfo,
CERTCertDBHandle *  certdb,
SECCertUsage  certusage 
)

Definition at line 299 of file cmssiginfo.c.

{
    CERTCertificate *cert;
    int64 stime;

    if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb)) == NULL) {
       signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
       return SECFailure;
    }

    /*
     * Get and convert the signing time; if available, it will be used
     * both on the cert verification and for importing the sender
     * email profile.
     */
    if (NSS_CMSSignerInfo_GetSigningTime (signerinfo, &stime) != SECSuccess)
       stime = PR_Now(); /* not found or conversion failed, so check against now */
    
    /*
     * XXX  This uses the signing time, if available.  Additionally, we
     * might want to, if there is no signing time, get the message time
     * from the mail header itself, and use that.  That would require
     * a change to our interface though, and for S/MIME callers to pass
     * in a time (and for non-S/MIME callers to pass in nothing, or
     * maybe make them pass in the current time, always?).
     */
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime, 
                        signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
       signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
       return SECFailure;
    }
    return SECSuccess;
}

Here is the call graph for this function:

int NSS_CMSUtil_DERCompare ( void a,
void b 
)

Definition at line 115 of file cmsutil.c.

{
    SECItem *der1 = (SECItem *)a;
    SECItem *der2 = (SECItem *)b;
    unsigned int j;

    /*
     * Find the lowest (lexigraphically) encoding.  One that is
     * shorter than all the rest is known to be "less" because each
     * attribute is of the same type (a SEQUENCE) and so thus the
     * first octet of each is the same, and the second octet is
     * the length (or the length of the length with the high bit
     * set, followed by the length, which also works out to always
     * order the shorter first).  Two (or more) that have the
     * same length need to be compared byte by byte until a mismatch
     * is found.
     */
    if (der1->len != der2->len)
       return (der1->len < der2->len) ? -1 : 1;

    for (j = 0; j < der1->len; j++) {
       if (der1->data[j] == der2->data[j])
           continue;
       return (der1->data[j] < der2->data[j]) ? -1 : 1;
    }
    return 0;
}
const SECHashObject* NSS_CMSUtil_GetHashObjByAlgID ( SECAlgorithmID *  algid)

Definition at line 217 of file cmsutil.c.

{
    SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm));
    const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag);

    return digobj;
}

Here is the call graph for this function:

Definition at line 310 of file cmsutil.c.

{
    size_t size;

    switch (type) {
    case SEC_OID_PKCS7_SIGNED_DATA:
       size = sizeof(NSSCMSSignedData);
       break;
    case SEC_OID_PKCS7_ENVELOPED_DATA:
       size = sizeof(NSSCMSEnvelopedData);
       break;
    case SEC_OID_PKCS7_ENCRYPTED_DATA:
       size = sizeof(NSSCMSEncryptedData);
       break;
    case SEC_OID_PKCS7_DIGESTED_DATA:
       size = sizeof(NSSCMSDigestedData);
       break;
    default:
    case SEC_OID_PKCS7_DATA:
       size = 0;
       break;
    }
    return size;
}

Definition at line 280 of file cmsutil.c.

Definition at line 364 of file cmsutil.c.

{
    switch (vs) {
    case NSSCMSVS_Unverified:                    return "Unverified";
    case NSSCMSVS_GoodSignature:          return "GoodSignature";
    case NSSCMSVS_BadSignature:                  return "BadSignature";
    case NSSCMSVS_DigestMismatch:         return "DigestMismatch";
    case NSSCMSVS_SigningCertNotFound:           return "SigningCertNotFound";
    case NSSCMSVS_SigningCertNotTrusted:  return "SigningCertNotTrusted";
    case NSSCMSVS_SignatureAlgorithmUnknown:     return "SignatureAlgorithmUnknown";
    case NSSCMSVS_SignatureAlgorithmUnsupported: return "SignatureAlgorithmUnsupported";
    case NSSCMSVS_MalformedSignature:            return "MalformedSignature";
    case NSSCMSVS_ProcessingError:        return "ProcessingError";
    default:                              return "Unknown";
    }
}
SECStatus NSS_SMIMESignerInfo_SaveSMIMEProfile ( NSSCMSSignerInfo *  signerinfo)

Definition at line 918 of file cmssiginfo.c.

{
    CERTCertificate *cert = NULL;
    SECItem *profile = NULL;
    NSSCMSAttribute *attr;
    SECItem *stime = NULL;
    SECItem *ekp;
    CERTCertDBHandle *certdb;
    int save_error;
    SECStatus rv;
    PRBool must_free_cert = PR_FALSE;

    certdb = CERT_GetDefaultCertDB();

    /* sanity check - see if verification status is ok (unverified does not count...) */
    if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)
       return SECFailure;

    /* find preferred encryption cert */
    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) &&
       (attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                            SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL)
    { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */
       ekp = NSS_CMSAttribute_GetValue(attr);
       if (ekp == NULL)
           return SECFailure;

       /* we assume that all certs coming with the message have been imported to the */
       /* temporary database */
       cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp);
       if (cert == NULL)
           return SECFailure;
       must_free_cert = PR_TRUE;
    }

    if (cert == NULL) {
       /* no preferred cert found?
        * find the cert the signerinfo is signed with instead */
       cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb);
       if (cert == NULL || cert->emailAddr == NULL || !cert->emailAddr[0])
           return SECFailure;
    }

    /* verify this cert for encryption (has been verified for signing so far) */
    /* don't verify this cert for encryption. It may just be a signing cert.
     * that's OK, we can still save the S/MIME profile. The encryption cert
     * should have already been saved */
#ifdef notdef
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
       if (must_free_cert)
           CERT_DestroyCertificate(cert);
       return SECFailure;
    }
#endif

    /* XXX store encryption cert permanently? */

    /*
     * Remember the current error set because we do not care about
     * anything set by the functions we are about to call.
     */
    save_error = PORT_GetError();

    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
       attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                   SEC_OID_PKCS9_SMIME_CAPABILITIES,
                                   PR_TRUE);
       profile = NSS_CMSAttribute_GetValue(attr);
       attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                   SEC_OID_PKCS9_SIGNING_TIME,
                                   PR_TRUE);
       stime = NSS_CMSAttribute_GetValue(attr);
    }

    rv = CERT_SaveSMimeProfile (cert, profile, stime);
    if (must_free_cert)
       CERT_DestroyCertificate(cert);

    /*
     * Restore the saved error in case the calls above set a new
     * one that we do not actually care about.
     */
    PORT_SetError (save_error);

    return rv;
}

Here is the call graph for this function: