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 + -
显示快捷键?