security/nss/lib/pkcs12/p12local.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nssrenam.h"
     6 #include "pkcs12.h"
     7 #include "secpkcs7.h"
     8 #include "secasn1.h"
     9 #include "seccomon.h"
    10 #include "secoid.h"
    11 #include "sechash.h"
    12 #include "secitem.h"
    13 #include "secerr.h"
    14 #include "pk11func.h"
    15 #include "p12local.h"
    16 #include "p12.h"
    18 #define SALT_LENGTH	16
    20 SEC_ASN1_MKSUB(SECKEY_PrivateKeyInfoTemplate)
    21 SEC_ASN1_MKSUB(sgn_DigestInfoTemplate)
    23 CK_MECHANISM_TYPE
    24 sec_pkcs12_algtag_to_mech(SECOidTag algtag)
    25 {
    26     switch (algtag) {
    27     case SEC_OID_MD2:
    28 	return CKM_MD2_HMAC;
    29     case SEC_OID_MD5:
    30 	return CKM_MD5_HMAC;
    31     case SEC_OID_SHA1:
    32 	return CKM_SHA_1_HMAC;
    33     case SEC_OID_SHA224:
    34 	return CKM_SHA224_HMAC;
    35     case SEC_OID_SHA256:
    36 	return CKM_SHA256_HMAC;
    37     case SEC_OID_SHA384:
    38 	return CKM_SHA384_HMAC;
    39     case SEC_OID_SHA512:
    40 	return CKM_SHA512_HMAC;
    41     default:
    42 	break;
    43     }
    44     return CKM_INVALID_MECHANISM;
    45 }
    47 /* helper functions */
    48 /* returns proper bag type template based upon object type tag */
    49 const SEC_ASN1Template *
    50 sec_pkcs12_choose_bag_type_old(void *src_or_dest, PRBool encoding)
    51 {
    52     const SEC_ASN1Template *theTemplate;
    53     SEC_PKCS12SafeBag *safebag;
    54     SECOidData *oiddata;
    56     if (src_or_dest == NULL) {
    57 	return NULL;
    58     }
    60     safebag = (SEC_PKCS12SafeBag*)src_or_dest;
    62     oiddata = safebag->safeBagTypeTag;
    63     if (oiddata == NULL) {
    64 	oiddata = SECOID_FindOID(&safebag->safeBagType);
    65 	safebag->safeBagTypeTag = oiddata;
    66     }
    68     switch (oiddata->offset) {
    69 	default:
    70 	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
    71 	    break;
    72 	case SEC_OID_PKCS12_KEY_BAG_ID:
    73 	    theTemplate = SEC_PointerToPKCS12KeyBagTemplate;
    74 	    break;
    75 	case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
    76 	    theTemplate = SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD;
    77 	    break;
    78         case SEC_OID_PKCS12_SECRET_BAG_ID:
    79 	    theTemplate = SEC_PointerToPKCS12SecretBagTemplate;
    80 	    break;
    81     }
    82     return theTemplate;
    83 }
    85 const SEC_ASN1Template *
    86 sec_pkcs12_choose_bag_type(void *src_or_dest, PRBool encoding)
    87 {
    88     const SEC_ASN1Template *theTemplate;
    89     SEC_PKCS12SafeBag *safebag;
    90     SECOidData *oiddata;
    92     if (src_or_dest == NULL) {
    93 	return NULL;
    94     }
    96     safebag = (SEC_PKCS12SafeBag*)src_or_dest;
    98     oiddata = safebag->safeBagTypeTag;
    99     if (oiddata == NULL) {
   100 	oiddata = SECOID_FindOID(&safebag->safeBagType);
   101 	safebag->safeBagTypeTag = oiddata;
   102     }
   104     switch (oiddata->offset) {
   105 	default:
   106 	    theTemplate = SEC_ASN1_GET(SEC_AnyTemplate);
   107 	    break;
   108 	case SEC_OID_PKCS12_KEY_BAG_ID:
   109 	    theTemplate = SEC_PKCS12PrivateKeyBagTemplate;
   110 	    break;
   111 	case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
   112 	    theTemplate = SEC_PKCS12CertAndCRLBagTemplate;
   113 	    break;
   114         case SEC_OID_PKCS12_SECRET_BAG_ID:
   115 	    theTemplate = SEC_PKCS12SecretBagTemplate;
   116 	    break;
   117     }
   118     return theTemplate;
   119 }
   121 /* returns proper cert crl template based upon type tag */
   122 const SEC_ASN1Template *
   123 sec_pkcs12_choose_cert_crl_type_old(void *src_or_dest, PRBool encoding)
   124 {
   125     const SEC_ASN1Template *theTemplate;
   126     SEC_PKCS12CertAndCRL *certbag;
   127     SECOidData *oiddata;
   129     if (src_or_dest == NULL) {
   130 	return NULL;
   131     }
   133     certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
   134     oiddata = certbag->BagTypeTag;
   135     if (oiddata == NULL) {
   136 	oiddata = SECOID_FindOID(&certbag->BagID);
   137 	certbag->BagTypeTag = oiddata;
   138     }
   140     switch (oiddata->offset) {
   141 	default:
   142 	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
   143 	    break;
   144 	case SEC_OID_PKCS12_X509_CERT_CRL_BAG:
   145 	    theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate_OLD;
   146 	    break;
   147 	case SEC_OID_PKCS12_SDSI_CERT_BAG:
   148 	    theTemplate = SEC_PointerToPKCS12SDSICertTemplate;
   149 	    break;
   150     }
   151     return theTemplate;
   152 }
   154 const SEC_ASN1Template *
   155 sec_pkcs12_choose_cert_crl_type(void *src_or_dest, PRBool encoding)
   156 {
   157     const SEC_ASN1Template *theTemplate;
   158     SEC_PKCS12CertAndCRL *certbag;
   159     SECOidData *oiddata;
   161     if (src_or_dest == NULL) {
   162 	return NULL;
   163     }
   165     certbag = (SEC_PKCS12CertAndCRL*)src_or_dest;
   166     oiddata = certbag->BagTypeTag;
   167     if (oiddata == NULL) {
   168 	oiddata = SECOID_FindOID(&certbag->BagID);
   169 	certbag->BagTypeTag = oiddata;
   170     }
   172     switch (oiddata->offset) {
   173 	default:
   174 	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
   175 	    break;
   176 	case SEC_OID_PKCS12_X509_CERT_CRL_BAG:
   177 	    theTemplate = SEC_PointerToPKCS12X509CertCRLTemplate;
   178 	    break;
   179 	case SEC_OID_PKCS12_SDSI_CERT_BAG:
   180 	    theTemplate = SEC_PointerToPKCS12SDSICertTemplate;
   181 	    break;
   182     }
   183     return theTemplate;
   184 }
   186 /* returns appropriate shroud template based on object type tag */
   187 const SEC_ASN1Template *
   188 sec_pkcs12_choose_shroud_type(void *src_or_dest, PRBool encoding)
   189 {
   190     const SEC_ASN1Template *theTemplate;
   191     SEC_PKCS12ESPVKItem *espvk;
   192     SECOidData *oiddata;
   194     if (src_or_dest == NULL) {
   195 	return NULL;
   196     }
   198     espvk = (SEC_PKCS12ESPVKItem*)src_or_dest;
   199     oiddata = espvk->espvkTag;
   200     if (oiddata == NULL) {
   201 	oiddata = SECOID_FindOID(&espvk->espvkOID);
   202  	espvk->espvkTag = oiddata;
   203     }
   205     switch (oiddata->offset) {
   206 	default:
   207 	    theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
   208 	    break;
   209 	case SEC_OID_PKCS12_PKCS8_KEY_SHROUDING:
   210 	   theTemplate = 
   211 		SEC_ASN1_GET(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate);
   212 	    break;
   213     }
   214     return theTemplate;
   215 }
   217 /* generate SALT  placing it into the character array passed in.
   218  * it is assumed that salt_dest is an array of appropriate size
   219  * XXX We might want to generate our own random context
   220  */
   221 SECItem *
   222 sec_pkcs12_generate_salt(void)
   223 {
   224     SECItem *salt;
   226     salt = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
   227     if(salt == NULL) {
   228 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   229 	return NULL;
   230     }
   231     salt->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) * 
   232 					      SALT_LENGTH);
   233     salt->len = SALT_LENGTH;
   234     if(salt->data == NULL) {
   235 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   236 	SECITEM_ZfreeItem(salt, PR_TRUE);
   237 	return NULL;
   238     }
   240     PK11_GenerateRandom(salt->data, salt->len);
   242     return salt;
   243 }
   245 /* generate KEYS -- as per PKCS12 section 7.  
   246  * only used for MAC
   247  */
   248 SECItem *
   249 sec_pkcs12_generate_key_from_password(SECOidTag algorithm, 
   250 				      SECItem *salt, 
   251 				      SECItem *password) 
   252 {
   253     unsigned char *pre_hash=NULL;
   254     unsigned char *hash_dest=NULL;
   255     SECStatus res;
   256     PLArenaPool *poolp;
   257     SECItem *key = NULL;
   258     int key_len = 0;
   260     if((salt == NULL) || (password == NULL)) {
   261 	return NULL;
   262     }
   264     poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   265     if(poolp == NULL) {
   266 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   267 	return NULL;
   268     }
   270     pre_hash = (unsigned char *)PORT_ArenaZAlloc(poolp, sizeof(char) * 
   271 						 (salt->len+password->len));
   272     if(pre_hash == NULL) {
   273 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   274 	goto loser;
   275     }
   277     hash_dest = (unsigned char *)PORT_ArenaZAlloc(poolp, 
   278 					sizeof(unsigned char) * SHA1_LENGTH);
   279     if(hash_dest == NULL) {
   280 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   281 	goto loser;
   282     }
   284     PORT_Memcpy(pre_hash, salt->data, salt->len);
   285     /* handle password of 0 length case */
   286     if(password->len > 0) {
   287 	PORT_Memcpy(&(pre_hash[salt->len]), password->data, password->len);
   288     }
   290     res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, pre_hash, 
   291                        (salt->len+password->len));
   292     if(res == SECFailure) {
   293 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   294 	goto loser;
   295     }
   297     switch(algorithm) {
   298 	case SEC_OID_SHA1:
   299 	    if(key_len == 0)
   300 		key_len = 16;
   301 	    key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
   302 	    if(key == NULL) {
   303 		PORT_SetError(SEC_ERROR_NO_MEMORY);
   304 		goto loser;
   305 	    }
   306 	    key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) 
   307 						     * key_len);
   308 	    if(key->data == NULL) {
   309 		PORT_SetError(SEC_ERROR_NO_MEMORY);
   310 		goto loser;
   311 	    }
   312 	    key->len = key_len;
   313 	    PORT_Memcpy(key->data, &hash_dest[SHA1_LENGTH-key->len], key->len);
   314 	    break;
   315 	default:
   316 	    goto loser;
   317 	    break;
   318     }
   320     PORT_FreeArena(poolp, PR_TRUE);
   321     return key;
   323 loser:
   324     PORT_FreeArena(poolp, PR_TRUE);
   325     if(key != NULL) {
   326 	SECITEM_ZfreeItem(key, PR_TRUE);
   327     }
   328     return NULL;
   329 }
   331 /* MAC is generated per PKCS 12 section 6.  It is expected that key, msg
   332  * and mac_dest are pre allocated, non-NULL arrays.  msg_len is passed in
   333  * because it is not known how long the message actually is.  String
   334  * manipulation routines will not necessarily work because msg may have
   335  * imbedded NULLs
   336  */
   337 static SECItem *
   338 sec_pkcs12_generate_old_mac(SECItem *key, 
   339 			    SECItem *msg)
   340 {
   341     SECStatus res;
   342     PLArenaPool *temparena = NULL;
   343     unsigned char *hash_dest=NULL, *hash_src1=NULL, *hash_src2 = NULL;
   344     int i;
   345     SECItem *mac = NULL;
   347     if((key == NULL) || (msg == NULL))
   348         goto loser;
   350     /* allocate return item */
   351     mac = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
   352     if(mac == NULL)
   353     	return NULL;
   354     mac->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char)
   355     	* SHA1_LENGTH);
   356     mac->len = SHA1_LENGTH;
   357     if(mac->data == NULL)
   358 	goto loser;
   360     /* allocate temporary items */
   361     temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   362     if(temparena == NULL)
   363 	goto loser;
   365     hash_src1 = (unsigned char *)PORT_ArenaZAlloc(temparena,
   366     	sizeof(unsigned char) * (16+msg->len));
   367     if(hash_src1 == NULL)
   368         goto loser;
   370     hash_src2 = (unsigned char *)PORT_ArenaZAlloc(temparena,
   371    	sizeof(unsigned char) * (SHA1_LENGTH+16));
   372     if(hash_src2 == NULL)
   373         goto loser;
   375     hash_dest = (unsigned char *)PORT_ArenaZAlloc(temparena, 
   376    	sizeof(unsigned char) * SHA1_LENGTH);
   377     if(hash_dest == NULL)
   378         goto loser;
   380     /* perform mac'ing as per PKCS 12 */
   382     /* first round of hashing */
   383     for(i = 0; i < 16; i++)
   384 	hash_src1[i] = key->data[i] ^ 0x36;
   385     PORT_Memcpy(&(hash_src1[16]), msg->data, msg->len);
   386     res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, hash_src1, (16+msg->len));
   387     if(res == SECFailure)
   388 	goto loser;
   390     /* second round of hashing */
   391     for(i = 0; i < 16; i++)
   392 	hash_src2[i] = key->data[i] ^ 0x5c;
   393     PORT_Memcpy(&(hash_src2[16]), hash_dest, SHA1_LENGTH);
   394     res = PK11_HashBuf(SEC_OID_SHA1, mac->data, hash_src2, SHA1_LENGTH+16);
   395     if(res == SECFailure)
   396 	goto loser;
   398     PORT_FreeArena(temparena, PR_TRUE);
   399     return mac;
   401 loser:
   402     if(temparena != NULL)
   403 	PORT_FreeArena(temparena, PR_TRUE);
   404     if(mac != NULL)
   405 	SECITEM_ZfreeItem(mac, PR_TRUE);
   406     return NULL;
   407 }
   409 /* MAC is generated per PKCS 12 section 6.  It is expected that key, msg
   410  * and mac_dest are pre allocated, non-NULL arrays.  msg_len is passed in
   411  * because it is not known how long the message actually is.  String
   412  * manipulation routines will not necessarily work because msg may have
   413  * imbedded NULLs
   414  */
   415 SECItem *
   416 sec_pkcs12_generate_mac(SECItem *key, 
   417 			SECItem *msg,
   418 			PRBool old_method)
   419 {
   420     SECStatus res = SECFailure;
   421     SECItem *mac = NULL;
   422     PK11Context *pk11cx = NULL;    
   423     SECItem ignore = {0};
   425     if((key == NULL) || (msg == NULL)) {
   426 	return NULL;
   427     }
   429     if(old_method == PR_TRUE) {
   430 	return sec_pkcs12_generate_old_mac(key, msg);
   431     }
   433     /* allocate return item */
   434     mac = SECITEM_AllocItem(NULL, NULL, SHA1_LENGTH);
   435     if (mac == NULL) {
   436 	return NULL;
   437     }
   439     pk11cx = PK11_CreateContextByRawKey(NULL, CKM_SHA_1_HMAC, PK11_OriginDerive,
   440                                         CKA_SIGN, key, &ignore, NULL);
   441     if (pk11cx == NULL) {
   442 	goto loser;
   443     }
   445     res = PK11_DigestBegin(pk11cx);
   446     if (res == SECFailure) {
   447 	goto loser;
   448     }
   450     res = PK11_DigestOp(pk11cx, msg->data, msg->len);
   451     if (res == SECFailure) {
   452 	goto loser;
   453     }
   455     res = PK11_DigestFinal(pk11cx, mac->data, &mac->len, SHA1_LENGTH);
   456     if (res == SECFailure) {
   457 	goto loser;
   458     }
   460     PK11_DestroyContext(pk11cx, PR_TRUE);
   461     pk11cx = NULL;
   463 loser:
   465     if(res != SECSuccess) {
   466 	SECITEM_ZfreeItem(mac, PR_TRUE);
   467 	mac = NULL;
   468 	if (pk11cx) {
   469 	    PK11_DestroyContext(pk11cx, PR_TRUE);
   470 	}
   471     }
   473     return mac;
   474 }
   476 /* compute the thumbprint of the DER cert and create a digest info
   477  * to store it in and return the digest info.
   478  * a return of NULL indicates an error.
   479  */
   480 SGNDigestInfo *
   481 sec_pkcs12_compute_thumbprint(SECItem *der_cert)
   482 {
   483     SGNDigestInfo *thumb = NULL;
   484     SECItem digest;
   485     PLArenaPool *temparena = NULL;
   486     SECStatus rv = SECFailure;
   488     if(der_cert == NULL)
   489 	return NULL;
   491     temparena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
   492     if(temparena == NULL) {
   493 	return NULL;
   494     }
   496     digest.data = (unsigned char *)PORT_ArenaZAlloc(temparena,
   497 						    sizeof(unsigned char) * 
   498 						    SHA1_LENGTH);
   499     /* digest data and create digest info */
   500     if(digest.data != NULL) {
   501 	digest.len = SHA1_LENGTH;
   502 	rv = PK11_HashBuf(SEC_OID_SHA1, digest.data, der_cert->data, 
   503 	                  der_cert->len);
   504 	if(rv == SECSuccess) {
   505 	    thumb = SGN_CreateDigestInfo(SEC_OID_SHA1, 
   506 					 digest.data, 
   507 					 digest.len);
   508 	} else {
   509 	    PORT_SetError(SEC_ERROR_NO_MEMORY);
   510 	}
   511     } else {
   512 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   513     }
   515     PORT_FreeArena(temparena, PR_TRUE);
   517     return thumb;
   518 }
   520 /* create a virtual password per PKCS 12, the password is converted
   521  * to unicode, the salt is prepended to it, and then the whole thing
   522  * is returned */
   523 SECItem *
   524 sec_pkcs12_create_virtual_password(SECItem *password, SECItem *salt,
   525 				   PRBool swap)
   526 {
   527     SECItem uniPwd = {siBuffer, NULL,0}, *retPwd = NULL;
   529     if((password == NULL) || (salt == NULL)) {
   530 	return NULL;
   531     }
   533     if(password->len == 0) {
   534 	uniPwd.data = (unsigned char*)PORT_ZAlloc(2);
   535 	uniPwd.len = 2;
   536 	if(!uniPwd.data) {
   537 	    return NULL;
   538 	}
   539     } else {
   540 	uniPwd.data = (unsigned char*)PORT_ZAlloc(password->len * 3);
   541 	uniPwd.len = password->len * 3;
   542 	if(!PORT_UCS2_ASCIIConversion(PR_TRUE, password->data, password->len,
   543 				uniPwd.data, uniPwd.len, &uniPwd.len, swap)) {
   544 	    SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
   545 	    return NULL;
   546 	}
   547     }
   549     retPwd = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
   550     if(retPwd == NULL) {
   551 	goto loser;
   552     }
   554     /* allocate space and copy proper data */
   555     retPwd->len = uniPwd.len + salt->len;
   556     retPwd->data = (unsigned char *)PORT_Alloc(retPwd->len);
   557     if(retPwd->data == NULL) {
   558 	PORT_Free(retPwd);
   559 	goto loser;
   560     }
   562     PORT_Memcpy(retPwd->data, salt->data, salt->len);
   563     PORT_Memcpy((retPwd->data + salt->len), uniPwd.data, uniPwd.len);
   565     SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
   567     return retPwd;
   569 loser:
   570     PORT_SetError(SEC_ERROR_NO_MEMORY);
   571     SECITEM_ZfreeItem(&uniPwd, PR_FALSE);
   572     return NULL;
   573 }
   575 /* appends a shrouded key to a key bag.  this is used for exporting
   576  * to store externally wrapped keys.  it is used when importing to convert
   577  * old items to new
   578  */
   579 SECStatus 
   580 sec_pkcs12_append_shrouded_key(SEC_PKCS12BaggageItem *bag,
   581 				SEC_PKCS12ESPVKItem *espvk)
   582 {
   583     int size;
   584     void *mark = NULL, *dummy = NULL;
   586     if((bag == NULL) || (espvk == NULL))
   587 	return SECFailure;
   589     mark = PORT_ArenaMark(bag->poolp);
   591     /* grow the list */
   592     size = (bag->nEspvks + 1) * sizeof(SEC_PKCS12ESPVKItem *);
   593     dummy = (SEC_PKCS12ESPVKItem **)PORT_ArenaGrow(bag->poolp,
   594 	    				bag->espvks, size, 
   595 	    				size + sizeof(SEC_PKCS12ESPVKItem *));
   596     bag->espvks = (SEC_PKCS12ESPVKItem**)dummy;
   597     if(dummy == NULL) {
   598 	PORT_SetError(SEC_ERROR_NO_MEMORY);
   599 	goto loser;
   600     }
   602     bag->espvks[bag->nEspvks] = espvk;
   603     bag->nEspvks++;
   604     bag->espvks[bag->nEspvks] = NULL;
   606     PORT_ArenaUnmark(bag->poolp, mark);
   607     return SECSuccess;
   609 loser:
   610     PORT_ArenaRelease(bag->poolp, mark);
   611     return SECFailure;
   612 }
   614 /* search a certificate list for a nickname, a thumbprint, or both
   615  * within a certificate bag.  if the certificate could not be
   616  * found or an error occurs, NULL is returned;
   617  */
   618 static SEC_PKCS12CertAndCRL *
   619 sec_pkcs12_find_cert_in_certbag(SEC_PKCS12CertAndCRLBag *certbag,
   620 				SECItem *nickname, SGNDigestInfo *thumbprint)
   621 {
   622     PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
   623     int i, j;
   625     if((certbag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
   626 	return NULL;
   627     }
   629     if(thumbprint && nickname) {
   630 	search_both = PR_TRUE;
   631     }
   633     if(nickname) {
   634 	search_nickname = PR_TRUE;
   635     }
   637 search_again:  
   638     i = 0;
   639     while(certbag->certAndCRLs[i] != NULL) {
   640 	SEC_PKCS12CertAndCRL *cert = certbag->certAndCRLs[i];
   642 	if(SECOID_FindOIDTag(&cert->BagID) == SEC_OID_PKCS12_X509_CERT_CRL_BAG) {
   644 	    /* check nicknames */
   645 	    if(search_nickname) {
   646 		if(SECITEM_CompareItem(nickname, &cert->nickname) == SECEqual) {
   647 		    return cert;
   648 		}
   649 	    } else {
   650 	    /* check thumbprints */
   651 		SECItem **derCertList;
   653 		/* get pointer to certificate list, does not need to
   654 		 * be freed since it is within the arena which will
   655 		 * be freed later.
   656 		 */
   657 		derCertList = SEC_PKCS7GetCertificateList(&cert->value.x509->certOrCRL);
   658 		j = 0;
   659 		if(derCertList != NULL) {
   660 		    while(derCertList[j] != NULL) {
   661 			SECComparison eq;
   662 			SGNDigestInfo *di;
   663 			di = sec_pkcs12_compute_thumbprint(derCertList[j]);
   664 			if(di) {
   665 			    eq = SGN_CompareDigestInfo(thumbprint, di);
   666 			    SGN_DestroyDigestInfo(di);
   667 			    if(eq == SECEqual) {
   668 				/* copy the derCert for later reference */
   669 				cert->value.x509->derLeafCert = derCertList[j];
   670 				return cert;
   671 			    }
   672 			} else {
   673 			    /* an error occurred */
   674 			    return NULL;
   675 			}
   676 			j++;
   677 		    }
   678 		}
   679 	    }
   680 	}
   682 	i++;
   683     }
   685     if(search_both) {
   686 	search_both = PR_FALSE;
   687 	search_nickname = PR_FALSE;
   688 	goto search_again;
   689     }
   691     return NULL;
   692 }
   694 /* search a key list for a nickname, a thumbprint, or both
   695  * within a key bag.  if the key could not be
   696  * found or an error occurs, NULL is returned;
   697  */
   698 static SEC_PKCS12PrivateKey *
   699 sec_pkcs12_find_key_in_keybag(SEC_PKCS12PrivateKeyBag *keybag,
   700 			      SECItem *nickname, SGNDigestInfo *thumbprint)
   701 {
   702     PRBool search_both = PR_FALSE, search_nickname = PR_FALSE;
   703     int i, j;
   705     if((keybag == NULL) || ((nickname == NULL) && (thumbprint == NULL))) {
   706 	return NULL;
   707     }
   709     if(keybag->privateKeys == NULL) {
   710 	return NULL;
   711     }
   713     if(thumbprint && nickname) {
   714 	search_both = PR_TRUE;
   715     }
   717     if(nickname) {
   718 	search_nickname = PR_TRUE;
   719     }
   721 search_again:  
   722     i = 0;
   723     while(keybag->privateKeys[i] != NULL) {
   724 	SEC_PKCS12PrivateKey *key = keybag->privateKeys[i];
   726 	/* check nicknames */
   727 	if(search_nickname) {
   728 	    if(SECITEM_CompareItem(nickname, &key->pvkData.nickname) == SECEqual) {
   729 		return key;
   730 	    }
   731 	} else {
   732 	    /* check digests */
   733 	    SGNDigestInfo **assocCerts = key->pvkData.assocCerts;
   734 	    if((assocCerts == NULL) || (assocCerts[0] == NULL)) {
   735 		return NULL;
   736 	    }
   738 	    j = 0;
   739 	    while(assocCerts[j] != NULL) {
   740 		SECComparison eq;
   741 		eq = SGN_CompareDigestInfo(thumbprint, assocCerts[j]);
   742 		if(eq == SECEqual) {
   743 		    return key;
   744 		}
   745 		j++;
   746 	    }
   747 	}
   748 	i++;
   749     }
   751     if(search_both) {
   752 	search_both = PR_FALSE;
   753 	search_nickname = PR_FALSE;
   754 	goto search_again;
   755     }
   757     return NULL;
   758 }
   760 /* seach the safe first then try the baggage bag 
   761  *  safe and bag contain certs and keys to search
   762  *  objType is the object type to look for
   763  *  bagType is the type of bag that was found by sec_pkcs12_find_object
   764  *  index is the entity in safe->safeContents or bag->unencSecrets which
   765  *    is being searched
   766  *  nickname and thumbprint are the search criteria
   767  * 
   768  * a return of null indicates no match
   769  */
   770 static void *
   771 sec_pkcs12_try_find(SEC_PKCS12SafeContents *safe,
   772 		  SEC_PKCS12BaggageItem *bag,
   773 		  SECOidTag objType, SECOidTag bagType, int index,
   774 		  SECItem *nickname, SGNDigestInfo *thumbprint)
   775 {
   776     PRBool searchSafe;
   777     int i = index;
   779     if((safe == NULL) && (bag == NULL)) {
   780 	return NULL;
   781     }
   783     searchSafe = (safe == NULL ? PR_FALSE : PR_TRUE);
   784     switch(objType) {
   785 	case SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID:
   786 	    if(objType == bagType) {
   787 		SEC_PKCS12CertAndCRLBag *certBag;
   789 		if(searchSafe) {
   790 		    certBag = safe->contents[i]->safeContent.certAndCRLBag;
   791 		} else {
   792 		    certBag = bag->unencSecrets[i]->safeContent.certAndCRLBag;
   793 		}
   794 		return sec_pkcs12_find_cert_in_certbag(certBag, nickname, 
   795 							thumbprint);
   796 	    }
   797 	    break;
   798 	case SEC_OID_PKCS12_KEY_BAG_ID:
   799 	    if(objType == bagType) {
   800 		SEC_PKCS12PrivateKeyBag *keyBag;
   802 		if(searchSafe) {
   803 		    keyBag = safe->contents[i]->safeContent.keyBag;
   804 		} else {
   805 		    keyBag = bag->unencSecrets[i]->safeContent.keyBag;
   806 		}
   807 		return sec_pkcs12_find_key_in_keybag(keyBag, nickname, 
   808 							 thumbprint);
   809 	    }
   810 	    break;
   811 	default:
   812 	    break;
   813     }
   815     return NULL;
   816 }
   818 /* searches both the baggage and the safe areas looking for
   819  * object of specified type matching either the nickname or the 
   820  * thumbprint specified.
   821  *
   822  * safe and baggage store certs and keys
   823  * objType is the OID for the bag type to be searched:
   824  *   SEC_OID_PKCS12_KEY_BAG_ID, or 
   825  *   SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID
   826  * nickname and thumbprint are the search criteria
   827  * 
   828  * if no match found, NULL returned and error set
   829  */
   830 void *
   831 sec_pkcs12_find_object(SEC_PKCS12SafeContents *safe,
   832 			SEC_PKCS12Baggage *baggage,
   833 			SECOidTag objType,
   834 			SECItem *nickname,
   835 			SGNDigestInfo *thumbprint)
   836 {
   837     int i, j;
   838     void *retItem;
   840     if(((safe == NULL) && (thumbprint == NULL)) ||
   841        ((nickname == NULL) && (thumbprint == NULL))) {
   842 	return NULL;
   843     }    
   845     i = 0;
   846     if((safe != NULL) && (safe->contents != NULL)) {
   847 	while(safe->contents[i] != NULL) {
   848 	    SECOidTag bagType = SECOID_FindOIDTag(&safe->contents[i]->safeBagType);
   849 	    retItem = sec_pkcs12_try_find(safe, NULL, objType, bagType, i,
   850 	    				  nickname, thumbprint);
   851 	    if(retItem != NULL) {
   852 		return retItem;
   853 	    }
   854 	    i++;
   855 	}
   856     }
   858     if((baggage != NULL) && (baggage->bags != NULL)) {
   859 	i = 0;
   860 	while(baggage->bags[i] != NULL) {
   861 	    SEC_PKCS12BaggageItem *xbag = baggage->bags[i];
   862 	    j = 0;
   863 	    if(xbag->unencSecrets != NULL) {
   864 		while(xbag->unencSecrets[j] != NULL) {
   865 		    SECOidTag bagType;
   866 		    bagType = SECOID_FindOIDTag(&xbag->unencSecrets[j]->safeBagType);
   867 		    retItem = sec_pkcs12_try_find(NULL, xbag, objType, bagType,
   868 		    				  j, nickname, thumbprint);
   869 		    if(retItem != NULL) {
   870 			return retItem;
   871 		    }
   872 		    j++;
   873 		}
   874 	    }
   875 	    i++;
   876 	}
   877     }
   879     PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME);
   880     return NULL;
   881 }
   883 /* this function converts a password to unicode and encures that the 
   884  * required double 0 byte be placed at the end of the string
   885  */
   886 PRBool
   887 sec_pkcs12_convert_item_to_unicode(PLArenaPool *arena, SECItem *dest,
   888 				   SECItem *src, PRBool zeroTerm,
   889 				   PRBool asciiConvert, PRBool toUnicode)
   890 {
   891     PRBool success = PR_FALSE;
   892     if(!src || !dest) {
   893 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   894 	return PR_FALSE;
   895     }
   897     dest->len = src->len * 3 + 2;
   898     if(arena) {
   899 	dest->data = (unsigned char*)PORT_ArenaZAlloc(arena, dest->len);
   900     } else {
   901 	dest->data = (unsigned char*)PORT_ZAlloc(dest->len);
   902     }
   904     if(!dest->data) {
   905 	dest->len = 0;
   906 	return PR_FALSE;
   907     }
   909     if(!asciiConvert) {
   910 	success = PORT_UCS2_UTF8Conversion(toUnicode, src->data, src->len, dest->data,
   911 					   dest->len, &dest->len);
   912     } else {
   913 #ifndef IS_LITTLE_ENDIAN
   914 	PRBool swapUnicode = PR_FALSE;
   915 #else
   916 	PRBool swapUnicode = PR_TRUE;
   917 #endif
   918 	success = PORT_UCS2_ASCIIConversion(toUnicode, src->data, src->len, dest->data,
   919 					    dest->len, &dest->len, swapUnicode);
   920     }
   922     if(!success) {
   923 	if(!arena) {
   924 	    PORT_Free(dest->data);
   925 	    dest->data = NULL;
   926 	    dest->len = 0;
   927 	}
   928 	return PR_FALSE;
   929     }
   931     if((dest->data[dest->len-1] || dest->data[dest->len-2]) && zeroTerm) {
   932 	if(dest->len + 2 > 3 * src->len) {
   933 	    if(arena) {
   934 		dest->data = (unsigned char*)PORT_ArenaGrow(arena, 
   935 						     dest->data, dest->len,
   936 						     dest->len + 2);
   937 	    } else {
   938 		dest->data = (unsigned char*)PORT_Realloc(dest->data, 
   939 							  dest->len + 2);
   940 	    }
   942 	    if(!dest->data) {
   943 		return PR_FALSE;
   944 	    }
   945 	}
   946 	dest->len += 2;
   947 	dest->data[dest->len-1] = dest->data[dest->len-2] = 0;
   948     }
   950     return PR_TRUE;
   951 }
   953 /* pkcs 12 templates */
   954 static const SEC_ASN1TemplateChooserPtr sec_pkcs12_shroud_chooser =
   955     sec_pkcs12_choose_shroud_type;
   957 const SEC_ASN1Template SEC_PKCS12CodedSafeBagTemplate[] =
   958 {
   959     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
   960     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
   961     { SEC_ASN1_ANY, offsetof(SEC_PKCS12SafeBag, derSafeContent) },
   962     { 0 }
   963 };
   965 const SEC_ASN1Template SEC_PKCS12CodedCertBagTemplate[] =
   966 {
   967     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
   968     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
   969     { SEC_ASN1_ANY, offsetof(SEC_PKCS12CertAndCRL, derValue) },
   970     { 0 }
   971 };
   973 const SEC_ASN1Template SEC_PKCS12CodedCertAndCRLBagTemplate[] =
   974 {
   975     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
   976 	SEC_PKCS12CodedCertBagTemplate },
   977 };
   979 const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate_OLD[] = 
   980 {
   981     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12ESPVKItem) },
   982     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12ESPVKItem, espvkOID) },
   983     { SEC_ASN1_INLINE, offsetof(SEC_PKCS12ESPVKItem, espvkData),
   984 	SEC_PKCS12PVKSupportingDataTemplate_OLD },
   985     { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
   986 	SEC_ASN1_DYNAMIC | 0, offsetof(SEC_PKCS12ESPVKItem, espvkCipherText),
   987 	&sec_pkcs12_shroud_chooser },
   988     { 0 }
   989 };
   991 const SEC_ASN1Template SEC_PKCS12ESPVKItemTemplate[] = 
   992 {
   993     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12ESPVKItem) },
   994     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12ESPVKItem, espvkOID) },
   995     { SEC_ASN1_INLINE, offsetof(SEC_PKCS12ESPVKItem, espvkData),
   996 	SEC_PKCS12PVKSupportingDataTemplate },
   997     { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
   998 	SEC_ASN1_DYNAMIC | 0, offsetof(SEC_PKCS12ESPVKItem, espvkCipherText),
   999 	&sec_pkcs12_shroud_chooser },
  1000     { 0 }
  1001 };
  1003 const SEC_ASN1Template SEC_PKCS12PVKAdditionalDataTemplate[] =
  1005     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKAdditionalData) },
  1006     { SEC_ASN1_OBJECT_ID, 
  1007 	offsetof(SEC_PKCS12PVKAdditionalData, pvkAdditionalType) },
  1008     { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
  1009 	offsetof(SEC_PKCS12PVKAdditionalData, pvkAdditionalContent) },
  1010     { 0 }
  1011 };
  1013 const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate_OLD[] =
  1015     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKSupportingData) },
  1016     { SEC_ASN1_SET_OF | SEC_ASN1_XTRN , 
  1017         offsetof(SEC_PKCS12PVKSupportingData, assocCerts),
  1018 	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
  1019     { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, 
  1020 	offsetof(SEC_PKCS12PVKSupportingData, regenerable) },
  1021     { SEC_ASN1_PRINTABLE_STRING, 
  1022 	offsetof(SEC_PKCS12PVKSupportingData, nickname) },
  1023     { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
  1024 	offsetof(SEC_PKCS12PVKSupportingData, pvkAdditionalDER) },
  1025     { 0 }
  1026 };
  1028 const SEC_ASN1Template SEC_PKCS12PVKSupportingDataTemplate[] =
  1030     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PVKSupportingData) },
  1031     { SEC_ASN1_SET_OF | SEC_ASN1_XTRN , 
  1032         offsetof(SEC_PKCS12PVKSupportingData, assocCerts),
  1033 	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
  1034     { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, 
  1035 	offsetof(SEC_PKCS12PVKSupportingData, regenerable) },
  1036     { SEC_ASN1_BMP_STRING, 
  1037 	offsetof(SEC_PKCS12PVKSupportingData, uniNickName) },
  1038     { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
  1039 	offsetof(SEC_PKCS12PVKSupportingData, pvkAdditionalDER) },
  1040     { 0 }
  1041 };
  1043 const SEC_ASN1Template SEC_PKCS12BaggageItemTemplate[] =
  1045     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12BaggageItem) },
  1046     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, espvks),
  1047 	SEC_PKCS12ESPVKItemTemplate },
  1048     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, unencSecrets),
  1049 	SEC_PKCS12SafeBagTemplate },
  1050     /*{ SEC_ASN1_SET_OF, offsetof(SEC_PKCS12BaggageItem, unencSecrets),
  1051 	SEC_PKCS12CodedSafeBagTemplate }, */
  1052     { 0 }
  1053 };
  1055 const SEC_ASN1Template SEC_PKCS12BaggageTemplate[] =
  1057     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12Baggage, bags),
  1058 	SEC_PKCS12BaggageItemTemplate },
  1059 };
  1061 const SEC_ASN1Template SEC_PKCS12BaggageTemplate_OLD[] =
  1063     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12Baggage_OLD, espvks),
  1064 	SEC_PKCS12ESPVKItemTemplate_OLD },
  1065 };
  1067 static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser =
  1068 	sec_pkcs12_choose_bag_type;
  1070 static const SEC_ASN1TemplateChooserPtr sec_pkcs12_bag_chooser_old =
  1071 	sec_pkcs12_choose_bag_type_old;
  1073 const SEC_ASN1Template SEC_PKCS12SafeBagTemplate_OLD[] =
  1075     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
  1076     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
  1077     { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
  1078 	SEC_ASN1_CONTEXT_SPECIFIC | 0,
  1079         offsetof(SEC_PKCS12SafeBag, safeContent),
  1080 	&sec_pkcs12_bag_chooser_old },
  1081     { 0 }
  1082 };
  1084 const SEC_ASN1Template SEC_PKCS12SafeBagTemplate[] =
  1086     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SafeBag) },
  1087     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12SafeBag, safeBagType) },
  1088     { SEC_ASN1_DYNAMIC | SEC_ASN1_POINTER,
  1089         offsetof(SEC_PKCS12SafeBag, safeContent),
  1090 	&sec_pkcs12_bag_chooser },
  1091     { SEC_ASN1_OPTIONAL | SEC_ASN1_BMP_STRING,
  1092 	offsetof(SEC_PKCS12SafeBag, uniSafeBagName) },
  1093     { 0 }
  1094 };
  1096 const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate_OLD[] =
  1098     { SEC_ASN1_SET_OF,
  1099 	offsetof(SEC_PKCS12SafeContents, contents),
  1100 	SEC_PKCS12SafeBagTemplate_OLD }
  1101 };
  1103 const SEC_ASN1Template SEC_PKCS12SafeContentsTemplate[] =
  1105     { SEC_ASN1_SET_OF,
  1106 	offsetof(SEC_PKCS12SafeContents, contents),
  1107 	SEC_PKCS12SafeBagTemplate }  /* here */
  1108 };
  1110 const SEC_ASN1Template SEC_PKCS12PrivateKeyTemplate[] =
  1112     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PrivateKey) },
  1113     { SEC_ASN1_INLINE, offsetof(SEC_PKCS12PrivateKey, pvkData),
  1114 	SEC_PKCS12PVKSupportingDataTemplate },
  1115     { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 
  1116         offsetof(SEC_PKCS12PrivateKey, pkcs8data),
  1117 	SEC_ASN1_SUB(SECKEY_PrivateKeyInfoTemplate) },
  1118     { 0 }
  1119 };
  1121 const SEC_ASN1Template SEC_PKCS12PrivateKeyBagTemplate[] =
  1123     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PrivateKeyBag) },
  1124     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12PrivateKeyBag, privateKeys),
  1125 	SEC_PKCS12PrivateKeyTemplate },
  1126     { 0 }
  1127 };
  1129 const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate_OLD[] =
  1131     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
  1132     { SEC_ASN1_INLINE, offsetof(SEC_PKCS12X509CertCRL, certOrCRL),
  1133 	sec_PKCS7ContentInfoTemplate },
  1134     { SEC_ASN1_INLINE | SEC_ASN1_XTRN , 
  1135         offsetof(SEC_PKCS12X509CertCRL, thumbprint),
  1136 	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
  1137     { 0 }
  1138 };
  1140 const SEC_ASN1Template SEC_PKCS12X509CertCRLTemplate[] =
  1142     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
  1143     { SEC_ASN1_INLINE, offsetof(SEC_PKCS12X509CertCRL, certOrCRL),
  1144 	sec_PKCS7ContentInfoTemplate },
  1145     { 0 }
  1146 };
  1148 const SEC_ASN1Template SEC_PKCS12SDSICertTemplate[] =
  1150     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12X509CertCRL) },
  1151     { SEC_ASN1_IA5_STRING, offsetof(SEC_PKCS12SDSICert, value) },
  1152     { 0 }
  1153 };
  1155 static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser_old =
  1156 	sec_pkcs12_choose_cert_crl_type_old;
  1158 static const SEC_ASN1TemplateChooserPtr sec_pkcs12_cert_crl_chooser =
  1159 	sec_pkcs12_choose_cert_crl_type;
  1161 const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate_OLD[] =
  1163     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
  1164     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
  1165     { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT |
  1166 	SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | 0,
  1167 	offsetof(SEC_PKCS12CertAndCRL, value),
  1168 	&sec_pkcs12_cert_crl_chooser_old },
  1169     { 0 }
  1170 };
  1172 const SEC_ASN1Template SEC_PKCS12CertAndCRLTemplate[] =
  1174     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRL) },
  1175     { SEC_ASN1_OBJECT_ID, offsetof(SEC_PKCS12CertAndCRL, BagID) },
  1176     { SEC_ASN1_DYNAMIC | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
  1177 	SEC_ASN1_CONTEXT_SPECIFIC | 0, 
  1178 	offsetof(SEC_PKCS12CertAndCRL, value),
  1179 	&sec_pkcs12_cert_crl_chooser },
  1180     { 0 }
  1181 };
  1183 const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate[] =
  1185     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
  1186 	SEC_PKCS12CertAndCRLTemplate },
  1187 };
  1189 const SEC_ASN1Template SEC_PKCS12CertAndCRLBagTemplate_OLD[] =
  1191     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12CertAndCRLBag) },
  1192     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12CertAndCRLBag, certAndCRLs),
  1193 	SEC_PKCS12CertAndCRLTemplate_OLD },
  1194     { 0 }
  1195 };
  1197 const SEC_ASN1Template SEC_PKCS12SecretAdditionalTemplate[] =
  1199     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12SecretAdditional) },
  1200     { SEC_ASN1_OBJECT_ID,
  1201 	offsetof(SEC_PKCS12SecretAdditional, secretAdditionalType) },
  1202     { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT,
  1203 	offsetof(SEC_PKCS12SecretAdditional, secretAdditionalContent) },
  1204     { 0 }
  1205 };
  1207 const SEC_ASN1Template SEC_PKCS12SecretTemplate[] =
  1209     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12Secret) },
  1210     { SEC_ASN1_BMP_STRING, offsetof(SEC_PKCS12Secret, uniSecretName) },
  1211     { SEC_ASN1_ANY, offsetof(SEC_PKCS12Secret, value) },
  1212     { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL,
  1213 	offsetof(SEC_PKCS12Secret, secretAdditional),
  1214 	SEC_PKCS12SecretAdditionalTemplate },
  1215     { 0 }
  1216 };
  1218 const SEC_ASN1Template SEC_PKCS12SecretItemTemplate[] = 
  1220     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12Secret) },
  1221     { SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 0,
  1222 	offsetof(SEC_PKCS12SecretItem, secret), SEC_PKCS12SecretTemplate },
  1223     { SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 1,
  1224 	offsetof(SEC_PKCS12SecretItem, subFolder), SEC_PKCS12SafeBagTemplate },
  1225     { 0 }
  1226 };
  1228 const SEC_ASN1Template SEC_PKCS12SecretBagTemplate[] =
  1230     { SEC_ASN1_SET_OF, offsetof(SEC_PKCS12SecretBag, secrets),
  1231 	SEC_PKCS12SecretItemTemplate },
  1232 };
  1234 const SEC_ASN1Template SEC_PKCS12MacDataTemplate[] =
  1236     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
  1237     { SEC_ASN1_INLINE | SEC_ASN1_XTRN , offsetof(SEC_PKCS12MacData, safeMac),
  1238 	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
  1239     { SEC_ASN1_BIT_STRING, offsetof(SEC_PKCS12MacData, macSalt) },
  1240     { 0 }
  1241 };
  1243 const SEC_ASN1Template SEC_PKCS12PFXItemTemplate[] =
  1245     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
  1246     { SEC_ASN1_OPTIONAL |
  1247 	SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 
  1248 	offsetof(SEC_PKCS12PFXItem, macData), SEC_PKCS12MacDataTemplate },
  1249     { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 
  1250 	offsetof(SEC_PKCS12PFXItem, authSafe), 
  1251 	sec_PKCS7ContentInfoTemplate },
  1252     { 0 }
  1253 };
  1255 const SEC_ASN1Template SEC_PKCS12PFXItemTemplate_OLD[] =
  1257     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12PFXItem) },
  1258     { SEC_ASN1_OPTIONAL |
  1259 	SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, 
  1260 	offsetof(SEC_PKCS12PFXItem, old_safeMac), 
  1261 	SEC_ASN1_SUB(sgn_DigestInfoTemplate) },
  1262     { SEC_ASN1_OPTIONAL | SEC_ASN1_BIT_STRING,
  1263 	offsetof(SEC_PKCS12PFXItem, old_macSalt) },
  1264     { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, 
  1265 	offsetof(SEC_PKCS12PFXItem, authSafe), 
  1266 	sec_PKCS7ContentInfoTemplate },
  1267     { 0 }
  1268 };
  1270 const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate[] =
  1272     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12AuthenticatedSafe) },
  1273     { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, 
  1274 	offsetof(SEC_PKCS12AuthenticatedSafe, version) }, 
  1275     { SEC_ASN1_OPTIONAL | SEC_ASN1_OBJECT_ID,
  1276 	offsetof(SEC_PKCS12AuthenticatedSafe, transportMode) },
  1277     { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL,
  1278 	offsetof(SEC_PKCS12AuthenticatedSafe, privacySalt) },
  1279     { SEC_ASN1_OPTIONAL | SEC_ASN1_SET_OF, 
  1280 	offsetof(SEC_PKCS12AuthenticatedSafe, baggage.bags), 
  1281 	SEC_PKCS12BaggageItemTemplate },
  1282     { SEC_ASN1_POINTER,
  1283 	offsetof(SEC_PKCS12AuthenticatedSafe, safe),
  1284 	sec_PKCS7ContentInfoTemplate },
  1285     { 0 }
  1286 };
  1288 const SEC_ASN1Template SEC_PKCS12AuthenticatedSafeTemplate_OLD[] =
  1290     { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS12AuthenticatedSafe) },
  1291     { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER, 
  1292 	offsetof(SEC_PKCS12AuthenticatedSafe, version) }, 
  1293     { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
  1294 	offsetof(SEC_PKCS12AuthenticatedSafe, transportMode) },
  1295     { SEC_ASN1_BIT_STRING,
  1296 	offsetof(SEC_PKCS12AuthenticatedSafe, privacySalt) },
  1297     { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
  1298     	SEC_ASN1_CONTEXT_SPECIFIC | 0, 
  1299 	offsetof(SEC_PKCS12AuthenticatedSafe, old_baggage), 
  1300 	SEC_PKCS12BaggageTemplate_OLD },
  1301     { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
  1302 	offsetof(SEC_PKCS12AuthenticatedSafe, old_safe),
  1303 	sec_PKCS7ContentInfoTemplate },
  1304     { 0 }
  1305 };
  1307 const SEC_ASN1Template SEC_PointerToPKCS12KeyBagTemplate[] =
  1309     { SEC_ASN1_POINTER, 0, SEC_PKCS12PrivateKeyBagTemplate }
  1310 };
  1312 const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate_OLD[] =
  1314     { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate_OLD }
  1315 };
  1317 const SEC_ASN1Template SEC_PointerToPKCS12CertAndCRLBagTemplate[] =
  1319     { SEC_ASN1_POINTER, 0, SEC_PKCS12CertAndCRLBagTemplate }
  1320 };
  1322 const SEC_ASN1Template SEC_PointerToPKCS12SecretBagTemplate[] =
  1324     { SEC_ASN1_POINTER, 0, SEC_PKCS12SecretBagTemplate }
  1325 };
  1327 const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate_OLD[] =
  1329     { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate_OLD }
  1330 };
  1332 const SEC_ASN1Template SEC_PointerToPKCS12X509CertCRLTemplate[] =
  1334     { SEC_ASN1_POINTER, 0, SEC_PKCS12X509CertCRLTemplate }
  1335 };
  1337 const SEC_ASN1Template SEC_PointerToPKCS12SDSICertTemplate[] =
  1339     { SEC_ASN1_POINTER, 0, SEC_PKCS12SDSICertTemplate }
  1340 };

mercurial