Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions
p12e.c File Reference
#include "nssrenam.h"
#include "p12t.h"
#include "p12.h"
#include "plarena.h"
#include "secitem.h"
#include "secoid.h"
#include "seccomon.h"
#include "secport.h"
#include "cert.h"
#include "secpkcs7.h"
#include "secasn1.h"
#include "secerr.h"
#include "pk11func.h"
#include "p12plcy.h"
#include "p12local.h"
#include "prcpucfg.h"

Go to the source code of this file.

Classes

struct  sec_pkcs12OutputBufferStr
struct  SEC_PKCS12SafeInfoStr
struct  SEC_PKCS12ExportContextStr
struct  sec_pkcs12_encoder_output
struct  sec_pkcs12_hmac_and_output_info
struct  sec_PKCS12EncoderContextStr
struct  inPlaceEncodeInfo
union  SEC_PKCS12ExportContextStr.integrityInfo
union  sec_PKCS12EncoderContextStr.output

Defines

#define PK12_OUTPUT_BUFFER_SIZE   8192

Typedefs

typedef struct sec_pkcs12OutputBufferStr
typedef struct
sec_PKCS12EncoderContextStr 
sec_PKCS12EncoderContext

Functions

SEC_PKCS12ExportContext * SEC_PKCS12CreateExportContext (SECKEYGetPasswordKey pwfn, void *pwfnarg, PK11SlotInfo *slot, void *wincx)
SECStatus SEC_PKCS12AddPasswordIntegrity (SEC_PKCS12ExportContext *p12ctxt, SECItem *pwitem, SECOidTag integAlg)
SECStatus SEC_PKCS12AddPublicKeyIntegrity (SEC_PKCS12ExportContext *p12ctxt, CERTCertificate *cert, CERTCertDBHandle *certDb, SECOidTag algorithm, int keySize)
static SECStatus sec_pkcs12_append_safe_info (SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *info)
SEC_PKCS12SafeInfo * SEC_PKCS12CreatePasswordPrivSafe (SEC_PKCS12ExportContext *p12ctxt, SECItem *pwitem, SECOidTag privAlg)
SEC_PKCS12SafeInfo * SEC_PKCS12CreateUnencryptedSafe (SEC_PKCS12ExportContext *p12ctxt)
SEC_PKCS12SafeInfo * SEC_PKCS12CreatePubKeyEncryptedSafe (SEC_PKCS12ExportContext *p12ctxt, CERTCertDBHandle *certDb, CERTCertificate *signer, CERTCertificate **recipients, SECOidTag algorithm, int keysize)
sec_PKCS12SafeContents * sec_PKCS12CreateSafeContents (PRArenaPool *arena)
SECStatus sec_pkcs12_append_bag_to_safe_contents (PRArenaPool *arena, sec_PKCS12SafeContents *safeContents, sec_PKCS12SafeBag *safeBag)
SECStatus sec_pkcs12_append_bag (SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safeInfo, sec_PKCS12SafeBag *safeBag)
sec_PKCS12SafeBag * sec_PKCS12CreateSafeBag (SEC_PKCS12ExportContext *p12ctxt, SECOidTag bagType, void *bagData)
sec_PKCS12CertBag * sec_PKCS12NewCertBag (PRArenaPool *arena, SECOidTag certType)
sec_PKCS12CRLBag * sec_PKCS12NewCRLBag (PRArenaPool *arena, SECOidTag crlType)
SECStatus sec_PKCS12AddAttributeToBag (SEC_PKCS12ExportContext *p12ctxt, sec_PKCS12SafeBag *safeBag, SECOidTag attrType, SECItem *attrData)
SECStatus SEC_PKCS12AddCert (SEC_PKCS12ExportContext *p12ctxt, SEC_PKCS12SafeInfo *safe, void *nestedDest, CERTCertificate *cert, CERTCertDBHandle *certDb, SECItem *keyId, PRBool includeCertChain)
static SECStatus SEC_PKCS12AddEncryptedKey (SEC_PKCS12ExportContext *p12ctxt, SECKEYEncryptedPrivateKeyInfo *epki, SEC_PKCS12SafeInfo *safe, void *nestedDest, SECItem *keyId, SECItem *nickName)
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_PKCS12AddDERCertAndEncryptedKey (SEC_PKCS12ExportContext *p12ctxt, void *certSafe, void *certNestedDest, SECItem *derCert, void *keySafe, void *keyNestedDest, SECKEYEncryptedPrivateKeyInfo *epki, char *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)
voidSEC_PKCS12CreateNestedSafeContents (SEC_PKCS12ExportContext *p12ctxt, void *baseSafe, void *nestedDest)
sec_PKCS12EncoderContextsec_pkcs12_encoder_start_context (SEC_PKCS12ExportContext *p12exp)
static void sec_P12A1OutputCB_Outer (void *arg, const char *buf, unsigned long len, int depth, SEC_ASN1EncodingPart data_kind)
static void sec_P12A1OutputCB_HmacP7Update (void *arg, const char *buf, unsigned long len, int depth, SEC_ASN1EncodingPart data_kind)
void sec_FlushPkcs12OutputBuffer (sec_pkcs12OutputBuffer *bufcx)
static void sec_P12P7OutputCB_CallA1Update (void *arg, const char *buf, unsigned long len)
static SECStatus sec_pkcs12_encoder_asafe_process (sec_PKCS12EncoderContext *p12ecx)
static SECStatus sec_Pkcs12FinishMac (sec_PKCS12EncoderContext *p12ecx)
static void sec_pkcs12_encoder_pfx_notify (void *arg, PRBool before, void *dest, int real_depth)
SECStatus SEC_PKCS12Encode (SEC_PKCS12ExportContext *p12exp, SEC_PKCS12EncoderOutputCallback output, void *outputarg)
void SEC_PKCS12DestroyExportContext (SEC_PKCS12ExportContext *p12ecx)
static void sec_pkcs12_in_place_encoder_output (void *arg, const char *buf, unsigned long len)
SECItem * SEC_PKCS12ExportCertificateAndKeyUsingPassword (SECKEYGetPasswordKey pwfn, void *pwfnarg, CERTCertificate *cert, PK11SlotInfo *slot, CERTCertDBHandle *certDb, SECItem *pwitem, PRBool shroudKey, SECOidTag shroudAlg, PRBool encryptCert, SECOidTag certEncAlg, SECOidTag integrityAlg, void *wincx)

Class Documentation

struct sec_pkcs12OutputBufferStr

Definition at line 78 of file p12e.c.

Class Members
char buf
unsigned int bufBytes
PK11Context * hmacCx
unsigned int numBytes
SEC_PKCS7EncoderContext * p7eCx
struct SEC_PKCS12SafeInfoStr

Definition at line 95 of file p12e.c.

Class Members
SECOidTag algorithm
PRArenaPool * arena
SEC_PKCS7ContentInfo * cinfo
PK11SymKey * encryptionKey
unsigned int itemCount
SECItem pwitem
sec_PKCS12SafeContents * safe
struct SEC_PKCS12ExportContextStr

Definition at line 118 of file p12e.c.

Collaboration diagram for SEC_PKCS12ExportContextStr:
Class Members
PRArenaPool * arena
sec_PKCS12AuthenticatedSafe authSafe
CERTCertificate ** certList
PRBool integrityEnabled
union SEC_PKCS12ExportContextStr integrityInfo
union SEC_PKCS12ExportContextStr integrityInfo
PRBool pwdIntegrity
SECKEYGetPasswordKey pwfn
void * pwfnarg
unsigned int safeInfoCount
SEC_PKCS12SafeInfo ** safeInfos
PK11SlotInfo * slot
void * wincx
struct sec_pkcs12_encoder_output

Definition at line 150 of file p12e.c.

Class Members
void * outputarg
SEC_PKCS12EncoderOutputCallback outputfn
struct sec_pkcs12_hmac_and_output_info

Definition at line 155 of file p12e.c.

Class Members
void * arg
struct sec_PKCS12EncoderContextStr

Definition at line 163 of file p12e.c.

Class Members
PRArenaPool * arena
SEC_PKCS7ContentInfo * aSafeCinfo
unsigned int currentSafe
PK11SymKey * encryptionKey
PK11Context * hmacCx
sec_pkcs12OutputBuffer innerBuf
sec_PKCS12MacData mac
SEC_ASN1EncoderContext * middleA1ecx
sec_pkcs12OutputBuffer middleBuf
SEC_PKCS7EncoderContext * middleP7ecx
SEC_ASN1EncoderContext * outerA1ecx
union sec_PKCS12EncoderContextStr output
union sec_PKCS12EncoderContextStr output
SEC_PKCS12ExportContext * p12exp
sec_PKCS12PFXItem pfx
struct inPlaceEncodeInfo

Definition at line 2233 of file p12e.c.

Class Members
PRBool error
SECItem outItem
union SEC_PKCS12ExportContextStr.integrityInfo

Definition at line 126 of file p12e.c.

union sec_PKCS12EncoderContextStr.output

Definition at line 172 of file p12e.c.


Define Documentation

Definition at line 76 of file p12e.c.


Typedef Documentation

typedef struct sec_pkcs12OutputBufferStr

Definition at line 85 of file p12e.c.


Function Documentation

void sec_FlushPkcs12OutputBuffer ( sec_pkcs12OutputBuffer *  bufcx)

Definition at line 1873 of file p12e.c.

{
    if (bufcx->numBytes > 0) {
       SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->numBytes);
       bufcx->numBytes = 0;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sec_P12A1OutputCB_HmacP7Update ( void arg,
const char *  buf,
unsigned long  len,
int  depth,
SEC_ASN1EncodingPart  data_kind 
) [static]

Definition at line 1828 of file p12e.c.

{
    sec_pkcs12OutputBuffer *  bufcx = (sec_pkcs12OutputBuffer *)arg;

    if(!buf || !len) 
       return;

    if (bufcx->hmacCx) {
       PK11_DigestOp(bufcx->hmacCx, (unsigned char *)buf, len);
    }

    /* buffer */
    if (bufcx->numBytes > 0) {
       int toCopy;
       if (len + bufcx->numBytes <= bufcx->bufBytes) {
           memcpy(bufcx->buf + bufcx->numBytes, buf, len);
           bufcx->numBytes += len;
           if (bufcx->numBytes < bufcx->bufBytes) 
              return;
           SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->bufBytes);
           bufcx->numBytes = 0;
           return;
       } 
       toCopy = bufcx->bufBytes - bufcx->numBytes;
       memcpy(bufcx->buf + bufcx->numBytes, buf, toCopy);
       SEC_PKCS7EncoderUpdate(bufcx->p7eCx, bufcx->buf, bufcx->bufBytes);
       bufcx->numBytes = 0;
       len -= toCopy;
       buf += toCopy;
    } 
    /* buffer is presently empty */
    if (len >= bufcx->bufBytes) {
       /* Just pass it through */
       SEC_PKCS7EncoderUpdate(bufcx->p7eCx, buf, len);
    } else {
       /* copy it all into the buffer, and return */
       memcpy(bufcx->buf, buf, len);
       bufcx->numBytes = len;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sec_P12A1OutputCB_Outer ( void arg,
const char *  buf,
unsigned long  len,
int  depth,
SEC_ASN1EncodingPart  data_kind 
) [static]

Definition at line 1814 of file p12e.c.

{
    struct sec_pkcs12_encoder_output *output;

    output = (struct sec_pkcs12_encoder_output*)arg;
    (* output->outputfn)(output->outputarg, buf, len);
}

Here is the caller graph for this function:

static void sec_P12P7OutputCB_CallA1Update ( void arg,
const char *  buf,
unsigned long  len 
) [static]

Definition at line 1885 of file p12e.c.

{
    SEC_ASN1EncoderContext *cx = (SEC_ASN1EncoderContext*)arg;

    if (!buf || !len) 
       return;

    SEC_ASN1EncoderUpdate(cx, buf, len);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus sec_pkcs12_append_bag ( SEC_PKCS12ExportContext *  p12ctxt,
SEC_PKCS12SafeInfo *  safeInfo,
sec_PKCS12SafeBag *  safeBag 
)

Definition at line 695 of file p12e.c.

{
    sec_PKCS12SafeContents *dest;
    SECStatus rv = SECFailure;

    if(!p12ctxt || !safeBag || !safeInfo) {
       return SECFailure;
    }

    if(!safeInfo->safe) {
       safeInfo->safe = sec_PKCS12CreateSafeContents(p12ctxt->arena);
       if(!safeInfo->safe) {
           return SECFailure;
       }
    }

    dest = safeInfo->safe;
    rv = sec_pkcs12_append_bag_to_safe_contents(p12ctxt->arena, dest, safeBag);
    if(rv == SECSuccess) {
       safeInfo->itemCount++;
    }
    
    return rv;
} 

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus sec_pkcs12_append_bag_to_safe_contents ( PRArenaPool arena,
sec_PKCS12SafeContents *  safeContents,
sec_PKCS12SafeBag *  safeBag 
)

Definition at line 648 of file p12e.c.

{
    void *mark = NULL, *dummy = NULL;

    if(!arena || !safeBag || !safeContents) {
       return SECFailure;
    }

    mark = PORT_ArenaMark(arena);
    if(!mark) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }

    /* allocate space for the list, or reallocate to increase space */
    if(!safeContents->safeBags) {
       safeContents->safeBags = (sec_PKCS12SafeBag **)PORT_ArenaZAlloc(arena, 
                                          (2 * sizeof(sec_PKCS12SafeBag *)));
       dummy = safeContents->safeBags;
       safeContents->bagCount = 0;
    } else {
       dummy = PORT_ArenaGrow(arena, safeContents->safeBags, 
                     (safeContents->bagCount + 1) * sizeof(sec_PKCS12SafeBag *),
                     (safeContents->bagCount + 2) * sizeof(sec_PKCS12SafeBag *));
       safeContents->safeBags = (sec_PKCS12SafeBag **)dummy;
    }

    if(!dummy) {
       PORT_ArenaRelease(arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }

    /* append the bag at the end and null terminate the list */
    safeContents->safeBags[safeContents->bagCount++] = safeBag;
    safeContents->safeBags[safeContents->bagCount] = NULL;

    PORT_ArenaUnmark(arena, mark);

    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus sec_pkcs12_append_safe_info ( SEC_PKCS12ExportContext *  p12ctxt,
SEC_PKCS12SafeInfo *  info 
) [static]

Definition at line 330 of file p12e.c.

{
    void *mark = NULL, *dummy1 = NULL, *dummy2 = NULL;

    if(!p12ctxt || !info) {
       return SECFailure;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);

    /* if no safeInfos have been set, create the list, otherwise expand it. */
    if(!p12ctxt->safeInfoCount) {
       p12ctxt->safeInfos = (SEC_PKCS12SafeInfo **)PORT_ArenaZAlloc(p12ctxt->arena, 
                                         2 * sizeof(SEC_PKCS12SafeInfo *));
       dummy1 = p12ctxt->safeInfos;
       p12ctxt->authSafe.encodedSafes = (SECItem **)PORT_ArenaZAlloc(p12ctxt->arena, 
                                   2 * sizeof(SECItem *));
       dummy2 = p12ctxt->authSafe.encodedSafes;
    } else {
       dummy1 = PORT_ArenaGrow(p12ctxt->arena, p12ctxt->safeInfos, 
                            (p12ctxt->safeInfoCount + 1) * sizeof(SEC_PKCS12SafeInfo *),
                            (p12ctxt->safeInfoCount + 2) * sizeof(SEC_PKCS12SafeInfo *));
       p12ctxt->safeInfos = (SEC_PKCS12SafeInfo **)dummy1;
       dummy2 = PORT_ArenaGrow(p12ctxt->arena, p12ctxt->authSafe.encodedSafes, 
                            (p12ctxt->authSafe.safeCount + 1) * sizeof(SECItem *),
                            (p12ctxt->authSafe.safeCount + 2) * sizeof(SECItem *));
       p12ctxt->authSafe.encodedSafes = (SECItem**)dummy2;
    }
    if(!dummy1 || !dummy2) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* append the new safeInfo and null terminate the list */
    p12ctxt->safeInfos[p12ctxt->safeInfoCount] = info;
    p12ctxt->safeInfos[++p12ctxt->safeInfoCount] = NULL;
    p12ctxt->authSafe.encodedSafes[p12ctxt->authSafe.safeCount] = 
        (SECItem*)PORT_ArenaZAlloc(p12ctxt->arena, sizeof(SECItem));
    if(!p12ctxt->authSafe.encodedSafes[p12ctxt->authSafe.safeCount]) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
    p12ctxt->authSafe.encodedSafes[++p12ctxt->authSafe.safeCount] = NULL;

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

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

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1900 of file p12e.c.

{
    SEC_PKCS7EncoderContext *innerP7ecx;
    SEC_PKCS7ContentInfo    *cinfo;
    PK11SymKey              *bulkKey      = NULL;
    SEC_ASN1EncoderContext  *innerA1ecx   = NULL;
    SECStatus                rv           = SECSuccess;

    if(p12ecx->currentSafe < p12ecx->p12exp->authSafe.safeCount) {
       SEC_PKCS12SafeInfo *safeInfo;
       SECOidTag cinfoType;

       safeInfo = p12ecx->p12exp->safeInfos[p12ecx->currentSafe];

       /* skip empty safes */
       if(safeInfo->itemCount == 0) {
           return SECSuccess;
       }

       cinfo = safeInfo->cinfo;
       cinfoType = SEC_PKCS7ContentType(cinfo);

       /* determine the safe type and set the appropriate argument */
       switch(cinfoType) {
           case SEC_OID_PKCS7_DATA:
           case SEC_OID_PKCS7_ENVELOPED_DATA:
              break;
           case SEC_OID_PKCS7_ENCRYPTED_DATA:
              bulkKey = safeInfo->encryptionKey;
              PK11_SetSymKeyUserData(bulkKey, &safeInfo->pwitem, NULL);
              break;
           default:
              return SECFailure;

       }

       /* start the PKCS7 encoder */
       innerP7ecx = SEC_PKCS7EncoderStart(cinfo, 
                              sec_P12P7OutputCB_CallA1Update,
                              p12ecx->middleA1ecx, bulkKey);
       if(!innerP7ecx) {
           goto loser;
       }

       /* encode safe contents */
       p12ecx->innerBuf.p7eCx    = innerP7ecx;
       p12ecx->innerBuf.hmacCx   = NULL;
       p12ecx->innerBuf.numBytes = 0;
       p12ecx->innerBuf.bufBytes = sizeof p12ecx->innerBuf.buf;

       innerA1ecx = SEC_ASN1EncoderStart(safeInfo->safe, 
                                  sec_PKCS12SafeContentsTemplate,
                               sec_P12A1OutputCB_HmacP7Update, 
                               &p12ecx->innerBuf);
       if(!innerA1ecx) {
           goto loser;
       }   
       rv = SEC_ASN1EncoderUpdate(innerA1ecx, NULL, 0);
       SEC_ASN1EncoderFinish(innerA1ecx);
       sec_FlushPkcs12OutputBuffer( &p12ecx->innerBuf);
       innerA1ecx = NULL;
       if(rv != SECSuccess) {
           goto loser;
       }


       /* finish up safe content info */
       rv = SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn, 
                                p12ecx->p12exp->pwfnarg);
    }
    memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
    return SECSuccess;

loser:
    if(innerP7ecx) {
       SEC_PKCS7EncoderFinish(innerP7ecx, p12ecx->p12exp->pwfn, 
                            p12ecx->p12exp->pwfnarg);
    }

    if(innerA1ecx) {
       SEC_ASN1EncoderFinish(innerA1ecx);
    }
    memset(&p12ecx->innerBuf, 0, sizeof p12ecx->innerBuf);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sec_pkcs12_encoder_pfx_notify ( void arg,
PRBool  before,
void dest,
int  real_depth 
) [static]

Definition at line 2066 of file p12e.c.

{
    sec_PKCS12EncoderContext *p12ecx;

    if(!before) {
       return;
    }

    /* look for authenticated safe */
    p12ecx = (sec_PKCS12EncoderContext*)arg;
    if(dest != &p12ecx->pfx.encodedAuthSafe) {
       return;
    }

    SEC_ASN1EncoderSetTakeFromBuf(p12ecx->outerA1ecx);
    SEC_ASN1EncoderSetStreaming(p12ecx->outerA1ecx);
    SEC_ASN1EncoderClearNotifyProc(p12ecx->outerA1ecx);
}

Here is the call graph for this function:

Here is the caller graph for this function:

sec_PKCS12EncoderContext* sec_pkcs12_encoder_start_context ( SEC_PKCS12ExportContext *  p12exp)

Definition at line 1645 of file p12e.c.

{
    sec_PKCS12EncoderContext *p12enc = NULL;
    unsigned int i, nonEmptyCnt;
    SECStatus rv;
    SECItem ignore = {0};
    void *mark;

    if(!p12exp || !p12exp->safeInfos) {
       return NULL;
    }

    /* check for any empty safes and skip them */
    i = nonEmptyCnt = 0;
    while(p12exp->safeInfos[i]) {
       if(p12exp->safeInfos[i]->itemCount) {
           nonEmptyCnt++;
       }
       i++;
    }
    if(nonEmptyCnt == 0) {
       return NULL;
    }
    p12exp->authSafe.encodedSafes[nonEmptyCnt] = NULL;

    /* allocate the encoder context */
    mark = PORT_ArenaMark(p12exp->arena);
    p12enc = PORT_ArenaZNew(p12exp->arena, sec_PKCS12EncoderContext);
    if(!p12enc) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    p12enc->arena = p12exp->arena;
    p12enc->p12exp = p12exp;

    /* set up the PFX version and information */
    PORT_Memset(&p12enc->pfx, 0, sizeof(sec_PKCS12PFXItem));
    if(!SEC_ASN1EncodeInteger(p12exp->arena, &(p12enc->pfx.version), 
                           SEC_PKCS12_VERSION) ) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* set up the authenticated safe content info based on the 
     * type of integrity being used.  this should be changed to
     * enforce integrity mode, but will not be implemented until
     * it is confirmed that integrity must be in place
     */
    if(p12exp->integrityEnabled && !p12exp->pwdIntegrity) {
       SECStatus rv;

       /* create public key integrity mode */
       p12enc->aSafeCinfo = SEC_PKCS7CreateSignedData(
                            p12exp->integrityInfo.pubkeyInfo.cert,
                            certUsageEmailSigner,
                            p12exp->integrityInfo.pubkeyInfo.certDb,
                            p12exp->integrityInfo.pubkeyInfo.algorithm,
                            NULL,
                            p12exp->pwfn,
                            p12exp->pwfnarg);
       if(!p12enc->aSafeCinfo) {
           goto loser;
       }
       if(SEC_PKCS7IncludeCertChain(p12enc->aSafeCinfo,NULL) != SECSuccess) {
           goto loser;
       }
       rv = SEC_PKCS7AddSigningTime(p12enc->aSafeCinfo);
       PORT_Assert(rv == SECSuccess);
    } else {
       p12enc->aSafeCinfo = SEC_PKCS7CreateData();

       /* init password pased integrity mode */
       if(p12exp->integrityEnabled) {
           SECItem  pwd = {siBuffer,NULL, 0};
           SECItem *salt = sec_pkcs12_generate_salt();
           PK11SymKey *symKey;
           SECItem *params;
           CK_MECHANISM_TYPE integrityMech;
           CK_MECHANISM_TYPE hmacMech;

           /* zero out macData and set values */
           PORT_Memset(&p12enc->mac, 0, sizeof(sec_PKCS12MacData));

           if(!salt) {
              PORT_SetError(SEC_ERROR_NO_MEMORY);
              goto loser;
           }
           if(SECITEM_CopyItem(p12exp->arena, &(p12enc->mac.macSalt), salt) 
                     != SECSuccess) {
              PORT_SetError(SEC_ERROR_NO_MEMORY);
              goto loser;
           }   

           /* generate HMAC key */
           if(!sec_pkcs12_convert_item_to_unicode(NULL, &pwd, 
                     p12exp->integrityInfo.pwdInfo.password, PR_TRUE, 
                     PR_TRUE, PR_TRUE)) {
              goto loser;
           }

           params = PK11_CreatePBEParams(salt, &pwd, 1);
           SECITEM_ZfreeItem(salt, PR_TRUE);
           SECITEM_ZfreeItem(&pwd, PR_FALSE);

           switch (p12exp->integrityInfo.pwdInfo.algorithm) {
           case SEC_OID_SHA1:
              integrityMech = CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN; break;
           case SEC_OID_MD5:
              integrityMech = CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN;  break;
           case SEC_OID_MD2:
              integrityMech = CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN;  break;
           default:
              goto loser;
           }

           symKey = PK11_KeyGen(NULL, integrityMech, params, 20, NULL);
           PK11_DestroyPBEParams(params);
           if(!symKey) {
              goto loser;
           }

           /* initialize hmac */
           /* XXX NBB, why is this mech different than the one above? */
           hmacMech =  sec_pkcs12_algtag_to_mech( 
                                     p12exp->integrityInfo.pwdInfo.algorithm);

           p12enc->hmacCx = PK11_CreateContextBySymKey( hmacMech, CKA_SIGN, 
                                                        symKey, &ignore);

           PK11_FreeSymKey(symKey);
           if(!p12enc->hmacCx) {
              PORT_SetError(SEC_ERROR_NO_MEMORY);
              goto loser;
           }
           rv = PK11_DigestBegin(p12enc->hmacCx);
           if (rv != SECSuccess)
              goto loser;
       }
    }

    if(!p12enc->aSafeCinfo) {
       goto loser;
    }

    PORT_ArenaUnmark(p12exp->arena, mark);

    return p12enc;

loser:
    if(p12enc) {
       if(p12enc->aSafeCinfo) {
           SEC_PKCS7DestroyContentInfo(p12enc->aSafeCinfo);
       }
       if(p12enc->hmacCx) {
           PK11_DestroyContext(p12enc->hmacCx, PR_TRUE);
       }
    }
    if (p12exp->arena != NULL)
       PORT_ArenaRelease(p12exp->arena, mark);

    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sec_pkcs12_in_place_encoder_output ( void arg,
const char *  buf,
unsigned long  len 
) [static]

Definition at line 2239 of file p12e.c.

{
    struct inPlaceEncodeInfo *outInfo = (struct inPlaceEncodeInfo*)arg;

    if(!outInfo || !len || outInfo->error) {
       return;
    }

    if(!outInfo->outItem.data) {
       outInfo->outItem.data = (unsigned char*)PORT_ZAlloc(len);
       outInfo->outItem.len = 0;
    } else {
       if(!PORT_Realloc(&(outInfo->outItem.data), (outInfo->outItem.len + len))) {
           SECITEM_ZfreeItem(&(outInfo->outItem), PR_FALSE);
           outInfo->outItem.data = NULL;
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           outInfo->error = PR_TRUE;
           return;
       }
    }

    PORT_Memcpy(&(outInfo->outItem.data[outInfo->outItem.len]), buf, len);
    outInfo->outItem.len += len;

    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus sec_PKCS12AddAttributeToBag ( SEC_PKCS12ExportContext *  p12ctxt,
sec_PKCS12SafeBag *  safeBag,
SECOidTag  attrType,
SECItem *  attrData 
)

Definition at line 903 of file p12e.c.

{
    sec_PKCS12Attribute *attribute;
    void *mark = NULL, *dummy = NULL;
    SECOidData *oiddata = NULL;
    SECItem unicodeName = { siBuffer, NULL, 0};
    void *src = NULL;
    unsigned int nItems = 0;
    SECStatus rv;

    if(!safeBag || !p12ctxt) {
       return SECFailure;
    }

    mark = PORT_ArenaMark(safeBag->arena);

    /* allocate the attribute */
    attribute = (sec_PKCS12Attribute *)PORT_ArenaZAlloc(safeBag->arena, 
                                          sizeof(sec_PKCS12Attribute));
    if(!attribute) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* set up the attribute */
    oiddata = SECOID_FindOIDByTag(attrType);
    if(!oiddata) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
    if(SECITEM_CopyItem(p12ctxt->arena, &attribute->attrType, &oiddata->oid) !=
              SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    nItems = 1;
    switch(attrType) {
       case SEC_OID_PKCS9_LOCAL_KEY_ID:
           {
              src = attrData;
              break;
           }
       case SEC_OID_PKCS9_FRIENDLY_NAME:
           {
              if(!sec_pkcs12_convert_item_to_unicode(p12ctxt->arena, 
                                   &unicodeName, attrData, PR_FALSE, 
                                   PR_FALSE, PR_TRUE)) {
                  goto loser;
              }
              src = &unicodeName;
              break;
           }
       default:
           goto loser;
    }

    /* append the attribute to the attribute value list  */
    attribute->attrValue = (SECItem **)PORT_ArenaZAlloc(p12ctxt->arena, 
                                       ((nItems + 1) * sizeof(SECItem *)));
    if(!attribute->attrValue) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* XXX this will need to be changed if attributes requiring more than
     * one element are ever used.
     */
    attribute->attrValue[0] = (SECItem *)PORT_ArenaZAlloc(p12ctxt->arena, 
                                                   sizeof(SECItem));
    if(!attribute->attrValue[0]) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
    attribute->attrValue[1] = NULL;

    rv = SECITEM_CopyItem(p12ctxt->arena, attribute->attrValue[0], 
                       (SECItem*)src);
    if(rv != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* append the attribute to the safeBag attributes */
    if(safeBag->nAttribs) {
       dummy = PORT_ArenaGrow(p12ctxt->arena, safeBag->attribs, 
                     ((safeBag->nAttribs + 1) * sizeof(sec_PKCS12Attribute *)),
                     ((safeBag->nAttribs + 2) * sizeof(sec_PKCS12Attribute *)));
       safeBag->attribs = (sec_PKCS12Attribute **)dummy;
    } else {
       safeBag->attribs = (sec_PKCS12Attribute **)PORT_ArenaZAlloc(p12ctxt->arena, 
                                          2 * sizeof(sec_PKCS12Attribute *));
       dummy = safeBag->attribs;
    }
    if(!dummy) {
       goto loser;
    }

    safeBag->attribs[safeBag->nAttribs] = attribute;
    safeBag->attribs[++safeBag->nAttribs] = NULL;

    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:

Here is the caller graph for this function:

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;
}
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; 
}
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; 
}
static SECStatus SEC_PKCS12AddEncryptedKey ( SEC_PKCS12ExportContext *  p12ctxt,
SECKEYEncryptedPrivateKeyInfo *  epki,
SEC_PKCS12SafeInfo *  safe,
void nestedDest,
SECItem *  keyId,
SECItem *  nickName 
) [static]

Definition at line 1201 of file p12e.c.

{
    void *mark;
    void *keyItem;
    SECOidTag keyType;
    SECStatus rv = SECFailure;
    sec_PKCS12SafeBag *returnBag;

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

    mark = PORT_ArenaMark(p12ctxt->arena);

    keyItem = PORT_ArenaZAlloc(p12ctxt->arena, 
                            sizeof(SECKEYEncryptedPrivateKeyInfo));
    if(!keyItem) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    rv = SECKEY_CopyEncryptedPrivateKeyInfo(p12ctxt->arena, 
                                   (SECKEYEncryptedPrivateKeyInfo *)keyItem,
                                   epki);
    keyType = SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID;

    if(rv != SECSuccess) {
       goto loser;
    }
       
    /* 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:

Here is the caller 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;
}
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;
}
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;
}
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;
}
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;
}
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;
} 
sec_PKCS12SafeBag* sec_PKCS12CreateSafeBag ( SEC_PKCS12ExportContext *  p12ctxt,
SECOidTag  bagType,
void bagData 
)

Definition at line 726 of file p12e.c.

{
    sec_PKCS12SafeBag *safeBag;
    PRBool setName = PR_TRUE;
    void *mark = NULL;
    SECStatus rv = SECSuccess;
    SECOidData *oidData = NULL;

    if(!p12ctxt) {
       return NULL;
    }

    mark = PORT_ArenaMark(p12ctxt->arena);
    if(!mark) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    safeBag = (sec_PKCS12SafeBag *)PORT_ArenaZAlloc(p12ctxt->arena, 
                                              sizeof(sec_PKCS12SafeBag));
    if(!safeBag) {
       PORT_ArenaRelease(p12ctxt->arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    /* set the bags content based upon bag type */
    switch(bagType) {
       case SEC_OID_PKCS12_V1_KEY_BAG_ID:
           safeBag->safeBagContent.pkcs8KeyBag =
               (SECKEYPrivateKeyInfo *)bagData;
           break;
       case SEC_OID_PKCS12_V1_CERT_BAG_ID:
           safeBag->safeBagContent.certBag = (sec_PKCS12CertBag *)bagData;
           break;
       case SEC_OID_PKCS12_V1_CRL_BAG_ID:
           safeBag->safeBagContent.crlBag = (sec_PKCS12CRLBag *)bagData;
           break;
       case SEC_OID_PKCS12_V1_SECRET_BAG_ID:
           safeBag->safeBagContent.secretBag = (sec_PKCS12SecretBag *)bagData;
           break;
       case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
           safeBag->safeBagContent.pkcs8ShroudedKeyBag = 
               (SECKEYEncryptedPrivateKeyInfo *)bagData;
           break;
       case SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID:
           safeBag->safeBagContent.safeContents = 
               (sec_PKCS12SafeContents *)bagData;
           setName = PR_FALSE;
           break;
       default:
           goto loser;
    }

    oidData = SECOID_FindOIDByTag(bagType);
    if(oidData) {
       rv = SECITEM_CopyItem(p12ctxt->arena, &safeBag->safeBagType, &oidData->oid);
       if(rv != SECSuccess) {
           PORT_SetError(SEC_ERROR_NO_MEMORY);
           goto loser;
       }
    } else {
       goto loser;
    }
    
    safeBag->arena = p12ctxt->arena;
    PORT_ArenaUnmark(p12ctxt->arena, mark);

    return safeBag;

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

    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

sec_PKCS12SafeContents* sec_PKCS12CreateSafeContents ( PRArenaPool arena)

Definition at line 618 of file p12e.c.

{
    sec_PKCS12SafeContents *safeContents;

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

    /* create the safe contents */
    safeContents = (sec_PKCS12SafeContents *)PORT_ArenaZAlloc(arena,
                                       sizeof(sec_PKCS12SafeContents));
    if(!safeContents) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* set up the internal contents info */
    safeContents->safeBags = NULL;
    safeContents->arena = arena;
    safeContents->bagCount = 0;

    return safeContents;

loser:
    return NULL;
}   

Here is the call graph for this function:

Here is the caller 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;
}
void SEC_PKCS12DestroyExportContext ( SEC_PKCS12ExportContext *  p12ecx)

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);
}
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;
}
SECItem* SEC_PKCS12ExportCertificateAndKeyUsingPassword ( SECKEYGetPasswordKey  pwfn,
void pwfnarg,
CERTCertificate *  cert,
PK11SlotInfo *  slot,
CERTCertDBHandle *  certDb,
SECItem *  pwitem,
PRBool  shroudKey,
SECOidTag  shroudAlg,
PRBool  encryptCert,
SECOidTag  certEncAlg,
SECOidTag  integrityAlg,
void wincx 
)

Definition at line 2281 of file p12e.c.

{
    struct inPlaceEncodeInfo outInfo;
    SEC_PKCS12ExportContext *p12ecx = NULL;
    SEC_PKCS12SafeInfo *keySafe, *certSafe;
    SECItem *returnItem = NULL;

    if(!cert || !pwitem || !slot) {
       return NULL;
    }

    outInfo.error = PR_FALSE;
    outInfo.outItem.data = NULL;
    outInfo.outItem.len = 0;

    p12ecx = SEC_PKCS12CreateExportContext(pwfn, pwfnarg, slot, wincx);
    if(!p12ecx) {
       return NULL;
    }

    /* set up cert safe */
    if(encryptCert) {
       certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem, certEncAlg);
    } else {
       certSafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
    }
    if(!certSafe) {
       goto loser;
    }

    /* set up key safe */
    if(shroudKey) {
       keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
    } else {
       keySafe = certSafe;
    }
    if(!keySafe) {
       goto loser;
    }

    /* add integrity mode */
    if(SEC_PKCS12AddPasswordIntegrity(p12ecx, pwitem, integrityAlg) 
              != SECSuccess) {
       goto loser;
    }

    /* add cert and key pair */
    if(SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert, certDb, 
                            keySafe, NULL, shroudKey, pwitem, shroudAlg)
              != SECSuccess) {
       goto loser;
    }

    /* encode the puppy */
    if(SEC_PKCS12Encode(p12ecx, sec_pkcs12_in_place_encoder_output, &outInfo)
              != SECSuccess) {
       goto loser;
    }
    if(outInfo.error) {
       goto loser;
    }

    SEC_PKCS12DestroyExportContext(p12ecx);
       
    returnItem = SECITEM_DupItem(&outInfo.outItem);
    SECITEM_ZfreeItem(&outInfo.outItem, PR_FALSE);

    return returnItem;

loser:
    if(outInfo.outItem.data) {
       SECITEM_ZfreeItem(&(outInfo.outItem), PR_TRUE);
    }

    if(p12ecx) {
       SEC_PKCS12DestroyExportContext(p12ecx);
    }

    return NULL;
}

Here is the call graph for this function:

Definition at line 1990 of file p12e.c.

{
    SECItem hmac = { siBuffer, NULL, 0 };
    SECStatus rv;
    SGNDigestInfo *di = NULL;
    void *dummy;

    if(!p12ecx) {
       return SECFailure;
    }

    /* make sure we are using password integrity mode */
    if(!p12ecx->p12exp->integrityEnabled) {
       return SECSuccess;
    }

    if(!p12ecx->p12exp->pwdIntegrity) {
       return SECSuccess;
    }

    /* finish the hmac */
    hmac.data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
    if(!hmac.data) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return SECFailure;
    }

    rv = PK11_DigestFinal(p12ecx->hmacCx, hmac.data, &hmac.len, SHA1_LENGTH);

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

    /* create the digest info */
    di = SGN_CreateDigestInfo(p12ecx->p12exp->integrityInfo.pwdInfo.algorithm,
                           hmac.data, hmac.len);
    if(!di) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       rv = SECFailure;
       goto loser;
    }

    rv = SGN_CopyDigestInfo(p12ecx->arena, &p12ecx->mac.safeMac, di);
    if(rv != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    /* encode the mac data */
    dummy = SEC_ASN1EncodeItem(p12ecx->arena, &p12ecx->pfx.encodedMacData, 
                         &p12ecx->mac, sec_PKCS12MacDataTemplate);
    if(!dummy) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       rv = SECFailure;
    }

loser:
    if(di) {
       SGN_DestroyDigestInfo(di);
    }
    if(hmac.data) {
       SECITEM_ZfreeItem(&hmac, PR_FALSE);
    }
    PK11_DestroyContext(p12ecx->hmacCx, PR_TRUE);
    p12ecx->hmacCx = NULL;

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

sec_PKCS12CertBag* sec_PKCS12NewCertBag ( PRArenaPool arena,
SECOidTag  certType 
)

Definition at line 809 of file p12e.c.

{
    sec_PKCS12CertBag *certBag = NULL;
    SECOidData *bagType = NULL;
    SECStatus rv;
    void *mark = NULL;

    if(!arena) {
       return NULL;
    }

    mark = PORT_ArenaMark(arena);
    certBag = (sec_PKCS12CertBag *)PORT_ArenaZAlloc(arena, 
                                              sizeof(sec_PKCS12CertBag));
    if(!certBag) {
       PORT_ArenaRelease(arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    bagType = SECOID_FindOIDByTag(certType);
    if(!bagType) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    rv = SECITEM_CopyItem(arena, &certBag->bagID, &bagType->oid);
    if(rv != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
       
    PORT_ArenaUnmark(arena, mark);
    return certBag;

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

Here is the call graph for this function:

Here is the caller graph for this function:

sec_PKCS12CRLBag* sec_PKCS12NewCRLBag ( PRArenaPool arena,
SECOidTag  crlType 
)

Definition at line 853 of file p12e.c.

{
    sec_PKCS12CRLBag *crlBag = NULL;
    SECOidData *bagType = NULL;
    SECStatus rv;
    void *mark = NULL;

    if(!arena) {
       return NULL;
    }

    mark = PORT_ArenaMark(arena);
    crlBag = (sec_PKCS12CRLBag *)PORT_ArenaZAlloc(arena, 
                                            sizeof(sec_PKCS12CRLBag));
    if(!crlBag) {
       PORT_ArenaRelease(arena, mark);
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    bagType = SECOID_FindOIDByTag(crlType);
    if(!bagType) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }

    rv = SECITEM_CopyItem(arena, &crlBag->bagID, &bagType->oid);
    if(rv != SECSuccess) {
       PORT_SetError(SEC_ERROR_NO_MEMORY);
       goto loser;
    }
       
    PORT_ArenaUnmark(arena, mark);
    return crlBag;

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

Here is the call graph for this function: