p12exp.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,408 行 · 第 1/3 页
C
1,408 行
int i, j; SECComparison rv = SECEqual; SECItem *t_name; SEC_PKCS12BaggageItem *bag; if((luggage == NULL) || (name == NULL)) { return NULL; } i = 0; while((found == PR_FALSE) && (i < luggage->luggage_size)) { j = 0; bag = luggage->bags[i]; while((found == PR_FALSE) && (j < bag->nEspvks)) { espvk = bag->espvks[j]; if(espvk->poolp == NULL) { espvk->poolp = luggage->poolp; } t_name = SECITEM_DupItem(&espvk->espvkData.nickname); if(t_name != NULL) { rv = SECITEM_CompareItem(name, t_name); if(rv == SECEqual) { found = PR_TRUE; } SECITEM_FreeItem(t_name, PR_TRUE); } else { PORT_SetError(SEC_ERROR_NO_MEMORY); return NULL; } j++; } i++; } if(found != PR_TRUE) { PORT_SetError(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME); return NULL; } return espvk;}/* locates a certificate and copies the thumbprint to the * appropriate private key */static SECStatus sec_pkcs12_propagate_thumbprints(SECItem **nicknames, CERTCertificate **ref_certs, SEC_PKCS12SafeContents *safe, SEC_PKCS12Baggage *baggage){ SEC_PKCS12CertAndCRL *cert; SEC_PKCS12PrivateKey *key; SEC_PKCS12ESPVKItem *espvk; int i; PRBool error = PR_FALSE; SECStatus rv = SECFailure; if((nicknames == NULL) || (safe == NULL)) { return SECFailure; } i = 0; while((nicknames[i] != NULL) && (error == PR_FALSE)) { /* process all certs */ cert = (SEC_PKCS12CertAndCRL *)sec_pkcs12_find_object(safe, baggage, SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID, nicknames[i], NULL); if(cert != NULL) { /* locate key and copy thumbprint */ key = (SEC_PKCS12PrivateKey *)sec_pkcs12_find_object(safe, baggage, SEC_OID_PKCS12_KEY_BAG_ID, nicknames[i], NULL); if(key != NULL) { key->pvkData.poolp = key->poolp; rv = sec_pkcs12_add_thumbprint(&key->pvkData, &cert->value.x509->thumbprint); if(rv == SECFailure) error = PR_TRUE; /* XXX Set error? */ } /* look in the baggage as well...*/ if((baggage != NULL) && (error == PR_FALSE)) { espvk = sec_pkcs12_get_espvk_by_name(baggage, nicknames[i]); if(espvk != NULL) { espvk->espvkData.poolp = espvk->poolp; rv = sec_pkcs12_add_thumbprint(&espvk->espvkData, &cert->value.x509->thumbprint); if(rv == SECFailure) error = PR_TRUE; /* XXX Set error? */ } } } i++; } if(error == PR_TRUE) { return SECFailure; } return SECSuccess;}/* append a safe bag to the end of the safe contents list */SECStatus sec_pkcs12_append_safe_bag(SEC_PKCS12SafeContents *safe, SEC_PKCS12SafeBag *bag){ int size; void *mark = NULL, *dummy = NULL; if((bag == NULL) || (safe == NULL)) return SECFailure; mark = PORT_ArenaMark(safe->poolp); size = (safe->safe_size * sizeof(SEC_PKCS12SafeBag *)); if(safe->safe_size > 0) { dummy = (SEC_PKCS12SafeBag **)PORT_ArenaGrow(safe->poolp, safe->contents, size, (size + sizeof(SEC_PKCS12SafeBag *))); safe->contents = dummy; } else { safe->contents = (SEC_PKCS12SafeBag **)PORT_ArenaZAlloc(safe->poolp, (2 * sizeof(SEC_PKCS12SafeBag *))); dummy = safe->contents; } if(dummy == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } safe->contents[safe->safe_size] = bag; safe->safe_size++; safe->contents[safe->safe_size] = NULL; PORT_ArenaUnmark(safe->poolp, mark); return SECSuccess;loser: PORT_ArenaRelease(safe->poolp, mark); return SECFailure;}/* append a certificate onto the end of a cert bag */static SECStatus sec_pkcs12_append_cert_to_bag(PRArenaPool *arena, SEC_PKCS12SafeBag *safebag, CERTCertificate *cert, SECItem *nickname){ int size; void *dummy = NULL, *mark = NULL; SEC_PKCS12CertAndCRL *p12cert; SEC_PKCS12CertAndCRLBag *bag; if((arena == NULL) || (safebag == NULL) || (cert == NULL) || (nickname == NULL)) { return SECFailure; } bag = safebag->safeContent.certAndCRLBag; if(bag == NULL) { return SECFailure; } mark = PORT_ArenaMark(arena); p12cert = sec_pkcs12_get_cert(arena, cert, nickname); if(p12cert == NULL) { PORT_ArenaRelease(bag->poolp, mark); return SECFailure; } size = bag->bag_size * sizeof(SEC_PKCS12CertAndCRL *); if(bag->bag_size > 0) { dummy = (SEC_PKCS12CertAndCRL **)PORT_ArenaGrow(bag->poolp, bag->certAndCRLs, size, size + sizeof(SEC_PKCS12CertAndCRL *)); bag->certAndCRLs = dummy; } else { bag->certAndCRLs = (SEC_PKCS12CertAndCRL **)PORT_ArenaZAlloc(bag->poolp, (2 * sizeof(SEC_PKCS12CertAndCRL *))); dummy = bag->certAndCRLs; } if(dummy == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } bag->certAndCRLs[bag->bag_size] = p12cert; bag->bag_size++; bag->certAndCRLs[bag->bag_size] = NULL; PORT_ArenaUnmark(bag->poolp, mark); return SECSuccess;loser: PORT_ArenaRelease(bag->poolp, mark); return SECFailure;}/* append a key onto the end of a list of keys in a key bag */SECStatus sec_pkcs12_append_key_to_bag(SEC_PKCS12SafeBag *safebag, SEC_PKCS12PrivateKey *pk){ void *mark, *dummy; SEC_PKCS12PrivateKeyBag *bag; int size; if((safebag == NULL) || (pk == NULL)) return SECFailure; bag = safebag->safeContent.keyBag; if(bag == NULL) { return SECFailure; } mark = PORT_ArenaMark(bag->poolp); size = (bag->bag_size * sizeof(SEC_PKCS12PrivateKey *)); if(bag->bag_size > 0) { dummy = (SEC_PKCS12PrivateKey **)PORT_ArenaGrow(bag->poolp, bag->privateKeys, size, size + sizeof(SEC_PKCS12PrivateKey *)); bag->privateKeys = dummy; } else { bag->privateKeys = (SEC_PKCS12PrivateKey **)PORT_ArenaZAlloc(bag->poolp, (2 * sizeof(SEC_PKCS12PrivateKey *))); dummy = bag->privateKeys; } if(dummy == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } bag->privateKeys[bag->bag_size] = pk; bag->bag_size++; bag->privateKeys[bag->bag_size] = NULL; PORT_ArenaUnmark(bag->poolp, mark); return SECSuccess;loser: /* XXX Free memory? */ PORT_ArenaRelease(bag->poolp, mark); return SECFailure;}/* append a safe bag to the baggage area */static SECStatus sec_pkcs12_append_unshrouded_bag(SEC_PKCS12BaggageItem *bag, SEC_PKCS12SafeBag *u_bag){ int size; void *mark = NULL, *dummy = NULL; if((bag == NULL) || (u_bag == NULL)) return SECFailure; mark = PORT_ArenaMark(bag->poolp); /* dump things into the first bag */ size = (bag->nSecrets + 1) * sizeof(SEC_PKCS12SafeBag *); dummy = PORT_ArenaGrow(bag->poolp, bag->unencSecrets, size, size + sizeof(SEC_PKCS12SafeBag *)); bag->unencSecrets = dummy; if(dummy == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } bag->unencSecrets[bag->nSecrets] = u_bag; bag->nSecrets++; bag->unencSecrets[bag->nSecrets] = NULL; PORT_ArenaUnmark(bag->poolp, mark); return SECSuccess;loser: PORT_ArenaRelease(bag->poolp, mark); return SECFailure;}/* gather up all certificates and keys and package them up * in the safe, baggage, or both. * nicknames is the list of nicknames and corresponding certs in ref_certs * ref_certs a null terminated list of certificates * rSafe, rBaggage -- return areas for safe and baggage * shroud_keys -- store keys externally * pwitem -- password for computing integrity mac and encrypting contents * wincx -- window handle * * if a failure occurs, an error is set and SECFailure returned. */static SECStatussec_pkcs12_package_certs_and_keys(SECItem **nicknames, CERTCertificate **ref_certs, PRBool unencryptedCerts, SEC_PKCS12SafeContents **rSafe, SEC_PKCS12Baggage **rBaggage, PRBool shroud_keys, SECOidTag shroud_alg, SECItem *pwitem, PKCS12UnicodeConvertFunction unicodeFn, void *wincx){ PRArenaPool *permArena; SEC_PKCS12SafeContents *safe = NULL; SEC_PKCS12Baggage *baggage = NULL; SECStatus rv = SECFailure; PRBool problem = PR_FALSE; SEC_PKCS12ESPVKItem *espvk = NULL; SEC_PKCS12PrivateKey *pk = NULL; CERTCertificate *add_cert = NULL; SEC_PKCS12SafeBag *certbag = NULL, *keybag = NULL; SEC_PKCS12BaggageItem *external_bag = NULL; int ncerts = 0, nkeys = 0; int i; if((nicknames == NULL) || (rSafe == NULL) || (rBaggage == NULL)) { return SECFailure; } *rBaggage = baggage; *rSafe = safe; permArena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if(permArena == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); return SECFailure; } /* allocate structures */ safe = sec_pkcs12_create_safe_contents(permArena); if(safe == NULL) { PORT_SetError(SEC_ERROR_NO_MEMORY); rv = SECFailure; goto loser; } certbag = sec_pkcs12_create_safe_bag(permArena, SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID); if(certbag == NULL) { rv = SECFailure; goto loser; } if(shroud_keys != PR_TRUE) { keybag = sec_pkcs12_create_safe_bag(permArena, SEC_OID_PKCS12_KEY_BAG_ID); if(keybag == NULL) { rv = SECFailure; goto loser; } } if((shroud_keys == PR_TRUE) || (unencryptedCerts == PR_TRUE)) { baggage = sec_pkcs12_create_baggage(permArena); if(baggage == NULL) { rv = SECFailure; goto loser; } external_bag = sec_pkcs12_create_external_bag(baggage); } /* package keys and certs */ i = 0; while((nicknames[i] != NULL) && (problem == PR_FALSE)) { if(ref_certs[i] != NULL) { /* append cert to bag o certs */ rv = sec_pkcs12_append_cert_to_bag(permArena, certbag, ref_certs[i], nicknames[i]); if(rv == SECFailure) { problem = PR_FALSE; } else { ncerts++; } if(rv == SECSuccess) { /* package up them keys */ if(shroud_keys == PR_TRUE) { espvk = sec_pkcs12_get_shrouded_key(permArena, nicknames[i], ref_certs[i], shroud_alg, pwitem, unicodeFn, wincx); if(espvk != NULL) { rv = sec_pkcs12_append_shrouded_key(external_bag, espvk); SECITEM_CopyItem(permArena, &espvk->derCert, &ref_certs[i]->derCert); } else { rv = SECFailure; } } else { pk = sec_pkcs12_get_private_key(permArena, nicknames[i], ref_certs[i], wincx); if(pk != NULL) { rv = sec_pkcs12_append_key_to_bag(keybag, pk); SECITEM_CopyItem(permArena, &espvk->derCert, &ref_certs[i]->derCert); } else { rv = SECFailure; } } if(rv == SECFailure) { problem = PR_TRUE; } else { nkeys++; } } } else { /* handle only keys here ? */ problem = PR_TRUE; } i++; } /* let success fall through */loser: if(problem == PR_FALSE) { /* if we have certs, we want to append the cert bag to the * appropriate area */ if(ncerts > 0) { if(unencryptedCerts != PR_TRUE) { rv = sec_pkcs12_append_safe_bag(safe, certbag); } else { rv = sec_pkcs12_append_unshrouded_bag(external_bag, certbag); } } else { rv = SECSuccess; } /* append key bag, if they are stored in safe contents */ if((rv == SECSuccess) && (shroud_keys == PR_FALSE) && (nkeys > 0)) { rv = sec_pkcs12_append_safe_bag(safe, keybag); } } else { rv = SECFailure; } /* if baggage not used, NULLify it */ if((shroud_keys == PR_TRUE) || (unencryptedCerts == PR_TRUE)) { if(((unencryptedCerts == PR_TRUE) && (ncerts == 0)) && ((shroud_keys == PR_TRUE) && (nkeys == 0))) baggage = NULL; } else { baggage = NULL; } if((problem == PR_TRUE) || (rv == SECFailure)) { PORT_FreeArena(permArena, PR_TRUE); rv = SECFailure; baggage = NULL; safe = NULL; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?