genname.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,611 行 · 第 1/3 页

C
1,611
字号
				    goto found;				}				if (rv == SECSuccess && excluded == PR_FALSE) {				    break;				}			    }			    current = cert_get_next_name_constraint(current);			} while (current != constraints);		    }		    if (rv != SECSuccess && excluded == PR_FALSE) {			goto loser;		    }		    if (*nameAVAS == NULL) {			break;		    }		}		if (*nameRDNS == NULL) {		    break;		}	    }	}	current = constraints;	do {	    switch (name->type) {	      case certDNSName:		nameString = (char*)PORT_ZAlloc(name->name.other.len + 1);		nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, 					  name->name.other.len);		constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1);		constraintString = PORT_Strncpy(constraintString, 						(char *) current->name.name.other.data,						current->name.name.other.len);		rv = compareNameToConstraint(nameString, constraintString, PR_FALSE);		if (nameString != NULL) {		    PORT_Free(nameString);		}		if (constraintString != NULL) {		    PORT_Free(constraintString);		}		break;	      case certRFC822Name:		nameString = (char*)PORT_ZAlloc(name->name.other.len + 1);		nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, 					  name->name.other.len);		start = 0;		while(nameString[start] != '@' && nameString[start + 1] != '\0') {		    start++;		} 		start++;		constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1);		constraintString = PORT_Strncpy(constraintString, 						(char *) current->name.name.other.data,						current->name.name.other.len);		rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE);		if (nameString != NULL) {		    PORT_Free(nameString);		}		if (constraintString != NULL) {		    PORT_Free(constraintString);		}		break;	      case certURI:	        nameString = (char*)PORT_ZAlloc(name->name.other.len + 1);		nameString = PORT_Strncpy(nameString, (char *) name->name.other.data, 					  name->name.other.len);		while(PORT_Strncmp(nameString + start, "://", 3) != 0 && 		      nameString[start + 3] != '\0') {		    start++;		}		start +=3;		end = 0;		while(nameString[start + end] != '/' && 		      nameString[start + end] != '\0') {		    end++;		}		nameString[start + end] = '\0';		constraintString = (char*)PORT_ZAlloc(current->name.name.other.len + 1);		constraintString = PORT_Strncpy(constraintString, 						(char *) current->name.name.other.data,						current->name.name.other.len);		rv = compareNameToConstraint(nameString + start, constraintString, PR_FALSE);		if (nameString != NULL) {		    PORT_Free(nameString);		}		if (constraintString != NULL) {		    PORT_Free(constraintString);		}		break;	      case certDirectoryName:  		if (current->name.type == certDirectoryName) {		    constraintNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 		    CERT_CopyName(constraintNameArena, &constraintName, &current->name.name.directoryName);		    constraintRDNS = constraintName.rdns;  		    for (;;) {			constraintRDN = *constraintRDNS++;			constraintAVAS = constraintRDN->avas;			for(;;) {			    constraintAVA = *constraintAVAS++;			    certNameArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);			    CERT_CopyName(certNameArena, &certName, &name->name.directoryName);			    nameRDNS = certName.rdns;			    for (;;) {				nameRDN = *nameRDNS++;				nameAVAS = nameRDN->avas++;				for(;;) {				    nameAVA = *nameAVAS++;				    status = CERT_CompareAVA(constraintAVA, nameAVA);				    if (status == SECEqual || *nameAVAS == NULL) {					break;				    }				}				if (status == SECEqual || *nameRDNS == NULL) {				    break;				}			    }			    if (status != SECEqual || *constraintAVAS == NULL) {				break;			    }			}			if (status != SECEqual || *constraintRDNS == NULL) {			    break;			}		    }		    if (status == SECEqual) {			if (excluded == PR_FALSE) {			    goto found;			} else {			    goto loser;			}		    }		    break;		} else if (current->name.type == certRFC822Name) {		    current = cert_get_next_name_constraint(current);		    continue;		}	      default:		/* other types are not supported */		if (excluded) {		    goto found;		} else {		    goto loser;		}	    }	    if (rv == SECSuccess && status == SECEqual) {		goto found;	    }	    current = cert_get_next_name_constraint(current);	} while (current !=constraints);    } else {	goto found;    }loser:    if (certName.arena) {	CERT_DestroyName(&certName);    }    if (constraintName.arena) {	CERT_DestroyName(&constraintName);    }    return SECFailure;found:    if (certName.arena) {	CERT_DestroyName(&certName);    }    if (constraintName.arena) {	CERT_DestroyName(&constraintName);    }    return SECSuccess;}CERTCertificate *CERT_CompareNameSpace(CERTCertificate  *cert,		      CERTGeneralName  *namesList, 		      SECItem          *namesListIndex, 		      PRArenaPool      *arena, 		      CERTCertDBHandle *handle){    SECStatus            rv;    SECItem              constraintsExtension;    CERTNameConstraints  *constraints;    CERTGeneralName      *currentName;    int                  count = 0;    CERTNameConstraint  *matchingConstraints;    CERTCertificate      *badCert = NULL;        rv = CERT_FindCertExtension(cert, SEC_OID_X509_NAME_CONSTRAINTS, &constraintsExtension);    if (rv != SECSuccess) {	return NULL;    }    constraints = cert_DecodeNameConstraints(arena, &constraintsExtension);    currentName = namesList;    if (constraints == NULL) {	goto loser;    }    do { 	if (constraints->excluded != NULL) { 	    rv = CERT_GetNameConstriantByType(constraints->excluded, currentName->type,  					      &matchingConstraints, arena); 	    if (rv != SECSuccess) { 		goto loser; 	    } 	    if (matchingConstraints != NULL) { 		rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, 						     PR_TRUE); 		if (rv != SECFailure) { 		    goto loser; 		} 	    } 	} 	if (constraints->permited != NULL) { 	    rv = CERT_GetNameConstriantByType(constraints->permited, currentName->type,  					      &matchingConstraints, arena);            if (rv != SECSuccess) {		goto loser;	    } 	    if (matchingConstraints != NULL) { 		rv = cert_CompareNameWithConstraints(currentName, matchingConstraints, 						     PR_FALSE); 		if (rv != SECSuccess) { 		    goto loser; 		} 	    } else { 		goto loser; 	    } 	} 	currentName = cert_get_next_general_name(currentName); 	count ++;    } while (currentName != namesList);    return NULL;loser:    badCert = CERT_FindCertByName (handle, &namesListIndex[count]);    return badCert;}/* Search the cert for an X509_SUBJECT_ALT_NAME extension.** ASN1 Decode it into a list of alternate names.** Search the list of alternate names for one with the NETSCAPE_NICKNAME OID.** ASN1 Decode that name.  Turn the result into a zString.  ** Look for duplicate nickname already in the certdb. ** If one is found, create a nickname string that is not a duplicate.*/char *CERT_GetNickName(CERTCertificate   *cert, 		 CERTCertDBHandle  *handle,		 PRArenaPool      *nicknameArena){     CERTGeneralName  *current;    CERTGeneralName  *names;    char             *nickname   = NULL;    char             *returnName = NULL;    char             *basename   = NULL;    PRArenaPool      *arena      = NULL;    CERTCertificate  *tmpcert;    SECStatus        rv;    int              count;    int              found = 0;    SECItem          altNameExtension;    SECItem          nick;    if (handle == NULL) {	handle = CERT_GetDefaultCertDB();    }    altNameExtension.data = NULL;    rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, 				&altNameExtension);    if (rv != SECSuccess) { 	goto loser;     }    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	goto loser;    }    names = CERT_DecodeAltNameExtension(arena, &altNameExtension);    if (names == NULL) {	goto loser;    }     current = names;    do {	if (current->type == certOtherName && 	    SECOID_FindOIDTag(&current->name.OthName.oid) == 	      SEC_OID_NETSCAPE_NICKNAME) {	    found = 1;	    break;	}	current = cert_get_next_general_name(current);    } while (current != names);    if (!found)    	goto loser;    rv = SEC_ASN1DecodeItem(arena, &nick, SEC_IA5StringTemplate, 			    &current->name.OthName.name);    if (rv != SECSuccess) {	goto loser;    }    /* make a null terminated string out of nick, with room enough at    ** the end to add on a number of up to 21 digits in length, (a signed    ** 64-bit number in decimal) plus a space and a "#".     */    nickname = (char*)PORT_ZAlloc(nick.len + 24);    if (!nickname) 	goto loser;    PORT_Strncpy(nickname, (char *)nick.data, nick.len);    /* Don't let this cert's nickname duplicate one already in the DB.    ** If it does, create a variant of the nickname that doesn't.    */    count = 0;    while ((tmpcert = CERT_FindCertByNickname(handle, nickname)) != NULL) {	CERT_DestroyCertificate(tmpcert);	if (!basename) {	    basename = PORT_Strdup(nickname);	    if (!basename)		goto loser;	}	count++;	sprintf(nickname, "%s #%d", basename, count);    }    /* success */    if (nicknameArena) {	returnName =  PORT_ArenaStrdup(nicknameArena, nickname);    } else {	returnName = nickname;	nickname = NULL;    }loser:    if (arena != NULL) 	PORT_FreeArena(arena, PR_FALSE);    if (nickname)	PORT_Free(nickname);    if (basename)	PORT_Free(basename);    if (altNameExtension.data)    	PORT_Free(altNameExtension.data);    return returnName;}SECStatusCERT_CompareGeneralName(CERTGeneralName *a, CERTGeneralName *b){    CERTGeneralName *currentA;    CERTGeneralName *currentB;    PRBool found;    currentA = a;    currentB = b;    if (a != NULL) {	do { 	    if (currentB == NULL) {		return SECFailure;	    }	    currentB = cert_get_next_general_name(currentB);	    currentA = cert_get_next_general_name(currentA);	} while (currentA != a);    }    if (currentB != b) {	return SECFailure;    }    currentA = a;    do {	currentB = b;	found = PR_FALSE;	do {	    if (currentB->type == currentA->type) {		switch (currentB->type) {		  case certDNSName:		  case certEDIPartyName:		  case certIPAddress:		  case certRegisterID:		  case certRFC822Name:		  case certX400Address:		  case certURI:		    if (SECITEM_CompareItem(&currentA->name.other,					    &currentB->name.other) 			== SECEqual) {			found = PR_TRUE;		    }		    break;		  case certOtherName:		    if (SECITEM_CompareItem(&currentA->name.OthName.oid,					    &currentB->name.OthName.oid) 			== SECEqual &&			SECITEM_CompareItem(&currentA->name.OthName.name,					    &currentB->name.OthName.name)			== SECEqual) {			found = PR_TRUE;		    }		    break;		  case certDirectoryName:		    if (CERT_CompareName(&currentA->name.directoryName,					 &currentB->name.directoryName)			== SECEqual) {			found = PR_TRUE;		    }		}		    	    }	    currentB = cert_get_next_general_name(currentB);	} while (currentB != b && found != PR_TRUE);	if (found != PR_TRUE) {	    return SECFailure;	}	currentA = cert_get_next_general_name(currentA);    } while (currentA != a);    return SECSuccess;}SECStatusCERT_CompareGeneralNameLists(CERTGeneralNameList *a, CERTGeneralNameList *b){    SECStatus rv;    if (a == b) {	return SECSuccess;    }    if (a != NULL && b != NULL) {	PR_Lock(a->lock);	PR_Lock(b->lock);	rv = CERT_CompareGeneralName(a->name, b->name);	PR_Unlock(a->lock);	PR_Unlock(b->lock);    } else {	rv = SECFailure;    }    return rv;}void *CERT_GetGeneralNameFromListByType(CERTGeneralNameList *list,				  CERTGeneralNameType type,				  PRArenaPool *arena){    CERTName *name = NULL;     SECItem *item = NULL;    OtherName *other = NULL;    OtherName *tmpOther = NULL;    void *data;    PR_Lock(list->lock);    data = CERT_GetGeneralNameByType(list->name, type, PR_FALSE);    if (data != NULL) {	switch (type) {	  case certDNSName:	  case certEDIPartyName:	  case certIPAddress:	  case certRegisterID:	  case certRFC822Name:	  case certX400Address:	  case certURI:	    if (arena != NULL) {		item = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem));		if (item != NULL) {		    SECITEM_CopyItem(arena, item, (SECItem *) data);		}	    } else { 		item = SECITEM_DupItem((SECItem *) data);	    }	    PR_Unlock(list->lock);	    return item;	  case certOtherName:	    other = (OtherName *) data;	    if (arena != NULL) {		tmpOther = (OtherName *)PORT_ArenaAlloc(arena, 							sizeof(OtherName));	    } else {		tmpOther = (OtherName *) PORT_Alloc(sizeof(OtherName));	    }	    if (tmpOther != NULL) {		SECITEM_CopyItem(arena, &tmpOther->oid, &other->oid);		SECITEM_CopyItem(arena, &tmpOther->name, &other->name);	    }	    PR_Unlock(list->lock);	    return tmpOther;	  case certDirectoryName:	    if (arena == NULL) {		PR_Unlock(list->lock);		return NULL;	    } else {		name = (CERTName *) PORT_ArenaZAlloc(list->arena, 						    sizeof(CERTName));		if (name != NULL) {		    CERT_CopyName(arena, name, (CERTName *) data);		}		PR_Unlock(list->lock);		return name;	    }	}    }    PR_Unlock(list->lock);    return NULL;}voidCERT_AddGeneralNameToList(CERTGeneralNameList *list, 			  CERTGeneralNameType type,			  void *data, SECItem *oid){    CERTGeneralName *name;    if (list != NULL && data != NULL) {	PR_Lock(list->lock);	name = (CERTGeneralName *) 	    PORT_ArenaZAlloc(list->arena, sizeof(CERTGeneralName));	name->type = type;	switch (type) {	  case certDNSName:	  case certEDIPartyName:	  case certIPAddress:	  case certRegisterID:	  case certRFC822Name:	  case certX400Address:	  case certURI:	    SECITEM_CopyItem(list->arena, &name->name.other, (SECItem *)data);	    break;	  case certOtherName:	    SECITEM_CopyItem(list->arena, &name->name.OthName.name,			     (SECItem *) data);	    SECITEM_CopyItem(list->arena, &name->name.OthName.oid,			     oid);	    break;	  case certDirectoryName:	    CERT_CopyName(list->arena, &name->name.directoryName,			  (CERTName *) data);	    break;	}	name->l.prev = name->l.next = &name->l;	list->name = cert_CombineNamesLists(list->name, name);	list->len++;	PR_Unlock(list->lock);    }    return;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?