⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_ciph.c

📁 一个用于点对点传输加密的工具包源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		curr = curr->next;		}	/*	 * Go through the list of used strength_bits values in descending	 * order.	 */	for (i = max_strength_bits; i >= 0; i--)		if (number_uses[i] > 0)			ssl_cipher_apply_rule(0, 0, 0, 0, CIPHER_ORD, i,					list, head_p, tail_p);	OPENSSL_free(number_uses);	return(1);	}static int ssl_cipher_process_rulestr(const char *rule_str,		CIPHER_ORDER *list, CIPHER_ORDER **head_p,		CIPHER_ORDER **tail_p, SSL_CIPHER **ca_list)	{	unsigned long algorithms, mask, algo_strength, mask_strength;	const char *l, *start, *buf;	int j, multi, found, rule, retval, ok, buflen;	char ch;	retval = 1;	l = rule_str;	for (;;)		{		ch = *l;		if (ch == '\0')			break;		/* done */		if (ch == '-')			{ rule = CIPHER_DEL; l++; }		else if (ch == '+')			{ rule = CIPHER_ORD; l++; }		else if (ch == '!')			{ rule = CIPHER_KILL; l++; }		else if (ch == '@')			{ rule = CIPHER_SPECIAL; l++; }		else			{ rule = CIPHER_ADD; }		if (ITEM_SEP(ch))			{			l++;			continue;			}		algorithms = mask = algo_strength = mask_strength = 0;		start=l;		for (;;)			{			ch = *l;			buf = l;			buflen = 0;#ifndef CHARSET_EBCDIC			while (	((ch >= 'A') && (ch <= 'Z')) ||				((ch >= '0') && (ch <= '9')) ||				((ch >= 'a') && (ch <= 'z')) ||				 (ch == '-'))#else			while (	isalnum(ch) || (ch == '-'))#endif				 {				 ch = *(++l);				 buflen++;				 }			if (buflen == 0)				{				/*				 * We hit something we cannot deal with,				 * it is no command or separator nor				 * alphanumeric, so we call this an error.				 */				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,				       SSL_R_INVALID_COMMAND);				retval = found = 0;				l++;				break;				}			if (rule == CIPHER_SPECIAL)				{				found = 0; /* unused -- avoid compiler warning */				break;	/* special treatment */				}			/* check for multi-part specification */			if (ch == '+')				{				multi=1;				l++;				}			else				multi=0;			/*			 * Now search for the cipher alias in the ca_list. Be careful			 * with the strncmp, because the "buflen" limitation			 * will make the rule "ADH:SOME" and the cipher			 * "ADH-MY-CIPHER" look like a match for buflen=3.			 * So additionally check whether the cipher name found			 * has the correct length. We can save a strlen() call:			 * just checking for the '\0' at the right place is			 * sufficient, we have to strncmp() anyway.			 */			 j = found = 0;			 while (ca_list[j])				{				if ((ca_list[j]->name[buflen] == '\0') &&				    !strncmp(buf, ca_list[j]->name, buflen))					{					found = 1;					break;					}				else					j++;				}			if (!found)				break;	/* ignore this entry */			algorithms |= ca_list[j]->algorithms;			mask |= ca_list[j]->mask;			algo_strength |= ca_list[j]->algo_strength;			mask_strength |= ca_list[j]->mask_strength;			if (!multi) break;			}		/*		 * Ok, we have the rule, now apply it		 */		if (rule == CIPHER_SPECIAL)			{	/* special command */			ok = 0;			if ((buflen == 8) &&				!strncmp(buf, "STRENGTH", 8))				ok = ssl_cipher_strength_sort(list,					head_p, tail_p);			else				SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,					SSL_R_INVALID_COMMAND);			if (ok == 0)				retval = 0;			/*			 * We do not support any "multi" options			 * together with "@", so throw away the			 * rest of the command, if any left, until			 * end or ':' is found.			 */			while ((*l != '\0') && ITEM_SEP(*l))				l++;			}		else if (found)			{			ssl_cipher_apply_rule(algorithms, mask,				algo_strength, mask_strength, rule, -1,				list, head_p, tail_p);			}		else			{			while ((*l != '\0') && ITEM_SEP(*l))				l++;			}		if (*l == '\0') break; /* done */		}	return(retval);	}STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,		STACK_OF(SSL_CIPHER) **cipher_list,		STACK_OF(SSL_CIPHER) **cipher_list_by_id,		const char *rule_str)	{	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;	unsigned long disabled_mask;	STACK_OF(SSL_CIPHER) *cipherstack;	const char *rule_p;	CIPHER_ORDER *list = NULL, *head = NULL, *tail = NULL, *curr;	SSL_CIPHER **ca_list = NULL;	/*	 * Return with error if nothing to do.	 */	if (rule_str == NULL) return(NULL);	if (init_ciphers) load_ciphers();	/*	 * To reduce the work to do we only want to process the compiled	 * in algorithms, so we first get the mask of disabled ciphers.	 */	disabled_mask = ssl_cipher_get_disabled();	/*	 * Now we have to collect the available ciphers from the compiled	 * in ciphers. We cannot get more than the number compiled in, so	 * it is used for allocation.	 */	num_of_ciphers = ssl_method->num_ciphers();	list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);	if (list == NULL)		{		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);		return(NULL);	/* Failure */		}	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, disabled_mask,				   list, &head, &tail);	/*	 * We also need cipher aliases for selecting based on the rule_str.	 * There might be two types of entries in the rule_str: 1) names	 * of ciphers themselves 2) aliases for groups of ciphers.	 * For 1) we need the available ciphers and for 2) the cipher	 * groups of cipher_aliases added together in one list (otherwise	 * we would be happy with just the cipher_aliases table).	 */	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;	ca_list =		(SSL_CIPHER **)OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);	if (ca_list == NULL)		{		OPENSSL_free(list);		SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST,ERR_R_MALLOC_FAILURE);		return(NULL);	/* Failure */		}	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mask,				   head);	/*	 * If the rule_string begins with DEFAULT, apply the default rule	 * before using the (possibly available) additional rules.	 */	ok = 1;	rule_p = rule_str;	if (strncmp(rule_str,"DEFAULT",7) == 0)		{		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,			list, &head, &tail, ca_list);		rule_p += 7;		if (*rule_p == ':')			rule_p++;		}	if (ok && (strlen(rule_p) > 0))		ok = ssl_cipher_process_rulestr(rule_p, list, &head, &tail,						ca_list);	OPENSSL_free(ca_list);	/* Not needed anymore */	if (!ok)		{	/* Rule processing failure */		OPENSSL_free(list);		return(NULL);		}	/*	 * Allocate new "cipherstack" for the result, return with error	 * if we cannot get one.	 */	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)		{		OPENSSL_free(list);		return(NULL);		}	/*	 * The cipher selection for the list is done. The ciphers are added	 * to the resulting precedence to the STACK_OF(SSL_CIPHER).	 */	for (curr = head; curr != NULL; curr = curr->next)		{		if (curr->active)			{			sk_SSL_CIPHER_push(cipherstack, curr->cipher);#ifdef CIPHER_DEBUG			printf("<%s>\n",curr->cipher->name);#endif			}		}	OPENSSL_free(list);	/* Not needed any longer */	/*	 * The following passage is a little bit odd. If pointer variables	 * were supplied to hold STACK_OF(SSL_CIPHER) return information,	 * the old memory pointed to is free()ed. Then, however, the	 * cipher_list entry will be assigned just a copy of the returned	 * cipher stack. For cipher_list_by_id a copy of the cipher stack	 * will be created. See next comment...	 */	if (cipher_list != NULL)		{		if (*cipher_list != NULL)			sk_SSL_CIPHER_free(*cipher_list);		*cipher_list = cipherstack;		}	if (cipher_list_by_id != NULL)		{		if (*cipher_list_by_id != NULL)			sk_SSL_CIPHER_free(*cipher_list_by_id);		*cipher_list_by_id = sk_SSL_CIPHER_dup(cipherstack);		}	/*	 * Now it is getting really strange. If something failed during	 * the previous pointer assignment or if one of the pointers was	 * not requested, the error condition is met. That might be	 * discussable. The strange thing is however that in this case	 * the memory "ret" pointed to is "free()ed" and hence the pointer	 * cipher_list becomes wild. The memory reserved for	 * cipher_list_by_id however is not "free()ed" and stays intact.	 */	if (	(cipher_list_by_id == NULL) ||		(*cipher_list_by_id == NULL) ||		(cipher_list == NULL) ||		(*cipher_list == NULL))		{		sk_SSL_CIPHER_free(cipherstack);		return(NULL);		}	sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);	return(cipherstack);	}char *SSL_CIPHER_description(SSL_CIPHER *cipher, char *buf, int len)	{	int is_export,pkl,kl;	char *ver,*exp;	char *kx,*au,*enc,*mac;	unsigned long alg,alg2,alg_s;	static char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n";		alg=cipher->algorithms;	alg_s=cipher->algo_strength;	alg2=cipher->algorithm2;	is_export=SSL_C_IS_EXPORT(cipher);	pkl=SSL_C_EXPORT_PKEYLENGTH(cipher);	kl=SSL_C_EXPORT_KEYLENGTH(cipher);	exp=is_export?" export":"";	if (alg & SSL_SSLV2)		ver="SSLv2";	else if (alg & SSL_SSLV3)		ver="SSLv3";	else		ver="unknown";	switch (alg&SSL_MKEY_MASK)		{	case SSL_kRSA:		kx=is_export?(pkl == 512 ? "RSA(512)" : "RSA(1024)"):"RSA";		break;	case SSL_kDHr:		kx="DH/RSA";		break;	case SSL_kDHd:		kx="DH/DSS";		break;	case SSL_kFZA:		kx="Fortezza";		break;	case SSL_kEDH:		kx=is_export?(pkl == 512 ? "DH(512)" : "DH(1024)"):"DH";		break;	default:		kx="unknown";		}	switch (alg&SSL_AUTH_MASK)		{	case SSL_aRSA:		au="RSA";		break;	case SSL_aDSS:		au="DSS";		break;	case SSL_aDH:		au="DH";		break;	case SSL_aFZA:	case SSL_aNULL:		au="None";		break;	default:		au="unknown";		break;		}	switch (alg&SSL_ENC_MASK)		{	case SSL_DES:		enc=(is_export && kl == 5)?"DES(40)":"DES(56)";		break;	case SSL_3DES:		enc="3DES(168)";		break;	case SSL_RC4:		enc=is_export?(kl == 5 ? "RC4(40)" : "RC4(56)")		  :((alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)");		break;	case SSL_RC2:		enc=is_export?(kl == 5 ? "RC2(40)" : "RC2(56)"):"RC2(128)";		break;	case SSL_IDEA:		enc="IDEA(128)";		break;	case SSL_eFZA:		enc="Fortezza";		break;	case SSL_eNULL:		enc="None";		break;	default:		enc="unknown";		break;		}	switch (alg&SSL_MAC_MASK)		{	case SSL_MD5:		mac="MD5";		break;	case SSL_SHA1:		mac="SHA1";		break;	default:		mac="unknown";		break;		}	if (buf == NULL)		{		len=128;		buf=OPENSSL_malloc(len);		if (buf == NULL) return("OPENSSL_malloc Error");		}	else if (len < 128)		return("Buffer too small");	BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,exp);	return(buf);	}char *SSL_CIPHER_get_version(SSL_CIPHER *c)	{	int i;	if (c == NULL) return("(NONE)");	i=(int)(c->id>>24L);	if (i == 3)		return("TLSv1/SSLv3");	else if (i == 2)		return("SSLv2");	else		return("unknown");	}/* return the actual cipher being used */const char *SSL_CIPHER_get_name(SSL_CIPHER *c)	{	if (c != NULL)		return(c->name);	return("(NONE)");	}/* number of bits for symmetric cipher */int SSL_CIPHER_get_bits(SSL_CIPHER *c, int *alg_bits)	{	int ret=0;	if (c != NULL)		{		if (alg_bits != NULL) *alg_bits = c->alg_bits;		ret = c->strength_bits;		}	return(ret);	}SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)	{	SSL_COMP *ctmp;	int i,nn;	if ((n == 0) || (sk == NULL)) return(NULL);	nn=sk_SSL_COMP_num(sk);	for (i=0; i<nn; i++)		{		ctmp=sk_SSL_COMP_value(sk,i);		if (ctmp->id == n)			return(ctmp);		}	return(NULL);	}static int sk_comp_cmp(const SSL_COMP * const *a,			const SSL_COMP * const *b)	{	return((*a)->id-(*b)->id);	}STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)	{	return(ssl_comp_methods);	}int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)	{	SSL_COMP *comp;	STACK_OF(SSL_COMP) *sk;	comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));	comp->id=id;	comp->method=cm;	if (ssl_comp_methods == NULL)		sk=ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);	else		sk=ssl_comp_methods;	if ((sk == NULL) || !sk_SSL_COMP_push(sk,comp))		{		SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,ERR_R_MALLOC_FAILURE);		return(0);		}	else		return(1);	}

⌨️ 快捷键说明

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