Blame nss/lib/pkcs12/p12local.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
Packit 40b132
#include "nssrenam.h"
Packit 40b132
#include "pkcs12.h"
Packit 40b132
#include "secpkcs7.h"
Packit 40b132
#include "secasn1.h"
Packit 40b132
#include "seccomon.h"
Packit 40b132
#include "secoid.h"
Packit 40b132
#include "sechash.h"
Packit 40b132
#include "secitem.h"
Packit 40b132
#include "secerr.h"
Packit 40b132
#include "pk11func.h"
Packit 40b132
#include "p12local.h"
Packit 40b132
#include "p12.h"
Packit 40b132
Packit 40b132
#define SALT_LENGTH	16
Packit 40b132
Packit 40b132
SEC_ASN1_MKSUB(SECKEY_PrivateKeyInfoTemplate)
Packit 40b132
SEC_ASN1_MKSUB(sgn_DigestInfoTemplate)
Packit 40b132
Packit 40b132
CK_MECHANISM_TYPE
Packit 40b132
sec_pkcs12_algtag_to_mech(SECOidTag algtag)
Packit 40b132
{
Packit 40b132
    switch (algtag) {
Packit 40b132
    case SEC_OID_MD2:
Packit 40b132
	return CKM_MD2_HMAC;
Packit 40b132
    case SEC_OID_MD5:
Packit 40b132
	return CKM_MD5_HMAC;
Packit 40b132
    case SEC_OID_SHA1:
Packit 40b132
	return CKM_SHA_1_HMAC;
Packit 40b132
    case SEC_OID_SHA224:
Packit 40b132
	return CKM_SHA224_HMAC;
Packit 40b132
    case SEC_OID_SHA256:
Packit 40b132
	return CKM_SHA256_HMAC;
Packit 40b132
    case SEC_OID_SHA384:
Packit 40b132
	return CKM_SHA384_HMAC;
Packit 40b132
    case SEC_OID_SHA512:
Packit 40b132
	return CKM_SHA512_HMAC;
Packit 40b132
    default:
Packit 40b132
	break;
Packit 40b132
    }
Packit 40b132
    return CKM_INVALID_MECHANISM;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* helper functions */
Packit 40b132
/* returns proper bag type template based upon object type tag */
Packit 40b132
const SEC_ASN1Template *
Packit 40b132
sec_pkcs12_choose_bag_type_old(void *src_or_dest, PRBool encoding)
Packit 40b132
{
Packit 40b132
    const SEC_ASN1Template *theTemplate;
Packit 40b132
    SEC_PKCS12SafeBag *safebag;
Packit 40b132
    SECOidData *oiddata;
Packit 40b132
Packit 40b132
    if (src_or_dest == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    safebag = (SEC_PKCS12SafeBag*)src_or_dest;
Packit 40b132
Packit 40b132
    oiddata = safebag->safeBagTypeTag;
Packit 40b132
    if (oiddata == NULL) {
Packit 40b132
	oiddata = SECOID_FindOID(&safebag->safeBagType);
Packit 40b132
	safebag->safeBagTypeTag = oiddata;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch (oiddata->offset) {
Packit 40b132
	default:
Packit 40b132
	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_KEY_BAG_ID:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12KeyBagTemplate;
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD;
Packit 40b132
	    break;
Packit 40b132
        case SEC_OID_PKCS12_SECRET_BAG_ID:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12SecretBagTemplate;
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
    return theTemplate;
Packit 40b132
}
Packit 40b132
Packit 40b132
const SEC_ASN1Template *
Packit 40b132
sec_pkcs12_choose_bag_type(void *src_or_dest, PRBool encoding)
Packit 40b132
{
Packit 40b132
    const SEC_ASN1Template *theTemplate;
Packit 40b132
    SEC_PKCS12SafeBag *safebag;
Packit 40b132
    SECOidData *oiddata;
Packit 40b132
Packit 40b132
    if (src_or_dest == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    safebag = (SEC_PKCS12SafeBag*)src_or_dest;
Packit 40b132
Packit 40b132
    oiddata = safebag->safeBagTypeTag;
Packit 40b132
    if (oiddata == NULL) {
Packit 40b132
	oiddata = SECOID_FindOID(&safebag->safeBagType);
Packit 40b132
	safebag->safeBagTypeTag = oiddata;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch (oiddata->offset) {
Packit 40b132
	default:
Packit 40b132
	    theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_KEY_BAG_ID:
Packit 40b132
	    theTemplate = SEC_PKCS12PrivateKeyBagTemplate;
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
Packit 40b132
	    theTemplate = SEC_PKCS12CertAndCRLBagTemplate;
Packit 40b132
	    break;
Packit 40b132
        case SEC_OID_PKCS12_SECRET_BAG_ID:
Packit 40b132
	    theTemplate = SEC_PKCS12SecretBagTemplate;
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
    return theTemplate;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* returns proper cert crl template based upon type tag */
Packit 40b132
const SEC_ASN1Template *
Packit 40b132
sec_pkcs12_choose_cert_crl_type_old(void *src_or_dest, PRBool encoding)
Packit 40b132
{
Packit 40b132
    const SEC_ASN1Template *theTemplate;
Packit 40b132
    SEC_PKCS12CertAndCRL *certbag;
Packit 40b132
    SECOidData *oiddata;
Packit 40b132
Packit 40b132
    if (src_or_dest == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
Packit 40b132
    oiddata = certbag->BagTypeTag;
Packit 40b132
    if (oiddata == NULL) {
Packit 40b132
	oiddata = SECOID_FindOID(&certbag->BagID);
Packit 40b132
	certbag->BagTypeTag = oiddata;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch (oiddata->offset) {
Packit 40b132
	default:
Packit 40b132
	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_X509_CERT_CRL_BAG:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate_OLD;
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_SDSI_CERT_BAG:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12SDSICertTemplate;
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
    return theTemplate;
Packit 40b132
}
Packit 40b132
Packit 40b132
const SEC_ASN1Template *
Packit 40b132
sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding)
Packit 40b132
{
Packit 40b132
    const SEC_ASN1Template *theTemplate;
Packit 40b132
    SEC_PKCS12CertAndCRL *certbag;
Packit 40b132
    SECOidData *oiddata;
Packit 40b132
Packit 40b132
    if (src_or_dest == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
Packit 40b132
    oiddata = certbag->BagTypeTag;
Packit 40b132
    if (oiddata == NULL) {
Packit 40b132
	oiddata = SECOID_FindOID(&certbag->BagID);
Packit 40b132
	certbag->BagTypeTag = oiddata;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch (oiddata->offset) {
Packit 40b132
	default:
Packit 40b132
	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_X509_CERT_CRL_BAG:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate;
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_SDSI_CERT_BAG:
Packit 40b132
	    theTemplate = SEC_PointerToPKCS12SDSICertTemplate;
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
    return theTemplate;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* returns appropriate shroud template based on object type tag */
Packit 40b132
const SEC_ASN1Template *
Packit 40b132
sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding)
Packit 40b132
{
Packit 40b132
    const SEC_ASN1Template *theTemplate;
Packit 40b132
    SEC_PKCS12ESPVKItem *espvk;
Packit 40b132
    SECOidData *oiddata;
Packit 40b132
Packit 40b132
    if (src_or_dest == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    espvk = (SEC_PKCS12ESPVKItem*)src_or_dest;
Packit 40b132
    oiddata = espvk->espvkTag;
Packit 40b132
    if (oiddata == NULL) {
Packit 40b132
	oiddata = SECOID_FindOID(&espvk->espvkOID);
Packit 40b132
 	espvk->espvkTag = oiddata;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch (oiddata->offset) {
Packit 40b132
	default:
Packit 40b132
	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_PKCS8_KEY_SHROUDING:
Packit 40b132
	   theTemplate = 
Packit 40b132
		SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate);
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
    return theTemplate;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* generate SALT  placing it into the character array passed in.
Packit 40b132
 * it is assumed that salt_dest is an array of appropriate size
Packit 40b132
 * XXX We might want to generate our own random context
Packit 40b132
 */
Packit 40b132
SECItem *
Packit 40b132
sec_pkcs12_generate_salt(void)
Packit 40b132
{
Packit 40b132
    SECItem *salt;
Packit 40b132
Packit 40b132
    salt = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
Packit 40b132
    if(salt == NULL) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
    salt->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) * 
Packit 40b132
					      SALT_LENGTH);
Packit 40b132
    salt->len = SALT_LENGTH;
Packit 40b132
    if(salt->data == NULL) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	SECITEM_ZfreeItem(salt, PR_TRUE);
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PK11_GenerateRandom(salt->data, salt->len);
Packit 40b132
Packit 40b132
    return salt;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* generate KEYS -- as per PKCS12 section 7.  
Packit 40b132
 * only used for MAC
Packit 40b132
 */
Packit 40b132
SECItem *
Packit 40b132
sec_pkcs12_generate_key_from_password(SECOidTag algorithm, 
Packit 40b132
				      SECItem *salt, 
Packit 40b132
				      SECItem *password) 
Packit 40b132
{
Packit 40b132
    unsigned char *pre_hash=NULL;
Packit 40b132
    unsigned char *hash_dest=NULL;
Packit 40b132
    SECStatus res;
Packit 40b132
    PLArenaPool *poolp;
Packit 40b132
    SECItem *key = NULL;
Packit 40b132
    int key_len = 0;
Packit 40b132
Packit 40b132
    if((salt == NULL) || (password == NULL)) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
Packit 40b132
    if(poolp == NULL) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    pre_hash = (unsigned char *)PORT_ArenaZAlloc(poolp, sizeof(char) * 
Packit 40b132
						 (salt->len+password->len));
Packit 40b132
    if(pre_hash == NULL) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    hash_dest = (unsigned char *)PORT_ArenaZAlloc(poolp, 
Packit 40b132
					sizeof(unsigned char) * SHA1_LENGTH);
Packit 40b132
    if(hash_dest == NULL) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PORT_Memcpy(pre_hash, salt->data, salt->len);
Packit 40b132
    /* handle password of 0 length case */
Packit 40b132
    if(password->len > 0) {
Packit 40b132
	PORT_Memcpy(&(pre_hash[salt->len]), password->data, password->len);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, pre_hash, 
Packit 40b132
                       (salt->len+password->len));
Packit 40b132
    if(res == SECFailure) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    switch(algorithm) {
Packit 40b132
	case SEC_OID_SHA1:
Packit 40b132
	    if(key_len == 0)
Packit 40b132
		key_len = 16;
Packit 40b132
	    key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
Packit 40b132
	    if(key == NULL) {
Packit 40b132
		PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
		goto loser;
Packit 40b132
	    }
Packit 40b132
	    key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) 
Packit 40b132
						     * key_len);
Packit 40b132
	    if(key->data == NULL) {
Packit 40b132
		PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
		goto loser;
Packit 40b132
	    }
Packit 40b132
	    key->len = key_len;
Packit 40b132
	    PORT_Memcpy(key->data, &hash_dest[SHA1_LENGTH-key->len], key->len);
Packit 40b132
	    break;
Packit 40b132
	default:
Packit 40b132
	    goto loser;
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PORT_FreeArena(poolp, PR_TRUE);
Packit 40b132
    return key;
Packit 40b132
Packit 40b132
loser:
Packit 40b132
    PORT_FreeArena(poolp, PR_TRUE);
Packit 40b132
    if(key != NULL) {
Packit 40b132
	SECITEM_ZfreeItem(key, PR_TRUE);
Packit 40b132
    }
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* MAC is generated per PKCS 12 section 6.  It is expected that key, msg
Packit 40b132
 * and mac_dest are pre allocated, non-NULL arrays.  msg_len is passed in
Packit 40b132
 * because it is not known how long the message actually is.  String
Packit 40b132
 * manipulation routines will not necessarily work because msg may have
Packit 40b132
 * imbedded NULLs
Packit 40b132
 */
Packit 40b132
static SECItem *
Packit 40b132
sec_pkcs12_generate_old_mac(SECItem *key, 
Packit 40b132
			    SECItem *msg)
Packit 40b132
{
Packit 40b132
    SECStatus res;
Packit 40b132
    PLArenaPool *temparena = NULL;
Packit 40b132
    unsigned char *hash_dest=NULL, *hash_src1=NULL, *hash_src2 = NULL;
Packit 40b132
    int i;
Packit 40b132
    SECItem *mac = NULL;
Packit 40b132
Packit 40b132
    if((key == NULL) || (msg == NULL))
Packit 40b132
        goto loser;
Packit 40b132
Packit 40b132
    /* allocate return item */
Packit 40b132
    mac = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
Packit 40b132
    if(mac == NULL)
Packit 40b132
    	return NULL;
Packit 40b132
    mac->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char)
Packit 40b132
    	* SHA1_LENGTH);
Packit 40b132
    mac->len = SHA1_LENGTH;
Packit 40b132
    if(mac->data == NULL)
Packit 40b132
	goto loser;
Packit 40b132
Packit 40b132
    /* allocate temporary items */
Packit 40b132
    temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
Packit 40b132
    if(temparena == NULL)
Packit 40b132
	goto loser;
Packit 40b132
Packit 40b132
    hash_src1 = (unsigned char *)PORT_ArenaZAlloc(temparena,
Packit 40b132
    	sizeof(unsigned char) * (16+msg->len));
Packit 40b132
    if(hash_src1 == NULL)
Packit 40b132
        goto loser;
Packit 40b132
Packit 40b132
    hash_src2 = (unsigned char *)PORT_ArenaZAlloc(temparena,
Packit 40b132
   	sizeof(unsigned char) * (SHA1_LENGTH+16));
Packit 40b132
    if(hash_src2 == NULL)
Packit 40b132
        goto loser;
Packit 40b132
Packit 40b132
    hash_dest = (unsigned char *)PORT_ArenaZAlloc(temparena, 
Packit 40b132
   	sizeof(unsigned char) * SHA1_LENGTH);
Packit 40b132
    if(hash_dest == NULL)
Packit 40b132
        goto loser;
Packit 40b132
Packit 40b132
    /* perform mac'ing as per PKCS 12 */
Packit 40b132
Packit 40b132
    /* first round of hashing */
Packit 40b132
    for(i = 0; i < 16; i++)
Packit 40b132
	hash_src1[i] = key->data[i] ^ 0x36;
Packit 40b132
    PORT_Memcpy(&(hash_src1[16]), msg->data, msg->len);
Packit 40b132
    res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, hash_src1, (16+msg->len));
Packit 40b132
    if(res == SECFailure)
Packit 40b132
	goto loser;
Packit 40b132
Packit 40b132
    /* second round of hashing */
Packit 40b132
    for(i = 0; i < 16; i++)
Packit 40b132
	hash_src2[i] = key->data[i] ^ 0x5c;
Packit 40b132
    PORT_Memcpy(&(hash_src2[16]), hash_dest, SHA1_LENGTH);
Packit 40b132
    res = PK11_HashBuf(SEC_OID_SHA1, mac->data, hash_src2, SHA1_LENGTH+16);
Packit 40b132
    if(res == SECFailure)
Packit 40b132
	goto loser;
Packit 40b132
Packit 40b132
    PORT_FreeArena(temparena, PR_TRUE);
Packit 40b132
    return mac;
Packit 40b132
Packit 40b132
loser:
Packit 40b132
    if(temparena != NULL)
Packit 40b132
	PORT_FreeArena(temparena, PR_TRUE);
Packit 40b132
    if(mac != NULL)
Packit 40b132
	SECITEM_ZfreeItem(mac, PR_TRUE);
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* MAC is generated per PKCS 12 section 6.  It is expected that key, msg
Packit 40b132
 * and mac_dest are pre allocated, non-NULL arrays.  msg_len is passed in
Packit 40b132
 * because it is not known how long the message actually is.  String
Packit 40b132
 * manipulation routines will not necessarily work because msg may have
Packit 40b132
 * imbedded NULLs
Packit 40b132
 */
Packit 40b132
SECItem *
Packit 40b132
sec_pkcs12_generate_mac(SECItem *key, 
Packit 40b132
			SECItem *msg,
Packit 40b132
			PRBool old_method)
Packit 40b132
{
Packit 40b132
    SECStatus res = SECFailure;
Packit 40b132
    SECItem *mac = NULL;
Packit 40b132
    PK11Context *pk11cx = NULL;    
Packit 40b132
    SECItem ignore = {0};
Packit 40b132
Packit 40b132
    if((key == NULL) || (msg == NULL)) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(old_method == PR_TRUE) {
Packit 40b132
	return sec_pkcs12_generate_old_mac(key, msg);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* allocate return item */
Packit 40b132
    mac = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
Packit 40b132
    if (mac == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    pk11cx = PK11_CreateContextByRawKey(NULL, CKM_SHA_1_HMAC, PK11_OriginDerive,
Packit 40b132
                                        CKA_SIGN, key, &ignore, NULL);
Packit 40b132
    if (pk11cx == NULL) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    res = PK11_DigestBegin(pk11cx);
Packit 40b132
    if (res == SECFailure) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    res = PK11_DigestOp(pk11cx, msg->data, msg->len);
Packit 40b132
    if (res == SECFailure) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    res = PK11_DigestFinal(pk11cx, mac->data, &mac->len, SHA1_LENGTH);
Packit 40b132
    if (res == SECFailure) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PK11_DestroyContext(pk11cx, PR_TRUE);
Packit 40b132
    pk11cx = NULL;
Packit 40b132
Packit 40b132
loser:
Packit 40b132
Packit 40b132
    if(res != SECSuccess) {
Packit 40b132
	SECITEM_ZfreeItem(mac, PR_TRUE);
Packit 40b132
	mac = NULL;
Packit 40b132
	if (pk11cx) {
Packit 40b132
	    PK11_DestroyContext(pk11cx, PR_TRUE);
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return mac;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* compute the thumbprint of the DER cert and create a digest info
Packit 40b132
 * to store it in and return the digest info.
Packit 40b132
 * a return of NULL indicates an error.
Packit 40b132
 */
Packit 40b132
SGNDigestInfo *
Packit 40b132
sec_pkcs12_compute_thumbprint(SECItem *der_cert)
Packit 40b132
{
Packit 40b132
    SGNDigestInfo *thumb = NULL;
Packit 40b132
    SECItem digest;
Packit 40b132
    PLArenaPool *temparena = NULL;
Packit 40b132
    SECStatus rv = SECFailure;
Packit 40b132
Packit 40b132
    if(der_cert == NULL)
Packit 40b132
	return NULL;
Packit 40b132
Packit 40b132
    temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
Packit 40b132
    if(temparena == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    digest.data = (unsigned char *)PORT_ArenaZAlloc(temparena,
Packit 40b132
						    sizeof(unsigned char) * 
Packit 40b132
						    SHA1_LENGTH);
Packit 40b132
    /* digest data and create digest info */
Packit 40b132
    if(digest.data != NULL) {
Packit 40b132
	digest.len = SHA1_LENGTH;
Packit 40b132
	rv = PK11_HashBuf(SEC_OID_SHA1, digest.data, der_cert->data, 
Packit 40b132
	                  der_cert->len);
Packit 40b132
	if(rv == SECSuccess) {
Packit 40b132
	    thumb = SGN_CreateDigestInfo(SEC_OID_SHA1, 
Packit 40b132
					 digest.data, 
Packit 40b132
					 digest.len);
Packit 40b132
	} else {
Packit 40b132
	    PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	}
Packit 40b132
    } else {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PORT_FreeArena(temparena, PR_TRUE);
Packit 40b132
Packit 40b132
    return thumb;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* create a virtual password per PKCS 12, the password is converted
Packit 40b132
 * to unicode, the salt is prepended to it, and then the whole thing
Packit 40b132
 * is returned */
Packit 40b132
SECItem *
Packit 40b132
sec_pkcs12_create_virtual_password(SECItem *password, SECItem *salt,
Packit 40b132
				   PRBool swap)
Packit 40b132
{
Packit 40b132
    SECItem uniPwd = {siBuffer, NULL,0}, *retPwd = NULL;
Packit 40b132
Packit 40b132
    if((password == NULL) || (salt == NULL)) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(password->len == 0) {
Packit 40b132
	uniPwd.data = (unsigned char*)PORT_ZAlloc(2);
Packit 40b132
	uniPwd.len = 2;
Packit 40b132
	if(!uniPwd.data) {
Packit 40b132
	    return NULL;
Packit 40b132
	}
Packit 40b132
    } else {
Packit 40b132
	uniPwd.data = (unsigned char*)PORT_ZAlloc(password->len * 3);
Packit 40b132
	uniPwd.len = password->len * 3;
Packit 40b132
	if(!PORT_UCS2_ASCIIConversion(PR_TRUE, password->data, password->len,
Packit 40b132
				uniPwd.data, uniPwd.len, &uniPwd.len, swap)) {
Packit 40b132
	    SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
Packit 40b132
	    return NULL;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    retPwd = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
Packit 40b132
    if(retPwd == NULL) {
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    /* allocate space and copy proper data */
Packit 40b132
    retPwd->len = uniPwd.len + salt->len;
Packit 40b132
    retPwd->data = (unsigned char *)PORT_Alloc(retPwd->len);
Packit 40b132
    if(retPwd->data == NULL) {
Packit 40b132
	PORT_Free(retPwd);
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PORT_Memcpy(retPwd->data, salt->data, salt->len);
Packit 40b132
    PORT_Memcpy((retPwd->data + salt->len), uniPwd.data, uniPwd.len);
Packit 40b132
Packit 40b132
    SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
Packit 40b132
Packit 40b132
    return retPwd;
Packit 40b132
Packit 40b132
loser:
Packit 40b132
    PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
    SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* appends a shrouded key to a key bag.  this is used for exporting
Packit 40b132
 * to store externally wrapped keys.  it is used when importing to convert
Packit 40b132
 * old items to new
Packit 40b132
 */
Packit 40b132
SECStatus 
Packit 40b132
sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
Packit 40b132
				SEC_PKCS12ESPVKItem *espvk)
Packit 40b132
{
Packit 40b132
    int size;
Packit 40b132
    void *mark = NULL, *dummy = NULL;
Packit 40b132
Packit 40b132
    if((bag == NULL) || (espvk == NULL))
Packit 40b132
	return SECFailure;
Packit 40b132
Packit 40b132
    mark = PORT_ArenaMark(bag->poolp);
Packit 40b132
Packit 40b132
    /* grow the list */
Packit 40b132
    size = (bag->nEspvks + 1) * sizeof(SEC_PKCS12ESPVKItem *);
Packit 40b132
    dummy = (SEC_PKCS12ESPVKItem **)PORT_ArenaGrow(bag->poolp,
Packit 40b132
	    				bag->espvks, size, 
Packit 40b132
	    				size + sizeof(SEC_PKCS12ESPVKItem *));
Packit 40b132
    bag->espvks = (SEC_PKCS12ESPVKItem**)dummy;
Packit 40b132
    if(dummy == NULL) {
Packit 40b132
	PORT_SetError(SEC_ERROR_NO_MEMORY);
Packit 40b132
	goto loser;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    bag->espvks[bag->nEspvks] = espvk;
Packit 40b132
    bag->nEspvks++;
Packit 40b132
    bag->espvks[bag->nEspvks] = NULL;
Packit 40b132
Packit 40b132
    PORT_ArenaUnmark(bag->poolp, mark);
Packit 40b132
    return SECSuccess;
Packit 40b132
Packit 40b132
loser:
Packit 40b132
    PORT_ArenaRelease(bag->poolp, mark);
Packit 40b132
    return SECFailure;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* search a certificate list for a nickname, a thumbprint, or both
Packit 40b132
 * within a certificate bag.  if the certificate could not be
Packit 40b132
 * found or an error occurs, NULL is returned;
Packit 40b132
 */
Packit 40b132
static SEC_PKCS12CertAndCRL *
Packit 40b132
sec_pkcs12_find_cert_in_certbag(SEC_PKCS12CertAndCRLBag *certbag,
Packit 40b132
				SECItem *nickname, SGNDigestInfo *thumbprint)
Packit 40b132
{
Packit 40b132
    PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
Packit 40b132
    int i, j;
Packit 40b132
Packit 40b132
    if((certbag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(thumbprint && nickname) {
Packit 40b132
	search_both = PR_TRUE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(nickname) {
Packit 40b132
	search_nickname = PR_TRUE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
search_again:  
Packit 40b132
    i = 0;
Packit 40b132
    while(certbag->certAndCRLs[i] != NULL) {
Packit 40b132
	SEC_PKCS12CertAndCRL *cert = certbag->certAndCRLs[i];
Packit 40b132
Packit 40b132
	if(SECOID_FindOIDTag(&cert->BagID) == SEC_OID_PKCS12_X509_CERT_CRL_BAG) {
Packit 40b132
Packit 40b132
	    /* check nicknames */
Packit 40b132
	    if(search_nickname) {
Packit 40b132
		if(SECITEM_CompareItem(nickname, &cert->nickname) == SECEqual) {
Packit 40b132
		    return cert;
Packit 40b132
		}
Packit 40b132
	    } else {
Packit 40b132
	    /* check thumbprints */
Packit 40b132
		SECItem **derCertList;
Packit 40b132
Packit 40b132
		/* get pointer to certificate list, does not need to
Packit 40b132
		 * be freed since it is within the arena which will
Packit 40b132
		 * be freed later.
Packit 40b132
		 */
Packit 40b132
		derCertList = SEC_PKCS7GetCertificateList(&cert->value.x509->certOrCRL);
Packit 40b132
		j = 0;
Packit 40b132
		if(derCertList != NULL) {
Packit 40b132
		    while(derCertList[j] != NULL) {
Packit 40b132
			SECComparison eq;
Packit 40b132
			SGNDigestInfo *di;
Packit 40b132
			di = sec_pkcs12_compute_thumbprint(derCertList[j]);
Packit 40b132
			if(di) {
Packit 40b132
			    eq = SGN_CompareDigestInfo(thumbprint, di);
Packit 40b132
			    SGN_DestroyDigestInfo(di);
Packit 40b132
			    if(eq == SECEqual) {
Packit 40b132
				/* copy the derCert for later reference */
Packit 40b132
				cert->value.x509->derLeafCert = derCertList[j];
Packit 40b132
				return cert;
Packit 40b132
			    }
Packit 40b132
			} else {
Packit 40b132
			    /* an error occurred */
Packit 40b132
			    return NULL;
Packit 40b132
			}
Packit 40b132
			j++;
Packit 40b132
		    }
Packit 40b132
		}
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
Packit 40b132
	i++;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(search_both) {
Packit 40b132
	search_both = PR_FALSE;
Packit 40b132
	search_nickname = PR_FALSE;
Packit 40b132
	goto search_again;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* search a key list for a nickname, a thumbprint, or both
Packit 40b132
 * within a key bag.  if the key could not be
Packit 40b132
 * found or an error occurs, NULL is returned;
Packit 40b132
 */
Packit 40b132
static SEC_PKCS12PrivateKey *
Packit 40b132
sec_pkcs12_find_key_in_keybag(SEC_PKCS12PrivateKeyBag *keybag,
Packit 40b132
			      SECItem *nickname, SGNDigestInfo *thumbprint)
Packit 40b132
{
Packit 40b132
    PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
Packit 40b132
    int i, j;
Packit 40b132
Packit 40b132
    if((keybag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(keybag->privateKeys == NULL) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(thumbprint && nickname) {
Packit 40b132
	search_both = PR_TRUE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(nickname) {
Packit 40b132
	search_nickname = PR_TRUE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
search_again:  
Packit 40b132
    i = 0;
Packit 40b132
    while(keybag->privateKeys[i] != NULL) {
Packit 40b132
	SEC_PKCS12PrivateKey *key = keybag->privateKeys[i];
Packit 40b132
Packit 40b132
	/* check nicknames */
Packit 40b132
	if(search_nickname) {
Packit 40b132
	    if(SECITEM_CompareItem(nickname, &key->pvkData.nickname) == SECEqual) {
Packit 40b132
		return key;
Packit 40b132
	    }
Packit 40b132
	} else {
Packit 40b132
	    /* check digests */
Packit 40b132
	    SGNDigestInfo **assocCerts = key->pvkData.assocCerts;
Packit 40b132
	    if((assocCerts == NULL) || (assocCerts[0] == NULL)) {
Packit 40b132
		return NULL;
Packit 40b132
	    }
Packit 40b132
Packit 40b132
	    j = 0;
Packit 40b132
	    while(assocCerts[j] != NULL) {
Packit 40b132
		SECComparison eq;
Packit 40b132
		eq = SGN_CompareDigestInfo(thumbprint, assocCerts[j]);
Packit 40b132
		if(eq == SECEqual) {
Packit 40b132
		    return key;
Packit 40b132
		}
Packit 40b132
		j++;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
	i++;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(search_both) {
Packit 40b132
	search_both = PR_FALSE;
Packit 40b132
	search_nickname = PR_FALSE;
Packit 40b132
	goto search_again;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* seach the safe first then try the baggage bag 
Packit 40b132
 *  safe and bag contain certs and keys to search
Packit 40b132
 *  objType is the object type to look for
Packit 40b132
 *  bagType is the type of bag that was found by sec_pkcs12_find_object
Packit 40b132
 *  index is the entity in safe->safeContents or bag->unencSecrets which
Packit 40b132
 *    is being searched
Packit 40b132
 *  nickname and thumbprint are the search criteria
Packit 40b132
 * 
Packit 40b132
 * a return of null indicates no match
Packit 40b132
 */
Packit 40b132
static void *
Packit 40b132
sec_pkcs12_try_find(SEC_PKCS12SafeContents *safe,
Packit 40b132
		  SEC_PKCS12BaggageItem *bag,
Packit 40b132
		  SECOidTag objType, SECOidTag bagType, int index,
Packit 40b132
		  SECItem *nickname, SGNDigestInfo *thumbprint)
Packit 40b132
{
Packit 40b132
    PRBool searchSafe;
Packit 40b132
    int i = index;
Packit 40b132
Packit 40b132
    if((safe == NULL) && (bag == NULL)) {
Packit 40b132
	return NULL;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    searchSafe = (safe == NULL ? PR_FALSE : PR_TRUE);
Packit 40b132
    switch(objType) {
Packit 40b132
	case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
Packit 40b132
	    if(objType == bagType) {
Packit 40b132
		SEC_PKCS12CertAndCRLBag *certBag;
Packit 40b132
Packit 40b132
		if(searchSafe) {
Packit 40b132
		    certBag = safe->contents[i]->safeContent.certAndCRLBag;
Packit 40b132
		} else {
Packit 40b132
		    certBag = bag->unencSecrets[i]->safeContent.certAndCRLBag;
Packit 40b132
		}
Packit 40b132
		return sec_pkcs12_find_cert_in_certbag(certBag, nickname, 
Packit 40b132
							thumbprint);
Packit 40b132
	    }
Packit 40b132
	    break;
Packit 40b132
	case SEC_OID_PKCS12_KEY_BAG_ID:
Packit 40b132
	    if(objType == bagType) {
Packit 40b132
		SEC_PKCS12PrivateKeyBag *keyBag;
Packit 40b132
Packit 40b132
		if(searchSafe) {
Packit 40b132
		    keyBag = safe->contents[i]->safeContent.keyBag;
Packit 40b132
		} else {
Packit 40b132
		    keyBag = bag->unencSecrets[i]->safeContent.keyBag;
Packit 40b132
		}
Packit 40b132
		return sec_pkcs12_find_key_in_keybag(keyBag, nickname, 
Packit 40b132
							 thumbprint);
Packit 40b132
	    }
Packit 40b132
	    break;
Packit 40b132
	default:
Packit 40b132
	    break;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* searches both the baggage and the safe areas looking for
Packit 40b132
 * object of specified type matching either the nickname or the 
Packit 40b132
 * thumbprint specified.
Packit 40b132
 *
Packit 40b132
 * safe and baggage store certs and keys
Packit 40b132
 * objType is the OID for the bag type to be searched:
Packit 40b132
 *   SEC_OID_PKCS12_KEY_BAG_ID, or 
Packit 40b132
 *   SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID
Packit 40b132
 * nickname and thumbprint are the search criteria
Packit 40b132
 * 
Packit 40b132
 * if no match found, NULL returned and error set
Packit 40b132
 */
Packit 40b132
void *
Packit 40b132
sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
Packit 40b132
			SEC_PKCS12Baggage *baggage,
Packit 40b132
			SECOidTag objType,
Packit 40b132
			SECItem *nickname,
Packit 40b132
			SGNDigestInfo *thumbprint)
Packit 40b132
{
Packit 40b132
    int i, j;
Packit 40b132
    void *retItem;
Packit 40b132
   
Packit 40b132
    if(((safe == NULL) && (thumbprint == NULL)) ||
Packit 40b132
       ((nickname == NULL) && (thumbprint == NULL))) {
Packit 40b132
	return NULL;
Packit 40b132
    }    
Packit 40b132
Packit 40b132
    i = 0;
Packit 40b132
    if((safe != NULL) && (safe->contents != NULL)) {
Packit 40b132
	while(safe->contents[i] != NULL) {
Packit 40b132
	    SECOidTag bagType = SECOID_FindOIDTag(&safe->contents[i]->safeBagType);
Packit 40b132
	    retItem = sec_pkcs12_try_find(safe, NULL, objType, bagType, i,
Packit 40b132
	    				  nickname, thumbprint);
Packit 40b132
	    if(retItem != NULL) {
Packit 40b132
		return retItem;
Packit 40b132
	    }
Packit 40b132
	    i++;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if((baggage != NULL) && (baggage->bags != NULL)) {
Packit 40b132
	i = 0;
Packit 40b132
	while(baggage->bags[i] != NULL) {
Packit 40b132
	    SEC_PKCS12BaggageItem *xbag = baggage->bags[i];
Packit 40b132
	    j = 0;
Packit 40b132
	    if(xbag->unencSecrets != NULL) {
Packit 40b132
		while(xbag->unencSecrets[j] != NULL) {
Packit 40b132
		    SECOidTag bagType;
Packit 40b132
		    bagType = SECOID_FindOIDTag(&xbag->unencSecrets[j]->safeBagType);
Packit 40b132
		    retItem = sec_pkcs12_try_find(NULL, xbag, objType, bagType,
Packit 40b132
		    				  j, nickname, thumbprint);
Packit 40b132
		    if(retItem != NULL) {
Packit 40b132
			return retItem;
Packit 40b132
		    }
Packit 40b132
		    j++;
Packit 40b132
		}
Packit 40b132
	    }
Packit 40b132
	    i++;
Packit 40b132
	}
Packit 40b132
    }
Packit 40b132
Packit 40b132
    PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME);
Packit 40b132
    return NULL;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* this function converts a password to unicode and encures that the 
Packit 40b132
 * required double 0 byte be placed at the end of the string
Packit 40b132
 */
Packit 40b132
PRBool
Packit 40b132
sec_pkcs12_convert_item_to_unicode(PLArenaPool *arena, SECItem *dest,
Packit 40b132
				   SECItem *src, PRBool zeroTerm,
Packit 40b132
				   PRBool asciiConvert, PRBool toUnicode)
Packit 40b132
{
Packit 40b132
    PRBool success = PR_FALSE;
Packit 40b132
    if(!src || !dest) {
Packit 40b132
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
Packit 40b132
	return PR_FALSE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    dest->len = src->len * 3 + 2;
Packit 40b132
    if(arena) {
Packit 40b132
	dest->data = (unsigned char*)PORT_ArenaZAlloc(arena, dest->len);
Packit 40b132
    } else {
Packit 40b132
	dest->data = (unsigned char*)PORT_ZAlloc(dest->len);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(!dest->data) {
Packit 40b132
	dest->len = 0;
Packit 40b132
	return PR_FALSE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(!asciiConvert) {
Packit 40b132
	success = PORT_UCS2_UTF8Conversion(toUnicode, src->data, src->len, dest->data,
Packit 40b132
					   dest->len, &dest->len);
Packit 40b132
    } else {
Packit 40b132
#ifndef IS_LITTLE_ENDIAN
Packit 40b132
	PRBool swapUnicode = PR_FALSE;
Packit 40b132
#else
Packit 40b132
	PRBool swapUnicode = PR_TRUE;
Packit 40b132
#endif
Packit 40b132
	success = PORT_UCS2_ASCIIConversion(toUnicode, src->data, src->len, dest->data,
Packit 40b132
					    dest->len, &dest->len, swapUnicode);
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if(!success) {
Packit 40b132
	if(!arena) {
Packit 40b132
	    PORT_Free(dest->data);
Packit 40b132
	    dest->data = NULL;
Packit 40b132
	    dest->len = 0;
Packit 40b132
	}
Packit 40b132
	return PR_FALSE;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    if ((dest->len >= 2) &&
Packit 40b132
	(dest->data[dest->len-1] || dest->data[dest->len-2]) && zeroTerm) {
Packit 40b132
	if(dest->len + 2 > 3 * src->len) {
Packit 40b132
	    if(arena) {
Packit 40b132
		dest->data = (unsigned char*)PORT_ArenaGrow(arena, 
Packit 40b132
						     dest->data, dest->len,
Packit 40b132
						     dest->len + 2);
Packit 40b132
	    } else {
Packit 40b132
		dest->data = (unsigned char*)PORT_Realloc(dest->data, 
Packit 40b132
							  dest->len + 2);
Packit 40b132
	    }
Packit 40b132
Packit 40b132
	    if(!dest->data) {
Packit 40b132
		return PR_FALSE;
Packit 40b132
	    }
Packit 40b132
	}
Packit 40b132
	dest->len += 2;
Packit 40b132
	dest->data[dest->len-1] = dest->data[dest->len-2] = 0;
Packit 40b132
    }
Packit 40b132
Packit 40b132
    return PR_TRUE;
Packit 40b132
}
Packit 40b132
Packit 40b132
/* pkcs 12 templates */
Packit 40b132
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_shroud_chooser =
Packit 40b132
    sec_pkcs12_choose_shroud_type;
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CodedSafeBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
Packit 40b132
    { SEC_ASN1_ANY, offsetof(SEC_PKCS12SafeBag, derSafeContent) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CodedCertBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
Packit 40b132
    { SEC_ASN1_ANY, offsetof(SEC_PKCS12CertAndCRL, derValue) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CodedCertAndCRLBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
Packit 40b132
	SEC_PKCS12CodedCertBagTemplate },
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate_OLD[] = 
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12ESPVKItem) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12ESPVKItem, espvkOID) },
Packit 40b132
    { SEC_ASN1_INLINE, offsetof(SEC_PKCS12ESPVKItem, espvkData),
Packit 40b132
	SEC_PKCS12PVKSupportingDataTemplate_OLD },
Packit 40b132
    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
Packit 40b132
	SEC_ASN1_DYNAMIC | 0, offsetof(SEC_PKCS12ESPVKItem, espvkCipherText),
Packit 40b132
	&sec_pkcs12_shroud_chooser },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate[] = 
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12ESPVKItem) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12ESPVKItem, espvkOID) },
Packit 40b132
    { SEC_ASN1_INLINE, offsetof(SEC_PKCS12ESPVKItem, espvkData),
Packit 40b132
	SEC_PKCS12PVKSupportingDataTemplate },
Packit 40b132
    { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
Packit 40b132
	SEC_ASN1_DYNAMIC | 0, offsetof(SEC_PKCS12ESPVKItem, espvkCipherText),
Packit 40b132
	&sec_pkcs12_shroud_chooser },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PVKAdditionalDataTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKAdditionalData) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, 
Packit 40b132
	offsetof(SEC_PKCS12PVKAdditionalData, pvkAdditionalType) },
Packit 40b132
    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
Packit 40b132
	offsetof(SEC_PKCS12PVKAdditionalData, pvkAdditionalContent) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKSupportingData) },
Packit 40b132
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN , 
Packit 40b132
        offsetof(SEC_PKCS12PVKSupportingData, assocCerts),
Packit 40b132
	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, 
Packit 40b132
	offsetof(SEC_PKCS12PVKSupportingData, regenerable) },
Packit 40b132
    { SEC_ASN1_PRINTABLE_STRING, 
Packit 40b132
	offsetof(SEC_PKCS12PVKSupportingData, nickname) },
Packit 40b132
    { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
Packit 40b132
	offsetof(SEC_PKCS12PVKSupportingData, pvkAdditionalDER) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKSupportingData) },
Packit 40b132
    { SEC_ASN1_SET_OF | SEC_ASN1_XTRN , 
Packit 40b132
        offsetof(SEC_PKCS12PVKSupportingData, assocCerts),
Packit 40b132
	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, 
Packit 40b132
	offsetof(SEC_PKCS12PVKSupportingData, regenerable) },
Packit 40b132
    { SEC_ASN1_BMP_STRING, 
Packit 40b132
	offsetof(SEC_PKCS12PVKSupportingData, uniNickName) },
Packit 40b132
    { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
Packit 40b132
	offsetof(SEC_PKCS12PVKSupportingData, pvkAdditionalDER) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12BaggageItemTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12BaggageItem) },
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, espvks),
Packit 40b132
	SEC_PKCS12ESPVKItemTemplate },
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, unencSecrets),
Packit 40b132
	SEC_PKCS12SafeBagTemplate },
Packit 40b132
    /*{ SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, unencSecrets),
Packit 40b132
	SEC_PKCS12CodedSafeBagTemplate }, */
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12BaggageTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12Baggage, bags),
Packit 40b132
	SEC_PKCS12BaggageItemTemplate },
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12BaggageTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12Baggage_OLD, espvks),
Packit 40b132
	SEC_PKCS12ESPVKItemTemplate_OLD },
Packit 40b132
};
Packit 40b132
Packit 40b132
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser =
Packit 40b132
	sec_pkcs12_choose_bag_type;
Packit 40b132
Packit 40b132
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser_old =
Packit 40b132
	sec_pkcs12_choose_bag_type_old;
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SafeBagTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
Packit 40b132
    { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
Packit 40b132
	SEC_ASN1_CONTEXT_SPECIFIC | 0,
Packit 40b132
        offsetof(SEC_PKCS12SafeBag, safeContent),
Packit 40b132
	&sec_pkcs12_bag_chooser_old },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SafeBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
Packit 40b132
    { SEC_ASN1_DYNAMIC | SEC_ASN1_POINTER,
Packit 40b132
        offsetof(SEC_PKCS12SafeBag, safeContent),
Packit 40b132
	&sec_pkcs12_bag_chooser },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BMP_STRING,
Packit 40b132
	offsetof(SEC_PKCS12SafeBag, uniSafeBagName) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF,
Packit 40b132
	offsetof(SEC_PKCS12SafeContents, contents),
Packit 40b132
	SEC_PKCS12SafeBagTemplate_OLD }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF,
Packit 40b132
	offsetof(SEC_PKCS12SafeContents, contents),
Packit 40b132
	SEC_PKCS12SafeBagTemplate }  /* here */
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PrivateKeyTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PrivateKey) },
Packit 40b132
    { SEC_ASN1_INLINE, offsetof(SEC_PKCS12PrivateKey, pvkData),
Packit 40b132
	SEC_PKCS12PVKSupportingDataTemplate },
Packit 40b132
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 
Packit 40b132
        offsetof(SEC_PKCS12PrivateKey, pkcs8data),
Packit 40b132
	SEC_ASN1_SUB(SECKEY_PrivateKeyInfoTemplate) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PrivateKeyBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PrivateKeyBag) },
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12PrivateKeyBag, privateKeys),
Packit 40b132
	SEC_PKCS12PrivateKeyTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
Packit 40b132
    { SEC_ASN1_INLINE, offsetof(SEC_PKCS12X509CertCRL, certOrCRL),
Packit 40b132
	sec_PKCS7ContentInfoTemplate },
Packit 40b132
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN , 
Packit 40b132
        offsetof(SEC_PKCS12X509CertCRL, thumbprint),
Packit 40b132
	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
Packit 40b132
    { SEC_ASN1_INLINE, offsetof(SEC_PKCS12X509CertCRL, certOrCRL),
Packit 40b132
	sec_PKCS7ContentInfoTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SDSICertTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
Packit 40b132
    { SEC_ASN1_IA5_STRING, offsetof(SEC_PKCS12SDSICert, value) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser_old =
Packit 40b132
	sec_pkcs12_choose_cert_crl_type_old;
Packit 40b132
Packit 40b132
static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser =
Packit 40b132
	sec_pkcs12_choose_cert_crl_type;
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
Packit 40b132
    { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT |
Packit 40b132
	SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | 0,
Packit 40b132
	offsetof(SEC_PKCS12CertAndCRL, value),
Packit 40b132
	&sec_pkcs12_cert_crl_chooser_old },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
Packit 40b132
    { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
Packit 40b132
	SEC_ASN1_CONTEXT_SPECIFIC | 0, 
Packit 40b132
	offsetof(SEC_PKCS12CertAndCRL, value),
Packit 40b132
	&sec_pkcs12_cert_crl_chooser },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
Packit 40b132
	SEC_PKCS12CertAndCRLTemplate },
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRLBag) },
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
Packit 40b132
	SEC_PKCS12CertAndCRLTemplate_OLD },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SecretAdditionalTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SecretAdditional) },
Packit 40b132
    { SEC_ASN1_OBJECT_ID,
Packit 40b132
	offsetof(SEC_PKCS12SecretAdditional, secretAdditionalType) },
Packit 40b132
    { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT,
Packit 40b132
	offsetof(SEC_PKCS12SecretAdditional, secretAdditionalContent) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SecretTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12Secret) },
Packit 40b132
    { SEC_ASN1_BMP_STRING, offsetof(SEC_PKCS12Secret, uniSecretName) },
Packit 40b132
    { SEC_ASN1_ANY, offsetof(SEC_PKCS12Secret, value) },
Packit 40b132
    { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
Packit 40b132
	offsetof(SEC_PKCS12Secret, secretAdditional),
Packit 40b132
	SEC_PKCS12SecretAdditionalTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SecretItemTemplate[] = 
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12Secret) },
Packit 40b132
    { SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 0,
Packit 40b132
	offsetof(SEC_PKCS12SecretItem, secret), SEC_PKCS12SecretTemplate },
Packit 40b132
    { SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 1,
Packit 40b132
	offsetof(SEC_PKCS12SecretItem, subFolder), SEC_PKCS12SafeBagTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12SecretBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12SecretBag, secrets),
Packit 40b132
	SEC_PKCS12SecretItemTemplate },
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12MacDataTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
Packit 40b132
    { SEC_ASN1_INLINE | SEC_ASN1_XTRN , offsetof(SEC_PKCS12MacData, safeMac),
Packit 40b132
	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
Packit 40b132
    { SEC_ASN1_BIT_STRING, offsetof(SEC_PKCS12MacData, macSalt) },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PFXItemTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
Packit 40b132
    { SEC_ASN1_OPTIONAL |
Packit 40b132
	SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 
Packit 40b132
	offsetof(SEC_PKCS12PFXItem, macData), SEC_PKCS12MacDataTemplate },
Packit 40b132
    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 
Packit 40b132
	offsetof(SEC_PKCS12PFXItem, authSafe), 
Packit 40b132
	sec_PKCS7ContentInfoTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12PFXItemTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
Packit 40b132
    { SEC_ASN1_OPTIONAL |
Packit 40b132
	SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 
Packit 40b132
	offsetof(SEC_PKCS12PFXItem, old_safeMac), 
Packit 40b132
	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING,
Packit 40b132
	offsetof(SEC_PKCS12PFXItem, old_macSalt) },
Packit 40b132
    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 
Packit 40b132
	offsetof(SEC_PKCS12PFXItem, authSafe), 
Packit 40b132
	sec_PKCS7ContentInfoTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12AuthenticatedSafe) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, 
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, version) }, 
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_OBJECT_ID,
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, transportMode) },
Packit 40b132
    { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL,
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, privacySalt) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_SET_OF, 
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, baggage.bags), 
Packit 40b132
	SEC_PKCS12BaggageItemTemplate },
Packit 40b132
    { SEC_ASN1_POINTER,
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, safe),
Packit 40b132
	sec_PKCS7ContentInfoTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12AuthenticatedSafe) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, 
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, version) }, 
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, transportMode) },
Packit 40b132
    { SEC_ASN1_BIT_STRING,
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, privacySalt) },
Packit 40b132
    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
Packit 40b132
    	SEC_ASN1_CONTEXT_SPECIFIC | 0, 
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, old_baggage), 
Packit 40b132
	SEC_PKCS12BaggageTemplate_OLD },
Packit 40b132
    { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
Packit 40b132
	offsetof(SEC_PKCS12AuthenticatedSafe, old_safe),
Packit 40b132
	sec_PKCS7ContentInfoTemplate },
Packit 40b132
    { 0 }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12KeyBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12PrivateKeyBagTemplate }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate_OLD }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12SecretBagTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12SecretBagTemplate }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate_OLD[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate_OLD }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate }
Packit 40b132
};
Packit 40b132
Packit 40b132
const SEC_ASN1Template SEC_PointerToPKCS12SDSICertTemplate[] =
Packit 40b132
{
Packit 40b132
    { SEC_ASN1_POINTER, 0, SEC_PKCS12SDSICertTemplate }
Packit 40b132
};
Packit 40b132
Packit 40b132