p12d.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,435 行 · 第 1/5 页
C
2,435 行
SECItem *src, *dest; if(!bag) { bag->problem = PR_TRUE; bag->error = SEC_ERROR_NO_MEMORY; return NULL; } src = sec_pkcs12_get_attribute_value(bag, SEC_OID_PKCS9_FRIENDLY_NAME); if(!src) { return NULL; } dest = (SECItem*)PORT_ZAlloc(sizeof(SECItem)); if(!dest) { goto loser; } if(!sec_pkcs12_convert_item_to_unicode(NULL, dest, src, PR_FALSE, PR_FALSE, PR_FALSE)) { goto loser; } sec_pkcs12_sanitize_nickname(bag->slot, dest); return dest;loser: if(dest) { SECITEM_ZfreeItem(dest, PR_TRUE); } bag->problem = PR_TRUE; bag->error = PORT_GetError(); return NULL;}static SECStatussec_pkcs12_set_nickname(sec_PKCS12SafeBag *bag, SECItem *name){ int i = 0; sec_PKCS12Attribute *attr = NULL; SECOidData *oid = SECOID_FindOIDByTag(SEC_OID_PKCS9_FRIENDLY_NAME); if(!bag || !bag->arena || !name) { return SECFailure; } if(!bag->attribs) { if(!oid) { goto loser; } bag->attribs = (sec_PKCS12Attribute**)PORT_ArenaZAlloc(bag->arena, sizeof(sec_PKCS12Attribute *)*2); if(!bag->attribs) { goto loser; } bag->attribs[0] = (sec_PKCS12Attribute*)PORT_ArenaZAlloc(bag->arena, sizeof(sec_PKCS12Attribute)); if(!bag->attribs[0]) { goto loser; } bag->attribs[1] = NULL; attr = bag->attribs[0]; if(SECITEM_CopyItem(bag->arena, &attr->attrType, &oid->oid) != SECSuccess) { goto loser; } } else { while(bag->attribs[i]) { if(SECOID_FindOIDTag(&bag->attribs[i]->attrType) == SEC_OID_PKCS9_FRIENDLY_NAME) { attr = bag->attribs[i]; goto have_attrib; } i++; } if(!attr) { bag->attribs = (sec_PKCS12Attribute **)PORT_ArenaGrow(bag->arena, bag->attribs, (i+1) * sizeof(sec_PKCS12Attribute *), (i+2) * sizeof(sec_PKCS12Attribute *)); if(!bag->attribs) { goto loser; } bag->attribs[i] = (sec_PKCS12Attribute *)PORT_ArenaZAlloc(bag->arena, sizeof(sec_PKCS12Attribute)); if(!bag->attribs[i]) { goto loser; } bag->attribs[i+1] = NULL; attr = bag->attribs[i]; if(SECITEM_CopyItem(bag->arena, &attr->attrType, &oid->oid) != SECSuccess) { goto loser; } } }have_attrib: PORT_Assert(attr); if(!attr->attrValue) { attr->attrValue = (SECItem **)PORT_ArenaZAlloc(bag->arena, sizeof(SECItem *) * 2); if(!attr->attrValue) { goto loser; } attr->attrValue[0] = (SECItem*)PORT_ArenaZAlloc(bag->arena, sizeof(SECItem)); if(!attr->attrValue[0]) { goto loser; } attr->attrValue[1] = NULL; } name->len = PORT_Strlen((char *)name->data); if(!sec_pkcs12_convert_item_to_unicode(bag->arena, attr->attrValue[0], name, PR_FALSE, PR_FALSE, PR_TRUE)) { goto loser; } return SECSuccess;loser: bag->problem = PR_TRUE; bag->error = SEC_ERROR_NO_MEMORY; return SECFailure;} static SECStatussec_pkcs12_get_key_info(sec_PKCS12SafeBag *key) { int i = 0; SECKEYPrivateKeyInfo *pki = NULL; if(!key) { return SECFailure; } /* if the bag does *not* contain an unencrypted PrivateKeyInfo * then we cannot convert the attributes. We are propagating * attributes within the PrivateKeyInfo to the SafeBag level. */ if(SECOID_FindOIDTag(&(key->safeBagType)) != SEC_OID_PKCS12_V1_KEY_BAG_ID) { return SECSuccess; } pki = key->safeBagContent.pkcs8KeyBag; if(!pki || !pki->attributes) { return SECSuccess; } while(pki->attributes[i]) { SECItem *attrValue = NULL; if(SECOID_FindOIDTag(&pki->attributes[i]->attrType) == SEC_OID_PKCS9_LOCAL_KEY_ID) { attrValue = sec_pkcs12_get_attribute_value(key, SEC_OID_PKCS9_LOCAL_KEY_ID); if(!attrValue) { if(sec_pkcs12_decoder_set_attribute_value(key, SEC_OID_PKCS9_LOCAL_KEY_ID, pki->attributes[i]->attrValue[0]) != SECSuccess) { key->problem = PR_TRUE; key->error = SEC_ERROR_NO_MEMORY; return SECFailure; } } } if(SECOID_FindOIDTag(&pki->attributes[i]->attrType) == SEC_OID_PKCS9_FRIENDLY_NAME) { attrValue = sec_pkcs12_get_attribute_value(key, SEC_OID_PKCS9_FRIENDLY_NAME); if(!attrValue) { if(sec_pkcs12_decoder_set_attribute_value(key, SEC_OID_PKCS9_FRIENDLY_NAME, pki->attributes[i]->attrValue[0]) != SECSuccess) { key->problem = PR_TRUE; key->error = SEC_ERROR_NO_MEMORY; return SECFailure; } } } i++; } return SECSuccess;}/* retrieve the nickname for the certificate bag. first look * in the cert bag, otherwise get it from the key. */static SECItem *sec_pkcs12_get_nickname_for_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key, void *wincx){ SECItem *nickname; if(!cert) { return NULL; } nickname = sec_pkcs12_get_nickname(cert); if(nickname) { return nickname; } if(key) { nickname = sec_pkcs12_get_nickname(key); if(nickname && sec_pkcs12_set_nickname(cert, nickname) != SECSuccess) { cert->error = SEC_ERROR_NO_MEMORY; cert->problem = PR_TRUE; if(nickname) { SECITEM_ZfreeItem(nickname, PR_TRUE); } return NULL; } } return nickname;}/* set the nickname for the certificate */static SECStatussec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert, sec_PKCS12SafeBag *key, SECItem *nickname, void *wincx){ if(!nickname || !cert) { return SECFailure; } if(sec_pkcs12_set_nickname(cert, nickname) != SECSuccess) { cert->error = SEC_ERROR_NO_MEMORY; cert->problem = PR_TRUE; return SECFailure; } if(key) { if(sec_pkcs12_set_nickname(key, nickname) != SECSuccess) { cert->error = SEC_ERROR_NO_MEMORY; cert->problem = PR_TRUE; return SECFailure; } } return SECSuccess;}/* retrieve the DER cert from the cert bag */static SECItem *sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert) { if(!cert) { return NULL; } if(SECOID_FindOIDTag(&cert->safeBagType) != SEC_OID_PKCS12_V1_CERT_BAG_ID) { return NULL; } /* only support X509 certs not SDSI */ if(SECOID_FindOIDTag(&cert->safeBagContent.certBag->bagID) != SEC_OID_PKCS9_X509_CERT) { return NULL; } return SECITEM_DupItem(&(cert->safeBagContent.certBag->value.x509Cert));}struct certNickInfo { PRArenaPool *arena; unsigned int nNicks; SECItem **nickList; unsigned int error;};/* callback for traversing certificates to gather the nicknames * used in a particular traversal. for instance, when using * CERT_TraversePermCertsForSubject, gather the nicknames and * store them in the certNickInfo for a particular DN. * * this handles the case where multiple nicknames are allowed * for the same dn, which is not currently allowed, but may be * in the future. */ static SECStatusgatherNicknames(CERTCertificate *cert, void *arg){ struct certNickInfo *nickArg = (struct certNickInfo *)arg; SECItem tempNick; unsigned int i; if(!cert || !nickArg || nickArg->error) { return SECFailure; } if(!cert->nickname) { return SECSuccess; } tempNick.data = (unsigned char *)cert->nickname; tempNick.len = PORT_Strlen(cert->nickname) + 1; /* do we already have the nickname in the list? */ if(nickArg->nNicks > 0) { /* nicknames have been encountered, but there is no list -- bad */ if(!nickArg->nickList) { nickArg->error = SEC_ERROR_NO_MEMORY; return SECFailure; } for(i = 0; i < nickArg->nNicks; i++) { if(SECITEM_CompareItem(nickArg->nickList[i], &tempNick) == SECEqual) { return SECSuccess; } } } /* add the nickname to the list */ if(nickArg->nNicks == 0) { nickArg->nickList = (SECItem **)PORT_ArenaZAlloc(nickArg->arena, 2 * sizeof(SECItem *)); } else { nickArg->nickList = (SECItem **)PORT_ArenaGrow(nickArg->arena, nickArg->nickList, (nickArg->nNicks + 1) * sizeof(SECItem *), (nickArg->nNicks + 2) * sizeof(SECItem *)); } if(!nickArg->nickList) { nickArg->error = SEC_ERROR_NO_MEMORY; return SECFailure; } nickArg->nickList[nickArg->nNicks] = (SECItem *)PORT_ArenaZAlloc(nickArg->arena, sizeof(SECItem)); if(!nickArg->nickList[nickArg->nNicks]) { nickArg->error = SEC_ERROR_NO_MEMORY; return SECFailure; } if(SECITEM_CopyItem(nickArg->arena, nickArg->nickList[nickArg->nNicks], &tempNick) != SECSuccess) { nickArg->error = SEC_ERROR_NO_MEMORY; return SECFailure; } nickArg->nNicks++; return SECSuccess;}/* traverses the certs in the data base or in the token for the * DN to see if any certs currently have a nickname set. * If so, return it. */static SECItem *sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert, void *wincx){ struct certNickInfo *nickArg = NULL; SECItem *derCert, *returnDn = NULL; PRArenaPool *arena = NULL; CERTCertificate *tempCert; if(!cert) { return NULL; } derCert = sec_pkcs12_get_der_cert(cert); if(!derCert) { return NULL; } tempCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL, PR_FALSE, PR_TRUE); if(!tempCert) { returnDn = NULL; goto loser; } arena = PORT_NewArena(1024); if(!arena) { returnDn = NULL; goto loser; } nickArg = (struct certNickInfo *)PORT_ArenaZAlloc(arena, sizeof(struct certNickInfo)); if(!nickArg) { returnDn = NULL; goto loser; } nickArg->error = 0; nickArg->nNicks = 0; nickArg->nickList = NULL; nickArg->arena = arena; /* if the token is local, first traverse the cert database * then traverse the token. */ if(PK11_IsInternal(cert->slot)) { if(CERT_TraversePermCertsForSubject(CERT_GetDefaultCertDB(), &tempCert->derSubject, gatherNicknames, nickArg) != SECSuccess) { returnDn = NULL; goto loser; } } if(PK11_TraverseCertsForSubjectInSlot(tempCert, cert->slot, gatherNicknames, (void *)nickArg) != SECSuccess) { returnDn = NULL; goto loser; } if(nickArg->error) { /* XXX do we want to set the error? */ returnDn = NULL; goto loser; } if(nickArg->nNicks == 0) { returnDn = NULL; goto loser; } /* set it to the first name, for now. handle multiple names? */ returnDn = SECITEM_DupItem(nickArg->nickList[0]);loser: if(arena) { PORT_FreeArena(arena, PR_TRUE); } if(tempCert) { CERT_DestroyCertificate(tempCert); } if(derCert) { SECITEM_FreeItem(derCert, PR_TRUE); } return (returnDn);}/* counts certificates found for a given traversal function */static SECStatuscountCertificate(CERTCertificate *cert, void *arg){ unsigned int *nCerts = (unsigned int *)arg; if(!cert || !arg) { return SECFailure; } (*nCerts)++; return SECSuccess;}static PRBoolsec_pkcs12_certs_for_nickname_exist(SECItem *nickname, PK11SlotInfo *slot){ unsigned int nCerts = 0; if(!nickname || !slot) { return PR_TRUE; } /* we want to check the local database first if we are importing to it */ if(PK11_IsInternal(slot)) { CERT_TraversePermCertsForNickname(CERT_GetDefaultCertDB(), (char *)nickname->data, countCertificate, (void *)&nCerts);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?