Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions
p12.h File Reference
#include "secoid.h"
#include "key.h"
#include "secpkcs7.h"
#include "p12t.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  sec_PKCS12PasswordModeInfo
struct  sec_PKCS12PublicKeyModeInfo
struct  SEC_PKCS12DecoderItemStr

Typedefs

typedef int(PR_CALLBACKPKCS12OpenFunction )(void *arg)
typedef int(PR_CALLBACKPKCS12ReadFunction )(void *arg, unsigned char *buffer, unsigned int *lenRead, unsigned int maxLen)
typedef int(PR_CALLBACKPKCS12WriteFunction )(void *arg, unsigned char *buffer, unsigned int *bufLen, unsigned int *lenWritten)
typedef int(PR_CALLBACKPKCS12CloseFunction )(void *arg)
typedef SECStatus(PR_CALLBACKPKCS12UnicodeConvertFunction )(PRArenaPool *arena, SECItem *dest, SECItem *src, PRBool toUnicode, PRBool swapBytes)
typedef void(PR_CALLBACKSEC_PKCS12EncoderOutputCallback )(void *arg, const char *buf, unsigned long len)
typedef void(PR_CALLBACKSEC_PKCS12DecoderOutputCallback )(void *arg, const char *buf, unsigned long len)
typedef SECItem *(PR_CALLBACKSEC_PKCS12NicknameCollisionCallback )(SECItem *old_nickname, PRBool *cancel, void *arg)
typedef SECStatus(PR_CALLBACKdigestOpenFn )(void *arg, PRBool readData)
typedef SECStatus(PR_CALLBACKdigestCloseFn )(void *arg, PRBool removeFile)
typedef int(PR_CALLBACKdigestIOFn )(void *arg, unsigned char *buf, unsigned long len)
typedef struct SEC_PKCS12ExportContextStr
typedef struct SEC_PKCS12SafeInfoStr
typedef struct SEC_PKCS12DecoderContextStr
typedef struct SEC_PKCS12DecoderItemStr

Functions

SEC_BEGIN_PROTOS
SEC_PKCS12SafeInfo * 
SEC_PKCS12CreatePubKeyEncryptedSafe (SEC_PKCS12ExportContext *p12ctxt, CERTCertDBHandle *certDb, CERTCertificate *signer, CERTCertificate **recipients, SECOidTag algorithm, int keysize)
SEC_PKCS12SafeInfo * SEC_PKCS12CreatePasswordPrivSafe (SEC_PKCS12ExportContext *p12ctxt, SECItem *pwitem, SECOidTag privAlg)
SEC_PKCS12SafeInfo * SEC_PKCS12CreateUnencryptedSafe (SEC_PKCS12ExportContext *p12ctxt)
SECStatus SEC_PKCS12AddPasswordIntegrity (SEC_PKCS12ExportContext *p12ctxt, SECItem *pwitem, SECOidTag integAlg)
SECStatus SEC_PKCS12AddPublicKeyIntegrity (SEC_PKCS12ExportContext *p12ctxt, CERTCertificate *cert, CERTCertDBHandle *certDb, SECOidTag algorithm, int keySize)
SEC_PKCS12ExportContext * SEC_PKCS12CreateExportContext (SECKEYGetPasswordKey pwfn, void *pwfnarg, PK11SlotInfo *slot, void *wincx)
SECStatus SEC_PKCS12AddCert (SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe, void *nestedDest, CERTCertificate *cert, CERTCertDBHandle *certDb, SECItem *keyId, PRBool includeCertChain)
SECStatus SEC_PKCS12AddKeyForCert (SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe, void *nestedDest, CERTCertificate *cert, PRBool shroudKey, SECOidTag algorithm, SECItem *pwitem, SECItem *keyId, SECItem *nickName)
SECStatus SEC_PKCS12AddCertAndKey (SEC_PKCS12ExportContext *p12ctxt, void *certSafe, void *certNestedDest, CERTCertificate *cert, CERTCertDBHandle *certDb, void *keySafe, void *keyNestedDest, PRBool shroudKey, SECItem *pwitem, SECOidTag algorithm)
SECStatus SEC_PKCS12AddDERCertAndEncryptedKey (SEC_PKCS12ExportContext *p12ctxt, void *certSafe, void *certNestedDest, SECItem *derCert, void *keySafe, void *keyNestedDest, SECKEYEncryptedPrivateKeyInfo *epki, char *nickname)
voidSEC_PKCS12CreateNestedSafeContents (SEC_PKCS12ExportContext *p12ctxt, void *baseSafe, void *nestedDest)
SECStatus SEC_PKCS12Encode (SEC_PKCS12ExportContext *p12exp, SEC_PKCS12EncoderOutputCallback output, void *outputarg)
void SEC_PKCS12DestroyExportContext (SEC_PKCS12ExportContext *p12exp)
SEC_PKCS12DecoderContext * SEC_PKCS12DecoderStart (SECItem *pwitem, PK11SlotInfo *slot, void *wincx, digestOpenFn dOpen, digestCloseFn dClose, digestIOFn dRead, digestIOFn dWrite, void *dArg)
SECStatus SEC_PKCS12DecoderSetTargetTokenCAs (SEC_PKCS12DecoderContext *p12dcx, SECPKCS12TargetTokenCAs tokenCAs)
SECStatus SEC_PKCS12DecoderUpdate (SEC_PKCS12DecoderContext *p12dcx, unsigned char *data, unsigned long len)
void SEC_PKCS12DecoderFinish (SEC_PKCS12DecoderContext *p12dcx)
SECStatus SEC_PKCS12DecoderVerify (SEC_PKCS12DecoderContext *p12dcx)
SECStatus SEC_PKCS12DecoderValidateBags (SEC_PKCS12DecoderContext *p12dcx, SEC_PKCS12NicknameCollisionCallback nicknameCb)
SECStatus SEC_PKCS12DecoderImportBags (SEC_PKCS12DecoderContext *p12dcx)
CERTCertList * SEC_PKCS12DecoderGetCerts (SEC_PKCS12DecoderContext *p12dcx)
SECStatus SEC_PKCS12DecoderIterateInit (SEC_PKCS12DecoderContext *p12dcx)
SECStatus SEC_PKCS12DecoderIterateNext (SEC_PKCS12DecoderContext *p12dcx, const SEC_PKCS12DecoderItem **ipp)

Class Documentation

struct sec_PKCS12PasswordModeInfo

Definition at line 85 of file p12.h.

Class Members
SECOidTag algorithm
SECItem * password
struct sec_PKCS12PublicKeyModeInfo

Definition at line 90 of file p12.h.

Collaboration diagram for sec_PKCS12PublicKeyModeInfo:
Class Members
SECOidTag algorithm
CERTCertificate * cert
CERTCertDBHandle * certDb
int keySize
struct SEC_PKCS12DecoderItemStr

Definition at line 97 of file p12.h.

Class Members
SECItem * der
SECItem * friendlyName
PRBool hasKey
SECOidTag type

Typedef Documentation

typedef SECStatus(PR_CALLBACK * digestCloseFn)(void *arg, PRBool removeFile)

Definition at line 76 of file p12.h.

typedef int(PR_CALLBACK * digestIOFn)(void *arg, unsigned char *buf, unsigned long len)

Definition at line 77 of file p12.h.

typedef SECStatus(PR_CALLBACK * digestOpenFn)(void *arg, PRBool readData)

Definition at line 75 of file p12.h.

Definition at line 55 of file p12.h.

Definition at line 46 of file p12.h.

typedef int(PR_CALLBACK * PKCS12ReadFunction)(void *arg, unsigned char *buffer, unsigned int *lenRead, unsigned int maxLen)

Definition at line 47 of file p12.h.

typedef SECStatus(PR_CALLBACK * PKCS12UnicodeConvertFunction)(PRArenaPool *arena, SECItem *dest, SECItem *src, PRBool toUnicode, PRBool swapBytes)

Definition at line 56 of file p12.h.

typedef int(PR_CALLBACK * PKCS12WriteFunction)(void *arg, unsigned char *buffer, unsigned int *bufLen, unsigned int *lenWritten)

Definition at line 51 of file p12.h.

Definition at line 82 of file p12.h.

typedef struct SEC_PKCS12DecoderItemStr

Definition at line 83 of file p12.h.

Definition at line 64 of file p12.h.

Definition at line 61 of file p12.h.

Definition at line 80 of file p12.h.

typedef SECItem*(PR_CALLBACK * SEC_PKCS12NicknameCollisionCallback)(SECItem *old_nickname, PRBool *cancel, void *arg)

Definition at line 67 of file p12.h.

typedef struct SEC_PKCS12SafeInfoStr

Definition at line 81 of file p12.h.


Function Documentation

SECStatus SEC_PKCS12AddCert ( SEC_PKCS12ExportContext *  p12ctxt,
SEC_PKCS12SafeInfo *  safe,
void nestedDest,
CERTCertificate *  cert,
CERTCertDBHandle *  certDb,
SECItem *  keyId,
PRBool  includeCertChain 
)

Definition at line 1030 of file p12e.c.

{
    sec_PKCS12CertBag *certBag;
    sec_PKCS12SafeBag *safeBag;
    void *mark;
    SECStatus rv;
    SECItem nick = {siBuffer, NULL,0};

    if(!p12ctxt || !cert) {
       return SECFailure;
    }
    mark = PORT_ArenaMark(p12ctxt->arena);

    /* allocate the cert bag */
    certBag = sec_PKCS12NewCertBag(p12ctxt->arena, 
                               SEC_OID_PKCS9_X509_CERT);
    if(!certBag) {
       goto loser;
    }

    if(SECITEM_CopyItem(p12ctxt->arena, &certBag->value.x509Cert, 
                     &cert->derCert) != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* if the cert chain is to be included, we should only be exporting
     * the cert from our internal database.
     */
    if(includeCertChain) {
       CERTCertificateList *certList = CERT_CertChainFromCert(cert,
                                                        certUsageSSLClient,
                                                        PR_TRUE);
       unsigned int count = 0;
       if(!certList) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }

       /* add cert chain */
       for(count = 0; count < (unsigned int)certList->len; count++) {
           if(SECITEM_CompareItem(&certList->certs[count], &cert->derCert)
                            != SECEqual) {
              CERTCertificate *tempCert;

              /* decode the certificate */
              /* XXX
               * This was rather silly.  The chain is constructed above
               * by finding all of the CERTCertificate's in the database.
               * Then the chain is put into a CERTCertificateList, which only
               * contains the DER.  Finally, the DER was decoded, and the
               * decoded cert was sent recursively back to this function.
               * Beyond being inefficent, this causes data loss (specifically,
               * the nickname).  Instead, for 3.4, we'll do a lookup by the
               * DER, which should return the cached entry.
               */
              tempCert = CERT_FindCertByDERCert(CERT_GetDefaultCertDB(),
                                                &certList->certs[count]);
              if(!tempCert) {
                  CERT_DestroyCertificateList(certList);
                  goto loser;
              }

              /* add the certificate */
              if(SEC_PKCS12AddCert(p12ctxt, safe, nestedDest, tempCert,
                             certDb, NULL, PR_FALSE) != SECSuccess) {
                  CERT_DestroyCertificate(tempCert);
                  CERT_DestroyCertificateList(certList);
                  goto loser;
              }
              CERT_DestroyCertificate(tempCert);
           }
       }
       CERT_DestroyCertificateList(certList);
    }

    /* if the certificate has a nickname, we will set the friendly name
     * to that.
     */
    if(cert->nickname) {
        if (cert->slot && !PK11_IsInternal(cert->slot)) {
         /*
          * The cert is coming off of an external token, 
          * let's strip the token name from the nickname
          * and only add what comes after the colon as the
          * nickname. -javi
          */
           char *delimit;
           
           delimit = PORT_Strchr(cert->nickname,':');
           if (delimit == NULL) {
               nick.data = (unsigned char *)cert->nickname;
              nick.len = PORT_Strlen(cert->nickname);
           } else {
               delimit++;
               nick.data = (unsigned char *)PORT_ArenaStrdup(p12ctxt->arena,
                                                       delimit);
              nick.len = PORT_Strlen(delimit);
           }
       } else {
           nick.data = (unsigned char *)cert->nickname;
           nick.len = PORT_Strlen(cert->nickname);
       }
    }

    safeBag = sec_PKCS12CreateSafeBag(p12ctxt, SEC_OID_PKCS12_V1_CERT_BAG_ID, 
                                  certBag);
    if(!safeBag) {
       goto loser;
    }

    /* add the friendly name and keyId attributes, if necessary */
    if(nick.data) {
       if(sec_PKCS12AddAttributeToBag(p12ctxt, safeBag, 
                                   SEC_OID_PKCS9_FRIENDLY_NAME, &nick) 
                                   != SECSuccess) {
           goto loser;
       }
    }
          
    if(keyId) {
       if(sec_PKCS12AddAttributeToBag(p12ctxt, safeBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
                                   keyId) != SECSuccess) {
           goto loser;
       }
    }

    /* append the cert safeBag */
    if(nestedDest) {
       rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena, 
                                     (sec_PKCS12SafeContents*)nestedDest, 
                                      safeBag);
    } else {
       rv = sec_pkcs12_append_bag(p12ctxt, safe, safeBag);
    }

    if(rv != SECSuccess) {
       goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return SECSuccess;

loser:
    if(mark) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
    }

    return SECFailure;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12AddCertAndKey ( SEC_PKCS12ExportContext *  p12ctxt,
void certSafe,
void certNestedDest,
CERTCertificate *  cert,
CERTCertDBHandle *  certDb,
void keySafe,
void keyNestedDest,
PRBool  shroudKey,
SECItem *  pwitem,
SECOidTag  algorithm 
)

Definition at line 1525 of file p12e.c.

{             
    SECStatus rv = SECFailure;
    SGNDigestInfo *digest = NULL;
    void *mark = NULL;

    if(!p12ctxt || !certSafe || !keySafe || !cert) {
       return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    /* generate the thumbprint of the cert to use as a keyId */
    digest = sec_pkcs12_compute_thumbprint(&cert->derCert);
    if(!digest) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
       return SECFailure;
    }

    /* add the certificate */
    rv = SEC_PKCS12AddCert(p12ctxt, (SEC_PKCS12SafeInfo*)certSafe, 
                        (SEC_PKCS12SafeInfo*)certNestedDest, cert, certDb,
                        &digest->digest, PR_TRUE);
    if(rv != SECSuccess) {
       goto loser;
    }

    /* add the key */
    rv = SEC_PKCS12AddKeyForCert(p12ctxt, (SEC_PKCS12SafeInfo*)keySafe, 
                             keyNestedDest, cert, 
                             shroudKey, algorithm, pwitem, 
                             &digest->digest, NULL );
    if(rv != SECSuccess) {
       goto loser;
    }

    SGN_DestroyDigestInfo(digest);

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return SECSuccess;

loser:
    SGN_DestroyDigestInfo(digest);
    PORT_ArenaRelease(p12ctxt->arena, mark);
    
    return SECFailure; 
}

Here is the call graph for this function:

SECStatus SEC_PKCS12AddDERCertAndEncryptedKey ( SEC_PKCS12ExportContext *  p12ctxt,
void certSafe,
void certNestedDest,
SECItem *  derCert,
void keySafe,
void keyNestedDest,
SECKEYEncryptedPrivateKeyInfo *  epki,
char *  nickname 
)

Definition at line 1442 of file p12e.c.

{             
    SECStatus rv = SECFailure;
    SGNDigestInfo *digest = NULL;
    void *mark = NULL;
    CERTCertificate *cert;
    SECItem nick = {siBuffer, NULL,0}, *nickPtr = NULL; 

    if(!p12ctxt || !certSafe || !keySafe || !derCert) {
       return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                   derCert, NULL, PR_FALSE, PR_FALSE);
    if(!cert) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }
    cert->nickname = nickname;

    /* generate the thumbprint of the cert to use as a keyId */
    digest = sec_pkcs12_compute_thumbprint(&cert->derCert);
    if(!digest) {
       CERT_DestroyCertificate(cert);
       return SECFailure;
    }

    /* add the certificate */
    rv = SEC_PKCS12AddCert(p12ctxt, (SEC_PKCS12SafeInfo*)certSafe, 
                        certNestedDest, cert, NULL,
                        &digest->digest, PR_FALSE);
    if(rv != SECSuccess) {
       goto loser;
    }

    if(nickname) {
       nick.data = (unsigned char *)nickname;
       nick.len = PORT_Strlen(nickname);
       nickPtr = &nick;
    } else {
       nickPtr = NULL;
    }

    /* add the key */
    rv = SEC_PKCS12AddEncryptedKey(p12ctxt, epki, (SEC_PKCS12SafeInfo*)keySafe,
                               keyNestedDest, &digest->digest, nickPtr );
    if(rv != SECSuccess) {
       goto loser;
    }

    SGN_DestroyDigestInfo(digest);

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return SECSuccess;

loser:
    SGN_DestroyDigestInfo(digest);
    CERT_DestroyCertificate(cert);
    PORT_ArenaRelease(p12ctxt->arena, mark);
    
    return SECFailure; 
}

Here is the call graph for this function:

SECStatus SEC_PKCS12AddKeyForCert ( SEC_PKCS12ExportContext *  p12ctxt,
SEC_PKCS12SafeInfo *  safe,
void nestedDest,
CERTCertificate *  cert,
PRBool  shroudKey,
SECOidTag  algorithm,
SECItem *  pwitem,
SECItem *  keyId,
SECItem *  nickName 
)

Definition at line 1292 of file p12e.c.

{
    void *mark;
    void *keyItem;
    SECOidTag keyType;
    SECStatus rv = SECFailure;
    SECItem nickname = {siBuffer,NULL,0}, uniPwitem = {siBuffer, NULL, 0};
    sec_PKCS12SafeBag *returnBag;

    if(!p12ctxt || !cert || !safe) {
       return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    /* retrieve the key based upon the type that it is and 
     * specify the type of safeBag to store the key in
     */          
    if(!shroudKey) {

       /* extract the key unencrypted.  this will most likely go away */
       SECKEYPrivateKeyInfo *pki = PK11_ExportPrivateKeyInfo(cert, 
                                                       p12ctxt->wincx);
       if(!pki) {
           PORT_ArenaRelease(p12ctxt->arena, mark);
           PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
           return SECFailure;
       }   
       keyItem = PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECKEYPrivateKeyInfo));
       if(!keyItem) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }
       rv = SECKEY_CopyPrivateKeyInfo(p12ctxt->arena, 
                                   (SECKEYPrivateKeyInfo *)keyItem, pki);
       keyType = SEC_OID_PKCS12_V1_KEY_BAG_ID;
       SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
    } else {

       /* extract the key encrypted */
       SECKEYEncryptedPrivateKeyInfo *epki = NULL;
       PK11SlotInfo *slot = NULL;

       if(!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena, &uniPwitem,
                             pwitem, PR_TRUE, PR_TRUE, PR_TRUE)) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }

       /* we want to make sure to take the key out of the key slot */
       if(PK11_IsInternal(p12ctxt->slot)) {
           slot = PK11_GetInternalKeySlot();
       } else {
           slot = PK11_ReferenceSlot(p12ctxt->slot);
       }

       epki = PK11_ExportEncryptedPrivateKeyInfo(slot, algorithm, 
                                            &uniPwitem, cert, 1, 
                                            p12ctxt->wincx);
       PK11_FreeSlot(slot);
       
       keyItem = PORT_ArenaZAlloc(p12ctxt->arena, 
                              sizeof(SECKEYEncryptedPrivateKeyInfo));
       if(!keyItem) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }
       if(!epki) {
           PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY);
           return SECFailure;
       }   
       rv = SECKEY_CopyEncryptedPrivateKeyInfo(p12ctxt->arena, 
                                   (SECKEYEncryptedPrivateKeyInfo *)keyItem,
                                   epki);
       keyType = SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID;
       SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE);
    }

    if(rv != SECSuccess) {
       goto loser;
    }
       
    /* if no nickname specified, let's see if the certificate has a 
     * nickname.
     */                                     
    if(!nickName) {
       if(cert->nickname) {
           nickname.data = (unsigned char *)cert->nickname;
           nickname.len = PORT_Strlen(cert->nickname);
           nickName = &nickname;
       }
    }

    /* create the safe bag and set any attributes */
    returnBag = sec_PKCS12CreateSafeBag(p12ctxt, keyType, keyItem);
    if(!returnBag) {
       rv = SECFailure;
       goto loser;
    }

    if(nickName) {
       if(sec_PKCS12AddAttributeToBag(p12ctxt, returnBag, 
                                   SEC_OID_PKCS9_FRIENDLY_NAME, nickName) 
                                   != SECSuccess) {
           goto loser;
       }
    }
          
    if(keyId) {
       if(sec_PKCS12AddAttributeToBag(p12ctxt, returnBag, SEC_OID_PKCS9_LOCAL_KEY_ID,
                                   keyId) != SECSuccess) {
           goto loser;
       }
    }

    if(nestedDest) {
       rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena,
                                     (sec_PKCS12SafeContents*)nestedDest, 
                                     returnBag);
    } else {
       rv = sec_pkcs12_append_bag(p12ctxt, safe, returnBag);
    }

loser:

    if (rv != SECSuccess) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
    } else {
       PORT_ArenaUnmark(p12ctxt->arena, mark);
    }

    return rv;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12AddPasswordIntegrity ( SEC_PKCS12ExportContext *  p12ctxt,
SECItem *  pwitem,
SECOidTag  integAlg 
)

Definition at line 262 of file p12e.c.

{                           
    if(!p12ctxt || p12ctxt->integrityEnabled) {
       return SECFailure;
    }
   
    /* set up integrity information */
    p12ctxt->pwdIntegrity = PR_TRUE;
    p12ctxt->integrityInfo.pwdInfo.password = 
        (SECItem*)PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECItem));
    if(!p12ctxt->integrityInfo.pwdInfo.password) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }
    if(SECITEM_CopyItem(p12ctxt->arena, 
                     p12ctxt->integrityInfo.pwdInfo.password, pwitem)
              != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }
    p12ctxt->integrityInfo.pwdInfo.algorithm = integAlg;
    p12ctxt->integrityEnabled = PR_TRUE;

    return SECSuccess;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12AddPublicKeyIntegrity ( SEC_PKCS12ExportContext *  p12ctxt,
CERTCertificate *  cert,
CERTCertDBHandle *  certDb,
SECOidTag  algorithm,
int  keySize 
)

Definition at line 301 of file p12e.c.

{
    if(!p12ctxt) {
       return SECFailure;
    }
    
    p12ctxt->integrityInfo.pubkeyInfo.cert = cert;
    p12ctxt->integrityInfo.pubkeyInfo.certDb = certDb;
    p12ctxt->integrityInfo.pubkeyInfo.algorithm = algorithm;
    p12ctxt->integrityInfo.pubkeyInfo.keySize = keySize;
    p12ctxt->integrityEnabled = PR_TRUE;

    return SECSuccess;
}
SEC_PKCS12ExportContext* SEC_PKCS12CreateExportContext ( SECKEYGetPasswordKey  pwfn,
void pwfnarg,
PK11SlotInfo *  slot,
void wincx 
)

Definition at line 210 of file p12e.c.

{
    PRArenaPool *arena = NULL;
    SEC_PKCS12ExportContext *p12ctxt = NULL;

    /* allocate the arena and create the context */
    arena = PORT_NewArena(4096);
    if(!arena) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    p12ctxt = (SEC_PKCS12ExportContext *)PORT_ArenaZAlloc(arena, 
                                   sizeof(SEC_PKCS12ExportContext));
    if(!p12ctxt) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* password callback for key retrieval */
    p12ctxt->pwfn = pwfn;
    p12ctxt->pwfnarg = pwfnarg;

    p12ctxt->integrityEnabled = PR_FALSE;
    p12ctxt->arena = arena;
    p12ctxt->wincx = wincx;
    p12ctxt->slot = (slot) ? PK11_ReferenceSlot(slot) : PK11_GetInternalSlot();

    return p12ctxt;

loser:
    if(arena) {
       PORT_FreeArena(arena, PR_TRUE);
    }

    return NULL;
}

Here is the call graph for this function:

void* SEC_PKCS12CreateNestedSafeContents ( SEC_PKCS12ExportContext *  p12ctxt,
void baseSafe,
void nestedDest 
)

Definition at line 1586 of file p12e.c.

{
    sec_PKCS12SafeContents *newSafe;
    sec_PKCS12SafeBag *safeContentsBag;
    void *mark;
    SECStatus rv;

    if(!p12ctxt || !baseSafe) {
       return NULL;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    newSafe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
    if(!newSafe) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    /* create the safeContents safeBag */
    safeContentsBag = sec_PKCS12CreateSafeBag(p12ctxt, 
                                   SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID,
                                   newSafe);
    if(!safeContentsBag) {
       goto loser;
    }

    /* append the safeContents to the appropriate area */
    if(nestedDest) {
       rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena, 
                                      (sec_PKCS12SafeContents*)nestedDest,
                                      safeContentsBag);
    } else {
       rv = sec_pkcs12_append_bag(p12ctxt, (SEC_PKCS12SafeInfo*)baseSafe, 
                               safeContentsBag);
    }
    if(rv != SECSuccess) {
       goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return newSafe;

loser:
    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

Here is the call graph for this function:

SEC_PKCS12SafeInfo* SEC_PKCS12CreatePasswordPrivSafe ( SEC_PKCS12ExportContext *  p12ctxt,
SECItem *  pwitem,
SECOidTag  privAlg 
)

Definition at line 390 of file p12e.c.

{
    SEC_PKCS12SafeInfo *safeInfo = NULL;
    void *mark = NULL;
    PK11SlotInfo *slot = NULL;
    SECAlgorithmID *algId;
    SECItem uniPwitem = {siBuffer, NULL, 0};

    if(!p12ctxt) {
       return NULL;
    }

    /* allocate the safe info */
    mark = PORT_ArenaMark(p12ctxt->arena);
    safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena, 
                                          sizeof(SEC_PKCS12SafeInfo));
    if(!safeInfo) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       PORT_ArenaRelease(p12ctxt->arena, mark);
       return NULL;
    }

    safeInfo->itemCount = 0;

    /* create the encrypted safe */
    safeInfo->cinfo = SEC_PKCS7CreateEncryptedData(privAlg, 0, p12ctxt->pwfn, 
                                             p12ctxt->pwfnarg);
    if(!safeInfo->cinfo) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
    safeInfo->arena = p12ctxt->arena;

    /* convert the password to unicode */ 
    if(!sec_pkcs12_convert_item_to_unicode(NULL, &uniPwitem, pwitem,
                                          PR_TRUE, PR_TRUE, PR_TRUE)) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
    if(SECITEM_CopyItem(p12ctxt->arena, &safeInfo->pwitem, &uniPwitem) != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* generate the encryption key */
    slot = PK11_ReferenceSlot(p12ctxt->slot);
    if(!slot) {
       slot = PK11_GetInternalKeySlot();
       if(!slot) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }
    }

    algId = SEC_PKCS7GetEncryptionAlgorithm(safeInfo->cinfo);
    safeInfo->encryptionKey = PK11_PBEKeyGen(slot, algId, &uniPwitem, 
                                        PR_FALSE, p12ctxt->wincx);
    if(!safeInfo->encryptionKey) {
       goto loser;
    }

    safeInfo->arena = p12ctxt->arena;
    safeInfo->safe = NULL;
    if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
       goto loser;
    }

    if(uniPwitem.data) {
       SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
    }
    PORT_ArenaUnmark(p12ctxt->arena, mark);

    if (slot) {
       PK11_FreeSlot(slot);
    }
    return safeInfo;

loser:
    if (slot) {
       PK11_FreeSlot(slot);
    }
    if(safeInfo->cinfo) {
       SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
    }

    if(uniPwitem.data) {
       SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
    }

    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

Here is the call graph for this function:

SEC_BEGIN_PROTOS SEC_PKCS12SafeInfo* SEC_PKCS12CreatePubKeyEncryptedSafe ( SEC_PKCS12ExportContext *  p12ctxt,
CERTCertDBHandle *  certDb,
CERTCertificate *  signer,
CERTCertificate **  recipients,
SECOidTag  algorithm,
int  keysize 
)

Definition at line 545 of file p12e.c.

{
    SEC_PKCS12SafeInfo *safeInfo = NULL;
    void *mark = NULL;

    if(!p12ctxt || !signer || !recipients || !(*recipients)) {
       return NULL;
    }

    /* allocate the safeInfo */
    mark = PORT_ArenaMark(p12ctxt->arena);
    safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena, 
                                                sizeof(SEC_PKCS12SafeInfo));
    if(!safeInfo) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    safeInfo->itemCount = 0;
    safeInfo->arena = p12ctxt->arena;

    /* create the enveloped content info using certUsageEmailSigner currently.
     * XXX We need to eventually use something other than certUsageEmailSigner
     */
    safeInfo->cinfo = SEC_PKCS7CreateEnvelopedData(signer, certUsageEmailSigner,
                                   certDb, algorithm, keysize, 
                                   p12ctxt->pwfn, p12ctxt->pwfnarg);
    if(!safeInfo->cinfo) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* add recipients */
    if(recipients) {
       unsigned int i = 0;
       while(recipients[i] != NULL) {
           SECStatus rv = SEC_PKCS7AddRecipient(safeInfo->cinfo, recipients[i],
                                          certUsageEmailRecipient, certDb);
           if(rv != SECSuccess) {
              goto loser;
           }
           i++;
       }
    }

    if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
       goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return safeInfo;

loser:
    if(safeInfo->cinfo) {
       SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
       safeInfo->cinfo = NULL;
    }

    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
} 

Here is the call graph for this function:

SEC_PKCS12SafeInfo* SEC_PKCS12CreateUnencryptedSafe ( SEC_PKCS12ExportContext *  p12ctxt)

Definition at line 490 of file p12e.c.

{
    SEC_PKCS12SafeInfo *safeInfo = NULL;
    void *mark = NULL;

    if(!p12ctxt) {
       return NULL;
    }

    /* create the safe info */
    mark = PORT_ArenaMark(p12ctxt->arena);
    safeInfo = (SEC_PKCS12SafeInfo *)PORT_ArenaZAlloc(p12ctxt->arena, 
                                         sizeof(SEC_PKCS12SafeInfo));
    if(!safeInfo) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    safeInfo->itemCount = 0;

    /* create the safe content */
    safeInfo->cinfo = SEC_PKCS7CreateData();
    if(!safeInfo->cinfo) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    if(sec_pkcs12_append_safe_info(p12ctxt, safeInfo) != SECSuccess) {
       goto loser;
    }

    PORT_ArenaUnmark(p12ctxt->arena, mark);
    return safeInfo;

loser:
    if(safeInfo->cinfo) {
       SEC_PKCS7DestroyContentInfo(safeInfo->cinfo);
    }

    PORT_ArenaRelease(p12ctxt->arena, mark);
    return NULL;
}

Here is the call graph for this function:

void SEC_PKCS12DecoderFinish ( SEC_PKCS12DecoderContext *  p12dcx)

Definition at line 1507 of file p12d.c.

{
    if(!p12dcx) {
       return;
    }

    if(p12dcx->pfxDcx) {
       SEC_ASN1DecoderFinish(p12dcx->pfxDcx);
       p12dcx->pfxDcx = NULL;
    }

    if(p12dcx->aSafeDcx) {
       SEC_ASN1DecoderFinish(p12dcx->aSafeDcx);
       p12dcx->aSafeDcx = NULL;
    }

    if(p12dcx->currentASafeP7Dcx) {
       SEC_PKCS7DecoderFinish(p12dcx->currentASafeP7Dcx);
       p12dcx->currentASafeP7Dcx = NULL;
    }

    if(p12dcx->aSafeP7Dcx) {
       SEC_PKCS7DecoderFinish(p12dcx->aSafeP7Dcx);
    }

    if(p12dcx->hmacDcx) {
       SEC_ASN1DecoderFinish(p12dcx->hmacDcx);
       p12dcx->hmacDcx = NULL;
    }
    
    if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE);
    }
    if (p12dcx->decitem.friendlyName != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
    }

    if(p12dcx->slot) {
       PK11_FreeSlot(p12dcx->slot);
       p12dcx->slot = NULL;
    }

    if(p12dcx->arena) {
       PORT_FreeArena(p12dcx->arena, PR_TRUE);
    }
}

Here is the call graph for this function:

CERTCertList* SEC_PKCS12DecoderGetCerts ( SEC_PKCS12DecoderContext *  p12dcx)

Definition at line 2561 of file p12d.c.

{
    CERTCertList *certList = NULL;
    sec_PKCS12SafeBag **safeBags;
    int i;

    if (!p12dcx || !p12dcx->safeBags || !p12dcx->safeBags[0]) {
       return NULL;
    }

    safeBags = p12dcx->safeBags;
    i = 0;
    certList = CERT_NewCertList();

    if (certList == NULL) {
        return NULL;
    }

    while(safeBags[i]) {
       if (SECOID_FindOIDTag(&(safeBags[i]->safeBagType)) 
                            == SEC_OID_PKCS12_V1_CERT_BAG_ID) {
              SECItem *derCert = sec_pkcs12_get_der_cert(safeBags[i]) ;
              CERTCertificate *tempCert = NULL;

              if (derCert == NULL) continue;
              tempCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                               derCert, NULL, 
                                               PR_FALSE, PR_TRUE);

              if (tempCert) {
                  CERT_AddCertToListTail(certList,tempCert);
              }
              SECITEM_FreeItem(derCert,PR_TRUE);
       }
       i++;
    }

    return certList;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderImportBags ( SEC_PKCS12DecoderContext *  p12dcx)

Definition at line 2913 of file p12d.c.

{
    if(!p12dcx || p12dcx->error) {
       return SECFailure;
    }

    if(!p12dcx->bagsVerified) {
       return SECFailure;
    }

    return sec_pkcs12_install_bags(p12dcx->safeBags, p12dcx->wincx);
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderIterateInit ( SEC_PKCS12DecoderContext *  p12dcx)

Definition at line 2981 of file p12d.c.

{
    if(!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    p12dcx->iteration = 0;
    return SECSuccess;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderIterateNext ( SEC_PKCS12DecoderContext *  p12dcx,
const SEC_PKCS12DecoderItem **  ipp 
)

Definition at line 2993 of file p12d.c.

{
    sec_PKCS12SafeBag *bag;
    
    if(!p12dcx || p12dcx->error) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    if (p12dcx->decitem.type != 0 && p12dcx->decitem.der != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.der, PR_TRUE);
    }
    if (p12dcx->decitem.friendlyName != NULL) {
        SECITEM_FreeItem(p12dcx->decitem.friendlyName, PR_TRUE);
    }
    p12dcx->decitem.type = 0;
    p12dcx->decitem.der = NULL;
    p12dcx->decitem.friendlyName = NULL;
    p12dcx->decitem.hasKey = PR_FALSE;
    *ipp = NULL;
    if (p12dcx->keyList == NULL) {
        p12dcx->keyList = sec_pkcs12_get_key_bags(p12dcx->safeBags);
    }

    
    for (; p12dcx->iteration < p12dcx->safeBagCount; p12dcx->iteration++) {
        bag = p12dcx->safeBags[p12dcx->iteration];
       if(bag == NULL || bag->problem) {
            continue;
        }
        p12dcx->decitem.type = SECOID_FindOIDTag(&(bag->safeBagType));
        switch(p12dcx->decitem.type) {
            case SEC_OID_PKCS12_V1_CERT_BAG_ID:
                p12dcx->decitem.der = sec_pkcs12_get_der_cert(bag);
                p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
                p12dcx->decitem.hasKey = sec_pkcs12_bagHasKey(p12dcx, bag);
                break;
            case SEC_OID_PKCS12_V1_KEY_BAG_ID:
            case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
                p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
                break;
            default:
                /* return these even though we don't expect them */
                break;
            case SEC_OID_UNKNOWN:
                /* ignore these */
                continue;
        }
        *ipp = &p12dcx->decitem;
        p12dcx->iteration++;
        break;  /* end for() */
    }
    
    PORT_SetError(0);       /* end-of-list is SECFailure with no PORT error */
    return ((p12dcx->decitem.type == 0) ? SECFailure : SECSuccess);
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderSetTargetTokenCAs ( SEC_PKCS12DecoderContext *  p12dcx,
SECPKCS12TargetTokenCAs  tokenCAs 
)

Definition at line 1255 of file p12d.c.

{
    if (!p12dcx || p12dcx->error) {
       return SECFailure;
    }
    p12dcx->tokenCAs = tokenCAs;
    return SECSuccess;
}
SEC_PKCS12DecoderContext* SEC_PKCS12DecoderStart ( SECItem *  pwitem,
PK11SlotInfo *  slot,
void wincx,
digestOpenFn  dOpen,
digestCloseFn  dClose,
digestIOFn  dRead,
digestIOFn  dWrite,
void dArg 
)

Definition at line 1175 of file p12d.c.

{
    SEC_PKCS12DecoderContext *p12dcx;
    PRArenaPool *arena;

    arena = PORT_NewArena(2048); /* different size? */
    if(!arena) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    /* allocate the decoder context and set the state variables */
    p12dcx = (SEC_PKCS12DecoderContext*)PORT_ArenaZAlloc(arena, sizeof(SEC_PKCS12DecoderContext));
    if(!p12dcx) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    if (!dOpen && !dClose && !dRead && !dWrite && !dArg) {
        /* use default implementations */
        dOpen = p12u_DigestOpen;
        dClose = p12u_DigestClose;
        dRead = p12u_DigestRead;
        dWrite = p12u_DigestWrite;
        dArg = (void*)p12dcx;
    }

    p12dcx->arena = arena;
    p12dcx->pwitem = pwitem;
    p12dcx->slot = (slot ? PK11_ReferenceSlot(slot) 
                                          : PK11_GetInternalKeySlot());
    p12dcx->wincx = wincx;
    p12dcx->tokenCAs = SECPKCS12TargetTokenNoCAs;
#ifdef IS_LITTLE_ENDIAN
    p12dcx->swapUnicodeBytes = PR_TRUE;
#else
    p12dcx->swapUnicodeBytes = PR_FALSE;
#endif
    p12dcx->errorValue = 0;
    p12dcx->error = PR_FALSE;

    /* start the decoding of the PFX and set the notify proc
     * for the PFX item.
     */
    p12dcx->pfxDcx = SEC_ASN1DecoderStart(p12dcx->arena, &p12dcx->pfx,
                                     sec_PKCS12PFXItemTemplate);
    if(!p12dcx->pfxDcx) {
       PORT_SetError(SEC_ERROR_NO_MEMORY); 
       PK11_FreeSlot(p12dcx->slot);
       goto loser;
    }

    SEC_ASN1DecoderSetNotifyProc(p12dcx->pfxDcx, 
                             sec_pkcs12_decoder_pfx_notify_proc,
                             p12dcx); 
    
    /* set up digest functions */
    p12dcx->dOpen = dOpen;
    p12dcx->dWrite = dWrite;
    p12dcx->dClose = dClose;
    p12dcx->dRead = dRead;
    p12dcx->dArg = dArg;
    
    p12dcx->keyList = NULL;
    p12dcx->decitem.type = 0;
    p12dcx->decitem.der = NULL;
    p12dcx->decitem.hasKey = PR_FALSE;
    p12dcx->decitem.friendlyName = NULL;
    p12dcx->iteration = 0;

    return p12dcx;

loser:
    PORT_FreeArena(arena, PR_TRUE);
    return NULL;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderUpdate ( SEC_PKCS12DecoderContext *  p12dcx,
unsigned char *  data,
unsigned long  len 
)

Definition at line 1275 of file p12d.c.

{
    SECStatus rv;

    if(!p12dcx || p12dcx->error) {
       return SECFailure;
    }

    /* update the PFX decoder context */
    rv = SEC_ASN1DecoderUpdate(p12dcx->pfxDcx, (const char *)data, len);
    if(rv != SECSuccess) {
       p12dcx->errorValue = SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE;
       goto loser;
    }

    return SECSuccess;

loser:

    p12dcx->error = PR_TRUE;
    return SECFailure;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderValidateBags ( SEC_PKCS12DecoderContext *  p12dcx,
SEC_PKCS12NicknameCollisionCallback  nicknameCb 
)

Definition at line 2719 of file p12d.c.

{
    SECStatus rv;
    int i, noInstallCnt, probCnt, bagCnt, errorVal = 0;
    if(!p12dcx || p12dcx->error || !p12dcx->safeBags) {
       return SECFailure;
    }

    rv = sec_pkcs12_validate_bags(p12dcx->safeBags, nicknameCb, p12dcx->wincx);
    if(rv == SECSuccess) {
       p12dcx->bagsVerified = PR_TRUE;
    }

    noInstallCnt = probCnt = bagCnt = 0;
    i = 0;
    while(p12dcx->safeBags[i]) {
       bagCnt++;
       if(p12dcx->safeBags[i]->noInstall) noInstallCnt++;
       if(p12dcx->safeBags[i]->problem) {
           probCnt++;
           errorVal = p12dcx->safeBags[i]->error;
       }
       i++;
    }

    if(bagCnt == noInstallCnt) {
       PORT_SetError(SEC_ERROR_PKCS12_DUPLICATE_DATA);
       return SECFailure;
    }

    if(probCnt) {
       PORT_SetError(errorVal);
       return SECFailure;
    }

    return rv;
}

Here is the call graph for this function:

SECStatus SEC_PKCS12DecoderVerify ( SEC_PKCS12DecoderContext *  p12dcx)

Definition at line 1458 of file p12d.c.

{
    SECStatus rv = SECSuccess;

    /* make sure that no errors have occured... */
    if(!p12dcx || p12dcx->error) {
       return SECFailure;
    }

    rv = SEC_ASN1DecoderFinish(p12dcx->pfxDcx);
    p12dcx->pfxDcx = NULL;
    if(rv != SECSuccess) {
       return rv;
    }

    /* check the signature or the mac depending on the type of
     * integrity used.
     */
    if(p12dcx->pfx.encodedMacData.len) {
       rv = SEC_ASN1DecodeItem(p12dcx->arena, &p12dcx->macData,
                            sec_PKCS12MacDataTemplate,
                            &p12dcx->pfx.encodedMacData);
       if(rv == SECSuccess) {
           return sec_pkcs12_decoder_verify_mac(p12dcx);
       } else {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
       }
    } else {
       if(SEC_PKCS7VerifySignature(p12dcx->aSafeCinfo, certUsageEmailSigner,
                                PR_FALSE)) {
           return SECSuccess;
       } else {
           PORT_SetError(SEC_ERROR_PKCS12_INVALID_MAC);
       }
    }

    return SECFailure;
}

Here is the call graph for this function:

void SEC_PKCS12DestroyExportContext ( SEC_PKCS12ExportContext *  p12exp)

Definition at line 2203 of file p12e.c.

{
    int i = 0;

    if(!p12ecx) {
       return;
    }

    if(p12ecx->safeInfos) {
       i = 0;
       while(p12ecx->safeInfos[i] != NULL) {
           if(p12ecx->safeInfos[i]->encryptionKey) {
              PK11_FreeSymKey(p12ecx->safeInfos[i]->encryptionKey);
           }
           if(p12ecx->safeInfos[i]->cinfo) {
              SEC_PKCS7DestroyContentInfo(p12ecx->safeInfos[i]->cinfo);
           }
           i++;
       }
    }

    PK11_FreeSlot(p12ecx->slot);

    PORT_FreeArena(p12ecx->arena, PR_TRUE);
}

Here is the call graph for this function:

SECStatus SEC_PKCS12Encode ( SEC_PKCS12ExportContext *  p12exp,
SEC_PKCS12EncoderOutputCallback  output,
void outputarg 
)

Definition at line 2095 of file p12e.c.

{
    sec_PKCS12EncoderContext *p12enc;
    struct sec_pkcs12_encoder_output outInfo;
    SECStatus rv;

    if(!p12exp || !output) {
       return SECFailure;
    }

    /* get the encoder context */
    p12enc = sec_pkcs12_encoder_start_context(p12exp);
    if(!p12enc) {
       return SECFailure;
    }

    outInfo.outputfn = output;
    outInfo.outputarg = outputarg;

    /* set up PFX encoder, the "outer" encoder.  Set it for streaming */
    p12enc->outerA1ecx = SEC_ASN1EncoderStart(&p12enc->pfx, 
                                       sec_PKCS12PFXItemTemplate,
                                   sec_P12A1OutputCB_Outer, 
                                   &outInfo);
    if(!p12enc->outerA1ecx) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       rv = SECFailure;
       goto loser;
    }
    SEC_ASN1EncoderSetStreaming(p12enc->outerA1ecx);
    SEC_ASN1EncoderSetNotifyProc(p12enc->outerA1ecx, 
                                 sec_pkcs12_encoder_pfx_notify, p12enc);
    rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);
    if(rv != SECSuccess) {
       rv = SECFailure;
       goto loser;
    }

    /* set up asafe cinfo - the output of the encoder feeds the PFX encoder */
    p12enc->middleP7ecx = SEC_PKCS7EncoderStart(p12enc->aSafeCinfo, 
                                   sec_P12P7OutputCB_CallA1Update,
                                   p12enc->outerA1ecx, NULL);
    if(!p12enc->middleP7ecx) {
       rv = SECFailure;
       goto loser;
    }

    /* encode asafe */
    p12enc->middleBuf.p7eCx    = p12enc->middleP7ecx;
    p12enc->middleBuf.hmacCx   = NULL;
    p12enc->middleBuf.numBytes = 0;
    p12enc->middleBuf.bufBytes = sizeof p12enc->middleBuf.buf;

    /* Setup the "inner ASN.1 encoder for Authenticated Safes.  */
    if(p12enc->p12exp->integrityEnabled && 
       p12enc->p12exp->pwdIntegrity) {
       p12enc->middleBuf.hmacCx = p12enc->hmacCx;
    }
    p12enc->middleA1ecx = SEC_ASN1EncoderStart(&p12enc->p12exp->authSafe,
                         sec_PKCS12AuthenticatedSafeTemplate,
                         sec_P12A1OutputCB_HmacP7Update,
                         &p12enc->middleBuf);
    if(!p12enc->middleA1ecx) {
       rv = SECFailure;
       goto loser;
    }
    SEC_ASN1EncoderSetStreaming(p12enc->middleA1ecx);
    SEC_ASN1EncoderSetTakeFromBuf(p12enc->middleA1ecx); 
       
    /* encode each of the safes */                
    while(p12enc->currentSafe != p12enc->p12exp->safeInfoCount) {
       sec_pkcs12_encoder_asafe_process(p12enc);
       p12enc->currentSafe++;
    }
    SEC_ASN1EncoderClearTakeFromBuf(p12enc->middleA1ecx);
    SEC_ASN1EncoderClearStreaming(p12enc->middleA1ecx);
    SEC_ASN1EncoderUpdate(p12enc->middleA1ecx, NULL, 0);
    SEC_ASN1EncoderFinish(p12enc->middleA1ecx);

    sec_FlushPkcs12OutputBuffer( &p12enc->middleBuf);

    /* finish the encoding of the authenticated safes */
    rv = SEC_PKCS7EncoderFinish(p12enc->middleP7ecx, p12exp->pwfn, 
                            p12exp->pwfnarg);
    if(rv != SECSuccess) {
       goto loser;
    }

    SEC_ASN1EncoderClearTakeFromBuf(p12enc->outerA1ecx);
    SEC_ASN1EncoderClearStreaming(p12enc->outerA1ecx);

    /* update the mac, if necessary */
    rv = sec_Pkcs12FinishMac(p12enc);
    if(rv != SECSuccess) {
       goto loser;
    }
   
    /* finish encoding the pfx */ 
    rv = SEC_ASN1EncoderUpdate(p12enc->outerA1ecx, NULL, 0);

    SEC_ASN1EncoderFinish(p12enc->outerA1ecx);

loser:
    return rv;
}

Here is the call graph for this function: